Skip to content

Commit

Permalink
feat(sync): preserve subpath in repositories when registry is defined
Browse files Browse the repository at this point in the history
  - Add `RegistryName` field to `repoDescriptor` for better registry handling.
  - Introduce `getSubPath` function to cleanly handle subpath extraction.
  - Update functions `imagesToCopyFromRegistry` and `filterSourceReferences` to include `RegistryName`.
  - Modify `syncOptions.run` to use `getSubPath`.
  - Add unit tests for `getSubPath`.

Resolves
  - containers#1992

Signed-off-by: David Beck <techiscool@gmail.com>
  • Loading branch information
TechIsCool committed May 15, 2024
1 parent d244a61 commit 83fb4f5
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
29 changes: 21 additions & 8 deletions cmd/skopeo/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,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'
RegistryName string // Name of the registry
ImageRefs []types.ImageReference // List of tagged image found for the repository
Context *types.SystemContext // SystemContext for the sync command
}

// tlsVerifyConfig is an implementation of the Unmarshaler interface, used to
Expand Down Expand Up @@ -374,8 +375,9 @@ func imagesToCopyFromRegistry(registryName string, cfg registrySyncConfig, sourc
continue
}
repoDescList = append(repoDescList, repoDescriptor{
ImageRefs: sourceReferences,
Context: serverCtx})
RegistryName: registryName,
ImageRefs: sourceReferences,
Context: serverCtx})
}

// include repository descriptors for cfg.ImagesByTagRegex
Expand Down Expand Up @@ -453,8 +455,9 @@ func filterSourceReferences(sys *types.SystemContext, registryName string, colle
}

repoDescList = append(repoDescList, repoDescriptor{
ImageRefs: filteredSourceReferences,
Context: sys,
RegistryName: registryName,
ImageRefs: filteredSourceReferences,
Context: sys,
})
}
return repoDescList
Expand Down Expand Up @@ -593,6 +596,16 @@ func imagesToCopy(source string, transport string, sourceCtx *types.SystemContex
return descriptors, nil
}

// getSubPath takes a full and base path string. Normally this looks like
// fullPath = "registry.fedoraproject.org/f38/flatpak-runtime:f38"
// basePath = "registry.fedoraproject.org"
// It returns a string with the basePath removed for example "f38/flatpak-runtime:f38".
func getSubPath(fullPath, basePath string) string {
cleanBasePath := filepath.Clean(basePath)
cleanFullPath := filepath.Clean(fullPath)
return strings.TrimPrefix(cleanFullPath, cleanBasePath+"/")
}

func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
if len(args) != 2 {
return errorShouldDisplayUsage{errors.New("Exactly two arguments expected")}
Expand Down Expand Up @@ -741,7 +754,7 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) (retErr error) {
}

if !opts.scoped {
destSuffix = path.Base(destSuffix)
destSuffix = getSubPath(destSuffix, srcRepo.RegistryName)
}

destRef, err := destinationReference(path.Join(destination, destSuffix)+opts.appendSuffix, opts.destination)
Expand Down
41 changes: 41 additions & 0 deletions cmd/skopeo/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,44 @@ func TestTLSVerifyConfig(t *testing.T) {
err := yaml.Unmarshal([]byte(`tls-verify: "not a valid bool"`), &config)
assert.Error(t, err)
}

func TestGetSubPath(t *testing.T) {
tests := []struct {
name string
registry string
fullPath string
expected string
}{
{
name: "Registry",
registry: "registry.fedoraproject.org",
fullPath: "registry.fedoraproject.org/f38/flatpak-runtime:f38",
expected: "f38/flatpak-runtime:f38",
},
{
name: "Registry with Subpath",
registry: "registry.fedoraproject.org/f38",
fullPath: "registry.fedoraproject.org/f38/flatpak-runtime:f38",
expected: "flatpak-runtime:f38",
},
{
name: "Dir without registry",
registry: "",
fullPath: "/media/usb/",
expected: "/media/usb",
},
{
name: "Repo without registy",
registry: "",
fullPath: "flatpak-runtime:f38",
expected: "flatpak-runtime:f38",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := getSubPath(tt.fullPath, tt.registry)
assert.Equal(t, tt.expected, result)
})
}
}

0 comments on commit 83fb4f5

Please sign in to comment.