Dustin Frisch
5 days ago
No known key found for this signature in database
GPG Key ID: B4C3BF012D9B26BE
24 changed files with 260 additions and 261 deletions
-
6TODO.md
-
16client/default.nix
-
2client/hardware.nix
-
5flake.nix
-
86installer/default.nix
-
19installer/installer.nix
-
28machines/installer/default.nix
-
65machines/installer/hardware.nix
-
59machines/installer/installer/default.nix
-
38machines/installer/netinstall.nix
-
1machines/installer/secrets/cache.crt
-
24machines/installer/secrets/cache.key
-
3machines/ldap/default.nix
-
2machines/nfs/cache.nix
-
2machines/nfs/default.nix
-
27machines/nfs/dhcp.nix
-
85machines/nfs/netinstaller.nix
-
24machines/nfs/secrets/cache.key
-
1machines/nfs/secrets/cache.pub
-
13shared/cache.nix
-
3shared/default.nix
-
3shared/network.nix
-
4shared/users.nix
-
1sops-config.nix
@ -0,0 +1,86 @@ |
|||||
|
{ pkgs, lib, modulesPath, config, target, ... }: |
||||
|
|
||||
|
with lib; |
||||
|
|
||||
|
let |
||||
|
installer = pkgs.callPackage ./installer.nix { inherit target; }; |
||||
|
|
||||
|
auto-installer = |
||||
|
let |
||||
|
# This removes the direct dependency from the installer to the target image. |
||||
|
# The install script is realized later during runtime using the cache. |
||||
|
# To make this work, the cache must provide the real installer script. |
||||
|
installer-path = builtins.unsafeDiscardStringContext (toString installer); |
||||
|
|
||||
|
in |
||||
|
pkgs.writers.writeBash "auto-installer" '' |
||||
|
set -o errexit |
||||
|
set -o nounset |
||||
|
set -o pipefail |
||||
|
|
||||
|
set -x |
||||
|
|
||||
|
${pkgs.retry}/bin/retry \ |
||||
|
--times 10 \ |
||||
|
--delay 15 \ |
||||
|
-- ${pkgs.nix}/bin/nix-store \ |
||||
|
--realize \ |
||||
|
--add-root /tmp/installer \ |
||||
|
"${installer-path}" |
||||
|
|
||||
|
/tmp/installer |
||||
|
|
||||
|
reboot |
||||
|
''; |
||||
|
|
||||
|
in |
||||
|
{ |
||||
|
imports = [ |
||||
|
"${modulesPath}/installer/netboot/netboot-minimal.nix" |
||||
|
|
||||
|
../shared/users.nix |
||||
|
../shared/network.nix |
||||
|
../shared/cache.nix |
||||
|
]; |
||||
|
|
||||
|
_module.args = { |
||||
|
name = "installer"; |
||||
|
}; |
||||
|
|
||||
|
networking.useDHCP = mkForce true; |
||||
|
|
||||
|
services.getty.autologinUser = lib.mkForce "root"; |
||||
|
|
||||
|
systemd.services."auto-install" = { |
||||
|
description = "Automated NixOS installer"; |
||||
|
|
||||
|
wants = [ "network-online.target" ]; |
||||
|
after = [ "network-online.target" ]; |
||||
|
|
||||
|
conflicts = [ "getty@tty1.service" ]; |
||||
|
|
||||
|
wantedBy = [ "multi-user.target" ]; |
||||
|
|
||||
|
path = with pkgs; [ bash nix ]; |
||||
|
|
||||
|
unitConfig = { |
||||
|
FailureAction = "force-reboot"; |
||||
|
}; |
||||
|
|
||||
|
serviceConfig = { |
||||
|
Type = "oneshot"; |
||||
|
|
||||
|
ExecStart = auto-installer; |
||||
|
|
||||
|
StandardInput = "none"; |
||||
|
StandardOutput = "journal+console"; |
||||
|
StandardError = "journal+console"; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
# Expose the installer script |
||||
|
system.build.installer = installer; |
||||
|
|
||||
|
system.stateVersion = config.system.nixos.release; |
||||
|
} |
||||
|
|
@ -0,0 +1,19 @@ |
|||||
|
{ writers, target, ... }: |
||||
|
|
||||
|
writers.writeBash "installer" '' |
||||
|
set -o errexit |
||||
|
set -o nounset |
||||
|
set -o pipefail |
||||
|
|
||||
|
set -x |
||||
|
|
||||
|
"${target.config.system.build.diskoScript}" |
||||
|
|
||||
|
"${target.config.system.build.nixos-install}/bin/nixos-install" \ |
||||
|
--root /mnt \ |
||||
|
--system "${target.config.system.build.toplevel}" \ |
||||
|
--no-channel-copy \ |
||||
|
--no-root-password \ |
||||
|
--verbose |
||||
|
'' |
||||
|
|
@ -1,28 +0,0 @@ |
|||||
{ |
|
||||
imports = [ |
|
||||
./hardware.nix |
|
||||
# TODO: ./cache.nix |
|
||||
# ./netinstall.nix |
|
||||
]; |
|
||||
|
|
||||
deployment = { |
|
||||
targetHost = "10.33.64.21"; |
|
||||
}; |
|
||||
|
|
||||
networking = { |
|
||||
interfaces."eth0" = { |
|
||||
ipv4.addresses = [{ |
|
||||
address = "10.33.64.21"; |
|
||||
prefixLength = 20; |
|
||||
}]; |
|
||||
}; |
|
||||
|
|
||||
defaultGateway = { |
|
||||
interface = "eth0"; |
|
||||
address = "10.33.64.1"; |
|
||||
}; |
|
||||
}; |
|
||||
|
|
||||
system.stateVersion = "24.05"; |
|
||||
} |
|
||||
|
|
@ -1,65 +0,0 @@ |
|||||
{ modulesPath, ... }: |
|
||||
|
|
||||
{ |
|
||||
imports = [ |
|
||||
"${modulesPath}/installer/scan/not-detected.nix" |
|
||||
]; |
|
||||
|
|
||||
nixpkgs.hostPlatform = "x86_64-linux"; |
|
||||
|
|
||||
boot.initrd.availableKernelModules = [ |
|
||||
"uhci_hcd" |
|
||||
"ehci_pci" |
|
||||
"ata_piix" |
|
||||
"mptsas" |
|
||||
"usb_storage" |
|
||||
"usbhid" |
|
||||
"sd_mod" |
|
||||
"sr_mod" |
|
||||
]; |
|
||||
|
|
||||
boot.loader = { |
|
||||
systemd-boot.enable = true; |
|
||||
efi.canTouchEfiVariables = true; |
|
||||
}; |
|
||||
|
|
||||
hardware.enableRedistributableFirmware = true; |
|
||||
hardware.cpu.intel.updateMicrocode = true; |
|
||||
|
|
||||
disko.devices = { |
|
||||
disk = { |
|
||||
root = { |
|
||||
type = "disk"; |
|
||||
device = "/dev/disk/by-path/pci-0000:01:00.0-scsi-0:1:0:0"; |
|
||||
imageSize = "64G"; |
|
||||
content = { |
|
||||
type = "gpt"; |
|
||||
partitions = { |
|
||||
boot = { |
|
||||
size = "1M"; |
|
||||
type = "EF02"; |
|
||||
}; |
|
||||
ESP = { |
|
||||
size = "512M"; |
|
||||
type = "EF00"; |
|
||||
content = { |
|
||||
type = "filesystem"; |
|
||||
format = "vfat"; |
|
||||
mountpoint = "/boot"; |
|
||||
}; |
|
||||
}; |
|
||||
root = { |
|
||||
size = "100%"; |
|
||||
content = { |
|
||||
type = "filesystem"; |
|
||||
format = "ext4"; |
|
||||
mountpoint = "/"; |
|
||||
}; |
|
||||
}; |
|
||||
}; |
|
||||
}; |
|
||||
}; |
|
||||
}; |
|
||||
}; |
|
||||
} |
|
||||
|
|
@ -1,59 +0,0 @@ |
|||||
{ pkgs, lib, modulesPath, config, target, ... }: |
|
||||
|
|
||||
with lib; |
|
||||
|
|
||||
let |
|
||||
installer = pkgs.writers.writeBash "installer" '' |
|
||||
set -euo pipefail |
|
||||
|
|
||||
"${target.config.system.build.diskoScript}" |
|
||||
|
|
||||
"${target.config.system.build.nixos-install}" \ |
|
||||
--root /mnt \ |
|
||||
--system "${target.config.system.build.toplevel}" \ |
|
||||
--no-channel-copy \ |
|
||||
--no-root-password \ |
|
||||
--verbose |
|
||||
|
|
||||
reboot |
|
||||
''; |
|
||||
|
|
||||
in { |
|
||||
imports = [ |
|
||||
"${modulesPath}/installer/netboot/netboot-minimal.nix" |
|
||||
]; |
|
||||
|
|
||||
networking.hostName = "installer"; |
|
||||
|
|
||||
services.getty.autologinUser = lib.mkForce "root"; |
|
||||
|
|
||||
systemd.services."auto-install" = { |
|
||||
description = "Automated NixOS installer"; |
|
||||
|
|
||||
wants = [ "network-online.target" ]; |
|
||||
after = [ "network-online.target" ]; |
|
||||
|
|
||||
conflicts = [ "getty@tty1.service" ]; |
|
||||
|
|
||||
wantedBy = [ "multi-user.target" ]; |
|
||||
|
|
||||
path = with pkgs; [ bash nix ]; |
|
||||
|
|
||||
unitConfig = { |
|
||||
FailureAction = "force-reboot"; |
|
||||
}; |
|
||||
|
|
||||
serviceConfig = { |
|
||||
Type = "oneshot"; |
|
||||
|
|
||||
ExecStart = installer; |
|
||||
|
|
||||
StandardInput = "none"; |
|
||||
StandardOutput = "journal+console"; |
|
||||
StandardError = "journal+console"; |
|
||||
}; |
|
||||
}; |
|
||||
|
|
||||
system.stateVersion = config.system.nixos.release; |
|
||||
} |
|
||||
|
|
@ -1,38 +0,0 @@ |
|||||
{ pkgs, lib, nodes, ... }: |
|
||||
|
|
||||
with lib; |
|
||||
|
|
||||
let |
|
||||
installer = pkgs.nixos [ |
|
||||
./installer |
|
||||
|
|
||||
{ |
|
||||
_module.args = { |
|
||||
target = nodes."client"; |
|
||||
}; |
|
||||
} |
|
||||
]; |
|
||||
|
|
||||
in |
|
||||
{ |
|
||||
services.pixiecore = { |
|
||||
enable = true; |
|
||||
|
|
||||
dhcpNoBind = true; |
|
||||
|
|
||||
port = 5080; |
|
||||
|
|
||||
mode = "boot"; |
|
||||
kernel = "file://${installer.config.system.build.kernel}/bzImage"; |
|
||||
initrd = "file://${installer.config.system.build.netbootRamdisk}/initrd"; |
|
||||
cmdLine = concatStringsSep " " [ |
|
||||
"init=${installer.config.system.build.toplevel}/init" |
|
||||
"loglevel=4" |
|
||||
"console=tty0" |
|
||||
"console=ttyS1,57600n8" |
|
||||
]; |
|
||||
|
|
||||
openFirewall = true; |
|
||||
}; |
|
||||
} |
|
||||
|
|
@ -1 +0,0 @@ |
|||||
cache.linuxlab.informatik.hs-fulda.de:jrTFzlS3uRzOOteHmynLmSIvFMWgb4+YH+ShcrczdEY= |
|
@ -1,24 +0,0 @@ |
|||||
{ |
|
||||
"data": "ENC[AES256_GCM,data:u2f84L2XIPqNBPKtkAU7LAwUj0wwxemsOuUB/qk/SSjutA8RLi5TmBQHnnBY/5l3u154JN9RzHsHQyMp7NHiT1gsmvrmNhdWRzLTxG7MfIJW0SVpjD7X6GLmH5vnVSLJZScRfHgdRcYl9sFO7HlT/vRAtb57ZYM+QZS5b1ZB,iv:yzwOKZA5iwrn/CkhtwF7tUytsy0lseJcBqm4UqVAsqA=,tag:WhxIH/K314fvOm81lfK6EQ==,type:str]", |
|
||||
"sops": { |
|
||||
"kms": null, |
|
||||
"gcp_kms": null, |
|
||||
"azure_kv": null, |
|
||||
"hc_vault": null, |
|
||||
"age": [ |
|
||||
{ |
|
||||
"recipient": "age1gsv9h0faztlavyw8ydl3t8p39u737jj48qvg8lrnsdkamthqaepsqegr08", |
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLVDhNSjF0amNnSWJ2ZEhq\ndnRoOXZpYk5oN09abFozK1Y0WVhDSVJ2U0RzCkw0OXhScjQwRGlDcDdnUHh2cDd3\nclBDd2RwQzRIMy9CVjZXbGFNSUdjU2cKLS0tIHBzSXdCMElkclJMU2I0WWtHbTJP\nWW5TQ2syRk9Obm5qYUtZVGZYbmtzTkEKkMiRInW2OuY6FhXTfueqokehWNxwO905\ntk5jVzyS0kVDt2Mi29Ny+HUhTpLWn2mJii8HMz698ElAxvXrHBZurQ==\n-----END AGE ENCRYPTED FILE-----\n" |
|
||||
}, |
|
||||
{ |
|
||||
"recipient": "age14lgxmyw860py9yyjz3cxkr6u0x30qra2e27c9my0sycqyfankf2sjrsse6", |
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvSHBOUUhqcHlPeTNXOE8z\nWDlNZkhSbnY5SEV5MFplWmhNVXpTaXlycHd3Ck9hY1F6LzNpWjhFdWN0SnpaT0M0\nR2R5TmRNek0wYTJUREp4YklTaVJzdXMKLS0tIDdOTWN6b2kwR1R3bzNTT2s1UFMr\nUm0yWHNkSXg5ZFR1dWhUdHRmSm13eG8Kcprh4nvmUDgI6/nntD+FTY4SsqpEAs3U\n44tvzXSNjEMp9dHIkVu45+NyKOGjZoNUAA7dEvFYAAgZqHPbLMJ0aw==\n-----END AGE ENCRYPTED FILE-----\n" |
|
||||
} |
|
||||
], |
|
||||
"lastmodified": "2024-11-11T21:50:59Z", |
|
||||
"mac": "ENC[AES256_GCM,data:n6TfbZmYcV2ER7n4fXanVJ9ekbytU07NdHVDO/VoTkERvstb1NuTeo7LjA+KVVKxM3ZUvAtMfjpAXvgP1exL4WkOzQHk5RV3odfZhGsvMOUaHp7cfww6/JrO8I+EzJWhDh2tO+xFpuD2sprvNiWT60PFG6kDQKn7XYy63+ECCyo=,iv:7ytrvXtk3Mz3ioeuv0hc80y2FLSyUWdtFyVEhidUeAI=,tag:BS8am9kxloRP+AbavEmfPA==,type:str]", |
|
||||
"pgp": null, |
|
||||
"unencrypted_suffix": "_unencrypted", |
|
||||
"version": "3.8.1" |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,85 @@ |
|||||
|
{ pkgs, lib, config, nodes, ... }: |
||||
|
|
||||
|
with lib; |
||||
|
|
||||
|
let |
||||
|
installer = pkgs.nixos [ |
||||
|
../../installer |
||||
|
|
||||
|
{ |
||||
|
_module.args = { |
||||
|
target = nodes."client"; |
||||
|
}; |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
ipxe-script = pkgs.writeText "boot-local.ipxe" '' |
||||
|
#!ipxe |
||||
|
|
||||
|
sleep 2 |
||||
|
|
||||
|
prompt --key 0x18 --timeout 5000 Press Ctrl-X to re-deploy system... || goto local |
||||
|
|
||||
|
echo "Starting installer..." |
||||
|
sleep 2 |
||||
|
|
||||
|
kernel --name kernel http://''${next-server:ipv4}/bzImage || goto err |
||||
|
initrd --name initrd http://''${next-server:ipv4}/initrd || goto err |
||||
|
|
||||
|
boot kernel initrd=initrd init=${installer.config.system.build.toplevel}/init loglevel=4 || goto err |
||||
|
|
||||
|
:err |
||||
|
shell |
||||
|
|
||||
|
:local |
||||
|
echo "Booting local disk..." |
||||
|
sleep 2 |
||||
|
|
||||
|
sanboot -n -d 0x80 |
||||
|
''; |
||||
|
|
||||
|
in |
||||
|
{ |
||||
|
services.nginx = { |
||||
|
enable = true; |
||||
|
|
||||
|
virtualHosts."boot.${config.networking.domain}" = { |
||||
|
locations."/" = { |
||||
|
root = pkgs.linkFarm "root" { |
||||
|
"bzImage" = installer.config.system.build.kernel + "/bzImage"; |
||||
|
"initrd" = installer.config.system.build.netbootRamdisk + "/initrd"; |
||||
|
}; |
||||
|
}; |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
services.pixiecore = |
||||
|
{ |
||||
|
enable = true; |
||||
|
debug = true; |
||||
|
|
||||
|
dhcpNoBind = true; |
||||
|
|
||||
|
port = 5080; |
||||
|
|
||||
|
mode = "boot"; |
||||
|
kernel = toString ipxe-script; |
||||
|
|
||||
|
openFirewall = true; |
||||
|
}; |
||||
|
|
||||
|
# Ensure the intaller script and therefore the client system is part of the |
||||
|
# store so it can be fetched by the installer. |
||||
|
boot.postBootCommands = '' |
||||
|
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/installer --set "${installer.installer}" |
||||
|
''; |
||||
|
|
||||
|
networking.extraHosts = '' |
||||
|
127.0.0.1 boot.${config.networking.domain} |
||||
|
''; |
||||
|
|
||||
|
networking.firewall.allowedTCPPorts = [ |
||||
|
80 # HTTP |
||||
|
]; |
||||
|
} |
||||
|
|
@ -0,0 +1,24 @@ |
|||||
|
{ |
||||
|
"data": "ENC[AES256_GCM,data:BNxKj72aiPMNMsiZf8GjGG1L1TLMHoENAfnaic1LqyYZa2zZq7eWm7BNps2Iz9sP4voQbp9GB7/kvZ1iS3g8B8xb6r4QrylAgPHGcb/nXQb7xvUVM5glRCtC0mgyPSqbnzWz3bObgVR+fTlDGX5Ckt3lt4WWK6Pg90TG1FUK,iv:LFL8p6vAzgS8KyAu0LVX+op72UdhXyLMbU98PZ+fSus=,tag:5LWxdkS9d0kCFXJfZJ5tRw==,type:str]", |
||||
|
"sops": { |
||||
|
"kms": null, |
||||
|
"gcp_kms": null, |
||||
|
"azure_kv": null, |
||||
|
"hc_vault": null, |
||||
|
"age": [ |
||||
|
{ |
||||
|
"recipient": "age1gsv9h0faztlavyw8ydl3t8p39u737jj48qvg8lrnsdkamthqaepsqegr08", |
||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2NUNFQWc3Z1NON3hRaW5B\nYlhkbllSTVlRUi9jS1lGTDZmVkRsYjJqMXpBCjZYak1OQ3ltT1hVMWp2Tis4Rklv\nK2E1MVN2OU9wUFp4c2RpdkZsMjVybUEKLS0tIFdidWp0TUE0RzBXd2l1L1lQYTVw\nWEJES29mRk1aSmtqeHJEWWNDV0d4L00K4nW0rBP4Rl+uDj+E0bq7MyuyDzKSsGRB\n0dtzqaEu+HHbRqne6MOU0+oh0bpln5vJhkSKdlD7bBIEOX3/AWwHdg==\n-----END AGE ENCRYPTED FILE-----\n" |
||||
|
}, |
||||
|
{ |
||||
|
"recipient": "age1kjjve9m33a5fads6ttc0kznmv0mn0cxladrk7nv8huhp8u2pw4vqyzuf2p", |
||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzZi9maENnTjFhU2k1S3RJ\nUGFpbkc1d3BNNFEyQWlPdW9SK0VjR1ZYaG4wCnJvamNZL3p2MWFQOGlqVTgvbXRw\nMHdGU3V0SmE5NkQydGVaYzVEMmxyUGcKLS0tIGkyTWVpd2xFYmJKVGRzNk1KV3BU\ndVFza01xTnBXYnF2dnhUekN4QWpZaWcKcuBiZAZPXjxUgnRGGWz9FMhODMaNwlV+\nwVP5j7gL8VX1HvTLUU0lGyNA/st+KoAnugMKabW5TYRiyQyACIlO/w==\n-----END AGE ENCRYPTED FILE-----\n" |
||||
|
} |
||||
|
], |
||||
|
"lastmodified": "2024-11-14T18:01:59Z", |
||||
|
"mac": "ENC[AES256_GCM,data:TanGp5W9pmtO0x7yjKiyqPPIetoxrEldVSi0h/0JD6liZ/9G1gTU0miDYhOn0j2C8n/QoXVxjWWFfX/JNVC+Lt4rUrGCJDCo1gpMRHxym4VyCYiiEGgCh0D5IiNYSKLkIs/3JPYDAm+CrOcX4XjbcLMYiZkvWVcV+gh2s8vtXcE=,iv:XO8/adw+hQ3Z/8icJTvv4ct78qPsxS0mJQC2veLtDvk=,tag:e2DS3nieE+BsUUTx9C3Xmw==,type:str]", |
||||
|
"pgp": null, |
||||
|
"unencrypted_suffix": "_unencrypted", |
||||
|
"version": "3.8.1" |
||||
|
} |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
cache.linuxlab.informatik.hs-fulda.de:ugWyeMyNqHvSEXDVgcPZ5NCniqq0wqKQCb3rjqXb/jU= |
@ -0,0 +1,13 @@ |
|||||
|
{ config, ... }: |
||||
|
|
||||
|
{ |
||||
|
nix.settings = { |
||||
|
substituters = [ |
||||
|
"http://cache.${config.networking.domain}" |
||||
|
]; |
||||
|
|
||||
|
trusted-public-keys = [ |
||||
|
"cache.${config.networking.domain}:ugWyeMyNqHvSEXDVgcPZ5NCniqq0wqKQCb3rjqXb/jU=" |
||||
|
]; |
||||
|
}; |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue