1361 lines
42 KiB
Nix
1361 lines
42 KiB
Nix
{
|
|
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 {
|
|
users.users.asonix.extraGroups = [ "jellyfin" ];
|
|
services = {
|
|
jellyfin = {
|
|
enable = true;
|
|
openFirewall = true;
|
|
};
|
|
|
|
samba = {
|
|
enable = true;
|
|
securityType = "user";
|
|
openFirewall = true;
|
|
extraConfig = ''
|
|
workgroup = WORKGROUP
|
|
server string = jellyfin
|
|
netbios name = jellyfin
|
|
security = user
|
|
hosts allow 192.168.5. 127.0.0.1 localhost
|
|
hosts deny 0.0.0.0/0
|
|
guest account = nobody
|
|
map to guest = bad user
|
|
'';
|
|
shares.private = {
|
|
path = "/storage/jellyfin";
|
|
browsable = "yes";
|
|
"read only" = "no";
|
|
"guest ok" = "no";
|
|
"create mask" = "0644";
|
|
"directory mask" = "0755";
|
|
"force user" = "jellyfin";
|
|
"force group" = "jellyfin";
|
|
};
|
|
};
|
|
|
|
samba-wsdd = {
|
|
enable = true;
|
|
openFirewall = true;
|
|
};
|
|
};
|
|
} 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 = [ "@exports" "@garage" ];
|
|
};
|
|
|
|
k3s = { ip, name }: {
|
|
inherit name;
|
|
primaryIp = ip;
|
|
mountDir = "/btrfs/nvme";
|
|
subvolumes = [ "@exports" "@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.27";
|
|
name = "whitestorm2";
|
|
}
|
|
{
|
|
ip = "192.168.20.24";
|
|
name = "redtail2";
|
|
}
|
|
]);
|
|
};
|
|
|
|
backup2 =
|
|
let
|
|
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.11";
|
|
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 = "nvme1";
|
|
subvolumes = [ "@development" "@documents" "@downloads" "@music" "@notes" "@photos" "@videos" ];
|
|
}
|
|
]) ++ [ graystripe ] ++ (builtins.map db [
|
|
{
|
|
ip = "192.168.20.27";
|
|
name = "whitestorm2";
|
|
}
|
|
{
|
|
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 = "whitestorm1";
|
|
ip = "192.168.20.26";
|
|
}
|
|
{
|
|
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;
|
|
};
|
|
}
|