Merge pull request #5926 from claudiubelu/import-add-platform-check

import: Raise error if the imported image is filtered out
This commit is contained in:
Phil Estes 2021-09-23 18:01:52 -04:00 committed by GitHub
commit 45e0e5a77e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 5 deletions

View File

@ -40,6 +40,10 @@ var (
// This applies only to a single descriptor in a handler // This applies only to a single descriptor in a handler
// chain and does not apply to descendant descriptors. // chain and does not apply to descendant descriptors.
ErrStopHandler = fmt.Errorf("stop handler") ErrStopHandler = fmt.Errorf("stop handler")
// ErrEmptyWalk is used when the WalkNotEmpty handlers return no
// children (e.g.: they were filtered out).
ErrEmptyWalk = fmt.Errorf("image might be filtered out")
) )
// Handler handles image manifests // Handler handles image manifests
@ -99,6 +103,36 @@ func Walk(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) err
} }
} }
} }
return nil
}
// WalkNotEmpty works the same way Walk does, with the exception that it ensures that
// some children are still found by Walking the descriptors (for example, not all of
// them have been filtered out by one of the handlers). If there are no children,
// then an ErrEmptyWalk error is returned.
func WalkNotEmpty(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) error {
isEmpty := true
var notEmptyHandler HandlerFunc = func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
children, err := handler.Handle(ctx, desc)
if err != nil {
return children, err
}
if len(children) > 0 {
isEmpty = false
}
return children, nil
}
err := Walk(ctx, notEmptyHandler, descs...)
if err != nil {
return err
}
if isEmpty {
return ErrEmptyWalk
}
return nil return nil
} }

View File

@ -185,7 +185,7 @@ func (c *Client) Import(ctx context.Context, reader io.Reader, opts ...ImportOpt
handler = images.FilterPlatforms(handler, platformMatcher) handler = images.FilterPlatforms(handler, platformMatcher)
handler = images.SetChildrenLabels(cs, handler) handler = images.SetChildrenLabels(cs, handler)
if err := images.Walk(ctx, handler, index); err != nil { if err := images.WalkNotEmpty(ctx, handler, index); err != nil {
return nil, err return nil, err
} }

View File

@ -25,6 +25,7 @@ import (
"io/ioutil" "io/ioutil"
"math/rand" "math/rand"
"reflect" "reflect"
"runtime"
"testing" "testing"
. "github.com/containerd/containerd" . "github.com/containerd/containerd"
@ -98,7 +99,8 @@ func TestImport(t *testing.T) {
empty := []byte("{}") empty := []byte("{}")
version := []byte("1.0") version := []byte("1.0")
c1, d2 := createConfig() c1, d2 := createConfig(runtime.GOOS, runtime.GOARCH)
badConfig, _ := createConfig("foo", "lish")
m1, d3, expManifest := createManifest(c1, [][]byte{b1}) m1, d3, expManifest := createManifest(c1, [][]byte{b1})
@ -172,6 +174,17 @@ func TestImport(t *testing.T) {
checkManifest(ctx, t, imgs[0].Target, nil) checkManifest(ctx, t, imgs[0].Target, nil)
}, },
}, },
{
Name: "DockerV2.1-BadOSArch",
Writer: tartest.TarAll(
tc.Dir("bd765cd43e95212f7aa2cab51d0a", 0755),
tc.File("bd765cd43e95212f7aa2cab51d0a/json", empty, 0644),
tc.File("bd765cd43e95212f7aa2cab51d0a/layer.tar", b1, 0644),
tc.File("bd765cd43e95212f7aa2cab51d0a/VERSION", version, 0644),
tc.File("e95212f7aa2cab51d0abd765cd43.json", badConfig, 0644),
tc.File("manifest.json", []byte(`[{"Config":"e95212f7aa2cab51d0abd765cd43.json","RepoTags":["test-import:notlatest", "another/repo:tag"],"Layers":["bd765cd43e95212f7aa2cab51d0a/layer.tar"]}]`), 0644),
),
},
{ {
Name: "OCI-BadFormat", Name: "OCI-BadFormat",
Writer: tartest.TarAll( Writer: tartest.TarAll(
@ -302,10 +315,10 @@ func createContent(size int64, seed int64) ([]byte, digest.Digest) {
return b, digest.FromBytes(b) return b, digest.FromBytes(b)
} }
func createConfig() ([]byte, digest.Digest) { func createConfig(osName, archName string) ([]byte, digest.Digest) {
image := ocispec.Image{ image := ocispec.Image{
OS: "any", OS: osName,
Architecture: "any", Architecture: archName,
Author: "test", Author: "test",
} }
b, _ := json.Marshal(image) b, _ := json.Marshal(image)