{ description = "A very basic flake"; inputs = { deploy-rs = { url = "github:serokell/deploy-rs"; inputs.nixpkgs.follows = "nixpkgs"; }; sd-images = { url = "git+https://git.asonix.dog/asonix/sd-images?ref=asonix/nabam-sd-image"; inputs.nixpkgsUnstable.follows = "nixpkgs"; }; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; sops-nix = { url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, deploy-rs, sd-images, nixpkgs, sops-nix }: let sharedModule = import ./modules/shared; btrbkModule = import ./modules/btrbk; dockerModule = import ./modules/docker; subvolumesModule = import ./modules/subvolumes; k3sModule = import ./modules/k3s; networkModule = import ./modules/network; wireguardModule = import ./modules/wireguard; desktopModule = import ./modules/desktop; serverModule = import ./modules/server; routerModule = import ./modules/router; makeConfig = { hostname, extraModules ? [ ] }: nixpkgs.lib.nixosSystem { system = "aarch64-linux"; modules = [ sops-nix.nixosModules.sops sharedModule { networking.hostName = hostname; } ] ++ extraModules; }; makeServerConfig = { hostname, extraModules ? [ ] }: makeConfig { inherit hostname; extraModules = [ (serverModule) ] ++ extraModules; }; makeDesktopConfig = { hostname, extraModules ? [ ] }: makeConfig { inherit hostname; extraModules = [ (desktopModule) ] ++ extraModules; }; makeGenericK3sConfig = { hostname, enableK3s ? true, serverIp ? null, extraModules ? [ ] }: makeServerConfig { inherit hostname; extraModules = [ (if serverIp == null then k3sModule.server { enable = enableK3s; } else k3sModule.agent { inherit serverIp; enable = enableK3s; }) ({ config, pkgs, ... }: { services.lvm.enable = true; services.rpcbind.enable = true; environment.systemPackages = with pkgs; [ nfs-utils ]; }) ] ++ extraModules; }; makeBoardK3sConfig = modules: { hostname, macAddress ? null, enableK3s ? true, selfIp, selfIp6, serverIp }: makeGenericK3sConfig { inherit hostname enableK3s serverIp; extraModules = [ (networkModule { inherit macAddress selfIp selfIp6; }) ] ++ modules; }; makeRock64K3sConfig = system: makeBoardK3sConfig sd-images.packages.${system}.Rock64.modules; makeRockPro64K3sConfig = system: makeBoardK3sConfig sd-images.packages.${system}.RockPro64v2.modules; makeQuartz64AK3sConfig = system: makeBoardK3sConfig sd-images.packages.${system}.Quartz64A.modules; makeOldSoQuartzK3sConfig = system: { hostname , enableK3s ? true , unlockMounts ? true , mountVolumes ? true , selfIp , selfIp6 , serverIp ? null }: let device = "/dev/mapper/cryptdrive1"; device2 = "/dev/mapper/cryptdrive2"; subvolumes = [ "@k3s-config" ]; subvolumes2 = [ "@exports" "@garage" ]; in makeGenericK3sConfig { inherit hostname serverIp; enableK3s = unlockMounts && mountVolumes && enableK3s; extraModules = sd-images.packages.${system}.SoQuartzBlade.modules ++ [ (networkModule { inherit selfIp selfIp6; }) (btrbkModule { instances = [ { inherit subvolumes; mountDir = "/btrfs/nvme"; primaryIp = serverIp; } { subvolumes = subvolumes2; mountDir = "/btrfs/nvme2"; name = "nvme2"; } ]; }) (if unlockMounts && mountVolumes then (subvolumesModule { inherit device subvolumes; }) else { }) ({ config, lib, pkgs, ... }: let keyFilePath = config.sops.secrets.k3sKeyFile.path; prepareNvme = '' #!/usr/bin/env bash set -e echo "Creating two partitions" fdisk -w always /dev/nvme0n1 << EOL g n 1 +50G n 2 w EOL echo "configure first part" echo "YES" | cryptsetup luksFormat /dev/nvme0n1p1 -d ${keyFilePath} cryptsetup luksOpen /dev/nvme0n1p1 cryptdrive1 -d ${keyFilePath} mkfs.btrfs /dev/mapper/cryptdrive1 mkdir -p /btrfs/nvme mount /dev/mapper/cryptdrive1 /btrfs/nvme btrfs subvolume create /btrfs/nvme/@k3s-config btrfs subvolume create /btrfs/nvme/@snapshots btrfs subvolume create /btrfs/nvme/@var-lib-rancher btrfs subvolume create /btrfs/nvme/@var-log-pods umount /btrfs/nvme cryptsetup luksClose cryptdrive1 echo "configure second part" echo "YES" | cryptsetup luksFormat /dev/nvme0n1p2 -d ${keyFilePath} cryptsetup luksOpen /dev/nvme0n1p2 cryptdrive2 -d ${keyFilePath} mkfs.btrfs /dev/mapper/cryptdrive2 mkdir -p /btrfs/nvme2 mount /dev/mapper/cryptdrive2 /btrfs/nvme2 btrfs subvolume create /btrfs/nvme2/@exports btrfs subvolume create /btrfs/nvme2/@garage btrfs subvolume create /btrfs/nvme2/@snapshots umount /btrfs/nvme2 cryptsetup luksClose cryptdrive2 ''; in { sops.secrets.k3sKeyFile = { format = "binary"; sopsFile = ./secrets/k3sKeyFile.bin; }; environment.systemPackages = with pkgs; [ (writeShellScriptBin "prepare-nvme" prepareNvme) ]; environment.etc.crypttab = { enable = unlockMounts; text = '' cryptdrive1 /dev/nvme0n1p1 ${keyFilePath} luks cryptdrive2 /dev/nvme0n1p2 ${keyFilePath} luks ''; }; fileSystems = let defaultOptions = [ "defaults" "rw" "compress=zstd" ]; fileSystemConfig = { "/btrfs/nvme" = { inherit device; fsType = "btrfs"; options = defaultOptions; }; "/btrfs/nvme2" = { device = device2; fsType = "btrfs"; options = defaultOptions; }; "/exports" = { device = device2; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@exports" ]; }; "/garage" = { device = device2; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@garage" ]; }; "/var/lib/rancher" = { inherit device; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@var-lib-rancher" ]; }; "/var/log/pods" = { inherit device; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@var-log-pods" ]; }; }; in if unlockMounts && mountVolumes then fileSystemConfig else { }; services.nfs.server = { enable = unlockMounts && mountVolumes; exports = '' /exports 192.168.20.0/24(rw,sync,fsid=0,no_subtree_check) /exports/k3s 192.168.20.0/24(rw,nohide,insecure,sync,no_subtree_check,no_root_squash) ''; }; }) ]; }; makeSoQuartzK3sConfig = system: { hostname , enableK3s ? true , unlockMounts ? true , mountVolumes ? true , selfIp , selfIp6 , serverIp ? null }: let device = "/dev/mapper/cryptdrive1"; subvolumes = [ "@k3s-config" ]; subvolumes2 = [ "@exports" "@garage" ]; in makeGenericK3sConfig { inherit hostname serverIp; enableK3s = unlockMounts && mountVolumes && enableK3s; extraModules = sd-images.packages.${system}.SoQuartzBlade.modules ++ [ (networkModule { inherit selfIp selfIp6; }) (btrbkModule { instances = [ { inherit subvolumes; mountDir = "/btrfs/nvme"; primaryIp = serverIp; } { subvolumes = subvolumes2; mountDir = "/btrfs/nvme"; name = "nvme"; } ]; }) (if unlockMounts && mountVolumes then (subvolumesModule { inherit device subvolumes; }) else { }) ({ config, lib, pkgs, ... }: let keyFilePath = config.sops.secrets.k3sKeyFile.path; prepareNvme = '' #!/usr/bin/env bash set -e fallocate -l 8G /swapfile chmod 0600 /swapfile mkswap /swapfile echo "YES" | cryptsetup luksFormat /dev/nvme0n1 -d ${keyFilePath} cryptsetup luksOpen /dev/nvme0n1 cryptdrive1 -d ${keyFilePath} mkfs.btrfs /dev/mapper/cryptdrive1 mkdir -p /btrfs/nvme mount /dev/mapper/cryptdrive1 /btrfs/nvme btrfs subvolume create /btrfs/nvme/@exports btrfs subvolume create /btrfs/nvme/@garage btrfs subvolume create /btrfs/nvme/@k3s-config btrfs subvolume create /btrfs/nvme/@snapshots btrfs subvolume create /btrfs/nvme/@swap btrfs subvolume create /btrfs/nvme/@var-lib-rancher btrfs subvolume create /btrfs/nvme/@var-log-pods umount /btrfs/nvme cryptsetup luksClose cryptdrive1 ''; in { sops.secrets.k3sKeyFile = { format = "binary"; sopsFile = ./secrets/k3sKeyFile.bin; }; environment.systemPackages = with pkgs; [ (writeShellScriptBin "prepare-nvme" prepareNvme) ]; environment.etc.crypttab = { enable = unlockMounts; text = '' cryptdrive1 /dev/nvme0n1 ${keyFilePath} luks ''; }; fileSystems = let defaultOptions = [ "defaults" "rw" "compress=zstd" ]; fileSystemConfig = { "/btrfs/nvme" = { inherit device; fsType = "btrfs"; options = defaultOptions; }; "/exports" = { device = device; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@exports" ]; }; "/garage" = { device = device; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@garage" ]; }; "/swap" = { inherit device; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@swap" ]; }; "/var/lib/rancher" = { inherit device; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@var-lib-rancher" ]; }; "/var/log/pods" = { inherit device; fsType = "btrfs"; options = defaultOptions ++ [ "subvol=@var-log-pods" ]; }; }; in if unlockMounts && mountVolumes then fileSystemConfig else { }; swapDevices = let swapFile = { device = "/swapfile"; size = (1024 * 8); }; in if unlockMounts && mountVolumes then [ swapFile ] else [ ]; services.nfs.server = { enable = unlockMounts && mountVolumes; exports = '' /exports 192.168.20.0/24(rw,sync,fsid=0,no_subtree_check) /exports/k3s 192.168.20.0/24(rw,nohide,insecure,sync,no_subtree_check,no_root_squash) ''; }; }) ]; }; makeBuildConfig = system: { hostname, macAddress ? null, selfIp, selfIp6 }: let device = "/btrfs.4G"; mountDir = "/btrfs/loop"; subvolumes = [ "@build-cfg" ]; in makeServerConfig { inherit hostname; extraModules = sd-images.packages.${system}.RockPro64v2.modules ++ [ dockerModule (networkModule { inherit macAddress selfIp selfIp6; }) (btrbkModule { instances = [{ inherit mountDir subvolumes; }]; }) (subvolumesModule { inherit device subvolumes; }) ({ lib, ... }: { fileSystems = { "${mountDir}" = { inherit device; fsType = "btrfs"; options = [ "defaults" "compress=zstd" "rw" "loop" ]; }; }; }) ]; }; makeRouterConfig = system: { hostName, wireguardPrivateKey }: makeServerConfig { hostname = hostName; extraModules = sd-images.packages.${system}.RockPro64v2.modules ++ [ (routerModule { inherit hostName wireguardPrivateKey; }) ]; }; makeBoardBackupConfig = modules: system: { hostname , selfIp , selfIp6 , unlockMounts ? true , mountVolumes ? true , enableBackups ? true , backupHosts ? [ ] }: let deviceLabel = "RAID"; device = "/dev/disk/by-label/${deviceLabel}"; mountDir = "/btrfs/raid"; in makeServerConfig { inherit hostname; extraModules = modules ++ [ (networkModule { inherit selfIp selfIp6; }) (btrbkModule { instances = backupHosts; localMountDir = mountDir; enabled = unlockMounts && mountVolumes && enableBackups; }) ({ config, lib, pkgs, ... }: let keyFile = "backupKeyFile"; keyFilePath = config.sops.secrets."${keyFile}".path; dryRun = '' for conf in $(ls /etc/btrbk); do btrbk -c /etc/btrbk/$conf dryrun done ''; prepareDrives = '' for drive in "$1" "$2"; do if [ "$drive" == "" ]; then echo "Must provide 2 drives" exit 1 fi done drive_num=1 for drive in "$1" "$2"; do echo "YES" | cryptsetup luksFormat $drive -d ${keyFilePath} --label="DATA$drive_num" cryptsetup luksOpen "$drive" "cryptdrive$drive_num" -d ${keyFilePath} drive_num=$((drive_num+1)) done mkfs.btrfs -L ${deviceLabel} -d raid1 /dev/mapper/cryptdrive1 /dev/mapper/cryptdrive2 mkdir -p ${mountDir} mount ${device} ${mountDir} btrfs subvolume create ${mountDir}/@snapshots umount ${mountDir} for drive_num in {1..2}; do cryptsetup luksClose "cryptdrive$drive_num" done ''; in { sops.secrets."${keyFile}" = { format = "binary"; sopsFile = ./secrets/${keyFile}.bin; }; environment.systemPackages = with pkgs; [ (writeShellScriptBin "prepare-drives" prepareDrives) (writeShellScriptBin "btrbk-dryrun" dryRun) ]; environment.etc.crypttab = { enable = unlockMounts; text = '' cryptdrive1 /dev/disk/by-label/DATA1 ${keyFilePath} luks cryptdrive2 /dev/disk/by-label/DATA2 ${keyFilePath} luks ''; }; fileSystems = let filesystemConfig = { "${mountDir}" = { inherit device; fsType = "btrfs"; options = [ "defaults" "compress=zstd" "rw" ]; }; }; in if unlockMounts && mountVolumes then filesystemConfig else { }; }) ]; }; makeRockPro64BackupConfig = makeBoardBackupConfig sd-images.packages.${system}.RockPro64v2.modules; makeQuartz64ABackupConfig = makeBoardBackupConfig sd-images.packages.${system}.Quartz64A.modules; makeJellyfinConfig = system: { hostname, selfIp, selfIp6, macAddress ? null, unlockMounts ? true, mountVolumes ? true, enableJellyfin ? true }: let deviceLabel = "RAID"; device = "/dev/disk/by-label/${deviceLabel}"; mountDir = "/btrfs/raid"; subvolumes = [ "@jellyfin" ]; in makeServerConfig { inherit hostname; extraModules = sd-images.packages.${system}.RockPro64v2.modules ++ [ (networkModule { inherit macAddress selfIp selfIp6; }) (if unlockMounts && mountVolumes then (btrbkModule { instances = [{ inherit mountDir subvolumes; name = "jellyfin"; }]; }) else { }) ({ config, lib, pkgs, ... }: let keyFile = "jellyfinKeyFile"; keyFilePath = config.sops.secrets."${keyFile}".path; dryRun = '' for conf in $(ls /etc/btrbk); do btrbk -c /etc/btrbk/$conf dryrun done ''; prepareDrives = '' for drive in "$1" "$2"; do if [ "$drive" == "" ]; then echo "Must provide 2 drives" exit 1 fi done drive_num=1 for drive in "$1" "$2"; do echo "YES" | cryptsetup luksFormat $drive -d ${keyFilePath} --label="DATA$drive_num" cryptsetup luksOpen "$drive" "cryptdrive$drive_num" -d ${keyFilePath} drive_num=$((drive_num+1)) done mkfs.btrfs -L ${deviceLabel} -d raid1 /dev/mapper/cryptdrive1 /dev/mapper/cryptdrive2 mkdir -p ${mountDir} mount ${device} ${mountDir} btrfs subvolume create ${mountDir}/@jellyfin-library btrfs subvolume create ${mountDir}/@jellyfin-state btrfs subvolume create ${mountDir}/@snapshots umount ${mountDir} for drive_num in {1..2}; do cryptsetup luksClose "cryptdrive$drive_num" done mkdir -p /storage/jellyfin mkdir -p /var/lib/jellyfin ''; in { sops.secrets."${keyFile}" = { format = "binary"; sopsFile = ./secrets/${keyFile}.bin; }; environment.systemPackages = with pkgs; [ (writeShellScriptBin "prepare-drives" prepareDrives) (writeShellScriptBin "btrbk-dryrun" dryRun) ]; environment.etc.crypttab = { enable = unlockMounts; text = '' cryptdrive1 /dev/disk/by-label/DATA1 ${keyFilePath} luks cryptdrive2 /dev/disk/by-label/DATA2 ${keyFilePath} luks ''; }; fileSystems = let filesystemConfig = { "${mountDir}" = { inherit device; fsType = "btrfs"; options = [ "defaults" "compress=zstd" "rw" ]; }; "/storage/jellyfin" = { inherit device; fsType = "btrfs"; options = [ "defaults" "compress=zstd" "rw" "subvol=@jellyfin-library" ]; }; "/var/lib/jellyfin" = { inherit device; fsType = "btrfs"; options = [ "defaults" "compress=zstd" "rw" "subvol=@jellyfin-state" ]; }; }; in if unlockMounts && mountVolumes then filesystemConfig else { }; }) (if unlockMounts && mountVolumes && enableJellyfin then { services.jellyfin = { enable = true; openFirewall = true; }; users.users.asonix.extraGroups = [ "jellyfin" ]; } else { }) ]; }; makePostgresConfig = system: { hostname, selfIp, selfIp6, macAddress, keyFile, primaryIp ? null, unlockMounts ? true, mountVolumes ? true, luksDevice ? "/dev/sda1" }: let device = "/dev/mapper/cryptdrive1"; mountDir = "/btrfs/ssd"; subvolumes = [ "@postgres" "@postgres-cfg" ]; in makeServerConfig { inherit hostname; extraModules = sd-images.packages.${system}.Rock64.modules ++ [ dockerModule (networkModule { inherit macAddress selfIp selfIp6; }) (if unlockMounts && mountVolumes then (btrbkModule { instances = [{ inherit mountDir primaryIp subvolumes; }]; }) else { }) (if primaryIp == null && unlockMounts && mountVolumes then (subvolumesModule { inherit device subvolumes; }) else { }) ({ config, lib, pkgs, ... }: let keyFilePath = config.sops.secrets.${keyFile}.path; prepareSsd = '' #!/usr/bin/env bash set -e DEVICE=$1 if [ "$DEVICE" == "" ]; then echo "Must provide device" exit 1 fi echo "YES" | cryptsetup luksFormat "$DEVICE" -d ${keyFilePath} --label=LUKS_SSD cryptsetup luksOpen "$DEVICE" cryptdrive1 -d ${keyFilePath} mkfs.btrfs /dev/mapper/cryptdrive1 mkdir -p ${mountDir} mount /dev/mapper/cryptdrive1 ${mountDir} btrfs subvolume create ${mountDir}/@postgres btrfs subvolume create ${mountDir}/@postgres-cfg btrfs subvolume create ${mountDir}/@snapshots umount ${mountDir} cryptsetup luksClose cryptdrive1 ''; in { sops.secrets.${keyFile} = { format = "binary"; sopsFile = ./secrets/${keyFile}.bin; }; environment.systemPackages = with pkgs; [ (writeShellScriptBin "prepare-ssd" prepareSsd) ]; environment.etc.crypttab = { enable = unlockMounts; text = '' cryptdrive1 ${luksDevice} ${keyFilePath} luks ''; }; fileSystems = if unlockMounts && mountVolumes then { "${mountDir}" = { inherit device; fsType = "btrfs"; options = [ "defaults" "compress=zstd" "rw" ]; }; } else { }; }) ]; }; system = "x86_64-linux"; in { nixosConfigurations = { redtail1 = makePostgresConfig system { hostname = "redtail1"; selfIp = "192.168.20.23"; selfIp6 = "2001:db8:20::23"; macAddress = "02:fe:30:d8:cf:64"; keyFile = "redtailKeyFile"; primaryIp = "192.168.20.24"; luksDevice = "/dev/disk/by-label/LUKS_SSD"; }; redtail2 = makePostgresConfig system { hostname = "redtail2"; selfIp = "192.168.20.24"; selfIp6 = "2001:db8:20::24"; macAddress = "02:8a:70:2a:a8:5e"; keyFile = "redtailKeyFile"; # primaryIp = "192.168.20.23"; }; whitestorm1 = makePostgresConfig system { hostname = "whitestorm1"; selfIp = "192.168.20.26"; selfIp6 = "2001:db8:20::26"; macAddress = "02:71:18:30:fc:0f"; keyFile = "whitestormKeyFile"; # primaryIp = "192.168.20.27"; }; whitestorm2 = makePostgresConfig system { hostname = "whitestorm2"; selfIp = "192.168.20.27"; selfIp6 = "2001:db8:20::27"; macAddress = "02:ff:ce:a9:d3:74"; keyFile = "whitestormKeyFile"; # primaryIp = "192.168.20.26"; }; build2 = makeBuildConfig system { hostname = "build2"; selfIp = "192.168.20.101"; selfIp6 = "2001:db8:20::101"; }; k3s1 = makeOldSoQuartzK3sConfig system { hostname = "k3s1"; selfIp = "192.168.20.120"; selfIp6 = "2001:db8:20::120"; }; k3s2 = makeOldSoQuartzK3sConfig system { hostname = "k3s2"; selfIp = "192.168.20.121"; selfIp6 = "2001:db8:20::121"; serverIp = "192.168.20.120"; }; k3s3 = makeOldSoQuartzK3sConfig system { hostname = "k3s3"; selfIp = "192.168.20.122"; selfIp6 = "2001:db8:20::122"; serverIp = "192.168.20.120"; }; k3s4 = makeOldSoQuartzK3sConfig system { hostname = "k3s4"; selfIp = "192.168.20.123"; selfIp6 = "2001:db8:20::123"; serverIp = "192.168.20.120"; }; k3s5 = makeOldSoQuartzK3sConfig system { hostname = "k3s5"; selfIp = "192.168.20.124"; selfIp6 = "2001:db8:20::124"; serverIp = "192.168.20.120"; }; k3s6 = makeSoQuartzK3sConfig system { hostname = "k3s6"; selfIp = "192.168.20.125"; selfIp6 = "2001:db8:20::125"; serverIp = "192.168.20.120"; }; k3s7 = makeSoQuartzK3sConfig system { hostname = "k3s7"; selfIp = "192.168.20.126"; selfIp6 = "2001:db8:20::126"; serverIp = "192.168.20.120"; }; k3s8 = makeSoQuartzK3sConfig system { hostname = "k3s8"; selfIp = "192.168.20.127"; selfIp6 = "2001:db8:20::127"; serverIp = "192.168.20.120"; }; k3s9 = makeSoQuartzK3sConfig system { hostname = "k3s9"; selfIp = "192.168.20.128"; selfIp6 = "2001:db8:20::128"; serverIp = "192.168.20.120"; }; k3s10 = makeSoQuartzK3sConfig system { hostname = "k3s10"; selfIp = "192.168.20.129"; selfIp6 = "2001:db8:20::129"; serverIp = "192.168.20.120"; }; k3s11 = makeSoQuartzK3sConfig system { hostname = "k3s11"; selfIp = "192.168.20.130"; selfIp6 = "2001:db8:20::130"; serverIp = "192.168.20.120"; }; k3s12 = makeSoQuartzK3sConfig system { hostname = "k3s12"; selfIp = "192.168.20.131"; selfIp6 = "2001:db8:20::131"; serverIp = "192.168.20.120"; }; k3s13 = makeSoQuartzK3sConfig system { hostname = "k3s13"; selfIp = "192.168.20.132"; selfIp6 = "2001:db8:20::132"; serverIp = "192.168.20.120"; }; k3s14 = makeSoQuartzK3sConfig system { hostname = "k3s14"; selfIp = "192.168.20.133"; selfIp6 = "2001:db8:20::133"; serverIp = "192.168.20.120"; }; k3s15 = makeSoQuartzK3sConfig system { hostname = "k3s15"; selfIp = "192.168.20.134"; selfIp6 = "2001:db8:20::134"; serverIp = "192.168.20.120"; }; k3s16 = makeSoQuartzK3sConfig system { hostname = "k3s16"; selfIp = "192.168.20.135"; selfIp6 = "2001:db8:20::135"; serverIp = "192.168.20.120"; }; k3s-rock1 = makeRock64K3sConfig system { hostname = "k3s-rock1"; selfIp = "192.168.20.110"; selfIp6 = "2001:db8:20::110"; serverIp = "192.168.20.120"; macAddress = "02:36:51:19:8c:5d"; }; k3s-rock2 = makeRock64K3sConfig system { hostname = "k3s-rock2"; selfIp = "192.168.20.111"; selfIp6 = "2001:db8:20::111"; serverIp = "192.168.20.120"; macAddress = "02:af:fa:0e:c5:41"; }; k3s-rock3 = makeRock64K3sConfig system { hostname = "k3s-rock3"; selfIp = "192.168.20.112"; selfIp6 = "2001:db8:20::112"; serverIp = "192.168.20.120"; macAddress = "02:86:c1:62:77:51"; }; k3s-rock4 = makeRock64K3sConfig system { hostname = "k3s-rock4"; selfIp = "192.168.20.113"; selfIp6 = "2001:db8:20::113"; serverIp = "192.168.20.120"; macAddress = "02:7a:2e:2c:bb:99"; }; k3s-rock5 = makeRock64K3sConfig system { hostname = "k3s-rock5"; selfIp = "192.168.20.114"; selfIp6 = "2001:db8:20::114"; serverIp = "192.168.20.120"; macAddress = "02:76:67:0f:a0:b7"; }; k3s-rock6 = makeRock64K3sConfig system { hostname = "k3s-rock6"; selfIp = "192.168.20.115"; selfIp6 = "2001:db8:20::115"; serverIp = "192.168.20.120"; macAddress = "02:6b:c5:f0:d7:6d"; }; k3s-rock7 = makeRock64K3sConfig system { hostname = "k3s-rock7"; selfIp = "192.168.20.116"; selfIp6 = "2001:db8:20::116"; serverIp = "192.168.20.120"; macAddress = "02:5b:c4:cf:25:c2"; }; k3s-quartza1 = makeQuartz64AK3sConfig system { hostname = "k3s-quartza1"; selfIp = "192.168.20.160"; selfIp6 = "2001:db8:20::160"; serverIp = "192.168.20.120"; }; k3s-rockpro1 = makeRockPro64K3sConfig system { hostname = "k3s-rockpro1"; selfIp = "192.168.20.180"; selfIp6 = "2001:db8:20::180"; serverIp = "192.168.20.120"; }; jellyfin = makeJellyfinConfig system { hostname = "jellyfin"; selfIp = "192.168.20.195"; selfIp6 = "2001:db8:20::195"; }; pinetab2 = makeDesktopConfig { hostname = "pinetab2"; extraModules = sd-images.packages.${system}.PineTab2.modules; }; backup1 = let k3sMain = { ip, name }: { inherit name; primaryIp = ip; mountDir = "/btrfs/nvme"; subvolumes = [ "@k3s-config" ]; }; k3sOld = { ip, name }: { inherit name; primaryIp = ip; mountDir = "/btrfs/nvme2"; subvolumes = [ "@garage" ]; }; k3s = { ip, name }: { inherit name; primaryIp = ip; mountDir = "/btrfs/nvme"; subvolumes = [ "@garage" ]; }; db = { ip, name }: { inherit name; primaryIp = ip; mountDir = "/btrfs/ssd"; subvolumes = [ "@postgres" "@postgres-cfg" ]; }; in makeQuartz64ABackupConfig system { hostname = "backup1"; selfIp = "192.168.20.190"; selfIp6 = "2001:db8:20::190"; backupHosts = [ (k3sMain { ip = "192.168.20.120"; name = "k3s1-config"; }) ] ++ (builtins.map k3sOld [ { ip = "192.168.20.120"; name = "k3s1"; } { ip = "192.168.20.121"; name = "k3s2"; } { ip = "192.168.20.122"; name = "k3s3"; } { ip = "192.168.20.123"; name = "k3s4"; } { ip = "192.168.20.124"; name = "k3s5"; } ]) ++ (builtins.map k3s [ { ip = "192.168.20.125"; name = "k3s6"; } { ip = "192.168.20.126"; name = "k3s7"; } { ip = "192.168.20.127"; name = "k3s8"; } { ip = "192.168.20.128"; name = "k3s9"; } { ip = "192.168.20.129"; name = "k3s10"; } { ip = "192.168.20.130"; name = "k3s11"; } { ip = "192.168.20.131"; name = "k3s12"; } { ip = "192.168.20.132"; name = "k3s13"; } { ip = "192.168.20.133"; name = "k3s14"; } { ip = "192.168.20.134"; name = "k3s15"; } { ip = "192.168.20.135"; name = "k3s16"; } ]) ++ (builtins.map db [ { ip = "192.168.20.26"; name = "whitestorm1"; } { ip = "192.168.20.24"; name = "redtail2"; } ]); }; backup2 = let k3sOld = { ip, name }: { inherit name; primaryIp = ip; mountDir = "/btrfs/nvme2"; subvolumes = [ "@exports" ]; }; k3s = { ip, name }: { inherit name; primaryIp = ip; mountDir = "/btrfs/nvme"; subvolumes = [ "@exports" ]; }; db = { ip, name }: { inherit name; primaryIp = ip; mountDir = "/btrfs/ssd"; subvolumes = [ "@postgres" "@postgres-cfg" ]; }; firestar = { name, subvolumes }: { name = "firestar-${name}"; primaryIp = "192.168.5.10"; mountDir = "/btrfs/${name}"; inherit subvolumes; }; graystripe = { name = "graystripe"; primaryIp = "192.168.5.9"; mountDir = "/btrfs/nvme"; subvolumes = [ "@" "@root" "@home" ]; }; in makeRockPro64BackupConfig system { hostname = "backup2"; selfIp = "192.168.20.191"; selfIp6 = "2001:db8:20::191"; backupHosts = (builtins.map firestar [ { name = "hdd"; subvolumes = [ "@diskimages" "@documents" "@downloads" "@music" "@pictures" "@videos" ]; } { name = "nvme"; subvolumes = [ "@development" ]; } ]) ++ [ graystripe ] ++ (builtins.map k3sOld [ { ip = "192.168.20.120"; name = "k3s1"; } { ip = "192.168.20.121"; name = "k3s2"; } { ip = "192.168.20.122"; name = "k3s3"; } { ip = "192.168.20.123"; name = "k3s4"; } { ip = "192.168.20.124"; name = "k3s5"; } ]) ++ (builtins.map k3s [ { ip = "192.168.20.125"; name = "k3s6"; } { ip = "192.168.20.126"; name = "k3s7"; } { ip = "192.168.20.127"; name = "k3s8"; } { ip = "192.168.20.128"; name = "k3s9"; } { ip = "192.168.20.129"; name = "k3s10"; } { ip = "192.168.20.130"; name = "k3s11"; } { ip = "192.168.20.131"; name = "k3s12"; } { ip = "192.168.20.132"; name = "k3s13"; } { ip = "192.168.20.133"; name = "k3s14"; } { ip = "192.168.20.134"; name = "k3s15"; } { ip = "192.168.20.135"; name = "k3s16"; } ]) ++ (builtins.map db [ { ip = "192.168.20.26"; name = "whitestorm1"; } { ip = "192.168.20.24"; name = "redtail2"; } ]); }; router = makeRouterConfig system { hostName = "router"; wireguardPrivateKey = "router-wg-private"; }; }; deploy.nodes = let nodes = [ { name = "redtail1"; ip = "192.168.20.23"; } { name = "redtail2"; ip = "192.168.20.24"; } { name = "whitestorm2"; ip = "192.168.20.27"; } { name = "build2"; ip = "192.168.20.101"; } { name = "k3s-rock1"; ip = "192.168.20.110"; } { name = "k3s-rock2"; ip = "192.168.20.111"; } { name = "k3s-rock3"; ip = "192.168.20.112"; } { name = "k3s-rock4"; ip = "192.168.20.113"; } { name = "k3s-rock5"; ip = "192.168.20.114"; } { name = "k3s-rock6"; ip = "192.168.20.115"; } { name = "k3s-rock7"; ip = "192.168.20.116"; } { name = "k3s1"; ip = "192.168.20.120"; } { name = "k3s2"; ip = "192.168.20.121"; } { name = "k3s3"; ip = "192.168.20.122"; } { name = "k3s4"; ip = "192.168.20.123"; } { name = "k3s5"; ip = "192.168.20.124"; } { name = "k3s6"; ip = "192.168.20.125"; } { name = "k3s7"; ip = "192.168.20.126"; } { name = "k3s8"; ip = "192.168.20.127"; } { name = "k3s9"; ip = "192.168.20.128"; } { name = "k3s10"; ip = "192.168.20.129"; } { name = "k3s11"; ip = "192.168.20.130"; } { name = "k3s12"; ip = "192.168.20.131"; } { name = "k3s13"; ip = "192.168.20.132"; } { name = "k3s14"; ip = "192.168.20.133"; } { name = "k3s15"; ip = "192.168.20.134"; } { name = "k3s16"; ip = "192.168.20.135"; } { name = "k3s-quartza1"; ip = "192.168.20.160"; } { name = "k3s-rockpro1"; ip = "192.168.20.180"; } { name = "backup1"; ip = "192.168.20.190"; } { name = "backup2"; ip = "192.168.20.191"; } { name = "pinetab2"; ip = "192.168.20.74"; } { name = "jellyfin"; ip = "192.168.20.195"; } { name = "router"; ip = "192.168.20.1"; port = "3128"; } ]; in builtins.foldl' (acc: { name, ip, port ? "22" }: acc // { ${name} = { hostname = ip; profiles.system = { magicRollback = false; sshUser = "asonix"; user = "root"; interactiveSudo = true; sshOpts = [ "-i" "/home/asonix/.ssh/kube-rsa" "-p" port ]; path = deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.${name}; }; }; }) { } nodes; formatter.${system} = nixpkgs.legacyPackages.${system}.nixpkgs-fmt; }; }