about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMathias Schreck <schreck.mathias@googlemail.com>2017-08-02 19:27:19 +0200
committerRobin Gloster <mail@glob.in>2017-08-03 11:52:03 +0200
commit86d9b09c9b2f0f76da0cfa5ea420ae476983d7a3 (patch)
tree4ea8c0a07f2942657d978d933b9ed869ed0388cf
parentf6817ddf99e30f2be55bc6a39c5225e0d0e5fbff (diff)
downloadnixlib-86d9b09c9b2f0f76da0cfa5ea420ae476983d7a3.tar
nixlib-86d9b09c9b2f0f76da0cfa5ea420ae476983d7a3.tar.gz
nixlib-86d9b09c9b2f0f76da0cfa5ea420ae476983d7a3.tar.bz2
nixlib-86d9b09c9b2f0f76da0cfa5ea420ae476983d7a3.tar.lz
nixlib-86d9b09c9b2f0f76da0cfa5ea420ae476983d7a3.tar.xz
nixlib-86d9b09c9b2f0f76da0cfa5ea420ae476983d7a3.tar.zst
nixlib-86d9b09c9b2f0f76da0cfa5ea420ae476983d7a3.zip
dockerTools: fix image json and manifest
The image json is not exactly the same as the layer json, therefore I
changed the implementation to use the `baseJson` which doesn’t include
layer specific details like `id`, `size` or the checksum of the layer.

Also the `history` entry was missing in the image json. I’m not totally
sure if this field is required, but a I got an error from a docker
registry when I’ve tried to receive the distribution manifest of an
image without those `history` entry:

GET: `http://<registry-host>/v2/<imageName>/manifests/<imageTag>`

```json
{
  "errors": [
    {
      "code": "MANIFEST_INVALID",
      "message": "manifest invalid",
      "detail": {}
    }
  ]
}
```

I’ve also used a while loop to iterate over all layers which should make
sure that the order of the layers is correct. Previously `find` was
used and I’m not sure if the order was always correct.
-rw-r--r--pkgs/build-support/docker/default.nix27
1 files changed, 17 insertions, 10 deletions
diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix
index 160c3f85977b..17d7f2da035c 100644
--- a/pkgs/build-support/docker/default.nix
+++ b/pkgs/build-support/docker/default.nix
@@ -497,16 +497,23 @@ rec {
         # Use the temp folder we've been working on to create a new image.
         mv temp image/$layerID
 
-        # Create image configuration file (used by registry v2) by using
-        # the configuration of the last layer
-        SHA_ARRAY=$(find ./ -name layer.tar | xargs sha256sum | cut -d" " -f1 | xargs -I{} echo -n '"sha256:{}" ' | sed 's/" "/","/g' | awk '{ print "["$1"]" }')
-        jq ". + {\"rootfs\": {\"diff_ids\": $SHA_ARRAY, \"type\": \"layers\"}}" image/$layerID/json > config.json
-        CONFIG_SHA=$(sha256sum config.json | cut -d ' ' -f1)
-        mv config.json image/$CONFIG_SHA.json
-
-        # Create image manifest
-        LAYER_PATHS=$(find image/ -name layer.tar -printf '"%P" ' | sed 's/" "/","/g')
-        jq -n "[{\"Config\":\"$CONFIG_SHA.json\",\"RepoTags\":[\"$imageName:$imageTag\"],\"Layers\":[$LAYER_PATHS]}]" > image/manifest.json
+        # Create image json and image manifest
+        imageJson=$(cat ${baseJson} | jq ". + {\"rootfs\": {\"diff_ids\": [], \"type\": \"layers\"}}")
+        manifestJson=$(jq -n "[{\"RepoTags\":[\"$imageName:$imageTag\"]}]")
+        currentID=$layerID
+        while [[ -n "$currentID" ]]; do
+          layerChecksum=$(sha256sum image/$currentID/layer.tar | cut -d ' ' -f1)
+          imageJson=$(echo "$imageJson" | jq ".history |= [{\"created\": \"${created}\"}] + .")
+          imageJson=$(echo "$imageJson" | jq ".rootfs.diff_ids |= [\"sha256:$layerChecksum\"] + .")
+          manifestJson=$(echo "$manifestJson" | jq ".[0].Layers |= [\"$currentID/layer.tar\"] + .")
+
+          currentID=$(cat image/$currentID/json | (jshon -e parent -u 2>/dev/null || true))
+        done
+
+        imageJsonChecksum=$(echo "$imageJson" | sha256sum | cut -d ' ' -f1)
+        echo "$imageJson" > "image/$imageJsonChecksum.json"
+        manifestJson=$(echo "$manifestJson" | jq ".[0].Config = \"$imageJsonChecksum.json\"")
+        echo "$manifestJson" > image/manifest.json
 
         # Store the json under the name image/repositories.
         jshon -n object \