Fix storageReference.tag for name:tag@digest

name:tag@digest is actually a valid input to reference.ParseNormalizedNamed;
the code used to set name:tag in s.name, but leave s.tag empty.

That happened to mostly work correctly, but for the wrong reasons.  So, fix
setting s.tag for name:tag@digest inputs, and then update DockerReference
to handle such cases.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač 2018-03-09 12:45:34 +01:00
parent 5b62b7d2ae
commit acf13f4d89
2 changed files with 10 additions and 10 deletions

View File

@ -116,19 +116,18 @@ func (s storageReference) DockerReference() reference.Named {
if s.name == nil {
return nil
}
name := s.name
if s.tag != "" {
if namedTagged, err := reference.WithTag(s.name, s.tag); err == nil {
return namedTagged
if namedTagged, err := reference.WithTag(name, s.tag); err == nil {
name = namedTagged
}
}
if s.digest != "" {
if canonical, err := reference.WithDigest(s.name, s.digest); err == nil {
return canonical
if canonical, err := reference.WithDigest(name, s.digest); err == nil {
name = canonical
}
}
// FIXME: This should never happen, ParseStoreReference sets name = reference.TagNameOnly(name) if s.digest == ""
// FIXME: This also violates the DockerReference contract.
return s.name
return name
}
// Return a name with a tag, prefixed with the graph root and driver name, to

View File

@ -236,11 +236,12 @@ func (s storageTransport) ParseStoreReference(store storage.Store, ref string) (
} else {
name = reference.TagNameOnly(name)
completeReference = reference.TagNameOnly(completeReference)
tagged, ok := name.(reference.Tagged)
if !ok {
if _, ok := name.(reference.Tagged); !ok { // Coverage: This should never happen; we check only to ensure that "tag" is set below.
return nil, errors.Errorf("error parsing possibly-tagless name %q", ref)
}
refname = name.String()
}
if tagged, ok := name.(reference.Tagged); ok {
tag = tagged.Tag()
}
}
@ -271,7 +272,7 @@ func (s *storageTransport) GetStore() (storage.Store, error) {
}
// ParseReference takes a name and a tag or digest and/or ID
// ("_name_"/"@_id_"/"_name_:_tag_"/"_name_:_tag_@_id_"/"_name_@_digest_"/"_name_@_digest_@_id_"),
// ("_name_"/"@_id_"/"_name_:_tag_"/"_name_:_tag_@_id_"/"_name_@_digest_"/"_name_@_digest_@_id_"/"_name_:_tag_@_digest_"/"_name_:_tag_@_digest_@_id_"),
// possibly prefixed with a store specifier in the form "[_graphroot_]" or
// "[_driver_@_graphroot_]" or "[_driver_@_graphroot_+_runroot_]" or
// "[_driver_@_graphroot_:_options_]" or "[_driver_@_graphroot_+_runroot_:_options_]",