From 9089946fc0f14f272c65e72746df52b91cf36ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Mon, 15 May 2023 14:54:05 +0200 Subject: [PATCH 1/2] move out code from kexec-installer into its own module --- nix/installer.nix | 56 +++++++++++++++++++++++++++ nix/kexec-installer/module.nix | 70 ++++------------------------------ 2 files changed, 63 insertions(+), 63 deletions(-) create mode 100644 nix/installer.nix diff --git a/nix/installer.nix b/nix/installer.nix new file mode 100644 index 0000000..e95222b --- /dev/null +++ b/nix/installer.nix @@ -0,0 +1,56 @@ +{ config, lib, pkgs, ... }: { + # We are stateless, so just default to latest. + system.stateVersion = config.system.nixos.version; + + # use latest kernel we can support to get more hardware support + boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages; + + # IPMI SOL console redirection stuff + boot.kernelParams = + [ "console=tty0" ] ++ + (lib.optional (pkgs.stdenv.hostPlatform.isAarch32 || pkgs.stdenv.hostPlatform.isAarch64) "console=ttyAMA0,115200") ++ + (lib.optional (pkgs.stdenv.hostPlatform.isRiscV) "console=ttySIF0,115200") ++ + [ "console=ttyS0,115200" ]; + + documentation.enable = false; + # Not really needed. Saves a few bytes and the only service we are running is sshd, which we want to be reachable. + networking.firewall.enable = false; + + systemd.network.enable = true; + networking.dhcpcd.enable = false; + + # for zapping of disko + environment.systemPackages = [ pkgs.jq ]; + + systemd.services.log-network-status = { + wantedBy = [ "multi-user.target" ]; + # No point in restarting this. We just need this after boot + restartIfChanged = false; + + serviceConfig = { + Type = "oneshot"; + StandardOutput = "journal+console"; + ExecStart = [ + # Allow failures, so it still prints what interfaces we have even if we + # not get online + "-${pkgs.systemd}/lib/systemd/systemd-networkd-wait-online" + "${pkgs.iproute2}/bin/ip -c addr" + "${pkgs.iproute2}/bin/ip -c -6 route" + "${pkgs.iproute2}/bin/ip -c -4 route" + ]; + }; + }; + + # Restore ssh host and user keys if they are available. + # This avoids warnings of unknown ssh keys. + boot.initrd.postMountCommands = '' + mkdir -m 700 -p /mnt-root/root/.ssh + mkdir -m 755 -p /mnt-root/etc/ssh + mkdir -m 755 -p /mnt-root/root/network + if [[ -f ssh/authorized_keys ]]; then + install -m 400 ssh/authorized_keys /mnt-root/root/.ssh + fi + install -m 400 ssh/ssh_host_* /mnt-root/etc/ssh + cp *.json /mnt-root/root/network/ + ''; +} diff --git a/nix/kexec-installer/module.nix b/nix/kexec-installer/module.nix index 98f11bb..61c56b2 100644 --- a/nix/kexec-installer/module.nix +++ b/nix/kexec-installer/module.nix @@ -1,14 +1,15 @@ { config, lib, modulesPath, pkgs, ... }: let - restore-network = pkgs.writers.writePython3 "restore-network" { - flakeIgnore = ["E501"]; - } ./restore_routes.py; + restore-network = pkgs.writers.writePython3 "restore-network" { flakeIgnore = [ "E501" ]; } + ./restore_routes.py; # does not link with iptables enabled iprouteStatic = pkgs.pkgsStatic.iproute2.override { iptables = null; }; -in { +in +{ imports = [ (modulesPath + "/installer/netboot/netboot-minimal.nix") + ../installer.nix ]; options = { system.kexec-installer.name = lib.mkOption { @@ -21,15 +22,9 @@ in { }; config = { - # We are stateless, so just default to latest. - system.stateVersion = config.system.nixos.version; - - # use latest kernel we can support to get more hardware support - boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages; - # This is a variant of the upstream kexecScript that also allows embedding # a ssh key. - system.build.kexecRun = pkgs.runCommand "kexec-run" {} '' + system.build.kexecRun = pkgs.runCommand "kexec-run" { } '' install -D -m 0755 ${./kexec-run.sh} $out sed -i \ @@ -40,7 +35,7 @@ in { ${pkgs.shellcheck}/bin/shellcheck $out ''; - system.build.kexecTarball = pkgs.runCommand "kexec-tarball" {} '' + system.build.kexecTarball = pkgs.runCommand "kexec-tarball" { } '' mkdir kexec $out cp "${config.system.build.netbootRamdisk}/initrd" kexec/initrd cp "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}" kexec/bzImage @@ -54,28 +49,9 @@ in { tar -czvf $out/${config.system.kexec-installer.name}-${pkgs.stdenv.hostPlatform.system}.tar.gz kexec ''; - # IPMI SOL console redirection stuff - boot.kernelParams = - [ "console=tty0" ] ++ - (lib.optional (pkgs.stdenv.hostPlatform.isAarch32 || pkgs.stdenv.hostPlatform.isAarch64) "console=ttyAMA0,115200") ++ - (lib.optional (pkgs.stdenv.hostPlatform.isRiscV) "console=ttySIF0,115200") ++ - [ "console=ttyS0,115200" ]; - - documentation.enable = false; - # Not really needed. Saves a few bytes and the only service we are running is sshd, which we want to be reachable. - networking.firewall.enable = false; - - systemd.network.enable = true; - networking.dhcpcd.enable = false; - # for detection if we are on kexec environment.etc.is_kexec.text = "true"; - # for zapping of disko - environment.systemPackages = [ - pkgs.jq - ]; - systemd.services.restore-network = { before = [ "network-pre.target" ]; wants = [ "network-pre.target" ]; @@ -95,37 +71,5 @@ in { "/root/network/routes-v6.json" ]; }; - - systemd.services.log-network-status = { - wantedBy = [ "multi-user.target" ]; - # No point in restarting this. We just need this after boot - restartIfChanged = false; - - serviceConfig = { - Type = "oneshot"; - StandardOutput = "journal+console"; - ExecStart = [ - # Allow failures, so it still prints what interfaces we have even if we - # not get online - "-${pkgs.systemd}/lib/systemd/systemd-networkd-wait-online" - "${pkgs.iproute2}/bin/ip -c addr" - "${pkgs.iproute2}/bin/ip -c -6 route" - "${pkgs.iproute2}/bin/ip -c -4 route" - ]; - }; - }; - - # Restore ssh host and user keys if they are available. - # This avoids warnings of unknown ssh keys. - boot.initrd.postMountCommands = '' - mkdir -m 700 -p /mnt-root/root/.ssh - mkdir -m 755 -p /mnt-root/etc/ssh - mkdir -m 755 -p /mnt-root/root/network - if [[ -f ssh/authorized_keys ]]; then - install -m 400 ssh/authorized_keys /mnt-root/root/.ssh - fi - install -m 400 ssh/ssh_host_* /mnt-root/etc/ssh - cp *.json /mnt-root/root/network/ - ''; }; } From 25f782b4ce9c7e08f55e1785b0b840bcd48c357e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sun, 14 May 2023 20:59:46 +0200 Subject: [PATCH 2/2] add netboot-installer-nixos-unstable --- flake.lock | 35 ++++++++++++++++++ flake.nix | 9 ++++- nix/netboot-installer/installer.nix | 0 nix/netboot-installer/module.nix | 55 +++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 nix/netboot-installer/installer.nix create mode 100644 nix/netboot-installer/module.nix diff --git a/flake.lock b/flake.lock index badd496..404d8c1 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,23 @@ { "nodes": { + "disko": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1683508929, + "narHash": "sha256-AqkIrwewCL8+zlkqhNxheF+kOfyakzZDk43SqRTIqRE=", + "owner": "nix-community", + "repo": "disko", + "rev": "2a59f5cf641607dbecb0cfec3ae32247e4aeb311", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, "nixos-2211": { "locked": { "lastModified": 1684141842, @@ -32,8 +50,25 @@ "type": "github" } }, + "nixpkgs": { + "locked": { + "lastModified": 1683442750, + "narHash": "sha256-IiJ0WWW6OcCrVFl1ijE+gTaP0ChFfV6dNkJR05yStmw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eb751d65225ec53de9cf3d88acbf08d275882389", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { + "disko": "disko", "nixos-2211": "nixos-2211", "nixos-unstable": "nixos-unstable" } diff --git a/flake.nix b/flake.nix index b5595bc..68c27b9 100644 --- a/flake.nix +++ b/flake.nix @@ -3,6 +3,7 @@ inputs.nixos-unstable.url = "github:NixOS/nixpkgs/nixos-unstable-small"; inputs.nixos-2211.url = "github:NixOS/nixpkgs/release-22.11"; + inputs.disko.url = "github:nix-community/disko"; nixConfig.extra-substituters = [ "https://cache.garnix.io" @@ -11,13 +12,14 @@ "cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g=" ]; - outputs = { self, nixos-unstable, nixos-2211 }: let + outputs = { self, nixos-unstable, nixos-2211, disko }: let supportedSystems = [ "aarch64-linux" "x86_64-linux" ]; forAllSystems = nixos-unstable.lib.genAttrs supportedSystems; in { packages = forAllSystems (system: let netboot = nixpkgs: (import (nixpkgs + "/nixos/release.nix") {}).netboot.${system}; kexec-installer = nixpkgs: modules: (nixpkgs.legacyPackages.${system}.nixos (modules ++ [self.nixosModules.kexec-installer])).config.system.build.kexecTarball; + netboot-installer = nixpkgs: (nixpkgs.legacyPackages.${system}.nixos [self.nixosModules.netboot-installer]).config.system.build.netboot; in { netboot-nixos-unstable = netboot nixos-unstable; netboot-nixos-2211 = netboot nixos-2211; @@ -32,10 +34,15 @@ { system.kexec-installer.name = "nixos-kexec-installer-noninteractive"; } self.nixosModules.noninteractive ]; + + netboot-installer-nixos-unstable = netboot-installer nixos-unstable; + netboot-installer-nixos-2211 = netboot-installer nixos-2211; }); nixosModules = { kexec-installer = ./nix/kexec-installer/module.nix; noninteractive = ./nix/noninteractive.nix; + # TODO: also add a test here once we have https://github.com/NixOS/nixpkgs/pull/228346 merged + netboot-installer = ./nix/netboot-installer/module.nix; }; checks.x86_64-linux = let pkgs = nixos-unstable.legacyPackages.x86_64-linux; diff --git a/nix/netboot-installer/installer.nix b/nix/netboot-installer/installer.nix new file mode 100644 index 0000000..e69de29 diff --git a/nix/netboot-installer/module.nix b/nix/netboot-installer/module.nix new file mode 100644 index 0000000..cbc60b5 --- /dev/null +++ b/nix/netboot-installer/module.nix @@ -0,0 +1,55 @@ +{ config, lib, modulesPath, pkgs, ... }: +{ + imports = [ + (modulesPath + "/installer/netboot/netboot-minimal.nix") + ../installer.nix + ]; + + # We are stateless, so just default to latest. + system.stateVersion = config.system.nixos.version; + + system.build.netboot = pkgs.symlinkJoin { + name = "netboot"; + paths = with config.system.build; [ + netbootRamdisk + kernel + (pkgs.runCommand "kernel-params" {} '' + mkdir -p $out + ln -s "${config.system.build.toplevel}/kernel-params" $out/kernel-params + ln -s "${config.system.build.toplevel}/init" $out/init + '') + ]; + preferLocalBuild = true; + }; + systemd.network.networks."10-uplink" = { + matchConfig.Type = "ether"; + networkConfig = { + DHCP = "yes"; + LLMNR = "yes"; + EmitLLDP = "yes"; + IPv6AcceptRA = "no"; + MulticastDNS = "yes"; + LinkLocalAddressing = "yes"; + LLDP = "yes"; + }; + + dhcpV4Config = { + UseHostname = false; + ClientIdentifier = "mac"; + }; + }; + + networking.hostName = ""; + # overrides normal activation script for setting hostname + system.activationScripts.hostname = lib.mkForce '' + # apply hostname from cmdline + for o in $(< /proc/cmdline); do + case $o in + hostname=*) + IFS== read -r -a hostParam <<< "$o" + ;; + esac + done + hostname "''${hostParam[1]:-nixos}" + ''; +}