about summary refs log tree commit diff
path: root/tools/nixery/server/builder
diff options
context:
space:
mode:
Diffstat (limited to 'tools/nixery/server/builder')
-rw-r--r--tools/nixery/server/builder/archive.go19
-rw-r--r--tools/nixery/server/builder/builder.go24
2 files changed, 32 insertions, 11 deletions
diff --git a/tools/nixery/server/builder/archive.go b/tools/nixery/server/builder/archive.go
index 55b3c2a8b79c..a3fb99882fd6 100644
--- a/tools/nixery/server/builder/archive.go
+++ b/tools/nixery/server/builder/archive.go
@@ -10,6 +10,8 @@ package builder
 import (
 	"archive/tar"
 	"compress/gzip"
+	"crypto/sha256"
+	"fmt"
 	"io"
 	"os"
 	"path/filepath"
@@ -19,26 +21,31 @@ import (
 
 // Create a new compressed tarball from each of the paths in the list
 // and write it to the supplied writer.
-func packStorePaths(l *layers.Layer, w io.Writer) error {
+//
+// The uncompressed tarball is hashed because image manifests must
+// contain both the hashes of compressed and uncompressed layers.
+func packStorePaths(l *layers.Layer, w io.Writer) (string, error) {
+	shasum := sha256.New()
 	gz := gzip.NewWriter(w)
-	t := tar.NewWriter(gz)
+	multi := io.MultiWriter(shasum, gz)
+	t := tar.NewWriter(multi)
 
 	for _, path := range l.Contents {
 		err := filepath.Walk(path, tarStorePath(t))
 		if err != nil {
-			return err
+			return "", err
 		}
 	}
 
 	if err := t.Close(); err != nil {
-		return err
+		return "", err
 	}
 
 	if err := gz.Close(); err != nil {
-		return err
+		return "", err
 	}
 
-	return nil
+	return fmt.Sprintf("sha256:%x", shasum.Sum([]byte{})), nil
 }
 
 func tarStorePath(w *tar.Writer) filepath.WalkFunc {
diff --git a/tools/nixery/server/builder/builder.go b/tools/nixery/server/builder/builder.go
index 748ff5f67d7b..39befd0fb8f3 100644
--- a/tools/nixery/server/builder/builder.go
+++ b/tools/nixery/server/builder/builder.go
@@ -117,9 +117,10 @@ type ImageResult struct {
 	// These fields are populated in case of success
 	Graph        layers.RuntimeGraph `json:"runtimeGraph"`
 	SymlinkLayer struct {
-		Size   int    `json:"size"`
-		SHA256 string `json:"sha256"`
-		Path   string `json:"path"`
+		Size     int    `json:"size"`
+		TarHash  string `json:"tarHash"`
+		GzipHash string `json:"gzipHash"`
+		Path     string `json:"path"`
 	} `json:"symlinkLayer"`
 }
 
@@ -269,8 +270,18 @@ func prepareLayers(ctx context.Context, s *State, image *Image, result *ImageRes
 			entries = append(entries, *entry)
 		} else {
 			lh := l.Hash()
+
+			// While packing store paths, the SHA sum of
+			// the uncompressed layer is computed and
+			// written to `tarhash`.
+			//
+			// TODO(tazjin): Refactor this to make the
+			// flow of data cleaner.
+			var tarhash string
 			lw := func(w io.Writer) error {
-				return packStorePaths(&l, w)
+				var err error
+				tarhash, err = packStorePaths(&l, w)
+				return err
 			}
 
 			entry, err := uploadHashLayer(ctx, s, lh, lw)
@@ -278,6 +289,7 @@ func prepareLayers(ctx context.Context, s *State, image *Image, result *ImageRes
 				return nil, err
 			}
 			entry.MergeRating = l.MergeRating
+			entry.TarHash = tarhash
 
 			var pkgs []string
 			for _, p := range l.Contents {
@@ -287,6 +299,7 @@ func prepareLayers(ctx context.Context, s *State, image *Image, result *ImageRes
 			log.WithFields(log.Fields{
 				"layer":    lh,
 				"packages": pkgs,
+				"tarhash":  tarhash,
 			}).Info("created image layer")
 
 			go cacheLayer(ctx, s, l.Hash(), *entry)
@@ -296,7 +309,7 @@ func prepareLayers(ctx context.Context, s *State, image *Image, result *ImageRes
 
 	// Symlink layer (built in the first Nix build) needs to be
 	// included here manually:
-	slkey := result.SymlinkLayer.SHA256
+	slkey := result.SymlinkLayer.GzipHash
 	entry, err := uploadHashLayer(ctx, s, slkey, func(w io.Writer) error {
 		f, err := os.Open(result.SymlinkLayer.Path)
 		if err != nil {
@@ -318,6 +331,7 @@ func prepareLayers(ctx context.Context, s *State, image *Image, result *ImageRes
 		return nil, err
 	}
 
+	entry.TarHash = "sha256:" + result.SymlinkLayer.TarHash
 	go cacheLayer(ctx, s, slkey, *entry)
 	entries = append(entries, *entry)