From 1e8b69c35e23760645e49f5055abe787b6743468 Mon Sep 17 00:00:00 2001 From: Tom Boettcher Date: Fri, 23 Sep 2016 16:10:47 -0500 Subject: [PATCH] dockerTools: Fix layer redundancy. When building an image with multiple layers, files already included in an underlying layer are supposed to be excluded from the current layer. However, some subtleties in the way filepaths are compared seem to be blocking this. Specifically: * tar generates relative filepaths with directories ending in '/' * find generates absolute filepaths with no trailing slashes on directories That is, paths extracted from the underlying tarball look like: nix/store/.../foobar/ whereas the layer being generated uses paths like: /nix/store/.../foobar This patch modifies the output of "tar -t" to match the latter format. --- pkgs/build-support/docker/default.nix | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index 4c5378ea73f3..dd5c523b91b5 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -1,5 +1,5 @@ { stdenv, lib, callPackage, runCommand, writeReferencesToFile, writeText, vmTools, writeScript -, docker, shadow, utillinux, coreutils, jshon, e2fsprogs, go, pigz }: +, docker, shadow, utillinux, coreutils, jshon, e2fsprogs, go, pigz, findutils }: # WARNING: this API is unstable and may be subject to backwards-incompatible changes in the future. @@ -249,7 +249,7 @@ EOF then mkPureLayer { inherit baseJson contents extraCommands; } else mkRootLayer { inherit baseJson fromImage fromImageName fromImageTag contents runAsRoot diskSize extraCommands; }); result = runCommand "${baseName}.tar.gz" { - buildInputs = [ jshon pigz ]; + buildInputs = [ jshon pigz coreutils findutils ]; imageName = name; imageTag = tag; @@ -261,6 +261,18 @@ EOF buildArgs = args; }; } '' + # Print tar contents: + # 1: Interpreted as relative to the root directory + # 2: With no trailing slashes on directories + # This is useful for ensuring that the output matches the values generated by the "find" command + ls_tar() { + for f in $(tar -tf $1 | xargs realpath -ms --relative-to=.); do + if [ "$f" != "." ]; then + echo "/$f" + fi + done + } + mkdir image touch baseFiles if [ -n "$fromImage" ]; then @@ -276,7 +288,7 @@ EOF parentID=$(jshon -e $fromImageName -e $fromImageTag -u < image/repositories) for l in image/*/layer.tar; do - tar -tf $l >> baseFiles + ls_tar $l >> baseFiles done fi @@ -297,8 +309,7 @@ EOF fi echo Adding layer - tar -tf temp/layer.tar >> baseFiles - sed 's/^\.//' -i baseFiles + ls_tar temp/layer.tar >> baseFiles comm <(sort -u baseFiles) <(sort -u layerFiles) -1 -3 > newFiles tar -rpf temp/layer.tar --mtime=0 --no-recursion --files-from newFiles 2>/dev/null || true