diff options
author | Dan Duvall <dduvall@wikimedia.org> | 2017-06-22 14:27:37 -0700 |
---|---|---|
committer | Dan Duvall <dduvall@wikimedia.org> | 2017-06-26 13:43:47 -0700 |
commit | 9f2ef14ba62f26ded606260891a648c294b50d4b (patch) | |
tree | b74ba8eacc218047dc88c76299e3f477b88e1485 /config | |
parent | 77b95b1f94de7cc6c1e28c0fdf2b4ecab93dd91a (diff) | |
download | blubber-9f2ef14ba62f26ded606260891a648c294b50d4b.tar.gz |
Support environment variables
Summary:
Added support for definition of environment variables under
`runs.environment`. Corresponding `ENV` instructions will be added to
Dockerfile output for the unprivileged build phase.
Fixes T168425
Test Plan: Run `go test ./...`.
Reviewers: thcipriani, mobrovac, hashar, Jrbranaa, mmodell, #release-engineering-team
Reviewed By: mobrovac
Tags: #release-engineering-team
Maniphest Tasks: T168425
Differential Revision: https://phabricator.wikimedia.org/D691
Diffstat (limited to 'config')
-rw-r--r-- | config/flag_test.go | 18 | ||||
-rw-r--r-- | config/runs.go | 51 | ||||
-rw-r--r-- | config/runs_test.go | 60 |
3 files changed, 111 insertions, 18 deletions
diff --git a/config/flag_test.go b/config/flag_test.go index 39aa254..6393dd5 100644 --- a/config/flag_test.go +++ b/config/flag_test.go @@ -7,18 +7,14 @@ import ( "phabricator.wikimedia.org/source/blubber.git/config" ) -const yaml = `--- -npm: { install: true } -sharedvolume: false - -variants: - development: - sharedvolume: true - npm: { install: false } -` - func TestFlagOverwrite(t *testing.T) { - cfg, err := config.ReadConfig([]byte(yaml)) + cfg, err := config.ReadConfig([]byte(`--- + npm: { install: true } + sharedvolume: false + variants: + development: + sharedvolume: true + npm: { install: false }`)) assert.Nil(t, err) diff --git a/config/runs.go b/config/runs.go index 7567685..2f064b4 100644 --- a/config/runs.go +++ b/config/runs.go @@ -1,6 +1,7 @@ package config import ( + "sort" "strconv" "phabricator.wikimedia.org/source/blubber.git/build" ) @@ -10,6 +11,7 @@ type RunsConfig struct { As string `yaml:"as"` Uid int `yaml:"uid"` Gid int `yaml:"gid"` + Environment map[string]string `yaml:"environment"` } func (run *RunsConfig) Merge(run2 RunsConfig) { @@ -17,6 +19,39 @@ func (run *RunsConfig) Merge(run2 RunsConfig) { if run2.As != "" { run.As = run2.As } if run2.Uid != 0 { run.Uid = run2.Uid } if run2.Gid != 0 { run.Gid = run2.Gid } + + if run.Environment == nil { + run.Environment = make(map[string]string) + } + + for name, value := range run2.Environment { + run.Environment[name] = value + } +} + +func (run RunsConfig) Home() string { + if run.As == "" { + return "/root" + } else { + return "/home/" + run.As + } +} + +func (run RunsConfig) EnvironmentDefinitions() []string { + defs := make([]string, 0, len(run.Environment)) + names := make([]string, 0, len(run.Environment)) + + for name := range run.Environment { + names = append(names, name) + } + + sort.Strings(names) + + for _, name := range names { + defs = append(defs, name + "=" + strconv.Quote(run.Environment[name])) + } + + return defs } func (run RunsConfig) InstructionsForPhase(phase build.Phase) []build.Instruction { @@ -25,13 +60,15 @@ func (run RunsConfig) InstructionsForPhase(phase build.Phase) []build.Instructio switch phase { case build.PhasePrivileged: if run.In != "" { - ins = append(ins, build.Instruction{build.Run, []string{"mkdir -p ", run.In}}) + ins = append(ins, build.Instruction{build.Run, []string{ + "mkdir -p ", run.In, + }}) } if run.As != "" { ins = append(ins, build.Instruction{build.Run, []string{ "groupadd -o -g ", strconv.Itoa(run.Gid), " -r ", run.As, " && ", - "useradd -o -m -d /home/", run.As, " -r -g ", run.As, + "useradd -o -m -d ", strconv.Quote(run.Home()), " -r -g ", run.As, " -u ", strconv.Itoa(run.Uid), " ", run.As, }}) @@ -43,11 +80,11 @@ func (run RunsConfig) InstructionsForPhase(phase build.Phase) []build.Instructio } } case build.PhasePrivilegeDropped: - if run.As != "" { - ins = append(ins, build.Instruction{build.Env, []string{ - "HOME=\"/home/" + run.As + "\"", - }}) - } + ins = append(ins, build.Instruction{build.Env, []string{ + "HOME=" + strconv.Quote(run.Home()), + }}) + + ins = append(ins, build.Instruction{build.Env, run.EnvironmentDefinitions()}) } return ins diff --git a/config/runs_test.go b/config/runs_test.go new file mode 100644 index 0000000..119ef3f --- /dev/null +++ b/config/runs_test.go @@ -0,0 +1,60 @@ +package config_test + +import ( + "testing" + "gopkg.in/stretchr/testify.v1/assert" + + "phabricator.wikimedia.org/source/blubber.git/config" +) + +func TestRunsConfig(t *testing.T) { + cfg, err := config.ReadConfig([]byte(`--- + runs: + as: someuser + in: /some/directory + uid: 666 + gid: 777 + environment: { FOO: bar } + variants: + development: {}`)) + + assert.Nil(t, err) + + variant, err := config.ExpandVariant(cfg, "development") + + assert.Nil(t, err) + + assert.Equal(t, "someuser", variant.Runs.As) + assert.Equal(t, "/some/directory", variant.Runs.In) + assert.Equal(t, 666, variant.Runs.Uid) + assert.Equal(t, 777, variant.Runs.Gid) + assert.Equal(t, map[string]string{"FOO": "bar"}, variant.Runs.Environment) +} + +func TestRunsHomeWithUser(t *testing.T) { + runs := config.RunsConfig{As: "someuser"} + + assert.Equal(t, "/home/someuser", runs.Home()) +} + +func TestRunsHomeWithoutUser(t *testing.T) { + runs := config.RunsConfig{} + + assert.Equal(t, "/root", runs.Home()) +} + +func TestEnvironmentDefinitionsIsSortedAndQuoted(t *testing.T) { + runs := config.RunsConfig{ + Environment: map[string]string{ + "fooname": "foovalue", + "barname": "barvalue", + "quxname": "quxvalue", + }, + } + + assert.Equal(t, []string{ + `barname="barvalue"`, + `fooname="foovalue"`, + `quxname="quxvalue"`, + }, runs.EnvironmentDefinitions()) +} |