diff options
Diffstat (limited to 'nixos/modules/installer/cd-dvd')
19 files changed, 1829 insertions, 0 deletions
diff --git a/nixos/modules/installer/cd-dvd/channel.nix b/nixos/modules/installer/cd-dvd/channel.nix new file mode 100644 index 00000000000..92164d65e53 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/channel.nix @@ -0,0 +1,49 @@ +# Provide an initial copy of the NixOS channel so that the user +# doesn't need to run "nix-channel --update" first. + +{ config, lib, pkgs, ... }: + +with lib; + +let + nixpkgs = lib.cleanSource pkgs.path; + + # We need a copy of the Nix expressions for Nixpkgs and NixOS on the + # CD. These are installed into the "nixos" channel of the root + # user, as expected by nixos-rebuild/nixos-install. FIXME: merge + # with make-channel.nix. + channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}" + { preferLocalBuild = true; } + '' + mkdir -p $out + cp -prd ${nixpkgs.outPath} $out/nixos + chmod -R u+w $out/nixos + if [ ! -e $out/nixos/nixpkgs ]; then + ln -s . $out/nixos/nixpkgs + fi + ${optionalString (config.system.nixos.revision != null) '' + echo -n ${config.system.nixos.revision} > $out/nixos/.git-revision + ''} + echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix + echo ${config.system.nixos.versionSuffix} | sed -e s/pre// > $out/nixos/svn-revision + ''; + +in + +{ + # Provide the NixOS/Nixpkgs sources in /etc/nixos. This is required + # for nixos-install. + boot.postBootCommands = mkAfter + '' + if ! [ -e /var/lib/nixos/did-channel-init ]; then + echo "unpacking the NixOS/Nixpkgs sources..." + mkdir -p /nix/var/nix/profiles/per-user/root + ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/per-user/root/channels \ + -i ${channelSources} --quiet --option build-use-substitutes false + mkdir -m 0700 -p /root/.nix-defexpr + ln -s /nix/var/nix/profiles/per-user/root/channels /root/.nix-defexpr/channels + mkdir -m 0755 -p /var/lib/nixos + touch /var/lib/nixos/did-channel-init + fi + ''; +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-base.nix new file mode 100644 index 00000000000..618057618d0 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-base.nix @@ -0,0 +1,50 @@ +# This module contains the basic configuration for building a NixOS +# installation CD. + +{ config, lib, options, pkgs, ... }: + +with lib; + +{ + imports = + [ ./iso-image.nix + + # Profiles of this basic installation CD. + ../../profiles/all-hardware.nix + ../../profiles/base.nix + ../../profiles/installation-device.nix + ]; + + # Adds terminus_font for people with HiDPI displays + console.packages = options.console.packages.default ++ [ pkgs.terminus_font ]; + + # ISO naming. + isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.iso"; + + # EFI booting + isoImage.makeEfiBootable = true; + + # USB booting + isoImage.makeUsbBootable = true; + + # Add Memtest86+ to the CD. + boot.loader.grub.memtest86.enable = true; + + # An installation media cannot tolerate a host config defined file + # system layout on a fresh machine, before it has been formatted. + swapDevices = mkImageMediaOverride [ ]; + fileSystems = mkImageMediaOverride config.lib.isoFileSystems; + + boot.postBootCommands = '' + for o in $(</proc/cmdline); do + case "$o" in + live.nixos.passwd=*) + set -- $(IFS==; echo $o) + echo "nixos:$2" | ${pkgs.shadow}/bin/chpasswd + ;; + esac + done + ''; + + system.stateVersion = mkDefault "18.03"; +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix new file mode 100644 index 00000000000..fa19daf1328 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix @@ -0,0 +1,56 @@ +# This module contains the basic configuration for building a graphical NixOS +# installation CD. + +{ lib, pkgs, ... }: + +with lib; + +{ + imports = [ ./installation-cd-base.nix ]; + + # Whitelist wheel users to do anything + # This is useful for things like pkexec + # + # WARNING: this is dangerous for systems + # outside the installation-cd and shouldn't + # be used anywhere else. + security.polkit.extraConfig = '' + polkit.addRule(function(action, subject) { + if (subject.isInGroup("wheel")) { + return polkit.Result.YES; + } + }); + ''; + + services.xserver.enable = true; + + # Provide networkmanager for easy wireless configuration. + networking.networkmanager.enable = true; + networking.wireless.enable = mkForce false; + + # KDE complains if power management is disabled (to be precise, if + # there is no power management backend such as upower). + powerManagement.enable = true; + + # Enable sound in graphical iso's. + hardware.pulseaudio.enable = true; + + environment.systemPackages = [ + # Include gparted for partitioning disks. + pkgs.gparted + + # Include some editors. + pkgs.vim + pkgs.bvi # binary editor + pkgs.joe + + # Include some version control tools. + pkgs.git + + # Firefox for reading the manual. + pkgs.firefox + + pkgs.glxinfo + ]; + +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix new file mode 100644 index 00000000000..303493741f3 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix @@ -0,0 +1,38 @@ +# This module defines a NixOS installation CD that contains GNOME. + +{ lib, ... }: + +with lib; + +{ + imports = [ ./installation-cd-graphical-base.nix ]; + + isoImage.edition = "gnome"; + + services.xserver.desktopManager.gnome = { + # Add Firefox and other tools useful for installation to the launcher + favoriteAppsOverride = '' + [org.gnome.shell] + favorite-apps=[ 'firefox.desktop', 'nixos-manual.desktop', 'org.gnome.Terminal.desktop', 'org.gnome.Nautilus.desktop', 'gparted.desktop' ] + ''; + enable = true; + }; + + services.xserver.displayManager = { + gdm = { + enable = true; + # autoSuspend makes the machine automatically suspend after inactivity. + # It's possible someone could/try to ssh'd into the machine and obviously + # have issues because it's inactive. + # See: + # * https://github.com/NixOS/nixpkgs/pull/63790 + # * https://gitlab.gnome.org/GNOME/gnome-control-center/issues/22 + autoSuspend = false; + }; + autoLogin = { + enable = true; + user = "nixos"; + }; + }; + +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5-new-kernel.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5-new-kernel.nix new file mode 100644 index 00000000000..d98325a99ac --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5-new-kernel.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: + +{ + imports = [ ./installation-cd-graphical-plasma5.nix ]; + + boot.kernelPackages = pkgs.linuxPackages_latest; +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5.nix new file mode 100644 index 00000000000..098c2b2870b --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5.nix @@ -0,0 +1,50 @@ +# This module defines a NixOS installation CD that contains X11 and +# Plasma 5. + +{ config, lib, pkgs, ... }: + +with lib; + +{ + imports = [ ./installation-cd-graphical-base.nix ]; + + isoImage.edition = "plasma5"; + + services.xserver = { + desktopManager.plasma5 = { + enable = true; + }; + + # Automatically login as nixos. + displayManager = { + sddm.enable = true; + autoLogin = { + enable = true; + user = "nixos"; + }; + }; + }; + + environment.systemPackages = with pkgs; [ + # Graphical text editor + kate + ]; + + system.activationScripts.installerDesktop = let + + # Comes from documentation.nix when xserver and nixos.enable are true. + manualDesktopFile = "/run/current-system/sw/share/applications/nixos-manual.desktop"; + + homeDir = "/home/nixos/"; + desktopDir = homeDir + "Desktop/"; + + in '' + mkdir -p ${desktopDir} + chown nixos ${homeDir} ${desktopDir} + + ln -sfT ${manualDesktopFile} ${desktopDir + "nixos-manual.desktop"} + ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop ${desktopDir + "gparted.desktop"} + ln -sfT ${pkgs.konsole}/share/applications/org.kde.konsole.desktop ${desktopDir + "org.kde.konsole.desktop"} + ''; + +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix b/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix new file mode 100644 index 00000000000..3911a2b01b1 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: + +{ + imports = [ ./installation-cd-minimal.nix ]; + + boot.kernelPackages = pkgs.linuxPackages_latest; +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix b/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix new file mode 100644 index 00000000000..97506045e0e --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix @@ -0,0 +1,14 @@ +# This module defines a small NixOS installation CD. It does not +# contain any graphical stuff. + +{ ... }: + +{ + imports = + [ ./installation-cd-base.nix + ]; + + isoImage.edition = "minimal"; + + fonts.fontconfig.enable = false; +} diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix new file mode 100644 index 00000000000..3ff1b3d670e --- /dev/null +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -0,0 +1,811 @@ +# 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, lib, pkgs, ... }: + +with lib; + +let + /** + * Given a list of `options`, concats the result of mapping each options + * to a menuentry for use in grub. + * + * * defaults: {name, image, params, initrd} + * * options: [ option... ] + * * option: {name, params, class} + */ + menuBuilderGrub2 = + defaults: options: lib.concatStrings + ( + map + (option: '' + menuentry '${defaults.name} ${ + # Name appended to menuentry defaults to params if no specific name given. + option.name or (if option ? params then "(${option.params})" else "") + }' ${if option ? class then " --class ${option.class}" else ""} { + linux ${defaults.image} \''${isoboot} ${defaults.params} ${ + option.params or "" + } + initrd ${defaults.initrd} + } + '') + options + ) + ; + + /** + * Given a `config`, builds the default options. + */ + buildMenuGrub2 = config: + buildMenuAdditionalParamsGrub2 config "" + ; + + /** + * Given a `config` and params to add to `params`, build a set of default options. + * Use this one when creating a variant (e.g. hidpi) + */ + buildMenuAdditionalParamsGrub2 = config: additional: + let + finalCfg = { + name = "NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}"; + params = "init=${config.system.build.toplevel}/init ${additional} ${toString config.boot.kernelParams}"; + image = "/boot/${config.system.boot.loader.kernelFile}"; + initrd = "/boot/initrd"; + }; + in + menuBuilderGrub2 + finalCfg + [ + { class = "installer"; } + { class = "nomodeset"; params = "nomodeset"; } + { class = "copytoram"; params = "copytoram"; } + { class = "debug"; params = "debug"; } + ] + ; + + # Timeout in syslinux is in units of 1/10 of a second. + # 0 is used to disable timeouts. + syslinuxTimeout = if config.boot.loader.timeout == null then + 0 + else + max (config.boot.loader.timeout * 10) 1; + + + max = x: y: if x > y then x else y; + + # The configuration file for syslinux. + + # Notes on syslinux configuration and UNetbootin compatiblity: + # * Do not use '/syslinux/syslinux.cfg' as the path for this + # configuration. UNetbootin will not parse the file and use it as-is. + # This results in a broken configuration if the partition label does + # not match the specified config.isoImage.volumeID. For this reason + # we're using '/isolinux/isolinux.cfg'. + # * Use APPEND instead of adding command-line arguments directly after + # the LINUX entries. + # * COM32 entries (chainload, reboot, poweroff) are not recognized. They + # result in incorrect boot entries. + + baseIsolinuxCfg = '' + SERIAL 0 115200 + TIMEOUT ${builtins.toString syslinuxTimeout} + UI vesamenu.c32 + MENU TITLE NixOS + MENU BACKGROUND /isolinux/background.png + MENU RESOLUTION 800 600 + MENU CLEAR + MENU ROWS 6 + MENU CMDLINEROW -4 + MENU TIMEOUTROW -3 + MENU TABMSGROW -2 + MENU HELPMSGROW -1 + MENU HELPMSGENDROW -1 + MENU MARGIN 0 + + # FG:AARRGGBB BG:AARRGGBB shadow + MENU COLOR BORDER 30;44 #00000000 #00000000 none + MENU COLOR SCREEN 37;40 #FF000000 #00E2E8FF none + MENU COLOR TABMSG 31;40 #80000000 #00000000 none + MENU COLOR TIMEOUT 1;37;40 #FF000000 #00000000 none + MENU COLOR TIMEOUT_MSG 37;40 #FF000000 #00000000 none + MENU COLOR CMDMARK 1;36;40 #FF000000 #00000000 none + MENU COLOR CMDLINE 37;40 #FF000000 #00000000 none + MENU COLOR TITLE 1;36;44 #00000000 #00000000 none + MENU COLOR UNSEL 37;44 #FF000000 #00000000 none + MENU COLOR SEL 7;37;40 #FFFFFFFF #FF5277C3 std + + DEFAULT boot + + LABEL boot + MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} + LINUX /boot/${config.system.boot.loader.kernelFile} + APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} + INITRD /boot/${config.system.boot.loader.initrdFile} + + # A variant to boot with 'nomodeset' + LABEL boot-nomodeset + MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (nomodeset) + LINUX /boot/${config.system.boot.loader.kernelFile} + APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} nomodeset + INITRD /boot/${config.system.boot.loader.initrdFile} + + # A variant to boot with 'copytoram' + LABEL boot-copytoram + MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (copytoram) + LINUX /boot/${config.system.boot.loader.kernelFile} + APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} copytoram + INITRD /boot/${config.system.boot.loader.initrdFile} + + # A variant to boot with verbose logging to the console + LABEL boot-debug + MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (debug) + LINUX /boot/${config.system.boot.loader.kernelFile} + APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} loglevel=7 + INITRD /boot/${config.system.boot.loader.initrdFile} + + # A variant to boot with a serial console enabled + LABEL boot-serial + MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (serial console=ttyS0,115200n8) + LINUX /boot/${config.system.boot.loader.kernelFile} + APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} console=ttyS0,115200n8 + INITRD /boot/${config.system.boot.loader.initrdFile} + ''; + + isolinuxMemtest86Entry = '' + LABEL memtest + MENU LABEL Memtest86+ + LINUX /boot/memtest.bin + APPEND ${toString config.boot.loader.grub.memtest86.params} + ''; + + isolinuxCfg = concatStringsSep "\n" + ([ baseIsolinuxCfg ] ++ optional config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry); + + refindBinary = if targetArch == "x64" || targetArch == "aa64" then "refind_${targetArch}.efi" else null; + + # Setup instructions for rEFInd. + refind = + if refindBinary != null then + '' + # Adds rEFInd to the ISO. + cp -v ${pkgs.refind}/share/refind/${refindBinary} $out/EFI/boot/ + '' + else + "# No refind for ${targetArch}" + ; + + grubPkgs = if config.boot.loader.grub.forcei686 then pkgs.pkgsi686Linux else pkgs; + + grubMenuCfg = '' + # + # Menu configuration + # + + # Search using a "marker file" + search --set=root --file /EFI/nixos-installer-image + + insmod gfxterm + insmod png + set gfxpayload=keep + set gfxmode=${concatStringsSep "," [ + # GRUB will use the first valid mode listed here. + # `auto` will sometimes choose the smallest valid mode it detects. + # So instead we'll list a lot of possibly valid modes :/ + #"3840x2160" + #"2560x1440" + "1920x1080" + "1366x768" + "1280x720" + "1024x768" + "800x600" + "auto" + ]} + + # Fonts can be loaded? + # (This font is assumed to always be provided as a fallback by NixOS) + if loadfont (\$root)/EFI/boot/unicode.pf2; then + set with_fonts=true + fi + if [ "\$textmode" != "true" -a "\$with_fonts" == "true" ]; then + # Use graphical term, it can be either with background image or a theme. + # input is "console", while output is "gfxterm". + # This enables "serial" input and output only when possible. + # Otherwise the failure mode is to not even enable gfxterm. + if test "\$with_serial" == "yes"; then + terminal_output gfxterm serial + terminal_input console serial + else + terminal_output gfxterm + terminal_input console + fi + else + # Sets colors for the non-graphical term. + set menu_color_normal=cyan/blue + set menu_color_highlight=white/blue + fi + + ${ # When there is a theme configured, use it, otherwise use the background image. + if config.isoImage.grubTheme != null then '' + # Sets theme. + set theme=(\$root)/EFI/boot/grub-theme/theme.txt + # Load theme fonts + $(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/boot/grub-theme/%P\n") + '' else '' + if background_image (\$root)/EFI/boot/efi-background.png; then + # Black background means transparent background when there + # is a background image set... This seems undocumented :( + set color_normal=black/black + set color_highlight=white/blue + else + # Falls back again to proper colors. + set menu_color_normal=cyan/blue + set menu_color_highlight=white/blue + fi + ''} + ''; + + # The EFI boot image. + # Notes about grub: + # * Yes, the grubMenuCfg has to be repeated in all submenus. Otherwise you + # will get white-on-black console-like text on sub-menus. *sigh* + efiDir = pkgs.runCommand "efi-directory" { + nativeBuildInputs = [ pkgs.buildPackages.grub2_efi ]; + strictDeps = true; + } '' + mkdir -p $out/EFI/boot/ + + # Add a marker so GRUB can find the filesystem. + touch $out/EFI/nixos-installer-image + + # ALWAYS required modules. + MODULES="fat iso9660 part_gpt part_msdos \ + normal boot linux configfile loopback chain halt \ + efifwsetup efi_gop \ + ls search search_label search_fs_uuid search_fs_file \ + gfxmenu gfxterm gfxterm_background gfxterm_menu test all_video loadenv \ + exfat ext2 ntfs btrfs hfsplus udf \ + videoinfo png \ + echo serial \ + " + + echo "Building GRUB with modules:" + for mod in $MODULES; do + echo " - $mod" + done + + # Modules that may or may not be available per-platform. + echo "Adding additional modules:" + for mod in efi_uga; do + if [ -f ${grubPkgs.grub2_efi}/lib/grub/${grubPkgs.grub2_efi.grubTarget}/$mod.mod ]; then + echo " - $mod" + MODULES+=" $mod" + fi + done + + # Make our own efi program, we can't rely on "grub-install" since it seems to + # probe for devices, even with --skip-fs-probe. + grub-mkimage --directory=${grubPkgs.grub2_efi}/lib/grub/${grubPkgs.grub2_efi.grubTarget} -o $out/EFI/boot/boot${targetArch}.efi -p /EFI/boot -O ${grubPkgs.grub2_efi.grubTarget} \ + $MODULES + cp ${grubPkgs.grub2_efi}/share/grub/unicode.pf2 $out/EFI/boot/ + + cat <<EOF > $out/EFI/boot/grub.cfg + + set with_fonts=false + set textmode=false + # If you want to use serial for "terminal_*" commands, you need to set one up: + # Example manual configuration: + # → serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 + # This uses the defaults, and makes the serial terminal available. + set with_serial=no + if serial; then set with_serial=yes ;fi + export with_serial + clear + set timeout=10 + + # This message will only be viewable when "gfxterm" is not used. + echo "" + echo "Loading graphical boot menu..." + echo "" + echo "Press 't' to use the text boot menu on this console..." + echo "" + + ${grubMenuCfg} + + hiddenentry 'Text mode' --hotkey 't' { + loadfont (\$root)/EFI/boot/unicode.pf2 + set textmode=true + terminal_output gfxterm console + } + hiddenentry 'GUI mode' --hotkey 'g' { + $(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/boot/grub-theme/%P\n") + set textmode=false + terminal_output gfxterm + } + + + # If the parameter iso_path is set, append the findiso parameter to the kernel + # line. We need this to allow the nixos iso to be booted from grub directly. + if [ \''${iso_path} ] ; then + set isoboot="findiso=\''${iso_path}" + fi + + # + # Menu entries + # + + ${buildMenuGrub2 config} + submenu "HiDPI, Quirks and Accessibility" --class hidpi --class submenu { + ${grubMenuCfg} + submenu "Suggests resolution @720p" --class hidpi-720p { + ${grubMenuCfg} + ${buildMenuAdditionalParamsGrub2 config "video=1280x720@60"} + } + submenu "Suggests resolution @1080p" --class hidpi-1080p { + ${grubMenuCfg} + ${buildMenuAdditionalParamsGrub2 config "video=1920x1080@60"} + } + + # If we boot into a graphical environment where X is autoran + # and always crashes, it makes the media unusable. Allow the user + # to disable this. + submenu "Disable display-manager" --class quirk-disable-displaymanager { + ${grubMenuCfg} + ${buildMenuAdditionalParamsGrub2 config "systemd.mask=display-manager.service"} + } + + # Some laptop and convertibles have the panel installed in an + # inconvenient way, rotated away from the keyboard. + # Those entries makes it easier to use the installer. + submenu "" {return} + submenu "Rotate framebuffer Clockwise" --class rotate-90cw { + ${grubMenuCfg} + ${buildMenuAdditionalParamsGrub2 config "fbcon=rotate:1"} + } + submenu "Rotate framebuffer Upside-Down" --class rotate-180 { + ${grubMenuCfg} + ${buildMenuAdditionalParamsGrub2 config "fbcon=rotate:2"} + } + submenu "Rotate framebuffer Counter-Clockwise" --class rotate-90ccw { + ${grubMenuCfg} + ${buildMenuAdditionalParamsGrub2 config "fbcon=rotate:3"} + } + + # As a proof of concept, mainly. (Not sure it has accessibility merits.) + submenu "" {return} + submenu "Use black on white" --class accessibility-blakconwhite { + ${grubMenuCfg} + ${buildMenuAdditionalParamsGrub2 config "vt.default_red=0xFF,0xBC,0x4F,0xB4,0x56,0xBC,0x4F,0x00,0xA1,0xCF,0x84,0xCA,0x8D,0xB4,0x84,0x68 vt.default_grn=0xFF,0x55,0xBA,0xBA,0x4D,0x4D,0xB3,0x00,0xA0,0x8F,0xB3,0xCA,0x88,0x93,0xA4,0x68 vt.default_blu=0xFF,0x58,0x5F,0x58,0xC5,0xBD,0xC5,0x00,0xA8,0xBB,0xAB,0x97,0xBD,0xC7,0xC5,0x68"} + } + + # Serial access is a must! + submenu "" {return} + submenu "Serial console=ttyS0,115200n8" --class serial { + ${grubMenuCfg} + ${buildMenuAdditionalParamsGrub2 config "console=ttyS0,115200n8"} + } + } + + ${lib.optionalString (refindBinary != null) '' + # GRUB apparently cannot do "chainloader" operations on "CD". + if [ "\$root" != "cd0" ]; then + # Force root to be the FAT partition + # Otherwise it breaks rEFInd's boot + search --set=root --no-floppy --fs-uuid 1234-5678 + menuentry 'rEFInd' --class refind { + chainloader (\$root)/EFI/boot/${refindBinary} + } + fi + ''} + menuentry 'Firmware Setup' --class settings { + fwsetup + clear + echo "" + echo "If you see this message, your EFI system doesn't support this feature." + echo "" + } + menuentry 'Shutdown' --class shutdown { + halt + } + EOF + + ${refind} + ''; + + efiImg = pkgs.runCommand "efi-image_eltorito" { + nativeBuildInputs = [ pkgs.buildPackages.mtools pkgs.buildPackages.libfaketime pkgs.buildPackages.dosfstools ]; + strictDeps = true; + } + # Be careful about determinism: du --apparent-size, + # dates (cp -p, touch, mcopy -m, faketime for label), IDs (mkfs.vfat -i) + '' + mkdir ./contents && cd ./contents + cp -rp "${efiDir}"/EFI . + mkdir ./boot + cp -p "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}" \ + "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}" ./boot/ + + # Rewrite dates for everything in the FS + find . -exec touch --date=2000-01-01 {} + + + # Round up to the nearest multiple of 1MB, for more deterministic du output + usage_size=$(( $(du -s --block-size=1M --apparent-size . | tr -cd '[:digit:]') * 1024 * 1024 )) + # Make the image 110% as big as the files need to make up for FAT overhead + image_size=$(( ($usage_size * 110) / 100 )) + # Make the image fit blocks of 1M + block_size=$((1024*1024)) + image_size=$(( ($image_size / $block_size + 1) * $block_size )) + echo "Usage size: $usage_size" + echo "Image size: $image_size" + truncate --size=$image_size "$out" + faketime "2000-01-01 00:00:00" mkfs.vfat -i 12345678 -n EFIBOOT "$out" + + # Force a fixed order in mcopy for better determinism, and avoid file globbing + for d in $(find EFI boot -type d | sort); do + faketime "2000-01-01 00:00:00" mmd -i "$out" "::/$d" + done + + for f in $(find EFI boot -type f | sort); do + mcopy -pvm -i "$out" "$f" "::/$f" + done + + # Verify the FAT partition. + fsck.vfat -vn "$out" + ''; # */ + + # Name used by UEFI for architectures. + targetArch = + if pkgs.stdenv.isi686 || config.boot.loader.grub.forcei686 then + "ia32" + else if pkgs.stdenv.isx86_64 then + "x64" + else if pkgs.stdenv.isAarch32 then + "arm" + else if pkgs.stdenv.isAarch64 then + "aa64" + else + throw "Unsupported architecture"; + + # Syslinux (and isolinux) only supports x86-based architectures. + canx86BiosBoot = pkgs.stdenv.hostPlatform.isx86; + +in + +{ + options = { + + isoImage.isoName = mkOption { + default = "${config.isoImage.isoBaseName}.iso"; + description = '' + Name of the generated ISO image file. + ''; + }; + + isoImage.isoBaseName = mkOption { + default = "nixos"; + description = '' + Prefix of the name of the generated ISO image file. + ''; + }; + + isoImage.compressImage = mkOption { + default = false; + description = '' + Whether the ISO image should be compressed using + <command>zstd</command>. + ''; + }; + + isoImage.squashfsCompression = mkOption { + default = with pkgs.stdenv.targetPlatform; "xz -Xdict-size 100% " + + lib.optionalString (isx86_32 || isx86_64) "-Xbcj x86" + # Untested but should also reduce size for these platforms + + lib.optionalString (isAarch32 || isAarch64) "-Xbcj arm" + + lib.optionalString (isPowerPC) "-Xbcj powerpc" + + lib.optionalString (isSparc) "-Xbcj sparc"; + description = '' + Compression settings to use for the squashfs nix store. + ''; + example = "zstd -Xcompression-level 6"; + }; + + isoImage.edition = mkOption { + default = ""; + description = '' + Specifies which edition string to use in the volume ID of the generated + ISO image. + ''; + }; + + isoImage.volumeID = mkOption { + # nixos-$EDITION-$RELEASE-$ARCH + default = "nixos${optionalString (config.isoImage.edition != "") "-${config.isoImage.edition}"}-${config.system.nixos.release}-${pkgs.stdenv.hostPlatform.uname.processor}"; + 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. + ''; + }; + + isoImage.contents = mkOption { + example = literalExpression '' + [ { 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. + ''; + }; + + isoImage.storeContents = mkOption { + example = literalExpression "[ pkgs.stdenv ]"; + description = '' + This option lists additional derivations to be included in the + Nix store in the generated ISO image. + ''; + }; + + isoImage.includeSystemBuildDependencies = mkOption { + default = false; + description = '' + Set this option to include all the needed sources etc in the + image. It significantly increases image size. Use that when + you want to be able to keep all the sources needed to build your + system or when you are going to install the system on a computer + with slow or non-existent network connection. + ''; + }; + + isoImage.makeEfiBootable = mkOption { + default = false; + description = '' + Whether the ISO image should be an efi-bootable volume. + ''; + }; + + isoImage.makeUsbBootable = mkOption { + default = false; + description = '' + Whether the ISO image should be bootable from CD as well as USB. + ''; + }; + + isoImage.efiSplashImage = mkOption { + default = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/NixOS/nixos-artwork/a9e05d7deb38a8e005a2b52575a3f59a63a4dba0/bootloader/efi-background.png"; + sha256 = "18lfwmp8yq923322nlb9gxrh5qikj1wsk6g5qvdh31c4h5b1538x"; + }; + description = '' + The splash image to use in the EFI bootloader. + ''; + }; + + isoImage.splashImage = mkOption { + default = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/NixOS/nixos-artwork/a9e05d7deb38a8e005a2b52575a3f59a63a4dba0/bootloader/isolinux/bios-boot.png"; + sha256 = "1wp822zrhbg4fgfbwkr7cbkr4labx477209agzc0hr6k62fr6rxd"; + }; + description = '' + The splash image to use in the legacy-boot bootloader. + ''; + }; + + isoImage.grubTheme = mkOption { + default = pkgs.nixos-grub2-theme; + type = types.nullOr (types.either types.path types.package); + description = '' + The grub2 theme used for UEFI boot. + ''; + }; + + isoImage.appendToMenuLabel = mkOption { + default = " Installer"; + example = " Live System"; + description = '' + The string to append after the menu label for the NixOS system. + This will be directly appended (without whitespace) to the NixOS version + string, like for example if it is set to <literal>XXX</literal>: + + <para><literal>NixOS 99.99-pre666XXX</literal></para> + ''; + }; + + }; + + # store them in lib so we can mkImageMediaOverride the + # entire file system layout in installation media (only) + config.lib.isoFileSystems = { + "/" = mkImageMediaOverride + { + fsType = "tmpfs"; + options = [ "mode=0755" ]; + }; + + # Note that /dev/root is a symlink to the actual root device + # specified on the kernel command line, created in the stage 1 + # init script. + "/iso" = mkImageMediaOverride + { device = "/dev/root"; + neededForBoot = true; + noCheck = true; + }; + + # In stage 1, mount a tmpfs on top of /nix/store (the squashfs + # image) to make this a live CD. + "/nix/.ro-store" = mkImageMediaOverride + { fsType = "squashfs"; + device = "/iso/nix-store.squashfs"; + options = [ "loop" ]; + neededForBoot = true; + }; + + "/nix/.rw-store" = mkImageMediaOverride + { fsType = "tmpfs"; + options = [ "mode=0755" ]; + neededForBoot = true; + }; + + "/nix/store" = mkImageMediaOverride + { fsType = "overlay"; + device = "overlay"; + options = [ + "lowerdir=/nix/.ro-store" + "upperdir=/nix/.rw-store/store" + "workdir=/nix/.rw-store/work" + ]; + depends = [ + "/nix/.ro-store" + "/nix/.rw-store/store" + "/nix/.rw-store/work" + ]; + }; + }; + + config = { + assertions = [ + { + assertion = !(stringLength config.isoImage.volumeID > 32); + # https://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor + # Volume Identifier can only be 32 bytes + message = let + length = stringLength config.isoImage.volumeID; + howmany = toString length; + toomany = toString (length - 32); + in + "isoImage.volumeID ${config.isoImage.volumeID} is ${howmany} characters. That is ${toomany} characters longer than the limit of 32."; + } + ]; + + boot.loader.grub.version = 2; + + # 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; + + environment.systemPackages = [ grubPkgs.grub2 grubPkgs.grub2_efi ] + ++ optional canx86BiosBoot pkgs.syslinux + ; + + # In stage 1 of the boot, mount the CD as the root FS by label so + # that we don't need to know its device. We pass the label of the + # root filesystem on the kernel command line, rather than in + # `fileSystems' below. This allows CD-to-USB converters such as + # UNetbootin to rewrite the kernel command line to pass the label or + # UUID of the USB stick. It would be nicer to write + # `root=/dev/disk/by-label/...' here, but UNetbootin doesn't + # recognise that. + boot.kernelParams = + [ "root=LABEL=${config.isoImage.volumeID}" + "boot.shell_on_fail" + ]; + + fileSystems = config.lib.isoFileSystems; + + boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "uas" "overlay" ]; + + boot.initrd.kernelModules = [ "loop" "overlay" ]; + + # 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.toplevel ] ++ + optional config.isoImage.includeSystemBuildDependencies + config.system.build.toplevel.drvPath; + + # Create the squashfs image that contains the Nix store. + system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix { + storeContents = config.isoImage.storeContents; + comp = config.isoImage.squashfsCompression; + }; + + # Individual files to be included on the CD, outside of the Nix + # store on the CD. + isoImage.contents = + [ + { source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile; + target = "/boot/" + config.system.boot.loader.kernelFile; + } + { source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile; + target = "/boot/" + config.system.boot.loader.initrdFile; + } + { source = config.system.build.squashfsStore; + target = "/nix-store.squashfs"; + } + { source = pkgs.writeText "version" config.system.nixos.label; + target = "/version.txt"; + } + ] ++ optionals canx86BiosBoot [ + { source = config.isoImage.splashImage; + target = "/isolinux/background.png"; + } + { source = pkgs.substituteAll { + name = "isolinux.cfg"; + src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg; + bootRoot = "/boot"; + }; + target = "/isolinux/isolinux.cfg"; + } + { source = "${pkgs.syslinux}/share/syslinux"; + target = "/isolinux"; + } + ] ++ optionals config.isoImage.makeEfiBootable [ + { source = efiImg; + target = "/boot/efi.img"; + } + { source = "${efiDir}/EFI"; + target = "/EFI"; + } + { source = (pkgs.writeTextDir "grub/loopback.cfg" "source /EFI/boot/grub.cfg") + "/grub"; + target = "/boot/grub"; + } + { source = config.isoImage.efiSplashImage; + target = "/EFI/boot/efi-background.png"; + } + ] ++ optionals (config.boot.loader.grub.memtest86.enable && canx86BiosBoot) [ + { source = "${pkgs.memtest86plus}/memtest.bin"; + target = "/boot/memtest.bin"; + } + ] ++ optionals (config.isoImage.grubTheme != null) [ + { source = config.isoImage.grubTheme; + target = "/EFI/boot/grub-theme"; + } + ]; + + boot.loader.timeout = 10; + + # Create the ISO image. + system.build.isoImage = pkgs.callPackage ../../../lib/make-iso9660-image.nix ({ + inherit (config.isoImage) isoName compressImage volumeID contents; + bootable = canx86BiosBoot; + bootImage = "/isolinux/isolinux.bin"; + syslinux = if canx86BiosBoot then pkgs.syslinux else null; + } // optionalAttrs (config.isoImage.makeUsbBootable && canx86BiosBoot) { + usbBootable = true; + isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin"; + } // optionalAttrs config.isoImage.makeEfiBootable { + efiBootable = true; + efiBootImage = "boot/efi.img"; + }); + + boot.postBootCommands = + '' + # After booting, register the contents of the Nix store on the + # CD in the Nix database in the tmpfs. + ${config.nix.package.out}/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.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system + ''; + + # Add vfat support to the initrd to enable people to copy the + # contents of the CD to a bootable USB stick. + boot.initrd.supportedFilesystems = [ "vfat" ]; + + }; + +} diff --git a/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix b/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix new file mode 100644 index 00000000000..a669d61571f --- /dev/null +++ b/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix @@ -0,0 +1,14 @@ +{ config, ... }: +{ + imports = [ + ../sd-card/sd-image-aarch64-new-kernel-installer.nix + ]; + config = { + warnings = [ + '' + .../cd-dvd/sd-image-aarch64-new-kernel.nix is deprecated and will eventually be removed. + Please switch to .../sd-card/sd-image-aarch64-new-kernel-installer.nix, instead. + '' + ]; + }; +} diff --git a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix new file mode 100644 index 00000000000..76c1509b8f7 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix @@ -0,0 +1,14 @@ +{ config, ... }: +{ + imports = [ + ../sd-card/sd-image-aarch64-installer.nix + ]; + config = { + warnings = [ + '' + .../cd-dvd/sd-image-aarch64.nix is deprecated and will eventually be removed. + Please switch to .../sd-card/sd-image-aarch64-installer.nix, instead. + '' + ]; + }; +} diff --git a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix new file mode 100644 index 00000000000..6ee0eb9e9b8 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix @@ -0,0 +1,14 @@ +{ config, ... }: +{ + imports = [ + ../sd-card/sd-image-armv7l-multiplatform-installer.nix + ]; + config = { + warnings = [ + '' + .../cd-dvd/sd-image-armv7l-multiplatform.nix is deprecated and will eventually be removed. + Please switch to .../sd-card/sd-image-armv7l-multiplatform-installer.nix, instead. + '' + ]; + }; +} diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix new file mode 100644 index 00000000000..747440ba9c6 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix @@ -0,0 +1,14 @@ +{ config, ... }: +{ + imports = [ + ../sd-card/sd-image-raspberrypi-installer.nix + ]; + config = { + warnings = [ + '' + .../cd-dvd/sd-image-raspberrypi.nix is deprecated and will eventually be removed. + Please switch to .../sd-card/sd-image-raspberrypi-installer.nix, instead. + '' + ]; + }; +} diff --git a/nixos/modules/installer/cd-dvd/sd-image.nix b/nixos/modules/installer/cd-dvd/sd-image.nix new file mode 100644 index 00000000000..e2d6dcb3fe3 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/sd-image.nix @@ -0,0 +1,14 @@ +{ config, ... }: +{ + imports = [ + ../sd-card/sd-image.nix + ]; + config = { + warnings = [ + '' + .../cd-dvd/sd-image.nix is deprecated and will eventually be removed. + Please switch to .../sd-card/sd-image.nix, instead. + '' + ]; + }; +} diff --git a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix new file mode 100644 index 00000000000..054c8c74a76 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix @@ -0,0 +1,160 @@ +{ config, lib, pkgs, ... }: + +with 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, ... }: + + { # Add your own options below, e.g.: + # services.openssh.enable = true; + nixpkgs.config.platform = pkgs.platforms.fuloong2f_n32; + } + ''; + + + pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l; + + # A clue for the kernel loading + kernelParams = pkgs.writeText "kernel-params.txt" '' + Kernel Parameters: + init=/boot/init ${toString config.boot.kernelParams} + ''; + + # System wide nixpkgs config + nixpkgsUserConfig = pkgs.writeText "config.nix" '' + pkgs: + { + platform = pkgs.platforms.fuloong2f_n32; + } + ''; + +in + +{ + imports = [ ./system-tarball.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.w3m # needed for the manual anyway + pkgs.testdisk # useful for repairing boot problems + pkgs.ms-sys # for writing Microsoft boot sectors / MBRs + pkgs.parted + pkgs.ddrescue + pkgs.ccrypt + pkgs.cryptsetup # needed for dm-crypt volumes + + # Some networking tools. + pkgs.sshfs-fuse + 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.btrfs-progs + pkgs.jfsutils + + # Some compression/archiver tools. + 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 = + [ "vfat" "reiserfs" ]; + + boot.kernelPackages = pkgs.linuxKernel.packages.linux_3_10; + boot.kernelParams = [ "console=tty1" ]; + + boot.postBootCommands = + '' + mkdir -p /mnt + + cp ${dummyConfiguration} /etc/nixos/configuration.nix + ''; + + # Some more help text. + services.getty.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.enableRalinkFirmware = 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 ] + ++ [ + { + object = config.system.build.bootStage2; + symlink = "/boot/init"; + } + { + object = config.system.build.toplevel; + symlink = "/boot/system"; + } + ]; + + tarball.contents = [ + { source = kernelParams; + target = "/kernelparams.txt"; + } + { source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile; + target = "/boot/" + config.system.boot.loader.kernelFile; + } + { source = nixpkgsUserConfig; + target = "/root/.nixpkgs/config.nix"; + } + ]; + + # 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.openssh.enable = true; + systemd.services.openssh.wantedBy = lib.mkOverride 50 []; + + boot.loader.grub.enable = false; + boot.loader.generationsDir.enable = false; + system.boot.loader.kernelFile = "vmlinux"; + + nixpkgs.config = { + platform = pkgs.platforms.fuloong2f_n32; + }; +} diff --git a/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt b/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt new file mode 100644 index 00000000000..887bf60d0fb --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt @@ -0,0 +1,89 @@ +Let all the files in the system tarball sit in a directory served by NFS (the +NFS root) like this in exportfs: + /home/pcroot 192.168.1.0/24(rw,no_root_squash,no_all_squash) + +Run "exportfs -a" after editing /etc/exportfs, for the nfs server to be aware +of the changes. + +Use a tftp server serving the root of boot/ (from the system tarball). + +In order to have PXE boot, use the boot/dhcpd.conf-example file for your dhcpd +server, as it will point your PXE clients to pxelinux.0 from the tftp server. +Adapt the configuration to your network. + +Adapt the pxelinux configuration (boot/pxelinux.cfg/default) to set the path to +your nfrroot. If you use ip=dhcp in the kernel, the nfs server ip will be taken +from dhcp and so you don't have to specify it. + +The linux in bzImage includes network drivers for some usual cards. + + +QEMU Testing +--------------- + +You can test qemu pxe boot without having a DHCP server adapted, but having +nfsroot, like this: + qemu-system-x86_64 -tftp /home/pcroot/boot -net nic -net user,bootfile=pxelinux.0 -boot n + +I don't know how to use NFS through the qemu '-net user' though. + + +QEMU Testing with NFS root and bridged network +------------------------------------------------- + +This allows testing with qemu as any other host in your LAN. + +Testing with the real dhcpd server requires setting up a bridge and having a +tap device. + tunctl -t tap0 + brctl addbr br0 + brctl addif br0 eth0 + brctl addif tap0 eth0 + ifconfig eth0 0.0.0.0 up + ifconfig tap0 0.0.0.0 up + ifconfig br0 up # With your ip configuration + +Then you can run qemu: + qemu-system-x86_64 -boot n -net tap,ifname=tap0,script=no -net nic,model=e1000 + + +Using the system-tarball-pc in a chroot +-------------------------------------------------- + +Installation: + mkdir nixos-chroot && cd nixos-chroot + tar xf your-system-tarball.tar.xz + mkdir sys dev proc tmp root var run + mount --bind /sys sys + mount --bind /dev dev + mount --bind /proc proc + +Activate the system: look for a directory in nix/store similar to: + "/nix/store/y0d1lcj9fppli0hl3x0m0ba5g1ndjv2j-nixos-feb97bx-53f008" +Having found it, activate that nixos system *twice*: + chroot . /nix/store/SOMETHING-nixos-SOMETHING/activate + chroot . /nix/store/SOMETHING-nixos-SOMETHING/activate + +This runs a 'hostname' command. Restore your old hostname with: + hostname OLDHOSTNAME + +Copy your system resolv.conf to the /etc/resolv.conf inside the chroot: + cp /etc/resolv.conf etc + +Then you can get an interactive shell in the nixos chroot. '*' means +to run inside the chroot interactive shell + chroot . /bin/sh +* source /etc/profile + +Populate the nix database: that should be done in the init script if you +had booted this nixos. Run: +* `grep local-cmds run/current-system/init` + +Then you can proceed normally subscribing to a nixos channel: + nix-channel --add https://nixos.org/channels/nixos-unstable + nix-channel --update + +Testing: + nix-env -i hello + which hello + hello diff --git a/nixos/modules/installer/cd-dvd/system-tarball-pc.nix b/nixos/modules/installer/cd-dvd/system-tarball-pc.nix new file mode 100644 index 00000000000..674fb6c8a33 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball-pc.nix @@ -0,0 +1,163 @@ +# This module contains the basic configuration for building a NixOS +# tarball, that can directly boot, maybe using PXE or unpacking on a fs. + +{ config, lib, pkgs, ... }: + +with lib; + +let + + pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l; + + # For PXE kernel loading + pxeconfig = pkgs.writeText "pxeconfig-default" '' + default menu.c32 + prompt 0 + + label bootlocal + menu default + localboot 0 + timeout 80 + TOTALTIMEOUT 9000 + + label nixos + MENU LABEL ^NixOS using nfsroot + KERNEL bzImage + append ip=dhcp nfsroot=/home/pcroot init=${config.system.build.toplevel}/init rw + + # I don't know how to make this boot with nfsroot (using the initrd) + label nixos_initrd + MENU LABEL NixOS booting the poor ^initrd. + KERNEL bzImage + append initrd=initrd ip=dhcp nfsroot=/home/pcroot init=${config.system.build.toplevel}/init rw + + label memtest + MENU LABEL ^${pkgs.memtest86.name} + KERNEL memtest + ''; + + dhcpdExampleConfig = pkgs.writeText "dhcpd.conf-example" '' + # Example configuration for booting PXE. + allow booting; + allow bootp; + + # Adapt this to your network configuration. + option domain-name "local"; + option subnet-mask 255.255.255.0; + option broadcast-address 192.168.1.255; + option domain-name-servers 192.168.1.1; + option routers 192.168.1.1; + + # PXE-specific configuration directives... + # Some BIOS don't accept slashes for paths inside the tftp servers, + # and will report Access Violation if they see slashes. + filename "pxelinux.0"; + # For the TFTP and NFS root server. Set the IP of your server. + next-server 192.168.1.34; + + subnet 192.168.1.0 netmask 255.255.255.0 { + range 192.168.1.50 192.168.1.55; + } + ''; + + readme = ./system-tarball-pc-readme.txt; + +in + +{ + imports = + [ ./system-tarball.nix + + # Profiles of this basic installation. + ../../profiles/all-hardware.nix + ../../profiles/base.nix + ../../profiles/installation-device.nix + ]; + + # To speed up further installation of packages, include the complete stdenv + # in the Nix store of the tarball. + tarball.storeContents = pkgs2storeContents [ pkgs.stdenv ]; + + tarball.contents = + [ { source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile; + target = "/boot/" + config.system.boot.loader.kernelFile; + } + { source = "${pkgs.syslinux}/share/syslinux/pxelinux.0"; + target = "/boot/pxelinux.0"; + } + { source = "${pkgs.syslinux}/share/syslinux/menu.c32"; + target = "/boot/menu.c32"; + } + { source = pxeconfig; + target = "/boot/pxelinux.cfg/default"; + } + { source = readme; + target = "/readme.txt"; + } + { source = dhcpdExampleConfig; + target = "/boot/dhcpd.conf-example"; + } + { source = "${pkgs.memtest86}/memtest.bin"; + # We can't leave '.bin', because pxelinux interprets this specially, + # and it would not load the image fine. + # http://forum.canardpc.com/threads/46464-0104-when-launched-via-pxe + target = "/boot/memtest"; + } + ]; + + # 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.openssh.enable = true; + systemd.services.openssh.wantedBy = lib.mkOverride 50 []; + + # To be able to use the systemTarball to catch troubles. + boot.crashDump = { + enable = true; + kernelPackages = pkgs.linuxKernel.packages.linux_3_4; + }; + + # No grub for the tarball. + boot.loader.grub.enable = false; + + /* fake entry, just to have a happy stage-1. Users + may boot without having stage-1 though */ + fileSystems.fake = + { mountPoint = "/"; + device = "/dev/something"; + }; + + nixpkgs.config = { + packageOverrides = p: { + linux_3_4 = p.linux_3_4.override { + extraConfig = '' + # Enable drivers in kernel for most NICs. + E1000 y + # E1000E y + # ATH5K y + 8139TOO y + NE2K_PCI y + ATL1 y + ATL1E y + ATL1C y + VORTEX y + VIA_RHINE y + R8169 y + + # Enable nfs root boot + UNIX y # http://www.linux-mips.org/archives/linux-mips/2006-11/msg00113.html + IP_PNP y + IP_PNP_DHCP y + FSCACHE y + NFS_FS y + NFS_FSCACHE y + ROOT_NFS y + + # Enable devtmpfs + DEVTMPFS y + DEVTMPFS_MOUNT y + ''; + }; + }; + }; +} diff --git a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix new file mode 100644 index 00000000000..458e313a3f7 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix @@ -0,0 +1,172 @@ +# This module contains the basic configuration for building a NixOS +# tarball for the sheevaplug. + +{ config, lib, pkgs, ... }: + +with 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, ... }: + + { + # Add your own options below and run "nixos-rebuild switch". + # E.g., + # services.openssh.enable = true; + } + ''; + + + pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l; + + # A clue for the kernel loading + kernelParams = pkgs.writeText "kernel-params.txt" '' + Kernel Parameters: + init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} + ''; + + +in + +{ + imports = [ ./system-tarball.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.w3m # needed for the manual anyway + pkgs.ddrescue + pkgs.ccrypt + pkgs.cryptsetup # needed for dm-crypt volumes + + # Some networking tools. + pkgs.sshfs-fuse + 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.btrfs-progs + + # Some compression/archiver tools. + pkgs.unzip + pkgs.zip + pkgs.xz + pkgs.dar # disk archiver + + # Some editors. + pkgs.nvi + pkgs.bvi # binary editor + pkgs.joe + ]; + + boot.loader.grub.enable = false; + boot.loader.generationsDir.enable = false; + system.boot.loader.kernelFile = "uImage"; + + boot.initrd.availableKernelModules = + [ "mvsdio" "reiserfs" "ext3" "ums-cypress" "rtc_mv" "ext4" ]; + + boot.postBootCommands = + '' + mkdir -p /mnt + + cp ${dummyConfiguration} /etc/nixos/configuration.nix + ''; + + boot.initrd.extraUtilsCommands = + '' + copy_bin_and_libs ${pkgs.util-linux}/sbin/hwclock + ''; + + boot.initrd.postDeviceCommands = + '' + hwclock -s + ''; + + boot.kernelParams = + [ + "selinux=0" + "console=tty1" + # "console=ttyS0,115200n8" # serial console + ]; + + boot.kernelPackages = pkgs.linuxKernel.packages.linux_3_4; + + boot.supportedFilesystems = [ "reiserfs" ]; + + /* fake entry, just to have a happy stage-1. Users + may boot without having stage-1 though */ + fileSystems.fake = + { mountPoint = "/"; + device = "/dev/something"; + }; + + services.getty = { + # Some more help text. + 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 "" + } + ''; + }; + + # Setting vesa, we don't get the nvidia driver, which can't work in arm. + services.xserver.videoDrivers = [ "vesa" ]; + + documentation.nixos.enable = false; + + # Include the firmware for various wireless cards. + networking.enableRalinkFirmware = 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 ]; + tarball.contents = [ + { source = kernelParams; + target = "/kernelparams.txt"; + } + { source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile; + target = "/boot/" + config.system.boot.loader.kernelFile; + } + { source = pkgs.ubootSheevaplug; + target = "/boot/uboot"; + } + ]; + + # 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.openssh.enable = true; + systemd.services.openssh.wantedBy = lib.mkOverride 50 []; + + # cpufrequtils fails to build on non-pc + powerManagement.enable = false; + + nixpkgs.config = { + platform = pkgs.platforms.sheevaplug; + }; +} diff --git a/nixos/modules/installer/cd-dvd/system-tarball.nix b/nixos/modules/installer/cd-dvd/system-tarball.nix new file mode 100644 index 00000000000..362c555cc53 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball.nix @@ -0,0 +1,93 @@ +# 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, lib, pkgs, ... }: + +with lib; + +let + + versionFile = pkgs.writeText "nixos-label" config.system.nixos.label; + +in + +{ + options = { + tarball.contents = mkOption { + example = literalExpression '' + [ { 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 = literalExpression "[ pkgs.stdenv ]"; + description = '' + This option lists additional derivations to be included in the + Nix store in the generated ISO image. + ''; + }; + + }; + + config = { + + # 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 = { }; + + # boot.initrd.availableKernelModules = [ "mvsdio" "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.toplevel; + symlink = "/run/current-system"; + } + ]; + + # Individual files to be included on the CD, outside of the Nix + # store on the CD. + tarball.contents = + [ { source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile; + target = "/boot/" + config.system.boot.loader.initrdFile; + } + { source = versionFile; + target = "/nixos-version.txt"; + } + ]; + + # Create the tarball + system.build.tarball = import ../../../lib/make-system-tarball.nix { + inherit (pkgs) stdenv closureInfo pixz; + + 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. + if [ -f /nix-path-registration ]; then + ${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration && + rm /nix-path-registration + fi + + # nixos-rebuild also requires a "system" profile and an + # /etc/NIXOS tag. + touch /etc/NIXOS + ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system + ''; + + }; + +} |