From 48cfdc8ca57bbd88b3d16ddb0c83c2be6a643f8c Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 1 Oct 2021 13:47:01 +0200 Subject: [PATCH 1/2] dockerTools: Add store dependencies of the customization layer --- nixos/tests/docker-tools.nix | 20 ++++++++++++++++---- pkgs/build-support/docker/default.nix | 4 ++-- pkgs/build-support/docker/examples.nix | 4 ++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index e482223436f..d2c2ca286ff 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -276,15 +276,22 @@ import ./make-test-python.nix ({ pkgs, ... }: { # Ensure the image has the correct number of layers assert len(set_of_layers("layered-bulk-layer")) == 4 - with subtest("Ensure correct behavior when no store is needed"): + with subtest("Ensure only minimal paths are added to the store"): + # TODO: make an example that has no store paths, for example by making + # busybox non-self-referential. + # This check tests that buildLayeredImage can build images that don't need a store. docker.succeed( "docker load --input='${pkgs.dockerTools.examples.no-store-paths}'" ) - # This check may be loosened to allow an *empty* store rather than *no* store. - docker.succeed("docker run --rm no-store-paths ls /") - docker.fail("docker run --rm no-store-paths ls /nix/store") + docker.succeed("docker run --rm no-store-paths ls / >/dev/console") + + # If busybox isn't self-referential, we need this line + # docker.fail("docker run --rm no-store-paths ls /nix/store >/dev/console") + # However, it currently is self-referential, so we check that it is the + # only store path. + docker.succeed("diff <(docker run --rm no-store-paths ls /nix/store) <(basename ${pkgs.pkgsStatic.busybox}) >/dev/console") with subtest("Ensure buildLayeredImage does not change store path contents."): docker.succeed( @@ -379,6 +386,11 @@ import ./make-test-python.nix ({ pkgs, ... }: { "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} sh -c 'stat -c '%u' /home/jane | grep -E ^1000$'" ) + with subtest("The image contains store paths referenced by the fakeRootCommands output"): + docker.succeed( + "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} /hello/bin/hello" + ) + with subtest("exportImage produces a valid tarball"): docker.succeed( "tar -tf ${examples.exportBash} | grep '\./bin/bash' > /dev/null" diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index 47fd99c12f8..fa71d430002 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -864,13 +864,13 @@ rec { }; closureRoots = lib.optionals includeStorePaths /* normally true */ ( - [ baseJson ] ++ contentsList + [ baseJson customisationLayer ] ); overallClosure = writeText "closure" (lib.concatStringsSep " " closureRoots); # These derivations are only created as implementation details of docker-tools, # so they'll be excluded from the created images. - unnecessaryDrvs = [ baseJson overallClosure ]; + unnecessaryDrvs = [ baseJson overallClosure customisationLayer ]; conf = runCommand "${baseName}-conf.json" { diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix index 9f6823a5878..0f7c3bd2820 100644 --- a/pkgs/build-support/docker/examples.nix +++ b/pkgs/build-support/docker/examples.nix @@ -350,6 +350,9 @@ rec { # This removes sharing of busybox and is not recommended. We do this # to make the example suitable as a test case with working binaries. cp -r ${pkgs.pkgsStatic.busybox}/* . + + # This is a "build" dependency that will not appear in the image + ${pkgs.hello}/bin/hello ''; }; @@ -504,6 +507,7 @@ rec { fakeRootCommands = '' mkdir -p ./home/jane chown 1000 ./home/jane + ln -s ${pkgs.pkgsStatic.hello} ./hello ''; }; From d0bcc212de13b1cd876bb8f01c90a8e8f42e25b6 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 2 Dec 2021 22:26:05 +0000 Subject: [PATCH 2/2] nixosTests.docker-tools: Use unique binary in test case --- nixos/tests/docker-tools.nix | 2 +- pkgs/build-support/docker/examples.nix | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index d2c2ca286ff..31c5a5909c3 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -388,7 +388,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { with subtest("The image contains store paths referenced by the fakeRootCommands output"): docker.succeed( - "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} /hello/bin/hello" + "docker run --rm ${examples.layeredImageWithFakeRootCommands.imageName} /hello/bin/layeredImageWithFakeRootCommands-hello" ) with subtest("exportImage produces a valid tarball"): diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix index 0f7c3bd2820..3861c25caa4 100644 --- a/pkgs/build-support/docker/examples.nix +++ b/pkgs/build-support/docker/examples.nix @@ -507,7 +507,11 @@ rec { fakeRootCommands = '' mkdir -p ./home/jane chown 1000 ./home/jane - ln -s ${pkgs.pkgsStatic.hello} ./hello + ln -s ${pkgs.hello.overrideAttrs (o: { + # A unique `hello` to make sure that it isn't included via another mechanism by accident. + configureFlags = o.configureFlags or "" + " --program-prefix=layeredImageWithFakeRootCommands-"; + doCheck = false; + })} ./hello ''; };