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:
parent
7b6495426d
commit
57ea150cad
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
FROM alpine:latest
|
||||
|
||||
RUN exit 42
|
||||
|
||||
CMD ["sleep", "1"]
|
||||
Loading…
Reference in New Issue