diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index 19ebed3ebd0b..8a240ddb17f2 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -215,6 +215,12 @@ import ./make-test-python.nix ({ pkgs, ... }: { f"docker run --rm ${examples.layersOrder.imageName} cat /tmp/layer{index}" ) + with subtest("Ensure layers unpacked in correct order before runAsRoot runs"): + assert "abc" in docker.succeed( + "docker load --input='${examples.layersUnpackOrder}'", + "docker run --rm ${examples.layersUnpackOrder.imageName} cat /layer-order" + ) + with subtest("Ensure environment variables are correctly inherited"): docker.succeed( "docker load --input='${examples.environmentVariables}'" diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index 9a20df57777c..1b6c340f7f0c 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -240,7 +240,7 @@ rec { # Unpack all of the parent layers into the image. lowerdir="" extractionID=0 - for layerTar in $(tac layer-list); do + for layerTar in $(cat layer-list); do echo "Unpacking layer $layerTar" extractionID=$((extractionID + 1)) diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix index f2d4f809ae4e..941ee048666d 100644 --- a/pkgs/build-support/docker/examples.nix +++ b/pkgs/build-support/docker/examples.nix @@ -405,6 +405,29 @@ rec { created = "now"; }; + # 23. Ensure that layers are unpacked in the correct order before the + # runAsRoot script is executed. + layersUnpackOrder = + let + layerOnTopOf = parent: layerName: + pkgs.dockerTools.buildImage { + name = "layers-unpack-order-${layerName}"; + tag = "latest"; + fromImage = parent; + contents = [ pkgs.coreutils ]; + runAsRoot = '' + #!${pkgs.runtimeShell} + echo -n "${layerName}" >> /layer-order + ''; + }; + # When executing the runAsRoot script when building layer C, if layer B is + # not unpacked on top of layer A, the contents of /layer-order will not be + # "ABC". + layerA = layerOnTopOf null "a"; + layerB = layerOnTopOf layerA "b"; + layerC = layerOnTopOf layerB "c"; + in layerC; + # buildImage without explicit tag bashNoTag = pkgs.dockerTools.buildImage { name = "bash-no-tag";