From cce44c45d57e12addd3d9017d21038a3c11c563f Mon Sep 17 00:00:00 2001 From: Zach Hill Date: Tue, 20 Nov 2018 23:52:36 -0800 Subject: [PATCH 1/6] Adds "list-tags" command to list tags with no known tag required. Fixes #276 Example: skopeo list-tags docker://docker.io/library/centos Returns response: { Repository": "docker.io/library/centos", "Tags": [ "6", "7", ... ] } Signed-off-by: Zach Hill --- cmd/skopeo/list_tags.go | 142 ++++++++++++++++++++++++++++++++++ cmd/skopeo/list_tags_test.go | 62 +++++++++++++++ cmd/skopeo/main.go | 1 + completions/bash/skopeo | 16 +++- docs/skopeo-list-tags.1.md | 102 ++++++++++++++++++++++++ docs/skopeo.1.md | 1 + integration/list_tags_test.go | 22 ++++++ 7 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 cmd/skopeo/list_tags.go create mode 100644 cmd/skopeo/list_tags_test.go create mode 100644 docs/skopeo-list-tags.1.md create mode 100644 integration/list_tags_test.go diff --git a/cmd/skopeo/list_tags.go b/cmd/skopeo/list_tags.go new file mode 100644 index 00000000..40499a5a --- /dev/null +++ b/cmd/skopeo/list_tags.go @@ -0,0 +1,142 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "github.com/containers/image/v5/docker" + "github.com/containers/image/v5/transports" + "github.com/containers/image/v5/transports/alltransports" + "github.com/containers/image/v5/types" + "github.com/docker/distribution/reference" + "github.com/pkg/errors" + "github.com/urfave/cli" + "strings" + + "io" +) + +// tagListOutput is the output format of (skopeo list-tags), primarily so that we can format it with a simple json.MarshalIndent. +type tagListOutput struct { + Repository string + Tags []string +} + +type tagsOptions struct { + global *globalOptions + image *imageOptions +} + +func tagsCmd(global *globalOptions) cli.Command { + sharedFlags, sharedOpts := sharedImageFlags() + imageFlags, imageOpts := dockerImageFlags(global, sharedOpts, "", "") + + opts := tagsOptions{ + global: global, + image: imageOpts, + } + + return cli.Command{ + Name: "list-tags", + Usage: "List tags in the transport/repository specified by the REPOSITORY-NAME", + Description: ` + Return the list of tags from the transport/repository "REPOSITORY-NAME" + + Supported transports: + docker + + See skopeo-list-tags(1) section "REPOSITORY NAMES" for the expected format + `, + ArgsUsage: "REPOSITORY-NAME", + Flags: append(sharedFlags, imageFlags...), + Action: commandAction(opts.run), + } +} + +// Customized version of the alltransports.ParseImageName and docker.ParseReference that does not place a default tag in the reference +// Would really love to not have this, but needed to enforce tag-less and digest-less names +func parseDockerRepositoryReference(refString string) (types.ImageReference, error) { + parts := strings.SplitN(refString, ":", 2) + if len(parts) != 2 { + return nil, errors.Errorf(`Invalid image name "%s", expected colon-separated transport:reference`, refString) + } + + transport := transports.Get(parts[0]) + if transport == nil || transport.Name() != docker.Transport.Name() { + return nil, errors.New("Invalid transport, can only parse docker transport references") + } + + if !strings.HasPrefix(parts[1], "//") { + return nil, errors.Errorf("docker: image reference %s does not start with //", parts[1]) + } + + ref, err := reference.ParseNormalizedNamed(strings.TrimPrefix(parts[1], "//")) + if err != nil { + return nil, err + } + + if !reference.IsNameOnly(ref) { + return nil, errors.New(`No tag or digest allowed in reference`) + } + + // Checks ok, now return a reference. This is a hack because the tag listing code expects a full image reference even though the tag is ignored + return docker.NewReference(reference.TagNameOnly(ref)) +} + +func listDockerTags(ctx context.Context, sys *types.SystemContext, referenceInput string) (string, []string, error) { + imgRef, err := parseDockerRepositoryReference(referenceInput) + if err != nil { + return ``, nil, fmt.Errorf("Cannot parse repository reference: %v", err) + } + + repositoryName := imgRef.DockerReference().Name() + + tags, err := docker.GetRepositoryTags(ctx, sys, imgRef) + if err != nil { + return ``, nil, fmt.Errorf("Error listing repository tags: %v", err) + } + return repositoryName, tags, nil +} + +func (opts *tagsOptions) run(args []string, stdout io.Writer) (retErr error) { + ctx, cancel := opts.global.commandTimeoutContext() + defer cancel() + var repositoryName string + var tagListing []string + + if len(args) != 1 { + return errorShouldDisplayUsage{errors.New("Exactly one non-option argument expected")} + } + + sys, err := opts.image.newSystemContext() + if err != nil { + return err + } + + transport := alltransports.TransportFromImageName(args[0]) + if transport == nil { + return errors.New("Invalid transport") + } + + if transport.Name() == docker.Transport.Name() { + repositoryName, tagListing, err = listDockerTags(ctx, sys, args[0]) + if err != nil { + return err + } + } else { + return fmt.Errorf("Unsupported transport '%v' for tag listing. Only '%v' currently supported", transport.Name(), docker.Transport.Name()) + } + + outputData := tagListOutput{ + Repository: repositoryName, + Tags: tagListing, + } + + out, err := json.MarshalIndent(outputData, "", " ") + if err != nil { + return err + } + _, err = fmt.Fprintf(stdout, "%s\n", string(out)) + + return err +} diff --git a/cmd/skopeo/list_tags_test.go b/cmd/skopeo/list_tags_test.go new file mode 100644 index 00000000..e628bf42 --- /dev/null +++ b/cmd/skopeo/list_tags_test.go @@ -0,0 +1,62 @@ +package main + +import ( + "github.com/containers/image/v5/transports/alltransports" + "github.com/stretchr/testify/assert" + "testing" +) + +// Tests the kinds of inputs allowed and expected to the command +func TestDockerRepositoryReferenceParser(t *testing.T) { + for _, test := range [][]string{ + {"docker://myhost.com:1000/nginx", "myhost.com:1000/nginx"}, //no tag + {"docker://myhost.com/nginx", "myhost.com/nginx"}, //no port or tag + {"docker://somehost.com", "docker.io/library/somehost.com"}, // Valid default expansion + {"docker://nginx", "docker.io/library/nginx"}, // Valid default expansion + {"docker://myhost.com:1000/nginx:foobar:foobar", ""}, // Invalid repository ref + {"docker://somehost.com:5000/", ""}, // no repo + {"docker://myhost.com:1000/nginx:latest", ""}, //tag not allowed + {"docker://myhost.com:1000/nginx@sha256:abcdef1234567890", ""}, //digest not allowed + } { + + ref, err := parseDockerRepositoryReference(test[0]) + + if test[1] == "" { + assert.Error(t, err, "Expected error in parsing but no error raised for %v", test[0]) + } else { + if assert.NoError(t, err, "Could not parse, got error on %v", test[0]) { + assert.Equal(t, test[1], ref.DockerReference().Name(), "Mismatched parse result for input %v", test[0]) + } + } + } +} + +func TestDockerRepositoryReferenceParserDrift(t *testing.T) { + for _, test := range [][]string{ + {"docker://myhost.com:1000/nginx", "myhost.com:1000/nginx"}, //no tag + {"docker://myhost.com/nginx", "myhost.com/nginx"}, //no port or tag + {"docker://somehost.com", "docker.io/library/somehost.com"}, // Valid default expansion + {"docker://nginx", "docker.io/library/nginx"}, // Valid default expansion + } { + + ref, err := parseDockerRepositoryReference(test[0]) + ref2, err2 := alltransports.ParseImageName(test[0]) + + if assert.NoError(t, err, "Could not parse, got error on %v", test[0]) && assert.NoError(t, err2, "Could not parse with regular parser, got error on %v", test[0]) { + assert.Equal(t, ref.DockerReference().String(), ref2.DockerReference().String(), "Different parsing output for input %v. Repo parse = %v, regular parser = %v", test[0], ref, ref2) + } + } +} + +func TestUnsupportedRepositoryReferenceParser(t *testing.T) { + for _, test := range [][]string{ + {"oci://somedir"}, + {"dir:/somepath"}, + {"docker-archive:/tmp/dir"}, + {"container-storage:myhost.com/someimage"}, + {"docker-daemon:myhost.com/someimage"}, + } { + _, err := parseDockerRepositoryReference(test[0]) + assert.Error(t, err, test[0]) + } +} diff --git a/cmd/skopeo/main.go b/cmd/skopeo/main.go index df608063..278a8a00 100644 --- a/cmd/skopeo/main.go +++ b/cmd/skopeo/main.go @@ -102,6 +102,7 @@ func createApp() (*cli.App, *globalOptions) { standaloneSignCmd(), standaloneVerifyCmd(), untrustedSignatureDumpCmd(), + tagsCmd(&opts), } return app, &opts } diff --git a/completions/bash/skopeo b/completions/bash/skopeo index 4797408e..72e6bab5 100644 --- a/completions/bash/skopeo +++ b/completions/bash/skopeo @@ -144,6 +144,20 @@ _skopeo_layers() { _complete_ "$options_with_args" "$boolean_options" } +_skopeo_list_repository_tags() { + local options_with_args=" + --authfile + --creds + --cert-dir + " + + local boolean_options=" + --tls-verify + --no-creds + " + _complete_ "$options_with_args" "$boolean_options" +} + _skopeo_skopeo() { # XXX: Changes here need to be refleceted in the manually expanded # string in the `case` statement below as well. @@ -194,7 +208,7 @@ _cli_bash_autocomplete() { local counter=1 while [ $counter -lt "$cword" ]; do case "${words[$counter]}" in - skopeo|copy|inspect|delete|manifest-digest|standalone-sign|standalone-verify|help|h) + skopeo|copy|inspect|delete|manifest-digest|standalone-sign|standalone-verify|help|h|list-repository-tags) command="${words[$counter]//-/_}" cpos=$counter (( cpos++ )) diff --git a/docs/skopeo-list-tags.1.md b/docs/skopeo-list-tags.1.md new file mode 100644 index 00000000..90ed8091 --- /dev/null +++ b/docs/skopeo-list-tags.1.md @@ -0,0 +1,102 @@ +% skopeo-list-tags(1) + +## NAME +skopeo\-list\-tags - Return a list of tags the transport-specific image repository + +## SYNOPSIS +**skopeo list-tags** _repository-name_ + +Return a list of tags from _repository-name_ in a registry. + + _repository-name_ name of repository to retrieve tag listing from + + **--authfile** _path_ + + Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`. + If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`. + + **--creds** _username[:password]_ for accessing the registry + + **--cert-dir** _path_ Use certificates at _path_ (\*.crt, \*.cert, \*.key) to connect to the registry + + **--tls-verify** _bool-value_ Require HTTPS and verify certificates when talking to container registries (defaults to true) + + **--no-creds** _bool-value_ Access the registry anonymously. + +## REPOSITORY NAMES + +Repository names are transport-specific references as each transport may have its own concept of a "repository" and "tags". Currently, only the Docker transport is supported. + +This commands refers to repositories using a _transport_`:`_details_ format. The following formats are supported: + + **docker://**_docker-repository-reference_ + A repository in a registry implementing the "Docker Registry HTTP API V2". By default, uses the authorization state in either `$XDG_RUNTIME_DIR/containers/auth.json`, which is set using `(podman login)`. If the authorization state is not found there, `$HOME/.docker/config.json` is checked, which is set using `(docker login)`. + A _docker-repository-reference_ is of the form: **registryhost:port/repositoryname** which is similar to an _image-reference_ but with no tag or digest allowed as the last component (e.g no `:latest` or `@sha256:xyz`) + + Examples of valid docker-repository-references: + "docker.io/myuser/myrepo" + "docker.io/nginx" + "docker.io/library/fedora" + "localhost:5000/myrepository" + + Examples of invalid references: + "docker.io/nginx:latest" + "docker.io/myuser/myimage:v1.0" + "docker.io/myuser/myimage@sha256:f48c4cc192f4c3c6a069cb5cca6d0a9e34d6076ba7c214fd0cc3ca60e0af76bb" + + +## EXAMPLES + +### Docker Transport +To get the list of tags in the "fedora" repository from the docker.io registry (the repository name expands to "library/fedora" per docker transport canonical form): +```sh +$ skopeo list-tags docker://docker.io/fedora +{ + "Repository": "docker.io/library/fedora", + "Tags": [ + "20", + "21", + "22", + "23", + "24", + "25", + "26-modular", + "26", + "27", + "28", + "29", + "30", + "31", + "32", + "branched", + "heisenbug", + "latest", + "modular", + "rawhide" + ] +} + +``` + +To list the tags in a local host docker/distribution registry on port 5000, in this case for the "fedora" repository: + +```sh +$ skopeo list-tags docker://localhost:5000/fedora +{ + "Repository": "localhost:5000/myapp", + "Tags": [ + "latest", + "v1.1.1", + "v1.2.0" + ] +} + +``` + +# SEE ALSO +skopeo(1), podman-login(1), docker-login(1) + +## AUTHORS + +Zach Hill + diff --git a/docs/skopeo.1.md b/docs/skopeo.1.md index dca05ec6..4adcbb66 100644 --- a/docs/skopeo.1.md +++ b/docs/skopeo.1.md @@ -75,6 +75,7 @@ Most commands refer to container images, using a _transport_`:`_details_ format. | [skopeo-standalone-sign(1)](skopeo-standalone-sign.1.md) | Sign an image. | | [skopeo-standalone-verify(1)](skopeo-standalone-verify.1.md)| Verify an image. | | [skopeo-sync(1)](skopeo-sync.1.md)| Copy images from one or more repositories to a user specified destination. | +| [skopeo-list-tags(1)](skopeo-list-tags.1.md) | List the tags for the given transport/repository. | ## FILES **/etc/containers/policy.json** diff --git a/integration/list_tags_test.go b/integration/list_tags_test.go new file mode 100644 index 00000000..a3d7e5c1 --- /dev/null +++ b/integration/list_tags_test.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/go-check/check" +) + +func init() { + check.Suite(&TagListSuite{}) +} + +type TagListSuite struct { + registry *testRegistryV2 +} + +// Simple tag listing +func (s *TagListSuite) TestListSimple(c *check.C) { + assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://docker.io/library/centos") + assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://centos") + assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://docker.io/centos") + assertSkopeoFails(c, ".*No tag or digest allowed.*", "", "list-tags", "docker://docker.io/centos:7") + assertSkopeoFails(c, ".*Unsupported transport.*", "", "list-tags", "docker-daemon://docker.io/centos:7") +} From b0cfab1d4589ba167a10d6932e1e94a02ff4b9e4 Mon Sep 17 00:00:00 2001 From: Zach Hill Date: Thu, 16 Jan 2020 15:33:26 -0800 Subject: [PATCH 2/6] Fix formatting on test Signed-off-by: Zach Hill --- cmd/skopeo/list_tags_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/skopeo/list_tags_test.go b/cmd/skopeo/list_tags_test.go index e628bf42..07ab2f6e 100644 --- a/cmd/skopeo/list_tags_test.go +++ b/cmd/skopeo/list_tags_test.go @@ -33,10 +33,10 @@ func TestDockerRepositoryReferenceParser(t *testing.T) { func TestDockerRepositoryReferenceParserDrift(t *testing.T) { for _, test := range [][]string{ - {"docker://myhost.com:1000/nginx", "myhost.com:1000/nginx"}, //no tag - {"docker://myhost.com/nginx", "myhost.com/nginx"}, //no port or tag - {"docker://somehost.com", "docker.io/library/somehost.com"}, // Valid default expansion - {"docker://nginx", "docker.io/library/nginx"}, // Valid default expansion + {"docker://myhost.com:1000/nginx", "myhost.com:1000/nginx"}, //no tag + {"docker://myhost.com/nginx", "myhost.com/nginx"}, //no port or tag + {"docker://somehost.com", "docker.io/library/somehost.com"}, // Valid default expansion + {"docker://nginx", "docker.io/library/nginx"}, // Valid default expansion } { ref, err := parseDockerRepositoryReference(test[0]) From 5554964a8fc5da29faf58655b87a64d4661e8ed3 Mon Sep 17 00:00:00 2001 From: Zach Hill Date: Mon, 3 Feb 2020 22:14:46 -0800 Subject: [PATCH 3/6] Fix inconsistency in manpage example for list-tags Signed-off-by: Zach Hill --- docs/skopeo-list-tags.1.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/skopeo-list-tags.1.md b/docs/skopeo-list-tags.1.md index 90ed8091..e797aa0a 100644 --- a/docs/skopeo-list-tags.1.md +++ b/docs/skopeo-list-tags.1.md @@ -83,11 +83,11 @@ To list the tags in a local host docker/distribution registry on port 5000, in t ```sh $ skopeo list-tags docker://localhost:5000/fedora { - "Repository": "localhost:5000/myapp", + "Repository": "localhost:5000/fedora", "Tags": [ "latest", - "v1.1.1", - "v1.2.0" + "30", + "31" ] } From 36fdc062babd94b062706c16758fab6f60bbcd94 Mon Sep 17 00:00:00 2001 From: Zach Hill Date: Tue, 4 Feb 2020 00:47:52 -0800 Subject: [PATCH 4/6] Updates based on code review to simplify logic and tests Signed-off-by: Zach Hill --- cmd/skopeo/list_tags.go | 44 +++++++++++++----------------- cmd/skopeo/list_tags_test.go | 50 +++++++++++++++-------------------- integration/list_tags_test.go | 14 +++++----- 3 files changed, 47 insertions(+), 61 deletions(-) diff --git a/cmd/skopeo/list_tags.go b/cmd/skopeo/list_tags.go index 40499a5a..b2786406 100644 --- a/cmd/skopeo/list_tags.go +++ b/cmd/skopeo/list_tags.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "github.com/containers/image/v5/docker" - "github.com/containers/image/v5/transports" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" "github.com/docker/distribution/reference" @@ -56,20 +55,15 @@ func tagsCmd(global *globalOptions) cli.Command { // Customized version of the alltransports.ParseImageName and docker.ParseReference that does not place a default tag in the reference // Would really love to not have this, but needed to enforce tag-less and digest-less names func parseDockerRepositoryReference(refString string) (types.ImageReference, error) { + if !strings.HasPrefix(refString, docker.Transport.Name()+"://") { + return nil, errors.Errorf("docker: image reference %s does not start with %s://", refString, docker.Transport.Name()) + } + parts := strings.SplitN(refString, ":", 2) if len(parts) != 2 { return nil, errors.Errorf(`Invalid image name "%s", expected colon-separated transport:reference`, refString) } - transport := transports.Get(parts[0]) - if transport == nil || transport.Name() != docker.Transport.Name() { - return nil, errors.New("Invalid transport, can only parse docker transport references") - } - - if !strings.HasPrefix(parts[1], "//") { - return nil, errors.Errorf("docker: image reference %s does not start with //", parts[1]) - } - ref, err := reference.ParseNormalizedNamed(strings.TrimPrefix(parts[1], "//")) if err != nil { return nil, err @@ -83,12 +77,8 @@ func parseDockerRepositoryReference(refString string) (types.ImageReference, err return docker.NewReference(reference.TagNameOnly(ref)) } -func listDockerTags(ctx context.Context, sys *types.SystemContext, referenceInput string) (string, []string, error) { - imgRef, err := parseDockerRepositoryReference(referenceInput) - if err != nil { - return ``, nil, fmt.Errorf("Cannot parse repository reference: %v", err) - } - +// List the tags from a repository contained in the imgRef reference. Any tag value in the reference is ignored +func listDockerTags(ctx context.Context, sys *types.SystemContext, imgRef types.ImageReference) (string, []string, error) { repositoryName := imgRef.DockerReference().Name() tags, err := docker.GetRepositoryTags(ctx, sys, imgRef) @@ -101,8 +91,6 @@ func listDockerTags(ctx context.Context, sys *types.SystemContext, referenceInpu func (opts *tagsOptions) run(args []string, stdout io.Writer) (retErr error) { ctx, cancel := opts.global.commandTimeoutContext() defer cancel() - var repositoryName string - var tagListing []string if len(args) != 1 { return errorShouldDisplayUsage{errors.New("Exactly one non-option argument expected")} @@ -115,18 +103,24 @@ func (opts *tagsOptions) run(args []string, stdout io.Writer) (retErr error) { transport := alltransports.TransportFromImageName(args[0]) if transport == nil { - return errors.New("Invalid transport") + return fmt.Errorf("Invalid %q: does not specify a transport", args[0]) } - if transport.Name() == docker.Transport.Name() { - repositoryName, tagListing, err = listDockerTags(ctx, sys, args[0]) - if err != nil { - return err - } - } else { + if transport.Name() != docker.Transport.Name() { return fmt.Errorf("Unsupported transport '%v' for tag listing. Only '%v' currently supported", transport.Name(), docker.Transport.Name()) } + // Do transport-specific parsing and validation to get an image reference + imgRef, err := parseDockerRepositoryReference(args[0]) + if err != nil { + return err + } + + repositoryName, tagListing, err := listDockerTags(ctx, sys, imgRef) + if err != nil { + return err + } + outputData := tagListOutput{ Repository: repositoryName, Tags: tagListing, diff --git a/cmd/skopeo/list_tags_test.go b/cmd/skopeo/list_tags_test.go index 07ab2f6e..33e6a9d4 100644 --- a/cmd/skopeo/list_tags_test.go +++ b/cmd/skopeo/list_tags_test.go @@ -9,26 +9,33 @@ import ( // Tests the kinds of inputs allowed and expected to the command func TestDockerRepositoryReferenceParser(t *testing.T) { for _, test := range [][]string{ - {"docker://myhost.com:1000/nginx", "myhost.com:1000/nginx"}, //no tag - {"docker://myhost.com/nginx", "myhost.com/nginx"}, //no port or tag - {"docker://somehost.com", "docker.io/library/somehost.com"}, // Valid default expansion - {"docker://nginx", "docker.io/library/nginx"}, // Valid default expansion - {"docker://myhost.com:1000/nginx:foobar:foobar", ""}, // Invalid repository ref - {"docker://somehost.com:5000/", ""}, // no repo - {"docker://myhost.com:1000/nginx:latest", ""}, //tag not allowed - {"docker://myhost.com:1000/nginx@sha256:abcdef1234567890", ""}, //digest not allowed + {"docker://myhost.com:1000/nginx"}, //no tag + {"docker://myhost.com/nginx"}, //no port or tag + {"docker://somehost.com"}, // Valid default expansion + {"docker://nginx"}, // Valid default expansion } { ref, err := parseDockerRepositoryReference(test[0]) - - if test[1] == "" { - assert.Error(t, err, "Expected error in parsing but no error raised for %v", test[0]) - } else { - if assert.NoError(t, err, "Could not parse, got error on %v", test[0]) { - assert.Equal(t, test[1], ref.DockerReference().Name(), "Mismatched parse result for input %v", test[0]) - } + expected, err := alltransports.ParseImageName(test[0]) + if assert.NoError(t, err, "Could not parse, got error on %v", test[0]) { + assert.Equal(t, expected.DockerReference().Name(), ref.DockerReference().Name(), "Mismatched parse result for input %v", test[0]) } } + + for _, test := range [][]string{ + {"oci://somedir"}, + {"dir:/somepath"}, + {"docker-archive:/tmp/dir"}, + {"container-storage:myhost.com/someimage"}, + {"docker-daemon:myhost.com/someimage"}, + {"docker://myhost.com:1000/nginx:foobar:foobar"}, // Invalid repository ref + {"docker://somehost.com:5000/"}, // no repo + {"docker://myhost.com:1000/nginx:latest"}, //tag not allowed + {"docker://myhost.com:1000/nginx@sha256:abcdef1234567890"}, //digest not allowed + } { + _, err := parseDockerRepositoryReference(test[0]) + assert.Error(t, err, test[0]) + } } func TestDockerRepositoryReferenceParserDrift(t *testing.T) { @@ -47,16 +54,3 @@ func TestDockerRepositoryReferenceParserDrift(t *testing.T) { } } } - -func TestUnsupportedRepositoryReferenceParser(t *testing.T) { - for _, test := range [][]string{ - {"oci://somedir"}, - {"dir:/somepath"}, - {"docker-archive:/tmp/dir"}, - {"container-storage:myhost.com/someimage"}, - {"docker-daemon:myhost.com/someimage"}, - } { - _, err := parseDockerRepositoryReference(test[0]) - assert.Error(t, err, test[0]) - } -} diff --git a/integration/list_tags_test.go b/integration/list_tags_test.go index a3d7e5c1..a122987e 100644 --- a/integration/list_tags_test.go +++ b/integration/list_tags_test.go @@ -8,15 +8,13 @@ func init() { check.Suite(&TagListSuite{}) } -type TagListSuite struct { - registry *testRegistryV2 -} +type TagListSuite struct {} // Simple tag listing func (s *TagListSuite) TestListSimple(c *check.C) { - assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://docker.io/library/centos") - assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://centos") - assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://docker.io/centos") - assertSkopeoFails(c, ".*No tag or digest allowed.*", "", "list-tags", "docker://docker.io/centos:7") - assertSkopeoFails(c, ".*Unsupported transport.*", "", "list-tags", "docker-daemon://docker.io/centos:7") + //assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://docker.io/library/centos") + //assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://centos") + //assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://docker.io/centos") + //assertSkopeoFails(c, ".*No tag or digest allowed.*", "", "list-tags", "docker://docker.io/centos:7") + //ssertSkopeoFails(c, ".*Unsupported transport.*", "", "list-tags", "docker-daemon:docker.io/centos:7") } From a9854e1173099f855005d038c5b3e3316a0a3cb4 Mon Sep 17 00:00:00 2001 From: Zach Hill Date: Tue, 4 Feb 2020 10:44:18 -0800 Subject: [PATCH 5/6] Remove the list_tags integration test since it does not cover much not already tested by the upstream container/images repo or local unit tests Signed-off-by: Zach Hill --- integration/list_tags_test.go | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 integration/list_tags_test.go diff --git a/integration/list_tags_test.go b/integration/list_tags_test.go deleted file mode 100644 index a122987e..00000000 --- a/integration/list_tags_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "github.com/go-check/check" -) - -func init() { - check.Suite(&TagListSuite{}) -} - -type TagListSuite struct {} - -// Simple tag listing -func (s *TagListSuite) TestListSimple(c *check.C) { - //assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://docker.io/library/centos") - //assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://centos") - //assertSkopeoSucceeds(c, `.*Repository: docker\.io/library/centos.*`, "list-tags", "docker://docker.io/centos") - //assertSkopeoFails(c, ".*No tag or digest allowed.*", "", "list-tags", "docker://docker.io/centos:7") - //ssertSkopeoFails(c, ".*Unsupported transport.*", "", "list-tags", "docker-daemon:docker.io/centos:7") -} From 07c89b49ffa59e75e9f82da29ff2fea5c32e1189 Mon Sep 17 00:00:00 2001 From: Zach Hill Date: Wed, 12 Feb 2020 14:05:55 -0800 Subject: [PATCH 6/6] Fix wrong import of docker reference Signed-off-by: Zach Hill --- cmd/skopeo/list_tags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/skopeo/list_tags.go b/cmd/skopeo/list_tags.go index b2786406..e56ed1c1 100644 --- a/cmd/skopeo/list_tags.go +++ b/cmd/skopeo/list_tags.go @@ -5,9 +5,9 @@ import ( "encoding/json" "fmt" "github.com/containers/image/v5/docker" + "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" - "github.com/docker/distribution/reference" "github.com/pkg/errors" "github.com/urfave/cli" "strings"