diff --git a/modules/data.nix b/modules/data.nix index 40f1f86..7668c7e 100644 --- a/modules/data.nix +++ b/modules/data.nix @@ -1,46 +1,187 @@ -{ lib, ... }: +{ + config, + ... +}: let - accounts = { - kiri = { - realName = "Jelle Spreeuwenberg"; - emails = { - personal = { - address = "mail@jelles.net"; - primary = true; - type = "mxrouting"; + homeModules = config.flake.modules.homeManager; +in +{ + repo = { + accounts = { + kiri = { + realName = "Jelle Spreeuwenberg"; + workstationModule = { + imports = [ + homeModules.workstation-base + homeModules.syncthing + homeModules.qbittorrent-client + ]; }; - old = { - address = "mail@jellespreeuwenberg.nl"; - type = "mxrouting"; + emails = { + personal = { + address = "mail@jelles.net"; + primary = true; + scope = "personal"; + type = "mxrouting"; + }; + old = { + address = "mail@jellespreeuwenberg.nl"; + scope = null; + type = "mxrouting"; + }; + uni = { + address = "j.spreeuwenberg@student.tue.nl"; + scope = null; + type = "office365"; + }; + work = { + address = "jelle.spreeuwenberg@yookr.org"; + scope = "work"; + type = "office365"; + }; }; - uni = { - address = "j.spreeuwenberg@student.tue.nl"; - type = "office365"; + }; + + ergon = { + realName = "Jelle Spreeuwenberg"; + sourceControl.projectScope = "work"; + workstationModule = { + imports = [ homeModules.workstation-base ]; }; - work = { - address = "jelle.spreeuwenberg@yookr.org"; - type = "office365"; + emails = { + personal = { + address = "mail@jelles.net"; + scope = "personal"; + type = "mxrouting"; + }; + work = { + address = "jelle.spreeuwenberg@yookr.org"; + primary = true; + scope = "work"; + type = "office365"; + }; }; }; }; - ergon = { - realName = "Jelle Spreeuwenberg"; - emails = { - personal = { - address = "mail@jelles.net"; - type = "mxrouting"; - }; - work = { - address = "jelle.spreeuwenberg@yookr.org"; - primary = true; - type = "office365"; + contact.email = "mail@jelles.net"; + + desktop = { + browser = { + command = "vivaldi"; + packagePath = [ "vivaldi" ]; + }; + + fileManager = { + command = "nautilus"; + packagePath = [ "nautilus" ]; + }; + + terminal = { + command = "kitty"; + desktopId = "kitty.desktop"; + packagePath = [ "kitty" ]; + }; + }; + + services = { + actual = { + domain = "finance.jelles.net"; + host = "127.0.0.1"; + port = 3000; + url = "https://finance.jelles.net"; + }; + + gitea = { + domain = "git.jelles.net"; + host = "127.0.0.1"; + port = 3001; + url = "https://git.jelles.net/"; + }; + + radicale = { + domain = "radicale.jelles.net"; + host = "127.0.0.1"; + port = 5232; + url = "https://radicale.jelles.net/"; + }; + + vaultwarden = { + domain = "vault.jelles.net"; + host = "127.0.0.1"; + port = 8100; + url = "https://vault.jelles.net"; + }; + }; + + theme = { + cursor = { + name = "phinger-cursors-light"; + packagePath = [ "phinger-cursors" ]; + size = 24; + }; + + kanagawa = { + displayName = "Kanagawa Wave"; + name = "kanagawa-wave"; + gtkThemeName = "Kanagawa-BL-LB"; + iconThemeName = "Kanagawa"; + owner = "Fausto-Korpsvart"; + repo = "Kanagawa-GKT-Theme"; + rev = "55ca4ba249eba21f861b9866b71ab41bb8930318"; + hash = "sha256-UdMoMx2DoovcxSp/zBZ3PRv/Qpj+prd0uPm1gmdak2E="; + version = "unstable-2025-10-23"; + + palette = { + background = "#1F1F28"; + foreground = "#DCD7BA"; + secondaryBackground = "#16161D"; + border = "#2A2A37"; + selectionBackground = "#2D4F67"; + selectionForeground = "#C8C093"; + url = "#72A7BC"; + cursor = "#C8C093"; + muted = "#727169"; + + accents = { + blue = "#7E9CD8"; + green = "#98BB6C"; + magenta = "#D27E99"; + orange = "#FFA066"; + purple = "#957FB8"; + red = "#E82424"; + yellow = "#E6C384"; + cyan = "#7AA89F"; + }; + + niri.border = { + active = "#7E9CD8"; + inactive = "#54546D"; + urgent = "#E82424"; + }; + + terminal = { + color0 = "#16161D"; + color1 = "#C34043"; + color2 = "#76946A"; + color3 = "#C0A36E"; + color4 = "#7E9CD8"; + color5 = "#957FB8"; + color6 = "#6A9589"; + color7 = "#C8C093"; + color8 = "#727169"; + color9 = "#E82424"; + color10 = "#98BB6C"; + color11 = "#E6C384"; + color12 = "#7FB4CA"; + color13 = "#938AA9"; + color14 = "#7AA89F"; + color15 = "#DCD7BA"; + color16 = "#FFA066"; + color17 = "#FF5D62"; + }; }; }; }; }; - -in -{ - repo.accounts = accounts; } diff --git a/modules/features/ai.nix b/modules/features/ai.nix index 0b659bf..21c5886 100644 --- a/modules/features/ai.nix +++ b/modules/features/ai.nix @@ -61,7 +61,7 @@ in "context-remaining" "five-hour-limit" ]; - projects.${config.meta.user.nixosConfigurationPath}.trust_level = "trusted"; + projects.${config.meta.user.account.nixosConfigurationPath}.trust_level = "trusted"; sandbox_mode = "workspace-write"; personality = "pragmatic"; features.undo = true; diff --git a/modules/features/bitwarden.nix b/modules/features/bitwarden.nix index c5f1ca5..f824deb 100644 --- a/modules/features/bitwarden.nix +++ b/modules/features/bitwarden.nix @@ -3,7 +3,7 @@ ... }: let - metaRepo = config.meta.lib.repo; + repo = config.repo; in { flake.modules.homeManager.bitwarden = @@ -13,14 +13,14 @@ in ... }: let - user = config.meta.user; + account = config.meta.user.account; in { programs.rbw = { enable = true; settings = { - base_url = metaRepo.services.vaultwarden.url; - email = user.primaryEmail.address; + base_url = repo.services.vaultwarden.url; + email = account.primaryEmail.address; pinentry = pkgs.pinentry-gnome3; }; }; diff --git a/modules/features/email.nix b/modules/features/email.nix index 40a11e9..746141a 100644 --- a/modules/features/email.nix +++ b/modules/features/email.nix @@ -7,7 +7,7 @@ ... }: let - user = config.meta.user; + account = config.meta.user.account; mkOffice365Account = { address, @@ -17,7 +17,7 @@ { enable = true; inherit address primary; - realName = user.realName; + realName = account.realName; userName = address; thunderbird = { enable = true; @@ -37,7 +37,7 @@ { enable = true; inherit address primary; - realName = user.realName; + realName = account.realName; userName = address; thunderbird.enable = true; imap = { @@ -81,6 +81,6 @@ }; }; - accounts.email.accounts = lib.mapAttrs (_: mkEmailAccount) user.emails; + accounts.email.accounts = lib.mapAttrs (_: mkEmailAccount) account.emails; }; } diff --git a/modules/features/git.nix b/modules/features/git.nix index 1df199c..56b45e7 100644 --- a/modules/features/git.nix +++ b/modules/features/git.nix @@ -6,7 +6,7 @@ ... }: let - user = config.meta.user; + account = config.meta.user.account; in { programs.git = { @@ -19,8 +19,8 @@ settings = { init.defaultBranch = "main"; user = { - name = user.realName; - email = user.primaryEmail.address; + name = account.realName; + email = account.primaryEmail.address; }; }; }; diff --git a/modules/features/input.nix b/modules/features/input.nix deleted file mode 100644 index 3724602..0000000 --- a/modules/features/input.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - config, - ... -}: -let - metaLib = config.meta.lib; -in -{ - flake.modules.nixos.input = - { - lib, - config, - ... - }: - let - inputProfiles = metaLib.mkInputProfiles config.meta.host.input; - in - { - services.libinput = lib.mkIf inputProfiles.hasPointerConfig { - enable = true; - inherit (inputProfiles.libinput) - mouse - touchpad - ; - }; - }; -} diff --git a/modules/features/local-apps.nix b/modules/features/local-apps.nix index c03108a..48ab463 100644 --- a/modules/features/local-apps.nix +++ b/modules/features/local-apps.nix @@ -1,18 +1,19 @@ { config, ... }: let - metaRepo = config.meta.lib.repo; + repo = config.repo; + repoHelpers = repo.helpers; in { flake.modules.homeManager.local-apps = { pkgs, ... }: let - browserPackage = config.meta.lib.resolvePackagePath { + browserPackage = repoHelpers.resolvePackagePath { inherit pkgs; - path = metaRepo.desktop.browser.packagePath; + path = repo.desktop.browser.packagePath; }; in { - home.sessionVariables.BROWSER = metaRepo.desktop.browser.command; + home.sessionVariables.BROWSER = repo.desktop.browser.command; home.packages = with pkgs; diff --git a/modules/features/neovim/default.nix b/modules/features/neovim/default.nix index 7d0fa2c..26587d2 100644 --- a/modules/features/neovim/default.nix +++ b/modules/features/neovim/default.nix @@ -1,6 +1,6 @@ { config, ... }: let - repoTheme = config.meta.lib.repo.theme.kanagawa; + repoTheme = config.repo.theme.kanagawa; in { flake.modules.homeManager.neovim = @@ -113,8 +113,8 @@ in # Hostname/ConfigDir needed for nixd nixdExtras = { nixpkgs = "import ${pkgs.path} {}"; - nixos_options = ''(builtins.getFlake "path://${config.meta.user.nixosConfigurationPath}").nixosConfigurations.${config.meta.host.name}.options''; - home_manager_options = ''(builtins.getFlake "path://${config.meta.user.nixosConfigurationPath}").nixosConfigurations.${config.meta.host.name}.options.home-manager.users.type.getSubOptions []''; + nixos_options = ''(builtins.getFlake "path://${config.meta.user.account.nixosConfigurationPath}").nixosConfigurations.${config.meta.machine.name}.options''; + home_manager_options = ''(builtins.getFlake "path://${config.meta.user.account.nixosConfigurationPath}").nixosConfigurations.${config.meta.machine.name}.options.home-manager.users.type.getSubOptions []''; }; themeSetup = import ./_kanagawa-theme.nix { diff --git a/modules/features/nh.nix b/modules/features/nh.nix index 384129e..6f18ad4 100644 --- a/modules/features/nh.nix +++ b/modules/features/nh.nix @@ -4,7 +4,7 @@ { programs.nh = { enable = true; - flake = config.meta.user.nixosConfigurationPath; + flake = config.meta.user.account.nixosConfigurationPath; }; }; } diff --git a/modules/features/niri/default.nix b/modules/features/niri/default.nix index 975c97b..60ea484 100644 --- a/modules/features/niri/default.nix +++ b/modules/features/niri/default.nix @@ -4,8 +4,8 @@ ... }: let - metaLib = config.meta.lib; - metaRepo = metaLib.repo; + repo = config.repo; + repoHelpers = repo.helpers; in { flake.modules.nixos.niri = @@ -31,11 +31,15 @@ in ... }: let - repoTheme = metaRepo.theme.kanagawa; - browserCommand = metaRepo.desktop.browser.command; - fileManagerPackage = metaLib.resolvePackagePath { + repoTheme = repo.theme.kanagawa; + browserCommand = repo.desktop.browser.command; + fileManagerPackage = repoHelpers.resolvePackagePath { inherit pkgs; - path = metaRepo.desktop.fileManager.packagePath; + path = repo.desktop.fileManager.packagePath; + }; + terminalPackage = repoHelpers.resolvePackagePath { + inherit pkgs; + path = repo.desktop.terminal.packagePath; }; outputs = lib.mapAttrs ( _: display: @@ -51,19 +55,24 @@ in // lib.optionalAttrs (display.scale != null) { inherit (display) scale; } - // lib.optionalAttrs (display.mode != null) { - inherit (display) mode; + // lib.optionalAttrs (display.width != null && display.height != null && display.refresh != null) { + mode = { + inherit (display) + width + height + refresh + ; + }; } - ) config.meta.host.displays; - inputProfiles = metaLib.mkInputProfiles config.meta.host.input; - terminal = metaLib.resolveRepoTerminal { - inherit pkgs; - }; + ) config.meta.machine.displays; in { - assertions = metaLib.mkTerminalAssertions { - inherit terminal; - }; + assertions = [ + { + assertion = fileManagerPackage != null; + message = "Unknown file manager package `${lib.showAttrPath repo.desktop.fileManager.packagePath}`."; + } + ]; home.sessionVariables.NIXOS_OZONE_WL = "1"; @@ -138,27 +147,22 @@ in input = { focus-follows-mouse.enable = true; + mouse."accel-speed" = 0.4; keyboard = { repeat-delay = 300; repeat-rate = 50; xkb.options = "caps:escape"; }; - } - // lib.optionalAttrs (inputProfiles.niri.mouse != { }) { - mouse = inputProfiles.niri.mouse; - } - // lib.optionalAttrs (inputProfiles.niri.touchpad != { }) { - touchpad = inputProfiles.niri.touchpad; }; binds = - if terminal.hasPackage then + if terminalPackage != null then import ./_bindings.nix { inherit browserCommand lib ; - terminalPackage = terminal.package; + terminalPackage = terminalPackage; } else { }; diff --git a/modules/features/noctalia.nix b/modules/features/noctalia.nix index a960723..8e87ec7 100644 --- a/modules/features/noctalia.nix +++ b/modules/features/noctalia.nix @@ -4,8 +4,9 @@ ... }: let - homeModules = config.flake.modules.homeManager; - metaLib = config.meta.lib; + repo = config.repo; + repoHelpers = repo.helpers; + mkNoctaliaSettings = { lib, @@ -17,6 +18,25 @@ let terminalPackage ; }; + + mkBaseSettings = + { + lib, + pkgs, + }: + let + terminalPackage = repoHelpers.resolvePackagePath { + inherit pkgs; + path = repo.desktop.terminal.packagePath; + }; + in + if terminalPackage == null then + { } + else + mkNoctaliaSettings { + inherit lib terminalPackage; + }; + mkPortableSettings = baseSettings: lib.recursiveUpdate baseSettings { @@ -40,55 +60,20 @@ let }; in { - flake.modules.homeManager.noctalia-base = - { - config, - lib, - pkgs, - ... - }: - let - terminal = metaLib.resolveRepoTerminal { - inherit pkgs; - }; - baseSettings = - if terminal.hasPackage then - mkNoctaliaSettings { - inherit lib; - terminalPackage = terminal.package; - } - else - { }; - in - { - options.meta.lib.noctaliaBaseSettings = lib.mkOption { - type = lib.types.attrs; - internal = true; - readOnly = true; - }; - - config = { - meta.lib.noctaliaBaseSettings = baseSettings; - - assertions = metaLib.mkTerminalAssertions { - inherit terminal; - }; - }; - }; - flake.modules.homeManager.noctalia = { - config, inputs, lib, pkgs, ... }: + let + baseSettings = mkBaseSettings { + inherit lib pkgs; + }; + in { - imports = [ - homeModules.noctalia-base - inputs.noctalia.homeModules.default - ]; + imports = [ inputs.noctalia.homeModules.default ]; programs.noctalia-shell = { enable = true; @@ -98,23 +83,33 @@ in } ); - settings = config.meta.lib.noctaliaBaseSettings; + settings = baseSettings; }; }; flake.modules.homeManager.noctalia-portable = { - config, + inputs, lib, + pkgs, ... }: + let + baseSettings = mkBaseSettings { + inherit lib pkgs; + }; + in { - imports = [ homeModules.noctalia ]; - programs.noctalia-shell.settings = lib.mkForce ( - if config.meta.lib.noctaliaBaseSettings == { } then - { } - else - mkPortableSettings config.meta.lib.noctaliaBaseSettings - ); + imports = [ inputs.noctalia.homeModules.default ]; + + programs.noctalia-shell = { + enable = true; + package = lib.mkForce ( + inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default.override { + calendarSupport = true; + } + ); + settings = if baseSettings == { } then { } else mkPortableSettings baseSettings; + }; }; } diff --git a/modules/features/pim.nix b/modules/features/pim.nix index 52beed9..a7dcb83 100644 --- a/modules/features/pim.nix +++ b/modules/features/pim.nix @@ -3,7 +3,7 @@ ... }: let - metaRepo = config.meta.lib.repo; + repo = config.repo; in { flake.modules.homeManager.pim = @@ -51,7 +51,7 @@ in }; remote = { - url = metaRepo.services.radicale.url; + url = repo.services.radicale.url; type = "caldav"; userName = config.home.username; passwordCommand = [ diff --git a/modules/features/services/actual.nix b/modules/features/services/actual.nix index ff3434a..121f463 100644 --- a/modules/features/services/actual.nix +++ b/modules/features/services/actual.nix @@ -1,8 +1,8 @@ { config, ... }: let - metaRepo = config.meta.lib.repo; - metaLib = config.meta.lib; - service = metaRepo.services.actual; + repo = config.repo; + repoHelpers = repo.helpers; + service = repo.services.actual; in { flake.modules.nixos.actual = @@ -19,7 +19,7 @@ in }; } - (metaLib.mkCaddyReverseProxy { + (repoHelpers.mkCaddyReverseProxy { inherit (service) domain port diff --git a/modules/features/services/caddy.nix b/modules/features/services/caddy.nix index fffc83d..3487616 100644 --- a/modules/features/services/caddy.nix +++ b/modules/features/services/caddy.nix @@ -1,12 +1,12 @@ { config, ... }: let - metaRepo = config.meta.lib.repo; + repo = config.repo; in { flake.modules.nixos.caddy = { services.caddy = { enable = true; - email = metaRepo.contact.email; + email = repo.contact.email; openFirewall = true; }; }; diff --git a/modules/features/services/gitea.nix b/modules/features/services/gitea.nix index 5fc00a8..3ec4419 100644 --- a/modules/features/services/gitea.nix +++ b/modules/features/services/gitea.nix @@ -1,8 +1,8 @@ { config, ... }: let - metaRepo = config.meta.lib.repo; - metaLib = config.meta.lib; - service = metaRepo.services.gitea; + repo = config.repo; + repoHelpers = repo.helpers; + service = repo.services.gitea; in { flake.modules.nixos.gitea = @@ -32,7 +32,7 @@ in services.openssh.settings.AllowUsers = [ "gitea" ]; } - (metaLib.mkCaddyReverseProxy { + (repoHelpers.mkCaddyReverseProxy { inherit (service) domain port diff --git a/modules/features/services/openssh.nix b/modules/features/services/openssh.nix index 9c88d8f..34ff813 100644 --- a/modules/features/services/openssh.nix +++ b/modules/features/services/openssh.nix @@ -20,7 +20,7 @@ settings = { PermitRootLogin = "no"; PasswordAuthentication = false; - AllowUsers = builtins.attrNames config.meta.host.users; + AllowUsers = builtins.attrNames config.meta.machine.users; }; }; }; diff --git a/modules/features/services/radicale.nix b/modules/features/services/radicale.nix index 3a6d773..20cd286 100644 --- a/modules/features/services/radicale.nix +++ b/modules/features/services/radicale.nix @@ -1,8 +1,8 @@ { config, ... }: let - metaRepo = config.meta.lib.repo; - metaLib = config.meta.lib; - service = metaRepo.services.radicale; + repo = config.repo; + repoHelpers = repo.helpers; + service = repo.services.radicale; in { flake.modules.nixos.radicale = @@ -25,7 +25,7 @@ in }; } - (metaLib.mkCaddyReverseProxy { + (repoHelpers.mkCaddyReverseProxy { inherit (service) domain port diff --git a/modules/features/services/vaultwarden.nix b/modules/features/services/vaultwarden.nix index 8983f3b..28ffc9c 100644 --- a/modules/features/services/vaultwarden.nix +++ b/modules/features/services/vaultwarden.nix @@ -1,8 +1,8 @@ { config, ... }: let - metaRepo = config.meta.lib.repo; - metaLib = config.meta.lib; - service = metaRepo.services.vaultwarden; + repo = config.repo; + repoHelpers = repo.helpers; + service = repo.services.vaultwarden; in { flake.modules.nixos.vaultwarden = @@ -21,7 +21,7 @@ in }; } - (metaLib.mkCaddyReverseProxy { + (repoHelpers.mkCaddyReverseProxy { inherit (service) domain port diff --git a/modules/features/sops-password.nix b/modules/features/sops-password.nix new file mode 100644 index 0000000..778ccff --- /dev/null +++ b/modules/features/sops-password.nix @@ -0,0 +1,17 @@ +{ lib, ... }: +{ + flake.modules.nixos.sops-password = + { config, ... }: + { + sops.secrets = lib.mapAttrs' ( + userName: _: + lib.nameValuePair "hashed-password-${userName}" { + neededForUsers = true; + } + ) config.meta.machine.users; + + users.users = lib.mapAttrs (userName: _: { + hashedPasswordFile = config.sops.secrets."hashed-password-${userName}".path; + }) config.meta.machine.users; + }; +} diff --git a/modules/features/source-control.nix b/modules/features/source-control.nix index 3545751..bc3883a 100644 --- a/modules/features/source-control.nix +++ b/modules/features/source-control.nix @@ -10,22 +10,19 @@ in ... }: let - host = config.meta.host; + machine = config.meta.machine; user = config.meta.user; - sourceControl = user.sourceControl; - sourceControlScopes = sourceControl.scopes; - hostSourceControlUsers = host.sourceControl.users; - hostUserSourceControl = hostSourceControlUsers.${user.name} or { }; + account = user.account; + sourceControl = account.sourceControl; - scopeConfig = scope: hostUserSourceControl.${scope} or null; - scopeIdentity = scope: sourceControlScopes.${scope} or null; + scopeConfig = scope: user.sourceControl.${scope} or null; emailForScope = scope: let - identity = scopeIdentity scope; + scopedEmails = lib.filter (email: email.scope == scope) (builtins.attrValues account.emails); in - if identity == null then null else identity.email; + if builtins.length scopedEmails == 1 then (builtins.head scopedEmails).address else null; scopeHasSigningKey = scope: @@ -51,7 +48,12 @@ in in if keyConfig == null then null else keyConfig.publicKey; - scopesInUse = builtins.attrNames sourceControlScopes; + scopesInUse = lib.unique [ + "personal" + sourceControl.projectScope + ]; + + missingEmailScopes = builtins.filter (scope: emailForScope scope == null) scopesInUse; allowedSignersLines = map (scope: "${emailForScope scope} ${publicKeyForScope scope}") ( builtins.filter (scope: emailForScope scope != null && scopeHasSigningKey scope) scopesInUse @@ -62,7 +64,7 @@ in lib.recursiveUpdate { user = { - name = user.realName; + name = account.realName; email = emailForScope scope; }; } @@ -75,7 +77,7 @@ in gitRoots = [ { - root = user.nixosConfigurationPath; + root = account.nixosConfigurationPath; scope = "personal"; } { @@ -87,6 +89,13 @@ in { imports = [ homeModules.git ]; + assertions = [ + { + assertion = missingEmailScopes == [ ]; + message = "Missing source-control email scope for `${account.name}`: ${lib.concatStringsSep ", " missingEmailScopes}."; + } + ]; + xdg.configFile."git/allowed_signers".text = lib.concatStringsSep "\n" ( allowedSignersLines ++ [ "" ] ); diff --git a/modules/features/syncthing.nix b/modules/features/syncthing.nix index 76eeb28..6d3ee53 100644 --- a/modules/features/syncthing.nix +++ b/modules/features/syncthing.nix @@ -1,19 +1,31 @@ +{ + config, + lib, + ... +}: +let + syncthingMesh = lib.listToAttrs ( + lib.concatMap ( + machine: + lib.mapAttrsToList ( + userName: user: + let + name = "${userName}@${machine.name}"; + in + { + inherit name; + value = { + inherit name; + id = user.syncthingId; + }; + } + ) (lib.filterAttrs (_: user: user.syncthingId != null) machine.users) + ) (builtins.attrValues config.repo.machines) + ); +in { flake.modules.homeManager.syncthing = { ... }: - let - syncthingMesh = { - "kiri@orion" = { - name = "kiri@orion"; - id = "NNRNQKZ-OWPHSVA-B6KKBHE-SDYLSTV-7SVHGPR-NEWLKPL-4MWNJG4-G5FHUAI"; - }; - - "kiri@polaris" = { - name = "kiri@polaris"; - id = "6HBAKXB-DB3B4H2-BODCAXF-KD23H5W-6X5LGLC-ZJHZHLG-7U7YMGO-BB6IXQ3"; - }; - }; - in { services.syncthing = { enable = true; diff --git a/modules/features/terminal.nix b/modules/features/terminal.nix index 027b569..1169d63 100644 --- a/modules/features/terminal.nix +++ b/modules/features/terminal.nix @@ -1,32 +1,46 @@ { config, ... }: let - metaLib = config.meta.lib; - metaRepo = metaLib.repo; + repo = config.repo; + repoHelpers = repo.helpers; in { flake.modules.homeManager.terminal = { - config, lib, pkgs, ... }: let - repoTheme = metaRepo.theme.kanagawa; + repoTheme = repo.theme.kanagawa; palette = repoTheme.palette; - terminal = metaLib.resolveRepoTerminal { + terminalPackage = repoHelpers.resolvePackagePath { inherit pkgs; + path = repo.desktop.terminal.packagePath; }; + terminalDesktopId = repo.desktop.terminal.desktopId; in { - assertions = metaLib.mkTerminalAssertions { - inherit terminal; - requireDesktopEntry = true; - }; + assertions = [ + { + assertion = terminalPackage != null; + message = "Unknown terminal package `${lib.showAttrPath repo.desktop.terminal.packagePath}`."; + } + { + assertion = repo.desktop.terminal.command == "kitty"; + message = "The terminal feature currently only supports kitty."; + } + { + assertion = + terminalPackage == null + || terminalDesktopId == null + || builtins.pathExists "${terminalPackage}/share/applications/${terminalDesktopId}"; + message = "Terminal package `${lib.showAttrPath repo.desktop.terminal.packagePath}` must provide `${terminalDesktopId}`."; + } + ]; xdg.terminal-exec = { enable = true; - settings.default = lib.optional (terminal.desktopId != null) terminal.desktopId; + settings.default = lib.optional (terminalDesktopId != null) terminalDesktopId; }; programs.kitty = { diff --git a/modules/features/theme.nix b/modules/features/theme.nix index ffd407e..3196897 100644 --- a/modules/features/theme.nix +++ b/modules/features/theme.nix @@ -3,8 +3,8 @@ ... }: let - metaLib = config.meta.lib; - metaRepo = metaLib.repo; + repo = config.repo; + repoHelpers = repo.helpers; in { flake.modules.nixos.theme = @@ -13,9 +13,9 @@ in ... }: let - repoTheme = metaRepo.theme; + repoTheme = repo.theme; cursorTheme = repoTheme.cursor // { - package = metaLib.resolvePackagePath { + package = repoHelpers.resolvePackagePath { inherit pkgs; path = repoTheme.cursor.packagePath; }; @@ -35,9 +35,9 @@ in flake.modules.homeManager.theme = { config, pkgs, ... }: let - repoTheme = metaRepo.theme; + repoTheme = repo.theme; cursorTheme = repoTheme.cursor // { - package = metaLib.resolvePackagePath { + package = repoHelpers.resolvePackagePath { inherit pkgs; path = repoTheme.cursor.packagePath; }; diff --git a/modules/features/vicinae.nix b/modules/features/vicinae.nix index 218fc52..15ec1fa 100644 --- a/modules/features/vicinae.nix +++ b/modules/features/vicinae.nix @@ -1,6 +1,6 @@ { config, ... }: let - metaRepo = config.meta.lib.repo; + repo = config.repo; in { flake.modules.homeManager.vicinae = @@ -10,7 +10,7 @@ in ... }: let - repoTheme = metaRepo.theme.kanagawa; + repoTheme = repo.theme.kanagawa; palette = repoTheme.palette; in { diff --git a/modules/features/workstation-base.nix b/modules/features/workstation-base.nix index 656ec9b..23e1930 100644 --- a/modules/features/workstation-base.nix +++ b/modules/features/workstation-base.nix @@ -4,18 +4,17 @@ let homeModules = config.flake.modules.homeManager; in { - flake.modules.nixos.workstation = { + flake.modules.nixos.workstation-base = { imports = [ nixosModules.audio nixosModules.bluetooth nixosModules.flatpak nixosModules.fonts - nixosModules.host-base - nixosModules.input nixosModules.networking nixosModules.niri nixosModules.plymouth nixosModules.printing + nixosModules.sops-password nixosModules.sddm nixosModules.sops-admin-key-file nixosModules.standard-boot @@ -30,7 +29,7 @@ in environment.localBinInPath = true; }; - flake.modules.homeManager.workstation = { + flake.modules.homeManager.workstation-base = { imports = [ homeModules.ai homeModules.bitwarden diff --git a/modules/features/xdg.nix b/modules/features/xdg.nix index d16a629..80b0945 100644 --- a/modules/features/xdg.nix +++ b/modules/features/xdg.nix @@ -1,19 +1,19 @@ { config, ... }: let - metaLib = config.meta.lib; - metaRepo = metaLib.repo; + repo = config.repo; + repoHelpers = repo.helpers; in { flake.modules.homeManager.xdg = { config, pkgs, ... }: let - browserPackage = metaLib.resolvePackagePath { + browserPackage = repoHelpers.resolvePackagePath { inherit pkgs; - path = metaRepo.desktop.browser.packagePath; + path = repo.desktop.browser.packagePath; }; - fileManagerPackage = metaLib.resolvePackagePath { + fileManagerPackage = repoHelpers.resolvePackagePath { inherit pkgs; - path = metaRepo.desktop.fileManager.packagePath; + path = repo.desktop.fileManager.packagePath; }; homeDir = config.home.homeDirectory; localDir = "${homeDir}/.local"; diff --git a/modules/hosts/orion/default.nix b/modules/hosts/orion/default.nix index e5d0b69..be6a7a9 100644 --- a/modules/hosts/orion/default.nix +++ b/modules/hosts/orion/default.nix @@ -1,19 +1,21 @@ { inputs, config, - lib, ... }: let nixosModules = config.flake.modules.nixos; - hmModules = config.flake.modules.homeManager; + accounts = config.repo.accounts; in { repo.machines.orion = { buildFunction = config.repo.helpers.mkHost; module = nixosModules.orion; - accounts = lib.getAttrs [ "kiri" ] config.repo.accounts; + users.kiri = { + account = accounts.kiri; + syncthingId = "NNRNQKZ-OWPHSVA-B6KKBHE-SDYLSTV-7SVHGPR-NEWLKPL-4MWNJG4-G5FHUAI"; + }; stateVersion = "24.05"; hmStateVersion = "24.05"; @@ -23,7 +25,6 @@ in { ... }: { imports = [ - nixosModules.host-base nixosModules.sops-host-ssh-key nixosModules.openssh nixosModules.caddy diff --git a/modules/hosts/polaris/default.nix b/modules/hosts/polaris/default.nix index 2886a24..7981136 100644 --- a/modules/hosts/polaris/default.nix +++ b/modules/hosts/polaris/default.nix @@ -6,18 +6,24 @@ let nixosModules = config.flake.modules.nixos; homeModules = config.flake.modules.homeManager; - metaLib = config.meta.lib; - workstationHomeImports = [ homeModules.workstation ]; - kiriHomeImports = workstationHomeImports ++ [ - homeModules.syncthing - homeModules.qbittorrent-client - homeModules.noctalia - ]; - ergonHomeImports = workstationHomeImports ++ [ homeModules.noctalia ]; + accounts = config.repo.accounts; in { - flake.modules.nixos.polaris = metaLib.mkHost { - name = "polaris"; + repo.machines.polaris = { + buildFunction = config.repo.helpers.mkWorkstationHost; + module = nixosModules.polaris; + + users = { + kiri = { + account = accounts.kiri; + syncthingId = "6HBAKXB-DB3B4H2-BODCAXF-KD23H5W-6X5LGLC-ZJHZHLG-7U7YMGO-BB6IXQ3"; + }; + + ergon.account = accounts.ergon; + }; + + stateVersion = "24.05"; + hmStateVersion = "24.05"; displays = { "LG Electronics LG ULTRAGEAR 103NTYT8R290" = { @@ -31,35 +37,26 @@ in y = 0; }; }; - - input = { - mouse.accelSpeed = 0.4; - }; - - users = { - kiri = { - account = metaLib.accounts.kiri; - needsPassword = true; - homeImports = kiriHomeImports; - }; - - ergon = { - account = metaLib.accounts.ergon; - needsPassword = true; - homeImports = ergonHomeImports; - }; - }; - - imports = [ - nixosModules.workstation - nixosModules.steam - ./_hardware.nix - ] - ++ (with inputs.nixos-hardware.nixosModules; [ - common-pc - common-pc-ssd - common-cpu-amd - common-gpu-amd - ]); }; + + flake.modules.nixos.polaris = + { ... }: + { + imports = [ + nixosModules.qbittorrent-client + nixosModules.steam + ./_hardware.nix + ] + ++ (with inputs.nixos-hardware.nixosModules; [ + common-pc + common-pc-ssd + common-cpu-amd + common-gpu-amd + ]); + + home-manager.users = { + kiri.imports = [ homeModules.noctalia ]; + ergon.imports = [ homeModules.noctalia ]; + }; + }; } diff --git a/modules/hosts/zenith/default.nix b/modules/hosts/zenith/default.nix index d25efca..0672543 100644 --- a/modules/hosts/zenith/default.nix +++ b/modules/hosts/zenith/default.nix @@ -6,87 +6,71 @@ let nixosModules = config.flake.modules.nixos; homeModules = config.flake.modules.homeManager; - metaLib = config.meta.lib; - workstationHomeImports = [ homeModules.workstation ]; - portableNoctalia = homeModules.noctalia-portable; - kiriHomeImports = workstationHomeImports ++ [ - homeModules.syncthing - homeModules.qbittorrent-client - portableNoctalia - ]; - ergonHomeImports = workstationHomeImports ++ [ - portableNoctalia - ( - { pkgs, ... }: - { - home.packages = [ - pkgs.usql - ]; - - programs.git.ignores = [ - # Devenv stuff - "devenv.*" - ".devenv*" - ".direnv" - "pre-commit-config.yaml" - ".envrc" - ]; - } - ) - ]; + accounts = config.repo.accounts; in { - flake.modules.nixos.zenith = metaLib.mkHost { - name = "zenith"; + repo.machines.zenith = { + buildFunction = config.repo.helpers.mkWorkstationHost; + module = nixosModules.zenith; - displays = { - "California Institute of Technology 0x1410 Unknown" = { - primary = true; - x = 0; - y = 0; - scale = 1.5; - mode = { - width = 3072; - height = 1920; - refresh = 120.002; + users = { + kiri.account = accounts.kiri; + ergon = { + account = accounts.ergon; + sourceControl = { + personal.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPdR3KP2U84i7f7MlRqcML/3YyMw8JL3hdm637SkMUwO ergon@zenith#personal"; + work.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHJz5uHKm0/TiMNh/cmzrODHNZ8NgEEZe+47XnJwQGk ergon@zenith#work"; }; }; }; - input = { - mouse.accelSpeed = 0.4; - }; - - sourceControl.users = { - ergon = { - personal.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPdR3KP2U84i7f7MlRqcML/3YyMw8JL3hdm637SkMUwO ergon@zenith#personal"; - work.publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIHJz5uHKm0/TiMNh/cmzrODHNZ8NgEEZe+47XnJwQGk ergon@zenith#work"; + displays = { + "California Institute of Technology 0x1410 Unknown" = { + primary = true; + scale = 1.5; + width = 3072; + height = 1920; + refresh = 120.002; }; }; - users = { - kiri = { - account = metaLib.accounts.kiri; - needsPassword = true; - homeImports = kiriHomeImports; - }; - - ergon = { - account = metaLib.accounts.ergon; - needsPassword = true; - homeImports = ergonHomeImports; - }; - }; - - imports = [ - nixosModules.workstation - nixosModules.laptop-power - { - hardware.enableRedistributableFirmware = true; - services.fwupd.enable = true; - } - ./_hardware.nix - inputs.nixos-hardware.nixosModules.lenovo-yoga-7-14ARH7-amdgpu - ]; + stateVersion = "24.05"; + hmStateVersion = "24.05"; }; + + flake.modules.nixos.zenith = + { ... }: + { + imports = [ + nixosModules.qbittorrent-client + nixosModules.laptop-power + { + hardware.enableRedistributableFirmware = true; + services.fwupd.enable = true; + } + ./_hardware.nix + inputs.nixos-hardware.nixosModules.lenovo-yoga-7-14ARH7-amdgpu + ]; + + home-manager.users = { + kiri.imports = [ homeModules.noctalia-portable ]; + ergon.imports = [ + homeModules.noctalia-portable + ( + { pkgs, ... }: + { + home.packages = [ pkgs.usql ]; + + programs.git.ignores = [ + "devenv.*" + ".devenv*" + ".direnv" + "pre-commit-config.yaml" + ".envrc" + ]; + } + ) + ]; + }; + }; } diff --git a/modules/lib/helpers.nix b/modules/lib/helpers.nix index 1ef3157..f17ec19 100644 --- a/modules/lib/helpers.nix +++ b/modules/lib/helpers.nix @@ -1,48 +1,80 @@ { lib, config, ... }: let nixosModules = config.flake.modules.nixos; - hmModules = config.flake.modules.homeManager; + + resolvePackagePath = + { + pkgs, + path, + }: + lib.attrByPath path null pkgs; + + mkCaddyReverseProxy = + { + domain, + port, + extraHeaders ? [ ], + extraConfigText ? "", + }: + let + headerLines = map (header: " header_up ${header.name} ${header.value}") extraHeaders; + extraConfigLines = map (line: " ${line}") ( + lib.filter (line: line != "") (lib.splitString "\n" extraConfigText) + ); + bodyLines = headerLines ++ extraConfigLines; + body = lib.concatStringsSep "\n" bodyLines; + in + { + services.caddy.virtualHosts.${domain}.extraConfig = + if body == "" then + "reverse_proxy :${toString port}" + else + '' + reverse_proxy :${toString port} { + ${body} + } + ''; + }; mkHost = machine: - { config, pkgs, ... }: + { pkgs, ... }: { imports = [ nixosModules.host-base - nixosModules.meta machine.module ]; + meta.machine = machine; networking.hostName = machine.name; system.stateVersion = machine.stateVersion; - # TODO: Move this programs.zsh.enable = true; - users.users = lib.mapAttrs ( - _: account: { - inherit (account) name extraGroups; - isNormalUser = true; - home = account.homeDirectory; - # TODO: Move this - shell = pkgs.zsh; - } - ); + users.users = lib.mapAttrs (_: user: { + isNormalUser = true; + home = user.account.homeDirectory; + extraGroups = [ + "wheel" + "networkmanager" + ]; + shell = pkgs.zsh; + }) machine.users; - home-manager.users = lib.mapAttrs ( - _: account: { - imports = [ - hmModules.meta - account.baseModule - ]; - meta = { - inherit machine account; - }; - home.homeDirectory = account.homeDirectory; - home.stateVersion = machine.hmStateVersion; - } - ); + home-manager.users = lib.mapAttrs (name: user: { + imports = [ user.account.baseModule ]; + + meta = { + inherit machine user; + }; + + home = { + username = name; + homeDirectory = user.account.homeDirectory; + stateVersion = machine.hmStateVersion; + }; + }) machine.users; }; mkWorkstationHost = @@ -54,11 +86,13 @@ let nixosModules.workstation-base ]; - home-manager.users = lib.mapAttrs ( - _: account: { - imports = [ account.workstationModule ]; - } - ); + users.users = lib.mapAttrs (_: _: { + extraGroups = [ "networkmanager" ]; + }) machine.users; + + home-manager.users = lib.mapAttrs (_: user: { + imports = [ user.account.workstationModule ]; + }) machine.users; }; in { @@ -68,5 +102,12 @@ in readOnly = true; }; - config.repo.helpers = { inherit mkHost mkWorkstationHost; }; + config.repo.helpers = { + inherit + mkCaddyReverseProxy + mkHost + mkWorkstationHost + resolvePackagePath + ; + }; } diff --git a/modules/lib/schema.nix b/modules/lib/schema.nix index f030ba9..56b5106 100644 --- a/modules/lib/schema.nix +++ b/modules/lib/schema.nix @@ -1,6 +1,10 @@ { lib, ... }: let - # Account types + sourceControlScopeType = lib.types.enum [ + "personal" + "work" + ]; + emailProviderType = lib.types.enum [ "mxrouting" "office365" @@ -22,6 +26,21 @@ let type = lib.mkOption { type = emailProviderType; }; + + scope = lib.mkOption { + type = lib.types.nullOr sourceControlScopeType; + default = null; + }; + }; + } + ); + + sourceControlAccountType = lib.types.submodule ( + { ... }: + { + options.projectScope = lib.mkOption { + type = sourceControlScopeType; + default = "personal"; }; } ); @@ -33,7 +52,6 @@ let name = lib.mkOption { type = lib.types.str; default = name; - readOnly = true; }; realName = lib.mkOption { @@ -55,11 +73,6 @@ let default = { }; }; - extraGroups = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - }; - baseModule = lib.mkOption { type = lib.types.deferredModule; default = { }; @@ -70,9 +83,13 @@ let default = { }; }; + sourceControl = lib.mkOption { + type = sourceControlAccountType; + default = { }; + }; + primaryEmail = lib.mkOption { type = lib.types.nullOr emailType; - readOnly = true; description = "Derived primary email entry for this user."; default = let @@ -84,7 +101,6 @@ let } ); - # Machine types displayType = lib.types.submodule ( { ... }: { @@ -106,19 +122,77 @@ let scale = lib.mkOption { type = lib.types.nullOr lib.types.float; - default = 1.0; + default = null; }; width = lib.mkOption { - type = lib.types.int; + type = lib.types.nullOr lib.types.int; + default = null; }; height = lib.mkOption { - type = lib.types.int; + type = lib.types.nullOr lib.types.int; + default = null; }; refresh = lib.mkOption { - type = lib.types.float; + type = lib.types.nullOr lib.types.float; + default = null; + }; + }; + } + ); + + sourceControlMachineKeyType = lib.types.submodule ( + { ... }: + { + options = { + publicKey = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + }; + + privateKeyPath = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + }; + }; + } + ); + + sourceControlMachineUserType = lib.types.submodule ( + { ... }: + { + options = { + personal = lib.mkOption { + type = lib.types.nullOr sourceControlMachineKeyType; + default = null; + }; + + work = lib.mkOption { + type = lib.types.nullOr sourceControlMachineKeyType; + default = null; + }; + }; + } + ); + + machineUserType = lib.types.submodule ( + { ... }: + { + options = { + account = lib.mkOption { + type = accountType; + }; + + sourceControl = lib.mkOption { + type = sourceControlMachineUserType; + default = { }; + }; + + syncthingId = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; }; }; } @@ -131,7 +205,6 @@ let name = lib.mkOption { type = lib.types.str; default = name; - readOnly = true; }; module = lib.mkOption { @@ -157,8 +230,8 @@ let default = { }; }; - accounts = lib.mkOption { - type = lib.types.attrsOf accountType; + users = lib.mkOption { + type = lib.types.attrsOf machineUserType; default = { }; }; }; @@ -171,14 +244,35 @@ in type = lib.types.attrsOf accountType; default = { }; }; + machines = lib.mkOption { type = lib.types.attrsOf machineType; default = { }; }; + + contact = lib.mkOption { + type = lib.types.raw; + default = { }; + }; + + desktop = lib.mkOption { + type = lib.types.raw; + default = { }; + }; + + services = lib.mkOption { + type = lib.types.raw; + default = { }; + }; + + theme = lib.mkOption { + type = lib.types.raw; + default = { }; + }; }; config.flake.modules.nixos.meta = - { config, ... }: + { ... }: { options.meta.machine = lib.mkOption { type = machineType; @@ -186,15 +280,15 @@ in }; config.flake.modules.homeManager.meta = - { config, ... }: + { ... }: { options.meta = { machine = lib.mkOption { type = machineType; }; - account = lib.mkOption { - type = accountType; + user = lib.mkOption { + type = machineUserType; }; }; };