refactor: centralize host and user metadata

This commit is contained in:
2026-04-21 12:12:43 +02:00
parent 5cfd4d01c8
commit 6332c96d3e
33 changed files with 805 additions and 479 deletions
+11 -1
View File
@@ -1,12 +1,22 @@
{ ... }:
{
flake.modules.homeManager.bitwarden =
{ pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
user = config.meta.user;
primaryEmail = builtins.head (lib.filter (email: email.primary) (builtins.attrValues user.emails));
in
{
programs.rbw = {
enable = true;
settings = {
base_url = "https://vault.jelles.net";
email = primaryEmail.address;
pinentry = pkgs.pinentry-gnome3;
};
};
+31 -16
View File
@@ -1,15 +1,29 @@
{ inputs, config, ... }:
{ config, ... }:
let
nixosModules = config.flake.modules.nixos;
in
{
flake.modules.nixos.desktopBase = {
flake.modules.nixos."core-base" = {
imports = [
inputs.home-manager.nixosModules.home-manager
nixosModules."meta-host"
nixosModules."home-manager-base"
nixosModules.nix
nixosModules.systemBase
nixosModules.standardBoot
nixosModules.regionNl
nixosModules."region-nl"
nixosModules."sops-host"
];
};
flake.modules.nixos."server-base" = {
imports = [
nixosModules."core-base"
nixosModules.openssh
];
};
flake.modules.nixos."workstation-base" = {
imports = [
nixosModules."core-base"
nixosModules."standard-boot"
nixosModules.sddm
nixosModules.niri
nixosModules.audio
@@ -18,18 +32,19 @@ in
nixosModules.fonts
nixosModules.networking
nixosModules.printing
nixosModules.qbittorrentClient
nixosModules.sopsHost
nixosModules."qbittorrent-client"
];
home-manager = {
useGlobalPkgs = true;
backupFileExtension = "bak";
extraSpecialArgs = { inherit inputs; };
};
users.mutableUsers = false;
security.sudo.extraConfig = ''
Defaults env_keep+=SSH_AUTH_SOCK
'';
services.dbus.implementation = "broker";
programs.nix-ld.enable = true;
environment.localBinInPath = true;
};
flake.modules.nixos."portable-host" = {
hardware.enableRedistributableFirmware = true;
services.fwupd.enable = true;
};
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
flake.modules.homeManager.devTools =
flake.modules.homeManager."dev-tools" =
{ config, ... }:
{
home.sessionVariables.CARGO_HOME = "${config.xdg.dataHome}/cargo";
+21 -34
View File
@@ -1,17 +1,23 @@
{ ... }:
{
flake.modules.homeManager.email =
{ config, ... }:
{
config,
lib,
...
}:
let
realName = "Jelle Spreeuwenberg";
user = config.meta.user;
mkOffice365Account =
{
address,
primary,
...
}:
{
enable = true;
inherit address primary realName;
inherit address primary;
realName = user.realName;
userName = address;
thunderbird = {
enable = true;
@@ -26,10 +32,12 @@
{
address,
primary,
...
}:
{
enable = true;
inherit address primary realName;
inherit address primary;
realName = user.realName;
userName = address;
thunderbird.enable = true;
imap = {
@@ -45,6 +53,14 @@
tls.enable = true;
};
};
mkEmailAccount =
email:
if email.type == "office365" then
mkOffice365Account email
else if email.type == "mxrouting" then
mkMxrouteAccount email
else
throw "Unsupported email type `${email.type}` for ${config.home.username}";
in
{
programs.thunderbird = {
@@ -65,35 +81,6 @@
};
};
accounts.email.accounts =
if config.home.username == "ergon" then
{
work = mkOffice365Account {
address = "jelle.spreeuwenberg@yookr.org";
primary = true;
};
}
else
{
main = mkMxrouteAccount {
address = "mail@jelles.net";
primary = true;
};
old = mkMxrouteAccount {
address = "mail@jellespreeuwenberg.nl";
primary = false;
};
uni = mkOffice365Account {
address = "j.spreeuwenberg@student.tue.nl";
primary = false;
};
work = mkOffice365Account {
address = "jelle.spreeuwenberg@yookr.org";
primary = false;
};
};
accounts.email.accounts = lib.mapAttrs (_: mkEmailAccount) user.emails;
};
}
+9
View File
@@ -0,0 +1,9 @@
{ config, ... }:
let
homeModules = config.flake.modules.homeManager;
in
{
flake.modules.homeManager."ergon-workstation" = {
imports = [ homeModules.nix ];
};
}
+13 -1
View File
@@ -1,7 +1,15 @@
{ ... }:
{
flake.modules.homeManager.git =
{ ... }:
{
config,
lib,
...
}:
let
user = config.meta.user;
primaryEmail = builtins.head (lib.filter (email: email.primary) (builtins.attrValues user.emails));
in
{
programs.git = {
enable = true;
@@ -12,6 +20,10 @@
];
settings = {
init.defaultBranch = "main";
user = {
name = user.realName;
email = primaryEmail.address;
};
};
};
};
+26
View File
@@ -0,0 +1,26 @@
{
inputs,
config,
...
}:
let
homeModules = config.flake.modules.homeManager;
in
{
flake.modules.nixos."home-manager-base" =
{ ... }:
{
imports = [ inputs.home-manager.nixosModules.home-manager ];
home-manager = {
useGlobalPkgs = true;
backupFileExtension = "bak";
extraSpecialArgs = { inherit inputs; };
sharedModules = [ homeModules."meta-context" ];
};
security.sudo.extraConfig = ''
Defaults env_keep+=SSH_AUTH_SOCK
'';
};
}
+23
View File
@@ -0,0 +1,23 @@
{ config, ... }:
let
homeModules = config.flake.modules.homeManager;
in
{
flake.modules.homeManager."kiri-workstation" = {
imports = [
homeModules.nix
homeModules.bitwarden
homeModules.email
homeModules.pim
homeModules.mpv
homeModules.niri
homeModules.clipboard
homeModules."local-apps"
homeModules."qbittorrent-client"
homeModules.vicinae
homeModules.xdg
homeModules.theme
homeModules.noctalia
];
};
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
flake.modules.homeManager.localApps =
flake.modules.homeManager."local-apps" =
{ pkgs, ... }:
{
home.sessionVariables.BROWSER = "vivaldi";
+147
View File
@@ -0,0 +1,147 @@
{ lib, ... }:
let
emailType = lib.types.submodule (
{ ... }:
{
options = {
address = lib.mkOption {
type = lib.types.str;
};
primary = lib.mkOption {
type = lib.types.bool;
};
type = lib.mkOption {
type = lib.types.str;
};
};
}
);
userType = lib.types.submodule (
{ ... }:
{
options = {
name = lib.mkOption {
type = lib.types.str;
};
realName = lib.mkOption {
type = lib.types.str;
};
homeDirectory = lib.mkOption {
type = lib.types.str;
};
emails = lib.mkOption {
type = lib.types.attrsOf emailType;
};
};
}
);
displayModeType = lib.types.submodule (
{ ... }:
{
options = {
width = lib.mkOption {
type = lib.types.int;
};
height = lib.mkOption {
type = lib.types.int;
};
refresh = lib.mkOption {
type = lib.types.float;
};
};
}
);
displayType = lib.types.submodule (
{ ... }:
{
options = {
primary = lib.mkOption {
type = lib.types.bool;
default = false;
};
x = lib.mkOption {
type = lib.types.int;
};
y = lib.mkOption {
type = lib.types.int;
};
scale = lib.mkOption {
type = lib.types.nullOr lib.types.float;
default = null;
};
mode = lib.mkOption {
type = lib.types.nullOr displayModeType;
default = null;
};
};
}
);
hostType = lib.types.submodule (
{ ... }:
{
options = {
name = lib.mkOption {
type = lib.types.str;
};
kind = lib.mkOption {
type = lib.types.enum [
"server"
"workstation"
];
};
traits = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
};
displays = lib.mkOption {
type = lib.types.attrsOf displayType;
default = { };
};
users = lib.mkOption {
type = lib.types.attrsOf userType;
default = { };
};
};
}
);
in
{
flake.modules.nixos."meta-host" = {
options.meta.host = lib.mkOption {
type = hostType;
};
};
flake.modules.homeManager."meta-context" = {
options.meta = {
host = lib.mkOption {
type = lib.types.nullOr hostType;
default = null;
};
user = lib.mkOption {
type = lib.types.nullOr userType;
default = null;
};
};
};
}
+2 -4
View File
@@ -2,10 +2,8 @@
flake.modules.homeManager.neovim =
{
pkgs,
lib,
config,
inputs,
osConfig,
...
}:
{
@@ -119,8 +117,8 @@
# Hostname/ConfigDir needed for nixd
nixdExtras = {
nixpkgs = "import ${pkgs.path} {}";
nixos_options = ''(builtins.getFlake "path://${config.home.homeDirectory}/.config/nixos").nixosConfigurations.${osConfig.networking.hostName}.options'';
home_manager_options = ''(builtins.getFlake "path://${config.home.homeDirectory}/.config/nixos").nixosConfigurations.${osConfig.networking.hostName}.options.home-manager.users.type.getSubOptions []'';
nixos_options = ''(builtins.getFlake "path://${config.home.homeDirectory}/.config/nixos").nixosConfigurations.${config.meta.host.name}.options'';
home_manager_options = ''(builtins.getFlake "path://${config.home.homeDirectory}/.config/nixos").nixosConfigurations.${config.meta.host.name}.options.home-manager.users.type.getSubOptions []'';
};
# TODO: Put in separate theme file
+8
View File
@@ -1,4 +1,12 @@
{
flake.modules.nixos."server-firewall" = {
networking = {
firewall.enable = true;
firewall.allowPing = false;
nftables.enable = true;
};
};
flake.modules.nixos.networking = {
networking = {
nftables.enable = true;
+27 -1
View File
@@ -16,7 +16,32 @@
};
flake.modules.homeManager.niri =
{ config, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
outputs = lib.mapAttrs (
_: display:
{
position = {
x = display.x;
y = display.y;
};
}
// lib.optionalAttrs (display.primary or false) {
"focus-at-startup" = true;
}
// lib.optionalAttrs (display ? scale) {
inherit (display) scale;
}
// lib.optionalAttrs (display ? mode) {
inherit (display) mode;
}
) config.meta.host.displays;
in
{
home.sessionVariables.NIXOS_OZONE_WL = "1";
@@ -34,6 +59,7 @@
];
programs.niri.settings = {
inherit outputs;
environment.DISPLAY = ":0";
spawn-at-startup = [
{ command = [ "xwayland-satellite" ]; }
+2 -2
View File
@@ -1,12 +1,12 @@
{
flake.modules.nixos.qbittorrentClient = {
flake.modules.nixos."qbittorrent-client" = {
networking.firewall = {
allowedTCPPorts = [ 43864 ];
allowedUDPPorts = [ 43864 ];
};
};
flake.modules.homeManager.qbittorrentClient =
flake.modules.homeManager."qbittorrent-client" =
{ pkgs, ... }:
{
home.packages = [ pkgs.qbittorrent ];
+1 -1
View File
@@ -1,6 +1,6 @@
{ ... }:
{
flake.modules.nixos.regionNl = {
flake.modules.nixos."region-nl" = {
time.timeZone = "Europe/Amsterdam";
i18n.defaultLocale = "en_US.UTF-8";
+20 -12
View File
@@ -1,17 +1,25 @@
{ config, ... }:
let
metaLib = config.meta.lib;
in
{
flake.modules.nixos.actual =
{ config, ... }:
{
services.actual = {
enable = true;
openFirewall = false;
settings = {
port = 3000;
hostname = "127.0.0.1";
{ lib, ... }:
lib.mkMerge [
{
services.actual = {
enable = true;
openFirewall = false;
settings = {
port = 3000;
hostname = "127.0.0.1";
};
};
};
}
services.caddy.virtualHosts."finance.jelles.net".extraConfig =
"reverse_proxy :${toString config.services.actual.settings.port}";
};
(metaLib.mkCaddyReverseProxy {
domain = "finance.jelles.net";
port = 3000;
})
];
}
+2 -2
View File
@@ -1,5 +1,5 @@
{
flake.modules.nixos.delugeService =
flake.modules.nixos."deluge-service" =
{ ... }:
{
sops.secrets.deluge-auth-file = { };
@@ -10,7 +10,7 @@
};
};
flake.modules.homeManager.delugeClient =
flake.modules.homeManager."deluge-client" =
{ pkgs, ... }:
{
home.packages = [ pkgs.deluge ];
+29 -19
View File
@@ -1,28 +1,38 @@
{ config, ... }:
let
metaLib = config.meta.lib;
in
{
flake.modules.nixos.gitea =
{ config, ... }:
{
services.gitea = {
enable = true;
{ lib, ... }:
lib.mkMerge [
{
services.gitea = {
enable = true;
settings = {
server = {
DOMAIN = "git.jelles.net";
ROOT_URL = "https://git.jelles.net/";
HTTP_PORT = 3001;
HTTP_ADDR = "127.0.0.1";
settings = {
server = {
DOMAIN = "git.jelles.net";
ROOT_URL = "https://git.jelles.net/";
HTTP_PORT = 3001;
HTTP_ADDR = "127.0.0.1";
START_SSH_SERVER = false;
SSH_PORT = 22;
START_SSH_SERVER = false;
SSH_PORT = 22;
};
service.DISABLE_REGISTRATION = true;
};
service.DISABLE_REGISTRATION = true;
};
};
}
services.openssh.settings.AllowUsers = [ "gitea" ];
{
services.openssh.settings.AllowUsers = [ "gitea" ];
}
services.caddy.virtualHosts."git.jelles.net".extraConfig =
"reverse_proxy :${toString config.services.gitea.settings.server.HTTP_PORT}";
};
(metaLib.mkCaddyReverseProxy {
domain = "git.jelles.net";
port = 3001;
})
];
}
+9 -6
View File
@@ -1,17 +1,20 @@
{ ... }:
{
flake.modules.nixos."ssh-agent-auth" = {
security.pam = {
sshAgentAuth.enable = true;
services.sudo.sshAgentAuth = true;
};
};
flake.modules.nixos.openssh =
{
config,
hostType ? "desktop",
lib,
...
}:
let
isServer = hostType == "server";
hostUserNames = builtins.attrNames (
lib.filterAttrs (_: user: user.isNormalUser or false) config.users.users
);
isServer = config.meta.host.kind == "server";
hostUserNames = builtins.attrNames config.meta.host.users;
in
{
services.openssh = {
+38 -20
View File
@@ -1,27 +1,45 @@
{ config, ... }:
let
metaLib = config.meta.lib;
in
{
flake.modules.nixos.radicale =
{ ... }:
{
services.radicale = {
enable = true;
settings = {
server.hosts = [ "127.0.0.1:5232" ];
{ lib, ... }:
lib.mkMerge [
{
services.radicale = {
enable = true;
settings = {
server.hosts = [ "127.0.0.1:5232" ];
auth = {
type = "htpasswd";
htpasswd_filename = "/var/lib/radicale/users";
htpasswd_encryption = "bcrypt";
auth = {
type = "htpasswd";
htpasswd_filename = "/var/lib/radicale/users";
htpasswd_encryption = "bcrypt";
};
storage.filesystem_folder = "/var/lib/radicale/collections";
};
storage.filesystem_folder = "/var/lib/radicale/collections";
};
};
}
services.caddy.virtualHosts."radicale.jelles.net".extraConfig = ''
reverse_proxy :5232 {
header_up X-Script-Name /
header_up X-Forwarded-For {remote}
header_up X-Remote-User {http.auth.user.id}
}'';
};
(metaLib.mkCaddyReverseProxy {
domain = "radicale.jelles.net";
port = 5232;
extraHeaders = [
{
name = "X-Script-Name";
value = "/";
}
{
name = "X-Forwarded-For";
value = "{remote}";
}
{
name = "X-Remote-User";
value = "{http.auth.user.id}";
}
];
})
];
}
+22 -14
View File
@@ -1,19 +1,27 @@
{ config, ... }:
let
metaLib = config.meta.lib;
in
{
flake.modules.nixos.vaultwarden =
{ config, ... }:
{
services.vaultwarden = {
enable = true;
backupDir = "/var/backup/vaultwarden";
config = {
DOMAIN = "https://vault.jelles.net";
SIGNUPS_ALLOWED = false;
ROCKET_PORT = 8100;
ROCKET_LOG = "critical";
{ lib, ... }:
lib.mkMerge [
{
services.vaultwarden = {
enable = true;
backupDir = "/var/backup/vaultwarden";
config = {
DOMAIN = "https://vault.jelles.net";
SIGNUPS_ALLOWED = false;
ROCKET_PORT = 8100;
ROCKET_LOG = "critical";
};
};
};
}
services.caddy.virtualHosts."vault.jelles.net".extraConfig =
"reverse_proxy :${toString config.services.vaultwarden.config.ROCKET_PORT}";
};
(metaLib.mkCaddyReverseProxy {
domain = "vault.jelles.net";
port = 8100;
})
];
}
+5 -1
View File
@@ -1,4 +1,5 @@
{
flake.modules.homeManager.shell =
{ lib, config, ... }:
{
@@ -145,7 +146,10 @@
};
};
programs.eza.enable = true;
programs.eza = {
enable = true;
extraOptions = [ "--group-directories-first" ];
};
programs.fzf = {
enable = true;
enableZshIntegration = true;
+1 -1
View File
@@ -1,5 +1,5 @@
{
flake.modules.homeManager.sshClient =
flake.modules.homeManager."ssh-client" =
{ config, ... }:
{
programs.ssh = {
+17 -2
View File
@@ -1,7 +1,7 @@
{ ... }:
{
flake.modules.nixos.standardBoot =
{ pkgs, ... }:
flake.modules.nixos."standard-boot" =
{ config, pkgs, ... }:
{
boot = {
loader = {
@@ -10,6 +10,21 @@
enable = true;
consoleMode = "auto";
configurationLimit = 5;
extraInstallCommands = ''
ENTRIES="${config.boot.loader.efi.efiSysMountPoint}/loader/entries"
PROFILES="/nix/var/nix/profiles"
for file in "$ENTRIES"/nixos-generation-*.conf; do
generation=$(${pkgs.coreutils}/bin/basename "$file" | ${pkgs.gnugrep}/bin/grep -o -E '[0-9]+')
timestamp=$(${pkgs.coreutils}/bin/stat -c %y "$PROFILES/system-$generation-link" 2>/dev/null | ${pkgs.coreutils}/bin/cut -d. -f1)
if [ -z "$timestamp" ]; then
timestamp="Unknown Date"
fi
${pkgs.gnused}/bin/sed -i "s/^version .*/version Generation $generation - $timestamp/" "$file"
done
'';
};
};
-10
View File
@@ -1,10 +0,0 @@
{
flake.modules.nixos.systemBase = {
users.mutableUsers = false;
services.dbus.implementation = "broker";
programs.nix-ld.enable = true;
environment.localBinInPath = true;
};
}
+11 -11
View File
@@ -3,17 +3,17 @@ let
homeModules = config.flake.modules.homeManager;
in
{
flake.modules.homeManager.userBase = {
imports = with homeModules; [
terminal
shell
neovim
sshClient
sopsAdmin
git
devTools
podman
gemini
flake.modules.homeManager."user-base" = {
imports = [
homeModules.terminal
homeModules.shell
homeModules.neovim
homeModules."ssh-client"
homeModules."sops-admin"
homeModules.git
homeModules."dev-tools"
homeModules.podman
homeModules.gemini
];
};
}