feat(luna): massively overhaul config, add gitea

This commit is contained in:
Price Hiller 2024-01-30 22:07:30 -06:00
parent 41c10d1606
commit 1f615e4632
Signed by: Price
SSH Key Fingerprint: SHA256:Y4S9ZzYphRn1W1kbJerJFO6GGsfu9O70VaBSxJO7dF8
25 changed files with 509 additions and 156 deletions

26
.editorconfig Normal file
View File

@ -0,0 +1,26 @@
root = true
[*]
end_of_line = lf
insert_final_newline = false
trim_trailing_whitespace = true
charset = utf-8
max_line_length = 100
indent_style = space
# We don't want to mess with encrypted files if they exist in the repo
[*.age]
indent_style = unset
indent_size = unset
tab_width = unset
end_of_line = unset
charset = unset
trim_trailing_whitespace = unset
insert_final_newline = unset
max_line_length = unset
[{*.bash,.envrc}]
indent_style = tab
[*.nix]
indent_size = 2

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
.direnv/ .direnv/
*.ignore *.ignore
.nixd.json

12
.nixd.nix Normal file
View File

@ -0,0 +1,12 @@
{
formatting = {
command = "nixpkgs-fmt";
};
options = {
enable = true;
target = {
args = [];
installable = ".#nixosConfigurations.luna.options";
};
};
}

View File

@ -68,6 +68,26 @@
"type": "github" "type": "github"
} }
}, },
"deploy-rs": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": "nixpkgs",
"utils": "utils"
},
"locked": {
"lastModified": 1704875591,
"narHash": "sha256-eWRLbqRcrILgztU/m/k7CYLzETKNbv0OsT2GjkaNm8A=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "1776009f1f3fb2b5d236b84d9815f2edee463a9b",
"type": "github"
},
"original": {
"owner": "serokell",
"repo": "deploy-rs",
"type": "github"
}
},
"disko": { "disko": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -75,11 +95,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1706145859, "lastModified": 1706491084,
"narHash": "sha256-+iGHKwzKVW6aGAWfUmUSJW1KiE6WLYhKyTyWZMTw/cg=", "narHash": "sha256-eaEv+orTmr2arXpoE4aFZQMVPOYXCBEbLgK22kOtkhs=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "5a2dc95464080764b9ca1b82b5d6d981157522be", "rev": "f67ba6552845ea5d7f596a24d57c33a8a9dc8de9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -88,6 +108,38 @@
"type": "github" "type": "github"
} }
}, },
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1687265871,
"narHash": "sha256-P8AOiQk/XN8/ia4289hDHlTfWB70cRQ5pc9GRfmEdpc=",
"owner": "inclyc",
"repo": "flake-compat",
"rev": "70e56389c58bbd300d11778913b255477ebbae22",
"type": "github"
},
"original": {
"owner": "inclyc",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"inputs": { "inputs": {
"systems": "systems_2" "systems": "systems_2"
@ -108,7 +160,7 @@
}, },
"flake-utils_2": { "flake-utils_2": {
"inputs": { "inputs": {
"systems": "systems_3" "systems": "systems_4"
}, },
"locked": { "locked": {
"lastModified": 1705309234, "lastModified": 1705309234,
@ -147,11 +199,11 @@
}, },
"impermanence": { "impermanence": {
"locked": { "locked": {
"lastModified": 1703656108, "lastModified": 1706639736,
"narHash": "sha256-hCSUqdFJKHHbER8Cenf5JRzjMlBjIdwdftGQsO0xoJs=", "narHash": "sha256-CaG4j9+UwBDfinxxvJMo6yOonSmSo0ZgnbD7aj2Put0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "impermanence", "repo": "impermanence",
"rev": "033643a45a4a920660ef91caa391fbffb14da466", "rev": "cd13c2917eaa68e4c49fea0ff9cada45440d7045",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -162,11 +214,27 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1705856552, "lastModified": 1702272962,
"narHash": "sha256-JXfnuEf5Yd6bhMs/uvM67/joxYKoysyE3M2k6T3eWbg=", "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "612f97239e2cc474c13c9dafa0df378058c5ad8d", "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1706371002,
"narHash": "sha256-dwuorKimqSYgyu8Cw6ncKhyQjUDOyuXoxDTVmAXq88s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c002c6aa977ad22c60398daaa9be52f2203d0006",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -180,10 +248,12 @@
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
"blog": "blog", "blog": "blog",
"deploy-rs": "deploy-rs",
"disko": "disko", "disko": "disko",
"flake-compat": "flake-compat_2",
"flake-utils": "flake-utils_2", "flake-utils": "flake-utils_2",
"impermanence": "impermanence", "impermanence": "impermanence",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs_2"
} }
}, },
"systems": { "systems": {
@ -230,6 +300,39 @@
"repo": "default", "repo": "default",
"type": "github" "type": "github"
} }
},
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

View File

@ -1,9 +1,10 @@
{ {
description = "Price Hiller's flake for managing system configurations"; description = "Asgard Eternal's flake for managing system configurations";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
deploy-rs.url = "github:serokell/deploy-rs";
impermanence = { impermanence = {
url = "github:nix-community/impermanence"; url = "github:nix-community/impermanence";
}; };
@ -15,6 +16,11 @@
url = "github:nix-community/disko"; url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
# For the nixd language server
flake-compat = {
url = "github:inclyc/flake-compat";
flake = false;
};
blog = { blog = {
type = "gitlab"; type = "gitlab";
owner = "blog"; owner = "blog";
@ -24,25 +30,25 @@
}; };
}; };
outputs = inputs @ { self, nixpkgs, impermanence, agenix, disko, flake-utils, blog, ... }:
outputs = inputs @ { self, nixpkgs, deploy-rs, impermanence, agenix, disko, flake-utils, blog, ... }:
let let
lib = import ./lib // nixpkgs.lib; lib = (import ./lib { lib = nixpkgs.lib; }) // nixpkgs.lib;
pkgs = nixpkgs.legacyPackages."x86_64-linux"; persist-dir = "/persist";
defaults = { defaults = {
config = { config = {
environment.etc.machine-id.source = "/nix/persist/ephemeral/etc/machine-id"; environment.etc.machine-id.source = "${persist-dir}/ephemeral/etc/machine-id";
environment.persistence.save = { environment.persistence.save = {
hideMounts = true; hideMounts = true;
persistentStoragePath = "/nix/persist/save"; persistentStoragePath = "${persist-dir}/save";
}; };
environment.persistence.ephemeral = { environment.persistence.ephemeral = {
persistentStoragePath = "/nix/persist/ephemeral"; persistentStoragePath = "${persist-dir}/ephemeral";
hideMounts = true; hideMounts = true;
directories = [ directories = [
"/var/lib" "/var/lib"
"/var/log" "/var/log"
"/etc/nixos" "/etc/nixos"
{ directory = "/persist"; user = "root"; group = "root"; mode = "0700"; }
]; ];
}; };
}; };
@ -58,27 +64,41 @@
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = { specialArgs = {
inherit self; inherit self;
inherit blog;
inherit flake-utils; inherit flake-utils;
inherit inputs; inherit inputs;
inherit hostname; inherit hostname;
inherit nixpkgs;
inherit lib; inherit lib;
inherit blog; inherit persist-dir;
secrets = "${self}/secrets/${hostname}"; root-disk = "/dev/nvme0n1";
disk = "nvme0n1";
fqdn = "orion-technologies.io"; fqdn = "orion-technologies.io";
}; };
modules = [ modules = [
{
_module.args = { };
}
defaults defaults
impermanence.nixosModules.impermanence impermanence.nixosModules.impermanence
agenix.nixosModules.default agenix.nixosModules.default
disko.nixosModules.disko disko.nixosModules.disko
{ config = (import "${self}/secrets" { agenix = false; inherit lib; }).${hostname}; }
./hosts/${hostname} ./hosts/${hostname}
]; ];
}; };
deploy.nodes = {
luna = {
hostname = "luna";
fastConnection = true;
profiles = {
system = {
sshUser = "price";
user = "root";
path =
deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.luna;
};
};
};
};
} // flake-utils.lib.eachDefaultSystem (system: } // flake-utils.lib.eachDefaultSystem (system:
let let
pkgs = import nixpkgs { pkgs = import nixpkgs {
@ -90,9 +110,10 @@
devShells.default = devShells.default =
pkgs.mkShell pkgs.mkShell
{ {
packages = with pkgs; [ age age-plugin-yubikey pkgs.agenix ]; packages = with pkgs; [ age age-plugin-yubikey pkgs.agenix nixos-rebuild pkgs.deploy-rs ];
shellHook = '' shellHook = ''
export RULES="$PWD/secrets/secrets.nix" export RULES="$PWD/secrets/secrets.nix"
nix eval --json --file ./.nixd.nix > .nixd.json
''; '';
}; };
}); });

View File

@ -1,6 +1,5 @@
{ config, lib, nixpkgs, ... }: { config, lib, nixpkgs, ... }:
{ {
imports = (lib.recurseFilesInDirs [ ./os ./modules ] ".nix"); imports = (lib.recurseFilesInDirs [ ./os ./modules ] ".nix");
system.stateVersion = "24.05"; system.stateVersion = "24.05";
} }

View File

@ -2,4 +2,7 @@
{ {
time.timeZone = "America/Chicago"; time.timeZone = "America/Chicago";
systemd.extraConfig = ''
DefaultTimeoutStopSec=10s
'';
} }

View File

@ -1,4 +1,4 @@
{ secrets, config, specialArgs, fqdn, ... }: { config, specialArgs, fqdn, ... }:
let let
gitlab_home = "/var/lib/gitlab"; gitlab_home = "/var/lib/gitlab";
gitlab_host = "gitlab.${fqdn}"; gitlab_host = "gitlab.${fqdn}";
@ -42,7 +42,6 @@ in
2222 2222
]; ];
age.secrets.gitlab-runner-reg-config.file = "${secrets}/gitlab-runner-reg-config.age";
services.gitlab-runner = { services.gitlab-runner = {
enable = true; enable = true;
services = { services = {

View File

@ -0,0 +1,77 @@
{ config, fqdn, ... }:
let gitea_host = "git.${fqdn}";
in {
age.secrets.gitea-db-pass = {
owner = config.services.gitea.user;
group = config.services.gitea.group;
};
services = {
postgresql = {
enable = true;
ensureDatabases = [ config.services.gitea.user ];
ensureUsers = [{
name = config.services.gitea.database.user;
ensureClauses = {
login = true;
createdb = true;
};
ensureDBOwnership = true;
}];
};
gitea = {
appName = "Price Hiller's Git Repositories";
enable = true;
dump.enable = true;
database = {
type = "postgres";
passwordFile = config.age.secrets.gitea-db-pass.path;
};
settings = {
service.DISABLE_REGISTRATION = true;
# Extend timeouts to 1 hour
"git.timeout" = {
DEFAULT = 3600;
MIGRATE = 3600;
MIRROR = 3600;
CLONE = 3600;
PULL = 3600;
GC = 3600;
};
markup.ENABLED = true;
mirror.DEFAULT_INTERVAL = "1h";
server = {
DOMAIN = "${gitea_host}";
HTTP_ADDR = "127.0.0.1";
ROOT_URL = "https://${gitea_host}/";
SSH_PORT = 2220;
START_SSH_SERVER = true;
DISABLE_QUERY_AUTH_TOKEN = true;
};
session.COOKIE_SECURE = true;
"repository.upload".FILE_MAX_SIZE = 1024;
};
};
# gitea-actions-runner.instances = {
#
# };
nginx.virtualHosts."${gitea_host}" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass =
"http://${config.services.gitea.settings.server.HTTP_ADDR}:${
builtins.toString config.services.gitea.settings.server.HTTP_PORT
}";
};
};
networking.firewall.allowedTCPPorts =
[ config.services.gitea.settings.server.SSH_PORT ];
environment.persistence.save.directories = [{
directory = config.services.gitea.stateDir;
user = config.services.gitea.user;
group = config.services.gitea.group;
}];
}

View File

@ -18,5 +18,4 @@
root = blog.packages.${pkgs.system}.default; root = blog.packages.${pkgs.system}.default;
locations."/".index = "home.html"; locations."/".index = "home.html";
}; };
} }

View File

@ -2,6 +2,7 @@
{ {
services.openssh = { services.openssh = {
enable = true; enable = true;
startWhenNeeded = true;
# We set the hostkeys manually so they persist through reboots # We set the hostkeys manually so they persist through reboots
hostKeys = [ hostKeys = [
{ {
@ -19,6 +20,7 @@
settings = { settings = {
PasswordAuthentication = false; PasswordAuthentication = false;
PermitRootLogin = "no"; PermitRootLogin = "no";
GatewayPorts = "yes";
LogLevel = "VERBOSE"; LogLevel = "VERBOSE";
KexAlgorithms = [ KexAlgorithms = [
"curve25519-sha256" "curve25519-sha256"

View File

@ -0,0 +1,33 @@
{ config, lib, pkgs, ... }:
{
services.postgresqlBackup = {
location = "/var/backup/postgresql";
backupAll = true;
};
services.postgresql = {
enable = true;
# Explicitly setting the data dir so upgrades (changing version from 15 -> 16) don't end up
# getting lost on system reboots
dataDir = "/var/lib/postgresql";
settings = {
log_connections = true;
log_disconnections = true;
logging_collector = true;
log_statement = "all";
log_destination = lib.mkForce "syslog,jsonlog";
};
ensureUsers = [
{
name = "root";
ensureClauses.superuser = true;
}
];
};
environment.systemPackages = [ pkgs.pgloader ];
environment.persistence.save.directories = [
{ directory = config.services.postgresql.dataDir; user = "postgres"; group = "postgres"; }
{ directory = config.services.postgresqlBackup.location; user = "postgres"; group = "postgres"; }
];
}

View File

@ -1,7 +1,5 @@
{ pkgs, user, config, secrets, ... }: { pkgs, user, config, ... }:
{ {
age.secrets.root-pw.file = "${secrets}/root-hash-pw.age";
security.sudo.wheelNeedsPassword = false; security.sudo.wheelNeedsPassword = false;
users.users = { users.users = {
root.hashedPasswordFile = config.age.secrets.root-pw.path; root.hashedPasswordFile = config.age.secrets.root-pw.path;

View File

@ -7,8 +7,15 @@
]; ];
boot = { boot = {
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
kernelModules = [ "kvm-intel" ];
kernelParams = [ "audit=1" ];
extraModulePackages = [ ];
initrd = { initrd = {
availableKernelModules = [ "xhci_pci" "ahci" "nvme" "uas" "sd_mod" ]; availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
kernelModules = [ ]; kernelModules = [ ];
systemd = { systemd = {
enable = true; enable = true;
@ -23,17 +30,24 @@
script = '' script = ''
mkdir -p /mnt mkdir -p /mnt
DISK_LABEL="NixOS-Primary" DISK_LABEL="NixOS-Primary"
ATTEMPTS=5 FOUND_DISK=0
ATTEMPTS=50
printf "Attempting to find disk with label '%s'\n" "$DISK_LABEL" printf "Attempting to find disk with label '%s'\n" "$DISK_LABEL"
while ((ATTEMPTS > 0)); do while ((ATTEMPTS > 0)); do
if findfs LABEL="$DISK_LABEL"; then if findfs LABEL="$DISK_LABEL"; then
FOUND_DISK=1
printf "Found disk!\n" printf "Found disk!\n"
break; break;
fi fi
((ATTEMPTS--)) ((ATTEMPTS--))
sleep 3 sleep .1
printf "Remaining disk discovery attempts: %s\n" "$ATTEMPTS" printf "Remaining disk discovery attempts: %s\n" "$ATTEMPTS"
done done
if (( FOUND_DISK == 0 )); then
printf "Discovery of disk with label '%s' failed! Cannot rollback!\n" "$DISK_LABEL"
exit 1
fi
mount -t btrfs -o subvol=/ $(findfs LABEL="$DISK_LABEL") /mnt mount -t btrfs -o subvol=/ $(findfs LABEL="$DISK_LABEL") /mnt
btrfs subvolume list -to /mnt/root \ btrfs subvolume list -to /mnt/root \
| awk 'NR>2 { printf $4"\n" }' \ | awk 'NR>2 { printf $4"\n" }' \
@ -53,12 +67,6 @@
}; };
}; };
}; };
loader = {
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
}; };
} }

View File

@ -1,57 +0,0 @@
{ disk ? "nvme0n1", ... }: {
disko.devices = {
disk.${disk} = {
type = "disk";
device = "/dev/${disk}";
content = {
type = "gpt";
partitions = {
esp =
let
label = "NixOS-Boot";
in
{
priority = 1;
size = "512M";
type = "EF00";
content = {
extraArgs = [ "-n ${label}" "-F 32" ];
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
};
};
root =
let
label = "NixOS-Primary";
in
{
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" "--label ${label}" ];
postCreateHook = ''
MOUNT="$(mktemp -d)"
mount "/dev/disk/by-label/${label}" "$MOUNT" -o subvol=/
trap 'umount $MOUNT; rm -rf $MOUNT' EXIT
btrfs subvolume snapshot -r "$MOUNT/root" "$MOUNT/root-base"
'';
subvolumes = {
"/root" = {
mountpoint = "/";
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" ];
};
};
};
};
};
};
};
};
}

87
hosts/luna/os/fs.nix Normal file
View File

@ -0,0 +1,87 @@
{ modulesPath, config, lib, root-disk, persist-dir, ... }:
{
services = {
fstrim.enable = true;
btrfs.autoScrub = {
enable = true;
fileSystems = [
"/"
"/nix"
"/persist"
];
};
snapper = {
# NOTE: According to `snapper-config(5)` the default timeline count for all timelines is 10
# (see TIMELINE_LIMIT_HOURLY, ...DAILY, etc.)
configs.persist = {
TIMELINE_CREATE = true;
TIMELINE_CLEANUP = true;
SUBVOLUME = "${persist-dir}";
};
};
};
fileSystems."/persist".neededForBoot = true;
disko.devices =
{
disk.${lib.removePrefix "/dev/" root-disk} = {
type = "disk";
device = "${root-disk}";
content = {
type = "gpt";
partitions = {
esp =
let
label = "NixOS-Boot";
in
{
priority = 1;
size = "512M";
type = "EF00";
content = {
extraArgs = [ "-n ${label}" "-F 32" ];
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"umask=0077"
"defaults"
];
};
};
root =
let
label = "NixOS-Primary";
in
{
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" "--label ${label}" ];
postCreateHook = ''
MOUNT="$(mktemp -d)"
mount "/dev/disk/by-label/${label}" "$MOUNT" -o subvol=/
trap 'umount $MOUNT; rm -rf $MOUNT' EXIT
btrfs subvolume snapshot -r "$MOUNT/root" "$MOUNT/root-base"
'';
subvolumes = {
"/root" = {
mountpoint = "/";
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" ];
};
"/persist" = {
mountpoint = "/persist";
mountOptions = [ "compress=zstd" "noatime" ];
};
};
};
};
};
};
};
};
}

View File

@ -1 +1 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF5AtCUEvm9pSi8iI4xH5wnJ6dR9tZZY7qPS4GLJbQAW luna" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJO2ufKRT1NCwp4c9cbOjxfb+/XlY8AUgnDLObA0gYaB luna"

19
install.bash Normal file → Executable file
View File

@ -40,14 +40,15 @@ gen-system-key() {
} }
main() { main() {
local persist_dir="/mnt/nix/persist" local persist_dir="/mnt/persist"
local flake_install_path="${persist_dir}/ephemeral/etc/nixos" local flake_install_path="${persist_dir}/ephemeral/etc/nixos"
local system="${1:?"Provide system to build!"}" local system="${1:?"Provide system to build!"}"
local flake=".#${system}" local flake=".#${system}"
local conn="${2:?"Provide ssh connection string! (E.g. root@myhost)"}" local conn="${2:?"Provide ssh connection string! (E.g. root@myhost)"}"
local priv_key_path="${3:?Provide path to private key}" local priv_key_path="${3:?Provide path to private key}"
shift 3 local ssh_port="${4:-22}"
if [[ ! -r "${priv_key_path}" ]]; then if [[ ! -r "${priv_key_path}" ]]; then
printf "Unable a private key file at '%s'\n!" "${priv_key_path}" 1>&2 printf "Unable a private key file at '%s'\n!" "${priv_key_path}" 1>&2
exit 1 exit 1
@ -67,9 +68,9 @@ main() {
local new_sys_key local new_sys_key
new_sys_key="$(gen-system-key "${system}" "${priv_key_path}")" new_sys_key="$(gen-system-key "${system}" "${priv_key_path}")"
local nixos_anywhere_log local nixos_anywhere_log
nixos_anywhere_log="$(nix run github:nix-community/nixos-anywhere -- --flake "${flake}" "${conn}" --stop-after-disko 2>&1 | tee >(cat >&2))" nixos_anywhere_log="$(nix run github:nix-community/nixos-anywhere -- --flake "${flake}" "${conn}" --stop-after-disko 2>&1 | tee >(cat >&2) -p "${ssh_port}")"
local ssh_login_key="${nixos_anywhere_log##*$'\n'}"; ssh_login_key="${ssh_login_key#*\'}"; ssh_login_key="${ssh_login_key%\'*}" local ssh_login_key="${nixos_anywhere_log##*$'\n'}"; ssh_login_key="${ssh_login_key#*\'}"; ssh_login_key="${ssh_login_key%\'*}"
local ssh_opts="-i ${ssh_login_key} -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" local ssh_opts="-i ${ssh_login_key} -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p ${ssh_port} -l root"
local ssh_cmd="ssh ${conn} ${ssh_opts}" local ssh_cmd="ssh ${conn} ${ssh_opts}"
local system_key_dest="${persist_dir}/ephemeral/etc/ssh/ssh_host_ed25519_key" local system_key_dest="${persist_dir}/ephemeral/etc/ssh/ssh_host_ed25519_key"
printf "SSH Command: %s\n" "${ssh_cmd}" printf "SSH Command: %s\n" "${ssh_cmd}"
@ -80,18 +81,20 @@ main() {
printf "Putting new system key into place\n" printf "Putting new system key into place\n"
printf "%s\n" "${new_sys_key}" > "${system_key_dest}" printf "%s\n" "${new_sys_key}" > "${system_key_dest}"
chmod 0600 "${system_key_dest}" chmod 0600 "${system_key_dest}"
printf "Installing rsync for later stage\n"
nix-env -f '<nixpkgs>' -iA rsync
__EOS__ __EOS__
printf "Copying flake to system\n"; printf "Copying flake to system\n";
rsync -r "${SCRIPT_DIR}"/{*,.*} "${conn}:${flake_install_path}" -e "ssh ${ssh_opts}" --info=PROGRESS2 local rsync_cmd="rsync -r '${SCRIPT_DIR}'/ '${conn}:${flake_install_path}' -e 'ssh ${ssh_opts}' --info=PROGRESS2"
printf "Issuing rsync command: '%s\n'" "${rsync_cmd}"
eval "${rsync_cmd}"
printf "Doing final install\n" printf "Doing final install\n"
eval "${ssh_cmd}" <<- __EOS__ eval "${ssh_cmd}" <<- __EOS__
set -euo pipefail set -euo pipefail
cd "${flake_install_path}" cd "${flake_install_path}"
nix-env -f '<nixpkgs>' -iA git nix-env -f '<nixpkgs>' -iA git
sudo nixos-install --flake "git+file:${flake}" --no-root-password --no-channel-copy sudo nixos-install --flake "git+file:${flake}" --no-root-password --no-channel-copy && reboot
reboot
__EOS__ __EOS__
printf "%s\n" "${ssh_cmd}"
cat <<- __EOS__ cat <<- __EOS__
────────────────────────────────────────── ──────────────────────────────────────────

View File

@ -1,4 +1,5 @@
# Some of these functions were taken from https://github.com/NixOS/nixpkgs/blob/master/lib/ # Some of these functions were taken from https://github.com/NixOS/nixpkgs/blob/master/lib/
{ lib ? (import <nixpkgs> { }).lib }:
rec { rec {
hasSuffix = hasSuffix =
suffix: suffix:
@ -29,4 +30,19 @@ rec {
(builtins.filter (file: hasSuffix "${suffix}" file) (recurseDir dir)); (builtins.filter (file: hasSuffix "${suffix}" file) (recurseDir dir));
recurseFilesInDirs = dirs: suffix: recurseFilesInDirs = dirs: suffix:
(builtins.concatMap (dir: (recurseFilesInDir dir "${suffix}")) dirs); (builtins.concatMap (dir: (recurseFilesInDir dir "${suffix}")) dirs);
# Full credit to https://stackoverflow.com/questions/54504685/nix-function-to-merge-attributes-records-recursively-and-concatenate-arrays/54505212#54505212
recursiveMerge = attrList:
let
f = attrPath:
lib.zipAttrsWith (n: values:
if lib.tail values == [ ]
then lib.head values
else if lib.all builtins.isList values
then lib.unique (lib.concatLists values)
else if lib.all builtins.isAttrs values
then f (attrPath ++ [ n ]) values
else lib.last values
);
in
f [ ] attrList;
} }

46
secrets/default.nix Normal file
View File

@ -0,0 +1,46 @@
{ agenix ? true, lib ? import ../lib { } }:
let
masterKeys = [
"age1yubikey1qfnj0k4mkzrn8ef5llwh2sv6hd7ckr0qml3n9hzdpz9c59ypvryhyst87k0"
];
hosts = {
luna =
let
secrets = "luna";
in
{
root-pw = "${secrets}/root-hash-pw.age";
gitlab-runner-reg-config = "${secrets}/gitlab-runner-reg-config.age";
gitea-db-pass = "${secrets}/gitea-db-pass.age";
};
};
in
if agenix then
(builtins.listToAttrs
(builtins.concatMap
(host:
let
hostSecrets = (builtins.getAttr host hosts);
in
(builtins.map
(hostSecretName:
let
secret = (builtins.getAttr hostSecretName hostSecrets);
in
{
name = builtins.toString secret;
value = {
publicKeys = [ (import ./../hosts/${host}/pubkey.nix) ] ++ masterKeys;
};
})
(builtins.attrNames hostSecrets)))
(builtins.attrNames hosts)))
else
(builtins.mapAttrs
(host: secrets:
(lib.recursiveMerge (builtins.map
(secretName: {
age.secrets.${secretName}.file = ./${secrets.${secretName}};
})
(builtins.attrNames hosts.${host}))))
hosts)

View File

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 1fG0ow ItVCvyKKXcmZVvuomgGsRw91c1jQCLXGPkIh2VXvGFg
NjOqD/+g+6FvOqurcaKw5LrZpmc2Tlo277ZYkv3loWU
-> piv-p256 rJs1HA AuseeP2+foV1YzNuU85cqXN/t/MxL1CSMfev9EBnn547
ErXvkp3KKibgLNbOQmE3iM1CjgooVs/Nsup84i4U8ds
--- lWtn0ntT2K5N9LlQR69UYGyJvELufjKuEqnWceJWZdQ
~eàt!ß„¦®…p`±8ÙîÓïó&nS ØW?§JåÎKY°U Ÿ”6?|I´Œ£MÇQ0ÿÛ¸ssêR,=¡??O²e{)^ŸiöœÇ÷
 åéAg</綵ñsºÝØ<1F>ÔêSjœŠýÁÐB—'áÕÙ§ <0B>¿~PTQ—¯Öy“ئkœ>ªnò4}(ˆóe£QHU"ð^ؘ?ไ}'*ò¼%†,Pˆ¤ªg½A Iêy9“15<35>ëU¿ôt

View File

@ -1,10 +1,7 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 4sH96w zBi3BGIf/OJza0ADpk264QCudT5mKzxcxgfxoNI9HSw -> ssh-ed25519 1fG0ow oP4nP83S4Hjf4MScoNCBbE3i4Vnzz5XiuJqaLXzRbw0
8Ys6frvd7UeXRXPpiClCJ+qoRHiE7K+TfQhbb1o34bk rNOkeT8FfDLCoUnghLs8/Fpzy4qINhhIhtgB3Ep3REc
-> piv-p256 rJs1HA Aw/GcBY+XMD/9++r819joYKKyIrf8gbpjgIgugLhBtBq -> piv-p256 rJs1HA AiyT5IFnxwxoONmRezlvneUSYSEjglGeXYav8x7Xt+HB
BTIRQ/6zl2HqJJrCGbeMwAwmp65EiU5jAs130/MoHOs JWAyCMNQNe0+LSRqdQV+f5PGixWMXFMf/wQmyoMEKNE
-> OKjJEPyZ-grease l {KDS$m oX;O="m --- ZnfbHqBM/51+BXYGhcSzBN6k1UtZpKJshgmxrr2eFGo
29gF4VbnR6zEbojhshhTvk2tYizn32MsCDsuutl+HCmVTNPvDIkWRSMPylfsZqLY ô<EFBFBD>™?f èÇíÇ$®À<08>Æb t,ñ$åÌ<C3A5>á€o8R«¸ûò­;¾Øn!õchzg•ý‰—lÁ= 5îOcâÀ—¯BNJð½„ÉaH1Ïýuƒ?ÙQCþfºN{†$ûM¨wLbs¾€:+•Ãá?ZC0™òÚ
AMl5wcis0Spit7SKkNKJVCtL/39fXu5zgJU
--- VTqUeA4weWW1vN8qr5jsTgIgbU/3rvYQX8A0gPgYGus
ÝúÑ<1A>†IVÒ¬Þïº*HøŒ[Õ°/IEz<45>Ôù#—ûMiÒ®Õp0ÒßMð(áë´TS—y§±î§—º‡¢ DÄn¾…@ƒ [/R亱?l7 (Ì 7&˜R“ö<E2809C>8 D¥ JE5°(˜±¦¨bÍÊpón5/·w/çßâ°

Binary file not shown.

View File

@ -1,29 +1 @@
let import ./default.nix { agenix = true; }
root-dir = builtins.toString ./.;
lib = import ../lib;
master-keys = [
"age1yubikey1qfnj0k4mkzrn8ef5llwh2sv6hd7ckr0qml3n9hzdpz9c59ypvryhyst87k0"
];
hosts = {
luna =
let
secrets = "${root-dir}/luna";
in
[
"${secrets}/gitlab-runner-reg-config.age"
"${secrets}/root-hash-pw.age"
];
};
in
(builtins.listToAttrs
(builtins.concatMap
(host:
(builtins.map
(secret: {
name = builtins.toString secret;
value = {
publicKeys = [ (import ./../hosts/${host}/pubkey.nix) ] ++ master-keys;
};
})
(builtins.getAttr host hosts)))
(builtins.attrNames hosts)))