diff --git a/flake.lock b/flake.lock index f3cc6b0..57e55aa 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": 1681932375, @@ -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 b62f6e0..e6f24e8 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; @@ -27,15 +29,22 @@ kexec-installer-nixos-unstable-noninteractive = kexec-installer nixos-unstable [ { system.kexec-installer.name = "nixos-kexec-installer-noninteractive"; } self.nixosModules.noninteractive + ({pkgs, ...}: { + boot.kernelPackages = disko.legacyPackages.${pkgs.hostPlatform.system}.linuxPackages_bcachefs; + }) ]; kexec-installer-nixos-2211-noninteractive = kexec-installer nixos-2211 [ { 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; + 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/module.nix b/nix/netboot-installer/module.nix new file mode 100644 index 0000000..7da7650 --- /dev/null +++ b/nix/netboot-installer/module.nix @@ -0,0 +1,102 @@ +{ config, lib, modulesPath, pkgs, ... }: +{ + imports = [ + (modulesPath + "/installer/netboot/netboot-minimal.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; + }; + + # 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; + + 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"; + }; + }; + + # 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" + ]; + }; + }; + 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}" + ''; + + boot.initrd.postMountCommands = '' + # add user keys if they are available. + 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 + ''; +}