feat(luna): massively overhaul config, add gitea
This commit is contained in:
parent
41c10d1606
commit
1f615e4632
26
.editorconfig
Normal file
26
.editorconfig
Normal 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
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
.direnv/
|
||||
*.ignore
|
||||
.nixd.json
|
12
.nixd.nix
Normal file
12
.nixd.nix
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
formatting = {
|
||||
command = "nixpkgs-fmt";
|
||||
};
|
||||
options = {
|
||||
enable = true;
|
||||
target = {
|
||||
args = [];
|
||||
installable = ".#nixosConfigurations.luna.options";
|
||||
};
|
||||
};
|
||||
}
|
125
flake.lock
125
flake.lock
@ -68,6 +68,26 @@
|
||||
"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": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@ -75,11 +95,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1706145859,
|
||||
"narHash": "sha256-+iGHKwzKVW6aGAWfUmUSJW1KiE6WLYhKyTyWZMTw/cg=",
|
||||
"lastModified": 1706491084,
|
||||
"narHash": "sha256-eaEv+orTmr2arXpoE4aFZQMVPOYXCBEbLgK22kOtkhs=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "5a2dc95464080764b9ca1b82b5d6d981157522be",
|
||||
"rev": "f67ba6552845ea5d7f596a24d57c33a8a9dc8de9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -88,6 +108,38 @@
|
||||
"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": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
@ -108,7 +160,7 @@
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_3"
|
||||
"systems": "systems_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
@ -147,11 +199,11 @@
|
||||
},
|
||||
"impermanence": {
|
||||
"locked": {
|
||||
"lastModified": 1703656108,
|
||||
"narHash": "sha256-hCSUqdFJKHHbER8Cenf5JRzjMlBjIdwdftGQsO0xoJs=",
|
||||
"lastModified": 1706639736,
|
||||
"narHash": "sha256-CaG4j9+UwBDfinxxvJMo6yOonSmSo0ZgnbD7aj2Put0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "impermanence",
|
||||
"rev": "033643a45a4a920660ef91caa391fbffb14da466",
|
||||
"rev": "cd13c2917eaa68e4c49fea0ff9cada45440d7045",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -162,11 +214,27 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1705856552,
|
||||
"narHash": "sha256-JXfnuEf5Yd6bhMs/uvM67/joxYKoysyE3M2k6T3eWbg=",
|
||||
"lastModified": 1702272962,
|
||||
"narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=",
|
||||
"owner": "NixOS",
|
||||
"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"
|
||||
},
|
||||
"original": {
|
||||
@ -180,10 +248,12 @@
|
||||
"inputs": {
|
||||
"agenix": "agenix",
|
||||
"blog": "blog",
|
||||
"deploy-rs": "deploy-rs",
|
||||
"disko": "disko",
|
||||
"flake-compat": "flake-compat_2",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"impermanence": "impermanence",
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
@ -230,6 +300,39 @@
|
||||
"repo": "default",
|
||||
"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",
|
||||
|
53
flake.nix
53
flake.nix
@ -1,9 +1,10 @@
|
||||
{
|
||||
description = "Price Hiller's flake for managing system configurations";
|
||||
description = "Asgard Eternal's flake for managing system configurations";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
deploy-rs.url = "github:serokell/deploy-rs";
|
||||
impermanence = {
|
||||
url = "github:nix-community/impermanence";
|
||||
};
|
||||
@ -15,6 +16,11 @@
|
||||
url = "github:nix-community/disko";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
# For the nixd language server
|
||||
flake-compat = {
|
||||
url = "github:inclyc/flake-compat";
|
||||
flake = false;
|
||||
};
|
||||
blog = {
|
||||
type = "gitlab";
|
||||
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
|
||||
lib = import ./lib // nixpkgs.lib;
|
||||
pkgs = nixpkgs.legacyPackages."x86_64-linux";
|
||||
lib = (import ./lib { lib = nixpkgs.lib; }) // nixpkgs.lib;
|
||||
persist-dir = "/persist";
|
||||
defaults = {
|
||||
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 = {
|
||||
hideMounts = true;
|
||||
persistentStoragePath = "/nix/persist/save";
|
||||
persistentStoragePath = "${persist-dir}/save";
|
||||
};
|
||||
environment.persistence.ephemeral = {
|
||||
persistentStoragePath = "/nix/persist/ephemeral";
|
||||
persistentStoragePath = "${persist-dir}/ephemeral";
|
||||
hideMounts = true;
|
||||
directories = [
|
||||
"/var/lib"
|
||||
"/var/log"
|
||||
"/etc/nixos"
|
||||
{ directory = "/persist"; user = "root"; group = "root"; mode = "0700"; }
|
||||
];
|
||||
};
|
||||
};
|
||||
@ -58,27 +64,41 @@
|
||||
system = "x86_64-linux";
|
||||
specialArgs = {
|
||||
inherit self;
|
||||
inherit blog;
|
||||
inherit flake-utils;
|
||||
inherit inputs;
|
||||
inherit hostname;
|
||||
inherit nixpkgs;
|
||||
inherit lib;
|
||||
inherit blog;
|
||||
secrets = "${self}/secrets/${hostname}";
|
||||
disk = "nvme0n1";
|
||||
inherit persist-dir;
|
||||
root-disk = "/dev/nvme0n1";
|
||||
fqdn = "orion-technologies.io";
|
||||
};
|
||||
modules = [
|
||||
{
|
||||
_module.args = { };
|
||||
}
|
||||
defaults
|
||||
impermanence.nixosModules.impermanence
|
||||
agenix.nixosModules.default
|
||||
disko.nixosModules.disko
|
||||
{ config = (import "${self}/secrets" { agenix = false; inherit lib; }).${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:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
@ -90,10 +110,11 @@
|
||||
devShells.default =
|
||||
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 = ''
|
||||
export RULES="$PWD/secrets/secrets.nix"
|
||||
nix eval --json --file ./.nixd.nix > .nixd.json
|
||||
'';
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
{ config, lib, nixpkgs, ... }:
|
||||
{
|
||||
|
||||
imports = (lib.recurseFilesInDirs [ ./os ./modules ] ".nix");
|
||||
system.stateVersion = "24.05";
|
||||
}
|
||||
}
|
@ -2,4 +2,7 @@
|
||||
|
||||
{
|
||||
time.timeZone = "America/Chicago";
|
||||
}
|
||||
systemd.extraConfig = ''
|
||||
DefaultTimeoutStopSec=10s
|
||||
'';
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
{ secrets, config, specialArgs, fqdn, ... }:
|
||||
{ config, specialArgs, fqdn, ... }:
|
||||
let
|
||||
gitlab_home = "/var/lib/gitlab";
|
||||
gitlab_host = "gitlab.${fqdn}";
|
||||
@ -42,7 +42,6 @@ in
|
||||
2222
|
||||
];
|
||||
|
||||
age.secrets.gitlab-runner-reg-config.file = "${secrets}/gitlab-runner-reg-config.age";
|
||||
services.gitlab-runner = {
|
||||
enable = true;
|
||||
services = {
|
||||
|
@ -4,4 +4,4 @@
|
||||
enable = true;
|
||||
maxretry = 10;
|
||||
};
|
||||
}
|
||||
}
|
77
hosts/luna/modules/services/gitea.nix
Normal file
77
hosts/luna/modules/services/gitea.nix
Normal 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;
|
||||
}];
|
||||
}
|
@ -18,5 +18,4 @@
|
||||
root = blog.packages.${pkgs.system}.default;
|
||||
locations."/".index = "home.html";
|
||||
};
|
||||
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
startWhenNeeded = true;
|
||||
# We set the hostkeys manually so they persist through reboots
|
||||
hostKeys = [
|
||||
{
|
||||
@ -19,6 +20,7 @@
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
PermitRootLogin = "no";
|
||||
GatewayPorts = "yes";
|
||||
LogLevel = "VERBOSE";
|
||||
KexAlgorithms = [
|
||||
"curve25519-sha256"
|
||||
@ -57,4 +59,4 @@
|
||||
└────────────────────────────────────────────────────┘
|
||||
'';
|
||||
};
|
||||
}
|
||||
}
|
33
hosts/luna/modules/services/postgresql.nix
Normal file
33
hosts/luna/modules/services/postgresql.nix
Normal 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"; }
|
||||
];
|
||||
}
|
@ -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;
|
||||
users.users = {
|
||||
root.hashedPasswordFile = config.age.secrets.root-pw.path;
|
||||
@ -14,4 +12,4 @@
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
@ -7,8 +7,15 @@
|
||||
];
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
kernelParams = [ "audit=1" ];
|
||||
extraModulePackages = [ ];
|
||||
initrd = {
|
||||
availableKernelModules = [ "xhci_pci" "ahci" "nvme" "uas" "sd_mod" ];
|
||||
availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
|
||||
kernelModules = [ ];
|
||||
systemd = {
|
||||
enable = true;
|
||||
@ -23,17 +30,24 @@
|
||||
script = ''
|
||||
mkdir -p /mnt
|
||||
DISK_LABEL="NixOS-Primary"
|
||||
ATTEMPTS=5
|
||||
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 3
|
||||
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" }' \
|
||||
@ -53,12 +67,6 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
loader = {
|
||||
systemd-boot.enable = true;
|
||||
efi.canTouchEfiVariables = true;
|
||||
};
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
extraModulePackages = [ ];
|
||||
};
|
||||
|
||||
}
|
||||
}
|
@ -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
87
hosts/luna/os/fs.nix
Normal 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" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1 +1 @@
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF5AtCUEvm9pSi8iI4xH5wnJ6dR9tZZY7qPS4GLJbQAW luna"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJO2ufKRT1NCwp4c9cbOjxfb+/XlY8AUgnDLObA0gYaB luna"
|
21
install.bash
Normal file → Executable file
21
install.bash
Normal file → Executable file
@ -40,14 +40,15 @@ gen-system-key() {
|
||||
}
|
||||
|
||||
main() {
|
||||
local persist_dir="/mnt/nix/persist"
|
||||
local persist_dir="/mnt/persist"
|
||||
local flake_install_path="${persist_dir}/ephemeral/etc/nixos"
|
||||
|
||||
local system="${1:?"Provide system to build!"}"
|
||||
local flake=".#${system}"
|
||||
local conn="${2:?"Provide ssh connection string! (E.g. root@myhost)"}"
|
||||
local priv_key_path="${3:?Provide path to private key}"
|
||||
shift 3
|
||||
local ssh_port="${4:-22}"
|
||||
|
||||
if [[ ! -r "${priv_key_path}" ]]; then
|
||||
printf "Unable a private key file at '%s'\n!" "${priv_key_path}" 1>&2
|
||||
exit 1
|
||||
@ -67,9 +68,9 @@ main() {
|
||||
local new_sys_key
|
||||
new_sys_key="$(gen-system-key "${system}" "${priv_key_path}")"
|
||||
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_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 system_key_dest="${persist_dir}/ephemeral/etc/ssh/ssh_host_ed25519_key"
|
||||
printf "SSH Command: %s\n" "${ssh_cmd}"
|
||||
@ -80,18 +81,20 @@ main() {
|
||||
printf "Putting new system key into place\n"
|
||||
printf "%s\n" "${new_sys_key}" > "${system_key_dest}"
|
||||
chmod 0600 "${system_key_dest}"
|
||||
printf "Installing rsync for later stage\n"
|
||||
nix-env -f '<nixpkgs>' -iA rsync
|
||||
__EOS__
|
||||
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"
|
||||
eval "${ssh_cmd}" <<- __EOS__
|
||||
set -euo pipefail
|
||||
cd "${flake_install_path}"
|
||||
nix-env -f '<nixpkgs>' -iA git
|
||||
sudo nixos-install --flake "git+file:${flake}" --no-root-password --no-channel-copy
|
||||
reboot
|
||||
sudo nixos-install --flake "git+file:${flake}" --no-root-password --no-channel-copy && reboot
|
||||
__EOS__
|
||||
printf "%s\n" "${ssh_cmd}"
|
||||
|
||||
cat <<- __EOS__
|
||||
──────────────────────────────────────────
|
||||
@ -103,4 +106,4 @@ main() {
|
||||
__EOS__
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
main "${@}"
|
@ -1,4 +1,5 @@
|
||||
# Some of these functions were taken from https://github.com/NixOS/nixpkgs/blob/master/lib/
|
||||
{ lib ? (import <nixpkgs> { }).lib }:
|
||||
rec {
|
||||
hasSuffix =
|
||||
suffix:
|
||||
@ -29,4 +30,19 @@ rec {
|
||||
(builtins.filter (file: hasSuffix "${suffix}" file) (recurseDir dir));
|
||||
recurseFilesInDirs = dirs: suffix:
|
||||
(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
46
secrets/default.nix
Normal 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)
|
8
secrets/luna/gitea-db-pass.age
Normal file
8
secrets/luna/gitea-db-pass.age
Normal 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
|
@ -1,10 +1,7 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 4sH96w zBi3BGIf/OJza0ADpk264QCudT5mKzxcxgfxoNI9HSw
|
||||
8Ys6frvd7UeXRXPpiClCJ+qoRHiE7K+TfQhbb1o34bk
|
||||
-> piv-p256 rJs1HA Aw/GcBY+XMD/9++r819joYKKyIrf8gbpjgIgugLhBtBq
|
||||
BTIRQ/6zl2HqJJrCGbeMwAwmp65EiU5jAs130/MoHOs
|
||||
-> OKjJEPyZ-grease l {KDS$m oX;O="m
|
||||
29gF4VbnR6zEbojhshhTvk2tYizn32MsCDsuutl+HCmVTNPvDIkWRSMPylfsZqLY
|
||||
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/çßâ°
|
||||
-> ssh-ed25519 1fG0ow oP4nP83S4Hjf4MScoNCBbE3i4Vnzz5XiuJqaLXzRbw0
|
||||
rNOkeT8FfDLCoUnghLs8/Fpzy4qINhhIhtgB3Ep3REc
|
||||
-> piv-p256 rJs1HA AiyT5IFnxwxoONmRezlvneUSYSEjglGeXYav8x7Xt+HB
|
||||
JWAyCMNQNe0+LSRqdQV+f5PGixWMXFMf/wQmyoMEKNE
|
||||
--- ZnfbHqBM/51+BXYGhcSzBN6k1UtZpKJshgmxrr2eFGo
|
||||
ô<EFBFBD>™?f èÇíÇ$®À<08>Æ‚bt,ñ$åÌ<C3A5>á€o8R«¸ûò;¾Øn!õchzg•ý‰—lÁ= 5îOcâÀ—¯BNJ‹ð½„ÉaH1Ï‚ýuƒ?ÙQCþfºN{†$ûM¨wLbs¾€:+•Ãá?Z†C0™òÚ
|
Binary file not shown.
@ -1,29 +1 @@
|
||||
let
|
||||
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)))
|
||||
import ./default.nix { agenix = true; }
|
Loading…
Reference in New Issue
Block a user