mirror of https://github.com/docker/docs.git
Support push and pull of sha256
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
parent
75e29f4550
commit
514be385f7
|
@ -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
|
RUN gem install --no-rdoc --no-ri fpm --version 1.3.2
|
||||||
|
|
||||||
# Install registry
|
# Install registry
|
||||||
ENV REGISTRY_COMMIT b4cc5e3ecc2e9f4fa0e95d94c389e1d79e902486
|
ENV REGISTRY_COMMIT 0c130dff5baf3168f2c85630c6d2344b81261269
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& git clone https://github.com/docker/distribution.git /go/src/github.com/docker/distribution \
|
&& 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) \
|
&& (cd /go/src/github.com/docker/distribution && git checkout -q $REGISTRY_COMMIT) \
|
||||||
|
|
|
@ -11,11 +11,11 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/distribution/digest"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
"github.com/docker/docker/image"
|
"github.com/docker/docker/image"
|
||||||
"github.com/docker/docker/pkg/common"
|
"github.com/docker/docker/pkg/common"
|
||||||
"github.com/docker/docker/pkg/progressreader"
|
"github.com/docker/docker/pkg/progressreader"
|
||||||
"github.com/docker/docker/pkg/tarsum"
|
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
)
|
)
|
||||||
|
@ -375,6 +375,7 @@ func WriteStatus(requestedTag string, out io.Writer, sf *utils.StreamFormatter,
|
||||||
type downloadInfo struct {
|
type downloadInfo struct {
|
||||||
imgJSON []byte
|
imgJSON []byte
|
||||||
img *image.Image
|
img *image.Image
|
||||||
|
digest digest.Digest
|
||||||
tmpFile *os.File
|
tmpFile *os.File
|
||||||
length int64
|
length int64
|
||||||
downloaded bool
|
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) {
|
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)
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -468,11 +469,12 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
chunks := strings.SplitN(sumStr, ":", 2)
|
dgst, err := digest.ParseDigest(sumStr)
|
||||||
if len(chunks) < 2 {
|
if err != nil {
|
||||||
return false, fmt.Errorf("expected 2 parts in the sumStr, got %#v", chunks)
|
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))
|
out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Pulling fs layer", nil))
|
||||||
|
|
||||||
downloadFunc := func(di *downloadInfo) error {
|
downloadFunc := func(di *downloadInfo) error {
|
||||||
|
@ -493,20 +495,19 @@ func (s *TagStore) pullV2Tag(eng *engine.Engine, r *registry.Session, out io.Wri
|
||||||
return err
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer r.Close()
|
defer r.Close()
|
||||||
|
|
||||||
// Wrap the reader with the appropriate TarSum reader.
|
verifier, err := digest.NewDigestVerifier(di.digest)
|
||||||
tarSumReader, err := tarsum.NewTarSumForLabel(r, true, sumType)
|
|
||||||
if err != nil {
|
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{
|
if _, err := io.Copy(tmpFile, progressreader.New(progressreader.Config{
|
||||||
In: ioutil.NopCloser(tarSumReader),
|
In: ioutil.NopCloser(io.TeeReader(r, verifier)),
|
||||||
Out: out,
|
Out: out,
|
||||||
Formatter: sf,
|
Formatter: sf,
|
||||||
Size: int(l),
|
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))
|
out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Verifying Checksum", nil))
|
||||||
|
|
||||||
if finalChecksum := tarSumReader.Sum(nil); !strings.EqualFold(finalChecksum, sumStr) {
|
if !verifier.Verified() {
|
||||||
log.Infof("Image verification failed: checksum mismatch - expected %q but got %q", sumStr, finalChecksum)
|
log.Infof("Image verification failed: checksum mismatch for %q", di.digest.String())
|
||||||
verified = false
|
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."))
|
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 {
|
if len(manifestDigest) > 0 {
|
||||||
out.Write(sf.FormatStatus("", "Digest: %s", digest))
|
out.Write(sf.FormatStatus("", "Digest: %s", manifestDigest))
|
||||||
}
|
}
|
||||||
|
|
||||||
if utils.DigestReference(tag) {
|
if utils.DigestReference(tag) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package graph
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -13,11 +14,11 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/distribution/digest"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
"github.com/docker/docker/image"
|
"github.com/docker/docker/image"
|
||||||
"github.com/docker/docker/pkg/common"
|
"github.com/docker/docker/pkg/common"
|
||||||
"github.com/docker/docker/pkg/progressreader"
|
"github.com/docker/docker/pkg/progressreader"
|
||||||
"github.com/docker/docker/pkg/tarsum"
|
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
|
@ -466,24 +467,17 @@ func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *
|
||||||
os.Remove(tf.Name())
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
size, err := bufferToFile(tf, ts)
|
dgst := digest.NewDigest("sha256", h)
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the layer
|
// Send the layer
|
||||||
log.Debugf("rendered layer for %s of [%d] size", img.ID, size)
|
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{
|
progressreader.New(progressreader.Config{
|
||||||
In: tf,
|
In: tf,
|
||||||
Out: out,
|
Out: out,
|
||||||
|
@ -497,7 +491,7 @@ func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
out.Write(sf.FormatProgress(common.TruncateID(img.ID), "Image successfully pushed", nil))
|
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.
|
// FIXME: Allow to interrupt current push when new push of same image is done.
|
||||||
|
|
Loading…
Reference in New Issue