aboutsummaryrefslogtreecommitdiff
path: root/infra/libkookie/nixpkgs/nixos/modules/installer
diff options
context:
space:
mode:
authorMx Kookie <kookie@spacekookie.de>2020-12-21 06:05:12 +0100
committerMx Kookie <kookie@spacekookie.de>2020-12-21 06:05:12 +0100
commitf107be784e6d5da5f90735765a68fdff96acfbb4 (patch)
tree145573a598009fb6adbd5ef7fbce0a850681f5f0 /infra/libkookie/nixpkgs/nixos/modules/installer
parent2e04b35e5ac3a9123cafffbc84494fa4d389cca0 (diff)
parente9158eca70ae59e73fae23be5d13d3fa0cfc78b4 (diff)
Add 'infra/libkookie/nixpkgs/' from commit 'e9158eca70ae59e73fae23be5d13d3fa0cfc78b4'
git-subtree-dir: infra/libkookie/nixpkgs git-subtree-mainline: 2e04b35e5ac3a9123cafffbc84494fa4d389cca0 git-subtree-split: e9158eca70ae59e73fae23be5d13d3fa0cfc78b4
Diffstat (limited to 'infra/libkookie/nixpkgs/nixos/modules/installer')
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix49
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-base.nix34
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix56
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix38
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5-new-kernel.nix7
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5.nix50
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix7
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix14
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix716
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix7
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix60
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix57
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix46
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix38
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix245
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix160
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt89
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc.nix163
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix172
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball.nix93
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot-base.nix17
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix10
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot.nix112
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/scan/detected.nix12
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/scan/not-detected.nix6
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/get-version-suffix22
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix6
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix18
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh52
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh74
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl646
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-install.sh217
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/CMakeLists.txt8
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/default.nix11
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/libnix-copy-paste.cc83
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/libnix-copy-paste.hh9
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc643
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh506
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-version.sh23
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/tools/tools.nix222
-rw-r--r--infra/libkookie/nixpkgs/nixos/modules/installer/virtualbox-demo.nix61
41 files changed, 4859 insertions, 0 deletions
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/channel.nix
new file mode 100644
index 000000000000..92164d65e533
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-base.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-base.nix
new file mode 100644
index 000000000000..6c7ea293e8ac
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-base.nix
@@ -0,0 +1,34 @@
+# 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;
+
+ system.stateVersion = mkDefault "18.03";
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix
new file mode 100644
index 000000000000..fa19daf13280
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix
new file mode 100644
index 000000000000..803bae4212ef
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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.gnome3 = {
+ # Add firefox to favorite-apps
+ favoriteAppsOverride = ''
+ [org.gnome.shell]
+ favorite-apps=[ 'firefox.desktop', 'org.gnome.Geary.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Photos.desktop', 'org.gnome.Nautilus.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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5-new-kernel.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5-new-kernel.nix
new file mode 100644
index 000000000000..d98325a99ac2
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma5.nix
new file mode 100644
index 000000000000..098c2b2870b0
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix
new file mode 100644
index 000000000000..3911a2b01b1e
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix
new file mode 100644
index 000000000000..97506045e0e1
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
new file mode 100644
index 000000000000..405fbfa10dbf
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -0,0 +1,716 @@
+# 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}
+ '';
+
+ 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);
+
+ # Setup instructions for rEFInd.
+ refind =
+ if targetArch == "x64" then
+ ''
+ # Adds rEFInd to the ISO.
+ cp -v ${pkgs.refind}/share/refind/refind_x64.efi $out/EFI/boot/
+ ''
+ else
+ "# No refind for ${targetArch}"
+ ;
+
+ grubPkgs = if config.boot.loader.grub.forcei686 then pkgs.pkgsi686Linux else pkgs;
+
+ grubMenuCfg = ''
+ #
+ # Menu configuration
+ #
+
+ insmod gfxterm
+ insmod png
+ set gfxpayload=keep
+
+ # Fonts can be loaded?
+ # (This font is assumed to always be provided as a fallback by NixOS)
+ if loadfont (hd0)/EFI/boot/unicode.pf2; 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=(hd0)/EFI/boot/grub-theme/theme.txt
+ # Load theme fonts
+ $(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (hd0)/EFI/boot/grub-theme/%P\n")
+ '' else ''
+ if background_image (hd0)/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" {} ''
+ mkdir -p $out/EFI/boot/
+
+ # 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.
+ ${grubPkgs.grub2_efi}/bin/grub-mkimage -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
+
+ # 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
+ ${grubMenuCfg}
+
+ # 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"}
+ }
+ }
+
+ menuentry 'rEFInd' --class refind {
+ # UUID is hard-coded in the derivation.
+ search --set=root --no-floppy --fs-uuid 1234-5678
+ chainloader (\$root)/EFI/boot/refind_x64.efi
+ }
+ 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" { buildInputs = [ pkgs.mtools pkgs.libfaketime ]; }
+ # 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/
+ touch --date=@0 ./EFI ./boot
+
+ usage_size=$(du -sb --apparent-size . | tr -cd '[:digit:]')
+ # 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"
+ ${pkgs.libfaketime}/bin/faketime "2000-01-01 00:00:00" ${pkgs.dosfstools}/sbin/mkfs.vfat -i 12345678 -n EFIBOOT "$out"
+ mcopy -psvm -i "$out" ./EFI ./boot ::
+ # Verify the FAT partition.
+ ${pkgs.dosfstools}/sbin/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.isAarch64 then
+ "aa64"
+ else
+ throw "Unsupported architecture";
+
+ # Syslinux (and isolinux) only supports x86-based architectures.
+ canx86BiosBoot = pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64;
+
+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 = "xz -Xdict-size 100%";
+ 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 = literalExample ''
+ [ { 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 = literalExample "[ 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>
+ '';
+ };
+
+ };
+
+ 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."/" =
+ { 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.
+ fileSystems."/iso" =
+ { 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.
+ fileSystems."/nix/.ro-store" =
+ { fsType = "squashfs";
+ device = "/iso/nix-store.squashfs";
+ options = [ "loop" ];
+ neededForBoot = true;
+ };
+
+ fileSystems."/nix/.rw-store" =
+ { fsType = "tmpfs";
+ options = [ "mode=0755" ];
+ neededForBoot = true;
+ };
+
+ fileSystems."/nix/store" =
+ { fsType = "overlay";
+ device = "overlay";
+ options = [
+ "lowerdir=/nix/.ro-store"
+ "upperdir=/nix/.rw-store/store"
+ "workdir=/nix/.rw-store/work"
+ ];
+ };
+
+ 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 = config.isoImage.splashImage;
+ target = "/isolinux/background.png";
+ }
+ { source = pkgs.writeText "version" config.system.nixos.label;
+ target = "/version.txt";
+ }
+ ] ++ optionals canx86BiosBoot [
+ { 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";
+ }
+ ] ++ 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";
+ }
+ ] ++ [
+ { source = config.isoImage.efiSplashImage;
+ target = "/EFI/boot/efi-background.png";
+ }
+ ];
+
+ 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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix
new file mode 100644
index 000000000000..2882fbcc7305
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix
@@ -0,0 +1,7 @@
+{ pkgs, ... }:
+
+{
+ imports = [ ./sd-image-aarch64.nix ];
+
+ boot.kernelPackages = pkgs.linuxPackages_latest;
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
new file mode 100644
index 000000000000..bef6cd2fb5a2
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
@@ -0,0 +1,60 @@
+# To build, use:
+# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-aarch64.nix -A config.system.build.sdImage
+{ config, lib, pkgs, ... }:
+
+{
+ imports = [
+ ../../profiles/base.nix
+ ../../profiles/installation-device.nix
+ ./sd-image.nix
+ ];
+
+ boot.loader.grub.enable = false;
+ boot.loader.generic-extlinux-compatible.enable = true;
+
+ boot.consoleLogLevel = lib.mkDefault 7;
+
+ # The serial ports listed here are:
+ # - ttyS0: for Tegra (Jetson TX1)
+ # - ttyAMA0: for QEMU's -machine virt
+ # Also increase the amount of CMA to ensure the virtual console on the RPi3 works.
+ boot.kernelParams = ["cma=32M" "console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
+
+ boot.initrd.availableKernelModules = [
+ # Allows early (earlier) modesetting for the Raspberry Pi
+ "vc4" "bcm2835_dma" "i2c_bcm2835"
+ # Allows early (earlier) modesetting for Allwinner SoCs
+ "sun4i_drm" "sun8i_drm_hdmi" "sun8i_mixer"
+ ];
+
+ sdImage = {
+ populateFirmwareCommands = let
+ configTxt = pkgs.writeText "config.txt" ''
+ kernel=u-boot-rpi3.bin
+
+ # Boot in 64-bit mode.
+ arm_control=0x200
+
+ # U-Boot used to need this to work, regardless of whether UART is actually used or not.
+ # TODO: check when/if this can be removed.
+ enable_uart=1
+
+ # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
+ # when attempting to show low-voltage or overtemperature warnings.
+ avoid_warnings=1
+ '';
+ in ''
+ (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
+ cp ${pkgs.ubootRaspberryPi3_64bit}/u-boot.bin firmware/u-boot-rpi3.bin
+ cp ${configTxt} firmware/config.txt
+ '';
+ populateRootCommands = ''
+ mkdir -p ./files/boot
+ ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
+ '';
+ };
+
+ # the installation media is also the installation target,
+ # so we don't want to provide the installation configuration.nix.
+ installer.cloneConfig = false;
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
new file mode 100644
index 000000000000..d2ba611532e0
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
@@ -0,0 +1,57 @@
+# To build, use:
+# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix -A config.system.build.sdImage
+{ config, lib, pkgs, ... }:
+
+{
+ imports = [
+ ../../profiles/base.nix
+ ../../profiles/installation-device.nix
+ ./sd-image.nix
+ ];
+
+ boot.loader.grub.enable = false;
+ boot.loader.generic-extlinux-compatible.enable = true;
+
+ boot.consoleLogLevel = lib.mkDefault 7;
+ boot.kernelPackages = pkgs.linuxPackages_latest;
+ # The serial ports listed here are:
+ # - ttyS0: for Tegra (Jetson TK1)
+ # - ttymxc0: for i.MX6 (Wandboard)
+ # - ttyAMA0: for Allwinner (pcDuino3 Nano) and QEMU's -machine virt
+ # - ttyO0: for OMAP (BeagleBone Black)
+ # - ttySAC2: for Exynos (ODROID-XU3)
+ boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=ttyO0,115200n8" "console=ttySAC2,115200n8" "console=tty0"];
+
+ sdImage = {
+ populateFirmwareCommands = let
+ configTxt = pkgs.writeText "config.txt" ''
+ # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
+ # when attempting to show low-voltage or overtemperature warnings.
+ avoid_warnings=1
+
+ [pi2]
+ kernel=u-boot-rpi2.bin
+
+ [pi3]
+ kernel=u-boot-rpi3.bin
+
+ # U-Boot used to need this to work, regardless of whether UART is actually used or not.
+ # TODO: check when/if this can be removed.
+ enable_uart=1
+ '';
+ in ''
+ (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
+ cp ${pkgs.ubootRaspberryPi2}/u-boot.bin firmware/u-boot-rpi2.bin
+ cp ${pkgs.ubootRaspberryPi3_32bit}/u-boot.bin firmware/u-boot-rpi3.bin
+ cp ${configTxt} firmware/config.txt
+ '';
+ populateRootCommands = ''
+ mkdir -p ./files/boot
+ ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
+ '';
+ };
+
+ # the installation media is also the installation target,
+ # so we don't want to provide the installation configuration.nix.
+ installer.cloneConfig = false;
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
new file mode 100644
index 000000000000..40a01f961771
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
@@ -0,0 +1,46 @@
+# To build, use:
+# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix -A config.system.build.sdImage
+{ config, lib, pkgs, ... }:
+
+{
+ imports = [
+ ../../profiles/base.nix
+ ../../profiles/installation-device.nix
+ ./sd-image.nix
+ ];
+
+ boot.loader.grub.enable = false;
+ boot.loader.generic-extlinux-compatible.enable = true;
+
+ boot.consoleLogLevel = lib.mkDefault 7;
+ boot.kernelPackages = pkgs.linuxPackages_rpi1;
+
+ sdImage = {
+ populateFirmwareCommands = let
+ configTxt = pkgs.writeText "config.txt" ''
+ # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
+ # when attempting to show low-voltage or overtemperature warnings.
+ avoid_warnings=1
+
+ [pi0]
+ kernel=u-boot-rpi0.bin
+
+ [pi1]
+ kernel=u-boot-rpi1.bin
+ '';
+ in ''
+ (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
+ cp ${pkgs.ubootRaspberryPiZero}/u-boot.bin firmware/u-boot-rpi0.bin
+ cp ${pkgs.ubootRaspberryPi}/u-boot.bin firmware/u-boot-rpi1.bin
+ cp ${configTxt} firmware/config.txt
+ '';
+ populateRootCommands = ''
+ mkdir -p ./files/boot
+ ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
+ '';
+ };
+
+ # the installation media is also the installation target,
+ # so we don't want to provide the installation configuration.nix.
+ installer.cloneConfig = false;
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix
new file mode 100644
index 000000000000..87545e842030
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix
@@ -0,0 +1,38 @@
+# To build, use:
+# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix -A config.system.build.sdImage
+{ config, lib, pkgs, ... }:
+
+{
+ imports = [
+ ../../profiles/base.nix
+ ../../profiles/installation-device.nix
+ ./sd-image.nix
+ ];
+
+ boot.loader.grub.enable = false;
+ boot.loader.raspberryPi.enable = true;
+ boot.loader.raspberryPi.version = 4;
+ boot.kernelPackages = pkgs.linuxPackages_rpi4;
+
+ boot.consoleLogLevel = lib.mkDefault 7;
+
+ sdImage = {
+ firmwareSize = 128;
+ firmwarePartitionName = "NIXOS_BOOT";
+ # This is a hack to avoid replicating config.txt from boot.loader.raspberryPi
+ populateFirmwareCommands =
+ "${config.system.build.installBootLoader} ${config.system.build.toplevel} -d ./firmware";
+ # As the boot process is done entirely in the firmware partition.
+ populateRootCommands = "";
+ };
+
+ fileSystems."/boot/firmware" = {
+ # This effectively "renames" the attrsOf entry set in sd-image.nix
+ mountPoint = "/boot";
+ neededForBoot = true;
+ };
+
+ # the installation media is also the installation target,
+ # so we don't want to provide the installation configuration.nix.
+ installer.cloneConfig = false;
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
new file mode 100644
index 000000000000..c8c5a46dfb87
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
@@ -0,0 +1,245 @@
+# This module creates a bootable SD card image containing the given NixOS
+# configuration. The generated image is MBR partitioned, with a FAT
+# /boot/firmware partition, and ext4 root partition. The generated image
+# is sized to fit its contents, and a boot script automatically resizes
+# the root partition to fit the device on the first boot.
+#
+# The firmware partition is built with expectation to hold the Raspberry
+# Pi firmware and bootloader, and be removed and replaced with a firmware
+# build for the target SoC for other board families.
+#
+# The derivation for the SD image will be placed in
+# config.system.build.sdImage
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ rootfsImage = pkgs.callPackage ../../../lib/make-ext4-fs.nix ({
+ inherit (config.sdImage) storePaths;
+ compressImage = true;
+ populateImageCommands = config.sdImage.populateRootCommands;
+ volumeLabel = "NIXOS_SD";
+ } // optionalAttrs (config.sdImage.rootPartitionUUID != null) {
+ uuid = config.sdImage.rootPartitionUUID;
+ });
+in
+{
+ imports = [
+ (mkRemovedOptionModule [ "sdImage" "bootPartitionID" ] "The FAT partition for SD image now only holds the Raspberry Pi firmware files. Use firmwarePartitionID to configure that partition's ID.")
+ (mkRemovedOptionModule [ "sdImage" "bootSize" ] "The boot files for SD image have been moved to the main ext4 partition. The FAT partition now only holds the Raspberry Pi firmware files. Changing its size may not be required.")
+ ];
+
+ options.sdImage = {
+ imageName = mkOption {
+ default = "${config.sdImage.imageBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.img";
+ description = ''
+ Name of the generated image file.
+ '';
+ };
+
+ imageBaseName = mkOption {
+ default = "nixos-sd-image";
+ description = ''
+ Prefix of the name of the generated image file.
+ '';
+ };
+
+ storePaths = mkOption {
+ type = with types; listOf package;
+ example = literalExample "[ pkgs.stdenv ]";
+ description = ''
+ Derivations to be included in the Nix store in the generated SD image.
+ '';
+ };
+
+ firmwarePartitionID = mkOption {
+ type = types.str;
+ default = "0x2178694e";
+ description = ''
+ Volume ID for the /boot/firmware partition on the SD card. This value
+ must be a 32-bit hexadecimal number.
+ '';
+ };
+
+ firmwarePartitionName = mkOption {
+ type = types.str;
+ default = "FIRMWARE";
+ description = ''
+ Name of the filesystem which holds the boot firmware.
+ '';
+ };
+
+ rootPartitionUUID = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "14e19a7b-0ae0-484d-9d54-43bd6fdc20c7";
+ description = ''
+ UUID for the filesystem on the main NixOS partition on the SD card.
+ '';
+ };
+
+ firmwareSize = mkOption {
+ type = types.int;
+ # As of 2019-08-18 the Raspberry pi firmware + u-boot takes ~18MiB
+ default = 30;
+ description = ''
+ Size of the /boot/firmware partition, in megabytes.
+ '';
+ };
+
+ populateFirmwareCommands = mkOption {
+ example = literalExample "'' cp \${pkgs.myBootLoader}/u-boot.bin firmware/ ''";
+ description = ''
+ Shell commands to populate the ./firmware directory.
+ All files in that directory are copied to the
+ /boot/firmware partition on the SD image.
+ '';
+ };
+
+ populateRootCommands = mkOption {
+ example = literalExample "''\${config.boot.loader.generic-extlinux-compatible.populateCmd} -c \${config.system.build.toplevel} -d ./files/boot''";
+ description = ''
+ Shell commands to populate the ./files directory.
+ All files in that directory are copied to the
+ root (/) partition on the SD image. Use this to
+ populate the ./files/boot (/boot) directory.
+ '';
+ };
+
+ postBuildCommands = mkOption {
+ example = literalExample "'' dd if=\${pkgs.myBootLoader}/SPL of=$img bs=1024 seek=1 conv=notrunc ''";
+ default = "";
+ description = ''
+ Shell commands to run after the image is built.
+ Can be used for boards requiring to dd u-boot SPL before actual partitions.
+ '';
+ };
+
+ compressImage = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether the SD image should be compressed using
+ <command>zstd</command>.
+ '';
+ };
+
+ };
+
+ config = {
+ fileSystems = {
+ "/boot/firmware" = {
+ device = "/dev/disk/by-label/${config.sdImage.firmwarePartitionName}";
+ fsType = "vfat";
+ # Alternatively, this could be removed from the configuration.
+ # The filesystem is not needed at runtime, it could be treated
+ # as an opaque blob instead of a discrete FAT32 filesystem.
+ options = [ "nofail" "noauto" ];
+ };
+ "/" = {
+ device = "/dev/disk/by-label/NIXOS_SD";
+ fsType = "ext4";
+ };
+ };
+
+ sdImage.storePaths = [ config.system.build.toplevel ];
+
+ system.build.sdImage = pkgs.callPackage ({ stdenv, dosfstools, e2fsprogs,
+ mtools, libfaketime, util-linux, zstd }: stdenv.mkDerivation {
+ name = config.sdImage.imageName;
+
+ nativeBuildInputs = [ dosfstools e2fsprogs mtools libfaketime util-linux zstd ];
+
+ inherit (config.sdImage) compressImage;
+
+ buildCommand = ''
+ mkdir -p $out/nix-support $out/sd-image
+ export img=$out/sd-image/${config.sdImage.imageName}
+
+ echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system
+ if test -n "$compressImage"; then
+ echo "file sd-image $img.zst" >> $out/nix-support/hydra-build-products
+ else
+ echo "file sd-image $img" >> $out/nix-support/hydra-build-products
+ fi
+
+ echo "Decompressing rootfs image"
+ zstd -d --no-progress "${rootfsImage}" -o ./root-fs.img
+
+ # Gap in front of the first partition, in MiB
+ gap=8
+
+ # Create the image file sized to fit /boot/firmware and /, plus slack for the gap.
+ rootSizeBlocks=$(du -B 512 --apparent-size ./root-fs.img | awk '{ print $1 }')
+ firmwareSizeBlocks=$((${toString config.sdImage.firmwareSize} * 1024 * 1024 / 512))
+ imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
+ truncate -s $imageSize $img
+
+ # type=b is 'W95 FAT32', type=83 is 'Linux'.
+ # The "bootable" partition is where u-boot will look file for the bootloader
+ # information (dtbs, extlinux.conf file).
+ sfdisk $img <<EOF
+ label: dos
+ label-id: ${config.sdImage.firmwarePartitionID}
+
+ start=''${gap}M, size=$firmwareSizeBlocks, type=b
+ start=$((gap + ${toString config.sdImage.firmwareSize}))M, type=83, bootable
+ EOF
+
+ # Copy the rootfs into the SD image
+ eval $(partx $img -o START,SECTORS --nr 2 --pairs)
+ dd conv=notrunc if=./root-fs.img of=$img seek=$START count=$SECTORS
+
+ # Create a FAT32 /boot/firmware partition of suitable size into firmware_part.img
+ eval $(partx $img -o START,SECTORS --nr 1 --pairs)
+ truncate -s $((SECTORS * 512)) firmware_part.img
+ faketime "1970-01-01 00:00:00" mkfs.vfat -i ${config.sdImage.firmwarePartitionID} -n ${config.sdImage.firmwarePartitionName} firmware_part.img
+
+ # Populate the files intended for /boot/firmware
+ mkdir firmware
+ ${config.sdImage.populateFirmwareCommands}
+
+ # Copy the populated /boot/firmware into the SD image
+ (cd firmware; mcopy -psvm -i ../firmware_part.img ./* ::)
+ # Verify the FAT partition before copying it.
+ fsck.vfat -vn firmware_part.img
+ dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
+
+ ${config.sdImage.postBuildCommands}
+
+ if test -n "$compressImage"; then
+ zstd -T$NIX_BUILD_CORES --rm $img
+ fi
+ '';
+ }) {};
+
+ boot.postBootCommands = ''
+ # On the first boot do some maintenance tasks
+ if [ -f /nix-path-registration ]; then
+ set -euo pipefail
+ set -x
+ # Figure out device names for the boot device and root filesystem.
+ rootPart=$(${pkgs.util-linux}/bin/findmnt -n -o SOURCE /)
+ bootDevice=$(lsblk -npo PKNAME $rootPart)
+ partNum=$(lsblk -npo MAJ:MIN $rootPart | awk -F: '{print $2}')
+
+ # Resize the root partition and the filesystem to fit the disk
+ echo ",+," | sfdisk -N$partNum --no-reread $bootDevice
+ ${pkgs.parted}/bin/partprobe
+ ${pkgs.e2fsprogs}/bin/resize2fs $rootPart
+
+ # Register the contents of the initial Nix store
+ ${config.nix.package.out}/bin/nix-store --load-db < /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
+
+ # Prevents this from running on later boots.
+ rm -f /nix-path-registration
+ fi
+ '';
+ };
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix
new file mode 100644
index 000000000000..6d4ba96dba0c
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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 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.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.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;
+ 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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt
new file mode 100644
index 000000000000..887bf60d0fbe
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-pc.nix
new file mode 100644
index 000000000000..f2af7dcde3d5
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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 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;
+ systemd.services.openssh.wantedBy = lib.mkOverride 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.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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
new file mode 100644
index 000000000000..0e67ae7de698
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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.linuxPackages_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.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.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/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/cd-dvd/system-tarball.nix
new file mode 100644
index 000000000000..58098c45535d
--- /dev/null
+++ b/infra/libkookie/nixpkgs/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 = literalExample ''
+ [ { 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 = literalExample "[ 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
+ '';
+
+ };
+
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot-base.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot-base.nix
new file mode 100644
index 000000000000..7e66a49c7391
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot-base.nix
@@ -0,0 +1,17 @@
+# This module contains the basic configuration for building netboot
+# images
+
+{ lib, ... }:
+
+with lib;
+
+{
+ imports =
+ [ ./netboot.nix
+
+ # Profiles of this basic netboot media
+ ../../profiles/all-hardware.nix
+ ../../profiles/base.nix
+ ../../profiles/installation-device.nix
+ ];
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix
new file mode 100644
index 000000000000..1563501a7e01
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot-minimal.nix
@@ -0,0 +1,10 @@
+# This module defines a small netboot environment.
+
+{ ... }:
+
+{
+ imports =
+ [ ./netboot-base.nix
+ ../../profiles/minimal.nix
+ ];
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot.nix
new file mode 100644
index 000000000000..95eba86bcb65
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/netboot/netboot.nix
@@ -0,0 +1,112 @@
+# This module creates netboot media containing the given NixOS
+# configuration.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+ options = {
+
+ netboot.storeContents = mkOption {
+ example = literalExample "[ pkgs.stdenv ]";
+ description = ''
+ This option lists additional derivations to be included in the
+ Nix store in the generated netboot image.
+ '';
+ };
+
+ };
+
+ config = {
+ # 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.
+ environment.systemPackages = [ pkgs.grub2_efi ]
+ ++ (if pkgs.stdenv.hostPlatform.system == "aarch64-linux"
+ then []
+ else [ pkgs.grub2 pkgs.syslinux ]);
+
+ fileSystems."/" =
+ { fsType = "tmpfs";
+ options = [ "mode=0755" ];
+ };
+
+ # In stage 1, mount a tmpfs on top of /nix/store (the squashfs
+ # image) to make this a live CD.
+ fileSystems."/nix/.ro-store" =
+ { fsType = "squashfs";
+ device = "../nix-store.squashfs";
+ options = [ "loop" ];
+ neededForBoot = true;
+ };
+
+ fileSystems."/nix/.rw-store" =
+ { fsType = "tmpfs";
+ options = [ "mode=0755" ];
+ neededForBoot = true;
+ };
+
+ fileSystems."/nix/store" =
+ { fsType = "overlay";
+ device = "overlay";
+ options = [
+ "lowerdir=/nix/.ro-store"
+ "upperdir=/nix/.rw-store/store"
+ "workdir=/nix/.rw-store/work"
+ ];
+ };
+
+ boot.initrd.availableKernelModules = [ "squashfs" "overlay" ];
+
+ boot.initrd.kernelModules = [ "loop" "overlay" ];
+
+ # Closures to be copied to the Nix store, namely the init
+ # script and the top-level system configuration directory.
+ netboot.storeContents =
+ [ config.system.build.toplevel ];
+
+ # Create the squashfs image that contains the Nix store.
+ system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix {
+ storeContents = config.netboot.storeContents;
+ };
+
+
+ # Create the initrd
+ system.build.netbootRamdisk = pkgs.makeInitrd {
+ inherit (config.boot.initrd) compressor;
+ prepend = [ "${config.system.build.initialRamdisk}/initrd" ];
+
+ contents =
+ [ { object = config.system.build.squashfsStore;
+ symlink = "/nix-store.squashfs";
+ }
+ ];
+ };
+
+ system.build.netbootIpxeScript = pkgs.writeTextDir "netboot.ipxe" ''
+ #!ipxe
+ kernel ${pkgs.stdenv.hostPlatform.platform.kernelTarget} init=${config.system.build.toplevel}/init initrd=initrd ${toString config.boot.kernelParams}
+ initrd initrd
+ boot
+ '';
+
+ boot.loader.timeout = 10;
+
+ boot.postBootCommands =
+ ''
+ # After booting, register the contents of the Nix store
+ # in the Nix database in the tmpfs.
+ ${config.nix.package}/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}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
+ '';
+
+ };
+
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/scan/detected.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/scan/detected.nix
new file mode 100644
index 000000000000..5c5fba56f517
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/scan/detected.nix
@@ -0,0 +1,12 @@
+# List all devices which are detected by nixos-generate-config.
+# Common devices are enabled by default.
+{ lib, ... }:
+
+with lib;
+
+{
+ config = mkDefault {
+ # Common firmware, i.e. for wifi cards
+ hardware.enableRedistributableFirmware = true;
+ };
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/scan/not-detected.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/scan/not-detected.nix
new file mode 100644
index 000000000000..baa068c08dbf
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/scan/not-detected.nix
@@ -0,0 +1,6 @@
+# Enables non-free firmware on devices not recognized by `nixos-generate-config`.
+{ lib, ... }:
+
+{
+ hardware.enableRedistributableFirmware = lib.mkDefault true;
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/get-version-suffix b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/get-version-suffix
new file mode 100644
index 000000000000..b8972cd57d22
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/get-version-suffix
@@ -0,0 +1,22 @@
+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 nixpkgs=$(nix-instantiate --find-file nixpkgs "$@"); then
+ getVersion $nixpkgs
+ if [ -n "$rev" ]; then
+ echo ".git.$rev"
+ fi
+fi
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix
new file mode 100644
index 000000000000..699fb555615b
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix
@@ -0,0 +1,6 @@
+{
+ x86_64-linux = "/nix/store/fwak7l5jjl0py4wldsqjbv7p7rdzql0b-nix-2.3.9";
+ i686-linux = "/nix/store/jlqrx9zw3vkwcczndaar5ban1j8g519z-nix-2.3.9";
+ aarch64-linux = "/nix/store/kzvpzlm12185hw27l5znrprgvcja54d0-nix-2.3.9";
+ x86_64-darwin = "/nix/store/kanh3awpf370pxfnjfvkh2m343wr3hj0-nix-2.3.9";
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
new file mode 100644
index 000000000000..e49ceba24245
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix
@@ -0,0 +1,18 @@
+{ system ? builtins.currentSystem
+, config ? {}
+, networkExpr
+}:
+
+let
+ nodes = builtins.mapAttrs (vm: module: {
+ _file = "${networkExpr}@node-${vm}";
+ imports = [ module ];
+ }) (import networkExpr);
+in
+
+with import ../../../../lib/testing-python.nix {
+ inherit system;
+ pkgs = import ../../../../.. { inherit system config; };
+};
+
+(makeTest { inherit nodes; testScript = ""; }).driverInteractive
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
new file mode 100644
index 000000000000..2a6c3ab11497
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-build-vms/nixos-build-vms.sh
@@ -0,0 +1,52 @@
+#! @runtimeShell@ -e
+
+# Shows the usage of this command to the user
+
+showUsage() {
+ exec man nixos-build-vms
+ exit 1
+}
+
+# Parse valid argument options
+
+nixBuildArgs=()
+networkExpr=
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --no-out-link)
+ nixBuildArgs+=("--no-out-link")
+ ;;
+ --show-trace)
+ nixBuildArgs+=("--show-trace")
+ ;;
+ -h|--help)
+ showUsage
+ exit 0
+ ;;
+ --option)
+ shift
+ nixBuildArgs+=("--option" "$1" "$2"); shift
+ ;;
+ *)
+ if [ ! -z "$networkExpr" ]; then
+ echo "Network expression already set!"
+ showUsage
+ exit 1
+ fi
+ networkExpr="$(readlink -f $1)"
+ ;;
+ esac
+
+ shift
+done
+
+if [ -z "$networkExpr" ]
+then
+ echo "ERROR: A network expression must be specified!" >&2
+ exit 1
+fi
+
+# Build a network of VMs
+nix-build '<nixpkgs/nixos/modules/installer/tools/nixos-build-vms/build-vms.nix>' \
+ --argstr networkExpr $networkExpr "${nixBuildArgs[@]}"
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
new file mode 100644
index 000000000000..c72ef6e9c28b
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
@@ -0,0 +1,74 @@
+#! @runtimeShell@
+
+set -e
+
+# Re-exec ourselves in a private mount namespace so that our bind
+# mounts get cleaned up automatically.
+if [ -z "$NIXOS_ENTER_REEXEC" ]; then
+ export NIXOS_ENTER_REEXEC=1
+ if [ "$(id -u)" != 0 ]; then
+ extraFlags="-r"
+ fi
+ exec unshare --fork --mount --uts --mount-proc --pid $extraFlags -- "$0" "$@"
+else
+ mount --make-rprivate /
+fi
+
+mountPoint=/mnt
+system=/nix/var/nix/profiles/system
+command=("$system/sw/bin/bash" "--login")
+silent=0
+
+while [ "$#" -gt 0 ]; do
+ i="$1"; shift 1
+ case "$i" in
+ --root)
+ mountPoint="$1"; shift 1
+ ;;
+ --system)
+ system="$1"; shift 1
+ ;;
+ --help)
+ exec man nixos-enter
+ exit 1
+ ;;
+ --command|-c)
+ command=("$system/sw/bin/bash" "-c" "$1")
+ shift 1
+ ;;
+ --silent)
+ silent=1
+ ;;
+ --)
+ command=("$@")
+ break
+ ;;
+ *)
+ echo "$0: unknown option \`$i'"
+ exit 1
+ ;;
+ esac
+done
+
+if [[ ! -e $mountPoint/etc/NIXOS ]]; then
+ echo "$0: '$mountPoint' is not a NixOS installation" >&2
+ exit 126
+fi
+
+mkdir -p "$mountPoint/dev" "$mountPoint/sys"
+chmod 0755 "$mountPoint/dev" "$mountPoint/sys"
+mount --rbind /dev "$mountPoint/dev"
+mount --rbind /sys "$mountPoint/sys"
+
+(
+ # If silent, write both stdout and stderr of activation script to /dev/null
+ # otherwise, write both streams to stderr of this process
+ if [ "$silent" -eq 1 ]; then
+ exec 2>/dev/null
+ fi
+
+ # Run the activation script. Set $LOCALE_ARCHIVE to supress some Perl locale warnings.
+ LOCALE_ARCHIVE="$system/sw/lib/locale/locale-archive" chroot "$mountPoint" "$system/activate" 1>&2 || true
+)
+
+exec chroot "$mountPoint" "${command[@]}"
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl
new file mode 100644
index 000000000000..6e3ddb875e1b
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -0,0 +1,646 @@
+#! @perl@
+
+use strict;
+use Cwd 'abs_path';
+use File::Spec;
+use File::Path;
+use File::Basename;
+use File::Slurp;
+use File::stat;
+
+umask(0022);
+
+sub uniq {
+ my %seen;
+ my @res = ();
+ foreach my $s (@_) {
+ if (!defined $seen{$s}) {
+ $seen{$s} = 1;
+ push @res, $s;
+ }
+ }
+ return @res;
+}
+
+sub runCommand {
+ my ($cmd) = @_;
+ open FILE, "$cmd 2>&1 |" or die "Failed to execute: $cmd\n";
+ my @ret = <FILE>;
+ close FILE;
+ return ($?, @ret);
+}
+
+# Process the command line.
+my $outDir = "/etc/nixos";
+my $rootDir = ""; # = /
+my $force = 0;
+my $noFilesystems = 0;
+my $showHardwareConfig = 0;
+
+for (my $n = 0; $n < scalar @ARGV; $n++) {
+ my $arg = $ARGV[$n];
+ if ($arg eq "--help") {
+ exec "man nixos-generate-config" or die;
+ }
+ elsif ($arg eq "--dir") {
+ $n++;
+ $outDir = $ARGV[$n];
+ die "$0: ‘--dir’ requires an argument\n" unless defined $outDir;
+ }
+ elsif ($arg eq "--root") {
+ $n++;
+ $rootDir = $ARGV[$n];
+ die "$0: ‘--root’ requires an argument\n" unless defined $rootDir;
+ $rootDir =~ s/\/*$//; # remove trailing slashes
+ }
+ elsif ($arg eq "--force") {
+ $force = 1;
+ }
+ elsif ($arg eq "--no-filesystems") {
+ $noFilesystems = 1;
+ }
+ elsif ($arg eq "--show-hardware-config") {
+ $showHardwareConfig = 1;
+ }
+ else {
+ die "$0: unrecognized argument ‘$arg’\n";
+ }
+}
+
+
+my @attrs = ();
+my @kernelModules = ();
+my @initrdKernelModules = ();
+my @initrdAvailableKernelModules = ();
+my @modulePackages = ();
+my @imports;
+
+
+sub debug {
+ return unless defined $ENV{"DEBUG"};
+ print STDERR @_;
+}
+
+
+my $cpuinfo = read_file "/proc/cpuinfo";
+
+
+sub hasCPUFeature {
+ my $feature = shift;
+ return $cpuinfo =~ /^flags\s*:.* $feature( |$)/m;
+}
+
+
+
+# Determine CPU governor to use
+if (-e "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors") {
+ my $governors = read_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors");
+ # ondemand governor is not available on sandy bridge or later Intel CPUs
+ my @desired_governors = ("ondemand", "powersave");
+ my $e;
+
+ foreach $e (@desired_governors) {
+ if (index($governors, $e) != -1) {
+ last if (push @attrs, "powerManagement.cpuFreqGovernor = lib.mkDefault \"$e\";");
+ }
+ }
+}
+
+
+# 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 = read_file "$path/vendor"; chomp $vendor;
+ my $device = read_file "$path/device"; chomp $device;
+ my $class = read_file "$path/class"; chomp $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 @initrdAvailableKernelModules, $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" ||
+ $device eq "0x4331" || $device eq "0x43a0" || $device eq "0x43b1"
+ ) )
+ {
+ push @modulePackages, "config.boot.kernelPackages.broadcom_sta";
+ push @kernelModules, "wl";
+ }
+
+ # broadcom FullMac driver
+ # list taken from
+ # https://wireless.wiki.kernel.org/en/users/Drivers/brcm80211#brcmfmac
+ if ($vendor eq "0x14e4" &&
+ ($device eq "0x43a3" || $device eq "0x43df" || $device eq "0x43ec" ||
+ $device eq "0x43d3" || $device eq "0x43d9" || $device eq "0x43e9" ||
+ $device eq "0x43ba" || $device eq "0x43bb" || $device eq "0x43bc" ||
+ $device eq "0xaa52" || $device eq "0x43ca" || $device eq "0x43cb" ||
+ $device eq "0x43cc" || $device eq "0x43c3" || $device eq "0x43c4" ||
+ $device eq "0x43c5"
+ ) )
+ {
+ # we need e.g. brcmfmac43602-pcie.bin
+ push @imports, "(modulesPath + \"/hardware/network/broadcom-43xx.nix\")";
+ }
+
+ # In case this is a virtio scsi device, we need to explicitly make this available.
+ if ($vendor eq "0x1af4" && $device eq "0x1004") {
+ push @initrdAvailableKernelModules, "virtio_scsi";
+ }
+
+ # 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).
+ # FIXME: do we want to enable an unfree driver here?
+ #$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 = read_file "$path/bInterfaceClass"; chomp $class;
+ my $subclass = read_file "$path/bInterfaceSubClass"; chomp $subclass;
+ my $protocol = read_file "$path/bInterfaceProtocol"; chomp $protocol;
+
+ 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 @initrdAvailableKernelModules, $module;
+ }
+ }
+}
+
+foreach my $path (glob "/sys/bus/usb/devices/*") {
+ if (-e "$path/bInterfaceClass") {
+ usbCheck $path;
+ }
+}
+
+
+# Add the modules for all block and MMC devices.
+foreach my $path (glob "/sys/class/{block,mmc_host}/*") {
+ my $module;
+ if (-e "$path/device/driver/module") {
+ $module = basename `readlink -f $path/device/driver/module`;
+ chomp $module;
+ push @initrdAvailableKernelModules, $module;
+ }
+}
+
+# Add bcache module, if needed.
+my @bcacheDevices = glob("/dev/bcache*");
+if (scalar @bcacheDevices > 0) {
+ push @initrdAvailableKernelModules, "bcache";
+}
+
+# Prevent unbootable systems if LVM snapshots are present at boot time.
+if (`lsblk -o TYPE` =~ "lvm") {
+ push @initrdKernelModules, "dm-snapshot";
+}
+
+my $virt = `systemd-detect-virt`;
+chomp $virt;
+
+
+# Check if we're a VirtualBox guest. If so, enable the guest
+# additions.
+if ($virt eq "oracle") {
+ push @attrs, "virtualisation.virtualbox.guest.enable = true;"
+}
+
+
+# Likewise for QEMU.
+if ($virt eq "qemu" || $virt eq "kvm" || $virt eq "bochs") {
+ push @imports, "(modulesPath + \"/profiles/qemu-guest.nix\")";
+}
+
+# Also for Hyper-V.
+if ($virt eq "microsoft") {
+ push @attrs, "virtualisation.hypervGuest.enable = true;"
+}
+
+
+# Pull in NixOS configuration for containers.
+if ($virt eq "systemd-nspawn") {
+ push @attrs, "boot.isContainer = true;";
+}
+
+
+# Provide firmware for devices that are not detected by this script,
+# unless we're in a VM/container.
+push @imports, "(modulesPath + \"/installer/scan/not-detected.nix\")"
+ if $virt eq "none";
+
+
+# For a device name like /dev/sda1, find a more stable path like
+# /dev/disk/by-uuid/X or /dev/disk/by-label/Y.
+sub findStableDevPath {
+ my ($dev) = @_;
+ return $dev if substr($dev, 0, 1) ne "/";
+ return $dev unless -e $dev;
+
+ my $st = stat($dev) or return $dev;
+
+ foreach my $dev2 (glob("/dev/disk/by-uuid/*"), glob("/dev/mapper/*"), glob("/dev/disk/by-label/*")) {
+ my $st2 = stat($dev2) or next;
+ return $dev2 if $st->rdev == $st2->rdev;
+ }
+
+ return $dev;
+}
+
+push @attrs, "services.xserver.videoDrivers = [ \"$videoDriver\" ];" if $videoDriver;
+
+# Generate the swapDevices option from the currently activated swap
+# devices.
+my @swaps = read_file("/proc/swaps", err_mode => 'carp');
+my @swapDevices;
+if (@swaps) {
+ shift @swaps;
+ foreach my $swap (@swaps) {
+ my @fields = split ' ', $swap;
+ my $swapFilename = $fields[0];
+ my $swapType = $fields[1];
+ next unless -e $swapFilename;
+ my $dev = findStableDevPath $swapFilename;
+ if ($swapType =~ "partition") {
+ # zram devices are more likely created by configuration.nix, so
+ # ignore them here
+ next if ($swapFilename =~ /^\/dev\/zram/);
+ push @swapDevices, "{ device = \"$dev\"; }";
+ } elsif ($swapType =~ "file") {
+ # swap *files* are more likely specified in configuration.nix, so
+ # ignore them here.
+ } else {
+ die "Unsupported swap type: $swapType\n";
+ }
+ }
+}
+
+
+# Generate the fileSystems option from the currently mounted
+# filesystems.
+sub in {
+ my ($d1, $d2) = @_;
+ return $d1 eq $d2 || substr($d1, 0, length($d2) + 1) eq "$d2/";
+}
+
+my $fileSystems;
+my %fsByDev;
+foreach my $fs (read_file("/proc/self/mountinfo")) {
+ chomp $fs;
+ my @fields = split / /, $fs;
+ my $mountPoint = $fields[4];
+ $mountPoint =~ s/\\040/ /g; # account for mount points with spaces in the name (\040 is the escape character)
+ $mountPoint =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
+ next unless -d $mountPoint;
+ my @mountOptions = split /,/, $fields[5];
+
+ next if !in($mountPoint, $rootDir);
+ $mountPoint = substr($mountPoint, length($rootDir)); # strip the root directory (e.g. /mnt)
+ $mountPoint = "/" if $mountPoint eq "";
+
+ # Skip special filesystems.
+ next if in($mountPoint, "/proc") || in($mountPoint, "/dev") || in($mountPoint, "/sys") || in($mountPoint, "/run") || $mountPoint eq "/var/lib/nfs/rpc_pipefs";
+
+ # Skip the optional fields.
+ my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
+ my $fsType = $fields[$n];
+ my $device = $fields[$n + 1];
+ my @superOptions = split /,/, $fields[$n + 2];
+ $device =~ s/\\040/ /g; # account for devices with spaces in the name (\040 is the escape character)
+ $device =~ s/\\011/\t/g; # account for mount points with tabs in the name (\011 is the escape character)
+
+ # Skip the read-only bind-mount on /nix/store.
+ next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions) && (grep { $_ eq "ro" } @mountOptions);
+
+ # Maybe this is a bind-mount of a filesystem we saw earlier?
+ if (defined $fsByDev{$fields[2]}) {
+ # Make sure this isn't a btrfs subvolume.
+ my $msg = `btrfs subvol show $rootDir$mountPoint`;
+ if ($? != 0 || $msg =~ /ERROR:/s) {
+ my $path = $fields[3]; $path = "" if $path eq "/";
+ my $base = $fsByDev{$fields[2]};
+ $base = "" if $base eq "/";
+ $fileSystems .= <<EOF;
+ fileSystems.\"$mountPoint\" =
+ { device = \"$base$path\";
+ fsType = \"none\";
+ options = \[ \"bind\" \];
+ };
+
+EOF
+ next;
+ }
+ }
+ $fsByDev{$fields[2]} = $mountPoint;
+
+ # We don't know how to handle FUSE filesystems.
+ if ($fsType eq "fuseblk" || $fsType eq "fuse") {
+ print STDERR "warning: don't know how to emit ‘fileSystem’ option for FUSE filesystem ‘$mountPoint’\n";
+ next;
+ }
+
+ # Is this a mount of a loopback device?
+ my @extraOptions;
+ if ($device =~ /\/dev\/loop(\d+)/) {
+ my $loopnr = $1;
+ my $backer = read_file "/sys/block/loop$loopnr/loop/backing_file";
+ if (defined $backer) {
+ chomp $backer;
+ $device = $backer;
+ push @extraOptions, "loop";
+ }
+ }
+
+ # Is this a btrfs filesystem?
+ if ($fsType eq "btrfs") {
+ my ($status, @info) = runCommand("btrfs subvol show $rootDir$mountPoint");
+ if ($status != 0 || join("", @info) =~ /ERROR:/) {
+ die "Failed to retrieve subvolume info for $mountPoint\n";
+ }
+ my @ids = join("\n", @info) =~ m/^(?!\/\n).*Subvolume ID:[ \t\n]*([0-9]+)/s;
+ if ($#ids > 0) {
+ die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
+ } elsif ($#ids == 0) {
+ my @paths = join("", @info) =~ m/^([^\n]*)/;
+ if ($#paths > 0) {
+ die "Btrfs returned multiple paths for a single subvolume id, mountpoint $mountPoint\n";
+ } elsif ($#paths != 0) {
+ die "Btrfs did not return a path for the subvolume at $mountPoint\n";
+ }
+ push @extraOptions, "subvol=$paths[0]";
+ }
+ }
+
+ # Don't emit tmpfs entry for /tmp, because it most likely comes from the
+ # boot.tmpOnTmpfs option in configuration.nix (managed declaratively).
+ next if ($mountPoint eq "/tmp" && $fsType eq "tmpfs");
+
+ # Emit the filesystem.
+ $fileSystems .= <<EOF;
+ fileSystems.\"$mountPoint\" =
+ { device = \"${\(findStableDevPath $device)}\";
+ fsType = \"$fsType\";
+EOF
+
+ if (scalar @extraOptions > 0) {
+ $fileSystems .= <<EOF;
+ options = \[ ${\join " ", map { "\"" . $_ . "\"" } uniq(@extraOptions)} \];
+EOF
+ }
+
+ $fileSystems .= <<EOF;
+ };
+
+EOF
+
+ # If this filesystem is on a LUKS device, then add a
+ # boot.initrd.luks.devices entry.
+ if (-e $device) {
+ my $deviceName = basename(abs_path($device));
+ if (-e "/sys/class/block/$deviceName"
+ && read_file("/sys/class/block/$deviceName/dm/uuid", err_mode => 'quiet') =~ /^CRYPT-LUKS/)
+ {
+ my @slaves = glob("/sys/class/block/$deviceName/slaves/*");
+ if (scalar @slaves == 1) {
+ my $slave = "/dev/" . basename($slaves[0]);
+ if (-e $slave) {
+ my $dmName = read_file("/sys/class/block/$deviceName/dm/name");
+ chomp $dmName;
+ # Ensure to add an entry only once
+ my $luksDevice = " boot.initrd.luks.devices.\"$dmName\".device";
+ if ($fileSystems !~ /^\Q$luksDevice\E/m) {
+ $fileSystems .= "$luksDevice = \"${\(findStableDevPath $slave)}\";\n\n";
+ }
+ }
+ }
+ }
+ }
+}
+
+# For lack of a better way to determine it, guess whether we should use a
+# bigger font for the console from the display mode on the first
+# framebuffer. A way based on the physical size/actual DPI reported by
+# the monitor would be nice, but I don't know how to do this without X :)
+my $fb_modes_file = "/sys/class/graphics/fb0/modes";
+if (-f $fb_modes_file && -r $fb_modes_file) {
+ my $modes = read_file($fb_modes_file);
+ $modes =~ m/([0-9]+)x([0-9]+)/;
+ my $console_width = $1, my $console_height = $2;
+ if ($console_width > 1920) {
+ push @attrs, "# high-resolution display";
+ push @attrs, 'hardware.video.hidpi.enable = lib.mkDefault true;';
+ }
+}
+
+
+# Generate the hardware configuration file.
+
+sub toNixStringList {
+ my $res = "";
+ foreach my $s (@_) {
+ $res .= " \"$s\"";
+ }
+ return $res;
+}
+sub toNixList {
+ my $res = "";
+ foreach my $s (@_) {
+ $res .= " $s";
+ }
+ return $res;
+}
+
+sub multiLineList {
+ my $indent = shift;
+ return " [ ]" if !@_;
+ my $res = "\n${indent}[ ";
+ my $first = 1;
+ foreach my $s (@_) {
+ $res .= "$indent " if !$first;
+ $first = 0;
+ $res .= "$s\n";
+ }
+ $res .= "$indent]";
+ return $res;
+}
+
+my $initrdAvailableKernelModules = toNixStringList(uniq @initrdAvailableKernelModules);
+my $initrdKernelModules = toNixStringList(uniq @initrdKernelModules);
+my $kernelModules = toNixStringList(uniq @kernelModules);
+my $modulePackages = toNixList(uniq @modulePackages);
+
+my $fsAndSwap = "";
+if (!$noFilesystems) {
+ $fsAndSwap = "\n$fileSystems ";
+ $fsAndSwap .= "swapDevices =" . multiLineList(" ", @swapDevices) . ";\n";
+}
+
+my $hwConfig = <<EOF;
+# Do not modify this file! It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations. Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+ imports =${\multiLineList(" ", @imports)};
+
+ boot.initrd.availableKernelModules = [$initrdAvailableKernelModules ];
+ boot.initrd.kernelModules = [$initrdKernelModules ];
+ boot.kernelModules = [$kernelModules ];
+ boot.extraModulePackages = [$modulePackages ];
+$fsAndSwap
+${\join "", (map { " $_\n" } (uniq @attrs))}}
+EOF
+
+sub generateNetworkingDhcpConfig {
+ my $config = <<EOF;
+ # The global useDHCP flag is deprecated, therefore explicitly set to false here.
+ # Per-interface useDHCP will be mandatory in the future, so this generated config
+ # replicates the default behaviour.
+ networking.useDHCP = false;
+EOF
+
+ foreach my $path (glob "/sys/class/net/*") {
+ my $dev = basename($path);
+ if ($dev ne "lo") {
+ $config .= " networking.interfaces.$dev.useDHCP = true;\n";
+ }
+ }
+
+ return $config;
+}
+
+
+if ($showHardwareConfig) {
+ print STDOUT $hwConfig;
+} else {
+ $outDir = "$rootDir$outDir";
+
+ my $fn = "$outDir/hardware-configuration.nix";
+ print STDERR "writing $fn...\n";
+ mkpath($outDir, 0, 0755);
+ write_file($fn, $hwConfig);
+
+ # Generate a basic configuration.nix, unless one already exists.
+ $fn = "$outDir/configuration.nix";
+ if ($force || ! -e $fn) {
+ print STDERR "writing $fn...\n";
+
+ my $bootLoaderConfig = "";
+ if (-e "/sys/firmware/efi/efivars") {
+ $bootLoaderConfig = <<EOF;
+ # Use the systemd-boot EFI boot loader.
+ boot.loader.systemd-boot.enable = true;
+ boot.loader.efi.canTouchEfiVariables = true;
+EOF
+ } elsif (-e "/boot/extlinux") {
+ $bootLoaderConfig = <<EOF;
+ # Use the extlinux boot loader. (NixOS wants to enable GRUB by default)
+ boot.loader.grub.enable = false;
+ # Enables the generation of /boot/extlinux/extlinux.conf
+ boot.loader.generic-extlinux-compatible.enable = true;
+EOF
+ } elsif ($virt ne "systemd-nspawn") {
+ $bootLoaderConfig = <<EOF;
+ # Use the GRUB 2 boot loader.
+ boot.loader.grub.enable = true;
+ boot.loader.grub.version = 2;
+ # boot.loader.grub.efiSupport = true;
+ # boot.loader.grub.efiInstallAsRemovable = true;
+ # boot.loader.efi.efiSysMountPoint = "/boot/efi";
+ # Define on which hard drive you want to install Grub.
+ # boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
+EOF
+ }
+
+ my $networkingDhcpConfig = generateNetworkingDhcpConfig();
+
+ (my $desktopConfiguration = <<EOF)=~s/^/ /gm;
+@desktopConfiguration@
+EOF
+
+ write_file($fn, <<EOF);
+@configuration@
+EOF
+ print STDERR "For more hardware-specific settings, see https://github.com/NixOS/nixos-hardware.\n"
+ } else {
+ print STDERR "warning: not overwriting existing $fn\n";
+ }
+}
+
+# workaround for a bug in substituteAll
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-install.sh b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-install.sh
new file mode 100644
index 000000000000..9d49d4055e43
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-install.sh
@@ -0,0 +1,217 @@
+#! @runtimeShell@
+
+set -e
+shopt -s nullglob
+
+export PATH=@path@:$PATH
+
+# Ensure a consistent umask.
+umask 0022
+
+# Parse the command line for the -I flag
+extraBuildFlags=()
+flakeFlags=()
+
+mountPoint=/mnt
+channelPath=
+system=
+verbosity=()
+
+while [ "$#" -gt 0 ]; do
+ i="$1"; shift 1
+ case "$i" in
+ --max-jobs|-j|--cores|-I|--substituters)
+ j="$1"; shift 1
+ extraBuildFlags+=("$i" "$j")
+ ;;
+ --option)
+ j="$1"; shift 1
+ k="$1"; shift 1
+ extraBuildFlags+=("$i" "$j" "$k")
+ ;;
+ --root)
+ mountPoint="$1"; shift 1
+ ;;
+ --system|--closure)
+ system="$1"; shift 1
+ ;;
+ --flake)
+ flake="$1"
+ flakeFlags=(--experimental-features 'nix-command flakes')
+ shift 1
+ ;;
+ --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
+ lockFlags+=("$i")
+ ;;
+ --update-input)
+ j="$1"; shift 1
+ lockFlags+=("$i" "$j")
+ ;;
+ --override-input)
+ j="$1"; shift 1
+ k="$1"; shift 1
+ lockFlags+=("$i" "$j" "$k")
+ ;;
+ --channel)
+ channelPath="$1"; shift 1
+ ;;
+ --no-channel-copy)
+ noChannelCopy=1
+ ;;
+ --no-root-passwd)
+ noRootPasswd=1
+ ;;
+ --no-bootloader)
+ noBootLoader=1
+ ;;
+ --show-trace|--impure|--keep-going)
+ extraBuildFlags+=("$i")
+ ;;
+ --help)
+ exec man nixos-install
+ exit 1
+ ;;
+ --debug)
+ set -x
+ ;;
+ -v*|--verbose)
+ verbosity+=("$i")
+ ;;
+ *)
+ echo "$0: unknown option \`$i'"
+ exit 1
+ ;;
+ esac
+done
+
+if ! test -e "$mountPoint"; then
+ echo "mount point $mountPoint doesn't exist"
+ exit 1
+fi
+
+# Verify permissions are okay-enough
+checkPath="$(realpath "$mountPoint")"
+while [[ "$checkPath" != "/" ]]; do
+ mode="$(stat -c '%a' "$checkPath")"
+ if [[ "${mode: -1}" -lt "5" ]]; then
+ echo "path $checkPath should have permissions 755, but had permissions $mode. Consider running 'chmod o+rx $checkPath'."
+ exit 1
+ fi
+ checkPath="$(dirname "$checkPath")"
+done
+
+# Get the path of the NixOS configuration file.
+if [[ -z $NIXOS_CONFIG ]]; then
+ NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix
+fi
+
+if [[ ${NIXOS_CONFIG:0:1} != / ]]; then
+ echo "$0: \$NIXOS_CONFIG is not an absolute path"
+ exit 1
+fi
+
+if [[ -n $flake ]]; then
+ if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
+ flake="${BASH_REMATCH[1]}"
+ flakeAttr="${BASH_REMATCH[2]}"
+ fi
+ if [[ -z "$flakeAttr" ]]; then
+ echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri."
+ echo "For example, to use the output nixosConfigurations.foo from the flake.nix, append \"#foo\" to the flake-uri."
+ exit 1
+ fi
+ flakeAttr="nixosConfigurations.\"$flakeAttr\""
+fi
+
+# Resolve the flake.
+if [[ -n $flake ]]; then
+ flake=$(nix "${flakeFlags[@]}" flake info --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
+fi
+
+if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake ]]; then
+ echo "configuration file $NIXOS_CONFIG doesn't exist"
+ exit 1
+fi
+
+# A place to drop temporary stuff.
+tmpdir="$(mktemp -d -p "$mountPoint")"
+trap 'rm -rf $tmpdir' EXIT
+
+# store temporary files on target filesystem by default
+export TMPDIR=${TMPDIR:-$tmpdir}
+
+sub="auto?trusted=1"
+
+# Build the system configuration in the target filesystem.
+if [[ -z $system ]]; then
+ outLink="$tmpdir/system"
+ if [[ -z $flake ]]; then
+ echo "building the configuration in $NIXOS_CONFIG..."
+ nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
+ --extra-substituters "$sub" \
+ '<nixpkgs/nixos>' -A system -I "nixos-config=$NIXOS_CONFIG" "${verbosity[@]}"
+ else
+ echo "building the flake in $flake..."
+ nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" \
+ --store "$mountPoint" --extra-substituters "$sub" "${verbosity[@]}" \
+ "${extraBuildFlags[@]}" "${lockFlags[@]}" --out-link "$outLink"
+ fi
+ system=$(readlink -f "$outLink")
+fi
+
+# Set the system profile to point to the configuration. TODO: combine
+# this with the previous step once we have a nix-env replacement with
+# a progress bar.
+nix-env --store "$mountPoint" "${extraBuildFlags[@]}" \
+ --extra-substituters "$sub" \
+ -p "$mountPoint"/nix/var/nix/profiles/system --set "$system" "${verbosity[@]}"
+
+# Copy the NixOS/Nixpkgs sources to the target as the initial contents
+# of the NixOS channel.
+if [[ -z $noChannelCopy ]]; then
+ if [[ -z $channelPath ]]; then
+ channelPath="$(nix-env -p /nix/var/nix/profiles/per-user/root/channels -q nixos --no-name --out-path 2>/dev/null || echo -n "")"
+ fi
+ if [[ -n $channelPath ]]; then
+ echo "copying channel..."
+ mkdir -p "$mountPoint"/nix/var/nix/profiles/per-user/root
+ nix-env --store "$mountPoint" "${extraBuildFlags[@]}" --extra-substituters "$sub" \
+ -p "$mountPoint"/nix/var/nix/profiles/per-user/root/channels --set "$channelPath" --quiet \
+ "${verbosity[@]}"
+ install -m 0700 -d "$mountPoint"/root/.nix-defexpr
+ ln -sfn /nix/var/nix/profiles/per-user/root/channels "$mountPoint"/root/.nix-defexpr/channels
+ fi
+fi
+
+# Mark the target as a NixOS installation, otherwise switch-to-configuration will chicken out.
+mkdir -m 0755 -p "$mountPoint/etc"
+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.
+if [[ -z $noBootLoader ]]; then
+ echo "installing the boot loader..."
+ # Grub needs an mtab.
+ ln -sfn /proc/mounts "$mountPoint"/etc/mtab
+ NIXOS_INSTALL_BOOTLOADER=1 nixos-enter --root "$mountPoint" -- /run/current-system/bin/switch-to-configuration boot
+fi
+
+# Ask the user to set a root password, but only if the passwd command
+# exists (i.e. when mutable user accounts are enabled).
+if [[ -z $noRootPasswd ]] && [ -t 0 ]; then
+ if nixos-enter --root "$mountPoint" -c 'test -e /nix/var/nix/profiles/system/sw/bin/passwd'; then
+ set +e
+ nixos-enter --root "$mountPoint" -c 'echo "setting root password..." && /nix/var/nix/profiles/system/sw/bin/passwd'
+ exit_code=$?
+ set -e
+
+ if [[ $exit_code != 0 ]]; then
+ echo "Setting a root password failed with the above printed error."
+ echo "You can set the root password manually by executing \`nixos-enter --root ${mountPoint@Q}\` and then running \`passwd\` in the shell of the new system."
+ exit $exit_code
+ fi
+ fi
+fi
+
+echo "installation finished!"
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/CMakeLists.txt b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/CMakeLists.txt
new file mode 100644
index 000000000000..e5834598c4fd
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required (VERSION 2.6)
+project (nixos-option)
+
+add_executable(nixos-option nixos-option.cc libnix-copy-paste.cc)
+target_link_libraries(nixos-option PRIVATE -lnixmain -lnixexpr -lnixstore -lnixutil)
+target_compile_features(nixos-option PRIVATE cxx_std_17)
+
+install (TARGETS nixos-option DESTINATION bin)
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/default.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/default.nix
new file mode 100644
index 000000000000..753fd92c7bbf
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/default.nix
@@ -0,0 +1,11 @@
+{lib, stdenv, boost, cmake, pkgconfig, nix, ... }:
+stdenv.mkDerivation rec {
+ name = "nixos-option";
+ src = ./.;
+ nativeBuildInputs = [ cmake pkgconfig ];
+ buildInputs = [ boost nix ];
+ meta = {
+ license = stdenv.lib.licenses.lgpl2Plus;
+ maintainers = with lib.maintainers; [ chkno ];
+ };
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/libnix-copy-paste.cc b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/libnix-copy-paste.cc
new file mode 100644
index 000000000000..875c07da6399
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/libnix-copy-paste.cc
@@ -0,0 +1,83 @@
+// These are useful methods inside the nix library that ought to be exported.
+// Since they are not, copy/paste them here.
+// TODO: Delete these and use the ones in the library as they become available.
+
+#include <nix/config.h> // for nix/globals.hh's reference to SYSTEM
+
+#include "libnix-copy-paste.hh"
+#include <boost/format/alt_sstream.hpp> // for basic_altstringbuf...
+#include <boost/format/alt_sstream_impl.hpp> // for basic_altstringbuf...
+#include <boost/format/format_class.hpp> // for basic_format
+#include <boost/format/format_fwd.hpp> // for format
+#include <boost/format/format_implementation.hpp> // for basic_format::basi...
+#include <boost/optional/optional.hpp> // for get_pointer
+#include <iostream> // for operator<<, basic_...
+#include <nix/types.hh> // for Strings, Error
+#include <string> // for string, basic_string
+
+using boost::format;
+using nix::Error;
+using nix::Strings;
+using std::string;
+
+// From nix/src/libexpr/attr-path.cc
+Strings parseAttrPath(const string & s)
+{
+ Strings res;
+ string cur;
+ string::const_iterator i = s.begin();
+ while (i != s.end()) {
+ if (*i == '.') {
+ res.push_back(cur);
+ cur.clear();
+ } else if (*i == '"') {
+ ++i;
+ while (1) {
+ if (i == s.end())
+ throw Error(format("missing closing quote in selection path '%1%'") % s);
+ if (*i == '"')
+ break;
+ cur.push_back(*i++);
+ }
+ } else
+ cur.push_back(*i);
+ ++i;
+ }
+ if (!cur.empty())
+ res.push_back(cur);
+ return res;
+}
+
+// From nix/src/nix/repl.cc
+bool isVarName(const string & s)
+{
+ if (s.size() == 0)
+ return false;
+ char c = s[0];
+ if ((c >= '0' && c <= '9') || c == '-' || c == '\'')
+ return false;
+ for (auto & i : s)
+ if (!((i >= 'a' && i <= 'z') || (i >= 'A' && i <= 'Z') || (i >= '0' && i <= '9') || i == '_' || i == '-' ||
+ i == '\''))
+ return false;
+ return true;
+}
+
+// From nix/src/nix/repl.cc
+std::ostream & printStringValue(std::ostream & str, const char * string)
+{
+ str << "\"";
+ for (const char * i = string; *i; i++)
+ if (*i == '\"' || *i == '\\')
+ str << "\\" << *i;
+ else if (*i == '\n')
+ str << "\\n";
+ else if (*i == '\r')
+ str << "\\r";
+ else if (*i == '\t')
+ str << "\\t";
+ else
+ str << *i;
+ str << "\"";
+ return str;
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/libnix-copy-paste.hh b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/libnix-copy-paste.hh
new file mode 100644
index 000000000000..2274e9a0f853
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/libnix-copy-paste.hh
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <iostream>
+#include <nix/types.hh>
+#include <string>
+
+nix::Strings parseAttrPath(const std::string & s);
+bool isVarName(const std::string & s);
+std::ostream & printStringValue(std::ostream & str, const char * string);
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc
new file mode 100644
index 000000000000..f779d82edbd6
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-option/nixos-option.cc
@@ -0,0 +1,643 @@
+#include <nix/config.h> // for nix/globals.hh's reference to SYSTEM
+
+#include <exception> // for exception_ptr, current_exception
+#include <functional> // for function
+#include <iostream> // for operator<<, basic_ostream, ostrin...
+#include <iterator> // for next
+#include <list> // for _List_iterator
+#include <memory> // for allocator, unique_ptr, make_unique
+#include <new> // for operator new
+#include <nix/args.hh> // for argvToStrings, UsageError
+#include <nix/attr-path.hh> // for findAlongAttrPath
+#include <nix/attr-set.hh> // for Attr, Bindings, Bindings::iterator
+#include <nix/common-eval-args.hh> // for MixEvalArgs
+#include <nix/eval-inline.hh> // for EvalState::forceValue
+#include <nix/eval.hh> // for EvalState, initGC, operator<<
+#include <nix/globals.hh> // for initPlugins, Settings, settings
+#include <nix/nixexpr.hh> // for Pos
+#include <nix/shared.hh> // for getArg, LegacyArgs, printVersion
+#include <nix/store-api.hh> // for openStore
+#include <nix/symbol-table.hh> // for Symbol, SymbolTable
+#include <nix/types.hh> // for Error, Path, Strings, PathSet
+#include <nix/util.hh> // for absPath, baseNameOf
+#include <nix/value.hh> // for Value, Value::(anonymous), Value:...
+#include <string> // for string, operator+, operator==
+#include <utility> // for move
+#include <variant> // for get, holds_alternative, variant
+#include <vector> // for vector<>::iterator, vector
+
+#include "libnix-copy-paste.hh"
+
+using nix::absPath;
+using nix::Bindings;
+using nix::Error;
+using nix::EvalError;
+using nix::EvalState;
+using nix::Path;
+using nix::PathSet;
+using nix::Strings;
+using nix::Symbol;
+using nix::tAttrs;
+using nix::ThrownError;
+using nix::tLambda;
+using nix::tString;
+using nix::UsageError;
+using nix::Value;
+
+// An ostream wrapper to handle nested indentation
+class Out
+{
+ public:
+ class Separator
+ {};
+ const static Separator sep;
+ enum LinePolicy
+ {
+ ONE_LINE,
+ MULTI_LINE
+ };
+ explicit Out(std::ostream & ostream) : ostream(ostream), policy(ONE_LINE), writeSinceSep(true) {}
+ Out(Out & o, const std::string & start, const std::string & end, LinePolicy policy);
+ Out(Out & o, const std::string & start, const std::string & end, int count)
+ : Out(o, start, end, count < 2 ? ONE_LINE : MULTI_LINE)
+ {}
+ Out(const Out &) = delete;
+ Out(Out &&) = default;
+ Out & operator=(const Out &) = delete;
+ Out & operator=(Out &&) = delete;
+ ~Out() { ostream << end; }
+
+ private:
+ std::ostream & ostream;
+ std::string indentation;
+ std::string end;
+ LinePolicy policy;
+ bool writeSinceSep;
+ template <typename T> friend Out & operator<<(Out & o, T thing);
+};
+
+template <typename T> Out & operator<<(Out & o, T thing)
+{
+ if (!o.writeSinceSep && o.policy == Out::MULTI_LINE) {
+ o.ostream << o.indentation;
+ }
+ o.writeSinceSep = true;
+ o.ostream << thing;
+ return o;
+}
+
+template <> Out & operator<<<Out::Separator>(Out & o, Out::Separator /* thing */)
+{
+ o.ostream << (o.policy == Out::ONE_LINE ? " " : "\n");
+ o.writeSinceSep = false;
+ return o;
+}
+
+Out::Out(Out & o, const std::string & start, const std::string & end, LinePolicy policy)
+ : ostream(o.ostream), indentation(policy == ONE_LINE ? o.indentation : o.indentation + " "),
+ end(policy == ONE_LINE ? end : o.indentation + end), policy(policy), writeSinceSep(true)
+{
+ o << start;
+ *this << Out::sep;
+}
+
+// Stuff needed for evaluation
+struct Context
+{
+ Context(EvalState & state, Bindings & autoArgs, Value optionsRoot, Value configRoot)
+ : state(state), autoArgs(autoArgs), optionsRoot(optionsRoot), configRoot(configRoot),
+ underscoreType(state.symbols.create("_type"))
+ {}
+ EvalState & state;
+ Bindings & autoArgs;
+ Value optionsRoot;
+ Value configRoot;
+ Symbol underscoreType;
+};
+
+Value evaluateValue(Context & ctx, Value & v)
+{
+ ctx.state.forceValue(v);
+ if (ctx.autoArgs.empty()) {
+ return v;
+ }
+ Value called{};
+ ctx.state.autoCallFunction(ctx.autoArgs, v, called);
+ return called;
+}
+
+bool isOption(Context & ctx, const Value & v)
+{
+ if (v.type != tAttrs) {
+ return false;
+ }
+ const auto & actualType = v.attrs->find(ctx.underscoreType);
+ if (actualType == v.attrs->end()) {
+ return false;
+ }
+ try {
+ Value evaluatedType = evaluateValue(ctx, *actualType->value);
+ if (evaluatedType.type != tString) {
+ return false;
+ }
+ return static_cast<std::string>(evaluatedType.string.s) == "option";
+ } catch (Error &) {
+ return false;
+ }
+}
+
+// Add quotes to a component of a path.
+// These are needed for paths like:
+// fileSystems."/".fsType
+// systemd.units."dbus.service".text
+std::string quoteAttribute(const std::string & attribute)
+{
+ if (isVarName(attribute)) {
+ return attribute;
+ }
+ std::ostringstream buf;
+ printStringValue(buf, attribute.c_str());
+ return buf.str();
+}
+
+const std::string appendPath(const std::string & prefix, const std::string & suffix)
+{
+ if (prefix.empty()) {
+ return quoteAttribute(suffix);
+ }
+ return prefix + "." + quoteAttribute(suffix);
+}
+
+bool forbiddenRecursionName(std::string name) { return (!name.empty() && name[0] == '_') || name == "haskellPackages"; }
+
+void recurse(const std::function<bool(const std::string & path, std::variant<Value, std::exception_ptr>)> & f,
+ Context & ctx, Value v, const std::string & path)
+{
+ std::variant<Value, std::exception_ptr> evaluated;
+ try {
+ evaluated = evaluateValue(ctx, v);
+ } catch (Error &) {
+ evaluated = std::current_exception();
+ }
+ if (!f(path, evaluated)) {
+ return;
+ }
+ if (std::holds_alternative<std::exception_ptr>(evaluated)) {
+ return;
+ }
+ const Value & evaluated_value = std::get<Value>(evaluated);
+ if (evaluated_value.type != tAttrs) {
+ return;
+ }
+ for (const auto & child : evaluated_value.attrs->lexicographicOrder()) {
+ if (forbiddenRecursionName(child->name)) {
+ continue;
+ }
+ recurse(f, ctx, *child->value, appendPath(path, child->name));
+ }
+}
+
+bool optionTypeIs(Context & ctx, Value & v, const std::string & soughtType)
+{
+ try {
+ const auto & typeLookup = v.attrs->find(ctx.state.sType);
+ if (typeLookup == v.attrs->end()) {
+ return false;
+ }
+ Value type = evaluateValue(ctx, *typeLookup->value);
+ if (type.type != tAttrs) {
+ return false;
+ }
+ const auto & nameLookup = type.attrs->find(ctx.state.sName);
+ if (nameLookup == type.attrs->end()) {
+ return false;
+ }
+ Value name = evaluateValue(ctx, *nameLookup->value);
+ if (name.type != tString) {
+ return false;
+ }
+ return name.string.s == soughtType;
+ } catch (Error &) {
+ return false;
+ }
+}
+
+bool isAggregateOptionType(Context & ctx, Value & v)
+{
+ return optionTypeIs(ctx, v, "attrsOf") || optionTypeIs(ctx, v, "listOf");
+}
+
+MakeError(OptionPathError, EvalError);
+
+Value getSubOptions(Context & ctx, Value & option)
+{
+ Value getSubOptions = evaluateValue(ctx, *findAlongAttrPath(ctx.state, "type.getSubOptions", ctx.autoArgs, option));
+ if (getSubOptions.type != tLambda) {
+ throw OptionPathError("Option's type.getSubOptions isn't a function");
+ }
+ Value emptyString{};
+ nix::mkString(emptyString, "");
+ Value v;
+ ctx.state.callFunction(getSubOptions, emptyString, v, nix::Pos{});
+ return v;
+}
+
+// Carefully walk an option path, looking for sub-options when a path walks past
+// an option value.
+struct FindAlongOptionPathRet
+{
+ Value option;
+ std::string path;
+};
+FindAlongOptionPathRet findAlongOptionPath(Context & ctx, const std::string & path)
+{
+ Strings tokens = parseAttrPath(path);
+ Value v = ctx.optionsRoot;
+ std::string processedPath;
+ for (auto i = tokens.begin(); i != tokens.end(); i++) {
+ const auto & attr = *i;
+ try {
+ bool lastAttribute = std::next(i) == tokens.end();
+ v = evaluateValue(ctx, v);
+ if (attr.empty()) {
+ throw OptionPathError("empty attribute name");
+ }
+ if (isOption(ctx, v) && optionTypeIs(ctx, v, "submodule")) {
+ v = getSubOptions(ctx, v);
+ }
+ if (isOption(ctx, v) && isAggregateOptionType(ctx, v)) {
+ auto subOptions = getSubOptions(ctx, v);
+ if (lastAttribute && subOptions.attrs->empty()) {
+ break;
+ }
+ v = subOptions;
+ // Note that we've consumed attr, but didn't actually use it. This is the path component that's looked
+ // up in the list or attribute set that doesn't name an option -- the "root" in "users.users.root.name".
+ } else if (v.type != tAttrs) {
+ throw OptionPathError("Value is %s while a set was expected", showType(v));
+ } else {
+ const auto & next = v.attrs->find(ctx.state.symbols.create(attr));
+ if (next == v.attrs->end()) {
+ throw OptionPathError("Attribute not found", attr, path);
+ }
+ v = *next->value;
+ }
+ processedPath = appendPath(processedPath, attr);
+ } catch (OptionPathError & e) {
+ throw OptionPathError("At '%s' in path '%s': %s", attr, path, e.msg());
+ }
+ }
+ return {v, processedPath};
+}
+
+// Calls f on all the option names at or below the option described by `path`.
+// Note that "the option described by `path`" is not trivial -- if path describes a value inside an aggregate
+// option (such as users.users.root), the *option* described by that path is one path component shorter
+// (eg: users.users), which results in f being called on sibling-paths (eg: users.users.nixbld1). If f
+// doesn't want these, it must do its own filtering.
+void mapOptions(const std::function<void(const std::string & path)> & f, Context & ctx, const std::string & path)
+{
+ auto root = findAlongOptionPath(ctx, path);
+ recurse(
+ [f, &ctx](const std::string & path, std::variant<Value, std::exception_ptr> v) {
+ bool isOpt = std::holds_alternative<std::exception_ptr>(v) || isOption(ctx, std::get<Value>(v));
+ if (isOpt) {
+ f(path);
+ }
+ return !isOpt;
+ },
+ ctx, root.option, root.path);
+}
+
+// Calls f on all the config values inside one option.
+// Simple options have one config value inside, like sound.enable = true.
+// Compound options have multiple config values. For example, the option
+// "users.users" has about 1000 config values inside it:
+// users.users.avahi.createHome = false;
+// users.users.avahi.cryptHomeLuks = null;
+// users.users.avahi.description = "`avahi-daemon' privilege separation user";
+// ...
+// users.users.avahi.openssh.authorizedKeys.keyFiles = [ ];
+// users.users.avahi.openssh.authorizedKeys.keys = [ ];
+// ...
+// users.users.avahi.uid = 10;
+// users.users.avahi.useDefaultShell = false;
+// users.users.cups.createHome = false;
+// ...
+// users.users.cups.useDefaultShell = false;
+// users.users.gdm = ... ... ...
+// users.users.messagebus = ... .. ...
+// users.users.nixbld1 = ... .. ...
+// ...
+// users.users.systemd-timesync = ... .. ...
+void mapConfigValuesInOption(
+ const std::function<void(const std::string & path, std::variant<Value, std::exception_ptr> v)> & f,
+ const std::string & path, Context & ctx)
+{
+ Value * option;
+ try {
+ option = findAlongAttrPath(ctx.state, path, ctx.autoArgs, ctx.configRoot);
+ } catch (Error &) {
+ f(path, std::current_exception());
+ return;
+ }
+ recurse(
+ [f, ctx](const std::string & path, std::variant<Value, std::exception_ptr> v) {
+ bool leaf = std::holds_alternative<std::exception_ptr>(v) || std::get<Value>(v).type != tAttrs ||
+ ctx.state.isDerivation(std::get<Value>(v));
+ if (!leaf) {
+ return true; // Keep digging
+ }
+ f(path, v);
+ return false;
+ },
+ ctx, *option, path);
+}
+
+std::string describeError(const Error & e) { return "«error: " + e.msg() + "»"; }
+
+void describeDerivation(Context & ctx, Out & out, Value v)
+{
+ // Copy-pasted from nix/src/nix/repl.cc :(
+ Bindings::iterator i = v.attrs->find(ctx.state.sDrvPath);
+ PathSet pathset;
+ try {
+ Path drvPath = i != v.attrs->end() ? ctx.state.coerceToPath(*i->pos, *i->value, pathset) : "???";
+ out << "«derivation " << drvPath << "»";
+ } catch (Error & e) {
+ out << describeError(e);
+ }
+}
+
+Value parseAndEval(EvalState & state, const std::string & expression, const std::string & path)
+{
+ Value v{};
+ state.eval(state.parseExprFromString(expression, absPath(path)), v);
+ return v;
+}
+
+void printValue(Context & ctx, Out & out, std::variant<Value, std::exception_ptr> maybeValue, const std::string & path);
+
+void printList(Context & ctx, Out & out, Value & v)
+{
+ Out listOut(out, "[", "]", v.listSize());
+ for (unsigned int n = 0; n < v.listSize(); ++n) {
+ printValue(ctx, listOut, *v.listElems()[n], "");
+ listOut << Out::sep;
+ }
+}
+
+void printAttrs(Context & ctx, Out & out, Value & v, const std::string & path)
+{
+ Out attrsOut(out, "{", "}", v.attrs->size());
+ for (const auto & a : v.attrs->lexicographicOrder()) {
+ std::string name = a->name;
+ if (!forbiddenRecursionName(name)) {
+ attrsOut << name << " = ";
+ printValue(ctx, attrsOut, *a->value, appendPath(path, name));
+ attrsOut << ";" << Out::sep;
+ }
+ }
+}
+
+void multiLineStringEscape(Out & out, const std::string & s)
+{
+ int i;
+ for (i = 1; i < s.size(); i++) {
+ if (s[i - 1] == '$' && s[i] == '{') {
+ out << "''${";
+ i++;
+ } else if (s[i - 1] == '\'' && s[i] == '\'') {
+ out << "'''";
+ i++;
+ } else {
+ out << s[i - 1];
+ }
+ }
+ if (i == s.size()) {
+ out << s[i - 1];
+ }
+}
+
+void printMultiLineString(Out & out, const Value & v)
+{
+ std::string s = v.string.s;
+ Out strOut(out, "''", "''", Out::MULTI_LINE);
+ std::string::size_type begin = 0;
+ while (begin < s.size()) {
+ std::string::size_type end = s.find('\n', begin);
+ if (end == std::string::npos) {
+ multiLineStringEscape(strOut, s.substr(begin, s.size() - begin));
+ break;
+ }
+ multiLineStringEscape(strOut, s.substr(begin, end - begin));
+ strOut << Out::sep;
+ begin = end + 1;
+ }
+}
+
+void printValue(Context & ctx, Out & out, std::variant<Value, std::exception_ptr> maybeValue, const std::string & path)
+{
+ try {
+ if (auto ex = std::get_if<std::exception_ptr>(&maybeValue)) {
+ std::rethrow_exception(*ex);
+ }
+ Value v = evaluateValue(ctx, std::get<Value>(maybeValue));
+ if (ctx.state.isDerivation(v)) {
+ describeDerivation(ctx, out, v);
+ } else if (v.isList()) {
+ printList(ctx, out, v);
+ } else if (v.type == tAttrs) {
+ printAttrs(ctx, out, v, path);
+ } else if (v.type == tString && std::string(v.string.s).find('\n') != std::string::npos) {
+ printMultiLineString(out, v);
+ } else {
+ ctx.state.forceValueDeep(v);
+ out << v;
+ }
+ } catch (ThrownError & e) {
+ if (e.msg() == "The option `" + path + "' is used but not defined.") {
+ // 93% of errors are this, and just letting this message through would be
+ // misleading. These values may or may not actually be "used" in the
+ // config. The thing throwing the error message assumes that if anything
+ // ever looks at this value, it is a "use" of this value. But here in
+ // nixos-option, we are looking at this value only to print it.
+ // In order to avoid implying that this undefined value is actually
+ // referenced, eat the underlying error message and emit "«not defined»".
+ out << "«not defined»";
+ } else {
+ out << describeError(e);
+ }
+ } catch (Error & e) {
+ out << describeError(e);
+ }
+}
+
+void printConfigValue(Context & ctx, Out & out, const std::string & path, std::variant<Value, std::exception_ptr> v)
+{
+ out << path << " = ";
+ printValue(ctx, out, std::move(v), path);
+ out << ";\n";
+}
+
+// Replace with std::starts_with when C++20 is available
+bool starts_with(const std::string & s, const std::string & prefix)
+{
+ return s.size() >= prefix.size() &&
+ std::equal(s.begin(), std::next(s.begin(), prefix.size()), prefix.begin(), prefix.end());
+}
+
+void printRecursive(Context & ctx, Out & out, const std::string & path)
+{
+ mapOptions(
+ [&ctx, &out, &path](const std::string & optionPath) {
+ mapConfigValuesInOption(
+ [&ctx, &out, &path](const std::string & configPath, std::variant<Value, std::exception_ptr> v) {
+ if (starts_with(configPath, path)) {
+ printConfigValue(ctx, out, configPath, v);
+ }
+ },
+ optionPath, ctx);
+ },
+ ctx, path);
+}
+
+void printAttr(Context & ctx, Out & out, const std::string & path, Value & root)
+{
+ try {
+ printValue(ctx, out, *findAlongAttrPath(ctx.state, path, ctx.autoArgs, root), path);
+ } catch (Error & e) {
+ out << describeError(e);
+ }
+}
+
+bool hasExample(Context & ctx, Value & option)
+{
+ try {
+ findAlongAttrPath(ctx.state, "example", ctx.autoArgs, option);
+ return true;
+ } catch (Error &) {
+ return false;
+ }
+}
+
+void printOption(Context & ctx, Out & out, const std::string & path, Value & option)
+{
+ out << "Value:\n";
+ printAttr(ctx, out, path, ctx.configRoot);
+
+ out << "\n\nDefault:\n";
+ printAttr(ctx, out, "default", option);
+
+ out << "\n\nType:\n";
+ printAttr(ctx, out, "type.description", option);
+
+ if (hasExample(ctx, option)) {
+ out << "\n\nExample:\n";
+ printAttr(ctx, out, "example", option);
+ }
+
+ out << "\n\nDescription:\n";
+ printAttr(ctx, out, "description", option);
+
+ out << "\n\nDeclared by:\n";
+ printAttr(ctx, out, "declarations", option);
+
+ out << "\n\nDefined by:\n";
+ printAttr(ctx, out, "files", option);
+ out << "\n";
+}
+
+void printListing(Out & out, Value & v)
+{
+ out << "This attribute set contains:\n";
+ for (const auto & a : v.attrs->lexicographicOrder()) {
+ std::string name = a->name;
+ if (!name.empty() && name[0] != '_') {
+ out << name << "\n";
+ }
+ }
+}
+
+void printOne(Context & ctx, Out & out, const std::string & path)
+{
+ try {
+ auto result = findAlongOptionPath(ctx, path);
+ Value & option = result.option;
+ option = evaluateValue(ctx, option);
+ if (path != result.path) {
+ out << "Note: showing " << result.path << " instead of " << path << "\n";
+ }
+ if (isOption(ctx, option)) {
+ printOption(ctx, out, result.path, option);
+ } else {
+ printListing(out, option);
+ }
+ } catch (Error & e) {
+ std::cerr << "error: " << e.msg()
+ << "\nAn error occurred while looking for attribute names. Are "
+ "you sure that '"
+ << path << "' exists?\n";
+ }
+}
+
+int main(int argc, char ** argv)
+{
+ bool recursive = false;
+ std::string path = ".";
+ std::string optionsExpr = "(import <nixpkgs/nixos> {}).options";
+ std::string configExpr = "(import <nixpkgs/nixos> {}).config";
+ std::vector<std::string> args;
+
+ struct MyArgs : nix::LegacyArgs, nix::MixEvalArgs
+ {
+ using nix::LegacyArgs::LegacyArgs;
+ };
+
+ MyArgs myArgs(nix::baseNameOf(argv[0]), [&](Strings::iterator & arg, const Strings::iterator & end) {
+ if (*arg == "--help") {
+ nix::showManPage("nixos-option");
+ } else if (*arg == "--version") {
+ nix::printVersion("nixos-option");
+ } else if (*arg == "-r" || *arg == "--recursive") {
+ recursive = true;
+ } else if (*arg == "--path") {
+ path = nix::getArg(*arg, arg, end);
+ } else if (*arg == "--options_expr") {
+ optionsExpr = nix::getArg(*arg, arg, end);
+ } else if (*arg == "--config_expr") {
+ configExpr = nix::getArg(*arg, arg, end);
+ } else if (!arg->empty() && arg->at(0) == '-') {
+ return false;
+ } else {
+ args.push_back(*arg);
+ }
+ return true;
+ });
+
+ myArgs.parseCmdline(nix::argvToStrings(argc, argv));
+
+ nix::initPlugins();
+ nix::initGC();
+ nix::settings.readOnlyMode = true;
+ auto store = nix::openStore();
+ auto state = std::make_unique<EvalState>(myArgs.searchPath, store);
+
+ Value optionsRoot = parseAndEval(*state, optionsExpr, path);
+ Value configRoot = parseAndEval(*state, configExpr, path);
+
+ Context ctx{*state, *myArgs.getAutoArgs(*state), optionsRoot, configRoot};
+ Out out(std::cout);
+
+ auto print = recursive ? printRecursive : printOne;
+ if (args.empty()) {
+ print(ctx, out, "");
+ }
+ for (const auto & arg : args) {
+ print(ctx, out, arg);
+ }
+
+ ctx.state.printStats();
+
+ return 0;
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
new file mode 100644
index 000000000000..e452e24d263d
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -0,0 +1,506 @@
+#! @runtimeShell@
+
+if [ -x "@runtimeShell@" ]; then export SHELL="@runtimeShell@"; fi;
+
+set -e
+set -o pipefail
+
+export PATH=@path@:$PATH
+
+showSyntax() {
+ exec man nixos-rebuild
+ exit 1
+}
+
+
+# Parse the command line.
+origArgs=("$@")
+extraBuildFlags=()
+lockFlags=()
+flakeFlags=()
+action=
+buildNix=1
+fast=
+rollback=
+upgrade=
+upgrade_all=
+repair=
+profile=/nix/var/nix/profiles/system
+buildHost=
+targetHost=
+maybeSudo=()
+
+while [ "$#" -gt 0 ]; do
+ i="$1"; shift 1
+ case "$i" in
+ --help)
+ showSyntax
+ ;;
+ switch|boot|test|build|edit|dry-build|dry-run|dry-activate|build-vm|build-vm-with-bootloader)
+ if [ "$i" = dry-run ]; then i=dry-build; fi
+ action="$i"
+ ;;
+ --install-grub)
+ echo "$0: --install-grub deprecated, use --install-bootloader instead" >&2
+ export NIXOS_INSTALL_BOOTLOADER=1
+ ;;
+ --install-bootloader)
+ export NIXOS_INSTALL_BOOTLOADER=1
+ ;;
+ --no-build-nix)
+ buildNix=
+ ;;
+ --rollback)
+ rollback=1
+ ;;
+ --upgrade)
+ upgrade=1
+ ;;
+ --upgrade-all)
+ upgrade=1
+ upgrade_all=1
+ ;;
+ --repair)
+ repair=1
+ extraBuildFlags+=("$i")
+ ;;
+ --max-jobs|-j|--cores|-I|--builders)
+ j="$1"; shift 1
+ extraBuildFlags+=("$i" "$j")
+ ;;
+ --show-trace|--keep-failed|-K|--keep-going|-k|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--repair|--no-build-output|-Q|-j*|-L|--refresh|--no-net|--impure)
+ extraBuildFlags+=("$i")
+ ;;
+ --option)
+ j="$1"; shift 1
+ k="$1"; shift 1
+ extraBuildFlags+=("$i" "$j" "$k")
+ ;;
+ --fast)
+ buildNix=
+ fast=1
+ 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
+ ;;
+ --build-host|h)
+ buildHost="$1"
+ shift 1
+ ;;
+ --target-host|t)
+ targetHost="$1"
+ shift 1
+ ;;
+ --use-remote-sudo)
+ maybeSudo=(sudo --)
+ ;;
+ --flake)
+ flake="$1"
+ flakeFlags=(--experimental-features 'nix-command flakes')
+ shift 1
+ ;;
+ --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
+ lockFlags+=("$i")
+ ;;
+ --update-input)
+ j="$1"; shift 1
+ lockFlags+=("$i" "$j")
+ ;;
+ --override-input)
+ j="$1"; shift 1
+ k="$1"; shift 1
+ lockFlags+=("$i" "$j" "$k")
+ ;;
+ *)
+ echo "$0: unknown option \`$i'"
+ exit 1
+ ;;
+ esac
+done
+
+if [ -n "$SUDO_USER" ]; then
+ maybeSudo=(sudo --)
+fi
+
+if [ -z "$buildHost" -a -n "$targetHost" ]; then
+ buildHost="$targetHost"
+fi
+if [ "$targetHost" = localhost ]; then
+ targetHost=
+fi
+if [ "$buildHost" = localhost ]; then
+ buildHost=
+fi
+
+buildHostCmd() {
+ if [ -z "$buildHost" ]; then
+ "$@"
+ elif [ -n "$remoteNix" ]; then
+ ssh $SSHOPTS "$buildHost" env PATH="$remoteNix:$PATH" "${maybeSudo[@]}" "$@"
+ else
+ ssh $SSHOPTS "$buildHost" "${maybeSudo[@]}" "$@"
+ fi
+}
+
+targetHostCmd() {
+ if [ -z "$targetHost" ]; then
+ "${maybeSudo[@]}" "$@"
+ else
+ ssh $SSHOPTS "$targetHost" "${maybeSudo[@]}" "$@"
+ fi
+}
+
+copyToTarget() {
+ if ! [ "$targetHost" = "$buildHost" ]; then
+ if [ -z "$targetHost" ]; then
+ NIX_SSHOPTS=$SSHOPTS nix-copy-closure --from "$buildHost" "$1"
+ elif [ -z "$buildHost" ]; then
+ NIX_SSHOPTS=$SSHOPTS nix-copy-closure --to "$targetHost" "$1"
+ else
+ buildHostCmd nix-copy-closure --to "$targetHost" "$1"
+ fi
+ fi
+}
+
+nixBuild() {
+ if [ -z "$buildHost" ]; then
+ nix-build "$@"
+ else
+ local instArgs=()
+ local buildArgs=()
+
+ while [ "$#" -gt 0 ]; do
+ local i="$1"; shift 1
+ case "$i" in
+ -o)
+ local out="$1"; shift 1
+ buildArgs+=("--add-root" "$out" "--indirect")
+ ;;
+ -A)
+ local j="$1"; shift 1
+ instArgs+=("$i" "$j")
+ ;;
+ -I) # We don't want this in buildArgs
+ shift 1
+ ;;
+ --no-out-link) # We don't want this in buildArgs
+ ;;
+ "<"*) # nix paths
+ instArgs+=("$i")
+ ;;
+ *)
+ buildArgs+=("$i")
+ ;;
+ esac
+ done
+
+ local drv="$(nix-instantiate "${instArgs[@]}" "${extraBuildFlags[@]}")"
+ if [ -a "$drv" ]; then
+ NIX_SSHOPTS=$SSHOPTS nix-copy-closure --to "$buildHost" "$drv"
+ buildHostCmd nix-store -r "$drv" "${buildArgs[@]}"
+ else
+ echo "nix-instantiate failed"
+ exit 1
+ fi
+ fi
+}
+
+
+if [ -z "$action" ]; then showSyntax; fi
+
+# Only run shell scripts from the Nixpkgs tree if the action is
+# "switch", "boot", or "test". With other actions (such as "build"),
+# the user may reasonably expect that no code from the Nixpkgs tree is
+# executed, so it's safe to run nixos-rebuild against a potentially
+# untrusted tree.
+canRun=
+if [ "$action" = switch -o "$action" = boot -o "$action" = test ]; then
+ canRun=1
+fi
+
+
+# If ‘--upgrade’ or `--upgrade-all` is given,
+# run ‘nix-channel --update nixos’.
+if [[ -n $upgrade && -z $_NIXOS_REBUILD_REEXEC && -z $flake ]]; then
+ # If --upgrade-all is passed, or there are other channels that
+ # contain a file called ".update-on-nixos-rebuild", update them as
+ # well. Also upgrade the nixos channel.
+
+ for channelpath in /nix/var/nix/profiles/per-user/root/channels/*; do
+ channel_name=$(basename "$channelpath")
+
+ if [[ "$channel_name" == "nixos" ]]; then
+ nix-channel --update "$channel_name"
+ elif [ -e "$channelpath/.update-on-nixos-rebuild" ]; then
+ nix-channel --update "$channel_name"
+ elif [[ -n $upgrade_all ]] ; then
+ nix-channel --update "$channel_name"
+ fi
+ done
+fi
+
+# Make sure that we use the Nix package we depend on, not something
+# else from the PATH for nix-{env,instantiate,build}. This is
+# important, because NixOS defaults the architecture of the rebuilt
+# system to the architecture of the nix-* binaries used. So if on an
+# amd64 system the user has an i686 Nix package in her PATH, then we
+# would silently downgrade the whole system to be i686 NixOS on the
+# next reboot.
+if [ -z "$_NIXOS_REBUILD_REEXEC" ]; then
+ export PATH=@nix@/bin:$PATH
+fi
+
+# Use /etc/nixos/flake.nix if it exists. It can be a symlink to the
+# actual flake.
+if [[ -z $flake && -e /etc/nixos/flake.nix ]]; then
+ flake="$(dirname "$(readlink -f /etc/nixos/flake.nix)")"
+fi
+
+# Re-execute nixos-rebuild from the Nixpkgs tree.
+# FIXME: get nixos-rebuild from $flake.
+if [[ -z $_NIXOS_REBUILD_REEXEC && -n $canRun && -z $fast && -z $flake ]]; then
+ if p=$(nix-build --no-out-link --expr 'with import <nixpkgs/nixos> {}; config.system.build.nixos-rebuild' "${extraBuildFlags[@]}"); then
+ export _NIXOS_REBUILD_REEXEC=1
+ exec $p/bin/nixos-rebuild "${origArgs[@]}"
+ exit 1
+ fi
+fi
+
+# For convenience, use the hostname as the default configuration to
+# build from the flake.
+if [[ -n $flake ]]; then
+ if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
+ flake="${BASH_REMATCH[1]}"
+ flakeAttr="${BASH_REMATCH[2]}"
+ fi
+ if [[ -z $flakeAttr ]]; then
+ read -r hostname < /proc/sys/kernel/hostname
+ if [[ -z $hostname ]]; then
+ hostname=default
+ fi
+ flakeAttr="nixosConfigurations.\"$hostname\""
+ else
+ flakeAttr="nixosConfigurations.\"$flakeAttr\""
+ fi
+fi
+
+# Resolve the flake.
+if [[ -n $flake ]]; then
+ flake=$(nix "${flakeFlags[@]}" flake info --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
+fi
+
+# Find configuration.nix and open editor instead of building.
+if [ "$action" = edit ]; then
+ if [[ -z $flake ]]; then
+ NIXOS_CONFIG=${NIXOS_CONFIG:-$(nix-instantiate --find-file nixos-config)}
+ if [[ -d $NIXOS_CONFIG ]]; then
+ NIXOS_CONFIG=$NIXOS_CONFIG/default.nix
+ fi
+ exec ${EDITOR:-nano} "$NIXOS_CONFIG"
+ else
+ exec nix "${flakeFlags[@]}" edit "${lockFlags[@]}" -- "$flake#$flakeAttr"
+ fi
+ exit 1
+fi
+
+
+tmpDir=$(mktemp -t -d nixos-rebuild.XXXXXX)
+SSHOPTS="$NIX_SSHOPTS -o ControlMaster=auto -o ControlPath=$tmpDir/ssh-%n -o ControlPersist=60"
+
+cleanup() {
+ for ctrl in "$tmpDir"/ssh-*; do
+ ssh -o ControlPath="$ctrl" -O exit dummyhost 2>/dev/null || true
+ done
+ rm -rf "$tmpDir"
+}
+trap cleanup 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
+
+
+# First build Nix, since NixOS may require a newer version than the
+# current one.
+if [ -n "$rollback" -o "$action" = dry-build ]; then
+ buildNix=
+fi
+
+nixSystem() {
+ machine="$(uname -m)"
+ if [[ "$machine" =~ i.86 ]]; then
+ machine=i686
+ fi
+ echo $machine-linux
+}
+
+prebuiltNix() {
+ machine="$1"
+ if [ "$machine" = x86_64 ]; then
+ echo @nix_x86_64_linux@
+ elif [[ "$machine" =~ i.86 ]]; then
+ echo @nix_i686_linux@
+ else
+ echo "$0: unsupported platform"
+ exit 1
+ fi
+}
+
+remotePATH=
+
+if [[ -n $buildNix && -z $flake ]]; then
+ echo "building Nix..." >&2
+ nixDrv=
+ if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then
+ if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nix.drv --indirect -A nix "${extraBuildFlags[@]}")"; then
+ if ! nixStorePath="$(nix-instantiate --eval '<nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix>' -A $(nixSystem) | sed -e 's/^"//' -e 's/"$//')"; then
+ nixStorePath="$(prebuiltNix "$(uname -m)")"
+ fi
+ if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \
+ --option extra-binary-caches https://cache.nixos.org/; then
+ echo "warning: don't know how to get latest Nix" >&2
+ fi
+ # Older version of nix-store -r don't support --add-root.
+ [ -e $tmpDir/nix ] || ln -sf $nixStorePath $tmpDir/nix
+ if [ -n "$buildHost" ]; then
+ remoteNixStorePath="$(prebuiltNix "$(buildHostCmd uname -m)")"
+ remoteNix="$remoteNixStorePath/bin"
+ if ! buildHostCmd nix-store -r $remoteNixStorePath \
+ --option extra-binary-caches https://cache.nixos.org/ >/dev/null; then
+ remoteNix=
+ echo "warning: don't know how to get latest Nix" >&2
+ fi
+ fi
+ fi
+ fi
+ if [ -a "$nixDrv" ]; then
+ nix-store -r "$nixDrv"'!'"out" --add-root $tmpDir/nix --indirect >/dev/null
+ if [ -n "$buildHost" ]; then
+ nix-copy-closure --to "$buildHost" "$nixDrv"
+ # The nix build produces multiple outputs, we add them all to the remote path
+ for p in $(buildHostCmd nix-store -r "$(readlink "$nixDrv")" "${buildArgs[@]}"); do
+ remoteNix="$remoteNix${remoteNix:+:}$p/bin"
+ done
+ 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 [[ -n $canRun && -z $flake ]]; then
+ if nixpkgs=$(nix-instantiate --find-file nixpkgs "${extraBuildFlags[@]}"); then
+ suffix=$($SHELL $nixpkgs/nixos/modules/installer/tools/get-version-suffix "${extraBuildFlags[@]}" || true)
+ if [ -n "$suffix" ]; then
+ echo -n "$suffix" > "$nixpkgs/.version-suffix" || true
+ fi
+ fi
+fi
+
+
+if [ "$action" = dry-build ]; 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
+ if [[ -z $flake ]]; then
+ pathToConfig="$(nixBuild '<nixpkgs/nixos>' --no-out-link -A system "${extraBuildFlags[@]}")"
+ else
+ outLink=$tmpDir/result
+ nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" \
+ "${extraBuildFlags[@]}" "${lockFlags[@]}" --out-link $outLink
+ pathToConfig="$(readlink -f $outLink)"
+ fi
+ copyToTarget "$pathToConfig"
+ targetHostCmd nix-env -p "$profile" --set "$pathToConfig"
+ elif [ "$action" = test -o "$action" = build -o "$action" = dry-build -o "$action" = dry-activate ]; then
+ if [[ -z $flake ]]; then
+ pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A system -k "${extraBuildFlags[@]}")"
+ else
+ nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" "${extraBuildFlags[@]}" "${lockFlags[@]}"
+ pathToConfig="$(readlink -f ./result)"
+ fi
+ elif [ "$action" = build-vm ]; then
+ if [[ -z $flake ]]; then
+ pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vm -k "${extraBuildFlags[@]}")"
+ else
+ nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.vm" \
+ "${extraBuildFlags[@]}" "${lockFlags[@]}"
+ pathToConfig="$(readlink -f ./result)"
+ fi
+ elif [ "$action" = build-vm-with-bootloader ]; then
+ if [[ -z $flake ]]; then
+ pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vmWithBootLoader -k "${extraBuildFlags[@]}")"
+ else
+ nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.vmWithBootLoader" \
+ "${extraBuildFlags[@]}" "${lockFlags[@]}"
+ pathToConfig="$(readlink -f ./result)"
+ fi
+ else
+ showSyntax
+ fi
+ # Copy build to target host if we haven't already done it
+ if ! [ "$action" = switch -o "$action" = boot ]; then
+ copyToTarget "$pathToConfig"
+ fi
+else # [ -n "$rollback" ]
+ if [ "$action" = switch -o "$action" = boot ]; then
+ targetHostCmd nix-env --rollback -p "$profile"
+ pathToConfig="$profile"
+ elif [ "$action" = test -o "$action" = build ]; then
+ systemNumber=$(
+ targetHostCmd nix-env -p "$profile" --list-generations |
+ sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h'
+ )
+ pathToConfig="$profile"-${systemNumber}-link
+ if [ -z "$targetHost" ]; then
+ ln -sT "$pathToConfig" ./result
+ fi
+ 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 -o "$action" = dry-activate ]; then
+ if ! targetHostCmd $pathToConfig/bin/switch-to-configuration "$action"; then
+ echo "warning: error(s) occurred while switching to the new configuration" >&2
+ exit 1
+ fi
+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/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-version.sh b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-version.sh
new file mode 100644
index 000000000000..f5e3f32b3c63
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/nixos-version.sh
@@ -0,0 +1,23 @@
+#! @runtimeShell@
+
+case "$1" in
+ -h|--help)
+ exec man nixos-version
+ exit 1
+ ;;
+ --hash|--revision)
+ if ! [[ @revision@ =~ ^[0-9a-f]+$ ]]; then
+ echo "$0: Nixpkgs commit hash is unknown"
+ exit 1
+ fi
+ echo "@revision@"
+ ;;
+ --json)
+ cat <<EOF
+@json@
+EOF
+ ;;
+ *)
+ echo "@version@ (@codeName@)"
+ ;;
+esac
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/tools/tools.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/tools.nix
new file mode 100644
index 000000000000..0582812f92d2
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/tools/tools.nix
@@ -0,0 +1,222 @@
+# This module generates nixos-install, nixos-rebuild,
+# nixos-generate-config, etc.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ makeProg = args: pkgs.substituteAll (args // {
+ dir = "bin";
+ isExecutable = true;
+ });
+
+ nixos-build-vms = makeProg {
+ name = "nixos-build-vms";
+ src = ./nixos-build-vms/nixos-build-vms.sh;
+ inherit (pkgs) runtimeShell;
+ };
+
+ nixos-install = makeProg {
+ name = "nixos-install";
+ src = ./nixos-install.sh;
+ inherit (pkgs) runtimeShell;
+ nix = config.nix.package.out;
+ path = makeBinPath [
+ pkgs.jq
+ nixos-enter
+ ];
+ };
+
+ nixos-rebuild =
+ let fallback = import ./nix-fallback-paths.nix; in
+ makeProg {
+ name = "nixos-rebuild";
+ src = ./nixos-rebuild.sh;
+ inherit (pkgs) runtimeShell;
+ nix = config.nix.package.out;
+ nix_x86_64_linux = fallback.x86_64-linux;
+ nix_i686_linux = fallback.i686-linux;
+ path = makeBinPath [ pkgs.jq ];
+ };
+
+ nixos-generate-config = makeProg {
+ name = "nixos-generate-config";
+ src = ./nixos-generate-config.pl;
+ path = lib.optionals (lib.elem "btrfs" config.boot.supportedFilesystems) [ pkgs.btrfs-progs ];
+ perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/${pkgs.perl.libPrefix}";
+ inherit (config.system.nixos-generate-config) configuration desktopConfiguration;
+ };
+
+ nixos-option =
+ if lib.versionAtLeast (lib.getVersion pkgs.nix) "2.4pre"
+ then null
+ else pkgs.callPackage ./nixos-option { };
+
+ nixos-version = makeProg {
+ name = "nixos-version";
+ src = ./nixos-version.sh;
+ inherit (pkgs) runtimeShell;
+ inherit (config.system.nixos) version codeName revision;
+ inherit (config.system) configurationRevision;
+ json = builtins.toJSON ({
+ nixosVersion = config.system.nixos.version;
+ } // optionalAttrs (config.system.nixos.revision != null) {
+ nixpkgsRevision = config.system.nixos.revision;
+ } // optionalAttrs (config.system.configurationRevision != null) {
+ configurationRevision = config.system.configurationRevision;
+ });
+ };
+
+ nixos-enter = makeProg {
+ name = "nixos-enter";
+ src = ./nixos-enter.sh;
+ inherit (pkgs) runtimeShell;
+ };
+
+in
+
+{
+
+ options.system.nixos-generate-config = {
+ configuration = mkOption {
+ internal = true;
+ type = types.str;
+ description = ''
+ The NixOS module that <literal>nixos-generate-config</literal>
+ saves to <literal>/etc/nixos/configuration.nix</literal>.
+
+ This is an internal option. No backward compatibility is guaranteed.
+ Use at your own risk!
+
+ Note that this string gets spliced into a Perl script. The perl
+ variable <literal>$bootLoaderConfig</literal> can be used to
+ splice in the boot loader configuration.
+ '';
+ };
+
+ desktopConfiguration = mkOption {
+ internal = true;
+ type = types.str;
+ default = "";
+ description = ''
+ Text to preseed the desktop configuration that <literal>nixos-generate-config</literal>
+ saves to <literal>/etc/nixos/configuration.nix</literal>.
+
+ This is an internal option. No backward compatibility is guaranteed.
+ Use at your own risk!
+
+ Note that this string gets spliced into a Perl script. The perl
+ variable <literal>$bootLoaderConfig</literal> can be used to
+ splice in the boot loader configuration.
+ '';
+ };
+ };
+
+ config = {
+ system.nixos-generate-config.configuration = mkDefault ''
+ # Edit this configuration file to define what should be installed on
+ # your system. Help is available in the configuration.nix(5) man page
+ # and in the NixOS manual (accessible by running ‘nixos-help’).
+
+ { config, pkgs, ... }:
+
+ {
+ imports =
+ [ # Include the results of the hardware scan.
+ ./hardware-configuration.nix
+ ];
+
+ $bootLoaderConfig
+ # networking.hostName = "nixos"; # Define your hostname.
+ # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
+
+ # Set your time zone.
+ # time.timeZone = "Europe/Amsterdam";
+
+ $networkingDhcpConfig
+ # Configure network proxy if necessary
+ # networking.proxy.default = "http://user:password\@proxy:port/";
+ # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
+
+ # Select internationalisation properties.
+ # i18n.defaultLocale = "en_US.UTF-8";
+ # console = {
+ # font = "Lat2-Terminus16";
+ # keyMap = "us";
+ # };
+
+ $desktopConfiguration
+ # Configure keymap in X11
+ # services.xserver.layout = "us";
+ # services.xserver.xkbOptions = "eurosign:e";
+
+ # Enable CUPS to print documents.
+ # services.printing.enable = true;
+
+ # Enable sound.
+ # sound.enable = true;
+ # hardware.pulseaudio.enable = true;
+
+ # Enable touchpad support (enabled default in most desktopManager).
+ # services.xserver.libinput.enable = true;
+
+ # Define a user account. Don't forget to set a password with ‘passwd’.
+ # users.users.jane = {
+ # isNormalUser = true;
+ # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
+ # };
+
+ # List packages installed in system profile. To search, run:
+ # \$ nix search wget
+ # environment.systemPackages = with pkgs; [
+ # wget vim
+ # firefox
+ # ];
+
+ # Some programs need SUID wrappers, can be configured further or are
+ # started in user sessions.
+ # programs.mtr.enable = true;
+ # programs.gnupg.agent = {
+ # enable = true;
+ # enableSSHSupport = true;
+ # };
+
+ # List services that you want to enable:
+
+ # Enable the OpenSSH daemon.
+ # services.openssh.enable = true;
+
+ # Open ports in the firewall.
+ # networking.firewall.allowedTCPPorts = [ ... ];
+ # networking.firewall.allowedUDPPorts = [ ... ];
+ # Or disable the firewall altogether.
+ # networking.firewall.enable = false;
+
+ # This value determines the NixOS release from which the default
+ # settings for stateful data, like file locations and database versions
+ # on your system were taken. It‘s perfectly fine and recommended to leave
+ # this value at the release version of the first install of this system.
+ # Before changing this value read the documentation for this option
+ # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
+ system.stateVersion = "${config.system.nixos.release}"; # Did you read the comment?
+
+ }
+ '';
+
+ environment.systemPackages =
+ [ nixos-build-vms
+ nixos-install
+ nixos-rebuild
+ nixos-generate-config
+ nixos-version
+ nixos-enter
+ ] ++ lib.optional (nixos-option != null) nixos-option;
+
+ system.build = {
+ inherit nixos-install nixos-generate-config nixos-option nixos-rebuild nixos-enter;
+ };
+
+ };
+
+}
diff --git a/infra/libkookie/nixpkgs/nixos/modules/installer/virtualbox-demo.nix b/infra/libkookie/nixpkgs/nixos/modules/installer/virtualbox-demo.nix
new file mode 100644
index 000000000000..af3e1aecca71
--- /dev/null
+++ b/infra/libkookie/nixpkgs/nixos/modules/installer/virtualbox-demo.nix
@@ -0,0 +1,61 @@
+{ lib, ... }:
+
+with lib;
+
+{
+ imports =
+ [ ../virtualisation/virtualbox-image.nix
+ ../installer/cd-dvd/channel.nix
+ ../profiles/demo.nix
+ ../profiles/clone-config.nix
+ ];
+
+ # FIXME: UUID detection is currently broken
+ boot.loader.grub.fsIdentifier = "provided";
+
+ # Allow mounting of shared folders.
+ users.users.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" "modesetting" ];
+
+ powerManagement.enable = false;
+ system.stateVersion = mkDefault "18.03";
+
+ installer.cloneConfigExtra = ''
+ # Let demo build as a trusted user.
+ # nix.trustedUsers = [ "demo" ];
+
+ # Mount a VirtualBox shared folder.
+ # This is configurable in the VirtualBox menu at
+ # Machine / Settings / Shared Folders.
+ # fileSystems."/mnt" = {
+ # fsType = "vboxsf";
+ # device = "nameofdevicetomount";
+ # options = [ "rw" ];
+ # };
+
+ # By default, the NixOS VirtualBox demo image includes SDDM and Plasma.
+ # If you prefer another desktop manager or display manager, you may want
+ # to disable the default.
+ # services.xserver.desktopManager.plasma5.enable = lib.mkForce false;
+ # services.xserver.displayManager.sddm.enable = lib.mkForce false;
+
+ # Enable GDM/GNOME by uncommenting above two lines and two lines below.
+ # services.xserver.displayManager.gdm.enable = true;
+ # services.xserver.desktopManager.gnome3.enable = true;
+
+ # Set your time zone.
+ # time.timeZone = "Europe/Amsterdam";
+
+ # List packages installed in system profile. To search, run:
+ # \$ nix search wget
+ # environment.systemPackages = with pkgs; [
+ # wget vim
+ # ];
+
+ # Enable the OpenSSH daemon.
+ # services.openssh.enable = true;
+ '';
+}