Переглянути джерело

Compress layers on push to a v2 registry

When buffering to file add support for compressing the tar contents. Since digest should be computed while writing buffer, include digest creation during buffer.

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Derek McGowan 10 роки тому
батько
коміт
851c64725d
2 змінених файлів з 19 додано та 14 видалено
  1. 18 6
      graph/graph.go
  2. 1 8
      graph/push.go

+ 18 - 6
graph/graph.go

@@ -1,6 +1,8 @@
 package graph
 package graph
 
 
 import (
 import (
+	"compress/gzip"
+	"crypto/sha256"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"io/ioutil"
 	"io/ioutil"
@@ -13,6 +15,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/distribution/digest"
 	"github.com/docker/docker/autogen/dockerversion"
 	"github.com/docker/docker/autogen/dockerversion"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
@@ -242,18 +245,27 @@ func (graph *Graph) newTempFile() (*os.File, error) {
 	return ioutil.TempFile(tmp, "")
 	return ioutil.TempFile(tmp, "")
 }
 }
 
 
-func bufferToFile(f *os.File, src io.Reader) (int64, error) {
-	n, err := io.Copy(f, src)
+func bufferToFile(f *os.File, src io.Reader) (int64, digest.Digest, error) {
+	var (
+		h = sha256.New()
+		w = gzip.NewWriter(io.MultiWriter(f, h))
+	)
+	_, err := io.Copy(w, src)
+	w.Close()
 	if err != nil {
 	if err != nil {
-		return n, err
+		return 0, "", err
 	}
 	}
 	if err = f.Sync(); err != nil {
 	if err = f.Sync(); err != nil {
-		return n, err
+		return 0, "", err
+	}
+	n, err := f.Seek(0, os.SEEK_CUR)
+	if err != nil {
+		return 0, "", err
 	}
 	}
 	if _, err := f.Seek(0, 0); err != nil {
 	if _, err := f.Seek(0, 0); err != nil {
-		return n, err
+		return 0, "", err
 	}
 	}
-	return n, nil
+	return n, digest.NewDigest("sha256", h), nil
 }
 }
 
 
 // setupInitLayer populates a directory with mountpoints suitable
 // setupInitLayer populates a directory with mountpoints suitable

+ 1 - 8
graph/push.go

@@ -1,7 +1,6 @@
 package graph
 package graph
 
 
 import (
 import (
-	"crypto/sha256"
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
@@ -13,7 +12,6 @@ import (
 	"sync"
 	"sync"
 
 
 	"github.com/Sirupsen/logrus"
 	"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/progressreader"
 	"github.com/docker/docker/pkg/progressreader"
@@ -465,12 +463,7 @@ func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *
 		os.Remove(tf.Name())
 		os.Remove(tf.Name())
 	}()
 	}()
 
 
-	h := sha256.New()
-	size, err := bufferToFile(tf, io.TeeReader(arch, h))
-	if err != nil {
-		return "", err
-	}
-	dgst := digest.NewDigest("sha256", h)
+	size, dgst, err := bufferToFile(tf, arch)
 
 
 	// Send the layer
 	// Send the layer
 	logrus.Debugf("rendered layer for %s of [%d] size", img.ID, size)
 	logrus.Debugf("rendered layer for %s of [%d] size", img.ID, size)