Merge pull request #3577 from dmcgowan/change-default-manifest-download

[carry #3127] Update pull default to skip all platform manifests
This commit is contained in:
Michael Crosby 2019-08-26 15:04:15 -04:00 committed by GitHub
commit df84e546b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 62 additions and 32 deletions

View File

@ -333,9 +333,8 @@ type RemoteContext struct {
// MaxConcurrentDownloads is the max concurrent content downloads for each pull. // MaxConcurrentDownloads is the max concurrent content downloads for each pull.
MaxConcurrentDownloads int MaxConcurrentDownloads int
// AppendDistributionSourceLabel allows fetcher to add distribute source // AllMetadata downloads all manifests and known-configuration files
// label for each blob content, which doesn't work for legacy schema1. AllMetadata bool
AppendDistributionSourceLabel bool
} }
func defaultRemoteContext() *RemoteContext { func defaultRemoteContext() *RemoteContext {

View File

@ -195,11 +195,10 @@ func WithMaxConcurrentDownloads(max int) RemoteOpt {
} }
} }
// WithAppendDistributionSourceLabel allows fetcher to add distribute source // WithAllMetadata downloads all manifests and known-configuration files
// label for each blob content, which doesn't work for legacy schema1. func WithAllMetadata() RemoteOpt {
func WithAppendDistributionSourceLabel() RemoteOpt {
return func(_ *Client, c *RemoteContext) error { return func(_ *Client, c *RemoteContext) error {
c.AppendDistributionSourceLabel = true c.AllMetadata = true
return nil return nil
} }
} }

View File

@ -287,9 +287,6 @@ func TestImagePullSomePlatforms(t *testing.T) {
count := 0 count := 0
for _, manifest := range manifests { for _, manifest := range manifests {
children, err := images.Children(ctx, cs, manifest) children, err := images.Children(ctx, cs, manifest)
if err != nil {
t.Fatal(err)
}
found := false found := false
for _, matcher := range m { for _, matcher := range m {
@ -315,6 +312,8 @@ func TestImagePullSomePlatforms(t *testing.T) {
} }
ra.Close() ra.Close()
} }
} else if err == nil {
t.Fatal("manifest should not have pulled children content")
} }
} }

View File

