diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2013-10-10 13:28:20 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2013-10-10 13:28:20 +0200 |
commit | 5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010 (patch) | |
tree | a6c0f605be6de3f372ae69905b331f9f75452da7 /nixos/modules/installer | |
parent | 6070bc016bd2fd945b04347e25cfd3738622d2ac (diff) | |
download | nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.gz nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.bz2 nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.lz nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.xz nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.zst nixpkgs-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.zip |
Move all of NixOS to nixos/ in preparation of the repository merge
Diffstat (limited to 'nixos/modules/installer')
28 files changed, 2655 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..8126ce46dd9 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/channel.nix @@ -0,0 +1,43 @@ +# Provide an initial copy of the NixOS channel so that the user +# doesn't need to run "nix-channel --update" first. + +{ config, pkgs, ... }: + +with pkgs.lib; + +let + + # 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. + channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}" + { expr = builtins.readFile ../../../lib/channel-expr.nix; } + '' + mkdir -p $out/nixos + cp -prd ${cleanSource ../../..} $out/nixos/nixos + cp -prd ${cleanSource <nixpkgs>} $out/nixos/nixpkgs + chmod -R u+w $out/nixos/nixos + echo -n ${config.system.nixosVersion} > $out/nixos/nixos/.version + echo -n "" > $out/nixos/nixos/.version-suffix + echo "$expr" > $out/nixos/default.nix + ''; + +in + +{ + # Provide the NixOS/Nixpkgs sources in /etc/nixos. This is required + # for nixos-install. + boot.postBootCommands = + '' + 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.environment.nix}/bin/nix-env -p /nix/var/nix/profiles/per-user/root/channels \ + -i ${channelSources} --quiet --option 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..999871ab074 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-base.nix @@ -0,0 +1,37 @@ +# This module contains the basic configuration for building a NixOS +# installation CD. + +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + imports = + [ ./channel.nix + ./iso-image.nix + + # Profiles of this basic installation CD. + ../../profiles/all-hardware.nix + ../../profiles/base.nix + ../../profiles/installation-device.nix + ]; + + # ISO naming. + isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixosVersion}-${pkgs.stdenv.system}.iso"; + + isoImage.volumeID = substring 0 32 "NIXOS_${config.system.nixosVersion}"; + + # Make the installer more likely to succeed in low memory + # environments. The kernel's overcommit heustistics bite us + # fairly often, preventing processes such as nix-worker or + # download-using-manifests.pl from forking even if there is + # plenty of free memory. + boot.kernel.sysctl."vm.overcommit_memory" = "1"; + + # To speed up installation a little bit, include the complete stdenv + # in the Nix store on the CD. + isoImage.storeContents = [ pkgs.stdenv pkgs.busybox ]; + + # Add Memtest86+ to the CD. + boot.loader.grub.memtest86 = true; +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-efi.nix b/nixos/modules/installer/cd-dvd/installation-cd-efi.nix new file mode 100644 index 00000000000..4aa788feeae --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-efi.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + # Move into base image once using 3.10 or later + + require = [ ./installation-cd-minimal.nix ]; + + boot.kernelPackages = pkgs.linuxPackages_3_10; + + # Get a console as soon as the initrd loads fbcon on EFI boot + boot.initrd.kernelModules = [ "fbcon" ]; + + isoImage.makeEfiBootable = true; +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical.nix new file mode 100644 index 00000000000..debf3e7db90 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical.nix @@ -0,0 +1,30 @@ +# This module defines a NixOS installation CD that contains X11 and +# KDE 4. + +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + imports = [ ./installation-cd-base.nix ../../profiles/graphical.nix ]; + + # Provide wicd for easy wireless configuration. + #networking.wicd.enable = true; + + # KDE complains if power management is disabled (to be precise, if + # there is no power management backend such as upower). + powerManagement.enable = true; + + # Don't start the X server by default. + services.xserver.autorun = mkForce false; + + # Auto-login as root. + services.xserver.displayManager.kdm.extraConfig = + '' + [X-*-Core] + AllowRootLogin=true + AutoLoginEnable=true + AutoLoginUser=root + AutoLoginPass="" + ''; +} 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..38d02ffd162 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./installation-cd-minimal.nix ]; + + boot.kernelPackages = pkgs.linuxPackages_3_10; + boot.vesa = false; +} 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..a7498906a86 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix @@ -0,0 +1,11 @@ +# This module defines a small NixOS installation CD. It does not +# contain any graphical stuff. + +{ config, pkgs, ... }: + +{ + imports = + [ ./installation-cd-base.nix + ../../profiles/minimal.nix + ]; +} diff --git a/nixos/modules/installer/cd-dvd/installation-cd-new-kernel.nix b/nixos/modules/installer/cd-dvd/installation-cd-new-kernel.nix new file mode 100644 index 00000000000..93bcbf00b25 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/installation-cd-new-kernel.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./installation-cd-graphical.nix ]; + + boot.kernelPackages = pkgs.linuxPackages_3_10; + boot.vesa = 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..de9728d677c --- /dev/null +++ b/nixos/modules/installer/cd-dvd/iso-image.nix @@ -0,0 +1,315 @@ +# 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, ... }: + +with pkgs.lib; + +let + + # The Grub image. + grubImage = pkgs.runCommand "grub_eltorito" {} + '' + ${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot + cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out + ''; # */ + + + # The configuration file for Grub. + grubCfg = + '' + set default=${builtins.toString config.boot.loader.grub.default} + set timeout=${builtins.toString config.boot.loader.grub.timeout} + + if loadfont /boot/grub/unicode.pf2; then + set gfxmode=640x480 + insmod gfxterm + insmod vbe + terminal_output gfxterm + + insmod png + if background_image /boot/grub/splash.png; then + set color_normal=white/black + set color_highlight=black/white + else + set menu_color_normal=cyan/blue + set menu_color_highlight=white/blue + fi + + fi + + ${config.boot.loader.grub.extraEntries} + ''; + + + # The efi boot image + efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools ]; } + '' + #Let's hope 10M is enough + dd bs=2048 count=5120 if=/dev/zero of="$out" + ${pkgs.dosfstools}/sbin/mkfs.vfat "$out" + mmd -i "$out" efi + mmd -i "$out" efi/boot + mmd -i "$out" efi/nixos + mmd -i "$out" loader + mmd -i "$out" loader/entries + mcopy -v -i "$out" \ + ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi \ + ::efi/boot/boot${targetArch}.efi + mcopy -v -i "$out" \ + ${config.boot.kernelPackages.kernel}/bzImage ::bzImage + mcopy -v -i "$out" \ + ${config.system.build.initialRamdisk}/initrd ::efi/nixos/initrd + echo "title NixOS LiveCD" > boot-params + echo "linux /bzImage" >> boot-params + echo "initrd /efi/nixos/initrd" >> boot-params + echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> boot-params + mcopy -v -i "$out" boot-params ::loader/entries/nixos-livecd.conf + echo "default nixos-livecd" > boot-params + echo "timeout 5" >> boot-params + mcopy -v -i "$out" boot-params ::loader/loader.conf + ''; + + targetArch = if pkgs.stdenv.isi686 then + "ia32" + else if pkgs.stdenv.isx86_64 then + "x64" + else + throw "Unsupported architecture"; + +in + +{ + options = { + + isoImage.isoName = mkOption { + default = "${config.isoImage.isoName}.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>bzip2</command>. + ''; + }; + + isoImage.volumeID = 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. + ''; + }; + + isoImage.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. + ''; + }; + + isoImage.storeContents = mkOption { + example = [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; + example = true; + 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 on non-existent network connection. + ''; + }; + + isoImage.makeEfiBootable = mkOption { + default = false; + description = '' + Whether the ISO image should be an efi-bootable volume. + ''; + }; + + + }; + + + config = { + + 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; + + # !!! Hack - attributes expected by other modules. + system.boot.loader.kernelFile = "bzImage"; + environment.systemPackages = [ pkgs.grub2 ]; + + # 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}" ]; + + # 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. + fileSystems."/".device = "/dev/root"; + + fileSystems."/nix/store" = + { fsType = "squashfs"; + device = "/nix-store.squashfs"; + options = "loop"; + }; + + boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ]; + + boot.initrd.kernelModules = [ "loop" ]; + + # In stage 1, mount a tmpfs on top of / (the ISO image) and + # /nix/store (the squashfs image) to make this a live CD. + boot.initrd.postMountCommands = + '' + mkdir -p /unionfs-chroot/ro-root + mount --rbind $targetRoot /unionfs-chroot/ro-root + + mkdir /unionfs-chroot/rw-root + mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-root + mkdir /mnt-root-union + unionfs -o allow_other,cow,chroot=/unionfs-chroot,max_files=32768 /rw-root=RW:/ro-root=RO /mnt-root-union + oldTargetRoot=$targetRoot + targetRoot=/mnt-root-union + + mkdir /unionfs-chroot/rw-store + mount -t tmpfs -o "mode=755" none /unionfs-chroot/rw-store + mkdir -p $oldTargetRoot/nix/store + unionfs -o allow_other,cow,nonempty,chroot=/unionfs-chroot,max_files=32768 /rw-store=RW:/ro-root/nix/store=RO /mnt-root-union/nix/store + ''; + + # 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 = import ../../../lib/make-squashfs.nix { + inherit (pkgs) stdenv squashfsTools perl pathsFromGraph; + storeContents = config.isoImage.storeContents; + }; + + # Individual files to be included on the CD, outside of the Nix + # store on the CD. + isoImage.contents = + [ { source = grubImage; + target = "/boot/grub/grub_eltorito"; + } + { source = pkgs.substituteAll { + name = "grub.cfg"; + src = pkgs.writeText "grub.cfg-in" grubCfg; + bootRoot = "/boot"; + }; + target = "/boot/grub/grub.cfg"; + } + { source = config.boot.kernelPackages.kernel + "/bzImage"; + target = "/boot/bzImage"; + } + { 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 = config.system.build.squashfsStore; + target = "/nix-store.squashfs"; + } + { # Quick hack: need a mount point for the store. + source = pkgs.runCommand "empty" {} "mkdir -p $out"; + target = "/nix/store"; + } + ] ++ optionals config.isoImage.makeEfiBootable [ + { source = efiImg; + target = "/boot/efi.img"; + } + ] ++ mapAttrsToList (n: v: { source = v; target = "/boot/${n}"; }) config.boot.loader.grub.extraFiles; + + # The Grub menu. + boot.loader.grub.extraEntries = + '' + menuentry "NixOS ${config.system.nixosVersion} Installer" { + linux /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} + initrd /boot/initrd + } + + menuentry "Boot from hard disk" { + set root=(hd0) + chainloader +1 + } + ''; + + boot.loader.grub.timeout = 10; + + # Create the ISO image. + system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({ + inherit (pkgs) stdenv perl cdrkit pathsFromGraph; + + inherit (config.isoImage) isoName compressImage volumeID contents; + + bootable = true; + bootImage = "/boot/grub/grub_eltorito"; + } // 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.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 /run/current-system + ''; + + # Add vfat support to the initrd to enable people to copy the + # contents of the CD to a bootable USB stick. Need unionfs-fuse for union mounts + boot.initrd.supportedFilesystems = [ "vfat" "unionfs-fuse" ]; + + }; + +} diff --git a/nixos/modules/installer/cd-dvd/live-dvd.nix b/nixos/modules/installer/cd-dvd/live-dvd.nix new file mode 100644 index 00000000000..e57be6d442e --- /dev/null +++ b/nixos/modules/installer/cd-dvd/live-dvd.nix @@ -0,0 +1,78 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./installation-cd-base.nix ]; + + # Build the build-time dependencies of this configuration on the DVD + # to speed up installation. + isoImage.storeContents = [ config.system.build.toplevel.drvPath ]; + + # Include lots of packages. + environment.systemPackages = + [ pkgs.utillinuxCurses + pkgs.upstartJobControl + pkgs.iproute + pkgs.bc + pkgs.fuse + pkgs.zsh + pkgs.sqlite + pkgs.gnupg + pkgs.manpages + pkgs.pinentry + pkgs.screen + pkgs.patch + pkgs.which + pkgs.diffutils + pkgs.file + pkgs.irssi + pkgs.mcabber + pkgs.mutt + pkgs.emacs + pkgs.vimHugeX + pkgs.bvi + pkgs.ddrescue + pkgs.cdrkit + pkgs.btrfsProgs + pkgs.xfsprogs + pkgs.jfsutils + pkgs.jfsrec + pkgs.ntfs3g + pkgs.subversion16 + pkgs.monotone + pkgs.git + pkgs.darcs + pkgs.mercurial + pkgs.bazaar + pkgs.cvs + pkgs.pciutils + pkgs.hddtemp + pkgs.sdparm + pkgs.hdparm + pkgs.usbutils + pkgs.openssh + pkgs.lftp + pkgs.w3m + pkgs.openssl + pkgs.ncat + pkgs.lynx + pkgs.wget + pkgs.elinks + pkgs.socat + pkgs.squid + pkgs.unrar + pkgs.zip + pkgs.unzip + pkgs.lzma + pkgs.cabextract + pkgs.cpio + pkgs.lsof + pkgs.ltrace + pkgs.perl + pkgs.python + pkgs.ruby + pkgs.guile + pkgs.clisp + pkgs.tcl + ]; + +} 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..85356118ce6 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix @@ -0,0 +1,164 @@ +{ 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, ... }: + + { # 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 systemConfig=/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.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.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 = + [ "vfat" "reiserfs" ]; + + boot.kernelPackages = pkgs.linuxPackages_3_10; + boot.kernelParams = [ "console=tty1" ]; + + 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.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; + + jobs.openssh.startOn = pkgs.lib.mkOverrideTemplate 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..8f0a8d355c6 --- /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 http://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..7619f074b74 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball-pc.nix @@ -0,0 +1,164 @@ +# This module contains the basic configuration for building a NixOS +# tarball, that can directly boot, maybe using PXE or unpacking on a fs. + +{ config, pkgs, ... }: + +with pkgs.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 systemConfig=${config.system.build.toplevel} 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 systemConfig=${config.system.build.toplevel} 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; + jobs.openssh.startOn = pkgs.lib.mkOverrideTemplate 50 {} ""; + + # To be able to use the systemTarball to catch troubles. + boot.crashDump = { + enable = true; + kernelPackages = pkgs.linuxPackages_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 = [ + { mountPoint = "/"; + device = "/dev/something"; + } + ]; + + nixpkgs.config = { + packageOverrides = p: rec { + 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..20fe4de2cd8 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix @@ -0,0 +1,176 @@ +# This module contains the basic configuration for building a NixOS +# tarball for the sheevaplug. + +{ 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, ... }: + + { + # 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.subversion # for nixos-checkout + pkgs.w3m # needed for the manual anyway + 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.btrfsProgs + + # 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 + ]; + + boot.loader.grub.enable = false; + boot.loader.generationsDir.enable = false; + system.boot.loader.kernelFile = "uImage"; + + boot.initrd.availableKernelModules = + [ "mvsdio" "mmc_block" "reiserfs" "ext3" "ums-cypress" "rtc_mv" + "ext4" ]; + + boot.postBootCommands = + '' + mkdir -p /mnt + + cp ${dummyConfiguration} /etc/nixos/configuration.nix + ''; + + boot.initrd.extraUtilsCommands = + '' + cp ${pkgs.utillinux}/sbin/hwclock $out/bin + ''; + + boot.initrd.postDeviceCommands = + '' + hwclock -s + ''; + + boot.kernelParams = + [ + "selinux=0" + "console=tty1" + # "console=ttyS0,115200n8" # serial console + ]; + + boot.kernelPackages = pkgs.linuxPackages_3_4; + + boot.supportedFilesystems = [ "reiserfs" ]; + + /* fake entry, just to have a happy stage-1. Users + may boot without having stage-1 though */ + fileSystems = [ + { mountPoint = "/"; + device = "/dev/something"; + } + ]; + + services.mingetty = { + # 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.videoDriver = "vesa"; + services.xserver.videoDrivers = []; + services.nixosManual.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; + jobs.openssh.startOn = pkgs.lib.mkOverrideTemplate 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..6bf8eebdac5 --- /dev/null +++ b/nixos/modules/installer/cd-dvd/system-tarball.nix @@ -0,0 +1,92 @@ +# 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 + + versionFile = pkgs.writeText "nixos-version" config.system.nixosVersion; + +in + +{ + 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. + ''; + }; + + }; + + 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" "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.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 + "/initrd"; + target = "/boot/initrd"; + } + { 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. + if [ -f /nix-path-registration ]; then + ${config.environment.nix}/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.environment.nix}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system + ''; + + }; + +} diff --git a/nixos/modules/installer/scan/detected.nix b/nixos/modules/installer/scan/detected.nix new file mode 100644 index 00000000000..09d04608e68 --- /dev/null +++ b/nixos/modules/installer/scan/detected.nix @@ -0,0 +1,13 @@ +# List all devices which are detected by nixos-hardware-scan. +# Common devices are enabled by default. +{config, pkgs, ...}: + +with pkgs.lib; + +{ + config = mkDefault { + # Wireless card firmware + networking.enableIntel2200BGFirmware = true; + networking.enableIntel3945ABGFirmware = true; + }; +} diff --git a/nixos/modules/installer/scan/not-detected.nix b/nixos/modules/installer/scan/not-detected.nix new file mode 100644 index 00000000000..814858fdffd --- /dev/null +++ b/nixos/modules/installer/scan/not-detected.nix @@ -0,0 +1,9 @@ +# List all devices which are _not_ detected by nixos-hardware-scan. +# Common devices are enabled by default. +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + hardware.enableAllFirmware = true; +} diff --git a/nixos/modules/installer/tools/get-version-suffix b/nixos/modules/installer/tools/get-version-suffix new file mode 100644 index 00000000000..76cec8d5dae --- /dev/null +++ b/nixos/modules/installer/tools/get-version-suffix @@ -0,0 +1,29 @@ +getVersion() { + local dir="$1" + rev= + if [ -e "$dir/.git" ]; then + if [ -z "$(type -P git)" ]; then + echo "warning: Git not found; cannot figure out revision of $dir" >&2 + return + fi + cd "$dir" + rev=$(git rev-parse --short HEAD) + if git describe --always --dirty | grep -q dirty; then + rev+=M + fi + fi +} + +if nixos=$(nix-instantiate --find-file nixos "$@"); then + getVersion $nixos + if [ -n "$rev" ]; then + suffix="pre-$rev" + if nixpkgs=$(nix-instantiate --find-file nixpkgs "$@"); then + getVersion $nixpkgs + if [ -n "$rev" ]; then + suffix+="-$rev" + fi + fi + echo $suffix + fi +fi diff --git a/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix b/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix new file mode 100644 index 00000000000..5e77b701ff5 --- /dev/null +++ b/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix @@ -0,0 +1,9 @@ +{ system ? builtins.currentSystem +, networkExpr +}: + +let nodes = import networkExpr; in + +with import ../../../../lib/testing.nix { inherit system; }; + +(complete { inherit nodes; testScript = ""; }).driver diff --git a/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh b/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh new file mode 100644 index 00000000000..0a6e8b920a1 --- /dev/null +++ b/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh @@ -0,0 +1,62 @@ +#! @shell@ -e + +# Shows the usage of this command to the user + +showUsage() +{ + echo "Usage: $0 network_expr" + echo "Options:" + echo + echo "--no-out-link Do not create a 'result' symlink" + echo "--show-trace Shows the output trace" + echo "-h,--help Shows the usage of this command" +} + +# Parse valid argument options + +PARAMS=`getopt -n $0 -o h -l no-out-link,show-trace,help -- "$@"` + +if [ $? != 0 ] +then + showUsage + exit 1 +fi + +eval set -- "$PARAMS" + +# Evaluate valid options + +while [ "$1" != "--" ] +do + case "$1" in + --no-out-link) + noOutLinkArg="--no-out-link" + ;; + --show-trace) + showTraceArg="--show-trace" + ;; + -h|--help) + showUsage + exit 0 + ;; + esac + + shift +done + +shift + +# Validate the given options + +if [ "$1" = "" ] +then + echo "ERROR: A network expression must be specified!" >&2 + exit 1 +else + networkExpr=$(readlink -f $1) +fi + +# Build a network of VMs + +nix-build '<nixos/modules/installer/tools/nixos-build-vms/build-vms.nix>' \ + --argstr networkExpr $networkExpr $noOutLinkArg $showTraceArg diff --git a/nixos/modules/installer/tools/nixos-checkout.nix b/nixos/modules/installer/tools/nixos-checkout.nix new file mode 100644 index 00000000000..1a734ca5eeb --- /dev/null +++ b/nixos/modules/installer/tools/nixos-checkout.nix @@ -0,0 +1,55 @@ +# This module generates the nixos-checkout script, which replaces the +# NixOS and Nixpkgs source trees in /etc/nixos/{nixos,nixpkgs} with +# Git checkouts. + +{config, pkgs, ...}: + +with pkgs.lib; + +let + + nixosCheckout = pkgs.substituteAll { + name = "nixos-checkout"; + dir = "bin"; + isExecutable = true; + src = pkgs.writeScript "nixos-checkout" + '' + #! ${pkgs.stdenv.shell} -e + + if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + echo "Usage: `basename $0` [PREFIX]. See NixOS Manual for more info." + exit 0 + fi + + prefix="$1" + if [ -z "$prefix" ]; then prefix=/etc/nixos; fi + mkdir -p "$prefix" + cd "$prefix" + + if [ -z "$(type -P git)" ]; then + echo "installing Git..." + nix-env -iA nixos.pkgs.git || nix-env -i git + fi + + # Move any old nixos or nixpkgs directories out of the way. + backupTimestamp=$(date "+%Y%m%d%H%M%S") + + if [ -e nixos -a ! -e nixos/.git ]; then + mv nixos nixos-$backupTimestamp + fi + + if [ -e nixpkgs -a ! -e nixpkgs/.git ]; then + mv nixpkgs nixpkgs-$backupTimestamp + fi + + # Check out the NixOS and Nixpkgs sources. + git clone git://github.com/NixOS/nixos.git nixos + git clone git://github.com/NixOS/nixpkgs.git nixpkgs + ''; + }; + +in + +{ + environment.systemPackages = [ nixosCheckout ]; +} diff --git a/nixos/modules/installer/tools/nixos-gen-seccure-keys.sh b/nixos/modules/installer/tools/nixos-gen-seccure-keys.sh new file mode 100644 index 00000000000..a97eef672f7 --- /dev/null +++ b/nixos/modules/installer/tools/nixos-gen-seccure-keys.sh @@ -0,0 +1,13 @@ +#! @shell@ -e + +mkdir -p /var/elliptic-keys +chmod 0755 /var/elliptic-keys +cd /var/elliptic-keys +touch private +chmod 0700 private +dd if=/dev/urandom bs=128 count=1 of=private +chmod 0500 private +public=$(seccure-key -F private 2>&1) +echo ${public#*The public key is: } > public +chmod 0555 public + diff --git a/nixos/modules/installer/tools/nixos-hardware-scan.pl b/nixos/modules/installer/tools/nixos-hardware-scan.pl new file mode 100644 index 00000000000..3204f3d4051 --- /dev/null +++ b/nixos/modules/installer/tools/nixos-hardware-scan.pl @@ -0,0 +1,248 @@ +#! @perl@/bin/perl -w + +use File::Spec; +use File::Basename; + + +my @attrs = (); +my @kernelModules = (); +my @initrdKernelModules = (); +my @modulePackages = (); +my @imports = ("<nixos/modules/installer/scan/not-detected.nix>"); + + +sub debug { + return unless defined $ENV{"DEBUG"}; + print STDERR @_; +} + + +# Read a file, returning undef if the file cannot be opened. +sub readFile { + my $filename = shift; + my $res; + if (open FILE, "<$filename") { + my $prev = $/; + undef $/; + $res = <FILE>; + $/ = $prev; + close FILE; + chomp $res; + } + return $res; +} + + +my $cpuinfo = readFile "/proc/cpuinfo"; + + +sub hasCPUFeature { + my $feature = shift; + return $cpuinfo =~ /^flags\s*:.* $feature( |$)/m; +} + + +# Detect the number of CPU cores. +my $cpus = scalar (grep {/^processor\s*:/} (split '\n', $cpuinfo)); + + +# Virtualization support? +push @kernelModules, "kvm-intel" if hasCPUFeature "vmx"; +push @kernelModules, "kvm-amd" if hasCPUFeature "svm"; + + +# Look at the PCI devices and add necessary modules. Note that most +# modules are auto-detected so we don't need to list them here. +# However, some are needed in the initrd to boot the system. + +my $videoDriver; + +sub pciCheck { + my $path = shift; + my $vendor = readFile "$path/vendor"; + my $device = readFile "$path/device"; + my $class = readFile "$path/class"; + + my $module; + if (-e "$path/driver/module") { + $module = basename `readlink -f $path/driver/module`; + chomp $module; + } + + debug "$path: $vendor $device $class"; + debug " $module" if defined $module; + debug "\n"; + + if (defined $module) { + # See the bottom of http://pciids.sourceforge.net/pci.ids for + # device classes. + if (# Mass-storage controller. Definitely important. + $class =~ /^0x01/ || + + # Firewire controller. A disk might be attached. + $class =~ /^0x0c00/ || + + # USB controller. Needed if we want to use the + # keyboard when things go wrong in the initrd. + $class =~ /^0x0c03/ + ) + { + push @initrdKernelModules, $module; + } + } + + # broadcom STA driver (wl.ko) + # list taken from http://www.broadcom.com/docs/linux_sta/README.txt + if ($vendor eq "0x14e4" && + ($device eq "0x4311" || $device eq "0x4312" || $device eq "0x4313" || + $device eq "0x4315" || $device eq "0x4327" || $device eq "0x4328" || + $device eq "0x4329" || $device eq "0x432a" || $device eq "0x432b" || + $device eq "0x432c" || $device eq "0x432d" || $device eq "0x4353" || + $device eq "0x4357" || $device eq "0x4358" || $device eq "0x4359" ) ) + { + push @modulePackages, "config.boot.kernelPackages.broadcom_sta"; + push @kernelModules, "wl"; + } + + # Can't rely on $module here, since the module may not be loaded + # due to missing firmware. Ideally we would check modules.pcimap + # here. + push @attrs, "networking.enableIntel2200BGFirmware = true;" if + $vendor eq "0x8086" && + ($device eq "0x1043" || $device eq "0x104f" || $device eq "0x4220" || + $device eq "0x4221" || $device eq "0x4223" || $device eq "0x4224"); + + push @attrs, "networking.enableIntel3945ABGFirmware = true;" if + $vendor eq "0x8086" && + ($device eq "0x4229" || $device eq "0x4230" || + $device eq "0x4222" || $device eq "0x4227"); + + # Assume that all NVIDIA cards are supported by the NVIDIA driver. + # There may be exceptions (e.g. old cards). + $videoDriver = "nvidia" if $vendor eq "0x10de" && $class =~ /^0x03/; +} + +foreach my $path (glob "/sys/bus/pci/devices/*") { + pciCheck $path; +} + + +# Idem for USB devices. + +sub usbCheck { + my $path = shift; + my $class = readFile "$path/bInterfaceClass"; + my $subclass = readFile "$path/bInterfaceSubClass"; + my $protocol = readFile "$path/bInterfaceProtocol"; + + my $module; + if (-e "$path/driver/module") { + $module = basename `readlink -f $path/driver/module`; + chomp $module; + } + + debug "$path: $class $subclass $protocol"; + debug " $module" if defined $module; + debug "\n"; + + if (defined $module) { + if (# Mass-storage controller. Definitely important. + $class eq "08" || + + # Keyboard. Needed if we want to use the + # keyboard when things go wrong in the initrd. + ($class eq "03" && $protocol eq "01") + ) + { + push @initrdKernelModules, $module; + } + } +} + +foreach my $path (glob "/sys/bus/usb/devices/*") { + if (-e "$path/bInterfaceClass") { + usbCheck $path; + } +} + + +# Add the modules for all block devices. + +foreach my $path (glob "/sys/class/block/*") { + my $module; + if (-e "$path/device/driver/module") { + $module = basename `readlink -f $path/device/driver/module`; + chomp $module; + push @initrdKernelModules, $module; + } +} + + +if ($videoDriver) { + push @attrs, "services.xserver.videoDrivers = [ \"$videoDriver\" ];"; +} + + +# Check if we're a VirtualBox guest. If so, enable the guest +# additions. +my $dmi = `@dmidecode@/sbin/dmidecode`; +if ($dmi =~ /Manufacturer: innotek/) { + push @attrs, "services.virtualbox.enable = true;" +} + + +# Generate the configuration file. + +sub removeDups { + my %seen; + my @res = (); + foreach my $s (@_) { + if (!defined $seen{$s}) { + $seen{$s} = ""; + push @res, $s; + } + } + return @res; +} + +sub toNixExpr { + my $res = ""; + foreach my $s (@_) { + $res .= " \"$s\""; + } + return $res; +} + +sub multiLineList { + my $indent = shift; + my $res = ""; + $res = "\n" if scalar @_ > 0; + foreach my $s (@_) { + $res .= "$indent$s\n"; + } + return $res; +} + +my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules); +my $kernelModules = toNixExpr(removeDups @kernelModules); +my $modulePackages = toNixExpr(removeDups @modulePackages); +my $attrs = multiLineList(" ", removeDups @attrs); +my $imports = multiLineList(" ", removeDups @imports); + + +print <<EOF ; +# This is a generated file. Do not modify! +# Make changes to /etc/nixos/configuration.nix instead. +{ config, pkgs, ... }: + +{ + imports = [$imports ]; + + boot.initrd.kernelModules = [$initrdKernelModules ]; + boot.kernelModules = [$kernelModules ]; + boot.extraModulePackages = [$modulePackages ]; + + nix.maxJobs = $cpus; +$attrs} +EOF +# workaround for a bug in substituteAll diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh new file mode 100644 index 00000000000..a4ac5b68dd7 --- /dev/null +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -0,0 +1,238 @@ +#! @shell@ + +# - [mount target device] <- currently disabled +# - make Nix store etc. +# - copy closure of Nix to target device +# - register validity +# - with a chroot to the target device: +# * nix-env -p /nix/var/nix/profiles/system -i <nix-expr for the configuration> +# * run the activation script of the configuration (also installs Grub) + +# Parse the command line for the -I flag +extraBuildFlags=() + +while [ "$#" -gt 0 ]; do + i="$1"; shift 1 + case "$i" in + -I) + given_path="$1"; shift 1 + absolute_path=$(readlink -m $given_path) + extraBuildFlags+=("$i" "/mnt$absolute_path") + ;; + *) + echo "$0: unknown option \`$i'" + exit 1 + ;; + esac +done + +set -e +shopt -s nullglob + +if test -z "$mountPoint"; then + mountPoint=/mnt +fi + +if test -z "$NIXOS_CONFIG"; then + NIXOS_CONFIG=/etc/nixos/configuration.nix +fi + +if ! test -e "$mountPoint"; then + echo "mount point $mountPoint doesn't exist" + exit 1 +fi + +if ! grep -F -q " $mountPoint " /proc/mounts; then + echo "$mountPoint doesn't appear to be a mount point" + exit 1 +fi + +if ! test -e "$mountPoint/$NIXOS_CONFIG"; then + echo "configuration file $mountPoint/$NIXOS_CONFIG doesn't exist" + exit 1 +fi + + + +# Mount some stuff in the target root directory. We bind-mount /etc +# into the chroot because we need networking and the nixbld user +# accounts in /etc/passwd. But we do need the target's /etc/nixos. +mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/mnt $mountPoint/mnt2 $mountPoint/mnt-nixos $mountPoint/mnt-nixpkgs $mountPoint/etc /etc/nixos +mount --make-private / # systemd makes / shared, which is annoying +mount --bind / $mountPoint/mnt +mount --bind /nix $mountPoint/mnt/nix +mount --bind /nix/store $mountPoint/mnt/nix/store +mount --bind /dev $mountPoint/dev +mount --bind /dev/shm $mountPoint/dev/shm +mount --bind /proc $mountPoint/proc +mount --bind /sys $mountPoint/sys +mount --bind /sys/firmware/efi/efivars $mountPoint/sys/firmware/efi/efivars &>/dev/null || true +mount --bind $mountPoint/etc/nixos $mountPoint/mnt2 +mount --bind /etc $mountPoint/etc +mount --bind $mountPoint/mnt2 $mountPoint/etc/nixos + +cleanup() { + set +e + mountpoint -q $mountPoint/etc/nixos && umount $mountPoint/etc/nixos + mountpoint -q $mountPoint/etc && umount $mountPoint/etc + umount $mountPoint/mnt2 + umount $mountPoint/mnt-nixos + umount $mountPoint/mnt-nixpkgs + umount $mountPoint/sys/firmware/efi/efivars &>/dev/null || true + umount $mountPoint/sys + umount $mountPoint/proc + umount $mountPoint/dev/shm + umount $mountPoint/dev + umount $mountPoint/mnt/nix/store + umount $mountPoint/mnt/nix + umount $mountPoint/mnt + rmdir $mountPoint/mnt $mountPoint/mnt2 $mountPoint/mnt-nixos $mountPoint/mnt-nixpkgs +} + +trap "cleanup" EXIT + +mkdir -m 01777 -p $mountPoint/tmp +mkdir -m 0755 -p $mountPoint/var + + +# Create the necessary Nix directories on the target device, if they +# don't already exist. +mkdir -m 0755 -p \ + $mountPoint/nix/var/nix/gcroots \ + $mountPoint/nix/var/nix/temproots \ + $mountPoint/nix/var/nix/manifests \ + $mountPoint/nix/var/nix/userpool \ + $mountPoint/nix/var/nix/profiles \ + $mountPoint/nix/var/nix/db \ + $mountPoint/nix/var/log/nix/drvs + +mkdir -m 1775 -p $mountPoint/nix/store +build_users_group=$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"build-users-group"};') +if test -n "$build_users_group"; then + chown root:"$build_users_group" $mountPoint/nix/store +else + chown root $mountPoint/nix/store +fi + + +# Get the store paths to copy from the references graph. +storePaths=$(@perl@/bin/perl @pathsFromGraph@ @nixClosure@) + + +# Copy Nix to the Nix store on the target device. +echo "copying Nix to $mountPoint...." +for i in $storePaths; do + echo " $i" + chattr -R -i $mountPoint/$i 2> /dev/null || true # clear immutable bit + rsync -a $i $mountPoint/nix/store/ +done + + +# We don't have locale-archive in the chroot, so clear $LANG. +export LANG= +export LC_ALL= +export LC_TIME= + + +# There is no daemon in the chroot +unset NIX_REMOTE + + +# Create a temporary Nix config file that causes the nixbld users to +# be used. +if test -n "$build_users_group"; then + echo "build-users-group = $build_users_group" > $mountPoint/tmp/nix.conf +fi +binary_caches=$(@perl@/bin/perl -I @nix@/lib/perl5/site_perl/*/* -e 'use Nix::Config; Nix::Config::readConfig; print $Nix::Config::config{"binary-caches"};') +if test -n "$binary_caches"; then + echo "binary-caches = $binary_caches" >> $mountPoint/tmp/nix.conf +fi +export NIX_CONF_DIR=/tmp + + +# Register the paths in the Nix closure as valid. This is necessary +# to prevent them from being deleted the first time we install +# something. (I.e., Nix will see that, e.g., the glibc path is not +# valid, delete it to get it out of the way, but as a result nothing +# will work anymore.) +chroot $mountPoint @nix@/bin/nix-store --register-validity < @nixClosure@ + + +# Create the required /bin/sh symlink; otherwise lots of things +# (notably the system() function) won't work. +mkdir -m 0755 -p $mountPoint/bin +# !!! assuming that @shell@ is in the closure +ln -sf @shell@ $mountPoint/bin/sh + + +if test -n "$NIXOS_PREPARE_CHROOT_ONLY"; then + echo "User requested only to prepare chroot. Exiting." + exit 0 +fi + + +# Make the build below copy paths from the CD if possible. Note that +# /mnt in the chroot is the root of the CD. +export NIX_OTHER_STORES=/mnt/nix:$NIX_OTHER_STORES + +p=@nix@/libexec/nix/substituters +export NIX_SUBSTITUTERS=$p/copy-from-other-stores.pl:$p/download-from-binary-cache.pl + + +# Make manifests available in the chroot. +rm -f $mountPoint/nix/var/nix/manifests/* +for i in /nix/var/nix/manifests/*.nixmanifest; do + chroot $mountPoint @nix@/bin/nix-store -r "$(readlink -f "$i")" > /dev/null + cp -pd "$i" $mountPoint/nix/var/nix/manifests/ +done + + +# Get the absolute path to the NixOS/Nixpkgs sources. +mount --bind $(readlink -f $(nix-instantiate --find-file nixpkgs)) $mountPoint/mnt-nixpkgs +mount --bind $(readlink -f $(nix-instantiate --find-file nixos)) $mountPoint/mnt-nixos + + +# Build the specified Nix expression in the target store and install +# it into the system configuration profile. +echo "building the system configuration..." +NIX_PATH="nixpkgs=/mnt-nixpkgs:nixos=/mnt-nixos:nixos-config=$NIXOS_CONFIG" NIXOS_CONFIG= \ + chroot $mountPoint @nix@/bin/nix-env \ + "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/system -f '<nixos>' --set -A system --show-trace + + +# Copy the NixOS/Nixpkgs sources to the target as the initial contents +# of the NixOS channel. +mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles +mkdir -m 1777 -p $mountPoint/nix/var/nix/profiles/per-user +mkdir -m 0755 -p $mountPoint/nix/var/nix/profiles/per-user/root +srcs=$(nix-env "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "") +if test -n "$srcs"; then + echo "copying NixOS/Nixpkgs sources..." + chroot $mountPoint @nix@/bin/nix-env \ + "${extraBuildFlags[@]}" -p /nix/var/nix/profiles/per-user/root/channels -i "$srcs" --quiet +fi +mkdir -m 0700 -p $mountPoint/root/.nix-defexpr +ln -sfn /nix/var/nix/profiles/per-user/root/channels $mountPoint/root/.nix-defexpr/channels + + +# We're done building/downloading, so we don't need the /etc bind +# mount anymore. In fact, below we want to modify the target's /etc. +umount $mountPoint/etc/nixos +umount $mountPoint/etc + + +# Grub needs an mtab. +ln -sfn /proc/mounts $mountPoint/etc/mtab + + +# Mark the target as a NixOS installation, otherwise +# switch-to-configuration will chicken out. +touch $mountPoint/etc/NIXOS + + +# Switch to the new system configuration. This will install Grub with +# a menu default pointing at the kernel/initrd/etc of the new +# configuration. +echo "finalising the installation..." +NIXOS_INSTALL_GRUB=1 chroot $mountPoint \ + /nix/var/nix/profiles/system/bin/switch-to-configuration boot diff --git a/nixos/modules/installer/tools/nixos-option.sh b/nixos/modules/installer/tools/nixos-option.sh new file mode 100644 index 00000000000..7f008d62c24 --- /dev/null +++ b/nixos/modules/installer/tools/nixos-option.sh @@ -0,0 +1,395 @@ +#! @shell@ -e + +# Allow the location of NixOS sources and the system configuration +# file to be overridden. + +: ${mountPoint=/mnt} +: ${NIXOS_CONFIG=/etc/nixos/configuration.nix} +export NIXOS_CONFIG + +usage () { + echo 1>&2 " +Usage: $0 [-v] [-d] [-l] [--xml] OPTION_NAME + $0 --install + +This program allows you to inspect the current value of NixOS +configuration options. It can also generate a basic NixOS +configuration file. + +Options: + + -i | --install Write a template NixOS configuration file to + ${mountPoint:+$mountPoint/}$NIXOS_CONFIG. + -v | --value Display the current value, based on your + configuration. + -d | --description Display the default value, the example and the + description. + -l | --lookup Display where the option is defined and where it + is declared. + --xml Print an XML representation of the result. + Implies -vdl options. + --help Show this message. + +Environment variables affecting $0: + + \$mountPoint Path to the target file system. + \$NIXOS_CONFIG Path to your configuration file. + +" + + exit 1; +} + +##################### +# Process Arguments # +##################### + +desc=false +defs=false +value=false +xml=false +install=false +verbose=false + +option="" + +argfun="" +for arg; do + if test -z "$argfun"; then + case $arg in + -*) + longarg="" + sarg="$arg" + while test "$sarg" != "-"; do + case $sarg in + --*) longarg=$arg; sarg="--";; + -d*) longarg="$longarg --description";; + -v*) longarg="$longarg --value";; + -l*) longarg="$longarg --lookup";; + -i*) longarg="$longarg --install";; + -*) usage;; + esac + # remove the first letter option + sarg="-${sarg#??}" + done + ;; + *) longarg=$arg;; + esac + for larg in $longarg; do + case $larg in + --description) desc=true;; + --value) value=true;; + --lookup) defs=true;; + --xml) xml=true;; + --install) install=true;; + --verbose) verbose=true;; + --help) usage;; + -*) usage;; + *) if test -z "$option"; then + option="$larg" + else + usage + fi;; + esac + done + else + case $argfun in + set_*) + var=$(echo $argfun | sed 's,^set_,,') + eval $var=$arg + ;; + esac + argfun="" + fi +done + +if $xml; then + value=true + desc=true + defs=true +fi + +# --install cannot be used with -d -v -l without option name. +if $value || $desc || $defs && $install && test -z "$option"; then + usage +fi + +generate=false +if ! $defs && ! $desc && ! $value && $install && test -z "$option"; then + generate=true +fi + +if ! $defs && ! $desc; then + value=true +fi + +if $verbose; then + set -x +else + set +x +fi + +############################# +# Process the configuration # +############################# + +evalNix(){ + nix-instantiate - --eval-only "$@" +} + +evalAttr(){ + local prefix=$1 + local suffix=$2 + local strict=$3 + echo "(import <nixos> {}).$prefix${option:+.$option}${suffix:+.$suffix}" | + evalNix ${strict:+--strict} +} + +evalOpt(){ + evalAttr "eval.options" "$@" +} + +evalCfg(){ + evalAttr "config" "$@" +} + +findSources(){ + local suffix=$1 + echo "builtins.map (f: f.source) (import <nixos> {}).eval.options${option:+.$option}.$suffix" | + evalNix --strict +} + +# Given a result from nix-instantiate, recover the list of attributes it +# contains. +attrNames() { + local attributeset=$1 + # sed is used to replace un-printable subset by 0s, and to remove most of + # the inner-attribute set, which reduce the likelyhood to encounter badly + # pre-processed input. + echo "builtins.attrNames $attributeset" | \ + sed 's,<[A-Z]*>,0,g; :inner; s/{[^\{\}]*};/0;/g; t inner;' | \ + evalNix --strict +} + +# map a simple list which contains strings or paths. +nixMap() { + local fun="$1" + local list="$2" + local elem + for elem in $list; do + test $elem = '[' -o $elem = ']' && continue; + $fun $elem + done +} + +if $install; then + NIXOS_CONFIG="$mountPoint$NIXOS_CONFIG" +fi + +if $generate; then + mkdir -p $(dirname "$NIXOS_CONFIG") + + # Scan the hardware and add the result to /etc/nixos/hardware-scan.nix. + hardware_config="${NIXOS_CONFIG%/configuration.nix}/hardware-configuration.nix" + if test -e "$hardware_config"; then + echo "A hardware configuration file exists, generation skipped." + else + echo "Generating a hardware configuration file in $hardware_config..." + nixos-hardware-scan > "$hardware_config" + fi + + if test -e "$NIXOS_CONFIG"; then + echo 1>&2 "error: Cannot generate a template configuration because a configuration file exists." + exit 1 + fi + + nl=" +" + if test -e /sys/firmware/efi/efivars; then + l1=" # Use the gummiboot efi boot loader." + l2=" boot.loader.grub.enable = false;" + l3=" boot.loader.gummiboot.enable = true;" + l4=" boot.loader.efi.canTouchEfiVariables = true;" + # !!! Remove me when nixos is on 3.10 or greater by default + l5=" # EFI booting requires kernel >= 3.10" + l6=" boot.kernelPackages = pkgs.linuxPackages_3_10;" + bootloader_config="$l1$nl$l2$nl$l3$nl$l4$nl$nl$l5$nl$l6" + else + l1=" # Use the Grub2 boot loader." + l2=" boot.loader.grub.enable = true;" + l3=" boot.loader.grub.version = 2;" + l4=" # Define on which hard drive you want to install Grub." + l5=' # boot.loader.grub.device = "/dev/sda";' + bootloader_config="$l1$nl$l2$nl$l3$nl$nl$l4$nl$l5" + fi + + echo "Generating a basic configuration file in $NIXOS_CONFIG..." + + # Generate a template configuration file where the user has to + # fill the gaps. + cat <<EOF > "$NIXOS_CONFIG" +# Edit this configuration file to define what should be installed on +# the system. Help is available in the configuration.nix(5) man page +# or the NixOS manual available on virtual console 8 (Alt+F8). + +{ config, pkgs, ... }: + +{ + imports = + [ # Include the results of the hardware scan. + ./hardware-configuration.nix + ]; + + boot.initrd.kernelModules = + [ # Specify all kernel modules that are necessary for mounting the root + # filesystem. + # "xfs" "ata_piix" + # fbcon # Uncomment this when EFI booting to see the console before the root partition is mounted + ]; + +$bootloader_config + + # networking.hostName = "nixos"; # Define your hostname. + # networking.wireless.enable = true; # Enables Wireless. + + # Add filesystem entries for each partition that you want to see + # mounted at boot time. This should include at least the root + # filesystem. + + # fileSystems."/".device = "/dev/disk/by-label/nixos"; + + # fileSystems."/data" = # where you want to mount the device + # { device = "/dev/sdb"; # the device + # fsType = "ext3"; # the type of the partition + # options = "data=journal"; + # }; + + # List swap partitions activated at boot time. + swapDevices = + [ # { device = "/dev/disk/by-label/swap"; } + ]; + + # Select internationalisation properties. + # i18n = { + # consoleFont = "lat9w-16"; + # consoleKeyMap = "us"; + # defaultLocale = "en_US.UTF-8"; + # }; + + # List services that you want to enable: + + # Enable the OpenSSH daemon. + # services.openssh.enable = true; + + # Enable CUPS to print documents. + # services.printing.enable = true; + + # Enable the X11 windowing system. + # services.xserver.enable = true; + # services.xserver.layout = "us"; + # services.xserver.xkbOptions = "eurosign:e"; + + # Enable the KDE Desktop Environment. + # services.xserver.displayManager.kdm.enable = true; + # services.xserver.desktopManager.kde4.enable = true; +} +EOF + + exit 0 +fi; + +# This duplicates the work made below, but it is useful for processing +# the output of nixos-option with other tools such as nixos-gui. +if $xml; then + evalNix --xml --no-location <<EOF +let + reach = attrs: attrs${option:+.$option}; + nixos = import <nixos> {}; + nixpkgs = import <nixpkgs> {}; + sources = builtins.map (f: f.source); + opt = reach nixos.eval.options; + cfg = reach nixos.config; +in + +with nixpkgs.lib; + +let + optStrict = v: + let + traverse = x : + if isAttrs x then + if x ? outPath then true + else all id (mapAttrsFlatten (n: traverseNoAttrs) x) + else traverseNoAttrs x; + traverseNoAttrs = x: + # do not continue in attribute sets + if isAttrs x then true + else if isList x then all id (map traverse x) + else true; + in assert traverse v; v; +in + +if isOption opt then + optStrict ({} + // optionalAttrs (opt ? default) { inherit (opt) default; } + // optionalAttrs (opt ? example) { inherit (opt) example; } + // optionalAttrs (opt ? description) { inherit (opt) description; } + // optionalAttrs (opt ? type) { typename = opt.type.name; } + // optionalAttrs (opt ? options) { inherit (opt) options; } + // { + # to disambiguate the xml output. + _isOption = true; + declarations = sources opt.declarations; + definitions = sources opt.definitions; + value = cfg; + }) +else + opt +EOF + exit $? +fi + +if test "$(evalOpt "_type" 2> /dev/null)" = '"option"'; then + $value && evalCfg; + + if $desc; then + $value && echo; + + if default=$(evalOpt "default" - 2> /dev/null); then + echo "Default: $default" + else + echo "Default: <None>" + fi + if example=$(evalOpt "example" - 2> /dev/null); then + echo "Example: $example" + fi + echo "Description:" + eval printf $(evalOpt "description") + fi + + if $defs; then + $desc || $value && echo; + + printPath () { echo " $1"; } + + echo "Declared by:" + nixMap printPath "$(findSources "declarations")" + echo "" + echo "Defined by:" + nixMap printPath "$(findSources "definitions")" + echo "" + fi + +else + # echo 1>&2 "Warning: This value is not an option." + + result=$(evalCfg) + if names=$(attrNames "$result" 2> /dev/null); then + echo 1>&2 "This attribute set contains:" + escapeQuotes () { eval echo "$1"; } + nixMap escapeQuotes "$names" + else + echo 1>&2 "An error occured while looking for attribute names." + echo $result + fi +fi diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh new file mode 100644 index 00000000000..8734cb273d4 --- /dev/null +++ b/nixos/modules/installer/tools/nixos-rebuild.sh @@ -0,0 +1,222 @@ +#! @shell@ -e + +showSyntax() { + # !!! more or less cut&paste from + # system/switch-to-configuration.sh (which we call, of course). + cat <<EOF +Usage: $0 [OPTIONS...] OPERATION + +The operation is one of the following: + + switch: make the configuration the boot default and activate now + boot: make the configuration the boot default + test: activate the configuration, but don't make it the boot default + build: build the configuration, but don't make it the default or + activate it + build-vm: build a virtual machine containing the configuration + (useful for testing) + build-vm-with-bootloader: + like build-vm, but include a boot loader in the VM + dry-run: just show what store paths would be built/downloaded + +Options: + + --upgrade fetch the latest version of NixOS before rebuilding + --install-grub (re-)install the Grub bootloader + --no-build-nix don't build the latest Nix from Nixpkgs before + building NixOS + --rollback restore the previous NixOS configuration (only + with switch, boot, test, build) + --profile-name / -p install in the specified system profile + --fast same as --no-build-nix --show-trace + +Various nix-build options are also accepted, in particular: + + --show-trace show a detailed stack trace for evaluation errors + +Environment variables affecting nixos-rebuild: + + \$NIX_PATH Nix expression search path + \$NIXOS_CONFIG path to the NixOS system configuration specification +EOF + exit 1 +} + + +# Parse the command line. +extraBuildFlags=() +action= +buildNix=1 +rollback= +upgrade= +repair= +profile=/nix/var/nix/profiles/system + +while [ "$#" -gt 0 ]; do + i="$1"; shift 1 + case "$i" in + --help) + showSyntax + ;; + switch|boot|test|build|dry-run|build-vm|build-vm-with-bootloader) + action="$i" + ;; + --install-grub) + export NIXOS_INSTALL_GRUB=1 + ;; + --no-build-nix) + buildNix= + ;; + --rollback) + rollback=1 + ;; + --upgrade) + upgrade=1 + ;; + --repair) + repair=1 + extraBuildFlags+=("$i") + ;; + --show-trace|--no-build-hook|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair) + extraBuildFlags+=("$i") + ;; + --max-jobs|-j|--cores|-I) + j="$1"; shift 1 + extraBuildFlags+=("$i" "$j") + ;; + --option) + j="$1"; shift 1 + k="$1"; shift 1 + extraBuildFlags+=("$i" "$j" "$k") + ;; + --fast) + buildNix= + extraBuildFlags+=(--show-trace) + ;; + --profile-name|-p) + if [ -z "$1" ]; then + echo "$0: ‘--profile-name’ requires an argument" + exit 1 + fi + if [ "$1" != system ]; then + profile="/nix/var/nix/profiles/system-profiles/$1" + mkdir -p -m 0755 "$(dirname "$profile")" + fi + shift 1 + ;; + *) + echo "$0: unknown option \`$i'" + exit 1 + ;; + esac +done + +if [ -z "$action" ]; then showSyntax; fi + +if [ -n "$rollback" ]; then + buildNix= +fi + + +tmpDir=$(mktemp -t -d nixos-rebuild.XXXXXX) +trap 'rm -rf "$tmpDir"' EXIT + + +# If the Nix daemon is running, then use it. This allows us to use +# the latest Nix from Nixpkgs (below) for expression evaluation, while +# still using the old Nix (via the daemon) for actual store access. +# This matters if the new Nix in Nixpkgs has a schema change. It +# would upgrade the schema, which should only happen once we actually +# switch to the new configuration. +# If --repair is given, don't try to use the Nix daemon, because the +# flag can only be used directly. +if [ -z "$repair" ] && systemctl show nix-daemon.socket nix-daemon.service | grep -q ActiveState=active; then + export NIX_REMOTE=${NIX_REMOTE:-daemon} +fi + + +# If ‘--upgrade’ is given, run ‘nix-channel --update nixos’. +if [ -n "$upgrade" ]; then + nix-channel --update nixos +fi + + +# First build Nix, since NixOS may require a newer version than the +# current one. Of course, the same goes for Nixpkgs, but Nixpkgs is +# more conservative. +if [ "$action" != dry-run -a -n "$buildNix" ]; then + echo "building Nix..." >&2 + if ! nix-build '<nixos>' -A config.environment.nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then + if ! nix-build '<nixos>' -A nixFallback -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then + nix-build '<nixpkgs>' -A nixUnstable -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null + fi + fi + PATH=$tmpDir/nix/bin:$PATH +fi + + +# Update the version suffix if we're building from Git (so that +# nixos-version shows something useful). +if nixos=$(nix-instantiate --find-file nixos "${extraBuildFlags[@]}"); then + suffix=$(@shell@ $nixos/modules/installer/tools/get-version-suffix "${extraBuildFlags[@]}") + if [ -n "$suffix" ]; then + echo -n "$suffix" > "$nixos/.version-suffix" || true + fi +fi + + +if [ "$action" = dry-run ]; then + extraBuildFlags+=(--dry-run) +fi + + +# Either upgrade the configuration in the system profile (for "switch" +# or "boot"), or just build it and create a symlink "result" in the +# current directory (for "build" and "test"). +if [ -z "$rollback" ]; then + echo "building the system configuration..." >&2 + if [ "$action" = switch -o "$action" = boot ]; then + nix-env "${extraBuildFlags[@]}" -p "$profile" -f '<nixos>' --set -A system + pathToConfig="$profile" + elif [ "$action" = test -o "$action" = build -o "$action" = dry-run ]; then + nix-build '<nixos>' -A system -K -k "${extraBuildFlags[@]}" > /dev/null + pathToConfig=./result + elif [ "$action" = build-vm ]; then + nix-build '<nixos>' -A vm -K -k "${extraBuildFlags[@]}" > /dev/null + pathToConfig=./result + elif [ "$action" = build-vm-with-bootloader ]; then + nix-build '<nixos>' -A vmWithBootLoader -K -k "${extraBuildFlags[@]}" > /dev/null + pathToConfig=./result + else + showSyntax + fi +else # [ -n "$rollback" ] + if [ "$action" = switch -o "$action" = boot ]; then + nix-env --rollback -p "$profile" + pathToConfig="$profile" + elif [ "$action" = test -o "$action" = build ]; then + systemNumber=$( + nix-env -p "$profile" --list-generations | + sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h' + ) + ln -sT "$profile"-${systemNumber}-link ./result + pathToConfig=./result + else + showSyntax + fi +fi + + +# If we're not just building, then make the new configuration the boot +# default and/or activate it now. +if [ "$action" = switch -o "$action" = boot -o "$action" = test ]; then + $pathToConfig/bin/switch-to-configuration "$action" +fi + + +if [ "$action" = build-vm ]; then + cat >&2 <<EOF + +Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm). +EOF +fi diff --git a/nixos/modules/installer/tools/nixos-version.sh b/nixos/modules/installer/tools/nixos-version.sh new file mode 100644 index 00000000000..5dbf277fe4c --- /dev/null +++ b/nixos/modules/installer/tools/nixos-version.sh @@ -0,0 +1,2 @@ +#! @shell@ +echo "@nixosVersion@ (@nixosCodeName@)" diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix new file mode 100644 index 00000000000..c761d74a890 --- /dev/null +++ b/nixos/modules/installer/tools/tools.nix @@ -0,0 +1,112 @@ +# This module generates nixos-install, nixos-rebuild, +# nixos-hardware-scan, etc. + +{ config, pkgs, modulesPath, ... }: + +let + ### implementation + cfg = config.installer; + + makeProg = args: pkgs.substituteAll (args // { + dir = "bin"; + isExecutable = true; + }); + + nixosBuildVMS = makeProg { + name = "nixos-build-vms"; + src = ./nixos-build-vms/nixos-build-vms.sh; + }; + + nixosInstall = makeProg { + name = "nixos-install"; + src = ./nixos-install.sh; + + inherit (pkgs) perl pathsFromGraph; + nix = config.environment.nix; + + nixClosure = pkgs.runCommand "closure" + { exportReferencesGraph = ["refs" config.environment.nix]; } + "cp refs $out"; + }; + + nixosRebuild = makeProg { + name = "nixos-rebuild"; + src = ./nixos-rebuild.sh; + }; + + /* + nixosGenSeccureKeys = makeProg { + name = "nixos-gen-seccure-keys"; + src = ./nixos-gen-seccure-keys.sh; + }; + */ + + nixosHardwareScan = makeProg { + name = "nixos-hardware-scan"; + src = ./nixos-hardware-scan.pl; + inherit (pkgs) perl dmidecode; + }; + + nixosOption = makeProg { + name = "nixos-option"; + src = ./nixos-option.sh; + }; + + nixosVersion = makeProg { + name = "nixos-version"; + src = ./nixos-version.sh; + inherit (config.system) nixosVersion nixosCodeName; + }; + + nixosGui = pkgs.xulrunnerWrapper { + launcher = "nixos-gui"; + application = pkgs.stdenv.mkDerivation { + name = "nixos-gui"; + buildCommand = '' + cp -r "$gui" "$out" + + # Do not force the copy if the file exists in the sources (this + # happens for developpers) + test -e "$out/chrome/content/jquery-1.5.2.js" || + cp -f "$jquery" "$out/chrome/content/jquery-1.5.2.js" + ''; + gui = pkgs.lib.cleanSource "${modulesPath}/../gui"; + jquery = pkgs.fetchurl { + url = http://code.jquery.com/jquery-1.5.2.min.js; + sha256 = "8f0a19ee8c606b35a10904951e0a27da1896eafe33c6e88cb7bcbe455f05a24a"; + }; + }; + }; + +in + +{ + options = { + + installer.enableGraphicalTools = pkgs.lib.mkOption { + default = false; + type = with pkgs.lib.types; bool; + example = true; + description = '' + Enable the installation of graphical tools. + ''; + }; + + }; + + config = { + environment.systemPackages = + [ nixosBuildVMS + nixosInstall + nixosRebuild + nixosHardwareScan + #nixosGenSeccureKeys + nixosOption + nixosVersion + ] ++ pkgs.lib.optional cfg.enableGraphicalTools nixosGui; + + system.build = { + inherit nixosInstall nixosHardwareScan nixosOption; + }; + }; +} diff --git a/nixos/modules/installer/virtualbox-demo.nix b/nixos/modules/installer/virtualbox-demo.nix new file mode 100644 index 00000000000..76cc29a1fac --- /dev/null +++ b/nixos/modules/installer/virtualbox-demo.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + imports = + [ ../virtualisation/virtualbox-image.nix + ../installer/cd-dvd/channel.nix + ../profiles/demo.nix + ../profiles/clone-config.nix + ]; + + # Allow mounting of shared folders. + users.extraUsers.demo.extraGroups = [ "vboxsf" ]; + + # Add some more video drivers to give X11 a shot at working in + # VMware and QEMU. + services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" ]; +} |