Browse code

Merge pull request #3064 from tianon/custom-dockerinit-path

Allow custom dockerinit path

Guillaume J. Charmes authored on 2013/12/20 07:31:41
Showing 5 changed files
... ...
@@ -469,6 +469,13 @@ func (cli *DockerCli) CmdInfo(args ...string) error {
469 469
 		fmt.Fprintf(cli.out, "LXC Version: %s\n", remoteInfo.Get("LXCVersion"))
470 470
 		fmt.Fprintf(cli.out, "EventsListeners: %d\n", remoteInfo.GetInt("NEventsListener"))
471 471
 		fmt.Fprintf(cli.out, "Kernel Version: %s\n", remoteInfo.Get("KernelVersion"))
472
+
473
+		if initSha1 := remoteInfo.Get("InitSha1"); initSha1 != "" {
474
+			fmt.Fprintf(cli.out, "Init SHA1: %s\n", initSha1)
475
+		}
476
+		if initPath := remoteInfo.Get("InitPath"); initPath != "" {
477
+			fmt.Fprintf(cli.out, "Init Path: %s\n", initPath)
478
+		}
472 479
 	}
473 480
 
474 481
 	if len(remoteInfo.GetList("IndexServerAddress")) != 0 {
... ...
@@ -12,6 +12,6 @@ export DOCKER_INITSHA1="$(sha1sum $DEST/dockerinit-$VERSION | cut -d' ' -f1)"
12 12
 # exported so that "dyntest" can easily access it later without recalculating it
13 13
 
14 14
 (
15
-	export LDFLAGS_STATIC="-X github.com/dotcloud/docker/utils.INITSHA1 \"$DOCKER_INITSHA1\""
15
+	export LDFLAGS_STATIC="-X github.com/dotcloud/docker/utils.INITSHA1 \"$DOCKER_INITSHA1\" -X github.com/dotcloud/docker/utils.INITPATH \"$DOCKER_INITPATH\""
16 16
 	source "$(dirname "$BASH_SOURCE")/binary"
17 17
 )
... ...
@@ -725,18 +725,18 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) {
725 725
 		return nil, fmt.Errorf("Could not locate dockerinit: This usually means docker was built incorrectly. See http://docs.docker.io/en/latest/contributing/devenvironment for official build instructions.")
726 726
 	}
727 727
 
728
-	if !utils.IAMSTATIC {
729
-		if err := os.Mkdir(path.Join(config.Root, fmt.Sprintf("init")), 0700); err != nil && !os.IsExist(err) {
728
+	if sysInitPath != localCopy {
729
+		// When we find a suitable dockerinit binary (even if it's our local binary), we copy it into config.Root at localCopy for future use (so that the original can go away without that being a problem, for example during a package upgrade).
730
+		if err := os.Mkdir(path.Dir(localCopy), 0700); err != nil && !os.IsExist(err) {
730 731
 			return nil, err
731 732
 		}
732
-
733 733
 		if _, err := utils.CopyFile(sysInitPath, localCopy); err != nil {
734 734
 			return nil, err
735 735
 		}
736
-		sysInitPath = localCopy
737
-		if err := os.Chmod(sysInitPath, 0700); err != nil {
736
+		if err := os.Chmod(localCopy, 0700); err != nil {
738 737
 			return nil, err
739 738
 		}
739
+		sysInitPath = localCopy
740 740
 	}
741 741
 
742 742
 	runtime := &Runtime{
... ...
@@ -633,6 +633,13 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
633 633
 		kernelVersion = kv.String()
634 634
 	}
635 635
 
636
+	// if we still have the original dockerinit binary from before we copied it locally, let's return the path to that, since that's more intuitive (the copied path is trivial to derive by hand given VERSION)
637
+	initPath := utils.DockerInitPath("")
638
+	if initPath == "" {
639
+		// if that fails, we'll just return the path from the runtime
640
+		initPath = srv.runtime.sysInitPath
641
+	}
642
+
636 643
 	v := &engine.Env{}
637 644
 	v.SetInt("Containers", len(srv.runtime.List()))
638 645
 	v.SetInt("Images", imgcount)
... ...
@@ -648,6 +655,8 @@ func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
648 648
 	v.SetInt("NEventsListener", len(srv.events))
649 649
 	v.Set("KernelVersion", kernelVersion)
650 650
 	v.Set("IndexServerAddress", auth.IndexServerAddress())
651
+	v.Set("InitSha1", utils.INITSHA1)
652
+	v.Set("InitPath", initPath)
651 653
 	if _, err := v.WriteTo(job.Stdout); err != nil {
652 654
 		job.Error(err)
653 655
 		return engine.StatusErr
... ...
@@ -26,6 +26,7 @@ import (
26 26
 var (
27 27
 	IAMSTATIC bool   // whether or not Docker itself was compiled statically via ./hack/make.sh binary
28 28
 	INITSHA1  string // sha1sum of separate static dockerinit, if Docker itself was compiled dynamically via ./hack/make.sh dynbinary
29
+	INITPATH  string // custom location to search for a valid dockerinit binary (available for packagers as a last resort escape hatch)
29 30
 )
30 31
 
31 32
 // A common interface to access the Fatal method of
... ...
@@ -162,14 +163,23 @@ func Trunc(s string, maxlen int) string {
162 162
 	return s[:maxlen]
163 163
 }
164 164
 
165
-// Figure out the absolute path of our own binary
165
+// Figure out the absolute path of our own binary (if it's still around).
166 166
 func SelfPath() string {
167 167
 	path, err := exec.LookPath(os.Args[0])
168 168
 	if err != nil {
169
+		if os.IsNotExist(err) {
170
+			return ""
171
+		}
172
+		if execErr, ok := err.(*exec.Error); ok && os.IsNotExist(execErr.Err) {
173
+			return ""
174
+		}
169 175
 		panic(err)
170 176
 	}
171 177
 	path, err = filepath.Abs(path)
172 178
 	if err != nil {
179
+		if os.IsNotExist(err) {
180
+			return ""
181
+		}
173 182
 		panic(err)
174 183
 	}
175 184
 	return path
... ...
@@ -190,7 +200,13 @@ func dockerInitSha1(target string) string {
190 190
 }
191 191
 
192 192
 func isValidDockerInitPath(target string, selfPath string) bool { // target and selfPath should be absolute (InitPath and SelfPath already do this)
193
+	if target == "" {
194
+		return false
195
+	}
193 196
 	if IAMSTATIC {
197
+		if selfPath == "" {
198
+			return false
199
+		}
194 200
 		if target == selfPath {
195 201
 			return true
196 202
 		}
... ...
@@ -216,6 +232,7 @@ func DockerInitPath(localCopy string) string {
216 216
 	}
217 217
 	var possibleInits = []string{
218 218
 		localCopy,
219
+		INITPATH,
219 220
 		filepath.Join(filepath.Dir(selfPath), "dockerinit"),
220 221
 
221 222
 		// FHS 3.0 Draft: "/usr/libexec includes internal binaries that are not intended to be executed directly by users or shell scripts. Applications may use a single subdirectory under /usr/libexec."
... ...
@@ -229,6 +246,9 @@ func DockerInitPath(localCopy string) string {
229 229
 		"/usr/local/lib/docker/dockerinit",
230 230
 	}
231 231
 	for _, dockerInit := range possibleInits {
232
+		if dockerInit == "" {
233
+			continue
234
+		}
232 235
 		path, err := exec.LookPath(dockerInit)
233 236
 		if err == nil {
234 237
 			path, err = filepath.Abs(path)