diff --git a/container.go b/container.go index 1888e91ff9..9fff926e40 100644 --- a/container.go +++ b/container.go @@ -431,6 +431,20 @@ func (container *Container) SaveHostConfig(hostConfig *HostConfig) (err error) { return ioutil.WriteFile(container.hostConfigPath(), data, 0666) } +func (container *Container) generateEnvConfig(env []string) error { + fo, err := os.Create(container.EnvConfigPath()) + if err != nil { + return err + } + defer fo.Close() + for _, item := range env { + if _, err := fo.WriteString(item + "\n"); err != nil { + return err + } + } + return nil +} + func (container *Container) generateLXCConfig(hostConfig *HostConfig) error { fo, err := os.Create(container.lxcConfigPath()) if err != nil { @@ -841,17 +855,17 @@ func (container *Container) Start(hostConfig *HostConfig) (err error) { params = append(params, "-u", container.Config.User) } - if container.Config.Tty { - params = append(params, "-e", "TERM=xterm") + // Setup environment + env := []string{ + "HOME=/", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "container=lxc", + "HOSTNAME=" + container.Config.Hostname, } - // Setup environment - params = append(params, - "-e", "HOME=/", - "-e", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "-e", "container=lxc", - "-e", "HOSTNAME="+container.Config.Hostname, - ) + if container.Config.Tty { + env = append(env, "TERM=xterm") + } // Init any links between the parent and children runtime := container.runtime @@ -887,11 +901,19 @@ func (container *Container) Start(hostConfig *HostConfig) (err error) { } for _, envVar := range link.ToEnv() { - params = append(params, "-e", envVar) + env = append(env, envVar) } } } + for _, elem := range container.Config.Env { + env = append(env, elem) + } + + if err := container.generateEnvConfig(env); err != nil { + return err + } + if container.Config.WorkingDir != "" { workingDir := path.Clean(container.Config.WorkingDir) utils.Debugf("[working dir] working dir is %s", workingDir) @@ -905,10 +927,6 @@ func (container *Container) Start(hostConfig *HostConfig) (err error) { ) } - for _, elem := range container.Config.Env { - params = append(params, "-e", elem) - } - // Program params = append(params, "--", container.Path) params = append(params, container.Args...) @@ -1416,6 +1434,10 @@ func (container *Container) jsonPath() string { return path.Join(container.root, "config.json") } +func (container *Container) EnvConfigPath() string { + return path.Join(container.root, "config.env") +} + func (container *Container) lxcConfigPath() string { return path.Join(container.root, "config.lxc") } diff --git a/graph.go b/graph.go index 992b396285..d4ce12e67b 100644 --- a/graph.go +++ b/graph.go @@ -201,6 +201,7 @@ func (graph *Graph) getDockerInitLayer() (string, error) { "/proc": "dir", "/sys": "dir", "/.dockerinit": "file", + "/.dockerenv": "file", "/etc/resolv.conf": "file", "/etc/hosts": "file", "/etc/hostname": "file", diff --git a/lxc_template.go b/lxc_template.go index 382c16029d..d6da584ae0 100644 --- a/lxc_template.go +++ b/lxc_template.go @@ -97,6 +97,9 @@ lxc.mount.entry = shm {{$ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec # Inject dockerinit lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/.dockerinit none bind,ro 0 0 +# Inject env +lxc.mount.entry = {{.EnvConfigPath}} {{$ROOTFS}}/.dockerenv none bind,ro 0 0 + # In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container lxc.mount.entry = {{.ResolvConfPath}} {{$ROOTFS}}/etc/resolv.conf none bind,ro 0 0 {{if .Volumes}} diff --git a/sysinit/sysinit.go b/sysinit/sysinit.go index a37db72423..05ee9c08ce 100644 --- a/sysinit/sysinit.go +++ b/sysinit/sysinit.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/dotcloud/docker/netlink" "github.com/dotcloud/docker/utils" + "io/ioutil" "log" "net" "os" @@ -69,9 +70,14 @@ func changeUser(u string) { } // Clear environment pollution introduced by lxc-start -func cleanupEnv(env utils.ListOpts) { +func cleanupEnv() { os.Clearenv() - for _, kv := range env { + content, err := ioutil.ReadFile("/.dockerenv") + if err != nil { + log.Fatalf("Unable to load environment variables: %v", err) + } + lines := strings.Split(string(content), "\n") + for _, kv := range lines { parts := strings.SplitN(kv, "=", 2) if len(parts) == 1 { parts = append(parts, "") @@ -104,12 +110,9 @@ func SysInit() { var gw = flag.String("g", "", "gateway address") var workdir = flag.String("w", "", "workdir") - var flEnv utils.ListOpts - flag.Var(&flEnv, "e", "Set environment variables") - flag.Parse() - cleanupEnv(flEnv) + cleanupEnv() setupNetworking(*gw) setupWorkingDirectory(*workdir) changeUser(*u)