Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -522,21 +522,9 @@ func rewriteDockerfileFrom(dockerfileName string, translator func(reference.Name |
| 522 | 522 |
if err != nil {
|
| 523 | 523 |
return nil, nil, err |
| 524 | 524 |
} |
| 525 |
- |
|
| 526 |
- digested := false |
|
| 527 |
- switch ref.(type) {
|
|
| 528 |
- case reference.NamedTagged: |
|
| 529 |
- case reference.Canonical: |
|
| 530 |
- digested = true |
|
| 531 |
- default: |
|
| 532 |
- ref, err = reference.WithTag(ref, reference.DefaultTag) |
|
| 533 |
- if err != nil {
|
|
| 534 |
- return nil, nil, err |
|
| 535 |
- } |
|
| 536 |
- } |
|
| 537 |
- |
|
| 538 |
- if !digested && isTrusted() {
|
|
| 539 |
- trustedRef, err := translator(ref.(reference.NamedTagged)) |
|
| 525 |
+ ref = reference.WithDefaultTag(ref) |
|
| 526 |
+ if ref, ok := ref.(reference.NamedTagged); ok && isTrusted() {
|
|
| 527 |
+ trustedRef, err := translator(ref) |
|
| 540 | 528 |
if err != nil {
|
| 541 | 529 |
return nil, nil, err |
| 542 | 530 |
} |
| ... | ... |
@@ -544,7 +532,7 @@ func rewriteDockerfileFrom(dockerfileName string, translator func(reference.Name |
| 544 | 544 |
line = dockerfileFromLinePattern.ReplaceAllLiteralString(line, fmt.Sprintf("FROM %s", trustedRef.String()))
|
| 545 | 545 |
resolvedTags = append(resolvedTags, &resolvedTag{
|
| 546 | 546 |
digestRef: trustedRef, |
| 547 |
- tagRef: ref.(reference.NamedTagged), |
|
| 547 |
+ tagRef: ref, |
|
| 548 | 548 |
}) |
| 549 | 549 |
} |
| 550 | 550 |
} |
| ... | ... |
@@ -25,14 +25,11 @@ func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error {
|
| 25 | 25 |
} |
| 26 | 26 |
|
| 27 | 27 |
var tag string |
| 28 |
- switch x := ref.(type) {
|
|
| 28 |
+ switch x := reference.WithDefaultTag(ref).(type) {
|
|
| 29 | 29 |
case reference.Canonical: |
| 30 | 30 |
tag = x.Digest().String() |
| 31 | 31 |
case reference.NamedTagged: |
| 32 | 32 |
tag = x.Tag() |
| 33 |
- default: |
|
| 34 |
- // pull only the image tagged 'latest' if no tag was specified |
|
| 35 |
- tag = reference.DefaultTag |
|
| 36 | 33 |
} |
| 37 | 34 |
|
| 38 | 35 |
// Resolve the Repository name from fqn to RepositoryInfo |
| ... | ... |
@@ -97,24 +94,13 @@ func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runc |
| 97 | 97 |
if err != nil {
|
| 98 | 98 |
return nil, err |
| 99 | 99 |
} |
| 100 |
- |
|
| 101 |
- isCanonical := false |
|
| 102 |
- switch ref.(type) {
|
|
| 103 |
- case reference.NamedTagged: |
|
| 104 |
- case reference.Canonical: |
|
| 105 |
- isCanonical = true |
|
| 106 |
- default: |
|
| 107 |
- ref, err = reference.WithTag(ref, reference.DefaultTag) |
|
| 108 |
- if err != nil {
|
|
| 109 |
- return nil, err |
|
| 110 |
- } |
|
| 111 |
- } |
|
| 100 |
+ ref = reference.WithDefaultTag(ref) |
|
| 112 | 101 |
|
| 113 | 102 |
var trustedRef reference.Canonical |
| 114 | 103 |
|
| 115 |
- if isTrusted() && !isCanonical {
|
|
| 104 |
+ if ref, ok := ref.(reference.NamedTagged); ok && isTrusted() {
|
|
| 116 | 105 |
var err error |
| 117 |
- trustedRef, err = cli.trustedReference(ref.(reference.NamedTagged)) |
|
| 106 |
+ trustedRef, err = cli.trustedReference(ref) |
|
| 118 | 107 |
if err != nil {
|
| 119 | 108 |
return nil, err |
| 120 | 109 |
} |
| ... | ... |
@@ -132,8 +118,8 @@ func (cli *DockerCli) createContainer(config *runconfig.Config, hostConfig *runc |
| 132 | 132 |
if err = cli.pullImageCustomOut(config.Image, cli.err); err != nil {
|
| 133 | 133 |
return nil, err |
| 134 | 134 |
} |
| 135 |
- if trustedRef != nil && !isCanonical {
|
|
| 136 |
- if err := cli.tagTrusted(trustedRef, ref.(reference.NamedTagged)); err != nil {
|
|
| 135 |
+ if ref, ok := ref.(reference.NamedTagged); ok && trustedRef != nil {
|
|
| 136 |
+ if err := cli.tagTrusted(trustedRef, ref); err != nil {
|
|
| 137 | 137 |
return nil, err |
| 138 | 138 |
} |
| 139 | 139 |
} |
| ... | ... |
@@ -13,8 +13,6 @@ import ( |
| 13 | 13 |
"github.com/docker/docker/registry" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
-var errTagCantBeUsed = errors.New("tag can't be used with --all-tags/-a")
|
|
| 17 |
- |
|
| 18 | 16 |
// CmdPull pulls an image or a repository from the registry. |
| 19 | 17 |
// |
| 20 | 18 |
// Usage: docker pull [OPTIONS] IMAGENAME[:TAG|@DIGEST] |
| ... | ... |
@@ -31,28 +29,21 @@ func (cli *DockerCli) CmdPull(args ...string) error {
|
| 31 | 31 |
if err != nil {
|
| 32 | 32 |
return err |
| 33 | 33 |
} |
| 34 |
+ if *allTags && !reference.IsNameOnly(distributionRef) {
|
|
| 35 |
+ return errors.New("tag can't be used with --all-tags/-a")
|
|
| 36 |
+ } |
|
| 37 |
+ |
|
| 38 |
+ if !*allTags && reference.IsNameOnly(distributionRef) {
|
|
| 39 |
+ distributionRef = reference.WithDefaultTag(distributionRef) |
|
| 40 |
+ fmt.Fprintf(cli.out, "Using default tag: %s\n", reference.DefaultTag) |
|
| 41 |
+ } |
|
| 34 | 42 |
|
| 35 | 43 |
var tag string |
| 36 | 44 |
switch x := distributionRef.(type) {
|
| 37 | 45 |
case reference.Canonical: |
| 38 |
- if *allTags {
|
|
| 39 |
- return errTagCantBeUsed |
|
| 40 |
- } |
|
| 41 | 46 |
tag = x.Digest().String() |
| 42 | 47 |
case reference.NamedTagged: |
| 43 |
- if *allTags {
|
|
| 44 |
- return errTagCantBeUsed |
|
| 45 |
- } |
|
| 46 | 48 |
tag = x.Tag() |
| 47 |
- default: |
|
| 48 |
- if !*allTags {
|
|
| 49 |
- tag = reference.DefaultTag |
|
| 50 |
- distributionRef, err = reference.WithTag(distributionRef, tag) |
|
| 51 |
- if err != nil {
|
|
| 52 |
- return err |
|
| 53 |
- } |
|
| 54 |
- fmt.Fprintf(cli.out, "Using default tag: %s\n", tag) |
|
| 55 |
- } |
|
| 56 | 49 |
} |
| 57 | 50 |
|
| 58 | 51 |
ref := registry.ParseReference(tag) |
| ... | ... |
@@ -28,9 +28,8 @@ func (cli *DockerCli) CmdTag(args ...string) error {
|
| 28 | 28 |
return errors.New("refusing to create a tag with a digest reference")
|
| 29 | 29 |
} |
| 30 | 30 |
|
| 31 |
- tag := "" |
|
| 32 |
- tagged, isTagged := ref.(reference.NamedTagged) |
|
| 33 |
- if isTagged {
|
|
| 31 |
+ var tag string |
|
| 32 |
+ if tagged, isTagged := ref.(reference.NamedTagged); isTagged {
|
|
| 34 | 33 |
tag = tagged.Tag() |
| 35 | 34 |
} |
| 36 | 35 |
|
| ... | ... |
@@ -334,9 +334,11 @@ func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registr |
| 334 | 334 |
return err |
| 335 | 335 |
} |
| 336 | 336 |
trustedRef, err := reference.WithDigest(repoInfo, r.digest) |
| 337 |
+ if err != nil {
|
|
| 338 |
+ return err |
|
| 339 |
+ } |
|
| 337 | 340 |
if err := cli.tagTrusted(trustedRef, tagged); err != nil {
|
| 338 | 341 |
return err |
| 339 |
- |
|
| 340 | 342 |
} |
| 341 | 343 |
} |
| 342 | 344 |
} |
| ... | ... |
@@ -154,8 +154,7 @@ func (s *router) postImagesCreate(ctx context.Context, w http.ResponseWriter, r |
| 154 | 154 |
return err |
| 155 | 155 |
} |
| 156 | 156 |
|
| 157 |
- switch newRef.(type) {
|
|
| 158 |
- case reference.Canonical: |
|
| 157 |
+ if _, isCanonical := newRef.(reference.Canonical); isCanonical {
|
|
| 159 | 158 |
return errors.New("cannot import digest reference")
|
| 160 | 159 |
} |
| 161 | 160 |
|
| ... | ... |
@@ -496,15 +495,12 @@ func sanitizeRepoAndTags(names []string) ([]reference.Named, error) {
|
| 496 | 496 |
if err != nil {
|
| 497 | 497 |
return nil, err |
| 498 | 498 |
} |
| 499 |
+ ref = reference.WithDefaultTag(ref) |
|
| 499 | 500 |
|
| 500 | 501 |
if _, isCanonical := ref.(reference.Canonical); isCanonical {
|
| 501 | 502 |
return nil, errors.New("build tag cannot contain a digest")
|
| 502 | 503 |
} |
| 503 | 504 |
|
| 504 |
- if _, isTagged := ref.(reference.NamedTagged); !isTagged {
|
|
| 505 |
- ref, err = reference.WithTag(ref, reference.DefaultTag) |
|
| 506 |
- } |
|
| 507 |
- |
|
| 508 | 505 |
nameWithTag := ref.String() |
| 509 | 506 |
|
| 510 | 507 |
if _, exists := uniqNames[nameWithTag]; !exists {
|
| ... | ... |
@@ -41,15 +41,7 @@ func (d Docker) Pull(name string) (*image.Image, error) {
|
| 41 | 41 |
if err != nil {
|
| 42 | 42 |
return nil, err |
| 43 | 43 |
} |
| 44 |
- switch ref.(type) {
|
|
| 45 |
- case reference.NamedTagged: |
|
| 46 |
- case reference.Canonical: |
|
| 47 |
- default: |
|
| 48 |
- ref, err = reference.WithTag(ref, "latest") |
|
| 49 |
- if err != nil {
|
|
| 50 |
- return nil, err |
|
| 51 |
- } |
|
| 52 |
- } |
|
| 44 |
+ ref = reference.WithDefaultTag(ref) |
|
| 53 | 45 |
|
| 54 | 46 |
pullRegistryAuth := &types.AuthConfig{}
|
| 55 | 47 |
if len(d.AuthConfigs) > 0 {
|
| ... | ... |
@@ -149,17 +149,7 @@ func (daemon *Daemon) getContainerUsingImage(imageID image.ID) *container.Contai |
| 149 | 149 |
// optional tag or digest reference. If tag or digest is omitted, the default |
| 150 | 150 |
// tag is used. Returns the resolved image reference and an error. |
| 151 | 151 |
func (daemon *Daemon) removeImageRef(ref reference.Named) (reference.Named, error) {
|
| 152 |
- switch ref.(type) {
|
|
| 153 |
- case reference.NamedTagged: |
|
| 154 |
- case reference.Canonical: |
|
| 155 |
- default: |
|
| 156 |
- var err error |
|
| 157 |
- ref, err = reference.WithTag(ref, reference.DefaultTag) |
|
| 158 |
- if err != nil {
|
|
| 159 |
- return nil, err |
|
| 160 |
- } |
|
| 161 |
- } |
|
| 162 |
- |
|
| 152 |
+ ref = reference.WithDefaultTag(ref) |
|
| 163 | 153 |
// Ignore the boolean value returned, as far as we're concerned, this |
| 164 | 154 |
// is an idempotent operation and it's okay if the reference didn't |
| 165 | 155 |
// exist in the first place. |
| ... | ... |
@@ -54,10 +54,7 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named) (fallback bool |
| 54 | 54 |
|
| 55 | 55 |
func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named) (err error) {
|
| 56 | 56 |
var refs []reference.Named |
| 57 |
- taggedName := ref |
|
| 58 |
- if _, isTagged := ref.(reference.NamedTagged); isTagged {
|
|
| 59 |
- refs = []reference.Named{ref}
|
|
| 60 |
- } else if _, isCanonical := ref.(reference.Canonical); isCanonical {
|
|
| 57 |
+ if !reference.IsNameOnly(ref) {
|
|
| 61 | 58 |
refs = []reference.Named{ref}
|
| 62 | 59 |
} else {
|
| 63 | 60 |
manSvc, err := p.repo.Manifests(ctx) |
| ... | ... |
@@ -92,7 +89,7 @@ func (p *v2Puller) pullV2Repository(ctx context.Context, ref reference.Named) (e |
| 92 | 92 |
layersDownloaded = layersDownloaded || pulledNew |
| 93 | 93 |
} |
| 94 | 94 |
|
| 95 |
- writeStatus(taggedName.String(), p.config.ProgressOutput, layersDownloaded) |
|
| 95 |
+ writeStatus(ref.String(), p.config.ProgressOutput, layersDownloaded) |
|
| 96 | 96 |
|
| 97 | 97 |
return nil |
| 98 | 98 |
} |
| ... | ... |
@@ -81,21 +81,19 @@ func (l *tarexporter) parseNames(names []string) (map[image.ID]*imageDescriptor, |
| 81 | 81 |
addAssoc(imgID, nil) |
| 82 | 82 |
continue |
| 83 | 83 |
} |
| 84 |
- if _, ok := ref.(reference.Canonical); !ok {
|
|
| 85 |
- if _, ok := ref.(reference.NamedTagged); !ok {
|
|
| 86 |
- assocs := l.rs.ReferencesByName(ref) |
|
| 87 |
- for _, assoc := range assocs {
|
|
| 88 |
- addAssoc(assoc.ImageID, assoc.Ref) |
|
| 89 |
- } |
|
| 90 |
- if len(assocs) == 0 {
|
|
| 91 |
- imgID, err := l.is.Search(name) |
|
| 92 |
- if err != nil {
|
|
| 93 |
- return nil, err |
|
| 94 |
- } |
|
| 95 |
- addAssoc(imgID, nil) |
|
| 84 |
+ if reference.IsNameOnly(ref) {
|
|
| 85 |
+ assocs := l.rs.ReferencesByName(ref) |
|
| 86 |
+ for _, assoc := range assocs {
|
|
| 87 |
+ addAssoc(assoc.ImageID, assoc.Ref) |
|
| 88 |
+ } |
|
| 89 |
+ if len(assocs) == 0 {
|
|
| 90 |
+ imgID, err := l.is.Search(name) |
|
| 91 |
+ if err != nil {
|
|
| 92 |
+ return nil, err |
|
| 96 | 93 |
} |
| 97 |
- continue |
|
| 94 |
+ addAssoc(imgID, nil) |
|
| 98 | 95 |
} |
| 96 |
+ continue |
|
| 99 | 97 |
} |
| 100 | 98 |
var imgID image.ID |
| 101 | 99 |
if imgID, err = l.rs.Get(ref); err != nil {
|
| ... | ... |
@@ -132,6 +132,25 @@ func (r *canonicalRef) Digest() digest.Digest {
|
| 132 | 132 |
return r.namedRef.Named.(distreference.Canonical).Digest() |
| 133 | 133 |
} |
| 134 | 134 |
|
| 135 |
+// WithDefaultTag adds a default tag to a reference if it only has a repo name. |
|
| 136 |
+func WithDefaultTag(ref Named) Named {
|
|
| 137 |
+ if IsNameOnly(ref) {
|
|
| 138 |
+ ref, _ = WithTag(ref, DefaultTag) |
|
| 139 |
+ } |
|
| 140 |
+ return ref |
|
| 141 |
+} |
|
| 142 |
+ |
|
| 143 |
+// IsNameOnly returns true if reference only contains a repo name. |
|
| 144 |
+func IsNameOnly(ref Named) bool {
|
|
| 145 |
+ if _, ok := ref.(NamedTagged); ok {
|
|
| 146 |
+ return false |
|
| 147 |
+ } |
|
| 148 |
+ if _, ok := ref.(Canonical); ok {
|
|
| 149 |
+ return false |
|
| 150 |
+ } |
|
| 151 |
+ return true |
|
| 152 |
+} |
|
| 153 |
+ |
|
| 135 | 154 |
// splitHostname splits a repository name to hostname and remotename string. |
| 136 | 155 |
// If no valid hostname is found, the default hostname is used. Repository name |
| 137 | 156 |
// needs to be already validated before. |
| ... | ... |
@@ -64,19 +64,6 @@ func (a lexicalAssociations) Len() int { return len(a) }
|
| 64 | 64 |
func (a lexicalAssociations) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
| 65 | 65 |
func (a lexicalAssociations) Less(i, j int) bool { return a[i].Ref.String() < a[j].Ref.String() }
|
| 66 | 66 |
|
| 67 |
-func defaultTagIfNameOnly(ref Named) Named {
|
|
| 68 |
- switch ref.(type) {
|
|
| 69 |
- case NamedTagged: |
|
| 70 |
- return ref |
|
| 71 |
- case Canonical: |
|
| 72 |
- return ref |
|
| 73 |
- default: |
|
| 74 |
- // Should never fail |
|
| 75 |
- ref, _ = WithTag(ref, DefaultTag) |
|
| 76 |
- return ref |
|
| 77 |
- } |
|
| 78 |
-} |
|
| 79 |
- |
|
| 80 | 67 |
// NewReferenceStore creates a new reference store, tied to a file path where |
| 81 | 68 |
// the set of references are serialized in JSON format. |
| 82 | 69 |
func NewReferenceStore(jsonPath string) (Store, error) {
|
| ... | ... |
@@ -107,7 +94,7 @@ func (store *store) AddTag(ref Named, id image.ID, force bool) error {
|
| 107 | 107 |
if _, isCanonical := ref.(Canonical); isCanonical {
|
| 108 | 108 |
return errors.New("refusing to create a tag with a digest reference")
|
| 109 | 109 |
} |
| 110 |
- return store.addReference(defaultTagIfNameOnly(ref), id, force) |
|
| 110 |
+ return store.addReference(WithDefaultTag(ref), id, force) |
|
| 111 | 111 |
} |
| 112 | 112 |
|
| 113 | 113 |
// AddDigest adds a digest reference to the store. |
| ... | ... |
@@ -162,7 +149,7 @@ func (store *store) addReference(ref Named, id image.ID, force bool) error {
|
| 162 | 162 |
// Delete deletes a reference from the store. It returns true if a deletion |
| 163 | 163 |
// happened, or false otherwise. |
| 164 | 164 |
func (store *store) Delete(ref Named) (bool, error) {
|
| 165 |
- ref = defaultTagIfNameOnly(ref) |
|
| 165 |
+ ref = WithDefaultTag(ref) |
|
| 166 | 166 |
|
| 167 | 167 |
store.mu.Lock() |
| 168 | 168 |
defer store.mu.Unlock() |
| ... | ... |
@@ -194,7 +181,7 @@ func (store *store) Delete(ref Named) (bool, error) {
|
| 194 | 194 |
|
| 195 | 195 |
// Get retrieves an item from the store by |
| 196 | 196 |
func (store *store) Get(ref Named) (image.ID, error) {
|
| 197 |
- ref = defaultTagIfNameOnly(ref) |
|
| 197 |
+ ref = WithDefaultTag(ref) |
|
| 198 | 198 |
|
| 199 | 199 |
store.mu.RLock() |
| 200 | 200 |
defer store.mu.RUnlock() |