Skip to content

Commit

Permalink
Fix containers#858 Add --all sync flag to emulate copy --all
Browse files Browse the repository at this point in the history
This replicates the --all copy flag to sync to perform the same
behavior. Namely, the default is CopySystemImage unless --all is passed
which changes the behavior to CopyAllImages. While it is probably
desirable for --all to be the default as there is no option to override
ones architecture with the sync command, --all can potentially break
existing sync incantations depending on registry support. Hence
CopySystemImage remains the default.

Signed-off-by: Andrew DeMaria <[email protected]>
  • Loading branch information
muff1nman committed Nov 16, 2020
1 parent 1a3eb47 commit 873fbee
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
16 changes: 12 additions & 4 deletions cmd/skopeo/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type syncOptions struct {
source string // Source repository name
destination string // Destination registry name
scoped bool // When true, namespace copied images at destination using the source repository name
all bool // Copy all of the images if an image in the source is a list
}

// repoDescriptor contains information of a single repository used as a sync source.
Expand Down Expand Up @@ -97,6 +98,7 @@ See skopeo-sync(1) for details.
flags.StringVarP(&opts.source, "src", "s", "", "SOURCE transport type")
flags.StringVarP(&opts.destination, "dest", "d", "", "DESTINATION transport type")
flags.BoolVar(&opts.scoped, "scoped", false, "Images at DESTINATION are prefix using the full source image path as scope")
flags.BoolVarP(&opts.all, "all", "a", false, "Copy all images if SOURCE-IMAGE is a list")
flags.AddFlagSet(&sharedFlags)
flags.AddFlagSet(&srcFlags)
flags.AddFlagSet(&destFlags)
Expand Down Expand Up @@ -523,6 +525,11 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) error {
return errors.New("sync from 'dir' to 'dir' not implemented, consider using rsync instead")
}

imageListSelection := copy.CopySystemImage
if opts.all {
imageListSelection = copy.CopyAllImages
}

sourceCtx, err := opts.srcImage.newSystemContext()
if err != nil {
return err
Expand All @@ -548,10 +555,11 @@ func (opts *syncOptions) run(args []string, stdout io.Writer) error {

imagesNumber := 0
options := copy.Options{
RemoveSignatures: opts.removeSignatures,
SignBy: opts.signByFingerprint,
ReportWriter: os.Stdout,
DestinationCtx: destinationCtx,
RemoveSignatures: opts.removeSignatures,
SignBy: opts.signByFingerprint,
ReportWriter: os.Stdout,
DestinationCtx: destinationCtx,
ImageListSelection: imageListSelection,
}

for _, srcRepo := range srcRepoList {
Expand Down
5 changes: 5 additions & 0 deletions docs/skopeo-sync.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ When the `--scoped` option is specified, images are prefixed with the source ima
name can be stored at _destination_.

## OPTIONS
**--all**
If one of the images in __src__ refers to a list of images, instead of copying just the image which matches the current OS and
architecture (subject to the use of the global --override-os, --override-arch and --override-variant options), attempt to copy all of
the images in the list, and the list itself.

**--authfile** _path_

Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `skopeo login`.
Expand Down
28 changes: 28 additions & 0 deletions integration/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,34 @@ func (s *SyncSuite) TestDocker2DirTagged(c *check.C) {
c.Assert(out, check.Equals, "")
}

func (s *SyncSuite) TestDocker2DirTaggedAll(c *check.C) {
tmpDir, err := ioutil.TempDir("", "skopeo-sync-test")
c.Assert(err, check.IsNil)
defer os.RemoveAll(tmpDir)

// FIXME: It would be nice to use one of the local Docker registries instead of neeeding an Internet connection.
image := "busybox:latest"
imageRef, err := docker.ParseReference(fmt.Sprintf("//%s", image))
c.Assert(err, check.IsNil)
imagePath := imageRef.DockerReference().String()

dir1 := path.Join(tmpDir, "dir1")
dir2 := path.Join(tmpDir, "dir2")

// sync docker => dir
assertSkopeoSucceeds(c, "", "sync", "--all", "--scoped", "--src", "docker", "--dest", "dir", image, dir1)
_, err = os.Stat(path.Join(dir1, imagePath, "manifest.json"))
c.Assert(err, check.IsNil)

// copy docker => dir
assertSkopeoSucceeds(c, "", "copy", "--all", "docker:https://"+image, "dir:"+dir2)
_, err = os.Stat(path.Join(dir2, "manifest.json"))
c.Assert(err, check.IsNil)

out := combinedOutputOfCommand(c, "diff", "-urN", path.Join(dir1, imagePath), dir2)
c.Assert(out, check.Equals, "")
}

func (s *SyncSuite) TestScoped(c *check.C) {
// FIXME: It would be nice to use one of the local Docker registries instead of needing an Internet connection.
image := "busybox:latest"
Expand Down

0 comments on commit 873fbee

Please sign in to comment.