2009-06-05 15:35:27 +02:00
|
|
|
# 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.isoImage.
|
|
|
|
|
|
|
|
{config, pkgs, ...}:
|
|
|
|
|
|
|
|
let
|
2009-06-09 14:01:31 +02:00
|
|
|
|
|
|
|
options = {
|
|
|
|
|
2009-06-09 17:23:03 +02:00
|
|
|
isoImage.isoName = pkgs.lib.mkOption {
|
|
|
|
default = "cd.iso";
|
|
|
|
description = ''
|
|
|
|
Name of the generated ISO image file.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
isoImage.compressImage = pkgs.lib.mkOption {
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Whether the ISO image should be compressed using
|
|
|
|
<command>bzip2</command>.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
isoImage.volumeID = pkgs.lib.mkOption {
|
|
|
|
default = "NIXOS_BOOT_CD";
|
|
|
|
description = ''
|
|
|
|
Specifies the label or volume ID of the generated ISO image.
|
|
|
|
Note that the label is used by stage 1 of the boot process to
|
|
|
|
mount the CD, so it should be reasonably distinctive.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-06-09 14:01:31 +02:00
|
|
|
isoImage.contents = pkgs.lib.mkOption {
|
|
|
|
example =
|
|
|
|
[ { source = pkgs.memtest86 + "/memtest.bin";
|
|
|
|
target = "boot/memtest.bin";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
description = ''
|
2009-06-09 15:27:50 +02:00
|
|
|
This option lists files to be copied to fixed locations in the
|
|
|
|
generated ISO image.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
isoImage.storeContents = pkgs.lib.mkOption {
|
2009-06-10 18:29:48 +02:00
|
|
|
example = [pkgs.stdenv];
|
2009-06-09 15:27:50 +02:00
|
|
|
description = ''
|
|
|
|
This option lists additional derivations to be included in the
|
|
|
|
Nix store in the generated ISO image.
|
2009-06-09 14:01:31 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2009-06-05 15:35:27 +02:00
|
|
|
|
|
|
|
# The configuration file for Grub.
|
|
|
|
grubCfg =
|
|
|
|
''
|
|
|
|
default 0
|
|
|
|
timeout 10
|
|
|
|
splashimage /boot/background.xpm.gz
|
|
|
|
|
2009-06-09 14:01:31 +02:00
|
|
|
${config.boot.extraGrubEntries}
|
2009-06-05 15:35:27 +02:00
|
|
|
'';
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
{
|
2009-06-09 14:01:31 +02:00
|
|
|
require = options;
|
|
|
|
|
2009-06-05 15:35:27 +02:00
|
|
|
# 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 = "/";
|
2009-06-09 17:23:03 +02:00
|
|
|
label = config.isoImage.volumeID;
|
2009-06-05 15:35:27 +02:00
|
|
|
}
|
2009-06-10 18:29:48 +02:00
|
|
|
{ mountPoint = "/nix/store";
|
|
|
|
fsType = "squashfs";
|
|
|
|
device = "/nix-store.squashfs";
|
|
|
|
options = "loop";
|
|
|
|
neededForBoot = true;
|
|
|
|
}
|
2009-06-05 15:35:27 +02:00
|
|
|
];
|
|
|
|
|
2009-06-10 18:29:48 +02:00
|
|
|
# We need squashfs in the initrd to mount the compressed Nix store,
|
|
|
|
# and aufs to make the root filesystem appear writable.
|
2009-06-05 15:35:27 +02:00
|
|
|
boot.extraModulePackages = [config.boot.kernelPackages.aufs];
|
2009-06-10 18:29:48 +02:00
|
|
|
boot.initrd.extraKernelModules = ["aufs" "squashfs"];
|
2009-06-05 15:35:27 +02:00
|
|
|
|
|
|
|
# Tell stage 1 of the boot to mount a tmpfs on top of the CD using
|
|
|
|
# AUFS. !!! It would be nicer to make the stage 1 init pluggable
|
|
|
|
# and move that bit of code here.
|
|
|
|
boot.isLiveCD = true;
|
|
|
|
|
2009-06-10 18:29:48 +02:00
|
|
|
# Closures to be copied to the Nix store on the CD, namely the init
|
|
|
|
# script and the top-level system configuration directory.
|
|
|
|
isoImage.storeContents =
|
|
|
|
[ config.system.build.bootStage2
|
|
|
|
config.system.build.system
|
|
|
|
];
|
|
|
|
|
|
|
|
# Create the squashfs image that contains the Nix store.
|
|
|
|
system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
|
|
|
|
inherit (pkgs) stdenv squashfsTools perl pathsFromGraph;
|
|
|
|
storeContents = config.isoImage.storeContents;
|
|
|
|
};
|
|
|
|
|
2009-06-09 14:01:31 +02:00
|
|
|
# Individual files to be included on the CD, outside of the Nix
|
|
|
|
# store on the CD.
|
|
|
|
isoImage.contents =
|
|
|
|
[ { source = "${pkgs.grub}/lib/grub/${if pkgs.stdenv.system == "i686-linux" then "i386-pc" else "x86_64-unknown"}/stage2_eltorito";
|
|
|
|
target = "/boot/grub/stage2_eltorito";
|
|
|
|
}
|
|
|
|
{ source = pkgs.writeText "menu.lst" grubCfg;
|
|
|
|
target = "/boot/grub/menu.lst";
|
|
|
|
}
|
|
|
|
{ source = config.boot.kernelPackages.kernel + "/vmlinuz";
|
|
|
|
target = "/boot/vmlinuz";
|
|
|
|
}
|
|
|
|
{ source = config.system.build.initialRamdisk + "/initrd";
|
|
|
|
target = "/boot/initrd";
|
|
|
|
}
|
|
|
|
{ source = config.boot.grubSplashImage;
|
|
|
|
target = "/boot/background.xpm.gz";
|
|
|
|
}
|
2009-06-10 18:29:48 +02:00
|
|
|
{ source = config.system.build.squashfsStore;
|
|
|
|
target = "/nix-store.squashfs";
|
2009-06-09 15:27:50 +02:00
|
|
|
}
|
2009-06-10 18:29:48 +02:00
|
|
|
{ # Quick hack: need a mount point for the store.
|
|
|
|
source = pkgs.runCommand "empty" {} "ensureDir $out";
|
|
|
|
target = "/nix/store";
|
2009-06-09 15:27:50 +02:00
|
|
|
}
|
2009-06-10 23:46:42 +02:00
|
|
|
{ # Another quick hack: the kernel needs a systemConfig
|
|
|
|
# parameter in menu.lst, but the system config depends on
|
|
|
|
# menu.lst. Break the cyclic dependency by having a /system
|
|
|
|
# symlink on the CD, and having menu.lst refer to /system.
|
|
|
|
source = pkgs.runCommand "system" {}
|
|
|
|
"ln -s ${config.system.build.system} $out";
|
|
|
|
target = "/system";
|
|
|
|
}
|
2009-06-09 15:27:50 +02:00
|
|
|
];
|
|
|
|
|
2009-06-09 14:01:31 +02:00
|
|
|
# The Grub menu.
|
|
|
|
boot.extraGrubEntries =
|
|
|
|
''
|
|
|
|
title Boot from hard disk
|
|
|
|
root (hd0)
|
|
|
|
chainloader +1
|
|
|
|
|
|
|
|
title NixOS Installer / Rescue
|
2009-06-10 23:46:42 +02:00
|
|
|
kernel /boot/vmlinuz init=${config.system.build.bootStage2} systemConfig=/system ${toString config.boot.kernelParams}
|
2009-06-09 14:01:31 +02:00
|
|
|
initrd /boot/initrd
|
|
|
|
'';
|
|
|
|
|
2009-06-05 15:35:27 +02:00
|
|
|
# Create the ISO image.
|
|
|
|
system.build.isoImage = import ../../../lib/make-iso9660-image.nix {
|
|
|
|
inherit (pkgs) stdenv perl cdrkit pathsFromGraph;
|
2009-06-09 17:23:03 +02:00
|
|
|
|
2009-06-10 18:29:48 +02:00
|
|
|
inherit (config.isoImage) isoName compressImage volumeID contents;
|
2009-06-05 15:35:27 +02:00
|
|
|
|
|
|
|
bootable = true;
|
2009-06-09 14:01:31 +02:00
|
|
|
bootImage = "/boot/grub/stage2_eltorito";
|
2009-06-05 15:35:27 +02:00
|
|
|
};
|
2009-06-05 18:02:58 +02:00
|
|
|
|
|
|
|
boot.postBootCommands =
|
|
|
|
''
|
2009-06-10 18:29:48 +02:00
|
|
|
# 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
|
2009-06-10 14:51:16 +02:00
|
|
|
|
|
|
|
# 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
|
2009-06-05 18:02:58 +02:00
|
|
|
'';
|
2009-06-05 15:35:27 +02:00
|
|
|
}
|