Skip to content

Commit 69d65c9

Browse files
authored
Merge pull request #3476 from dmcgowan/fix-push-exist-check
Prevent push by tag for sub-manifests
2 parents ac1cb6d + c965a6c commit 69d65c9

3 files changed

Lines changed: 29 additions & 22 deletions

File tree

client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,11 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor,
403403
}
404404
}
405405

406+
// Annotate ref with digest to push only push tag for single digest
407+
if !strings.Contains(ref, "@") {
408+
ref = ref + "@" + desc.Digest.String()
409+
}
410+
406411
pusher, err := pushCtx.Resolver.Pusher(ctx, ref)
407412
if err != nil {
408413
return err

remotes/docker/pusher.go

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import (
3737

3838
type 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+
274283
type pushWriter struct {
275284
base *dockerBase
276285
ref string

remotes/docker/resolver.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -399,21 +399,14 @@ func (r *dockerResolver) Pusher(ctx context.Context, ref string) (remotes.Pusher
399399
return nil, err
400400
}
401401

402-
// Manifests can be pushed by digest like any other object, but the passed in
403-
// reference cannot take a digest without the associated content. A tag is allowed
404-
// and will be used to tag pushed manifests.
405-
if refspec.Object != "" && strings.Contains(refspec.Object, "@") {
406-
return nil, errors.New("cannot use digest reference for push locator")
407-
}
408-
409402
base, err := r.base(refspec)
410403
if err != nil {
411404
return nil, err
412405
}
413406

414407
return dockerPusher{
415408
dockerBase: base,
416-
tag: refspec.Object,
409+
object: refspec.Object,
417410
tracker: r.tracker,
418411
}, nil
419412
}

0 commit comments

Comments
 (0)