Skip to content

Commit

Permalink
fix: rewrite how image env is merged
Browse files Browse the repository at this point in the history
  • Loading branch information
hackercat committed Sep 27, 2021
1 parent bfcf0ab commit ccde10e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 74 deletions.
78 changes: 38 additions & 40 deletions pkg/container/docker_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/go-git/go-billy/v5/helper/polyfill"
"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
"github.com/joho/godotenv"

"github.com/docker/cli/cli/connhelper"
"github.com/docker/docker/api/types"
Expand Down Expand Up @@ -72,6 +73,7 @@ type Container interface {
Start(attach bool) common.Executor
Exec(command []string, env map[string]string, user, workdir string) common.Executor
UpdateFromEnv(srcPath string, env *map[string]string) common.Executor
UpdateFromImageEnv(env *map[string]string) common.Executor
UpdateFromPath(env *map[string]string) common.Executor
Remove() common.Executor
}
Expand Down Expand Up @@ -167,6 +169,10 @@ func (cr *containerReference) UpdateFromEnv(srcPath string, env *map[string]stri
return cr.extractEnv(srcPath, env).IfNot(common.Dryrun)
}

func (cr *containerReference) UpdateFromImageEnv(env *map[string]string) common.Executor {
return cr.extractFromImageEnv(env).IfNot(common.Dryrun)
}

func (cr *containerReference) UpdateFromPath(env *map[string]string) common.Executor {
return cr.extractPath(env).IfNot(common.Dryrun)
}
Expand Down Expand Up @@ -296,13 +302,6 @@ func (cr *containerReference) create(capAdd []string, capDrop []string) common.E
isTerminal := term.IsTerminal(int(os.Stdout.Fd()))
input := cr.input

insp, _, err := cr.cli.ImageInspectWithRaw(ctx, input.Image)
if err != nil {
logger.Error(err)
}

input.Env = mergeEnvFromImage(input.Env, insp.Config.Env)

config := &container.Config{
Image: input.Image,
Cmd: input.Cmd,
Expand Down Expand Up @@ -355,39 +354,6 @@ func (cr *containerReference) create(capAdd []string, capDrop []string) common.E
}
}

func mergeEnvFromImage(inputEnv, imageEnv []string) []string {
envMap := make(map[string]string)
for _, v := range inputEnv {
e := strings.Split(v, `=`)
if e[1] == "" {
envMap[e[0]] = ""
} else {
envMap[e[0]] = e[1]
}
}

for _, v := range imageEnv {
e := strings.SplitN(v, `=`, 2)
if env, ok := envMap[e[0]]; !ok {
if e[1] != "" {
envMap[e[0]] = e[1]
}
} else {
if e[0] == "PATH" {
if e[1] != "" {
envMap[e[0]] = strings.Join([]string{env, e[1]}, `:`)
}
}
}
}

out := make([]string, 0)
for k, v := range envMap {
out = append(out, strings.Join([]string{k, v}, `=`))
}
return out
}

var singleLineEnvPattern, mulitiLineEnvPattern *regexp.Regexp

func (cr *containerReference) extractEnv(srcPath string, env *map[string]string) common.Executor {
Expand Down Expand Up @@ -437,6 +403,38 @@ func (cr *containerReference) extractEnv(srcPath string, env *map[string]string)
}
}

func (cr *containerReference) extractFromImageEnv(env *map[string]string) common.Executor {
envMap := *env
return func(ctx context.Context) error {
logger := common.Logger(ctx)

inspect, _, err := cr.cli.ImageInspectWithRaw(ctx, cr.input.Image)
if err != nil {
logger.Error(err)
}

imageEnv, err := godotenv.Unmarshal(strings.Join(inspect.Config.Env, "\n"))
if err != nil {
logger.Error(err)
}

for k, v := range imageEnv {
if k == "PATH" {
if envMap[k] == "" {
envMap[k] = v
} else {
envMap[k] += `:` + v
}
} else if envMap[k] == "" {
envMap[k] = v
}
}

env = &envMap
return nil
}
}

func (cr *containerReference) extractPath(env *map[string]string) common.Executor {
localEnv := *env
return func(ctx context.Context) error {
Expand Down
33 changes: 0 additions & 33 deletions pkg/container/docker_run_test.go
Original file line number Diff line number Diff line change
@@ -1,34 +1 @@
package container

import (
"sort"
"testing"

"github.com/stretchr/testify/assert"
)

func TestMergeEnvFromImage(t *testing.T) {
inputEnv := []string{
"PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin",
"GOPATH=/root/go",
"GOOS=linux",
}
imageEnv := []string{
"PATH=/root/go/bin",
"GOPATH=/tmp",
"GOARCH=amd64",
}

merged := mergeEnvFromImage(inputEnv, imageEnv)
sort.Strings(merged)

expected := []string{
"PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin:/root/go/bin",
"GOPATH=/root/go",
"GOOS=linux",
"GOARCH=amd64",
}
sort.Strings(expected)

assert.Equal(t, expected, merged)
}
1 change: 1 addition & 0 deletions pkg/runner/run_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
rc.stopJobContainer(),
rc.JobContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),
rc.JobContainer.Start(false),
rc.JobContainer.UpdateFromImageEnv(&rc.Env),
rc.JobContainer.UpdateFromEnv("/etc/environment", &rc.Env),
rc.JobContainer.Exec([]string{"mkdir", "-m", "0777", "-p", ActPath}, rc.Env, "root", ""),
rc.JobContainer.CopyDir(copyToPath, rc.Config.Workdir+string(filepath.Separator)+".", rc.Config.UseGitIgnore).IfBool(copyWorkspace),
Expand Down
6 changes: 5 additions & 1 deletion pkg/runner/step_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,11 @@ func (sc *StepContext) setupEnv(ctx context.Context) (ExpressionEvaluator, error
rc := sc.RunContext
sc.Env = sc.mergeEnv()
if sc.Env != nil {
err := rc.JobContainer.UpdateFromEnv(sc.Env["GITHUB_ENV"], &sc.Env)(ctx)
err := rc.JobContainer.UpdateFromImageEnv(&sc.Env)(ctx)
if err != nil {
return nil, err
}
err = rc.JobContainer.UpdateFromEnv(sc.Env["GITHUB_ENV"], &sc.Env)(ctx)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit ccde10e

Please sign in to comment.