diff --git a/runtime.go b/runtime.go index d9fe5cb4c7..66df7a2489 100644 --- a/runtime.go +++ b/runtime.go @@ -38,6 +38,7 @@ type Capabilities struct { type Runtime struct { repository string + sysInitPath string containers *list.List networkManager *NetworkManager graph *Graph @@ -404,11 +405,6 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin return nil, nil, fmt.Errorf("No command specified") } - sysInitPath := utils.DockerInitPath() - if sysInitPath == "" { - return nil, 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.") - } - // Generate id id := GenerateID() @@ -459,7 +455,7 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin Image: img.ID, // Always use the resolved image id NetworkSettings: &NetworkSettings{}, // FIXME: do we need to store this in the container? - SysInitPath: sysInitPath, + SysInitPath: runtime.sysInitPath, Name: name, Driver: runtime.driver.String(), } @@ -701,6 +697,26 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) { return nil, err } + localCopy := path.Join(config.Root, "init", fmt.Sprintf("dockerinit-%s", VERSION)) + sysInitPath := utils.DockerInitPath(localCopy) + if sysInitPath == "" { + 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.") + } + + if !utils.IAMSTATIC { + if err := os.Mkdir(path.Join(config.Root, fmt.Sprintf("init")), 0700); err != nil && !os.IsExist(err) { + return nil, err + } + + if _, err := utils.CopyFile(sysInitPath, localCopy); err != nil { + return nil, err + } + sysInitPath = localCopy + if err := os.Chmod(sysInitPath, 0700); err != nil { + return nil, err + } + } + runtime := &Runtime{ repository: runtimeRepo, containers: list.New(), @@ -713,6 +729,7 @@ func NewRuntimeFromDirectory(config *DaemonConfig) (*Runtime, error) { config: config, containerGraph: graph, driver: driver, + sysInitPath: sysInitPath, } if err := runtime.restore(); err != nil { diff --git a/utils/utils.go b/utils/utils.go index 892afd0c1d..cfdc73bb2e 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -270,13 +270,14 @@ func isValidDockerInitPath(target string, selfPath string) bool { // target and } // Figure out the path of our dockerinit (which may be SelfPath()) -func DockerInitPath() string { +func DockerInitPath(localCopy string) string { selfPath := SelfPath() if isValidDockerInitPath(selfPath, selfPath) { // if we're valid, don't bother checking anything else return selfPath } var possibleInits = []string{ + localCopy, filepath.Join(filepath.Dir(selfPath), "dockerinit"), // "/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." "/usr/libexec/docker/dockerinit", @@ -1292,3 +1293,23 @@ func GetCallerName(depth int) string { callerShortName := parts[len(parts)-1] return callerShortName } + +func CopyFile(src, dst string) (int64, error) { + if src == dst { + return 0, nil + } + sf, err := os.Open(src) + if err != nil { + return 0, err + } + defer sf.Close() + if err := os.Remove(dst); err != nil && !os.IsNotExist(err) { + return 0, err + } + df, err := os.Create(dst) + if err != nil { + return 0, err + } + defer df.Close() + return io.Copy(df, sf) +}