From 272413627d21478bc0f174430c2713571859f871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20Schwarz=C3=A4ugl?= Date: Thu, 18 Dec 2025 17:29:25 +0100 Subject: [PATCH] docs: increase docs verbosity --- .github/README.md | 3 +- SwarselSystems.org | 253 +++--- index.html | 1911 +++++++++++++++++++++++++++----------------- 3 files changed, 1347 insertions(+), 820 deletions(-) diff --git a/.github/README.md b/.github/README.md index 62c7dc8..3af1d53 100644 --- a/.github/README.md +++ b/.github/README.md @@ -155,6 +155,7 @@ |⛏️ **Minecraft** | [Minecraft](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/minecraft.nix) | |☁️ **S3** | [Garage](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/garage.nix) | |πŸ•ΈοΈ **Nix Binary Cache** | [Attic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/attic.nix) | + |πŸ™ **Nix Build farm** | [Attic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/hydra.nix) | |πŸ”‘ **Cert-based SSH** | [OPKSSH](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/opkssh.nix) | |πŸ”¨ **Home Asset Management**| [Homebox](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/homebox.nix) | |πŸ‘€ **DNS** | [NSD](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/nsd.nix) | @@ -180,7 +181,7 @@ |πŸ“± **magicant** | Samsung Galaxy Z Flip 6 | Phone | |πŸ’Ώ **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts | |πŸ’Ώ **brickroad** | - | Kexec tarball for bootstrapping low-memory machines | - |❔ **chaotheatre** | - | Demo config for checking out this configuration | + |❔ **hotel** | - | Demo config for checking out this configuration | |❔ **toto** | - | Helper configuration for testing purposes | diff --git a/SwarselSystems.org b/SwarselSystems.org index e4643c6..d461752 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -46,13 +46,13 @@ For a beginner, I recommend to read this file like a book, from start to finish. This file is structured as follows: - [[#h:a86fe971-f169-4052-aacf-15e0f267c6cd][Introduction (no code)]] - This is the block you are currently in. It holds no code that actually builds the system, it just outlines the general approach and explains my rough mentality + This is the block you are currently in. It holds no code that actually builds the system, it just outlines the general approach and explains the rough design mentality. For simply understanding the code in here, reading this should not be necessary (feel free to skip to [[#h:c7588c0d-2528-485d-b2df-04d6336428d7][flake.nix]]) - [[#h:c7588c0d-2528-485d-b2df-04d6336428d7][flake.nix]] - This block holds everything related to the heart of the nix side of the configuration - the =flake.nix= file. + This block holds everything related to the heart of the nix side of the configuration - the =flake.nix= file. I am using [[https://github.com/hercules-ci/flake-parts][flake-parts]] to manage this flake, so different aspects of the configuration are handled by flake-part modules in different files. - [[#h:02cd20be-1ffa-4904-9d5a-da5a89ba1421][System]] - This section holds all configuration options that apply to NixOS or home-manager. In other words, here we are doing system and user level configuration. + This section holds all configuration options that apply to NixOS or home-manager. In other words, here we are doing system and user level configuration. In a way, I consider this the most important part of this file, as (nearly) all of the nix magic is going to happen here. - [[#h:ed4cd05c-0879-41c6-bc39-3f1246a96f04][Emacs]] This section defines my Emacs configuration. For a while, I considered to use rycee's =emacs-init= module ([[https://github.com/nix-community/nur-combined/blob/master/repos/rycee/hm-modules/emacs-init.nix]]) to manage my Emacs configuration; I have since come to the conclusion that this would be a bad idea: at the moment, even though it might seem as I am very bound to the configuration file that you are currently reading, if I ever decide to change how I run my system, I can simply take the generated =.nix= and =.el= files and put them wherever I need them. This file only simplifies that generation without putting further restrictions on my. If I were however to switch to =emacs-init= then I would be indeed to some level confined to the nix ecosystem with my Emacs configuration, as I would no longer have a valid =.org= file to manage it with, instead generating an =init.el= directly from nix code. I like to keep that level of freedom for potential future use. Also, you will notice there is no package system setup in this configuration. This is because packages are automatically handled on the NixOS side by parsing the generated =init.el= file for package installs. @@ -120,10 +120,7 @@ window.addEventListener('load', addDarkmodeWidget); This section hold code that can be templated at other parts of the configuration. This is mostly used for the NixOS side of the configuration where I define my host systems that usually have a lot in common. -- [[#h:8fc9f66a-7412-4091-8dee-a06f897baf67][Appendix A: Supplementary Files]] - This section holds files that are not written in nix but are still referenced in the configuration in some way. This is mostly used for configuration of programs that have no native nix support, like tridactyl. Note that shell scripts are still defined under their respective entry in [[#h:64a5cc16-6b16-4802-b421-c67ccef853e1][Packages]]. - -- Historical Note: Noweb-Ref blocks +- [[#h:dae0c5bb-edb7-4fe4-ae31-9f8f064cc53c][Appendix A: Noweb-Ref blocks]] These blocks were used in several places throughout the configurations, but not on all machines necessarily. For example, the theming section used need to be in a NixOS block on NixOS machines but in a home-manager block on non-NixOS. @@ -146,6 +143,13 @@ which can then be used in a block like: not that noweb-reffed blocks will not be indented correctly. You will want to account for that when checking your nix flake with the formatter of your choice. Personally, I have solved this issue using the functions defined in [[#h:59d4306e-9b73-4b2c-b039-6a6518c357fc][org-mode: Upon-save actions (Auto-tangle, export to html, formatting)]]. Originally, I also automatically exported to html there, but it incurred a too high memory penalty which made Emacs become sluggish over time. +- [[#h:8fc9f66a-7412-4091-8dee-a06f897baf67][Appendix B: Supplementary Files]] + This section holds files that are not written in nix but are still referenced in the configuration in some way. This is mostly used for configuration of programs that have no native nix support, like tridactyl. Note that shell scripts are still defined under their respective entry in [[#h:64a5cc16-6b16-4802-b421-c67ccef853e1][Packages]]. Over time, the goal is to reduce this section to a minimum, but things like the aforementioned tridactyl might stay for a long time, until we have a stable interface to configure browser plugins. + +- [[#h:8ea35dcc-ef94-4c10-9112-8be8efd6f424][Appendix C: Explanations to nix functions and operators]] + When I started to learn about nix, I found that journey quite arduous; while I disagree with the general public in that the documentation is too sparse, I will say that, while it is very good, reading (and understanding!) it requires a certain level of existing nix knowledge that one will problably not have when starging out. Hence, the goal of this document is to explain common nix functions as they come up in this document (I thing I wrote this before :sweat:), in hopes that you will be able to understand most of the code. When a new function appears for the first time, I will try to link to an entry in the appendix. + + ** TODO Structure of this flake :PROPERTIES: :CUSTOM_ID: h:2c5529ed-e6d9-44b6-b0d3-5bf96a6bed64 @@ -161,7 +165,7 @@ The structure of this flake as seen many revisions, however lately I have settle The corresponding configurations are automatically generated by =mkFullHostConfigs= and =mkHalfHostConfigs=. A "full" host either in the nixos or darwin folder, while a "half" host is in either of home or android. This has to do with the scheme in which these configurations are generated. - These folders hold in turn a number of folders, the actual configurations. At this time, the files stored in this folder are: + These folders hold on the first level a folder describing the machine archetype (=x86_64-linux= or =aarch64-linux= for linux, =x86_64-darwin= or =aarch64-darwin= for macs). Those folders then hold a number of folders, the actual configurations. At this time, the files stored in this folder are: - default.nix: This file holds the abstracted configuration of the host. This should mostly be enabling [[#h:f0f1c961-3e7a-47b8-99ab-1654bb45dffc][Profiles]] as well as setting some [[#h:f4f22166-e345-43e6-b15f-b7f5bb886554][Shared Configuration Options]]. - hardware-config.nix: @@ -169,7 +173,7 @@ The structure of this flake as seen many revisions, however lately I have settle - disk-config.nix Holds the aforementioned filesystem configuration and is applied using [[https://github.com/nix-community/disko][disko]]. - - The hosts// folders may also have a =secrets= folder, under which a single file =pii.nix.enc= can be stored. As the name suggests, this file should be encrypted. Specifically, it needs to be a [[https://github.com/getsops/sops][sops]]-encrypted file (sops does not seem to suggest a file ending other than .yml or others, which is not verbose enough for me, so I went with =.enc=). This file should have the structure of a nix expression, e.g.: + - The hosts// folders may also have a =secrets= folder, under which files of the ending =.nix.enc= may be stored. As the name suggests, these files should be encrypted. Specifically, they need to be [[https://github.com/getsops/sops][sops]]-encrypted files (sops does not seem to suggest a file ending other than .yml or others, which is not verbose enough for me, so I went with =.enc=). This should have the structure of a nix expression, e.g.: #+begin_src nix-ts :tangle no { @@ -182,51 +186,59 @@ The structure of this flake as seen many revisions, however lately I have settle Using the mechanisms in [[#h:82b8ede2-02d8-4c43-8952-7200ebd4dc23][PII management]] (which in turn uses [[#h:87c7893e-e946-4fc0-8973-1ca27d15cf0e][extra-builtins]] and [[#h:315e6ef6-27d5-4cd8-85ff-053eabe60ddb][sops-decrypt-and-cache]]), these files are decrypted during evaluation time and stored under a persistent directory. As the name suggests, I am using these files to store personally identifiable information - these "secrets" are stored world-readable in the nix store. As such, this should not be used to store important secrets, but rather information that you would not like everyone on the internet to easily find in your git repo. + Other than that, the =secrets= folder will also be used to store conventional (decryted at activation-time) sops-encrypted secrets in the standard =.yaml= / =.toml= / =.ini= formats. + - =modules= This folder holds the most part of the actual system configuration done in this repository. At some point I thought it was cool to have my whole configuration exposed under the flakes =nixosModules=, which is indeed achieved (its usefulness is however debatable). In any way, this folder splits up as: - nixos: Holds true NixOS configuration - home: Holds configuration to be used by home-manager (either as a NixOS submodule or not) - - darwin: Holds configuration for nix-darwin. This folder further splits up into a nixos and a home folder, which hold respective nix or home-manager configuration for nix-darwin. - - iso: Holds specific configuration for my installer ISO that I do not want to have loaded in the rest of the configuration. + - shared: This is for configuraion bits that are to be used by both types. The nixos and home folders further split up: - common: Configuration that can be used by all hosts (TODO: this currently includes configuration used by my user devices, which will mostly not be used by servers) - server: Configuration to be used on servers + - darwin: Holds configuration for nix-darwin. - optional: Configuration that will be used rather rarely - This structure is very optionated and highly subjective. I will possibly change this in the future. + This structure is very optionated and highly subjective. I will possibly change this in the future. - By themselves, most of the files in the modules folder will not do anything. In order for them to do something, their corresponding =config.swarselsystems.modules= attribute needs to be enabled. This is done using... + By themselves, most of the files in the modules folder will not do anything. In order for them to do something, their corresponding =config.swarselmodules= attribute needs to be enabled. This is partly done using... - - =profiles=: This folder splits up into =home= and =nixos= subfolders, where groupings of module enablers are stored for the respective home and nix setups. Note that =home= profiles are also used in NixOS setups (extensively even)! + - =profiles=: This folder splits up into =home= and =nixos= subfolders, where groupings of module enablers are stored for the respective home and nix setups. Note that =home= profiles are also used in NixOS setups (extensively even)! This is used to quickly enable common configuration for a machine use, e.g. the [[#h:dfc076fd-ee74-4663-b164-653370c52b75][Server]] profile. - - =nix=: This special folder holds mostly =.nix= files that are not automatically loaded, but rather setup specific things that affect most of the flake. For example, here lies the aforementioned [[#h:87c7893e-e946-4fc0-8973-1ca27d15cf0e][extra-builtins]] as well as the setup for the [[*Globals][Globals]] system. TODO: Move flake-parts units there and explain them here. + - =nix=: This special folder holds mostly =.nix= files that are not automatically loaded, but rather setup specific things that affect most of the flake. For example, here lies the aforementioned [[#h:87c7893e-e946-4fc0-8973-1ca27d15cf0e][extra-builtins]] as well as the setup for the [[*Globals][Globals]] system. Also in here are the flake-parts files that you read about earlier. This gives the following functionality: + - =lib=: I define some utility functions that I add to the nixpkgs library under the =swarselsystems= attribute set. An example would be the =mkIfElse= function. + - =checks=: As part of a [[#h:4d0548db-99b2-4e07-b762-6d86fbb26d4c][Devshell (checks)]], I declare pre-commit hooks that should run before I push changes to my repo. + - =overlays=: Here we also define the main (default) overlay I am using in my configuration. It is responsible for adding my defined packages and modifications to the final nixpkgs. Also I add some other conveniences like all past stable nixpkgs and some other package sets. + - =apps=: I also define [[#h:52e1fae8-0e8c-4be6-a6ce-758ada652dd3][Apps]], which is an output of derivations that can be called by =nix run= without having the flake locally - this is mostly used for my =swarsel-*= utilities. + - =topology=: I also created a diagram of my infrastructure using [[https://github.com/oddlama/nix-topology][nix-topology]]. While I do not update this too often, this (I think) can quickly give a good overview of the scope of this flake as well as its services. - - =lib=: This folder holds utility functions that I add to the nixpkgs library under the =swarselsystems= attribute set. An example would be the =mkIfElse= function. + - =pkgs=: This folder holds derivations (mostly packages) that I define myself. This is mostly used to grab versions that are not (yet) in nixpkgs, or modified versions of another package. Each derivation in this folder is in turn in its own folder which holds a defautlt.nix. Using the mechanism in [[#h:64a5cc16-6b16-4802-b421-c67ccef853e1][Packages]], these are automatically built and available to all configurations (packages still need to be installed e.g. in =environment.systemPackages=). Note that the folder at the top level splits up in =config= and =flake= subdirectories: + - The =config= dir is used for packages that need the actual config of the machine where they run in order to be built. These packages cannot simply be released as a flake output (or better, it would not make a lot of sense). Instead, these are added within the configuration as an overlay - - =pkgs=: This folder holds derivations (mostly packages) that I define myself. This is mostly used to grab versions that are not (yet) in nixpkgs, or modified versions of another package. Each derivation in this folder is in turn in its own folder which holds a defautlt.nix. Using the mechanism in [[#h:64a5cc16-6b16-4802-b421-c67ccef853e1][Packages]], these are automatically built and available to all configurations (packages still need to be installed e.g. in =environment.systemPackages=) + - The =flake= dir is used for the conventional packages that I described above. - - =checks=: Holds a file that defines my pre-commit-hook checks. TODO: move this to /nix probably + - =files=: This is kind of a catchall folder that holds (nearly) all non-nix files. It mostly holds blocks created in [[#h:8fc9f66a-7412-4091-8dee-a06f897baf67][Appendix B: Supplementary Files]], but also some more specific directories: + - =scripts=: This folder holds a bunch of shell scripts that I use for various tasks. Nearly all of these are made into a derivation using =pkgs.writeShellApplication=. In the future (TODO?), I might convert these to native nix, but in the past I kept the as true shellfiles in case I ever wanted to move away from nix. This is becoming less and less likely, however. And even in case that this would happen, I could retrieve these files from the nix store and would simply have to remove the nix store paths. + - =wallpaper=: Holds my wallpapers and profile pictures :) + - =topology-images=: Holds pictures used by [[#h:391e7712-fef3-4f13-a3ed-d36e228166fd][Topology]] :) - - =scripts=: This folder holds a bunch of shell scripts that I use for various tasks. Nearly all of these are made into a derivation using =pkgs.writeShellApplication=. In the future (TODO?), I might convert these to native nix, but in the past I kept the as true shellfiles in case I ever wanted to move away from nix. This is becoming less and less likely, however. And even in case that this would happen, I could retrieve these files from the nix store and would simply have to remove the nix store paths. + - =secrets=: Unlike the similar folder under =hosts=, this folder holds sops-encrypted secrets and PIIs that are used by a number of hosts that is greater than one. - - =secrets=: Unlike the similar folder under =hosts=, this folder holds actual sops-encrypted secrets that are created at activation time and not in the nix store. The folder splits up into a bunch of folders, as well as a =repo= folder, which holds another =pii.nix.enc=, which holds global PII's, and a =certs= folder that holds some longer certificate style secrets. + - =install=: This folder holds another [[#h:1d4514b4-e952-4faf-b30e-d89e73a526c6][Installer flake]]. That flake pulls in the =nixosConfigurationsMinimal= that are defined in [[#h:5c5bf78a-9a66-436f-bd85-85871d9d402b][Hosts]] of the main flake, which enables me to build an extemely reduced configuration when I deploy a new host for the first time - this is used by [[#h:74db57ae-0bb9-4257-84be-eddbc85130dd][swarsel-bootstrap]] in the first installation step. It also holds the configuration of the two installer images that I use to deploy this flake: + - [[#h:8583371d-5d47-468b-84ba-210aad7e2c90][Drugstore (ISO installer config)]]: This is the general installer ISO that I use whenever I can when I want to deploy a new host. It has a few conveniences like some of my utility programs for figuring out some dependencies or network quirks, as well as my public ssh keys so that I can immediately login to them. - - =overlays=: This holds a single =default.nix= that defines the overlay I am using in my configuration. It is responsible for adding my defined packages and modifications to the final nixpkgs. Also I add some other conveniences like all past stable nixpkgs and some other package sets. + - [[#h:e9fe580c-f1b2-4d7b-aaff-bbdf89a8c9f9][Brick Road (kexec image)]]: This is a kexec tarball that can be used by [[#h:74db57ae-0bb9-4257-84be-eddbc85130dd][swarsel-bootstrap]] in case that I need to deploy to a machine that has less than 1GB of RAM. It is basically just an even more stripped down version of the detault one used by nixos-anywhere, but notably I added cryptsetup so that it can be used when setting up an encrypted device using disko. - - =programs=: This folder holds configurations for various programs (most notably emacs' =init.el= and =early-init.el=), that are being rendered using org-babel and loaded using nix. - - - =wallpaper=: Holds wallpapers and profile pictures. - - - =topology=: Holds the configuration used by [[https://github.com/oddlama/nix-topology][nix-topology]]. + - =.github=: Canonically, this holds github related files like the [[#h:bf3e6fc0-a95a-46d0-9305-0d1068b2f1ec][GitHub Readme]] and some workflows. ** Hosts :PROPERTIES: :CUSTOM_ID: h:48e0cb2c-e412-4ae3-a244-80a8c09dbb02 :END: -Here I give a brief overview over the hostmachines that I am using. This is held in markdown so that I can render it into my GitHub README. +Here I give a brief overview over the host machines that I am using. This is held in markdown so that I can render it into my [[#h:bf3e6fc0-a95a-46d0-9305-0d1068b2f1ec][GitHub Readme]] without further effort. #+begin_src markdown :tangle no :noweb-ref hosts | Name | Hardware | Use | @@ -247,7 +259,7 @@ Here I give a brief overview over the hostmachines that I am using. This is held |πŸ“± **magicant** | Samsung Galaxy Z Flip 6 | Phone | |πŸ’Ώ **drugstore** | - | NixOS-installer ISO for bootstrapping new hosts | |πŸ’Ώ **brickroad** | - | Kexec tarball for bootstrapping low-memory machines | - |❔ **chaotheatre** | - | Demo config for checking out this configuration | + |❔ **hotel** | - | Demo config for checking out this configuration | |❔ **toto** | - | Helper configuration for testing purposes | #+end_src @@ -256,6 +268,8 @@ Here I give a brief overview over the hostmachines that I am using. This is held :CUSTOM_ID: h:3bb92528-c61c-4b8d-8214-bf2a40baaa32 :END: +This is meant to give a brief overview over the main programs/components that I use on a daily basis on my client machines. This should be mostly useful for people wanting to rice their config, or people who believed this repos title and are looking for =.dotfiles= :p + #+begin_src markdown :tangle no :noweb-ref programs | Topic | Program | |---------------|-----------------------------------------------------------------------------------------------------------------------------| @@ -276,6 +290,8 @@ Here I give a brief overview over the hostmachines that I am using. This is held :CUSTOM_ID: h:191e82b6-6ae5-4ec8-ae6d-dc683ce325d9 :END: +This is a comprehensive list of the services/components ran by my server machines. + #+begin_src markdown :tangle no :noweb-ref services | Topic | Program | |----------------------------|----------------------------------------------------------------------------------------------------------------| @@ -304,6 +320,7 @@ Here I give a brief overview over the hostmachines that I am using. This is held |⛏️ **Minecraft** | [Minecraft](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/minecraft.nix) | |☁️ **S3** | [Garage](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/garage.nix) | |πŸ•ΈοΈ **Nix Binary Cache** | [Attic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/attic.nix) | + |πŸ™ **Nix Build farm** | [Attic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/hydra.nix) | |πŸ”‘ **Cert-based SSH** | [OPKSSH](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/opkssh.nix) | |πŸ”¨ **Home Asset Management**| [Homebox](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/homebox.nix) | |πŸ‘€ **DNS** | [NSD](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/nsd.nix) | @@ -315,7 +332,14 @@ Here I give a brief overview over the hostmachines that I am using. This is held :CUSTOM_ID: h:ed34ee4d-31f9-4d27-bc6e-ba37ee502d5a :END: -#+begin_src markdown :noweb yes :exports both :results html +In the [[#h:a86fe971-f169-4052-aacf-15e0f267c6cd][Introduction (no code)]], I mentioned that this is a nearly fully declarative config. In fact, most client configs are in one way or another not fully declarative. I use oneshotting systemd services + sentinel files for most such tasks (which makes them declarative!), but some of them I would rather perform manually once. This mainly concerns work related things. + +Whenever I encounter a configuration bit that needs manual steps, I use a [[#h:dae0c5bb-edb7-4fe4-ae31-9f8f064cc53c][Appendix A: Noweb-Ref blocks]] to tangle that bit of information into a central place (here). I discern between the following scenarios: + - =setup=: Used in a standard NixOs + home-manager deployment + - =worksetup=: Stuff to be done only on work machines + - =homemanageronlysetup=: Steps that are needed only on machines that are not running NixOs. + +#+begin_src markdown :noweb yes :exports results :results html These steps are required when setting up a normal NixOS host: <> @@ -365,14 +389,20 @@ 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` -#+end_export +#+end -** Current issues +** TODO Current issues :PROPERTIES: :CUSTOM_ID: h:b562adaf-536c-4267-88a5-026d8a0cda61 :END: -#+begin_src markdown :noweb yes :exports both :results html +Besides the manual steps outlined above, sometimes things break when I update this flake. The fix, for me, is most of the times one of these two: + - instead of the broken package, use the package from the latest stable nixpkgs release where the package is still functoning (this is why I pull all of these in as inputs) + - if the broken component is critical, I perform manual patches/overrides. + +In order to keep track of these changes, I gather them here in a similar style to what you saw in [[#h:ed34ee4d-31f9-4d27-bc6e-ba37ee502d5a][Manual steps when setting up a new machine]]. I simply prefix them with the date and check them after a while to see if things got better. TODO: this list is not comprehensive probably + +#+begin_src markdown :noweb yes :exports results :results html Currently, these adaptions are made to the configuration to account for bugs in upstream repos: <> @@ -419,11 +449,11 @@ Nowadays, I use flake-parts to manage my flake. It allows me to conveniently spl :CUSTOM_ID: h:aee5ec75-7ca6-40d8-b6ac-a3e7e33a474b :END: -In general, a nix flake consists of one or more inputs and several outputs. The inputs are used to define where nix should be looking for packages, modules, and more. The outputs generate expressions that can be used in .nix files as well as system configurations using these files. +In general, a nix flake consists of one or more inputs and several outputs. The inputs are used to define where nix should be looking for packages, modules, and more (the most common input is =nixpkgs=, which provides a lot of packages, library functions and modules). The outputs generate expressions that can be used in .nix files as well as system configurations using these files. In the start, I enable some public cache repositories. This saves some time during rebuilds because it avoids building as many packages from scratch - this is mainly important for community flakes like =emacs-overlay=, which basically would trigger a rebuild whenever updating the flake. The repository does of course not hold everything, but it lightens the pain. It would look cleaner if this were to be used only inside a nix configuration block of an actual system, but I want these caches to be used for e.g. app calls as well. -In many flakes, you see a structure like this: =outputs = inputs@ [...]=, the =inputs@= makes it so that all inputs are automatically passed to the outputs and can be called as =inputs.=, whereas explicit arguments may just be called by using ==. For most flakes this is fully sufficient, as they do not need to be called often and it saves me maintainance effort with this file. In fact, I also used to make use of this mechanism. However, using flake-parts, all I really need for the outputs function is inputs, which is why my outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } { [...] ). Note that flake-parts must inherit these inputs and no other arguments are expected. +In many flakes, you see a structure like this: =outputs = inputs@ [...]=, the =inputs@= makes it so that all inputs are automatically passed to the outputs and can be called as =inputs.=, whereas explicit arguments may just be called by using == (for a more detailed explanation, s). For most flakes this is fully sufficient, as they do not need to be called often and it saves me maintainance effort with this file. In fact, I also used to make use of this mechanism. However, using flake-parts, all I really need for the outputs function is inputs, which is why my outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } { [...] ). Note that flake-parts must inherit these inputs and no other arguments are expected. In this section I am creating some attributes that define general concepts of my configuration: @@ -450,15 +480,15 @@ Here, just add the input names, urls and other options that are needed, like =ni A short overview over each input and what it does: - [[https://github.com/NixOS/nixpkgs][nixpkgs]] - This is the base repository that I am following for all packages. I follow the unstable branch. + This is the base repository that I am following for all packages. I follow the unstable branch. Also I pull in some older revisions of nixpkgs stable for various purposes. - [[https://github.com/nix-community/home-manager][home-manager]] This handles user-level configuration and mostly provides dotfiles that are generated and symlinked to =~/.config/=. -- [[https://github.com/Swarsel/.dotfiles][swarsel]] - This pulls in the very dotfiles you are currently reading. I am adding this to the flake registry in order to have easier access to my customizations in nix calls, for example =nix-instantiate= +- [[https://github.com/Swarsel/swarsel-nix][swarsel-nix]] + This pulls in the very dotfiles you are currently reading. I am adding this to the flake registry in order to - [[https://github.com/nix-community/NUR][NUR]] The nix user repository contains user provided modules, packages and expressions. These are not audited by the nix community, so be aware of supply chain vulnerabilities when using those. I am only really using rycee's firefox addons from there which saves me a lot of hassle, and it seems to be a safe resource. - [[https://github.com/nix-community/nixGL][nixGL]] - This solves the problem that nix has with "OpenGL", as libraries are not linked and programs will often fail to find drivers. But I do not fully understand what it does. All I know is that I usually have to use this on non-NIxoS systems. + This solves the problem that nix has with =OpenGL=, as libraries are not linked and programs will often fail to find drivers. Nowadays, this is included in the [[#h:90af1862-90b3-4c93-8730-2443bc62986a][nixGL]] module of home-manager, but even that requres a binary for nixGL, which is what I pull from this input. - [[https://github.com/danth/stylix][stylix]] As described before, this handles all theme related options. - [[https://github.com/Mic92/sops-nix][sops-nix]] @@ -489,10 +519,33 @@ A short overview over each input and what it does: Provides access to several checks that can be hooked to be run before several stages in the process. - [[https://github.com/oddlama/nix-topology][nix-topology]] This automatically creates a topology diagram of my configuration. -- flake-parts +- [[https://github.com/hercules-ci/flake-parts][flake-parts]] The aforementioned system that allows for more convenient flake crafting. -- devshell +- [[https://github.com/numtide/devshell][devshell]] This provides devshell support for flake-parts +- [[https://github.com/Gerg-L/spicetify-nix][spicetify]] + This is a improved spotify client. This provides a NixOs module to manage it. +- [[https://github.com/sodiboo/niri-flake][niri-flake]] + This is an optional input that I reserve to use in the future; it provides a module to manage [[#h:06e77ca4-28ff-4cfd-bc60-b7fd848bfedb][Niri]] in a way that is way more all-encompassing than the current modules in nixpkgs/home-manager. However, I do not include this by default as this leads to a full compilation of latest niri - this is used only be the niri config evaluator, but is even built if niri is not included in the final config. Also, the binary cache provided by this flake does usually not have the latest niri cached. +- [[https://github.com/microvm-nix/microvm.nix][microvm.nix]] + This flake brings support for microvms to nix. This is basically a more isolated alternative to classic NixOs containers, while keeping most of their benefits. +- [[https://github.com/numtide/treefmt-nix][treefmt-nix]] + This allows to specify a range of formatters for different languages and aspects which can all be run upon =nix fmt=. +- [[https://github.com/oddlama/nixos-extra-modules][nixos-extra-modules]] + This is a collection of modules that add some qualitative functions to several aspects of nix, for example: + - microvm management + - wireguard support for nix-topology + - some extensions to the network library + + At the moment I am not using the full range of modules, but my usage keeps increasing steadily. Using this module forced me to make some adjustments in my config, namely exposing the =nodes= output in [[#h:48e0cb2c-e412-4ae3-a244-80a8c09dbb02][Hosts]]. +- [[https://github.com/nix-community/dns.nix][dns.nix]] + This adds a module that helps with creating zone files (like [[#h:dc1dbc54-46f7-406d-a551-527e97439614][nsd (dns) - site1]]). This flake was competing with [[https://github.com/Janik-Haag/nixos-dns/][NixOS-DNS]] for my favour - while the latter adds many nice utilities that generage records straight from a host configuration, I prefer to do this myself using the [[#h:af83893d-c0f9-4b45-b816-4849110d41b3][Globals]] + [[#h:5c3027b4-ba66-445e-9c5f-c27e332c90e5][Share configuration between nodes (automatically active)]] systems. In the end, I just tried out dns.nix without giving NixOS-DNS a chance and it has been working great, but I believe NixOS-DNS still deserves a mention here, as it would have been a great fit as well, most likely. +- [[https://github.com/Infinidoge/nix-minecraft][nix-minecraft]] + This adds a module that makes it easier to manage (modded) minecraft servers. At the moment, it does not really work with Forge 1.20.1 (which is what my server is running), so I am not making full use of it right now, but I keep close watch on it every day. +- [[https://gitlab.com/simple-nixos-mailserver/nixos-mailserver][nixos-mailserver]] + This adds a module that basically sets up a full mailserver stack. Apart of DNS records and a few extra steps for e.g. a web client, this is one-stop solution that has been working greatly for me. +- [[https://github.com/NixOS/hydra][hydra]] + The hydra module already exists in nixpkgs - however, because, I am also using [[https://github.com/shlevy/nix-plugins][nix-plugins]], I need to build all tools that are using nix against a specific nix version (this is also why I pull in =nix-eval-jobs= as a flake input). #+begin_src nix :noweb yes :tangle flake.nix { @@ -2871,8 +2924,9 @@ This is my main server that I run at home. It handles most tasks that require bi isLinux = true; isNixos = true; isSwap = false; - rootDisk = "/dev/sda"; + rootDisk = "/dev/disk/by-id/ata-TS128GMTS430S_H537280456"; withMicroVMs = false; + server.localNetwork = "lan"; }; } // lib.optionalAttrs (!minimal) { @@ -2881,38 +2935,8 @@ This is my main server that I run at home. It handles most tasks that require bi server = true; }; - swarselmodules = { - server = { - 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; - }; + swarselmodules.server = { + nginx = lib.mkForce false; }; microvm.vms = @@ -21414,20 +21438,29 @@ When setting up a new machine: }; } { - # work main screen + # work side screen output = { criteria = "HP Inc. HP 732pk CNC4080YL5"; scale = 1.0; mode = "3840x2160"; + transform = "270"; }; } + # { + # # work side screen + # output = { + # criteria = "Hewlett Packard HP Z24i CN44250RDT"; + # scale = 1.0; + # mode = "1920x1200"; + # transform = "270"; + # }; + # } { - # work side screen + # work main screen output = { - criteria = "Hewlett Packard HP Z24i CN44250RDT"; + criteria = "HP Inc. HP Z32 CN41212T55"; scale = 1.0; - mode = "1920x1200"; - transform = "270"; + mode = "3840x2160"; }; } { @@ -21435,28 +21468,28 @@ When setting up a new machine: name = "lidopen"; exec = [ "${pkgs.swaybg}/bin/swaybg --output '${config.swarselsystems.sharescreen}' --image ${config.swarselsystems.wallpaper} --mode ${config.stylix.imageScalingMode}" - "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP 732pk CNC4080YL5' --image ${self}/files/wallpaper/botanicswp.png --mode ${config.stylix.imageScalingMode}" - "${pkgs.swaybg}/bin/swaybg --output 'Hewlett Packard HP Z24i CN44250RDT' --image ${self}/files/wallpaper/op6wp.png --mode ${config.stylix.imageScalingMode}" + "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP Z32 CN41212T55' --image ${self}/files/wallpaper/botanicswp.png --mode ${config.stylix.imageScalingMode}" + "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP 732pk CNC4080YL5' --image ${self}/files/wallpaper/op6wp.png --mode ${config.stylix.imageScalingMode}" ]; outputs = [ { criteria = config.swarselsystems.sharescreen; status = "enable"; scale = 1.5; - position = "1462,0"; + position = "2560,0"; } { criteria = "HP Inc. HP 732pk CNC4080YL5"; - scale = 1.4; + scale = 1.0; mode = "3840x2160"; - position = "-1280,0"; + position = "-3440,-1050"; + transform = "270"; } { - criteria = "Hewlett Packard HP Z24i CN44250RDT"; + criteria = "HP Inc. HP Z32 CN41212T55"; scale = 1.0; - mode = "1920x1200"; - transform = "90"; - position = "-2480,0"; + mode = "3840x2160"; + position = "-1280,0"; } ]; }; @@ -21493,8 +21526,8 @@ When setting up a new machine: profile = { name = "lidclosed"; exec = [ - "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP 732pk CNC4080YL5' --image ${self}/files/wallpaper/botanicswp.png --mode ${config.stylix.imageScalingMode}" - "${pkgs.swaybg}/bin/swaybg --output 'Hewlett Packard HP Z24i CN44250RDT' --image ${self}/files/wallpaper/op6wp.png --mode ${config.stylix.imageScalingMode}" + "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP Z32 CN41212T55' --image ${self}/files/wallpaper/botanicswp.png --mode ${config.stylix.imageScalingMode}" + "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP 732pk CNC4080YL5' --image ${self}/files/wallpaper/op6wp.png --mode ${config.stylix.imageScalingMode}" ]; outputs = [ { @@ -21503,16 +21536,16 @@ When setting up a new machine: } { criteria = "HP Inc. HP 732pk CNC4080YL5"; - scale = 1.4; + scale = 1.0; mode = "3840x2160"; - position = "-1280,0"; + position = "-3440,-1050"; + transform = "270"; } { - criteria = "Hewlett Packard HP Z24i CN44250RDT"; + criteria = "HP Inc. HP Z32 CN41212T55"; scale = 1.0; - mode = "1920x1200"; - transform = "270"; - position = "-2480,0"; + mode = "3840x2160"; + position = "-1280,0"; } ]; }; @@ -21697,25 +21730,35 @@ When setting up a new machine: # output = "DP-7"; output = name; }; - work_back_right = rec { + work_middle_middle_main = rec { name = "HP Inc. HP Z32 CN41212T55"; mode = "3840x2160"; scale = "1"; - position = "5120,0"; + position = "-1280,0"; workspace = "1:δΈ€"; # output = "DP-3"; output = name; }; - work_middle_middle_main = rec { + # work_middle_middle_main = rec { + # name = "HP Inc. HP 732pk CNC4080YL5"; + # mode = "3840x2160"; + # scale = "1"; + # position = "-1280,0"; + # workspace = "11:M"; + # # output = "DP-8"; + # output = name; + # }; + work_middle_middle_side = rec { name = "HP Inc. HP 732pk CNC4080YL5"; mode = "3840x2160"; + transform = "270"; scale = "1"; - position = "-1280,0"; - workspace = "11:M"; + position = "-3440,-1050"; + workspace = "12:S"; # output = "DP-8"; output = name; }; - work_middle_middle_side = rec { + work_middle_middle_old = rec { name = "Hewlett Packard HP Z24i CN44250RDT"; mode = "1920x1200"; transform = "270"; @@ -23014,6 +23057,7 @@ This program sets up a new NixOS host remotely. It also takes care of secret man function cleanup() { rm -rf "$temp" + rm -rf /tmp/disko-password } trap cleanup exit @@ -23117,7 +23161,7 @@ This program sets up a new NixOS host remotely. It also takes care of secret man LOCKED="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.node.lockFromBootstrapping)" if [[ $LOCKED == "true" ]]; then - red "THIS SYSTEM IS LOCKED FROM BOOTSTRAPPING - set `node.lockFromBootstrapping = lib.mkForce false;` to proceed" + red "THIS SYSTEM IS LOCKED FROM BOOTSTRAPPING - set 'node.lockFromBootstrapping = lib.mkForce false;' to proceed" exit fi @@ -23207,6 +23251,7 @@ This program sets up a new NixOS host remotely. It also takes care of secret man green "Please confirm passphrase:" read -rs luks_passphrase_confirm if [[ $luks_passphrase == "$luks_passphrase_confirm" ]]; then + echo "$luks_passphrase" > /tmp/disko-password $ssh_root_cmd "echo '$luks_passphrase' > /tmp/disko-password" break else @@ -23295,7 +23340,7 @@ This program sets up a new NixOS host remotely. It also takes care of secret man vim "${git_root}"/.sops.yaml fi green "Updating all secrets files to reflect updates .sops.yaml" - sops updatekeys --yes --enable-local-keyservice "${git_root}"/hosts/nixos/"$target_arch"/"$target_hostname"/secrets/* + sops updatekeys --yes --enable-local-keyservice "${git_root}"/hosts/nixos/"$target_arch"/"$target_hostname"/secrets/* || true # -------------------------- 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 @@ -23366,6 +23411,8 @@ This program sets up a new NixOS host remotely. It also takes care of secret man if yes_or_no "Reboot now?"; then $ssh_root_cmd "reboot" fi + + rm -rf /tmp/disko-password #+end_src #+RESULTS: diff --git a/index.html b/index.html index 2b48665..40c054a 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 @@ -210,7 +210,7 @@
  • 1.5. Programs
  • 1.6. Services
  • 1.7. Manual steps when setting up a new machine
  • -
  • 1.8. Current issues
  • +
  • 1.8. TODO Current issues
  • 2. flake.nix @@ -309,25 +309,25 @@
  • 3.1.3.2.3. disko
  • -
  • 3.1.3.3. Stoicclub (OCI) +
  • 3.1.3.3. Stoicclub (OCI)
  • -
  • 3.1.3.4. Liliputsteps (OCI) +
  • 3.1.3.4. Liliputsteps (OCI)
  • -
  • 3.1.3.5. Twothreetunnel (OCI) +
  • 3.1.3.5. Twothreetunnel (OCI)
  • 3.1.3.6. Eagleland (Hetzner) @@ -393,7 +393,7 @@
  • 3.2.2.8. Pipewire
  • 3.2.2.9. Common network settings
  • 3.2.2.10. sops
  • -
  • 3.2.2.11. Remote building
  • +
  • 3.2.2.11. Remote building
  • 3.2.2.12. Theme (stylix)
  • 3.2.2.13. Programs (including zsh setup)
  • 3.2.4. Darwin @@ -507,10 +508,10 @@
  • 3.2.5.8. AMD GPU
  • 3.2.5.9. Hibernation
  • 3.2.5.10. work
  • -
  • 3.2.5.11. Uni
  • +
  • 3.2.5.11. Uni
  • 3.2.5.12. microvm-host
  • 3.2.5.13. microvm-guest
  • -
  • 3.2.5.14. systemd-networkd (server)
  • +
  • 3.2.5.14. systemd-networkd (server)
  • @@ -633,36 +634,37 @@
  • 3.4.6.4. hm-specialisation
  • 3.4.6.5. cdw
  • 3.4.6.6. cdb
  • -
  • 3.4.6.7. bak
  • -
  • 3.4.6.8. timer
  • -
  • 3.4.6.9. e
  • -
  • 3.4.6.10. command-not-found
  • -
  • 3.4.6.11. swarselcheck
  • -
  • 3.4.6.12. swarselcheck-niri
  • -
  • 3.4.6.13. swarselzellij
  • -
  • 3.4.6.14. waybarupdate
  • -
  • 3.4.6.15. opacitytoggle
  • -
  • 3.4.6.16. fs-diff
  • -
  • 3.4.6.17. github-notifications
  • -
  • 3.4.6.18. kanshare
  • -
  • 3.4.6.19. swarsel-bootstrap
  • -
  • 3.4.6.20. swarsel-rebuild
  • -
  • 3.4.6.21. swarsel-install
  • -
  • 3.4.6.22. swarsel-postinstall
  • -
  • 3.4.6.23. t2ts
  • -
  • 3.4.6.24. ts2t
  • -
  • 3.4.6.25. vershell
  • -
  • 3.4.6.26. eontimer
  • -
  • 3.4.6.27. project
  • -
  • 3.4.6.28. fhs
  • -
  • 3.4.6.29. swarsel-displaypower
  • -
  • 3.4.6.30. swarsel-mgba
  • -
  • 3.4.6.31. swarsel-deploy
  • -
  • 3.4.6.32. swarsel-build
  • -
  • 3.4.6.33. swarsel-instantiate
  • -
  • 3.4.6.34. sshrm
  • -
  • 3.4.6.35. endme
  • -
  • 3.4.6.36. git-replace
  • +
  • 3.4.6.7. prstatus
  • +
  • 3.4.6.8. bak
  • +
  • 3.4.6.9. timer
  • +
  • 3.4.6.10. e
  • +
  • 3.4.6.11. command-not-found
  • +
  • 3.4.6.12. swarselcheck
  • +
  • 3.4.6.13. swarselcheck-niri
  • +
  • 3.4.6.14. swarselzellij
  • +
  • 3.4.6.15. waybarupdate
  • +
  • 3.4.6.16. opacitytoggle
  • +
  • 3.4.6.17. fs-diff
  • +
  • 3.4.6.18. github-notifications
  • +
  • 3.4.6.19. kanshare
  • +
  • 3.4.6.20. swarsel-bootstrap
  • +
  • 3.4.6.21. swarsel-rebuild
  • +
  • 3.4.6.22. swarsel-install
  • +
  • 3.4.6.23. swarsel-postinstall
  • +
  • 3.4.6.24. t2ts
  • +
  • 3.4.6.25. ts2t
  • +
  • 3.4.6.26. vershell
  • +
  • 3.4.6.27. eontimer
  • +
  • 3.4.6.28. project
  • +
  • 3.4.6.29. fhs
  • +
  • 3.4.6.30. swarsel-displaypower
  • +
  • 3.4.6.31. swarsel-mgba
  • +
  • 3.4.6.32. swarsel-deploy
  • +
  • 3.4.6.33. swarsel-build
  • +
  • 3.4.6.34. swarsel-instantiate
  • +
  • 3.4.6.35. sshrm
  • +
  • 3.4.6.36. endme
  • +
  • 3.4.6.37. git-replace
  • 3.4.7. Packages (config) @@ -696,7 +698,7 @@
  • -
  • 4. Emacs +
  • 4. Emacse
    • 4.1. Initialization (early-init.el)
        @@ -923,7 +925,7 @@

        -This file has 115249 words spanning 30878 lines and was last revised on 2025-12-02 17:29:11 +0100. +This file has 118389 words spanning 31287 lines and was last revised on 2025-12-18 17:25:42 +0100.

        @@ -977,13 +979,13 @@ This file is structured as follows:

        • Introduction (no code) -This is the block you are currently in. It holds no code that actually builds the system, it just outlines the general approach and explains my rough mentality
        • +This is the block you are currently in. It holds no code that actually builds the system, it just outlines the general approach and explains the rough design mentality. For simply understanding the code in here, reading this should not be necessary (feel free to skip to flake.nix)
        • flake.nix -This block holds everything related to the heart of the nix side of the configuration - the flake.nix file.
        • +This block holds everything related to the heart of the nix side of the configuration - the flake.nix file. I am using flake-parts to manage this flake, so different aspects of the configuration are handled by flake-part modules in different files.
        • System -This section holds all configuration options that apply to NixOS or home-manager. In other words, here we are doing system and user level configuration.
        • +This section holds all configuration options that apply to NixOS or home-manager. In other words, here we are doing system and user level configuration. In a way, I consider this the most important part of this file, as (nearly) all of the nix magic is going to happen here.
        • Emacs @@ -991,7 +993,7 @@ This section defines my Emacs configuration. For a while, I considered to use ry

          -My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2025-12-02 17:29:11 +0100) +My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2025-12-18 17:25:42 +0100)

        @@ -1072,10 +1074,7 @@ This section hold code that can be templated at other parts of the configuration

          -
        • Appendix A: Supplementary Files -This section holds files that are not written in nix but are still referenced in the configuration in some way. This is mostly used for configuration of programs that have no native nix support, like tridactyl. Note that shell scripts are still defined under their respective entry in Packages.
        • - -
        • Historical Note: Noweb-Ref blocks
        • +
        • Appendix A: Noweb-Ref blocks

        @@ -1112,6 +1111,14 @@ which can then be used in a block like:

        not that noweb-reffed blocks will not be indented correctly. You will want to account for that when checking your nix flake with the formatter of your choice. Personally, I have solved this issue using the functions defined in org-mode: Upon-save actions (Auto-tangle, export to html, formatting). Originally, I also automatically exported to html there, but it incurred a too high memory penalty which made Emacs become sluggish over time.

        + +
          +
        • Appendix B: Supplementary Files +This section holds files that are not written in nix but are still referenced in the configuration in some way. This is mostly used for configuration of programs that have no native nix support, like tridactyl. Note that shell scripts are still defined under their respective entry in Packages. Over time, the goal is to reduce this section to a minimum, but things like the aforementioned tridactyl might stay for a long time, until we have a stable interface to configure browser plugins.
        • + +
        • Appendix C: Explanations to nix functions and operators +When I started to learn about nix, I found that journey quite arduous; while I disagree with the general public in that the documentation is too sparse, I will say that, while it is very good, reading (and understanding!) it requires a certain level of existing nix knowledge that one will problably not have when starging out. Hence, the goal of this document is to explain common nix functions as they come up in this document (I thing I wrote this before :sweat:), in hopes that you will be able to understand most of the code. When a new function appears for the first time, I will try to link to an entry in the appendix.
        • +
        @@ -1136,7 +1143,7 @@ The corresponding configurations are automatically generated by mkFullHost

        -These <hosttype> folders hold in turn a number of <hostname> folders, the actual configurations. At this time, the files stored in this folder are: +These <hosttype> folders hold on the first level a folder describing the machine archetype (x86_64-linux or aarch64-linux for linux, x86_64-darwin or aarch64-darwin for macs). Those folders then hold a number of <hostname> folders, the actual configurations. At this time, the files stored in this folder are:

        • default.nix: @@ -1146,7 +1153,7 @@ It is not clearly defined what I hold in this file. Mostly it is just the attrib
        • disk-config.nix Holds the aforementioned filesystem configuration and is applied using disko.
        • -
        • The hosts/<hosttype>/<hostname> folders may also have a secrets folder, under which a single file pii.nix.enc can be stored. As the name suggests, this file should be encrypted. Specifically, it needs to be a sops-encrypted file (sops does not seem to suggest a file ending other than .yml or others, which is not verbose enough for me, so I went with .enc). This file should have the structure of a nix expression, e.g.:
        • +
        • The hosts/<hosttype>/<hostname> folders may also have a secrets folder, under which files of the ending .nix.enc may be stored. As the name suggests, these files should be encrypted. Specifically, they need to be sops-encrypted files (sops does not seem to suggest a file ending other than .yml or others, which is not verbose enough for me, so I went with .enc). This should have the structure of a nix expression, e.g.:
        @@ -1163,6 +1170,10 @@ Holds the aforementioned filesystem configuration and is applied using PII management (which in turn uses extra-builtins and sops-decrypt-and-cache), these files are decrypted during evaluation time and stored under a persistent directory. As the name suggests, I am using these files to store personally identifiable information - these "secrets" are stored world-readable in the nix store. As such, this should not be used to store important secrets, but rather information that you would not like everyone on the internet to easily find in your git repo.

        +

        +Other than that, the secrets folder will also be used to store conventional (decryted at activation-time) sops-encrypted secrets in the standard .yaml / .toml / .ini formats. +

        +
        • modules @@ -1171,8 +1182,7 @@ This folder holds the most part of the actual system configuration done in this

          • nixos: Holds true NixOS configuration
          • home: Holds configuration to be used by home-manager (either as a NixOS submodule or not)
          • -
          • darwin: Holds configuration for nix-darwin. This folder further splits up into a nixos and a home folder, which hold respective nix or home-manager configuration for nix-darwin.
          • -
          • iso: Holds specific configuration for my installer ISO that I do not want to have loaded in the rest of the configuration.
          • +
          • shared: This is for configuraion bits that are to be used by both types.

          @@ -1182,38 +1192,55 @@ The nixos and home folders further split up:

          • common: Configuration that can be used by all hosts (TODO: this currently includes configuration used by my user devices, which will mostly not be used by servers)
          • server: Configuration to be used on servers
          • -
          • optional: Configuration that will be used rather rarely
          • -
          - -

          -This structure is very optionated and highly subjective. I will possibly change this in the future. +

        • darwin: Holds configuration for nix-darwin.
        • +
        • +optional: Configuration that will be used rather rarely

          -By themselves, most of the files in the modules folder will not do anything. In order for them to do something, their corresponding config.swarselsystems.modules attribute needs to be enabled. This is done using… +This structure is very optionated and highly subjective. I will possibly change this in the future. +

        • +
        + +

        +By themselves, most of the files in the modules folder will not do anything. In order for them to do something, their corresponding config.swarselmodules attribute needs to be enabled. This is partly done using…

        -
      • profiles: This folder splits up into home and nixos subfolders, where groupings of module enablers are stored for the respective home and nix setups. Note that home profiles are also used in NixOS setups (extensively even)!
      • +
      • profiles: This folder splits up into home and nixos subfolders, where groupings of module enablers are stored for the respective home and nix setups. Note that home profiles are also used in NixOS setups (extensively even)! This is used to quickly enable common configuration for a machine use, e.g. the Server profile.
      • -
      • nix: This special folder holds mostly .nix files that are not automatically loaded, but rather setup specific things that affect most of the flake. For example, here lies the aforementioned extra-builtins as well as the setup for the Globals system. TODO: Move flake-parts units there and explain them here.
      • +
      • nix: This special folder holds mostly .nix files that are not automatically loaded, but rather setup specific things that affect most of the flake. For example, here lies the aforementioned extra-builtins as well as the setup for the Globals system. Also in here are the flake-parts files that you read about earlier. This gives the following functionality: +
          +
        • lib: I define some utility functions that I add to the nixpkgs library under the swarselsystems attribute set. An example would be the mkIfElse function.
        • +
        • checks: As part of a Devshell (checks), I declare pre-commit hooks that should run before I push changes to my repo.
        • +
        • overlays: Here we also define the main (default) overlay I am using in my configuration. It is responsible for adding my defined packages and modifications to the final nixpkgs. Also I add some other conveniences like all past stable nixpkgs and some other package sets.
        • +
        • apps: I also define Apps, which is an output of derivations that can be called by nix run without having the flake locally - this is mostly used for my swarsel-* utilities.
        • +
        • topology: I also created a diagram of my infrastructure using nix-topology. While I do not update this too often, this (I think) can quickly give a good overview of the scope of this flake as well as its services.
        • +
      • -
      • lib: This folder holds utility functions that I add to the nixpkgs library under the swarselsystems attribute set. An example would be the mkIfElse function.
      • +
      • pkgs: This folder holds derivations (mostly packages) that I define myself. This is mostly used to grab versions that are not (yet) in nixpkgs, or modified versions of another package. Each derivation in this folder is in turn in its own folder which holds a defautlt.nix. Using the mechanism in Packages, these are automatically built and available to all configurations (packages still need to be installed e.g. in environment.systemPackages). Note that the folder at the top level splits up in config and flake subdirectories: +
          +
        • The config dir is used for packages that need the actual config of the machine where they run in order to be built. These packages cannot simply be released as a flake output (or better, it would not make a lot of sense). Instead, these are added within the configuration as an overlay
        • -
        • pkgs: This folder holds derivations (mostly packages) that I define myself. This is mostly used to grab versions that are not (yet) in nixpkgs, or modified versions of another package. Each derivation in this folder is in turn in its own folder which holds a defautlt.nix. Using the mechanism in Packages, these are automatically built and available to all configurations (packages still need to be installed e.g. in environment.systemPackages)
        • - -
        • checks: Holds a file that defines my pre-commit-hook checks. TODO: move this to /nix probably
        • +
        • The flake dir is used for the conventional packages that I described above.
        • +
      • +
      • files: This is kind of a catchall folder that holds (nearly) all non-nix files. It mostly holds blocks created in Appendix B: Supplementary Files, but also some more specific directories: +
        • scripts: This folder holds a bunch of shell scripts that I use for various tasks. Nearly all of these are made into a derivation using pkgs.writeShellApplication. In the future (TODO?), I might convert these to native nix, but in the past I kept the as true shellfiles in case I ever wanted to move away from nix. This is becoming less and less likely, however. And even in case that this would happen, I could retrieve these files from the nix store and would simply have to remove the nix store paths.
        • +
        • wallpaper: Holds my wallpapers and profile pictures :)
        • +
        • topology-images: Holds pictures used by Topology :)
        • +
      • -
      • secrets: Unlike the similar folder under hosts, this folder holds actual sops-encrypted secrets that are created at activation time and not in the nix store. The folder splits up into a bunch of <hostname> folders, as well as a repo folder, which holds another pii.nix.enc, which holds global PII's, and a certs folder that holds some longer certificate style secrets.
      • +
      • secrets: Unlike the similar folder under hosts, this folder holds sops-encrypted secrets and PIIs that are used by a number of hosts that is greater than one.
      • -
      • overlays: This holds a single default.nix that defines the overlay I am using in my configuration. It is responsible for adding my defined packages and modifications to the final nixpkgs. Also I add some other conveniences like all past stable nixpkgs and some other package sets.
      • +
      • install: This folder holds another Installer flake. That flake pulls in the nixosConfigurationsMinimal that are defined in Hosts of the main flake, which enables me to build an extemely reduced configuration when I deploy a new host for the first time - this is used by swarsel-bootstrap in the first installation step. It also holds the configuration of the two installer images that I use to deploy this flake: +
          +
        • Drugstore (ISO installer config): This is the general installer ISO that I use whenever I can when I want to deploy a new host. It has a few conveniences like some of my utility programs for figuring out some dependencies or network quirks, as well as my public ssh keys so that I can immediately login to them.
        • -
        • programs: This folder holds configurations for various programs (most notably emacs' init.el and early-init.el), that are being rendered using org-babel and loaded using nix.
        • +
        • Brick Road (kexec image): This is a kexec tarball that can be used by swarsel-bootstrap in case that I need to deploy to a machine that has less than 1GB of RAM. It is basically just an even more stripped down version of the detault one used by nixos-anywhere, but notably I added cryptsetup so that it can be used when setting up an encrypted device using disko.
        • +
      • -
      • wallpaper: Holds wallpapers and profile pictures.
      • - -
      • topology: Holds the configuration used by nix-topology.
      • +
      • .github: Canonically, this holds github related files like the GitHub Readme and some workflows.
      @@ -1221,30 +1248,30 @@ By themselves, most of the files in the modules folder will not do anything. In

      1.4. Hosts

      -Here I give a brief overview over the hostmachines that I am using. This is held in markdown so that I can render it into my GitHub README. +Here I give a brief overview over the host machines that I am using. This is held in markdown so that I can render it into my GitHub Readme without further effort.

      -
      | Name                | Hardware                                            | Use                                                 |
      -|---------------------|-----------------------------------------------------|-----------------------------------------------------|
      -|πŸ’» **pyramid**       | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                         |
      -|πŸ’» **bakery**        | Lenovo Ideapad 720S-13IKB                           | Personal laptop                                     |
      -|πŸ’» **machpizza**     | MacBook Pro 2016                                    | MacOS reference and build sandbox                   |
      -|🏠 **treehouse**     | NVIDIA DGX Spark                                    | AI Workstation, remote builder, hm-only-reference   |
      -|πŸ–₯️ **summers**       | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM  | Homeserver (microvms), remote builder, datastorage  |
      -|πŸ–₯️ **winters**       | ASRock J4105-ITX, 32GB RAM                          | Homeserver (IoT server in spe)                      |
      -|πŸ–₯️ **hintbooth**     | HUNSN RM02, 8GB RAM                                 | Router                                              |
      -|☁️ **stoicclub**     | Cloud Server: 1 vCPUs, 8GB RAM                      | Authoritative dns server                            |
      -|☁️ **liliputsteps**  | Cloud Server: 1 vCPUs, 8GB RAM                      | SSH bastion                                         |
      -|☁️ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM                      | Service proxy                                       |
      -|☁️ **eagleland**     | Cloud Server: 2 vCPUs, 8GB RAM                      | Mailserver                                          |
      -|☁️ **moonside**      | Cloud Server: 4 vCPUs, 24GB RAM                     | Gaming server, syncthing + lightweight services     |
      -|☁️ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM                     | Hydra builder and nix binarycache                   |
      -|πŸ“± **magicant**      | Samsung Galaxy Z Flip 6                             | Phone                                               |
      -|πŸ’Ώ **drugstore**     | -                                                   | NixOS-installer ISO for bootstrapping new hosts     |
      -|πŸ’Ώ **brickroad**     | -                                                   | Kexec tarball for bootstrapping low-memory machines |
      -|❔ **chaotheatre**   | -                                                   | Demo config for checking out this configuration     |
      -|❔ **toto**          | -                                                   | Helper configuration for testing purposes           |
      +
      | Name                | Hardware                                            | Use                                                             |
      +|---------------------|-----------------------------------------------------|-----------------------------------------------------------------|
      +|πŸ’» **pyramid**       | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                                     |
      +|πŸ’» **bakery**        | Lenovo Ideapad 720S-13IKB                           | Personal laptop                                                 |
      +|πŸ’» **machpizza**     | MacBook Pro 2016                                    | MacOS reference and build sandbox                               |
      +|🏠 **treehouse**     | NVIDIA DGX Spark                                    | AI Workstation, remote builder, hm-only-reference               |
      +|πŸ–₯️ **summers**       | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM  | Homeserver (microvms), remote builder, data storage             |
      +|πŸ–₯️ **winters**       | ASRock J4105-ITX, 32GB RAM                          | Homeserver (IoT server in spe)                                  |
      +|πŸ–₯️ **hintbooth**     | HUNSN RM02, 8GB RAM                                 | Router                                                          |
      +|☁️ **stoicclub**     | Cloud Server: 1 vCPUs, 8GB RAM                      | Authoritative DNS server                                        |
      +|☁️ **liliputsteps**  | Cloud Server: 1 vCPUs, 8GB RAM                      | SSH bastion                                                     |
      +|☁️ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM                      | Service proxy                                                   |
      +|☁️ **eagleland**     | Cloud Server: 2 vCPUs, 8GB RAM                      | Mailserver                                                      |
      +|☁️ **moonside**      | Cloud Server: 4 vCPUs, 24GB RAM                     | Gaming server, syncthing + lightweight services                 |
      +|☁️ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM                     | Hydra builder and nix binary cache                              |
      +|πŸ“± **magicant**      | Samsung Galaxy Z Flip 6                             | Phone                                                           |
      +|πŸ’Ώ **drugstore**     | -                                                   | NixOS-installer ISO for bootstrapping new hosts                 |
      +|πŸ’Ώ **brickroad**     | -                                                   | Kexec tarball for bootstrapping low-memory machines             |
      +|❔ **hotel**         | -                                                   | Demo config for checking out this configuration                 |
      +|❔ **toto**          | -                                                   | Helper configuration for testing purposes                       |
       
      @@ -1252,19 +1279,23 @@ Here I give a brief overview over the hostmachines that I am using. This is held

      1.5. Programs

      +

      +This is meant to give a brief overview over the main programs/components that I use on a daily basis on my client machines. This should be mostly useful for people wanting to rice their config, or people who believed this repos title and are looking for .dotfiles :p +

      +
      -
      | Topic         | Program                         |
      -|---------------|---------------------------------|
      -|🐚 **Shell**   | [zsh](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/zsh.nix)                            |
      -|πŸšͺ **DM**      | [greetd](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/common/login.nix)                         |
      -|πŸͺŸ **WM**      | [SwayFX](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/sway.nix)                         |
      -|⛩️ **Bar**     | [Waybar](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/waybar.nix)                         |
      -|βœ’οΈ **Editor**  | [Emacs](https://github.com/Swarsel/.dotfiles/tree/main/files/emacs/init.el)                          |
      -|πŸ–₯️ **Terminal**| [Kitty](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/kitty.nix)                          |
      -|πŸš€ **Launcher**| [Fuzzel](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/fuzzel.nix)                         |
      -|🚨 **Alerts**  | [Mako](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/mako.nix)                           |
      -|🌐 **Browser** | [Firefox](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/zsh.nix)                        |
      -|🎨 **Theme**   | [City-Lights (managed by stylix)](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/sharedsetup.nix)|
      +
      | Topic         | Program                                                                                                                     |
      +|---------------|-----------------------------------------------------------------------------------------------------------------------------|
      +|🐚 **Shell**   | [zsh](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/zsh.nix)                                           |
      +|πŸšͺ **DM**      | [greetd](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/common/login.nix)                                     |
      +|πŸͺŸ **WM**      | [SwayFX](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/sway.nix)                                       |
      +|⛩️ **Bar**     | [Waybar](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/waybar.nix)                                     |
      +|βœ’οΈ **Editor**  | [Emacs](https://github.com/Swarsel/.dotfiles/tree/main/files/emacs/init.el)                                                 |
      +|πŸ–₯️ **Terminal**| [Kitty](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/kitty.nix)                                       |
      +|πŸš€ **Launcher**| [Fuzzel](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/fuzzel.nix)                                     |
      +|🚨 **Alerts**  | [Mako](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/mako.nix)                                         |
      +|🌐 **Browser** | [Firefox](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/zsh.nix)                                       |
      +|🎨 **Theme**   | [City-Lights (managed by stylix)](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/sharedsetup.nix)       |
       
      @@ -1272,31 +1303,43 @@ Here I give a brief overview over the hostmachines that I am using. This is held

      1.6. Services

      +

      +This is a comprehensive list of the services/components ran by my server machines. +

      +
      -
      | Topic                 | Program                                                                                                             |
      -|-----------------------|---------------------------------------------------------------------------------------------------------------------|
      -|πŸ“– **Books**           |  [Kavita](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/kavita.nix)                           |
      -|πŸ“Ό **Videos**          | [Jellyfin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/jellyfin.nix)                        |
      -|🎡 **Music**           | [Navidrome](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/navidrome.nix) +  [Spotifyd](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/spotifyd.nix) +  [MPD](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/mpd.nix)                                                              |
      -|πŸ—¨οΈ **Messaging**       | [Matrix](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/matrix.nix)                            |
      -|πŸ“ **Filesharing**     | [Nectcloud](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/nextcloud.nix)                      |
      -|🎞️ **Photos**          | [Immich](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/immich.nix)                            |
      -|πŸ“„ **Documents**       | [Paperless](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/paperless.nix)                      |
      -|πŸ”„ **File Sync**       | [Syncthing](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/syncthing.nix)                      |
      -|πŸ’Ύ **Backups**         | [Restic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/restic.nix)                            |
      -|πŸ‘οΈ **Monitoring**      | [Grafana](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/monitoring.nix)                       |
      -|🍴 **RSS**             | [FreshRss](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/freshrss.nix)                        |
      -|🌳 **Git**             | [Forgejo](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/forgejo.nix)                          |
      -|βš“ **Anki Sync**       | [Anki Sync Server](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/ankisync.nix)                |
      -|πŸͺͺ **SSO**             | [Kanidm](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/kanidm.nix) + [oauth2-proxy](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/oauth2-proxy.nix)                                            |
      -|πŸ’Έ **Finance**         | [Firefly-III](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/firefly-iii.nix)                  |
      -|πŸƒ **Collections**     | [Koillection](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/koillection.nix)                  |
      -|πŸ—ƒοΈ **Shell History**   | [Atuin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/atuin.nix)                              |
      -|πŸ“… **CalDav/CardDav**  | [Radicale](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/radicale.nix)                        |
      -|↔️ **P2P Filesharing** | [Croc](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/croc.nix)                                |
      -|βœ‚οΈ **Paste Tool**      | [Microbin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/microbin.nix)                        |
      -|πŸ“Έ **Image Sharing**   | [Slink](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/slink.nix)                              |
      -|πŸ”— **Link Shortener**  | [Shlink](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/shlink.nix)                            |
      +
      | Topic                      | Program                                                                                                        |
      +|----------------------------|----------------------------------------------------------------------------------------------------------------|
      +|πŸ“– **Books**                |  [Kavita](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/kavita.nix)                      |
      +|πŸ“Ό **Videos**               | [Jellyfin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/jellyfin.nix)                   |
      +|🎡 **Music**                | [Navidrome](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/navidrome.nix) +  [Spotifyd](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/spotifyd.nix) +  [MPD](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/mpd.nix)                                                              |
      +|πŸ—¨οΈ **Messaging**            | [Matrix](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/matrix.nix)                       |
      +|πŸ“ **Filesharing**          | [Nectcloud](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/nextcloud.nix)                 |
      +|🎞️ **Photos**               | [Immich](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/immich.nix)                       |
      +|πŸ“„ **Documents**            | [Paperless](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/paperless.nix)                 |
      +|πŸ”„ **File Sync**            | [Syncthing](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/syncthing.nix)                 |
      +|πŸ’Ύ **Backups**              | [Restic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/restic.nix)                       |
      +|πŸ‘οΈ **Monitoring**           | [Grafana](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/monitoring.nix)                  |
      +|🍴 **RSS**                  | [FreshRss](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/freshrss.nix)                   |
      +|🌳 **Git**                  | [Forgejo](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/forgejo.nix)                     |
      +|βš“ **Anki Sync**            | [Anki Sync Server](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/ankisync.nix)           |
      +|πŸͺͺ **SSO**                  | [Kanidm](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/kanidm.nix) + [oauth2-proxy](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/oauth2-proxy.nix)                                            |
      +|πŸ’Έ **Finance**              | [Firefly-III](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/firefly-iii.nix)             |
      +|πŸƒ **Collections**          | [Koillection](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/koillection.nix)             |
      +|πŸ—ƒοΈ **Shell History**        | [Atuin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/atuin.nix)                         |
      +|πŸ“… **CalDav/CardDav**       | [Radicale](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/radicale.nix)                   |
      +|↔️ **P2P Filesharing**      | [Croc](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/croc.nix)                           |
      +|βœ‚οΈ **Paste Tool**           | [Microbin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/microbin.nix)                   |
      +|πŸ“Έ **Image Sharing**        | [Slink](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/slink.nix)                         |
      +|πŸ”— **Link Shortener**       | [Shlink](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/shlink.nix)                       |
      +|⛏️ **Minecraft**            | [Minecraft](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/minecraft.nix)                 |
      +|☁️ **S3**                   | [Garage](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/garage.nix)                       |
      +|πŸ•ΈοΈ **Nix Binary Cache**     | [Attic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/attic.nix)                         |
      +|πŸ™ **Nix Build farm**       | [Attic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/hydra.nix)                         |
      +|πŸ”‘ **Cert-based SSH**       | [OPKSSH](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/opkssh.nix)                       |
      +|πŸ”¨ **Home Asset Management**| [Homebox](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/homebox.nix)                     |
      +|πŸ‘€ **DNS**                  | [NSD](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/nsd.nix)                             |
      +|βœ‰οΈ **Mail**                 | [simple-nixos-mailserver](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/mailserver.nix)  |
       
      @@ -1304,43 +1347,18 @@ 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

      -
      -
      These steps are required when setting up a normal NixOS host:
      +

      +In the Introduction (no code), I mentioned that this is a nearly fully declarative config. In fact, most client configs are in one way or another not fully declarative. I use oneshotting systemd services + sentinel files for most such tasks (which makes them declarative!), but some of them I would rather perform manually once. This mainly concerns work related things. +

      -- 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` - - `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 <account name, e.g. 'work'>` - - `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 '<nixpkgs>' 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` -
      -
      +

      +Whenever I encounter a configuration bit that needs manual steps, I use a Appendix A: Noweb-Ref blocks to tangle that bit of information into a central place (here). I discern between the following scenarios: +

      +
        +
      • setup: Used in a standard NixOs + home-manager deployment
      • +
      • worksetup: Stuff to be done only on work machines
      • +
      • homemanageronlysetup: Steps that are needed only on machines that are not running NixOs.
      • +
      These steps are required when setting up a normal NixOS host: @@ -1376,34 +1394,88 @@ 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` +

      +#+beginexport html +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`
        • +
        • `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 <account name, e.g. 'work'>`
        • +
        • `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: +
      • +
      • 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. +
        3. `nix –extra-experimental-features 'nix-command flakes' develop`
        4. +
        5. `home-manager –extra-experimental-features 'nix-command flakes' switch –flake .#$(hostname) –show-trace`
        6. +
      • +
      +

      +#+end +

      -

      1.8. Current issues

      +

      1.8. TODO Current issues

      -
      -
      Currently, these adaptions are made to the configuration to account for bugs in upstream repos:
      +

      +Besides the manual steps outlined above, sometimes things break when I update this flake. The fix, for me, is most of the times one of these two: +

      +
        +
      • instead of the broken package, use the package from the latest stable nixpkgs release where the package is still functoning (this is why I pull all of these in as inputs)
      • +
      • if the broken component is critical, I perform manual patches/overrides.
      • +
      -- 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) -
      -
      +

      +In order to keep track of these changes, I gather them here in a similar style to what you saw in Manual steps when setting up a new machine. I simply prefix them with the date and check them after a while to see if things got better. TODO: this list is not comprehensive probably +

      Currently, these adaptions are made to the configuration to account for bugs in upstream repos: @@ -1448,7 +1520,7 @@ Nowadays, I use flake-parts to manage my flake. It allows me to conveniently spl

      2.1. flake.nix skeleton (inputs)

      -In general, a nix flake consists of one or more inputs and several outputs. The inputs are used to define where nix should be looking for packages, modules, and more. The outputs generate expressions that can be used in .nix files as well as system configurations using these files. +In general, a nix flake consists of one or more inputs and several outputs. The inputs are used to define where nix should be looking for packages, modules, and more (the most common input is nixpkgs, which provides a lot of packages, library functions and modules). The outputs generate expressions that can be used in .nix files as well as system configurations using these files.

      @@ -1456,7 +1528,7 @@ In the start, I enable some public cache repositories. This saves some time duri

      -In many flakes, you see a structure like this: outputs = inputs@ [...], the inputs@ makes it so that all inputs are automatically passed to the outputs and can be called as inputs.<name>, whereas explicit arguments may just be called by using <name>. For most flakes this is fully sufficient, as they do not need to be called often and it saves me maintainance effort with this file. In fact, I also used to make use of this mechanism. However, using flake-parts, all I really need for the outputs function is inputs, which is why my outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } { […] ). Note that flake-parts must inherit these inputs and no other arguments are expected. +In many flakes, you see a structure like this: outputs = inputs@ [...], the inputs@ makes it so that all inputs are automatically passed to the outputs and can be called as inputs.<name>, whereas explicit arguments may just be called by using <name> (for a more detailed explanation, s). For most flakes this is fully sufficient, as they do not need to be called often and it saves me maintainance effort with this file. In fact, I also used to make use of this mechanism. However, using flake-parts, all I really need for the outputs function is inputs, which is why my outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } { […] ). Note that flake-parts must inherit these inputs and no other arguments are expected.

      @@ -1503,15 +1575,15 @@ A short overview over each input and what it does:

      • nixpkgs -This is the base repository that I am following for all packages. I follow the unstable branch.
      • +This is the base repository that I am following for all packages. I follow the unstable branch. Also I pull in some older revisions of nixpkgs stable for various purposes.
      • home-manager This handles user-level configuration and mostly provides dotfiles that are generated and symlinked to ~/.config/.
      • -
      • swarsel -This pulls in the very dotfiles you are currently reading. I am adding this to the flake registry in order to have easier access to my customizations in nix calls, for example nix-instantiate
      • +
      • swarsel-nix +This pulls in the very dotfiles you are currently reading. I am adding this to the flake registry in order to
      • NUR The nix user repository contains user provided modules, packages and expressions. These are not audited by the nix community, so be aware of supply chain vulnerabilities when using those. I am only really using rycee's firefox addons from there which saves me a lot of hassle, and it seems to be a safe resource.
      • nixGL -This solves the problem that nix has with "OpenGL", as libraries are not linked and programs will often fail to find drivers. But I do not fully understand what it does. All I know is that I usually have to use this on non-NIxoS systems.
      • +This solves the problem that nix has with OpenGL, as libraries are not linked and programs will often fail to find drivers. Nowadays, this is included in the nixGL module of home-manager, but even that requres a binary for nixGL, which is what I pull from this input.
      • stylix As described before, this handles all theme related options.
      • sops-nix @@ -1542,10 +1614,39 @@ After learning that MacOS systems can also be configured using nix, I managed to Provides access to several checks that can be hooked to be run before several stages in the process.
      • nix-topology This automatically creates a topology diagram of my configuration.
      • -
      • flake-parts +
      • flake-parts The aforementioned system that allows for more convenient flake crafting.
      • -
      • devshell +
      • devshell This provides devshell support for flake-parts
      • +
      • spicetify +This is a improved spotify client. This provides a NixOs module to manage it.
      • +
      • niri-flake +This is an optional input that I reserve to use in the future; it provides a module to manage Niri in a way that is way more all-encompassing than the current modules in nixpkgs/home-manager. However, I do not include this by default as this leads to a full compilation of latest niri - this is used only be the niri config evaluator, but is even built if niri is not included in the final config. Also, the binary cache provided by this flake does usually not have the latest niri cached.
      • +
      • microvm.nix +This flake brings support for microvms to nix. This is basically a more isolated alternative to classic NixOs containers, while keeping most of their benefits.
      • +
      • treefmt-nix +This allows to specify a range of formatters for different languages and aspects which can all be run upon nix fmt.
      • +
      • +nixos-extra-modules +This is a collection of modules that add some qualitative functions to several aspects of nix, for example: +

        +
          +
        • microvm management
        • +
        • wireguard support for nix-topology
        • +
        • some extensions to the network library
        • +
        + +

        +At the moment I am not using the full range of modules, but my usage keeps increasing steadily. Using this module forced me to make some adjustments in my config, namely exposing the nodes output in Hosts. +

      • +
      • dns.nix +This adds a module that helps with creating zone files (like nsd (dns) - site1). This flake was competing with NixOS-DNS for my favour - while the latter adds many nice utilities that generage records straight from a host configuration, I prefer to do this myself using the Globals + Share configuration between nodes (automatically active) systems. In the end, I just tried out dns.nix without giving NixOS-DNS a chance and it has been working great, but I believe NixOS-DNS still deserves a mention here, as it would have been a great fit as well, most likely.
      • +
      • nix-minecraft +This adds a module that makes it easier to manage (modded) minecraft servers. At the moment, it does not really work with Forge 1.20.1 (which is what my server is running), so I am not making full use of it right now, but I keep close watch on it every day.
      • +
      • nixos-mailserver +This adds a module that basically sets up a full mailserver stack. Apart of DNS records and a few extra steps for e.g. a web client, this is one-stop solution that has been working greatly for me.
      • +
      • hydra +The hydra module already exists in nixpkgs - however, because, I am also using nix-plugins, I need to build all tools that are using nix against a specific nix version (this is also why I pull in nix-eval-jobs as a flake input).
      @@ -1562,6 +1663,20 @@ This provides devshell support for flake-parts
    • }; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + hydra.url = "github:nixos/hydra/nix-2.30"; + # hydra.inputs.nix.follows = "nix"; + hydra.inputs.nix-eval-jobs.follows = "nix-eval-jobs"; + # nix = { + # url = "github:NixOS/nix/2.30-maintenance"; + # # We want to control the deps precisely + # flake = false; + # }; + nix-eval-jobs = { + url = "github:nix-community/nix-eval-jobs/v2.30.0"; + # We want to control the deps precisely + flake = false; + }; + smallpkgs.url = "github:nixos/nixpkgs/08fcb0dcb59df0344652b38ea6326a2d8271baff?narHash=sha256-HXIQzULIG/MEUW2Q/Ss47oE3QrjxvpUX7gUl4Xp6lnc%3D&shallow=1"; nixpkgs-dev.url = "github:Swarsel/nixpkgs/main"; nixpkgs-kernel.url = "github:NixOS/nixpkgs/063f43f2dbdef86376cc29ad646c45c46e93234c?narHash=sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o%3D"; #specifically pinned for kernel version @@ -3872,11 +3987,13 @@ 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, minimal, ... }:
      +
      { self, lib, minimal, ... }:
       {
       
         imports = [
           ./hardware-configuration.nix
      +
      +    "${self}/modules/nixos/optional/systemd-networkd-server.nix"
         ];
       
         boot = {
      @@ -3899,8 +4016,12 @@ This is my main server that I run at home. It handles most tasks that require bi
           isBtrfs = false;
           isLinux = true;
           isNixos = true;
      -    proxyHost = "moonside";
      +    proxyHost = "twothreetunnel";
           server = {
      +      wireguard = {
      +        isClient = true;
      +        serverName = "twothreetunnel";
      +      };
             restic = {
               bucketName = "SwarselWinters";
               paths = [
      @@ -3932,6 +4053,7 @@ This is my main server that I run at home. It handles most tasks that require bi
       
         swarselmodules.server = {
           diskEncryption = lib.mkForce false;
      +    wireguard = lib.mkDefault true;
           nfs = lib.mkDefault true;
           nginx = lib.mkDefault true;
           kavita = lib.mkDefault true;
      @@ -4047,16 +4169,21 @@ This is my main server that I run at home. It handles most tasks that require bi
           loader.efi.canTouchEfiVariables = true;
         };
       
      +  node.lockFromBootstrapping = lib.mkForce false;
      +
         swarselsystems = {
           info = "ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM";
           flakePath = "/root/.dotfiles";
           isImpermanence = true;
      -    isSecureBoot = true;
      +    isSecureBoot = false;
           isCrypted = true;
           isBtrfs = true;
           isLinux = true;
           isNixos = true;
      +    isSwap = false;
      +    rootDisk = "/dev/disk/by-id/ata-TS128GMTS430S_H537280456";
           withMicroVMs = false;
      +    server.localNetwork = "lan";
         };
       
       } // lib.optionalAttrs (!minimal) {
      @@ -4065,39 +4192,8 @@ This is my main server that I run at home. It handles most tasks that require bi
           server = true;
         };
       
      -  swarselmodules = {
      -    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;
      -    };
      +  swarselmodules.server = {
      +    nginx = lib.mkForce false;
         };
       
         microvm.vms =
      @@ -4343,19 +4439,21 @@ in
       
      3.1.2.5.1. Main Configuration
      -
      { lib, minimal,  ... }:
      +
      { self, lib, minimal,  ... }:
       {
       
         imports = [
           ./hardware-configuration.nix
           ./disk-config.nix
      +
      +    "${self}/modules/nixos/optional/systemd-networkd-server.nix"
         ];
       
         swarselsystems = {
           info = "HUNSN RM02, 8GB RAM";
           flakePath = "/root/.dotfiles";
           isImpermanence = true;
      -    isSecureBoot = true;
      +    isSecureBoot = false;
           isCrypted = true;
           isBtrfs = true;
           isLinux = true;
      @@ -4641,7 +4739,7 @@ My phone. I use only a minimal config for remote debugging here.
       
      3.1.2.8. Treehouse (DGX Spark)
      -
      { self, lib, pkgs, ... }:
      +
      { self, pkgs, ... }:
       {
       
         imports = [
      @@ -4709,34 +4807,18 @@ This machine mainly acts as my proxy server to stand before my local machines.
       
      3.1.3.1.1. Main Configuration
      -
      { lib, config, minimal, ... }:
      +
      { self, lib, config, minimal, ... }:
       let
         inherit (config.repo.secrets.local.syncthing) dev1 dev2 dev3 loc1;
      -  inherit (config.swarselsystems) sopsFile;
       in
       {
         imports = [
           ./hardware-configuration.nix
           ./disk-config.nix
      +
      +    "${self}/modules/nixos/optional/systemd-networkd-server.nix"
         ];
       
      -  sops = {
      -    age.sshKeyPaths = lib.mkDefault [ "/etc/ssh/ssh_host_ed25519_key" ];
      -    secrets = {
      -      wireguard-private-key = { inherit sopsFile; };
      -      wireguard-home-preshared-key = { inherit sopsFile; };
      -    };
      -  };
      -
      -  boot = {
      -    loader.systemd-boot.enable = true;
      -    tmp.cleanOnBoot = true;
      -  };
      -
      -  environment = {
      -    etc."issue".text = "\4";
      -  };
      -
         topology.self = {
           icon = "devices.cloud-server";
           interfaces.wg = {
      @@ -4747,45 +4829,6 @@ in
           };
         };
       
      -  networking = {
      -    domain = "subnet03291956.vcn03291956.oraclevcn.com";
      -    firewall = {
      -      allowedTCPPorts = [ 8384 ];
      -    };
      -    wireguard = {
      -      enable = true;
      -      interfaces = {
      -        home-vpn = {
      -          privateKeyFile = config.sops.secrets.wireguard-private-key.path;
      -          # ips = [ "192.168.3.4/32" ];
      -          ips = [ "192.168.178.201/24" ];
      -          peers = [
      -            {
      -              # publicKey = "NNGvakADslOTCmN9HJOW/7qiM+oJ3jAlSZGoShg4ZWw=";
      -              publicKey = "PmeFInoEJcKx+7Kva4dNnjOEnJ8lbudSf1cbdo/tzgw=";
      -              presharedKeyFile = config.sops.secrets.wireguard-home-preshared-key.path;
      -              name = "moonside";
      -              persistentKeepalive = 25;
      -              # endpoint = "${config.repo.secrets.common.ipv4}:51820";
      -              endpoint = "${config.repo.secrets.common.wireguardEndpoint}";
      -              # allowedIPs = [
      -              #   "192.168.3.0/24"
      -              #   "192.168.1.0/24"
      -              # ];
      -              allowedIPs = [
      -                "192.168.178.0/24"
      -              ];
      -            }
      -          ];
      -        };
      -      };
      -    };
      -  };
      -
      -  hardware = {
      -    enableAllFirmware = lib.mkForce false;
      -  };
      -
         system.stateVersion = "23.11";
       
         services.syncthing = {
      @@ -4848,7 +4891,13 @@ in
           isBtrfs = true;
           isNixos = true;
           isLinux = true;
      +    isCloud = true;
      +    proxyHost = "twothreetunnel";
           server = {
      +      wireguard = {
      +        isClient = true;
      +        serverName = "twothreetunnel";
      +      };
             restic = {
               bucketName = "SwarselMoonside";
               paths = [
      @@ -4866,7 +4915,7 @@ in
         };
       
         swarselmodules.server = {
      -    oauth2-proxy = true;
      +    wireguard = true;
           croc = true;
           microbin = true;
           shlink = true;
      @@ -5076,7 +5125,12 @@ in
           isNixos = true;
           isLinux = true;
           isCloud = true;
      +    proxyHost = "twothreetunnel";
           server = {
      +      wireguard = {
      +        isClient = true;
      +        serverName = "twothreetunnel";
      +      };
             garage = {
               data_dir = {
                 capacity = "150G";
      @@ -5099,10 +5153,12 @@ in
         };
       
         swarselmodules.server = {
      -    ssh-builder = lib.mkDefault true;
      -    postgresql = lib.mkDefault true;
      -    attic = lib.mkDefault true;
      -    garage = lib.mkDefault true;
      +    wireguard = true;
      +    ssh-builder = true;
      +    postgresql = true;
      +    attic = true;
      +    garage = true;
      +    hydra = true;
           dns-hostrecord = true;
         };
       
      @@ -5266,12 +5322,12 @@ in
       
      -
      -
      3.1.3.3. Stoicclub (OCI)
      +
      +
      3.1.3.3. Stoicclub (OCI)
      -
      -
      3.1.3.3.1. Main Configuration
      +
      +
      3.1.3.3.1. Main Configuration
      { self, lib, minimal, ... }:
      @@ -5319,8 +5375,8 @@ in
       
      -
      -
      3.1.3.3.2. hardware-configuration
      +
      +
      3.1.3.3.2. hardware-configuration
      { lib, modulesPath, ... }:
      @@ -5342,8 +5398,8 @@ in
       
      -
      -
      3.1.3.3.3. disko
      +
      +
      3.1.3.3.3. disko
      { lib, pkgs, config, ... }:
      @@ -5473,12 +5529,12 @@ in
       
      -
      -
      3.1.3.4. Liliputsteps (OCI)
      +
      +
      3.1.3.4. Liliputsteps (OCI)
      -
      -
      3.1.3.4.1. Main Configuration
      +
      +
      3.1.3.4.1. Main Configuration
      { self, lib, minimal, ... }:
      @@ -5528,8 +5584,8 @@ in
       
      -
      -
      3.1.3.4.2. hardware-configuration
      +
      +
      3.1.3.4.2. hardware-configuration
      { lib, modulesPath, ... }:
      @@ -5551,8 +5607,8 @@ in
       
      -
      -
      3.1.3.4.3. disko
      +
      +
      3.1.3.4.3. disko
      { lib, pkgs, config, ... }:
      @@ -5682,12 +5738,12 @@ in
       
      -
      -
      3.1.3.5. Twothreetunnel (OCI)
      +
      +
      3.1.3.5. Twothreetunnel (OCI)
      -
      -
      3.1.3.5.1. Main Configuration
      +
      +
      3.1.3.5.1. Main Configuration
      { self, lib, minimal, ... }:
      @@ -5715,6 +5771,18 @@ in
           isNixos = true;
           isLinux = true;
           isCloud = true;
      +    server = {
      +      wireguard = {
      +        ifName = "wg";
      +        isServer = true;
      +        peers = [
      +          "moonside"
      +          "winters"
      +          "belchsfactory"
      +          "eagleland"
      +        ];
      +      };
      +    };
         };
       } // lib.optionalAttrs (!minimal) {
         swarselprofiles = {
      @@ -5722,8 +5790,10 @@ in
         };
       
         swarselmodules.server = {
      -    nginx = false;
      +    nginx = true; # for now
      +    oauth2-proxy = true; # for now
           dns-hostrecord = true;
      +    wireguard = true;
         };
       
       }
      @@ -5732,8 +5802,8 @@ in
       
      -
      -
      3.1.3.5.2. hardware-configuration
      +
      +
      3.1.3.5.2. hardware-configuration
      { lib, modulesPath, ... }:
      @@ -5755,8 +5825,8 @@ in
       
      -
      -
      3.1.3.5.3. disko
      +
      +
      3.1.3.5.3. disko
      { lib, pkgs, config, ... }:
      @@ -5928,6 +5998,7 @@ in
         swarselmodules.server = {
           mailserver = true;
           dns-hostrecord = true;
      +    postgresql = true;
         };
       
         swarselprofiles = {
      @@ -8049,6 +8120,9 @@ Needed for control over system-wide privileges etc. Also I make sure that the ro
         config = lib.mkIf config.swarselmodules.security {
       
           security = {
      +      # pki.certificateFiles = [
      +      #   config.sops.secrets.harica-root-ca.path
      +      # ];
             pam.services = lib.mkIf (!minimal) {
               login.u2fAuth = true;
               sudo.u2fAuth = true;
      @@ -8223,7 +8297,7 @@ Here I only enable networkmanager and a few default networks. The r
       
      { self, lib, pkgs, config, globals, ... }:
       let
         certsSopsFile = self + /secrets/repo/certs.yaml;
      -  clientSopsFile = "${config.node.secretsDir}/secrets.yaml";
      +  clientSopsFile = config.node.secretsDir + "/secrets.yaml";
       
         inherit (config.repo.secrets.common.network) wlan1 mobile1 vpn1-location vpn1-cipher vpn1-address eduroam-anon;
       
      @@ -8542,7 +8616,7 @@ I use sops-nix to handle secrets that I want to have available on my machines at
       
    -
    { config, lib, ... }:
    +
    { self, config, lib, ... }:
     {
       options.swarselmodules.sops = lib.mkEnableOption "sops config";
       config = lib.mkIf config.swarselmodules.sops {
    @@ -8550,7 +8624,8 @@ I use sops-nix to handle secrets that I want to have available on my machines at
     
           # age.sshKeyPaths = lib.swarselsystems.mkIfElseList config.swarselsystems.isBtrfs [ "/persist/.ssh/sops" "/persist/.ssh/ssh_host_ed25519_key" ] [ "${config.swarselsystems.homeDir}/.ssh/sops" "/etc/ssh/sops" "/etc/ssh/ssh_host_ed25519_key" ];
           age.sshKeyPaths = [ "${if config.swarselsystems.isImpermanence then "/persist" else ""}/etc/ssh/ssh_host_ed25519_key" ];
    -      defaultSopsFile = "${if config.swarselsystems.isImpermanence then "/persist" else ""}${config.swarselsystems.flakePath}/secrets/repo/common.yaml";
    +      # defaultSopsFile = "${if config.swarselsystems.isImpermanence then "/persist" else ""}${config.swarselsystems.flakePath}/secrets/repo/common.yaml";
    +      defaultSopsFile = self + "/secrets/repo/common.yaml";
     
           validateSopsFiles = false;
     
    @@ -8561,8 +8636,8 @@ I use sops-nix to handle secrets that I want to have available on my machines at
     
    -
    -
    3.2.2.11. Remote building
    +
    +
    3.2.2.11. Remote building
    { lib, config, globals, ... }:
    @@ -8604,6 +8679,7 @@ in
             }
           ];
         };
    +
         programs.ssh = {
           knownHosts = {
             nixbuild = {
    @@ -9730,6 +9806,7 @@ in
           sops
           swarsel-deploy
           tmux
    +      busybox
         ];
       };
     }
    @@ -9804,10 +9881,9 @@ in
     
    3.2.3.5. NGINX
    -
    { pkgs, lib, config, ... }:
    +
    { pkgs, lib, config, globals, ... }:
     let
    -  inherit (config.repo.secrets.common) dnsProvider dnsBase;
    -  inherit (config.repo.secrets.common.mail) address3;
    +  inherit (config.repo.secrets.common) dnsProvider dnsBase dnsMail;
     
       serviceUser = "nginx";
       serviceGroup = serviceUser;
    @@ -9824,42 +9900,66 @@ 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.";
    +    defaultStapling = lib.mkEnableOption "add ssl stapling 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.";
    +        lib.types.submodule (topmod: {
    +          options = {
    +            defaultStapling = lib.mkOption {
    +              type = lib.types.bool;
    +              default = config.services.nginx.defaultStapling;
    +              description = "Whether to add ssl stapling to this location.";
    +            };
    +            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";
    +                    };
                       };
     
    -                  X-Frame-Options = lib.mkOption {
    -                    type = lib.types.str;
    -                    default = "DENY";
    -                    description = "The value to use for X-Frame-Options";
    +                  config = {
    +                    extraConfig = lib.mkIf submod.config.recommendedSecurityHeaders (lib.mkBefore ''
    +                      # Hide upstream's versions
    +                      proxy_hide_header Strict-Transport-Security;
    +                      proxy_hide_header Referrer-Policy;
    +                      proxy_hide_header X-Content-Type-Options;
    +                      proxy_hide_header X-Frame-Options;
    +
    +                      # 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 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 = {
    +            extraConfig = lib.mkIf topmod.config.defaultStapling (lib.mkAfter ''
    +              ssl_stapling on;
    +              ssl_stapling_verify on;
    +              resolver 1.1.1.1 8.8.8.8 valid=300s;
    +              resolver_timeout 5s;
    +            '');
    +          };
    +        })
           );
         };
       };
    @@ -9868,33 +9968,36 @@ in
           lego
         ];
     
    -    sops = {
    +    sops = lib.mkIf (config.node.name == config.swarselsystems.proxyHost) {
           secrets = {
    -        acme-dns-token = { inherit (config.swarselsystems) sopsFile; };
    +        acme-creds = { format = "json"; key = ""; group = "acme"; sopsFile = config.node.secretsDir + "/acme.json"; mode = "0660"; };
           };
           templates."certs.secret".content = ''
    -        ACME_DNS_API_BASE=${dnsBase}
    -        ACME_DNS_STORAGE_PATH=${config.sops.placeholder.acme-dns-token}
    +        ACME_DNS_API_BASE = ${dnsBase}
    +        ACME_DNS_STORAGE_PATH=${config.sops.secrets.acme-creds.path}
           '';
         };
     
         users.groups.acme.members = [ "nginx" ];
     
    -    security.acme = {
    +    security.acme = lib.mkIf (config.node.name == config.swarselsystems.proxyHost) {
           acceptTerms = true;
           defaults = {
             inherit dnsProvider;
    -        email = address3;
    +        email = dnsMail;
             environmentFile = "${config.sops.templates."certs.secret".path}";
             reloadServices = [ "nginx" ];
             dnsPropagationCheck = true;
           };
    +      certs."${globals.domains.main}" = {
    +        domain = "*.${globals.domains.main}";
    +      };
         };
     
         networking.firewall.allowedTCPPorts = [ 80 443 ];
     
         environment.persistence."/persist" = lib.mkIf config.swarselsystems.isImpermanence {
    -      directories = [ { directory = "/var/lib/acme"; } ];
    +      directories = [{ directory = "/var/lib/acme"; }];
           files = [ dhParamsPathBase ];
         };
     
    @@ -9909,6 +10012,7 @@ in
           recommendedGzipSettings = true;
           recommendedBrotliSettings = true;
           recommendedSecurityHeaders = true;
    +      defaultStapling = 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 = {
    @@ -9935,11 +10039,11 @@ in
             ${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0755 /persist${sslBasePath}" else ""}
     
             if [ ! -f "${dhParamsPath}" ]; then
    -          ${pkgs.openssl}/bin/openssl dhparam -out "${dhParamsPath}" 4096
    -          chmod 0644 "${dhParamsPath}"
    -          chown ${serviceUser}:${serviceGroup} "${dhParamsPath}"
    +        ${pkgs.openssl}/bin/openssl dhparam -out "${dhParamsPath}" 4096
    +        chmod 0644 "${dhParamsPath}"
    +        chown ${serviceUser}:${serviceGroup} "${dhParamsPath}"
             else
    -          echo 'Already generated DHParams'
    +        echo 'Already generated DHParams'
             fi
           '';
         };
    @@ -10021,8 +10125,8 @@ Here I am forcing startWhenNeeded to false so that the value will n
     
    -
    -
    3.2.3.7. Bastion
    +
    +
    3.2.3.7. Bastion
    { self, lib, config, ... }:
    @@ -10096,8 +10200,8 @@ Here I am forcing startWhenNeeded to false so that the value will n
     
    -
    -
    3.2.3.8. ssh builder config
    +
    +
    3.2.3.8. ssh builder config

    Restricts access to the system by the nix build user as per https://discourse.nixos.org/t/wrapper-to-restrict-builder-access-through-ssh-worth-upstreaming/25834. @@ -10137,6 +10241,14 @@ in }; }; + services.openssh = { + settings = { + AllowUsers = [ + "builder" + ]; + }; + }; + }; } @@ -10155,7 +10267,7 @@ Generate hostId using head -c4 /dev/urandom | od -A none -t x4 let netConfig = config.repo.secrets.local.networking; netPrefix = "${if config.swarselsystems.isCloud then config.node.name else "home"}"; - netName = "${netPrefix}-${config.swarselsystems.server.localNetwork}"; + # netName = "${netPrefix}-${config.swarselsystems.server.localNetwork}"; in { options = { @@ -10167,7 +10279,7 @@ in }; netConfigName = lib.mkOption { type = lib.types.str; - default = netName; + default = "${netPrefix}-${config.swarselsystems.server.localNetwork}"; readOnly = true; }; netConfigPrefix = lib.mkOption { @@ -10181,10 +10293,21 @@ in swarselsystems.server.localNetwork = netConfig.localNetwork or ""; - globals.networks.${netName}.hosts.${config.node.name} = { - inherit (netConfig.networks.${netConfig.localNetwork}) id; - mac = netConfig.networks.${netConfig.localNetwork}.mac or null; - }; + # globals.networks.${netName}.hosts.${config.node.name} = { + # inherit (netConfig.networks.${netConfig.localNetwork}) id; + # mac = netConfig.networks.${netConfig.localNetwork}.mac or null; + # }; + + globals.networks = lib.mapAttrs' + (netName: _: + lib.nameValuePair "${netPrefix}-${netName}" { + hosts.${config.node.name} = { + inherit (netConfig.networks.${netName}) id; + mac = netConfig.networks.${netName}.mac or null; + }; + } + ) + netConfig.networks; globals.hosts.${config.node.name} = { inherit (config.repo.secrets.local.networking) defaultGateway4; @@ -10438,6 +10561,7 @@ in "ip=${localIp}::${gatewayIp}:${subnetMask}:${config.networking.hostName}::none" ]; initrd = { + secrets."${hostKeyPathBase}" = lib.mkIf (!minimal) hostKeyPathBase; availableKernelModules = config.swarselsystems.networkKernelModules; network = { enable = true; @@ -10487,141 +10611,191 @@ in

    -
    -
    3.2.3.11. Wireguard
    +
    +
    3.2.3.11. Wireguard
    -
    { lib, config, confLib ... }:
    +
    { self, lib, pkgs, config, confLib, nodes, globals, ... }:
     let
       wgInterface = "wg0";
       inherit (confLib.gen { name = "wireguard"; port = 52829; user = "systemd-network"; group = "systemd-network"; }) servicePort serviceName serviceUser serviceGroup;
     
       inherit (config.swarselsystems) sopsFile;
    -  inherit (config.swarselsystems.server.wireguard) peers isClient isServer;
    +  wgSopsFile = self + "/secrets/repo/wg.yaml";
    +  inherit (config.swarselsystems.server.wireguard) peers isClient isServer serverName serverNetConfigPrefix ifName;
     in
     {
       options = {
    -    swarselmodules.${serviceName} = lib.mkEnableOption "enable ${serviceName} settings";
    +    swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} settings";
         swarselsystems.server.wireguard = {
           isServer = lib.mkEnableOption "set this as a wireguard server";
    +      isClient = lib.mkEnableOption "set this as a wireguard client";
    +      serverName = lib.mkOption {
    +        type = lib.types.str;
    +        default = "";
    +      };
    +      serverNetConfigPrefix = lib.mkOption {
    +        type = lib.types.str;
    +        default = "${if nodes.${serverName}.config.swarselsystems.isCloud then nodes.${serverName}.config.node.name else "home"}";
    +        readOnly = true;
    +      };
    +      ifName = lib.mkOption {
    +        type = lib.types.str;
    +        default = wgInterface;
    +      };
           peers = lib.mkOption {
    -        type = lib.types.listOf (lib.types.submodule {
    -          freeformType = lib.types.attrs;
    -          options = { };
    -        });
    +        type = lib.types.listOf lib.types.str;
             default = [ ];
    -        description = "Wireguard peer submodules as expected by systemd.network.netdevs.<name>.wireguardPeers";
    +        description = "Wireguard peer config names";
           };
    -      ;
    -      };
    -      config = lib.mkIf config.swarselmodules.${serviceName} {
    +    };
     
    -        sops = {
    -          secrets = {
    -            wireguard-private-key = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0600"; };
    -            wireguard-home-preshared-key = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0600"; };
    -          };
    +  };
    +  config = lib.mkIf config.swarselmodules.server.${serviceName} {
    +
    +    environment.systemPackages = with pkgs; [
    +      wireguard-tools
    +    ];
    +
    +    sops = {
    +      secrets = {
    +        wireguard-private-key = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0600"; };
    +        # create this secret only if this is a simple client with only one peer (the server)
    +        "wireguard-${serverName}-${config.node.name}-presharedKey" = lib.mkIf (isClient && peers == [ ]) { sopsFile = wgSopsFile; owner = serviceUser; group = serviceGroup; mode = "0600"; };
    +      }
    +      # create these secrets only if this host has multiple peers
    +      // lib.optionalAttrs (peers != [ ]) (builtins.listToAttrs (map
    +        (clientName: {
    +          name = "wireguard-${config.node.name}-${clientName}-presharedKey";
    +          value = { sopsFile = wgSopsFile; owner = serviceUser; group = serviceGroup; mode = "0600"; };
    +        })
    +        peers));
    +    };
    +
    +    networking = {
    +      firewall.checkReversePath = lib.mkIf isClient "loose";
    +      firewall.allowedUDPPorts = [ servicePort ];
    +      # nat = lib.mkIf (config.swarselsystems.isCloud && isServer) {
    +      #   enable = true;
    +      #   enableIPv6 = true;
    +      #   externalInterface = "enp0s6";
    +      #   internalInterfaces = [ ifName ];
    +      # };
    +      # interfaces.${ifName}.mtu = 1280; # the default (1420) is not enough!
    +    };
    +
    +    systemd.network = {
    +      enable = true;
    +
    +      networks."50-${ifName}" = {
    +        matchConfig.Name = ifName;
    +        linkConfig = {
    +          MTUBytes = 1408; # TODO: figure out where we lose those 12 bits (8 from pppoe maybe + ???)
             };
     
    -        networking = {
    -          firewall.allowedUDPPorts = [ servicePort ];
    -          nat = {
    -            enable = true;
    -            enableIPv6 = true;
    -            externalInterface = "ens6";
    -            internalInterfaces = [ wgInterface ];
    -          };
    -        };
    -
    -        systemd.network = {
    -          enable = true;
    -
    -          networks."50-${wgInterface}" = {
    -            matchConfig.Name = wgInterface;
    -
    -            networkConfig = {
    -              IPv4Forwarding = true;
    -              IPv6Forwarding = true;
    -            };
    -
    -            address = [
    -              "${globals.networks."${config.swarselsystems.server.netConfigPrefix}-wg".hosts.${config.node.name}.cidrv4}"
    -              "${globals.networks."${config.swarselsystems.server.netConfigPrefix}-wg".hosts.${config.node.name}.cidrv6}"
    -            ];
    -          };
    -
    -          netdevs."50-wg0" = {
    -            netdevConfig = {
    -              Kind = "wireguard";
    -              Name = wgInterface;
    -            };
    -
    -            wireguardConfig = {
    -              ListenPort = lib.mkIf isServer servicePort;
    -
    -              # ensure file is readable by `systemd-network` user
    -              PrivateKeyFile = config.age.secrets.wg-key-vps.path;
    -
    -              # To automatically create routes for everything in AllowedIPs,
    -              # add RouteTable=main
    -              # RouteTable = "main";
    -
    -              # FirewallMark marks all packets send and received by wg0
    -              # with the number 42, which can be used to define policy rules on these packets.
    -              # FirewallMark = 42;
    -            };
    -            wireguardPeers = peers ++ lib.optionals isClient [
    -              {
    -                PublicKey = builtins.readFile "${self}/secrets/public/wg/${config.node.name}.pub";
    -                PresharedKeyFile = config.sops.secrets."${config.node.name}-presharedKey".path;
    -                Endpoint = "${globals.hosts.${config.node.name}.wanAddress4}:${toString servicePort}";
    -                # Access to the whole network is routed through our entry node.
    -                AllowedIPs =
    -                  (optional (networkCfg.cidrv4 != null) networkCfg.cidrv4)
    -                    ++ (optional (networkCfg.cidrv6 != null) networkCfg.cidrv6);
    -              }
    -            ];
    -          };
    -        };
    -
    -        # networking = {
    -        #   wireguard = {
    -        #     enable = true;
    -        #     interfaces = {
    -        #       wg1 = {
    -        #         privateKeyFile = config.sops.secrets.wireguard-private-key.path;
    -        #         ips = [ "192.168.178.201/24" ];
    -        #         peers = [
    -        #           {
    -        #             publicKey = "PmeFInoEJcKx+7Kva4dNnjOEnJ8lbudSf1cbdo/tzgw=";
    -        #             presharedKeyFile = config.sops.secrets.wireguard-home-preshared-key.path;
    -        #             name = "moonside";
    -        #             persistentKeepalive = 25;
    -        #             # endpoint = "${config.repo.secrets.common.ipv4}:51820";
    -        #             endpoint = "${config.repo.secrets.common.wireguardEndpoint}";
    -        #             # allowedIPs = [
    -        #             #   "192.168.3.0/24"
    -        #             #   "192.168.1.0/24"
    -        #             # ];
    -        #             allowedIPs = [
    -        #               "192.168.178.0/24"
    -        #             ];
    -        #           }
    -        #         ];
    -        #       };
    -        #     };
    -        #   };
    +        # networkConfig = lib.mkIf (config.swarselsystems.isCloud && isServer) {
    +        #   IPv4Forwarding = true;
    +        #   IPv6Forwarding = true;
             # };
     
    +        address = if isServer then [
    +          globals.networks."${config.swarselsystems.server.netConfigPrefix}-wg".hosts.${config.node.name}.cidrv4
    +          globals.networks."${config.swarselsystems.server.netConfigPrefix}-wg".hosts.${config.node.name}.cidrv6
    +        ] else [
    +          globals.networks."${serverNetConfigPrefix}-wg".hosts.${config.node.name}.cidrv4
    +          globals.networks."${serverNetConfigPrefix}-wg".hosts.${config.node.name}.cidrv6
    +        ];
    +      };
    +
    +      netdevs."50-${ifName}" = {
    +        netdevConfig = {
    +          Kind = "wireguard";
    +          Name = ifName;
    +        };
    +
    +        wireguardConfig = {
    +          ListenPort = lib.mkIf isServer servicePort;
    +
    +          # ensure file is readable by `systemd-network` user
    +          PrivateKeyFile = config.sops.secrets.wireguard-private-key.path;
    +
    +          # To automatically create routes for everything in AllowedIPs,
    +          # add RouteTable=main
    +          RouteTable = lib.mkIf isClient "main";
    +
    +          # FirewallMark marks all packets send and received by wg0
    +          # with the number 42, which can be used to define policy rules on these packets.
    +          # FirewallMark = 42;
    +        };
    +        wireguardPeers = lib.optionals isClient [
    +          {
    +            PublicKey = builtins.readFile "${self}/secrets/public/wg/${serverName}.pub";
    +            PresharedKeyFile = config.sops.secrets."wireguard-${serverName}-${config.node.name}-presharedKey".path;
    +            Endpoint = "server.${serverName}.${globals.domains.main}:${toString servicePort}";
    +            # Access to the whole network is routed through our entry node.
    +            PersistentKeepalive = 25;
    +            AllowedIPs =
    +              let
    +                wgNetwork = globals.networks."${serverNetConfigPrefix}-wg";
    +              in
    +                (lib.optional (wgNetwork.cidrv4 != null) wgNetwork.cidrv4)
    +                   ++ (lib.optional (wgNetwork.cidrv6 != null) wgNetwork.cidrv6);
    +          }
    +        ] ++ lib.optionals isServer (map
    +          (clientName: {
    +            PublicKey = builtins.readFile "${self}/secrets/public/wg/${clientName}.pub";
    +            PresharedKeyFile = config.sops.secrets."wireguard-${config.node.name}-${clientName}-presharedKey".path;
    +            # PersistentKeepalive = 25;
    +            AllowedIPs =
    +              let
    +                clientInWgNetwork = globals.networks."${config.swarselsystems.server.netConfigPrefix}-wg".hosts.${clientName};
    +              in
    +                (lib.optional (clientInWgNetwork.ipv4 != null) (lib.net.cidr.make 32 clientInWgNetwork.ipv4))
    +                ++ (lib.optional (clientInWgNetwork.ipv6 != null) (lib.net.cidr.make 128 clientInWgNetwork.ipv6));
    +          })
    +          peers);
     
           };
    -    }
    +    };
    +
    +    # networking = {
    +    #   wireguard = {
    +    #     enable = true;
    +    #     interfaces = {
    +    #       wg1 = {
    +    #         privateKeyFile = config.sops.secrets.wireguard-private-key.path;
    +    #         ips = [ "192.168.178.201/24" ];
    +    #         peers = [
    +    #           {
    +    #             publicKey = "PmeFInoEJcKx+7Kva4dNnjOEnJ8lbudSf1cbdo/tzgw=";
    +    #             presharedKeyFile = config.sops.secrets.wireguard-home-preshared-key.path;
    +    #             name = "moonside";
    +    #             persistentKeepalive = 25;
    +    #             # endpoint = "${config.repo.secrets.common.ipv4}:51820";
    +    #             endpoint = "${config.repo.secrets.common.wireguardEndpoint}";
    +    #             # allowedIPs = [
    +    #             #   "192.168.3.0/24"
    +    #             #   "192.168.1.0/24"
    +    #             # ];
    +    #             allowedIPs = [
    +    #               "192.168.178.0/24"
    +    #             ];
    +    #           }
    +    #         ];
    +    #       };
    +    #     };
    +    #   };
    +    # };
    +
    +
    +  };
    +}
     
    -
    -
    3.2.3.12. BTRFS
    +
    +
    3.2.3.12. BTRFS
    { lib, config, ... }:
    @@ -10759,7 +10933,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -10836,7 +11011,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -10979,7 +11155,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = true;
    @@ -11520,7 +11697,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               listen = [
    @@ -11636,7 +11814,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -11707,7 +11886,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -11861,7 +12041,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -12205,7 +12386,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -12307,7 +12489,7 @@ This section exposes several metrics that I use to check the health of my server
     

    -
    { self, lib, config, globals, dns, confLib, ... }:
    +
    { lib, config, globals, dns, confLib, ... }:
     let
       inherit (confLib.gen { name = "grafana"; port = 3000; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
     
    @@ -12321,7 +12503,7 @@ let
     
       inherit (config.swarselsystems) sopsFile;
     
    -  sopsFile2 = "${config.node.secretsDir}/secrets2.yaml";
    +  # sopsFile2 = config.node.secretsDir + "/secrets2.yaml";
     in
     {
       options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    @@ -12336,7 +12518,8 @@ in
             grafana-admin-pw = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
             prometheus-admin-pw = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
             kanidm-grafana-client = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
    -        prometheus-admin-hash = { sopsFile = sopsFile2; owner = prometheusUser; group = prometheusGroup; mode = "0440"; };
    +        # prometheus-admin-hash = { sopsFile = sopsFile2; owner = prometheusUser; group = prometheusGroup; mode = "0440"; };
    +        prometheus-admin-hash = { inherit sopsFile; owner = prometheusUser; group = prometheusGroup; mode = "0440"; };
     
           };
           templates = {
    @@ -12535,7 +12718,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -12563,7 +12747,7 @@ in
     
    -
    3.2.3.29. Jenkins
    +
    3.2.3.29. Jenkins (currently unused)

    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. @@ -12606,7 +12790,8 @@ in }; virtualHosts = { "${serviceDomain}" = { - enableACME = true; + useACMEHost = globals.domains.main; + forceSSL = true; acmeRoot = null; locations = { @@ -12766,7 +12951,8 @@ in }; virtualHosts = { "${serviceDomain}" = { - enableACME = true; + useACMEHost = globals.domains.main; + forceSSL = true; acmeRoot = null; oauth2.enable = true; @@ -12936,7 +13122,8 @@ in }; virtualHosts = { "${serviceDomain}" = { - enableACME = true; + useACMEHost = globals.domains.main; + forceSSL = true; acmeRoot = null; locations = { @@ -13014,7 +13201,8 @@ in }; virtualHosts = { "${serviceDomain}" = { - enableACME = true; + useACMEHost = globals.domains.main; + forceSSL = true; acmeRoot = null; locations = { @@ -13051,6 +13239,18 @@ A stupid (but simple) way to get the originUrl is to simply set any To get other URLs (token, etc.), use https://<kanidmdomain>/oauth2/openid/%3CclientID%3E/.well-known/oauth-authorization-server, e.g. https://<kanidmdomain>/oauth2/openid/nextcloud/.well-known/oauth-authorization-server, with clienID being the client name as specified in kanidm.

    +

    +Create user: +

    + +

    +kanidm login -D idmadmin +

    + +

    +kanidm person credential create-reset-token <user> +

    +
    { self, lib, pkgs, config, globals, dns, confLib, ... }:
     let
    @@ -13230,7 +13430,7 @@ in
     
         services = {
           ${serviceName} = {
    -        package = pkgs.kanidmWithSecretProvisioning_1_7;
    +        package = pkgs.kanidmWithSecretProvisioning_1_8;
             enableServer = true;
             serverSettings = {
               domain = serviceDomain;
    @@ -13444,7 +13644,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -13678,7 +13879,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -13796,7 +13998,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = true;
    @@ -13945,7 +14148,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -14008,7 +14212,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -14034,10 +14239,11 @@ in
     
    3.2.3.39. Radicale
    -
    { self, lib, config, globals, dns, confLib, ... }:
    +
    { lib, config, globals, dns, confLib, ... }:
     let
       inherit (confLib.gen { name = "radicale"; port = 8000; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
    -  sopsFile = "${config.node.secretsDir}/secrets2.yaml";
    +  # sopsFile = config.node.secretsDir + "/secrets2.yaml";
    +  inherit (config.swarselsystems) sopsFile;
     
       cfg = config.services.${serviceName};
     in
    @@ -14136,7 +14342,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = false;
    @@ -14165,7 +14372,7 @@ in
     
    { self, lib, config, pkgs, dns, globals, confLib, ... }:
     let
    -  inherit (confLib.gen { name = "croc"; }) serviceName serviceDomain proxyAddress4 proxyAddress6;
    +  inherit (confLib.gen { name = "croc"; proxy = config.node.name; }) serviceName serviceDomain proxyAddress4 proxyAddress6;
       servicePorts = [
         9009
         9010
    @@ -14362,7 +14569,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -14487,7 +14695,7 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
               forceSSL = true;
               acmeRoot = null;
               locations = {
    @@ -14593,7 +14801,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = true;
    @@ -14618,13 +14827,14 @@ in
     
    -
    3.2.3.44. Snipe-IT
    +
    3.2.3.44. Snipe-IT (currently unused)
    -
    { self, lib, config, globals, dns, confLib, ... }:
    +
    { lib, config, globals, dns, confLib, ... }:
     let
       inherit (confLib.gen { name = "snipeit"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
    -  sopsFile = "${config.node.secretsDir}/secrets2.yaml";
    +  # sopsFile = config.node.secretsDir + "/secrets2.yaml";
    +  inherit (config.swarselsystems) sopsFile;
     
       serviceDB = "snipeit";
     
    @@ -14678,7 +14888,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = false;
    @@ -14745,7 +14956,8 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
    +
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = false;
    @@ -14859,8 +15071,8 @@ let
       garageAdminPort = 3903;
       garageK2VPort = 3904;
     
    -  adminDomain = "${subDomain}admin.${baseDomain}";
    -  webDomain = "${subDomain}web.${baseDomain}";
    +  adminDomain = "${subDomain}-admin.${baseDomain}";
    +  webDomain = "${subDomain}-web.${baseDomain}";
     in
     {
       options = {
    @@ -14911,12 +15123,14 @@ in
           }
         ];
     
    +    networking.firewall.allowedTCPPorts = [ servicePort 3901 3902 3903 3904 ];
    +
         nodes.stoicclub.swarselsystems.server.dns.${baseDomain}.subdomainRecords = {
           "${subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
    -      "${subDomain}admin" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
    -      "${subDomain}web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
    +      "${subDomain}-admin" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
    +      "${subDomain}-web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
           "*.${subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
    -      "*.${subDomain}web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
    +      "*.${subDomain}-web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
         };
     
         sops = {
    @@ -15147,10 +15361,6 @@ in
           };
         };
     
    -    security.acme.certs."${webDomain}" = {
    -      domain = "*.${webDomain}";
    -    };
    -
         nodes.${serviceProxy}.services.nginx = {
           upstreams = {
             ${serviceName} = {
    @@ -15171,7 +15381,7 @@ in
           };
           virtualHosts = {
             "${adminDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = false;
    @@ -15182,7 +15392,7 @@ in
               };
             };
             "*.${webDomain}" = {
    -          useACMEHost = webDomain;
    +          useACMEHost = globals.domains.main;
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = false;
    @@ -15194,7 +15404,7 @@ in
             };
             "${serviceDomain}" = {
               serverAliases = [ "*.${serviceDomain}" ];
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = false;
    @@ -15203,6 +15413,11 @@ in
                   proxyPass = "http://${serviceName}";
                   extraConfig = ''
                     client_max_body_size 0;
    +                client_body_timeout        600s;
    +                proxy_connect_timeout      600s;
    +                proxy_send_timeout         600s;
    +                proxy_read_timeout         600s;
    +                proxy_request_buffering    off;
                   '';
                 };
               };
    @@ -15216,8 +15431,8 @@ in
     
    -
    -
    3.2.3.48. Set host domain for dns
    +
    +
    3.2.3.48. Set host domain for dns
    { lib, config, globals, dns, confLib, ... }:
    @@ -15345,7 +15560,7 @@ with dns.lib.combinators; {
       SOA = {
         nameServer = "soa";
         adminEmail = "admin@${globals.domains.main}"; # this option is not parsed as domain (we cannot just write "admin")
    -    serial = 2025120203; # update this on changes for secondary dns
    +    serial = 2025120506; # update this on changes for secondary dns
       };
     
       useOrigin = false;
    @@ -15355,6 +15570,7 @@ with dns.lib.combinators; {
         "srv"
       ] ++ globals.domains.externalDns;
     
    +  CAA = letsEncrypt config.repo.secrets.common.dnsMail;
     
       A = [ config.repo.secrets.local.dns.homepage-ip ];
     
    @@ -15450,7 +15666,7 @@ with dns.lib.combinators; {
     
    { lib, config, pkgs, globals, dns, confLib, ... }:
     let
    -  inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
    +  inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; proxy = config.node.name; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
       inherit (config.swarselsystems) mainUser;
       worldName = "${mainUser}craft";
     in
    @@ -15510,7 +15726,7 @@ in
     let
       inherit (config.swarselsystems) sopsFile;
       inherit (confLib.gen { name = "mailserver"; dir = "/var/lib/dovecot"; user = "virtualMail"; group = "virtualMail"; port = 443; }) serviceName serviceDir servicePort serviceUser serviceGroup serviceDomain serviceProxy proxyAddress4 proxyAddress6;
    -  inherit (config.repo.secrets.local.mailserver) user1 alias1_1 alias1_2 alias1_3 alias1_4 user2 alias2_1 user3;
    +  inherit (config.repo.secrets.local.mailserver) user1 alias1_1 alias1_2 alias1_3 alias1_4 user2 alias2_1 alias2_2 user3;
       baseDomain = globals.domains.main;
     in
     {
    @@ -15539,7 +15755,7 @@ in
           { directory = "/var/sieve"; user = serviceUser; group = serviceGroup; mode = "0770"; }
           { directory = "/var/dkim"; user = "rspamd"; group = "rspamd"; mode = "0700"; }
           { directory = serviceDir; user = serviceUser; group = serviceGroup; mode = "0700"; }
    -      { directory = "/var/lib/postgresql"; user = "postgres"; group = "postgres"; mode = "0750"; }
    +      # { directory = "/var/lib/postgresql"; user = "postgres"; group = "postgres"; mode = "0750"; }
           { directory = "/var/lib/rspamd"; user = "rspamd"; group = "rspamd"; mode = "0700"; }
           { directory = "/var/lib/roundcube"; user = "roundcube"; group = "roundcube"; mode = "0700"; }
           { directory = "/var/lib/redis-rspamd"; user = "redis-rspamd"; group = "redis-rspamd"; mode = "0700"; }
    @@ -15571,6 +15787,7 @@ in
               hashedPasswordFile = config.sops.secrets.user2-hashed-pw.path;
               aliases = [
                 "${alias2_1}@${baseDomain}"
    +            "${alias2_2}@${baseDomain}"
               ];
               sendOnly = true;
             };
    @@ -15643,7 +15860,7 @@ $ attic cache create hello
     

    -
    { lib, config, globals, dns, confLib, ... }:
    +
    { lib, config, pkgs, globals, dns, confLib, ... }:
     let
       inherit (confLib.gen { name = "attic"; port = 8091; }) serviceName serviceDir servicePort serviceAddress serviceDomain serviceProxy proxyAddress4 proxyAddress6;
       inherit (config.swarselsystems) mainUser isPublic sopsFile;
    @@ -15681,8 +15898,33 @@ in
           };
         };
     
    +    networking.firewall.allowedTCPPorts = [ servicePort ];
    +
         services.atticd = {
           enable = true;
    +      # NOTE: remove once https://github.com/zhaofengli/attic/pull/268 is merged
    +      package = pkgs.attic-server.overrideAttrs
    +        (oldAttrs: {
    +          patches = (oldAttrs.patches or [ ]) ++ [
    +            (pkgs.writeText "remove-s3-checksums.patch" ''
    +              diff --git a/server/src/storage/s3.rs b/server/src/storage/s3.rs
    +              index 1d5719f3..036f3263 100644
    +              --- a/server/src/storage/s3.rs
    +              +++ b/server/src/storage/s3.rs
    +              @@ -278,10 +278,6 @@ impl StorageBackend for S3Backend {
    +                               CompletedPart::builder()
    +                                   .set_e_tag(part.e_tag().map(str::to_string))
    +                                   .set_part_number(Some(part_number as i32))
    +              -                    .set_checksum_crc32(part.checksum_crc32().map(str::to_string))
    +              -                    .set_checksum_crc32_c(part.checksum_crc32_c().map(str::to_string))
    +              -                    .set_checksum_sha1(part.checksum_sha1().map(str::to_string))
    +              -                    .set_checksum_sha256(part.checksum_sha256().map(str::to_string))
    +                                   .build()
    +                           })
    +                           .collect::<Vec<_>>();
    +            '')
    +          ];
    +        });
           environmentFile = config.sops.templates."attic.env".path;
           settings = {
             listen = "[::]:${builtins.toString servicePort}";
    @@ -15704,12 +15946,10 @@ in
                 bucket = serviceName;
                 # attic must be patched to never serve pre-signed s3 urls directly
                 # otherwise it will redirect clients to this localhost endpoint
    -            endpoint = "http://127.0.0.1:3900";
    +            endpoint = "http://127.0.0.1:3900"; # garage port
               } else {
                 type = "local";
                 path = serviceDir;
    -            # attic must be patched to never serve pre-signed s3 urls directly
    -            # otherwise it will redirect clients to this localhost endpoint
               };
     
             garbage-collection = {
    @@ -15718,11 +15958,11 @@ in
             };
     
             chunking = {
    -          nar-size-threshold = if config.swarselmodules.server.garage then 0 else 64 * 1024; # 64 KiB
    +          nar-size-threshold = if config.swarselmodules.server.garage then 0 else 64 * 1024; # garage using s3
     
    -          min-size = 16 * 1024; # 16 KiB
    -          avg-size = 64 * 1024; # 64 KiB
    -          max-size = 256 * 1024; # 256 KiBize = 262144;
    +          min-size = 16 * 1024;
    +          avg-size = 64 * 1024;
    +          max-size = 256 * 1024;
             };
           };
         };
    @@ -15754,7 +15994,7 @@ in
           };
           virtualHosts = {
             "${serviceDomain}" = {
    -          enableACME = true;
    +          useACMEHost = globals.domains.main;
               forceSSL = true;
               acmeRoot = null;
               oauth2.enable = false;
    @@ -15763,6 +16003,11 @@ in
                   proxyPass = "http://${serviceName}";
                   extraConfig = ''
                     client_max_body_size 0;
    +                client_body_timeout        600s;
    +                proxy_connect_timeout      600s;
    +                proxy_send_timeout         600s;
    +                proxy_read_timeout         600s;
    +                proxy_request_buffering    off;
                   '';
                 };
               };
    @@ -15776,6 +16021,157 @@ in
     
    +
    +
    3.2.3.54. Hydra
    +
    +

    +Need to create user manually: +

    + +

    +$ hydra-create-user alice –full-name 'Alice Q. User' \ + –email-address 'alice@example.org' –password-prompt –role admin +

    + + +
    +
    { inputs, lib, config, globals, dns, confLib, ... }:
    +let
    +  inherit (confLib.gen { name = "hydra"; port = 8002; }) serviceName servicePort serviceUser serviceGroup serviceAddress serviceDomain serviceProxy proxyAddress4 proxyAddress6;
    +  inherit (config.swarselsystems) sopsFile;
    +in
    +  {
    +    options = {
    +      swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
    +    };
    +    config = lib.mkIf config.swarselmodules.server.${serviceName} {
    +
    +      nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
    +        "${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
    +      };
    +
    +      globals.services.${serviceName} = {
    +        domain = serviceDomain;
    +        inherit proxyAddress4 proxyAddress6;
    +      };
    +
    +      sops = {
    +        secrets = {
    +          nixbuild-net-key = { mode = "0600"; };
    +          hydra-pw = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
    +        };
    +        templates = {
    +          "hydra-env" = {
    +            content = ''
    +              HYDRA_PW="${config.sops.placeholder.hydra-pw}"
    +            '';
    +            owner = serviceUser;
    +            group = serviceGroup;
    +            mode = "0440";
    +          };
    +        };
    +      };
    +
    +      services.hydra = {
    +        enable = true;
    +        package = inputs.hydra.packages.${config.node.arch}.hydra;
    +        port = servicePort;
    +        hydraURL = "https://${serviceDomain}";
    +        listenHost = "*";
    +        notificationSender = "hydra@${globals.domains.main}";
    +        minimumDiskFreeEvaluator = 20; # 20G
    +        minimumDiskFree = 20; # 20G
    +        useSubstitutes = true;
    +        smtpHost = globals.services.mailserver.domain;
    +        buildMachinesFiles = [
    +          "/etc/nix/machines"
    +        ];
    +        extraConfig = ''
    +          using_frontend_proxy 1
    +        '';
    +      };
    +
    +      systemd.services.hydra-user-setup = {
    +        description = "Create admin user for Hydra";
    +        serviceConfig = {
    +          Type = "oneshot";
    +          RemainAfterExit = true;
    +          User = "hydra";
    +          EnvironmentFile = [
    +            config.sops.templates.hydra-env.path
    +          ];
    +        };
    +        wantedBy = [ "multi-user.target" ];
    +        requires = [ "hydra-init.service" ];
    +        after = [ "hydra-init.service" ];
    +        environment = lib.mkForce config.systemd.services.hydra-init.environment;
    +        script = ''
    +          set -eu
    +        if [ ! -e ~hydra/.user-setup-done ]; then
    +          /run/current-system/sw/bin/hydra-create-user admin --full-name 'admin' --email-address 'admin@${globals.domains.main}' --password "$HYDRA_PW" --role admin
    +          touch ~hydra/.user-setup-done
    +        fi
    +        '';
    +      };
    +
    +      environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
    +      ];
    +
    +      nix = {
    +        settings.builders-use-substitutes = true;
    +        distributedBuilds = true;
    +        buildMachines = [
    +          {
    +            hostName = "localhost";
    +            protocol = null;
    +            system = config.node.arch;
    +            supportedFeatures = [ "kvm" "nixos-test" "big-parallel" "benchmark" ];
    +            maxJobs = 4;
    +          }
    +        ];
    +      };
    +
    +      networking.firewall.allowedTCPPorts = [ servicePort ];
    +
    +      programs.ssh = {
    +        extraConfig = ''
    +          StrictHostKeyChecking no
    +        '';
    +      };
    +
    +      nodes.${serviceProxy}.services.nginx = {
    +        upstreams = {
    +          ${serviceName} = {
    +            servers = {
    +              "${serviceAddress}:${builtins.toString servicePort}" = { };
    +            };
    +          };
    +        };
    +        virtualHosts = {
    +          "${serviceDomain}" = {
    +            enableACME = true;
    +            forceSSL = true;
    +            acmeRoot = null;
    +            oauth2.enable = false;
    +            locations = {
    +              "/" = {
    +                proxyPass = "http://${serviceName}";
    +                extraConfig = ''
    +                  client_max_body_size 0;
    +                proxy_set_header  X-Request-Base    /hydra;
    +                '';
    +              };
    +            };
    +          };
    +        };
    +      };
    +
    +    };
    +  }
    +
    +
    +
    +

    3.2.4. Darwin

    @@ -16270,6 +16666,7 @@ in _1password.enable = true; _1password-gui = { enable = true; + package = pkgs._1password-gui-beta; polkitPolicyOwners = [ "${mainUser}" ]; }; }; @@ -16437,8 +16834,8 @@ in
    -
    -
    3.2.5.11. Uni
    +
    +
    3.2.5.11. Uni
    { self, config, ... }:
    @@ -16504,8 +16901,8 @@ Some standard options that should be set vor every microvm guest. We set the def
     
    -
    -
    3.2.5.14. systemd-networkd (server)
    +
    +
    3.2.5.14. systemd-networkd (server)

    Some standard options that should be set vor every microvm guest. We set the default @@ -16518,7 +16915,7 @@ Some standard options that should be set vor every microvm guest. We set the def useDHCP = lib.mkForce false; useNetworkd = true; dhcpcd.enable = false; - renameInterfacesByMac = lib.mapAttrs (_: v: v.mac) ( + renameInterfacesByMac = lib.mapAttrs (_: v: if (v ? mac) then v.mac else "") ( config.repo.secrets.local.networking.networks or { } ); }; @@ -16728,8 +17125,8 @@ Again, we adapt nix to our needs, enable the home-manager command f (lib.mkIf ((config.swarselmodules ? server) ? ssh-builder) "builder") ]; connect-timeout = 5; - bash-prompt-prefix = lib.mkIf (config.swarselsystems.isClient) "$SHLVL:\\w "; - bash-prompt = lib.mkIf (config.swarselsystems.isClient) "$(if [[ $? -gt 0 ]]; then printf \"\"; else printf \"\"; fi)Ξ» "; + bash-prompt-prefix = lib.mkIf config.swarselsystems.isClient "$SHLVL:\\w "; + bash-prompt = lib.mkIf config.swarselsystems.isClient "$(if [[ $? -gt 0 ]]; then printf \"\"; else printf \"\"; fi)Ξ» "; fallback = true; min-free = 128000000; max-free = 1000000000; @@ -17110,6 +17507,7 @@ This is just a separate container for derivations defined in -

    { config, lib, inputs, type, ... }:
    +
    { self, config, lib, type, ... }:
     let
       inherit (config.swarselsystems) homeDir;
     in
    @@ -17152,7 +17550,8 @@ in
         config = lib.optionalAttrs (type != "nixos")  {
           sops = lib.mkIf (!config.swarselsystems.isNixos) {
             age.sshKeyPaths = [ "${if config.swarselsystems.isImpermanence then "/persist" else ""}${homeDir}/.ssh/sops" ];
    -        defaultSopsFile = "${if config.swarselsystems.isImpermanence then "/persist" else ""}${homeDir}/.dotfiles/secrets/repo/common.yaml";
    +        # defaultSopsFile = "${if config.swarselsystems.isImpermanence then "/persist" else ""}${homeDir}/.dotfiles/secrets/repo/common.yaml";
    +        defaultSopsFile = self + "/secrets/repo/common.yaml";
     
             validateSopsFiles = false;
           };
    @@ -17166,7 +17565,7 @@ in
     
    3.3.2.7. Yubikey
    -
    { lib, config, inputs, confLib, type, ... }:
    +
    { lib, config, confLib, type, ... }:
     let
       inherit (config.swarselsystems) homeDir;
     in
    @@ -17199,7 +17598,7 @@ It is very convenient to have SSH aliases in place for machines that I use. This
     

    -
    { inputs, lib, config, confLib, type, ... }:
    +
    { lib, config, confLib, type, ... }:
     {
       options.swarselmodules.ssh = lib.mkEnableOption "ssh settings";
       config = lib.mkIf config.swarselmodules.ssh ({
    @@ -18082,7 +18481,7 @@ Currently I only use it as before with initExtra though.
     

    -
    { config, pkgs, lib, minimal, inputs, globals, confLib, type, ... }:
    +
    { config, pkgs, lib, minimal, globals, confLib, type, ... }:
     let
       inherit (config.swarselsystems) flakePath isNixos;
       crocDomain = globals.services.croc.domain;
    @@ -19597,7 +19996,7 @@ Normally I use 4 mail accounts - here I set them all up. Three of them are Googl
     

    -
    { lib, config, inputs, globals, confLib, type, ... }:
    +
    { lib, config, globals, confLib, type, ... }:
     let
       inherit (confLib.getConfig.repo.secrets.common.mail) address1 address2 address2-name address3 address3-name address4;
       inherit (confLib.getConfig.repo.secrets.common) fullName;
    @@ -19978,7 +20377,7 @@ The rest of the related configuration is found here:
     
     
     
    -
    { self, config, lib, inputs, pkgs, type, ... }:
    +
    { self, config, lib, pkgs, type, ... }:
     let
       inherit (config.swarselsystems) xdgDir;
       generateIcons = n: lib.concatStringsSep " " (builtins.map (x: "{icon" + toString x + "}") (lib.range 0 (n - 1)));
    @@ -21826,7 +22225,7 @@ in
     
    3.3.2.39. Anki
    -
    { lib, config, pkgs, globals, inputs, confLib, type, ... }:
    +
    { lib, config, pkgs, globals, confLib, type, ... }:
     let
       moduleName = "anki";
       inherit (config.swarselsystems) isPublic isNixos;
    @@ -22675,7 +23074,7 @@ When setting up a new machine:
       - `pizauth dump > ~/.pizauth.state`
     
     
    -
    { self, inputs, config, pkgs, lib, vars, confLib, type, ... }:
    +
    { self, config, pkgs, lib, vars, confLib, type, ... }:
     let
       inherit (config.swarselsystems) homeDir mainUser;
       inherit (confLib.getConfig.repo.secrets.local.mail) allMailAddresses;
    @@ -22985,20 +23384,29 @@ in
                 };
               }
               {
    -            # work main screen
    +            # work side screen
                 output = {
                   criteria = "HP Inc. HP 732pk CNC4080YL5";
                   scale = 1.0;
                   mode = "3840x2160";
    +              transform = "270";
                 };
               }
    +          # {
    +          #   # work side screen
    +          #   output = {
    +          #     criteria = "Hewlett Packard HP Z24i CN44250RDT";
    +          #     scale = 1.0;
    +          #     mode = "1920x1200";
    +          #     transform = "270";
    +          #   };
    +          # }
               {
    -            # work side screen
    +            # work main screen
                 output = {
    -              criteria = "Hewlett Packard HP Z24i CN44250RDT";
    +              criteria = "HP Inc. HP Z32 CN41212T55";
                   scale = 1.0;
    -              mode = "1920x1200";
    -              transform = "270";
    +              mode = "3840x2160";
                 };
               }
               {
    @@ -23006,28 +23414,28 @@ in
                   name = "lidopen";
                   exec = [
                     "${pkgs.swaybg}/bin/swaybg --output '${config.swarselsystems.sharescreen}' --image ${config.swarselsystems.wallpaper} --mode ${config.stylix.imageScalingMode}"
    -                "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP 732pk CNC4080YL5' --image ${self}/files/wallpaper/botanicswp.png --mode ${config.stylix.imageScalingMode}"
    -                "${pkgs.swaybg}/bin/swaybg --output 'Hewlett Packard HP Z24i CN44250RDT' --image ${self}/files/wallpaper/op6wp.png --mode ${config.stylix.imageScalingMode}"
    +                "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP Z32 CN41212T55' --image ${self}/files/wallpaper/botanicswp.png --mode ${config.stylix.imageScalingMode}"
    +                "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP 732pk CNC4080YL5' --image ${self}/files/wallpaper/op6wp.png --mode ${config.stylix.imageScalingMode}"
                   ];
                   outputs = [
                     {
                       criteria = config.swarselsystems.sharescreen;
                       status = "enable";
                       scale = 1.5;
    -                  position = "1462,0";
    +                  position = "2560,0";
                     }
                     {
                       criteria = "HP Inc. HP 732pk CNC4080YL5";
    -                  scale = 1.4;
    +                  scale = 1.0;
                       mode = "3840x2160";
    -                  position = "-1280,0";
    +                  position = "-3440,-1050";
    +                  transform = "270";
                     }
                     {
    -                  criteria = "Hewlett Packard HP Z24i CN44250RDT";
    +                  criteria = "HP Inc. HP Z32 CN41212T55";
                       scale = 1.0;
    -                  mode = "1920x1200";
    -                  transform = "90";
    -                  position = "-2480,0";
    +                  mode = "3840x2160";
    +                  position = "-1280,0";
                     }
                   ];
                 };
    @@ -23064,8 +23472,8 @@ in
                 profile = {
                   name = "lidclosed";
                   exec = [
    -                "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP 732pk CNC4080YL5' --image ${self}/files/wallpaper/botanicswp.png --mode ${config.stylix.imageScalingMode}"
    -                "${pkgs.swaybg}/bin/swaybg --output 'Hewlett Packard HP Z24i CN44250RDT' --image ${self}/files/wallpaper/op6wp.png --mode ${config.stylix.imageScalingMode}"
    +                "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP Z32 CN41212T55'  --image ${self}/files/wallpaper/botanicswp.png --mode ${config.stylix.imageScalingMode}"
    +                "${pkgs.swaybg}/bin/swaybg --output 'HP Inc. HP 732pk CNC4080YL5' --image ${self}/files/wallpaper/op6wp.png --mode ${config.stylix.imageScalingMode}"
                   ];
                   outputs = [
                     {
    @@ -23074,16 +23482,16 @@ in
                     }
                     {
                       criteria = "HP Inc. HP 732pk CNC4080YL5";
    -                  scale = 1.4;
    +                  scale = 1.0;
                       mode = "3840x2160";
    -                  position = "-1280,0";
    +                  position = "-3440,-1050";
    +                  transform = "270";
                     }
                     {
    -                  criteria = "Hewlett Packard HP Z24i CN44250RDT";
    +                  criteria = "HP Inc. HP Z32 CN41212T55";
                       scale = 1.0;
    -                  mode = "1920x1200";
    -                  transform = "270";
    -                  position = "-2480,0";
    +                  mode = "3840x2160";
    +                  position = "-1280,0";
                     }
                   ];
                 };
    @@ -23160,7 +23568,7 @@ in
             };
     
             Service = {
    -          ExecStart = "${pkgs._1password-gui}/bin/1password";
    +          ExecStart = "${pkgs._1password-gui-beta}/bin/1password";
             };
           };
     
    @@ -23268,25 +23676,35 @@ in
               # output = "DP-7";
               output = name;
             };
    -        work_back_right = rec {
    +        work_middle_middle_main = rec {
               name = "HP Inc. HP Z32 CN41212T55";
               mode = "3840x2160";
               scale = "1";
    -          position = "5120,0";
    +          position = "-1280,0";
               workspace = "1:δΈ€";
               # output = "DP-3";
               output = name;
             };
    -        work_middle_middle_main = rec {
    +        # work_middle_middle_main = rec {
    +        #   name = "HP Inc. HP 732pk CNC4080YL5";
    +        #   mode = "3840x2160";
    +        #   scale = "1";
    +        #   position = "-1280,0";
    +        #   workspace = "11:M";
    +        #   # output = "DP-8";
    +        #   output = name;
    +        # };
    +        work_middle_middle_side = rec {
               name = "HP Inc. HP 732pk CNC4080YL5";
               mode = "3840x2160";
    +          transform = "270";
               scale = "1";
    -          position = "-1280,0";
    -          workspace = "11:M";
    +          position = "-3440,-1050";
    +          workspace = "12:S";
               # output = "DP-8";
               output = name;
             };
    -        work_middle_middle_side = rec {
    +        work_middle_middle_old = rec {
               name = "Hewlett Packard HP Z24i CN44250RDT";
               mode = "1920x1200";
               transform = "270";
    @@ -23478,8 +23896,9 @@ TODO: check which of these can be replaced but builtin functions.
         isLinux = lib.mkEnableOption "whether this is a linux machine";
         isBtrfs = lib.mkEnableOption "use btrfs filesystem";
         sopsFile = lib.mkOption {
    -      type = lib.types.str;
    -      default = "${if config.swarselsystems.isImpermanence then "/persist" else ""}${config.node.secretsDir}/secrets.yaml";
    +      type = lib.types.either lib.types.str lib.types.path;
    +      # default = (if config.swarselsystems.isImpermanence then "/persist" else "") + config.node.secretsDir + "/secrets.yaml";
    +      default = config.node.secretsDir + "/secrets.yaml";
         };
         homeDir = lib.mkOption {
           type = lib.types.str;
    @@ -23822,7 +24241,18 @@ In short, the options defined here are passed to the modules systems using 
    +
    +
    +
    +
    +
    3.4.6.7. prstatus
    +
    +

    +This script allows for quick checking of nixpkgs PR statuses. +

    + +
    +
    { name, writeShellApplication, curl, ... }:
    +
    +writeShellApplication {
    +  inherit name;
    +  runtimeInputs = [ curl ];
    +  text = ''
    +    curl https://nixpkgs.molybdenum.software/api/v2/landings/"$1"
    +  '';
    +}
    +
     
    -
    3.4.6.7. bak
    +
    3.4.6.8. bak

    This script lets me quickly backup files by appending .bak to the filename. @@ -24127,7 +24579,7 @@ writeShellApplication {

    -
    3.4.6.8. timer
    +
    3.4.6.9. timer

    This app starts a configuratble timer and uses TTS to say something once the timer runs out. @@ -24150,7 +24602,7 @@ writeShellApplication {

    -
    3.4.6.9. e
    +
    3.4.6.10. 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. @@ -24196,7 +24648,7 @@ writeShellApplication {

    -
    3.4.6.10. command-not-found
    +
    3.4.6.11. 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. @@ -24242,7 +24694,7 @@ command_not_found_handler() {

    -
    3.4.6.11. swarselcheck
    +
    3.4.6.12. 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. @@ -24327,7 +24779,7 @@ writeShellApplication {

    -
    3.4.6.12. swarselcheck-niri
    +
    3.4.6.13. swarselcheck-niri
    while :; do
    @@ -24382,7 +24834,7 @@ writeShellApplication {
     
    -
    3.4.6.13. swarselzellij
    +
    3.4.6.14. swarselzellij
    # KITTIES=$(($(pgrep -P 1 kitty | wc -l) - 1))
    @@ -24409,7 +24861,7 @@ writeShellApplication {
     
    -
    3.4.6.14. waybarupdate
    +
    3.4.6.15. 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. @@ -24456,7 +24908,7 @@ writeShellApplication {

    -
    3.4.6.15. opacitytoggle
    +
    3.4.6.16. opacitytoggle

    This app quickly toggles between 5% and 0% transparency. @@ -24483,7 +24935,7 @@ writeShellApplication {

    -
    3.4.6.16. fs-diff
    +
    3.4.6.17. 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. @@ -24524,7 +24976,7 @@ writeShellApplication {

    -
    3.4.6.17. github-notifications
    +
    3.4.6.18. 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. @@ -24550,7 +25002,7 @@ writeShellApplication {

    -
    3.4.6.18. kanshare
    +
    3.4.6.19. 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. @@ -24574,7 +25026,7 @@ writeShellApplication {

    -
    3.4.6.19. swarsel-bootstrap
    +
    3.4.6.20. swarsel-bootstrap

    This program sets up a new NixOS host remotely. It also takes care of secret management on the new host. @@ -24619,6 +25071,7 @@ function help_and_exit() { function cleanup() { rm -rf "$temp" + rm -rf /tmp/disko-password } trap cleanup exit @@ -24722,7 +25175,7 @@ fi LOCKED="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.node.lockFromBootstrapping)" if [[ $LOCKED == "true" ]]; then - red "THIS SYSTEM IS LOCKED FROM BOOTSTRAPPING" + red "THIS SYSTEM IS LOCKED FROM BOOTSTRAPPING - set 'node.lockFromBootstrapping = lib.mkForce false;' to proceed" exit fi @@ -24812,6 +25265,7 @@ if [ "$disk_encryption" -eq 1 ]; then green "Please confirm passphrase:" read -rs luks_passphrase_confirm if [[ $luks_passphrase == "$luks_passphrase_confirm" ]]; then + echo "$luks_passphrase" > /tmp/disko-password $ssh_root_cmd "echo '$luks_passphrase' > /tmp/disko-password" break else @@ -24900,7 +25354,7 @@ if yes_or_no "Do you want to manually edit .sops.yaml now?"; then vim "${git_root}"/.sops.yaml fi green "Updating all secrets files to reflect updates .sops.yaml" -sops updatekeys --yes --enable-local-keyservice "${git_root}"/hosts/nixos/"$target_arch"/"$target_hostname"/secrets/* +sops updatekeys --yes --enable-local-keyservice "${git_root}"/hosts/nixos/"$target_arch"/"$target_hostname"/secrets/* || true # -------------------------- 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 @@ -24971,6 +25425,8 @@ fi if yes_or_no "Reboot now?"; then $ssh_root_cmd "reboot" fi + +rm -rf /tmp/disko-password

    @@ -24987,7 +25443,7 @@ writeShellApplication {
    -
    3.4.6.20. swarsel-rebuild
    +
    3.4.6.21. swarsel-rebuild
    set -eo pipefail
    @@ -25117,7 +25573,7 @@ writeShellApplication {
     
    -
    3.4.6.21. swarsel-install
    +
    3.4.6.22. swarsel-install

    Autoformatting always puts the EOF with indentation, which makes shfmt check fail. When editing this block, unindent them manually. @@ -25330,7 +25786,7 @@ writeShellApplication {

    -
    3.4.6.22. swarsel-postinstall
    +
    3.4.6.23. swarsel-postinstall
    set -eo pipefail
    @@ -25422,7 +25878,7 @@ writeShellApplication {
     
    -
    3.4.6.23. t2ts
    +
    3.4.6.24. t2ts
    { name, writeShellApplication, ... }:
    @@ -25440,7 +25896,7 @@ writeShellApplication {
     
    -
    3.4.6.24. ts2t
    +
    3.4.6.25. ts2t
    { name, writeShellApplication, ... }:
    @@ -25458,7 +25914,7 @@ writeShellApplication {
     
    -
    3.4.6.25. vershell
    +
    3.4.6.26. vershell
    { name, writeShellApplication, ... }:
    @@ -25476,7 +25932,7 @@ writeShellApplication {
     
    -
    3.4.6.26. eontimer
    +
    3.4.6.27. eontimer
    { lib
    @@ -25580,7 +26036,7 @@ python3.pkgs.buildPythonApplication rec {
     
    -
    3.4.6.27. project
    +
    3.4.6.28. project
    set -euo pipefail
    @@ -25604,7 +26060,7 @@ writeShellApplication {
     
    -
    3.4.6.28. fhs
    +
    3.4.6.29. fhs
    { name, pkgs, ... }:
    @@ -25623,7 +26079,7 @@ pkgs.buildFHSEnv (base // {
     
    -
    3.4.6.29. swarsel-displaypower
    +
    3.4.6.30. swarsel-displaypower

    A crude script to power on all displays that might be attached. Needed because sometimes displays do not awake from sleep. @@ -25648,7 +26104,7 @@ writeShellApplication {

    -
    3.4.6.30. swarsel-mgba
    +
    3.4.6.31. swarsel-mgba

    AppImage version of mgba in which the lua scripting works. @@ -25682,7 +26138,7 @@ appimageTools.wrapType2 {

    -
    3.4.6.31. swarsel-deploy
    +
    3.4.6.32. swarsel-deploy
    # heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix
    @@ -25814,7 +26270,7 @@ writeShellApplication {
     
    -
    3.4.6.32. swarsel-build
    +
    3.4.6.33. swarsel-build
    { name, nix-output-monitor, writeShellApplication, ... }:
    @@ -25838,7 +26294,7 @@ writeShellApplication {
     
    -
    3.4.6.33. swarsel-instantiate
    +
    3.4.6.34. 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. @@ -25859,7 +26315,7 @@ writeShellApplication {

    -
    3.4.6.34. sshrm
    +
    3.4.6.35. 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. @@ -25892,7 +26348,7 @@ writeShellApplication {

    -
    3.4.6.35. endme
    +
    3.4.6.36. 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. @@ -25914,7 +26370,7 @@ writeShellApplication {

    -
    3.4.6.36. git-replace
    +
    3.4.6.37. git-replace

    This script allows for quick git replace of a string. @@ -26564,7 +27020,7 @@ in

    -

    4. Emacs

    +

    4. Emacse

    @@ -32857,7 +33313,7 @@ Here lies defined the readme for GitHub and Forgejo:

    -
      [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FSwarsel%2F.dotfiles%2Fbadge%3Fref%3Dmain&style=flat&labelColor=11111b)](https://actions-badge.atrox.dev/Swarsel/.dotfiles/goto?ref=main)
    +
    [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FSwarsel%2F.dotfiles%2Fbadge%3Fref%3Dmain&style=flat&labelColor=11111b)](https://actions-badge.atrox.dev/Swarsel/.dotfiles/goto?ref=main)
     
       ###### Disclaimer
     
    @@ -32881,33 +33337,38 @@ Here lies defined the readme for GitHub and Forgejo:
         - [nix-darwin](https://github.com/LnL7/nix-darwin)
         - [nix-on-droid](https://github.com/nix-community/nix-on-droid)
       - Streamlined configuration and deployment pipeline:
    -    - Framework for [packages](https://github.com/Swarsel/.dotfiles/blob/main/pkgs/default.nix), [overlays](https://github.com/Swarsel/.dotfiles/blob/main/overlays/default.nix), [modules](https://github.com/Swarsel/.dotfiles/tree/main/modules), and [library functions](https://github.com/Swarsel/.dotfiles/tree/main/lib/default.nix)
    -    - Dynamically generated host configurations
    -    - Limited local installer (no secrets handling) with a supported demo build
    -    - Fully autonomous remote deployment using [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) and [disko](https://github.com/nix-community/disko) (with secrets handling)
    +    - Framework for [packages](https://github.com/Swarsel/.dotfiles/blob/main/nix/packages.nix), [overlays](https://github.com/Swarsel/.dotfiles/blob/main/nix/overlays.nix), [modules](https://github.com/Swarsel/.dotfiles/tree/main/modules), and [library functions](https://github.com/Swarsel/.dotfiles/blob/main/nix/lib.nix)
    +    - Dynamically generated config:
    +      - host configurations
    +      - dns records
    +      - network setup (+ wireguard mesh on systemd-networkd)
    +    - Remote Builders for [x86_64,aarch64]-linux running in hydra, feeding a private nix binary cache
    +    - Bootstrapping:
    +      - Limited local installer (no secrets handling) with a supported demo build
    +      - Fully autonomous remote deployment using [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) and [disko](https://github.com/nix-community/disko) (with secrets handling)
         - Improved nix tooling
       - Support for advanced features:
         - Secrets handling using [sops-nix](https://github.com/Mic92/sops-nix) (pls no pwn ❀️)
         - Management of personally identifiable information using [nix-plugins](https://github.com/shlevy/nix-plugins)
         - Full Yubikey support
    -    - LUKS-encryption
    +    - LUKS-encryption with support for remote disk unlock over SSH
         - Secure boot using [Lanzaboote](https://github.com/nix-community/lanzaboote)
         - BTRFS-based [Impermanence](https://github.com/nix-community/impermanence)
         - Configuration shared between configurations (configuration for one nixosConfiguration can be defined in another nixosConfiguration)
         - Global attributes shared between all configurations to reduce attribute redeclaration
    +    - [Config library](https://github.com/Swarsel/.dotfiles/blob/9acfc5f93457ec14773cc0616cab616917cc8af5/modules/shared/config-lib.nix#L4) for defining config-based functions for generating service information
    +    - Reduced friction between full NixOS- and home-manager-only deployments regarding secrets handling and config sharing
     
       ## Documentation
     
    -  If you are mainly interested in how I configured this system, check out this page:
    +  The full documentation can be found here:
     
       [SwarselSystems literate configuration](https://swarsel.github.io/.dotfiles/)
     
    -  This file will take you through my design process, in varying amounts of detail.
    +  I went to great lengths in order to document the full design process of my infrastructure properly; the above document strives to serve as an introductory lecture to nix / NixOS while at the same time explaining the config in general.
     
    -  Otherwise, the files that are possibly of biggest interest are found here:
    +  If you only came here for my Emacs configuration, the relevant files are here:
     
    -  - [SwarselSystems.org](../SwarselSystems.org)
    -  - [flake.nix](../flake.nix)
       - [early-init.el](../files/emacs/early-init.el)
       - [init.el](../files/emacs/init.el)
     
    @@ -32967,68 +33428,76 @@ Here lies defined the readme for GitHub and Forgejo:
     
       ### Programs
     
    -  | Topic         | Program                         |
    -  |---------------|---------------------------------|
    -  |🐚 **Shell**   | [zsh](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/zsh.nix)                            |
    -  |πŸšͺ **DM**      | [greetd](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/common/login.nix)                         |
    -  |πŸͺŸ **WM**      | [SwayFX](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/sway.nix)                         |
    -  |⛩️ **Bar**     | [Waybar](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/waybar.nix)                         |
    -  |βœ’οΈ **Editor**  | [Emacs](https://github.com/Swarsel/.dotfiles/tree/main/files/emacs/init.el)                          |
    -  |πŸ–₯️ **Terminal**| [Kitty](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/kitty.nix)                          |
    -  |πŸš€ **Launcher**| [Fuzzel](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/fuzzel.nix)                         |
    -  |🚨 **Alerts**  | [Mako](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/mako.nix)                           |
    -  |🌐 **Browser** | [Firefox](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/zsh.nix)                        |
    -  |🎨 **Theme**   | [City-Lights (managed by stylix)](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/sharedsetup.nix)|
    +  | Topic         | Program                                                                                                                     |
    +  |---------------|-----------------------------------------------------------------------------------------------------------------------------|
    +  |🐚 **Shell**   | [zsh](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/zsh.nix)                                           |
    +  |πŸšͺ **DM**      | [greetd](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/common/login.nix)                                     |
    +  |πŸͺŸ **WM**      | [SwayFX](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/sway.nix)                                       |
    +  |⛩️ **Bar**     | [Waybar](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/waybar.nix)                                     |
    +  |βœ’οΈ **Editor**  | [Emacs](https://github.com/Swarsel/.dotfiles/tree/main/files/emacs/init.el)                                                 |
    +  |πŸ–₯️ **Terminal**| [Kitty](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/kitty.nix)                                       |
    +  |πŸš€ **Launcher**| [Fuzzel](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/fuzzel.nix)                                     |
    +  |🚨 **Alerts**  | [Mako](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/mako.nix)                                         |
    +  |🌐 **Browser** | [Firefox](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/zsh.nix)                                       |
    +  |🎨 **Theme**   | [City-Lights (managed by stylix)](https://github.com/Swarsel/.dotfiles/tree/main/modules/home/common/sharedsetup.nix)       |
     
       ### Services
     
    -  | Topic                 | Program                                                                                                             |
    -  |-----------------------|---------------------------------------------------------------------------------------------------------------------|
    -  |πŸ“– **Books**           |  [Kavita](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/kavita.nix)                           |
    -  |πŸ“Ό **Videos**          | [Jellyfin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/jellyfin.nix)                        |
    -  |🎡 **Music**           | [Navidrome](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/navidrome.nix) +  [Spotifyd](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/spotifyd.nix) +  [MPD](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/mpd.nix)                                                              |
    -  |πŸ—¨οΈ **Messaging**       | [Matrix](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/matrix.nix)                            |
    -  |πŸ“ **Filesharing**     | [Nectcloud](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/nextcloud.nix)                      |
    -  |🎞️ **Photos**          | [Immich](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/immich.nix)                            |
    -  |πŸ“„ **Documents**       | [Paperless](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/paperless.nix)                      |
    -  |πŸ”„ **File Sync**       | [Syncthing](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/syncthing.nix)                      |
    -  |πŸ’Ύ **Backups**         | [Restic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/restic.nix)                            |
    -  |πŸ‘οΈ **Monitoring**      | [Grafana](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/monitoring.nix)                       |
    -  |🍴 **RSS**             | [FreshRss](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/freshrss.nix)                        |
    -  |🌳 **Git**             | [Forgejo](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/forgejo.nix)                          |
    -  |βš“ **Anki Sync**       | [Anki Sync Server](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/ankisync.nix)                |
    -  |πŸͺͺ **SSO**             | [Kanidm](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/kanidm.nix) + [oauth2-proxy](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/oauth2-proxy.nix)                                            |
    -  |πŸ’Έ **Finance**         | [Firefly-III](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/firefly-iii.nix)                  |
    -  |πŸƒ **Collections**     | [Koillection](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/koillection.nix)                  |
    -  |πŸ—ƒοΈ **Shell History**   | [Atuin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/atuin.nix)                              |
    -  |πŸ“… **CalDav/CardDav**  | [Radicale](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/radicale.nix)                        |
    -  |↔️ **P2P Filesharing** | [Croc](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/croc.nix)                                |
    -  |βœ‚οΈ **Paste Tool**      | [Microbin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/microbin.nix)                        |
    -  |πŸ“Έ **Image Sharing**   | [Slink](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/slink.nix)                              |
    -  |πŸ”— **Link Shortener**  | [Shlink](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/shlink.nix)                            |
    +  | Topic                      | Program                                                                                                        |
    +  |----------------------------|----------------------------------------------------------------------------------------------------------------|
    +  |πŸ“– **Books**                |  [Kavita](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/kavita.nix)                      |
    +  |πŸ“Ό **Videos**               | [Jellyfin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/jellyfin.nix)                   |
    +  |🎡 **Music**                | [Navidrome](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/navidrome.nix) +  [Spotifyd](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/spotifyd.nix) +  [MPD](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/mpd.nix)                                                              |
    +  |πŸ—¨οΈ **Messaging**            | [Matrix](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/matrix.nix)                       |
    +  |πŸ“ **Filesharing**          | [Nectcloud](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/nextcloud.nix)                 |
    +  |🎞️ **Photos**               | [Immich](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/immich.nix)                       |
    +  |πŸ“„ **Documents**            | [Paperless](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/paperless.nix)                 |
    +  |πŸ”„ **File Sync**            | [Syncthing](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/syncthing.nix)                 |
    +  |πŸ’Ύ **Backups**              | [Restic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/restic.nix)                       |
    +  |πŸ‘οΈ **Monitoring**           | [Grafana](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/monitoring.nix)                  |
    +  |🍴 **RSS**                  | [FreshRss](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/freshrss.nix)                   |
    +  |🌳 **Git**                  | [Forgejo](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/forgejo.nix)                     |
    +  |βš“ **Anki Sync**            | [Anki Sync Server](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/ankisync.nix)           |
    +  |πŸͺͺ **SSO**                  | [Kanidm](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/kanidm.nix) + [oauth2-proxy](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/oauth2-proxy.nix)                                            |
    +  |πŸ’Έ **Finance**              | [Firefly-III](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/firefly-iii.nix)             |
    +  |πŸƒ **Collections**          | [Koillection](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/koillection.nix)             |
    +  |πŸ—ƒοΈ **Shell History**        | [Atuin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/atuin.nix)                         |
    +  |πŸ“… **CalDav/CardDav**       | [Radicale](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/radicale.nix)                   |
    +  |↔️ **P2P Filesharing**      | [Croc](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/croc.nix)                           |
    +  |βœ‚οΈ **Paste Tool**           | [Microbin](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/microbin.nix)                   |
    +  |πŸ“Έ **Image Sharing**        | [Slink](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/slink.nix)                         |
    +  |πŸ”— **Link Shortener**       | [Shlink](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/shlink.nix)                       |
    +  |⛏️ **Minecraft**            | [Minecraft](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/minecraft.nix)                 |
    +  |☁️ **S3**                   | [Garage](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/garage.nix)                       |
    +  |πŸ•ΈοΈ **Nix Binary Cache**     | [Attic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/attic.nix)                         |
    +  |πŸ™ **Nix Build farm**       | [Attic](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/hydra.nix)                         |
    +  |πŸ”‘ **Cert-based SSH**       | [OPKSSH](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/opkssh.nix)                       |
    +  |πŸ”¨ **Home Asset Management**| [Homebox](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/homebox.nix)                     |
    +  |πŸ‘€ **DNS**                  | [NSD](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/nsd.nix)                             |
    +  |βœ‰οΈ **Mail**                 | [simple-nixos-mailserver](https://github.com/Swarsel/.dotfiles/tree/main/modules/nixos/server/mailserver.nix)  |
     
       ### Hosts
     
    -  | Name                | Hardware                                            | Use                                                 |
    -  |---------------------|-----------------------------------------------------|-----------------------------------------------------|
    -  |πŸ’» **pyramid**       | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                         |
    -  |πŸ’» **bakery**        | Lenovo Ideapad 720S-13IKB                           | Personal laptop                                     |
    -  |πŸ’» **machpizza**     | MacBook Pro 2016                                    | MacOS reference and build sandbox                   |
    -  |🏠 **treehouse**     | NVIDIA DGX Spark                                    | AI Workstation, remote builder, hm-only-reference   |
    -  |πŸ–₯️ **summers**       | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM  | Homeserver (microvms), remote builder, datastorage  |
    -  |πŸ–₯️ **winters**       | ASRock J4105-ITX, 32GB RAM                          | Homeserver (IoT server in spe)                      |
    -  |πŸ–₯️ **hintbooth**     | HUNSN RM02, 8GB RAM                                 | Router                                              |
    -  |☁️ **stoicclub**     | Cloud Server: 1 vCPUs, 8GB RAM                      | Authoritative dns server                            |
    -  |☁️ **liliputsteps**  | Cloud Server: 1 vCPUs, 8GB RAM                      | SSH bastion                                         |
    -  |☁️ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM                      | Service proxy                                       |
    -  |☁️ **eagleland**     | Cloud Server: 2 vCPUs, 8GB RAM                      | Mailserver                                          |
    -  |☁️ **moonside**      | Cloud Server: 4 vCPUs, 24GB RAM                     | Gaming server, syncthing + lightweight services     |
    -  |☁️ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM                     | Hydra builder and nix binarycache                   |
    -  |πŸ“± **magicant**      | Samsung Galaxy Z Flip 6                             | Phone                                               |
    -  |πŸ’Ώ **drugstore**     | -                                                   | NixOS-installer ISO for bootstrapping new hosts     |
    -  |πŸ’Ώ **brickroad**     | -                                                   | Kexec tarball for bootstrapping low-memory machines |
    -  |❔ **chaotheatre**   | -                                                   | Demo config for checking out this configuration     |
    -  |❔ **toto**          | -                                                   | Helper configuration for testing purposes           |
    +  | Name                | Hardware                                            | Use                                                             |
    +  |---------------------|-----------------------------------------------------|-----------------------------------------------------------------|
    +  |πŸ’» **pyramid**       | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                                     |
    +  |πŸ’» **bakery**        | Lenovo Ideapad 720S-13IKB                           | Personal laptop                                                 |
    +  |πŸ’» **machpizza**     | MacBook Pro 2016                                    | MacOS reference and build sandbox                               |
    +  |🏠 **treehouse**     | NVIDIA DGX Spark                                    | AI Workstation, remote builder, hm-only-reference               |
    +  |πŸ–₯️ **summers**       | ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM  | Homeserver (microvms), remote builder, data storage             |
    +  |πŸ–₯️ **winters**       | ASRock J4105-ITX, 32GB RAM                          | Homeserver (IoT server in spe)                                  |
    +  |πŸ–₯️ **hintbooth**     | HUNSN RM02, 8GB RAM                                 | Router                                                          |
    +  |☁️ **stoicclub**     | Cloud Server: 1 vCPUs, 8GB RAM                      | Authoritative DNS server                                        |
    +  |☁️ **liliputsteps**  | Cloud Server: 1 vCPUs, 8GB RAM                      | SSH bastion                                                     |
    +  |☁️ **twothreetunnel**| Cloud Server: 2 vCPUs, 8GB RAM                      | Service proxy                                                   |
    +  |☁️ **eagleland**     | Cloud Server: 2 vCPUs, 8GB RAM                      | Mailserver                                                      |
    +  |☁️ **moonside**      | Cloud Server: 4 vCPUs, 24GB RAM                     | Gaming server, syncthing + lightweight services                 |
    +  |☁️ **belchsfactory** | Cloud Server: 4 vCPUs, 24GB RAM                     | Hydra builder and nix binary cache                              |
    +  |πŸ“± **magicant**      | Samsung Galaxy Z Flip 6                             | Phone                                                           |
    +  |πŸ’Ώ **drugstore**     | -                                                   | NixOS-installer ISO for bootstrapping new hosts                 |
    +  |πŸ’Ώ **brickroad**     | -                                                   | Kexec tarball for bootstrapping low-memory machines             |
    +  |❔ **hotel**         | -                                                   | Demo config for checking out this configuration                 |
    +  |❔ **toto**          | -                                                   | Helper configuration for testing purposes                       |
       </details>
     
       ## General Nix tips & useful links
    @@ -33315,6 +33784,16 @@ If you want to merge nested attribute sets, use nixpkgs.lib.recursiveUpdat
     
     [ 2 3 4 ]
     
    + + +
    +
    swarsel-instantiate 'lib.map (x: { result = x + 1; }) [1 2 3]'
    +
    +
    + +
    +[ { result = 2; } { result = 3; } { result = 4; } ]
    +
    @@ -33493,7 +33972,7 @@ similarly, there exists an version that starts from the right.

    Author: Leon SchwarzΓ€ugl

    -

    Created: 2025-12-02 Di 17:29

    +

    Created: 2025-12-18 Do 17:26

    Validate