Просмотр исходного кода

Setup daemon pidfile/cleanup in Server.Daemon() instead of main()

Solomon Hykes 11 лет назад
Родитель
Сommit
c1ae1a0e1c
3 измененных файлов с 67 добавлено и 57 удалено
  1. 1 52
      docker/docker.go
  2. 30 5
      server.go
  3. 36 0
      utils/daemon.go

+ 1 - 52
docker/docker.go

@@ -7,13 +7,9 @@ import (
 	"github.com/dotcloud/docker/sysinit"
 	"github.com/dotcloud/docker/utils"
 	"github.com/dotcloud/docker/engine"
-	"io/ioutil"
 	"log"
 	"os"
-	"os/signal"
-	"strconv"
 	"strings"
-	"syscall"
 )
 
 var (
@@ -89,7 +85,7 @@ func main() {
 		job.SetenvList("ProtoAddresses", flHosts)
 		job.Setenv("DefaultIp", *flDefaultIp)
 		job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
-		if err := daemon(job, *pidfile); err != nil {
+		if err := job.Run(); err != nil {
 			log.Fatal(err)
 		}
 	} else {
@@ -109,50 +105,3 @@ func main() {
 func showVersion() {
 	fmt.Printf("Docker version %s, build %s\n", VERSION, GITCOMMIT)
 }
-
-func createPidFile(pidfile string) error {
-	if pidString, err := ioutil.ReadFile(pidfile); err == nil {
-		pid, err := strconv.Atoi(string(pidString))
-		if err == nil {
-			if _, err := os.Stat(fmt.Sprintf("/proc/%d/", pid)); err == nil {
-				return fmt.Errorf("pid file found, ensure docker is not running or delete %s", pidfile)
-			}
-		}
-	}
-
-	file, err := os.Create(pidfile)
-	if err != nil {
-		return err
-	}
-
-	defer file.Close()
-
-	_, err = fmt.Fprintf(file, "%d", os.Getpid())
-	return err
-}
-
-func removePidFile(pidfile string) {
-	if err := os.Remove(pidfile); err != nil {
-		log.Printf("Error removing %s: %s", pidfile, err)
-	}
-}
-
-// daemon runs `job` as a daemon. 
-// A pidfile is created for the duration of the job,
-// and all signals are intercepted.
-func daemon(job *engine.Job, pidfile string) error {
-	if err := createPidFile(pidfile); err != nil {
-		log.Fatal(err)
-	}
-	defer removePidFile(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)
-		removePidFile(pidfile)
-		os.Exit(0)
-	}()
-	return job.Run()
-}

+ 30 - 5
server.go

@@ -24,6 +24,7 @@ import (
 	"sync"
 	"time"
 	"syscall"
+	"os/signal"
 )
 
 func (srv *Server) Close() error {
@@ -40,8 +41,31 @@ func JobServeApi(job *engine.Job) string {
 		return err.Error()
 	}
 	defer srv.Close()
-	// Parse addresses to serve on
-	protoAddrs := job.Args
+	if err := srv.Daemon(); 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)
+		os.Exit(0)
+	}()
+
+	protoAddrs := srv.runtime.config.ProtoAddresses
 	chErrors := make(chan error, len(protoAddrs))
 	for _, protoAddr := range protoAddrs {
 		protoAddrParts := strings.SplitN(protoAddr, "://", 2)
@@ -52,7 +76,7 @@ func JobServeApi(job *engine.Job) string {
 				log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
 			}
 		} else {
-			return "Invalid protocol format."
+			return fmt.Errorf("Invalid protocol format.")
 		}
 		go func() {
 			chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], srv, true)
@@ -61,12 +85,13 @@ func JobServeApi(job *engine.Job) string {
 	for i := 0; i < len(protoAddrs); i += 1 {
 		err := <-chErrors
 		if err != nil {
-			return err.Error()
+			return err
 		}
 	}
-	return "0"
+	return nil
 }
 
+
 func (srv *Server) DockerVersion() APIVersion {
 	return APIVersion{
 		Version:   VERSION,

+ 36 - 0
utils/daemon.go

@@ -0,0 +1,36 @@
+package utils
+
+import (
+	"os"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"strconv"
+)
+
+func CreatePidFile(pidfile string) error {
+	if pidString, err := ioutil.ReadFile(pidfile); err == nil {
+		pid, err := strconv.Atoi(string(pidString))
+		if err == nil {
+			if _, err := os.Stat(fmt.Sprintf("/proc/%d/", pid)); err == nil {
+				return fmt.Errorf("pid file found, ensure docker is not running or delete %s", pidfile)
+			}
+		}
+	}
+
+	file, err := os.Create(pidfile)
+	if err != nil {
+		return err
+	}
+
+	defer file.Close()
+
+	_, err = fmt.Fprintf(file, "%d", os.Getpid())
+	return err
+}
+
+func RemovePidFile(pidfile string) {
+	if err := os.Remove(pidfile); err != nil {
+		log.Printf("Error removing %s: %s", pidfile, err)
+	}
+}