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

Merge pull request #1536 from griff/envfile

Runtime: Keep env variables out of the command line
Victor Vieux 11 лет назад
Родитель
Сommit
bdbb0371a7
5 измененных файлов с 74 добавлено и 27 удалено
  1. 44 15
      container.go
  2. 12 6
      container_test.go
  3. 1 0
      graph.go
  4. 3 0
      lxc_template.go
  5. 14 6
      sysinit/sysinit.go

+ 44 - 15
container.go

@@ -226,6 +226,18 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
 		}
 	}
 
+	envs := []string{}
+
+	for _, env := range flEnv {
+		arr := strings.Split(env, "=")
+		if len(arr) > 1 {
+			envs = append(envs, env)
+		} else {
+			v := os.Getenv(env)
+			envs = append(envs, env+"="+v)
+		}
+	}
+
 	var binds []string
 
 	// add any bind targets to the list of container volumes
@@ -298,7 +310,7 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
 		AttachStdin:     flAttach.Get("stdin"),
 		AttachStdout:    flAttach.Get("stdout"),
 		AttachStderr:    flAttach.Get("stderr"),
-		Env:             flEnv,
+		Env:             envs,
 		Cmd:             runCmd,
 		Dns:             flDns,
 		Image:           image,
@@ -431,6 +443,15 @@ func (container *Container) SaveHostConfig(hostConfig *HostConfig) (err error) {
 	return ioutil.WriteFile(container.hostConfigPath(), data, 0666)
 }
 
+func (container *Container) generateEnvConfig(env []string) error {
+	data, err := json.Marshal(env)
+	if err != nil {
+		return err
+	}
+	ioutil.WriteFile(container.EnvConfigPath(), data, 0600)
+	return nil
+}
+
 func (container *Container) generateLXCConfig(hostConfig *HostConfig) error {
 	fo, err := os.Create(container.lxcConfigPath())
 	if err != nil {
@@ -841,17 +862,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 +908,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 +934,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 +1441,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")
 }

+ 12 - 6
container_test.go

@@ -973,14 +973,15 @@ func TestTty(t *testing.T) {
 }
 
 func TestEnv(t *testing.T) {
+	os.Setenv("TRUE", "false")
+	os.Setenv("TRICKY", "tri\ncky\n")
 	runtime := mkRuntime(t)
 	defer nuke(runtime)
-	container, _, err := runtime.Create(&Config{
-		Image: GetTestImage(runtime).ID,
-		Cmd:   []string{"env"},
-	},
-		"",
-	)
+	config, _, _, err := ParseRun([]string{"-e=FALSE=true", "-e=TRUE", "-e=TRICKY", GetTestImage(runtime).ID, "env"}, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	container, _, err := runtime.Create(config, "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1010,6 +1011,11 @@ func TestEnv(t *testing.T) {
 		"HOME=/",
 		"container=lxc",
 		"HOSTNAME=" + container.ShortID(),
+		"FALSE=true",
+		"TRUE=false",
+		"TRICKY=tri",
+		"cky",
+		"",
 	}
 	sort.Strings(goodEnv)
 	if len(goodEnv) != len(actualEnv) {

+ 1 - 0
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",

+ 3 - 0
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}}

+ 14 - 6
sysinit/sysinit.go

@@ -1,10 +1,12 @@
 package sysinit
 
 import (
+	"encoding/json"
 	"flag"
 	"fmt"
 	"github.com/dotcloud/docker/netlink"
 	"github.com/dotcloud/docker/utils"
+	"io/ioutil"
 	"log"
 	"net"
 	"os"
@@ -69,9 +71,18 @@ func changeUser(u string) {
 }
 
 // Clear environment pollution introduced by lxc-start
-func cleanupEnv(env utils.ListOpts) {
+func cleanupEnv() {
 	os.Clearenv()
-	for _, kv := range env {
+	var lines []string
+	content, err := ioutil.ReadFile("/.dockerenv")
+	if err != nil {
+		log.Fatalf("Unable to load environment variables: %v", err)
+	}
+	err = json.Unmarshal(content, &lines)
+	if err != nil {
+		log.Fatalf("Unable to unmarshal environment variables: %v", err)
+	}
+	for _, kv := range lines {
 		parts := strings.SplitN(kv, "=", 2)
 		if len(parts) == 1 {
 			parts = append(parts, "")
@@ -104,12 +115,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)