From 56a35d5cb9b8e10f04bc3ea7966f5beb1e8985b4 Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Thu, 16 Nov 2017 16:54:30 -0800 Subject: [PATCH] Update docker pusher check tag Currently pushing a new tag to a manifest which already exists in the registry skips the tag push because it only checks that the manifest exists. This updates the logic to instead check if the tag exists and is at the same digest. Signed-off-by: Derek McGowan --- remotes/docker/pusher.go | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/remotes/docker/pusher.go b/remotes/docker/pusher.go index c97fd4f73..405480b54 100644 --- a/remotes/docker/pusher.go +++ b/remotes/docker/pusher.go @@ -52,7 +52,11 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex: isManifest = true - existCheck = path.Join("manifests", desc.Digest.String()) + if p.tag == "" { + existCheck = path.Join("manifests", desc.Digest.String()) + } else { + existCheck = path.Join("manifests", p.tag) + } default: existCheck = path.Join("blobs", desc.Digest.String()) } @@ -71,15 +75,26 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten log.G(ctx).WithError(err).Debugf("Unable to check existence, continuing with push") } else { if resp.StatusCode == http.StatusOK { - p.tracker.SetStatus(ref, Status{ - Status: content.Status{ - Ref: ref, - // TODO: Set updated time? - }, - }) - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest) - } - if resp.StatusCode != http.StatusNotFound { + var exists bool + if isManifest && p.tag != "" { + dgstHeader := digest.Digest(resp.Header.Get("Docker-Content-Digest")) + if dgstHeader == desc.Digest { + exists = true + } + } else { + exists = true + } + + if exists { + p.tracker.SetStatus(ref, Status{ + Status: content.Status{ + Ref: ref, + // TODO: Set updated time? + }, + }) + return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest) + } + } else if resp.StatusCode != http.StatusNotFound { // TODO: log error return nil, errors.Errorf("unexpected response: %s", resp.Status) }