2014-07-29 22:04:39 -04:00
|
|
|
// DEPRECATION NOTICE. PLEASE DO NOT ADD ANYTHING TO THIS FILE.
|
|
|
|
//
|
|
|
|
// For additional commments see server/server.go
|
|
|
|
//
|
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
gosignal "os/signal"
|
|
|
|
"sync/atomic"
|
|
|
|
"syscall"
|
|
|
|
|
|
|
|
"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")
|
|
|
|
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{
|
2014-07-31 07:50:59 -04:00
|
|
|
"info": srv.DockerInfo,
|
|
|
|
"build": srv.Build,
|
|
|
|
"pull": srv.ImagePull,
|
|
|
|
"push": srv.ImagePush,
|
2014-07-29 22:04:39 -04:00
|
|
|
} {
|
|
|
|
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{
|
2014-07-31 07:50:59 -04:00
|
|
|
Eng: eng,
|
|
|
|
daemon: daemon,
|
|
|
|
pullingPool: make(map[string]chan struct{}),
|
|
|
|
pushingPool: make(map[string]chan struct{}),
|
2014-07-29 22:04:39 -04:00
|
|
|
}
|
|
|
|
daemon.SetServer(srv)
|
|
|
|
return srv, nil
|
|
|
|
}
|