runWithOverlay
pkgs.dockerTools.runWithOverlay
Docs pulled from | This Revision | 10 minutes ago
Run commands in a virtual machine.
Noogle detected
Implementation
The following is the current implementation of this function.
runWithOverlay =
{
name,
fromImage ? null,
fromImageName ? null,
fromImageTag ? null,
diskSize ? 1024,
buildVMMemorySize ? 512,
preMount ? "",
postMount ? "",
postUmount ? "",
}:
vmTools.runInLinuxVM (
runCommand name
{
preVM = vmTools.createEmptyImage {
size = diskSize;
fullName = "docker-run-disk";
destination = "./image";
};
inherit fromImage fromImageName fromImageTag;
memSize = buildVMMemorySize;
nativeBuildInputs = [
util-linux
e2fsprogs
jshon
rsync
jq
];
}
''
mkdir disk
mkfs /dev/${vmTools.hd}
mount /dev/${vmTools.hd} disk
cd disk
function dedup() {
declare -A seen
while read ln; do
if [[ -z "''${seen["$ln"]:-}" ]]; then
echo "$ln"; seen["$ln"]=1
fi
done
}
if [[ -n "$fromImage" ]]; then
echo "Unpacking base image..."
mkdir image
tar -C image -xpf "$fromImage"
if [[ -n "$fromImageName" ]] && [[ -n "$fromImageTag" ]]; then
parentID="$(
cat "image/manifest.json" |
jq -r '.[] | select(.RepoTags | contains([$desiredTag])) | rtrimstr(".json")' \
--arg desiredTag "$fromImageName:$fromImageTag"
)"
else
echo "From-image name or tag wasn't set. Reading the first ID."
parentID="$(cat "image/manifest.json" | jq -r '.[0].Config | rtrimstr(".json")')"
fi
# In case of repeated layers, unpack only the last occurrence of each
cat ./image/manifest.json | jq -r '.[0].Layers | .[]' | tac | dedup | tac > layer-list
else
touch layer-list
fi
# Unpack all of the parent layers into the image.
lowerdir=""
extractionID=0
for layerTar in $(cat layer-list); do
echo "Unpacking layer $layerTar"
extractionID=$((extractionID + 1))
mkdir -p image/$extractionID/layer
tar -C image/$extractionID/layer -xpf image/$layerTar
rm image/$layerTar
find image/$extractionID/layer -name ".wh.*" -exec bash -c 'name="$(basename {}|sed "s/^.wh.//")"; mknod "$(dirname {})/$name" c 0 0; rm {}' \;
# Get the next lower directory and continue the loop.
lowerdir=image/$extractionID/layer''${lowerdir:+:}$lowerdir
done
mkdir work
mkdir layer
mkdir mnt
${lib.optionalString (preMount != "") ''
# Execute pre-mount steps
echo "Executing pre-mount steps..."
${preMount}
''}
if [ -n "$lowerdir" ]; then
mount -t overlay overlay -olowerdir=$lowerdir,workdir=work,upperdir=layer mnt
else
mount --bind layer mnt
fi
${lib.optionalString (postMount != "") ''
# Execute post-mount steps
echo "Executing post-mount steps..."
${postMount}
''}
umount mnt
(
cd layer
cmd='name="$(basename {})"; touch "$(dirname {})/.wh.$name"; rm "{}"'
find . -type c -exec bash -c "$cmd" \;
)
${postUmount}
''
);