-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand build argument from environment when no value specified #993
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| FROM debian:9.11 | ||
|
|
||
| ARG SSH_PRIVATE_KEY | ||
| ARG SSH_PUBLIC_KEY | ||
|
|
||
| RUN mkdir .ssh && \ | ||
| chmod 700 .ssh && \ | ||
| echo "$SSH_PRIVATE_KEY" > .ssh/id_rsa && \ | ||
| echo "$SSH_PUBLIC_KEY" > .ssh/id_rsa.pub && \ | ||
| chmod 600 .ssh/id_rsa .ssh/id_rsa.pub |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ limitations under the License. | |
| package integration | ||
|
|
||
| import ( | ||
| "bytes" | ||
| "fmt" | ||
| "io/ioutil" | ||
| "os" | ||
|
|
@@ -46,10 +47,11 @@ const ( | |
|
|
||
| // Arguments to build Dockerfiles with, used for both docker and kaniko builds | ||
| var argsMap = map[string][]string{ | ||
| "Dockerfile_test_run": {"file=/file"}, | ||
| "Dockerfile_test_workdir": {"workdir=/arg/workdir"}, | ||
| "Dockerfile_test_add": {"file=context/foo"}, | ||
| "Dockerfile_test_onbuild": {"file=/tmp/onbuild"}, | ||
| "Dockerfile_test_run": {"file=/file"}, | ||
| "Dockerfile_test_workdir": {"workdir=/arg/workdir"}, | ||
| "Dockerfile_test_add": {"file=context/foo"}, | ||
| "Dockerfile_test_arg_secret": {"SSH_PRIVATE_KEY", "SSH_PUBLIC_KEY=Pµbl1cK€Y"}, | ||
| "Dockerfile_test_onbuild": {"file=/tmp/onbuild"}, | ||
| "Dockerfile_test_scratch": { | ||
| "image=scratch", | ||
| "hello=hello-value", | ||
|
|
@@ -59,6 +61,11 @@ var argsMap = map[string][]string{ | |
| "Dockerfile_test_multistage": {"file=/foo2"}, | ||
| } | ||
|
|
||
| // Environment to build Dockerfiles with, used for both docker and kaniko builds | ||
| var envsMap = map[string][]string{ | ||
| "Dockerfile_test_arg_secret": {"SSH_PRIVATE_KEY=ThEPriv4t3Key"}, | ||
| } | ||
|
|
||
| // Arguments to build Dockerfiles with when building with docker | ||
| var additionalDockerFlagsMap = map[string][]string{ | ||
| "Dockerfile_test_target": {"--target=second"}, | ||
|
|
@@ -71,6 +78,36 @@ var additionalKanikoFlagsMap = map[string][]string{ | |
| "Dockerfile_test_target": {"--target=second"}, | ||
| } | ||
|
|
||
| // output check to do when building with kaniko | ||
| var outputChecks = map[string]func(string, []byte) error{ | ||
| "Dockerfile_test_arg_secret": checkArgsNotPrinted, | ||
| } | ||
|
|
||
| // Checks if argument are not printed in output. | ||
| // Argument may be passed through --build-arg key=value manner or --build-arg key with key in environment | ||
| func checkArgsNotPrinted(dockerfile string, out []byte) error { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this checks to make sure the value of none of the build args are logged? It makes no distinction between whether they were added as literals or expanded from the env?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cvgw I could have make the distinction in the test, however I could not find any way to make the distinction in the code as env like variable (env, arg and meta arg ) are used everywhere as a mere string
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No changes needed. Was just clarifying for my owner understanding. I think it's reasonable to not log any ARG values. |
||
| for _, arg := range argsMap[dockerfile] { | ||
| argSplitted := strings.Split(arg, "=") | ||
| if len(argSplitted) == 2 { | ||
| if idx := bytes.Index(out, []byte(argSplitted[1])); idx >= 0 { | ||
| return fmt.Errorf("Argument value %s for argument %s displayed in output", argSplitted[1], argSplitted[0]) | ||
| } | ||
| } else if len(argSplitted) == 1 { | ||
| if envs, ok := envsMap[dockerfile]; ok { | ||
| for _, env := range envs { | ||
| envSplitted := strings.Split(env, "=") | ||
| if len(envSplitted) == 2 { | ||
| if idx := bytes.Index(out, []byte(envSplitted[1])); idx >= 0 { | ||
| return fmt.Errorf("Argument value %s for argument %s displayed in output", envSplitted[1], argSplitted[0]) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| var bucketContextTests = []string{"Dockerfile_test_copy_bucket"} | ||
| var reproducibleTests = []string{"Dockerfile_test_reproducible"} | ||
|
|
||
|
|
@@ -164,8 +201,7 @@ func (d *DockerFileBuilder) BuildImage(config *gcpConfig, dockerfilesPath, docke | |
| var buildArgs []string | ||
| buildArgFlag := "--build-arg" | ||
| for _, arg := range argsMap[dockerfile] { | ||
| buildArgs = append(buildArgs, buildArgFlag) | ||
| buildArgs = append(buildArgs, arg) | ||
| buildArgs = append(buildArgs, buildArgFlag, arg) | ||
| } | ||
| // build docker image | ||
| additionalFlags := append(buildArgs, additionalDockerFlagsMap[dockerfile]...) | ||
|
|
@@ -177,6 +213,9 @@ func (d *DockerFileBuilder) BuildImage(config *gcpConfig, dockerfilesPath, docke | |
| "."}, | ||
| additionalFlags...)..., | ||
| ) | ||
| if env, ok := envsMap[dockerfile]; ok { | ||
| dockerCmd.Env = append(dockerCmd.Env, env...) | ||
| } | ||
|
|
||
| timer := timing.Start(dockerfile + "_docker") | ||
| out, err := RunCommandWithoutTest(dockerCmd) | ||
|
|
@@ -225,7 +264,11 @@ func (d *DockerFileBuilder) BuildImage(config *gcpConfig, dockerfilesPath, docke | |
| "-v", cwd + ":/workspace", | ||
| "-v", benchmarkDir + ":/kaniko/benchmarks", | ||
| } | ||
|
|
||
| if env, ok := envsMap[dockerfile]; ok { | ||
| for _, envVariable := range env { | ||
| dockerRunFlags = append(dockerRunFlags, "-e", envVariable) | ||
| } | ||
| } | ||
| dockerRunFlags = addServiceAccountFlags(dockerRunFlags, serviceAccount) | ||
|
|
||
| dockerRunFlags = append(dockerRunFlags, ExecutorImage, | ||
|
|
@@ -242,6 +285,11 @@ func (d *DockerFileBuilder) BuildImage(config *gcpConfig, dockerfilesPath, docke | |
| if err != nil { | ||
| return fmt.Errorf("Failed to build image %s with kaniko command \"%s\": %s %s", dockerImage, kanikoCmd.Args, err, string(out)) | ||
| } | ||
| if outputCheck := outputChecks[dockerfile]; outputCheck != nil { | ||
| if err := outputCheck(dockerfile, out); err != nil { | ||
| return fmt.Errorf("Output check failed for image %s with kaniko command \"%s\": %s %s", dockerImage, kanikoCmd.Args, err, string(out)) | ||
| } | ||
| } | ||
|
|
||
| d.FilesBuilt[dockerfile] = true | ||
| return nil | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this will take an argument like
FOOand replace it withFOO=FOO?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cvgw this will take the argument array such as
[ "foo=bar", "EnvVariable" ]crawl through it and replace any argument without=with"EnvVariable=EnvValue"if a value was returned byresolverfunction (os.Getenvin prod code, mocked function in tests). If zero length value returned, it will be replaced with"EnvVariable="There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for explaining, cheers