Merge pull request #1536 from griff/envfile

Runtime: Keep env variables out of the command line
This commit is contained in:
Victor Vieux 2013-10-30 19:20:29 -07:00
commit bdbb0371a7
5 changed files with 74 additions and 27 deletions

View file

@ -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")
}

View file

@ -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) {

View file

@ -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",

View file

@ -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}}

View file

@ -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)