c8d/pull: Handle pull all tags
Use the distribution code to query the remote repository for tags and pull them sequentially just like the non-c8d pull. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
095d2a29a3
commit
d9b5445f39
3 changed files with 45 additions and 8 deletions
|
@ -2,6 +2,7 @@ package containerd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
|
@ -12,7 +13,7 @@ import (
|
|||
"github.com/containerd/log"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/events"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
registrytypes "github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/distribution"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/internal/compatcontext"
|
||||
|
@ -21,8 +22,43 @@ import (
|
|||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// PullImage initiates a pull operation. ref is the image to pull.
|
||||
func (i *ImageService) PullImage(ctx context.Context, ref reference.Named, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error {
|
||||
// PullImage initiates a pull operation. baseRef is the image to pull.
|
||||
// If reference is not tagged, all tags are pulled.
|
||||
func (i *ImageService) PullImage(ctx context.Context, baseRef reference.Named, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registrytypes.AuthConfig, outStream io.Writer) error {
|
||||
out := streamformatter.NewJSONProgressOutput(outStream, false)
|
||||
|
||||
if tagged, ok := baseRef.(reference.NamedTagged); ok {
|
||||
return i.pullTag(ctx, tagged, platform, metaHeaders, authConfig, out)
|
||||
}
|
||||
|
||||
tags, err := distribution.Tags(ctx, baseRef, &distribution.Config{
|
||||
RegistryService: i.registryService,
|
||||
MetaHeaders: metaHeaders,
|
||||
AuthConfig: authConfig,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, tag := range tags {
|
||||
ref, err := reference.WithTag(baseRef, tag)
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"tag": tag,
|
||||
"baseRef": baseRef,
|
||||
}).Warn("invalid tag, won't pull")
|
||||
continue
|
||||
}
|
||||
|
||||
if err := i.pullTag(ctx, ref, platform, metaHeaders, authConfig, out); err != nil {
|
||||
return fmt.Errorf("error pulling %s: %w", ref, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ImageService) pullTag(ctx context.Context, ref reference.NamedTagged, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registrytypes.AuthConfig, out progress.Output) error {
|
||||
var opts []containerd.RemoteOpt
|
||||
if platform != nil {
|
||||
opts = append(opts, containerd.WithPlatform(platforms.Format(*platform)))
|
||||
|
@ -49,7 +85,6 @@ func (i *ImageService) PullImage(ctx context.Context, ref reference.Named, platf
|
|||
})
|
||||
opts = append(opts, containerd.WithImageHandler(h))
|
||||
|
||||
out := streamformatter.NewJSONProgressOutput(outStream, false)
|
||||
pp := pullProgress{store: i.client.ContentStore(), showExists: true}
|
||||
finishProgress := jobs.showProgress(ctx, out, pp)
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ func (i *ImageService) newResolverFromAuthConfig(ctx context.Context, authConfig
|
|||
}), tracker
|
||||
}
|
||||
|
||||
func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.AuthConfig, regService RegistryConfigProvider) docker.RegistryHosts {
|
||||
func hostsWrapper(hostsFn docker.RegistryHosts, optAuthConfig *registrytypes.AuthConfig, regService registryResolver) docker.RegistryHosts {
|
||||
var authorizer docker.Authorizer
|
||||
if optAuthConfig != nil {
|
||||
authorizer = authorizerFromAuthConfig(*optAuthConfig)
|
||||
|
|
|
@ -30,16 +30,18 @@ type ImageService struct {
|
|||
containers container.Store
|
||||
snapshotter string
|
||||
registryHosts docker.RegistryHosts
|
||||
registryService RegistryConfigProvider
|
||||
registryService registryResolver
|
||||
eventsService *daemonevents.Events
|
||||
pruneRunning atomic.Bool
|
||||
refCountMounter snapshotter.Mounter
|
||||
idMapping idtools.IdentityMapping
|
||||
}
|
||||
|
||||
type RegistryConfigProvider interface {
|
||||
type registryResolver interface {
|
||||
IsInsecureRegistry(host string) bool
|
||||
ResolveRepository(name reference.Named) (*registry.RepositoryInfo, error)
|
||||
LookupPullEndpoints(hostname string) ([]registry.APIEndpoint, error)
|
||||
LookupPushEndpoints(hostname string) ([]registry.APIEndpoint, error)
|
||||
}
|
||||
|
||||
type ImageServiceConfig struct {
|
||||
|
@ -47,7 +49,7 @@ type ImageServiceConfig struct {
|
|||
Containers container.Store
|
||||
Snapshotter string
|
||||
RegistryHosts docker.RegistryHosts
|
||||
Registry RegistryConfigProvider
|
||||
Registry registryResolver
|
||||
EventsService *daemonevents.Events
|
||||
RefCountMounter snapshotter.Mounter
|
||||
IDMapping idtools.IdentityMapping
|
||||
|
|
Loading…
Add table
Reference in a new issue