// 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, SIGKILL and SIGTERM are intercepted for cleanup. func jobInitApi(job *engine.Job) string { job.Logf("Creating server") srv, err := NewServer(job.Eng, ConfigFromJob(job)) if err != nil { return err.Error() } if srv.runtime.config.Pidfile != "" { job.Logf("Creating pidfile") if err := utils.CreatePidFile(srv.runtime.config.Pidfile); err != nil { log.Fatal(err) } } job.Logf("Setting up signal traps") c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM)) go func() { sig := <-c log.Printf("Received signal '%v', exiting\n", sig) utils.RemovePidFile(srv.runtime.config.Pidfile) srv.Close() os.Exit(0) }() job.Eng.Hack_SetGlobalVar("httpapi.server", srv) if err := job.Eng.Register("create", srv.ContainerCreate); err != nil { return err.Error() } if err := job.Eng.Register("start", srv.ContainerStart); err != nil { return err.Error() } if err := job.Eng.Register("serveapi", srv.ListenAndServe); err != nil { return err.Error() } return "0" }
// Daemon 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, SIGKILL and SIGTERM are intercepted for cleanup. func (srv *Server) Daemon() error { if err := utils.CreatePidFile(srv.runtime.config.Pidfile); err != nil { log.Fatal(err) } defer utils.RemovePidFile(srv.runtime.config.Pidfile) c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill, os.Signal(syscall.SIGTERM)) go func() { sig := <-c log.Printf("Received signal '%v', exiting\n", sig) utils.RemovePidFile(srv.runtime.config.Pidfile) srv.Close() os.Exit(0) }() protoAddrs := srv.runtime.config.ProtoAddresses chErrors := make(chan error, len(protoAddrs)) for _, protoAddr := range protoAddrs { protoAddrParts := strings.SplitN(protoAddr, "://", 2) switch protoAddrParts[0] { case "unix": if err := syscall.Unlink(protoAddrParts[1]); err != nil && !os.IsNotExist(err) { log.Fatal(err) } case "tcp": if !strings.HasPrefix(protoAddrParts[1], "127.0.0.1") { log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\") } default: return fmt.Errorf("Invalid protocol format.") } go func() { chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], srv, true) }() } for i := 0; i < len(protoAddrs); i += 1 { err := <-chErrors if err != nil { return err } } return nil }