@@ -37,7 +37,7 @@ import (
3737
3838type dockerPusher struct {
3939 * dockerBase
40- tag string
40+ object string
4141
4242 // TODO: namespace tracker
4343 tracker StatusTracker
@@ -74,11 +74,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
7474 case images .MediaTypeDockerSchema2Manifest , images .MediaTypeDockerSchema2ManifestList ,
7575 ocispec .MediaTypeImageManifest , ocispec .MediaTypeImageIndex :
7676 isManifest = true
77- if p .tag == "" {
78- existCheck = []string {"manifests" , desc .Digest .String ()}
79- } else {
80- existCheck = []string {"manifests" , p .tag }
81- }
77+ existCheck = getManifestPath (p .object , desc .Digest )
8278 default :
8379 existCheck = []string {"blobs" , desc .Digest .String ()}
8480 }
@@ -97,7 +93,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
9793 } else {
9894 if resp .StatusCode == http .StatusOK {
9995 var exists bool
100- if isManifest && p . tag != "" {
96+ if isManifest && existCheck [ 1 ] != desc . Digest . String () {
10197 dgstHeader := digest .Digest (resp .Header .Get ("Docker-Content-Digest" ))
10298 if dgstHeader == desc .Digest {
10399 exists = true
@@ -122,13 +118,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
122118 }
123119
124120 if isManifest {
125- var putPath []string
126- if p .tag != "" {
127- putPath = []string {"manifests" , p .tag }
128- } else {
129- putPath = []string {"manifests" , desc .Digest .String ()}
130- }
131-
121+ putPath := getManifestPath (p .object , desc .Digest )
132122 req = p .request (host , http .MethodPut , putPath ... )
133123 req .header .Add ("Content-Type" , desc .MediaType )
134124 } else {
@@ -271,6 +261,25 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
271261 }, nil
272262}
273263
264+ func getManifestPath (object string , dgst digest.Digest ) []string {
265+ if i := strings .IndexByte (object , '@' ); i >= 0 {
266+ if object [i + 1 :] != dgst .String () {
267+ // use digest, not tag
268+ object = ""
269+ } else {
270+ // strip @<digest> for registry path to make tag
271+ object = object [:i ]
272+ }
273+
274+ }
275+
276+ if object == "" {
277+ return []string {"manifests" , dgst .String ()}
278+ }
279+
280+ return []string {"manifests" , object }
281+ }
282+
274283type pushWriter struct {
275284 base * dockerBase
276285 ref string
0 commit comments