Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.

Commit c73dca1

Browse files
authored
Merge pull request #365 from thaJeztah/19.03_backport_pull_platform_regression
[19.03 backport] Fix error handling of incorrect --platform values Upstream-commit: 80727e5a92d571007007697a4d3c89656c440dfd Component: engine
2 parents 2144efc + d676d18 commit c73dca1

3 files changed

Lines changed: 80 additions & 0 deletions

File tree

components/engine/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
@@ -170,3 +175,24 @@ func statusCodeFromDistributionError(err error) int {
170175
}
171176
return http.StatusInternalServerError
172177
}
178+
179+
// statusCodeFromContainerdError returns status code for containerd errors when
180+
// consumed directly (not through gRPC)
181+
func statusCodeFromContainerdError(err error) int {
182+
switch {
183+
case containerderrors.IsInvalidArgument(err):
184+
return http.StatusBadRequest
185+
case containerderrors.IsNotFound(err):
186+
return http.StatusNotFound
187+
case containerderrors.IsAlreadyExists(err):
188+
return http.StatusConflict
189+
case containerderrors.IsFailedPrecondition(err):
190+
return http.StatusPreconditionFailed
191+
case containerderrors.IsUnavailable(err):
192+
return http.StatusServiceUnavailable
193+
case containerderrors.IsNotImplemented(err):
194+
return http.StatusNotImplemented
195+
default:
196+
return http.StatusInternalServerError
197+
}
198+
}

components/engine/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"
@@ -614,6 +615,35 @@ func TestBuildPreserveOwnership(t *testing.T) {
614615
}
615616
}
616617

618+
func TestBuildPlatformInvalid(t *testing.T) {
619+
skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "experimental in older versions")
620+
621+
ctx := context.Background()
622+
defer setupTest(t)()
623+
624+
dockerfile := `FROM busybox
625+
`
626+
627+
buf := bytes.NewBuffer(nil)
628+
w := tar.NewWriter(buf)
629+
writeTarRecord(t, w, "Dockerfile", dockerfile)
630+
err := w.Close()
631+
assert.NilError(t, err)
632+
633+
apiclient := testEnv.APIClient()
634+
_, err = apiclient.ImageBuild(ctx,
635+
buf,
636+
types.ImageBuildOptions{
637+
Remove: true,
638+
ForceRemove: true,
639+
Platform: "foobar",
640+
})
641+
642+
assert.Assert(t, err != nil)
643+
assert.ErrorContains(t, err, "unknown operating system or architecture")
644+
assert.Assert(t, errdefs.IsInvalidParameter(err))
645+
}
646+
617647
func writeTarRecord(t *testing.T, w *tar.Writer, fn, contents string) {
618648
err := w.WriteHeader(&tar.Header{
619649
Name: fn,
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)