From c0558450693d798481f91bbb4d0ccd04371a23c4 Mon Sep 17 00:00:00 2001 From: Yorick van Pelt Date: Fri, 3 May 2024 16:40:48 +0200 Subject: [PATCH 1/4] dockerTools.streamLayeredImage: add includeNixDB argument, expose conf and streamScript --- pkgs/build-support/docker/default.nix | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index 0583f522bda3..de081d709f9f 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -911,6 +911,8 @@ rec { , fakeRootCommands ? "" , enableFakechroot ? false , includeStorePaths ? true + # Generate a Nix DB inside the image. The same caveats as `buildImageWithNixDb` apply. + , includeNixDB ? false , passthru ? {} , }: @@ -941,7 +943,9 @@ rec { customisationLayer = symlinkJoin { name = "${baseName}-customisation-layer"; paths = contentsList; - inherit extraCommands fakeRootCommands; + extraCommands = + (lib.optionalString includeNixDB (mkDbExtraCommand contents)) + extraCommands; + inherit fakeRootCommands; nativeBuildInputs = [ fakeroot ] ++ optionals enableFakechroot [ @@ -1094,7 +1098,9 @@ rec { result = runCommand "stream-${baseName}" { + inherit conf; inherit (conf) imageName; + inherit streamScript; preferLocalBuild = true; passthru = passthru // { inherit (conf) imageTag; @@ -1105,7 +1111,7 @@ rec { }; nativeBuildInputs = [ makeWrapper ]; } '' - makeWrapper ${streamScript} $out --add-flags ${conf} + makeWrapper $streamScript $out --add-flags $conf ''; in result From 62e9e0f963afed39d02cba9d9d88dbb7f3bb47cf Mon Sep 17 00:00:00 2001 From: Yorick van Pelt Date: Mon, 6 May 2024 14:57:08 +0200 Subject: [PATCH 2/4] dockerTools: add includeNixDB to buildImage and document --- .../images/dockertools.section.md | 13 +++++++++ pkgs/build-support/docker/default.nix | 28 +++++++++---------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/doc/build-helpers/images/dockertools.section.md b/doc/build-helpers/images/dockertools.section.md index 001d5695290e..945bfdb27682 100644 --- a/doc/build-helpers/images/dockertools.section.md +++ b/doc/build-helpers/images/dockertools.section.md @@ -185,6 +185,19 @@ Similarly, if you encounter errors similar to `Error_Protocol ("certificate has _Default value:_ `"gz"`.\ _Possible values:_ `"none"`, `"gz"`, `"zstd"`. +`includeNixDB` (Boolean; _optional_) + +: Populate the nix database in the image with the dependencies of `copyToRoot`. + The main purpose is to be able to use nix commands in the container. + + :::{.caution} + Be careful since this doesn't work well in combination with `fromImage`. In particular, in a multi-layered image, only the Nix paths from the lower image will be in the database. + + This also neglects to register the store paths that are pulled into the image as a dependency of one of the other values, but aren't a dependency of `copyToRoot`. + ::: + + _Default value:_ `false`. + `contents` **DEPRECATED** : This attribute is deprecated, and users are encouraged to use `copyToRoot` instead. diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index de081d709f9f..d915778c0731 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -570,6 +570,8 @@ rec { created ? "1970-01-01T00:00:01Z" , # Compressor to use. One of: none, gz, zstd. compressor ? "gz" + # Populate the nix database in the image with the dependencies of `copyToRoot`. + , includeNixDB ? false , # Deprecated. contents ? null , @@ -607,20 +609,26 @@ rec { compress = compressorForImage compressor name; + # TODO: add the dependencies of the config json. + extraCommandsWithDB = + if includeNixDB then (mkDbExtraCommand rootContents) + extraCommands + else extraCommands; + layer = if runAsRoot == null then mkPureLayer { name = baseName; - inherit baseJson keepContentsDirlinks extraCommands uid gid; + inherit baseJson keepContentsDirlinks uid gid; + extraCommands = extraCommandsWithDB; copyToRoot = rootContents; } else mkRootLayer { name = baseName; inherit baseJson fromImage fromImageName fromImageTag - keepContentsDirlinks runAsRoot diskSize buildVMMemorySize - extraCommands; + keepContentsDirlinks runAsRoot diskSize buildVMMemorySize; + extraCommands = extraCommandsWithDB; copyToRoot = rootContents; }; result = runCommand "docker-image-${baseName}.tar${compress.ext}" @@ -879,18 +887,9 @@ rec { # the container. # Be careful since this doesn't work well with multilayer. # TODO: add the dependencies of the config json. - buildImageWithNixDb = args@{ copyToRoot ? contents, contents ? null, extraCommands ? "", ... }: ( - buildImage (args // { - extraCommands = (mkDbExtraCommand copyToRoot) + extraCommands; - }) - ); + buildImageWithNixDb = args: buildImage (args // { includeNixDB = true; }); - # TODO: add the dependencies of the config json. - buildLayeredImageWithNixDb = args@{ contents ? null, extraCommands ? "", ... }: ( - buildLayeredImage (args // { - extraCommands = (mkDbExtraCommand contents) + extraCommands; - }) - ); + buildLayeredImageWithNixDb = args: buildLayeredImage (args // { includeNixDB = true; }); # Arguments are documented in ../../../doc/build-helpers/images/dockertools.section.md streamLayeredImage = lib.makeOverridable ( @@ -911,7 +910,6 @@ rec { , fakeRootCommands ? "" , enableFakechroot ? false , includeStorePaths ? true - # Generate a Nix DB inside the image. The same caveats as `buildImageWithNixDb` apply. , includeNixDB ? false , passthru ? {} , From 4d51990bc5c4831bc25c29ea3efbcfe3630e2d45 Mon Sep 17 00:00:00 2001 From: Yorick van Pelt Date: Mon, 6 May 2024 15:06:50 +0200 Subject: [PATCH 3/4] dockerTools: document streamLayeredImage's includeNixDB argument --- doc/build-helpers/images/dockertools.section.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/build-helpers/images/dockertools.section.md b/doc/build-helpers/images/dockertools.section.md index 945bfdb27682..064a854a17eb 100644 --- a/doc/build-helpers/images/dockertools.section.md +++ b/doc/build-helpers/images/dockertools.section.md @@ -587,6 +587,19 @@ This allows the function to produce reproducible images. _Default value:_ `true` +`includeNixDB` (Boolean; _optional_) + +: Populate the nix database in the image with the dependencies of `copyToRoot`. + The main purpose is to be able to use nix commands in the container. + + :::{.caution} + Be careful since this doesn't work well in combination with `fromImage`. In particular, in a multi-layered image, only the Nix paths from the lower image will be in the database. + + This also neglects to register the store paths that are pulled into the image as a dependency of one of the other values, but aren't a dependency of `copyToRoot`. + ::: + + _Default value:_ `false`. + `passthru` (Attribute Set; _optional_) : Use this to pass any attributes as [passthru](#var-stdenv-passthru) for the resulting derivation. From 8891e98f24db151da233b74725067ea91b19d85a Mon Sep 17 00:00:00 2001 From: Yorick van Pelt Date: Mon, 6 May 2024 17:48:49 +0200 Subject: [PATCH 4/4] dockerTools: add nixDB tests --- nixos/tests/docker-tools.nix | 12 ++++++++++++ pkgs/build-support/docker/examples.nix | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/nixos/tests/docker-tools.nix b/nixos/tests/docker-tools.nix index 7d91076600f9..f71fff3f2a41 100644 --- a/nixos/tests/docker-tools.nix +++ b/nixos/tests/docker-tools.nix @@ -559,6 +559,12 @@ in { docker.succeed("docker run --rm image-with-certs:latest test -r /etc/pki/tls/certs/ca-bundle.crt") docker.succeed("docker image rm image-with-certs:latest") + with subtest("buildImageWithNixDB: Has a nix database"): + docker.succeed( + "docker load --input='${examples.nix}'", + "docker run --rm ${examples.nix.imageName} nix-store -q --references /bin/bash" + ) + with subtest("buildNixShellImage: Can build a basic derivation"): docker.succeed( "${examples.nix-shell-basic} | docker load", @@ -624,5 +630,11 @@ in { "${nonRootTestImage} | docker load", "docker run --rm ${chownTestImage.imageName} | diff /dev/stdin <(echo 12345:12345)" ) + + with subtest("streamLayeredImage: with nix db"): + docker.succeed( + "${examples.nix-layered} | docker load", + "docker run --rm ${examples.nix-layered.imageName} nix-store -q --references /bin/bash" + ) ''; }) diff --git a/pkgs/build-support/docker/examples.nix b/pkgs/build-support/docker/examples.nix index 72c1cbe0d410..cc6760f3aacf 100644 --- a/pkgs/build-support/docker/examples.nix +++ b/pkgs/build-support/docker/examples.nix @@ -881,4 +881,16 @@ rec { ''; }; + nix-layered = pkgs.dockerTools.streamLayeredImage { + name = "nix-layered"; + tag = "latest"; + contents = [ pkgs.nix pkgs.bash ]; + includeNixDB = true; + config = { + Env = [ + "NIX_PAGER=cat" + ]; + }; + }; + }