diff --git a/integration-test.sh b/integration-test.sh index 0463fb89c..3af24c922 100755 --- a/integration-test.sh +++ b/integration-test.sh @@ -37,4 +37,4 @@ fi echo "Running integration tests..." make out/executor make out/warmer -go test ./integration/... -v --bucket "${GCS_BUCKET}" --repo "${IMAGE_REPO}" --timeout 30m "$@" +go test ./integration/... -v --bucket "${GCS_BUCKET}" --repo "${IMAGE_REPO}" --timeout 50m "$@" diff --git a/integration/dockerfiles-with-context/issue-1020/Dockerfile b/integration/dockerfiles-with-context/issue-1020/Dockerfile new file mode 100644 index 000000000..d8d6e5c4f --- /dev/null +++ b/integration/dockerfiles-with-context/issue-1020/Dockerfile @@ -0,0 +1,23 @@ +# Copyright 2020 Google, Inc. All rights reserved. +# +# 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. + +FROM atomist/sdm-base:0.4.1 + +COPY package.json package-lock.json ./ +RUN npm ci \ + && npm cache clean --force + +COPY . ./ + +USER atomist:atomist diff --git a/integration/dockerfiles-with-context/issue-1020/package-lock.json b/integration/dockerfiles-with-context/issue-1020/package-lock.json new file mode 100644 index 000000000..2251887ee --- /dev/null +++ b/integration/dockerfiles-with-context/issue-1020/package-lock.json @@ -0,0 +1,7 @@ +{ + "name": "foo", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": {} +} diff --git a/integration/dockerfiles-with-context/issue-1020/package.json b/integration/dockerfiles-with-context/issue-1020/package.json new file mode 100644 index 000000000..f1c4fb61e --- /dev/null +++ b/integration/dockerfiles-with-context/issue-1020/package.json @@ -0,0 +1,11 @@ +{ + "name": "foo", + "version": "2.0.0", + "description": "Don't forget to sanitize your inputs", + "author": "Little Bobby Tables", + "private": false, + "devDependencies": {}, + "scripts": {}, + "license": "MIT", + "dependencies": {} +} diff --git a/integration/dockerfiles-with-context/issue-721/Dockerfile b/integration/dockerfiles-with-context/issue-721/Dockerfile new file mode 100644 index 000000000..b8462585f --- /dev/null +++ b/integration/dockerfiles-with-context/issue-721/Dockerfile @@ -0,0 +1,17 @@ +# Copyright 2020 Google, Inc. All rights reserved. +# +# 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. + +FROM alpine + +ADD test.txt /tmp/ diff --git a/integration/dockerfiles-with-context/issue-721/test.txt b/integration/dockerfiles-with-context/issue-721/test.txt new file mode 100644 index 000000000..375d5c3ce --- /dev/null +++ b/integration/dockerfiles-with-context/issue-721/test.txt @@ -0,0 +1 @@ +meow diff --git a/integration/dockerfiles-with-context/issue-774/Dockerfile b/integration/dockerfiles-with-context/issue-774/Dockerfile new file mode 100644 index 000000000..25f1462c2 --- /dev/null +++ b/integration/dockerfiles-with-context/issue-774/Dockerfile @@ -0,0 +1,16 @@ +# Copyright 2020 Google, Inc. All rights reserved. +# +# 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. + +FROM phusion/baseimage:0.11 +ADD test-file /etc/service/file diff --git a/integration/dockerfiles-with-context/issue-774/test-file b/integration/dockerfiles-with-context/issue-774/test-file new file mode 100644 index 000000000..e69de29bb diff --git a/integration/images.go b/integration/images.go index 50fea929a..ad711f8fd 100644 --- a/integration/images.go +++ b/integration/images.go @@ -189,12 +189,17 @@ func addServiceAccountFlags(flags []string, serviceAccount string) []string { // The resulting image will be tagged with imageRepo. If the dockerfile will be built with // context (i.e. it is in `buildContextTests`) the context will be pulled from gcsBucket. func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfilesPath, dockerfile string) error { + _, ex, _, _ := runtime.Caller(0) + cwd := filepath.Dir(ex) + + return d.BuildImageWithContext(config, dockerfilesPath, dockerfile, cwd) +} + +func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig, dockerfilesPath, dockerfile, contextDir string) error { if _, present := d.filesBuilt[dockerfile]; present { return nil } gcsBucket, serviceAccount, imageRepo := config.gcsBucket, config.serviceAccount, config.imageRepo - _, ex, _, _ := runtime.Caller(0) - cwd := filepath.Dir(ex) fmt.Printf("Building images for Dockerfile %s\n", dockerfile) @@ -203,16 +208,24 @@ func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfile for _, arg := range argsMap[dockerfile] { buildArgs = append(buildArgs, buildArgFlag, arg) } + // build docker image additionalFlags := append(buildArgs, additionalDockerFlagsMap[dockerfile]...) dockerImage := strings.ToLower(imageRepo + dockerPrefix + dockerfile) - dockerCmd := exec.Command("docker", - append([]string{"build", - "-t", dockerImage, - "-f", path.Join(dockerfilesPath, dockerfile), - "."}, - additionalFlags...)..., - ) + + dockerArgs := []string{ + "build", + "-t", dockerImage, + } + + if dockerfilesPath != "" { + dockerArgs = append(dockerArgs, "-f", path.Join(dockerfilesPath, dockerfile)) + } + + dockerArgs = append(dockerArgs, contextDir) + dockerArgs = append(dockerArgs, additionalFlags...) + + dockerCmd := exec.Command("docker", dockerArgs...) if env, ok := envsMap[dockerfile]; ok { dockerCmd.Env = append(dockerCmd.Env, env...) } @@ -259,20 +272,28 @@ func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfile additionalFlags = append(buildArgs, additionalKanikoFlagsMap[dockerfile]...) kanikoImage := GetKanikoImage(imageRepo, dockerfile) fmt.Printf("Going to build image with kaniko: %s, flags: %s \n", kanikoImage, additionalFlags) + dockerRunFlags := []string{"run", "--net=host", "-e", benchmarkEnv, - "-v", cwd + ":/workspace", + "-v", contextDir + ":/workspace", "-v", benchmarkDir + ":/kaniko/benchmarks", } + if env, ok := envsMap[dockerfile]; ok { for _, envVariable := range env { dockerRunFlags = append(dockerRunFlags, "-e", envVariable) } } + dockerRunFlags = addServiceAccountFlags(dockerRunFlags, serviceAccount) + kanikoDockerfilePath := path.Join(buildContextPath, dockerfilesPath, dockerfile) + if dockerfilesPath == "" { + kanikoDockerfilePath = path.Join(buildContextPath, "Dockerfile") + } + dockerRunFlags = append(dockerRunFlags, ExecutorImage, - "-f", path.Join(buildContextPath, dockerfilesPath, dockerfile), + "-f", kanikoDockerfilePath, "-d", kanikoImage, reproducibleFlag, contextFlag, contextPath) dockerRunFlags = append(dockerRunFlags, additionalFlags...) @@ -282,9 +303,11 @@ func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfile timer = timing.Start(dockerfile + "_kaniko") out, err = RunCommandWithoutTest(kanikoCmd) timing.DefaultRun.Stop(timer) + 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)) @@ -292,6 +315,7 @@ func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfile } d.filesBuilt[dockerfile] = struct{}{} + return nil } diff --git a/integration/integration_with_context_test.go b/integration/integration_with_context_test.go new file mode 100644 index 000000000..7f27fd17c --- /dev/null +++ b/integration/integration_with_context_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 integration + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestWithContext(t *testing.T) { + cwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + + dir := filepath.Join(cwd, "dockerfiles-with-context") + + testDirs, err := ioutil.ReadDir(dir) + if err != nil { + t.Fatal(err) + } + + builder := NewDockerFileBuilder() + + for _, tdInfo := range testDirs { + name := tdInfo.Name() + testDir := filepath.Join(dir, name) + + t.Run("test_with_context_"+name, func(t *testing.T) { + t.Parallel() + + if err := builder.BuildImageWithContext( + config, "", name, testDir, + ); err != nil { + t.Fatal(err) + } + + dockerImage := GetDockerImage(config.imageRepo, name) + kanikoImage := GetKanikoImage(config.imageRepo, name) + + diff := containerDiff(t, daemonPrefix+dockerImage, kanikoImage, "--no-cache") + + expected := fmt.Sprintf(emptyContainerDiff, dockerImage, kanikoImage, dockerImage, kanikoImage) + checkContainerDiffOutput(t, diff, expected) + + }) + } + + if err := logBenchmarks("benchmark"); err != nil { + t.Logf("Failed to create benchmark file: %v", err) + } +}