diff --git a/docker/daemon/daemon_dest.go b/docker/daemon/daemon_dest.go index 5873d9697..d6c145236 100644 --- a/docker/daemon/daemon_dest.go +++ b/docker/daemon/daemon_dest.go @@ -22,7 +22,8 @@ import ( ) type daemonImageDestination struct { - ref daemonReference + ref daemonReference + namedTaggedRef reference.NamedTagged // Strictly speaking redundant with ref above; having the field makes it structurally impossible for later users to fail. // For talking to imageLoadGoroutine goroutineCancel context.CancelFunc statusChannel <-chan error @@ -37,7 +38,8 @@ func newImageDestination(systemCtx *types.SystemContext, ref daemonReference) (t if ref.ref == nil { return nil, fmt.Errorf("Invalid destination docker-daemon:%s: a destination must be a name:tag", ref.StringWithinTransport()) } - if _, ok := ref.ref.(reference.NamedTagged); !ok { + namedTaggedRef, ok := ref.ref.(reference.NamedTagged) + if !ok { return nil, fmt.Errorf("Invalid destination docker-daemon:%s: a destination must be a name:tag", ref.StringWithinTransport()) } @@ -55,6 +57,7 @@ func newImageDestination(systemCtx *types.SystemContext, ref daemonReference) (t return &daemonImageDestination{ ref: ref, + namedTaggedRef: namedTaggedRef, goroutineCancel: goroutineCancel, statusChannel: statusChannel, writer: writer, @@ -181,9 +184,28 @@ func (d *daemonImageDestination) PutManifest(m []byte) error { for _, l := range man.Layers { layerPaths = append(layerPaths, l.Digest) } + + // For github.com/docker/docker consumers, this works just as well as + // refString := d.namedTaggedRef.String() [i.e. d.ref.ref.String()] + // because when reading the RepoTags strings, github.com/docker/docker/reference + // normalizes both of them to the same value. + // + // Doing it this way to include the normalized-out `docker.io[/library]` does make + // a difference for github.com/projectatomic/docker consumers, with the + // “Add --add-registry and --block-registry options to docker daemon” patch. + // These consumers treat reference strings which include a hostname and reference + // strings without a hostname differently. + // + // Using the host name here is more explicit about the intent, and it has the same + // effect as (docker pull) in projectatomic/docker, which tags the result using + // a hostname-qualified reference. + // See https://github.com/containers/image/issues/72 for a more detailed + // analysis and explanation. + refString := fmt.Sprintf("%s:%s", d.namedTaggedRef.FullName(), d.namedTaggedRef.Tag()) + items := []manifestItem{{ Config: man.Config.Digest, - RepoTags: []string{d.ref.ref.String()}, // newImageDestination ensures that d.ref.ref is a reference.NamedTagged + RepoTags: []string{refString}, Layers: layerPaths, Parent: "", LayerSources: nil,