From 470d1918ab6fbd67b540565b1723d4de9f22554d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sun, 7 May 2023 21:06:12 +0200 Subject: [PATCH] kexec-installer: build variants --- build-images.sh | 2 +- flake.nix | 20 +++- nix/kexec-installer/module.nix | 195 +++++++++++++++++---------------- 3 files changed, 120 insertions(+), 97 deletions(-) diff --git a/build-images.sh b/build-images.sh index d839870..2f77f52 100755 --- a/build-images.sh +++ b/build-images.sh @@ -22,7 +22,7 @@ build_netboot_image() { build_kexec_installer() { declare -r tag=$1 arch=$2 tmp=$3 variant=$4 out=$(nix build --print-out-paths --option accept-flake-config true -L ".#packages.${arch}.kexec-installer-${tag//.}${variant}") - echo "$out/nixos-kexec-installer-$arch.tar.gz" + echo "$out/nixos-kexec-installer${variant}-$arch.tar.gz" } main() { diff --git a/flake.nix b/flake.nix index 236464a..4811391 100644 --- a/flake.nix +++ b/flake.nix @@ -24,11 +24,23 @@ kexec-installer-nixos-unstable = kexec-installer nixos-unstable []; kexec-installer-nixos-2211 = kexec-installer nixos-2211 []; - kexec-installer-nixos-unstable-noninteractive = kexec-installer nixos-unstable [ self.nixosModules.noninteractive ]; - kexec-installer-nixos-2211-noninteractive = kexec-installer nixos-2211 [ self.nixosModules.noninteractive ]; + kexec-installer-nixos-unstable-noninteractive = kexec-installer nixos-unstable [ + { system.kexec-installer.name = "kexec-installer-noninteractive"; } + self.nixosModules.noninteractive + ]; + kexec-installer-nixos-2211-noninteractive = kexec-installer nixos-2211 [ + { system.kexec-installer.name = "kexec-installer-noninteractive"; } + self.nixosModules.noninteractive + ]; - kexec-installer-nixos-unstable-virtual-noninteractive = kexec-installer nixos-unstable [ self.nixosModules.noninteractive self.nixosModules.virtual ]; - kexec-installer-nixos-2211-virtual-noninteractive = kexec-installer nixos-2211 [ self.nixosModules.noninteractive self.nixosModules.virtual ]; + kexec-installer-nixos-unstable-virtual-noninteractive = kexec-installer nixos-unstable [ + { system.kexec-installer.name = "kexec-installer-virtual-noninteractive"; } + self.nixosModules.noninteractive self.nixosModules.virtual + ]; + kexec-installer-nixos-2211-virtual-noninteractive = kexec-installer nixos-2211 [ + { system.kexec-installer.name = "kexec-installer-virtual-noninteractive"; } + self.nixosModules.noninteractive self.nixosModules.virtual + ]; }); nixosModules = { kexec-installer = ./nix/kexec-installer/module.nix; diff --git a/nix/kexec-installer/module.nix b/nix/kexec-installer/module.nix index 494f1ba..df2a7d7 100644 --- a/nix/kexec-installer/module.nix +++ b/nix/kexec-installer/module.nix @@ -10,104 +10,115 @@ in { imports = [ (modulesPath + "/installer/netboot/netboot-minimal.nix") ]; - - # We are stateless, so just default to latest. - system.stateVersion = config.system.nixos.version; - - # This is a variant of the upstream kexecScript that also allows embedding - # a ssh key. - system.build.kexecRun = pkgs.runCommand "kexec-run" {} '' - install -D -m 0755 ${./kexec-run.sh} $out - - sed -i \ - -e 's|@init@|${config.system.build.toplevel}/init|' \ - -e 's|@kernelParams@|${lib.escapeShellArgs config.boot.kernelParams}|' \ - $out - - ${pkgs.shellcheck}/bin/shellcheck $out - ''; - - 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 - cp "${config.system.build.kexecRun}" kexec/run - cp "${pkgs.pkgsStatic.kexec-tools}/bin/kexec" kexec/kexec - cp "${iprouteStatic}/bin/ip" kexec/ip - tar -czvf $out/nixos-kexec-installer-${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" ]; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStart = [ - "${restore-network} /root/network/addrs.json /root/network/routes-v4.json /root/network/routes-v6.json /etc/systemd/network" - ]; + options = { + system.kexec-installer.name = lib.mkOption { + type = lib.types.str; + default = "nixos-kexec-installer"; + description = '' + The variant of the kexec installer to use. + ''; }; + }; - unitConfig.ConditionPathExists = [ - "/root/network/addrs.json" - "/root/network/routes-v4.json" - "/root/network/routes-v6.json" + config = { + # We are stateless, so just default to latest. + system.stateVersion = config.system.nixos.version; + + # This is a variant of the upstream kexecScript that also allows embedding + # a ssh key. + system.build.kexecRun = pkgs.runCommand "kexec-run" {} '' + install -D -m 0755 ${./kexec-run.sh} $out + + sed -i \ + -e 's|@init@|${config.system.build.toplevel}/init|' \ + -e 's|@kernelParams@|${lib.escapeShellArgs config.boot.kernelParams}|' \ + $out + + ${pkgs.shellcheck}/bin/shellcheck $out + ''; + + 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 + cp "${config.system.build.kexecRun}" kexec/run + cp "${pkgs.pkgsStatic.kexec-tools}/bin/kexec" kexec/kexec + cp "${iprouteStatic}/bin/ip" kexec/ip + 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.log-network-status = { - wantedBy = [ "multi-user.target" ]; - # No point in restarting this. We just need this after boot - restartIfChanged = false; + systemd.services.restore-network = { + before = [ "network-pre.target" ]; + wants = [ "network-pre.target" ]; + wantedBy = [ "multi-user.target" ]; - 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" + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = [ + "${restore-network} /root/network/addrs.json /root/network/routes-v4.json /root/network/routes-v6.json /etc/systemd/network" + ]; + }; + + unitConfig.ConditionPathExists = [ + "/root/network/addrs.json" + "/root/network/routes-v4.json" + "/root/network/routes-v6.json" ]; }; - }; - # 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/ - ''; + 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/ + ''; + }; }