// 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, } { 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) } 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") srv, err := NewServer(job.Eng, daemonconfig.ConfigFromJob(job)) if err != nil { return job.Error(err) } job.Logf("Setting up signal traps") c := make(chan os.Signal, 1) signals := []os.Signal{os.Interrupt, syscall.SIGTERM} if os.Getenv("DEBUG") == "" { signals = append(signals, syscall.SIGQUIT) } gosignal.Notify(c, signals...) go func() { interruptCount := uint32(0) for sig := range c { go func(sig os.Signal) { log.Printf("Received signal '%v', starting shutdown of docker...\n", sig) switch sig { case os.Interrupt, syscall.SIGTERM: // If the user really wants to interrupt, let him do so. if atomic.LoadUint32(&interruptCount) < 3 { atomic.AddUint32(&interruptCount, 1) // Initiate the cleanup only once if atomic.LoadUint32(&interruptCount) == 1 { utils.RemovePidFile(srv.daemon.Config().Pidfile) srv.Close() } else { return } } else { log.Printf("Force shutdown of docker, interrupting cleanup\n") } case syscall.SIGQUIT: } os.Exit(128 + int(sig.(syscall.Signal))) }(sig) } }() 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 }
// 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") srv, err := NewServer(job.Eng, daemonconfig.ConfigFromJob(job)) if err != nil { return job.Error(err) } job.Logf("Setting up signal traps") c := make(chan os.Signal, 1) signals := []os.Signal{os.Interrupt, syscall.SIGTERM} if os.Getenv("DEBUG") == "" { signals = append(signals, syscall.SIGQUIT) } gosignal.Notify(c, signals...) go func() { interruptCount := uint32(0) for sig := range c { go func(sig os.Signal) { log.Printf("Received signal '%v', starting shutdown of docker...\n", sig) switch sig { case os.Interrupt, syscall.SIGTERM: // If the user really wants to interrupt, let him do so. if atomic.LoadUint32(&interruptCount) < 3 { atomic.AddUint32(&interruptCount, 1) // Initiate the cleanup only once if atomic.LoadUint32(&interruptCount) == 1 { utils.RemovePidFile(srv.daemon.Config().Pidfile) srv.Close() } else { return } } else { log.Printf("Force shutdown of docker, interrupting cleanup\n") } case syscall.SIGQUIT: } os.Exit(128 + int(sig.(syscall.Signal))) }(sig) } }() job.Eng.Hack_SetGlobalVar("httpapi.server", srv) job.Eng.Hack_SetGlobalVar("httpapi.daemon", srv.daemon) for name, handler := range map[string]engine.Handler{ "export": srv.ContainerExport, "create": srv.ContainerCreate, "stop": srv.ContainerStop, "restart": srv.ContainerRestart, "start": srv.ContainerStart, "kill": srv.ContainerKill, "pause": srv.ContainerPause, "unpause": srv.ContainerUnpause, "wait": srv.ContainerWait, "tag": srv.ImageTag, // FIXME merge with "image_tag" "resize": srv.ContainerResize, "commit": srv.ContainerCommit, "info": srv.DockerInfo, "container_delete": srv.ContainerDestroy, "image_export": srv.ImageExport, "images": srv.Images, "history": srv.ImageHistory, "viz": srv.ImagesViz, "container_copy": srv.ContainerCopy, "attach": srv.ContainerAttach, "logs": srv.ContainerLogs, "changes": srv.ContainerChanges, "top": srv.ContainerTop, "load": srv.ImageLoad, "build": srv.Build, "pull": srv.ImagePull, "import": srv.ImageImport, "image_delete": srv.ImageDelete, "events": srv.Events, "push": srv.ImagePush, "containers": srv.Containers, } { 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 }