From ecc293ff7aa443f95117294e31e7a670e76cd6c7 Mon Sep 17 00:00:00 2001 From: Viktor Kronvall Date: Tue, 30 Mar 2021 16:04:47 +0900 Subject: [PATCH] dockerTools: Implement merging of image tarballs The `docker load` command supports loading tarballs that contain multiple docker images with their respective image names and tags. This enables distributing these images as a single file which simplifies the release of software when an application requires multiple services to run. However, pkgs.dockerTools only create tarballs with a single docker image and there exists is no mechanism in nixpkgs to combine the created tarballs. This commit implements merging of tarballs in a way that is compatible with `docker load`. --- pkgs/build-support/docker/default.nix | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index b03bfcca87f4..aebdb4a6fd81 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -682,6 +682,34 @@ rec { in result; + # Merge the tarballs of two images built with buildImage into a single + # tarball that contains both images. Running `docker load` on the resulting + # tarball with load both images into the docker daemon. + mergeImages = a: b: runCommand "merge-docker-images" + { + nativeBuildInputs = [ pigz jq ]; + } '' + mkdir a b image + # Extract images + tar -I pigz -xf ${a} -C a + tar -I pigz -xf ${b} -C b + # Make writable (to enable mv) + chmod -R +w a b + # Merge repositories objects (image:tag -> hash) + jq -s add a/repositories b/repositories > repositories + # Merge docker images manifests ([image]) + jq -s add a/manifest.json b/manifest.json > manifest.json + # Move layers to output directory + mv --no-clobber a/* image/ + mv --no-clobber b/* image/ + # Move merged repositories object and manifest list to output directory + mv repositories image/repositories + mv manifest.json image/manifest.json + # Create tarball and gzip + tar -C image --hard-dereference --sort=name --mtime="@$SOURCE_DATE_EPOCH" --owner=0 --group=0 --xform s:'^./':: -c . | pigz -nT > $out + ''; + + # Provide a /etc/passwd and /etc/group that contain root and nobody. # Useful when packaging binaries that insist on using nss to look up # username/groups (like nginx).