Browse code

Set environment variables using a file.

Brian Olsen authored on 2013/08/14 07:40:23
Showing 4 changed files
... ...
@@ -431,6 +431,20 @@ func (container *Container) SaveHostConfig(hostConfig *HostConfig) (err error) {
431 431
 	return ioutil.WriteFile(container.hostConfigPath(), data, 0666)
432 432
 }
433 433
 
434
+func (container *Container) generateEnvConfig(env []string) error {
435
+	fo, err := os.Create(container.EnvConfigPath())
436
+	if err != nil {
437
+		return err
438
+	}
439
+	defer fo.Close()
440
+	for _, item := range env {
441
+		if _, err := fo.WriteString(item + "\n"); err != nil {
442
+			return err
443
+		}
444
+	}
445
+	return nil
446
+}
447
+
434 448
 func (container *Container) generateLXCConfig(hostConfig *HostConfig) error {
435 449
 	fo, err := os.Create(container.lxcConfigPath())
436 450
 	if err != nil {
... ...
@@ -841,17 +855,17 @@ func (container *Container) Start(hostConfig *HostConfig) (err error) {
841 841
 		params = append(params, "-u", container.Config.User)
842 842
 	}
843 843
 
844
-	if container.Config.Tty {
845
-		params = append(params, "-e", "TERM=xterm")
844
+	// Setup environment
845
+	env := []string{
846
+		"HOME=/",
847
+		"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
848
+		"container=lxc",
849
+		"HOSTNAME=" + container.Config.Hostname,
846 850
 	}
847 851
 
848
-	// Setup environment
849
-	params = append(params,
850
-		"-e", "HOME=/",
851
-		"-e", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
852
-		"-e", "container=lxc",
853
-		"-e", "HOSTNAME="+container.Config.Hostname,
854
-	)
852
+	if container.Config.Tty {
853
+		env = append(env, "TERM=xterm")
854
+	}
855 855
 
856 856
 	// Init any links between the parent and children
857 857
 	runtime := container.runtime
... ...
@@ -887,11 +901,19 @@ func (container *Container) Start(hostConfig *HostConfig) (err error) {
887 887
 			}
888 888
 
889 889
 			for _, envVar := range link.ToEnv() {
890
-				params = append(params, "-e", envVar)
890
+				env = append(env, envVar)
891 891
 			}
892 892
 		}
893 893
 	}
894 894
 
895
+	for _, elem := range container.Config.Env {
896
+		env = append(env, elem)
897
+	}
898
+
899
+	if err := container.generateEnvConfig(env); err != nil {
900
+		return err
901
+	}
902
+
895 903
 	if container.Config.WorkingDir != "" {
896 904
 		workingDir := path.Clean(container.Config.WorkingDir)
897 905
 		utils.Debugf("[working dir] working dir is %s", workingDir)
... ...
@@ -905,10 +927,6 @@ func (container *Container) Start(hostConfig *HostConfig) (err error) {
905 905
 		)
906 906
 	}
907 907
 
908
-	for _, elem := range container.Config.Env {
909
-		params = append(params, "-e", elem)
910
-	}
911
-
912 908
 	// Program
913 909
 	params = append(params, "--", container.Path)
914 910
 	params = append(params, container.Args...)
... ...
@@ -1416,6 +1434,10 @@ func (container *Container) jsonPath() string {
1416 1416
 	return path.Join(container.root, "config.json")
1417 1417
 }
1418 1418
 
1419
+func (container *Container) EnvConfigPath() string {
1420
+	return path.Join(container.root, "config.env")
1421
+}
1422
+
1419 1423
 func (container *Container) lxcConfigPath() string {
1420 1424
 	return path.Join(container.root, "config.lxc")
1421 1425
 }
... ...
@@ -201,6 +201,7 @@ func (graph *Graph) getDockerInitLayer() (string, error) {
201 201
 		"/proc":            "dir",
202 202
 		"/sys":             "dir",
203 203
 		"/.dockerinit":     "file",
204
+		"/.dockerenv":      "file",
204 205
 		"/etc/resolv.conf": "file",
205 206
 		"/etc/hosts":       "file",
206 207
 		"/etc/hostname":    "file",
... ...
@@ -97,6 +97,9 @@ lxc.mount.entry = shm {{$ROOTFS}}/dev/shm tmpfs size=65536k,nosuid,nodev,noexec
97 97
 # Inject dockerinit
98 98
 lxc.mount.entry = {{.SysInitPath}} {{$ROOTFS}}/.dockerinit none bind,ro 0 0
99 99
 
100
+# Inject env
101
+lxc.mount.entry = {{.EnvConfigPath}} {{$ROOTFS}}/.dockerenv none bind,ro 0 0
102
+
100 103
 # In order to get a working DNS environment, mount bind (ro) the host's /etc/resolv.conf into the container
101 104
 lxc.mount.entry = {{.ResolvConfPath}} {{$ROOTFS}}/etc/resolv.conf none bind,ro 0 0
102 105
 {{if .Volumes}}
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"fmt"
6 6
 	"github.com/dotcloud/docker/netlink"
7 7
 	"github.com/dotcloud/docker/utils"
8
+	"io/ioutil"
8 9
 	"log"
9 10
 	"net"
10 11
 	"os"
... ...
@@ -69,9 +70,14 @@ func changeUser(u string) {
69 69
 }
70 70
 
71 71
 // Clear environment pollution introduced by lxc-start
72
-func cleanupEnv(env utils.ListOpts) {
72
+func cleanupEnv() {
73 73
 	os.Clearenv()
74
-	for _, kv := range env {
74
+	content, err := ioutil.ReadFile("/.dockerenv")
75
+	if err != nil {
76
+		log.Fatalf("Unable to load environment variables: %v", err)
77
+	}
78
+	lines := strings.Split(string(content), "\n")
79
+	for _, kv := range lines {
75 80
 		parts := strings.SplitN(kv, "=", 2)
76 81
 		if len(parts) == 1 {
77 82
 			parts = append(parts, "")
... ...
@@ -104,12 +110,9 @@ func SysInit() {
104 104
 	var gw = flag.String("g", "", "gateway address")
105 105
 	var workdir = flag.String("w", "", "workdir")
106 106
 
107
-	var flEnv utils.ListOpts
108
-	flag.Var(&flEnv, "e", "Set environment variables")
109
-
110 107
 	flag.Parse()
111 108
 
112
-	cleanupEnv(flEnv)
109
+	cleanupEnv()
113 110
 	setupNetworking(*gw)
114 111
 	setupWorkingDirectory(*workdir)
115 112
 	changeUser(*u)