From 067d069f0c6742a98dbb6cc8ede5ac0cd55c886a Mon Sep 17 00:00:00 2001 From: Tanvir Tian Date: Sat, 10 Oct 2026 18:14:12 +0600 Subject: [PATCH] fix: return remote context download errors Signed-off-by: Tanvir Tian --- cli/command/image/build.go | 7 +++++-- cli/command/image/build_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/cli/command/image/build.go b/cli/command/image/build.go index 26a873985429..f57a0c2aa6ce 100644 --- a/cli/command/image/build.go +++ b/cli/command/image/build.go @@ -260,8 +260,11 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions) contextDir = tempDir case build.ContextTypeRemote: buildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, options.context, options.dockerfileName) - if err != nil && options.quiet { - _, _ = fmt.Fprintln(dockerCli.Err(), progBuff) + if err != nil { + if options.quiet { + _, _ = fmt.Fprintln(dockerCli.Err(), progBuff) + } + return err } default: return fmt.Errorf("unable to prepare context: path %q not found", options.context) diff --git a/cli/command/image/build_test.go b/cli/command/image/build_test.go index 1d61d05bbe70..4cb644829709 100644 --- a/cli/command/image/build_test.go +++ b/cli/command/image/build_test.go @@ -6,6 +6,8 @@ import ( "compress/gzip" "context" "io" + "net/http" + "net/http/httptest" "os" "path/filepath" "slices" @@ -172,6 +174,35 @@ RUN echo hello world assert.DeepEqual(t, fakeBuild.filenames(t), []string{"Dockerfile"}) } +// TestRunBuildRemoteContextDownloadError verifies that remote context +// download errors are propagated. +// +// regression test for https://github.com/docker/cli/issues/7372 +func TestRunBuildRemoteContextDownloadError(t *testing.T) { + t.Setenv("DOCKER_BUILDKIT", "0") + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Error(w, "not found", http.StatusNotFound) + })) + defer server.Close() + + imageBuildCalled := false + cli := test.NewFakeCli(&fakeClient{ + imageBuildFunc: func(ctx context.Context, buildContext io.Reader, options client.ImageBuildOptions) (client.ImageBuildResult, error) { + imageBuildCalled = true + return client.ImageBuildResult{Body: io.NopCloser(bytes.NewReader(nil))}, nil + }, + }) + + options := newBuildOptions() + options.context = server.URL + + err := runBuild(context.Background(), cli, options) + + assert.ErrorContains(t, err, "unable to download remote context") + assert.Assert(t, !imageBuildCalled, "ImageBuild should not be called when downloading the remote context fails") +} + type fakeBuild struct { context *tar.Reader options client.ImageBuildOptions