diff --git a/lib/make-system-tarball.nix b/lib/make-system-tarball.nix new file mode 100644 index 00000000000..0fa34a186ad --- /dev/null +++ b/lib/make-system-tarball.nix @@ -0,0 +1,38 @@ +{ stdenv, perl, xz, pathsFromGraph + +, # The file name of the resulting tarball + fileName ? "nixos-built.tar.bz2" + +, # The files and directories to be placed in the tarball. + # 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 + +, # In addition to `contents', the closure of the store paths listed + # in `packages' are also placed in the Nix store of the tarball. This is + # a list of attribute sets {object, symlink} where `object' if a + # store path whose closure will be copied, and `symlink' is a + # symlink to `object' that will be added to the tarball. + storeContents ? [] +}: + +stdenv.mkDerivation { + name = "tarball"; + builder = ./make-system-tarball.sh; + buildInputs = [perl xz]; + + inherit fileName pathsFromGraph; + + # !!! should use XML. + sources = map (x: x.source) contents; + targets = map (x: x.target) contents; + + # !!! should use XML. + objects = map (x: x.object) storeContents; + symlinks = map (x: x.symlink) storeContents; + + # For obtaining the closure of `storeContents'. + exportReferencesGraph = + map (x: [("closure-" + baseNameOf x.object) x.object]) storeContents; +} diff --git a/lib/make-system-tarball.sh b/lib/make-system-tarball.sh new file mode 100644 index 00000000000..5465c3497aa --- /dev/null +++ b/lib/make-system-tarball.sh @@ -0,0 +1,56 @@ +source $stdenv/setup +set -x + +sources_=($sources) +targets_=($targets) + +echo $objects +objects=($objects) +symlinks=($symlinks) + + +# Remove the initial slash from a path, since genisofs likes it that way. +stripSlash() { + res="$1" + if test "${res:0:1}" = /; then res=${res:1}; fi +} + +touch pathlist + +# Add the individual files. +for ((i = 0; i < ${#targets_[@]}; i++)); do + stripSlash "${targets_[$i]}" + mkdir -p "$(dirname "$res")" + cp -a "${sources_[$i]}" "$res" +done + + +# Add the closures of the top-level store objects. +mkdir -p nix/store +storePaths=$(perl $pathsFromGraph closure-*) +for i in $storePaths; do + cp -a "$i" "${i:1}" +done + + +# TODO tar ruxo +# Also include a manifest of the closures in a format suitable for +# nix-store --load-db. +printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration + +# Add symlinks to the top-level store objects. +for ((n = 0; n < ${#objects[*]}; n++)); do + object=${objects[$n]} + symlink=${symlinks[$n]} + if test "$symlink" != "none"; then + mkdir -p $(dirname ./$symlink) + ln -s $object ./$symlink + fi +done + +ensureDir $out/tarball + +tar cvJf $out/tarball/$fileName.tar.xz * + +ensureDir $out/nix-support +echo $system > $out/nix-support/system diff --git a/modules/installer/cd-dvd/system-tarball-pc.nix b/modules/installer/cd-dvd/system-tarball-pc.nix new file mode 100644 index 00000000000..7774876447b --- /dev/null +++ b/modules/installer/cd-dvd/system-tarball-pc.nix @@ -0,0 +1,178 @@ +# This module contains the basic configuration for building a NixOS +# installation CD. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + # A dummy /etc/nixos/configuration.nix in the booted CD that + # rebuilds the CD's configuration (and allows the configuration to + # be modified, of course, providing a true live CD). Problem is + # that we don't really know how the CD was built - the Nix + # expression language doesn't allow us to query the expression being + # evaluated. So we'll just hope for the best. + dummyConfiguration = pkgs.writeText "configuration.nix" + '' + {config, pkgs, ...}: + + { + require = [ ]; + + # Add your own options below and run "nixos-rebuild switch". + # E.g., + # services.sshd.enable = true; + } + ''; + + + pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l; + + options = { + + system.nixosVersion = mkOption { + default = "${builtins.readFile ../../../VERSION}"; + description = '' + NixOS version number. + ''; + }; + }; + +in + +{ + require = + [ options + ./system-tarball.nix + ../../hardware/network/rt73.nix + ]; + + + # Disable some other stuff we don't need. + security.sudo.enable = false; + + # Include only the en_US locale. This saves 75 MiB or so compared to + # the full glibcLocales package. + i18n.supportedLocales = ["en_US.UTF-8/UTF-8" "en_US/ISO-8859-1"]; + + # Include some utilities that are useful for installing or repairing + # the system. + environment.systemPackages = + [ pkgs.subversion # for nixos-checkout + pkgs.w3m # needed for the manual anyway + pkgs.testdisk # useful for repairing boot problems + pkgs.mssys # for writing Microsoft boot sectors / MBRs + pkgs.parted + pkgs.ddrescue + pkgs.ccrypt + pkgs.cryptsetup # needed for dm-crypt volumes + + # Some networking tools. + pkgs.sshfsFuse + pkgs.socat + pkgs.screen + pkgs.wpa_supplicant # !!! should use the wpa module + + # Hardware-related tools. + pkgs.sdparm + pkgs.hdparm + pkgs.dmraid + + # Tools to create / manipulate filesystems. + pkgs.ntfsprogs # for resizing NTFS partitions + pkgs.btrfsProgs + pkgs.xfsprogs + pkgs.jfsutils + pkgs.jfsrec + + # Some compression/archiver tools. + pkgs.unrar + pkgs.unzip + pkgs.zip + pkgs.xz + pkgs.dar # disk archiver + + # Some editors. + pkgs.nvi + pkgs.bvi # binary editor + pkgs.joe + ]; + + # The initrd has to contain any module that might be necessary for + # mounting the CD/DVD. + boot.initrd.availableKernelModules = + [ # SATA/PATA support. + "ahci" + + "ata_piix" + + "sata_inic162x" "sata_nv" "sata_promise" "sata_qstor" + "sata_sil" "sata_sil24" "sata_sis" "sata_svw" "sata_sx4" + "sata_uli" "sata_via" "sata_vsc" + + "pata_ali" "pata_amd" "pata_artop" "pata_atiixp" + "pata_cs5520" "pata_cs5530" "pata_cs5535" "pata_efar" + "pata_hpt366" "pata_hpt37x" "pata_hpt3x2n" "pata_hpt3x3" + "pata_it8213" "pata_it821x" "pata_jmicron" "pata_marvell" + "pata_mpiix" "pata_netcell" "pata_ns87410" "pata_oldpiix" + "pata_pcmcia" "pata_pdc2027x" "pata_qdi" "pata_rz1000" + "pata_sc1200" "pata_serverworks" "pata_sil680" "pata_sis" + "pata_sl82c105" "pata_triflex" "pata_via" + "pata_winbond" + + # SCSI support (incomplete). + "3w-9xxx" "3w-xxxx" "aic79xx" "aic7xxx" "arcmsr" + + # USB support, especially for booting from USB CD-ROM + # drives. + "usb_storage" + + # Firewire support. Not tested. + "ohci1394" "sbp2" + + # Virtio (QEMU, KVM etc.) support. + "virtio_net" "virtio_pci" "virtio_blk" "virtio_balloon" + + # Add vfat to enable people to copy the contents of the CD to a + # bootable USB stick. + "vfat" + ]; + + boot.initrd.kernelModules = + [ # Wait for SCSI devices to appear. + "scsi_wait_scan" + ]; + + boot.postBootCommands = + '' + mkdir -p /mnt + + cp ${dummyConfiguration} /etc/nixos/configuration.nix + ''; + + # Some more help text. + services.mingetty.helpLine = + '' + + Log in as "root" with an empty password. ${ + if config.services.xserver.enable then + "Type `start xserver' to start\nthe graphical user interface." + else "" + } + ''; + + # Include the firmware for various wireless cards. + networking.enableRT73Firmware = true; + networking.enableIntel2200BGFirmware = true; + + # To speed up further installation of packages, include the complete stdenv + # in the Nix store of the tarball. + tarball.storeContents = pkgs2storeContents [ pkgs.stdenv pkgs.klibc pkgs.klibcShrunk ]; + + # Allow sshd to be started manually through "start sshd". It should + # not be started by default on the installation CD because the + # default root password is empty. + services.sshd.enable = true; + jobs.sshd.startOn = pkgs.lib.mkOverride 50 {} ""; +} diff --git a/modules/installer/cd-dvd/system-tarball.nix b/modules/installer/cd-dvd/system-tarball.nix new file mode 100644 index 00000000000..f5684c7c1eb --- /dev/null +++ b/modules/installer/cd-dvd/system-tarball.nix @@ -0,0 +1,126 @@ +# This module creates a bootable ISO image containing the given NixOS +# configuration. The derivation for the ISO image will be placed in +# config.system.build.tarball. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + options = { + tarball.contents = mkOption { + example = + [ { source = pkgs.memtest86 + "/memtest.bin"; + target = "boot/memtest.bin"; + } + ]; + description = '' + This option lists files to be copied to fixed locations in the + generated ISO image. + ''; + }; + + tarball.storeContents = mkOption { + example = [pkgs.stdenv]; + description = '' + This option lists additional derivations to be included in the + Nix store in the generated ISO image. + ''; + }; + + }; + + # A clue for the uboot loading + ubootKernelParams = pkgs.writeText "uboot-kernel-params.txt" '' + Kernel Parameters: + init=${config.system.build.bootStage2} + systemConfig=${config.system.build.toplevel} + ${toString config.boot.kernelParams} + ''; + + versionFile = pkgs.writeText "nixos-version" config.system.nixosVersion; + +in + +{ + require = options; + + # Don't build the GRUB menu builder script, since we don't need it + # here and it causes a cyclic dependency. + boot.loader.grub.enable = false; + + # !!! Hack - attributes expected by other modules. + system.build.menuBuilder = "true"; + system.boot.loader.kernelFile = "vmlinuz"; + environment.systemPackages = [ pkgs.grub2 ]; + + # In stage 1 of the boot, mount the CD/DVD as the root FS by label + # so that we don't need to know its device. + fileSystems = + [ { mountPoint = "/"; + label = "rootfs"; + } + ]; + + # boot.initrd.availableKernelModules = [ "mvsdio" "mmc_block" "reiserfs" "ext3" "ext4" ]; + + # boot.initrd.kernelModules = [ "rtc_mv" ]; + + # Closures to be copied to the Nix store on the CD, namely the init + # script and the top-level system configuration directory. + tarball.storeContents = + [ { + object = config.system.build.bootStage2; + symlink = "none"; + } + { + object = config.system.build.toplevel; + symlink = "/var/run/current-system"; + } + ]; + + # Individual files to be included on the CD, outside of the Nix + # store on the CD. + tarball.contents = + [ { source = config.boot.kernelPackages.kernel + "/vmlinuz"; + target = "/boot/vmlinuz"; + } + { source = config.system.build.initialRamdisk + "/initrd"; + target = "/boot/initrd"; + } + { source = "${pkgs.grub2}/share/grub/unicode.pf2"; + target = "/boot/grub/unicode.pf2"; + } + { source = config.boot.loader.grub.splashImage; + target = "/boot/grub/splash.png"; + } +/* + { source = pkgs.ubootKernelParams; + target = "/uboot-kernelparams.txt"; + } +*/ + { source = versionFile; + target = "/nixos-version.txt"; + } + ]; + + # Create the tarball + system.build.tarball = import ../../../lib/make-system-tarball.nix { + inherit (pkgs) stdenv perl xz pathsFromGraph; + + inherit (config.tarball) contents storeContents; + }; + + boot.postBootCommands = + '' + # After booting, register the contents of the Nix store on the + # CD in the Nix database in the tmpfs. + ${config.environment.nix}/bin/nix-store --load-db < /nix/store/nix-path-registration + + # nixos-rebuild also requires a "system" profile and an + # /etc/NIXOS tag. + touch /etc/NIXOS + ${config.environment.nix}/bin/nix-env -p /nix/var/nix/profiles/system --set /var/run/current-system + ''; +} diff --git a/release.nix b/release.nix index 91aa722e2a9..cecb773b434 100644 --- a/release.nix +++ b/release.nix @@ -40,6 +40,35 @@ let echo "file iso" $iso/iso/*.iso* >> $out/nix-support/hydra-build-products ''; # */ + makeSystemTarball = + { module, maintainers ? ["viric"]}: + { nixosSrc ? {outPath = ./.; rev = 1234;} + , officialRelease ? false + , system ? "i686-linux" + }: + + with import nixpkgs {inherit system;}; + + let + + version = builtins.readFile ./VERSION + (if officialRelease then "" else "pre${toString nixosSrc.rev}"); + + versionModule = { system.nixosVersion = version; }; + + config = (import lib/eval-config.nix { + inherit system nixpkgs; + modules = [ module versionModule ]; + }).config; + + tarball = config.system.build.tarball; + in + tarball // + { meta = { + description = "NixOS system tarball for ${system} - ${platform.name}"; + maintainers = map (x: lib.getAttr x lib.maintainers) maintainers; + }; + }; + jobs = rec { @@ -105,6 +134,14 @@ let description = "graphical"; }; + # Provide a tarball that can be unpacked into an SD card, and easily + # boot that system from uboot (like for the sheevaplug). + # The pc variant helps preparing the expression for the system tarball + # in a machine faster than the sheevpalug + system_tarball_pc = makeSystemTarball { + module = ./modules/installer/cd-dvd/system-tarball-pc.nix; + }; + # Hacky: doesn't depend on configuration. Yet configuration is evaluated (TODO) minimal_install_archive = {system ? "i686-linux"}: (iso_minimal {inherit system;}) .config.system.build.minimalInstallArchive;