From 57ea150cade8689a311a1db4bba23ee705b06728 Mon Sep 17 00:00:00 2001 From: Benjamin Krenn Date: Tue, 1 Jun 2021 19:43:49 +0200 Subject: [PATCH] Exit Code Propagation (#1655) * exit codes of failed RUN commands may now be propagated to the caller by using the --propagate-exit-code flag * removed exit code propagation flag; the exit function now unwraps the error and looks for an exit code * added integration test for exit code propagation * added trailing new line in test Dockerfile_exit_code_propagation; tidying up README.md removing all traces of error propagation flag * moved exit code propagation test to integration_test.go; moved exit code propagation test files to 'testdata' to avoid interference with other integration tests --- cmd/executor/cmd/root.go | 14 ++++- integration/integration_test.go | 57 +++++++++++++++++++ .../Dockerfile_exit_code_propagation | 5 ++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 integration/testdata/exit-code-propagation/Dockerfile_exit_code_propagation diff --git a/cmd/executor/cmd/root.go b/cmd/executor/cmd/root.go index da3a85bc2..b22d9ce39 100644 --- a/cmd/executor/cmd/root.go +++ b/cmd/executor/cmd/root.go @@ -19,6 +19,7 @@ package cmd import ( "fmt" "os" + "os/exec" "path/filepath" "regexp" "strings" @@ -340,8 +341,19 @@ func resolveRelativePaths() error { } func exit(err error) { + var execErr *exec.ExitError + if errors.As(err, &execErr) { + // if there is an exit code propagate it + exitWithCode(err, execErr.ExitCode()) + } + // otherwise exit with catch all 1 + exitWithCode(err, 1) +} + +//exits with the given error and exit code +func exitWithCode(err error, exitCode int) { fmt.Println(err) - os.Exit(1) + os.Exit(exitCode) } func isURL(path string) bool { diff --git a/integration/integration_test.go b/integration/integration_test.go index ad8d7ab49..2ce1ba055 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -528,6 +528,63 @@ func TestRelativePaths(t *testing.T) { }) } +func TestExitCodePropagation(t *testing.T) { + + currentDir, err := os.Getwd() + if err != nil { + t.Fatal("Could not get working dir") + } + + context := fmt.Sprintf("%s/testdata/exit-code-propagation", currentDir) + dockerfile := fmt.Sprintf("%s/Dockerfile_exit_code_propagation", context) + + t.Run("test error code propagation", func(t *testing.T) { + // building the image with docker should fail with exit code 42 + dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_exit_code_propagation") + dockerCmd := exec.Command("docker", + append([]string{"build", + "-t", dockerImage, + "-f", dockerfile, + context})...) + _, kanikoErr := RunCommandWithoutTest(dockerCmd) + if kanikoErr == nil { + t.Fatal("docker build did not produce an error") + } + var dockerCmdExitErr *exec.ExitError + var dockerExitCode int + + if errors.As(kanikoErr, &dockerCmdExitErr) { + dockerExitCode = dockerCmdExitErr.ExitCode() + testutil.CheckDeepEqual(t, 42, dockerExitCode) + } else { + t.Fatalf("did not produce the expected error") + } + + //try to build the same image with kaniko the error code should match with the one from the plain docker build + contextVolume := fmt.Sprintf("%s:/workspace", context) + dockerCmdWithKaniko := exec.Command("docker", append([]string{ + "run", + "-v", contextVolume, + ExecutorImage, + "-c", "dir:///workspace/", + "-f", "./Dockerfile_exit_code_propagation", + "--no-push", + })...) + + _, kanikoErr = RunCommandWithoutTest(dockerCmdWithKaniko) + if kanikoErr == nil { + t.Fatal("the kaniko build did not produce the expected error") + } + + var kanikoExitErr *exec.ExitError + if errors.As(kanikoErr, &kanikoExitErr) { + testutil.CheckDeepEqual(t, dockerExitCode, kanikoExitErr.ExitCode()) + } else { + t.Fatalf("did not produce the expected error") + } + }) +} + type fileDiff struct { Name string Size int diff --git a/integration/testdata/exit-code-propagation/Dockerfile_exit_code_propagation b/integration/testdata/exit-code-propagation/Dockerfile_exit_code_propagation new file mode 100644 index 000000000..14fa1da26 --- /dev/null +++ b/integration/testdata/exit-code-propagation/Dockerfile_exit_code_propagation @@ -0,0 +1,5 @@ +FROM alpine:latest + +RUN exit 42 + +CMD ["sleep", "1"]