Skip to content

Commit

Permalink
Support BuildArgs for arg command
Browse files Browse the repository at this point in the history
  • Loading branch information
Priya Wadhwa committed May 9, 2018
1 parent 3aafb84 commit 5396143
Show file tree
Hide file tree
Showing 37 changed files with 296 additions and 90 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ After each command, we append a layer of changed files to the base image (if the
The majority of Dockerfile commands can be executed with kaniko, but we're still working on supporting the following commands:

* HEALTHCHECK
* ARG

Multi-Stage Dockerfiles are also unsupported currently, but will be ready soon.

Expand Down
28 changes: 25 additions & 3 deletions cmd/executor/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import (
"os"
"path/filepath"

"github.com/genuinetools/amicontained/container"

"github.com/GoogleContainerTools/kaniko/pkg/executor"
"github.com/genuinetools/amicontained/container"
"strings"

"github.com/GoogleContainerTools/kaniko/pkg/constants"
"github.com/GoogleContainerTools/kaniko/pkg/util"
Expand All @@ -40,6 +40,7 @@ var (
dockerInsecureSkipTLSVerify bool
logLevel string
force bool
buildArgs buildArg
)

func init() {
Expand All @@ -49,6 +50,7 @@ func init() {
RootCmd.PersistentFlags().StringVarP(&destination, "destination", "d", "", "Registry the final image should be pushed to (ex: gcr.io/test/example:latest)")
RootCmd.MarkPersistentFlagRequired("destination")
RootCmd.PersistentFlags().StringVarP(&snapshotMode, "snapshotMode", "", "full", "Set this flag to change the file attributes inspected during snapshotting")
RootCmd.PersistentFlags().VarP(&buildArgs, "build-arg", "", "This flag allows you to pass in ARG values at build time. Set it repeatedly for multiple values.")
RootCmd.PersistentFlags().BoolVarP(&dockerInsecureSkipTLSVerify, "insecure-skip-tls-verify", "", false, "Push to insecure registry ignoring TLS verify")
RootCmd.PersistentFlags().StringVarP(&logLevel, "verbosity", "v", constants.DefaultLogLevel, "Log level (debug, info, warn, error, fatal, panic")
RootCmd.PersistentFlags().BoolVarP(&force, "force", "", false, "Force building outside of a container")
Expand Down Expand Up @@ -77,13 +79,33 @@ var RootCmd = &cobra.Command{
logrus.Error(err)
os.Exit(1)
}
if err := executor.DoBuild(dockerfilePath, srcContext, destination, snapshotMode, dockerInsecureSkipTLSVerify); err != nil {
if err := executor.DoBuild(dockerfilePath, srcContext, destination, snapshotMode, dockerInsecureSkipTLSVerify, buildArgs); err != nil {
logrus.Error(err)
os.Exit(1)
}
},
}

type buildArg []string

// Now, for our new type, implement the two methods of
// the flag.Value interface...
// The first method is String() string
func (b *buildArg) String() string {
return strings.Join(*b, ",")
}

// The second method is Set(value string) error
func (b *buildArg) Set(value string) error {
logrus.Infof("appending to build args %s", value)
*b = append(*b, value)
return nil
}

func (b *buildArg) Type() string {
return "Build ARG Type"
}

func checkContained() bool {
_, err := container.DetectRuntime()
return err == nil
Expand Down
4 changes: 4 additions & 0 deletions integration_tests/dockerfiles/Dockerfile_test_add
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ ADD $contextenv/* /tmp/${contextenv}/
ADD context/tars/fil* /tars/
ADD context/tars/file.tar /tars_again

# Test with ARG
ARG file
COPY $file /arg

# Finally, test adding a remote URL, concurrently with a normal file
ADD https://github.com/GoogleCloudPlatform/docker-credential-gcr/releases/download/v1.4.3/docker-credential-gcr_linux_386-1.4.3.tar.gz context/foo /test/all/
3 changes: 2 additions & 1 deletion integration_tests/dockerfiles/Dockerfile_test_onbuild
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM gcr.io/kaniko-test/onbuild-base:latest
COPY context/foo foo
ENV dir /new/workdir/
ONBUILD RUN echo "onbuild" > /tmp/onbuild
ARG file
ONBUILD RUN echo "onbuild" > $file
ONBUILD RUN echo "onbuild 2" > ${dir}
ONBUILD WORKDIR /new/workdir
4 changes: 4 additions & 0 deletions integration_tests/dockerfiles/Dockerfile_test_run
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ RUN echo "hey" > /etc/foo
RUN echo "baz" > /etc/baz
RUN cp /etc/baz /etc/bar
RUN rm /etc/baz

# Test with ARG
ARG file
RUN echo "run" > $file
16 changes: 13 additions & 3 deletions integration_tests/dockerfiles/Dockerfile_test_scratch
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
FROM scratch
ADD context/foo /foo
ENV hello hello
ADD context/foo /$hello
# First, make sure simple arg replacement works
ARG file
COPY $file /foo
# Check that setting a default value works
ARG file2=context/bar/bat
COPY $file2 /bat
# Check that overriding a default value works
ARG file3=context/bar/baz
COPY $file3 /baz
# Check that setting an ENV will override the ARG
ENV file context/bar/bam/bat
COPY $file /env

4 changes: 4 additions & 0 deletions integration_tests/dockerfiles/Dockerfile_test_workdir
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ ENV dir /another/new/dir
WORKDIR $dir/newdir
WORKDIR $dir/$doesntexist
WORKDIR /

# Test with ARG
ARG workdir
WORKDIR $workdir
33 changes: 28 additions & 5 deletions integration_tests/integration_test_yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ var fileTests = []struct {
kanikoContextBucket bool
repo string
snapshotMode string
args []string
}{
{
description: "test extract filesystem",
Expand All @@ -64,6 +65,9 @@ var fileTests = []struct {
dockerContext: dockerfilesPath,
kanikoContext: dockerfilesPath,
repo: "test-run",
args: []string{
"file=/file",
},
},
{
description: "test run no files changed",
Expand Down Expand Up @@ -99,6 +103,9 @@ var fileTests = []struct {
dockerContext: buildcontextPath,
kanikoContext: buildcontextPath,
repo: "test-workdir",
args: []string{
"workdir=/arg/workdir",
},
},
{
description: "test volume",
Expand All @@ -115,6 +122,9 @@ var fileTests = []struct {
dockerContext: buildcontextPath,
kanikoContext: buildcontextPath,
repo: "test-add",
args: []string{
"file=context/foo",
},
},
{
description: "test mv add",
Expand All @@ -139,6 +149,9 @@ var fileTests = []struct {
dockerContext: buildcontextPath,
kanikoContext: buildcontextPath,
repo: "test-onbuild",
args: []string{
"file=/tmp/onbuild",
},
},
{
description: "test scratch",
Expand All @@ -147,6 +160,11 @@ var fileTests = []struct {
dockerContext: buildcontextPath,
kanikoContext: buildcontextPath,
repo: "test-scratch",
args: []string{
"hello=hello-value",
"file=context/foo",
"file3=context/b*",
},
},
}

Expand Down Expand Up @@ -231,18 +249,23 @@ func main() {
Args: []string{"push", onbuildBaseImage},
}
y := testyaml{
Steps: []step{containerDiffStep, containerDiffPermissions, GCSBucketTarBuildContext, uploadTarBuildContext, buildExecutorImage,
buildOnbuildImage, pushOnbuildBase},
Steps: []step{containerDiffStep, containerDiffPermissions, GCSBucketTarBuildContext,
uploadTarBuildContext, buildExecutorImage, buildOnbuildImage, pushOnbuildBase},
Timeout: "1200s",
}
for _, test := range fileTests {
// First, build the image with docker
dockerImageTag := testRepo + dockerPrefix + test.repo
var buildArgs []string
buildArgFlag := "--build-arg"
for _, arg := range test.args {
buildArgs = append(buildArgs, buildArgFlag)
buildArgs = append(buildArgs, arg)
}
dockerBuild := step{
Name: dockerImage,
Args: []string{"build", "-t", dockerImageTag, "-f", test.dockerfilePath, test.dockerContext},
Args: append([]string{"build", "-t", dockerImageTag, "-f", test.dockerfilePath, test.dockerContext}, buildArgs...),
}

// Then, buld the image with kaniko
kanikoImage := testRepo + kanikoPrefix + test.repo
snapshotMode := ""
Expand All @@ -255,7 +278,7 @@ func main() {
}
kaniko := step{
Name: executorImage,
Args: []string{"--destination", kanikoImage, "--dockerfile", test.dockerfilePath, contextFlag, test.kanikoContext, snapshotMode},
Args: append([]string{"--destination", kanikoImage, "--dockerfile", test.dockerfilePath, contextFlag, test.kanikoContext, snapshotMode}, buildArgs...),
}

// Pull the kaniko image
Expand Down
8 changes: 5 additions & 3 deletions pkg/commands/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package commands

import (
"github.com/docker/docker/builder/dockerfile"
"path/filepath"
"strings"

Expand All @@ -41,15 +42,16 @@ type AddCommand struct {
// - If dest doesn't end with a slash, the filepath is inferred to be <dest>/<filename>
// 2. If <src> is a local tar archive:
// -If <src> is a local tar archive, it is unpacked at the dest, as 'tar -x' would
func (a *AddCommand) ExecuteCommand(config *v1.Config) error {
func (a *AddCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
srcs := a.cmd.SourcesAndDest[:len(a.cmd.SourcesAndDest)-1]
dest := a.cmd.SourcesAndDest[len(a.cmd.SourcesAndDest)-1]

logrus.Infof("cmd: Add %s", srcs)
logrus.Infof("dest: %s", dest)

// First, resolve any environment replacement
resolvedEnvs, err := util.ResolveEnvironmentReplacementList(a.cmd.SourcesAndDest, config.Env, true)
replacementEnvs := util.ReplacementEnvs(config, buildArgs)
resolvedEnvs, err := util.ResolveEnvironmentReplacementList(a.cmd.SourcesAndDest, replacementEnvs, true)
if err != nil {
return err
}
Expand Down Expand Up @@ -101,7 +103,7 @@ func (a *AddCommand) ExecuteCommand(config *v1.Config) error {
},
buildcontext: a.buildcontext,
}
if err := copyCmd.ExecuteCommand(config); err != nil {
if err := copyCmd.ExecuteCommand(config, buildArgs); err != nil {
return err
}
a.snapshotFiles = append(a.snapshotFiles, copyCmd.snapshotFiles...)
Expand Down
46 changes: 46 additions & 0 deletions pkg/commands/arg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package commands

import (
"github.com/docker/docker/builder/dockerfile"
"github.com/docker/docker/builder/dockerfile/instructions"
"github.com/google/go-containerregistry/v1"
"github.com/sirupsen/logrus"
"strings"
)

type ArgCommand struct {
cmd *instructions.ArgCommand
}

// ExecuteCommand only needs to add this ARG key/value as seen
func (r *ArgCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
logrus.Info("ARG")
buildArgs.AddArg(r.cmd.Key, r.cmd.Value)
return nil
}

// FilesToSnapshot returns an empty array since this command only touches metadata.
func (r *ArgCommand) FilesToSnapshot() []string {
return []string{}
}

// CreatedBy returns some information about the command for the image config history
func (r *ArgCommand) CreatedBy() string {
return strings.Join([]string{r.cmd.Name(), r.cmd.Key}, " ")
}
3 changes: 2 additions & 1 deletion pkg/commands/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package commands

import (
"github.com/docker/docker/builder/dockerfile"
"strings"

"github.com/docker/docker/builder/dockerfile/instructions"
Expand All @@ -30,7 +31,7 @@ type CmdCommand struct {

// ExecuteCommand executes the CMD command
// Argument handling is the same as RUN.
func (c *CmdCommand) ExecuteCommand(config *v1.Config) error {
func (c *CmdCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
logrus.Info("cmd: CMD")
var newCommand []string
if c.cmd.PrependShell {
Expand Down
8 changes: 3 additions & 5 deletions pkg/commands/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ limitations under the License.
package commands

import (
"testing"

"github.com/google/go-containerregistry/v1"

"github.com/GoogleContainerTools/kaniko/testutil"
"github.com/docker/docker/builder/dockerfile/instructions"
"github.com/google/go-containerregistry/v1"
"testing"
)

var cmdTests = []struct {
Expand Down Expand Up @@ -56,7 +54,7 @@ func TestExecuteCmd(t *testing.T) {
},
},
}
err := cmd.ExecuteCommand(cfg)
err := cmd.ExecuteCommand(cfg, nil)
testutil.CheckErrorAndDeepEqual(t, false, err, test.expectedCmd, cfg.Cmd)
}
}
5 changes: 4 additions & 1 deletion pkg/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package commands

import (
"github.com/docker/docker/builder/dockerfile"
"github.com/docker/docker/builder/dockerfile/instructions"
"github.com/google/go-containerregistry/v1"
"github.com/pkg/errors"
Expand All @@ -28,7 +29,7 @@ type DockerCommand interface {
// 1. Making required changes to the filesystem (ex. copying files for ADD/COPY or setting ENV variables)
// 2. Updating metadata fields in the config
// It should not change the config history.
ExecuteCommand(*v1.Config) error
ExecuteCommand(*v1.Config, *dockerfile.BuildArgs) error
// The config history has a "created by" field, should return information about the command
CreatedBy() string
// A list of files to snapshot, empty for metadata commands or nil if we don't know
Expand Down Expand Up @@ -63,6 +64,8 @@ func GetCommand(cmd instructions.Command, buildcontext string) (DockerCommand, e
return &VolumeCommand{cmd: c}, nil
case *instructions.StopSignalCommand:
return &StopSignalCommand{cmd: c}, nil
case *instructions.ArgCommand:
return &ArgCommand{cmd: c}, nil
case *instructions.MaintainerCommand:
logrus.Warnf("%s is deprecated, skipping", cmd.Name())
return nil, nil
Expand Down
Loading

0 comments on commit 5396143

Please sign in to comment.