Always store the image digest when pulling and pushing an image.

Always attempt to add digest even when tag already exists.
Ensure digest does not currently exist.
When image id is mismatched, output an error log.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
Derek McGowan 2016-06-27 10:09:57 -07:00
parent cccfe63e86
commit 33984f256b
4 changed files with 37 additions and 8 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/digest"
"github.com/docker/docker/api"
"github.com/docker/docker/distribution/metadata"
"github.com/docker/docker/distribution/xfer"
@ -203,3 +204,22 @@ func ValidateRepoName(name string) error {
}
return nil
}
func addDigestReference(store reference.Store, ref reference.Named, dgst digest.Digest, imageID image.ID) error {
dgstRef, err := reference.WithDigest(ref, dgst)
if err != nil {
return err
}
if oldTagImageID, err := store.Get(dgstRef); err == nil {
if oldTagImageID != imageID {
// Updating digests not supported by reference store
logrus.Errorf("Image ID for digest %s changed from %s to %s, cannot update", dgst.String(), oldTagImageID, imageID)
}
return nil
} else if err != reference.ErrDoesNotExist {
return err
}
return store.AddDigest(dgstRef, imageID, true)
}

View File

@ -393,7 +393,7 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named) (tagUpdat
oldTagImageID, err := p.config.ReferenceStore.Get(ref)
if err == nil {
if oldTagImageID == imageID {
return false, nil
return false, addDigestReference(p.config.ReferenceStore, ref, manifestDigest, imageID)
}
} else if err != reference.ErrDoesNotExist {
return false, err
@ -403,10 +403,14 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named) (tagUpdat
if err = p.config.ReferenceStore.AddDigest(canonical, imageID, true); err != nil {
return false, err
}
} else if err = p.config.ReferenceStore.AddTag(ref, imageID, true); err != nil {
return false, err
} else {
if err = addDigestReference(p.config.ReferenceStore, ref, manifestDigest, imageID); err != nil {
return false, err
}
if err = p.config.ReferenceStore.AddTag(ref, imageID, true); err != nil {
return false, err
}
}
return true, nil
}

View File

@ -200,6 +200,11 @@ func (p *v2Pusher) pushV2Tag(ctx context.Context, ref reference.NamedTagged, ima
manifestDigest := digest.FromBytes(canonicalManifest)
progress.Messagef(p.config.ProgressOutput, "", "%s: digest: %s size: %d", ref.Tag(), manifestDigest, len(canonicalManifest))
if err := addDigestReference(p.config.ReferenceStore, ref, manifestDigest, imageID); err != nil {
return err
}
// Signal digest to the trust client so it can sign the
// push, if appropriate.
progress.Aux(p.config.ProgressOutput, PushResult{Tag: ref.Tag(), Digest: manifestDigest, Size: len(canonicalManifest)})

View File

@ -287,7 +287,7 @@ func (s *DockerTrustSuite) TestTrustedPush(c *check.C) {
s.trustedCmd(pullCmd)
out, _, err = runCommandWithOutput(pullCmd)
c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Image is up to date", check.Commentf(out))
// Assert that we rotated the snapshot key to the server by checking our local keystore
contents, err := ioutil.ReadDir(filepath.Join(cliconfig.ConfigDir(), "trust/private/tuf_keys", privateRegistryURL, "dockerclitrusted/pushtest"))
@ -312,7 +312,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) {
s.trustedCmd(pullCmd)
out, _, err = runCommandWithOutput(pullCmd)
c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Image is up to date", check.Commentf(out))
}
func (s *DockerTrustSuite) TestTrustedPushWithFailingServer(c *check.C) {
@ -358,7 +358,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) {
s.trustedCmd(pullCmd)
out, _, err = runCommandWithOutput(pullCmd)
c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Image is up to date", check.Commentf(out))
}
func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) {
@ -492,7 +492,7 @@ func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegationOnly(c *check.C)
s.trustedCmd(pullCmd)
out, _, err = runCommandWithOutput(pullCmd)
c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
c.Assert(string(out), checker.Contains, "Status: Image is up to date", check.Commentf(out))
}
func (s *DockerTrustSuite) TestTrustedPushSignsAllFirstLevelRolesWeHaveKeysFor(c *check.C) {