Skip to content

Commit 81dbed4

Browse files
authored
Merge pull request moby#39527 from thaJeztah/pull_platform_regression
Fix error handling of incorrect --platform values
2 parents 2645e31 + 9d1b4f5 commit 81dbed4

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

errdefs/http_helpers.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"net/http"
66

7+
containerderrors "github.com/containerd/containerd/errdefs"
78
"github.com/docker/distribution/registry/api/errcode"
89
"github.com/sirupsen/logrus"
910
"google.golang.org/grpc/codes"
@@ -47,6 +48,10 @@ func GetHTTPErrorStatusCode(err error) int {
4748
if statusCode != http.StatusInternalServerError {
4849
return statusCode
4950
}
51+
statusCode = statusCodeFromContainerdError(err)
52+
if statusCode != http.StatusInternalServerError {
53+
return statusCode
54+
}
5055
statusCode = statusCodeFromDistributionError(err)
5156
if statusCode != http.StatusInternalServerError {
5257
return statusCode
@@ -163,3 +168,24 @@ func statusCodeFromDistributionError(err error) int {
163168
}
164169
return http.StatusInternalServerError
165170
}
171+
172+
// statusCodeFromContainerdError returns status code for containerd errors when
173+
// consumed directly (not through gRPC)
174+
func statusCodeFromContainerdError(err error) int {
175+
switch {
176+
case containerderrors.IsInvalidArgument(err):
177+
return http.StatusBadRequest
178+
case containerderrors.IsNotFound(err):
179+
return http.StatusNotFound
180+
case containerderrors.IsAlreadyExists(err):
181+
return http.StatusConflict
182+
case containerderrors.IsFailedPrecondition(err):
183+
return http.StatusPreconditionFailed
184+
case containerderrors.IsUnavailable(err):
185+
return http.StatusServiceUnavailable
186+
case containerderrors.IsNotImplemented(err):
187+
return http.StatusNotImplemented
188+
default:
189+
return http.StatusInternalServerError
190+
}
191+
}

integration/build/build_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/docker/docker/api/types"
1414
"github.com/docker/docker/api/types/filters"
1515
"github.com/docker/docker/api/types/versions"
16+
"github.com/docker/docker/errdefs"
1617
"github.com/docker/docker/internal/test/fakecontext"
1718
"github.com/docker/docker/pkg/jsonmessage"
1819
"gotest.tools/assert"
@@ -562,6 +563,35 @@ func TestBuildPreserveOwnership(t *testing.T) {
562563
}
563564
}
564565

566+
func TestBuildPlatformInvalid(t *testing.T) {
567+
skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "experimental in older versions")
568+
569+
ctx := context.Background()
570+
defer setupTest(t)()
571+
572+
dockerfile := `FROM busybox
573+
`
574+
575+
buf := bytes.NewBuffer(nil)
576+
w := tar.NewWriter(buf)
577+
writeTarRecord(t, w, "Dockerfile", dockerfile)
578+
err := w.Close()
579+
assert.NilError(t, err)
580+
581+
apiclient := testEnv.APIClient()
582+
_, err = apiclient.ImageBuild(ctx,
583+
buf,
584+
types.ImageBuildOptions{
585+
Remove: true,
586+
ForceRemove: true,
587+
Platform: "foobar",
588+
})
589+
590+
assert.Assert(t, err != nil)
591+
assert.ErrorContains(t, err, "unknown operating system or architecture")
592+
assert.Assert(t, errdefs.IsInvalidParameter(err))
593+
}
594+
565595
func writeTarRecord(t *testing.T, w *tar.Writer, fn, contents string) {
566596
err := w.WriteHeader(&tar.Header{
567597
Name: fn,

integration/image/pull_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package image
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/docker/docker/api/types"
8+
"github.com/docker/docker/api/types/versions"
9+
"github.com/docker/docker/errdefs"
10+
"gotest.tools/assert"
11+
"gotest.tools/skip"
12+
)
13+
14+
func TestImagePullPlatformInvalid(t *testing.T) {
15+
skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "experimental in older versions")
16+
defer setupTest(t)()
17+
client := testEnv.APIClient()
18+
ctx := context.Background()
19+
20+
_, err := client.ImagePull(ctx, "docker.io/library/hello-world:latest", types.ImagePullOptions{Platform: "foobar"})
21+
assert.Assert(t, err != nil)
22+
assert.ErrorContains(t, err, "unknown operating system or architecture")
23+
assert.Assert(t, errdefs.IsInvalidParameter(err))
24+
}

0 commit comments

Comments
 (0)