summary refs log tree commit diff
diff options
context:
space:
mode:
authorlewo <lewo@abesis.fr>2019-05-13 15:27:43 +0200
committerGitHub <noreply@github.com>2019-05-13 15:27:43 +0200
commit42ee7cdf9d4aa9228d002c02d98def7dd0eb9942 (patch)
treeb1145b514608536ce98e3891bc3a047ac1c451cf
parent7b89adb493425f726620dd26e3e2f70a6c1db33f (diff)
parenta5a5820048165fd80fb806e8d71be52ba627823e (diff)
downloadnixpkgs-42ee7cdf9d4aa9228d002c02d98def7dd0eb9942.tar
nixpkgs-42ee7cdf9d4aa9228d002c02d98def7dd0eb9942.tar.gz
nixpkgs-42ee7cdf9d4aa9228d002c02d98def7dd0eb9942.tar.bz2
nixpkgs-42ee7cdf9d4aa9228d002c02d98def7dd0eb9942.tar.lz
nixpkgs-42ee7cdf9d4aa9228d002c02d98def7dd0eb9942.tar.xz
nixpkgs-42ee7cdf9d4aa9228d002c02d98def7dd0eb9942.tar.zst
nixpkgs-42ee7cdf9d4aa9228d002c02d98def7dd0eb9942.zip
Merge pull request #61089 from nlewo/pr-fix-layer-order
dockerTools: Fix Docker layers order 
-rw-r--r--nixos/tests/docker-tools.nix7
-rw-r--r--pkgs/build-support/docker/default.nix21
-rw-r--r--pkgs/build-support/docker/examples.nix39
3 files changed, 57 insertions, 10 deletions
diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix
index 502b537ed68..f91121077ea 100644
--- a/nixos/tests/docker-tools.nix
+++ b/nixos/tests/docker-tools.nix
@@ -67,5 +67,12 @@ import ./make-test.nix ({ pkgs, ... }: {
       # Ensure building an image on top of a layered Docker images work
       $docker->succeed("docker load --input='${pkgs.dockerTools.examples.layered-on-top}'");
       $docker->succeed("docker run --rm ${pkgs.dockerTools.examples.layered-on-top.imageName}");
+
+      # Ensure order of layers is correct
+      $docker->succeed("docker load --input='${pkgs.dockerTools.examples.layersOrder}'");
+      $docker->succeed("docker run --rm  ${pkgs.dockerTools.examples.layersOrder.imageName} cat /tmp/layer1 | grep -q layer1");
+      # This is to be sure the order of layers of the parent image is preserved
+      $docker->succeed("docker run --rm  ${pkgs.dockerTools.examples.layersOrder.imageName} cat /tmp/layer2 | grep -q layer2");
+      $docker->succeed("docker run --rm  ${pkgs.dockerTools.examples.layersOrder.imageName} cat /tmp/layer3 | grep -q layer3");
     '';
 })
diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix
index 11945e7b6f7..57e40069003 100644
--- a/pkgs/build-support/docker/default.nix
+++ b/pkgs/build-support/docker/default.nix
@@ -216,7 +216,7 @@ rec {
         find image/$extractionID/layer -name ".wh.*" -exec bash -c 'name="$(basename {}|sed "s/^.wh.//")"; mknod "$(dirname {})/$name" c 0 0; rm {}' \;
 
         # Get the next lower directory and continue the loop.
-        lowerdir=$lowerdir''${lowerdir:+:}image/$extractionID/layer
+        lowerdir=image/$extractionID/layer''${lowerdir:+:}$lowerdir
       done
 
       mkdir work
@@ -585,9 +585,9 @@ rec {
           layerID=$(sha256sum "$layer/json" | cut -d ' ' -f 1)
           ln -s "$layer" "./image/$layerID"
 
-          manifestJson=$(echo "$manifestJson" | jq ".[0].Layers |= [\"$layerID/layer.tar\"] + .")
-          imageJson=$(echo "$imageJson" | jq ".history |= [{\"created\": \"$(jq -r .created ${configJson})\"}] + .")
-          imageJson=$(echo "$imageJson" | jq ".rootfs.diff_ids |= [\"sha256:$layerChecksum\"] + .")
+          manifestJson=$(echo "$manifestJson" | jq ".[0].Layers |= . + [\"$layerID/layer.tar\"]")
+          imageJson=$(echo "$imageJson" | jq ".history |= . + [{\"created\": \"$(jq -r .created ${configJson})\"}]")
+          imageJson=$(echo "$imageJson" | jq ".rootfs.diff_ids |= . + [\"sha256:$layerChecksum\"]")
         done
         imageJsonChecksum=$(echo "$imageJson" | sha256sum | cut -d ' ' -f1)
         echo "$imageJson" > "image/$imageJsonChecksum.json"
@@ -779,23 +779,24 @@ rec {
         # Use the temp folder we've been working on to create a new image.
         mv temp image/$layerID
 
-        # Add the new layer ID to the beginning of the layer list
+        # Add the new layer ID to the end of the layer list
         (
+          cat layer-list
           # originally this used `sed -i "1i$layerID" layer-list`, but
           # would fail if layer-list was completely empty.
           echo "$layerID/layer.tar"
-          cat layer-list
         ) | ${pkgs.moreutils}/bin/sponge layer-list
 
         # Create image json and image manifest
         imageJson=$(cat ${baseJson} | jq ". + {\"rootfs\": {\"diff_ids\": [], \"type\": \"layers\"}}")
         manifestJson=$(jq -n "[{\"RepoTags\":[\"$imageName:$imageTag\"]}]")
 
-        for layerTar in $(tac ./layer-list); do
+        for layerTar in $(cat ./layer-list); do
           layerChecksum=$(sha256sum image/$layerTar | cut -d ' ' -f1)
-          imageJson=$(echo "$imageJson" | jq ".history |= [{\"created\": \"$(jq -r .created ${baseJson})\"}] + .")
-          imageJson=$(echo "$imageJson" | jq ".rootfs.diff_ids |= [\"sha256:$layerChecksum\"] + .")
-          manifestJson=$(echo "$manifestJson" | jq ".[0].Layers |= [\"$layerTar\"] + .")
+          imageJson=$(echo "$imageJson" | jq ".history |= . + [{\"created\": \"$(jq -r .created ${baseJson})\"}]")
+          # diff_ids order is from the bottom-most to top-most layer
+          imageJson=$(echo "$imageJson" | jq ".rootfs.diff_ids |= . + [\"sha256:$layerChecksum\"]")
+          manifestJson=$(echo "$manifestJson" | jq ".[0].Layers |= . + [\"$layerTar\"]")
         done
 
         imageJsonChecksum=$(echo "$imageJson" | sha256sum | cut -d ' ' -f1)
diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix
index 557a4dbf54b..ac21be907b8 100644
--- a/pkgs/build-support/docker/examples.nix
+++ b/pkgs/build-support/docker/examples.nix
@@ -187,4 +187,43 @@ rec {
     runAsRoot = "touch /example-file";
     fromImage = bash;
   };
+
+  # 13. example of 3 layers images This image is used to verify the
+  # order of layers is correct.
+  # It allows to validate
+  # - the layer of parent are below
+  # - the order of parent layer is preserved at image build time
+  #   (this is why there are 3 images)
+  layersOrder = let
+    l1 = pkgs.dockerTools.buildImage {
+      name = "l1";
+      tag = "latest";
+      extraCommands = ''
+        mkdir -p tmp
+        echo layer1 > tmp/layer1
+        echo layer1 > tmp/layer2
+        echo layer1 > tmp/layer3
+      '';
+    };
+    l2 = pkgs.dockerTools.buildImage {
+      name = "l2";
+      fromImage = l1;
+      tag = "latest";
+      extraCommands = ''
+        mkdir -p tmp
+        echo layer2 > tmp/layer2
+        echo layer2 > tmp/layer3
+      '';
+    };
+  in pkgs.dockerTools.buildImage {
+    name = "l3";
+    fromImage = l2;
+    tag = "latest";
+    contents = [ pkgs.coreutils ];
+    extraCommands = ''
+      mkdir -p tmp
+      echo layer3 > tmp/layer3
+    '';
+  };
+
 }