Browse Source

Make daemon initialization in main goroutine

It is simplifies code and lead to next refactoring step, where daemon
will be incorporated to some structure which represents API.

Signed-off-by: Alexander Morozov <lk4d4@docker.com>
Alexander Morozov 10 years ago
parent
commit
181fea24aa
2 changed files with 27 additions and 55 deletions
  1. 25 53
      docker/daemon.go
  2. 2 2
      integration-cli/docker_cli_daemon_test.go

+ 25 - 53
docker/daemon.go

@@ -7,7 +7,6 @@ import (
 	"io"
 	"io"
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
-	"strings"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	apiserver "github.com/docker/docker/api/server"
 	apiserver "github.com/docker/docker/api/server"
@@ -93,40 +92,6 @@ func mainDaemon() {
 	}
 	}
 	daemonCfg.TrustKeyPath = *flTrustKey
 	daemonCfg.TrustKeyPath = *flTrustKey
 
 
-	registryService := registry.NewService(registryCfg)
-	// load the daemon in the background so we can immediately start
-	// the http api so that connections don't fail while the daemon
-	// is booting
-	daemonInitWait := make(chan error)
-	go func() {
-		d, err := daemon.NewDaemon(daemonCfg, eng, registryService)
-		if err != nil {
-			daemonInitWait <- err
-			return
-		}
-
-		logrus.WithFields(logrus.Fields{
-			"version":     dockerversion.VERSION,
-			"commit":      dockerversion.GITCOMMIT,
-			"execdriver":  d.ExecutionDriver().Name(),
-			"graphdriver": d.GraphDriver().String(),
-		}).Info("Docker daemon")
-
-		if err := d.Install(eng); err != nil {
-			daemonInitWait <- err
-			return
-		}
-
-		b := &builder.BuilderJob{eng, d}
-		b.Install()
-
-		// after the daemon is done setting up we can tell the api to start
-		// accepting connections
-		apiserver.AcceptConnections()
-
-		daemonInitWait <- nil
-	}()
-
 	serverConfig := &apiserver.ServerConfig{
 	serverConfig := &apiserver.ServerConfig{
 		Logging:     true,
 		Logging:     true,
 		EnableCors:  daemonCfg.EnableCors,
 		EnableCors:  daemonCfg.EnableCors,
@@ -153,30 +118,37 @@ func mainDaemon() {
 		serveAPIWait <- nil
 		serveAPIWait <- nil
 	}()
 	}()
 
 
-	// Wait for the daemon startup goroutine to finish
-	// This makes sure we can actually cleanly shutdown the daemon
-	logrus.Debug("waiting for daemon to initialize")
-	errDaemon := <-daemonInitWait
-	if errDaemon != nil {
+	registryService := registry.NewService(registryCfg)
+	d, err := daemon.NewDaemon(daemonCfg, eng, registryService)
+	if err != nil {
 		eng.Shutdown()
 		eng.Shutdown()
-		outStr := fmt.Sprintf("Shutting down daemon due to errors: %v", errDaemon)
-		if strings.Contains(errDaemon.Error(), "engine is shutdown") {
-			// if the error is "engine is shutdown", we've already reported (or
-			// will report below in API server errors) the error
-			outStr = "Shutting down daemon due to reported errors"
-		}
-		// we must "fatal" exit here as the API server may be happy to
-		// continue listening forever if the error had no impact to API
-		logrus.Fatal(outStr)
-	} else {
-		logrus.Info("Daemon has completed initialization")
+		logrus.Fatalf("Error starting daemon: %v", err)
 	}
 	}
 
 
+	if err := d.Install(eng); err != nil {
+		eng.Shutdown()
+		logrus.Fatalf("Error starting daemon: %v", err)
+	}
+
+	logrus.Info("Daemon has completed initialization")
+
+	logrus.WithFields(logrus.Fields{
+		"version":     dockerversion.VERSION,
+		"commit":      dockerversion.GITCOMMIT,
+		"execdriver":  d.ExecutionDriver().Name(),
+		"graphdriver": d.GraphDriver().String(),
+	}).Info("Docker daemon")
+
+	b := &builder.BuilderJob{eng, d}
+	b.Install()
+
+	// after the daemon is done setting up we can tell the api to start
+	// accepting connections
+	apiserver.AcceptConnections()
+
 	// Daemon is fully initialized and handling API traffic
 	// Daemon is fully initialized and handling API traffic
 	// Wait for serve API job to complete
 	// Wait for serve API job to complete
 	errAPI := <-serveAPIWait
 	errAPI := <-serveAPIWait
-	// If we have an error here it is unique to API (as daemonErr would have
-	// exited the daemon process above)
 	eng.Shutdown()
 	eng.Shutdown()
 	if errAPI != nil {
 	if errAPI != nil {
 		logrus.Fatalf("Shutting down due to ServeAPI error: %v", errAPI)
 		logrus.Fatalf("Shutting down due to ServeAPI error: %v", errAPI)

+ 2 - 2
integration-cli/docker_cli_daemon_test.go

@@ -498,9 +498,9 @@ func TestDaemonExitOnFailure(t *testing.T) {
 			t.Fatalf("Expected daemon not to start, got %v", err)
 			t.Fatalf("Expected daemon not to start, got %v", err)
 		}
 		}
 		// look in the log and make sure we got the message that daemon is shutting down
 		// look in the log and make sure we got the message that daemon is shutting down
-		runCmd := exec.Command("grep", "Shutting down daemon due to", d.LogfileName())
+		runCmd := exec.Command("grep", "Error starting daemon", d.LogfileName())
 		if out, _, err := runCommandWithOutput(runCmd); err != nil {
 		if out, _, err := runCommandWithOutput(runCmd); err != nil {
-			t.Fatalf("Expected 'shutting down daemon due to error' message; but doesn't exist in log: %q, err: %v", out, err)
+			t.Fatalf("Expected 'Error starting daemon' message; but doesn't exist in log: %q, err: %v", out, err)
 		}
 		}
 	} else {
 	} else {
 		//if we didn't get an error and the daemon is running, this is a failure
 		//if we didn't get an error and the daemon is running, this is a failure