From 2aa5e0095c7ee9a25f34f4e510bad4f1b6d79964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Schwarz=C3=A4ugl?= Date: Sun, 29 Jun 2025 22:43:04 +0200 Subject: [PATCH] feat: add globals system --- SwarselSystems.org | 703 ++++++++++++++++---------- flake.lock | 50 +- flake.nix | 280 ++++++---- hosts/nixos/iso/default.nix | 3 + lib/default.nix | 88 +--- modules/nixos/common/globals.nix | 75 +++ modules/nixos/common/sharedsetup.nix | 32 -- modules/nixos/server/ankisync.nix | 4 +- modules/nixos/server/atuin.nix | 3 +- modules/nixos/server/croc.nix | 3 +- modules/nixos/server/firefly-iii.nix | 13 +- modules/nixos/server/forgejo.nix | 2 + modules/nixos/server/freshrss.nix | 4 +- modules/nixos/server/immich.nix | 5 +- modules/nixos/server/jellyfin.nix | 3 +- modules/nixos/server/kanidm.nix | 6 +- modules/nixos/server/kavita.nix | 3 +- modules/nixos/server/koillection.nix | 1 + modules/nixos/server/matrix.nix | 2 + modules/nixos/server/microbin.nix | 3 +- modules/nixos/server/monitoring.nix | 1 + modules/nixos/server/navidrome.nix | 2 + modules/nixos/server/nextcloud.nix | 3 + modules/nixos/server/oauth2-proxy.nix | 6 +- modules/nixos/server/paperless.nix | 2 + modules/nixos/server/radicale.nix | 3 +- modules/nixos/server/shlink.nix | 3 + modules/nixos/server/syncthing.nix | 2 + modules/nixos/server/transmission.nix | 2 + nix/globals.nix | 48 ++ secrets/repo/pii.nix.enc | 6 +- 31 files changed, 833 insertions(+), 528 deletions(-) create mode 100644 modules/nixos/common/globals.nix create mode 100644 nix/globals.nix diff --git a/SwarselSystems.org b/SwarselSystems.org index 88d871a..4d57033 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -148,28 +148,130 @@ In =outputs = inputs@ [...]=, the =inputs@= makes it so that all inputs are auto }; outputs = inputs@{ self - , nixpkgs - , home-manager - , systems - , ... - }: + , nixpkgs + , home-manager + , systems + , ... + }: let <> in - { - <> + inputs.flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ + ./nix/globals.nix + ]; + flake = { config, ... }: + let + <> - nixosConfigurations = - <> - homeConfigurations = - <> - darwinConfigurations = - <> - nixOnDroidConfigurations = - <> + linuxUser = "swarsel"; + macUser = "leon.schwarzaeugl"; - topology = - <> + mkFullHost = host: type: { + ${host} = + let + systemFunc = if (type == "nixos") then lib.nixosSystem else inputs.nix-darwin.lib.darwinSystem; + in + systemFunc { + specialArgs = { inherit inputs outputs lib self; inherit (config) globals; }; + modules = [ + { + node.name = host; + node.secretsDir = ./hosts/${type}/${host}/secrets; + } + # put inports here that are for all hosts + inputs.disko.nixosModules.disko + inputs.sops-nix.nixosModules.sops + inputs.impermanence.nixosModules.impermanence + inputs.lanzaboote.nixosModules.lanzaboote + inputs.fw-fanctrl.nixosModules.default + "${self}/hosts/${type}/${host}" + { + _module.args.primaryUser = linuxUser; + } + ] ++ + (if (host == "iso") then [ + inputs.nix-topology.nixosModules.default + ] else + ([ + # put nixos imports here that are for all servers and normal hosts + inputs.nix-topology.nixosModules.default + "${self}/modules/${type}/common" + inputs.stylix.nixosModules.stylix + inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm + ] ++ (if (type == "nixos") then [ + inputs.home-manager.nixosModules.home-manager + "${self}/profiles/nixos" + "${self}/modules/nixos/server" + "${self}/modules/nixos/optional" + { + home-manager.users."${linuxUser}".imports = [ + # put home-manager imports here that are for all normal hosts + "${self}/modules/home/common" + "${self}/modules/home/server" + "${self}/modules/home/optional" + "${self}/profiles/home" + ]; + } + ] else [ + # put nixos imports here that are for darwin hosts + "${self}/modules/darwin/nixos/common" + "${self}/profiles/darwin" + inputs.home-manager.darwinModules.home-manager + { + home-manager.users."${macUser}".imports = [ + # put home-manager imports here that are for darwin hosts + "${self}/modules/darwin/home" + "${self}/modules/home/server" + "${self}/modules/home/optional" + "${self}/profiles/home" + ]; + } + ]) + )); + }; + }; + + mkHalfHost = host: type: pkgs: { + ${host} = + let + systemFunc = if (type == "home") then inputs.home-manager.lib.homeManagerConfiguration else inputs.nix-on-droid.lib.nixOnDroidConfiguration; + in + systemFunc + { + inherit pkgs; + extraSpecialArgs = { inherit inputs outputs lib self; }; + modules = [ "${self}/hosts/${type}/${host}" ]; + }; + }; + + mkFullHostConfigs = hosts: type: lib.foldl (acc: set: acc // set) { } (lib.map (host: mkFullHost host type) hosts); + + mkHalfHostConfigs = hosts: type: pkgs: lib.foldl (acc: set: acc // set) { } (lib.map (host: mkHalfHost host type pkgs) hosts); + + in + { + <> + + nixosConfigurations = mkFullHostConfigs (lib.swarselsystems.readHosts "nixos") "nixos"; + homeConfigurations = mkHalfHostConfigs (lib.swarselsystems.readHosts "home") "home" lib.swarselsystems.pkgsFor.x86_64-linux; + darwinConfigurations = mkFullHostConfigs (lib.swarselsystems.readHosts "darwin") "darwin"; + nixOnDroidConfigurations = mkHalfHostConfigs (lib.swarselsystems.readHosts "android") "android" lib.swarselsystems.pkgsFor.aarch64-linux; + + topology = lib.swarselsystems.forEachSystem (pkgs: import inputs.nix-topology { + inherit pkgs; + modules = [ + "${self}/topology" + { inherit (self) nixosConfigurations; } + ]; + }); + + nodes = config.nixosConfigurations; + }; + systems = [ + "x86_64-linux" + "aarch64-linux" + ]; }; } #+end_src @@ -304,6 +406,7 @@ When setting this option normally, the password would normally be written world- inputs.nixpkgs.follows = "nixpkgs"; }; nix-topology.url = "github:oddlama/nix-topology"; + flake-parts.url = "github:hercules-ci/flake-parts"; #+end_src ** let :PROPERTIES: @@ -497,7 +600,6 @@ Note: The preceding =nixosConfigurations= is found in [[#h:aee5ec75-7ca6-40d8-b6 #+begin_src nix :tangle no :noweb-ref flakenixosconf - lib.swarselsystems.mkFullHostConfigs (lib.swarselsystems.readHosts "nixos") "nixos"; #+end_src ** darwinConfigurations :PROPERTIES: @@ -510,7 +612,6 @@ Note: The preceding =darwinConfigurations= is found in [[#h:aee5ec75-7ca6-40d8-b =3a272b1 feat!: dynamically create hosts=, and the deprecated system definitions removed in =7457109 main chore: remove deprecated static host config=. See those commits for a state with a simpler config. #+begin_src nix :tangle no :noweb-ref flakedarwinconf - lib.swarselsystems.mkFullHostConfigs (lib.swarselsystems.readHosts "darwin") "darwin"; #+end_src ** homeConfigurations @@ -530,7 +631,6 @@ In contrast, this defines home-manager systems, which I only have one of, that s # ]; # }; - lib.swarselsystems.mkHalfHostConfigs (lib.swarselsystems.readHosts "home") "home" lib.swarselsystems.pkgsFor.x86_64-linux; #+end_src ** nixOnDroidConfigurations @@ -549,7 +649,6 @@ Nix on Android also demands an own flake output, which is provided here. # ]; # }; - lib.swarselsystems.mkHalfHostConfigs (lib.swarselsystems.readHosts "android") "android" lib.swarselsystems.pkgsFor.aarch64-linux; #+end_src @@ -561,13 +660,6 @@ Nix on Android also demands an own flake output, which is provided here. #+begin_src nix :tangle no :noweb-ref topologyconf - lib.swarselsystems.forEachSystem (pkgs: import inputs.nix-topology { - inherit pkgs; - modules = [ - "${self}/topology" - { inherit (self) nixosConfigurations; } - ]; - }); #+end_src @@ -2118,48 +2210,63 @@ Also, an initial bash history is provided to allow for a very quick local deploy #+begin_src nix :tangle hosts/nixos/iso/default.nix - { self, pkgs, inputs, config, lib, modulesPath, primaryUser ? "swarsel", ... }: - let - pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh"; - in - { + { self, pkgs, inputs, config, lib, modulesPath, primaryUser ? "swarsel", ... }: + let + pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh"; + in + { - imports = [ - "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" - "${modulesPath}/installer/cd-dvd/channel.nix" + imports = [ + "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" + "${modulesPath}/installer/cd-dvd/channel.nix" - "${self}/modules/iso/minimal.nix" - "${self}/modules/nixos/common/sharedsetup.nix" - "${self}/modules/nixos/common/topology.nix" - "${self}/modules/home/common/sharedsetup.nix" + "${self}/modules/iso/minimal.nix" + "${self}/modules/nixos/common/sharedsetup.nix" + "${self}/modules/nixos/common/topology.nix" + "${self}/modules/home/common/sharedsetup.nix" - inputs.home-manager.nixosModules.home-manager - { - home-manager.users."${primaryUser}".imports = [ - "${self}/modules/home/common/settings.nix" - "${self}/modules/home/common/sharedsetup.nix" - ]; - } - ]; + "${self}/modules/nixos/common/globals.nix" - options.node = { - name = lib.mkOption { - description = "Node Name."; - type = lib.types.str; + + inputs.home-manager.nixosModules.home-manager + { + home-manager.users."${primaryUser}".imports = [ + "${self}/modules/home/common/settings.nix" + "${self}/modules/home/common/sharedsetup.nix" + ]; + } + ]; + + options.node = { + name = lib.mkOption { + description = "Node Name."; + type = lib.types.str; + }; + secretsDir = lib.mkOption { + description = "Path to the secrets directory for this node."; + type = lib.types.path; + default = ./.; + }; }; - secretsDir = lib.mkOption { - description = "Path to the secrets directory for this node."; - type = lib.types.path; - default = ./.; - }; - }; - config = { - node.name = lib.mkForce "drugstore"; - swarselsystems = { - info = "~SwarselSystems~ installer ISO"; - }; - home-manager.users."${primaryUser}" = { - home = { + config = { + node.name = lib.mkForce "drugstore"; + swarselsystems = { + info = "~SwarselSystems~ installer ISO"; + }; + home-manager.users."${primaryUser}" = { + home = { + stateVersion = "23.05"; + file = { + ".bash_history" = { + source = self + /programs/bash/.bash_history; + }; + }; + }; + swarselsystems = { + modules.general = lib.mkForce true; + }; + }; + home-manager.users.root.home = { stateVersion = "23.05"; file = { ".bash_history" = { @@ -2167,92 +2274,80 @@ Also, an initial bash history is provided to allow for a very quick local deploy }; }; }; - swarselsystems = { - modules.general = lib.mkForce true; + + # environment.etc."issue".text = "\x1B[32m~SwarselSystems~\x1B[0m\nIP of primary interface: \x1B[31m\\4\x1B[0m\nThe Password for all users & root is '\x1B[31msetup\x1B[0m'.\nInstall the system remotely by running '\x1B[33mbootstrap -n -d [--impermanence] [--encryption]\x1B[0m' on a machine with deployed secrets.\nAlternatively, run '\x1B[33mswarsel-install -d -f \x1B[0m' for a local install.\n"; + environment.etc."issue".source = "${self}/programs/etc/issue"; + networking.dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload"; + + isoImage = { + makeEfiBootable = true; + makeUsbBootable = true; + squashfsCompression = "zstd -Xcompression-level 3"; }; - }; - home-manager.users.root.home = { - stateVersion = "23.05"; - file = { - ".bash_history" = { - source = self + /programs/bash/.bash_history; - }; + + nixpkgs = { + hostPlatform = lib.mkDefault "x86_64-linux"; + config.allowUnfree = true; }; - }; - # environment.etc."issue".text = "\x1B[32m~SwarselSystems~\x1B[0m\nIP of primary interface: \x1B[31m\\4\x1B[0m\nThe Password for all users & root is '\x1B[31msetup\x1B[0m'.\nInstall the system remotely by running '\x1B[33mbootstrap -n -d [--impermanence] [--encryption]\x1B[0m' on a machine with deployed secrets.\nAlternatively, run '\x1B[33mswarsel-install -d -f \x1B[0m' for a local install.\n"; - environment.etc."issue".source = "${self}/programs/etc/issue"; - networking.dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload"; + services.getty.autologinUser = lib.mkForce primaryUser; - isoImage = { - makeEfiBootable = true; - makeUsbBootable = true; - squashfsCompression = "zstd -Xcompression-level 3"; - }; - - nixpkgs = { - hostPlatform = lib.mkDefault "x86_64-linux"; - config.allowUnfree = true; - }; - - services.getty.autologinUser = lib.mkForce primaryUser; - - users = { - allowNoPasswordLogin = true; - groups.swarsel = { }; users = { - swarsel = { - name = primaryUser; - group = primaryUser; - isNormalUser = true; - password = "setup"; # this is overwritten after install - openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key); - extraGroups = [ "wheel" ]; - }; - root = { - # password = lib.mkForce config.users.users.swarsel.password; # this is overwritten after install - openssh.authorizedKeys.keys = config.users.users."${primaryUser}".openssh.authorizedKeys.keys; + allowNoPasswordLogin = true; + groups.swarsel = { }; + users = { + swarsel = { + name = primaryUser; + group = primaryUser; + isNormalUser = true; + password = "setup"; # this is overwritten after install + openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key); + extraGroups = [ "wheel" ]; + }; + root = { + # password = lib.mkForce config.users.users.swarsel.password; # this is overwritten after install + openssh.authorizedKeys.keys = config.users.users."${primaryUser}".openssh.authorizedKeys.keys; + }; }; }; - }; - boot = { - loader.systemd-boot.enable = lib.mkForce true; - loader.efi.canTouchEfiVariables = true; - }; + boot = { + loader.systemd-boot.enable = lib.mkForce true; + loader.efi.canTouchEfiVariables = true; + }; - programs.bash.shellAliases = { - "swarsel-install" = "nix run github:Swarsel/.dotfiles#swarsel-install --"; - }; + programs.bash.shellAliases = { + "swarsel-install" = "nix run github:Swarsel/.dotfiles#swarsel-install --"; + }; - system.activationScripts.cache = { - text = '' - mkdir -p -m=0777 /home/${primaryUser}/.local/state/nix/profiles - mkdir -p -m=0777 /home/${primaryUser}/.local/state/home-manager/gcroots - mkdir -p -m=0777 /home/${primaryUser}/.local/share/nix/ - printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /home/${primaryUser}/.local/share/nix/trusted-settings.json > /dev/null - mkdir -p /root/.local/share/nix/ - printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /root/.local/share/nix/trusted-settings.json > /dev/null - ''; - }; - systemd = { - services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ]; - targets = { - sleep.enable = false; - suspend.enable = false; - hibernate.enable = false; - hybrid-sleep.enable = false; + system.activationScripts.cache = { + text = '' + mkdir -p -m=0777 /home/${primaryUser}/.local/state/nix/profiles + mkdir -p -m=0777 /home/${primaryUser}/.local/state/home-manager/gcroots + mkdir -p -m=0777 /home/${primaryUser}/.local/share/nix/ + printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /home/${primaryUser}/.local/share/nix/trusted-settings.json > /dev/null + mkdir -p /root/.local/share/nix/ + printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /root/.local/share/nix/trusted-settings.json > /dev/null + ''; + }; + systemd = { + services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ]; + targets = { + sleep.enable = false; + suspend.enable = false; + hibernate.enable = false; + hybrid-sleep.enable = false; + }; + }; + + system.stateVersion = lib.mkForce "23.05"; + + networking = { + hostName = "drugstore"; + wireless.enable = false; }; }; - - system.stateVersion = lib.mkForce "23.05"; - - networking = { - hostName = "drugstore"; - wireless.enable = false; - }; - }; - } + } #+end_src @@ -5092,11 +5187,7 @@ The interesting part is in the start: TODO #+begin_src nix :tangle lib/default.nix - { self, lib, systems, inputs, outputs, ... }: - let - linuxUser = "swarsel"; - macUser = "leon.schwarzaeugl"; - in + { self, lib, systems, inputs, ... }: { mkIfElseList = p: yes: no: lib.mkMerge [ @@ -5141,88 +5232,6 @@ TODO forEachSystem = f: lib.genAttrs (import systems) (system: f lib.swarselsystems.pkgsFor.${system}); - mkFullHost = host: type: { - ${host} = - let - systemFunc = if (type == "nixos") then lib.nixosSystem else inputs.nix-darwin.lib.darwinSystem; - in - systemFunc { - specialArgs = { inherit inputs outputs lib self; }; - modules = [ - { - node.name = host; - node.secretsDir = ../hosts/${type}/${host}/secrets; - } - # put inports here that are for all hosts - inputs.disko.nixosModules.disko - inputs.sops-nix.nixosModules.sops - inputs.impermanence.nixosModules.impermanence - inputs.lanzaboote.nixosModules.lanzaboote - inputs.fw-fanctrl.nixosModules.default - "${self}/hosts/${type}/${host}" - { - _module.args.primaryUser = linuxUser; - } - ] ++ - (if (host == "iso") then [ - inputs.nix-topology.nixosModules.default - ] else - ([ - # put nixos imports here that are for all servers and normal hosts - inputs.nix-topology.nixosModules.default - "${self}/modules/${type}/common" - inputs.stylix.nixosModules.stylix - inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm - ] ++ (if (type == "nixos") then [ - inputs.home-manager.nixosModules.home-manager - "${self}/profiles/nixos" - "${self}/modules/nixos/server" - "${self}/modules/nixos/optional" - { - home-manager.users."${linuxUser}".imports = [ - # put home-manager imports here that are for all normal hosts - "${self}/modules/home/common" - "${self}/modules/home/server" - "${self}/modules/home/optional" - "${self}/profiles/home" - ]; - } - ] else [ - # put nixos imports here that are for darwin hosts - "${self}/modules/darwin/nixos/common" - "${self}/profiles/darwin" - inputs.home-manager.darwinModules.home-manager - { - home-manager.users."${macUser}".imports = [ - # put home-manager imports here that are for darwin hosts - "${self}/modules/darwin/home" - "${self}/modules/home/server" - "${self}/modules/home/optional" - "${self}/profiles/home" - ]; - } - ]) - )); - }; - }; - - mkHalfHost = host: type: pkgs: { - ${host} = - let - systemFunc = if (type == "home") then inputs.home-manager.lib.homeManagerConfiguration else inputs.nix-on-droid.lib.nixOnDroidConfiguration; - in - systemFunc - { - inherit pkgs; - extraSpecialArgs = { inherit inputs outputs lib self; }; - modules = [ "${self}/hosts/${type}/${host}" ]; - }; - }; - - mkFullHostConfigs = hosts: type: lib.foldl (acc: set: acc // set) { } (lib.map (host: lib.swarselsystems.mkFullHost host type) hosts); - - mkHalfHostConfigs = hosts: type: pkgs: lib.foldl (acc: set: acc // set) { } (lib.map (host: lib.swarselsystems.mkHalfHost host type pkgs) hosts); - readHosts = type: lib.attrNames (builtins.readDir "${self}/hosts/${type}"); readNix = type: lib.filter (name: name != "default.nix") (lib.attrNames (builtins.readDir "${self}/${type}")); @@ -5533,6 +5542,60 @@ in }; } +#+end_src +**** Globals + +#+begin_src nix :tangle nix/globals.nix + { inputs, ... }: + { + flake = + { + config, + lib, + ... + }: + { + globals = + let + globalsSystem = lib.evalModules { + prefix = [ "globals" ]; + specialArgs = { + inherit lib; + inherit inputs; + inherit (config) nodes; + }; + modules = [ + ../modules/nixos/common/globals.nix + ( + { lib, ... }: + { + globals = lib.mkMerge ( + lib.concatLists ( + lib.flip lib.mapAttrsToList config.nodes ( + name: cfg: + builtins.addErrorContext "while aggregating globals from nixosConfigurations.${name} into flake-level globals:" cfg.config._globalsDefs + ) + ) + ); + } + ) + ]; + }; + in + { + # Make sure the keys of this attrset are trivially evaluatable to avoid infinite recursion, + # therefore we inherit relevant attributes from the config. + inherit (globalsSystem.config.globals) + domains + services + macs + myuser + root + ; + }; + }; + } + #+end_src ** NixOS :PROPERTIES: @@ -5604,38 +5667,6 @@ I usually use =mutableUsers = false= in my NixOS configuration. However, on a ne isImpermanence = lib.mkEnableOption "use impermanence on this system"; isSecureBoot = lib.mkEnableOption "use secure boot on this system"; }; - globals = lib.mkOption { - default = { }; - type = lib.types.submodule { - options = { - - services = lib.mkOption { - type = lib.types.attrsOf ( - lib.types.submodule { - options = { - domain = lib.mkOption { - type = lib.types.str; - description = "Domain that the service runs under"; - }; - }; - } - ); - }; - domains = { - main = lib.mkOption { - type = lib.types.str; - description = "My main domain."; - }; - }; - }; - }; - }; - # _globalsDefs = lib.mkOption { - # type = lib.types.unspecified; - # default = options.globals.definitions; - # readOnly = true; - # internal = true; - # }; }; } #+end_src @@ -5810,6 +5841,86 @@ A breakdown of the flags being set: } #+end_src +**** Global options + +#+begin_src nix :tangle modules/nixos/common/globals.nix +{ lib, options, ... }: +let + inherit (lib) + mkOption + types + ; + +in +{ + options = { + globals = mkOption { + default = { }; + type = types.submodule { + options = { + root = { + hashedPassword = mkOption { + type = types.str; + description = "My root user's password hash."; + }; + }; + + myuser = { + name = mkOption { + type = types.str; + description = "My unix username."; + }; + hashedPassword = mkOption { + type = types.str; + description = "My unix password hash."; + }; + }; + + + services = mkOption { + type = types.attrsOf ( + types.submodule { + options = { + domain = mkOption { + type = types.str; + description = "The domain under which this service can be reached"; + }; + }; + } + ); + }; + + domains = { + me = mkOption { + type = types.str; + description = "My main domain."; + }; + + personal = mkOption { + type = types.str; + description = "My personal domain."; + }; + }; + + macs = mkOption { + default = { }; + type = types.attrsOf types.str; + description = "Known MAC addresses for external devices."; + }; + }; + }; + }; + + _globalsDefs = mkOption { + type = types.unspecified; + default = options.globals.definitions; + readOnly = true; + internal = true; + }; + }; +} +#+end_src + **** System Packages :PROPERTIES: :CUSTOM_ID: h:0e7e8bea-ec58-499c-9731-09dddfc39532 @@ -7910,7 +8021,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t let serviceName = "kavita"; serviceUser = "kavita"; - serviceDomain = "scroll.swarsel.win"; + serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; servicePort = 8080; in { @@ -7933,6 +8044,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t info = "https://${serviceDomain}"; icon = "${self}/topology/images/kavita.png"; }; + globals.services.${serviceName}.domain = serviceDomain; services.kavita = { enable = true; @@ -8002,7 +8114,8 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t ]; }; - topology.self.services.jellyfin.info = "https://${serviceDomain}"; + topology.self.services.${serviceName}.info = "https://${serviceDomain}"; + globals.services.${serviceName}.domain = serviceDomain; services.jellyfin = { enable = true; @@ -8085,6 +8198,8 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t networking.firewall.allowedTCPPorts = [ 4040 ]; + globals.services.${serviceName}.domain = serviceDomain; + services.navidrome = { enable = true; openFirewall = true; @@ -8444,6 +8559,8 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t }; }; + globals.services.${serviceName}.domain = matrixDomain; + services = { postgresql = { enable = true; @@ -8728,6 +8845,9 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t }; }; + + globals.services.${serviceName}.domain = serviceDomain; + services = { nextcloud = { enable = true; @@ -8785,7 +8905,7 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t :END: #+begin_src nix :tangle modules/nixos/server/immich.nix - { lib, config, ... }: + { lib, config, globals, ... }: let serviceDomain = "shots.swarsel.win"; servicePort = 3001; @@ -8800,7 +8920,8 @@ Here I am forcing =startWhenNeeded= to false so that the value will not be set t extraGroups = [ "video" "render" "users" ]; }; - topology.self.services.immich.info = "https://${serviceDomain}"; + topology.self.services.${serviceName}.info = "https://${serviceDomain}"; + globals.services.${serviceName}.domain = serviceDomain; services.immich = { enable = true; @@ -8891,6 +9012,8 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= networking.firewall.allowedTCPPorts = [ servicePort ]; + globals.services.${serviceName}.domain = serviceDomain; + services = { paperless = { enable = true; @@ -9085,6 +9208,8 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= prowlarr.info = "https://${serviceDomain}/prowlarr"; }; + globals.services.transmission.domain = serviceDomain; + services = { radarr = { enable = true; @@ -9206,6 +9331,8 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml= networking.firewall.allowedTCPPorts = [ servicePort ]; + globals.services.${serviceName}.domain = serviceDomain; + services.syncthing = { enable = true; user = serviceUser; @@ -9420,6 +9547,7 @@ This section exposes several metrics that I use to check the health of my server networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ]; topology.self.services.prometheus.info = "https://${serviceDomain}/${prometheusWebRoot}"; + globals.services.${moduleName}.domain = serviceDomain; services = { grafana = { @@ -9746,12 +9874,14 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with # }; }; - topology.self.services.freshrss = { + topology.self.services.${serviceName} = { name = "FreshRSS"; info = "https://${serviceDomain}"; icon = "${self}/topology/images/freshrss.png"; }; + globals.services.${serviceName}.domain = serviceDomain; + services.freshrss = { enable = true; virtualHost = serviceDomain; @@ -9829,6 +9959,8 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with kanidm-forgejo-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; }; }; + globals.services.${serviceName}.domain = serviceDomain; + services.forgejo = { enable = true; user = serviceUser; @@ -9976,11 +10108,13 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with sops.secrets.swarsel = { owner = "root"; }; - topology.self.services.anki = { + topology.self.services.${serviceName} = { name = lib.mkForce "Anki Sync Server"; info = "https://${serviceDomain}"; }; + globals.services.${serviceName}.domain = serviceDomain; + services.anki-sync-server = { enable = true; port = servicePort; @@ -10036,7 +10170,7 @@ A stupid (but simple) way to get the =originUrl= is to simply set any URL there To get other URLs (token, etc.), use https:///oauth2/openid//.well-known/oauth-authorization-server, e.g. https://sso.swarsel.win/oauth2/openid/nextcloud/.well-known/oauth-authorization-server, with clienID being the client name as specified in kanidm. #+begin_src nix :tangle modules/nixos/server/kanidm.nix - { self, lib, pkgs, config, ... }: + { self, lib, pkgs, config, globals, ... }: let certsSopsFile = self + /secrets/certs/secrets.yaml; serviceDomain = "sso.swarsel.win"; @@ -10044,7 +10178,7 @@ To get other URLs (token, etc.), use https:///oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid//oauth2/openid/