query
On this page

runWithOverlay

pkgs.dockerTools.runWithOverlay

Docs pulled from | This Revision | about 1 hour 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}
        '');