1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/server/init.go
Solomon Hykes c9f3fd3fc7 Cleanup: refactor shutdown and signal handling facility
This disentangles the following functions, which were previously all mixed together:

* 1) Waiting for jobs to terminate when shutting down
* 2) Handling signals in the Docker daemon
* 3) Per-subsystem cleanup handlers
* 4) pidfile management

Responsibilities are dispatched as follows:

* Signal traps are set in `main`, and trigger `engine.Shutdown`
* `engine.Shutdown` coordinates cleanup by waiting for jobs to complete, and calling shutdown handlers
* To perform cleanup at shutdown, each subsystem registers handlers with `engine.OnShutdown`
* `daemon` is one subsystem, so it registers cleanup via `engine.OnShutdown`.
* `daemon` owns the pidfile, which is used to lock access to `/var/lib/docker`. Part of its cleanup is to remove the pidfile.

Signed-off-by: Solomon Hykes <solomon@docker.com>
2014-08-06 17:56:11 +00:00

87 lines
2.3 KiB
Go

// DEPRECATION NOTICE. PLEASE DO NOT ADD ANYTHING TO THIS FILE.
//
// For additional commments see server/server.go
//
package server
import (
"fmt"
"github.com/docker/docker/daemon"
"github.com/docker/docker/daemonconfig"
"github.com/docker/docker/engine"
"github.com/docker/docker/utils"
)
func (srv *Server) handlerWrap(h engine.Handler) engine.Handler {
return func(job *engine.Job) engine.Status {
if !srv.IsRunning() {
return job.Errorf("Server is not running")
}
srv.tasks.Add(1)
defer srv.tasks.Done()
return h(job)
}
}
func InitPidfile(job *engine.Job) engine.Status {
if len(job.Args) == 0 {
return job.Error(fmt.Errorf("no pidfile provided to initialize"))
}
job.Logf("Creating pidfile")
if err := utils.CreatePidFile(job.Args[0]); err != nil {
return job.Error(err)
}
return engine.StatusOK
}
// 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 InitServer(job *engine.Job) engine.Status {
job.Logf("Creating server")
cfg := daemonconfig.ConfigFromJob(job)
srv, err := NewServer(job.Eng, cfg)
if err != nil {
return job.Error(err)
}
job.Eng.Hack_SetGlobalVar("httpapi.server", srv)
job.Eng.Hack_SetGlobalVar("httpapi.daemon", srv.daemon)
for name, handler := range map[string]engine.Handler{
"build": srv.Build,
"pull": srv.ImagePull,
"push": srv.ImagePush,
} {
if err := job.Eng.Register(name, srv.handlerWrap(handler)); err != nil {
return job.Error(err)
}
}
// Install image-related commands from the image subsystem.
// See `graph/service.go`
if err := srv.daemon.Repositories().Install(job.Eng); err != nil {
return job.Error(err)
}
// Install daemon-related commands from the daemon subsystem.
// See `daemon/`
if err := srv.daemon.Install(job.Eng); err != nil {
return job.Error(err)
}
srv.SetRunning(true)
return engine.StatusOK
}
func NewServer(eng *engine.Engine, config *daemonconfig.Config) (*Server, error) {
daemon, err := daemon.NewDaemon(config, eng)
if err != nil {
return nil, err
}
srv := &Server{
Eng: eng,
daemon: daemon,
pullingPool: make(map[string]chan struct{}),
pushingPool: make(map[string]chan struct{}),
}
daemon.SetServer(srv)
return srv, nil
}