Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contrib/completions/bash/oc
Original file line number Diff line number Diff line change
Expand Up @@ -13576,6 +13576,8 @@ _oc_image_mirror()
local_nonpersistent_flags+=("--from-dir=")
flags+=("--insecure")
local_nonpersistent_flags+=("--insecure")
flags+=("--keep-manifest-list")
local_nonpersistent_flags+=("--keep-manifest-list")
flags+=("--max-per-registry=")
two_word_flags+=("--max-per-registry")
local_nonpersistent_flags+=("--max-per-registry=")
Expand Down
2 changes: 2 additions & 0 deletions contrib/completions/zsh/oc
Original file line number Diff line number Diff line change
Expand Up @@ -13718,6 +13718,8 @@ _oc_image_mirror()
local_nonpersistent_flags+=("--from-dir=")
flags+=("--insecure")
local_nonpersistent_flags+=("--insecure")
flags+=("--keep-manifest-list")
local_nonpersistent_flags+=("--keep-manifest-list")
flags+=("--max-per-registry=")
two_word_flags+=("--max-per-registry")
local_nonpersistent_flags+=("--max-per-registry=")
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/admin/catalog/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func (o *MirrorCatalogOptions) Complete(cmd *cobra.Command, args []string) error
a.SecurityOptions = o.SecurityOptions
a.FilterOptions = o.FilterOptions
a.ParallelOptions = o.ParallelOptions
a.ForceManifestList = true
a.KeepManifestList = true
a.Mappings = []imgmirror.Mapping{{
Source: fromRef[0],
Destination: toRef,
Expand Down
13 changes: 11 additions & 2 deletions pkg/cli/image/manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ func (o *FilterOptions) Complete(flags *pflag.FlagSet) error {
return nil
}

// IsWildcardFilter returns true if the filter regex is set to a wildcard
func (o *FilterOptions) IsWildcardFilter() bool {
wildcardFilter := ".*"
if o.FilterByOS == wildcardFilter {
return true
}
return false
}

// Include returns true if the provided manifest should be included, or the first image if the user didn't alter the
// default selection and there is only one image.
func (o *FilterOptions) Include(d *manifestlist.ManifestDescriptor, hasMultiple bool) bool {
Expand Down Expand Up @@ -330,7 +339,7 @@ func ManifestToImageConfig(ctx context.Context, srcManifest distribution.Manifes
}
}

func ProcessManifestList(ctx context.Context, srcDigest digest.Digest, srcManifest distribution.Manifest, manifests distribution.ManifestService, ref imagereference.DockerImageReference, filterFn FilterFunc, forceManifestList bool) ([]distribution.Manifest, distribution.Manifest, digest.Digest, error) {
func ProcessManifestList(ctx context.Context, srcDigest digest.Digest, srcManifest distribution.Manifest, manifests distribution.ManifestService, ref imagereference.DockerImageReference, filterFn FilterFunc, keepManifestList bool) ([]distribution.Manifest, distribution.Manifest, digest.Digest, error) {
var srcManifests []distribution.Manifest
switch t := srcManifest.(type) {
case *manifestlist.DeserializedManifestList:
Expand Down Expand Up @@ -379,7 +388,7 @@ func ProcessManifestList(ctx context.Context, srcDigest digest.Digest, srcManife
}

switch {
case len(srcManifests) == 1 && !forceManifestList:
case len(srcManifests) == 1 && !keepManifestList:
manifestDigest, err := registryclient.ContentDigestForManifest(srcManifests[0], srcDigest.Algorithm())
if err != nil {
return nil, nil, "", err
Expand Down
12 changes: 7 additions & 5 deletions pkg/cli/image/mirror/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ type MirrorImageOptions struct {
SkipMultipleScopes bool
SkipMissing bool
Force bool
ForceManifestList bool
KeepManifestList bool

MaxRegistry int
ParallelOptions imagemanifest.ParallelOptions
Expand Down Expand Up @@ -145,14 +145,12 @@ func NewCmdMirrorImage(name string, streams genericclioptions.IOStreams) *cobra.
o.FilterOptions.Bind(flag)
o.ParallelOptions.Bind(flag)

// Always mirror manifestlist if available
o.ForceManifestList = true

flag.BoolVar(&o.DryRun, "dry-run", o.DryRun, "Print the actions that would be taken and exit without writing to the destinations.")
flag.BoolVar(&o.SkipMissing, "skip-missing", o.SkipMissing, "If an input image is not found, skip them.")
flag.BoolVar(&o.SkipMount, "skip-mount", o.SkipMount, "Always push layers instead of cross-mounting them")
flag.BoolVar(&o.SkipMultipleScopes, "skip-multiple-scopes", o.SkipMultipleScopes, "Some registries do not support multiple scopes passed to the registry login.")
flag.BoolVar(&o.Force, "force", o.Force, "Attempt to write all layers and manifests even if they exist in the remote repository.")
flag.BoolVar(&o.KeepManifestList, "keep-manifest-list", o.KeepManifestList, "If an image is part of a manifest list, always mirror the list even if only one image is found. The default is to mirror the specific image unless unless --filter-by-os is '.*'.")
flag.IntVar(&o.MaxRegistry, "max-registry", o.MaxRegistry, "Number of concurrent registries to connect to at any one time.")
flag.StringSliceVar(&o.AttemptS3BucketCopy, "s3-source-bucket", o.AttemptS3BucketCopy, "A list of bucket/path locations on S3 that may contain already uploaded blobs. Add [store] to the end to use the container image registry path convention.")
flag.StringSliceVarP(&o.Filenames, "filename", "f", o.Filenames, "One or more files to read SRC=DST or SRC DST [DST ...] mappings from.")
Expand All @@ -167,6 +165,10 @@ func (o *MirrorImageOptions) Complete(cmd *cobra.Command, args []string) error {
return err
}

if o.FilterOptions.IsWildcardFilter() {
o.KeepManifestList = true
}

registryContext, err := o.SecurityOptions.Context()
if err != nil {
return err
Expand Down Expand Up @@ -466,7 +468,7 @@ func (o *MirrorImageOptions) plan() (*plan, error) {

// filter or load manifest list as appropriate
originalSrcDigest := srcDigest
srcManifests, srcManifest, srcDigest, err := imagemanifest.ProcessManifestList(ctx, srcDigest, srcManifest, manifests, src.ref.Ref, o.FilterOptions.IncludeAll, o.ForceManifestList)
srcManifests, srcManifest, srcDigest, err := imagemanifest.ProcessManifestList(ctx, srcDigest, srcManifest, manifests, src.ref.Ref, o.FilterOptions.IncludeAll, o.KeepManifestList)
if err != nil {
plan.AddError(retrieverError{src: src.ref, err: err})
return
Expand Down