diff --git a/Makefile b/Makefile index 86e38cc92..7e4e8abf3 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ GOOS ?= $(shell go env GOOS) GOARCH = amd64 ORG := github.com/GoogleCloudPlatform PROJECT := k8s-container-builder -REGISTRY?=gcr.io/kbuild-project +REGISTRY?=gcr.io/kaniko-project REPOPATH ?= $(ORG)/$(PROJECT) @@ -32,23 +32,23 @@ GO_LDFLAGS := '-extldflags "-static"' GO_BUILD_TAGS := "containers_image_ostree_stub containers_image_openpgp exclude_graphdriver_devicemapper exclude_graphdriver_btrfs exclude_graphdriver_overlay" EXECUTOR_PACKAGE = $(REPOPATH)/executor -KBUILD_PACKAGE = $(REPOPATH)/kbuild +KANIKO_PROJECT = $(REPOPATH)/kaniko out/executor: $(GO_FILES) GOARCH=$(GOARCH) GOOS=linux CGO_ENABLED=0 go build -ldflags $(GO_LDFLAGS) -tags $(GO_BUILD_TAGS) -o $@ $(EXECUTOR_PACKAGE) -out/kbuild: $(GO_FILES) - GOOS=$* GOARCH=$(GOARCH) CGO_ENABLED=0 go build -ldflags $(GO_LDFLAGS) -tags $(GO_BUILD_TAGS) -o $@ $(KBUILD_PACKAGE) +out/kaniko: $(GO_FILES) + GOOS=$* GOARCH=$(GOARCH) CGO_ENABLED=0 go build -ldflags $(GO_LDFLAGS) -tags $(GO_BUILD_TAGS) -o $@ $(KANIKO_PROJECT) .PHONY: test -test: out/executor out/kbuild +test: out/executor out/kaniko @ ./test.sh .PHONY: integration-test -integration-test: out/executor out/kbuild +integration-test: out/executor out/kaniko @ ./integration-test.sh .PHONY: images -images: out/executor out/kbuild +images: out/executor out/kaniko docker build -t $(REGISTRY)/executor:latest -f deploy/Dockerfile . diff --git a/README.md b/README.md index a0171eed9..2e49d811a 100644 --- a/README.md +++ b/README.md @@ -1 +1,141 @@ -kbuild is a tool to build container images from a Dockerfile in a Kubernetes cluster. \ No newline at end of file +# kaniko + +kaniko is a tool to build unpriviliged container images from a Dockerfile. +kaniko doesn't depend on a Docker daemon and executes each command within a Dockerfile completely in userspace. +This enables building container images in environments that can't easily or securely run a Docker daemon, such as a standard Kubernetes cluster. + +The majority of Dockerfile commands can be executed with kaniko, but we're still working on supporting the following commands: +* SHELL +* HEALTHCHECK +* STOPSIGNAL +* ARG + +We're currently in the process of building kaniko, so as of now it isn't production ready. +Please let us know if you have any feature requests or find any bugs! + +## How does kaniko work? + +The kaniko executor image is responsible for building an image from a Dockerfile and pushing it to a registry. +Within the executor image, we extract the filesystem of the base image (the FROM image in the Dockerfile). +We then execute the commands in the Dockerfile, snapshotting the filesystem in userspace after each one. +After each command, we append a layer of changed files to the base image (if there are any) and update image metadata. + +## kaniko Build Contexts +kaniko supports local directories and GCS buckets as build contexts. To specify a local directory, pass in the `--context` flag as an argument to the executor image. +To specify a GCS bucket, pass in the `--bucket` flag. +The GCS bucket should contain a compressed tar of the build context called `context.tar.gz`, which kaniko will unpack and use as the build context. + +To create `context.tar.gz`, run the following command: +```shell +tar -C -zcvf context.tar.gz . +``` + +Or, you can use [skaffold](https://github.com/GoogleCloudPlatform/skaffold) to create `context.tar.gz` by running +``` +skaffold docker context +``` + +We can copy over the compressed tar to a GCS bucket with gsutil: + +``` +gsutil cp context.tar.gz gs:// +``` + +## Running kaniko locally + +Requirements: +* Docker +* gcloud + +We can run the kaniko executor image locally in a Docker daemon to build and push an image from a Dockerfile. + +First, we want to load the executor image into the Docker daemon by running +```shell +make images +``` + +To run kaniko in Docker, run the following command: +```shell +./run_in_docker.sh +``` + +## Running kaniko in a Kubernetes cluster + +Requirements: +* Standard Kubernetes cluster +* Kubernetes Secret + +To run kaniko in a Kubernetes cluster, you will need a standard running Kubernetes cluster and a Kubernetes secret, which contains the auth required to push the final image. + +To create the secret, first you will need to create a service account in the Pantheon project you want to push the final image to, with `Storage Admin` permissions. +You can download a JSON key for this service account, and rename it `kaniko-secret.json`. +To create the secret, run: + +```shell +kubectl create secret generic kaniko-secret --from-file= +``` + +The Kubernetes Pod spec should look similar to this, with the args parameters filled in: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: kaniko +spec: + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=", + "--bucket=", + "--destination="] + volumeMounts: + - name: kaniko-secret + mountPath: /secret + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /secret/kaniko-secret.json + restartPolicy: Never + volumes: + - name: kaniko-secret + secret: + secretName: kaniko-secret +``` + +This example pulls the build context from a GCS bucket. +To use a local directory build context, you could consider using configMaps to mount in small build contexts. + +## Running kaniko in Google Container Builder +To run kaniko in GCB, add it to your build config as a build step: + +```yaml +steps: + - name: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=", + "--context=", + "--destination="] +``` +kaniko will build and push the final image in this build step. + +## Comparison with Other Tools + +Similar tools include: +* [img](https://github.com/genuinetools/img) +* [orca-build](https://github.com/cyphar/orca-build) +* [buildah](https://github.com/projectatomic/buildah) +* [FTL](https://github.com/GoogleCloudPlatform/runtimes-common/tree/master/ftl) + +All of these tools build container images with different approaches. +Both kaniko and img build unprivileged images, but they interpret “unprivileged” differently. +img builds as a non root user from within the container, while kaniko is run in an unprivileged environment with root access inside the container. + +orca-build depends on runC to build images from Dockerfiles; since kaniko doesn't use runC it doesn't require the use of kernel namespacing techniques. + +buildah requires the same root privilges as a Docker daemon does to run, while kaniko runs without any special privileges or permissions. + +FTL aims to achieve the fastest possible creation of Docker images for a subset of images. +It can be thought of as a special-case "fast path" that can be used in conjunction with the support for general Dockerfiles kaniko provides. + +## Community + +[kaniko-users](https://groups.google.com/forum/#!forum/kaniko-users) Google group diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 3020be1bc..37b07e01d 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -15,10 +15,11 @@ # Builds the static Go image to execute in a Kubernetes job FROM scratch -ADD out/executor /kbuild/executor +ADD out/executor /kaniko/executor ADD files/ca-certificates.crt /etc/ssl/certs/ ADD files/docker-credential-gcr /usr/local/bin/ ADD files/config.json /root/.docker/ +RUN ["docker-credential-gcr", "config", "--token-source=env"] ENV HOME /root ENV PATH /usr/local/bin -ENTRYPOINT ["/kbuild/executor"] +ENTRYPOINT ["/kaniko/executor"] diff --git a/executor/cmd/root.go b/executor/cmd/root.go index 546c9bd4c..14a1c68e8 100644 --- a/executor/cmd/root.go +++ b/executor/cmd/root.go @@ -17,12 +17,15 @@ limitations under the License. package cmd import ( + "fmt" "github.com/GoogleCloudPlatform/k8s-container-builder/pkg/commands" "github.com/GoogleCloudPlatform/k8s-container-builder/pkg/constants" "github.com/GoogleCloudPlatform/k8s-container-builder/pkg/dockerfile" "github.com/GoogleCloudPlatform/k8s-container-builder/pkg/image" "github.com/GoogleCloudPlatform/k8s-container-builder/pkg/snapshot" "github.com/GoogleCloudPlatform/k8s-container-builder/pkg/util" + "github.com/containers/image/manifest" + "github.com/docker/docker/builder/dockerfile/instructions" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -52,13 +55,15 @@ func init() { var RootCmd = &cobra.Command{ Use: "executor", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - return util.SetLogLevel(logLevel) + if err := util.SetLogLevel(logLevel); err != nil { + return err + } + if err := resolveSourceContext(); err != nil { + return err + } + return checkDockerfilePath() }, Run: func(cmd *cobra.Command, args []string) { - if err := resolveSourceContext(); err != nil { - logrus.Error(err) - os.Exit(1) - } if err := execute(); err != nil { logrus.Error(err) os.Exit(1) @@ -66,6 +71,18 @@ var RootCmd = &cobra.Command{ }, } +func checkDockerfilePath() error { + if util.FilepathExists(dockerfilePath) { + return nil + } + // Otherwise, check if the path relative to the build context exists + if util.FilepathExists(filepath.Join(srcContext, dockerfilePath)) { + dockerfilePath = filepath.Join(srcContext, dockerfilePath) + return nil + } + return errors.New("please provide a valid path to a Dockerfile within the build context") +} + // resolveSourceContext unpacks the source context if it is a tar in a GCS bucket // it resets srcContext to be the path to the unpacked build context within the image func resolveSourceContext() error { @@ -85,11 +102,6 @@ func resolveSourceContext() error { } logrus.Debugf("Unpacked tar from %s to path %s", bucket, buildContextPath) srcContext = buildContextPath - // If path to dockerfile doesn't exist, assume it is in the unpacked tar - if !util.FilepathExists(dockerfilePath) { - logrus.Debugf("Expecting dockerfile to be located at %s within the tar build context", dockerfilePath) - dockerfilePath = filepath.Join(srcContext, dockerfilePath) - } return nil } @@ -112,7 +124,11 @@ func execute() error { return err } - l := snapshot.NewLayeredMap(getHasher()) + hasher, err := getHasher() + if err != nil { + return err + } + l := snapshot.NewLayeredMap(hasher) snapshotter := snapshot.NewSnapshotter(l, constants.RootDir) // Take initial snapshot @@ -134,6 +150,9 @@ func execute() error { imageConfig := sourceImage.Config() // Currently only supports single stage builds for _, stage := range stages { + if err := resolveOnBuild(&stage, imageConfig); err != nil { + return err + } for _, cmd := range stage.Commands { dockerCommand, err := commands.GetCommand(cmd, srcContext) if err != nil { @@ -148,6 +167,7 @@ func execute() error { if err != nil { return err } + util.MoveVolumeWhitelistToWhitelist() if contents == nil { logrus.Info("No files were changed, appending empty layer to config.") sourceImage.AppendConfigHistory(constants.Author, true) @@ -166,12 +186,30 @@ func execute() error { return image.PushImage(sourceImage, destination) } -func getHasher() func(string) (string, error) { - if snapshotMode == "time" { +func getHasher() (func(string) (string, error), error) { + if snapshotMode == constants.SnapshotModeTime { logrus.Info("Only file modification time will be considered when snapshotting") - return util.MtimeHasher() + return util.MtimeHasher(), nil } - return util.Hasher() + if snapshotMode == constants.SnapshotModeFull { + return util.Hasher(), nil + } + return nil, fmt.Errorf("%s is not a valid snapshot mode", snapshotMode) +} + +func resolveOnBuild(stage *instructions.Stage, config *manifest.Schema2Config) error { + if config.OnBuild == nil { + return nil + } + // Otherwise, parse into commands + cmds, err := dockerfile.ParseCommands(config.OnBuild) + if err != nil { + return err + } + // Append to the beginning of the commands in the stage + stage.Commands = append(cmds, stage.Commands...) + logrus.Infof("Executing %v build triggers", len(cmds)) + return nil } // setDefaultEnv sets default values for HOME and PATH so that diff --git a/integration_tests/dockerfiles/Dockerfile_onbuild_base b/integration_tests/dockerfiles/Dockerfile_onbuild_base new file mode 100644 index 000000000..85532c1a0 --- /dev/null +++ b/integration_tests/dockerfiles/Dockerfile_onbuild_base @@ -0,0 +1,6 @@ +FROM gcr.io/google-appengine/debian9:latest +ENV dir /tmp/dir/ +ONBUILD RUN echo "onbuild" > /tmp/onbuild +ONBUILD RUN mkdir $dir +ONBUILD RUN echo "onbuild 2" > ${dir}/onbuild2 +ONBUILD WORKDIR /new/workdir diff --git a/integration_tests/dockerfiles/Dockerfile_test_onbuild b/integration_tests/dockerfiles/Dockerfile_test_onbuild new file mode 100644 index 000000000..2968c0c62 --- /dev/null +++ b/integration_tests/dockerfiles/Dockerfile_test_onbuild @@ -0,0 +1,6 @@ +FROM gcr.io/kaniko-test/onbuild-base:latest +COPY context/foo foo +ENV dir /new/workdir/ +ONBUILD RUN echo "onbuild" > /tmp/onbuild +ONBUILD RUN echo "onbuild 2" > ${dir} +ONBUILD WORKDIR /new/workdir diff --git a/integration_tests/dockerfiles/Dockerfile_test_volume b/integration_tests/dockerfiles/Dockerfile_test_volume new file mode 100644 index 000000000..f5a255cfe --- /dev/null +++ b/integration_tests/dockerfiles/Dockerfile_test_volume @@ -0,0 +1,7 @@ +FROM gcr.io/google-appengine/debian9 +RUN mkdir /foo +RUN echo "hello" > /foo/hey +VOLUME /foo/bar /tmp +ENV VOL /baz/bat +VOLUME ["${VOL}"] +RUN echo "hello again" > /tmp/hey diff --git a/integration_tests/dockerfiles/config_test_add.json b/integration_tests/dockerfiles/config_test_add.json index b6d7a2020..135cd04a3 100644 --- a/integration_tests/dockerfiles/config_test_add.json +++ b/integration_tests/dockerfiles/config_test_add.json @@ -1,7 +1,7 @@ [ { - "Image1": "gcr.io/kbuild-test/docker-test-add:latest", - "Image2": "gcr.io/kbuild-test/kbuild-test-add:latest", + "Image1": "gcr.io/kaniko-test/docker-test-add:latest", + "Image2": "gcr.io/kaniko-test/kaniko-test-add:latest", "DiffType": "File", "Diff": { "Adds": null, diff --git a/integration_tests/dockerfiles/config_test_bucket_buildcontext.json b/integration_tests/dockerfiles/config_test_bucket_buildcontext.json index 690bbea5a..04c066831 100644 --- a/integration_tests/dockerfiles/config_test_bucket_buildcontext.json +++ b/integration_tests/dockerfiles/config_test_bucket_buildcontext.json @@ -1,7 +1,7 @@ [ { - "Image1": "gcr.io/kbuild-test/docker-test-bucket-buildcontext:latest", - "Image2": "gcr.io/kbuild-test/kbuild-test-bucket-buildcontext:latest", + "Image1": "gcr.io/kaniko-test/docker-test-bucket-buildcontext:latest", + "Image2": "gcr.io/kaniko-test/kaniko-test-bucket-buildcontext:latest", "DiffType": "File", "Diff": { "Adds": null, diff --git a/integration_tests/dockerfiles/config_test_copy.json b/integration_tests/dockerfiles/config_test_copy.json index 6d222de51..c2fcf57d6 100644 --- a/integration_tests/dockerfiles/config_test_copy.json +++ b/integration_tests/dockerfiles/config_test_copy.json @@ -1,7 +1,7 @@ [ { - "Image1": "gcr.io/kbuild-test/docker-test-copy:latest", - "Image2": "gcr.io/kbuild-test/kbuild-test-copy:latest", + "Image1": "gcr.io/kaniko-test/docker-test-copy:latest", + "Image2": "gcr.io/kaniko-test/kaniko-test-copy:latest", "DiffType": "File", "Diff": { "Adds": null, diff --git a/integration_tests/dockerfiles/config_test_extract_fs.json b/integration_tests/dockerfiles/config_test_extract_fs.json index a5b03a8e9..2143ed492 100644 --- a/integration_tests/dockerfiles/config_test_extract_fs.json +++ b/integration_tests/dockerfiles/config_test_extract_fs.json @@ -1,7 +1,7 @@ [ { - "Image1": "gcr.io/kbuild-test/docker-extract-filesystem:latest", - "Image2": "gcr.io/kbuild-test/kbuild-extract-filesystem:latest", + "Image1": "gcr.io/kaniko-test/docker-extract-filesystem:latest", + "Image2": "gcr.io/kaniko-test/kaniko-extract-filesystem:latest", "DiffType": "File", "Diff": { "Adds": null, diff --git a/integration_tests/dockerfiles/config_test_onbuild.json b/integration_tests/dockerfiles/config_test_onbuild.json new file mode 100644 index 000000000..e7fa9a1e4 --- /dev/null +++ b/integration_tests/dockerfiles/config_test_onbuild.json @@ -0,0 +1,12 @@ +[ + { + "Image1": "gcr.io/kaniko-test/docker-test-onbuild:latest", + "Image2": "gcr.io/kaniko-test/kaniko-test-onbuild:latest", + "DiffType": "File", + "Diff": { + "Adds": null, + "Dels": null, + "Mods": null + } + } +] \ No newline at end of file diff --git a/integration_tests/dockerfiles/config_test_run.json b/integration_tests/dockerfiles/config_test_run.json index 7715d8a57..ae2b3d8f2 100644 --- a/integration_tests/dockerfiles/config_test_run.json +++ b/integration_tests/dockerfiles/config_test_run.json @@ -1,7 +1,7 @@ [ { - "Image1": "gcr.io/kbuild-test/docker-test-run:latest", - "Image2": "gcr.io/kbuild-test/kbuild-test-run:latest", + "Image1": "gcr.io/kaniko-test/docker-test-run:latest", + "Image2": "gcr.io/kaniko-test/kaniko-test-run:latest", "DiffType": "File", "Diff": { "Adds": null, diff --git a/integration_tests/dockerfiles/config_test_run_2.json b/integration_tests/dockerfiles/config_test_run_2.json index 0301973df..11f48cbca 100644 --- a/integration_tests/dockerfiles/config_test_run_2.json +++ b/integration_tests/dockerfiles/config_test_run_2.json @@ -1,7 +1,7 @@ [ { - "Image1": "gcr.io/kbuild-test/docker-test-run-2:latest", - "Image2": "gcr.io/kbuild-test/kbuild-test-run-2:latest", + "Image1": "gcr.io/kaniko-test/docker-test-run-2:latest", + "Image2": "gcr.io/kaniko-test/kaniko-test-run-2:latest", "DiffType": "File", "Diff": { "Adds": null, diff --git a/integration_tests/dockerfiles/config_test_volume.json b/integration_tests/dockerfiles/config_test_volume.json new file mode 100644 index 000000000..706bda2c3 --- /dev/null +++ b/integration_tests/dockerfiles/config_test_volume.json @@ -0,0 +1,12 @@ +[ + { + "Image1": "gcr.io/kaniko-test/docker-test-volume:latest", + "Image2": "gcr.io/kaniko-test/kaniko-test-volume:latest", + "DiffType": "File", + "Diff": { + "Adds": null, + "Dels": null, + "Mods": null + } + } +] \ No newline at end of file diff --git a/integration_tests/dockerfiles/config_test_workdir.json b/integration_tests/dockerfiles/config_test_workdir.json index c87503403..3b3fcefab 100644 --- a/integration_tests/dockerfiles/config_test_workdir.json +++ b/integration_tests/dockerfiles/config_test_workdir.json @@ -1,7 +1,7 @@ [ { - "Image1": "gcr.io/kbuild-test/docker-test-workdir:latest", - "Image2": "gcr.io/kbuild-test/kbuild-test-workdir:latest", + "Image1": "gcr.io/kaniko-test/docker-test-workdir:latest", + "Image2": "gcr.io/kaniko-test/kaniko-test-workdir:latest", "DiffType": "File", "Diff": { "Adds": null, diff --git a/integration_tests/integration_test_yaml.go b/integration_tests/integration_test_yaml.go index 1fa7d27e1..03001d7c3 100644 --- a/integration_tests/integration_test_yaml.go +++ b/integration_tests/integration_test_yaml.go @@ -26,14 +26,15 @@ const ( executorImage = "executor-image" dockerImage = "gcr.io/cloud-builders/docker" ubuntuImage = "ubuntu" - testRepo = "gcr.io/kbuild-test/" + testRepo = "gcr.io/kaniko-test/" dockerPrefix = "docker-" - kbuildPrefix = "kbuild-" + kanikoPrefix = "kaniko-" daemonPrefix = "daemon://" containerDiffOutputFile = "container-diff.json" - kbuildTestBucket = "kbuild-test-bucket" + kanikoTestBucket = "kaniko-test-bucket" buildcontextPath = "/workspace/integration_tests" dockerfilesPath = "/workspace/integration_tests/dockerfiles" + onbuildBaseImage = testRepo + "onbuild-base:latest" ) var fileTests = []struct { @@ -41,8 +42,8 @@ var fileTests = []struct { dockerfilePath string configPath string dockerContext string - kbuildContext string - kbuildContextBucket bool + kanikoContext string + kanikoContextBucket bool repo string snapshotMode string }{ @@ -51,7 +52,7 @@ var fileTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_extract_fs", configPath: "/workspace/integration_tests/dockerfiles/config_test_extract_fs.json", dockerContext: dockerfilesPath, - kbuildContext: dockerfilesPath, + kanikoContext: dockerfilesPath, repo: "extract-filesystem", snapshotMode: "time", }, @@ -60,7 +61,7 @@ var fileTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_run", configPath: "/workspace/integration_tests/dockerfiles/config_test_run.json", dockerContext: dockerfilesPath, - kbuildContext: dockerfilesPath, + kanikoContext: dockerfilesPath, repo: "test-run", }, { @@ -68,7 +69,7 @@ var fileTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_run_2", configPath: "/workspace/integration_tests/dockerfiles/config_test_run_2.json", dockerContext: dockerfilesPath, - kbuildContext: dockerfilesPath, + kanikoContext: dockerfilesPath, repo: "test-run-2", snapshotMode: "time", }, @@ -77,7 +78,7 @@ var fileTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_copy", configPath: "/workspace/integration_tests/dockerfiles/config_test_copy.json", dockerContext: buildcontextPath, - kbuildContext: buildcontextPath, + kanikoContext: buildcontextPath, repo: "test-copy", snapshotMode: "time", }, @@ -86,8 +87,8 @@ var fileTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_copy", configPath: "/workspace/integration_tests/dockerfiles/config_test_bucket_buildcontext.json", dockerContext: buildcontextPath, - kbuildContext: kbuildTestBucket, - kbuildContextBucket: true, + kanikoContext: kanikoTestBucket, + kanikoContextBucket: true, repo: "test-bucket-buildcontext", }, { @@ -95,17 +96,33 @@ var fileTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_workdir", configPath: "/workspace/integration_tests/dockerfiles/config_test_workdir.json", dockerContext: buildcontextPath, - kbuildContext: buildcontextPath, + kanikoContext: buildcontextPath, repo: "test-workdir", }, + { + description: "test volume", + dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_volume", + configPath: "/workspace/integration_tests/dockerfiles/config_test_volume.json", + dockerContext: buildcontextPath, + kanikoContext: buildcontextPath, + repo: "test-volume", + }, { description: "test add", dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_add", configPath: "/workspace/integration_tests/dockerfiles/config_test_add.json", dockerContext: buildcontextPath, - kbuildContext: buildcontextPath, + kanikoContext: buildcontextPath, repo: "test-add", }, + { + description: "test onbuild", + dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_onbuild", + configPath: "/workspace/integration_tests/dockerfiles/config_test_onbuild.json", + dockerContext: buildcontextPath, + kanikoContext: buildcontextPath, + repo: "test-onbuild", + }, } var structureTests = []struct { @@ -113,7 +130,7 @@ var structureTests = []struct { dockerfilePath string structureTestYamlPath string dockerBuildContext string - kbuildContext string + kanikoContext string repo string }{ { @@ -121,7 +138,7 @@ var structureTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_env", repo: "test-env", dockerBuildContext: dockerfilesPath, - kbuildContext: dockerfilesPath, + kanikoContext: dockerfilesPath, structureTestYamlPath: "/workspace/integration_tests/dockerfiles/test_env.yaml", }, { @@ -129,7 +146,7 @@ var structureTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_metadata", repo: "test-metadata", dockerBuildContext: dockerfilesPath, - kbuildContext: dockerfilesPath, + kanikoContext: dockerfilesPath, structureTestYamlPath: "/workspace/integration_tests/dockerfiles/test_metadata.yaml", }, { @@ -137,7 +154,7 @@ var structureTests = []struct { dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_user_run", repo: "test-user", dockerBuildContext: dockerfilesPath, - kbuildContext: dockerfilesPath, + kanikoContext: dockerfilesPath, structureTestYamlPath: "/workspace/integration_tests/dockerfiles/test_user.yaml", }, } @@ -178,7 +195,7 @@ func main() { } uploadTarBuildContext := step{ Name: "gcr.io/cloud-builders/gsutil", - Args: []string{"cp", "/workspace/context.tar.gz", "gs://kbuild-test-bucket/"}, + Args: []string{"cp", "/workspace/context.tar.gz", "gs://kaniko-test-bucket/"}, } // Build executor image @@ -186,8 +203,19 @@ func main() { Name: dockerImage, Args: []string{"build", "-t", executorImage, "-f", "deploy/Dockerfile", "."}, } + + // Build and push onbuild base images + buildOnbuildImage := step{ + Name: dockerImage, + Args: []string{"build", "-t", onbuildBaseImage, "-f", "/workspace/integration_tests/dockerfiles/Dockerfile_onbuild_base", "."}, + } + pushOnbuildBase := step{ + Name: dockerImage, + Args: []string{"push", onbuildBaseImage}, + } y := testyaml{ - Steps: []step{containerDiffStep, containerDiffPermissions, structureTestsStep, structureTestPermissions, GCSBucketTarBuildContext, uploadTarBuildContext, buildExecutorImage}, + Steps: []step{containerDiffStep, containerDiffPermissions, structureTestsStep, structureTestPermissions, GCSBucketTarBuildContext, uploadTarBuildContext, buildExecutorImage, + buildOnbuildImage, pushOnbuildBase}, } for _, test := range fileTests { // First, build the image with docker @@ -197,31 +225,31 @@ func main() { Args: []string{"build", "-t", dockerImageTag, "-f", test.dockerfilePath, test.dockerContext}, } - // Then, buld the image with kbuild - kbuildImage := testRepo + kbuildPrefix + test.repo + // Then, buld the image with kaniko + kanikoImage := testRepo + kanikoPrefix + test.repo snapshotMode := "" if test.snapshotMode != "" { snapshotMode = "--snapshotMode=" + test.snapshotMode } contextFlag := "--context" - if test.kbuildContextBucket { + if test.kanikoContextBucket { contextFlag = "--bucket" } - kbuild := step{ + kaniko := step{ Name: executorImage, - Args: []string{"--destination", kbuildImage, "--dockerfile", test.dockerfilePath, contextFlag, test.kbuildContext, snapshotMode}, + Args: []string{"--destination", kanikoImage, "--dockerfile", test.dockerfilePath, contextFlag, test.kanikoContext, snapshotMode}, } - // Pull the kbuild image - pullKbuildImage := step{ + // Pull the kaniko image + pullKanikoImage := step{ Name: dockerImage, - Args: []string{"pull", kbuildImage}, + Args: []string{"pull", kanikoImage}, } daemonDockerImage := daemonPrefix + dockerImageTag - daemonKbuildImage := daemonPrefix + kbuildImage + daemonKanikoImage := daemonPrefix + kanikoImage // Run container diff on the images - args := "container-diff-linux-amd64 diff " + daemonDockerImage + " " + daemonKbuildImage + " --type=file -j >" + containerDiffOutputFile + args := "container-diff-linux-amd64 diff " + daemonDockerImage + " " + daemonKanikoImage + " --type=file -j >" + containerDiffOutputFile containerDiff := step{ Name: ubuntuImage, Args: []string{"sh", "-c", args}, @@ -237,7 +265,7 @@ func main() { Args: []string{"cmp", test.configPath, containerDiffOutputFile}, } - y.Steps = append(y.Steps, dockerBuild, kbuild, pullKbuildImage, containerDiff, catContainerDiffOutput, compareOutputs) + y.Steps = append(y.Steps, dockerBuild, kaniko, pullKanikoImage, containerDiff, catContainerDiffOutput, compareOutputs) } for _, test := range structureTests { @@ -249,19 +277,19 @@ func main() { Args: []string{"build", "-t", dockerImageTag, "-f", test.dockerfilePath, test.dockerBuildContext}, } - // Build the image with kbuild - kbuildImage := testRepo + kbuildPrefix + test.repo - kbuild := step{ + // Build the image with kaniko + kanikoImage := testRepo + kanikoPrefix + test.repo + kaniko := step{ Name: executorImage, - Args: []string{"--destination", kbuildImage, "--dockerfile", test.dockerfilePath, "--context", test.kbuildContext}, + Args: []string{"--destination", kanikoImage, "--dockerfile", test.dockerfilePath, "--context", test.kanikoContext}, } - // Pull the kbuild image - pullKbuildImage := step{ + // Pull the kaniko image + pullKanikoImage := step{ Name: dockerImage, - Args: []string{"pull", kbuildImage}, + Args: []string{"pull", kanikoImage}, } - // Run structure tests on the kbuild and docker image - args := "container-structure-test -image " + kbuildImage + " " + test.structureTestYamlPath + // Run structure tests on the kaniko and docker image + args := "container-structure-test -image " + kanikoImage + " " + test.structureTestYamlPath structureTest := step{ Name: ubuntuImage, Args: []string{"sh", "-c", args}, @@ -274,7 +302,7 @@ func main() { Env: []string{"PATH=/workspace:/bin"}, } - y.Steps = append(y.Steps, dockerBuild, kbuild, pullKbuildImage, structureTest, dockerStructureTest) + y.Steps = append(y.Steps, dockerBuild, kaniko, pullKanikoImage, structureTest, dockerStructureTest) } d, _ := yaml.Marshal(&y) diff --git a/kbuild/cmd/root.go b/kaniko/cmd/root.go similarity index 86% rename from kbuild/cmd/root.go rename to kaniko/cmd/root.go index 0d7b9c05d..dc81e1a6c 100644 --- a/kbuild/cmd/root.go +++ b/kaniko/cmd/root.go @@ -21,9 +21,9 @@ import ( ) var RootCmd = &cobra.Command{ - Use: "kbuild", - Short: "kbuild is a CLI tool for building container images with full Dockerfile support without the need for Docker", - Long: `kbuild is a CLI tool for building container images with full Dockerfile support. It doesn't require Docker, + Use: "kaniko", + Short: "kaniko is a CLI tool for building container images with full Dockerfile support without the need for Docker", + Long: `kaniko is a CLI tool for building container images with full Dockerfile support. It doesn't require Docker, and builds the images in a Kubernetes cluster before pushing the final image to a registry.`, Run: func(cmd *cobra.Command, args []string) { }, diff --git a/kbuild/main.go b/kaniko/main.go similarity index 91% rename from kbuild/main.go rename to kaniko/main.go index 54046e53a..ba8a61643 100644 --- a/kbuild/main.go +++ b/kaniko/main.go @@ -18,7 +18,7 @@ package main import ( "fmt" - "github.com/GoogleCloudPlatform/k8s-container-builder/kbuild/cmd" + "github.com/GoogleCloudPlatform/k8s-container-builder/kaniko/cmd" "os" ) diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index fd040decc..f2dd30fb2 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -56,6 +56,10 @@ func GetCommand(cmd instructions.Command, buildcontext string) (DockerCommand, e return &LabelCommand{cmd: c}, nil case *instructions.UserCommand: return &UserCommand{cmd: c}, nil + case *instructions.OnbuildCommand: + return &OnBuildCommand{cmd: c}, nil + case *instructions.VolumeCommand: + return &VolumeCommand{cmd: c}, nil } return nil, errors.Errorf("%s is not a supported command", cmd.Name()) } diff --git a/pkg/commands/onbuild.go b/pkg/commands/onbuild.go new file mode 100644 index 000000000..db4711604 --- /dev/null +++ b/pkg/commands/onbuild.go @@ -0,0 +1,54 @@ +/* +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/GoogleCloudPlatform/k8s-container-builder/pkg/util" + "github.com/containers/image/manifest" + "github.com/docker/docker/builder/dockerfile/instructions" + "github.com/sirupsen/logrus" +) + +type OnBuildCommand struct { + cmd *instructions.OnbuildCommand +} + +//ExecuteCommand adds the specified expression in Onbuild to the config +func (o *OnBuildCommand) ExecuteCommand(config *manifest.Schema2Config) error { + logrus.Info("cmd: ONBUILD") + logrus.Infof("args: %s", o.cmd.Expression) + resolvedExpression, err := util.ResolveEnvironmentReplacement(o.cmd.Expression, config.Env, false) + if err != nil { + return err + } + if config.OnBuild == nil { + config.OnBuild = []string{resolvedExpression} + } else { + config.OnBuild = append(config.OnBuild, resolvedExpression) + } + return nil +} + +// FilesToSnapshot returns that no files have changed, this command only touches metadata. +func (o *OnBuildCommand) FilesToSnapshot() []string { + return []string{} +} + +// CreatedBy returns some information about the command for the image config history +func (o *OnBuildCommand) CreatedBy() string { + return o.cmd.Expression +} diff --git a/pkg/commands/onbuild_test.go b/pkg/commands/onbuild_test.go new file mode 100644 index 000000000..3004e99c9 --- /dev/null +++ b/pkg/commands/onbuild_test.go @@ -0,0 +1,69 @@ +/* +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/GoogleCloudPlatform/k8s-container-builder/testutil" + "github.com/containers/image/manifest" + "github.com/docker/docker/builder/dockerfile/instructions" + "testing" +) + +var onbuildTests = []struct { + expression string + onbuildArray []string + expectedArray []string +}{ + { + expression: "RUN echo \\\"hi\\\" > $dir", + onbuildArray: nil, + expectedArray: []string{ + "RUN echo \"hi\" > /some/dir", + }, + }, + { + expression: "COPY foo foo", + onbuildArray: []string{ + "RUN echo \"hi\" > /some/dir", + }, + expectedArray: []string{ + "RUN echo \"hi\" > /some/dir", + "COPY foo foo", + }, + }, +} + +func TestExecuteOnbuild(t *testing.T) { + for _, test := range onbuildTests { + cfg := &manifest.Schema2Config{ + Env: []string{ + "dir=/some/dir", + }, + OnBuild: test.onbuildArray, + } + + onbuildCmd := &OnBuildCommand{ + &instructions.OnbuildCommand{ + Expression: test.expression, + }, + } + + err := onbuildCmd.ExecuteCommand(cfg) + testutil.CheckErrorAndDeepEqual(t, false, err, test.expectedArray, cfg.OnBuild) + } + +} diff --git a/pkg/commands/volume.go b/pkg/commands/volume.go new file mode 100644 index 000000000..d5fd8ad05 --- /dev/null +++ b/pkg/commands/volume.go @@ -0,0 +1,71 @@ +/* +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/GoogleCloudPlatform/k8s-container-builder/pkg/util" + "github.com/containers/image/manifest" + "github.com/docker/docker/builder/dockerfile/instructions" + "github.com/sirupsen/logrus" + "os" + "strings" +) + +type VolumeCommand struct { + cmd *instructions.VolumeCommand + snapshotFiles []string +} + +func (v *VolumeCommand) ExecuteCommand(config *manifest.Schema2Config) error { + logrus.Info("cmd: VOLUME") + volumes := v.cmd.Volumes + resolvedVolumes, err := util.ResolveEnvironmentReplacementList(volumes, config.Env, true) + if err != nil { + return err + } + existingVolumes := config.Volumes + if existingVolumes == nil { + existingVolumes = map[string]struct{}{} + } + for _, volume := range resolvedVolumes { + var x struct{} + existingVolumes[volume] = x + err := util.AddPathToVolumeWhitelist(volume) + if err != nil { + return err + } + + logrus.Infof("Creating directory %s", volume) + if err := os.MkdirAll(volume, 0755); err != nil { + return err + } + + //Check if directory already exists? + v.snapshotFiles = append(v.snapshotFiles, volume) + } + config.Volumes = existingVolumes + + return nil +} + +func (v *VolumeCommand) FilesToSnapshot() []string { + return v.snapshotFiles +} + +func (v *VolumeCommand) CreatedBy() string { + return strings.Join(append([]string{v.cmd.Name()}, v.cmd.Volumes...), " ") +} diff --git a/pkg/commands/volume_test.go b/pkg/commands/volume_test.go new file mode 100644 index 000000000..69bd5b9c4 --- /dev/null +++ b/pkg/commands/volume_test.go @@ -0,0 +1,54 @@ +/* +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/GoogleCloudPlatform/k8s-container-builder/testutil" + "github.com/containers/image/manifest" + "github.com/docker/docker/builder/dockerfile/instructions" + "testing" +) + +func TestUpdateVolume(t *testing.T) { + cfg := &manifest.Schema2Config{ + Env: []string{ + "VOLUME=/etc", + }, + Volumes: map[string]struct{}{}, + } + + volumes := []string{ + "/tmp", + "/var/lib", + "$VOLUME", + } + + volumeCmd := &VolumeCommand{ + cmd: &instructions.VolumeCommand{ + Volumes: volumes, + }, + snapshotFiles: []string{}, + } + + expectedVolumes := map[string]struct{}{ + "/tmp": {}, + "/var/lib": {}, + "/etc": {}, + } + + err := volumeCmd.ExecuteCommand(cfg) + testutil.CheckErrorAndDeepEqual(t, false, err, expectedVolumes, cfg.Volumes) +} diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index f2f1709dd..2a3845c53 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -26,17 +26,21 @@ const ( // WorkspaceDir is the path to the workspace directory WorkspaceDir = "/workspace" - //KbuildDir is the path to the kbuild directory - KbuildDir = "/kbuild" + //KanikoDir is the path to the Kaniko directory + KanikoDir = "/kaniko" WhitelistPath = "/proc/self/mountinfo" - Author = "kbuild" + Author = "kaniko" // ContextTar is the default name of the tar uploaded to GCS buckets ContextTar = "context.tar.gz" // BuildContextDir is the directory a build context will be unpacked into, // for example, a tarball from a GCS bucket will be unpacked here - BuildContextDir = "/kbuild/buildcontext/" + BuildContextDir = "/kaniko/buildcontext/" + + // Various snapshot modes: + SnapshotModeTime = "time" + SnapshotModeFull = "full" ) diff --git a/pkg/dockerfile/dockerfile.go b/pkg/dockerfile/dockerfile.go index 948cffa50..f755a547e 100644 --- a/pkg/dockerfile/dockerfile.go +++ b/pkg/dockerfile/dockerfile.go @@ -18,6 +18,7 @@ package dockerfile import ( "bytes" + "strings" "github.com/docker/docker/builder/dockerfile/instructions" "github.com/docker/docker/builder/dockerfile/parser" @@ -35,3 +36,21 @@ func Parse(b []byte) ([]instructions.Stage, error) { } return stages, err } + +// ParseCommands parses an array of commands into an array of instructions.Command; used for onbuild +func ParseCommands(cmdArray []string) ([]instructions.Command, error) { + var cmds []instructions.Command + cmdString := strings.Join(cmdArray, "\n") + ast, err := parser.Parse(strings.NewReader(cmdString)) + if err != nil { + return nil, err + } + for _, child := range ast.AST.Children { + cmd, err := instructions.ParseCommand(child) + if err != nil { + return nil, err + } + cmds = append(cmds, cmd) + } + return cmds, nil +} diff --git a/pkg/snapshot/snapshot_test.go b/pkg/snapshot/snapshot_test.go index ef77e6f81..040669abe 100644 --- a/pkg/snapshot/snapshot_test.go +++ b/pkg/snapshot/snapshot_test.go @@ -39,7 +39,7 @@ func TestSnapshotFileChange(t *testing.T) { newFiles := map[string]string{ "foo": "newbaz1", "bar/bat": "baz", - "kbuild/bat": "bat", + "kaniko/bat": "bat", } if err := testutil.SetupFiles(testDir, newFiles); err != nil { t.Fatalf("Error setting up fs: %s", err) @@ -135,14 +135,14 @@ func TestSnapshotFiles(t *testing.T) { // Make some changes to the filesystem newFiles := map[string]string{ "foo": "newbaz1", - "kbuild/file": "bat", + "kaniko/file": "bat", } if err := testutil.SetupFiles(testDir, newFiles); err != nil { t.Fatalf("Error setting up fs: %s", err) } filesToSnapshot := []string{ filepath.Join(testDir, "foo"), - filepath.Join(testDir, "kbuild/file"), + filepath.Join(testDir, "kaniko/file"), } contents, err := snapshotter.TakeSnapshot(filesToSnapshot) if err != nil { @@ -199,7 +199,7 @@ func setUpTestDir() (string, *Snapshotter, error) { files := map[string]string{ "foo": "baz1", "bar/bat": "baz2", - "kbuild/file": "file", + "kaniko/file": "file", } // Set up initial files if err := testutil.SetupFiles(testDir, files); err != nil { diff --git a/pkg/util/bucket_util.go b/pkg/util/bucket_util.go index c96bb715c..043c2890f 100644 --- a/pkg/util/bucket_util.go +++ b/pkg/util/bucket_util.go @@ -25,7 +25,7 @@ import ( "path/filepath" ) -// UnpackTarFromGCSBucket unpacks the kbuild.tar file in the given bucket to the given directory +// UnpackTarFromGCSBucket unpacks the context.tar.gz file in the given bucket to the given directory func UnpackTarFromGCSBucket(bucketName, directory string) error { // Get the tar from the bucket tarPath, err := getTarFromBucket(bucketName, directory) @@ -41,7 +41,7 @@ func UnpackTarFromGCSBucket(bucketName, directory string) error { return os.Remove(tarPath) } -// getTarFromBucket gets kbuild.tar from the GCS bucket and saves it to the filesystem +// getTarFromBucket gets context.tar.gz from the GCS bucket and saves it to the filesystem // It returns the path to the tar file func getTarFromBucket(bucketName, directory string) (string, error) { ctx := context.Background() @@ -50,7 +50,7 @@ func getTarFromBucket(bucketName, directory string) (string, error) { return "", err } bucket := client.Bucket(bucketName) - // Get the tarfile kbuild.tar from the GCS bucket, and save it to a tar object + // Get the tarfile context.tar.gz from the GCS bucket, and save it to a tar object reader, err := bucket.Object(constants.ContextTar).NewReader(ctx) if err != nil { return "", err diff --git a/pkg/util/fs_util.go b/pkg/util/fs_util.go index b3b020c15..58815dbe2 100644 --- a/pkg/util/fs_util.go +++ b/pkg/util/fs_util.go @@ -30,7 +30,8 @@ import ( "time" ) -var whitelist = []string{"/kbuild"} +var whitelist = []string{"/kaniko"} +var volumeWhitelist = []string{} // ExtractFileSystemFromImage pulls an image and unpacks it to a file system at root func ExtractFileSystemFromImage(img string) error { @@ -156,6 +157,25 @@ func CreateFile(path string, reader io.Reader, perm os.FileMode) error { return dest.Chmod(perm) } +// AddPathToVolumeWhitelist adds the given path to the volume whitelist +// It will get snapshotted when the VOLUME command is run then ignored +// for subsequent commands. +func AddPathToVolumeWhitelist(path string) error { + logrus.Infof("adding %s to volume whitelist", path) + volumeWhitelist = append(volumeWhitelist, path) + return nil +} + +// MoveVolumeWhitelistToWhitelist copies over all directories that were volume mounted +// in this step to be whitelisted for all subsequent docker commands. +func MoveVolumeWhitelistToWhitelist() error { + if len(volumeWhitelist) > 0 { + whitelist = append(whitelist, volumeWhitelist...) + volumeWhitelist = []string{} + } + return nil +} + // DownloadFileToDest downloads the file at rawurl to the given dest for the ADD command // From add command docs: // 1. If is a remote file URL: diff --git a/pkg/util/fs_util_test.go b/pkg/util/fs_util_test.go index c8ebc88cf..19bef1d9b 100644 --- a/pkg/util/fs_util_test.go +++ b/pkg/util/fs_util_test.go @@ -46,7 +46,7 @@ func Test_fileSystemWhitelist(t *testing.T) { } actualWhitelist, err := fileSystemWhitelist(path) - expectedWhitelist := []string{"/kbuild", "/proc", "/dev", "/dev/pts", "/sys"} + expectedWhitelist := []string{"/kaniko", "/proc", "/dev", "/dev/pts", "/sys"} sort.Strings(actualWhitelist) sort.Strings(expectedWhitelist) testutil.CheckErrorAndDeepEqual(t, false, err, expectedWhitelist, actualWhitelist) @@ -61,7 +61,7 @@ var tests = []struct { files: map[string]string{ "/workspace/foo/a": "baz1", "/workspace/foo/b": "baz2", - "/kbuild/file": "file", + "/kaniko/file": "file", }, directory: "/workspace/foo/", expectedFiles: []string{ @@ -84,7 +84,7 @@ var tests = []struct { "/workspace/foo/a": "baz1", "/workspace/foo/b": "baz2", "/workspace/baz": "hey", - "/kbuild/file": "file", + "/kaniko/file": "file", }, directory: "/workspace", expectedFiles: []string{ @@ -99,16 +99,16 @@ var tests = []struct { files: map[string]string{ "/workspace/foo/a": "baz1", "/workspace/foo/b": "baz2", - "/kbuild/file": "file", + "/kaniko/file": "file", }, directory: "", expectedFiles: []string{ "workspace/foo/a", "workspace/foo/b", - "kbuild/file", + "kaniko/file", "workspace", "workspace/foo", - "kbuild", + "kaniko", ".", }, }, diff --git a/run_in_docker.sh b/run_in_docker.sh index 50a0ca33f..dd90ea947 100755 --- a/run_in_docker.sh +++ b/run_in_docker.sh @@ -15,13 +15,13 @@ #!/bin/bash set -e -if [ $# -ne 2 ]; - then echo "Usage: run_in_docker.sh " +if [ $# -ne 3 ]; + then echo "Usage: run_in_docker.sh " fi - -context=$1 -tag=$2 +dockerfile=$1 +context=$2 +tag=$3 if [[ ! -e $HOME/.config/gcloud/application_default_credentials.json ]]; then echo "Application Default Credentials do not exist. Run [gcloud auth application-default login] to configure them" @@ -31,5 +31,5 @@ fi docker run \ -v $HOME/.config/gcloud:/root/.config/gcloud \ -v ${context}:/workspace \ - gcr.io/kbuild-project/executor:latest \ - /kbuild/executor -d ${tag} + gcr.io/kaniko-project/executor:latest \ + -f ${dockerfile} -d ${tag} -c /workspace/