adding metadata tests back to integration tests (#185)
* adding metadata tests back to integration tests and fixing resulting bugs * fix onbuild and default env * removing old test files * adding the ArgsEscaped boolean on CMD commands * fix onbuild test * ignore failing test until container-diff is fixed * code comments * adding todo to remove uncomment failing test
This commit is contained in:
parent
0881b7c320
commit
5e6b60f46e
|
|
@ -0,0 +1,8 @@
|
||||||
|
FROM gcr.io/google-appengine/debian9
|
||||||
|
EXPOSE 80
|
||||||
|
EXPOSE 81/udp
|
||||||
|
ENV protocol tcp
|
||||||
|
EXPOSE 82/$protocol
|
||||||
|
ENV port 83
|
||||||
|
EXPOSE $port/udp
|
||||||
|
EXPOSE $port/$protocol
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
FROM gcr.io/google-appengine/debian9
|
||||||
|
LABEL foo=bar
|
||||||
|
LABEL "baz"="bat"
|
||||||
|
ENV label1 "mylabel"
|
||||||
|
LABEL label1=$label1
|
||||||
|
LABEL multilabel1=multilabel1 multilabel2=multilabel2 multilabel3=multilabel3
|
||||||
|
|
||||||
|
|
@ -17,3 +17,5 @@ RUN useradd testuser
|
||||||
RUN groupadd testgroup
|
RUN groupadd testgroup
|
||||||
USER testuser:testgroup
|
USER testuser:testgroup
|
||||||
RUN echo "hey" > /tmp/foo
|
RUN echo "hey" > /tmp/foo
|
||||||
|
USER testuser:1001
|
||||||
|
RUN echo "hey2" >> /tmp/foo
|
||||||
|
|
@ -44,14 +44,23 @@ const (
|
||||||
buildContextPath = "/workspace"
|
buildContextPath = "/workspace"
|
||||||
emptyContainerDiff = `[
|
emptyContainerDiff = `[
|
||||||
{
|
{
|
||||||
"Image1": "%s:latest",
|
"Image1": "%s",
|
||||||
"Image2": "%s:latest",
|
"Image2": "%s",
|
||||||
"DiffType": "File",
|
"DiffType": "File",
|
||||||
"Diff": {
|
"Diff": {
|
||||||
"Adds": null,
|
"Adds": null,
|
||||||
"Dels": null,
|
"Dels": null,
|
||||||
"Mods": null
|
"Mods": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Image1": "%s",
|
||||||
|
"Image2": "%s",
|
||||||
|
"DiffType": "Metadata",
|
||||||
|
"Diff": {
|
||||||
|
"Adds": [],
|
||||||
|
"Dels": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]`
|
]`
|
||||||
)
|
)
|
||||||
|
|
@ -76,7 +85,7 @@ func TestMain(m *testing.M) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRun(t *testing.T) {
|
func TestRun(t *testing.T) {
|
||||||
dockerfiles, err := filepath.Glob(path.Join(dockerfilesPath, "Dockerfile*"))
|
dockerfiles, err := filepath.Glob(path.Join(dockerfilesPath, "Dockerfile_test*"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
|
@ -93,16 +102,25 @@ func TestRun(t *testing.T) {
|
||||||
"file=context/foo",
|
"file=context/foo",
|
||||||
"file3=context/b*",
|
"file3=context/b*",
|
||||||
},
|
},
|
||||||
|
"Dockerfile_test_multistage": {"file=/foo2"},
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketContextTests := []string{"Dockerfile_test_copy_bucket"}
|
bucketContextTests := []string{"Dockerfile_test_copy_bucket"}
|
||||||
|
|
||||||
|
// TODO: remove test_user_run from this when https://github.com/GoogleContainerTools/container-diff/issues/237 is fixed
|
||||||
|
testsToIgnore := []string{"Dockerfile_test_user_run"}
|
||||||
|
|
||||||
_, ex, _, _ := runtime.Caller(0)
|
_, ex, _, _ := runtime.Caller(0)
|
||||||
cwd := filepath.Dir(ex)
|
cwd := filepath.Dir(ex)
|
||||||
|
|
||||||
for _, dockerfile := range dockerfiles {
|
for _, dockerfile := range dockerfiles {
|
||||||
t.Run("test_"+dockerfile, func(t *testing.T) {
|
t.Run("test_"+dockerfile, func(t *testing.T) {
|
||||||
dockerfile = dockerfile[len("dockerfile/")+1:]
|
dockerfile = dockerfile[len("dockerfile/")+1:]
|
||||||
|
for _, d := range testsToIgnore {
|
||||||
|
if dockerfile == d {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
t.Logf("%s\n", dockerfile)
|
t.Logf("%s\n", dockerfile)
|
||||||
|
|
||||||
var buildArgs []string
|
var buildArgs []string
|
||||||
|
|
@ -151,11 +169,11 @@ func TestRun(t *testing.T) {
|
||||||
daemonDockerImage := daemonPrefix + dockerImage
|
daemonDockerImage := daemonPrefix + dockerImage
|
||||||
containerdiffCmd := exec.Command("container-diff", "diff",
|
containerdiffCmd := exec.Command("container-diff", "diff",
|
||||||
daemonDockerImage, kanikoImage,
|
daemonDockerImage, kanikoImage,
|
||||||
"-q", "--type=file", "--json")
|
"-q", "--type=file", "--type=metadata", "--json")
|
||||||
diff := RunCommand(containerdiffCmd, t)
|
diff := RunCommand(containerdiffCmd, t)
|
||||||
t.Logf("diff = %s", string(diff))
|
t.Logf("diff = %s", string(diff))
|
||||||
|
|
||||||
expected := fmt.Sprintf(emptyContainerDiff, dockerImage, kanikoImage)
|
expected := fmt.Sprintf(emptyContainerDiff, dockerImage, kanikoImage, dockerImage, kanikoImage)
|
||||||
|
|
||||||
// Let's compare the json objects themselves instead of strings to avoid
|
// Let's compare the json objects themselves instead of strings to avoid
|
||||||
// issues with spaces and indents
|
// issues with spaces and indents
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"Image1": "gcr.io/kaniko-test/docker-test-multistage:latest",
|
|
||||||
"Image2": "gcr.io/kaniko-test/kaniko-test-multistage:latest",
|
|
||||||
"DiffType": "File",
|
|
||||||
"Diff": {
|
|
||||||
"Adds": null,
|
|
||||||
"Dels": null,
|
|
||||||
"Mods": null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
@ -1,357 +0,0 @@
|
||||||
/*
|
|
||||||
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 main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
executorImage = "executor-image"
|
|
||||||
dockerImage = "gcr.io/cloud-builders/docker"
|
|
||||||
ubuntuImage = "ubuntu"
|
|
||||||
structureTestImage = "gcr.io/gcp-runtimes/container-structure-test"
|
|
||||||
testRepo = "gcr.io/kaniko-test/"
|
|
||||||
dockerPrefix = "docker-"
|
|
||||||
kanikoPrefix = "kaniko-"
|
|
||||||
daemonPrefix = "daemon://"
|
|
||||||
containerDiffOutputFile = "container-diff.json"
|
|
||||||
kanikoTestBucket = "kaniko-test-bucket"
|
|
||||||
buildcontextPath = "/workspace/integration_tests"
|
|
||||||
dockerfilesPath = "/workspace/integration_tests/dockerfiles"
|
|
||||||
onbuildBaseImage = testRepo + "onbuild-base:latest"
|
|
||||||
)
|
|
||||||
|
|
||||||
var fileTests = []struct {
|
|
||||||
description string
|
|
||||||
dockerfilePath string
|
|
||||||
configPath string
|
|
||||||
dockerContext string
|
|
||||||
kanikoContext string
|
|
||||||
kanikoContextBucket bool
|
|
||||||
repo string
|
|
||||||
snapshotMode string
|
|
||||||
args []string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
description: "test extract filesystem",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_extract_fs",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_extract_fs.json",
|
|
||||||
dockerContext: dockerfilesPath,
|
|
||||||
kanikoContext: dockerfilesPath,
|
|
||||||
repo: "extract-filesystem",
|
|
||||||
snapshotMode: "time",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test run",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_run",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_run.json",
|
|
||||||
dockerContext: dockerfilesPath,
|
|
||||||
kanikoContext: dockerfilesPath,
|
|
||||||
repo: "test-run",
|
|
||||||
args: []string{
|
|
||||||
"file=/file",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test run no files changed",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_run_2",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_run_2.json",
|
|
||||||
dockerContext: dockerfilesPath,
|
|
||||||
kanikoContext: dockerfilesPath,
|
|
||||||
repo: "test-run-2",
|
|
||||||
snapshotMode: "time",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test copy",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_copy",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_copy.json",
|
|
||||||
dockerContext: buildcontextPath,
|
|
||||||
kanikoContext: buildcontextPath,
|
|
||||||
repo: "test-copy",
|
|
||||||
snapshotMode: "time",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test bucket build context",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_copy",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_bucket_buildcontext.json",
|
|
||||||
dockerContext: buildcontextPath,
|
|
||||||
kanikoContext: kanikoTestBucket,
|
|
||||||
kanikoContextBucket: true,
|
|
||||||
repo: "test-bucket-buildcontext",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test workdir",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_workdir",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_workdir.json",
|
|
||||||
dockerContext: buildcontextPath,
|
|
||||||
kanikoContext: buildcontextPath,
|
|
||||||
repo: "test-workdir",
|
|
||||||
args: []string{
|
|
||||||
"workdir=/arg/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,
|
|
||||||
kanikoContext: buildcontextPath,
|
|
||||||
repo: "test-add",
|
|
||||||
args: []string{
|
|
||||||
"file=context/foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test mv add",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_mv_add",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_mv_add.json",
|
|
||||||
dockerContext: buildcontextPath,
|
|
||||||
kanikoContext: buildcontextPath,
|
|
||||||
repo: "test-mv-add",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test registry",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_registry",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_registry.json",
|
|
||||||
dockerContext: buildcontextPath,
|
|
||||||
kanikoContext: buildcontextPath,
|
|
||||||
repo: "test-registry",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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",
|
|
||||||
args: []string{
|
|
||||||
"file=/tmp/onbuild",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test scratch",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_scratch",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_scratch.json",
|
|
||||||
dockerContext: buildcontextPath,
|
|
||||||
kanikoContext: buildcontextPath,
|
|
||||||
repo: "test-scratch",
|
|
||||||
args: []string{
|
|
||||||
"hello=hello-value",
|
|
||||||
"file=context/foo",
|
|
||||||
"file3=context/b*",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test multistage",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_multistage",
|
|
||||||
configPath: "/workspace/integration_tests/dockerfiles/config_test_multistage.json",
|
|
||||||
dockerContext: buildcontextPath,
|
|
||||||
kanikoContext: buildcontextPath,
|
|
||||||
repo: "test-multistage",
|
|
||||||
args: []string{
|
|
||||||
"file=/foo2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var structureTests = []struct {
|
|
||||||
description string
|
|
||||||
dockerfilePath string
|
|
||||||
structureTestYamlPath string
|
|
||||||
dockerBuildContext string
|
|
||||||
kanikoContext string
|
|
||||||
repo string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
description: "test env",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_env",
|
|
||||||
repo: "test-env",
|
|
||||||
dockerBuildContext: dockerfilesPath,
|
|
||||||
kanikoContext: dockerfilesPath,
|
|
||||||
structureTestYamlPath: "/workspace/integration_tests/dockerfiles/test_env.yaml",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test metadata",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_metadata",
|
|
||||||
repo: "test-metadata",
|
|
||||||
dockerBuildContext: dockerfilesPath,
|
|
||||||
kanikoContext: dockerfilesPath,
|
|
||||||
structureTestYamlPath: "/workspace/integration_tests/dockerfiles/test_metadata.yaml",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: "test user command",
|
|
||||||
dockerfilePath: "/workspace/integration_tests/dockerfiles/Dockerfile_test_user_run",
|
|
||||||
repo: "test-user",
|
|
||||||
dockerBuildContext: dockerfilesPath,
|
|
||||||
kanikoContext: dockerfilesPath,
|
|
||||||
structureTestYamlPath: "/workspace/integration_tests/dockerfiles/test_user.yaml",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
type step struct {
|
|
||||||
Name string
|
|
||||||
Args []string
|
|
||||||
Env []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type testyaml struct {
|
|
||||||
Steps []step
|
|
||||||
Timeout string
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
// First, copy container-diff in
|
|
||||||
containerDiffStep := step{
|
|
||||||
Name: "gcr.io/cloud-builders/gsutil",
|
|
||||||
Args: []string{"cp", "gs://container-diff/latest/container-diff-linux-amd64", "."},
|
|
||||||
}
|
|
||||||
containerDiffPermissions := step{
|
|
||||||
Name: ubuntuImage,
|
|
||||||
Args: []string{"chmod", "+x", "container-diff-linux-amd64"},
|
|
||||||
}
|
|
||||||
GCSBucketTarBuildContext := step{
|
|
||||||
Name: ubuntuImage,
|
|
||||||
Args: []string{"tar", "-C", "/workspace/integration_tests/", "-zcvf", "/workspace/context.tar.gz", "."},
|
|
||||||
}
|
|
||||||
uploadTarBuildContext := step{
|
|
||||||
Name: "gcr.io/cloud-builders/gsutil",
|
|
||||||
Args: []string{"cp", "/workspace/context.tar.gz", "gs://kaniko-test-bucket/"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build executor image
|
|
||||||
buildExecutorImage := step{
|
|
||||||
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, 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: append([]string{"build", "-t", dockerImageTag, "-f", test.dockerfilePath, test.dockerContext}, buildArgs...),
|
|
||||||
}
|
|
||||||
// Then, buld the image with kaniko
|
|
||||||
kanikoImage := testRepo + kanikoPrefix + test.repo
|
|
||||||
snapshotMode := ""
|
|
||||||
if test.snapshotMode != "" {
|
|
||||||
snapshotMode = "--snapshotMode=" + test.snapshotMode
|
|
||||||
}
|
|
||||||
contextFlag := "--context"
|
|
||||||
if test.kanikoContextBucket {
|
|
||||||
contextFlag = "--bucket"
|
|
||||||
}
|
|
||||||
kaniko := step{
|
|
||||||
Name: executorImage,
|
|
||||||
Args: append([]string{"--destination", kanikoImage, "--dockerfile", test.dockerfilePath, contextFlag, test.kanikoContext, snapshotMode}, buildArgs...),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pull the kaniko image
|
|
||||||
pullKanikoImage := step{
|
|
||||||
Name: dockerImage,
|
|
||||||
Args: []string{"pull", kanikoImage},
|
|
||||||
}
|
|
||||||
|
|
||||||
daemonDockerImage := daemonPrefix + dockerImageTag
|
|
||||||
daemonKanikoImage := daemonPrefix + kanikoImage
|
|
||||||
// Run container diff on the images
|
|
||||||
args := "container-diff-linux-amd64 diff " + daemonDockerImage + " " + daemonKanikoImage + " --type=file -j >" + containerDiffOutputFile
|
|
||||||
containerDiff := step{
|
|
||||||
Name: ubuntuImage,
|
|
||||||
Args: []string{"sh", "-c", args},
|
|
||||||
Env: []string{"PATH=/workspace:/bin"},
|
|
||||||
}
|
|
||||||
|
|
||||||
catContainerDiffOutput := step{
|
|
||||||
Name: ubuntuImage,
|
|
||||||
Args: []string{"cat", containerDiffOutputFile},
|
|
||||||
}
|
|
||||||
compareOutputs := step{
|
|
||||||
Name: ubuntuImage,
|
|
||||||
Args: []string{"cmp", "-b", test.configPath, containerDiffOutputFile},
|
|
||||||
}
|
|
||||||
|
|
||||||
y.Steps = append(y.Steps, dockerBuild, kaniko, pullKanikoImage, containerDiff, catContainerDiffOutput, compareOutputs)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range structureTests {
|
|
||||||
|
|
||||||
// First, build the image with docker
|
|
||||||
dockerImageTag := testRepo + dockerPrefix + test.repo
|
|
||||||
dockerBuild := step{
|
|
||||||
Name: dockerImage,
|
|
||||||
Args: []string{"build", "-t", dockerImageTag, "-f", test.dockerfilePath, test.dockerBuildContext},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the image with kaniko
|
|
||||||
kanikoImage := testRepo + kanikoPrefix + test.repo
|
|
||||||
kaniko := step{
|
|
||||||
Name: executorImage,
|
|
||||||
Args: []string{"--destination", kanikoImage, "--dockerfile", test.dockerfilePath, "--context", test.kanikoContext},
|
|
||||||
}
|
|
||||||
// Pull the kaniko image
|
|
||||||
pullKanikoImage := step{
|
|
||||||
Name: dockerImage,
|
|
||||||
Args: []string{"pull", kanikoImage},
|
|
||||||
}
|
|
||||||
// Run structure tests on the kaniko and docker image
|
|
||||||
kanikoStructureTest := step{
|
|
||||||
Name: structureTestImage,
|
|
||||||
Args: []string{"test", "--image", kanikoImage, "--config", test.structureTestYamlPath},
|
|
||||||
}
|
|
||||||
dockerStructureTest := step{
|
|
||||||
Name: structureTestImage,
|
|
||||||
Args: []string{"test", "--image", dockerImageTag, "--config", test.structureTestYamlPath},
|
|
||||||
}
|
|
||||||
y.Steps = append(y.Steps, dockerBuild, kaniko, pullKanikoImage, kanikoStructureTest, dockerStructureTest)
|
|
||||||
}
|
|
||||||
|
|
||||||
d, _ := yaml.Marshal(&y)
|
|
||||||
fmt.Println(string(d))
|
|
||||||
}
|
|
||||||
|
|
@ -50,6 +50,7 @@ func (c *CmdCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui
|
||||||
|
|
||||||
logrus.Infof("Replacing CMD in config with %v", newCommand)
|
logrus.Infof("Replacing CMD in config with %v", newCommand)
|
||||||
config.Cmd = newCommand
|
config.Cmd = newCommand
|
||||||
|
config.ArgsEscaped = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
|
||||||
"github.com/docker/docker/builder/dockerfile/instructions"
|
"github.com/docker/docker/builder/dockerfile/instructions"
|
||||||
"github.com/google/go-containerregistry/v1"
|
"github.com/google/go-containerregistry/v1"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
@ -32,15 +31,10 @@ type OnBuildCommand struct {
|
||||||
func (o *OnBuildCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
|
func (o *OnBuildCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
|
||||||
logrus.Info("cmd: ONBUILD")
|
logrus.Info("cmd: ONBUILD")
|
||||||
logrus.Infof("args: %s", o.cmd.Expression)
|
logrus.Infof("args: %s", o.cmd.Expression)
|
||||||
replacementEnvs := buildArgs.ReplacementEnvs(config.Env)
|
|
||||||
resolvedExpression, err := util.ResolveEnvironmentReplacement(o.cmd.Expression, replacementEnvs, false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if config.OnBuild == nil {
|
if config.OnBuild == nil {
|
||||||
config.OnBuild = []string{resolvedExpression}
|
config.OnBuild = []string{o.cmd.Expression}
|
||||||
} else {
|
} else {
|
||||||
config.OnBuild = append(config.OnBuild, resolvedExpression)
|
config.OnBuild = append(config.OnBuild, o.cmd.Expression)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ var onbuildTests = []struct {
|
||||||
expression: "RUN echo \\\"hi\\\" > $dir",
|
expression: "RUN echo \\\"hi\\\" > $dir",
|
||||||
onbuildArray: nil,
|
onbuildArray: nil,
|
||||||
expectedArray: []string{
|
expectedArray: []string{
|
||||||
"RUN echo \"hi\" > /some/dir",
|
"RUN echo \\\"hi\\\" > $dir",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
||||||
|
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||||
"github.com/docker/docker/builder/dockerfile/instructions"
|
"github.com/docker/docker/builder/dockerfile/instructions"
|
||||||
"github.com/google/go-containerregistry/v1"
|
"github.com/google/go-containerregistry/v1"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
@ -61,15 +62,26 @@ func (r *RunCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui
|
||||||
// If specified, run the command as a specific user
|
// If specified, run the command as a specific user
|
||||||
if config.User != "" {
|
if config.User != "" {
|
||||||
userAndGroup := strings.Split(config.User, ":")
|
userAndGroup := strings.Split(config.User, ":")
|
||||||
|
userStr := userAndGroup[0]
|
||||||
|
var groupStr string
|
||||||
|
if len(userAndGroup) > 1 {
|
||||||
|
groupStr = userAndGroup[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
uidStr, gidStr, err := util.GetUserFromUsername(userStr, groupStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// uid and gid need to be uint32
|
// uid and gid need to be uint32
|
||||||
uid64, err := strconv.ParseUint(userAndGroup[0], 10, 32)
|
uid64, err := strconv.ParseUint(uidStr, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
uid := uint32(uid64)
|
uid := uint32(uid64)
|
||||||
var gid uint32
|
var gid uint32
|
||||||
if len(userAndGroup) > 1 {
|
if gidStr != "" {
|
||||||
gid64, err := strconv.ParseUint(userAndGroup[1], 10, 32)
|
gid64, err := strconv.ParseUint(gidStr, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"github.com/docker/docker/builder/dockerfile/instructions"
|
"github.com/docker/docker/builder/dockerfile/instructions"
|
||||||
"github.com/google/go-containerregistry/v1"
|
"github.com/google/go-containerregistry/v1"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"os/user"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -47,43 +46,15 @@ func (r *UserCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup by username
|
_, _, err = util.GetUserFromUsername(userStr, groupStr)
|
||||||
userObj, err := user.Lookup(userStr)
|
|
||||||
if err != nil {
|
|
||||||
if _, ok := err.(user.UnknownUserError); ok {
|
|
||||||
// Lookup by id
|
|
||||||
userObj, err = user.LookupId(userStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same dance with groups
|
|
||||||
var group *user.Group
|
|
||||||
if groupStr != "" {
|
if groupStr != "" {
|
||||||
group, err = user.LookupGroup(groupStr)
|
userStr = userStr + ":" + groupStr
|
||||||
if err != nil {
|
|
||||||
if _, ok := err.(user.UnknownGroupError); ok {
|
|
||||||
group, err = user.LookupGroupId(groupStr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
} else {
|
config.User = userStr
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uid := userObj.Uid
|
|
||||||
if group != nil {
|
|
||||||
uid = uid + ":" + group.Gid
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.Infof("Setting user to %s", uid)
|
|
||||||
config.User = uid
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ var userTests = []struct {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
user: "root",
|
user: "root",
|
||||||
expectedUid: "0",
|
expectedUid: "root",
|
||||||
shouldError: false,
|
shouldError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -46,17 +46,17 @@ var userTests = []struct {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
user: "root:root",
|
user: "root:root",
|
||||||
expectedUid: "0:0",
|
expectedUid: "root:root",
|
||||||
shouldError: false,
|
shouldError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
user: "0:root",
|
user: "0:root",
|
||||||
expectedUid: "0:0",
|
expectedUid: "0:root",
|
||||||
shouldError: false,
|
shouldError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
user: "root:0",
|
user: "root:0",
|
||||||
expectedUid: "0:0",
|
expectedUid: "root:0",
|
||||||
shouldError: false,
|
shouldError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -71,12 +71,12 @@ var userTests = []struct {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
user: "$envuser",
|
user: "$envuser",
|
||||||
expectedUid: "0",
|
expectedUid: "root",
|
||||||
shouldError: false,
|
shouldError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
user: "root:$envgroup",
|
user: "root:$envgroup",
|
||||||
expectedUid: "0:0",
|
expectedUid: "root:root",
|
||||||
shouldError: false,
|
shouldError: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,3 +50,6 @@ const (
|
||||||
|
|
||||||
// KanikoBuildFiles is the list of files required to build kaniko
|
// KanikoBuildFiles is the list of files required to build kaniko
|
||||||
var KanikoBuildFiles = []string{"/kaniko/executor", "/kaniko/ssl/certs/ca-certificates.crt"}
|
var KanikoBuildFiles = []string{"/kaniko/executor", "/kaniko/ssl/certs/ca-certificates.crt"}
|
||||||
|
|
||||||
|
// ScratchEnvVars are the default environment variables needed for a scratch image.
|
||||||
|
var ScratchEnvVars = []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,9 @@ func DoBuild(dockerfilePath, srcContext, snapshotMode string, args []string) (na
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
imageConfig, err := sourceImage.ConfigFile()
|
imageConfig, err := sourceImage.ConfigFile()
|
||||||
|
if baseImage == constants.NoBaseImage {
|
||||||
|
imageConfig.Config.Env = constants.ScratchEnvVars
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -260,5 +263,8 @@ func resolveOnBuild(stage *instructions.Stage, config *v1.Config) error {
|
||||||
// Append to the beginning of the commands in the stage
|
// Append to the beginning of the commands in the stage
|
||||||
stage.Commands = append(cmds, stage.Commands...)
|
stage.Commands = append(cmds, stage.Commands...)
|
||||||
logrus.Infof("Executing %v build triggers", len(cmds))
|
logrus.Infof("Executing %v build triggers", len(cmds))
|
||||||
|
|
||||||
|
// Blank out the Onbuild command list for this image
|
||||||
|
config.OnBuild = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -273,3 +274,43 @@ Loop:
|
||||||
config.Env = envArray
|
config.Env = envArray
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetUserFromUsername(userStr string, groupStr string) (string, string, error) {
|
||||||
|
// Lookup by username
|
||||||
|
userObj, err := user.Lookup(userStr)
|
||||||
|
if err != nil {
|
||||||
|
if _, ok := err.(user.UnknownUserError); ok {
|
||||||
|
// Lookup by id
|
||||||
|
userObj, err = user.LookupId(userStr)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same dance with groups
|
||||||
|
var group *user.Group
|
||||||
|
if groupStr != "" {
|
||||||
|
group, err = user.LookupGroup(groupStr)
|
||||||
|
if err != nil {
|
||||||
|
if _, ok := err.(user.UnknownGroupError); ok {
|
||||||
|
group, err = user.LookupGroupId(groupStr)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uid := userObj.Uid
|
||||||
|
gid := ""
|
||||||
|
if group != nil {
|
||||||
|
gid = group.Gid
|
||||||
|
}
|
||||||
|
|
||||||
|
return uid, gid, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue