5 , img ? pkgs.stdenv.hostPlatform.linux-kernel.target
6 , storeDir ? builtins.storeDir
8 [ "virtio_pci" "virtio_mmio" "virtio_blk" "virtio_balloon" "virtio_rng" "ext4" "unix" "9p" "9pnet_virtio" "crc32c_generic" ]
9 ++ pkgs.lib.optional pkgs.stdenv.hostPlatform.isx86 "rtc_cmos"
13 inherit (pkgs) bash bashInteractive busybox cpio coreutils e2fsprogs fetchurl kmod rpm
15 buildPackages writeScript writeText runCommand;
18 qemu-common = import ../../../nixos/lib/qemu-common.nix { inherit lib pkgs; };
20 qemu = buildPackages.qemu_kvm;
22 modulesClosure = pkgs.makeModulesClosure {
23 inherit kernel rootModules;
28 hd = "vda"; # either "sda" or "vda"
30 initrdUtils = runCommand "initrd-utils"
31 { nativeBuildInputs = [ buildPackages.nukeReferences ];
32 allowedReferences = [ "out" modulesClosure ]; # prevent accidents like glibc being included in the initrd
38 # Copy what we need from Glibc.
40 ${pkgs.stdenv.cc.libc}/lib/ld-*.so.? \
41 ${pkgs.stdenv.cc.libc}/lib/libc.so.* \
42 ${pkgs.stdenv.cc.libc}/lib/libm.so.* \
43 ${pkgs.stdenv.cc.libc}/lib/libresolv.so.* \
44 ${pkgs.stdenv.cc.libc}/lib/libpthread.so.* \
45 ${pkgs.zstd.out}/lib/libzstd.so.* \
46 ${pkgs.xz.out}/lib/liblzma.so.* \
50 cp -pd ${pkgs.busybox}/bin/* $out/bin
51 cp -pd ${pkgs.kmod}/bin/* $out/bin
53 # Run patchelf to make the programs refer to the copied libraries.
54 for i in $out/bin/* $out/lib/*; do if ! test -L $i; then nuke-refs $i; fi; done
56 for i in $out/bin/*; do
57 if [ -f "$i" -a ! -L "$i" ]; then
59 patchelf --set-interpreter $out/lib/ld-*.so.? --set-rpath $out/lib $i || true
63 find $out/lib -type f \! -name 'ld*.so.?' | while read i; do
65 patchelf --set-rpath $out/lib $i
70 stage1Init = writeScript "vm-run-stage1" ''
71 #! ${initrdUtils}/bin/ash -e
73 export PATH=${initrdUtils}/bin
78 mount -t proc none /proc
79 mount -t sysfs none /sys
81 echo 2 > /proc/sys/vm/panic_on_oom
83 for o in $(cat /proc/cmdline); do
86 mountDisk=''${mountDisk#mountDisk=}
89 set -- $(IFS==; echo $o)
93 set -- $(IFS==; echo $o)
99 echo "loading kernel modules..."
100 for i in $(cat ${modulesClosure}/insmod-list); do
101 insmod $i || echo "warning: unable to load $i"
104 mount -t devtmpfs devtmpfs /dev
105 ln -s /proc/self/fd /dev/fd
106 ln -s /proc/self/fd/0 /dev/stdin
107 ln -s /proc/self/fd/1 /dev/stdout
108 ln -s /proc/self/fd/2 /dev/stderr
114 if test -z "$mountDisk"; then
115 mount -t tmpfs none /fs
116 elif [[ -e "$mountDisk" ]]; then
117 mount "$mountDisk" /fs
123 mount -o bind /dev /fs/dev
125 mkdir -p /fs/dev/shm /fs/dev/pts
126 mount -t tmpfs -o "mode=1777" none /fs/dev/shm
127 mount -t devpts none /fs/dev/pts
129 echo "mounting Nix store..."
130 mkdir -p /fs${storeDir}
131 mount -t 9p store /fs${storeDir} -o trans=virtio,version=9p2000.L,cache=loose,msize=131072
133 mkdir -p /fs/tmp /fs/run /fs/var
134 mount -t tmpfs -o "mode=1777" none /fs/tmp
135 mount -t tmpfs -o "mode=755" none /fs/run
136 ln -sfn /run /fs/var/run
138 echo "mounting host's temporary directory..."
139 mkdir -p /fs/tmp/xchg
140 mount -t 9p xchg /fs/tmp/xchg -o trans=virtio,version=9p2000.L,msize=131072
143 mount -t proc none /fs/proc
146 mount -t sysfs none /fs/sys
149 ln -sf /proc/mounts /fs/etc/mtab
150 echo "127.0.0.1 localhost" > /fs/etc/hosts
151 # Ensures tools requiring /etc/passwd will work (e.g. nix)
152 if [ ! -e /fs/etc/passwd ]; then
153 echo "root:x:0:0:System administrator:/root:/bin/sh" > /fs/etc/passwd
156 echo "starting stage 2 ($command)"
157 exec switch_root /fs $command $out
161 initrd = pkgs.makeInitrd {
163 { object = stage1Init;
170 stage2Init = writeScript "vm-run-stage2" ''
172 source /tmp/xchg/saved-env
174 # Set the system time from the hardware clock. Works around an
175 # apparent KVM > 1.5.2 bug.
176 ${util-linux}/bin/hwclock -s
178 export NIX_STORE=${storeDir}
179 export NIX_BUILD_TOP=/tmp
185 if ! test -e /bin/sh; then
186 ${coreutils}/bin/mkdir -p /bin
187 ${coreutils}/bin/ln -s ${bash}/bin/sh /bin/sh
190 # Set up automatic kernel module loading.
191 export MODULE_DIR=${kernel}/lib/modules/
192 ${coreutils}/bin/cat <<EOF > /run/modprobe
194 export MODULE_DIR=$MODULE_DIR
195 exec ${kmod}/bin/modprobe "\$@"
197 ${coreutils}/bin/chmod 755 /run/modprobe
198 echo /run/modprobe > /proc/sys/kernel/modprobe
200 # For debugging: if this is the second time this image is run,
201 # then don't start the build again, but instead drop the user into
202 # an interactive shell.
203 if test -n "$origBuilder" -a ! -e /.debug; then
205 ${coreutils}/bin/touch /.debug
206 $origBuilder $origArgs
207 echo $? > /tmp/xchg/in-vm-exit
209 ${busybox}/bin/mount -o remount,ro dummy /
211 ${busybox}/bin/poweroff -f
213 export PATH=/bin:/usr/bin:${coreutils}/bin
214 echo "Starting interactive shell..."
215 echo "(To run the original builder: \$origBuilder \$origArgs)"
216 exec ${busybox}/bin/setsid ${bashInteractive}/bin/bash < /dev/${qemu-common.qemuSerialDevice} &> /dev/${qemu-common.qemuSerialDevice}
221 qemuCommandLinux = ''
222 ${if (customQemu != null) then customQemu else (qemu-common.qemuBinary qemu)} \
223 -nographic -no-reboot \
224 -device virtio-rng-pci \
225 -virtfs local,path=${storeDir},security_model=none,mount_tag=store \
226 -virtfs local,path=$TMPDIR/xchg,security_model=none,mount_tag=xchg \
227 ''${diskImage:+-drive file=$diskImage,if=virtio,cache=unsafe,werror=report} \
228 -kernel ${kernel}/${img} \
229 -initrd ${initrd}/initrd \
230 -append "console=${qemu-common.qemuSerialDevice} panic=1 command=${stage2Init} out=$out mountDisk=$mountDisk loglevel=4" \
235 vmRunCommand = qemuCommand: writeText "vm-run" ''
238 PATH=${coreutils}/bin
244 if [ "$enableParallelBuilding" = 1 ]; then
245 if [ ''${NIX_BUILD_CORES:-0} = 0 ]; then
246 QEMU_OPTS+=" -smp cpus=$(nproc)"
248 QEMU_OPTS+=" -smp cpus=$NIX_BUILD_CORES"
252 # Write the command to start the VM to a file so that the user can
253 # debug inside the VM if the build fails (when Nix is called with
254 # the -K option to preserve the temporary build directory).
257 ''${diskImage:+diskImage=$diskImage}
263 mkdir -p -m 0700 $out
268 if ! test -e xchg/in-vm-exit; then
269 echo "Virtual machine didn't produce an exit code."
273 exitCode="$(cat xchg/in-vm-exit)"
274 if [ "$exitCode" != "0" ]; then
282 A bash script fragment that produces a disk image at `destination`.
285 # Disk image size in MiB
287 # Name that will be written to ${destination}/nix-support/full-name
289 # Where to write the image files, defaulting to $out
292 mkdir -p ${destination}
293 diskImage=${destination}/disk-image.qcow2
294 ${qemu}/bin/qemu-img create -f qcow2 $diskImage "${toString size}M"
296 mkdir ${destination}/nix-support
297 echo "${fullName}" > ${destination}/nix-support/full-name
301 defaultCreateRootFS = ''
303 ${e2fsprogs}/bin/mkfs.ext4 /dev/${hd}
304 ${util-linux}/bin/mount -t ext4 /dev/${hd} /mnt
306 if test -e /mnt/.debug; then
311 mkdir /mnt/proc /mnt/dev /mnt/sys
315 /* Run a derivation in a Linux virtual machine (using Qemu/KVM). By
316 default, there is no disk image; the root filesystem is a tmpfs,
317 and the nix store is shared with the host (via the 9P protocol).
318 Thus, any pure Nix derivation should run unmodified, e.g. the
321 runInLinuxVM patchelf
323 will build the derivation `patchelf' inside a VM. The attribute
324 `preVM' can optionally contain a shell command to be evaluated
325 *before* the VM is started (i.e., on the host). The attribute
326 `memSize' specifies the memory size of the VM in megabytes,
327 defaulting to 512. The attribute `diskImage' can optionally
328 specify a file system image to be attached to /dev/sda. (Note
329 that currently we expect the image to contain a filesystem, not a
330 full disk image with a partition table etc.)
332 If the build fails and Nix is run with the `-K' option, a script
333 `run-vm' will be left behind in the temporary build directory
334 that allows you to boot into the VM and debug it interactively. */
336 runInLinuxVM = drv: lib.overrideDerivation drv ({ memSize ? 512, QEMU_OPTS ? "", args, builder, ... }: {
337 requiredSystemFeatures = [ "kvm" ];
338 builder = "${bash}/bin/sh";
339 args = ["-e" (vmRunCommand qemuCommandLinux)];
341 origBuilder = builder;
342 QEMU_OPTS = "${QEMU_OPTS} -m ${toString memSize}";
343 passAsFile = []; # HACK fix - see https://github.com/NixOS/nixpkgs/issues/16742
347 extractFs = {file, fs ? null} :
349 stdenv.mkDerivation {
350 name = "extract-file";
351 buildInputs = [ util-linux ];
353 ln -s ${kernel}/lib /lib
354 ${kmod}/bin/modprobe loop
355 ${kmod}/bin/modprobe ext4
356 ${kmod}/bin/modprobe hfs
357 ${kmod}/bin/modprobe hfsplus
358 ${kmod}/bin/modprobe squashfs
359 ${kmod}/bin/modprobe iso9660
360 ${kmod}/bin/modprobe ufs
361 ${kmod}/bin/modprobe cramfs
365 mount -o loop,ro,ufstype=44bsd ${lib.optionalString (fs != null) "-t ${fs} "}${file} tmp ||
366 mount -o loop,ro ${lib.optionalString (fs != null) "-t ${fs} "}${file} tmp
367 cp -Rv tmp/* $out/ || exit 0
372 extractMTDfs = {file, fs ? null} :
374 stdenv.mkDerivation {
375 name = "extract-file-mtd";
376 buildInputs = [ pkgs.util-linux pkgs.mtdutils ];
378 ln -s ${kernel}/lib /lib
379 ${kmod}/bin/modprobe mtd
380 ${kmod}/bin/modprobe mtdram total_size=131072
381 ${kmod}/bin/modprobe mtdchar
382 ${kmod}/bin/modprobe mtdblock
383 ${kmod}/bin/modprobe jffs2
384 ${kmod}/bin/modprobe zlib
389 dd if=${file} of=/dev/mtd0
390 mount ${lib.optionalString (fs != null) "-t ${fs} "}/dev/mtdblock0 tmp
397 /* Like runInLinuxVM, but run the build not using the stdenv from
398 the Nix store, but using the tools provided by /bin, /usr/bin
399 etc. from the specified filesystem image, which typically is a
400 filesystem containing a non-NixOS Linux distribution. */
402 runInLinuxImage = drv: runInLinuxVM (lib.overrideDerivation drv (attrs: {
403 mountDisk = attrs.mountDisk or true;
405 /* Mount `image' as the root FS, but use a temporary copy-on-write
406 image since we don't want to (and can't) write to `image'. */
408 diskImage=$(pwd)/disk-image.qcow2
409 origImage=${attrs.diskImage}
410 if test -d "$origImage"; then origImage="$origImage/disk-image.qcow2"; fi
411 ${qemu}/bin/qemu-img create -F ${attrs.diskImageFormat} -b "$origImage" -f qcow2 $diskImage
414 /* Inside the VM, run the stdenv setup script normally, but at the
415 very end set $PATH and $SHELL to the `native' paths for the
416 distribution inside the VM. */
418 PATH=/usr/bin:/bin:/usr/sbin:/sbin
423 origPostHook = lib.optionalString (attrs ? postHook) attrs.postHook;
425 /* Don't run Nix-specific build steps like patchelf. */
430 /* Create a filesystem image of the specified size and fill it with
431 a set of RPM packages. */
434 { size ? 4096, rpms, name, fullName, preInstall ? "", postInstall ? ""
435 , runScripts ? true, createRootFS ? defaultCreateRootFS
436 , QEMU_OPTS ? "", memSize ? 512
437 , unifiedSystemDir ? false
440 runInLinuxVM (stdenv.mkDerivation {
441 inherit name preInstall postInstall rpms QEMU_OPTS memSize;
442 preVM = createEmptyImage {inherit size fullName;};
447 chroot=$(type -tP chroot)
449 # Make the Nix store available in /mnt, because that's where the RPMs live.
450 mkdir -p /mnt${storeDir}
451 ${util-linux}/bin/mount -o bind ${storeDir} /mnt${storeDir}
453 # Newer distributions like Fedora 18 require /lib etc. to be
455 ${lib.optionalString unifiedSystemDir ''
456 mkdir -p /mnt/usr/bin /mnt/usr/sbin /mnt/usr/lib /mnt/usr/lib64
457 ln -s /usr/bin /mnt/bin
458 ln -s /usr/sbin /mnt/sbin
459 ln -s /usr/lib /mnt/lib
460 ln -s /usr/lib64 /mnt/lib64
461 ${util-linux}/bin/mount -t proc none /mnt/proc
464 echo "unpacking RPMs..."
468 ${rpm}/bin/rpm2cpio "$i" | chroot /mnt ${cpio}/bin/cpio -i --make-directories --unconditional
473 echo "initialising RPM DB..."
474 PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \
476 PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \
479 ${util-linux}/bin/mount -o bind /tmp /mnt/tmp
481 echo "installing RPMs..."
482 PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \
483 rpm -iv --nosignature ${lib.optionalString (!runScripts) "--noscripts"} $rpms
485 echo "running post-install script..."
490 ${util-linux}/bin/umount /mnt${storeDir} /mnt/tmp ${lib.optionalString unifiedSystemDir "/mnt/proc"}
491 ${util-linux}/bin/umount /mnt
494 passthru = { inherit fullName; };
498 /* Generate a script that can be used to run an interactive session
499 in the given image. */
501 makeImageTestScript = image: writeScript "image-test" ''
503 if test -z "$1"; then
504 echo "Syntax: $0 <copy-on-write-temp-file>"
508 if ! test -e "$diskImage"; then
509 ${qemu}/bin/qemu-img create -b ${image}/disk-image.qcow2 -f qcow2 -F qcow2 "$diskImage"
511 export TMPDIR=$(mktemp -d)
516 export > $TMPDIR/xchg/saved-env
522 /* Build RPM packages from the tarball `src' in the Linux
523 distribution installed in the filesystem `diskImage'. The
524 tarball must contain an RPM specfile. */
526 buildRPM = attrs: runInLinuxImage (stdenv.mkDerivation ({
527 prePhases = [ "prepareImagePhase" "sysInfoPhase" ];
528 dontConfigure = true;
530 outDir = "rpms/${attrs.diskImage.name}";
532 prepareImagePhase = ''
533 if test -n "$extraRPMs"; then
534 for rpmdir in $extraRPMs ; do
535 rpm -iv $(ls $rpmdir/rpms/*/*.rpm | grep -v 'src\.rpm' | sort | head -1)
541 echo "System/kernel: $(uname -a)"
542 if test -e /etc/fedora-release; then echo "Fedora release: $(cat /etc/fedora-release)"; fi
543 if test -e /etc/SuSE-release; then echo "SUSE release: $(cat /etc/SuSE-release)"; fi
544 echo "installed RPM packages"
545 rpm -qa --qf "%{Name}-%{Version}-%{Release} (%{Arch}; %{Distribution}; %{Vendor})\n"
551 srcName="$(rpmspec --srpm -q --qf '%{source}' *.spec)"
552 cp "$src" "$srcName" # `ln' doesn't work always work: RPM requires that the file is owned by root
554 export HOME=/tmp/home
558 mkdir $rpmout $rpmout/SPECS $rpmout/BUILD $rpmout/RPMS $rpmout/SRPMS
560 echo "%_topdir $rpmout" >> $HOME/.rpmmacros
562 if [ `uname -m` = i686 ]; then extra="--target i686-linux"; fi
563 rpmbuild -vv $extra -ta "$srcName"
571 mkdir -p $out/$outDir
572 find $rpmout -name "*.rpm" -exec cp {} $out/$outDir \;
574 for i in $out/$outDir/*.rpm; do
575 echo "Generated RPM/SRPM: $i"
584 /* Create a filesystem image of the specified size and fill it with
585 a set of Debian packages. `debs' must be a list of list of
586 .deb files, namely, the Debian packages grouped together into
587 strongly connected components. See deb/deb-closure.nix. */
590 { size ? 4096, debs, name, fullName, postInstall ? null, createRootFS ? defaultCreateRootFS
591 , QEMU_OPTS ? "", memSize ? 512, ... }@args:
593 runInLinuxVM (stdenv.mkDerivation ({
594 inherit name postInstall QEMU_OPTS memSize;
596 debs = (lib.intersperse "|" debs);
598 preVM = createEmptyImage {inherit size fullName;};
603 PATH=$PATH:${lib.makeBinPath [ pkgs.dpkg pkgs.glibc pkgs.xz ]}
605 # Unpack the .debs. We do this to prevent pre-install scripts
606 # (which have lots of circular dependencies) from barfing.
607 echo "unpacking Debs..."
610 if test "$deb" != "|"; then
612 dpkg-deb --extract "$deb" /mnt
616 # Make the Nix store available in /mnt, because that's where the .debs live.
617 mkdir -p /mnt/inst${storeDir}
618 ${util-linux}/bin/mount -o bind ${storeDir} /mnt/inst${storeDir}
619 ${util-linux}/bin/mount -o bind /proc /mnt/proc
620 ${util-linux}/bin/mount -o bind /dev /mnt/dev
622 # Misc. files/directories assumed by various packages.
623 echo "initialising Dpkg DB..."
624 touch /mnt/etc/shells
625 touch /mnt/var/lib/dpkg/status
626 touch /mnt/var/lib/dpkg/available
627 touch /mnt/var/lib/dpkg/diversions
629 # Now install the .debs. This is basically just to register
630 # them with dpkg and to make their pre/post-install scripts
632 echo "installing Debs..."
634 export DEBIAN_FRONTEND=noninteractive
638 for component in $debs; do
641 echo ">>> INSTALLING COMPONENT: $component"
643 for i in $component; do
644 debs="$debs /inst/$i";
646 chroot=$(type -tP chroot)
648 # Create a fake start-stop-daemon script, as done in debootstrap.
649 mv "/mnt/sbin/start-stop-daemon" "/mnt/sbin/start-stop-daemon.REAL"
650 echo "#!/bin/true" > "/mnt/sbin/start-stop-daemon"
651 chmod 755 "/mnt/sbin/start-stop-daemon"
653 PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \
654 /usr/bin/dpkg --install --force-all $debs < /dev/null || true
656 # Move the real start-stop-daemon back into its place.
657 mv "/mnt/sbin/start-stop-daemon.REAL" "/mnt/sbin/start-stop-daemon"
660 echo "running post-install script..."
665 ${util-linux}/bin/umount /mnt/inst${storeDir}
666 ${util-linux}/bin/umount /mnt/proc
667 ${util-linux}/bin/umount /mnt/dev
668 ${util-linux}/bin/umount /mnt
671 passthru = { inherit fullName; };
675 /* Generate a Nix expression containing fetchurl calls for the
676 closure of a set of top-level RPM packages from the
677 `primary.xml.gz' file of a Fedora or openSUSE distribution. */
679 rpmClosureGenerator =
680 {name, packagesLists, urlPrefixes, packages, archs ? []}:
681 assert (builtins.length packagesLists) == (builtins.length urlPrefixes);
682 runCommand "${name}.nix" {
683 nativeBuildInputs = [ buildPackages.perl buildPackages.perlPackages.XMLSimple ];
686 ${lib.concatImapStrings (i: pl: ''
687 gunzip < ${pl} > ./packages_${toString i}.xml
689 perl -w ${rpm/rpm-closure.pl} \
690 ${lib.concatImapStrings (i: pl: "./packages_${toString i}.xml ${pl.snd} " ) (lib.zipLists packagesLists urlPrefixes)} \
691 ${toString packages} > $out
695 /* Helper function that combines rpmClosureGenerator and
696 fillDiskWithRPMs to generate a disk image from a set of package
699 makeImageFromRPMDist =
700 { name, fullName, size ? 4096
701 , urlPrefix ? "", urlPrefixes ? [urlPrefix]
702 , packagesList ? "", packagesLists ? [packagesList]
703 , packages, extraPackages ? []
704 , preInstall ? "", postInstall ? "", archs ? ["noarch" "i386"]
705 , runScripts ? true, createRootFS ? defaultCreateRootFS
706 , QEMU_OPTS ? "", memSize ? 512
707 , unifiedSystemDir ? false }:
710 inherit name fullName size preInstall postInstall runScripts createRootFS unifiedSystemDir QEMU_OPTS memSize;
711 rpms = import (rpmClosureGenerator {
712 inherit name packagesLists urlPrefixes archs;
713 packages = packages ++ extraPackages;
714 }) { inherit fetchurl; };
718 /* Like `rpmClosureGenerator', but now for Debian/Ubuntu releases
719 (i.e. generate a closure from a Packages.bz2 file). */
721 debClosureGenerator =
722 {name, packagesLists, urlPrefix, packages}:
724 runCommand "${name}.nix"
725 { nativeBuildInputs = [ buildPackages.perl buildPackages.dpkg ]; } ''
726 for i in ${toString packagesLists}; do
730 xz -d < $i >> ./Packages
733 bunzip2 < $i >> ./Packages
736 gzip -dc < $i >> ./Packages
741 perl -w ${deb/deb-closure.pl} \
742 ./Packages ${urlPrefix} ${toString packages} > $out
746 /* Helper function that combines debClosureGenerator and
747 fillDiskWithDebs to generate a disk image from a set of package
750 makeImageFromDebDist =
751 { name, fullName, size ? 4096, urlPrefix
752 , packagesList ? "", packagesLists ? [packagesList]
753 , packages, extraPackages ? [], postInstall ? ""
754 , extraDebs ? [], createRootFS ? defaultCreateRootFS
755 , QEMU_OPTS ? "", memSize ? 512, ... }@args:
758 expr = debClosureGenerator {
759 inherit name packagesLists urlPrefix;
760 packages = packages ++ extraPackages;
764 inherit name fullName size postInstall createRootFS QEMU_OPTS memSize;
765 debs = import expr {inherit fetchurl;} ++ extraDebs;
766 } // args)) // {inherit expr;};
769 /* The set of supported RPM-based distributions. */
773 # Note: no i386 release for Fedora >= 26
777 name = "fedora-${version}-x86_64";
778 fullName = "Fedora ${version} (x86_64)";
779 packagesList = fetchurl rec {
780 url = "mirror://fedora/linux/releases/${version}/Everything/x86_64/os/repodata/${sha256}-primary.xml.gz";
781 sha256 = "880055a50c05b20641530d09b23f64501a000b2f92fe252417c530178730a95e";
783 urlPrefix = "mirror://fedora/linux/releases/${version}/Everything/x86_64/os";
784 archs = ["noarch" "x86_64"];
785 packages = commonFedoraPackages ++ [ "cronie" "util-linux" ];
786 unifiedSystemDir = true;
792 name = "fedora-${version}-x86_64";
793 fullName = "Fedora ${version} (x86_64)";
794 packagesList = fetchurl rec {
795 url = "mirror://fedora/linux/releases/${version}/Everything/x86_64/os/repodata/${sha256}-primary.xml.gz";
796 sha256 = "48986ce4583cd09825c6d437150314446f0f49fa1a1bd62dcfa1085295030fe9";
798 urlPrefix = "mirror://fedora/linux/releases/${version}/Everything/x86_64/os";
799 archs = ["noarch" "x86_64"];
800 packages = commonFedoraPackages ++ [ "cronie" "util-linux" ];
801 unifiedSystemDir = true;
807 name = "centos-${version}-i386";
808 fullName = "CentOS ${version} (i386)";
809 urlPrefix = "mirror://centos/${version}/os/i386";
810 packagesList = fetchurl rec {
811 url = "${urlPrefix}/repodata/${sha256}-primary.xml.gz";
812 sha256 = "b826a45082ef68340325c0855f3d2e5d5a4d0f77d28ba3b871791d6f14a97aeb";
814 archs = ["noarch" "i386"];
815 packages = commonCentOSPackages ++ [ "procps" ];
821 name = "centos-${version}-x86_64";
822 fullName = "CentOS ${version} (x86_64)";
823 urlPrefix = "mirror://centos/${version}/os/x86_64";
824 packagesList = fetchurl rec {
825 url = "${urlPrefix}/repodata/${sha256}-primary.xml.gz";
826 sha256 = "ed2b2d4ac98d774d4cd3e91467e1532f7e8b0275cfc91a0d214b532dcaf1e979";
828 archs = ["noarch" "x86_64"];
829 packages = commonCentOSPackages ++ [ "procps" ];
832 # Note: no i386 release for 7.x
834 let version = "7.4.1708";
836 name = "centos-${version}-x86_64";
837 fullName = "CentOS ${version} (x86_64)";
838 urlPrefix = "mirror://centos/${version}/os/x86_64";
839 packagesList = fetchurl rec {
840 url = "${urlPrefix}/repodata/${sha256}-primary.xml.gz";
841 sha256 = "b686d3a0f337323e656d9387b9a76ce6808b26255fc3a138b1a87d3b1cb95ed5";
843 archs = ["noarch" "x86_64"];
844 packages = commonCentOSPackages ++ [ "procps-ng" ];
849 /* The set of supported Dpkg-based distributions. */
853 name = "ubuntu-14.04-trusty-i386";
854 fullName = "Ubuntu 14.04 Trusty (i386)";
857 url = "mirror://ubuntu/dists/trusty/main/binary-i386/Packages.bz2";
858 sha256 = "1d5y3v3v079gdq45hc07ja0bjlmzqfwdwwlq0brwxi8m75k3iz7x";
861 url = "mirror://ubuntu/dists/trusty/universe/binary-i386/Packages.bz2";
862 sha256 = "03x9w92by320rfklrqhcl3qpwmnxds9c8ijl5zhcb21d6dcz5z1a";
865 urlPrefix = "mirror://ubuntu";
866 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
870 name = "ubuntu-14.04-trusty-amd64";
871 fullName = "Ubuntu 14.04 Trusty (amd64)";
874 url = "mirror://ubuntu/dists/trusty/main/binary-amd64/Packages.bz2";
875 sha256 = "1hhzbyqfr5i0swahwnl5gfp5l9p9hspywb1vpihr3b74p1z935bh";
878 url = "mirror://ubuntu/dists/trusty/universe/binary-amd64/Packages.bz2";
879 sha256 = "04560ba8s4z4v5iawknagrkn9q1nzvpn081ycmqvhh73p3p3g1jm";
882 urlPrefix = "mirror://ubuntu";
883 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
887 name = "ubuntu-16.04-xenial-i386";
888 fullName = "Ubuntu 16.04 Xenial (i386)";
891 url = "mirror://ubuntu/dists/xenial/main/binary-i386/Packages.xz";
892 sha256 = "13r75sp4slqy8w32y5dnr7pp7p3cfvavyr1g7gwnlkyrq4zx4ahy";
895 url = "mirror://ubuntu/dists/xenial/universe/binary-i386/Packages.xz";
896 sha256 = "14fid1rqm3sc0wlygcvn0yx5aljf51c2jpd4x0zxij4019316hsh";
899 urlPrefix = "mirror://ubuntu";
900 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
904 name = "ubuntu-16.04-xenial-amd64";
905 fullName = "Ubuntu 16.04 Xenial (amd64)";
908 url = "mirror://ubuntu/dists/xenial/main/binary-amd64/Packages.xz";
909 sha256 = "110qnkhjkkwm316fbig3aivm2595ydz6zskc4ld5cr8ngcrqm1bn";
912 url = "mirror://ubuntu/dists/xenial/universe/binary-amd64/Packages.xz";
913 sha256 = "0mm7gj491yi6q4v0n4qkbsm94s59bvqir6fk60j73w7y4la8rg68";
916 urlPrefix = "mirror://ubuntu";
917 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
921 name = "ubuntu-18.04-bionic-i386";
922 fullName = "Ubuntu 18.04 Bionic (i386)";
925 url = "mirror://ubuntu/dists/bionic/main/binary-i386/Packages.xz";
926 sha256 = "0f0v4131kwf7m7f8j3288rlqdxk1k3vqy74b7fcfd6jz9j8d840i";
929 url = "mirror://ubuntu/dists/bionic/universe/binary-i386/Packages.xz";
930 sha256 = "1v75c0dqr0wp0dqd4hnci92qqs4hll8frqdbpswadgxm5chn91bw";
933 urlPrefix = "mirror://ubuntu";
934 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
938 name = "ubuntu-18.04-bionic-amd64";
939 fullName = "Ubuntu 18.04 Bionic (amd64)";
942 url = "mirror://ubuntu/dists/bionic/main/binary-amd64/Packages.xz";
943 sha256 = "1ls81bjyvmfz6i919kszl7xks1ibrh1xqhsk6698ackndkm0wp39";
946 url = "mirror://ubuntu/dists/bionic/universe/binary-amd64/Packages.xz";
947 sha256 = "1832nqpn4ap95b3sj870xqayrza9in4kih9jkmjax27pq6x15v1r";
950 urlPrefix = "mirror://ubuntu";
951 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
955 name = "ubuntu-20.04-focal-i386";
956 fullName = "Ubuntu 20.04 Focal (i386)";
959 url = "mirror://ubuntu/dists/focal/main/binary-i386/Packages.xz";
960 sha256 = "sha256-7RAYURoN3RKYQAHpwBS9TIV6vCmpURpphyMJQmV4wLc=";
963 url = "mirror://ubuntu/dists/focal/universe/binary-i386/Packages.xz";
964 sha256 = "sha256-oA551xVE80volUPgkMyvzpQ1d+GhuZd4DAe7dXZnULM=";
967 urlPrefix = "mirror://ubuntu";
968 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
972 name = "ubuntu-20.04-focal-amd64";
973 fullName = "Ubuntu 20.04 Focal (amd64)";
976 url = "mirror://ubuntu/dists/focal/main/binary-amd64/Packages.xz";
977 sha256 = "sha256-d1eSH/j+7Zw5NKDJk21EG6SiOL7j6myMHfXLzUP8mGE=";
980 url = "mirror://ubuntu/dists/focal/universe/binary-amd64/Packages.xz";
981 sha256 = "sha256-RqdG2seJvZU3rKVNsWgLnf9RwkgVMRE1A4IZnX2WudE=";
984 urlPrefix = "mirror://ubuntu";
985 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
989 name = "ubuntu-22.04-jammy-i386";
990 fullName = "Ubuntu 22.04 Jammy (i386)";
993 url = "mirror://ubuntu/dists/jammy/main/binary-i386/Packages.xz";
994 sha256 = "sha256-iZBmwT0ep4v+V3sayybbOgZBOFFZwPGpOKtmuLMMVPQ=";
997 url = "mirror://ubuntu/dists/jammy/universe/binary-i386/Packages.xz";
998 sha256 = "sha256-DO2LdpZ9rDDBhWj2gvDWd0TJJVZHxKsYTKTi6GXjm1E=";
1001 urlPrefix = "mirror://ubuntu";
1002 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
1005 ubuntu2204x86_64 = {
1006 name = "ubuntu-22.04-jammy-amd64";
1007 fullName = "Ubuntu 22.04 Jammy (amd64)";
1010 url = "mirror://ubuntu/dists/jammy/main/binary-amd64/Packages.xz";
1011 sha256 = "sha256-N8tX8VVMv6ccWinun/7hipqMF4K7BWjgh0t/9M6PnBE=";
1014 url = "mirror://ubuntu/dists/jammy/universe/binary-amd64/Packages.xz";
1015 sha256 = "sha256-0pyyTJP+xfQyVXBrzn60bUd5lSA52MaKwbsUpvNlXOI=";
1018 urlPrefix = "mirror://ubuntu";
1019 packages = commonDebPackages ++ [ "diffutils" "libc-bin" ];
1023 name = "debian-10.13-buster-i386";
1024 fullName = "Debian 10.13 Buster (i386)";
1025 packagesList = fetchurl {
1026 url = "https://snapshot.debian.org/archive/debian/20221126T084953Z/dists/buster/main/binary-i386/Packages.xz";
1027 hash = "sha256-n9JquhtZgxw3qr9BX0MQoY3ZTIHN0dit+iru3DC31UY=";
1029 urlPrefix = "https://snapshot.debian.org/archive/debian/20221126T084953Z";
1030 packages = commonDebianPackages;
1034 name = "debian-10.13-buster-amd64";
1035 fullName = "Debian 10.13 Buster (amd64)";
1036 packagesList = fetchurl {
1037 url = "https://snapshot.debian.org/archive/debian/20221126T084953Z/dists/buster/main/binary-amd64/Packages.xz";
1038 hash = "sha256-YukIIB3u87jgp9oudwklsxyKVKjSL618wFgDSXiFmjU=";
1040 urlPrefix = "https://snapshot.debian.org/archive/debian/20221126T084953Z";
1041 packages = commonDebianPackages;
1045 name = "debian-11.8-bullseye-i386";
1046 fullName = "Debian 11.8 Bullseye (i386)";
1047 packagesList = fetchurl {
1048 url = "https://snapshot.debian.org/archive/debian/20231124T031419Z/dists/bullseye/main/binary-i386/Packages.xz";
1049 hash = "sha256-0bKSLLPhEC7FB5D1NA2jaQP0wTe/Qp1ddiA/NDVjRaI=";
1051 urlPrefix = "https://snapshot.debian.org/archive/debian/20231124T031419Z";
1052 packages = commonDebianPackages;
1056 name = "debian-11.8-bullseye-amd64";
1057 fullName = "Debian 11.8 Bullseye (amd64)";
1058 packagesList = fetchurl {
1059 url = "https://snapshot.debian.org/archive/debian/20231124T031419Z/dists/bullseye/main/binary-amd64/Packages.xz";
1060 hash = "sha256-CYPsGgQgJZkh3JmbcAQkYDWP193qrkOADOgrMETZIeo=";
1062 urlPrefix = "https://snapshot.debian.org/archive/debian/20231124T031419Z";
1063 packages = commonDebianPackages;
1067 name = "debian-12.2-bookworm-i386";
1068 fullName = "Debian 12.2 Bookworm (i386)";
1069 packagesList = fetchurl {
1070 url = "https://snapshot.debian.org/archive/debian/20231124T031419Z/dists/bookworm/main/binary-i386/Packages.xz";
1071 hash = "sha256-OeN9Q2HFM3GsPNhOa4VhM7qpwT66yUNwC+6Z8SbGEeQ=";
1073 urlPrefix = "https://snapshot.debian.org/archive/debian/20231124T031419Z";
1074 packages = commonDebianPackages;
1078 name = "debian-12.2-bookworm-amd64";
1079 fullName = "Debian 12.2 Bookworm (amd64)";
1080 packagesList = fetchurl {
1081 url = "https://snapshot.debian.org/archive/debian/20231124T031419Z/dists/bookworm/main/binary-amd64/Packages.xz";
1082 hash = "sha256-SZDElRfe9BlBwDlajQB79Qdn08rv8whYoQDeVCveKVs=";
1084 urlPrefix = "https://snapshot.debian.org/archive/debian/20231124T031419Z";
1085 packages = commonDebianPackages;
1090 /* Common packages for Fedora images. */
1091 commonFedoraPackages = [
1106 "pkgconf-pkg-config"
1113 commonCentOSPackages = [
1135 commonRHELPackages = [
1157 /* Common packages for openSUSE images. */
1158 commonOpenSUSEPackages = [
1181 /* Common packages for Debian/Ubuntu images. */
1182 commonDebPackages = [
1202 # Needed by checkinstall:
1207 # Needed because it provides /etc/login.defs, whose absence causes
1208 # the "passwd" post-installs script to fail.
1213 commonDebianPackages = commonDebPackages ++ [ "sysvinit" "diff" ];
1216 /* A set of functions that build the Linux distributions specified
1217 in `rpmDistros' and `debDistros'. For instance,
1218 `diskImageFuns.ubuntu1004x86_64 { }' builds an Ubuntu 10.04 disk
1219 image containing the default packages specified above. Overrides
1220 of the default image parameters can be given. In particular,
1221 `extraPackages' specifies the names of additional packages from
1222 the distribution that should be included in the image; `packages'
1223 allows the entire set of packages to be overridden; and `size'
1224 sets the size of the disk in megabytes. E.g.,
1225 `diskImageFuns.ubuntu1004x86_64 { extraPackages = ["firefox"];
1226 size = 8192; }' builds an 8 GiB image containing Firefox in
1227 addition to the default packages. */
1229 (lib.mapAttrs (name: as: as2: makeImageFromRPMDist (as // as2)) rpmDistros) //
1230 (lib.mapAttrs (name: as: as2: makeImageFromDebDist (as // as2)) debDistros);
1233 /* Shorthand for `diskImageFuns.<attr> { extraPackages = ... }'. */
1234 diskImageExtraFuns =
1235 lib.mapAttrs (name: f: extraPackages: f { inherit extraPackages; }) diskImageFuns;
1238 /* Default disk images generated from the `rpmDistros' and
1239 `debDistros' sets. */
1240 diskImages = lib.mapAttrs (name: f: f {}) diskImageFuns;