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
1 change: 1 addition & 0 deletions pkg/cli/admin/catalog/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ func (o *MirrorCatalogOptions) Complete(cmd *cobra.Command, args []string) error
a.ParallelOptions = o.ParallelOptions
a.KeepManifestList = true
a.Mappings = mappings
a.SkipMultipleScopes = true
if err := a.Validate(); err != nil {
fmt.Fprintf(o.IOStreams.ErrOut, "error configuring image mirroring: %v\n", err)
}
Expand Down
94 changes: 34 additions & 60 deletions pkg/cli/image/mirror/mappings.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ import (
// ErrAlreadyExists may be returned by the blob Create function to indicate that the blob already exists.
var ErrAlreadyExists = fmt.Errorf("blob already exists in the target location")

// As length of mappings increases, so does Authorization Header size, and this causes upload failures with
// registries that have a header size limit (quay.io)
var maxLenMappings = 10

type Mapping struct {
Source imagesource.TypedImageReference
Destination imagesource.TypedImageReference
Expand Down Expand Up @@ -173,69 +169,47 @@ func (d *destinations) mergeIntoDigests(srcDigest digest.Digest, target pushTarg

type targetTree map[key]*destinations

func buildTargetTrees(mappings []Mapping) []targetTree {
var trees []targetTree
// split targetTrees into groups of 10
splitMappings := split(mappings, maxLenMappings)
for _, splitm := range splitMappings {
tree := make(targetTree)
for _, m := range splitm {
srcKey := key{t: m.Source.Type, registry: m.Source.Ref.Registry, repository: m.Source.Ref.RepositoryName()}
dstKey := key{t: m.Destination.Type, registry: m.Destination.Ref.Registry, repository: m.Destination.Ref.RepositoryName()}

src, ok := tree[srcKey]
if !ok {
src = &destinations{}
src.ref = imagesource.TypedImageReference{Ref: m.Source.Ref.AsRepository(), Type: m.Source.Type}
src.digests = make(map[string]pushTargets)
src.tags = make(map[string]pushTargets)
tree[srcKey] = src
}
func buildTargetTree(mappings []Mapping) targetTree {
tree := make(targetTree)
for _, m := range mappings {
srcKey := key{t: m.Source.Type, registry: m.Source.Ref.Registry, repository: m.Source.Ref.RepositoryName()}
dstKey := key{t: m.Destination.Type, registry: m.Destination.Ref.Registry, repository: m.Destination.Ref.RepositoryName()}

var current pushTargets
if id := m.Source.Ref.ID; len(id) > 0 {
current = src.digests[m.Source.Ref.ID]
if current == nil {
current = make(pushTargets)
src.digests[m.Source.Ref.ID] = current
}
} else {
tag := m.Source.Ref.Tag
current = src.tags[tag]
if current == nil {
current = make(pushTargets)
src.tags[tag] = current
}
}
src, ok := tree[srcKey]
if !ok {
src = &destinations{}
src.ref = imagesource.TypedImageReference{Ref: m.Source.Ref.AsRepository(), Type: m.Source.Type}
src.digests = make(map[string]pushTargets)
src.tags = make(map[string]pushTargets)
tree[srcKey] = src
}

dst, ok := current[dstKey]
if !ok {
dst.ref = imagesource.TypedImageReference{Ref: m.Destination.Ref.AsRepository(), Type: m.Destination.Type}
var current pushTargets
if id := m.Source.Ref.ID; len(id) > 0 {
current = src.digests[m.Source.Ref.ID]
if current == nil {
current = make(pushTargets)
src.digests[m.Source.Ref.ID] = current
}
if len(m.Destination.Ref.Tag) > 0 {
dst.tags = append(dst.tags, m.Destination.Ref.Tag)
} else {
tag := m.Source.Ref.Tag
current = src.tags[tag]
if current == nil {
current = make(pushTargets)
src.tags[tag] = current
}
current[dstKey] = dst
}
trees = append(trees, tree)
}
return trees
}

func split(mappings []Mapping, size int) [][]Mapping {
var splitMappings [][]Mapping
for i := 0; i < len(mappings); i += size {
m := mappings[i:min(i+size, len(mappings))]
splitMappings = append(splitMappings, m)
}
return splitMappings
}

func min(a, b int) int {
if a <= b {
return a
dst, ok := current[dstKey]
if !ok {
dst.ref = imagesource.TypedImageReference{Ref: m.Destination.Ref.AsRepository(), Type: m.Destination.Type}
}
if len(m.Destination.Ref.Tag) > 0 {
dst.tags = append(dst.tags, m.Destination.Ref.Tag)
}
current[dstKey] = dst
}
return b
return tree
}

func addDockerRegistryScopes(scopes map[contextKey]map[string]bool, targets map[string]pushTargets, srcKey key) {
Expand Down
Loading