From fff70110669973a561019f2c23e59fca5c9d0244 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 Nov 2006 17:56:50 +0000 Subject: [PATCH] Purifying the NixOS build stuff. * make-initrd.nix: builds a initial RAM disk. The resulting initrd will contain just a Nix store containing the specified lists of packages, with a symlink `/init' to the actual init program in the Nix store. * make-iso9660-image.nix: builds a bootable ISO image. * rescue-system.nix: builds a bootable ISO image (using the two function above) that boots into a very minimal Linux environment containing (at the moment) the dietlibc-based bash and coreutils, loaded from the initrd. Eventually this should become a two-stage boot (load kernel modules from the initrd, mount the actual root file system (e.g., the installation CD), call the real init). The rescue system (probably a misnomer) should become the minimal environment necessary for the installer (on CD) and the boot process of an installed NixOS (on HD). svn path=/nixu/trunk/; revision=6926 --- test/isolinux.cfg | 6 +++++ test/make-initrd.nix | 20 ++++++++++++++++ test/make-initrd.sh | 20 ++++++++++++++++ test/make-iso9660-image.nix | 28 ++++++++++++++++++++++ test/make-iso9660-image.sh | 10 ++++++++ test/rescue-system.nix | 47 +++++++++++++++++++++++++++++++++++++ 6 files changed, 131 insertions(+) create mode 100644 test/isolinux.cfg create mode 100644 test/make-initrd.nix create mode 100644 test/make-initrd.sh create mode 100644 test/make-iso9660-image.nix create mode 100644 test/make-iso9660-image.sh create mode 100644 test/rescue-system.nix diff --git a/test/isolinux.cfg b/test/isolinux.cfg new file mode 100644 index 00000000000..be947a949f7 --- /dev/null +++ b/test/isolinux.cfg @@ -0,0 +1,6 @@ +default linux +prompt 1 +timeout 60 +label linux + kernel vmlinuz + append initrd=initrd diff --git a/test/make-initrd.nix b/test/make-initrd.nix new file mode 100644 index 00000000000..f850e1cf657 --- /dev/null +++ b/test/make-initrd.nix @@ -0,0 +1,20 @@ +# Create an initial ramdisk containing the specified set of packages. +# An initial ramdisk is used during the initial stages of booting a +# Linux system. It is loaded by the boot loader along with the kernel +# image. It's supposed to contain everything (such as kernel modules) +# necessary to allow us to mount the root file system. Once the root +# file system is mounted, the `real' boot script can be called. +# +# An initrd is really just a gzipped cpio archive. +# +# A symlink `/init' is made to the store path passed in the `init' +# argument. + +{stdenv, cpio, packages, init}: + +stdenv.mkDerivation { + name = "initrd"; + builder = ./make-initrd.sh; + buildInputs = [cpio]; + inherit packages init; +} diff --git a/test/make-initrd.sh b/test/make-initrd.sh new file mode 100644 index 00000000000..f3b522d5384 --- /dev/null +++ b/test/make-initrd.sh @@ -0,0 +1,20 @@ +source $stdenv/setup + +set -o pipefail + +# Get the paths in the closure of `packages'. Unfortunately, the only +# way to get the closure is to call Nix, which is strictly speaking +# forbidden. But we do it anyway. In time, we should add a feature +# to Nix to let Nix pass closures to builders. +packagesClosure=$(/nix/bin/nix-store -qR $packages $init) + +# Paths in cpio archives *must* be relative, otherwise the kernel +# won't unpack 'em. +mkdir root +cd root +cp -prvd --parents $packagesClosure . + +# Put the closure in a gzipped cpio archive. +ensureDir $out +ln -s $init init +find * -print0 | cpio -ov -H newc --null | gzip -9 > $out/initrd diff --git a/test/make-iso9660-image.nix b/test/make-iso9660-image.nix new file mode 100644 index 00000000000..976f7047fd4 --- /dev/null +++ b/test/make-iso9660-image.nix @@ -0,0 +1,28 @@ +{ stdenv, cdrtools + + # The file name of the resulting ISO image. +, isoName ? "cd.iso" + +, # The files and directories to be placed in the ISO file system. + # This is a list of attribute sets {source, target} where `source' + # is the file system object (regular file or directory) to be + # grafted in the file system at path `target'. + contents + + # Whether this should be an El-Torito bootable CD. +, bootable ? false + + # The path (in the ISO file system) of the boot image. +, bootImage ? "" + +}: + +assert bootable -> bootImage != ""; + +stdenv.mkDerivation { + name = "iso9660-image"; + builder = ./make-iso9660-image.sh; + buildInputs = [cdrtools]; + inherit isoName bootable bootImage; + graftList = map ({source, target}: target + "=" + source) contents; +} diff --git a/test/make-iso9660-image.sh b/test/make-iso9660-image.sh new file mode 100644 index 00000000000..7e9017f41a1 --- /dev/null +++ b/test/make-iso9660-image.sh @@ -0,0 +1,10 @@ +source $stdenv/setup + +ensureDir $out + +if test -n "$bootable"; then + bootFlags="-b $bootImage -c boot.cat -no-emul-boot -boot-load-size 4" +fi + +# !!! -f is a quick hack. +mkisofs -r -J -f -o $out/$isoName $bootFlags -graft-points $graftList diff --git a/test/rescue-system.nix b/test/rescue-system.nix new file mode 100644 index 00000000000..ba8e0151037 --- /dev/null +++ b/test/rescue-system.nix @@ -0,0 +1,47 @@ +rec { + + pkgs = import ./pkgs/top-level/all-packages.nix {}; + + stdenvLinuxStuff = import ./pkgs/stdenv/linux { + system = pkgs.stdenv.system; + allPackages = import ./pkgs/top-level/all-packages.nix; + }; + + bash = pkgs.bash; + + + initialRamdisk = import ./make-initrd.nix { + inherit (pkgs) stdenv cpio; + packages = [ + stdenvLinuxStuff.staticTools + ]; + init = stdenvLinuxStuff.bootstrapTools.bash; + }; + + + rescueCD = import ./make-iso9660-image.nix { + inherit (pkgs) stdenv cdrtools; + isoName = "nixos.iso"; + + contents = [ + { source = pkgs.syslinux + "/lib/syslinux/isolinux.bin"; + target = "isolinux/isolinux.bin"; + } + { source = ./isolinux.cfg; + target = "isolinux/isolinux.cfg"; + } + { source = pkgs.kernel + "/vmlinuz"; + target = "isolinux/vmlinuz"; + } + { source = initialRamdisk + "/initrd"; + #/boot/initrd-2.6.13-15.12-default; + target = "isolinux/initrd"; + } + ]; + + bootable = true; + bootImage = "isolinux/isolinux.bin"; + }; + + +}