From f566d8b8e5351393c03bc0ff475a18174e57af3f Mon Sep 17 00:00:00 2001 From: Aditya Rajan Date: Thu, 16 Dec 2021 17:07:16 +0530 Subject: [PATCH 1/2] build: relay exitcode from imagebuildah to registry Podman does not relay exit code from buildah instead returns a generic error code `125`. Following PR allows `podman` to relay exit code from `imagebuildah` to `registry` as it is. Signed-off-by: Aditya Rajan --- cmd/podman/images/build.go | 18 ++++++++++++++++++ cmd/podman/utils/error.go | 26 ++++++++++++++++++++++++++ test/e2e/build_test.go | 17 +++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 4c563ed276..751db099f8 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -1,9 +1,11 @@ package images import ( + "fmt" "io" "io/ioutil" "os" + "os/exec" "path/filepath" "strings" "time" @@ -289,7 +291,23 @@ func build(cmd *cobra.Command, args []string) error { } report, err := registry.ImageEngine().Build(registry.GetContext(), containerFiles, *apiBuildOpts) + if err != nil { + exitCode := buildahCLI.ExecErrorCodeGeneric + if registry.IsRemote() { + // errors from server does not contain ExitCode + // so parse exit code from error message + remoteExitCode, parseErr := utils.ExitCodeFromBuildError(fmt.Sprint(errors.Cause(err))) + if parseErr == nil { + exitCode = remoteExitCode + } + } + + if ee, ok := (errors.Cause(err)).(*exec.ExitError); ok { + exitCode = ee.ExitCode() + } + + registry.SetExitCode(exitCode) return err } diff --git a/cmd/podman/utils/error.go b/cmd/podman/utils/error.go index 2d58bc70d9..aab1da675c 100644 --- a/cmd/podman/utils/error.go +++ b/cmd/podman/utils/error.go @@ -1,8 +1,13 @@ package utils import ( + "errors" "fmt" "os" + "strconv" + "strings" + + buildahCLI "github.com/containers/buildah/pkg/cli" ) type OutputErrors []error @@ -17,3 +22,24 @@ func (o OutputErrors) PrintErrors() (lastError error) { } return } + +/* For remote client, server does not returns error with exit code + instead returns a message and we cast it to a new error. + + Following function performs parsing on build error and returns + exit status which was exepected for this current build +*/ +func ExitCodeFromBuildError(errorMsg string) (int, error) { + if strings.Contains(errorMsg, "exit status") { + errorSplit := strings.Split(errorMsg, " ") + if errorSplit[len(errorSplit)-2] == "status" { + tmpSplit := strings.Split(errorSplit[len(errorSplit)-1], "\n") + exitCodeRemote, err := strconv.Atoi(tmpSplit[0]) + if err == nil { + return exitCodeRemote, nil + } + return buildahCLI.ExecErrorCodeGeneric, err + } + } + return buildahCLI.ExecErrorCodeGeneric, errors.New("error message does not contains a valid exit code") +} diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index 9a9dec191e..f4511860da 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -273,6 +273,23 @@ RUN printenv http_proxy`, ALPINE) os.Unsetenv("http_proxy") }) + It("podman build relay exit code to process", func() { + if IsRemote() { + // following states true for all the remote commands + Skip("Remote server does not emits error with exit status") + } + podmanTest.AddImageToRWStore(ALPINE) + dockerfile := fmt.Sprintf(`FROM %s +RUN exit 5`, ALPINE) + + dockerfilePath := filepath.Join(podmanTest.TempDir, "Dockerfile") + err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) + Expect(err).To(BeNil()) + session := podmanTest.Podman([]string{"build", "-t", "error-test", "--file", dockerfilePath, podmanTest.TempDir}) + session.Wait(120) + Expect(session).Should(Exit(5)) + }) + It("podman build and check identity", func() { session := podmanTest.Podman([]string{"build", "--pull-never", "-f", "build/basicalpine/Containerfile.path", "--no-cache", "-t", "test", "build/basicalpine"}) session.WaitWithDefaultTimeout() From 6423174c67d486522354806bf326c843c07d18c1 Mon Sep 17 00:00:00 2001 From: Aditya Rajan Date: Fri, 17 Dec 2021 14:40:24 +0530 Subject: [PATCH 2/2] tests: adjust old build test to expect exit code Old build tests were expecting genric error code `125` however another commit in this PR ensures that we relay exact exit code from build to registry. Hence adjusting tests Signed-off-by: Aditya Rajan --- test/e2e/build_test.go | 8 ++++---- test/system/070-build.bats | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index f4511860da..5ed873f783 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -275,8 +275,8 @@ RUN printenv http_proxy`, ALPINE) It("podman build relay exit code to process", func() { if IsRemote() { - // following states true for all the remote commands - Skip("Remote server does not emits error with exit status") + podmanTest.StopRemoteService() + podmanTest.StartRemoteService() } podmanTest.AddImageToRWStore(ALPINE) dockerfile := fmt.Sprintf(`FROM %s @@ -663,7 +663,7 @@ RUN ls /dev/fuse`, ALPINE) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session).Should(Exit(125)) + Expect(session).Should(Exit(1)) session = podmanTest.Podman([]string{"build", "--pull-never", "--device", "/dev/fuse", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -679,7 +679,7 @@ RUN ls /dev/test1`, ALPINE) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() - Expect(session).Should(Exit(125)) + Expect(session).Should(Exit(1)) session = podmanTest.Podman([]string{"build", "--pull-never", "--device", "/dev/zero:/dev/test1", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 3c47b1f5be..5e920506d3 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -115,7 +115,7 @@ FROM $IMAGE RUN echo $rand_content EOF - run_podman 125 --runtime-flag invalidflag build -t build_test $tmpdir + run_podman 1 --runtime-flag invalidflag build -t build_test $tmpdir is "$output" ".*invalidflag" "failed when passing undefined flags to the runtime" }