diff --git a/SwarselSystems.org b/SwarselSystems.org index 22247d7..5dd1d8c 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -832,7 +832,7 @@ More information on the actual packages build can be found in [[#h:64a5cc16-6b16 inherit (self.outputs) lib; in { - packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import "${self}/pkgs" { inherit self lib pkgs; }); + packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import "${self}/pkgs/flake" { inherit self lib pkgs; }); }; perSystem = { pkgs, system, ... }: @@ -1725,7 +1725,7 @@ On the structure of overlays: as you notice, all of the attributes within overla overlays = { default = final: prev: let - additions = final: _: import "${self}/pkgs" { pkgs = final; inherit self lib; } + additions = final: _: import "${self}/pkgs/flake" { pkgs = final; inherit self lib; } // { swarsel-nix = import inputs.swarsel-nix { pkgs = prev; @@ -4646,11 +4646,13 @@ in :END: #+begin_src nix-ts :tangle modules/nixos/common/home-manager-secrets.nix - { lib, config, globals, ... }: + { self, lib, config, globals, ... }: let inherit (config.swarselsystems) mainUser homeDir; inherit (config.repo.secrets.common.emacs) radicaleUser; modules = config.home-manager.users.${mainUser}.swarselmodules; + + certsSopsFile = self + /secrets/certs/secrets.yaml; in { config = lib.mkIf config.swarselsystems.withHomeManager { @@ -4670,6 +4672,8 @@ in github-nixpkgs-review-token = { owner = mainUser; }; }) // (lib.optionalAttrs modules.emacs { emacs-radicale-pw = { owner = mainUser; }; + }) // (lib.optionalAttrs modules.optional.work { + harica-root-ca = { sopsFile = certsSopsFile; path = "${homeDir}/.aws/certs/harica-root.pem"; owner = mainUser; }; }) // (lib.optionalAttrs modules.anki { anki-user = { owner = mainUser; }; anki-pw = { owner = mainUser; }; @@ -4851,7 +4855,19 @@ A breakdown of the flags being set: system.stateVersion = lib.mkDefault "23.05"; nixpkgs = { - overlays = [ outputs.overlays.default ]; + overlays = [ + outputs.overlays.default + (final: prev: + let + additions = final: _: import "${self}/pkgs/config" { + inherit self config lib; + pkgs = final; + homeConfig = config.home-manager.users.${config.swarselsystems.mainUser}; + }; + in + additions final prev + ) + ]; config = { allowUnfree = true; }; @@ -12220,97 +12236,108 @@ Again, we adapt =nix= to our needs, enable the home-manager command for non-NixO let inherit (config.swarselsystems) mainUser flakePath isNixos isLinux; in - { - options.swarselmodules.general = lib.mkEnableOption "general nix settings"; - config = - let - nix-version = "2_30"; - in - lib.mkIf config.swarselmodules.general { - nix = lib.mkIf (!config.swarselsystems.isNixos) { - package = lib.mkForce pkgs.nixVersions."nix_${nix-version}"; - # extraOptions = '' - # plugin-files = ${pkgs.dev.nix-plugins}/lib/nix/plugins - # extra-builtins-file = ${self + /nix/extra-builtins.nix} - # ''; - extraOptions = - let - nix-plugins = pkgs.nix-plugins.override { - nixComponents = pkgs.nixVersions."nixComponents_${nix-version}"; - }; - in - '' + { + options.swarselmodules.general = lib.mkEnableOption "general nix settings"; + config = + let + nix-version = "2_30"; + in + lib.mkIf config.swarselmodules.general { + nix = lib.mkIf (!config.swarselsystems.isNixos) { + package = lib.mkForce pkgs.nixVersions."nix_${nix-version}"; + # extraOptions = '' + # plugin-files = ${pkgs.dev.nix-plugins}/lib/nix/plugins + # extra-builtins-file = ${self + /nix/extra-builtins.nix} + # ''; + extraOptions = + let + nix-plugins = pkgs.nix-plugins.override { + nixComponents = pkgs.nixVersions."nixComponents_${nix-version}"; + }; + in + '' plugin-files = ${nix-plugins}/lib/nix/plugins extra-builtins-file = ${self + /nix/extra-builtins.nix} - ''; - settings = { - experimental-features = [ - "nix-command" - "flakes" - "ca-derivations" - "cgroups" - "pipe-operators" - ]; - trusted-users = [ "@wheel" "${mainUser}" ]; - connect-timeout = 5; - bash-prompt-prefix = "$SHLVL:\\w "; - bash-prompt = "$(if [[ $? -gt 0 ]]; then printf \"\"; else printf \"\"; fi)λ "; - fallback = true; - min-free = 128000000; - max-free = 1000000000; - auto-optimise-store = true; - warn-dirty = false; - max-jobs = 1; - use-cgroups = lib.mkIf isLinux true; - }; - }; + ''; + settings = { + experimental-features = [ + "nix-command" + "flakes" + "ca-derivations" + "cgroups" + "pipe-operators" + ]; + trusted-users = [ "@wheel" "${mainUser}" ]; + connect-timeout = 5; + bash-prompt-prefix = "$SHLVL:\\w "; + bash-prompt = "$(if [[ $? -gt 0 ]]; then printf \"\"; else printf \"\"; fi)λ "; + fallback = true; + min-free = 128000000; + max-free = 1000000000; + auto-optimise-store = true; + warn-dirty = false; + max-jobs = 1; + use-cgroups = lib.mkIf isLinux true; + }; + }; - # nixpkgs.overlays = lib.mkIf isNixos (lib.mkForce null); - nixpkgs = lib.mkIf (!isNixos) { - overlays = [ outputs.overlays.default ]; - config = { - allowUnfree = true; - }; - }; + nixpkgs = lib.mkIf (!isNixos) { + overlays = [ + outputs.overlays.default + (final: prev: + let + additions = final: _: import "${self}/pkgs/config" { + inherit self config lib; + pkgs = final; + homeConfig = config; + }; + in + additions final prev + ) + ]; + config = { + allowUnfree = true; + }; + }; - programs = { - # home-manager.enable = lib.mkIf (!isNixos) true; - man = { - enable = true; - generateCaches = true; - }; - }; + programs = { + # home-manager.enable = lib.mkIf (!isNixos) true; + man = { + enable = true; + generateCaches = true; + }; + }; - targets.genericLinux.enable = lib.mkIf (!isNixos) true; + targets.genericLinux.enable = lib.mkIf (!isNixos) true; - home = { - username = lib.mkDefault mainUser; - homeDirectory = lib.mkDefault "/home/${mainUser}"; - stateVersion = lib.mkDefault "23.05"; - keyboard.layout = "us"; - sessionVariables = { - FLAKE = "/home/${mainUser}/.dotfiles"; - }; - extraOutputsToInstall = [ - "doc" - "info" - "devdoc" - ]; - packages = lib.mkIf (!isNixos) [ - (pkgs.symlinkJoin { - name = "home-manager"; - buildInputs = [ pkgs.makeWrapper ]; - paths = [ pkgs.home-manager ]; - postBuild = '' + home = { + username = lib.mkDefault mainUser; + homeDirectory = lib.mkDefault "/home/${mainUser}"; + stateVersion = lib.mkDefault "23.05"; + keyboard.layout = "us"; + sessionVariables = { + FLAKE = "/home/${mainUser}/.dotfiles"; + }; + extraOutputsToInstall = [ + "doc" + "info" + "devdoc" + ]; + packages = lib.mkIf (!isNixos) [ + (pkgs.symlinkJoin { + name = "home-manager"; + buildInputs = [ pkgs.makeWrapper ]; + paths = [ pkgs.home-manager ]; + postBuild = '' wrapProgram $out/bin/home-manager \ --append-flags '--flake ${flakePath}#$(hostname)' - ''; - }) - ]; - }; - }; + ''; + }) + ]; + }; + }; - } + } #+end_src **** nixGL @@ -12583,6 +12610,7 @@ This is just a separate container for derivations defined in [[#h:64a5cc16-6b16- pass-fuzzel cdw cdb + cdr bak timer e @@ -12607,8 +12635,6 @@ This is just a separate container for derivations defined in [[#h:64a5cc16-6b16- sshrm endme git-replace - - rustdesk-vbc ]; }; } @@ -13533,7 +13559,8 @@ Currently I only use it as before with =initExtra= though. hotspot = "nmcli connection up local; nmcli device wifi hotspot;"; youtube-dl = "yt-dlp"; cat-orig = "cat"; - cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\""; + # cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\""; + cdr = "source cdr"; nix-ldd-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; nix-ldd-locate = "nix-locate --minimal --top-level -w "; @@ -14326,6 +14353,19 @@ Currently I only use it as before with =initExtra= though. _children = [{ Resize._args = [ "Increase" ]; }]; }; } + { + bind = { + _args = [ "Alt r" ]; + _children = [ + { + WriteChars._args = [ "source cdr" ]; + } + { + WriteChars._args = [ "\n" ]; + } + ]; + }; + } { bind = { _args = [ "Alt f" ]; @@ -17880,31 +17920,39 @@ When setting up a new machine: #+end_src #+begin_src nix-ts :tangle modules/home/optional/work.nix :noweb yes - { self, config, pkgs, lib, vars, nixosConfig ? config, ... }: + { self, inputs, config, pkgs, lib, vars, nixosConfig ? config, ... }: let - inherit (config.swarselsystems) homeDir; + inherit (config.swarselsystems) homeDir mainUser; inherit (nixosConfig.repo.secrets.local.mail) allMailAddresses; inherit (nixosConfig.repo.secrets.local.work) mailAddress; + + certsSopsFile = self + /secrets/certs/secrets.yaml; in { options.swarselmodules.optional.work = lib.mkEnableOption "optional work settings"; config = lib.mkIf config.swarselmodules.optional.work - { - home.packages = with pkgs; [ - stable.teams-for-linux - shellcheck - dig - docker - postman - # rclone - libguestfs-with-appliance - prometheus.cli - tigervnc - # openstackclient + ({ + home = { + packages = with pkgs; [ + stable.teams-for-linux + shellcheck + dig + docker + postman + # rclone + libguestfs-with-appliance + prometheus.cli + tigervnc + # openstackclient - vscode - ]; + vscode + rustdesk-vbc + ]; + sessionVariables = { + AWS_CA_BUNDLE = nixosConfig.sops.secrets.harica-root-ca.path; + }; + }; systemd.user.sessionVariables = { DOCUMENT_DIR_WORK = lib.mkForce "${homeDir}/Documents/Work"; } // lib.optionalAttrs (!config.swarselsystems.isPublic) { @@ -17997,10 +18045,10 @@ When setting up a new machine: let inherit (config.wayland.windowManager.sway.config) modifier; in - { - "${modifier}+Shift+d" = "exec ${pkgs.quickpass}/bin/quickpass work/adm/${user1}/${user1Long}@${domain1}"; - "${modifier}+Shift+i" = "exec ${pkgs.quickpass}/bin/quickpass work/${mailAddress}"; - }; + { + "${modifier}+Shift+d" = "exec ${pkgs.quickpass}/bin/quickpass work/adm/${user1}/${user1Long}@${domain1}"; + "${modifier}+Shift+i" = "exec ${pkgs.quickpass}/bin/quickpass work/${mailAddress}"; + }; }; }; @@ -18526,7 +18574,16 @@ When setting up a new machine: }; }; - }; + } // lib.optionalAttrs (inputs ? sops) { + sops.secrets = lib.mkIf (!config.swarselsystems.isPublic && !config.swarselsystems.isNixos) { + harica-root-ca = { + sopsFile = certsSopsFile; + path = "${homeDir}/.aws/certs/harica-root.pem"; + owner = mainUser; + }; + }; + + }); } @@ -18930,7 +18987,7 @@ In short, the options defined here are passed to the modules systems using =_mod } #+end_src -** Packages +*** Packages :PROPERTIES: :CUSTOM_ID: h:64a5cc16-6b16-4802-b421-c67ccef853e1 :END: @@ -18939,23 +18996,25 @@ This is the central station for self-defined packages. These are all referenced Note: The structure of generating the packages was changed in commit =2cf03a3 refactor: package and module generation=. That commit can be checked out in order to see a simpler version of achieving the same thing. -#+begin_src nix-ts :tangle pkgs/default.nix +*** Packages (flake) + +#+begin_src nix-ts :tangle pkgs/flake/default.nix { self, lib, pkgs, ... }: let mkPackages = names: pkgs: builtins.listToAttrs (map (name: { inherit name; - value = pkgs.callPackage "${self}/pkgs/${name}" { inherit self name; }; + value = pkgs.callPackage "${self}/pkgs/flake/${name}" { inherit self name; }; }) names); - packageNames = lib.swarselsystems.readNix "pkgs"; + packageNames = lib.swarselsystems.readNix "pkgs/flake"; in mkPackages packageNames pkgs #+end_src -*** pass-fuzzel +**** pass-fuzzel :PROPERTIES: :CUSTOM_ID: h:4fce458d-7c9c-4bcd-bd90-76b745fe5ce3 :END: @@ -19016,7 +19075,7 @@ This app allows me, in conjunction with my Yubikey, to quickly enter passwords w notify-send -u critical -a pass -t 1000 "Copied/Typed Password" #+end_src -#+begin_src nix-ts :tangle pkgs/pass-fuzzel/default.nix +#+begin_src nix-ts :tangle pkgs/flake/pass-fuzzel/default.nix { self, name, writeShellApplication, libnotify, pass, fuzzel, wtype }: writeShellApplication { inherit name; @@ -19026,7 +19085,7 @@ This app allows me, in conjunction with my Yubikey, to quickly enter passwords w #+end_src -*** quickpass +**** quickpass #+begin_src shell :tangle files/scripts/quickpass.sh :mkdirp yes shopt -s nullglob globstar @@ -19042,7 +19101,7 @@ This app allows me, in conjunction with my Yubikey, to quickly enter passwords w notify-send -u critical -a pass -t 1000 "Typed Password" #+end_src -#+begin_src nix-ts :tangle pkgs/quickpass/default.nix +#+begin_src nix-ts :tangle pkgs/flake/quickpass/default.nix { self, name, writeShellApplication, libnotify, pass, wtype }: writeShellApplication { inherit name; @@ -19052,7 +19111,7 @@ This app allows me, in conjunction with my Yubikey, to quickly enter passwords w #+end_src -*** cura5 +**** cura5 :PROPERTIES: :CUSTOM_ID: h:799579f3-ddd3-4f76-928a-a8c665980476 :END: @@ -19060,7 +19119,7 @@ This app allows me, in conjunction with my Yubikey, to quickly enter passwords w The version of =cura= used to be quite outdated in nixpkgs. I am fetching a newer AppImage here and use that instead. -#+begin_src nix-ts :tangle pkgs/cura5/default.nix +#+begin_src nix-ts :tangle pkgs/flake/cura5/default.nix # taken from https://github.com/NixOS/nixpkgs/issues/186570#issuecomment-1627797219 { appimageTools, fetchurl, writeScriptBin, pkgs, ... }: @@ -19093,7 +19152,7 @@ The version of =cura= used to be quite outdated in nixpkgs. I am fetching a newe #+end_src -*** hm-specialisation +**** hm-specialisation :PROPERTIES: :CUSTOM_ID: h:e6612cff-0804-47ef-9f2b-d2cc6d81a896 :END: @@ -19101,7 +19160,7 @@ The version of =cura= used to be quite outdated in nixpkgs. I am fetching a newe This script allows for quick git home-manager specialisation switching. -#+begin_src nix-ts :tangle pkgs/hm-specialisation/default.nix +#+begin_src nix-ts :tangle pkgs/flake/hm-specialisation/default.nix { name, writeShellApplication, fzf, findutils, home-manager, ... }: writeShellApplication { @@ -19117,7 +19176,7 @@ This script allows for quick git home-manager specialisation switching. #+end_src -*** cdw +**** cdw :PROPERTIES: :CUSTOM_ID: h:73b14c7a-5444-4fed-b7ac-d65542cdeda3 :END: @@ -19125,7 +19184,7 @@ This script allows for quick git home-manager specialisation switching. This script allows for quick git worktree switching. -#+begin_src nix-ts :tangle pkgs/cdw/default.nix +#+begin_src nix-ts :tangle pkgs/flake/cdw/default.nix { name, writeShellApplication, fzf, ... }: writeShellApplication { @@ -19139,14 +19198,14 @@ This script allows for quick git worktree switching. #+end_src -*** cdb +**** cdb :PROPERTIES: :CUSTOM_ID: h:5ad99997-e54c-4f0b-9ab7-15f76b1e16e1 :END: This script allows for quick git branch switching. -#+begin_src nix-ts :tangle pkgs/cdb/default.nix +#+begin_src nix-ts :tangle pkgs/flake/cdb/default.nix { name, writeShellApplication, fzf, ... }: writeShellApplication { @@ -19159,7 +19218,7 @@ This script allows for quick git branch switching. #+end_src -*** bak +**** bak :PROPERTIES: :CUSTOM_ID: h:03b1b77b-3ca8-4a8f-8e28-9f29004d96d3 :END: @@ -19167,7 +19226,7 @@ This script allows for quick git branch switching. This script lets me quickly backup files by appending =.bak= to the filename. -#+begin_src nix-ts :tangle pkgs/bak/default.nix +#+begin_src nix-ts :tangle pkgs/flake/bak/default.nix { name, writeShellApplication, ... }: writeShellApplication { @@ -19180,7 +19239,7 @@ This script lets me quickly backup files by appending =.bak= to the filename. #+end_src -*** timer +**** timer :PROPERTIES: :CUSTOM_ID: h:3c72d263-411c-44f0-90ff-55f14d4d9d49 :END: @@ -19188,7 +19247,7 @@ This script lets me quickly backup files by appending =.bak= to the filename. This app starts a configuratble timer and uses TTS to say something once the timer runs out. -#+begin_src nix-ts :tangle pkgs/timer/default.nix +#+begin_src nix-ts :tangle pkgs/flake/timer/default.nix { name, writeShellApplication, speechd, ... }: writeShellApplication { @@ -19201,7 +19260,7 @@ This app starts a configuratble timer and uses TTS to say something once the tim #+end_src -*** e +**** e :PROPERTIES: :CUSTOM_ID: h:1834df06-9238-4efa-9af6-851dafe66c68 :END: @@ -19234,7 +19293,7 @@ This is a shorthand for calling emacsclient mostly. Also, it hides the kittyterm fi #+end_src -#+begin_src nix-ts :tangle pkgs/e/default.nix +#+begin_src nix-ts :tangle pkgs/flake/e/default.nix { self, name, writeShellApplication, emacs30-pgtk, sway, jq }: writeShellApplication { inherit name; @@ -19244,7 +19303,7 @@ This is a shorthand for calling emacsclient mostly. Also, it hides the kittyterm #+end_src -*** command-not-found +**** command-not-found :PROPERTIES: :CUSTOM_ID: h:10268005-a9cd-4a00-967c-cbe975c552fa :END: @@ -19288,7 +19347,7 @@ The normal =command-not-found.sh= uses the outdated =nix-shell= commands as sugg } #+end_src -*** swarselcheck +**** swarselcheck :PROPERTIES: :CUSTOM_ID: h:82f4f414-749b-4d5a-aaaa-6e3ec15fbc3d :END: @@ -19360,7 +19419,7 @@ This app checks for different apps that I keep around in the scratchpad for quic fi #+end_src -#+begin_src nix-ts :tangle pkgs/swarselcheck/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarselcheck/default.nix { self, name, writeShellApplication, kitty, element-desktop, vesktop, spotify-player, jq }: writeShellApplication { inherit name; @@ -19370,7 +19429,7 @@ This app checks for different apps that I keep around in the scratchpad for quic #+end_src -*** swarselcheck-niri +**** swarselcheck-niri :PROPERTIES: :CUSTOM_ID: h:96da8360-2d23-4e86-9602-415fbdb972af :END: @@ -19414,7 +19473,7 @@ This app checks for different apps that I keep around in the scratchpad for quic fi #+end_src -#+begin_src nix-ts :tangle pkgs/swarselcheck-niri/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarselcheck-niri/default.nix { self, name, writeShellApplication, kitty, element-desktop, vesktop, spotify-player, jq }: writeShellApplication { inherit name; @@ -19424,7 +19483,7 @@ This app checks for different apps that I keep around in the scratchpad for quic #+end_src -*** swarselzellij +**** swarselzellij :PROPERTIES: :CUSTOM_ID: h:564c102c-e335-4f17-a613-c5a436bb4864 :END: @@ -19440,7 +19499,7 @@ This app checks for different apps that I keep around in the scratchpad for quic exec kitty -o confirm_os_window_close=0 zellij #+end_src -#+begin_src nix-ts :tangle pkgs/swarselzellij/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarselzellij/default.nix { self, name, writeShellApplication, kitty }: writeShellApplication { inherit name; @@ -19450,7 +19509,7 @@ This app checks for different apps that I keep around in the scratchpad for quic #+end_src -*** waybarupdate +**** waybarupdate :PROPERTIES: :CUSTOM_ID: h:f93f66f9-6b8b-478e-b139-b2f382c1f25e :END: @@ -19484,7 +19543,7 @@ This scripts checks if there are uncommited changes in either my dotfile repo, m echo "$OUT" #+end_src -#+begin_src nix-ts :tangle pkgs/waybarupdate/default.nix +#+begin_src nix-ts :tangle pkgs/flake/waybarupdate/default.nix { self, name, writeShellApplication, git }: writeShellApplication { inherit name; @@ -19494,7 +19553,7 @@ This scripts checks if there are uncommited changes in either my dotfile repo, m #+end_src -*** opacitytoggle +**** opacitytoggle :PROPERTIES: :CUSTOM_ID: h:a1d94db2-837a-40c4-bbd8-81ce847440ee :END: @@ -19509,7 +19568,7 @@ This app quickly toggles between 5% and 0% transparency. fi #+end_src -#+begin_src nix-ts :tangle pkgs/opacitytoggle/default.nix +#+begin_src nix-ts :tangle pkgs/flake/opacitytoggle/default.nix { self, name, writeShellApplication, sway }: writeShellApplication { inherit name; @@ -19518,7 +19577,7 @@ This app quickly toggles between 5% and 0% transparency. } #+end_src -*** fs-diff +**** fs-diff :PROPERTIES: :CUSTOM_ID: h:7c4e41b3-8c1e-4f71-87a6-30d40baed6a0 :END: @@ -19548,7 +19607,7 @@ This utility is used to compare the current state of the root directory with the done #+end_src -#+begin_src nix-ts :tangle pkgs/fs-diff/default.nix +#+begin_src nix-ts :tangle pkgs/flake/fs-diff/default.nix { self, name, writeShellApplication }: writeShellApplication { inherit name; @@ -19556,7 +19615,7 @@ This utility is used to compare the current state of the root directory with the } #+end_src -*** github-notifications +**** github-notifications :PROPERTIES: :CUSTOM_ID: h:a9398c4e-4d3b-4942-b03c-192f9c0517e5 :END: @@ -19564,7 +19623,7 @@ This utility is used to compare the current state of the root directory with the This utility checks if there are updated packages in nixpkgs-unstable. It does so by fully building the most recent configuration, which I do not love, but it has its merits once I am willing to switch to the newer version. -#+begin_src nix-ts :tangle pkgs/github-notifications/default.nix +#+begin_src nix-ts :tangle pkgs/flake/github-notifications/default.nix { name, writeShellApplication, jq, ... }: writeShellApplication { @@ -19580,7 +19639,7 @@ This utility checks if there are updated packages in nixpkgs-unstable. It does s } #+end_src -*** kanshare +**** kanshare :PROPERTIES: :CUSTOM_ID: h:3981cd16-00c0-4ea8-95e2-c6d8c04ec4e5 :END: @@ -19588,7 +19647,7 @@ This utility checks if there are updated packages in nixpkgs-unstable. It does s This utility checks if there are updated packages in nixpkgs-unstable. It does so by fully building the most recent configuration, which I do not love, but it has its merits once I am willing to switch to the newer version. -#+begin_src nix-ts :tangle pkgs/kanshare/default.nix +#+begin_src nix-ts :tangle pkgs/flake/kanshare/default.nix { name, writeShellApplication, wlr-randr, busybox, wl-mirror, mako, ... }: writeShellApplication { @@ -19602,7 +19661,7 @@ This utility checks if there are updated packages in nixpkgs-unstable. It does s } #+end_src -*** swarsel-bootstrap +**** swarsel-bootstrap :PROPERTIES: :CUSTOM_ID: h:74db57ae-0bb9-4257-84be-eddbc85130dd :END: @@ -19984,7 +20043,7 @@ This program sets up a new NixOS host remotely. It also takes care of secret man | [ | Babel | evaluation | exited | with | code | 1 | ] | -#+begin_src nix-ts :tangle pkgs/swarsel-bootstrap/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-bootstrap/default.nix { self, name, writeShellApplication, openssh }: writeShellApplication { inherit name; @@ -19993,7 +20052,7 @@ This program sets up a new NixOS host remotely. It also takes care of secret man } #+end_src -*** swarsel-rebuild +**** swarsel-rebuild :PROPERTIES: :CUSTOM_ID: h:1eabdc59-8832-44ca-a22b-11f848ab150a :END: @@ -20113,7 +20172,7 @@ This program sets up a new NixOS host remotely. It also takes care of secret man -#+begin_src nix-ts :tangle pkgs/swarsel-rebuild/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-rebuild/default.nix { self, name, writeShellApplication, git }: writeShellApplication { inherit name; @@ -20122,7 +20181,7 @@ This program sets up a new NixOS host remotely. It also takes care of secret man } #+end_src -*** swarsel-install +**** swarsel-install :PROPERTIES: :CUSTOM_ID: h:fbd8aaf2-9dca-4ca3-aca1-19d0d188a435 :END: @@ -20327,7 +20386,7 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f -#+begin_src nix-ts :tangle pkgs/swarsel-install/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-install/default.nix { self, name, writeShellApplication, git }: writeShellApplication { inherit name; @@ -20336,7 +20395,7 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f } #+end_src -*** swarsel-postinstall +**** swarsel-postinstall :PROPERTIES: :CUSTOM_ID: h:c98a7615-e5da-4f47-8ed1-2b2ea65519e9 :END: @@ -20418,7 +20477,7 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f -#+begin_src nix-ts :tangle pkgs/swarsel-postinstall/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-postinstall/default.nix { self, name, writeShellApplication, git }: writeShellApplication { inherit name; @@ -20427,12 +20486,12 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f } #+end_src -*** t2ts +**** t2ts :PROPERTIES: :CUSTOM_ID: h:5ad99997-e54c-4f0b-9ab7-15f76b1e16e1 :END: -#+begin_src nix-ts :tangle pkgs/t2ts/default.nix +#+begin_src nix-ts :tangle pkgs/flake/t2ts/default.nix { name, writeShellApplication, ... }: writeShellApplication { @@ -20445,12 +20504,12 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f #+end_src -*** ts2t +**** ts2t :PROPERTIES: :CUSTOM_ID: h:5ad99997-e54c-4f0b-9ab7-15f76b1e16e1 :END: -#+begin_src nix-ts :tangle pkgs/ts2t/default.nix +#+begin_src nix-ts :tangle pkgs/flake/ts2t/default.nix { name, writeShellApplication, ... }: writeShellApplication { @@ -20463,12 +20522,12 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f #+end_src -*** vershell +**** vershell :PROPERTIES: :CUSTOM_ID: h:7806b129-a4a5-4d10-af27-6cbeafbcb294 :END: -#+begin_src nix-ts :tangle pkgs/vershell/default.nix +#+begin_src nix-ts :tangle pkgs/flake/vershell/default.nix { name, writeShellApplication, ... }: writeShellApplication { @@ -20481,12 +20540,12 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f #+end_src -*** eontimer +**** eontimer :PROPERTIES: :CUSTOM_ID: h:9fda7829-09a4-4b8f-86f6-08b078ab2874 :END: -#+begin_src nix-ts :tangle pkgs/eontimer/default.nix +#+begin_src nix-ts :tangle pkgs/flake/eontimer/default.nix { lib , python3 , fetchFromGitHub @@ -20585,7 +20644,7 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f #+end_src -*** project +**** project :PROPERTIES: :CUSTOM_ID: h:154b6df4-dd50-4f60-9794-05a140d02994 :END: @@ -20600,7 +20659,7 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f direnv allow #+end_src -#+begin_src nix-ts :tangle pkgs/project/default.nix +#+begin_src nix-ts :tangle pkgs/flake/project/default.nix { self, name, writeShellApplication }: writeShellApplication { inherit name; @@ -20608,13 +20667,13 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f } #+end_src -*** fhs +**** fhs :PROPERTIES: :CUSTOM_ID: h:36d6c17c-6d91-4297-b76d-9d7feab6c1a0 :END: -#+begin_src nix-ts :tangle pkgs/fhs/default.nix +#+begin_src nix-ts :tangle pkgs/flake/fhs/default.nix { name, pkgs, ... }: let base = pkgs.appimageTools.defaultFhsEnvArgs; @@ -20628,7 +20687,7 @@ Autoformatting always puts the =EOF= with indentation, which makes shfmt check f }) #+end_src -*** swarsel-displaypower +**** swarsel-displaypower :PROPERTIES: :CUSTOM_ID: h:814d5e7f-4b95-412d-b246-33f888514ec6 :END: @@ -20640,7 +20699,7 @@ A crude script to power on all displays that might be attached. Needed because s swaymsg "output * dpms on" > /dev/null 2>&1 || true #+end_src -#+begin_src nix-ts :tangle pkgs/swarsel-displaypower/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-displaypower/default.nix { self, name, writeShellApplication, sway }: writeShellApplication { inherit name; @@ -20650,7 +20709,7 @@ A crude script to power on all displays that might be attached. Needed because s #+end_src -*** swarsel-mgba +**** swarsel-mgba :PROPERTIES: :CUSTOM_ID: h:799579f3-ddd3-4f76-928a-a8c665980476 :END: @@ -20658,7 +20717,7 @@ A crude script to power on all displays that might be attached. Needed because s AppImage version of mgba in which the lua scripting works. -#+begin_src nix-ts :tangle pkgs/swarsel-mgba/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-mgba/default.nix { appimageTools, fetchurl, ... }: let pname = "mgba"; @@ -20682,12 +20741,12 @@ AppImage version of mgba in which the lua scripting works. #+end_src -*** swarsel-deploy +**** swarsel-deploy :PROPERTIES: :CUSTOM_ID: h:c3362d4e-d3a8-43e8-9ef7-272b6de0572e :END: -#+begin_src nix-ts :tangle pkgs/swarsel-deploy/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-deploy/default.nix # heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix { name, bc, nix-output-monitor, writeShellApplication, ... }: writeShellApplication { @@ -20814,12 +20873,12 @@ AppImage version of mgba in which the lua scripting works. #+end_src -*** swarsel-build +**** swarsel-build :PROPERTIES: :CUSTOM_ID: h:c3362d4e-d3a8-43e8-9ef7-272b6de0572e :END: -#+begin_src nix-ts :tangle pkgs/swarsel-build/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-build/default.nix { name, nix-output-monitor, writeShellApplication, ... }: writeShellApplication { runtimeInputs = [ nix-output-monitor ]; @@ -20838,14 +20897,14 @@ AppImage version of mgba in which the lua scripting works. #+end_src -*** swarsel-instantiate +**** swarsel-instantiate :PROPERTIES: :CUSTOM_ID: h:95ebfd13-1f6b-427f-950d-e30c1ed6f9fa :END: This is a convenience function that calls =nix-instantiate= with a number of flags that I need in order to evaluate nix expressions in org-src blocks. -#+begin_src nix-ts :tangle pkgs/swarsel-instantiate/default.nix +#+begin_src nix-ts :tangle pkgs/flake/swarsel-instantiate/default.nix { name, writeShellApplication, ... }: writeShellApplication { inherit name; @@ -20857,7 +20916,7 @@ This is a convenience function that calls =nix-instantiate= with a number of fla #+end_src -*** sshrm +**** sshrm :PROPERTIES: :CUSTOM_ID: h:02842543-caca-4d4c-a4d2-7ac749b5c136 :END: @@ -20878,7 +20937,7 @@ This programs simply runs ssh-keygen on the last host that I tried to ssh into. fi #+end_src -#+begin_src nix-ts :tangle pkgs/sshrm/default.nix +#+begin_src nix-ts :tangle pkgs/flake/sshrm/default.nix { self, name, writeShellApplication, openssh }: writeShellApplication { inherit name; @@ -20886,11 +20945,11 @@ This programs simply runs ssh-keygen on the last host that I tried to ssh into. text = builtins.readFile "${self}/files/scripts/${name}.sh"; } #+end_src -*** endme +**** endme Sometimes my DE crashes after putting it to suspend - to be precise, it happens when I put it into suspend when I have multiple screens plugged in. I have never taken the time to debug the issue, but instead just switch to a different TTY and then use this script to kill the hanging session. -#+begin_src nix-ts :tangle pkgs/endme/default.nix +#+begin_src nix-ts :tangle pkgs/flake/endme/default.nix { name, writeShellApplication, ... }: writeShellApplication { inherit name; @@ -20903,12 +20962,12 @@ Sometimes my DE crashes after putting it to suspend - to be precise, it happens #+end_src -*** git-replace +**** git-replace This script allows for quick git replace of a string. -#+begin_src nix-ts :tangle pkgs/git-replace/default.nix +#+begin_src nix-ts :tangle pkgs/flake/git-replace/default.nix { name, writeShellApplication, git, gnugrep, findutils, ... }: writeShellApplication { @@ -20974,6 +21033,43 @@ This script allows for quick git replace of a string. } +#+end_src + +*** Packages (config) + +#+begin_src nix-ts :tangle pkgs/config/default.nix + { self, homeConfig, lib, pkgs, ... }: + let + mkPackages = names: pkgs: builtins.listToAttrs (map + (name: { + inherit name; + value = pkgs.callPackage "${self}/pkgs/config/${name}" { inherit self name homeConfig; }; + }) + names); + packageNames = lib.swarselsystems.readNix "pkgs/config"; + in + mkPackages packageNames pkgs +#+end_src + +**** cdr + + +#+begin_src nix-ts :tangle pkgs/config/cdr/default.nix + { name, homeConfig, writeShellApplication, fzf, ... }: + + writeShellApplication { + inherit name; + runtimeInputs = [ fzf ]; + text = '' + DOCUMENT_DIR_WORK=${homeConfig.systemd.user.sessionVariables.DOCUMENT_DIR_WORK or ""} + DOCUMENT_DIR_PRIV=${homeConfig.systemd.user.sessionVariables.DOCUMENT_DIR_PRIV} + FLAKE=${homeConfig.home.sessionVariables.FLAKE} + + cd "$( (find "$DOCUMENT_DIR_WORK" "$DOCUMENT_DIR_PRIV" -maxdepth 1 && echo "$FLAKE") | fzf )" + ''; + } + + #+end_src ** Profiles @@ -22117,6 +22213,22 @@ This function was found here: [[https://www.reddit.com/r/emacs/comments/re31i6/h (define-key minibuffer-local-filename-completion-map [C-backspace] #'up-directory) +#+end_src +**** Magit: List directories using vertico/consult + +#+begin_src emacs-lisp + + (defun swarsel/consult-magit-repos () + (interactive) + (require 'magit) + (let* ((repos (magit-list-repos)) + (repo (consult--read repos + :prompt "Magit repo: " + :require-match t + :history 'my/consult-magit-repos-history + :sort t))) + (magit-status repo))) + #+end_src **** org-mode: General setup :PROPERTIES: @@ -22321,6 +22433,7 @@ I also define some keybinds to some combinations directly. Those are used mostly "l" '(:ignore l :which-key "links") "lc" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (org-overview) )) :which-key "SwarselSystems.org") "le" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "Emacs") ) (org-overview) (org-cycle) )) :which-key "Emacs.org") + "lr" '(swarsel/consult-magit-repos :which-key "List repos") "ln" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "System") ) (org-overview) (org-cycle))) :which-key "Nixos.org") "lp" '((lambda () (interactive) (projectile-switch-project)) :which-key "switch project") "lg" '((lambda () (interactive) (magit-list-repositories)) :which-key "list git repos") @@ -22370,6 +22483,7 @@ I also define some keybinds to some combinations directly. Those are used mostly "C-c D" 'crux-duplicate-and-comment-current-line-or-region "" 'swarsel/last-buffer "M-\\" 'indent-region + "M-r" 'swarsel/consult-magit-repos "" 'yank "" 'kill-region "" 'kill-ring-save @@ -24083,8 +24197,8 @@ Also, Emacs needs a little extra love to accept my Yubikey for git commits etc. (use-package magit :config - (setq magit-repository-directories `((,swarsel-work-projects-directory . 1) - (,swarsel-private-projects-directory . 1) + (setq magit-repository-directories `((,swarsel-work-projects-directory . 3) + (,swarsel-private-projects-directory . 3) ("~/.dotfiles/" . 0))) :custom (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) ; stay in the same window diff --git a/files/emacs/init.el b/files/emacs/init.el index 5a013e3..5ada956 100644 --- a/files/emacs/init.el +++ b/files/emacs/init.el @@ -162,6 +162,17 @@ create a new one." (define-key minibuffer-local-filename-completion-map [C-backspace] #'up-directory) +(defun swarsel/consult-magit-repos () + (interactive) + (require 'magit) + (let* ((repos (magit-list-repos)) + (repo (consult--read repos + :prompt "Magit repo: " + :require-match t + :history 'my/consult-magit-repos-history + :sort t))) + (magit-status repo))) + (defun swarsel/org-mode-setup () (variable-pitch-mode 1) (add-hook 'org-tab-first-hook 'org-end-of-line) @@ -272,6 +283,7 @@ create a new one." "l" '(:ignore l :which-key "links") "lc" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (org-overview) )) :which-key "SwarselSystems.org") "le" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "Emacs") ) (org-overview) (org-cycle) )) :which-key "Emacs.org") + "lr" '(swarsel/consult-magit-repos :which-key "List repos") "ln" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "System") ) (org-overview) (org-cycle))) :which-key "Nixos.org") "lp" '((lambda () (interactive) (projectile-switch-project)) :which-key "switch project") "lg" '((lambda () (interactive) (magit-list-repositories)) :which-key "list git repos") @@ -321,6 +333,7 @@ create a new one." "C-c D" 'crux-duplicate-and-comment-current-line-or-region "" 'swarsel/last-buffer "M-\\" 'indent-region + "M-r" 'swarsel/consult-magit-repos "" 'yank "" 'kill-region "" 'kill-ring-save @@ -1241,8 +1254,8 @@ create a new one." (use-package magit :config - (setq magit-repository-directories `((,swarsel-work-projects-directory . 1) - (,swarsel-private-projects-directory . 1) + (setq magit-repository-directories `((,swarsel-work-projects-directory . 3) + (,swarsel-private-projects-directory . 3) ("~/.dotfiles/" . 0))) :custom (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) ; stay in the same window diff --git a/index.html b/index.html index 6583879..73a386f 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + SwarselSystems: NixOS + Emacs Configurationo @@ -209,8 +209,8 @@
  • 1.4. Hosts
  • 1.5. Programs
  • 1.6. Services
  • -
  • 1.7. Manual steps when setting up a new machine
  • -
  • 1.8. Current issues
  • +
  • 1.7. Manual steps when setting up a new machine
  • +
  • 1.8. Current issues
  • 2. flake.nix @@ -263,33 +263,45 @@
  • 3.1.2.2.3. disko
  • -
  • 3.1.2.3. Winters (Server) +
  • 3.1.2.3. Winters (Server: ASRock J4105-ITX)
  • -
  • 3.1.2.4. machpizza (MacBook Pro)
  • -
  • 3.1.2.5. Magicant (Phone)
  • -
  • 3.1.2.6. Treehouse (DGX Spark)
  • +
  • 3.1.2.4. Summers (Server: ASUS Z10PA-D8) + +
  • +
  • 3.1.2.5. Hintbooth (Router: HUNSN RM02) + +
  • +
  • 3.1.2.6. machpizza (MacBook Pro)
  • +
  • 3.1.2.7. Magicant (Phone)
  • +
  • 3.1.2.8. Treehouse (DGX Spark)
  • 3.1.3. Virtual hosts
  • 3.1.4. Utility hosts @@ -301,7 +313,7 @@
  • 3.1.4.2. TODO Drugstore (ISO installer config)
  • -
  • 3.1.4.3. ChaosTheatre (Demo Physical/VM) +
  • 3.1.4.3. Hotel (Demo Physical/VM)
  • 3.2.4. Darwin @@ -445,15 +462,15 @@
  • 3.2.5.8. Hibernation
  • 3.2.5.9. BTRFS
  • 3.2.5.10. work
  • -
  • 3.2.5.11. microvm-host
  • -
  • 3.2.5.12. microvm-guest
  • +
  • 3.2.5.11. microvm-host
  • +
  • 3.2.5.12. microvm-guest
  • 3.3. Home-manager
  • 3.3.3. Server @@ -550,73 +574,81 @@
  • 4.4.2. Nix Mode
  • @@ -735,7 +769,7 @@
  • 4.4.5. Ansible
  • 4.4.6. Dockerfile
  • 4.4.7. Terraform Mode
  • -
  • 4.4.8. nixpkgs-fmt
  • +
  • 4.4.8. nix formatting
  • 4.4.9. shfmt
  • 4.4.10. Markdown Mode @@ -1153,16 +1187,21 @@ Here I give a brief overview over the hostmachines that I am using. This is held
    | Name               | Hardware                                            | Use                                                  |
     |--------------------|-----------------------------------------------------|------------------------------------------------------|
     |💻 **pyramid**      | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                          |
    -|💻 **bakery**       | Lenovo Ideapad 720S-13IKB                           | Personal lapto                                       |
    -|💻 **machpizza**    | MacBook Pro 2016                                    | MacOS sandbox                                        |
    -|🖥️ **winters**      | ASRock J4105-ITX, 32GB RAM                          | Main homeserver and data storgae                     |
    -|🖥️ **milkywell**    | Oracle Cloud: VM.Standard.E2.1.Micro                | Server for lightweight synchronization tasks         |
    -|🖥️ **moonside**     | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services  |
    +|💻 **bakery**       | Lenovo Ideapad 720S-13IKB                           | Personal laptop                                      |
    +|💻 **machpizza**    | MacBook Pro 2016                                    | MacOS reference and build sandbox                    |
    +|🏠 **treehouse**    | NVIDIA DGX Spark                                    | Workstation, AI playground and home-manager reference|
    +|🖥️ **winters**      | ASRock J4105-ITX, 32GB RAM                          | Secondary homeserver and data storgae                |
    +|🖥️ **summers**      | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM  | Main homeserver running microvms, data storage       |
    +|🖥️ **hintbooth**    | HUNSN RM02, 8GB RAM                                 | Router                                               |
    +|☁️ **milkywell**    | Oracle Cloud: VM.Standard.E2.1.Micro                | Server for lightweight synchronization tasks         |
    +|☁️ **moonside**     | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services  |
    +|☁️ **belchsfactory**| Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Hydra builder and nix binary cache                   |
    +|☁️ **monkeycave**   | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Gaming server                                        |
    +|☁️ **eagleland**    | Hetzner Cloud: CX23                                 | Mail server                                          |
     |📱 **magicant**     | Samsung Galaxy Z Flip 6                             | Phone                                                |
     |💿 **drugstore**    | -                                                   | ISO installer configuration                          |
     |❔ **chaotheatre**  | -                                                   | Demo config for checking out my configurtion         |
     |❔ **toto**         | -                                                   | Helper configuration for bootstrapping a new system  |
    -|🏠 **treehouse**    | -                                                   | Reference configuration for a home-manager only host |
     
    @@ -1219,12 +1258,20 @@ Here I give a brief overview over the hostmachines that I am using. This is held -
    -

    1.7. Manual steps when setting up a new machine

    +
    +

    1.7. Manual steps when setting up a new machine

    These steps are required when setting up a normal NixOS host:
     
    +- setup yubikey (automatic yubikey enrollment is not yet supported by `disko`):
    +  - `systemd-cryptenroll --fido2-device=auto /dev/<device, e.g. 'nvme0n1p2'>`
    +
    +If the new machine is a work machine, these steps are additionally needed:
    +
    +- setup the work VPN:
    +  - using the laptop certificate `.pem` as User cert and private key (CA cert: none)
    +  - vpn gateway is found in `nixosConfig.repo.secrets.local.work.vpnGateway`
     - setup gpgsm for signing of mails using S/MIME:
       - `gpgsm --import ~/Certificates/<certname>.p12`
       - `gpgsm --import ~/Certificates/harica-root.pem`
    @@ -1234,18 +1281,9 @@ Here I give a brief overview over the hostmachines that I am using. This is held
     - setup pizauth for microsoft mail sync (account names are possibly `uni` and `work`):
       - `pizauth auth <account name, e.g. 'work'>`
       - `pizauth dump > ~/.pizauth.state`
    -- setup yubikey (automatic yubikey enrollment is not yet supported by `disko`):
    -  - `systemd-cryptenroll --fido2-device=auto /dev/<device, e.g. 'nvme0n1p2'>`
    -
    -If the new machine is a work machine, these steps are additionally needed:
    -
    -- setup the work VPN:
    -  - using the laptop certificate `.pem` as User cert and private key (CA cert: none)
    -  - vpn gateway is found in `nixosConfig.repo.secrets.local.work.vpnGateway`
     
     If the new machine is home-manager only, perform these steps:
     
    -
     - (Optional) Install openssh-server
     - Set hostname to the name specified in the home-manager configuration
     - Install nix, either:
    @@ -1258,13 +1296,47 @@ If the new machine is home-manager only, perform these steps:
       1) Clone dotfile repo & change into it
       2) `nix --extra-experimental-features 'nix-command flakes' develop`
       3) `home-manager --extra-experimental-features 'nix-command flakes' switch --flake .#$(hostname) --show-trace`
    -
     
    + +These steps are required when setting up a normal NixOS host: + +- setup yubikey (automatic yubikey enrollment is not yet supported by `disko`): + - `systemd-cryptenroll --fido2-device=auto /dev/` + +If the new machine is a work machine, these steps are additionally needed: + +- setup the work VPN: + - using the laptop certificate `.pem` as User cert and private key (CA cert: none) + - vpn gateway is found in `nixosConfig.repo.secrets.local.work.vpnGateway` +- setup gpgsm for signing of mails using S/MIME: + - `gpgsm --import ~/Certificates/.p12` + - `gpgsm --import ~/Certificates/harica-root.pem` + - `gpgsm --import ~/Certificates/harica-intermediate.pem` + - `gpgsm --list-keys --with-validation "HARICA Client RSA Root CA 2021"` + - trust the certificate and set passphrase +- setup pizauth for microsoft mail sync (account names are possibly `uni` and `work`): + - `pizauth auth ` + - `pizauth dump > ~/.pizauth.state` + +If the new machine is home-manager only, perform these steps: + +- (Optional) Install openssh-server +- Set hostname to the name specified in the home-manager configuration +- Install nix, either: + - (if upgrading existing nix) Install nix version matching with version that `nix-plugins` is compiled against: `nix-env --install --file '' cacert -I nixpkgs=channel:nixpkgs-unstable --attr nixVersions.nix_x_yy` + - (or installing nix freshly): + - Grab the link to the install script of the needed nix version from https://releases.nixos.org/?prefix=nix, e.g. https://releases.nixos.org/nix/nix-2.30.1/install + - `bash <(curl -L https://releases.nixos.org/nix/nix-x-yy-y/install) --daemon` +- add the following to /etc/nix/nix.conf to become a trusted user: `trusted-users = @wheel root swarsel` +- For the first build: + 1) Clone dotfile repo & change into it + 2) `nix --extra-experimental-features 'nix-command flakes' develop` + 3) `home-manager --extra-experimental-features 'nix-command flakes' switch --flake .#$(hostname) --show-trace`
    -
    -

    1.8. Current issues

    +
    +

    1.8. Current issues

    Currently, these adaptions are made to the configuration to account for bugs in upstream repos:
    @@ -1289,6 +1361,27 @@ If the new machine is home-manager only, perform these steps:
           - pinned to version not in nixpkgs (fixes https://github.com/ErikReider/SwayOSD/issues/175)
     
    + +Currently, these adaptions are made to the configuration to account for bugs in upstream repos: + +- 202501102: + - flake: + - emacs-overlay: + - : version pinned because emacsclient is currently broken on latest + - niri-flake: + - currently not using the sugared version of screenshot-[,window], as it is currently broken + - home-manager: + - emacs-tramp: + - using stable version in extraPackages (broken in unstable) + - :ensure nil in emacs tramp settings to use package in extraPackages + - emacs-calfwL + - pinned to version not in nixpkgs (is in latest emacs-overlay, but that is broken) + - vesktop: + - running stable version (broken in unstable) + - batgrep: + - running stable version (broken in unstable) + - swayosd: + - pinned to version not in nixpkgs (fixes https://github.com/ErikReider/SwayOSD/issues/175)
    @@ -1436,8 +1529,8 @@ This provides devshell support for flake-parts
  • swarsel-modules.url = "github:Swarsel/swarsel-modules/main"; swarsel-nix.url = "github:Swarsel/swarsel-nix/main"; home-manager = { - url = "github:nix-community/home-manager"; - # url = "github:Swarsel/home-manager/main"; + # url = "github:nix-community/home-manager"; + url = "github:Swarsel/home-manager/main"; inputs.nixpkgs.follows = "nixpkgs"; }; swarsel.url = "github:Swarsel/.dotfiles"; @@ -1509,10 +1602,15 @@ This provides devshell support for flake-parts url = "github:sodiboo/niri-flake"; inputs.nixpkgs.follows = "nixpkgs"; }; + nixos-extra-modules = { + url = "github:oddlama/nixos-extra-modules"; + inputs.nixpkgs.follows = "nixpkgs"; + }; microvm = { url = "github:astro/microvm.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + treefmt-nix.url = "github:numtide/treefmt-nix"; }; outputs = @@ -1565,7 +1663,7 @@ a separate repo containing my secrets

    -As for the second approach, I actually used this up to some point (see for example 7e11641: feat: add initial oauth2-proxy and freshrss oidc as one of the lasts commits still using this system). However, it is quite bothersome to constantly have to keep two repositories up to date and in sync. Also, having a repo that every configuration relied upon that was also a private repo led to the problem that my demo configuration (ChaosTheatre (Demo Physical/VM)) would fail to build with that present, and I had to take several extra steps to make it buildable. Ever since deleting that dependency I also got rid of that problem. The whole system is inspired by this blog article and large parts of it are adapted from oddlama's nix-config. +As for the second approach, I actually used this up to some point (see for example 7e11641: feat: add initial oauth2-proxy and freshrss oidc as one of the lasts commits still using this system). However, it is quite bothersome to constantly have to keep two repositories up to date and in sync. Also, having a repo that every configuration relied upon that was also a private repo led to the problem that my demo configuration (Hotel (Demo Physical/VM)) would fail to build with that present, and I had to take several extra steps to make it buildable. Ever since deleting that dependency I also got rid of that problem. The whole system is inspired by this blog article and large parts of it are adapted from oddlama's nix-config.

    @@ -1717,6 +1815,22 @@ let inherit (inputs.nixpkgs) lib; in rec { + cidrToSubnetMask = cidr: + let + prefixLength = lib.toInt (lib.last (lib.splitString "/" cidr)); + bits = lib.genList (i: if i < prefixLength then 1 else 0) 32; + octets = lib.genList + (i: + let + octetBits = lib.sublist (i * 8) 8 bits; + octetValue = lib.foldl (acc: bit: acc * 2 + bit) 0 octetBits; + in + octetValue + ) 4; + subnetMask = lib.concatStringsSep "." (map toString octets); + in + subnetMask; + mkIfElseList = p: yes: no: lib.mkMerge [ (lib.mkIf p yes) (lib.mkIf (!p) no) @@ -1768,6 +1882,9 @@ in inherit (inputs.home-manager.lib) hm; inherit swarselsystems; }); + + swarselsystemsLib = swarselsystems; + homeLib = self.outputs.lib; }; } @@ -1790,14 +1907,39 @@ More information on the actual packages build can be found in -
    { self, ... }:
    +
    { self, inputs, ... }:
     {
    +  imports = [
    +    (
    +      { lib, flake-parts-lib, ... }:
    +      flake-parts-lib.mkTransposedPerSystemModule {
    +        name = "pkgs";
    +        file = ./packages.nix;
    +        option = lib.mkOption {
    +          type = lib.types.unspecified;
    +        };
    +      }
    +    )
    +  ];
       flake = _:
         let
           inherit (self.outputs) lib;
         in
         {
    -      packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import "${self}/pkgs" { inherit self lib pkgs; });
    +      packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import "${self}/pkgs/flake" { inherit self lib pkgs; });
    +    };
    +
    +  perSystem = { pkgs, system, ... }:
    +    {
    +      # see https://flake.parts/module-arguments.html?highlight=modulewith#persystem-module-parameters
    +      _module.args.pkgs = import inputs.nixpkgs {
    +        inherit system;
    +        config.allowUnfree = true;
    +        overlays = [
    +          self.overlays.default
    +        ];
    +      };
    +      inherit pkgs;
         };
     }
     
    @@ -1827,7 +1969,7 @@ Lastly, in order make this actually available to my configurations, i use the
    # adapted from https://github.com/oddlama/nix-config/blob/main/nix/globals.nix
    -{ inputs, ... }:
    +{ self, inputs, ... }:
     {
       flake = { config, lib, ... }:
         {
    @@ -1836,7 +1978,8 @@ Lastly, in order make this actually available to my configurations, i use the 
    @@ -2115,11 +2299,11 @@ Another note concerning flake-parts:
                   (mkConnection "milkywell" "wan")
                   (mkConnection "magicant" "wifi")
                   (mkConnection "toto" "bootstrapper")
    -              (mkConnection "chaostheatre" "demo host")
    +              (mkConnection "hotel" "demo host")
                 ];
               };
     
    -          chaostheatre.interfaces."demo host" = { };
    +          hotel.interfaces."demo host" = { };
               toto.interfaces."bootstrapper" = { };
               milkywell.interfaces.wan = { };
               moonside.interfaces.wan = { };
    @@ -2297,7 +2481,7 @@ Lastly, in the perSystem attribute set, we see that it is actually
         inputs.pre-commit-hooks.flakeModule
       ];
     
    -  perSystem = { pkgs, system, ... }:
    +  perSystem = { pkgs, config, system, ... }:
         {
           pre-commit = {
             check.enable = true;
    @@ -2319,6 +2503,7 @@ Lastly, in the perSystem attribute set, we see that it is actually
                 nixpkgs-fmt.enable = true;
                 statix.enable = true;
                 trim-trailing-whitespace.enable = true;
    +            treefmt.enable = true;
     
                 destroyed-symlinks = {
                   enable = true;
    @@ -2338,110 +2523,142 @@ Lastly, in the perSystem attribute set, we see that it is actually
             };
           };
     
    -      devshells.default = let
    -        nix-version = "2_30";
    -      in {
    -        packages = [
    -          (builtins.trace "alarm: pinned nix_${nix-version}" pkgs.nixVersions."nix_${nix-version}")
    -          pkgs.git
    -          pkgs.just
    -          pkgs.age
    -          pkgs.ssh-to-age
    -          pkgs.sops
    -          pkgs.nixpkgs-fmt
    -          self.packages.${system}.swarsel-build
    -          self.packages.${system}.swarsel-deploy
    -          (pkgs.symlinkJoin {
    -            name = "home-manager";
    -            buildInputs = [ pkgs.makeWrapper ];
    -            paths = [ pkgs.home-manager ];
    -            postBuild = ''
    -              wrapProgram $out/bin/home-manager \
    -              --append-flags '--flake .#$(hostname)'
    -              '';
    -          })
    -        ];
    +      devshells = {
    +        deploy =
    +          let
    +            nix-version = "2_28";
    +          in {
    +          packages = [
    +            (builtins.trace "alarm: pinned nix_${nix-version}" pkgs.stable25_05.nixVersions."nix_${nix-version}")
    +            pkgs.git
    +            pkgs.just
    +            pkgs.age
    +            pkgs.ssh-to-age
    +            pkgs.sops
    +          ];
     
    -        commands = [
    +          env =
    +            [
    +              {
    +                name = "NIX_CONFIG";
    +                value = ''
    +                  plugin-files = ${pkgs.stable25_05.nix-plugins.overrideAttrs (o: {
    +                    buildInputs = [pkgs.stable25_05.nixVersions."nix_${nix-version}" pkgs.stable25_05.boost];
    +                    patches = (o.patches or []) ++ [./nix-plugins.patch];
    +                  })}/lib/nix/plugins
    +                  extra-builtins-file = ${self + /nix/extra-builtins.nix}
    +                '';
    +              }
    +            ];
    +        };
    +        default =
    +          let
    +            nix-version = "2_30";
    +          in
               {
    -            package = pkgs.statix;
    -            help = "Lint flake";
    -          }
    -          {
    -            package = pkgs.deadnix;
    -            help = "Check flake for dead code";
    -          }
    -          {
    -            package = pkgs.nix-tree;
    -            help = "Interactively browse dependency graphs of Nix derivations";
    -          }
    -          {
    -            package = pkgs.nvd;
    -            help = "Diff two nix toplevels and show which packages were upgraded";
    -          }
    -          {
    -            package = pkgs.nix-diff;
    -            help = "Explain why two Nix derivations differ";
    -          }
    -          {
    -            package = pkgs.nix-output-monitor;
    -            help = "Nix Output Monitor (a drop-in alternative for `nix` which shows a build graph)";
    -            name = "nom \"$@\"";
    -          }
    -          {
    -            name = "hm";
    -            help = "Manage home-manager config";
    -            command = "home-manager \"$@\"";
    -          }
    -          {
    -            name = "fmt";
    -            help = "Format flake";
    -            command = "nixpkgs-fmt --check \"$FLAKE\"";
    -          }
    -          {
    -            name = "sd";
    -            help = "Build and deploy this nix config to nodes";
    -            command = "swarsel-deploy \"$@\"";
    -          }
    -          {
    -            name = "sl";
    -            help = "Build and deploy a config to nodes";
    -            command = "swarsel-deploy \${1} switch";
    -          }
    -          {
    -            name = "sw";
    -            help = "Build and switch to the host's config locally";
    -            command = "swarsel-deploy $(hostname) switch";
    -          }
    -          {
    -            name = "bld";
    -            help = "Build a number of configurations";
    -            command = "swarsel-build \"$@\"";
    -          }
    -          {
    -            name = "c";
    -            help = "Work with the flake git repository";
    -            command = "git --git-dir=$FLAKE/.git --work-tree=$FLAKE/ \"$@\"";
    -          }
    -        ];
    +            packages = [
    +              (builtins.trace "alarm: pinned nix_${nix-version}" pkgs.nixVersions."nix_${nix-version}")
    +              pkgs.git
    +              pkgs.just
    +              pkgs.age
    +              pkgs.ssh-to-age
    +              pkgs.sops
    +              pkgs.nixpkgs-fmt
    +              self.packages.${system}.swarsel-build
    +              self.packages.${system}.swarsel-deploy
    +              (pkgs.symlinkJoin {
    +                name = "home-manager";
    +                buildInputs = [ pkgs.makeWrapper ];
    +                paths = [ pkgs.home-manager ];
    +                postBuild = ''
    +                  wrapProgram $out/bin/home-manager \
    +                  --append-flags '--flake .#$(hostname)'
    +                '';
    +              })
    +            ];
     
    -        devshell.startup.pre-commit-install.text = "pre-commit install";
    +            commands = [
    +              {
    +                package = pkgs.statix;
    +                help = "Lint flake";
    +              }
    +              {
    +                package = pkgs.deadnix;
    +                help = "Check flake for dead code";
    +              }
    +              {
    +                package = pkgs.nix-tree;
    +                help = "Interactively browse dependency graphs of Nix derivations";
    +              }
    +              {
    +                package = pkgs.nvd;
    +                help = "Diff two nix toplevels and show which packages were upgraded";
    +              }
    +              {
    +                package = pkgs.nix-diff;
    +                help = "Explain why two Nix derivations differ";
    +              }
    +              {
    +                package = pkgs.nix-output-monitor;
    +                help = "Nix Output Monitor (a drop-in alternative for `nix` which shows a build graph)";
    +                name = "nom \"$@\"";
    +              }
    +              {
    +                name = "hm";
    +                help = "Manage home-manager config";
    +                command = "home-manager \"$@\"";
    +              }
    +              {
    +                name = "fmt";
    +                help = "Format flake";
    +                command = "nixpkgs-fmt --check \"$FLAKE\"";
    +              }
    +              {
    +                name = "sd";
    +                help = "Build and deploy this nix config to nodes";
    +                command = "swarsel-deploy \"$@\"";
    +              }
    +              {
    +                name = "sl";
    +                help = "Build and deploy a config to nodes";
    +                command = "swarsel-deploy \${1} switch";
    +              }
    +              {
    +                name = "sw";
    +                help = "Build and switch to the host's config locally";
    +                command = "swarsel-deploy $(hostname) switch";
    +              }
    +              {
    +                name = "bld";
    +                help = "Build a number of configurations";
    +                command = "swarsel-build \"$@\"";
    +              }
    +              {
    +                name = "c";
    +                help = "Work with the flake git repository";
    +                command = "git --git-dir=$FLAKE/.git --work-tree=$FLAKE/ \"$@\"";
    +              }
    +            ];
     
    -        env = let
    -          nix-plugins = pkgs.nix-plugins.override {
    -            nixComponents = pkgs.nixVersions."nixComponents_${nix-version}";
    +            # devshell.startup.pre-commit-install.text = "pre-commit install";
    +            devshell.startup.pre-commit.text = config.pre-commit.installationScript;
    +
    +            env =
    +              let
    +                nix-plugins = pkgs.nix-plugins.override {
    +                  nixComponents = pkgs.nixVersions."nixComponents_${nix-version}";
    +                };
    +              in
    +              [
    +                {
    +                  name = "NIX_CONFIG";
    +                  value = ''
    +                    plugin-files = ${nix-plugins}/lib/nix/plugins
    +                    extra-builtins-file = ${self + /nix/extra-builtins.nix}
    +                  '';
    +                }
    +              ];
               };
    -        in [
    -          {
    -            # Additionally configure nix-plugins with our extra builtins file.
    -            # We need this for our repo secrets.
    -            name = "NIX_CONFIG";
    -            value = ''
    -              plugin-files = ${nix-plugins}/lib/nix/plugins
    -              extra-builtins-file = ${self + /nix/extra-builtins.nix}
    -            '';
    -          }
    -        ];
           };
         };
     }
    @@ -2504,10 +2721,32 @@ Defines a formatter that can be called using nix flake format. Whil
     

    -
    _:
    +
    { inputs, ... }:
     {
    +  imports = [
    +    inputs.treefmt-nix.flakeModule
    +  ];
    +
       perSystem = { pkgs, ... }: {
    -    formatter = pkgs.nixpkgs-fmt;
    +    # formatter = pkgs.nixpkgs-fmt;
    +    # formatter is set by treefmt to:
    +    # formatter = lib.mkIf config.treefmt.flakeFormatter (lib.mkDefault config.treefmt.build.wrapper);
    +    treefmt = {
    +      projectRootFile = "flake.nix";
    +      programs = {
    +        nixfmt = {
    +          enable = true;
    +          package = pkgs.nixpkgs-fmt;
    +        };
    +        deadnix.enable = true;
    +        statix.enable = true;
    +        shellcheck.enable = true;
    +      };
    +      settings.formatter.shellcheck.options = [
    +        "--shell"
    +        "bash"
    +      ];
    +    };
       };
     }
     
    @@ -2649,7 +2888,7 @@ in
           overlays = {
             default = final: prev:
               let
    -            additions = final: _: import "${self}/pkgs" { pkgs = final; inherit self lib; }
    +            additions = final: _: import "${self}/pkgs/flake" { pkgs = final; inherit self lib; }
                   // {
                   swarsel-nix = import inputs.swarsel-nix {
                     pkgs = prev;
    @@ -2662,6 +2901,11 @@ in
                   #   withSystemVencord = true;
                   # };
     
    +              lib = prev.lib // {
    +                swarselsystems = self.outputs.swarselsystemsLib;
    +                hm = self.outputs.homeLib;
    +              };
    +
                   firefox = prev.firefox.override {
                     nativeMessagingHosts = [
                       prev.tridactyl-native
    @@ -2712,15 +2956,19 @@ in
                     (builtins.attrNames nixpkgsInputs));
     
               in
    -          (additions final prev)
    -          // (modifications final prev)
    -          // (nixpkgs-stable-versions final prev)
    -          // (inputs.niri-flake.overlays.niri final prev)
    -          // (inputs.vbc-nix.overlays.default final prev)
    -          // (inputs.nur.overlays.default final prev)
    -          // (inputs.emacs-overlay.overlay final prev)
    -          // (inputs.nix-topology.overlays.default final prev)
    -          // (inputs.nixgl.overlay final prev);
    +          lib.recursiveUpdate
    +            (
    +              (additions final prev)
    +              // (nixpkgs-stable-versions final prev)
    +              // (inputs.niri-flake.overlays.niri final prev)
    +              // (inputs.vbc-nix.overlays.default final prev)
    +              // (inputs.nur.overlays.default final prev)
    +              // (inputs.emacs-overlay.overlay final prev)
    +              // (inputs.nix-topology.overlays.default final prev)
    +              // (inputs.nixgl.overlay final prev)
    +              // (inputs.nixos-extra-modules.overlays.default final prev)
    +            )
    +            (modifications final prev);
           };
         };
     }
    @@ -3545,7 +3793,7 @@ in
     
    -
    3.1.2.3. Winters (Server)
    +
    3.1.2.3. Winters (Server: ASRock J4105-ITX)

    This is my main server that I run at home. It handles most tasks that require bigger amounts of storage than I can receive for free at OCI. Also it houses some data that I find too sensitive to hand over to Oracle. @@ -3555,7 +3803,7 @@ This is my main server that I run at home. It handles most tasks that require bi

    3.1.2.3.1. Main Configuration
    -
    { lib, config, minimal, ... }:
    +
    { lib, minimal, ... }:
     {
     
       imports = [
    @@ -3567,25 +3815,29 @@ This is my main server that I run at home. It handles most tasks that require bi
         loader.efi.canTouchEfiVariables = true;
       };
     
    -  globals.hosts.${config.node.name}.ipv4 = config.repo.secrets.local.ipv4;
    -
    -  networking = {
    -    inherit (config.repo.secrets.local) hostId;
    -    hostName = "winters";
    -    firewall.enable = true;
    -    enableIPv6 = false;
    -    firewall.allowedTCPPorts = [ 80 443 ];
    -  };
    +  # globals.hosts.${config.node.name}.ipv4 = config.repo.secrets.local.ipv4;
    +  # globals.networks.home.hosts.${config.node.name} = {
    +  #   ipv4 = config.repo.secrets.local.home-ipv4;
    +  #   mac = config.repo.secrets.local.home-mac;
    +  # };
     
       swarselsystems = {
         info = "ASRock J4105-ITX, 32GB RAM";
         flakePath = "/root/.dotfiles";
         isImpermanence = false;
    -    isSecureBoot = true;
    -    isCrypted = true;
    +    isSecureBoot = false;
    +    isCrypted = false;
         isBtrfs = false;
         isLinux = true;
         isNixos = true;
    +    server.garage = {
    +      data_dir = [
    +        {
    +          capacity = "200G";
    +          path = "/Vault/data/garage/main";
    +        }
    +      ];
    +    };
       };
     
     } // lib.optionalAttrs (!minimal) {
    @@ -3595,6 +3847,7 @@ This is my main server that I run at home. It handles most tasks that require bi
       };
     
       swarselmodules.server = {
    +    diskEncryption = lib.mkForce false;
         nfs = lib.mkDefault true;
         nginx = lib.mkDefault true;
         kavita = lib.mkDefault true;
    @@ -3623,6 +3876,8 @@ This is my main server that I run at home. It handles most tasks that require bi
         ankisync = lib.mkDefault true;
         # snipeit = lib.mkDefault false;
         homebox = lib.mkDefault true;
    +    opkssh = lib.mkDefault true;
    +    garage = lib.mkDefault false;
       };
     
     }
    @@ -3685,180 +3940,17 @@ This is my main server that I run at home. It handles most tasks that require bi
     
    -
    -
    3.1.2.4. machpizza (MacBook Pro)
    -
    -

    -A Mac notebook that I have received from work. I use this machine for getting accustomed to the Apple ecosystem as well as as a sandbox for nix-darwin configurations (the darwin configuration is severely under-developed). -

    - +
    +
    3.1.2.4. Summers (Server: ASUS Z10PA-D8)
    +
    +
    +
    +
    3.1.2.4.1. Main Configuration
    +
    -
    { lib, config, ... }:
    -let
    -  inherit (config.repo.secrets.local) workUser;
    -in
    +
    { inputs, lib, config, minimal, nodes, globals, ... }:
     {
     
    -  # Auto upgrade nix package and the daemon service.
    -  services.nix-daemon.enable = true;
    -  services.karabiner-elements.enable = true;
    -
    -  home-manager.users.workUser.home = {
    -    username = lib.mkForce workUser;
    -    swarselsystems = {
    -      isDarwin = true;
    -      isLaptop = true;
    -      isNixos = false;
    -      isBtrfs = false;
    -      mainUser = workUser;
    -      homeDir = "/home/${workUser}";
    -      flakePath = "/home/${workUser}/.dotfiles";
    -    };
    -  };
    -}
    -
    -
    -
    -
    -
    -
    3.1.2.5. Magicant (Phone)
    -
    -

    -My phone. I use only a minimal config for remote debugging here. -

    - -
    -
    -{ pkgs, ... }: {
    -  environment = {
    -    packages = with pkgs; [
    -      vim
    -      git
    -      openssh
    -      # toybox
    -      dig
    -      man
    -      gnupg
    -      curl
    -      deadnix
    -      statix
    -      nixpgks-fmt
    -      nvd
    -    ];
    -
    -    etcBackupExtension = ".bak";
    -    extraOutputsToInstall = [
    -      "doc"
    -      "info"
    -      "devdoc"
    -    ];
    -    motd = null;
    -  };
    -
    -  android-integration = {
    -    termux-open.enable = true;
    -    xdg-open.enable = true;
    -    termux-open-url.enable = true;
    -    termux-reload-settings.enable = true;
    -    termux-setup-storage.enable = true;
    -  };
    -
    -  # Backup etc files instead of failing to activate generation if a file already exists in /etc
    -
    -  # Read the changelog before changing this value
    -  system.stateVersion = "23.05";
    -
    -  # Set up nix for flakes
    -  nix.extraOptions = ''
    -    experimental-features = nix-command flakes
    -  '';
    -}
    -
    -
    -
    -
    -
    -
    -
    -
    3.1.2.6. Treehouse (DGX Spark)
    -
    -
    -
    { self, outputs, ... }:
    -{
    -
    -  imports = [
    -    # inputs.sops-nix.homeManagerModules.sops
    -    "${self}/modules/home"
    -    "${self}/modules/nixos/common/pii.nix"
    -    "${self}/modules/nixos/common/meta.nix"
    -  ];
    -
    -  nixpkgs = {
    -    overlays = [ outputs.overlays.default ];
    -    config = {
    -      allowUnfree = true;
    -    };
    -  };
    -
    -  services.xcape = {
    -    enable = true;
    -    mapExpression = {
    -      Control_L = "Escape";
    -    };
    -  };
    -
    -  # programs.zsh.initContent = "
    -  #   export GPG_TTY=\"$(tty)\"
    -  # export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
    -  # gpgconf --launch gpg-agent
    -  #       ";
    -
    -  swarselsystems = {
    -    isLaptop = false;
    -    isNixos = false;
    -    wallpaper = self + /files/wallpaper/surfacewp.png;
    -  };
    -
    -  swarselprofiles = {
    -    dgxspark = true;
    -  };
    -
    -}
    -
    -
    -
    -
    -
    -
    -
    -
    -

    3.1.3. Virtual hosts

    -
    -

    -My server setup was originally built on Proxmox VE; back when I started, I created all kinds of wild Debian/Ubuntu/etc. KVMs and LXCs on there. However, the root disk has suffered a weird failure where it has become unable to be cloned, but was still functional. I was for a long time rewriting all machines on there to use NixOS instead; this process is now finished. -

    - -

    -I have removed most of the machines from this section. What remains are some hosts that I have deployed on OCI: -

    -
      -
    • MilkyWell: cloud server used for very lightweight sync tasks of non-critical data
    • -
    • Moonside: Proxy server + some lightweight services
    • -
    -
    -
    -
    3.1.3.1. MilkyWell (OCI)
    -
    -

    -For this I use a free Ampere instance from OCI with 50G of space. In case my account gets terminated, all of this data is easily replaceable or backed up regularly anyways. -

    -
    -
    -
    3.1.3.1.1. Main configuration
    -
    -
    -
    { lib, minimal, ... }:
    -{
       imports = [
         ./hardware-configuration.nix
         ./disk-config.nix
    @@ -3866,66 +3958,121 @@ For this I use a free Ampere instance from OCI with 50G of space. In case my acc
     
       boot = {
         loader.systemd-boot.enable = true;
    -    tmp.cleanOnBoot = true;
    -  };
    -
    -  networking = {
    -    nftables.enable = lib.mkForce false;
    -    hostName = "milkywell";
    -    enableIPv6 = true;
    -    domain = "subnet03112148.vcn03112148.oraclevcn.com";
    -  };
    -
    -  topology.self = {
    -    icon = "devices.cloud-server";
    -  };
    -
    -  hardware = {
    -    enableAllFirmware = lib.mkForce false;
    +    loader.efi.canTouchEfiVariables = true;
       };
     
       swarselsystems = {
    -    info = "VM.Standard.E2.1.Micro";
    +    info = "ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM";
    +    flakePath = "/root/.dotfiles";
         isImpermanence = true;
    -    isSecureBoot = false;
    +    isSecureBoot = true;
         isCrypted = true;
    -    isSwap = true;
    -    rootDisk = "/dev/sda";
    -    swapSize = "4G";
         isBtrfs = true;
         isLinux = true;
         isNixos = true;
    +    withMicroVMs = false;
       };
     
     } // lib.optionalAttrs (!minimal) {
    +
       swarselprofiles = {
         server = true;
       };
     
    -  swarselmodules.server = {
    -    forgejo = lib.mkDefault false;
    -    ankisync = lib.mkDefault false;
    +  swarselmodules = {
    +    optional = {
    +      microvmHost = true;
    +    };
    +    server = {
    +      diskEncryption = lib.mkForce false; # TODO: disable
    +      nfs = false;
    +      nginx = false;
    +      kavita = false;
    +      restic = false;
    +      jellyfin = false;
    +      navidrome = false;
    +      spotifyd = false;
    +      mpd = false;
    +      postgresql = false;
    +      matrix = false;
    +      nextcloud = false;
    +      immich = false;
    +      paperless = false;
    +      transmission = false;
    +      syncthing = false;
    +      grafana = false;
    +      emacs = false;
    +      freshrss = false;
    +      jenkins = false;
    +      kanidm = false;
    +      firefly-iii = false;
    +      koillection = false;
    +      radicale = false;
    +      atuin = false;
    +      forgejo = false;
    +      ankisync = false;
    +      homebox = false;
    +      opkssh = false;
    +      garage = false;
    +    };
       };
    +
    +  microvm.vms =
    +    let
    +      mkMicrovm = guestName: {
    +        ${guestName} = {
    +          backend = "microvm";
    +          autostart = true;
    +          modules = [
    +            ./guests/${guestName}.nix
    +            {
    +              node.secretsDir = ./secrets/${guestName};
    +            }
    +          ];
    +          microvm = {
    +            system = "x86_64-linux";
    +            # baseMac = config.repo.secrets.local.networking.interfaces.lan.mac;
    +            # interfaces.vlan-services = { };
    +          };
    +          specialArgs = {
    +            inherit (config) nodes globals;
    +            inherit lib;
    +            inherit inputs minimal;
    +          };
    +        };
    +      };
    +    in
    +    lib.mkIf (!minimal && config.swarselsystems.withMicroVMs) (
    +      { }
    +      // mkMicrovm "guest1"
    +    );
    +
     }
     
     
    -
    -
    3.1.3.1.2. hardware-configuration
    -
    +
    +
    3.1.2.4.2. hardware-configuration
    +
    -
    { config, lib, modulesPath, ... }: {
    -  imports = [
    -    (modulesPath + "/profiles/qemu-guest.nix")
    -  ];
    +
    { config, lib, modulesPath, ... }:
    +
    +{
    +  imports =
    +    [
    +      (modulesPath + "/installer/scan/not-detected.nix")
    +    ];
     
       boot = {
    -    initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ];
    +    initrd.availableKernelModules = [ "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
         initrd.kernelModules = [ ];
    -    kernelModules = [ "kvm-amd" ];
    +    kernelModules = [ "kvm-intel" ];
         extraModulePackages = [ ];
    +
    +    supportedFilesystems = [ "zfs" ];
    +    zfs.extraPools = [ "Vault" ];
       };
     
       # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
    @@ -3933,24 +4080,20 @@ For this I use a free Ampere instance from OCI with 50G of space. In case my acc
       # still possible to use this option, but it's recommended to use it in conjunction
       # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
       networking.useDHCP = lib.mkDefault true;
    -  # networking.interfaces.ens3.useDHCP = lib.mkDefault true;
    +  # networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
     
       nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
    -  hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
    +  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
     }
     
    -
    -
    3.1.3.1.3. disko
    -
    +
    +
    3.1.2.4.3. disko
    +
    -
    # NOTE: ... is needed because dikso passes diskoFile
    -{ lib
    -, config
    -, ...
    -}:
    +
    { lib, config, ... }:
     let
       type = "btrfs";
       extraArgs = [ "-L" "nixos" "-f" ]; # force overwrite
    @@ -4022,7 +4165,7 @@ in
                     mountOptions = [ "defaults" ];
                   };
                 };
    -            root = {
    +            root = lib.mkIf (!config.swarselsystems.isCrypted) {
                   size = "100%";
                   content = {
                     inherit type subvolumes extraArgs;
    @@ -4034,6 +4177,31 @@ in
                     '';
                   };
                 };
    +            luks = lib.mkIf config.swarselsystems.isCrypted {
    +              size = "100%";
    +              content = {
    +                type = "luks";
    +                name = "cryptroot";
    +                passwordFile = "/tmp/disko-password"; # this is populated by bootstrap.sh
    +                settings = {
    +                  allowDiscards = true;
    +                  # https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
    +                  crypttabExtraOpts = [
    +                    "fido2-device=auto"
    +                    "token-timeout=10"
    +                  ];
    +                };
    +                content = {
    +                  inherit type subvolumes extraArgs;
    +                  postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
    +                    MNTPOINT=$(mktemp -d)
    +                    mount "/dev/mapper/cryptroot" "$MNTPOINT" -o subvolid=5
    +                    trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
    +                    btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
    +                  '';
    +                };
    +              };
    +            };
               };
             };
           };
    @@ -4043,6 +4211,391 @@ in
       fileSystems."/persist".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
       fileSystems."/home".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
     }
    +
    +
    +
    +
    +
    +
    3.1.2.4.4. Guests
    +
    +
    +
    +3.1.2.4.4.1. Guest 1 +
    +
    +
    { lib, minimal, ... }:
    +{
    +
    +  swarselsystems = {
    +    info = "ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM";
    +  };
    +
    +} // lib.optionalAttrs (!minimal) {
    +
    +  swarselprofiles = {
    +    server = false;
    +  };
    +
    +  swarselmodules = {
    +    optional = {
    +      microvmGuest = false;
    +    };
    +  };
    +
    +  microvm = {
    +    mem = 1024 * 4;
    +    vcpu = 2;
    +  };
    +
    +}
    +
    +
    +
    +
    +
    +
    +
    +
    +
    3.1.2.5. Hintbooth (Router: HUNSN RM02)
    +
    +
    +
    +
    3.1.2.5.1. Main Configuration
    +
    +
    +
    { lib, minimal,  ... }:
    +{
    +
    +  imports = [
    +    ./hardware-configuration.nix
    +    ./disk-config.nix
    +  ];
    +
    +  swarselsystems = {
    +    info = "HUNSN RM02, 8GB RAM";
    +    flakePath = "/root/.dotfiles";
    +    isImpermanence = true;
    +    isSecureBoot = true;
    +    isCrypted = true;
    +    isBtrfs = true;
    +    isLinux = true;
    +    isNixos = true;
    +    rootDisk = "/dev/sda";
    +    swapSize = "8G";
    +    networkKernelModules = [ "igb" ];
    +  };
    +
    +} // lib.optionalAttrs (!minimal) {
    +
    +  swarselprofiles = {
    +    server = true;
    +    router = false;
    +  };
    +
    +  swarselmodules = {
    +    server = {
    +      nginx = lib.mkForce false; # we get this from the server profile
    +    };
    +  };
    +
    +}
    +
    +
    +
    +
    +
    +
    +
    3.1.2.5.2. hardware-configuration
    +
    +
    +
    { config, lib, modulesPath, ... }:
    +
    +{
    +  imports =
    +    [
    +      (modulesPath + "/installer/scan/not-detected.nix")
    +    ];
    +
    +  boot = {
    +    initrd.availableKernelModules = [ "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
    +    initrd.kernelModules = [ ];
    +    extraModulePackages = [ ];
    +  };
    +
    +  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
    +  # (the default) this is the recommended approach. When using systemd-networkd it's
    +  # still possible to use this option, but it's recommended to use it in conjunction
    +  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
    +  networking.useDHCP = lib.mkDefault true;
    +  # networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
    +
    +  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
    +  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
    +}
    +
    +
    +
    +
    +
    +
    3.1.2.5.3. disko
    +
    +
    +
    { lib, config, ... }:
    +let
    +  type = "btrfs";
    +  extraArgs = [ "-L" "nixos" "-f" ]; # force overwrite
    +  subvolumes = {
    +    "/root" = {
    +      mountpoint = "/";
    +      mountOptions = [
    +        "subvol=root"
    +        "compress=zstd"
    +        "noatime"
    +      ];
    +    };
    +    "/home" = lib.mkIf config.swarselsystems.isImpermanence {
    +      mountpoint = "/home";
    +      mountOptions = [
    +        "subvol=home"
    +        "compress=zstd"
    +        "noatime"
    +      ];
    +    };
    +    "/persist" = lib.mkIf config.swarselsystems.isImpermanence {
    +      mountpoint = "/persist";
    +      mountOptions = [
    +        "subvol=persist"
    +        "compress=zstd"
    +        "noatime"
    +      ];
    +    };
    +    "/log" = lib.mkIf config.swarselsystems.isImpermanence {
    +      mountpoint = "/var/log";
    +      mountOptions = [
    +        "subvol=log"
    +        "compress=zstd"
    +        "noatime"
    +      ];
    +    };
    +    "/nix" = {
    +      mountpoint = "/nix";
    +      mountOptions = [
    +        "subvol=nix"
    +        "compress=zstd"
    +        "noatime"
    +      ];
    +    };
    +    "/swap" = lib.mkIf config.swarselsystems.isSwap {
    +      mountpoint = "/.swapvol";
    +      swap.swapfile.size = config.swarselsystems.swapSize;
    +    };
    +  };
    +in
    +{
    +  disko.devices = {
    +    disk = {
    +      disk0 = {
    +        type = "disk";
    +        device = config.swarselsystems.rootDisk;
    +        content = {
    +          type = "gpt";
    +          partitions = {
    +            ESP = {
    +              priority = 1;
    +              name = "ESP";
    +              size = "512M";
    +              type = "EF00";
    +              content = {
    +                type = "filesystem";
    +                format = "vfat";
    +                mountpoint = "/boot";
    +                mountOptions = [ "defaults" ];
    +              };
    +            };
    +            root = lib.mkIf (!config.swarselsystems.isCrypted) {
    +              size = "100%";
    +              content = {
    +                inherit type subvolumes extraArgs;
    +                postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
    +                  MNTPOINT=$(mktemp -d)
    +                  mount "/dev/disk/by-label/nixos" "$MNTPOINT" -o subvolid=5
    +                  trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
    +                  btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
    +                '';
    +              };
    +            };
    +            luks = lib.mkIf config.swarselsystems.isCrypted {
    +              size = "100%";
    +              content = {
    +                type = "luks";
    +                name = "cryptroot";
    +                passwordFile = "/tmp/disko-password"; # this is populated by bootstrap.sh
    +                settings = {
    +                  allowDiscards = true;
    +                  # https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
    +                  crypttabExtraOpts = [
    +                    "fido2-device=auto"
    +                    "token-timeout=10"
    +                  ];
    +                };
    +                content = {
    +                  inherit type subvolumes extraArgs;
    +                  postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
    +                    MNTPOINT=$(mktemp -d)
    +                    mount "/dev/mapper/cryptroot" "$MNTPOINT" -o subvolid=5
    +                    trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
    +                    btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
    +                  '';
    +                };
    +              };
    +            };
    +          };
    +        };
    +      };
    +    };
    +  };
    +
    +  fileSystems."/persist".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
    +  fileSystems."/home".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
    +}
    +
    +
    +
    +
    +
    +
    +
    3.1.2.6. machpizza (MacBook Pro)
    +
    +

    +A Mac notebook that I have received from work. I use this machine for getting accustomed to the Apple ecosystem as well as as a sandbox for nix-darwin configurations (the darwin configuration is severely under-developed). +

    + +
    +
    { lib, config, ... }:
    +let
    +  inherit (config.repo.secrets.local) workUser;
    +in
    +{
    +
    +  # Auto upgrade nix package and the daemon service.
    +  services.nix-daemon.enable = true;
    +  services.karabiner-elements.enable = true;
    +
    +  home-manager.users.workUser.home = {
    +    username = lib.mkForce workUser;
    +    swarselsystems = {
    +      isDarwin = true;
    +      isLaptop = true;
    +      isNixos = false;
    +      isBtrfs = false;
    +      mainUser = workUser;
    +      homeDir = "/home/${workUser}";
    +      flakePath = "/home/${workUser}/.dotfiles";
    +    };
    +  };
    +}
    +
    +
    +
    +
    +
    +
    3.1.2.7. Magicant (Phone)
    +
    +

    +My phone. I use only a minimal config for remote debugging here. +

    + +
    +
    +{ pkgs, ... }: {
    +  environment = {
    +    packages = with pkgs; [
    +      vim
    +      git
    +      openssh
    +      # toybox
    +      dig
    +      man
    +      gnupg
    +      curl
    +      deadnix
    +      statix
    +      nixpgks-fmt
    +      nvd
    +    ];
    +
    +    etcBackupExtension = ".bak";
    +    extraOutputsToInstall = [
    +      "doc"
    +      "info"
    +      "devdoc"
    +    ];
    +    motd = null;
    +  };
    +
    +  android-integration = {
    +    termux-open.enable = true;
    +    xdg-open.enable = true;
    +    termux-open-url.enable = true;
    +    termux-reload-settings.enable = true;
    +    termux-setup-storage.enable = true;
    +  };
    +
    +  # Backup etc files instead of failing to activate generation if a file already exists in /etc
    +
    +  # Read the changelog before changing this value
    +  system.stateVersion = "23.05";
    +
    +  # Set up nix for flakes
    +  nix.extraOptions = ''
    +    experimental-features = nix-command flakes
    +  '';
    +}
    +
    +
    +
    +
    +
    +
    +
    +
    3.1.2.8. Treehouse (DGX Spark)
    +
    +
    +
    { self, ... }:
    +{
    +
    +  imports = [
    +    # inputs.sops-nix.homeManagerModules.sops
    +    "${self}/modules/home"
    +    "${self}/modules/nixos/common/pii.nix"
    +    "${self}/modules/nixos/common/meta.nix"
    +  ];
    +
    +
    +  services.xcape = {
    +    enable = true;
    +    mapExpression = {
    +      Control_L = "Escape";
    +    };
    +  };
    +
    +  # programs.zsh.initContent = "
    +  #   export GPG_TTY=\"$(tty)\"
    +  # export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
    +  # gpgconf --launch gpg-agent
    +  #       ";
    +
    +  swarselsystems = {
    +    isLaptop = false;
    +    isNixos = false;
    +    wallpaper = self + /files/wallpaper/surfacewp.png;
    +  };
    +
    +  swarselprofiles = {
    +    dgxspark = true;
    +  };
    +
    +}
     
     
     
    @@ -4050,15 +4603,30 @@ in
    +
    +

    3.1.3. Virtual hosts

    +
    +

    +My server setup was originally built on Proxmox VE; back when I started, I created all kinds of wild Debian/Ubuntu/etc. KVMs and LXCs on there. However, the root disk has suffered a weird failure where it has become unable to be cloned, but was still functional. I was for a long time rewriting all machines on there to use NixOS instead; this process is now finished. +

    + +

    +I have removed most of the machines from this section. What remains are some hosts that I have deployed on OCI: +

    +
      +
    • MilkyWell: cloud server used for very lightweight sync tasks of non-critical data
    • +
    • Moonside: Proxy server + some lightweight services
    • +
    +
    -
    3.1.3.2. Moonside (OCI)
    +
    3.1.3.1. Moonside (OCI)

    This machine mainly acts as my proxy server to stand before my local machines.

    -
    3.1.3.2.1. Main Configuration
    +
    3.1.3.1.1. Main Configuration
    { lib, config, minimal, ... }:
    @@ -4101,12 +4669,9 @@ in
       };
     
       networking = {
    -    nftables.enable = lib.mkForce false;
    -    hostName = "moonside";
    -    enableIPv6 = false;
         domain = "subnet03291956.vcn03291956.oraclevcn.com";
         firewall = {
    -      allowedTCPPorts = [ 80 443 8384 ];
    +      allowedTCPPorts = [ 8384 ];
         };
         wireguard = {
           enable = true;
    @@ -4195,7 +4760,7 @@ in
     
       swarselsystems = {
         flakePath = "/root/.dotfiles";
    -    info = "VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM";
    +    info = "VM.Standard.A1.Flex, 4 vCPUs, 24GB RAM";
         isImpermanence = true;
         isSecureBoot = false;
         isCrypted = false;
    @@ -4215,12 +4780,13 @@ in
       };
     
       swarselmodules.server = {
    -    oauth2-proxy = lib.mkDefault true;
    -    croc = lib.mkDefault true;
    -    microbin = lib.mkDefault true;
    -    shlink = lib.mkDefault true;
    -    slink = lib.mkDefault true;
    -    syncthing = lib.mkDefault true;
    +    oauth2-proxy = true;
    +    croc = true;
    +    microbin = true;
    +    shlink = true;
    +    slink = true;
    +    syncthing = true;
    +    diskEncryption = lib.mkForce false;
       };
     }
     
    @@ -4229,7 +4795,7 @@ in
     
    -
    3.1.3.2.2. hardware-configuration
    +
    3.1.3.1.2. hardware-configuration
    { lib, modulesPath, ... }:
    @@ -4252,7 +4818,7 @@ in
     
    -
    3.1.3.2.3. disko
    +
    3.1.3.1.3. disko
    # NOTE: ... is needed because dikso passes diskoFile
    @@ -4418,6 +4984,13 @@ This is a slim setup for developing base configuration. I do not track the hardw
         minimal = lib.mkForce true;
       };
     
    +  swarselmodules = {
    +    server = {
    +      network = lib.mkForce false;
    +      diskEncryption = lib.mkForce false;
    +    };
    +  };
    +
       swarselsystems = {
         info = "~SwarselSystems~ remote install helper";
         wallpaper = self + /files/wallpaper/lenovowp.png;
    @@ -4600,36 +5173,32 @@ TODO: cleanup this mess
     
    { self, config, pkgs, lib, ... }:
     let
       pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh";
    +  stateVersion = lib.mkDefault "23.05";
    +      homeFiles = {
    +        ".bash_history" = {
    +          text = ''
    +            swarsel-install -n hotel
    +          '';
    +        };
    +      };
     in
     {
     
       config = {
         home-manager.users.root.home = {
    -      stateVersion = "23.05";
    -      file = {
    -        ".bash_history" = {
    -          text = ''
    -            swarsel-install -n chaostheatre
    -          '';
    -        };
    -      };
    +      inherit stateVersion;
    +      file = homeFiles;
         };
         home-manager.users.swarsel = {
           home = {
             username = "swarsel";
             homeDirectory = lib.mkDefault "/home/swarsel";
    -        stateVersion = lib.mkDefault "23.05";
    +        inherit stateVersion;
             keyboard.layout = "us";
             sessionVariables = {
               FLAKE = "/home/swarsel/.dotfiles";
             };
    -        file = {
    -          ".bash_history" = {
    -            text = ''
    -              swarsel-install -n chaostheatre
    -            '';
    -          };
    -        };
    +        file = homeFiles;
           };
         };
     
    @@ -4647,10 +5216,6 @@ in
         nix = {
           channel.enable = false;
           package = pkgs.nixVersions.nix_2_28;
    -      # extraOptions = ''
    -      #   plugin-files = ${pkgs.dev.nix-plugins}/lib/nix/plugins
    -      #   extra-builtins-file = ${../nix/extra-builtins.nix}
    -      # '';
           extraOptions = ''
             plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: {
               buildInputs = [config.nix.package pkgs.boost];
    @@ -4702,6 +5267,7 @@ in
         environment.etc."issue".text = ''
           ~SwarselSystems~
           IP of primary interface: \4
    +      These IPs were also found: \4{eth0} \4{eth1} \4{eth2} \4{eth3} \4{eth4} \4{eth5} \4{wlan0}
           The Password for all users & root is 'setup'.
           Install the system remotely by running 'bootstrap -n <CONFIGURATION_NAME> -d <IP_FROM_ABOVE> ' on a machine with deployed secrets.
           Alternatively, run 'swarsel-install -n <CONFIGURATION_NAME>' for a local install. For your convenience, an example call is in the bash history (press up on the keyboard to access).
    @@ -4712,6 +5278,7 @@ in
           wireless.enable = false;
           # dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload";
           networkmanager.enable = true;
    +      usePredictableInterfaceNames = false;
         };
     
         services.getty.autologinUser = lib.mkForce "root";
    @@ -4738,6 +5305,8 @@ in
     
         programs.bash.shellAliases = {
           "swarsel-install" = "nix run github:Swarsel/.dotfiles#swarsel-install --";
    +      "swarsel-net-manufacturer" = "lspci -nn | grep -i 'network\\|ethernet'";
    +      "swarsel-kernel-module" = "lspci -k -d";
         };
     
         system.activationScripts.cache = {
    @@ -4771,7 +5340,7 @@ in
     
    -
    3.1.4.3. ChaosTheatre (Demo Physical/VM)
    +
    3.1.4.3. Hotel (Demo Physical/VM)

    This is just a demo host. It applies all the configuration found in the common parts of the flake, but disables all secrets-related features (as they would not work without the proper SSH keys). @@ -4812,10 +5381,17 @@ in }; networking = { - hostName = "chaostheatre"; + hostName = "hotel"; firewall.enable = true; }; + swarselmodules = { + server = { + network = lib.mkForce false; + diskEncryption = lib.mkForce false; + }; + }; + swarselsystems = { info = "~SwarselSystems~ demo host"; wallpaper = self + /files/wallpaper/lenovowp.png; @@ -4834,7 +5410,7 @@ in } // lib.optionalAttrs (!minimal) { swarselprofiles = { - chaostheatre = true; + hotel = true; minimal = true; }; } @@ -5135,6 +5711,91 @@ let mkOption types ; + + networkOptions = netSubmod: { + cidrv4 = mkOption { + type = types.nullOr types.net.cidrv4; + description = "The CIDRv4 of this network"; + default = null; + }; + + subnetMask4 = mkOption { + type = types.nullOr types.net.ipv4; + description = "The dotted decimal form of the subnet mask of this network"; + readOnly = true; + default = lib.swarselsystems.cidrToSubnetMask netSubmod.config.cidrv4; + }; + + cidrv6 = mkOption { + type = types.nullOr types.net.cidrv6; + description = "The CIDRv6 of this network"; + default = null; + }; + + hosts = mkOption { + default = { }; + type = types.attrsOf ( + types.submodule (hostSubmod: { + options = { + id = mkOption { + type = types.int; + description = "The id of this host in the network"; + }; + + mac = mkOption { + type = types.nullOr types.net.mac; + description = "The MAC of the interface on this host that belongs to this network."; + default = null; + }; + + ipv4 = mkOption { + type = types.nullOr types.net.ipv4; + description = "The IPv4 of this host in this network"; + readOnly = true; + default = + if netSubmod.config.cidrv4 == null then + null + else + lib.net.cidr.host hostSubmod.config.id netSubmod.config.cidrv4; + }; + + ipv6 = mkOption { + type = types.nullOr types.net.ipv6; + description = "The IPv6 of this host in this network"; + readOnly = true; + default = + if netSubmod.config.cidrv6 == null then + null + else + lib.net.cidr.host hostSubmod.config.id netSubmod.config.cidrv6; + }; + + cidrv4 = mkOption { + type = types.nullOr types.str; # FIXME: this is not types.net.cidr because it would zero out the host part + description = "The IPv4 of this host in this network, including CIDR mask"; + readOnly = true; + default = + if netSubmod.config.cidrv4 == null then + null + else + lib.net.cidr.hostCidr hostSubmod.config.id netSubmod.config.cidrv4; + }; + + cidrv6 = mkOption { + type = types.nullOr types.str; # FIXME: this is not types.net.cidr because it would zero out the host part + description = "The IPv6 of this host in this network, including CIDR mask"; + readOnly = true; + default = + if netSubmod.config.cidrv6 == null then + null + else + lib.net.cidr.hostCidr hostSubmod.config.id netSubmod.config.cidrv6; + }; + }; + }) + ); + }; + }; in { options = { @@ -5170,12 +5831,44 @@ in ); }; + networks = mkOption { + default = { }; + type = types.attrsOf ( + types.submodule (netSubmod: { + options = networkOptions netSubmod // { + vlans = mkOption { + default = { }; + type = types.attrsOf ( + types.submodule (vlanNetSubmod: { + options = networkOptions vlanNetSubmod // { + id = mkOption { + type = types.ints.between 1 4094; + description = "The VLAN id"; + }; + + name = mkOption { + description = "The name of this VLAN"; + default = vlanNetSubmod.config._module.args.name; + type = types.str; + }; + }; + }) + ); + }; + }; + }) + ); + }; + hosts = mkOption { type = types.attrsOf ( types.submodule { options = { - ipv4 = mkOption { - type = types.str; + defaultGateway4 = mkOption { + type = types.nullOr types.net.ipv4; + }; + defaultGateway6 = mkOption { + type = types.nullOr types.net.ipv6; }; }; } @@ -5231,11 +5924,13 @@ in

    3.2.1.5. Expose home-manager sops secrets in NixOS (automatically active)
    -
    { lib, config, globals, ... }:
    +
    { self, lib, config, globals, ... }:
     let
       inherit (config.swarselsystems) mainUser homeDir;
       inherit (config.repo.secrets.common.emacs) radicaleUser;
       modules = config.home-manager.users.${mainUser}.swarselmodules;
    +
    +  certsSopsFile = self + /secrets/certs/secrets.yaml;
     in
     {
       config = lib.mkIf config.swarselsystems.withHomeManager {
    @@ -5255,6 +5950,8 @@ in
             github-nixpkgs-review-token = { owner = mainUser; };
           }) // (lib.optionalAttrs modules.emacs {
             emacs-radicale-pw = { owner = mainUser; };
    +      }) // (lib.optionalAttrs modules.optional.work {
    +        harica-root-ca = { sopsFile = certsSopsFile; path = "${homeDir}/.aws/certs/harica-root.pem"; owner = mainUser; };
           }) // (lib.optionalAttrs modules.anki {
             anki-user = { owner = mainUser; };
             anki-pw = { owner = mainUser; };
    @@ -5448,7 +6145,19 @@ in
             system.stateVersion = lib.mkDefault "23.05";
     
             nixpkgs = {
    -          overlays = [ outputs.overlays.default ];
    +          overlays = [
    +            outputs.overlays.default
    +            (final: prev:
    +              let
    +                additions = final: _: import "${self}/pkgs/config" {
    +                  inherit self config lib;
    +                  pkgs = final;
    +                  homeConfig = config.home-manager.users.${config.swarselsystems.mainUser};
    +                };
    +              in
    +              additions final prev
    +            )
    +          ];
               config = {
                 allowUnfree = true;
               };
    @@ -5469,7 +6178,7 @@ We enable the use of home-manager as a NixoS module. A nice trick h
     

    -
    { self, inputs, config, lib, outputs, globals, nodes, minimal, configName, ... }:
    +
    { self, inputs, config, lib, homeLib, outputs, globals, nodes, minimal, configName, ... }:
     {
       options.swarselmodules.home-manager = lib.mkEnableOption "home-manager";
       config = lib.mkIf config.swarselmodules.home-manager {
    @@ -5478,6 +6187,7 @@ We enable the use of home-manager as a NixoS module. A nice trick h
           useUserPackages = true;
           verbose = true;
           backupFileExtension = "hm-bak";
    +      overwriteBackup = true;
           users.${config.swarselsystems.mainUser}.imports = [
             inputs.nix-index-database.homeModules.nix-index
             inputs.sops-nix.homeManagerModules.sops
    @@ -5500,7 +6210,11 @@ We enable the use of home-manager as a NixoS module. A nice trick h
               home.stateVersion = lib.mkDefault config.system.stateVersion;
             }
           ];
    -      extraSpecialArgs = { inherit (inputs) self nixgl; inherit inputs outputs globals nodes minimal configName; };
    +      extraSpecialArgs = {
    +        inherit (inputs) self nixgl;
    +        inherit inputs outputs globals nodes minimal configName;
    +        lib = homeLib;
    +      };
         };
       };
     }
    @@ -5623,7 +6337,7 @@ This is also exposed to home-manager configurations, in case this ever breaks, I
     
     
    # largely based on https://github.com/oddlama/nix-config/blob/main/modules/secrets.nix
    -{ config, inputs, lib, minimal, ... }:
    +{ config, inputs, lib, ... }:
     let
       # If the given expression is a bare set, it will be wrapped in a function,
       # so that the imported file can always be applied to the inputs, similar to
    @@ -5689,7 +6403,7 @@ in
           let
             local = config.node.secretsDir + "/pii.nix.enc";
           in
    -      (lib.optionalAttrs (lib.pathExists local && !minimal) { inherit local; }) // lib.optionalAttrs (!minimal) {
    +      (lib.optionalAttrs (lib.pathExists local) { inherit local; }) // lib.optionalAttrs true {
             common = ../../../secrets/repo/pii.nix.enc;
           };
       };
    @@ -6661,12 +7375,15 @@ Here I disable global completion to prevent redundant compinit calls and cache i
     let
       inherit (config.swarselsystems) mainUser homeDir;
       devices = config.swarselsystems.syncthing.syncDevices;
    +  servicePort = 8384;
     in
     {
       options.swarselmodules.syncthing = lib.mkEnableOption "syncthing config";
       config = lib.mkIf config.swarselmodules.syncthing {
         services.syncthing = {
           enable = true;
    +      systemService = true;
    +      guiAddress = "127.0.0.1:${builtins.toString servicePort}";
           package = pkgs.syncthing;
           user = mainUser;
           dataDir = homeDir;
    @@ -7567,12 +8284,16 @@ in
           xwayland-satellite-unstable
         ];
     
    -    niri-flake.cache.enable = true;
     
         programs.niri = {
           enable = true;
           package = pkgs.niri-unstable; # the actual niri that will be installed and used
         };
    +  } // {
    +    niri-flake.cache.enable = true;
    +    programs.niri = {
    +      package = null;
    +    };
       };
     }
     
    @@ -7640,6 +8361,7 @@ in environment.shellAliases = lib.recursiveUpdate { nswitch = "cd ${flakePath}; swarsel-deploy $(hostname) switch; cd -;"; + ntest = "cd ${flakePath}; swarsel-deploy $(hostname) test; cd -;"; nboot = "cd ${flakePath}; swarsel-deploy $(hostname) boot; cd -;"; ndry = "cd ${flakePath}; swarsel-deploy $(hostname) dry-activate; cd -;"; } @@ -7761,9 +8483,60 @@ let inherit (config.repo.secrets.common) dnsProvider; inherit (config.repo.secrets.common.mail) address3; + serviceUser = "nginx"; + serviceGroup = serviceUser; + + sslBasePath = "/etc/ssl"; + dhParamsPathBase = "${sslBasePath}/dhparams.pem"; + dhParamsPath = + if config.swarselsystems.isImpermanence then + "/persist/${dhParamsPathBase}" + else + "${dhParamsPathBase}"; in { options.swarselmodules.server.nginx = lib.mkEnableOption "enable nginx on server"; + options.services.nginx = { + recommendedSecurityHeaders = lib.mkEnableOption "additional security headers by default in each location block."; + virtualHosts = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule { + options.locations = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule (submod: { + options = { + recommendedSecurityHeaders = lib.mkOption { + type = lib.types.bool; + default = config.services.nginx.recommendedSecurityHeaders; + description = "Whether to add additional security headers to this location."; + }; + + X-Frame-Options = lib.mkOption { + type = lib.types.str; + default = "DENY"; + description = "The value to use for X-Frame-Options"; + }; + }; + config = lib.mkIf submod.config.recommendedSecurityHeaders { + extraConfig = lib.mkBefore '' + # Enable HTTP Strict Transport Security (HSTS) + add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; + + # Minimize information leaked to other domains + add_header Referrer-Policy "origin-when-cross-origin"; + + add_header X-XSS-Protection "1; mode=block"; + add_header X-Frame-Options "${submod.config.X-Frame-Options}"; + add_header X-Content-Type-Options "nosniff"; + ''; + }; + }) + ); + }; + } + ); + }; + }; config = lib.mkIf config.swarselmodules.server.nginx { environment.systemPackages = with pkgs; [ lego @@ -7776,24 +8549,68 @@ in ''; }; + users.groups.acme.members = [ "nginx" ]; + security.acme = { acceptTerms = true; defaults = { inherit dnsProvider; email = address3; environmentFile = "${config.sops.templates."certs.secret".path}"; + reloadServices = [ "nginx" ]; + dnsPropagationCheck = true; }; }; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + environment.persistence."/persist" = lib.mkIf config.swarselsystems.isImpermanence { + files = [ dhParamsPathBase ]; + }; + services.nginx = { enable = true; + user = serviceUser; + group = serviceGroup; statusPage = true; recommendedProxySettings = true; recommendedTlsSettings = true; recommendedOptimisation = true; recommendedGzipSettings = true; - # virtualHosts are defined in the respective sections + recommendedBrotliSettings = true; + recommendedSecurityHeaders = true; + sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:!aNULL"; + sslDhparam = dhParamsPathBase; + virtualHosts.fallback = { + default = true; + rejectSSL = true; + locations."/".extraConfig = '' + deny all; + ''; + }; }; + system.activationScripts."createPersistentStorageDirs" = lib.mkIf config.swarselsystems.isImpermanence { + deps = [ "generateDHParams" "users" "groups" ]; + }; + system.activationScripts."generateDHParams" = + { + text = '' + set -eu + + ${pkgs.coreutils}/bin/install -d -m 0755 ${sslBasePath} + ${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0755 /persist${sslBasePath}" else ""} + + if [ ! -f "${dhParamsPathBase}" ]; then + ${pkgs.openssl}/bin/openssl dhparam -out ${dhParamsPath} 4096 + chmod 0644 ${dhParamsPath} + chown ${serviceUser}:${serviceGroup} ${dhParamsPath} + fi + ''; + deps = [ + "etc" + (lib.mkIf config.swarselsystems.isImpermanence "specialfs") + ]; + }; }; }
    @@ -7844,8 +8661,374 @@ Here I am forcing startWhenNeeded to false so that the value will n
    +
    +
    3.2.3.7. Network settings
    +
    +
    +
    { lib, config, ... }:
    +{
    +  options.swarselmodules.server.network = lib.mkEnableOption "enable server network config";
    +  config = lib.mkIf config.swarselmodules.server.network {
    +
    +    globals.networks.home.hosts.${config.node.name} = {
    +      inherit (config.repo.secrets.local.networking.networks.home) id;
    +      mac = config.repo.secrets.local.networking.networks.home.mac or null;
    +    };
    +
    +    globals.hosts.${config.node.name} = {
    +      inherit (config.repo.secrets.local.networking) defaultGateway4;
    +    };
    +
    +    networking = {
    +      inherit (config.repo.secrets.local.networking) hostId;
    +      hostName = config.node.name;
    +      nftables.enable = lib.mkDefault false;
    +      enableIPv6 = lib.mkDefault true;
    +      firewall = {
    +        enable = lib.mkDefault true;
    +      };
    +    };
    +
    +  };
    +}
    +
    +
    +
    +
    +
    +
    3.2.3.8. Disk encryption
    +
    +

    +The hostkey can be generated with ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key. +Use lspci -v | grep -iA8 'network\|ethernet' to supposedly find out which kernel module is needed for networking in initrd. However I prefer a different approach: +

    + +

    +Use lspci -nn | grep -i network to find out manufacturer info: +

    + +
    +
    lspci -nn | grep -i 'network\|ethernet'
    +
    +
    + + + + +++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    04:00.0Networkcontroller[0280]:MEDIATEKCorp.MT7922802.11axPCIExpressWirelessNetworkAdapter[14c3:0616]
    6a:00.0Ethernetcontroller[0200]:IntelCorporationI210GigabitNetworkConnection[8086:1533](rev03) 
    + +

    +From the last bracket you then find out the correct kernel module: +

    + +
    +
    lspci -k -d 14c3:0616
    +
    +
    + + + + +++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    04:00.0Networkcontroller:MEDIATEKCorp.MT7922802.11axPCIExpressWirelessNetworkAdapter
     Subsystem:MEDIATEKCorp.Devicee616      
     Kerneldriverinuse:mt7921e      
     Kernelmodules:mt7921e        
    + +
    +
    { self, pkgs, lib, config, globals, minimal, ... }:
    +let
    +  localIp = globals.networks.home.hosts.${config.node.name}.ipv4;
    +  subnetMask = globals.networks.home.subnetMask4;
    +  gatewayIp = globals.hosts.${config.node.name}.defaultGateway4;
    +
    +  hostKeyPath = "/etc/secrets/initrd/ssh_host_ed25519_key";
    +in
    +{
    +  options.swarselmodules.server.diskEncryption = lib.mkEnableOption "enable disk encryption config";
    +  options.swarselsystems.networkKernelModules = lib.mkOption {
    +    type = lib.types.listOf lib.types.str;
    +    default = [ ];
    +  };
    +  config = lib.mkIf (config.swarselmodules.server.diskEncryption && config.swarselsystems.isCrypted) {
    +
    +    system.activationScripts.ensureInitrdHostkey = lib.mkIf (config.swarselprofiles.server || minimal) {
    +      text = ''
    +        [[ -e ${hostKeyPath} ]] || ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -N "" -f ${hostKeyPath}
    +      '';
    +      deps = [ "users" ];
    +    };
    +
    +    environment.persistence."/persist" = lib.mkIf (config.swarselsystems.isImpermanence && (config.swarselprofiles.server || minimal)) {
    +      files = [ hostKeyPath ];
    +    };
    +
    +    boot = lib.mkIf (config.swarselprofiles.server || minimal) {
    +      kernelParams = lib.mkIf (!config.swarselsystems.isLaptop) [
    +        "ip=${localIp}::${gatewayIp}:${subnetMask}:${config.networking.hostName}::none"
    +      ];
    +      initrd = {
    +        availableKernelModules = config.swarselsystems.networkKernelModules;
    +        network = {
    +          enable = true;
    +          udhcpc.enable = lib.mkIf config.swarselsystems.isLaptop true;
    +          flushBeforeStage2 = true;
    +          ssh = {
    +            enable = true;
    +            port = 2222; # avoid hostkey changed nag
    +            authorizedKeyFiles = [
    +              (self + /secrets/keys/ssh/yubikey.pub)
    +              (self + /secrets/keys/ssh/magicant.pub)
    +            ];
    +            hostKeys = [ hostKeyPath ];
    +          };
    +          # postCommands = ''
    +          #   echo 'cryptsetup-askpass || echo "Unlock was successful; exiting SSH session" && exit 1' >> /root/.profile
    +          # '';
    +        };
    +        systemd = {
    +          initrdBin = with pkgs; [
    +            cryptsetup
    +          ];
    +          services = {
    +            unlock-luks = {
    +              wantedBy = [ "initrd.target" ];
    +              after = [ "network.target" ];
    +              before = [ "systemd-cryptsetup@cryptroot.service" ];
    +              path = [ "/bin" ];
    +
    +              serviceConfig = {
    +                Type = "oneshot";
    +                RemainAfterExit = true;
    +              };
    +
    +              script = ''
    +                echo "systemctl default" >> /root/.profile
    +              '';
    +            };
    +          };
    +        };
    +      };
    +    };
    +  };
    +
    +}
    +
    +
    +
    +
    +
    +
    3.2.3.9. Router
    +
    +
    +
    { lib, config, ... }:
    +let
    +  serviceName = "router";
    +in
    +{
    +  options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    +  config = lib.mkIf config.swarselmodules.server.${serviceName} {
    +
    +    systemd.network = {
    +      wait-online.anyInterface = true;
    +      networks = {
    +        "30-lan0" = {
    +          matchConfig.Name = "lan0";
    +          linkConfig.RequiredForOnline = "enslaved";
    +          networkConfig = {
    +            ConfigureWithoutCarrier = true;
    +          };
    +        };
    +        "30-lan1" = {
    +          matchConfig.Name = "lan1";
    +          linkConfig.RequiredForOnline = "enslaved";
    +          networkConfig = {
    +            ConfigureWithoutCarrier = true;
    +          };
    +        };
    +        "30-lan2" = {
    +          matchConfig.Name = "lan2";
    +          linkConfig.RequiredForOnline = "enslaved";
    +          networkConfig = {
    +            ConfigureWithoutCarrier = true;
    +          };
    +        };
    +        "30-lan3" = {
    +          matchConfig.Name = "lan3";
    +          linkConfig.RequiredForOnline = "enslaved";
    +          networkConfig = {
    +            ConfigureWithoutCarrier = true;
    +          };
    +        };
    +        "10-wan" = {
    +          matchConfig.Name = "wan";
    +          networkConfig = {
    +            # start a DHCP Client for IPv4 Addressing/Routing
    +            DHCP = "ipv4";
    +            DNSOverTLS = true;
    +            DNSSEC = true;
    +            IPv6PrivacyExtensions = false;
    +            IPForward = true;
    +          };
    +          # make routing on this interface a dependency for network-online.target
    +          linkConfig.RequiredForOnline = "routable";
    +    };
    +  };
    +};
    +  };
    +}
    +
    +
    +
    +
    -
    3.2.3.7. kavita
    +
    3.2.3.10. kavita
    { self, lib, config, pkgs, globals, ... }:
    @@ -7856,7 +9039,7 @@ let
       serviceName = "kavita";
       serviceUser = "kavita";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     in
     {
       options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    @@ -7919,7 +9102,7 @@ in
     
    -
    3.2.3.8. jellyfin
    +
    3.2.3.11. jellyfin
    { pkgs, lib, config, globals, ... }:
    @@ -7928,7 +9111,7 @@ let
       serviceName = "jellyfin";
       serviceUser = "jellyfin";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     in
     {
       options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    @@ -7990,7 +9173,7 @@ in
     
    -
    3.2.3.9. navidrome
    +
    3.2.3.12. navidrome
    { pkgs, config, lib, globals, ... }:
    @@ -8000,7 +9183,7 @@ let
       serviceUser = "navidrome";
       serviceGroup = serviceUser;
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     in
     {
       options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    @@ -8036,6 +9219,27 @@ in
     
         globals.services.${serviceName}.domain = serviceDomain;
     
    +    services.snapserver = {
    +      enable = true;
    +      settings = {
    +        stream = {
    +          port = 1704;
    +          source = "pipe:///tmp/snapfifo?name=default";
    +          bind_to_address = "0.0.0.0";
    +        };
    +      };
    +    };
    +
    +    systemd.services = {
    +      ${serviceName}.serviceConfig = {
    +        PrivateDevices = lib.mkForce false;
    +        PrivateUsers = lib.mkForce false;
    +        RestrictRealtime = lib.mkForce false;
    +        SystemCallFilter = lib.mkForce null;
    +        RootDirectory = lib.mkForce null;
    +      };
    +    };
    +
         services.${serviceName} = {
           enable = true;
           openFirewall = true;
    @@ -8050,8 +9254,9 @@ in
             EnableTranscodingConfig = true;
             Scanner.GroupAlbumReleases = true;
             ScanSchedule = "@every 24h";
    -        MPVPath = "${pkgs.mpv}/bin/mpv";
    -        MPVCommandTemplate = "mpv --audio-device=%d --no-audio-display --pause %f";
    +        # MPVPath = "";
    +        # MPVCommandTemplate = "${pkgs.mpv}/bin/mpv --audio-device=%d --input-ipc-server=%s --no-audio-display --log-file=/tmp/mpv.log --pause %f";
    +        # MPVCmdTemplate = "${pkgs.mpv}/bin/mpv --no-audio-display --pause %f --input-ipc-server=%s --audio-channels=stereo --audio-samplerate=48000 --audio-format=s16 --ao=pcm --ao-pcm-file=/tmp/snapfifo --log-file=/tmp/mpv.log";
             ReverseProxyWhitelist = "0.0.0.0/0";
             ReverseProxyUserHeader = "X-User";
             Jukebox = {
    @@ -8135,7 +9340,7 @@ in
     
    -
    3.2.3.10. spotifyd
    +
    3.2.3.13. spotifyd
    { lib, config, ... }:
    @@ -8194,7 +9399,7 @@ in
     
    -
    3.2.3.11. mpd
    +
    3.2.3.14. mpd
    { self, lib, config, pkgs, ... }:
    @@ -8268,7 +9473,7 @@ in
     
    -
    3.2.3.12. pipewire
    +
    3.2.3.15. pipewire
    { lib, config, ... }:
    @@ -8296,7 +9501,7 @@ in
     
    -
    3.2.3.13. postgresql
    +
    3.2.3.16. postgresql
    { config, lib, pkgs, ... }:
    @@ -8321,7 +9526,7 @@ in
     
    -
    3.2.3.14. matrix
    +
    3.2.3.17. matrix
    { lib, config, pkgs, globals, ... }:
    @@ -8332,7 +9537,7 @@ let
       serviceName = "matrix";
       serviceDomain = config.repo.secrets.common.services.domains.matrix;
       serviceUser = "matrix-synapse";
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     
       federationPort = 8448;
       whatsappPort = 29318;
    @@ -8677,7 +9882,7 @@ in
     
    -
    3.2.3.15. nextcloud
    +
    3.2.3.18. nextcloud
    { pkgs, lib, config, globals, ... }:
    @@ -8690,7 +9895,9 @@ let
       serviceGroup = serviceUser;
       serviceName = "nextcloud";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
    +
    +  nextcloudVersion = "32";
     in
     {
       options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    @@ -8711,7 +9918,7 @@ in
               trusted_proxies = [ "0.0.0.0" ];
               overwriteprotocol = "https";
             };
    -        package = pkgs.nextcloud31;
    +        package = pkgs."nextcloud${nextcloudVersion}";
             hostName = serviceDomain;
             home = "/Vault/data/${serviceName}";
             datadir = "/Vault/data/${serviceName}";
    @@ -8719,7 +9926,7 @@ in
             configureRedis = true;
             maxUploadSize = "4G";
             extraApps = {
    -          inherit (pkgs.nextcloud31Packages.apps) mail calendar contacts cospend phonetrack polls tasks sociallogin;
    +          inherit (pkgs."nextcloud${nextcloudVersion}Packages".apps) mail calendar contacts cospend phonetrack polls tasks sociallogin;
             };
             extraAppsEnable = true;
             config = {
    @@ -8761,7 +9968,7 @@ in
     
    -
    3.2.3.16. immich
    +
    3.2.3.19. immich
    { lib, pkgs, config, globals, ... }:
    @@ -8770,7 +9977,7 @@ let
       serviceUser = "immich";
       serviceName = "immich";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     in
     {
       options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    @@ -8839,7 +10046,7 @@ in
     
    -
    3.2.3.17. paperless (tika, gotenberg)
    +
    3.2.3.20. paperless (tika, gotenberg)

    This is my personal document management system. It automatically pulls documents from several sources, the only manual step for physical documents is to put them in my scanner and use email delivery. @@ -8859,7 +10066,7 @@ let serviceGroup = serviceUser; serviceName = "paperless"; serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; - serviceAddress = globals.hosts.winters.ipv4; + serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4; tikaPort = 9998; gotenbergPort = 3002; @@ -8986,7 +10193,7 @@ in

    -
    3.2.3.18. transmission
    +
    3.2.3.21. transmission
    { self, pkgs, lib, config, ... }:
    @@ -9175,7 +10382,7 @@ in
     
    -
    3.2.3.19. syncthing
    +
    3.2.3.22. syncthing
    { lib, config, configName, globals, ... }:
    @@ -9187,7 +10394,7 @@ let
       serviceUser = "syncthing";
       serviceGroup = serviceUser;
       serviceName = "syncthing";
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
       specificServiceName = "syncthing-${configName}";
     
       cfg = config.services.${serviceName};
    @@ -9328,7 +10535,7 @@ in
     
    -
    3.2.3.20. restic
    +
    3.2.3.23. restic

    This manages backups for my pictures and obsidian files. @@ -9403,7 +10610,7 @@ in

    -
    3.2.3.21. monitoring (Grafana, Prometheus)
    +
    3.2.3.24. monitoring (Grafana, Prometheus)

    This section exposes several metrics that I use to check the health of my server. I need to expand on the exporters section at some point, but for now I have everything I need. @@ -9417,7 +10624,7 @@ let serviceGroup = serviceUser; serviceName = "grafana"; serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; - serviceAddress = globals.hosts.winters.ipv4; + serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4; prometheusPort = 9090; prometheusUser = "prometheus"; @@ -9661,7 +10868,7 @@ in

    -
    3.2.3.22. Jenkins
    +
    3.2.3.25. Jenkins

    This is a WIP Jenkins instance. It is used to automatically build a new system when pushes to the main repository are detected. I have turned this service off for now however, as I actually prefer to start my builds manually. @@ -9673,7 +10880,7 @@ let servicePort = 8088; serviceName = "jenkins"; serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; - serviceAddress = globals.hosts.winters.ipv4; + serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4; in { options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; @@ -9720,7 +10927,7 @@ in

    -
    3.2.3.23. Emacs elfeed (RSS Server)
    +
    3.2.3.26. Emacs elfeed (RSS Server)

    This was an approach of hosting an RSS server from within emacs. That would have been useful as it would have allowed me to allow my feeds from any device. However, it proved impossible to do bidirectional syncing, so I abandoned this configuration in favor of FreshRSS. @@ -9752,7 +10959,7 @@ in

    -
    3.2.3.24. FreshRSS
    +
    3.2.3.27. FreshRSS

    FreshRSS is a more 'classical' RSS aggregator that I can just host as a distinct service. This also has its upsides because I jave more control over the state this way. @@ -9778,7 +10985,7 @@ let serviceUser = "freshrss"; serviceGroup = serviceName; serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; - serviceAddress = globals.hosts.winters.ipv4; + serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4; inherit (config.swarselsystems) sopsFile; in @@ -9882,7 +11089,7 @@ in

    -
    3.2.3.25. forgejo (git server)
    +
    3.2.3.28. forgejo (git server)
    { lib, config, pkgs, globals, ... }:
    @@ -9894,7 +11101,7 @@ let
       serviceGroup = serviceUser;
       serviceName = "forgejo";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     
       kanidmDomain = globals.services.kanidm.domain;
     in
    @@ -10048,7 +11255,7 @@ in
     
    -
    3.2.3.26. Anki Sync Server
    +
    3.2.3.29. Anki Sync Server
    { self, lib, config, globals, ... }:
    @@ -10058,7 +11265,7 @@ let
       servicePort = 27701;
       serviceName = "ankisync";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     
       ankiUser = globals.user.name;
     in
    @@ -10123,7 +11330,7 @@ in
     
    -
    3.2.3.27. kanidm
    +
    3.2.3.30. kanidm

    The forgejo configuration is a little broken and will show a 500 error when signing in through kanidm. However, when pressing back and refreshing the page, I am logged in. Currently I cannot be bothered to fix this. @@ -10149,7 +11356,7 @@ let serviceGroup = serviceUser; serviceName = "kanidm"; serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; - serviceAddress = globals.hosts.winters.ipv4; + serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4; oauth2ProxyDomain = globals.services.oauth2Proxy.domain; immichDomain = globals.services.immich.domain; @@ -10161,8 +11368,18 @@ let certBase = "/etc/ssl"; certsDir = "${certBase}/certs"; privateDir = "${certBase}/private"; - certPath = "${certsDir}/${serviceName}.crt"; - keyPath = "${privateDir}/${serviceName}.key"; + certPathBase = "${certsDir}/${serviceName}.crt"; + certPath = + if config.swarselsystems.isImpermanence then + "/persist${certPathBase}" + else + "${certPathBase}"; + keyPathBase = "${privateDir}/${serviceName}.key"; + keyPath = + if config.swarselsystems.isImpermanence then + "/persist${keyPathBase}" + else + "${keyPathBase}"; in { options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; @@ -10195,6 +11412,16 @@ in globals.services.${serviceName}.domain = serviceDomain; + environment.persistence."/persist" = lib.mkIf config.swarselsystems.isImpermanence { + files = [ + certPathBase + keyPathBase + ]; + }; + + system.activationScripts."createPersistentStorageDirs" = lib.mkIf config.swarselsystems.isImpermanence { + deps = [ "generateSSLCert-${serviceName}" "users" "groups" ]; + }; system.activationScripts."generateSSLCert-${serviceName}" = let daysValid = 3650; @@ -10205,13 +11432,15 @@ in set -eu ${pkgs.coreutils}/bin/install -d -m 0755 ${certsDir} + ${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0755 /persist${certsDir}" else ""} ${pkgs.coreutils}/bin/install -d -m 0750 ${privateDir} + ${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0750 /persist${privateDir}" else ""} need_gen=0 - if [ ! -f "${certPath}" ] || [ ! -f "${keyPath}" ]; then + if [ ! -f "${certPathBase}" ] || [ ! -f "${keyPathBase}" ]; then need_gen=1 else - enddate="$(${pkgs.openssl}/bin/openssl x509 -noout -enddate -in "${certPath}" | cut -d= -f2)" + enddate="$(${pkgs.openssl}/bin/openssl x509 -noout -enddate -in "${certPathBase}" | cut -d= -f2)" end_epoch="$(${pkgs.coreutils}/bin/date -d "$enddate" +%s)" now_epoch="$(${pkgs.coreutils}/bin/date +%s)" seconds_left=$(( end_epoch - now_epoch )) @@ -10233,7 +11462,10 @@ in chown ${serviceUser}:${serviceGroup} "${certPath}" "${keyPath}" fi ''; - deps = [ "etc" ]; + deps = [ + "etc" + (lib.mkIf config.swarselsystems.isImpermanence "specialfs") + ]; }; services = { @@ -10244,9 +11476,9 @@ in domain = serviceDomain; origin = "https://${serviceDomain}"; # tls_chain = config.sops.secrets.kanidm-self-signed-crt.path; - tls_chain = certPath; + tls_chain = certPathBase; # tls_key = config.sops.secrets.kanidm-self-signed-key.path; - tls_key = keyPath; + tls_key = keyPathBase; bindaddress = "0.0.0.0:${toString servicePort}"; trust_x_forward_for = true; }; @@ -10276,6 +11508,7 @@ in "firefly.access" = { }; "radicale.access" = { }; "slink.access" = { }; + "opkssh.access" = { }; }; inherit (config.repo.secrets.local) persons; @@ -10370,6 +11603,23 @@ in }; }; }; + opkssh = { + displayName = "OPKSSH"; + originUrl = [ + "http://localhost:3000" + "http://localhost:3000/login-callback" + "http://localhost:10001/login-callback" + "http://localhost:11110/login-callback" + ]; + originLanding = "http://localhost:3000"; + public = true; + enableLocalhostRedirects = true; + scopeMaps."opkssh.access" = [ + "openid" + "email" + "profile" + ]; + }; oauth2-proxy = { displayName = "Oauth2-Proxy"; originUrl = "https://${oauth2ProxyDomain}/oauth2/callback"; @@ -10455,7 +11705,7 @@ in

    -
    3.2.3.28. oauth2-proxy
    +
    3.2.3.31. oauth2-proxy
    { lib, config, globals, ... }:
    @@ -10687,7 +11937,7 @@ in
     
    -
    3.2.3.29. Firefly-III
    +
    3.2.3.32. Firefly-III
    { self, lib, config, globals, ... }:
    @@ -10697,7 +11947,7 @@ let
       serviceGroup = serviceUser;
       serviceName = "firefly-iii";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     
       nginxGroup = "nginx";
     
    @@ -10807,7 +12057,7 @@ in
     
    -
    3.2.3.30. Koillection
    +
    3.2.3.33. Koillection
    { self, lib, config, globals, ... }:
    @@ -10818,7 +12068,7 @@ let
       servicePort = 2282;
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
       serviceDir = "/Vault/data/koillection";
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     
       postgresUser = config.systemd.services.postgresql.serviceConfig.User; # postgres
       postgresPort = config.services.postgresql.settings.port; # 5432
    @@ -10949,7 +12199,7 @@ in
     
    -
    3.2.3.31. Atuin
    +
    3.2.3.34. Atuin
    { lib, config, globals, ... }:
    @@ -10957,7 +12207,7 @@ let
       servicePort = 8888;
       serviceName = "atuin";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     in
     {
       options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    @@ -11007,7 +12257,7 @@ in
     
    -
    3.2.3.32. Radicale
    +
    3.2.3.35. Radicale
    { self, lib, config, globals, ... }:
    @@ -11019,7 +12269,7 @@ let
       serviceUser = "radicale";
       serviceGroup = serviceUser;
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     
       cfg = config.services.${serviceName};
     in
    @@ -11088,9 +12338,15 @@ in
           };
         };
     
    -    systemd.tmpfiles.rules = [
    -      "d ${cfg.settings.storage.filesystem_folder} 0750 ${serviceUser} ${serviceGroup} - -"
    -    ];
    +    systemd.tmpfiles.settings."10-radicale" = {
    +      "${cfg.settings.storage.filesystem_folder}" = {
    +        d = {
    +          group = serviceGroup;
    +          user = serviceUser;
    +          mode = "0750";
    +        };
    +      };
    +    };
     
         networking.firewall.allowedTCPPorts = [ servicePort ];
     
    @@ -11128,7 +12384,7 @@ in
     
    -
    3.2.3.33. croc
    +
    3.2.3.36. croc
    { self, lib, config, pkgs, ... }:
    @@ -11204,7 +12460,7 @@ in
     
    -
    3.2.3.34. microbin
    +
    3.2.3.37. microbin
    { self, lib, config, ... }:
    @@ -11343,7 +12599,7 @@ in
     
    -
    3.2.3.35. shlink
    +
    3.2.3.38. shlink
    { self, lib, config, ... }:
    @@ -11396,13 +12652,25 @@ in
           ];
         };
     
    -    systemd.tmpfiles.rules = [
    -      "d ${serviceDir}/data 0750 1001 root - -"
    -      "d ${serviceDir}/data/cache 0750 1001 root - -"
    -      "d ${serviceDir}/data/locks 0750 1001 root - -"
    -      "d ${serviceDir}/data/log 0750 1001 root - -"
    -      "d ${serviceDir}/data/proxies 0750 1001 root - -"
    -    ];
    +    systemd.tmpfiles.settings."11-shlink" = builtins.listToAttrs (
    +      map
    +        (path: {
    +          name = "${serviceDir}/${path}";
    +          value = {
    +            d = {
    +              group = "root";
    +              user = "1001";
    +              mode = "0750";
    +            };
    +          };
    +        }) [
    +        "data"
    +        "data/cache"
    +        "data/locks"
    +        "data/log"
    +        "data/proxies"
    +      ]
    +    );
     
         networking.firewall.allowedTCPPorts = [ servicePort ];
     
    @@ -11446,7 +12714,7 @@ in
     
    -
    3.2.3.36. slink
    +
    3.2.3.39. slink

    Deployment notes: @@ -11489,10 +12757,22 @@ in ]; }; - systemd.tmpfiles.rules = [ - "d ${serviceDir}/var/data 0750 root root - -" - "d ${serviceDir}/images 0750 root root - -" - ]; + systemd.tmpfiles.settings."12-slink" = builtins.listToAttrs ( + map + (path: { + name = "${serviceDir}/${path}"; + value = { + d = { + group = "root"; + user = "root"; + mode = "0750"; + }; + }; + }) [ + "var/data" + "images" + ] + ); networking.firewall.allowedTCPPorts = [ servicePort ]; @@ -11542,7 +12822,7 @@ in

    -
    3.2.3.37. Snipe-IT
    +
    3.2.3.40. Snipe-IT
    { self, lib, config, globals, ... }:
    @@ -11556,7 +12836,7 @@ let
       serviceUser = "snipeit";
       serviceGroup = serviceUser;
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     
       mysqlPort = 3306;
     in
    @@ -11621,7 +12901,7 @@ in
     
    -
    3.2.3.38. Homebox
    +
    3.2.3.41. Homebox
    { lib, pkgs, config, globals, ... }:
    @@ -11629,7 +12909,7 @@ let
       servicePort = 7745;
       serviceName = "homebox";
       serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
    -  serviceAddress = globals.hosts.winters.ipv4;
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
     in
     {
       options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    @@ -11682,6 +12962,166 @@ in
     
    +
    +
    3.2.3.42. OPKSSH
    +
    +
    +
    { lib, config, globals, ... }:
    +let
    +  serviceName = "opkssh";
    +  serviceUser = "opksshuser";
    +  serviceGroup = serviceUser;
    +
    +  kanidmDomain = globals.services.kanidm.domain;
    +
    +  inherit (config.swarselsystems) mainUser;
    +  inherit (config.repo.secrets.local) persons;
    +in
    +{
    +  options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    +  config = lib.mkIf config.swarselmodules.server.${serviceName} {
    +
    +    services.${serviceName} = {
    +      enable = true;
    +      user = serviceUser;
    +      group = serviceGroup;
    +      providers = {
    +        kanidm = {
    +          lifetime = "oidc";
    +          issuer = "https://${kanidmDomain}/oauth2/openid/${serviceName}";
    +          clientId = serviceName;
    +        };
    +      };
    +      authorizations = [
    +        {
    +          user = mainUser;
    +          principal = builtins.head persons.${mainUser}.mailAddresses;
    +          inherit (config.services.opkssh.providers.kanidm) issuer;
    +        }
    +      ];
    +    };
    +
    +  };
    +
    +}
    +
    +
    +
    +
    +
    +
    3.2.3.43. Garage
    +
    +

    +Generate the admin token using openssl rand -base64 32. +Generate the rpc token using openssl rand -hex 32. +

    + +
    +
    { self, lib, pkgs, config, configName, globals, ... }:
    +let
    +  sopsFile = self + /secrets/${configName}/secrets2.yaml;
    +
    +  serviceName = "garage";
    +  servicePort = 3900;
    +  serviceDomain = config.repo.secrets.common.services.domains."${serviceName}-${configName}";
    +  serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
    +
    +  cfg = config.services.${serviceName};
    +  metadata_dir = "/var/lib/garage/meta";
    +in
    +{
    +  options = {
    +    swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    +    swarselsystems.server.${serviceName} = {
    +      data_dir = lib.mkOption {
    +        type = lib.types.either lib.types.path (lib.types.listOf lib.types.attrs);
    +        default = "/var/lib/garage/data";
    +      };
    +    };
    +  };
    +  config = lib.mkIf config.swarselmodules.server.${serviceName} {
    +
    +    sops = {
    +      secrets.garage-admin-token = { inherit sopsFile; };
    +      secrets.garage-rpc-secret = { inherit sopsFile; };
    +    };
    +
    +    environment = {
    +      persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
    +        { directory = metadata_dir; }
    +      ];
    +      systemPackages = [
    +        cfg.package
    +      ];
    +    };
    +
    +    systemd.services.${serviceName}.serviceConfig = {
    +      DynamicUser = false;
    +      ProtectHome = lib.mkForce false;
    +    };
    +
    +    services.${serviceName} = {
    +      enable = true;
    +      package = pkgs.garage_2;
    +      settings = {
    +        inherit (config.swarselsystems.${serviceName}) data_dir;
    +        inherit metadata_dir;
    +        db_engine = "lmdb";
    +        block_size = "1MiB";
    +        use_local_tz = false;
    +
    +        replication_factor = 2; # Number of copies of data
    +
    +        rpc_bind_addr = "[::]:3901";
    +        rpc_public_addr = "${config.repo.secrets.local.ipv4}:4317";
    +        rpc_secret_file = config.sops.secrets.garage-rpc-secret.path;
    +
    +        s3_api = {
    +          s3_region = "swarsel";
    +          api_bind_addr = "0.0.0.0:${builtins.toString servicePort}";
    +          root_domain = ".s3.garage.localhost";
    +        };
    +
    +        admin = {
    +          api_bind_addr = "0.0.0.0:3903";
    +          admin_token_file = config.sops.secrets.garage-admin-token.path;
    +        };
    +
    +        k2v_api = {
    +          api_bind_addr = "[::]:3904";
    +        };
    +      };
    +    };
    +
    +    nodes.moonside.services.nginx = {
    +      upstreams = {
    +        ${serviceName} = {
    +          servers = {
    +            "${serviceAddress}:${builtins.toString servicePort}" = { };
    +          };
    +        };
    +      };
    +      virtualHosts = {
    +        "${serviceDomain}" = {
    +          enableACME = true;
    +          forceSSL = true;
    +          acmeRoot = null;
    +          oauth2.enable = false;
    +          locations = {
    +            "/" = {
    +              proxyPass = "http://${serviceName}";
    +            };
    +          };
    +        };
    +      };
    +    };
    +
    +  };
    +}
    +
    +
    +
    +

    3.2.4. Darwin

    @@ -12061,6 +13501,10 @@ When setting up a new machine:
    +- setup the work VPN: + - using the laptop certificate `.pem` as User cert and private key (CA cert: none) + - vpn gateway is found in `nixosConfig.repo.secrets.local.work.vpnGateway` +
    { self, lib, pkgs, config, configName, ... }:
     let
    @@ -12300,8 +13744,8 @@ in
     
    -
    -
    3.2.5.11. microvm-host
    +
    +
    3.2.5.11. microvm-host

    Some standard options that should be set for every microvm host. @@ -12310,25 +13754,26 @@ Some standard options that should be set for every microvm host.

    { lib, config, ... }:
     {
    -  options.swarselmodules.optional.microvmHost = lib.mkEnableOption "optional microvmHost settings";
    -  # imports = [
    -  #   inputs.microvm.nixosModules.host
    -  # ];
    +  options = {
    +    swarselmodules.optional.microvmHost = lib.mkEnableOption "optional microvmHost settings";
    +  };
    +    # imports = [
    +    #   inputs.microvm.nixosModules.host
    +    # ];
     
    -  config = lib.mkIf (config.swarselmodules.optional.microvmHost && config.swarselsystems.withMicroVMs) {
    +  config = lib.mkIf (config.guests != {}) {
     
         microvm = {
           hypervisor = lib.mkDefault "qemu";
         };
       };
    -
     }
     
    -
    -
    3.2.5.12. microvm-guest
    +
    +
    3.2.5.12. microvm-guest

    Some standard options that should be set vor every microvm guest. We set the default @@ -12345,58 +13790,6 @@ Some standard options that should be set vor every microvm guest. We set the def # ]; config = lib.mkIf config.swarselmodules.optional.microvmGuest { - # imports = [ - # inputs.microvm.nixosModules.microvm - - # "${self}/profiles/nixos" - # "${self}/modules/nixos" - # ]; - - boot.kernelParams = [ "systemd.hostname=${config.networking.hostName}" ]; - - node.name = config; - documentation.enable = lib.mkForce false; - - microvm = { - guest.enable = lib.mkForce true; - hypervisor = lib.mkDefault "qemu"; - mem = lib.mkDefault 1024 * 4; - vcpu = lib.mkDefault 4; - optimize.enable = false; - writableStoreOverlay = "/nix/.rw-store"; - - # interfaces = flip lib.mapAttrsToList guestCfg.microvm.interfaces ( - # _: { mac, hostLink, ...}: - # { - # type = "macvtap"; - # id = "vm-${replaceStrings [ ":" ] [ "" ] mac}"; - # inherit mac; - # macvtap = { - # link = hostLink; - # mode = "bridge"; - # }; - # } - # ); - shares = - [ - { - source = "/nix/store"; - mountPoint = "/nix/.ro-store"; - tag = "ro-store"; - proto = "virtiofs"; - } - ]; - }; - # systemd.network.networks = lib.flip lib.concatMapAttrs guestCfg.microvm.interfaces ( - # name: - # { mac, ... }: - # { - # "10-${name}".matchConfig = mkForce { - # MACAddress = mac; - # }; - # } - # ); - }; } @@ -12425,16 +13818,15 @@ in

    -
    -

    3.3.1. Steps to setup/upgrade home-manager only

    +
    +

    3.3.1. Steps to setup/upgrade home-manager only

    Steps to get a home-manager only setup up and running:

    -
    -- (Optional) Install openssh-server
    +
    - (Optional) Install openssh-server
     - Set hostname to the name specified in the home-manager configuration
     - Install nix, either:
       - (if upgrading existing nix) Install nix version matching with version that `nix-plugins` is compiled against: `nix-env --install --file '<nixpkgs>' cacert -I nixpkgs=channel:nixpkgs-unstable --attr nixVersions.nix_x_yy`
    @@ -12446,9 +13838,21 @@ Steps to get a home-manager only setup up and running:
       1) Clone dotfile repo & change into it
       2) `nix --extra-experimental-features 'nix-command flakes' develop`
       3) `home-manager --extra-experimental-features 'nix-command flakes' switch --flake .#$(hostname) --show-trace`
    -
     
    + +- (Optional) Install openssh-server +- Set hostname to the name specified in the home-manager configuration +- Install nix, either: + - (if upgrading existing nix) Install nix version matching with version that `nix-plugins` is compiled against: `nix-env --install --file '' cacert -I nixpkgs=channel:nixpkgs-unstable --attr nixVersions.nix_x_yy` + - (or installing nix freshly): + - Grab the link to the install script of the needed nix version from https://releases.nixos.org/?prefix=nix, e.g. https://releases.nixos.org/nix/nix-2.30.1/install + - `bash <(curl -L https://releases.nixos.org/nix/nix-x-yy-y/install) --daemon` +- add the following to /etc/nix/nix.conf to become a trusted user: `trusted-users = @wheel root swarsel` +- For the first build: + 1) Clone dotfile repo & change into it + 2) `nix --extra-experimental-features 'nix-command flakes' develop` + 3) `home-manager --extra-experimental-features 'nix-command flakes' switch --flake .#$(hostname) --show-trace`
    @@ -12506,7 +13910,7 @@ Again, we adapt nix to our needs, enable the home-manager command f

    -
    { self, lib, pkgs, config, ... }:
    +
    { self, outputs, lib, pkgs, config, ... }:
     let
       inherit (config.swarselsystems) mainUser flakePath isNixos isLinux;
     in
    @@ -12530,7 +13934,7 @@ in
                 };
               in
               ''
    -            plugin-files = ${nix-plugins}/lib/nix/plugins
    +                  plugin-files = ${nix-plugins}/lib/nix/plugins
                 extra-builtins-file = ${self + /nix/extra-builtins.nix}
               '';
             settings = {
    @@ -12555,7 +13959,24 @@ in
             };
           };
     
    -      nixpkgs.overlays = lib.mkIf isNixos (lib.mkForce null);
    +      nixpkgs = lib.mkIf (!isNixos) {
    +        overlays = [
    +          outputs.overlays.default
    +          (final: prev:
    +            let
    +              additions = final: _: import "${self}/pkgs/config" {
    +                inherit self config lib;
    +                pkgs = final;
    +                homeConfig = config;
    +              };
    +            in
    +            additions final prev
    +          )
    +        ];
    +        config = {
    +          allowUnfree = true;
    +        };
    +      };
     
           programs = {
             # home-manager.enable = lib.mkIf (!isNixos) true;
    @@ -12586,7 +14007,7 @@ in
                 buildInputs = [ pkgs.makeWrapper ];
                 paths = [ pkgs.home-manager ];
                 postBuild = ''
    -              wrapProgram $out/bin/home-manager \
    +                  wrapProgram $out/bin/home-manager \
                   --append-flags '--flake ${flakePath}#$(hostname)'
                 '';
               })
    @@ -12695,6 +14116,9 @@ This holds packages that I can use as provided, or with small modifications (as
           simple-scan
           cura-appimage
     
    +      # ssh login using idm
    +      opkssh
    +
           # dict
           (aspellWithDicts (dicts: with dicts; [ de en en-computers en-science ]))
     
    @@ -12878,6 +14302,7 @@ This is just a separate container for derivations defined in 
     
     
    -
    { lib, config, ... }:
    +
    { lib, config, nixosConfig ? config, ... }:
     {
       options.swarselmodules.ssh = lib.mkEnableOption "ssh settings";
       config = lib.mkIf config.swarselmodules.ssh {
    @@ -13013,43 +14436,7 @@ It is very convenient to have SSH aliases in place for machines that I use. This
               controlPath = "~/.ssh/master-%r@%n:%p";
               controlPersist = "no";
             };
    -        "pfsense" = {
    -          hostname = "192.168.1.1";
    -          user = "root";
    -        };
    -        "bakery" = {
    -          hostname = "192.168.1.136";
    -          user = "root";
    -        };
    -        "dgx" = {
    -          hostname = "192.168.48.200";
    -          user = "swarsel";
    -        };
    -        "winters" = {
    -          hostname = "192.168.178.24";
    -          user = "root";
    -        };
    -        "minecraft" = {
    -          hostname = "130.61.119.129";
    -          user = "opc";
    -        };
    -        "milkywell" = {
    -          hostname = "193.122.53.173";
    -          user = "root";
    -        };
    -        "moonside" = {
    -          hostname = "130.61.238.239";
    -          user = "root";
    -        };
    -        "songdiver" = {
    -          hostname = "89.168.100.65";
    -          user = "ubuntu";
    -        };
    -        "pkv" = {
    -          hostname = "46.232.248.161";
    -          user = "root";
    -        };
    -      };
    +      } // nixosConfig.repo.secrets.common.ssh.hosts;
         };
       };
     }
    @@ -13454,8 +14841,8 @@ nix-index provides a way to find out which packages are provided by which deriva
     
    -
    -
    3.3.2.15. nix-your-shell
    +
    +
    3.3.2.15. nix-your-shell
    { lib, config, ... }:
    @@ -13824,11 +15211,23 @@ The theme is handled by stylix.
       config = lib.mkIf config.swarselmodules.kitty {
         programs.kitty = {
           enable = true;
    -      keybindings = { };
    +      keybindings = let
    +        bindWithModifier = lib.mapAttrs' (key: lib.nameValuePair ("ctrl+shift" + key));
    +      in bindWithModifier {
    +        "page_up" = "scroll_page_up";
    +        "up" = "scroll_page_up";
    +        "page_down" = "scroll_page_down";
    +        "down" = "scroll_page_down";
    +        "w" = "no_op";
    +      };
           settings = {
    -        scrollback_lines = 10000;
    +        cursor_blink_interval = 0;
    +        disable_ligatures = "cursor";
             enable_audio_bell = false;
             notify_on_cmd_finish = "always 20";
    +        open_url_with = "xdg-open";
    +        scrollback_lines = 100000;
    +        scrollback_pager_history_size = 512;
           };
         };
       };
    @@ -13907,6 +15306,7 @@ in
                 hg = "history | grep";
                 hmswitch = lib.mkIf (!isNixos) "${lib.getExe pkgs.home-manager} --flake ${flakePath}#$(hostname) switch |& nom";
                 nswitch = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) switch; cd -;";
    +            ntest = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) test; cd -;";
                 nboot = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) boot; cd -;";
                 ndry = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) dry-activate; cd -;";
                 magit = "emacsclient -nc -e \"(magit-status)\"";
    @@ -13918,7 +15318,8 @@ in
                 hotspot = "nmcli connection up local; nmcli device wifi hotspot;";
                 youtube-dl = "yt-dlp";
                 cat-orig = "cat";
    -            cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\"";
    +            # cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\"";
    +            cdr = "source cdr";
                 nix-ldd-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd";
                 nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd";
                 nix-ldd-locate = "nix-locate --minimal --top-level -w ";
    @@ -14025,9 +15426,13 @@ in
     
    -
    -
    3.3.2.25. zellij
    -
    +
    +
    3.3.2.25. zellij
    +
    +
    +
    +
    3.3.2.25.1. Main config
    +
    { self, lib, config, pkgs, ... }:
     {
    @@ -14036,6 +15441,43 @@ in
         programs.zellij = {
           enable = true;
           enableZshIntegration = true;
    +      settings = {
    +        pane_frames = false;
    +        simplified_ui = false;
    +        default_shell = "zsh";
    +        copy_on_select = true;
    +        on_force_close = "detach";
    +        show_startup_tips = false;
    +        support_kitty_keyboard_protocol = true;
    +        default_layout = "swarsel";
    +        layout_dir = "${config.home.homeDirectory}/.config/zellij/layouts";
    +        theme_dir = "${config.home.homeDirectory}/.config/zellij/themes";
    +        scrollback_lines_to_serialize = config.programs.kitty.settings.scrollback_lines;
    +        session_serialization = true;
    +
    +        copy_command =
    +          if pkgs.stdenv.hostPlatform.isLinux then
    +              "wl-copy"
    +          else if pkgs.stdenv.hostPlatform.isDarwin then
    +              "pbcopy"
    +          else
    +              "";
    +        ui.pane_frames = {
    +            rounded_corners = true;
    +            hide_session_name = true;
    +        };
    +        plugins = {
    +          tab-bar.path = "tab-bar";
    +          status-bar.path = "status-bar";
    +          strider.path = "strider";
    +          compact-bar.path = "compact-bar";
    +          # configuration.path = "configuration";
    +          # filepicker.path = "strider";
    +          # plugin-manager.path = "plugin-manager";
    +          # session-manager.path = "session-manager";
    +          # welcome-screen.path = "session-manager";
    +        };
    +      };
         };
     
         home.packages = with pkgs; [
    @@ -14043,8 +15485,8 @@ in
         ];
     
         xdg.configFile = {
    -      "zellij/config.kdl".text = import "${self}/files/zellij/config.kdl.nix" { inherit config; };
    -      "zellij/layouts/default.kdl".text = import "${self}/files/zellij/layouts/default.kdl.nix" { inherit config pkgs; };
    +      # "zellij/config.kdl".text = import "${self}/files/zellij/config.kdl.nix" { inherit config; };
    +      "zellij/layouts/swarsel.kdl".text = import "${self}/files/zellij/layouts/swarsel.kdl.nix" { inherit config pkgs; };
         };
       };
     
    @@ -14053,6 +15495,1159 @@ in
     
    +
    +
    3.3.2.25.2. Keybinds
    +
    +
    +
    { lib, config, ... }:
    +{
    +  config = lib.mkIf config.swarselmodules.zellij {
    +    programs.zellij = {
    +      settings.keybinds = {
    +        _props.clear-defaults = true;
    +
    +        locked = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl g" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        pane = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl p" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "left" ];
    +                _children = [{ MoveFocus._args = [ "left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "down" ];
    +                _children = [{ MoveFocus._args = [ "down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "up" ];
    +                _children = [{ MoveFocus._args = [ "up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "right" ];
    +                _children = [{ MoveFocus._args = [ "right" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "h" ];
    +                _children = [{ MoveFocus._args = [ "left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "j" ];
    +                _children = [{ MoveFocus._args = [ "down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "k" ];
    +                _children = [{ MoveFocus._args = [ "up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "l" ];
    +                _children = [{ MoveFocus._args = [ "right" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "d" ];
    +                _children = [
    +                  { NewPane._args = [ "down" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "e" ];
    +                _children = [
    +                  { TogglePaneEmbedOrFloating = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "f" ];
    +                _children = [
    +                  { ToggleFocusFullscreen = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "n" ];
    +                _children = [
    +                  { NewPane = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "p" ];
    +                _children = [{ SwitchFocus = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "f12" ];
    +                _children = [
    +                  { ToggleFloatingPanes = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +          ];
    +        };
    +
    +        tab = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl t" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "left" ];
    +                _children = [{ GoToPreviousTab = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "down" ];
    +                _children = [{ GoToNextTab = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "up" ];
    +                _children = [{ GoToPreviousTab = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "right" ];
    +                _children = [{ GoToNextTab = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "1" ];
    +                _children = [
    +                  { GoToTab._args = [ 1 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "2" ];
    +                _children = [
    +                  { GoToTab._args = [ 2 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "3" ];
    +                _children = [
    +                  { GoToTab._args = [ 3 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "4" ];
    +                _children = [
    +                  { GoToTab._args = [ 4 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "5" ];
    +                _children = [
    +                  { GoToTab._args = [ 5 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "6" ];
    +                _children = [
    +                  { GoToTab._args = [ 6 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "7" ];
    +                _children = [
    +                  { GoToTab._args = [ 7 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "8" ];
    +                _children = [
    +                  { GoToTab._args = [ 8 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "9" ];
    +                _children = [
    +                  { GoToTab._args = [ 9 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "h" ];
    +                _children = [{ GoToPreviousTab = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "j" ];
    +                _children = [{ GoToNextTab = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "k" ];
    +                _children = [{ GoToPreviousTab = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "l" ];
    +                _children = [{ GoToNextTab = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "n" ];
    +                _children = [
    +                  { NewTab = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "r" ];
    +                _children = [
    +                  { SwitchToMode._args = [ "renametab" ]; }
    +                  { TabNameInput._args = [ 0 ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "s" ];
    +                _children = [
    +                  { ToggleActiveSyncTab = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "x" ];
    +                _children = [
    +                  { CloseTab = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +          ];
    +        };
    +
    +        resize = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl n" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "left" ];
    +                _children = [{ Resize._args = [ "Increase left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "down" ];
    +                _children = [{ Resize._args = [ "Increase down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "up" ];
    +                _children = [{ Resize._args = [ "Increase up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "right" ];
    +                _children = [{ Resize._args = [ "Increase right" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "+" ];
    +                _children = [{ Resize._args = [ "Increase" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "-" ];
    +                _children = [{ Resize._args = [ "Decrease" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "=" ];
    +                _children = [{ Resize._args = [ "Increase" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "H" ];
    +                _children = [{ Resize._args = [ "Decrease left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "J" ];
    +                _children = [{ Resize._args = [ "Decrease down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "K" ];
    +                _children = [{ Resize._args = [ "Decrease up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "L" ];
    +                _children = [{ Resize._args = [ "Decrease right" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "h" ];
    +                _children = [{ Resize._args = [ "Increase left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "j" ];
    +                _children = [{ Resize._args = [ "Increase down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "k" ];
    +                _children = [{ Resize._args = [ "Increase up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "l" ];
    +                _children = [{ Resize._args = [ "Increase right" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        move = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl h" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "left" ];
    +                _children = [{ MovePane._args = [ "left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "down" ];
    +                _children = [{ MovePane._args = [ "down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "up" ];
    +                _children = [{ MovePane._args = [ "up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "right" ];
    +                _children = [{ MovePane._args = [ "right" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "h" ];
    +                _children = [{ MovePane._args = [ "left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "j" ];
    +                _children = [{ MovePane._args = [ "down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "k" ];
    +                _children = [{ MovePane._args = [ "up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "l" ];
    +                _children = [{ MovePane._args = [ "right" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        scroll = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "e" ];
    +                _children = [
    +                  { EditScrollback = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "s" ];
    +                _children = [
    +                  { SwitchToMode._args = [ "entersearch" ]; }
    +                  { SearchInput._args = [ 0 ]; }
    +                ];
    +              };
    +            }
    +          ];
    +        };
    +
    +        search = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "c" ];
    +                _children = [{ SearchToggleOption._args = [ "CaseSensitivity" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "n" ];
    +                _children = [{ Search._args = [ "down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "o" ];
    +                _children = [{ SearchToggleOption._args = [ "WholeWord" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "p" ];
    +                _children = [{ Search._args = [ "up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "w" ];
    +                _children = [{ SearchToggleOption._args = [ "Wrap" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        session = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl o" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "c" ];
    +                _children = [
    +                  {
    +                    LaunchOrFocusPlugin._args = [ "configuration" ];
    +                    LaunchOrFocusPlugin._children = [
    +                      { floating._args = [ true ]; }
    +                      { move_to_focused_tab._args = [ true ]; }
    +                    ];
    +                  }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "p" ];
    +                _children = [
    +                  {
    +                    LaunchOrFocusPlugin._args = [ "plugin-manager" ];
    +                    LaunchOrFocusPlugin._children = [
    +                      { floating._args = [ true ]; }
    +                      { move_to_focused_tab._args = [ true ]; }
    +                    ];
    +                  }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "w" ];
    +                _children = [
    +                  {
    +                    LaunchOrFocusPlugin._args = [ "session-manager" ];
    +                    LaunchOrFocusPlugin._children = [
    +                      { floating._args = [ true ]; }
    +                      { move_to_focused_tab._args = [ true ]; }
    +                    ];
    +                  }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"locked\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Alt left" ];
    +                _children = [{ MoveFocusOrTab._args = [ "left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt down" ];
    +                _children = [{ MoveFocus._args = [ "down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt up" ];
    +                _children = [{ MoveFocus._args = [ "up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt right" ];
    +                _children = [{ MoveFocusOrTab._args = [ "right" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt +" ];
    +                _children = [{ Resize._args = [ "Increase" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt -" ];
    +                _children = [{ Resize._args = [ "Decrease" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt =" ];
    +                _children = [{ Resize._args = [ "Increase" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt r" ];
    +                _children = [
    +                  {
    +                    WriteChars._args = [ "source cdr" ];
    +                  }
    +                  {
    +                    WriteChars._args = [ "\n" ];
    +                  }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt f" ];
    +                _children = [{ ToggleFloatingPanes = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Ctrl g" ];
    +                _children = [{ SwitchToMode._args = [ "locked" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt h" ];
    +                _children = [{ MoveFocusOrTab._args = [ "left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt i" ];
    +                _children = [{ MoveTab._args = [ "left" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt j" ];
    +                _children = [{ MoveFocus._args = [ "down" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt k" ];
    +                _children = [{ MoveFocus._args = [ "up" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt p" ];
    +                _children = [{ NewPane = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Alt n" ];
    +                _children = [{ NewTab = { }; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"locked\" \"move\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl h" ];
    +                _children = [{ SwitchToMode._args = [ "move" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"locked\" \"session\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl o" ];
    +                _children = [{ SwitchToMode._args = [ "session" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"locked\" \"scroll\" \"search\" \"tmux\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl b" ];
    +                _children = [{ SwitchToMode._args = [ "tmux" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"locked\" \"scroll\" \"search\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl s" ];
    +                _children = [{ SwitchToMode._args = [ "scroll" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"locked\" \"tab\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl t" ];
    +                _children = [{ SwitchToMode._args = [ "tab" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"locked\" \"pane\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl p" ];
    +                _children = [{ SwitchToMode._args = [ "pane" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"locked\" \"resize\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl n" ];
    +                _children = [{ SwitchToMode._args = [ "resize" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"normal\" \"locked\" \"entersearch\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "enter" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_except \"normal\" \"locked\" \"entersearch\" \"renametab\" \"renamepane\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "esc" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_among \"pane\" \"tmux\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "x" ];
    +                _children = [
    +                  { CloseFocus = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_among \"scroll\" \"search\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "PageDown" ];
    +                _children = [{ PageScrollDown = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "PageUp" ];
    +                _children = [{ PageScrollUp = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "left" ];
    +                _children = [{ PageScrollUp = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "down" ];
    +                _children = [{ ScrollDown = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "up" ];
    +                _children = [{ ScrollUp = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "right" ];
    +                _children = [{ PageScrollDown = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Ctrl b" ];
    +                _children = [{ PageScrollUp = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Ctrl c" ];
    +                _children = [
    +                  { ScrollToBottom = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "d" ];
    +                _children = [{ HalfPageScrollDown = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Ctrl f" ];
    +                _children = [{ PageScrollDown = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "h" ];
    +                _children = [{ PageScrollUp = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "j" ];
    +                _children = [{ ScrollDown = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "k" ];
    +                _children = [{ ScrollUp = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "l" ];
    +                _children = [{ PageScrollDown = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Ctrl s" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "u" ];
    +                _children = [{ HalfPageScrollUp = { }; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        entersearch = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl c" ];
    +                _children = [{ SwitchToMode._args = [ "scroll" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "esc" ];
    +                _children = [{ SwitchToMode._args = [ "scroll" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "enter" ];
    +                _children = [{ SwitchToMode._args = [ "search" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        renametab = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "esc" ];
    +                _children = [
    +                  { UndoRenameTab = { }; }
    +                  { SwitchToMode._args = [ "tab" ]; }
    +                ];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_among \"renametab\" \"renamepane\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "Ctrl c" ];
    +                _children = [{ SwitchToMode._args = [ "normal" ]; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        renamepane = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "esc" ];
    +                _children = [
    +                  { UndoRenamePane = { }; }
    +                  { SwitchToMode._args = [ "pane" ]; }
    +                ];
    +              };
    +            }
    +          ];
    +        };
    +
    +        "shared_among \"session\" \"tmux\"" = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "d" ];
    +                _children = [{ Detach = { }; }];
    +              };
    +            }
    +          ];
    +        };
    +
    +        tmux = {
    +          _children = [
    +            {
    +              bind = {
    +                _args = [ "left" ];
    +                _children = [
    +                  { MoveFocus._args = [ "left" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "down" ];
    +                _children = [
    +                  { MoveFocus._args = [ "down" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "up" ];
    +                _children = [
    +                  { MoveFocus._args = [ "up" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "right" ];
    +                _children = [
    +                  { MoveFocus._args = [ "right" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "space" ];
    +                _children = [{ NextSwapLayout = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "\"" ];
    +                _children = [
    +                  { NewPane._args = [ "down" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "%" ];
    +                _children = [
    +                  { NewPane._args = [ "right" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "," ];
    +                _children = [{ SwitchToMode._args = [ "renametab" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "[" ];
    +                _children = [{ SwitchToMode._args = [ "scroll" ]; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "Ctrl b" ];
    +                _children = [
    +                  { Write._args = [ 2 ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "c" ];
    +                _children = [
    +                  { NewTab = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "h" ];
    +                _children = [
    +                  { MoveFocus._args = [ "left" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "j" ];
    +                _children = [
    +                  { MoveFocus._args = [ "down" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "k" ];
    +                _children = [
    +                  { MoveFocus._args = [ "up" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "l" ];
    +                _children = [
    +                  { MoveFocus._args = [ "right" ]; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "n" ];
    +                _children = [
    +                  { GoToNextTab = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "o" ];
    +                _children = [{ FocusNextPane = { }; }];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "p" ];
    +                _children = [
    +                  { GoToPreviousTab = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +            {
    +              bind = {
    +                _args = [ "z" ];
    +                _children = [
    +                  { ToggleFocusFullscreen = { }; }
    +                  { SwitchToMode._args = [ "normal" ]; }
    +                ];
    +              };
    +            }
    +          ];
    +        };
    +      };
    +    };
    +  };
    +
    +}
    +
    +
    +
    +
    +
    3.3.2.26. tmux
    @@ -14380,7 +16975,7 @@ Lastly, I am defining some more packages here that the parser has problems findi
    { self, lib, config, pkgs, globals, inputs, ... }:
     let
    -  inherit (config.swarselsystems) homeDir isPublic isNixos;
    +  inherit (config.swarselsystems) homeDir mainUser isPublic isNixos;
       inherit (config.repo.secrets.common.emacs) radicaleUser;
     in
     {
    @@ -14389,6 +16984,31 @@ in
         # needed for elfeed
         # enable emacs overlay for bleeding edge features
         # also read init.el file and install use-package packages
    +
    +    home.activation.setupEmacsOrgFiles =
    +      lib.hm.dag.entryAfter [ "writeBoundary" ] ''
    +        set -eu
    +
    +        if [ ! -d ${homeDir}/Org ]; then
    +          ${pkgs.coreutils}/bin/install -d -m 0755 ${homeDir}/Org
    +          ${pkgs.coreutils}/bin/chown ${mainUser}:syncthing ${homeDir}/Org
    +        fi
    +
    +        # create dummy files to make Emacs calendar work
    +        # these have low modified dates and should be marked as sync-conflicts
    +        for file in "Tasks" "Archive" "Journal"; do
    +          if [ ! -f ${homeDir}/Org/"$file".org ]; then
    +            ${pkgs.coreutils}/bin/touch --time=access --time=modify -t 197001010000.00 ${homeDir}/Org/"$file".org
    +            ${pkgs.coreutils}/bin/chown ${mainUser}:syncthing ${homeDir}/Org/"$file".org
    +          fi
    +        done
    +
    +        # when the configuration is build again, these sync-conflicts will be cleaned up
    +        for file in $(find ${homeDir}/Org/ -name "*sync-conflict*"); do
    +          ${pkgs.coreutils}/bin/rm "$file"
    +        done
    +      '';
    +
         programs.emacs = {
           enable = true;
           package = pkgs.emacsWithPackagesFromUsePackage {
    @@ -15180,8 +17800,8 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
     
    -
    -
    3.3.2.31.6. blueman-applet
    +
    +
    3.3.2.31.6. blueman-applet
    { lib, config, ... }:
    @@ -15195,8 +17815,8 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
     
    -
    -
    3.3.2.31.7. network-manager-applet
    +
    +
    3.3.2.31.7. network-manager-applet
    { lib, config, ... }:
    @@ -15211,8 +17831,8 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
     
    -
    -
    3.3.2.31.8. obsidian service for tray
    +
    +
    3.3.2.31.8. obsidian service for tray
    { lib, config, ... }:
    @@ -15246,8 +17866,8 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
     
    -
    -
    3.3.2.31.9. anki service for tray
    +
    +
    3.3.2.31.9. anki service for tray

    Sets up a systemd user service for anki that does not stall the shutdown process. Note that the outcommented ExecStart does not work because the home-manager anki package builds a separate anki package that - I think - cannot be referenced as no such expression exists in the module. @@ -15294,8 +17914,8 @@ Sets up a systemd user service for anki that does not stall the shutdown process

    -
    -
    3.3.2.31.10. element service for tray
    +
    +
    3.3.2.31.10. element service for tray
    { lib, config, pkgs, ... }:
    @@ -15329,8 +17949,8 @@ Sets up a systemd user service for anki that does not stall the shutdown process
     
    -
    -
    3.3.2.31.11. vesktop service for tray
    +
    +
    3.3.2.31.11. vesktop service for tray
    { lib, config, pkgs, ... }:
    @@ -15359,6 +17979,134 @@ Sets up a systemd user service for anki that does not stall the shutdown process
         };
       };
     
    +}
    +
    +
    +
    +
    +
    +
    3.3.2.31.12. syncthing service for tray
    +
    +
    +
    { lib, config, pkgs, ... }:
    +{
    +  options.swarselmodules.syncthing-tray = lib.mkEnableOption "enable syncthing applet for tray";
    +  config = lib.mkIf config.swarselmodules.syncthing-tray {
    +
    +    home.activation.setupSyncthingIni =
    +      let
    +        syncthingApiEnvVarName = "SYNCTHING_API_KEY";
    +        syncthingIni = {
    +          file = "${config.home.homeDirectory}/.config/syncthingtray.ini";
    +          content = ''
    +            [General]
    +            v=2.0.2
    +
    +            [qt]
    +            customfont=false
    +            customicontheme=false
    +            customlocale=false
    +            custompalette=false
    +            customstylesheet=false
    +            customwidgetstyle=false
    +            font="Cantarell,11,-1,5,400,0,0,0,0,0,0,0,0,0,0,1"
    +            icontheme=hicolor
    +            iconthemepath=
    +            locale=en_US
    +            palette="@Variant(\0\0\0\x44\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff  jj\x86\x86\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff\xff\xff\xff\xff\xff\xff\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff\0\0\0\0\0\0\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\xc0\xc0nn\xce\xce\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff  jj\x86\x86\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\xff\xff\xff\xff\xff\xff\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff\0\0\0\0\0\0\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\x66\x66\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\xc0\xc0nn\xce\xce\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff  jj\x86\x86\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff\xff\xff\xff\xff\xff\xff\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff\0\0\0\0\0\0\0\0\x1\x2\xff\xffP\x14\xff\xff\x65\x65\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\xc0\xc0nn\xce\xce\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0)"
    +            plugindir=
    +            stylesheetpath=
    +            trpath=
    +            widgetstyle=
    +
    +            [startup]
    +            considerForReconnect=false
    +            considerLauncherForReconnect=false
    +            showButton=false
    +            showLauncherButton=false
    +            stopOnMetered=false
    +            stopServiceOnMetered=false
    +            syncthingArgs="serve --no-browser --logflags=3"
    +            syncthingAutostart=false
    +            syncthingPath=syncthing
    +            syncthingUnit=syncthing.service
    +            systemUnit=false
    +            useLibSyncthing=false
    +
    +            [tray]
    +            connections\1\apiKey=@ByteArray(''$${syncthingApiEnvVarName})
    +            connections\1\authEnabled=falsex
    +            connections\1\autoConnect=true
    +            connections\1\devStatsPollInterval=60000
    +            connections\1\diskEventLimit=200
    +            connections\1\errorsPollInterval=30000
    +            connections\1\httpsCertPath=${config.home.homeDirectory}/.config/syncthing/https-cert.pem
    +            connections\1\label=Primary instance
    +            connections\1\localPath=
    +            connections\1\longPollingTimeout=0
    +            connections\1\password=
    +            connections\1\pauseOnMetered=false
    +            connections\1\reconnectInterval=30000
    +            connections\1\requestTimeout=0
    +            connections\1\statusComputionFlags=123
    +            connections\1\syncthingUrl=http://${config.services.syncthing.guiAddress}
    +            connections\1\trafficPollInterval=5000
    +            connections\1\userName=
    +            connections\size=1
    +            dbusNotifications=true
    +            distinguishTrayIcons=false
    +            frameStyle=16
    +            ignoreInavailabilityAfterStart=15
    +            notifyOnDisconnect=true
    +            notifyOnErrors=true
    +            notifyOnLauncherErrors=true
    +            notifyOnLocalSyncComplete=false
    +            notifyOnNewDeviceConnects=false
    +            notifyOnNewDirectoryShared=false
    +            notifyOnRemoteSyncComplete=false
    +            positioning\assumedIconPos=@Point(0 0)
    +            positioning\useAssumedIconPosition=false
    +            positioning\useCursorPos=true
    +            preferIconsFromTheme=false
    +            showDownloads=false
    +            showSyncthingNotifications=true
    +            showTabTexts=true
    +            showTraffic=true
    +            statusIcons="#ff26b6db,#ff0882c8,#ffffffff;#ffdb3c26,#ffc80828,#ffffffff;#ffc9ce3b,#ffebb83b,#ffffffff;#ff2d9d69,#ff2d9d69,#ffffffff;#ff26b6db,#ff0882c8,#ffffffff;#ff26b6db,#ff0882c8,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff"
    +            statusIconsRenderSize=@Size(32 32)
    +            statusIconsStrokeWidth=0
    +            tabPos=1
    +            trayIcons="#ff26b6db,#ff0882c8,#ffffffff;#ffdb3c26,#ffc80828,#ffffffff;#ffc9ce3b,#ffebb83b,#ffffffff;#ff2d9d69,#ff2d9d69,#ffffffff;#ff26b6db,#ff0882c8,#ffffffff;#ff26b6db,#ff0882c8,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff"
    +            trayIconsRenderSize=@Size(32 32)
    +            trayIconsStrokeWidth=0
    +            trayMenuSize=@Size(575 475)
    +            usePaletteForStatusIcons=false
    +            usePaletteForTrayIcons=false
    +            windowType=0
    +
    +            [webview]
    +            customCommand=
    +            disabled=false
    +            mode=0
    +
    +          '';
    +        };
    +      in
    +      lib.hm.dag.entryAfter [ "writeBoundary" ] ''
    +        set -eu
    +
    +        if [ ! -f ${syncthingIni.file} ]; then
    +        cat >${syncthingIni.file} <<'EOF'
    +        ${syncthingIni.content}
    +        EOF
    +        export ${syncthingApiEnvVarName}=$(cat /run/syncthing-init/api_key)
    +        ${lib.getExe pkgs.envsubst} -i ${syncthingIni.file} -o ${syncthingIni.file}
    +        unset ${syncthingApiEnvVarName}
    +        fi
    +      '';
    +
    +  };
    +
     }
     
    @@ -15504,83 +18252,83 @@ Currently, I am too lazy to explain every option here, but most of it is very se in lib.recursiveUpdate { - "${modifier}+q" = "kill"; - "${modifier}+f" = "exec firefox"; - "${modifier}+Shift+f" = "exec swaymsg fullscreen"; - "${modifier}+Space" = "exec fuzzel"; - "${modifier}+Shift+Space" = "floating toggle"; - "${modifier}+e" = "exec emacsclient -nquc -a emacs -e \"(dashboard-open)\""; - "${modifier}+m" = "exec swaymsg workspace back_and_forth"; - "${modifier}+a" = "exec swarselcheck -s"; - "${modifier}+x" = "exec swarselcheck -k"; - "${modifier}+d" = "exec swarselcheck -d"; - "${modifier}+w" = "exec swarselcheck -e"; - "${modifier}+Shift+t" = "exec opacitytoggle"; - "${modifier}+Shift+F12" = "move scratchpad"; - "${modifier}+F12" = "scratchpad show"; - "${modifier}+Shift+c" = "exec qalculate-gtk"; - "${modifier}+c" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-org-capture)'"; - "${modifier}+t" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-org-agenda)'"; - "${modifier}+Shift+m" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-mu4e)'"; - "${modifier}+Shift+a" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-swarsel/open-calendar)'"; - "${modifier}+p" = "exec pass-fuzzel"; - "${modifier}+o" = "exec pass-fuzzel --otp"; - "${modifier}+Shift+p" = "exec pass-fuzzel --type"; - "${modifier}+Shift+o" = "exec pass-fuzzel --otp --type"; - "${modifier}+Ctrl+p" = "exec 1password --quick-acces"; - # "${modifier}+Escape" = "mode $exit"; - "${modifier}+Shift+Escape" = "exec kitty -o confirm_os_window_close=0 btm"; - "${modifier}+Escape" = "exec wlogout"; - "${modifier}+h" = "exec hyprpicker | wl-copy"; - "${modifier}+s" = "exec grim -g \"$(slurp)\" -t png - | wl-copy -t image/png"; - "${modifier}+Shift+s" = "exec slurp | grim -g - Pictures/Screenshots/$(date +'screenshot_%Y-%m-%d-%H%M%S.png')"; - "${modifier}+Shift+v" = "exec wf-recorder -g '$(slurp -f %o -or)' -f ~/Videos/screenrecord_$(date +%Y-%m-%d-%H%M%S).mkv"; - "${modifier}+1" = "workspace 1:一"; - "${modifier}+Shift+1" = "move container to workspace 1:一"; - "${modifier}+2" = "workspace 2:二"; - "${modifier}+Shift+2" = "move container to workspace 2:二"; - "${modifier}+3" = "workspace 3:三"; - "${modifier}+Shift+3" = "move container to workspace 3:三"; - "${modifier}+4" = "workspace 4:四"; - "${modifier}+Shift+4" = "move container to workspace 4:四"; - "${modifier}+5" = "workspace 5:五"; - "${modifier}+Shift+5" = "move container to workspace 5:五"; - "${modifier}+6" = "workspace 6:六"; - "${modifier}+Shift+6" = "move container to workspace 6:六"; - "${modifier}+7" = "workspace 7:七"; - "${modifier}+Shift+7" = "move container to workspace 7:七"; - "${modifier}+8" = "workspace 8:八"; - "${modifier}+Shift+8" = "move container to workspace 8:八"; - "${modifier}+9" = "workspace 9:九"; - "${modifier}+Shift+9" = "move container to workspace 9:九"; "${modifier}+0" = "workspace 10:十"; - "${modifier}+Shift+0" = "move container to workspace 10:十"; - "${modifier}+Ctrl+m" = "workspace 11:M"; - "${modifier}+Ctrl+Shift+m" = "move container to workspace 11:M"; - "${modifier}+Ctrl+s" = "workspace 12:S"; - "${modifier}+Ctrl+Shift+s" = "move container to workspace 12:S"; - "${modifier}+Ctrl+e" = "workspace 13:E"; + "${modifier}+1" = "workspace 1:一"; + "${modifier}+2" = "workspace 2:二"; + "${modifier}+3" = "workspace 3:三"; + "${modifier}+4" = "workspace 4:四"; + "${modifier}+5" = "workspace 5:五"; + "${modifier}+6" = "workspace 6:六"; + "${modifier}+7" = "workspace 7:七"; + "${modifier}+8" = "workspace 8:八"; + "${modifier}+9" = "workspace 9:九"; + "${modifier}+Ctrl+Shift+c" = "reload"; "${modifier}+Ctrl+Shift+e" = "move container to workspace 13:E"; - "${modifier}+Ctrl+t" = "workspace 14:T"; - "${modifier}+Ctrl+Shift+t" = "move container to workspace 14:T"; - "${modifier}+Ctrl+l" = "workspace 15:L"; - "${modifier}+Ctrl+Shift+l" = "move container to workspace 15:L"; - "${modifier}+Ctrl+f" = "workspace 16:F"; "${modifier}+Ctrl+Shift+f" = "move container to workspace 16:F"; - "${modifier}+Left" = "focus left"; - "${modifier}+Right" = "focus right"; + "${modifier}+Ctrl+Shift+l" = "move container to workspace 15:L"; + "${modifier}+Ctrl+Shift+m" = "move container to workspace 11:M"; + "${modifier}+Ctrl+Shift+r" = "exec swarsel-displaypower"; + "${modifier}+Ctrl+Shift+s" = "move container to workspace 12:S"; + "${modifier}+Ctrl+Shift+t" = "move container to workspace 14:T"; + "${modifier}+Ctrl+e" = "workspace 13:E"; + "${modifier}+Ctrl+f" = "workspace 16:F"; + "${modifier}+Ctrl+l" = "workspace 15:L"; + "${modifier}+Ctrl+m" = "workspace 11:M"; + "${modifier}+Ctrl+p" = "exec 1password --quick-acces"; + "${modifier}+Ctrl+s" = "workspace 12:S"; + "${modifier}+Ctrl+t" = "workspace 14:T"; "${modifier}+Down" = "focus down"; - "${modifier}+Up" = "focus up"; + "${modifier}+Escape" = "exec wlogout"; + "${modifier}+F12" = "scratchpad show"; + "${modifier}+Left" = "focus left"; + "${modifier}+Return" = "exec swarselzellij"; + "${modifier}+Right" = "focus right"; + "${modifier}+Shift+0" = "move container to workspace 10:十"; + "${modifier}+Shift+1" = "move container to workspace 1:一"; + "${modifier}+Shift+2" = "move container to workspace 2:二"; + "${modifier}+Shift+3" = "move container to workspace 3:三"; + "${modifier}+Shift+4" = "move container to workspace 4:四"; + "${modifier}+Shift+5" = "move container to workspace 5:五"; + "${modifier}+Shift+6" = "move container to workspace 6:六"; + "${modifier}+Shift+7" = "move container to workspace 7:七"; + "${modifier}+Shift+8" = "move container to workspace 8:八"; + "${modifier}+Shift+9" = "move container to workspace 9:九"; + "${modifier}+Shift+Down" = "move down 40px"; + "${modifier}+Shift+Escape" = "exec kitty -o confirm_os_window_close=0 btm"; + "${modifier}+Shift+F12" = "move scratchpad"; "${modifier}+Shift+Left" = "move left 40px"; "${modifier}+Shift+Right" = "move right 40px"; - "${modifier}+Shift+Down" = "move down 40px"; + "${modifier}+Shift+Space" = "floating toggle"; "${modifier}+Shift+Up" = "move up 40px"; - "${modifier}+Ctrl+Shift+c" = "reload"; - "${modifier}+Ctrl+Shift+r" = "exec swarsel-displaypower"; + "${modifier}+Shift+a" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-swarsel/open-calendar)'"; + "${modifier}+Shift+c" = "exec qalculate-gtk"; "${modifier}+Shift+e" = "exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'"; + "${modifier}+Shift+f" = "exec swaymsg fullscreen"; + "${modifier}+Shift+m" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-mu4e)'"; + "${modifier}+Shift+o" = "exec pass-fuzzel --otp --type"; + "${modifier}+Shift+p" = "exec pass-fuzzel --type"; + "${modifier}+Shift+s" = "exec slurp | grim -g - Pictures/Screenshots/$(date +'screenshot_%Y-%m-%d-%H%M%S.png')"; + "${modifier}+Shift+t" = "exec opacitytoggle"; + "${modifier}+Shift+v" = "exec wf-recorder -g '$(slurp -f %o -or)' -f ~/Videos/screenrecord_$(date +%Y-%m-%d-%H%M%S).mkv"; + "${modifier}+Space" = "exec fuzzel"; + "${modifier}+Up" = "focus up"; + "${modifier}+a" = "exec swarselcheck -s"; + "${modifier}+c" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-org-capture)'"; + "${modifier}+d" = "exec swarselcheck -d"; + "${modifier}+e" = "exec emacsclient -nquc -a emacs -e \"(dashboard-open)\""; + "${modifier}+f" = "exec firefox"; + "${modifier}+h" = "exec hyprpicker | wl-copy"; + "${modifier}+m" = "exec swaymsg workspace back_and_forth"; + "${modifier}+o" = "exec pass-fuzzel --otp"; + "${modifier}+p" = "exec pass-fuzzel"; + "${modifier}+q" = "kill"; "${modifier}+r" = "mode resize"; + "${modifier}+s" = "exec grim -g \"$(slurp)\" -t png - | wl-copy -t image/png"; + "${modifier}+t" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-org-agenda)'"; + "${modifier}+w" = "exec swarselcheck -e"; + "${modifier}+x" = "exec swarselcheck -k"; + # "${modifier}+Escape" = "mode $exit"; # "${modifier}+Return" = "exec kitty"; - "${modifier}+Return" = "exec swarselzellij"; "XF86AudioRaiseVolume" = "exec swayosd-client --output-volume raise"; "XF86AudioLowerVolume" = "exec swayosd-client --output-volume lower"; "XF86AudioMute" = "exec swayosd-client --output-volume mute-toggle"; @@ -16017,6 +18765,12 @@ Currently, I am too lazy to explain every option here, but most of it is very se }; }; + } // { + programs.niri = lib.mkIf (!config.swarselmodules.niri) { + package = null; + config = null; + settings = null; + }; }; } @@ -16068,7 +18822,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se exec = [ "${pkgs.swaybg}/bin/swaybg --output '${config.swarselsystems.sharescreen}' --image ${config.swarselsystems.wallpaper} --mode ${config.stylix.imageScalingMode}" ]; outputs = [ { - criteria = "eDP-2"; + criteria = config.swarselsystems.sharescreen; status = "enable"; scale = 1.0; } @@ -16154,6 +18908,13 @@ When setting up a new machine:
    +- setup gpgsm for signing of mails using S/MIME: + - `gpgsm --import ~/Certificates/.p12` + - `gpgsm --import ~/Certificates/harica-root.pem` + - `gpgsm --import ~/Certificates/harica-intermediate.pem` + - `gpgsm --list-keys --with-validation "HARICA Client RSA Root CA 2021"` + - trust the certificate and set passphrase +
    { self, lib, config, pkgs, ... }:
     let
    @@ -16194,9 +18955,15 @@ in
         };
     
         # assure correct permissions
    -    systemd.user.tmpfiles.rules = [
    -      "d ${homeDir}/.gnupg 700 ${mainUser} users"
    -    ];
    +    systemd.user.tmpfiles.settings."30-gpgagent".rules = {
    +      "${homeDir}/.gnupg" = {
    +        d = {
    +          group = "users";
    +          user = mainUser;
    +          mode = "0700";
    +        };
    +      };
    +    };
       };
     
     }
    @@ -16261,8 +19028,8 @@ in
     
    -
    -
    3.3.2.38. Obsidian
    +
    +
    3.3.2.38. Obsidian
    { lib, config, pkgs, nixosConfig ? config, ... }:
    @@ -16422,8 +19189,8 @@ in
     
    -
    -
    3.3.2.39. Anki
    +
    +
    3.3.2.39. Anki
    { lib, config, pkgs, globals, inputs, nixosConfig ? config, ... }:
    @@ -16496,8 +19263,8 @@ in
     
    -
    -
    3.3.2.40. Element-desktop
    +
    +
    3.3.2.40. Element-desktop
    { lib, config, ... }:
    @@ -16533,8 +19300,8 @@ in
     
    -
    -
    3.3.2.41. Hexchat
    +
    +
    3.3.2.41. Hexchat
    { lib, config, nixosConfig ? config, ... }:
    @@ -16558,8 +19325,8 @@ in
     
    -
    -
    3.3.2.42. obs-studio
    +
    +
    3.3.2.42. obs-studio
    { lib, config, ... }:
    @@ -16579,8 +19346,8 @@ in
     
    -
    -
    3.3.2.43. spotify-player
    +
    +
    3.3.2.43. spotify-player
    { lib, config, ... }:
    @@ -16600,8 +19367,8 @@ in
     
    -
    -
    3.3.2.44. vesktop
    +
    +
    3.3.2.44. vesktop
    { lib, pkgs, config, ... }:
    @@ -16688,8 +19455,8 @@ in
     
    -
    -
    3.3.2.45. batsignal
    +
    +
    3.3.2.45. batsignal
    { lib, config, ... }:
    @@ -16721,8 +19488,8 @@ in
     
    -
    -
    3.3.2.46. autotiling
    +
    +
    3.3.2.46. autotiling
    { lib, config, ... }:
    @@ -16743,8 +19510,8 @@ in
     
    -
    -
    3.3.2.47. swayidle
    +
    +
    3.3.2.47. swayidle
    { lib, config, pkgs, ... }:
    @@ -16785,8 +19552,8 @@ in
     
    -
    -
    3.3.2.48. swaylock
    +
    +
    3.3.2.48. swaylock
    { lib, config, pkgs, ... }:
    @@ -16809,6 +19576,44 @@ in
         };
       };
     
    +}
    +
    +
    +
    +
    +
    +
    3.3.2.49. opkssh
    +
    +
    +
    { lib, config, ... }:
    +let
    +  moduleName = "opkssh";
    +in
    +{
    +  options.swarselmodules.${moduleName} = lib.mkEnableOption "enable ${moduleName} and settings";
    +  config = lib.mkIf config.swarselmodules.${moduleName} {
    +    programs.${moduleName} = {
    +      enable = true;
    +      settings = {
    +        default_provider = "kanidm";
    +
    +        providers = [
    +          {
    +            alias = "kanidm";
    +            issuer = "https://sso.swarsel.win/oauth2/openid/opkssh";
    +            client_id = "opkssh";
    +            scopes = "openid email profile";
    +            redirect_uris = [
    +              "http://localhost:3000/login-callback"
    +              "http://localhost:10001/login-callback"
    +              "http://localhost:11110/login-callback"
    +            ];
    +          }
    +        ];
    +      };
    +    };
    +  };
    +
     }
     
    @@ -17009,32 +19814,44 @@ When setting up a new machine:
    +- setup pizauth for microsoft mail sync (account names are possibly `uni` and `work`): + - `pizauth auth ` + - `pizauth dump > ~/.pizauth.state` +
    -
    { self, config, pkgs, lib, vars, nixosConfig ? config, ... }:
    +
    { self, inputs, config, pkgs, lib, vars, nixosConfig ? config, ... }:
     let
    -  inherit (config.swarselsystems) homeDir;
    +  inherit (config.swarselsystems) homeDir mainUser;
       inherit (nixosConfig.repo.secrets.local.mail) allMailAddresses;
       inherit (nixosConfig.repo.secrets.local.work) mailAddress;
    +
    +  certsSopsFile = self + /secrets/certs/secrets.yaml;
     in
     {
       options.swarselmodules.optional.work = lib.mkEnableOption "optional work settings";
       config = lib.mkIf config.swarselmodules.optional.work
    -    {
    -      home.packages = with pkgs; [
    -        stable.teams-for-linux
    -        shellcheck
    -        dig
    -        docker
    -        postman
    -        # rclone
    -        libguestfs-with-appliance
    -        prometheus.cli
    -        tigervnc
    -        # openstackclient
    +    ({
    +      home = {
    +        packages = with pkgs; [
    +          stable.teams-for-linux
    +          shellcheck
    +          dig
    +          docker
    +          postman
    +          # rclone
    +          libguestfs-with-appliance
    +          prometheus.cli
    +          tigervnc
    +          # openstackclient
     
    -        vscode
    -      ];
    +          vscode
     
    +          rustdesk-vbc
    +        ];
    +        sessionVariables = {
    +          AWS_CA_BUNDLE = nixosConfig.sops.secrets.harica-root-ca.path;
    +        };
    +      };
           systemd.user.sessionVariables = {
             DOCUMENT_DIR_WORK = lib.mkForce "${homeDir}/Documents/Work";
           } // lib.optionalAttrs (!config.swarselsystems.isPublic) {
    @@ -17117,6 +19934,23 @@ in
           #   };
           # };
     
    +      wayland.windowManager.sway =
    +        let
    +          inherit (nixosConfig.repo.secrets.local.work) user1 user1Long domain1 mailAddress;
    +        in
    +        {
    +          config = {
    +            keybindings =
    +              let
    +                inherit (config.wayland.windowManager.sway.config) modifier;
    +              in
    +              {
    +                "${modifier}+Shift+d" = "exec ${pkgs.quickpass}/bin/quickpass work/adm/${user1}/${user1Long}@${domain1}";
    +                "${modifier}+Shift+i" = "exec ${pkgs.quickpass}/bin/quickpass work/${mailAddress}";
    +              };
    +          };
    +        };
    +
           stylix = {
             targets.firefox.profileNames =
               let
    @@ -17639,7 +20473,16 @@ in
             };
     
           };
    -    };
    +    } // lib.optionalAttrs (inputs ? sops) {
    +      sops.secrets = lib.mkIf (!config.swarselsystems.isPublic && !config.swarselsystems.isNixos) {
    +        harica-root-ca = {
    +          sopsFile = certsSopsFile;
    +          path = "${homeDir}/.aws/certs/harica-root.pem";
    +          owner = mainUser;
    +        };
    +      };
    +
    +    });
     
     }
     
    @@ -18064,10 +20907,9 @@ In short, the options defined here are passed to the modules systems using 
     
    -
    -
    -

    3.5. Packages

    -
    +
    +

    3.4.3. Packages

    +

    This is the central station for self-defined packages. These are all referenced in default.nix. Wherever possible, I am keeping the shell version of these scripts in this file as well and then read it using builtin.readFile in the NixOS configurations. This lets me keep full control in this one file but also keep the separate files uncluttered.

    @@ -18075,17 +20917,21 @@ This is the central station for self-defined packages. These are all referenced

    Note: The structure of generating the packages was changed in commit 2cf03a3 refactor: package and module generation. That commit can be checked out in order to see a simpler version of achieving the same thing.

    - +
    +
    +
    +

    3.4.4. Packages (flake)

    +
    { self, lib, pkgs, ... }:
     let
       mkPackages = names: pkgs: builtins.listToAttrs (map
         (name: {
           inherit name;
    -      value = pkgs.callPackage "${self}/pkgs/${name}" { inherit self name; };
    +      value = pkgs.callPackage "${self}/pkgs/flake/${name}" { inherit self name; };
         })
         names);
    -  packageNames = lib.swarselsystems.readNix "pkgs";
    +  packageNames = lib.swarselsystems.readNix "pkgs/flake";
     in
     mkPackages packageNames pkgs
     
    @@ -18093,9 +20939,9 @@ mkPackages packageNames pkgs
     
    -
    -

    3.5.1. pass-fuzzel

    -
    +
    +
    3.4.4.1. pass-fuzzel
    +

    This app allows me, in conjunction with my Yubikey, to quickly enter passwords when the need arises. Normal and TOTP passwords are supported, and they can either be printed directly or copied to the clipboard.

    @@ -18167,9 +21013,40 @@ writeShellApplication {
    -
    -

    3.5.2. cura5

    -
    +
    +
    3.4.4.2. quickpass
    +
    +
    +
    shopt -s nullglob globstar
    +
    +notify-send "$(env | grep -E 'WAYLAND|SWAY')"
    +
    +password="$1"
    +
    +pass show "$password" | {
    +    IFS= read -r pass
    +    printf %s "$pass"
    +} | wtype -
    +
    +notify-send -u critical -a pass -t 1000 "Typed Password"
    +
    +
    + +
    +
    { self, name, writeShellApplication, libnotify, pass, wtype }:
    +writeShellApplication {
    +  inherit name;
    +  runtimeInputs = [ libnotify pass wtype ];
    +  text = builtins.readFile "${self}/files/scripts/${name}.sh";
    +}
    +
    +
    +
    +
    +
    +
    +
    3.4.4.3. cura5
    +

    The version of cura used to be quite outdated in nixpkgs. I am fetching a newer AppImage here and use that instead.

    @@ -18210,9 +21087,9 @@ writeScriptBin "cura" ''
    -
    -

    3.5.3. hm-specialisation

    -
    +
    +
    3.4.4.4. hm-specialisation
    +

    This script allows for quick git home-manager specialisation switching.

    @@ -18236,9 +21113,9 @@ writeShellApplication {
    -
    -

    3.5.4. cdw

    -
    +
    +
    3.4.4.5. cdw
    +

    This script allows for quick git worktree switching.

    @@ -18260,9 +21137,9 @@ writeShellApplication {
    -
    -

    3.5.5. cdb

    -
    +
    +
    3.4.4.6. cdb
    +

    This script allows for quick git branch switching.

    @@ -18282,9 +21159,9 @@ writeShellApplication {
    -
    -

    3.5.6. bak

    -
    +
    +
    3.4.4.7. bak
    +

    This script lets me quickly backup files by appending .bak to the filename.

    @@ -18305,9 +21182,9 @@ writeShellApplication {
    -
    -

    3.5.7. timer

    -
    +
    +
    3.4.4.8. timer
    +

    This app starts a configuratble timer and uses TTS to say something once the timer runs out.

    @@ -18328,9 +21205,9 @@ writeShellApplication {
    -
    -

    3.5.8. e

    -
    +
    +
    3.4.4.9. e
    +

    This is a shorthand for calling emacsclient mostly. Also, it hides the kittyterm scratchpad window that I sometimes use for calling a command quickly, in case it is on the screen. After emacs closes, the kittyterm window is then shown again if it was visible earlier.

    @@ -18374,9 +21251,9 @@ writeShellApplication {
    -
    -

    3.5.9. command-not-found

    -
    +
    +
    3.4.4.10. command-not-found
    +

    The normal command-not-found.sh uses the outdated nix-shell commands as suggestions. This version supplies me with the more modern nixpkgs#<name> version.

    @@ -18420,9 +21297,9 @@ command_not_found_handler() {
    -
    -

    3.5.10. swarselcheck

    -
    +
    +
    3.4.4.11. swarselcheck
    +

    This app checks for different apps that I keep around in the scratchpad for quick viewing and hiding (messengers and music players mostly) and then behaves like the kittyterm hider that I described in e.

    @@ -18505,9 +21382,9 @@ writeShellApplication {
    -
    -

    3.5.11. swarselcheck-niri

    -
    +
    +
    3.4.4.12. swarselcheck-niri
    +
    while :; do
         case ${1:-} in
    @@ -18560,9 +21437,9 @@ writeShellApplication {
     
    -
    -

    3.5.12. swarselzellij

    -
    +
    +
    3.4.4.13. swarselzellij
    +
    # KITTIES=$(($(pgrep -P 1 kitty | wc -l) - 1))
     
    @@ -18587,9 +21464,9 @@ writeShellApplication {
     
    -
    -

    3.5.13. waybarupdate

    -
    +
    +
    3.4.4.14. waybarupdate
    +

    This scripts checks if there are uncommited changes in either my dotfile repo, my university repo, or my passfile repo. In that case a warning will be shown in waybar.

    @@ -18634,9 +21511,9 @@ writeShellApplication {
    -
    -

    3.5.14. opacitytoggle

    -
    +
    +
    3.4.4.15. opacitytoggle
    +

    This app quickly toggles between 5% and 0% transparency.

    @@ -18661,9 +21538,9 @@ writeShellApplication {
    -
    -

    3.5.15. fs-diff

    -
    +
    +
    3.4.4.16. fs-diff
    +

    This utility is used to compare the current state of the root directory with the blanket state that is stored in /root-blank (the snapshot that is restored on each reboot of an impermanence machine). Using this, I can find files that I will lose once I reboot - if there are important files in that list, I can then easily add them to the persist options.

    @@ -18702,9 +21579,9 @@ writeShellApplication {
    -
    -

    3.5.16. github-notifications

    -
    +
    +
    3.4.4.17. github-notifications
    +

    This utility checks if there are updated packages in nixpkgs-unstable. It does so by fully building the most recent configuration, which I do not love, but it has its merits once I am willing to switch to the newer version.

    @@ -18728,9 +21605,9 @@ writeShellApplication {
    -
    -

    3.5.17. kanshare

    -
    +
    +
    3.4.4.18. kanshare
    +

    This utility checks if there are updated packages in nixpkgs-unstable. It does so by fully building the most recent configuration, which I do not love, but it has its merits once I am willing to switch to the newer version.

    @@ -18752,9 +21629,9 @@ writeShellApplication {
    -
    -

    3.5.18. swarsel-bootstrap

    -
    +
    +
    3.4.4.19. swarsel-bootstrap
    +

    This program sets up a new NixOS host remotely. It also takes care of secret management on the new host.

    @@ -18765,6 +21642,7 @@ set -eo pipefail target_hostname="" target_destination="" +target_arch="" target_user="swarsel" ssh_port="22" persist_dir="" @@ -18780,6 +21658,7 @@ function help_and_exit() { echo "ARGS:" echo " -n <target_hostname> specify target_hostname of the target host to deploy the nixos config on." echo " -d <target_destination> specify ip or url to the target host." + echo " -a <targeit_arch> specify the architecture of the target host." echo " target during install process." echo echo "OPTIONS:" @@ -18862,6 +21741,10 @@ while [[ $# -gt 0 ]]; do shift target_destination=$1 ;; + -a) + shift + target_arch=$1 + ;; -u) shift target_user=$1 @@ -18882,6 +21765,11 @@ while [[ $# -gt 0 ]]; do shift done +if [[ $target_arch == "" || $target_destination == "" || $target_hostname == "" ]]; then + red "error: target_arch, target_destination or target_hostname not set." + help_and_exit +fi + green "~SwarselSystems~ remote installer" green "Reading system information for $target_hostname ..." @@ -18936,6 +21824,7 @@ if [ ! -d "$FLAKE" ]; then fi cd "$FLAKE" + rm install/flake.lock || true git_root=$(git rev-parse --show-toplevel) # ------------------------ @@ -18973,8 +21862,13 @@ fi green "Generating hardware-config.nix for $target_hostname and adding it to the nix-config." $ssh_root_cmd "nixos-generate-config --force --no-filesystems --root /mnt" -mkdir -p "$FLAKE"/hosts/nixos/"$target_hostname" -$scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix "${git_root}"/hosts/nixos/"$target_hostname"/hardware-configuration.nix +mkdir -p "$FLAKE"/hosts/nixos/"$target_arch"/"$target_hostname" +$scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix "${git_root}"/hosts/nixos/"$target_arch"/"$target_hostname"/hardware-configuration.nix +# ------------------------ +# green "Generating hostkey for ssh initrd" +# $ssh_root_cmd "mkdir -p $temp/etc/secrets/initrd /etc/secrets/initrd" +# $ssh_root_cmd "ssh-keygen -t ed25519 -N '' -f $temp/etc/secrets/initrd/ssh_host_ed25519_key" +# $ssh_root_cmd "cp $temp/etc/secrets/initrd/ssh_host_ed25519_key /etc/secrets/initrd/ssh_host_ed25519_key" # ------------------------ green "Deploying minimal NixOS installation on $target_destination" @@ -19039,7 +21933,7 @@ if yes_or_no "Do you want to manually edit .sops.yaml now?"; then fi green "Updating all secrets files to reflect updates .sops.yaml" sops updatekeys --yes --enable-local-keyservice "${git_root}"/secrets/*/secrets.yaml -sops updatekeys --yes --enable-local-keyservice "${git_root}"/hosts/nixos/"$target_hostname"/secrets/pii.nix.enc +sops updatekeys --yes --enable-local-keyservice "${git_root}"/hosts/nixos/"$target_arch"/"$target_hostname"/secrets/pii.nix.enc # -------------------------- green "Making ssh_host_ed25519_key available to home-manager for user $target_user" sed -i "/$target_hostname/d; /$target_destination/d" ~/.ssh/known_hosts @@ -19098,10 +21992,10 @@ fi green "NixOS was successfully installed!" if yes_or_no "You can now commit and push the nix-config, which includes the hardware-configuration.nix for $target_hostname?"; then cd "${git_root}" - deadnix hosts/nixos/"$target_hostname"/hardware-configuration.nix -qe - nixpkgs--fmt hosts/nixos/"$target_hostname"/hardware-configuration.nix + deadnix hosts/nixos/"$target_arch"/"$target_hostname"/hardware-configuration.nix -qe + nixpkgs--fmt hosts/nixos/"$target_arch"/"$target_hostname"/hardware-configuration.nix (.pre-commit-config.yaml mit run --all-files 2> /dev/null || true) && - git add "$git_root/hosts/nixos/$target_hostname/hardware-configuration.nix" && + git add "$git_root/hosts/nixos/$target_arch/$target_hostname/hardware-configuration.nix" && git add "$git_root/.sops.yaml" && git add "$git_root/secrets" && (git commit -m "feat: deployed $target_hostname" || true) && git push @@ -19125,13 +22019,14 @@ writeShellApplication {
    -
    -

    3.5.19. swarsel-rebuild

    -
    +
    +
    3.4.4.20. swarsel-rebuild
    +
    set -eo pipefail
     
    -target_config="chaostheatre"
    +target_config="hotel"
    +target_arch=""
     target_user="swarsel"
     
     function help_and_exit() {
    @@ -19141,10 +22036,11 @@ function help_and_exit() {
         echo "USAGE: $0 [OPTIONS]"
         echo
         echo "ARGS:"
    -    echo "  -n <target_config>                       specify nixos config to build."
    -    echo "                                          Default: chaostheatre"
    +    echo "  -n <target_config>                      specify nixos config to build."
    +    echo "                                          Default: hotel"
         echo "  -u <target_user>                        specify user to deploy for."
         echo "                                          Default: swarsel"
    +    echo "  -a <target_arch>                        specify target architecture."
         echo "  -h | --help                             Print this help."
         exit 0
     }
    @@ -19174,6 +22070,10 @@ while [[ $# -gt 0 ]]; do
             shift
             target_config=$1
             ;;
    +    -a)
    +        shift
    +        target_arch=$1
    +        ;;
         -u)
             shift
             target_user=$1
    @@ -19187,6 +22087,11 @@ while [[ $# -gt 0 ]]; do
         shift
     done
     
    +if [[ $target_arch == "" ]]; then
    +    red "error: target_arch not set."
    +    help_and_exit
    +fi
    +
     cd /home/"$target_user"
     
     if [ ! -d /home/"$target_user"/.dotfiles ]; then
    @@ -19214,7 +22119,7 @@ if [[ $local_keys != *"${pub_arr[1]}"* ]]; then
         rm modules/home/common/mail.nix
         rm modules/home/common/yubikey.nix
         rm modules/nixos/server/restic.nix
    -    rm hosts/nixos/milkywell/default.nix
    +    rm hosts/nixos/aarch64-linux/milkywell/default.nix
         rm -rf modules/nixos/server
         rm -rf modules/home/server
         nix flake update vbc-nix
    @@ -19222,8 +22127,8 @@ if [[ $local_keys != *"${pub_arr[1]}"* ]]; then
     else
         green "Valid SSH key found! Continuing with installation"
     fi
    -sudo nixos-generate-config --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/
    -git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
    +sudo nixos-generate-config --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_arch"/"$target_config"/
    +git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_arch"/"$target_config"/hardware-configuration.nix
     
     green "Installing flake $target_config"
     sudo nixos-rebuild --show-trace --flake .#"$target_config" boot
    @@ -19244,9 +22149,9 @@ writeShellApplication {
     
    -
    -

    3.5.20. swarsel-install

    -
    +
    +
    3.4.4.21. swarsel-install
    +

    Autoformatting always puts the EOF with indentation, which makes shfmt check fail. When editing this block, unindent them manually.

    @@ -19254,9 +22159,10 @@ Autoformatting always puts the EOF with indentation, which makes sh
    set -eo pipefail
     
    -target_config="chaostheatre"
    -target_hostname="chaostheatre"
    +target_config="hotel"
    +target_hostname="hotel"
     target_user="swarsel"
    +target_arch=""
     persist_dir=""
     target_disk="/dev/vda"
     disk_encryption=0
    @@ -19269,11 +22175,12 @@ function help_and_exit() {
         echo
         echo "ARGS:"
         echo "  -n <target_config>                      specify the nixos config to deploy."
    -    echo "                                          Default: chaostheatre"
    +    echo "                                          Default: hotel"
         echo "  -d <target_disk>                        specify disk to install on."
         echo "                                          Default: /dev/vda"
         echo "  -u <target_user>                        specify user to deploy for."
         echo "                                          Default: swarsel"
    +    echo "  -a <target_arch>                        specify target architecture."
         echo "  -h | --help                             Print this help."
         exit 0
     }
    @@ -19312,6 +22219,10 @@ while [[ $# -gt 0 ]]; do
             shift
             target_disk=$1
             ;;
    +    -a)
    +        shift
    +        target_arch=$1
    +        ;;
         -h | --help) help_and_exit ;;
         *)
             echo "Invalid option detected."
    @@ -19327,6 +22238,11 @@ function cleanup() {
     }
     trap cleanup exit
     
    +if [[ $target_arch == "" || $target_hostname == "" ]]; then
    +    red "error: target_arch or target_hostname not set."
    +    help_and_exit
    +fi
    +
     green "~SwarselSystems~ local installer"
     
     cd /home/"$target_user"
    @@ -19406,7 +22322,7 @@ if [ "$disk_encryption" -eq 1 ]; then
     fi
     
     green "Setting up disk ..."
    -if [[ $target_config == "chaostheatre" ]]; then
    +if [[ $target_config == "hotel" ]]; then
         sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/v1.10.0 -- --mode destroy,format,mount --flake .#"$target_config" --yes-wipe-all-disks --arg diskDevice "$target_disk"
     else
         sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount --flake .#"$target_config" --yes-wipe-all-disks
    @@ -19416,9 +22332,9 @@ sudo cp -r /home/"$target_user"/.dotfiles /mnt/"$persist_dir"/home/"$target_user
     sudo chown -R 1000:100 /mnt/"$persist_dir"/home/"$target_user"
     
     green "Generating hardware configuration ..."
    -sudo nixos-generate-config --root /mnt --no-filesystems --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/
    +sudo nixos-generate-config --root /mnt --no-filesystems --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_arch"/"$target_config"/
     
    -git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
    +git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_arch"/"$target_config"/hardware-configuration.nix
     sudo 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}}' | sudo tee /root/.local/share/nix/trusted-settings.json > /dev/null
     green "Installing flake $target_config"
    @@ -19446,13 +22362,13 @@ writeShellApplication {
     
    -
    -

    3.5.21. swarsel-postinstall

    -
    +
    +
    3.4.4.22. swarsel-postinstall
    +
    set -eo pipefail
     
    -target_config="chaostheatre"
    +target_config="hotel"
     target_user="swarsel"
     
     function help_and_exit() {
    @@ -19464,8 +22380,8 @@ function help_and_exit() {
         echo "ARGS:"
         echo "  -d <disk>                               specify disk to install on."
         echo "  -n <target_config>                      specify the nixos config to deploy."
    -    echo "                                          Default: chaostheatre"
    -    echo "                                          Default: chaostheatre"
    +    echo "                                          Default: hotel"
    +    echo "                                          Default: hotel"
         echo "  -u <target_user>                        specify user to deploy for."
         echo "                                          Default: swarsel"
         echo "  -h | --help                             Print this help."
    @@ -19538,9 +22454,9 @@ writeShellApplication {
     
    -
    -

    3.5.22. t2ts

    -
    +
    +
    3.4.4.23. t2ts
    +
    { name, writeShellApplication, ... }:
     
    @@ -19556,9 +22472,9 @@ writeShellApplication {
     
    -
    -

    3.5.23. ts2t

    -
    +
    +
    3.4.4.24. ts2t
    +
    { name, writeShellApplication, ... }:
     
    @@ -19574,9 +22490,9 @@ writeShellApplication {
     
    -
    -

    3.5.24. vershell

    -
    +
    +
    3.4.4.25. vershell
    +
    { name, writeShellApplication, ... }:
     
    @@ -19592,9 +22508,9 @@ writeShellApplication {
     
    -
    -

    3.5.25. eontimer

    -
    +
    +
    3.4.4.26. eontimer
    +
    { lib
     , python3
    @@ -19696,9 +22612,9 @@ python3.pkgs.buildPythonApplication rec {
     
    -
    -

    3.5.26. project

    -
    +
    +
    3.4.4.27. project
    +
    set -euo pipefail
     
    @@ -19720,9 +22636,9 @@ writeShellApplication {
     
    -
    -

    3.5.27. fhs

    -
    +
    +
    3.4.4.28. fhs
    +
    { name, pkgs, ... }:
     let
    @@ -19739,9 +22655,9 @@ pkgs.buildFHSEnv (base // {
     
    -
    -

    3.5.28. swarsel-displaypower

    -
    +
    +
    3.4.4.29. swarsel-displaypower
    +

    A crude script to power on all displays that might be attached. Needed because sometimes displays do not awake from sleep.

    @@ -19764,9 +22680,9 @@ writeShellApplication {
    -
    -

    3.5.29. swarsel-mgba

    -
    +
    +
    3.4.4.30. swarsel-mgba
    +

    AppImage version of mgba in which the lua scripting works.

    @@ -19798,9 +22714,9 @@ appimageTools.wrapType2 {
    -
    -

    3.5.30. swarsel-deploy

    -
    +
    +
    3.4.4.31. swarsel-deploy
    +
    # heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix
     { name, bc, nix-output-monitor, writeShellApplication, ... }:
    @@ -19930,9 +22846,9 @@ writeShellApplication {
     
    -
    -

    3.5.31. swarsel-build

    -
    +
    +
    3.4.4.32. swarsel-build
    +
    { name, nix-output-monitor, writeShellApplication, ... }:
     writeShellApplication {
    @@ -19954,9 +22870,9 @@ writeShellApplication {
     
    -
    -

    3.5.32. swarsel-instantiate

    -
    +
    +
    3.4.4.33. swarsel-instantiate
    +

    This is a convenience function that calls nix-instantiate with a number of flags that I need in order to evaluate nix expressions in org-src blocks.

    @@ -19975,9 +22891,9 @@ writeShellApplication {
    -
    -

    3.5.33. sshrm

    -
    +
    +
    3.4.4.34. sshrm
    +

    This programs simply runs ssh-keygen on the last host that I tried to ssh into. I need this frequently when working with cloud-init usually.

    @@ -20008,9 +22924,9 @@ writeShellApplication {
    -
    -

    3.5.34. endme

    -
    +
    +
    3.4.4.35. endme
    +

    Sometimes my DE crashes after putting it to suspend - to be precise, it happens when I put it into suspend when I have multiple screens plugged in. I have never taken the time to debug the issue, but instead just switch to a different TTY and then use this script to kill the hanging session.

    @@ -20030,9 +22946,9 @@ writeShellApplication {
    -
    -

    3.5.35. git-replace

    -
    +
    +
    3.4.4.36. git-replace
    +

    This script allows for quick git replace of a string.

    @@ -20109,8 +23025,51 @@ writeShellApplication {
    +
    +

    3.4.5. Packages (config)

    +
    +
    +
    { self, homeConfig, lib, pkgs, ... }:
    +let
    +  mkPackages = names: pkgs: builtins.listToAttrs (map
    +    (name: {
    +      inherit name;
    +      value = pkgs.callPackage "${self}/pkgs/config/${name}" { inherit self name homeConfig; };
    +    })
    +    names);
    +  packageNames = lib.swarselsystems.readNix "pkgs/config";
    +in
    +mkPackages packageNames pkgs
    +
    +
    +
    +
    +
    3.4.5.1. cdr
    +
    +
    +
    { name, homeConfig, writeShellApplication, fzf, ... }:
    +
    +writeShellApplication {
    +  inherit name;
    +  runtimeInputs = [ fzf ];
    +  text = ''
    +    DOCUMENT_DIR_WORK=${homeConfig.systemd.user.sessionVariables.DOCUMENT_DIR_WORK or ""}
    +    DOCUMENT_DIR_PRIV=${homeConfig.systemd.user.sessionVariables.DOCUMENT_DIR_PRIV}
    +    FLAKE=${homeConfig.home.sessionVariables.FLAKE}
    +
    +    cd "$( (find "$DOCUMENT_DIR_WORK" "$DOCUMENT_DIR_PRIV" -maxdepth 1 && echo "$FLAKE") | fzf )"
    +  '';
    +}
    +
    +
    +
    +
    +
    +
    +
    +
    -

    3.6. Profiles

    +

    3.5. Profiles

    In this section I define custom modules under the swarsel attribute. These are mostly used to define settings specific to a host. I keep these settings confined to either home-manager or nixos to maintain compatibility with non-NixOS machines. @@ -20121,7 +23080,7 @@ Note: The structure of generating the packages was changed in commit 2cf03

    -

    3.6.1. NixOS

    +

    3.5.1. NixOS

    Modules that need to be loaded on the NixOS level. Note that these will not be available on systems that are not running NixOS. @@ -20139,7 +23098,7 @@ in

    -
    3.6.1.1. Personal
    +
    3.5.1.1. Personal
    { lib, config, ... }:
    @@ -20170,7 +23129,7 @@ in
           lowBattery = lib.mkDefault false;
           network = lib.mkDefault true;
           networkDevices = lib.mkDefault true;
    -      niri = lib.mkDefault true;
    +      niri = lib.mkDefault false;
           nix-ld = lib.mkDefault true;
           nvd = lib.mkDefault true;
           packages = lib.mkDefault true;
    @@ -20210,7 +23169,7 @@ in
     
    -
    3.6.1.2. Minimal
    +
    3.5.1.2. Minimal
    { lib, config, ... }:
    @@ -20236,6 +23195,7 @@ in
     
           server = {
             ssh = lib.mkDefault true;
    +        diskEncryption = lib.mkDefault true;
           };
         };
     
    @@ -20247,9 +23207,9 @@ in
     
    -
    -
    3.6.1.3. Optionals
    -
    +
    +
    3.5.1.3. Optionals
    +
    { lib, config, ... }:
     {
    @@ -20277,13 +23237,13 @@ in
     
    -
    3.6.1.4. Chaostheatre
    +
    3.5.1.4. Hotel
    { lib, config, ... }:
     {
    -  options.swarselprofiles.chaostheatre = lib.mkEnableOption "is this a chaostheatre host";
    -  config = lib.mkIf config.swarselprofiles.chaostheatre {
    +  options.swarselprofiles.hotel = lib.mkEnableOption "is this a hotel host";
    +  config = lib.mkIf config.swarselprofiles.hotel {
         swarselmodules = {
           packages = lib.mkForce true;
           general = lib.mkForce true;
    @@ -20336,7 +23296,7 @@ in
     
    -
    3.6.1.5. Work
    +
    3.5.1.5. Work
    { lib, config, ... }:
    @@ -20363,7 +23323,7 @@ in
     
    -
    3.6.1.6. Uni
    +
    3.5.1.6. Uni
    { lib, config, ... }:
    @@ -20390,7 +23350,7 @@ in
     
    -
    3.6.1.7. Framework
    +
    3.5.1.7. Framework
    { lib, config, ... }:
    @@ -20417,7 +23377,7 @@ in
     
    -
    3.6.1.8. Server
    +
    3.5.1.8. Server
    { lib, config, ... }:
    @@ -20426,6 +23386,7 @@ in
       config = lib.mkIf config.swarselprofiles.server {
         swarselmodules = {
             general = lib.mkDefault true;
    +        lanzaboote = lib.mkDefault true;
             pii = lib.mkDefault true;
             home-manager = lib.mkDefault true;
             xserver = lib.mkDefault true;
    @@ -20437,6 +23398,8 @@ in
             boot = lib.mkDefault true;
             server = {
               general = lib.mkDefault true;
    +          network = lib.mkDefault true;
    +          diskEncryption = lib.mkDefault true;
               packages = lib.mkDefault true;
               ssh = lib.mkDefault true;
               nginx = lib.mkDefault true;
    @@ -20446,13 +23409,34 @@ in
     
     }
     
    +
    +
    +
    +
    +
    +
    3.5.1.9. Router
    +
    +
    +
    { lib, config, ... }:
    +{
    +  options.swarselprofiles.router = lib.mkEnableOption "enable the router profile";
    +  config = lib.mkIf config.swarselprofiles.router {
    +    swarselmodules = {
    +        server = {
    +          router = lib.mkDefault true;
    +        };
    +      };
    +  };
    +
    +}
    +
     
    -

    3.6.2. home-manager

    +

    3.5.2. home-manager

    This holds modules that are to be used on most hosts. These are also the most important options to configure, as these allow me easy access to monitor, keyboard, and other setups. @@ -20470,7 +23454,7 @@ in

    -
    3.6.2.1. Personal
    +
    3.5.2.1. Personal
    { lib, config, ... }:
    @@ -20504,7 +23488,7 @@ in
           kitty = lib.mkDefault true;
           mail = lib.mkDefault true;
           mako = lib.mkDefault true;
    -      niri = lib.mkDefault true;
    +      niri = lib.mkDefault false;
           nix-index = lib.mkDefault true;
           nixgl = lib.mkDefault true;
           nix-your-shell = lib.mkDefault true;
    @@ -20512,6 +23496,7 @@ in
           obs-studio = lib.mkDefault true;
           obsidian = lib.mkDefault true;
           obsidian-tray = lib.mkDefault true;
    +      opkssh = lib.mkDefault true;
           ownpackages = lib.mkDefault true;
           packages = lib.mkDefault true;
           passwordstore = lib.mkDefault true;
    @@ -20530,6 +23515,7 @@ in
           tmux = lib.mkDefault true;
           vesktop = lib.mkDefault true;
           vesktop-tray = lib.mkDefault true;
    +      syncthing-tray = lib.mkDefault true;
           waybar = lib.mkDefault true;
           yubikey = lib.mkDefault false;
           yubikeytouch = lib.mkDefault true;
    @@ -20544,9 +23530,9 @@ in
     
    -
    -
    3.6.2.2. DGX Spark
    -
    +
    +
    3.5.2.2. DGX Spark
    +
    { lib, config, ... }:
     {
    @@ -20605,6 +23591,7 @@ in
           tmux = lib.mkDefault true;
           vesktop = lib.mkDefault false;
           vesktop-tray = lib.mkDefault false;
    +      syncthing-tray = lib.mkDefault false;
           waybar = lib.mkDefault false;
           yubikey = lib.mkDefault false;
           yubikeytouch = lib.mkDefault false;
    @@ -20620,7 +23607,7 @@ in
     
    -
    3.6.2.3. Optionals
    +
    3.5.2.3. Optionals
    { lib, config, ... }:
    @@ -20642,7 +23629,7 @@ in
     
    -
    3.6.2.4. Minimal
    +
    3.5.2.4. Minimal
    { lib, config, ... }:
    @@ -20665,13 +23652,13 @@ in
     
    -
    3.6.2.5. Chaostheatre
    +
    3.5.2.5. Hotel
    { lib, config, ... }:
     {
    -  options.swarselprofiles.chaostheatre = lib.mkEnableOption "is this a chaostheatre host";
    -  config = lib.mkIf config.swarselprofiles.chaostheatre {
    +  options.swarselprofiles.hotel = lib.mkEnableOption "is this a hotel host";
    +  config = lib.mkIf config.swarselprofiles.hotel {
         swarselmodules = {
           packages = lib.mkForce true;
           ownpackages = lib.mkForce true;
    @@ -20718,7 +23705,7 @@ in
     
    -
    3.6.2.6. toto
    +
    3.5.2.6. toto
    { lib, config, ... }:
    @@ -20741,7 +23728,7 @@ in
     
    -
    3.6.2.7. Work
    +
    3.5.2.7. Work
    { lib, config, ... }:
    @@ -20762,7 +23749,7 @@ in
     
    -
    3.6.2.8. Uni
    +
    3.5.2.8. Uni
    { lib, config, ... }:
    @@ -20783,7 +23770,7 @@ in
     
    -
    3.6.2.9. Framework
    +
    3.5.2.9. Framework
    { lib, config, ... }:
    @@ -20805,7 +23792,7 @@ in
     
    -
    3.6.2.10. Local Server
    +
    3.5.2.10. Local Server
    -
    4.2.1.9. org-mode: General setup
    +
    4.2.1.10. org-mode: General setup
    -
    4.2.1.10. org-mode: Visual-fill column
    +
    4.2.1.11. org-mode: Visual-fill column

    This function sets the width of buffers in org-mode. @@ -21358,7 +24365,7 @@ Used in: Centered org-mode Buf

    -
    4.2.1.11. org-mode: Upon-save actions (Auto-tangle, export to html, formatting)
    +
    4.2.1.12. org-mode: Upon-save actions (Auto-tangle, export to html, formatting)

    This section handles everything that shoudld happen when I save SwarselSystems.org. It: @@ -21400,7 +24407,7 @@ We set a hook that runs everytime we save the file. It would be a bit more effic

    -
    4.2.1.12. org-mode: Fold current heading
    +
    4.2.1.13. org-mode: Fold current heading

    Normally emacs cycles between three states: @@ -21431,7 +24438,7 @@ However, I want to be able to fold a single heading consistently.

    -
    4.2.1.13. corfu: Do not interrupt navigation
    +
    4.2.1.14. corfu: Do not interrupt navigation
    -
    4.2.1.14. Disable garbage collection while minibuffer is active
    +
    4.2.1.15. Disable garbage collection while minibuffer is active
    @@ -21543,6 +24550,7 @@ I also define some keybinds to some combinations directly. Those are used mostly
         "l"  '(:ignore l :which-key "links")
         "lc" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (org-overview) )) :which-key "SwarselSystems.org")
         "le" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "Emacs") ) (org-overview) (org-cycle) )) :which-key "Emacs.org")
    +    "lr" '(swarsel/consult-magit-repos :which-key "List repos")
         "ln" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "System") ) (org-overview) (org-cycle))) :which-key "Nixos.org")
         "lp" '((lambda () (interactive) (projectile-switch-project)) :which-key "switch project")
         "lg" '((lambda () (interactive) (magit-list-repositories)) :which-key "list git repos")
    @@ -21592,6 +24600,7 @@ I also define some keybinds to some combinations directly. Those are used mostly
      "C-c D" 'crux-duplicate-and-comment-current-line-or-region
      "<DUMMY-m>" 'swarsel/last-buffer
      "M-\\" 'indent-region
    + "M-r" 'swarsel/consult-magit-repos
      "<Paste>" 'yank
      "<Cut>" 'kill-region
      "<Copy>" 'kill-ring-save
    @@ -23045,6 +26054,17 @@ Recently I have grown fond of holding presentations using Emacs :)
     (add-hook 'org-present-mode-quit-hook 'swarsel/org-present-end)
     (add-hook 'org-present-after-navigate-functions 'swarsel/org-present-slide)
     
    +
    +
    +
    +
    +
    +
    4.4.1.11. Render markdown blocks as body to expand noweb blocks
    +
    +
    +
    (defun org-babel-execute:markdown (body params)
    +  "Just return BODY unchanged, allowing noweb expansion."
    +  body)
     
    @@ -23186,7 +26206,7 @@ This adds support for Terraform configuration files. I need this at work.
    -

    4.4.8. nixpkgs-fmt

    +

    4.4.8. nix formatting

    Adds functions for formatting nix code. @@ -23485,8 +26505,8 @@ Also, Emacs needs a little extra love to accept my Yubikey for git commits etc.

     (use-package magit
       :config
    -  (setq magit-repository-directories `((,swarsel-work-projects-directory  . 1)
    -                                       (,swarsel-private-projects-directory . 1)
    +  (setq magit-repository-directories `((,swarsel-work-projects-directory  . 3)
    +                                       (,swarsel-private-projects-directory . 3)
                                            ("~/.dotfiles/" . 0)))
       :custom
       (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) ; stay in the same window
    @@ -24255,8 +27275,8 @@ This adds the simple utility of sending desktop notifications whenever a new mai
     
    -
    -
    4.4.39.3. Work: Signing Mails (S/MIME, smime)
    +
    +
    4.4.39.3. Work: Signing Mails (S/MIME, smime)
    -
    -

    5.1. General steps when setting up a new machine

    +
    +

    5.1. General steps when setting up a new machine

    These general steps are needed when setting up a new machine and do not fit into another block well: @@ -24552,10 +27572,13 @@ These general steps are needed when setting up a new machine and do not fit into - `systemd-cryptenroll --fido2-device=auto /dev/<device, e.g. 'nvme0n1p2'>`

    + +- setup yubikey (automatic yubikey enrollment is not yet supported by `disko`): + - `systemd-cryptenroll --fido2-device=auto /dev/`
    -
    -

    5.2. Current patches and fixes

    +
    +

    5.2. Current patches and fixes

    These are current deviations from the standard settings that I take while some things are broken upstream @@ -24582,6 +27605,25 @@ These are current deviations from the standard settings that I take while some t - pinned to version not in nixpkgs (fixes https://github.com/ErikReider/SwayOSD/issues/175)

    + +- 202501102: + - flake: + - emacs-overlay: + - : version pinned because emacsclient is currently broken on latest + - niri-flake: + - currently not using the sugared version of screenshot-[,window], as it is currently broken + - home-manager: + - emacs-tramp: + - using stable version in extraPackages (broken in unstable) + - :ensure nil in emacs tramp settings to use package in extraPackages + - emacs-calfwL + - pinned to version not in nixpkgs (is in latest emacs-overlay, but that is broken) + - vesktop: + - running stable version (broken in unstable) + - batgrep: + - running stable version (broken in unstable) + - swayosd: + - pinned to version not in nixpkgs (fixes https://github.com/ErikReider/SwayOSD/issues/175)
    @@ -25330,12 +28372,9 @@ check-trace: update: nix flake update -iso: +iso CONFIG="live-iso": rm -rf result - nix build .#nixosConfigurations.iso.config.system.build.isoImage && ln -sf result/iso/*.iso latest.iso - -iso-flake FLAKE SYSTEM="x86_64" FORMAT="iso": - nixos-generate --flake .#{{FLAKE}} -f {{FORMAT}} --system {{SYSTEM}} + nix build --print-out-paths .#live-iso iso-install DRIVE: iso sudo dd if=$(eza --sort changed result/iso/*.iso | tail -n1) of={{DRIVE}} bs=4M status=progress oflag=sync @@ -25346,6 +28385,9 @@ dd DRIVE ISO: sync USER HOST: rsync -rltv --filter=':- .gitignore' -e "ssh -l {{USER}}" . {{USER}}@{{HOST}}:.dotfiles/ +bootstrap DEST CONFIG ARCH="x86_64-linux": + nix develop .#deploy --command zsh -c "swarsel-bootstrap -n {{CONFIG}} -d {{DEST}} -a {{ARCH}}" +
    @@ -25389,7 +28431,7 @@ index 3a0f90e..bb10f8b 100644
    -

    6.8. Zellij layout default.kdl.nix

    +

    6.8. Zellij layout swarsel.kdl.nix

    { config, pkgs }:
    @@ -26954,7 +29996,7 @@ Here lies defined the readme for GitHub and Forgejo:
       nix run --experimental-features 'nix-command flakes' github:Swarsel/.dotfiles#swarsel-rebuild -- -u <YOUR_USERNAME>
       ```
     
    -  This will activate the `chaostheatre` configuration on your system, which is a de-facto mirror of my main configuration with secret-based settings removed.
    +  This will activate the `hotel` configuration on your system, which is a de-facto mirror of my main configuration with secret-based settings removed.
       Please keep in mind that this limited installer will make local changes to the cloned repository in order to be able to install it (otherwise the builder would fail at fetching my private secrets repository). As such, this should only be used to evaluate the system - if you want to use it longterm, you will need to create a fork and make some changes.
       </details>
     
    @@ -26967,7 +30009,7 @@ Here lies defined the readme for GitHub and Forgejo:
     
       #### Remote deployment (recommended if you have at least one running system)
     
    -  0) Fork this repo, and write your own host config at `hosts/nixos/<YOUR_CONFIG_NAME>/default.nix` (you can use one of the other configurations as a template. Also see https://github.com/Swarsel/.dotfiles/tree/main/modules for a list of all additional options). At the very least, you should replace the `secrets/` directory with your own secrets and replace the SSH public keys with your own ones (otherwise I will come visit you!🔓❤️). I personally recommend to use the literate configuration and `org-babel-tangle-file` in Emacs, but you can also simply edit the separate `.nix` files.
    +  0) Fork this repo, and write your own host config at `hosts/nixos/<YOUR_ARCHITECTURE>/<YOUR_CONFIG_NAME>/default.nix` (you can use one of the other configurations as a template. Also see https://github.com/Swarsel/.dotfiles/tree/main/modules for a list of all additional options). At the very least, you should replace the `secrets/` directory with your own secrets and replace the SSH public keys with your own ones (otherwise I will come visit you!🔓❤️). I personally recommend to use the literate configuration and `org-babel-tangle-file` in Emacs, but you can also simply edit the separate `.nix` files.
       1) Have a system with `nix` available booted (this does not need to be installed, i.e. you can use a NixOS installer image; a custom minimal installer ISO can be built by running `just iso` in the root of this repo)
       2) Make sure that your Yubikey is plugged in or that you have your SSH key available (and configured)
       3) Run `swarsel-bootstrap -n <CONFIGURATION_NAME> -d <TARGET_IP>` on your existing system.
    @@ -27041,16 +30083,21 @@ Here lies defined the readme for GitHub and Forgejo:
       | Name               | Hardware                                            | Use                                                  |
       |--------------------|-----------------------------------------------------|------------------------------------------------------|
       |💻 **pyramid**      | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                          |
    -  |💻 **bakery**       | Lenovo Ideapad 720S-13IKB                           | Personal lapto                                       |
    -  |💻 **machpizza**    | MacBook Pro 2016                                    | MacOS sandbox                                        |
    -  |🖥️ **winters**      | ASRock J4105-ITX, 32GB RAM                          | Main homeserver and data storgae                     |
    -  |🖥️ **milkywell**    | Oracle Cloud: VM.Standard.E2.1.Micro                | Server for lightweight synchronization tasks         |
    -  |🖥️ **moonside**     | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services  |
    +  |💻 **bakery**       | Lenovo Ideapad 720S-13IKB                           | Personal laptop                                      |
    +  |💻 **machpizza**    | MacBook Pro 2016                                    | MacOS reference and build sandbox                    |
    +  |🏠 **treehouse**    | NVIDIA DGX Spark                                    | Workstation, AI playground and home-manager reference|
    +  |🖥️ **winters**      | ASRock J4105-ITX, 32GB RAM                          | Secondary homeserver and data storgae                |
    +  |🖥️ **summers**      | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM  | Main homeserver running microvms, data storage       |
    +  |🖥️ **hintbooth**    | HUNSN RM02, 8GB RAM                                 | Router                                               |
    +  |☁️ **milkywell**    | Oracle Cloud: VM.Standard.E2.1.Micro                | Server for lightweight synchronization tasks         |
    +  |☁️ **moonside**     | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services  |
    +  |☁️ **belchsfactory**| Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Hydra builder and nix binary cache                   |
    +  |☁️ **monkeycave**   | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Gaming server                                        |
    +  |☁️ **eagleland**    | Hetzner Cloud: CX23                                 | Mail server                                          |
       |📱 **magicant**     | Samsung Galaxy Z Flip 6                             | Phone                                                |
       |💿 **drugstore**    | -                                                   | ISO installer configuration                          |
       |❔ **chaotheatre**  | -                                                   | Demo config for checking out my configurtion         |
       |❔ **toto**         | -                                                   | Helper configuration for bootstrapping a new system  |
    -  |🏠 **treehouse**    | -                                                   | Reference configuration for a home-manager only host |
       </details>
     
       ## General Nix tips & useful links
    @@ -27267,7 +30314,7 @@ builtins.listToAttrs converts a list of name-value pairs into an attribute set.
     
    -{ bakery = "directory"; chaostheatre = "directory"; milkywell = "directory"; moonside = "directory"; pyramid = "directory"; toto = "directory"; winters = "directory"; }
    +{ aarch64-linux = "directory"; x86_64-linux = "directory"; }
     
    @@ -27515,7 +30562,7 @@ similarly, there exists an version that starts from the right.

    Author: Leon Schwarzäugl

    -

    Created: 2025-11-03 Mo 17:12

    +

    Created: 2025-11-19 Mi 15:22

    Validate

    diff --git a/modules/home/common/custom-packages.nix b/modules/home/common/custom-packages.nix index 302ba29..8efebe1 100644 --- a/modules/home/common/custom-packages.nix +++ b/modules/home/common/custom-packages.nix @@ -7,6 +7,7 @@ pass-fuzzel cdw cdb + cdr bak timer e @@ -31,8 +32,6 @@ sshrm endme git-replace - - rustdesk-vbc ]; }; } diff --git a/modules/home/common/settings.nix b/modules/home/common/settings.nix index 0f690f9..3793cbc 100644 --- a/modules/home/common/settings.nix +++ b/modules/home/common/settings.nix @@ -47,9 +47,20 @@ in }; }; - # nixpkgs.overlays = lib.mkIf isNixos (lib.mkForce null); nixpkgs = lib.mkIf (!isNixos) { - overlays = [ outputs.overlays.default ]; + overlays = [ + outputs.overlays.default + (final: prev: + let + additions = final: _: import "${self}/pkgs/config" { + inherit self config lib; + pkgs = final; + homeConfig = config; + }; + in + additions final prev + ) + ]; config = { allowUnfree = true; }; diff --git a/modules/home/common/zellij-keybinds.nix b/modules/home/common/zellij-keybinds.nix index b9ce4d4..80d28c5 100644 --- a/modules/home/common/zellij-keybinds.nix +++ b/modules/home/common/zellij-keybinds.nix @@ -620,6 +620,19 @@ _children = [{ Resize._args = [ "Increase" ]; }]; }; } + { + bind = { + _args = [ "Alt r" ]; + _children = [ + { + WriteChars._args = [ "source cdr" ]; + } + { + WriteChars._args = [ "\n" ]; + } + ]; + }; + } { bind = { _args = [ "Alt f" ]; diff --git a/modules/home/common/zsh.nix b/modules/home/common/zsh.nix index 7813983..30aa13c 100644 --- a/modules/home/common/zsh.nix +++ b/modules/home/common/zsh.nix @@ -35,7 +35,8 @@ in hotspot = "nmcli connection up local; nmcli device wifi hotspot;"; youtube-dl = "yt-dlp"; cat-orig = "cat"; - cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\""; + # cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\""; + cdr = "source cdr"; nix-ldd-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; nix-ldd-locate = "nix-locate --minimal --top-level -w "; diff --git a/modules/home/optional/work.nix b/modules/home/optional/work.nix index ad74838..006638a 100644 --- a/modules/home/optional/work.nix +++ b/modules/home/optional/work.nix @@ -1,28 +1,36 @@ -{ self, config, pkgs, lib, vars, nixosConfig ? config, ... }: +{ self, inputs, config, pkgs, lib, vars, nixosConfig ? config, ... }: let - inherit (config.swarselsystems) homeDir; + inherit (config.swarselsystems) homeDir mainUser; inherit (nixosConfig.repo.secrets.local.mail) allMailAddresses; inherit (nixosConfig.repo.secrets.local.work) mailAddress; + + certsSopsFile = self + /secrets/certs/secrets.yaml; in { options.swarselmodules.optional.work = lib.mkEnableOption "optional work settings"; config = lib.mkIf config.swarselmodules.optional.work - { - home.packages = with pkgs; [ - stable.teams-for-linux - shellcheck - dig - docker - postman - # rclone - libguestfs-with-appliance - prometheus.cli - tigervnc - # openstackclient + ({ + home = { + packages = with pkgs; [ + stable.teams-for-linux + shellcheck + dig + docker + postman + # rclone + libguestfs-with-appliance + prometheus.cli + tigervnc + # openstackclient - vscode - ]; + vscode + rustdesk-vbc + ]; + sessionVariables = { + AWS_CA_BUNDLE = nixosConfig.sops.secrets.harica-root-ca.path; + }; + }; systemd.user.sessionVariables = { DOCUMENT_DIR_WORK = lib.mkForce "${homeDir}/Documents/Work"; } // lib.optionalAttrs (!config.swarselsystems.isPublic) { @@ -644,6 +652,15 @@ in }; }; - }; + } // lib.optionalAttrs (inputs ? sops) { + sops.secrets = lib.mkIf (!config.swarselsystems.isPublic && !config.swarselsystems.isNixos) { + harica-root-ca = { + sopsFile = certsSopsFile; + path = "${homeDir}/.aws/certs/harica-root.pem"; + owner = mainUser; + }; + }; + + }); } diff --git a/modules/nixos/common/home-manager-secrets.nix b/modules/nixos/common/home-manager-secrets.nix index 7c2a3e1..fd2db03 100644 --- a/modules/nixos/common/home-manager-secrets.nix +++ b/modules/nixos/common/home-manager-secrets.nix @@ -1,8 +1,10 @@ -{ lib, config, globals, ... }: +{ self, lib, config, globals, ... }: let inherit (config.swarselsystems) mainUser homeDir; inherit (config.repo.secrets.common.emacs) radicaleUser; modules = config.home-manager.users.${mainUser}.swarselmodules; + + certsSopsFile = self + /secrets/certs/secrets.yaml; in { config = lib.mkIf config.swarselsystems.withHomeManager { @@ -22,6 +24,8 @@ in github-nixpkgs-review-token = { owner = mainUser; }; }) // (lib.optionalAttrs modules.emacs { emacs-radicale-pw = { owner = mainUser; }; + }) // (lib.optionalAttrs modules.optional.work { + harica-root-ca = { sopsFile = certsSopsFile; path = "${homeDir}/.aws/certs/harica-root.pem"; owner = mainUser; }; }) // (lib.optionalAttrs modules.anki { anki-user = { owner = mainUser; }; anki-pw = { owner = mainUser; }; diff --git a/modules/nixos/common/settings.nix b/modules/nixos/common/settings.nix index 5539de5..cdcf3a2 100644 --- a/modules/nixos/common/settings.nix +++ b/modules/nixos/common/settings.nix @@ -107,7 +107,19 @@ in system.stateVersion = lib.mkDefault "23.05"; nixpkgs = { - overlays = [ outputs.overlays.default ]; + overlays = [ + outputs.overlays.default + (final: prev: + let + additions = final: _: import "${self}/pkgs/config" { + inherit self config lib; + pkgs = final; + homeConfig = config.home-manager.users.${config.swarselsystems.mainUser}; + }; + in + additions final prev + ) + ]; config = { allowUnfree = true; }; diff --git a/nix/overlays.nix b/nix/overlays.nix index 828aba2..1f8fdc2 100644 --- a/nix/overlays.nix +++ b/nix/overlays.nix @@ -9,7 +9,7 @@ in overlays = { default = final: prev: let - additions = final: _: import "${self}/pkgs" { pkgs = final; inherit self lib; } + additions = final: _: import "${self}/pkgs/flake" { pkgs = final; inherit self lib; } // { swarsel-nix = import inputs.swarsel-nix { pkgs = prev; diff --git a/nix/packages.nix b/nix/packages.nix index 233747c..2f2f525 100644 --- a/nix/packages.nix +++ b/nix/packages.nix @@ -17,7 +17,7 @@ inherit (self.outputs) lib; in { - packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import "${self}/pkgs" { inherit self lib pkgs; }); + packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import "${self}/pkgs/flake" { inherit self lib pkgs; }); }; perSystem = { pkgs, system, ... }: diff --git a/pkgs/config/cdr/default.nix b/pkgs/config/cdr/default.nix new file mode 100644 index 0000000..56b44df --- /dev/null +++ b/pkgs/config/cdr/default.nix @@ -0,0 +1,13 @@ +{ name, homeConfig, writeShellApplication, fzf, ... }: + +writeShellApplication { + inherit name; + runtimeInputs = [ fzf ]; + text = '' + DOCUMENT_DIR_WORK=${homeConfig.systemd.user.sessionVariables.DOCUMENT_DIR_WORK or ""} + DOCUMENT_DIR_PRIV=${homeConfig.systemd.user.sessionVariables.DOCUMENT_DIR_PRIV} + FLAKE=${homeConfig.home.sessionVariables.FLAKE} + + cd "$( (find "$DOCUMENT_DIR_WORK" "$DOCUMENT_DIR_PRIV" -maxdepth 1 && echo "$FLAKE") | fzf )" + ''; +} diff --git a/pkgs/config/default.nix b/pkgs/config/default.nix new file mode 100644 index 0000000..668619b --- /dev/null +++ b/pkgs/config/default.nix @@ -0,0 +1,11 @@ +{ self, homeConfig, lib, pkgs, ... }: +let + mkPackages = names: pkgs: builtins.listToAttrs (map + (name: { + inherit name; + value = pkgs.callPackage "${self}/pkgs/config/${name}" { inherit self name homeConfig; }; + }) + names); + packageNames = lib.swarselsystems.readNix "pkgs/config"; +in +mkPackages packageNames pkgs diff --git a/pkgs/bak/default.nix b/pkgs/flake/bak/default.nix similarity index 100% rename from pkgs/bak/default.nix rename to pkgs/flake/bak/default.nix diff --git a/pkgs/cdb/default.nix b/pkgs/flake/cdb/default.nix similarity index 100% rename from pkgs/cdb/default.nix rename to pkgs/flake/cdb/default.nix diff --git a/pkgs/cdw/default.nix b/pkgs/flake/cdw/default.nix similarity index 100% rename from pkgs/cdw/default.nix rename to pkgs/flake/cdw/default.nix diff --git a/pkgs/cura5/default.nix b/pkgs/flake/cura5/default.nix similarity index 100% rename from pkgs/cura5/default.nix rename to pkgs/flake/cura5/default.nix diff --git a/pkgs/default.nix b/pkgs/flake/default.nix similarity index 54% rename from pkgs/default.nix rename to pkgs/flake/default.nix index 4301f59..2bc3808 100644 --- a/pkgs/default.nix +++ b/pkgs/flake/default.nix @@ -3,9 +3,9 @@ let mkPackages = names: pkgs: builtins.listToAttrs (map (name: { inherit name; - value = pkgs.callPackage "${self}/pkgs/${name}" { inherit self name; }; + value = pkgs.callPackage "${self}/pkgs/flake/${name}" { inherit self name; }; }) names); - packageNames = lib.swarselsystems.readNix "pkgs"; + packageNames = lib.swarselsystems.readNix "pkgs/flake"; in mkPackages packageNames pkgs diff --git a/pkgs/e/default.nix b/pkgs/flake/e/default.nix similarity index 100% rename from pkgs/e/default.nix rename to pkgs/flake/e/default.nix diff --git a/pkgs/endme/default.nix b/pkgs/flake/endme/default.nix similarity index 100% rename from pkgs/endme/default.nix rename to pkgs/flake/endme/default.nix diff --git a/pkgs/eontimer/default.nix b/pkgs/flake/eontimer/default.nix similarity index 100% rename from pkgs/eontimer/default.nix rename to pkgs/flake/eontimer/default.nix diff --git a/pkgs/fhs/default.nix b/pkgs/flake/fhs/default.nix similarity index 100% rename from pkgs/fhs/default.nix rename to pkgs/flake/fhs/default.nix diff --git a/pkgs/fs-diff/default.nix b/pkgs/flake/fs-diff/default.nix similarity index 100% rename from pkgs/fs-diff/default.nix rename to pkgs/flake/fs-diff/default.nix diff --git a/pkgs/git-replace/default.nix b/pkgs/flake/git-replace/default.nix similarity index 100% rename from pkgs/git-replace/default.nix rename to pkgs/flake/git-replace/default.nix diff --git a/pkgs/github-notifications/default.nix b/pkgs/flake/github-notifications/default.nix similarity index 100% rename from pkgs/github-notifications/default.nix rename to pkgs/flake/github-notifications/default.nix diff --git a/pkgs/hm-specialisation/default.nix b/pkgs/flake/hm-specialisation/default.nix similarity index 100% rename from pkgs/hm-specialisation/default.nix rename to pkgs/flake/hm-specialisation/default.nix diff --git a/pkgs/kanshare/default.nix b/pkgs/flake/kanshare/default.nix similarity index 100% rename from pkgs/kanshare/default.nix rename to pkgs/flake/kanshare/default.nix diff --git a/pkgs/opacitytoggle/default.nix b/pkgs/flake/opacitytoggle/default.nix similarity index 100% rename from pkgs/opacitytoggle/default.nix rename to pkgs/flake/opacitytoggle/default.nix diff --git a/pkgs/pass-fuzzel/default.nix b/pkgs/flake/pass-fuzzel/default.nix similarity index 100% rename from pkgs/pass-fuzzel/default.nix rename to pkgs/flake/pass-fuzzel/default.nix diff --git a/pkgs/project/default.nix b/pkgs/flake/project/default.nix similarity index 100% rename from pkgs/project/default.nix rename to pkgs/flake/project/default.nix diff --git a/pkgs/quickpass/default.nix b/pkgs/flake/quickpass/default.nix similarity index 100% rename from pkgs/quickpass/default.nix rename to pkgs/flake/quickpass/default.nix diff --git a/pkgs/sshrm/default.nix b/pkgs/flake/sshrm/default.nix similarity index 100% rename from pkgs/sshrm/default.nix rename to pkgs/flake/sshrm/default.nix diff --git a/pkgs/swarsel-bootstrap/default.nix b/pkgs/flake/swarsel-bootstrap/default.nix similarity index 100% rename from pkgs/swarsel-bootstrap/default.nix rename to pkgs/flake/swarsel-bootstrap/default.nix diff --git a/pkgs/swarsel-build/default.nix b/pkgs/flake/swarsel-build/default.nix similarity index 100% rename from pkgs/swarsel-build/default.nix rename to pkgs/flake/swarsel-build/default.nix diff --git a/pkgs/swarsel-deploy/default.nix b/pkgs/flake/swarsel-deploy/default.nix similarity index 100% rename from pkgs/swarsel-deploy/default.nix rename to pkgs/flake/swarsel-deploy/default.nix diff --git a/pkgs/swarsel-displaypower/default.nix b/pkgs/flake/swarsel-displaypower/default.nix similarity index 100% rename from pkgs/swarsel-displaypower/default.nix rename to pkgs/flake/swarsel-displaypower/default.nix diff --git a/pkgs/swarsel-install/default.nix b/pkgs/flake/swarsel-install/default.nix similarity index 100% rename from pkgs/swarsel-install/default.nix rename to pkgs/flake/swarsel-install/default.nix diff --git a/pkgs/swarsel-instantiate/default.nix b/pkgs/flake/swarsel-instantiate/default.nix similarity index 100% rename from pkgs/swarsel-instantiate/default.nix rename to pkgs/flake/swarsel-instantiate/default.nix diff --git a/pkgs/swarsel-mgba/default.nix b/pkgs/flake/swarsel-mgba/default.nix similarity index 100% rename from pkgs/swarsel-mgba/default.nix rename to pkgs/flake/swarsel-mgba/default.nix diff --git a/pkgs/swarsel-postinstall/default.nix b/pkgs/flake/swarsel-postinstall/default.nix similarity index 100% rename from pkgs/swarsel-postinstall/default.nix rename to pkgs/flake/swarsel-postinstall/default.nix diff --git a/pkgs/swarsel-rebuild/default.nix b/pkgs/flake/swarsel-rebuild/default.nix similarity index 100% rename from pkgs/swarsel-rebuild/default.nix rename to pkgs/flake/swarsel-rebuild/default.nix diff --git a/pkgs/swarselcheck-niri/default.nix b/pkgs/flake/swarselcheck-niri/default.nix similarity index 100% rename from pkgs/swarselcheck-niri/default.nix rename to pkgs/flake/swarselcheck-niri/default.nix diff --git a/pkgs/swarselcheck/default.nix b/pkgs/flake/swarselcheck/default.nix similarity index 100% rename from pkgs/swarselcheck/default.nix rename to pkgs/flake/swarselcheck/default.nix diff --git a/pkgs/swarselzellij/default.nix b/pkgs/flake/swarselzellij/default.nix similarity index 100% rename from pkgs/swarselzellij/default.nix rename to pkgs/flake/swarselzellij/default.nix diff --git a/pkgs/t2ts/default.nix b/pkgs/flake/t2ts/default.nix similarity index 100% rename from pkgs/t2ts/default.nix rename to pkgs/flake/t2ts/default.nix diff --git a/pkgs/timer/default.nix b/pkgs/flake/timer/default.nix similarity index 100% rename from pkgs/timer/default.nix rename to pkgs/flake/timer/default.nix diff --git a/pkgs/ts2t/default.nix b/pkgs/flake/ts2t/default.nix similarity index 100% rename from pkgs/ts2t/default.nix rename to pkgs/flake/ts2t/default.nix diff --git a/pkgs/vershell/default.nix b/pkgs/flake/vershell/default.nix similarity index 100% rename from pkgs/vershell/default.nix rename to pkgs/flake/vershell/default.nix diff --git a/pkgs/waybarupdate/default.nix b/pkgs/flake/waybarupdate/default.nix similarity index 100% rename from pkgs/waybarupdate/default.nix rename to pkgs/flake/waybarupdate/default.nix diff --git a/pkgs/fullscreen/default.nix b/pkgs/fullscreen/default.nix deleted file mode 100644 index ca6080c..0000000 --- a/pkgs/fullscreen/default.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ name, writeShellApplication, sway, ... }: - -writeShellApplication { - inherit name; - runtimeInputs = [ sway ]; - text = '' - swaymsg '[app_id=at.yrlf.wl_mirror] move to workspace 14:T' - swaymsg '[app_id=at.yrlf.wl_mirror] fullscreen' - ''; -} diff --git a/secrets/certs/secrets.yaml b/secrets/certs/secrets.yaml index 6f70d30..6564dea 100644 --- a/secrets/certs/secrets.yaml +++ b/secrets/certs/secrets.yaml @@ -2,6 +2,7 @@ pia-vpn1-crl-pem: ENC[AES256_GCM,data:vIngU8HivUQpJLZyOVTeBTmlaDxfPnyTfPakYk7aEf pia-vpn1-ca-pem: ENC[AES256_GCM,data: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,iv:bIQdKQPSsaR7cY6mfTZdqQTowEcga4H9yzNANHKcNEw=,tag:oto4R2yeumVxKoPy+U2eKQ==,type:str] kanidm-self-signed-crt: ENC[AES256_GCM,data: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,iv:LIuJpGoxOCBX73ZyjIUl9mYVA0wcRdue8EJyfqQzcK0=,tag:5W2UVbOH3Lma99lVxDdkNw==,type:str] kanidm-self-signed-key: ENC[AES256_GCM,data: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,iv:p7TGpmls39IYix0rHgeeV+ngkQkXybrUtKQCOF+M8rk=,tag:lNmUlYzd/zxvCfpk50TXTw==,type:str] +harica-root-ca: ENC[AES256_GCM,data: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,iv:0FTPt+bXgzOngxxFqoP1Sg12j0BMk4pJj5JIsHWPIuQ=,tag:tigFlF0LxzG8Za5+kbG4fA==,type:str] sops: age: - recipient: age16lnmuuxfuxxtty3atnhut8wseppwnhp7rdhmxqd5tdvs9qnjffjq42sqyy @@ -67,8 +68,8 @@ sops: bHRhZnBtUXZybm9VT2Y3TGhjbCtsSVEKfEo8jXw9wQdncX1gWev5xxz4s9XRMrX0 OampKe7MO30BsocF2blkgRQqJe8aZqFgZt0AvSBc7OyuI3mRZMPCBQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-07-05T11:01:02Z" - mac: ENC[AES256_GCM,data:XnLmZ65mZqoTHQfSKdvPVr+IGb1mb0nFRQLBiVPSyKfg9ABlqwsht3sykR+enDkmIk1urRewpKvPRr1YyLKAezHaE2I5CQdRwMViGTxbtN18SCqlKcL6CgGzC7UzAI8A2jVqB6D9swCx63TEOwnaWySBFnQuOog58R43rhxcJJc=,iv:U0ZMZZyuRJVAE0el0tRAdvHS7qtqU+z2kN78XEZOW2k=,tag:TrPIoG7cxLBDgG4vXJ5NiQ==,type:str] + lastmodified: "2025-11-19T14:09:27Z" + mac: ENC[AES256_GCM,data:tZ6QzVPivueZiC9Qfb3KNZAv02QatgHRNnlM+Y0iV4BZkYoBjxeDojutizvAMwUarnubUdk5I6m2OZK1mvVDZKXyI6zALX4JMeT2xYQWRHYzHpOygLhhGwTFVhV+0C4jN+eJFF2cNf9lu7NuZI9ylZSOY8I3YKUl+l0l3CkXUl4=,iv:JSGOUq+j9T/NXspn70dfu0J4ISV6vVFZUe/Z1CirrJk=,tag:Hm9N55f9qMc056nSTR1piw==,type:str] pgp: - created_at: "2025-11-11T17:51:25Z" enc: |- @@ -102,4 +103,4 @@ sops: -----END PGP MESSAGE----- fp: 4BE7925262289B476DBBC17B76FD3810215AE097 unencrypted_suffix: _unencrypted - version: 3.10.2 + version: 3.11.0