query
On this page

fillDiskWithDebs

pkgs.vmTools.fillDiskWithDebs

Docs pulled from | This Revision | 10 minutes ago


Create a filesystem image of the specified size and fill it with a set of Debian packages. `debs' must be a list of list of .deb files, namely, the Debian packages grouped together into strongly connected components. See deb/deb-closure.nix.


Noogle detected

Implementation

The following is the current implementation of this function.

fillDiskWithDebs =
    {
      size ? 4096,
      debs,
      name,
      fullName,
      postInstall ? null,
      createRootFS ? defaultCreateRootFS,
      QEMU_OPTS ? "",
      memSize ? 512,
      ...
    }@args:

    runInLinuxVM (
      stdenv.mkDerivation (
        {
          inherit
            name
            postInstall
            QEMU_OPTS
            memSize
            ;

          debs = (lib.intersperse "|" debs);

          preVM = createEmptyImage { inherit size fullName; };

          buildCommand = ''
            ${createRootFS}

            PATH=$PATH:${
              lib.makeBinPath [
                pkgs.dpkg
                pkgs.glibc
                pkgs.xz
              ]
            }

            # Unpack the .debs.  We do this to prevent pre-install scripts
            # (which have lots of circular dependencies) from barfing.
            echo "unpacking Debs..."

            for deb in $debs; do
              if test "$deb" != "|"; then
                echo "$deb..."
                dpkg-deb --extract "$deb" /mnt
              fi
            done

            # Make the Nix store available in /mnt, because that's where the .debs live.
            mkdir -p /mnt/inst${storeDir}
            ${util-linux}/bin/mount -o bind ${storeDir} /mnt/inst${storeDir}
            ${util-linux}/bin/mount -o bind /proc /mnt/proc
            ${util-linux}/bin/mount -o bind /dev /mnt/dev

            # Misc. files/directories assumed by various packages.
            echo "initialising Dpkg DB..."
            touch /mnt/etc/shells
            touch /mnt/var/lib/dpkg/status
            touch /mnt/var/lib/dpkg/available
            touch /mnt/var/lib/dpkg/diversions

            # Now install the .debs.  This is basically just to register
            # them with dpkg and to make their pre/post-install scripts
            # run.
            echo "installing Debs..."

            export DEBIAN_FRONTEND=noninteractive

            oldIFS="$IFS"
            IFS="|"
            for component in $debs; do
              IFS="$oldIFS"
              echo
              echo ">>> INSTALLING COMPONENT: $component"
              debs=
              for i in $component; do
                debs="$debs /inst/$i";
              done
              chroot=$(type -tP chroot)

              # Create a fake start-stop-daemon script, as done in debootstrap.
              mv "/mnt/sbin/start-stop-daemon" "/mnt/sbin/start-stop-daemon.REAL"
              echo "#!/bin/true" > "/mnt/sbin/start-stop-daemon"
              chmod 755 "/mnt/sbin/start-stop-daemon"

              PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \
                /usr/bin/dpkg --install --force-all $debs < /dev/null || true

              # Move the real start-stop-daemon back into its place.
              mv "/mnt/sbin/start-stop-daemon.REAL" "/mnt/sbin/start-stop-daemon"
            done

            echo "running post-install script..."
            eval "$postInstall"

            rm /mnt/.debug

            ${util-linux}/bin/umount /mnt/inst${storeDir}
            ${util-linux}/bin/umount /mnt/proc
            ${util-linux}/bin/umount /mnt/dev
            ${util-linux}/bin/umount /mnt
          '';

          passthru = { inherit fullName; };
        }
        // args
      )
    );