diff --git a/api/api.go b/api/api.go index 61069445fc..b722eb5c60 100644 --- a/api/api.go +++ b/api/api.go @@ -36,6 +36,10 @@ const ( type HttpApiFunc func(eng *engine.Engine, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error +func init() { + engine.Register("serveapi", ServeApi) +} + func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) { conn, _, err := w.(http.Hijacker).Hijack() if err != nil { @@ -1160,3 +1164,30 @@ func ListenAndServe(proto, addr string, eng *engine.Engine, logging, enableCors httpSrv := http.Server{Addr: addr, Handler: r} return httpSrv.Serve(l) } + +// ServeApi loops through all of the protocols sent in to docker and spawns +// off a go routine to setup a serving http.Server for each. +func ServeApi(job *engine.Job) engine.Status { + protoAddrs := job.Args + chErrors := make(chan error, len(protoAddrs)) + + for _, protoAddr := range protoAddrs { + protoAddrParts := strings.SplitN(protoAddr, "://", 2) + go func() { + log.Printf("Listening for HTTP on %s (%s)\n", protoAddrParts[0], protoAddrParts[1]) + chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version")) + }() + } + + for i := 0; i < len(protoAddrs); i += 1 { + err := <-chErrors + if err != nil { + return job.Error(err) + } + } + + // Tell the init daemon we are accepting requests + go systemd.SdNotify("READY=1") + + return engine.StatusOK +} diff --git a/docker/docker.go b/docker/docker.go index 2da9c1fa26..ba7764050b 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -83,7 +83,7 @@ func main() { log.Fatal(err) } // Load plugin: httpapi - job := eng.Job("initapi") + job := eng.Job("initserver") job.Setenv("Pidfile", *pidfile) job.Setenv("Root", *flRoot) job.SetenvBool("AutoRestart", *flAutoRestart) @@ -103,6 +103,7 @@ func main() { 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) } diff --git a/integration/runtime_test.go b/integration/runtime_test.go index 9afc10f5af..da95967a30 100644 --- a/integration/runtime_test.go +++ b/integration/runtime_test.go @@ -125,7 +125,7 @@ func setupBaseImage() { if err != nil { log.Fatalf("Can't initialize engine at %s: %s", unitTestStoreBase, err) } - job := eng.Job("initapi") + job := eng.Job("initserver") job.Setenv("Root", unitTestStoreBase) job.SetenvBool("Autorestart", false) job.Setenv("BridgeIface", unitTestNetworkBridge) @@ -573,7 +573,7 @@ func TestRestore(t *testing.T) { if err != nil { t.Fatal(err) } - job := eng.Job("initapi") + job := eng.Job("initserver") job.Setenv("Root", eng.Root()) job.SetenvBool("Autorestart", false) if err := job.Run(); err != nil { @@ -605,7 +605,7 @@ func TestRestore(t *testing.T) { } func TestReloadContainerLinks(t *testing.T) { - // FIXME: here we don't use NewTestEngine because it calls initapi with Autorestart=false, + // 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 { @@ -615,7 +615,7 @@ func TestReloadContainerLinks(t *testing.T) { if err != nil { t.Fatal(err) } - job := eng.Job("initapi") + job := eng.Job("initserver") job.Setenv("Root", eng.Root()) job.SetenvBool("Autorestart", true) if err := job.Run(); err != nil { @@ -665,7 +665,7 @@ func TestReloadContainerLinks(t *testing.T) { if err != nil { t.Fatal(err) } - job = eng.Job("initapi") + job = eng.Job("initserver") job.Setenv("Root", eng.Root()) job.SetenvBool("Autorestart", false) if err := job.Run(); err != nil { diff --git a/integration/server_test.go b/integration/server_test.go index c3371ce8bf..45d4930ad7 100644 --- a/integration/server_test.go +++ b/integration/server_test.go @@ -262,7 +262,7 @@ func TestRestartKillWait(t *testing.T) { t.Fatal(err) } - job = eng.Job("initapi") + job = eng.Job("initserver") job.Setenv("Root", eng.Root()) job.SetenvBool("AutoRestart", false) // TestGetEnabledCors and TestOptionsRoute require EnableCors=true diff --git a/integration/utils_test.go b/integration/utils_test.go index d7a2814472..67f31a312a 100644 --- a/integration/utils_test.go +++ b/integration/utils_test.go @@ -188,7 +188,7 @@ func NewTestEngine(t utils.Fataler) *engine.Engine { } // Load default plugins // (This is manually copied and modified from main() until we have a more generic plugin system) - job := eng.Job("initapi") + job := eng.Job("initserver") job.Setenv("Root", root) job.SetenvBool("AutoRestart", false) // TestGetEnabledCors and TestOptionsRoute require EnableCors=true diff --git a/server.go b/server.go index 3561e76abd..f4d2f3722f 100644 --- a/server.go +++ b/server.go @@ -4,12 +4,10 @@ import ( "encoding/json" "errors" "fmt" - "github.com/dotcloud/docker/api" "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/auth" "github.com/dotcloud/docker/engine" "github.com/dotcloud/docker/pkg/graphdb" - "github.com/dotcloud/docker/pkg/systemd" "github.com/dotcloud/docker/registry" "github.com/dotcloud/docker/utils" "io" @@ -35,13 +33,13 @@ func (srv *Server) Close() error { } func init() { - engine.Register("initapi", jobInitApi) + engine.Register("initserver", jobInitServer) } // jobInitApi runs the remote api server `srv` as a daemon, // Only one api server can run at the same time - this is enforced by a pidfile. // The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup. -func jobInitApi(job *engine.Job) engine.Status { +func jobInitServer(job *engine.Job) engine.Status { job.Logf("Creating server") srv, err := NewServer(job.Eng, DaemonConfigFromJob(job)) if err != nil { @@ -77,7 +75,6 @@ func jobInitApi(job *engine.Job) engine.Status { "restart": srv.ContainerRestart, "start": srv.ContainerStart, "kill": srv.ContainerKill, - "serveapi": srv.ListenAndServe, "wait": srv.ContainerWait, "tag": srv.ImageTag, "resize": srv.ContainerResize, @@ -112,33 +109,6 @@ func jobInitApi(job *engine.Job) engine.Status { return engine.StatusOK } -// ListenAndServe loops through all of the protocols sent in to docker and spawns -// off a go routine to setup a serving http.Server for each. -func (srv *Server) ListenAndServe(job *engine.Job) engine.Status { - protoAddrs := job.Args - chErrors := make(chan error, len(protoAddrs)) - - for _, protoAddr := range protoAddrs { - protoAddrParts := strings.SplitN(protoAddr, "://", 2) - go func() { - log.Printf("Listening for HTTP on %s (%s)\n", protoAddrParts[0], protoAddrParts[1]) - chErrors <- api.ListenAndServe(protoAddrParts[0], protoAddrParts[1], srv.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), VERSION) - }() - } - - for i := 0; i < len(protoAddrs); i += 1 { - err := <-chErrors - if err != nil { - return job.Error(err) - } - } - - // Tell the init daemon we are accepting requests - go systemd.SdNotify("READY=1") - - return engine.StatusOK -} - // simpleVersionInfo is a simple implementation of // the interface VersionInfo, which is used // to provide version information for some product,