about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-10-11T11·26+0100
committerVincent Ambo <github@tazj.in>2019-10-11T11·37+0100
commit1853c74998953048478b8526f408f8c57b129958 (patch)
tree4abdbdd522e5d55a197110b5375b9d5b9533586f
parente22ff5d176ba53deecf59737d402cac5d0cb9433 (diff)
refactor(server): Only compress symlink forest layer once
Instead of compressing & decompressing again to get the underlying tar
hash, use a similar mechanism as for store path layers for the symlink
layer and only compress it once while uploading.
-rw-r--r--tools/nixery/build-image/build-image.nix13
-rw-r--r--tools/nixery/server/builder/builder.go27
2 files changed, 24 insertions, 16 deletions
diff --git a/tools/nixery/build-image/build-image.nix b/tools/nixery/build-image/build-image.nix
index ab785006a9af..d4df707a8a3a 100644
--- a/tools/nixery/build-image/build-image.nix
+++ b/tools/nixery/build-image/build-image.nix
@@ -126,9 +126,9 @@ let
   # Image layer that contains the symlink forest created above. This
   # must be included in the image to ensure that the filesystem has a
   # useful layout at runtime.
-  symlinkLayer = runCommand "symlink-layer.tar.gz" {} ''
+  symlinkLayer = runCommand "symlink-layer.tar" {} ''
     cp -r ${contentsEnv}/ ./layer
-    tar --transform='s|^\./||' -C layer --sort=name --mtime="@$SOURCE_DATE_EPOCH" --owner=0 --group=0 -czf $out .
+    tar --transform='s|^\./||' -C layer --sort=name --mtime="@$SOURCE_DATE_EPOCH" --owner=0 --group=0 -cf $out .
   '';
 
   # Metadata about the symlink layer which is required for serving it.
@@ -137,14 +137,11 @@ let
   symlinkLayerMeta = fromJSON (readFile (runCommand "symlink-layer-meta.json" {
     buildInputs = with pkgs; [ coreutils jq openssl ];
   }''
-    gzipHash=$(sha256sum ${symlinkLayer} | cut -d ' ' -f1)
-    tarHash=$(cat ${symlinkLayer} | gzip -d | sha256sum | cut -d ' ' -f1)
+    tarHash=$(sha256sum ${symlinkLayer} | cut -d ' ' -f1)
     layerSize=$(stat --printf '%s' ${symlinkLayer})
 
-    jq -n -c --arg gzipHash $gzipHash --arg tarHash $tarHash --arg size $layerSize \
-      --arg path ${symlinkLayer} \
-      '{ size: ($size | tonumber), tarHash: $tarHash, gzipHash: $gzipHash, path: $path }' \
-      >> $out
+    jq -n -c --arg tarHash $tarHash --arg size $layerSize --arg path ${symlinkLayer} \
+      '{ size: ($size | tonumber), tarHash: $tarHash, path: $path }' >> $out
   ''));
 
   # Final output structure returned to Nixery if the build succeeded
diff --git a/tools/nixery/server/builder/builder.go b/tools/nixery/server/builder/builder.go
index 39befd0fb8f3..2a3aa182ac14 100644
--- a/tools/nixery/server/builder/builder.go
+++ b/tools/nixery/server/builder/builder.go
@@ -20,6 +20,7 @@ package builder
 import (
 	"bufio"
 	"bytes"
+	"compress/gzip"
 	"context"
 	"crypto/sha256"
 	"encoding/json"
@@ -117,10 +118,9 @@ type ImageResult struct {
 	// These fields are populated in case of success
 	Graph        layers.RuntimeGraph `json:"runtimeGraph"`
 	SymlinkLayer struct {
-		Size     int    `json:"size"`
-		TarHash  string `json:"tarHash"`
-		GzipHash string `json:"gzipHash"`
-		Path     string `json:"path"`
+		Size    int    `json:"size"`
+		TarHash string `json:"tarHash"`
+		Path    string `json:"path"`
 	} `json:"symlinkLayer"`
 }
 
@@ -309,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.GzipHash
+	slkey := result.SymlinkLayer.TarHash
 	entry, err := uploadHashLayer(ctx, s, slkey, func(w io.Writer) error {
 		f, err := os.Open(result.SymlinkLayer.Path)
 		if err != nil {
@@ -317,14 +317,25 @@ func prepareLayers(ctx context.Context, s *State, image *Image, result *ImageRes
 				"image": image.Name,
 				"tag":   image.Tag,
 				"layer": slkey,
-			}).Error("failed to upload symlink layer")
+			}).Error("failed to open symlink layer")
 
 			return err
 		}
 		defer f.Close()
 
-		_, err = io.Copy(w, f)
-		return err
+		gz := gzip.NewWriter(w)
+		_, err = io.Copy(gz, f)
+		if err != nil {
+			log.WithError(err).WithFields(log.Fields{
+				"image": image.Name,
+				"tag":   image.Tag,
+				"layer": slkey,
+			}).Error("failed to upload symlink layer")
+
+			return err
+		}
+
+		return gz.Close()
 	})
 
 	if err != nil {