@ -34,7 +34,7 @@ import (
"github.com/containerd/containerd/pkg/progress" "github.com/containerd/containerd/pkg/progress"
"github.com/containerd/containerd/platforms" "github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/remotes" "github.com/containerd/containerd/remotes"
digest "github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -66,6 +66,14 @@ Most of this is experimental and there are few leaps to make this work.`,
Name: "all-platforms", Name: "all-platforms",
Usage: "pull content from all platforms", Usage: "pull content from all platforms",
}, },
cli.BoolFlag{
Name: "all-metadata",
Usage: "Pull metadata for all platforms",
},
cli.BoolFlag{
Name: "metadata-only",
Usage: "Pull all metadata including manifests and configs",
},
), ),
Action: func(clicontext *cli.Context) error { Action: func(clicontext *cli.Context) error {
var ( var (
@ -80,6 +88,7 @@ Most of this is experimental and there are few leaps to make this work.`,
if err != nil { if err != nil {
return err return err
} }
_, err = Fetch(ctx, client, ref, config) _, err = Fetch(ctx, client, ref, config)
return err return err
}, },
@ -93,8 +102,12 @@ type FetchConfig struct {
ProgressOutput io.Writer ProgressOutput io.Writer
// Labels to set on the content // Labels to set on the content
Labels []string Labels []string
// PlatformMatcher matches platforms, supersedes Platforms
PlatformMatcher platforms.MatchComparer
// Platforms to fetch // Platforms to fetch
Platforms []string Platforms []string
// Whether or not download all metadata
AllMetadata bool
} }
// NewFetchConfig returns the default FetchConfig from cli flags // NewFetchConfig returns the default FetchConfig from cli flags
@ -117,6 +130,15 @@ func NewFetchConfig(ctx context.Context, clicontext *cli.Context) (*FetchConfig,
} }
config.Platforms = p config.Platforms = p
} }
if clicontext.Bool("metadata-only") {
config.AllMetadata = true
// Any with an empty set is None
config.PlatformMatcher = platforms.Any()
} else if clicontext.Bool("all-metadata") {
config.AllMetadata = true
}
return config, nil return config, nil
} }
@ -149,11 +171,18 @@ func Fetch(ctx context.Context, client *containerd.Client, ref string, config *F
containerd.WithResolver(config.Resolver), containerd.WithResolver(config.Resolver),
containerd.WithImageHandler(h), containerd.WithImageHandler(h),
containerd.WithSchema1Conversion, containerd.WithSchema1Conversion,
containerd.WithAppendDistributionSourceLabel(),
} }
for _, platform := range config.Platforms { if config.AllMetadata {
opts = append(opts, containerd.WithPlatform(platform)) opts = append(opts, containerd.WithAllMetadata())
}
if config.PlatformMatcher != nil {
opts = append(opts, containerd.WithPlatformMatcher(config.PlatformMatcher))
} else {
for _, platform := range config.Platforms {
opts = append(opts, containerd.WithPlatform(platform))
}
} }
img, err := client.Fetch(pctx, ref, opts...) img, err := client.Fetch(pctx, ref, opts...)

View File

@ -51,7 +51,11 @@ command. As part of this process, we do the following:
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "all-platforms", Name: "all-platforms",
Usage: "pull content from all platforms", Usage: "pull content and metadata from all platforms",
},
cli.BoolFlag{
Name: "all-metadata",
Usage: "Pull metadata for all platforms",
}, },
), ),
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
@ -78,6 +82,7 @@ command. As part of this process, we do the following:
if err != nil { if err != nil {
return err return err
} }
img, err := content.Fetch(ctx, client, ref, config) img, err := content.Fetch(ctx, client, ref, config)
if err != nil { if err != nil {
return err return err

View File

@ -99,9 +99,7 @@ func TestImagePullWithDistSourceLabel(t *testing.T) {
pMatcher := platforms.Default() pMatcher := platforms.Default()
// pull content without unpack and add distribution source label // pull content without unpack and add distribution source label
image, err := client.Pull(ctx, imageName, image, err := client.Pull(ctx, imageName, WithPlatformMatcher(pMatcher))
WithPlatformMatcher(pMatcher),
WithAppendDistributionSourceLabel())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -183,7 +181,7 @@ func TestImageUsage(t *testing.T) {
imageName = imageName + "@" + image.Target().Digest.String() imageName = imageName + "@" + image.Target().Digest.String()
// Fetch single platforms, but all manifests pulled // Fetch single platforms, but all manifests pulled
if _, err := client.Fetch(ctx, imageName, WithPlatformMatcher(testPlatform)); err != nil { if _, err := client.Fetch(ctx, imageName, WithPlatformMatcher(testPlatform), WithAllMetadata()); err != nil {
t.Fatal(err) t.Fatal(err)
} }

27
pull.go
View File

@ -140,9 +140,14 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
childrenHandler := images.ChildrenHandler(store) childrenHandler := images.ChildrenHandler(store)
// Set any children labels for that content // Set any children labels for that content
childrenHandler = images.SetChildrenLabels(store, childrenHandler) childrenHandler = images.SetChildrenLabels(store, childrenHandler)
// Filter manifests by platforms but allow to handle manifest if rCtx.AllMetadata {
// and configuration for not-target platforms // Filter manifests by platforms but allow to handle manifest
childrenHandler = remotes.FilterManifestByPlatformHandler(childrenHandler, rCtx.PlatformMatcher) // and configuration for not-target platforms
childrenHandler = remotes.FilterManifestByPlatformHandler(childrenHandler, rCtx.PlatformMatcher)
} else {
// Filter children by platforms if specified.
childrenHandler = images.FilterPlatforms(childrenHandler, rCtx.PlatformMatcher)
}
// Sort and limit manifests if a finite number is needed // Sort and limit manifests if a finite number is needed
if limit > 0 { if limit > 0 {
childrenHandler = images.LimitManifests(childrenHandler, rCtx.PlatformMatcher, limit) childrenHandler = images.LimitManifests(childrenHandler, rCtx.PlatformMatcher, limit)
@ -159,22 +164,18 @@ func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, lim
}, },
) )
appendDistSrcLabelHandler, err := docker.AppendDistributionSourceLabel(store, ref)
if err != nil {
return images.Image{}, err
}
handlers := append(rCtx.BaseHandlers, handlers := append(rCtx.BaseHandlers,
remotes.FetchHandler(store, fetcher), remotes.FetchHandler(store, fetcher),
convertibleHandler, convertibleHandler,
childrenHandler, childrenHandler,
appendDistSrcLabelHandler,
) )
// append distribution source label to blob data
if rCtx.AppendDistributionSourceLabel {
appendDistSrcLabelHandler, err := docker.AppendDistributionSourceLabel(store, ref)
if err != nil {
return images.Image{}, err
}
handlers = append(handlers, appendDistSrcLabelHandler)
}
handler = images.Handlers(handlers...) handler = images.Handlers(handlers...)
converterFunc = func(ctx context.Context, desc ocispec.Descriptor) (ocispec.Descriptor, error) { converterFunc = func(ctx context.Context, desc ocispec.Descriptor) (ocispec.Descriptor, error) {