Procházet zdrojové kódy

Support push and pull of sha256

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Derek McGowan před 10 roky
rodič
revize
514be385f7
3 změnil soubory, kde provedl 24 přidání a 29 odebrání
  1. 1 1
      Dockerfile
  2. 16 15
      graph/pull.go
  3. 7 13
      graph/push.go

+ 1 - 1
Dockerfile

@@ -108,7 +108,7 @@ RUN go get golang.org/x/tools/cmd/cover
 RUN gem install --no-rdoc --no-ri fpm --version 1.3.2
 
 # Install registry
-ENV REGISTRY_COMMIT b4cc5e3ecc2e9f4fa0e95d94c389e1d79e902486
+ENV REGISTRY_COMMIT 0c130dff5baf3168f2c85630c6d2344b81261269
 RUN set -x \
 	&& git clone https://github.com/docker/distribution.git /go/src/github.com/docker/distribution \
 	&& (cd /go/src/github.com/docker/distribution && git checkout -q $REGISTRY_COMMIT) \

+ 16 - 15
graph/pull.go

@@ -11,11 +11,11 @@ import (
 	"time"
 
 	log "github.com/Sirupsen/logrus"
+	"github.com/docker/distribution/digest"
 	"github.com/docker/docker/engine"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/common"
 	"github.com/docker/docker/pkg/progressreader"
-	"github.com/docker/docker/pkg/tarsum"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/utils"
 )
@@ -375,6 +375,7 @@ func WriteStatus(requestedTag string, out io.Writer, sf *utils.StreamFormatter,
 type downloadInfo struct {
 	imgJSON    []byte
 	img        *image.Image
+	digest     digest.Digest
 	tmpFile    *os.File
 	length     int64
 	downloaded bool
@@ -429,7 +430,7 @@ func (s *TagStore) pullV2Repository(eng *engine.Engine, r *registry.Session, out
 
 func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Writer, endpoint *registry.Endpoint, repoInfo *registry.RepositoryInfo, tag string, sf *utils.StreamFormatter, parallel bool, auth *registry.RequestAuthorization) (bool, error) {
 	log.Debugf("Pulling tag from V2 registry: %q", tag)
-	manifestBytes, digest, err := r.GetV2ImageManifest(endpoint, repoInfo.RemoteName, tag, auth)
+	manifestBytes, manifestDigest, err := r.GetV2ImageManifest(endpoint, repoInfo.RemoteName, tag, auth)
 	if err != nil {
 		return false, err
 	}
@@ -468,11 +469,12 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
 			continue
 		}
 
-		chunks := strings.SplitN(sumStr, ":", 2)
-		if len(chunks) < 2 {
-			return false, fmt.Errorf("expected 2 parts in the sumStr, got %#v", chunks)
+		dgst, err := digest.ParseDigest(sumStr)
+		if err != nil {
+			return false, err
 		}
-		sumType, checksum := chunks[0], chunks[1]
+		downloads[i].digest = dgst
+
 		out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Pulling fs layer", nil))
 
 		downloadFunc := func(di *downloadInfo) error {
@@ -493,20 +495,19 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
 					return err
 				}
 
-				r, l, err := r.GetV2ImageBlobReader(endpoint, repoInfo.RemoteName, sumType, checksum, auth)
+				r, l, err := r.GetV2ImageBlobReader(endpoint, repoInfo.RemoteName, di.digest.Algorithm(), di.digest.Hex(), auth)
 				if err != nil {
 					return err
 				}
 				defer r.Close()
 
-				// Wrap the reader with the appropriate TarSum reader.
-				tarSumReader, err := tarsum.NewTarSumForLabel(r, true, sumType)
+				verifier, err := digest.NewDigestVerifier(di.digest)
 				if err != nil {
-					return fmt.Errorf("unable to wrap image blob reader with TarSum: %s", err)
+					return err
 				}
 
 				if _, err := io.Copy(tmpFile, progressreader.New(progressreader.Config{
-					In:        ioutil.NopCloser(tarSumReader),
+					In:        ioutil.NopCloser(io.TeeReader(r, verifier)),
 					Out:       out,
 					Formatter: sf,
 					Size:      int(l),
@@ -519,8 +520,8 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
 
 				out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Verifying Checksum", nil))
 
-				if finalChecksum := tarSumReader.Sum(nil); !strings.EqualFold(finalChecksum, sumStr) {
-					log.Infof("Image verification failed: checksum mismatch - expected %q but got %q", sumStr, finalChecksum)
+				if !verifier.Verified() {
+					log.Infof("Image verification failed: checksum mismatch for %q", di.digest.String())
 					verified = false
 				}
 
@@ -604,8 +605,8 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
 		out.Write(sf.FormatStatus(utils.ImageReference(repoInfo.CanonicalName, tag), "The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security."))
 	}
 
-	if len(digest) > 0 {
-		out.Write(sf.FormatStatus("", "Digest: %s", digest))
+	if len(manifestDigest) > 0 {
+		out.Write(sf.FormatStatus("", "Digest: %s", manifestDigest))
 	}
 
 	if utils.DigestReference(tag) {

+ 7 - 13
graph/push.go

@@ -2,6 +2,7 @@ package graph
 
 import (
 	"bytes"
+	"crypto/sha256"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -13,11 +14,11 @@ import (
 	"sync"
 
 	log "github.com/Sirupsen/logrus"
+	"github.com/docker/distribution/digest"
 	"github.com/docker/docker/engine"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/common"
 	"github.com/docker/docker/pkg/progressreader"
-	"github.com/docker/docker/pkg/tarsum"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/docker/utils"
@@ -466,24 +467,17 @@ func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *
 		os.Remove(tf.Name())
 	}()
 
-	ts, err := tarsum.NewTarSum(arch, true, tarsum.Version1)
+	h := sha256.New()
+	size, err := bufferToFile(tf, io.TeeReader(arch, h))
 	if err != nil {
 		return "", err
 	}
-	size, err := bufferToFile(tf, ts)
-	if err != nil {
-		return "", err
-	}
-	checksum := ts.Sum(nil)
-	sumParts := strings.SplitN(checksum, ":", 2)
-	if len(sumParts) < 2 {
-		return "", fmt.Errorf("Invalid checksum: %s", checksum)
-	}
+	dgst := digest.NewDigest("sha256", h)
 
 	// Send the layer
 	log.Debugf("rendered layer for %s of [%d] size", img.ID, size)
 
-	if err := r.PutV2ImageBlob(endpoint, imageName, sumParts[0], sumParts[1],
+	if err := r.PutV2ImageBlob(endpoint, imageName, dgst.Algorithm(), dgst.Hex(),
 		progressreader.New(progressreader.Config{
 			In:        tf,
 			Out:       out,
@@ -497,7 +491,7 @@ func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *
 		return "", err
 	}
 	out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Image successfully pushed", nil))
-	return checksum, nil
+	return dgst.String(), nil
 }
 
 // FIXME: Allow to interrupt current push when new push of same image is done.