feat: support import image for specific platform

Signed-off-by: jonyhy <yun.hao@daocloud.io>
This commit is contained in:
jonyhy 2021-09-29 14:00:17 +08:00
parent d132691f10
commit da16d492cd
2 changed files with 41 additions and 13 deletions

View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/containerd/images/archive" "github.com/containerd/containerd/images/archive"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/platforms"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -72,6 +73,10 @@ If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadb
Name: "all-platforms", Name: "all-platforms",
Usage: "imports content for all platforms, false by default", Usage: "imports content for all platforms, false by default",
}, },
cli.BoolFlag{
Name: "platform",
Usage: "imports content for specific platform",
},
cli.BoolFlag{ cli.BoolFlag{
Name: "no-unpack", Name: "no-unpack",
Usage: "skip unpacking the images, false by default", Usage: "skip unpacking the images, false by default",
@ -84,8 +89,9 @@ If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadb
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
var ( var (
in = context.Args().First() in = context.Args().First()
opts []containerd.ImportOpt opts []containerd.ImportOpt
platformMacher platforms.MatchComparer
) )
prefix := context.String("base-name") prefix := context.String("base-name")
@ -115,6 +121,15 @@ If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadb
opts = append(opts, containerd.WithImportCompression()) opts = append(opts, containerd.WithImportCompression())
} }
if platform := context.String("platform"); platform != "" {
platSpec, err := platforms.Parse(platform)
if err != nil {
return err
}
platformMacher = platforms.Only(platSpec)
opts = append(opts, containerd.WithImportPlatform(platformMacher))
}
opts = append(opts, containerd.WithAllPlatforms(context.Bool("all-platforms"))) opts = append(opts, containerd.WithAllPlatforms(context.Bool("all-platforms")))
client, ctx, cancel, err := commands.NewClient(context) client, ctx, cancel, err := commands.NewClient(context)
@ -145,8 +160,10 @@ If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadb
log.G(ctx).Debugf("unpacking %d images", len(imgs)) log.G(ctx).Debugf("unpacking %d images", len(imgs))
for _, img := range imgs { for _, img := range imgs {
// TODO: Allow configuration of the platform if platformMacher == nil { // if platform not specified use default.
image := containerd.NewImage(client, img) platformMacher = platforms.Default()
}
image := containerd.NewImageWithPlatform(client, img, platformMacher)
// TODO: Show unpack status // TODO: Show unpack status
fmt.Printf("unpacking %s (%s)...", img.Name, img.Target.Digest) fmt.Printf("unpacking %s (%s)...", img.Name, img.Target.Digest)

View File

@ -31,12 +31,13 @@ import (
) )
type importOpts struct { type importOpts struct {
indexName string indexName string
imageRefT func(string) string imageRefT func(string) string
dgstRefT func(digest.Digest) string dgstRefT func(digest.Digest) string
skipDgstRef func(string) bool skipDgstRef func(string) bool
allPlatforms bool allPlatforms bool
compress bool platformMatcher platforms.MatchComparer
compress bool
} }
// ImportOpt allows the caller to specify import specific options // ImportOpt allows the caller to specify import specific options
@ -87,6 +88,14 @@ func WithAllPlatforms(allPlatforms bool) ImportOpt {
} }
} }
// WithImportPlatform is used to import content for specific platform.
func WithImportPlatform(platformMacher platforms.MatchComparer) ImportOpt {
return func(c *importOpts) error {
c.platformMatcher = platformMacher
return nil
}
}
// WithImportCompression compresses uncompressed layers on import. // WithImportCompression compresses uncompressed layers on import.
// This is used for import formats which do not include the manifest. // This is used for import formats which do not include the manifest.
func WithImportCompression() ImportOpt { func WithImportCompression() ImportOpt {
@ -135,9 +144,11 @@ func (c *Client) Import(ctx context.Context, reader io.Reader, opts ...ImportOpt
Target: index, Target: index,
}) })
} }
var platformMatcher = platforms.All var platformMatcher = c.platform
if !iopts.allPlatforms { if iopts.allPlatforms {
platformMatcher = c.platform platformMatcher = platforms.All
} else if iopts.platformMatcher != nil {
platformMatcher = iopts.platformMatcher
} }
var handler images.HandlerFunc = func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { var handler images.HandlerFunc = func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {