Compare commits

..

No commits in common. "e44ec3cba7356080c8fefb9cc78cb82b847cfda2" and "aa1ca78c3b4f35b9fdb4c3fb9b70f22a658c07cf" have entirely different histories.

14 changed files with 147 additions and 83 deletions

View File

@ -188,7 +188,25 @@
}); });
nixosConfigurations = nixosConfigurations =
let let
clib = (import ./lib { lib = nixpkgs.lib; }); lib = (import ./lib { lib = nixpkgs.lib; }) // nixpkgs.lib;
persist-dir = "/persist";
defaults = {
config = {
environment.etc.machine-id.source = "${persist-dir}/ephemeral/etc/machine-id";
environment.persistence.save = {
hideMounts = true;
persistentStoragePath = "${persist-dir}/save";
};
environment.persistence.ephemeral = {
persistentStoragePath = "${persist-dir}/ephemeral";
hideMounts = true;
directories = [
"/var/lib"
"/etc/nixos"
];
};
};
};
in in
{ {
orion = orion =
@ -202,9 +220,12 @@
inherit inputs; inherit inputs;
inherit outputs; inherit outputs;
inherit hostname; inherit hostname;
inherit clib; inherit lib;
inherit persist-dir;
root-disk = "/dev/nvme0n1";
}; };
modules = [ modules = [
defaults
./modules/btrfs-rollback.nix ./modules/btrfs-rollback.nix
inputs.impermanence.nixosModules.impermanence inputs.impermanence.nixosModules.impermanence
inputs.agenix.nixosModules.default inputs.agenix.nixosModules.default
@ -213,7 +234,7 @@
config = config =
(import "${self}/secrets" { (import "${self}/secrets" {
agenix = false; agenix = false;
inherit clib; inherit lib;
}).${hostname}; }).${hostname};
} }
./hosts/${hostname} ./hosts/${hostname}
@ -230,10 +251,13 @@
inherit inputs; inherit inputs;
inherit hostname; inherit hostname;
inherit nixpkgs; inherit nixpkgs;
inherit clib; inherit lib;
inherit persist-dir;
root-disk = "/dev/nvme0n1";
fqdn = "orion-technologies.io";
}; };
modules = [ modules = [
./modules/btrfs-rollback.nix defaults
inputs.impermanence.nixosModules.impermanence inputs.impermanence.nixosModules.impermanence
inputs.agenix.nixosModules.default inputs.agenix.nixosModules.default
inputs.disko.nixosModules.disko inputs.disko.nixosModules.disko
@ -243,7 +267,7 @@
config = config =
(import "${self}/secrets" { (import "${self}/secrets" {
agenix = false; agenix = false;
inherit clib; inherit lib;
}).${hostname}; }).${hostname};
} }
./hosts/${hostname} ./hosts/${hostname}

View File

@ -1,7 +1,7 @@
{ clib, ... }: { lib, ... }:
{ {
imports = ( imports = (
clib.recurseFilesInDirs [ lib.recurseFilesInDirs [
./os ./os
./modules ./modules
] ".nix" ] ".nix"

View File

@ -1,4 +1,9 @@
{ pkgs, config, ... }: {
persist-dir,
pkgs,
config,
...
}:
let let
laurel-user = "_laurel"; laurel-user = "_laurel";
in in
@ -140,7 +145,7 @@ in
"-a always,exit -F arch=b64 -S open -F dir=/opt -F success=0 -F key=unauthedfileaccess" "-a always,exit -F arch=b64 -S open -F dir=/opt -F success=0 -F key=unauthedfileaccess"
"-a always,exit -F arch=b64 -S open -F dir=/boot -F success=0 -F key=unauthedfileaccess" "-a always,exit -F arch=b64 -S open -F dir=/boot -F success=0 -F key=unauthedfileaccess"
"-a always,exit -F arch=b64 -S open -F dir=/nix -F success=0 -F key=unauthedfileaccess" "-a always,exit -F arch=b64 -S open -F dir=/nix -F success=0 -F key=unauthedfileaccess"
"-a always,exit -F arch=b64 -S open -F dir=/persist -F success=0 -F key=unauthedfileaccess" "-a always,exit -F arch=b64 -S open -F dir=${persist-dir} -F success=0 -F key=unauthedfileaccess"
# File deletion events by users # File deletion events by users
"-a always,exit -F arch=b64 -S rmdir -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=-1 -F key=delete" "-a always,exit -F arch=b64 -S rmdir -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=-1 -F key=delete"

View File

@ -1,6 +1,11 @@
{ config, ... }: {
config,
pkgs,
fqdn,
...
}:
let let
grafana_host = "grafana.orion-technologies.io"; grafana_host = "grafana.${fqdn}";
in in
{ {
services = { services = {

View File

@ -1,6 +1,11 @@
{ config, pkgs, ... }: {
config,
fqdn,
pkgs,
...
}:
let let
prometheus_host = "prometheus.orion-technologies.io"; prometheus_host = "prometheus.${fqdn}";
in in
{ {
services = { services = {

View File

@ -1,12 +1,13 @@
{ {
config, config,
fqdn,
inputs, inputs,
pkgs, pkgs,
lib, lib,
... ...
}: }:
let let
gitea_host = "git.orion-technologies.io"; gitea_host = "git.${fqdn}";
# TODO: Move this docker image out to a separate package and NixOS Module # TODO: Move this docker image out to a separate package and NixOS Module
# Huge thank you to https://icewind.nl/entry/gitea-actions-nix/ -- wouldn't have figured this out # Huge thank you to https://icewind.nl/entry/gitea-actions-nix/ -- wouldn't have figured this out
# without that post 🙂 # without that post 🙂

View File

@ -1,4 +1,4 @@
{ config, ... }: { config, fqdn, ... }:
{ {
services.lakewatch-api = { services.lakewatch-api = {
enable = true; enable = true;
@ -14,7 +14,7 @@
passwordFile = config.age.secrets.lakewatch-db-pass.path; passwordFile = config.age.secrets.lakewatch-db-pass.path;
}; };
}; };
services.nginx.virtualHosts."lakewatch.orion-technologies.io" = { services.nginx.virtualHosts."lakewatch.${fqdn}" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
locations."/".proxyPass = "http://${config.services.lakewatch-api.host}:${builtins.toString config.services.lakewatch-api.port}"; locations."/".proxyPass = "http://${config.services.lakewatch-api.host}:${builtins.toString config.services.lakewatch-api.port}";

View File

@ -1,4 +1,9 @@
{ inputs, pkgs, ... }: {
inputs,
pkgs,
fqdn,
...
}:
{ {
services.nginx = { services.nginx = {
enable = true; enable = true;
@ -14,7 +19,7 @@
}; };
services.nginx.virtualHosts = { services.nginx.virtualHosts = {
"blog.orion-technologies.io" = { "blog.${fqdn}" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
globalRedirect = "price-hiller.com"; globalRedirect = "price-hiller.com";

View File

@ -1,15 +1,8 @@
{ modulesPath, ... }: { modulesPath, pkgs, ... }:
{ {
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
services.btrfs-rollback = {
enable = true;
diskLabel = "NixOS-Primary";
subvolume = "root";
snapshot = "root-base";
};
boot = { boot = {
tmp = { tmp = {
useTmpfs = true; useTmpfs = true;
@ -31,7 +24,58 @@
"sd_mod" "sd_mod"
]; ];
kernelModules = [ ]; kernelModules = [ ];
systemd.enable = true; systemd = {
enable = true;
initrdBin = [
pkgs.libuuid
pkgs.gawk
];
services.rollback = {
description = "Rollback btrfs root subvolume";
wantedBy = [ "initrd.target" ];
before = [ "sysroot.mount" ];
after = [ "initrd-root-device.target" ];
unitConfig.DefaultDependencies = "no";
serviceConfig.Type = "oneshot";
script = ''
mkdir -p /mnt
DISK_LABEL="NixOS-Primary"
FOUND_DISK=0
ATTEMPTS=50
printf "Attempting to find disk with label '%s'\n" "$DISK_LABEL"
while ((ATTEMPTS > 0)); do
if findfs LABEL="$DISK_LABEL"; then
FOUND_DISK=1
printf "Found disk!\n"
break;
fi
((ATTEMPTS--))
sleep .1
printf "Remaining disk discovery attempts: %s\n" "$ATTEMPTS"
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
btrfs subvolume list -to /mnt/root \
| awk 'NR>2 { printf $4"\n" }' \
| while read subvol; do
printf "Removing Subvolume: %s\n" "$subvol";
btrfs subvolume delete "/mnt/$subvol"
done
printf "Removing /root subvolume\n"
btrfs subvolume delete /mnt/root
printf "Restoring base /root subvolume\n"
btrfs subvolume snapshot /mnt/root-base /mnt/root
umount /mnt
'';
};
};
}; };
}; };
} }

View File

@ -1,22 +1,10 @@
{ lib, ... }:
let
root-disk = "/dev/nvme0n1";
persist-dir = "/persist";
in
{ {
environment.etc.machine-id.source = "${persist-dir}/ephemeral/etc/machine-id"; lib,
environment.persistence.save = { root-disk,
hideMounts = true; persist-dir,
persistentStoragePath = "${persist-dir}/save"; ...
}; }:
environment.persistence.ephemeral = { {
persistentStoragePath = "${persist-dir}/ephemeral";
hideMounts = true;
directories = [
"/var/lib"
"/etc/nixos"
];
};
services = { services = {
fstrim.enable = true; fstrim.enable = true;
btrfs.autoScrub = { btrfs.autoScrub = {
@ -24,7 +12,7 @@ in
fileSystems = [ fileSystems = [
"/" "/"
"/nix" "/nix"
"${persist-dir}" "/persist"
]; ];
}; };
snapper = { snapper = {

View File

@ -1,7 +1,7 @@
{ pkgs, clib, ... }: { pkgs, lib, ... }:
{ {
imports = ( imports = (
clib.recurseFilesInDirs [ lib.recurseFilesInDirs [
./os ./os
./modules ./modules
] ".nix" ] ".nix"

View File

@ -1,8 +1,9 @@
{ lib, ... }: {
let lib,
root-disk = "/dev/nvme0n1"; root-disk,
persist-dir = "/persist"; persist-dir,
in ...
}:
{ {
services = { services = {
fstrim.enable = true; fstrim.enable = true;
@ -16,20 +17,6 @@ in
}; };
}; };
environment.etc.machine-id.source = "${persist-dir}/ephemeral/etc/machine-id";
environment.persistence.save = {
hideMounts = true;
persistentStoragePath = "${persist-dir}/save";
};
environment.persistence.ephemeral = {
persistentStoragePath = "${persist-dir}/ephemeral";
hideMounts = true;
directories = [
"/var/lib"
"/etc/nixos"
];
};
fileSystems."${persist-dir}".neededForBoot = true; fileSystems."${persist-dir}".neededForBoot = true;
disko.devices = { disko.devices = {

View File

@ -1,6 +1,6 @@
{ {
agenix ? false, agenix ? false,
clib ? import ../clib { }, lib ? import ../lib { },
}: }:
let let
masterKeys = [ masterKeys = [
@ -54,7 +54,7 @@ if agenix then
else else
(builtins.mapAttrs ( (builtins.mapAttrs (
host: secrets: host: secrets:
(clib.recursiveMerge ( (lib.recursiveMerge (
builtins.map (secretName: { age.secrets.${secretName}.file = ./${secrets.${secretName}}; }) ( builtins.map (secretName: { age.secrets.${secretName}.file = ./${secrets.${secretName}}; }) (
builtins.attrNames hosts.${host} builtins.attrNames hosts.${host}
) )

View File

@ -1,15 +1,15 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFdvUU04QSBKek5B YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFdvUU04QSBBMUpT
RWhneDgyY2MzUVJuYU5CNDdFenY2cTQyNTJ2TDhnN2pidkpNYjBFCkFWV0F3Mmsx dHNFbGpKM1NiczNqK0cvZlVsSVZkelhYSFN6VEV4b3FHNU0zUGxVCllhQmlWenZw
cGxMOEwxU2RSVlFnRXQvUG5sZDkxdkRMRE5lNUlVdVBJZkkKLT4gWDI1NTE5IHJk aFJOUlhlZGhhc0dFd0Q4Y29JSldEV3pva1RoRW1LYUQwU1UKLT4gWDI1NTE5IHI4
bFcwSkxGdjBoYUtwWFAvSkVRL0c0eVFtRThoWDNCUlNDMFJHMXBWeTQKZEdIUTlB M2pYbTFQSnpJdUdGWjZmbmZGM3VRL2YwWkM1clh5d0NRY3Y5Qm8yVmsKYU1QV0Ey
UnhvRGRGY0lJR1hiNUV4b0oxL0RNU3I0VVJkbXhxa0QvUFlrUQotPiBwaXYtcDI1 YU14ZlhpQmNGOEZOazVIaDdsRTQ5QmRBdEI4bHp5RGdmdC8yWQotPiBwaXYtcDI1
NiBySnMxSEEgQXo2azJGUjR5ZUFMVXRmZm12NzhVaGNxb1JCZHdYQm1TTG5QSi93 NiBySnMxSEEgQThoMTJnQkRBQWRtZVBqT3pqODdzMkxjUkh2NWFxZnQ4OE9ZdzZi
WTFJTGEKZW5pdnRUbmFlM1FNV3RtQVJmd3NVSmszT0hCZUc2V285Y0RDRTNGVlNZ VjB0OEIKRUdRdUt0Q0lUYjl6WE1IZGt1MlA1bFlHcTgxNzZzeWxlRXdPeGxPanNG
QQotPiBiYV0sLWdyZWFzZSAycFUxYSBxOF97dCBwKiB2Q1JeCjRKQ3czL1RtUTVZ ZwotPiBaOChOO3lBLWdyZWFzZSBVcid8SDYgTTQgZgo4YVFMbS9KbFUzTDNCSlNN
RVBUQTMwVVJtUEJBdUJXVDlZVVVVeENuY0ZhUWRLbXBycTEzSHhWaFltb1pLN3k5 dWdHcVQ3QjRyaEVKCi0tLSBNc3d2ZWtIR3o4R2xab0U1b3YydkhBMVB0RzFmYUd4
UQotLS0gWk96N3U1aElBL1NBUzQ2UlFpSmdTWnN2cHpPaWV4aXAyb211dHJRekYw VStQb0hXTTRLeXVBCvsPJI93CZTHTCiNiWbRI4MiEcYm9t2CQ40vWZEtu223/4iQ
awpMQoWOGu/d8JcDYMr5954FuagIGNhNMRb7IBQpXQpDT9fjOCnkngU8p4YxcF5V VEYUk58tRs83+ngrAIoVizPwJ2K3dlVZ3DYEy3y8yTM7sV49Fy62SxE4UU6ZQiA8
sgReOo63cA0LnbXS+3v2oSDHCyiHKr25sTF4Bxw//jzg49uxT4Wsv9ieBlDTD2zn f1F3HqFaYPSPzjhxgQi79Go1B4D9f1y1hScggpr4NY2W2rQyg+wWus17SgW/ttAr
K6E+pph5fIkHAGpL +xbvskRp00E=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----