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
This commit is contained in:
Benjamin Krenn 2021-06-01 19:43:49 +02:00 committed by GitHub
parent 7b6495426d
commit 57ea150cad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 1 deletions

View File

@ -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 {

View File

@ -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

View File

@ -0,0 +1,5 @@
FROM alpine:latest
RUN exit 42
CMD ["sleep", "1"]