Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a per-repo destination-path-style setting for yaml source #1769

Closed
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: 0 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ updates:
time: "10:00"
timezone: Europe/Berlin
open-pull-requests-limit: 10

49 changes: 36 additions & 13 deletions cmd/skopeo/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ type syncOptions struct {

// repoDescriptor contains information of a single repository used as a sync source.
type repoDescriptor struct {
DirBasePath string // base path when source is 'dir'
ImageRefs []types.ImageReference // List of tagged image found for the repository
Context *types.SystemContext // SystemContext for the sync command
DirBasePath string // base path when source is 'dir'
ImageRefs []types.ImageReference // List of tagged image found for the repository
Context *types.SystemContext // SystemContext for the sync command
DestinationPathStyle string // path style for the destination
}

// tlsVerifyConfig is an implementation of the Unmarshaler interface, used to
Expand All @@ -64,11 +65,12 @@ type tlsVerifyConfig struct {
// registrySyncConfig contains information about a single registry, read from
// the source YAML file
type registrySyncConfig struct {
Images map[string][]string // Images map images name to slices with the images' references (tags, digests)
ImagesByTagRegex map[string]string `yaml:"images-by-tag-regex"` // Images map images name to regular expression with the images' tags
Credentials types.DockerAuthConfig // Username and password used to authenticate with the registry
TLSVerify tlsVerifyConfig `yaml:"tls-verify"` // TLS verification mode (enabled by default)
CertDir string `yaml:"cert-dir"` // Path to the TLS certificates of the registry
Images map[string][]string // Images map images name to slices with the images' references (tags, digests)
ImagesByTagRegex map[string]string `yaml:"images-by-tag-regex"` // Images map images name to regular expression with the images' tags
Credentials types.DockerAuthConfig // Username and password used to authenticate with the registry
TLSVerify tlsVerifyConfig `yaml:"tls-verify"` // TLS verification mode (enabled by default)
CertDir string `yaml:"cert-dir"` // Path to the TLS certificates of the registry
DestinationPathStyle string `yaml:"destination-path-style"` // path style for the destination
}

// sourceConfig contains all registries information read from the source YAML file
Expand Down Expand Up @@ -365,8 +367,9 @@ func imagesToCopyFromRegistry(registryName string, cfg registrySyncConfig, sourc
continue
}
repoDescList = append(repoDescList, repoDescriptor{
ImageRefs: sourceReferences,
Context: serverCtx})
ImageRefs: sourceReferences,
Context: serverCtx,
DestinationPathStyle: cfg.DestinationPathStyle})
}

for imageName, tagRegex := range cfg.ImagesByTagRegex {
Expand Down Expand Up @@ -419,8 +422,9 @@ func imagesToCopyFromRegistry(registryName string, cfg registrySyncConfig, sourc
continue
}
repoDescList = append(repoDescList, repoDescriptor{
ImageRefs: sourceReferences,
Context: serverCtx})
ImageRefs: sourceReferences,
Context: serverCtx,
DestinationPathStyle: cfg.DestinationPathStyle})
}

return repoDescList, nil
Expand Down Expand Up @@ -646,7 +650,26 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
}
}

if !opts.scoped {
var destSuffixStyle string
destSuffixStyle = srcRepo.DestinationPathStyle

if opts.scoped {
if !(destSuffixStyle == "full" || destSuffixStyle == "") {
logrus.Infof("destination-style-path setting in yaml is overridden by global --scoped cli flag")
}
destSuffixStyle = "full"
}

switch destSuffixStyle {
case "flat":
destSuffix = path.Base(destSuffix)
case "full":
case "full-no-registry":
destSuffix = strings.SplitN(destSuffix, "/", 2)[1]
default:
if opts.source == "yaml" && destSuffixStyle != "" {
logrus.Warnf("destination-path-style yaml setting doesn't match 'full', 'full-no-registry' or 'flat', but is '%s'. Using 'flat' style as default.", destSuffixStyle)
}
destSuffix = path.Base(destSuffix)
}

Expand Down
8 changes: 8 additions & 0 deletions docs/skopeo-sync.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ registry.example.com:
cert-dir: /home/john/certs
quay.io:
tls-verify: false
destination-path-style: "full-no-registry"
images:
coreos/etcd:
- latest
Expand All @@ -225,6 +226,13 @@ TLS verification is normally enabled, and it can be disabled setting `tls-verify
In the above example, TLS verification is enabled for `registry.example.com`, while is
disabled for `quay.io`.

The final path could be defined using the `destionation-path-style` setting per each source repository. Can take the following values: `flat` (default), `full`, `full-no-registry`.
Examples for the `registry.example.com/prom/node-exporter` as source and `dest.registry.com` as destination:
- `flat` results in `dest.registry.com/node-exporter`
- `full` results in `dest.registry.com/registry.example.com/prom/node-exporter`
- `full-no-registry` results in `dest.registry.com/prom/node-exporter`
`--scoped` CLI flag overrides the behaviour of the `destination-path-style` setting, setting it to `full` for every source repository.

## SEE ALSO
skopeo(1), skopeo-login(1), docker-login(1), containers-auth.json(5), containers-policy.json(5), containers-transports(5)

Expand Down