diff --git a/SwarselSystems.org b/SwarselSystems.org index 14d08ba..baba124 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -290,22 +290,23 @@ Here I give a brief overview over the hostmachines that I am using. This is held :CUSTOM_ID: h:c7588c0d-2528-485d-b2df-04d6336428d7 :END: -Handling the flake.nix file used to be a bit of a chore, since it felt like writing so much boilerplate code just to define new systems. The noweb-approach here makes this a little bit less painful. +Handling the flake.nix file used to be a bit of a chore, since it felt like writing so much boilerplate code just to define new systems. For a while, I used noweb-ref in order to alleviate this problem (see [[#h:dae0c5bb-edb7-4fe4-ae31-9f8f064cc53c][Appendix A: Noweb-Ref blocks]], an example of the repository at that time would be =acc0ad6: Add several NixOS hosts on Proxmox and Oracle Cloud=.). However, the true answer laid in making use of builtin nix functionality. -These blocks are later inserted here: [[#h:aee5ec75-7ca6-40d8-b6ac-a3e7e33a474b][flake.nix template]]. Adding new flake inputs is very easy, you just add them to [[#h:8a411ee2-a58e-4b5b-99bd-4ba772f8f0a2][Inputs & Inputs@Outputs]] first by name in the first source-block, and then the path in the second source-block. Any variables to be set for the host configuration are done in [[#h:df0072bc-853f-438f-bd85-bfc869501015][let]], and the specific setup is done in either [[#h:9c9b9e3b-8771-44fa-ba9e-5056ae809655][nixosConfigurations]] (for NixOS systems), [[#h:f881aa05-a670-48dd-a57b-2916abdcb692][homeConfigurations]] (for home-manager systems), or [[#h:5f6ef553-59f9-4239-b6f3-63d33b57f335][nixOnDroidConfigurations]] (for Nix on Android) and [[#h:f881aa05-a670-48dd-a57b-2916abdcb692][darwinConfigurations]] (for Darwin systems, also known as Macs). There also used to be a [[#h:6a08495a-8566-4bb5-9fac-b03df01f6c81][nixos-generators]] section that used to define a Proxmox LXC image when I was still using Proxmox as my main server. An example of the repository at that time would be =acc0ad6: Add several NixOS hosts on Proxmox and Oracle Cloud=. +Nowadays, I use flake-parts to manage my flake. It allows me to conveniently split the actual flake into multiple files ("parts") using the following mechanism: + +- =imports= are files pulled in to build the flake configuration (similar to the imports in the module system) +- =systems= defines the architectures that the flake should be provided for - I go here for the four "main" architectures, although true support is only provided for linux systems (see [[#h:6ed1a641-dba8-4e85-a62e-be93264df57a][Packages (pkgs)]] for the main reason) ** flake.nix skeleton :PROPERTIES: :CUSTOM_ID: h:aee5ec75-7ca6-40d8-b6ac-a3e7e33a474b :END: -This sections puts together the =flake.nix= file from the [[#h:d39b8dfb-536d-414f-9fc0-7d67df48cee4][Noweb-Ref blocks]] section. This tangles the flake.nix file; This block only needs to be touched when updating the general structure of the flake. For everything else, see the respective noweb-ref block. +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, options, and more. 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 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. - -In =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 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 this section I am creating some attributes that define general concepts of my configuration: @@ -349,8 +350,6 @@ A short overview over each input and what it does: This brings nix to android in an app that is similar to tmux! Of course most of the configuration does not apply to this, but it is still neat to have! - [[https://github.com/NixOS/nixos-hardware][nixos-hardware]] Provides specific hardware setting for some hardware configurations. For example, this sets some better defaults for my Lenovo Thinkpad P14s Gen2. -- [[https://github.com/thiagokokada/nix-alien][nix-alien]] - This is supposed to allow me to run unpatched libraries directly without a need for ELF patching or resorting to =steam-run=. However, I have not yet gotten this to work. - [[https://github.com/nix-community/nixos-generators][nixos-generators]] Provides me with images that I can use to create LXCs on Proxmox. - [[https://github.com/Swarsel/nswitch-rcm-nix][nswitch-rcm-nix]] @@ -369,12 +368,12 @@ A short overview over each input and what it does: After learning that MacOS systems can also be configured using nix, I managed to get access to an old MacBook for testing. This allows to set most general settings that can otherwise be set using the Mac GUI. - [[https://github.com/cachix/git-hooks.nix][pre-commit-hooks]] Provides access to several checks that can be hooked to be run before several stages in the process. -- nix-secrets - This is a private repository that I use for settings in modules that do not expose a =secretsFile= (or similar) option. An example is the =LastFM.ApiKey= option in [[#h:f347f3ad-5100-4c4f-8616-cfd7f8e14a72][navidrome]]: - =LastFM.ApiKey = builtins.readFile "${secretsDirectory}/navidrome/lastfm-secret";= -When setting this option normally, the password would normally be written world-readable not only in the nix store, but also in the configuration. Hence, I put such passwords into a private repository. This allows me to keep purity of the flake while keeping a level of security on these secrets. - [[https://github.com/oddlama/nix-topology][nix-topology]] This automatically creates a topology diagram of my configuration. +- flake-parts + The aforementioned system that allows for more convenient flake crafting. +- devshell + This provides devshell support for flake-parts #+begin_src nix :noweb yes :tangle flake.nix { @@ -422,9 +421,6 @@ When setting this option normally, the password would normally be written world- nixos-hardware = { url = "github:NixOS/nixos-hardware/master"; }; - nix-alien = { - url = "github:thiagokokada/nix-alien"; - }; nswitch-rcm-nix = { url = "github:Swarsel/nswitch-rcm-nix"; }; @@ -493,11 +489,23 @@ When setting this option normally, the password would normally be written world- :PROPERTIES: :CUSTOM_ID: h:23602ad9-91f6-4eba-943a-2308070fbaec :END: + +Here I define some extra files that are crucial for success in building my configurations. These are not pulled in by the flake directly, but I still feel like they should be mentioned at the flake level. + *** extra-builtins :PROPERTIES: :CUSTOM_ID: h:87c7893e-e946-4fc0-8973-1ca27d15cf0e :END: +This file is used by [[https://github.com/shlevy/nix-plugins][nix-plugins]]. nix-plugins generally allows for the introduction of arbitrary functions into the =builtins= set. However, I do not want to allow just any function to be added there. Instead, I only add a single function called =sopsImportEncrypted=. This function is used in order to help me store PII (personally identifiable information) in my repo without having to resort to either: + +- [[https://github.com/AGWA/git-crypt][git-crypt]] +- a separate repo containing my secrets + + As for the second approach, I actually used this up to some point (see for example =7e11641: feat: add initial oauth2-proxy and freshrss oidc= as one of the lasts commits still using this system). However, it is quite bothersome to constantly have to keep two repositories up to date and in sync. Also, having a repo that every configuration relied upon that was also a private repo led to the problem that my demo configuration ([[#h:e1498bef-ec67-483d-bf02-76264e30be8e][ChaosTheatre (Demo Physical/VM)]]) would fail to build with that present, and I had to take several extra steps to make it buildable. Ever since deleting that dependency I also got rid of that problem. The whole system is inspired by [[https://oddlama.org/blog/evaluation-time-secrets-in-nix/][this blog article]] and large parts of it are adapted from [[https://github.com/oddlama/nix-config][oddlama's nix-config]]. + +The builtin that is added is a simple call to the =exec= function that calls a bash script. In order to keep some sanity, we are checking that we are actually calling it no an encryted nix file (even though there is no syntax check inside) and that the path given is a true nix path. Note that a string path will not be accepted, as that can have impurity implications. + #+begin_src nix-ts :tangle nix/extra-builtins.nix # adapted from https://github.com/oddlama/nix-config/blob/main/nix/extra-builtins.nix { exec, ... }: @@ -533,6 +541,8 @@ When setting this option normally, the password would normally be written world- :CUSTOM_ID: h:315e6ef6-27d5-4cd8-85ff-053eabe60ddb :END: +This is the file that manages the actual decryption of the files mentioned in [[#h:87c7893e-e946-4fc0-8973-1ca27d15cf0e][extra-builtins]]. We simply fetch the appropriate system age key from the ssh host key and then call =sops decrypt=. Since it would be a bother to decrypt these files on every build, I keep the result cached and only re-decrypt if it changes. Keeping it cached outside the nix store incurrs a theoretical bit of impurity. However, this is easier to manage and also nothing really relies on these files being present. + #+begin_src shell :tangle nix/sops-decrypt-and-cache.sh :shebang #!/usr/bin/env bash # adapted from https://github.com/oddlama/nix-config/blob/main/nix/rage-decrypt-and-cache.sh set -euo pipefail @@ -579,18 +589,25 @@ When setting this option normally, the password would normally be written world- :CUSTOM_ID: h:f9b7ffba-b7e2-4554-9a35-ece0bf173e1c :END: -This section defines all functions of my own that I add to =lib=. These are used in all places over the config, with many of them being used in =flake.nix=. +This section defines all functions of my own that I add to =lib=. These are used in all places over the config, however mainly in the files responsible for handling various imports. + +A breakdown for the functions that have a non-obvious purpose: + +- =pkgsFor=: This function reads all available systems from nixpkgs and generates pkgs for them. This is needed for my generation of home-manager and nix-on-droid systems in [[#h:5c5bf78a-9a66-436f-bd85-85871d9d402b][Hosts]]. + - =nixpkgs.lib.genAttrs= is used to generate an attribute set (a dictionary-like structure) from a list of keys and a function that computes the values for those keys: =genAttrs ["a" "b" "c"] (x: "${x}-value")= will produce ={ a = "a-value"; b = "b-value"; c = "c-value"; }=. + - Also, in that function I am defining the =pkgs= that should be used when I reference =pkgs= in the actual configuration. I want to make sure that the correct system is used (keep in mind this is for home-manager configurations, which need that info! As a remark, you would not set this for a NixOS host), that I load my [[#h:7a059bd9-13f8-4005-b270-b41eeb6a4af2][Overlays]] (extra packages and modifications that I add to =pkgs=), as well as a setting that allows me to install unfree software. As a base package set I choose =nixpkgs= from my inputs (and so does nearly every configuration out there. Keep in mind however that you could use any package set here! =nixpkgs= however also comes with a lot of useful =lib= functions (that are not =builtins= to the nix language!)) +- =mkTrueOption=: Defines a nixos module option that is by default enables (as opposed to =mkEnableOption= which are per default disabled). +- =mkStrong=: This function uses =nixpkgs.lib.mkOverride= in order to set a priority for an expression that is higher than setting an option normally (i.e. =option = value=;) which has priority 100, while being of lower priority than using =nixpkgs.lib.mkForce=, which has priority 50 (lower priority takes precedence). For completeness' sake, the priority set when using =nixpkgs.lib.mkDefault= is 1000 (a very low value). +- =forEachLinuxSystem=: performs the =pkgsFor= function for a set of =systems= (here: =x86_64-linux= and =aarch64-linux=). I need to use this in the [[#h:6ed1a641-dba8-4e85-a62e-be93264df57a][Packages (pkgs)]] section in order to avoid trying to build those packages for darwin systems. +- =readHosts=: Reads the names of directories under the =hosts/= folder for a particular system type + - =builtins.readDir= reads the name of items of a directory as attributes and their type as values. As an example =builtins.readDir ./hosts/nixos= ran on this flake yieled at some point the output ={ bakery = "directory"; chaostheatre = "directory"; milkywell = "directory"; moonside = "directory"; pyramid = "directory"; toto = "directory"; winters = "directory"; }= + - =nixpkgs.lib.attrNames= is used to aquire these attribute names (you might think of them as the "keys") from the output of =builtins.readDir= +- =readNix=: reads all files in a directory that are not =default.nix= (usually used to simply load everything from a folder and is called inside that respective =default.nix=). +- =mk[Modules,Profiles,Imports]=: These are used to help with importing files mostly: + - builtins.listToAttrs converts a list of name-value pairs into an attribute set. =builtins.listToAttrs [{ name = "foo"; value = 1; } { name = "bar"; value = 2; }]= for example returns ={ bar = 2; foo = 1; }=. + - =nixpkgs.lib.map= takes a function and applies the elements of a list upon them, e.g. =lib.map (x: x + 1) [1 2 3]= yields =[ 2 3 4 ]=. This is always used in =mkImports= to actually import the list of modules that are generated by the other =mk[...]= options. -A breakdown of each function: -The interesting part is in the start: -- first, I define =pkgsFor=. This function reads all available systems from nixpkgs and generates pkgs for them. -- next, =forEachSystem= is a function that can be called to declare an output for each such defined system. -- =forAllSystems= is a crude function that I use for expressions that depend on =system=, as the prior two attributes already consumed it at that stage. This is only really used to generate the checks in their own file. -- =mkFullHostConfigs= is the function that dynamically creates all definded hosts. The hosts are defined by placing a directory in =hosts/= under either the =nixos/= or =darwin/= directory. These directories are being read by =readHosts= and delivered to this funtion in the later call in [[#h:9c9b9e3b-8771-44fa-ba9e-5056ae809655][nixosConfigurations]] or [[#h:f881aa05-a670-48dd-a57b-2916abdcb692][darwinConfigurations]]. -- =mkFullHost=: - This is a function that takes a hostname as well as a boolean whether it is NixOS or not, and returns a matching =nixosSystem= or =darwinSystem=. This function is only used for systems that can use both NixOS and home-manager options (darwin still counts here as it can use some NixOS options). This is used in mkFullHostConfigs. In more detail, it dynamically creates a nixosConfiguration host, setting its =speciaArgs= and =modules= attributes. The modules are populated based on whether this is a NixOS or darwin host. For the latter, I will only ever use machines that I get for testing from work, and for these my username is different, so I implemented an if-condition for it. This could be done more cleanly using variables, but some care needs to be taken with the home-manager imports and this approach works, so for now this is fine. Thanks to this function, the import sections of the host configs are pretty clean for most hosts. - =lib.optionals= evaluates to an empty list (=[]=) in case that the conditional is not met. #+begin_src nix-ts :tangle nix/lib.nix { self, inputs, ... }: @@ -636,15 +653,12 @@ The interesting part is in the start: mkStrong = lib.mkOverride 60; - forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system}); + # forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system}); forEachLinuxSystem = f: lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: f pkgsFor.${system}); readHosts = type: lib.attrNames (builtins.readDir "${self}/hosts/${type}"); readNix = type: lib.filter (name: name != "default.nix") (lib.attrNames (builtins.readDir "${self}/${type}")); - - - mkModules = names: type: builtins.listToAttrs (map (name: { inherit name; @@ -659,18 +673,7 @@ The interesting part is in the start: }) names); - mkImports = names: baseDir: lib.map (name: "${self}/${baseDir}/${name}") names; - - eachMonitor = _: monitor: { - inherit (monitor) name; - value = builtins.removeAttrs monitor [ "workspace" "name" "output" ]; - }; - - eachOutput = _: monitor: { - inherit (monitor) name; - value = builtins.removeAttrs monitor [ "mode" "name" "scale" "transform" "position" ]; - }; }; in { @@ -687,7 +690,9 @@ The interesting part is in the start: :CUSTOM_ID: h:6ed1a641-dba8-4e85-a62e-be93264df57a :END: -This does not use =perSystem= since some of my custom packages are not able to be built on darwin systems, and I was not yet interested in writing logic for handling that. +This does not use =perSystem= from =flake-parts= since some of my custom packages are not able to be built on darwin systems, and I was not yet interested in writing logic for handling that. Instead I use =forEachLinuxSystem= as described in [[#h:f9b7ffba-b7e2-4554-9a35-ece0bf173e1c][Library functions]] in roder to only build this for linux hosts. + +More information on the actual packages build can be found in [[#h:64a5cc16-6b16-4802-b421-c67ccef853e1][Packages]]. #+begin_src nix-ts :tangle nix/packages.nix { self, ... }: @@ -706,7 +711,16 @@ This does not use =perSystem= since some of my custom packages are not able to b :CUSTOM_ID: h:af83893d-c0f9-4b45-b816-4849110d41b3 :END: -The structure of =globals.nix.enc= requires a toplevel =globals=. +This file is used to parse each =nixosConfiguration= present in this flake and scan them for options set under the =globals= attribute set. I use =lib.evalModules= to evaluate a mini module system that only consists of these globals options and then load them into the actual configuration by providing a =globals= output to the flake. This treads a dangerous ground of infinite recursions, which is why both the module system as well as the inherited attributes are kept to the minimal size. Each module has a globals option loaded from a module file which will be separately loaded by this mini-evaluation. + + - =nixpkgs.lib.mapAttrsToList= converts an attribute set into a list by applying a given function to each name-value pair: =lib.mapAttrsToList (name: value: "${name} = ${value}) { a = "1"; b = "2"; }= yields the list =[ "a = 1" "b = 2" ]=. It is used on =config.nodes=. + - =nixpkgs.lib.flip= is used to reverse the function argument order of the =mapAttrsToList= call, so that we can give the attribute set (=config.nodes=) first. Alternatively, we could have written =lib.mapAttrsToList (name: cfg: [...]) config.nodes= but it would be harder to read since there would be a big block between the arguments. + - =nixpkgs.lib.concatLists=, as the name suggests, concatenates lists: =lib.concatLists [ [ 1 2 ] [ 3 4 ] [ 5 ] ]= yields =[ 1 2 3 4 5 ]=. =options.config._globalDefs= holds the =options.globals.definitions= for each node (which in turn basically holds the information that has been set for each node under the =globals= option), so the concatenated list will look something like =[ { services.kanidm.domain = "foo"; }; } { services.freshrss.domain = "bar"; } ]=. + - =nixpgks.lib.mkMerge= is used to merge these seperate attribute sets in the list into one big attribute set (the above attribute set example would become then ={ services = { kanidm.domain = "foo"; freshrss.domain = "bar"; }; }=. You can see how this can now be referenced as a "global" set. + +I also have a file for global values that cannot be attributed to one =nixosConfiguration= alsone; the structure of this =globals.nix.enc= requires a toplevel =globals= - that means, =globals.nix.enc= has the structure ={ globals = [...] }=. + +Lastly, in order make this actually available to my configurations, i use the =inherit (globalsSystem.config.globals) [...]= which produces the =globals= output which I will pass to the =specialArgs= of my =nixosConfigurations=, which is when I will be finally able to use these definitions in my config. #+begin_src nix-ts :tangle nix/globals.nix # adapted from https://github.com/oddlama/nix-config/blob/main/nix/globals.nix @@ -778,6 +792,15 @@ The structure of =globals.nix.enc= requires a toplevel =globals=. :CUSTOM_ID: h:5c5bf78a-9a66-436f-bd85-85871d9d402b :END: +Here I define my hosts. Earlier (in [[#h:aee5ec75-7ca6-40d8-b6ac-a3e7e33a474b][flake.nix skeleton]]), I told you how I used to use noweb-ref blocks to achieve this task. You see, a single =nixosConfiguration= uses =nixpkgs.lib.nixosSystem=, passing modules and arguments to define itself. I have automated this process by reading all directories in the =hosts/= directory and then applying =nixpkgs.lib.nixosSystem= as a function on these returns. I also provide a =nixosConfigurationsMinimal= output which is ingested by the flake in =install/flake.nix= to be used during the initial deployment of a new system (it basically just disables most modules). + +- =mkNixosHost=: Very much akin to a simple call of =nixpkgs.lib.nixosSystem=, I simply define =specialArgs= and =modules= that I want to use for every configuration. Here, I load all the extra modules from my other input flakes. Also, I add the =globals= output from [[#h:af83893d-c0f9-4b45-b816-4849110d41b3][Globals]] and the =nodes= output that I define right here (it simply mirrors all "full" configurations - nixOS and darwin. I like to refer to home-manager only and nix-on-droid as a "half" configurations). It is also here that I set the node name for the configuration (I prefer this explicit call over referencing =networking.hostName= or such) and the directory that should be used for secrets of a configuration. +- =mkDarwinHost= works in the same way but for darwin machines. + +- =mkFullHostConfigs= is the function that dynamically creates all definded hosts. The hosts are defined by placing a directory in =hosts/= under either the =nixos/= or =darwin/= directory. These directories are being read by =readHosts= and delivered to this funtion in the later call in [[#h:9c9b9e3b-8771-44fa-ba9e-5056ae809655][nixosConfigurations]] or [[#h:f881aa05-a670-48dd-a57b-2916abdcb692][darwinConfigurations]]. +- =mkFullHost=: + This is a function that takes a hostname as well as a boolean whether it is NixOS or not, and returns a matching =nixosSystem= or =darwinSystem=. This function is only used for systems that can use both NixOS and home-manager options (darwin still counts here as it can use some NixOS options). This is used in mkFullHostConfigs. In more detail, it dynamically creates a nixosConfiguration host, setting its =speciaArgs= and =modules= attributes. The modules are populated based on whether this is a NixOS or darwin host. For the latter, I will only ever use machines that I get for testing from work, and for these my username is different, so I implemented an if-condition for it. This could be done more cleanly using variables, but some care needs to be taken with the home-manager imports and this approach works, so for now this is fine. Thanks to this function, the import sections of the host configs are pretty clean for most hosts. + #+begin_src nix-ts :tangle nix/hosts.nix { self, inputs, ... }: { @@ -5486,6 +5509,10 @@ Also, since I use a GPG key in sops, it seems that scdaemon creates an instance #+begin_src nix-ts :tangle modules/nixos/client/hardwarecompatibility-yubikey.nix { lib, config, pkgs, ... }: + let + inherit (config.swarselsystems) mainUser; + inherit (config.repo.secrets.common.yubikeys) cfg1 cfg2; + in { options.swarselsystems.modules.yubikey = lib.mkEnableOption "yubikey config"; config = lib.mkIf config.swarselsystems.modules.yubikey { @@ -5495,6 +5522,21 @@ Also, since I use a GPG key in sops, it seems that scdaemon creates an instance hardware.gpgSmartcards.enable = true; + security.pam.u2f = { + enable = true; + control = "sufficient"; + settings = { + interactive = false; # displays a prompt BEFORE asking for presence + cue = true; # prints a message that a touch is requrired + origin = "pam://${mainUser}"; # make the keys work on all machines + authfile = pkgs.writeText "u2f-mappings" (lib.concatStrings [ + mainUser + cfg1 + cfg2 + ]); + }; + }; + services.udev.packages = with pkgs; [ yubikey-personalization ]; @@ -12937,6 +12979,12 @@ Currently, I am too lazy to explain every option here, but most of it is very se #+begin_src nix-ts :tangle modules/home/common/sway.nix { self, config, lib, ... }: + let + eachOutput = _: monitor: { + inherit (monitor) name; + value = builtins.removeAttrs monitor [ "mode" "name" "scale" "transform" "position" ]; + }; + in { options.swarselsystems = { modules.sway = lib.mkEnableOption "sway settings"; @@ -12992,15 +13040,15 @@ Currently, I am too lazy to explain every option here, but most of it is very se swayfxConfig = lib.mkOption { type = lib.types.str; default = " - blur enable - blur_xray disable - blur_passes 1 - blur_radius 1 - shadows enable - corner_radius 2 - titlebar_separator disable - default_dim_inactive 0.02 - "; + blur enable + blur_xray disable + blur_passes 1 + blur_radius 1 + shadows enable + corner_radius 2 + titlebar_separator disable + default_dim_inactive 0.02 + "; internal = true; }; }; @@ -13147,7 +13195,6 @@ Currently, I am too lazy to explain every option here, but most of it is very se }; }; defaultWorkspace = "workspace 1:δΈ€"; - # output = lib.mapAttrs' lib.swarselsystems.eachMonitor monitors; output = { "${config.swarselsystems.sharescreen}" = { bg = "${self}/files/wallpaper/lenovowp.png ${config.stylix.imageScalingMode}"; @@ -13159,7 +13206,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se input = config.swarselsystems.standardinputs; workspaceOutputAssign = let - workplaceSets = lib.mapAttrs' lib.swarselsystems.eachOutput config.swarselsystems.monitors; + workplaceSets = lib.mapAttrs' eachOutput config.swarselsystems.monitors; workplaceOutputs = map (key: lib.getAttr key workplaceSets) (lib.attrNames workplaceSets); in workplaceOutputs; @@ -13308,36 +13355,36 @@ Currently, I am too lazy to explain every option here, but most of it is very se swayfxSettings = config.swarselsystems.swayfxConfig; in " - exec_always autotiling - set $exit \"exit: [s]leep, [l]ock, [p]oweroff, [r]eboot, [u]ser logout\" + exec_always autotiling + set $exit \"exit: [s]leep, [l]ock, [p]oweroff, [r]eboot, [u]ser logout\" - mode $exit { - bindsym --to-code { - s exec \"systemctl suspend\", mode \"default\" - h exec \"systemctl hibernate\", mode \"default\" - l exec \"swaylock --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2 --daemonize\", mode \"default\ - p exec \"systemctl poweroff\" - r exec \"systemctl reboot\" - u exec \"swaymsg exit\" + mode $exit { + bindsym --to-code { + s exec \"systemctl suspend\", mode \"default\" + h exec \"systemctl hibernate\", mode \"default\" + l exec \"swaylock --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2 --daemonize\", mode \"default\ + p exec \"systemctl poweroff\" + r exec \"systemctl reboot\" + u exec \"swaymsg exit\" - Return mode \"default\" - Escape mode \"default\" - ${modifier}+Escape mode \"default\" + Return mode \"default\" + Escape mode \"default\" + ${modifier}+Escape mode \"default\" + } } - } - exec systemctl --user import-environment - exec swayidle -w + exec systemctl --user import-environment + exec swayidle -w - seat * hide_cursor 2000 + seat * hide_cursor 2000 - exec_always kill -1 $(pidof kanshi) + exec_always kill -1 $(pidof kanshi) - bindswitch --locked lid:on exec kanshictl switch lidclosed - bindswitch --locked lid:off exec kanshictl switch lidopen + bindswitch --locked lid:on exec kanshictl switch lidclosed + bindswitch --locked lid:off exec kanshictl switch lidopen - ${swayfxSettings} - "; + ${swayfxSettings} + "; }; }; } @@ -16574,7 +16621,7 @@ This holds modules that are to be used on most hosts. These are also the most im general = lib.mkDefault true; nixgl = lib.mkDefault true; sops = lib.mkDefault true; - yubikey = lib.mkDefault true; + yubikey = lib.mkDefault false; ssh = lib.mkDefault true; stylix = lib.mkDefault true; desktop = lib.mkDefault true; diff --git a/flake.lock b/flake.lock index 233156d..f1c4043 100644 --- a/flake.lock +++ b/flake.lock @@ -228,21 +228,6 @@ } }, "flake-compat_3": { - "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_4": { "flake": false, "locked": { "lastModified": 1696426674, @@ -258,7 +243,7 @@ "type": "github" } }, - "flake-compat_5": { + "flake-compat_4": { "flake": false, "locked": { "lastModified": 1696426674, @@ -625,26 +610,6 @@ "type": "github" } }, - "nix-alien": { - "inputs": { - "flake-compat": "flake-compat_3", - "nix-index-database": "nix-index-database", - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1749976779, - "narHash": "sha256-Mjb4qsu+Fma1cXe1lGo0GqisvsiUeW0LfacziI7C7oM=", - "owner": "thiagokokada", - "repo": "nix-alien", - "rev": "f8716e36f8864e2f50663fde364ddd8dce5d937f", - "type": "github" - }, - "original": { - "owner": "thiagokokada", - "repo": "nix-alien", - "type": "github" - } - }, "nix-darwin": { "inputs": { "nixpkgs": [ @@ -689,27 +654,6 @@ } }, "nix-index-database": { - "inputs": { - "nixpkgs": [ - "nix-alien", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1749960154, - "narHash": "sha256-EWlr9MZDd+GoGtZB4QsDzaLyaDQPGnRY03MFp6u2wSg=", - "owner": "nix-community", - "repo": "nix-index-database", - "rev": "424a40050cdc5f494ec45e46462d288f08c64475", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nix-index-database", - "type": "github" - } - }, - "nix-index-database_2": { "inputs": { "nixpkgs": [ "nixpkgs" @@ -759,7 +703,7 @@ "inputs": { "devshell": "devshell_2", "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs_3", + "nixpkgs": "nixpkgs_2", "pre-commit-hooks": "pre-commit-hooks" }, "locked": { @@ -779,7 +723,7 @@ "nixgl": { "inputs": { "flake-utils": "flake-utils_2", - "nixpkgs": "nixpkgs_4" + "nixpkgs": "nixpkgs_3" }, "locked": { "lastModified": 1751696036, @@ -1019,39 +963,7 @@ "type": "github" } }, - "nixpkgs_10": { - "locked": { - "lastModified": 1750865895, - "narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "61c0f513911459945e2cb8bf333dc849f1b976ff", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nixpkgs_2": { - "locked": { - "lastModified": 1749794982, - "narHash": "sha256-Kh9K4taXbVuaLC0IL+9HcfvxsSUx8dPB5s5weJcc9pc=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "ee930f9755f58096ac6e8ca94a1887e0534e2d81", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { "locked": { "lastModified": 1730531603, "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=", @@ -1067,7 +979,7 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_3": { "locked": { "lastModified": 1746378225, "narHash": "sha256-OeRSuL8PUjIfL3Q0fTbNJD/fmv1R+K2JAOqWJd3Oceg=", @@ -1082,7 +994,7 @@ "type": "github" } }, - "nixpkgs_5": { + "nixpkgs_4": { "locked": { "lastModified": 1751792365, "narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=", @@ -1098,7 +1010,7 @@ "type": "github" } }, - "nixpkgs_6": { + "nixpkgs_5": { "locked": { "lastModified": 1720957393, "narHash": "sha256-oedh2RwpjEa+TNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA=", @@ -1114,7 +1026,7 @@ "type": "github" } }, - "nixpkgs_7": { + "nixpkgs_6": { "locked": { "lastModified": 1751792365, "narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=", @@ -1130,7 +1042,7 @@ "type": "github" } }, - "nixpkgs_8": { + "nixpkgs_7": { "locked": { "lastModified": 1744868846, "narHash": "sha256-5RJTdUHDmj12Qsv7XOhuospjAjATNiTMElplWnJE9Hs=", @@ -1146,7 +1058,7 @@ "type": "github" } }, - "nixpkgs_9": { + "nixpkgs_8": { "locked": { "lastModified": 1748460289, "narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=", @@ -1162,6 +1074,22 @@ "type": "github" } }, + "nixpkgs_9": { + "locked": { + "lastModified": 1750865895, + "narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "61c0f513911459945e2cb8bf333dc849f1b976ff", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nmd": { "flake": false, "locked": { @@ -1219,7 +1147,7 @@ "nswitch-rcm-nix": { "inputs": { "flake-parts": "flake-parts_3", - "nixpkgs": "nixpkgs_6" + "nixpkgs": "nixpkgs_5" }, "locked": { "lastModified": 1721304043, @@ -1238,7 +1166,7 @@ "nur": { "inputs": { "flake-parts": "flake-parts_4", - "nixpkgs": "nixpkgs_7" + "nixpkgs": "nixpkgs_6" }, "locked": { "lastModified": 1751906969, @@ -1282,7 +1210,7 @@ }, "pre-commit-hooks": { "inputs": { - "flake-compat": "flake-compat_4", + "flake-compat": "flake-compat_3", "gitignore": "gitignore_2", "nixpkgs": [ "nix-topology", @@ -1335,7 +1263,7 @@ }, "pre-commit-hooks_2": { "inputs": { - "flake-compat": "flake-compat_5", + "flake-compat": "flake-compat_4", "gitignore": "gitignore_3", "nixpkgs": [ "nixpkgs" @@ -1365,15 +1293,14 @@ "home-manager": "home-manager", "impermanence": "impermanence", "lanzaboote": "lanzaboote", - "nix-alien": "nix-alien", "nix-darwin": "nix-darwin", - "nix-index-database": "nix-index-database_2", + "nix-index-database": "nix-index-database", "nix-on-droid": "nix-on-droid", "nix-topology": "nix-topology", "nixgl": "nixgl", "nixos-generators": "nixos-generators", "nixos-hardware": "nixos-hardware", - "nixpkgs": "nixpkgs_5", + "nixpkgs": "nixpkgs_4", "nixpkgs-dev": "nixpkgs-dev", "nixpkgs-kernel": "nixpkgs-kernel", "nixpkgs-stable": "nixpkgs-stable_2", @@ -1449,7 +1376,7 @@ }, "sops-nix": { "inputs": { - "nixpkgs": "nixpkgs_8" + "nixpkgs": "nixpkgs_7" }, "locked": { "lastModified": 1751606940, @@ -1474,7 +1401,7 @@ "firefox-gnome-theme": "firefox-gnome-theme", "flake-parts": "flake-parts_5", "gnome-shell": "gnome-shell", - "nixpkgs": "nixpkgs_9", + "nixpkgs": "nixpkgs_8", "nur": "nur_2", "systems": "systems_3", "tinted-foot": "tinted-foot", @@ -1716,7 +1643,7 @@ "inputs": { "crane": "crane_2", "flake-utils": "flake-utils_3", - "nixpkgs": "nixpkgs_10", + "nixpkgs": "nixpkgs_9", "rust-overlay": "rust-overlay_2" }, "locked": { diff --git a/flake.nix b/flake.nix index 6f82b3c..13a5864 100644 --- a/flake.nix +++ b/flake.nix @@ -43,9 +43,6 @@ nixos-hardware = { url = "github:NixOS/nixos-hardware/master"; }; - nix-alien = { - url = "github:thiagokokada/nix-alien"; - }; nswitch-rcm-nix = { url = "github:Swarsel/nswitch-rcm-nix"; }; diff --git a/index.html b/index.html index 3b60c2e..0b1ea37 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + SwarselSystems: NixOS + Emacs Configuration @@ -246,7 +246,7 @@
  • 3.1.2. Physical hosts
  • @@ -782,7 +782,7 @@

    -This file has 85605 words spanning 22598 lines and was last revised on 2025-07-14 01:07:45 +0200. +This file has 87025 words spanning 22627 lines and was last revised on 2025-07-14 03:07:10 +0200.

    @@ -835,7 +835,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-07-14 01:07:45 +0200) +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-07-14 03:07:10 +0200)

    @@ -1071,16 +1071,17 @@ Here I give a brief overview over the hostmachines that I am using. This is held
    | Name               | Hardware                                            | Use                                                  |
     |--------------------|-----------------------------------------------------|------------------------------------------------------|
    -|πŸ’» **nbl-imba-2**   | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                          |
    -|πŸ’» **nbm-imba-166** | MacBook Pro 2016                                    | MacOS Sandbox                                        |
    +|πŸ’» **pyramid**      | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                          |
    +|πŸ’» **bakery**       | Lenovo Ideapad 720S-13IKB                           | Personal lapto                                       |
    +|πŸ’» **machpizza**    | MacBook Pro 2016                                    | MacOS sandbox                                        |
     |πŸ–₯️ **winters**      | ASRock J4105-ITX, 32GB RAM                          | Main homeserver and data storgae                     |
    -|πŸ–₯️ **milkywell**         | Oracle Cloud: VM.Standard.E2.1.Micro                | Server for lightweight synchronization tasks         |
    +|πŸ–₯️ **milkywell**    | Oracle Cloud: VM.Standard.E2.1.Micro                | Server for lightweight synchronization tasks         |
     |πŸ–₯️ **moonside**     | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services  |
     |πŸ“± **magicant**     | Samsung Galaxy Z Flip 6                             | Phone                                                |
     |πŸ’Ώ **drugstore**    | -                                                   | ISO installer configuration                          |
     |❔ **chaotheatre**  | -                                                   | Demo config for checking out my configurtion         |
     |❔ **toto**         | -                                                   | Helper configuration for bootstrapping a new system  |
    -|🏠 **Treehouse**         | -                                                   | Reference configuration for a home-manager only host |
    +|🏠 **treehouse**    | -                                                   | Reference configuration for a home-manager only host |
     
    @@ -1141,30 +1142,31 @@ Here I give a brief overview over the hostmachines that I am using. This is held

    2. flake.nix

    -Handling the flake.nix file used to be a bit of a chore, since it felt like writing so much boilerplate code just to define new systems. The noweb-approach here makes this a little bit less painful. +Handling the flake.nix file used to be a bit of a chore, since it felt like writing so much boilerplate code just to define new systems. For a while, I used noweb-ref in order to alleviate this problem (see Appendix A: Noweb-Ref blocks, an example of the repository at that time would be acc0ad6: Add several NixOS hosts on Proxmox and Oracle Cloud.). However, the true answer laid in making use of builtin nix functionality.

    -These blocks are later inserted here: flake.nix template. Adding new flake inputs is very easy, you just add them to [BROKEN LINK: h:8a411ee2-a58e-4b5b-99bd-4ba772f8f0a2] first by name in the first source-block, and then the path in the second source-block. Any variables to be set for the host configuration are done in [BROKEN LINK: h:df0072bc-853f-438f-bd85-bfc869501015], and the specific setup is done in either [BROKEN LINK: h:9c9b9e3b-8771-44fa-ba9e-5056ae809655] (for NixOS systems), [BROKEN LINK: h:f881aa05-a670-48dd-a57b-2916abdcb692] (for home-manager systems), or [BROKEN LINK: h:5f6ef553-59f9-4239-b6f3-63d33b57f335] (for Nix on Android) and [BROKEN LINK: h:f881aa05-a670-48dd-a57b-2916abdcb692] (for Darwin systems, also known as Macs). There also used to be a [BROKEN LINK: h:6a08495a-8566-4bb5-9fac-b03df01f6c81] section that used to define a Proxmox LXC image when I was still using Proxmox as my main server. An example of the repository at that time would be acc0ad6: Add several NixOS hosts on Proxmox and Oracle Cloud. +Nowadays, I use flake-parts to manage my flake. It allows me to conveniently split the actual flake into multiple files ("parts") using the following mechanism:

    + +
      +
    • imports are files pulled in to build the flake configuration (similar to the imports in the module system)
    • +
    • systems defines the architectures that the flake should be provided for - I go here for the four "main" architectures, although true support is only provided for linux systems (see Packages (pkgs) for the main reason)
    • +

    2.1. flake.nix skeleton

    -This sections puts together the flake.nix file from the [BROKEN LINK: h:d39b8dfb-536d-414f-9fc0-7d67df48cee4] section. This tangles the flake.nix file; This block only needs to be touched when updating the general structure of the flake. For everything else, see the respective noweb-ref block. +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, options, and more. 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 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. -

    - -

    -In 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 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.

    @@ -1228,8 +1230,6 @@ Provides secure boot for NixOS. Needed for my Surface Pro 3. This brings nix to android in an app that is similar to tmux! Of course most of the configuration does not apply to this, but it is still neat to have!

  • nixos-hardware Provides specific hardware setting for some hardware configurations. For example, this sets some better defaults for my Lenovo Thinkpad P14s Gen2.
  • -
  • nix-alien -This is supposed to allow me to run unpatched libraries directly without a need for ELF patching or resorting to steam-run. However, I have not yet gotten this to work.
  • nixos-generators Provides me with images that I can use to create LXCs on Proxmox.
  • nswitch-rcm-nix @@ -1248,16 +1248,12 @@ This provides access to the internal fans of Frameworks laptops. This is a bit m After learning that MacOS systems can also be configured using nix, I managed to get access to an old MacBook for testing. This allows to set most general settings that can otherwise be set using the Mac GUI.
  • pre-commit-hooks Provides access to several checks that can be hooked to be run before several stages in the process.
  • -
  • nix-secrets -This is a private repository that I use for settings in modules that do not expose a secretsFile (or similar) option. An example is the LastFM.ApiKey option in navidrome: -LastFM.ApiKey = builtins.readFile "${secretsDirectory}/navidrome/lastfm-secret";
  • - -

    -When setting this option normally, the password would normally be written world-readable not only in the nix store, but also in the configuration. Hence, I put such passwords into a private repository. This allows me to keep purity of the flake while keeping a level of security on these secrets. -

    -
    • nix-topology This automatically creates a topology diagram of my configuration.
    • +
    • flake-parts +The aforementioned system that allows for more convenient flake crafting.
    • +
    • devshell +This provides devshell support for flake-parts
    @@ -1306,9 +1302,6 @@ This automatically creates a topology diagram of my configuration. nixos-hardware = { url = "github:NixOS/nixos-hardware/master"; }; - nix-alien = { - url = "github:thiagokokada/nix-alien"; - }; nswitch-rcm-nix = { url = "github:Swarsel/nswitch-rcm-nix"; }; @@ -1379,10 +1372,32 @@ This automatically creates a topology diagram of my configuration.

    2.2. Auxiliary files

    +

    +Here I define some extra files that are crucial for success in building my configurations. These are not pulled in by the flake directly, but I still feel like they should be mentioned at the flake level. +

    2.2.1. extra-builtins

    +

    +This file is used by nix-plugins. nix-plugins generally allows for the introduction of arbitrary functions into the builtins set. However, I do not want to allow just any function to be added there. Instead, I only add a single function called sopsImportEncrypted. This function is used in order to help me store PII (personally identifiable information) in my repo without having to resort to either: +

    + +
      +
    • git-crypt
    • +
    • +a separate repo containing my secrets +

      + +

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

    • +
    + +

    +The builtin that is added is a simple call to the exec function that calls a bash script. In order to keep some sanity, we are checking that we are actually calling it no an encryted nix file (even though there is no syntax check inside) and that the path given is a true nix path. Note that a string path will not be accepted, as that can have impurity implications. +

    +
    # adapted from https://github.com/oddlama/nix-config/blob/main/nix/extra-builtins.nix
     { exec, ... }:
    @@ -1419,6 +1434,10 @@ in
     

    2.2.2. sops-decrypt-and-cache

    +

    +This is the file that manages the actual decryption of the files mentioned in extra-builtins. We simply fetch the appropriate system age key from the ssh host key and then call sops decrypt. Since it would be a bother to decrypt these files on every build, I keep the result cached and only re-decrypt if it changes. Keeping it cached outside the nix store incurrs a theoretical bit of impurity. However, this is easier to manage and also nothing really relies on these files being present. +

    +
    # adapted from https://github.com/oddlama/nix-config/blob/main/nix/rage-decrypt-and-cache.sh
     set -euo pipefail
    @@ -1468,26 +1487,37 @@ fi
     

    2.3. Library functions

    -This section defines all functions of my own that I add to lib. These are used in all places over the config, with many of them being used in flake.nix. +This section defines all functions of my own that I add to lib. These are used in all places over the config, however mainly in the files responsible for handling various imports.

    -A breakdown of each function: +A breakdown for the functions that have a non-obvious purpose:

    -

    -The interesting part is in the start: -

      -
    • first, I define pkgsFor. This function reads all available systems from nixpkgs and generates pkgs for them.
    • -
    • next, forEachSystem is a function that can be called to declare an output for each such defined system.
    • -
    • forAllSystems is a crude function that I use for expressions that depend on system, as the prior two attributes already consumed it at that stage. This is only really used to generate the checks in their own file.
    • -
    • mkFullHostConfigs is the function that dynamically creates all definded hosts. The hosts are defined by placing a directory in hosts/ under either the nixos/ or darwin/ directory. These directories are being read by readHosts and delivered to this funtion in the later call in [BROKEN LINK: h:9c9b9e3b-8771-44fa-ba9e-5056ae809655] or [BROKEN LINK: h:f881aa05-a670-48dd-a57b-2916abdcb692].
    • -
    • mkFullHost: -This is a function that takes a hostname as well as a boolean whether it is NixOS or not, and returns a matching nixosSystem or darwinSystem. This function is only used for systems that can use both NixOS and home-manager options (darwin still counts here as it can use some NixOS options). This is used in mkFullHostConfigs. In more detail, it dynamically creates a nixosConfiguration host, setting its speciaArgs and modules attributes. The modules are populated based on whether this is a NixOS or darwin host. For the latter, I will only ever use machines that I get for testing from work, and for these my username is different, so I implemented an if-condition for it. This could be done more cleanly using variables, but some care needs to be taken with the home-manager imports and this approach works, so for now this is fine. Thanks to this function, the import sections of the host configs are pretty clean for most hosts. -lib.optionals evaluates to an empty list ([]) in case that the conditional is not met.
    • +
    • pkgsFor: This function reads all available systems from nixpkgs and generates pkgs for them. This is needed for my generation of home-manager and nix-on-droid systems in Hosts. +
        +
      • nixpkgs.lib.genAttrs is used to generate an attribute set (a dictionary-like structure) from a list of keys and a function that computes the values for those keys: genAttrs ["a" "b" "c"] (x: "${x}-value") will produce { a = "a-value"; b = "b-value"; c = "c-value"; }.
      • +
      • Also, in that function I am defining the pkgs that should be used when I reference pkgs in the actual configuration. I want to make sure that the correct system is used (keep in mind this is for home-manager configurations, which need that info! As a remark, you would not set this for a NixOS host), that I load my Overlays (extra packages and modifications that I add to pkgs), as well as a setting that allows me to install unfree software. As a base package set I choose nixpkgs from my inputs (and so does nearly every configuration out there. Keep in mind however that you could use any package set here! nixpkgs however also comes with a lot of useful lib functions (that are not builtins to the nix language!))
      • +
    • +
    • mkTrueOption: Defines a nixos module option that is by default enables (as opposed to mkEnableOption which are per default disabled).
    • +
    • mkStrong: This function uses nixpkgs.lib.mkOverride in order to set a priority for an expression that is higher than setting an option normally (i.e. option = value;) which has priority 100, while being of lower priority than using nixpkgs.lib.mkForce, which has priority 50 (lower priority takes precedence). For completeness' sake, the priority set when using nixpkgs.lib.mkDefault is 1000 (a very low value).
    • +
    • forEachLinuxSystem: performs the pkgsFor function for a set of systems (here: x86_64-linux and aarch64-linux). I need to use this in the Packages (pkgs) section in order to avoid trying to build those packages for darwin systems.
    • +
    • readHosts: Reads the names of directories under the hosts/ folder for a particular system type +
        +
      • builtins.readDir reads the name of items of a directory as attributes and their type as values. As an example builtins.readDir ./hosts/nixos ran on this flake yieled at some point the output { bakery = "directory"; chaostheatre = "directory"; milkywell = "directory"; moonside = "directory"; pyramid = "directory"; toto = "directory"; winters = "directory"; }
      • +
      • nixpkgs.lib.attrNames is used to aquire these attribute names (you might think of them as the "keys") from the output of builtins.readDir
      • +
    • +
    • readNix: reads all files in a directory that are not default.nix (usually used to simply load everything from a folder and is called inside that respective default.nix).
    • +
    • mk[Modules,Profiles,Imports]: These are used to help with importing files mostly: +
        +
      • builtins.listToAttrs converts a list of name-value pairs into an attribute set. builtins.listToAttrs [{ name = "foo"; value = 1; } { name = "bar"; value = 2; }] for example returns { bar = 2; foo = 1; }.
      • +
      • nixpkgs.lib.map takes a function and applies the elements of a list upon them, e.g. lib.map (x: x + 1) [1 2 3] yields [ 2 3 4 ]. This is always used in mkImports to actually import the list of modules that are generated by the other mk[...] options.
      • +
    + +
    { self, inputs, ... }:
     let
    @@ -1532,15 +1562,12 @@ let
     
           mkStrong = lib.mkOverride 60;
     
    -      forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system});
    +      # forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system});
           forEachLinuxSystem = f: lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: f pkgsFor.${system});
     
           readHosts = type: lib.attrNames (builtins.readDir "${self}/hosts/${type}");
           readNix = type: lib.filter (name: name != "default.nix") (lib.attrNames (builtins.readDir "${self}/${type}"));
     
    -
    -
    -
           mkModules = names: type: builtins.listToAttrs (map
             (name: {
               inherit name;
    @@ -1555,18 +1582,7 @@ let
             })
             names);
     
    -
           mkImports = names: baseDir: lib.map (name: "${self}/${baseDir}/${name}") names;
    -
    -      eachMonitor = _: monitor: {
    -        inherit (monitor) name;
    -        value = builtins.removeAttrs monitor [ "workspace" "name" "output" ];
    -      };
    -
    -      eachOutput = _: monitor: {
    -        inherit (monitor) name;
    -        value = builtins.removeAttrs monitor [ "mode" "name" "scale" "transform" "position" ];
    -      };
         };
     in
     {
    @@ -1585,7 +1601,11 @@ in
     

    2.4. Packages (pkgs)

    -This does not use perSystem since some of my custom packages are not able to be built on darwin systems, and I was not yet interested in writing logic for handling that. +This does not use perSystem from flake-parts since some of my custom packages are not able to be built on darwin systems, and I was not yet interested in writing logic for handling that. Instead I use forEachLinuxSystem as described in Library functions in roder to only build this for linux hosts. +

    + +

    +More information on the actual packages build can be found in Packages.

    @@ -1607,7 +1627,22 @@ This does not use perSystem since some of my custom packages are no

    2.5. Globals

    -The structure of globals.nix.enc requires a toplevel globals. +This file is used to parse each nixosConfiguration present in this flake and scan them for options set under the globals attribute set. I use lib.evalModules to evaluate a mini module system that only consists of these globals options and then load them into the actual configuration by providing a globals output to the flake. This treads a dangerous ground of infinite recursions, which is why both the module system as well as the inherited attributes are kept to the minimal size. Each module has a globals option loaded from a module file which will be separately loaded by this mini-evaluation. +

    + +
      +
    • nixpkgs.lib.mapAttrsToList converts an attribute set into a list by applying a given function to each name-value pair: lib.mapAttrsToList (name: value: "${name} = ${value}) { a = "1"; b = "2"; } yields the list [ "a = 1" "b = 2" ]. It is used on config.nodes.
    • +
    • nixpkgs.lib.flip is used to reverse the function argument order of the mapAttrsToList call, so that we can give the attribute set (config.nodes) first. Alternatively, we could have written lib.mapAttrsToList (name: cfg: [...]) config.nodes but it would be harder to read since there would be a big block between the arguments.
    • +
    • nixpkgs.lib.concatLists, as the name suggests, concatenates lists: lib.concatLists [ [ 1 2 ] [ 3 4 ] [ 5 ] ] yields [ 1 2 3 4 5 ]. options.config._globalDefs holds the options.globals.definitions for each node (which in turn basically holds the information that has been set for each node under the globals option), so the concatenated list will look something like [ { services.kanidm.domain = "foo"; }; } { services.freshrss.domain = "bar"; } ].
    • +
    • nixpgks.lib.mkMerge is used to merge these seperate attribute sets in the list into one big attribute set (the above attribute set example would become then { services = { kanidm.domain = "foo"; freshrss.domain = "bar"; }; }. You can see how this can now be referenced as a "global" set.
    • +
    + +

    +I also have a file for global values that cannot be attributed to one nixosConfiguration alsone; the structure of this globals.nix.enc requires a toplevel globals - that means, globals.nix.enc has the structure { globals = [...] }. +

    + +

    +Lastly, in order make this actually available to my configurations, i use the inherit (globalsSystem.config.globals) [...] which produces the globals output which I will pass to the specialArgs of my nixosConfigurations, which is when I will be finally able to use these definitions in my config.

    @@ -1680,6 +1715,19 @@ The structure of globals.nix.enc requires a toplevel globals<

    2.6. Hosts

    +

    +Here I define my hosts. Earlier (in flake.nix skeleton), I told you how I used to use noweb-ref blocks to achieve this task. You see, a single nixosConfiguration uses nixpkgs.lib.nixosSystem, passing modules and arguments to define itself. I have automated this process by reading all directories in the hosts/ directory and then applying nixpkgs.lib.nixosSystem as a function on these returns. I also provide a nixosConfigurationsMinimal output which is ingested by the flake in install/flake.nix to be used during the initial deployment of a new system (it basically just disables most modules). +

    + +
      +
    • mkNixosHost: Very much akin to a simple call of nixpkgs.lib.nixosSystem, I simply define specialArgs and modules that I want to use for every configuration. Here, I load all the extra modules from my other input flakes. Also, I add the globals output from Globals and the nodes output that I define right here (it simply mirrors all "full" configurations - nixOS and darwin. I like to refer to home-manager only and nix-on-droid as a "half" configurations). It is also here that I set the node name for the configuration (I prefer this explicit call over referencing networking.hostName or such) and the directory that should be used for secrets of a configuration.
    • +
    • mkDarwinHost works in the same way but for darwin machines.
    • + +
    • mkFullHostConfigs is the function that dynamically creates all definded hosts. The hosts are defined by placing a directory in hosts/ under either the nixos/ or darwin/ directory. These directories are being read by readHosts and delivered to this funtion in the later call in [BROKEN LINK: h:9c9b9e3b-8771-44fa-ba9e-5056ae809655] or [BROKEN LINK: h:f881aa05-a670-48dd-a57b-2916abdcb692].
    • +
    • mkFullHost: +This is a function that takes a hostname as well as a boolean whether it is NixOS or not, and returns a matching nixosSystem or darwinSystem. This function is only used for systems that can use both NixOS and home-manager options (darwin still counts here as it can use some NixOS options). This is used in mkFullHostConfigs. In more detail, it dynamically creates a nixosConfiguration host, setting its speciaArgs and modules attributes. The modules are populated based on whether this is a NixOS or darwin host. For the latter, I will only ever use machines that I get for testing from work, and for these my username is different, so I implemented an if-condition for it. This could be done more cleanly using variables, but some care needs to be taken with the home-manager imports and this approach works, so for now this is fine. Thanks to this function, the import sections of the host configs are pretty clean for most hosts.
    • +
    +
    { self, inputs, ... }:
     {
    @@ -1910,7 +1958,7 @@ The structure of globals.nix.enc requires a toplevel globals<
               connections = {
                 eth2 = mkConnection "nswitch" "eth1";
                 eth7 = mkConnection "pc" "eth1";
    -            eth8 = mkConnection "nbl-imba-2" "eth1";
    +            eth8 = mkConnection "pyramid" "eth1";
               };
             };
     
    @@ -1926,7 +1974,7 @@ The structure of globals.nix.enc requires a toplevel globals<
               interfaces.eth1 = { };
             };
     
    -        nbl-imba-2.interfaces.eth1 = { };
    +        pyramid.interfaces.eth1 = { };
     
             switch-bedroom = mkSwitch "Switch Bedroom" {
               info = "TL-SG1005D";
    @@ -2641,7 +2689,7 @@ This is a list of all physical machines that I maintain.
     

    -
    3.1.2.1. nbl-imba-2 (Framework Laptop 16)
    +
    3.1.2.1. pyramid (Framework Laptop 16)

    My work machine. Built for more security, this is the gold standard of my configurations at the moment. @@ -3271,7 +3319,7 @@ in

    -
    3.1.2.4. nbm-imba-166 (MacBook Pro)
    +
    3.1.2.4. machpizza (MacBook Pro)

    A Mac notebook that I have received from work. I use this machine for getting accustomed to the Apple ecosystem as well as as a sandbox for nix-darwin configurations. @@ -14226,6 +14274,12 @@ Currently, I am too lazy to explain every option here, but most of it is very se

    { self, config, lib, ... }:
    +let
    +  eachOutput = _: monitor: {
    +    inherit (monitor) name;
    +    value = builtins.removeAttrs monitor [ "mode" "name" "scale" "transform" "position" ];
    +  };
    +in
     {
       options.swarselsystems = {
         modules.sway = lib.mkEnableOption "sway settings";
    @@ -14281,15 +14335,15 @@ Currently, I am too lazy to explain every option here, but most of it is very se
         swayfxConfig = lib.mkOption {
           type = lib.types.str;
           default = "
    -                      blur enable
    -                      blur_xray disable
    -                      blur_passes 1
    -                      blur_radius 1
    -                      shadows enable
    -                      corner_radius 2
    -                      titlebar_separator disable
    -                      default_dim_inactive 0.02
    -                  ";
    +                        blur enable
    +                        blur_xray disable
    +                        blur_passes 1
    +                        blur_radius 1
    +                        shadows enable
    +                        corner_radius 2
    +                        titlebar_separator disable
    +                        default_dim_inactive 0.02
    +                    ";
           internal = true;
         };
       };
    @@ -14436,7 +14490,6 @@ Currently, I am too lazy to explain every option here, but most of it is very se
               };
             };
             defaultWorkspace = "workspace 1:δΈ€";
    -        # output = lib.mapAttrs' lib.swarselsystems.eachMonitor monitors;
             output = {
               "${config.swarselsystems.sharescreen}" = {
                 bg = "${self}/files/wallpaper/lenovowp.png ${config.stylix.imageScalingMode}";
    @@ -14448,7 +14501,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se
             input = config.swarselsystems.standardinputs;
             workspaceOutputAssign =
               let
    -            workplaceSets = lib.mapAttrs' lib.swarselsystems.eachOutput config.swarselsystems.monitors;
    +            workplaceSets = lib.mapAttrs' eachOutput config.swarselsystems.monitors;
                 workplaceOutputs = map (key: lib.getAttr key workplaceSets) (lib.attrNames workplaceSets);
               in
               workplaceOutputs;
    @@ -14597,36 +14650,36 @@ Currently, I am too lazy to explain every option here, but most of it is very se
               swayfxSettings = config.swarselsystems.swayfxConfig;
             in
             "
    -        exec_always autotiling
    -        set $exit \"exit: [s]leep, [l]ock, [p]oweroff, [r]eboot, [u]ser logout\"
    +          exec_always autotiling
    +          set $exit \"exit: [s]leep, [l]ock, [p]oweroff, [r]eboot, [u]ser logout\"
     
    -        mode $exit {
    -          bindsym --to-code {
    -            s exec \"systemctl suspend\", mode \"default\"
    -            h exec \"systemctl hibernate\", mode \"default\"
    -            l exec \"swaylock --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2 --daemonize\", mode \"default\
    -            p exec \"systemctl poweroff\"
    -            r exec \"systemctl reboot\"
    -            u exec \"swaymsg exit\"
    +          mode $exit {
    +            bindsym --to-code {
    +              s exec \"systemctl suspend\", mode \"default\"
    +              h exec \"systemctl hibernate\", mode \"default\"
    +              l exec \"swaylock --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2 --daemonize\", mode \"default\
    +              p exec \"systemctl poweroff\"
    +              r exec \"systemctl reboot\"
    +              u exec \"swaymsg exit\"
     
    -            Return mode \"default\"
    -            Escape mode \"default\"
    -            ${modifier}+Escape mode \"default\"
    +              Return mode \"default\"
    +              Escape mode \"default\"
    +              ${modifier}+Escape mode \"default\"
    +            }
               }
    -        }
     
    -        exec systemctl --user import-environment
    -        exec swayidle -w
    +          exec systemctl --user import-environment
    +          exec swayidle -w
     
    -        seat * hide_cursor 2000
    +          seat * hide_cursor 2000
     
    -        exec_always kill -1 $(pidof kanshi)
    +          exec_always kill -1 $(pidof kanshi)
     
    -        bindswitch --locked lid:on exec kanshictl switch lidclosed
    -        bindswitch --locked lid:off exec kanshictl switch lidopen
    +          bindswitch --locked lid:on exec kanshictl switch lidclosed
    +          bindswitch --locked lid:off exec kanshictl switch lidopen
     
    -        ${swayfxSettings}
    -        ";
    +          ${swayfxSettings}
    +          ";
         };
       };
     }
    @@ -20440,8 +20493,8 @@ This adds a rudimentary nix-mode to Emacs. I have not really tried this out, as
       (setq lsp-nix-nixd-server-path "nixd"
             lsp-nix-nixd-formatting-command [ "nixpkgs-fmt" ]
             lsp-nix-nixd-nixpkgs-expr "import (builtins.getFlake \"/home/swarsel/.dotfiles\").inputs.nixpkgs { }"
    -        lsp-nix-nixd-nixos-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.nbl-imba-2.options"
    -        lsp-nix-nixd-home-manager-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.nbl-imba-2.options.home-manager.users.type.getSubOptions []"
    +        lsp-nix-nixd-nixos-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.pyramid.options"
    +        lsp-nix-nixd-home-manager-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.pyramid.options.home-manager.users.type.getSubOptions []"
             ))
     
     (use-package nix-ts-mode
    @@ -20456,8 +20509,8 @@ This adds a rudimentary nix-mode to Emacs. I have not really tried this out, as
       (setq lsp-nix-nixd-server-path "nixd"
             lsp-nix-nixd-formatting-command [ "nixpkgs-fmt" ]
             lsp-nix-nixd-nixpkgs-expr "import (builtins.getFlake \"/home/swarsel/.dotfiles\").inputs.nixpkgs { }"
    -        lsp-nix-nixd-nixos-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.nbl-imba-2.options"
    -        lsp-nix-nixd-home-manager-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.nbl-imba-2.options.home-manager.users.type.getSubOptions []"
    +        lsp-nix-nixd-nixos-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.pyramid.options"
    +        lsp-nix-nixd-home-manager-options-expr "(builtins.getFlake \"/home/swarsel/.dotfiles\").nixosConfigurations.pyramid.options.home-manager.users.type.getSubOptions []"
             ))
     
     
    @@ -24304,16 +24357,17 @@ Alternatively, to install this from any NixOS live ISO, run `nix run --experimen
     
     | Name               | Hardware                                            | Use                                                  |
     |--------------------|-----------------------------------------------------|------------------------------------------------------|
    -|πŸ’» **nbl-imba-2**   | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                          |
    -|πŸ’» **nbm-imba-166** | MacBook Pro 2016                                    | MacOS Sandbox                                        |
    +|πŸ’» **pyramid**      | Framework Laptop 16, AMD 7940HS, RX 7700S, 64GB RAM | Work laptop                                          |
    +|πŸ’» **bakery**       | Lenovo Ideapad 720S-13IKB                           | Personal lapto                                       |
    +|πŸ’» **machpizza**    | MacBook Pro 2016                                    | MacOS sandbox                                        |
     |πŸ–₯️ **winters**      | ASRock J4105-ITX, 32GB RAM                          | Main homeserver and data storgae                     |
    -|πŸ–₯️ **milkywell**         | Oracle Cloud: VM.Standard.E2.1.Micro                | Server for lightweight synchronization tasks         |
    +|πŸ–₯️ **milkywell**    | Oracle Cloud: VM.Standard.E2.1.Micro                | Server for lightweight synchronization tasks         |
     |πŸ–₯️ **moonside**     | Oracle Cloud: VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM| Proxy for local services, some lightweight services  |
     |πŸ“± **magicant**     | Samsung Galaxy Z Flip 6                             | Phone                                                |
     |πŸ’Ώ **drugstore**    | -                                                   | ISO installer configuration                          |
     |❔ **chaotheatre**  | -                                                   | Demo config for checking out my configurtion         |
     |❔ **toto**         | -                                                   | Helper configuration for bootstrapping a new system  |
    -|🏠 **Treehouse**         | -                                                   | Reference configuration for a home-manager only host |
    +|🏠 **treehouse**    | -                                                   | Reference configuration for a home-manager only host |
     </details>
     
     ## General Nix tips & useful links
    @@ -24442,7 +24496,7 @@ If you feel that I forgot to pay you tribute for code that I used in this reposi
     

    Author: Leon SchwarzΓ€ugl

    -

    Created: 2025-07-14 Mo 01:07

    +

    Created: 2025-07-14 Mo 03:07

    Validate

    diff --git a/modules/home/common/sway.nix b/modules/home/common/sway.nix index 29148fd..4e19ab2 100644 --- a/modules/home/common/sway.nix +++ b/modules/home/common/sway.nix @@ -1,4 +1,10 @@ { self, config, lib, ... }: +let + eachOutput = _: monitor: { + inherit (monitor) name; + value = builtins.removeAttrs monitor [ "mode" "name" "scale" "transform" "position" ]; + }; +in { options.swarselsystems = { modules.sway = lib.mkEnableOption "sway settings"; @@ -54,15 +60,15 @@ swayfxConfig = lib.mkOption { type = lib.types.str; default = " - blur enable - blur_xray disable - blur_passes 1 - blur_radius 1 - shadows enable - corner_radius 2 - titlebar_separator disable - default_dim_inactive 0.02 - "; + blur enable + blur_xray disable + blur_passes 1 + blur_radius 1 + shadows enable + corner_radius 2 + titlebar_separator disable + default_dim_inactive 0.02 + "; internal = true; }; }; @@ -209,7 +215,6 @@ }; }; defaultWorkspace = "workspace 1:δΈ€"; - # output = lib.mapAttrs' lib.swarselsystems.eachMonitor monitors; output = { "${config.swarselsystems.sharescreen}" = { bg = "${self}/files/wallpaper/lenovowp.png ${config.stylix.imageScalingMode}"; @@ -221,7 +226,7 @@ input = config.swarselsystems.standardinputs; workspaceOutputAssign = let - workplaceSets = lib.mapAttrs' lib.swarselsystems.eachOutput config.swarselsystems.monitors; + workplaceSets = lib.mapAttrs' eachOutput config.swarselsystems.monitors; workplaceOutputs = map (key: lib.getAttr key workplaceSets) (lib.attrNames workplaceSets); in workplaceOutputs; @@ -370,36 +375,36 @@ swayfxSettings = config.swarselsystems.swayfxConfig; in " - exec_always autotiling - set $exit \"exit: [s]leep, [l]ock, [p]oweroff, [r]eboot, [u]ser logout\" + exec_always autotiling + set $exit \"exit: [s]leep, [l]ock, [p]oweroff, [r]eboot, [u]ser logout\" - mode $exit { - bindsym --to-code { - s exec \"systemctl suspend\", mode \"default\" - h exec \"systemctl hibernate\", mode \"default\" - l exec \"swaylock --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2 --daemonize\", mode \"default\ - p exec \"systemctl poweroff\" - r exec \"systemctl reboot\" - u exec \"swaymsg exit\" + mode $exit { + bindsym --to-code { + s exec \"systemctl suspend\", mode \"default\" + h exec \"systemctl hibernate\", mode \"default\" + l exec \"swaylock --screenshots --clock --effect-blur 7x5 --effect-vignette 0.5:0.5 --fade-in 0.2 --daemonize\", mode \"default\ + p exec \"systemctl poweroff\" + r exec \"systemctl reboot\" + u exec \"swaymsg exit\" - Return mode \"default\" - Escape mode \"default\" - ${modifier}+Escape mode \"default\" + Return mode \"default\" + Escape mode \"default\" + ${modifier}+Escape mode \"default\" + } } - } - exec systemctl --user import-environment - exec swayidle -w + exec systemctl --user import-environment + exec swayidle -w - seat * hide_cursor 2000 + seat * hide_cursor 2000 - exec_always kill -1 $(pidof kanshi) + exec_always kill -1 $(pidof kanshi) - bindswitch --locked lid:on exec kanshictl switch lidclosed - bindswitch --locked lid:off exec kanshictl switch lidopen + bindswitch --locked lid:on exec kanshictl switch lidclosed + bindswitch --locked lid:off exec kanshictl switch lidopen - ${swayfxSettings} - "; + ${swayfxSettings} + "; }; }; } diff --git a/modules/nixos/client/hardwarecompatibility-yubikey.nix b/modules/nixos/client/hardwarecompatibility-yubikey.nix index a20af81..1974260 100644 --- a/modules/nixos/client/hardwarecompatibility-yubikey.nix +++ b/modules/nixos/client/hardwarecompatibility-yubikey.nix @@ -1,4 +1,8 @@ { lib, config, pkgs, ... }: +let + inherit (config.swarselsystems) mainUser; + inherit (config.repo.secrets.common.yubikeys) cfg1 cfg2; +in { options.swarselsystems.modules.yubikey = lib.mkEnableOption "yubikey config"; config = lib.mkIf config.swarselsystems.modules.yubikey { @@ -8,6 +12,21 @@ hardware.gpgSmartcards.enable = true; + security.pam.u2f = { + enable = true; + control = "sufficient"; + settings = { + interactive = false; # displays a prompt BEFORE asking for presence + cue = true; # prints a message that a touch is requrired + origin = "pam://${mainUser}"; # make the keys work on all machines + authfile = pkgs.writeText "u2f-mappings" (lib.concatStrings [ + mainUser + cfg1 + cfg2 + ]); + }; + }; + services.udev.packages = with pkgs; [ yubikey-personalization ]; diff --git a/nix/lib.nix b/nix/lib.nix index 8660d56..8de818b 100644 --- a/nix/lib.nix +++ b/nix/lib.nix @@ -41,15 +41,12 @@ let mkStrong = lib.mkOverride 60; - forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system}); + # forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system}); forEachLinuxSystem = f: lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: f pkgsFor.${system}); readHosts = type: lib.attrNames (builtins.readDir "${self}/hosts/${type}"); readNix = type: lib.filter (name: name != "default.nix") (lib.attrNames (builtins.readDir "${self}/${type}")); - - - mkModules = names: type: builtins.listToAttrs (map (name: { inherit name; @@ -64,18 +61,7 @@ let }) names); - mkImports = names: baseDir: lib.map (name: "${self}/${baseDir}/${name}") names; - - eachMonitor = _: monitor: { - inherit (monitor) name; - value = builtins.removeAttrs monitor [ "workspace" "name" "output" ]; - }; - - eachOutput = _: monitor: { - inherit (monitor) name; - value = builtins.removeAttrs monitor [ "mode" "name" "scale" "transform" "position" ]; - }; }; in { diff --git a/profiles/home/personal/default.nix b/profiles/home/personal/default.nix index 767629b..5177629 100644 --- a/profiles/home/personal/default.nix +++ b/profiles/home/personal/default.nix @@ -8,7 +8,7 @@ general = lib.mkDefault true; nixgl = lib.mkDefault true; sops = lib.mkDefault true; - yubikey = lib.mkDefault true; + yubikey = lib.mkDefault false; ssh = lib.mkDefault true; stylix = lib.mkDefault true; desktop = lib.mkDefault true; diff --git a/secrets/repo/pii.nix.enc b/secrets/repo/pii.nix.enc index e198dce..b3c617b 100644 --- a/secrets/repo/pii.nix.enc +++ b/secrets/repo/pii.nix.enc @@ -1,5 +1,5 @@ { - "data": "ENC[AES256_GCM,data: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,iv:i2EIMD409Y6wYhRwVjLtf30m2pR3JtFDqT+VnFBaTz8=,tag:03MllePz2dHzk5IW+DmvHw==,type:str]", + "data": "ENC[AES256_GCM,data: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,iv:pEDV2WLEFisblx+XrhuoaNpxtk4Byj+jB/ixhsk3uPQ=,tag:T4xI5g6sIrIobuSuViG5+A==,type:str]", "sops": { "age": [ { @@ -27,8 +27,8 @@ "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtU240VjVRZmJ5TGsrclJF\nRXRLbTRCZURtR0Z3d2E2eDNNeGRDODlXVEY4CllTeVFYbDJQWlRSS1RFLzAxSnlM\nZi9NU1c3cWo3YWRLcUJ2U2ZFWFBBVEEKLS0tIGtmZU9qSWdBT3RDeStaaFFDSWtk\ndkUzZXJwZUl4LzVxYXdidmxXRnNnclUKyAMZqCKSY/RQvTR4bbjLaPnGKwdBcHXc\nvtiVSrLdIdzMa6id/J07TJH5UesUmcp0wjU41MDa4aMBLy+cXhuBHA==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2025-07-05T11:16:37Z", - "mac": "ENC[AES256_GCM,data:gdnY/T7kDdSzGR9FCrnMJdBhBgr3ruveVnMGnFFjydVeJeZCLkDYdGHxyoaywrJ/KQpx3OpIai/DwzDVQmNjNhC66cEE11xovLV37IzxXY2+2kFqeosIFMaAiA4vZuTBml9YbVMschGZypPwXn9rkjJxaFH0pVt3CJaNbaBn/tQ=,iv:LYHfq3rxkD1c4hvDl605Tp3OlQ4hSocSPnb2uynuc2g=,tag:Rtx8g+1CgIkrAcmsaI92KA==,type:str]", + "lastmodified": "2025-07-14T02:08:47Z", + "mac": "ENC[AES256_GCM,data:ZT2q2cHleWw+h7JNzWi+UnFo7G72xMMjzkbr4Ixp09xT9jqHjeHRitRveoNyh8jcRSbWxVeYf1fpKEKPEAxqU77NORhD/QBFjQm1iG/UH/xkRNBTQ/kE+yp/6jlkyfJ/m8ulTSbegz2eQkko9HP9qG7+QMcESP6zE7ko8UFPXAY=,iv:AvQDzn9kQYj1cr6K/luFZkv2G1UAQT27cA9/pQMRJl0=,tag:uuH3aZSI644HrJXYR5I7UQ==,type:str]", "pgp": [ { "created_at": "2025-06-13T20:13:06Z",