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`.
This commit is contained in:
Viktor Kronvall 2021-03-30 16:04:47 +09:00
parent e3c239fa55
commit ecc293ff7a

View File

@ -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).