dockerTools: Add minimal test case for #214434

This commit is contained in:
Andrew Brooks 2023-02-03 17:49:39 -06:00
parent a59fe7abba
commit 6f63865cf4

View File

@ -1,6 +1,49 @@
# this test creates a simple GNU image with docker tools and sees if it executes
import ./make-test-python.nix ({ pkgs, ... }: {
import ./make-test-python.nix ({ pkgs, ... }:
let
# nixpkgs#214434: dockerTools.buildImage fails to unpack base images
# containing duplicate rootfs diffs when those duplicate tarballs
# appear under the manifest's 'Layers'. Docker can generate images
# like this even though dockerTools does not.
repeatedLayerTestImage =
let
# Rootfs diffs for layers 1 and 2 are identical (and empty)
layer1 = pkgs.dockerTools.buildImage { name = "empty"; };
layer2 = layer1.overrideAttrs (_: { fromImage = layer1; });
repeatedRootfsDiffs = pkgs.runCommandNoCC "image-with-links.tar" {
nativeBuildInputs = [pkgs.jq];
} ''
mkdir contents
tar -xf "${layer2}" -C contents
cd contents
first_rootfs=$(jq -r '.[0].Layers[0]' manifest.json)
second_rootfs=$(jq -r '.[0].Layers[1]' manifest.json)
target_rootfs=$(sha256sum "$first_rootfs" | cut -d' ' -f 1).tar
# Replace duplicated rootfs diffs with symlinks to one tarball
chmod -R ug+w .
mv "$first_rootfs" "$target_rootfs"
rm "$second_rootfs"
ln -s "../$target_rootfs" "$first_rootfs"
ln -s "../$target_rootfs" "$second_rootfs"
# Update manifest's layers to use the symlinks' target
cat manifest.json | \
jq ".[0].Layers[0] = \"$target_rootfs\"" |
jq ".[0].Layers[1] = \"$target_rootfs\"" > manifest.json.new
mv manifest.json.new manifest.json
tar --sort=name --hard-dereference -cf $out .
'';
in pkgs.dockerTools.buildImage {
fromImage = repeatedRootfsDiffs;
name = "repeated-layer-test";
copyToRoot = pkgs.bash;
# A runAsRoot script is required to force previous layers to be unpacked
runAsRoot = "";
};
in {
name = "docker-tools";
meta = with pkgs.lib.maintainers; {
maintainers = [ lnl7 roberth ];
@ -221,6 +264,12 @@ import ./make-test-python.nix ({ pkgs, ... }: {
"docker run --rm ${examples.layersUnpackOrder.imageName} cat /layer-order"
)
with subtest("Ensure repeated base layers handled by buildImage"):
docker.succeed(
"docker load --input='${repeatedLayerTestImage}'",
"docker run --rm ${repeatedLayerTestImage.imageName} /bin/bash -c 'exit 0'"
)
with subtest("Ensure environment variables are correctly inherited"):
docker.succeed(
"docker load --input='${examples.environmentVariables}'"