func setupBaseImage() { eng, err := engine.New(unitTestStoreBase) if err != nil { log.Fatalf("Can't initialize engine at %s: %s", unitTestStoreBase, err) } job := eng.Job("initserver") job.Setenv("Root", unitTestStoreBase) job.SetenvBool("Autorestart", false) job.Setenv("BridgeIface", unitTestNetworkBridge) if err := job.Run(); err != nil { log.Fatalf("Unable to create a runtime for tests: %s", err) } job = eng.Job("inspect", unitTestImageName, "image") img, _ := job.Stdout.AddEnv() // If the unit test is not found, try to download it. if err := job.Run(); err != nil || img.Get("id") != unitTestImageID { // Retrieve the Image job = eng.Job("pull", unitTestImageName) job.Stdout.Add(utils.NopWriteCloser(os.Stdout)) if err := job.Run(); err != nil { log.Fatalf("Unable to pull the test image: %s", err) } } }
func NewTestEngine(t utils.Fataler) *engine.Engine { root, err := newTestDirectory(unitTestStoreBase) if err != nil { t.Fatal(err) } eng, err := engine.New(root) if err != nil { t.Fatal(err) } // Load default plugins // (This is manually copied and modified from main() until we have a more generic plugin system) job := eng.Job("initserver") job.Setenv("Root", root) job.SetenvBool("AutoRestart", false) // TestGetEnabledCors and TestOptionsRoute require EnableCors=true job.SetenvBool("EnableCors", true) if err := job.Run(); err != nil { t.Fatal(err) } return eng }
// Create a temporary runtime suitable for unit testing. // Call t.Fatal() at the first error. func mkRuntime(f utils.Fataler) *docker.Runtime { root, err := newTestDirectory(unitTestStoreBase) if err != nil { f.Fatal(err) } config := &docker.DaemonConfig{ Root: root, AutoRestart: false, Mtu: docker.DefaultNetworkMtu, } eng, err := engine.New(root) if err != nil { f.Fatal(err) } r, err := docker.NewRuntimeFromDirectory(config, eng) if err != nil { f.Fatal(err) } return r }
func TestRestartKillWait(t *testing.T) { eng := NewTestEngine(t) srv := mkServerFromEngine(eng, t) runtime := mkRuntimeFromEngine(eng, t) defer runtime.Nuke() config, hostConfig, _, err := docker.ParseRun([]string{"-i", unitTestImageID, "/bin/cat"}, nil) if err != nil { t.Fatal(err) } id := createTestContainer(eng, config, t) job := eng.Job("containers") job.SetenvBool("all", true) outs, err := job.Stdout.AddListTable() if err != nil { t.Fatal(err) } if err := job.Run(); err != nil { t.Fatal(err) } if len(outs.Data) != 1 { t.Errorf("Expected 1 container, %v found", len(outs.Data)) } job = eng.Job("start", id) if err := job.ImportEnv(hostConfig); err != nil { t.Fatal(err) } if err := job.Run(); err != nil { t.Fatal(err) } job = eng.Job("kill", id) if err := job.Run(); err != nil { t.Fatal(err) } eng, err = engine.New(eng.Root()) if err != nil { t.Fatal(err) } job = eng.Job("initserver") job.Setenv("Root", eng.Root()) job.SetenvBool("AutoRestart", false) // TestGetEnabledCors and TestOptionsRoute require EnableCors=true job.SetenvBool("EnableCors", true) if err := job.Run(); err != nil { t.Fatal(err) } srv = mkServerFromEngine(eng, t) job = srv.Eng.Job("containers") job.SetenvBool("all", true) outs, err = job.Stdout.AddListTable() if err != nil { t.Fatal(err) } if err := job.Run(); err != nil { t.Fatal(err) } if len(outs.Data) != 1 { t.Errorf("Expected 1 container, %v found", len(outs.Data)) } setTimeout(t, "Waiting on stopped container timedout", 5*time.Second, func() { job = srv.Eng.Job("wait", outs.Data[0].Get("Id")) var statusStr string job.Stdout.AddString(&statusStr) if err := job.Run(); err != nil { t.Fatal(err) } }) }
func TestReloadContainerLinks(t *testing.T) { // FIXME: here we don't use NewTestEngine because it calls initserver with Autorestart=false, // and we want to set it to true. root, err := newTestDirectory(unitTestStoreBase) if err != nil { t.Fatal(err) } eng, err := engine.New(root) if err != nil { t.Fatal(err) } job := eng.Job("initserver") job.Setenv("Root", eng.Root()) job.SetenvBool("Autorestart", true) if err := job.Run(); err != nil { t.Fatal(err) } runtime1 := mkRuntimeFromEngine(eng, t) defer nuke(runtime1) // Create a container with one instance of docker container1, _, _ := mkContainer(runtime1, []string{"-i", "_", "/bin/sh"}, t) defer runtime1.Destroy(container1) // Create a second container meant to be killed container2, _, _ := mkContainer(runtime1, []string{"-i", "_", "/bin/cat"}, t) defer runtime1.Destroy(container2) // Start the container non blocking if err := container2.Start(); err != nil { t.Fatal(err) } // Add a link to container 2 // FIXME @shykes: setting hostConfig.Links seems redundant with calling RegisterLink(). // Why do we need it @crosbymichael? // container1.hostConfig.Links = []string{"/" + container2.ID + ":first"} if err := runtime1.RegisterLink(container1, container2, "first"); err != nil { t.Fatal(err) } if err := container1.Start(); err != nil { t.Fatal(err) } if !container2.State.IsRunning() { t.Fatalf("Container %v should appear as running but isn't", container2.ID) } if !container1.State.IsRunning() { t.Fatalf("Container %s should appear as running but isn't", container1.ID) } if len(runtime1.List()) != 2 { t.Errorf("Expected 2 container, %v found", len(runtime1.List())) } // Here are are simulating a docker restart - that is, reloading all containers // from scratch eng, err = engine.New(root) if err != nil { t.Fatal(err) } job = eng.Job("initserver") job.Setenv("Root", eng.Root()) job.SetenvBool("Autorestart", false) if err := job.Run(); err != nil { t.Fatal(err) } runtime2 := mkRuntimeFromEngine(eng, t) if len(runtime2.List()) != 2 { t.Errorf("Expected 2 container, %v found", len(runtime2.List())) } runningCount := 0 for _, c := range runtime2.List() { if c.State.IsRunning() { runningCount++ } } if runningCount != 2 { t.Fatalf("Expected 2 container alive, %d found", runningCount) } // FIXME: we no longer test if containers were registered in the right order, // because there is no public // Make sure container 2 ( the child of container 1 ) was registered and started first // with the runtime // containers := runtime2.List() if len(containers) == 0 { t.Fatalf("Runtime has no containers") } first := containers[0] if first.ID != container2.ID { t.Fatalf("Container 2 %s should be registered first in the runtime", container2.ID) } // Verify that the link is still registered in the runtime if c := runtime2.Get(container1.Name); c == nil { t.Fatal("Named container is no longer registered after restart") } }
func TestRestore(t *testing.T) { eng := NewTestEngine(t) runtime1 := mkRuntimeFromEngine(eng, t) defer runtime1.Nuke() // Create a container with one instance of docker container1, _, _ := mkContainer(runtime1, []string{"_", "ls", "-al"}, t) defer runtime1.Destroy(container1) // Create a second container meant to be killed container2, _, _ := mkContainer(runtime1, []string{"-i", "_", "/bin/cat"}, t) defer runtime1.Destroy(container2) // Start the container non blocking if err := container2.Start(); err != nil { t.Fatal(err) } if !container2.State.IsRunning() { t.Fatalf("Container %v should appear as running but isn't", container2.ID) } // Simulate a crash/manual quit of dockerd: process dies, states stays 'Running' cStdin, _ := container2.StdinPipe() cStdin.Close() if err := container2.WaitTimeout(2 * time.Second); err != nil { t.Fatal(err) } container2.State.SetRunning(42) container2.ToDisk() if len(runtime1.List()) != 2 { t.Errorf("Expected 2 container, %v found", len(runtime1.List())) } if err := container1.Run(); err != nil { t.Fatal(err) } if !container2.State.IsRunning() { t.Fatalf("Container %v should appear as running but isn't", container2.ID) } // Here are are simulating a docker restart - that is, reloading all containers // from scratch root := eng.Root() eng, err := engine.New(root) if err != nil { t.Fatal(err) } job := eng.Job("initserver") job.Setenv("Root", eng.Root()) job.SetenvBool("Autorestart", false) if err := job.Run(); err != nil { t.Fatal(err) } runtime2 := mkRuntimeFromEngine(eng, t) if len(runtime2.List()) != 2 { t.Errorf("Expected 2 container, %v found", len(runtime2.List())) } runningCount := 0 for _, c := range runtime2.List() { if c.State.IsRunning() { t.Errorf("Running container found: %v (%v)", c.ID, c.Path) runningCount++ } } if runningCount != 0 { t.Fatalf("Expected 0 container alive, %d found", runningCount) } container3 := runtime2.Get(container1.ID) if container3 == nil { t.Fatal("Unable to Get container") } if err := container3.Run(); err != nil { t.Fatal(err) } container2.State.SetStopped(0) }
func main() { if selfPath := utils.SelfPath(); selfPath == "/sbin/init" || selfPath == "/.dockerinit" { // Running in init mode sysinit.SysInit() return } var ( flVersion = flag.Bool([]string{"v", "-version"}, false, "Print version information and quit") flDaemon = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode") flDebug = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode") flAutoRestart = flag.Bool([]string{"r", "-restart"}, true, "Restart previously running containers") bridgeName = flag.String([]string{"b", "-bridge"}, "", "Attach containers to a pre-existing network bridge; use 'none' to disable container networking") bridgeIp = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b") pidfile = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file") flRoot = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the docker runtime") flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API") flDns = docker.NewListOpts(docker.ValidateIp4Address) flEnableIptables = flag.Bool([]string{"#iptables", "-iptables"}, true, "Disable docker's addition of iptables rules") flEnableIpForward = flag.Bool([]string{"#ip-forward", "-ip-forward"}, true, "Disable enabling of net.ipv4.ip_forward") flDefaultIp = flag.String([]string{"#ip", "-ip"}, "0.0.0.0", "Default IP address to use when binding container ports") flInterContainerComm = flag.Bool([]string{"#icc", "-icc"}, true, "Enable inter-container communication") flGraphDriver = flag.String([]string{"s", "-storage-driver"}, "", "Force the docker runtime to use a specific storage driver") flHosts = docker.NewListOpts(docker.ValidateHost) flMtu = flag.Int([]string{"#mtu", "-mtu"}, docker.DefaultNetworkMtu, "Set the containers network mtu") ) flag.Var(&flDns, []string{"#dns", "-dns"}, "Force docker to use specific DNS servers") flag.Var(&flHosts, []string{"H", "-host"}, "tcp://host:port, unix://path/to/socket, fd://* or fd://socketfd to use in daemon mode. Multiple sockets can be specified") flag.Parse() if *flVersion { showVersion() return } if flHosts.Len() == 0 { defaultHost := os.Getenv("DOCKER_HOST") if defaultHost == "" || *flDaemon { // If we do not have a host, default to unix socket defaultHost = fmt.Sprintf("unix://%s", api.DEFAULTUNIXSOCKET) } flHosts.Set(defaultHost) } if *bridgeName != "" && *bridgeIp != "" { log.Fatal("You specified -b & --bip, mutually exclusive options. Please specify only one.") } if *flDebug { os.Setenv("DEBUG", "1") } docker.GITCOMMIT = GITCOMMIT docker.VERSION = VERSION if *flDaemon { if flag.NArg() != 0 { flag.Usage() return } eng, err := engine.New(*flRoot) if err != nil { log.Fatal(err) } // Load plugin: httpapi job := eng.Job("initserver") job.Setenv("Pidfile", *pidfile) job.Setenv("Root", *flRoot) job.SetenvBool("AutoRestart", *flAutoRestart) job.SetenvList("Dns", flDns.GetAll()) job.SetenvBool("EnableIptables", *flEnableIptables) job.SetenvBool("EnableIpForward", *flEnableIpForward) job.Setenv("BridgeIface", *bridgeName) job.Setenv("BridgeIP", *bridgeIp) job.Setenv("DefaultIp", *flDefaultIp) job.SetenvBool("InterContainerCommunication", *flInterContainerComm) job.Setenv("GraphDriver", *flGraphDriver) job.SetenvInt("Mtu", *flMtu) if err := job.Run(); err != nil { log.Fatal(err) } // Serve api job = eng.Job("serveapi", flHosts.GetAll()...) job.SetenvBool("Logging", true) job.SetenvBool("EnableCors", *flEnableCors) job.Setenv("Version", VERSION) if err := job.Run(); err != nil { log.Fatal(err) } } else { if flHosts.Len() > 1 { log.Fatal("Please specify only one -H") } protoAddrParts := strings.SplitN(flHosts.GetAll()[0], "://", 2) if err := docker.ParseCommands(protoAddrParts[0], protoAddrParts[1], flag.Args()...); err != nil { if sterr, ok := err.(*utils.StatusError); ok { if sterr.Status != "" { log.Println(sterr.Status) } os.Exit(sterr.StatusCode) } log.Fatal(err) } } }