diff --git a/.github/README.md b/.github/README.md
index 9fcbec2..236919b 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -49,8 +49,8 @@ Otherwise, the files that are possibly of biggest interest are found here:
- [SwarselSystems.org](../SwarselSystems.org)
- [flake.nix](../flake.nix)
-- [early-init.el](../programs/emacs/early-init.el)
-- [init.el](../programs/emacs/init.el)
+- [early-init.el](../files/emacs/early-init.el)
+- [init.el](../files/emacs/init.el)
### Getting started
@@ -112,7 +112,7 @@ Alternatively, to install this from any NixOS live ISO, run `nix run --experimen
|🚪 **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/programs/emacs/init.el) |
+|✒️ **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) |
diff --git a/SwarselSystems.org b/SwarselSystems.org
index 24bb9f8..2141ffc 100644
--- a/SwarselSystems.org
+++ b/SwarselSystems.org
@@ -1,5 +1,5 @@
#+title: SwarselSystems: NixOS + Emacs Configuration
-#+PROPERTY: header-args:emacs-lisp :tangle programs/emacs/init.el :mkdirp yes
+#+PROPERTY: header-args:emacs-lisp :tangle files/emacs/init.el :mkdirp yes
#+PROPERTY: header-args:nix :mkdirp yes
#+PROPERTY: header-args:nix-ts :mkdirp yes
#+PROPERTY: header-args:shell :mkdirp yes
@@ -245,7 +245,7 @@ Here I give a brief overview over the hostmachines that I am using. This is held
|🚪 **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/programs/emacs/init.el) |
+ |✒️ **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) |
@@ -481,6 +481,7 @@ When setting this option normally, the password would normally be written world-
./nix/templates.nix
./nix/formatter.nix
./nix/modules.nix
+ ./nix/iso.nix
];
systems = [
"x86_64-linux"
@@ -867,7 +868,7 @@ The structure of =globals.nix.enc= requires a toplevel =globals=.
homeConfigurations = mkHalfHostConfigs (lib.swarselsystems.readHosts "home") "home" lib.swarselsystems.pkgsFor.x86_64-linux;
nixOnDroidConfigurations = mkHalfHostConfigs (lib.swarselsystems.readHosts "android") "android" lib.swarselsystems.pkgsFor.aarch64-linux;
- diskoConfigurations.default = import "${self}/templates/hosts/nixos/disk-config.nix";
+ diskoConfigurations.default = import "${self}/files/templates/hosts/nixos/disk-config.nix";
nodes = config.nixosConfigurations // config.darwinConfigurations;
@@ -930,7 +931,7 @@ The structure of =globals.nix.enc= requires a toplevel =globals=.
pfsense = mkRouter "pfSense" {
info = "HUNSN RM02";
- image = "${self}/topology-images/hunsn.png";
+ image = "${self}/files/topology-images/hunsn.png";
interfaceGroups = [
[
"eth2"
@@ -979,7 +980,7 @@ The structure of =globals.nix.enc= requires a toplevel =globals=.
wifi-ap = mkSwitch "Wi-Fi AP" {
info = "Huawei";
- image = "${self}/topology-images/huawei.png";
+ image = "${self}/files/topology-images/huawei.png";
interfaceGroups = [
[
"eth1"
@@ -990,7 +991,7 @@ The structure of =globals.nix.enc= requires a toplevel =globals=.
switch-livingroom = mkSwitch "Switch Livingroom" {
info = "TL-SG108";
- image = "${self}/topology-images/TL-SG108.png";
+ image = "${self}/files/topology-images/TL-SG108.png";
interfaceGroups = [
[
"eth1"
@@ -1012,13 +1013,13 @@ The structure of =globals.nix.enc= requires a toplevel =globals=.
nswitch = mkDevice "Nintendo Switch" {
info = "Nintendo Switch";
- image = "${self}/topology-images/nintendo-switch.png";
+ image = "${self}/files/topology-images/nintendo-switch.png";
interfaces.eth1 = { };
};
pc = mkDevice "Windows Gaming Server" {
info = "i7-4790k, GTX970, 32GB RAM";
- image = "${self}/topology-images/pc.png";
+ image = "${self}/files/topology-images/pc.png";
interfaces.eth1 = { };
};
@@ -1026,7 +1027,7 @@ The structure of =globals.nix.enc= requires a toplevel =globals=.
switch-bedroom = mkSwitch "Switch Bedroom" {
info = "TL-SG1005D";
- image = "${self}/topology-images/TL-SG1005D.png";
+ image = "${self}/files/topology-images/TL-SG1005D.png";
interfaceGroups = [
[
"eth1"
@@ -1041,7 +1042,7 @@ The structure of =globals.nix.enc= requires a toplevel =globals=.
printer = mkDevice "Printer" {
info = "DELL C2665dnf";
- image = "${self}/topology-images/DELL-C2665dnf.png";
+ image = "${self}/files/topology-images/DELL-C2665dnf.png";
interfaces.eth1 = { };
};
@@ -1224,7 +1225,7 @@ This file defines the templates that are being exposed by the flake. These can b
(name: {
inherit name;
value = {
- path = "${self}/templates/${name}";
+ path = "${self}/files/templates/${name}";
description = "${name} project ";
};
})
@@ -1429,6 +1430,30 @@ Lastly, I add some of my own library functions to be used alongside the function
};
}
#+end_src
+** Installer iso
+
+#+begin_src nix-ts :tangle nix/iso.nix
+ { inputs, ... }:
+ {
+ perSystem = { pkgs, system, ... }:
+ {
+ # nix build --print-out-paths --no-link .#images.
-This file has 83537 words spanning 21934 lines and was last revised on 2025-07-02 01:23:11 +0200.
+This file has 83754 words spanning 22016 lines and was last revised on 2025-07-04 18:25:33 +0200.
@@ -825,7 +822,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-02 01:23:11 +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-04 18:25:33 +0200)
-
-
-
+
-
-
+
+
+
-
+
+
-
@@ -1085,7 +1082,7 @@ Here I give a brief overview over the hostmachines that I am using. This is held
|🚪 **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/programs/emacs/init.el) |
+|✒️ **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) |
@@ -1135,7 +1132,7 @@ Handling the flake.nix file used to be a bit of a chore, since it felt like writ
-
-
-
-
-
-
-
-
@@ -772,7 +769,7 @@
-
-
-These blocks are later inserted here: flake.nix template. Adding new flake inputs is very easy, you just add them to 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 let, and the specific setup is done in either nixosConfigurations (for NixOS systems), homeConfigurations (for home-manager systems), or nixOnDroidConfigurations (for Nix on Android) and darwinConfigurations (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.
+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.
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.
-{
- description = "SwarseFlake - Nix Flake for all SwarselSystems";
+
+In this section I am creating some attributes that define general concepts of my configuration:
+
- nixConfig = {
- extra-substituters = [
- "https://nix-community.cachix.org"
- "https://cache.ngi0.nixos.org/"
- ];
- extra-trusted-public-keys = [
- "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
- "cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA="
- ];
- };
- inputs = {
+nixosModules imports self-defined options that I only want to use on NixOS systems. All modules are held as separately as possible, to allow for easier sharing with other people mostly.homeModules imports modules that are to be used on NixOS and non-NixOS systems. These are mostly used to define outputs (monitors), keyboards and special commands for machines.packages holds packages that I am building myself. These are mostly shell scripts, but also a few others such as AppImages and firefox addons.devShells provides a development shell that can be used as a bootstrap for new installs using nix develop while inside the flake directory. It received an overhaul in 0a6cf0e feat: add checks to devShell, since when it is handled using forAllSystems and now including pre-commit-hook checks.formatter provides the formatter that is to be used on .nix files. It can be called by using nix fmt.check provides the pre-commit-hook checks that I have explained in [BROKEN LINK: h:cbd5002c-e0fa-434a-951b-e05b179e4e3f].
+overlays imports a few community overlays (such as the emacs-overlay) and also three overlays of my own:
+
additions holds derivations that I am adding myself to nixpkgs - i.e. this is where the packages defined in /pkgs get added to nixpkgs.modifications holds derivations that I have performed overrides on. The list of interesting attribute overrides can be found by looking at the source code of a derivation and looking at the start of the file for lines of the form <name> ? <val>. But this can also be used to, for example, fetch a different version of a package instead.nixpkgs-stable holds the newest version of stable nixpkgs. I only use this on packages that seem broken on unstable, which are not many.zjstatus holds some options for zellij, but I have stopped using it since I prefer tmux.
+They are defined in [BROKEN LINK: h:5e3e21e0-57af-4dad-b32f-6400af9b7aab]. The way this is handled was simplified in 647a2ae feat: simplify overlay structure; however, the old structure might be easier to understand as a reference.
+
Here we define inputs and outputs of the flake. First, the following list is for the outputs of the flake.
@@ -1525,257 +1248,861 @@ This automatically creates a topology diagram of my configuration.
-nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
-nixpkgs-kernel.url = "github:NixOS/nixpkgs/063f43f2dbdef86376cc29ad646c45c46e93234c?narHash=sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o%3D"; #specifically pinned for kernel version
-nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.05";
-nixpkgs-stable24_05.url = "github:NixOS/nixpkgs/nixos-24.05";
-nixpkgs-stable24_11.url = "github:NixOS/nixpkgs/nixos-24.11";
-systems.url = "github:nix-systems/default";
-home-manager = {
- url = "github:nix-community/home-manager";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-emacs-overlay = {
- url = "github:nix-community/emacs-overlay";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-nur.url = "github:nix-community/NUR";
-nixgl.url = "github:guibou/nixGL";
-stylix.url = "github:danth/stylix";
-sops-nix.url = "github:Mic92/sops-nix";
-lanzaboote.url = "github:nix-community/lanzaboote";
-nix-on-droid = {
- url = "github:nix-community/nix-on-droid/release-24.05";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-nixos-generators = {
- url = "github:nix-community/nixos-generators";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-nixos-hardware = {
- url = "github:NixOS/nixos-hardware/master";
-};
-nix-alien = {
- url = "github:thiagokokada/nix-alien";
-};
-nswitch-rcm-nix = {
- url = "github:Swarsel/nswitch-rcm-nix";
-};
-nix-index-database = {
- url = "github:nix-community/nix-index-database";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-disko = {
- url = "github:nix-community/disko";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-impermanence.url = "github:nix-community/impermanence";
-zjstatus = {
- url = "github:dj95/zjstatus";
-};
-fw-fanctrl = {
- url = "github:TamtamHero/fw-fanctrl/packaging/nix";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-nix-darwin = {
- url = "github:lnl7/nix-darwin";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-pre-commit-hooks = {
- url = "github:cachix/git-hooks.nix";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-nix-secrets = {
- url = "git+ssh://git@github.com/Swarsel/nix-secrets.git?ref=main&shallow=1";
- flake = false;
- inputs = { };
-};
-vbc-nix = {
- url = "git+ssh://git@github.com/vbc-it/vbc-nix.git?ref=main";
- inputs.nixpkgs.follows = "nixpkgs";
-};
-nix-topology.url = "github:oddlama/nix-topology";
-flake-parts.url = "github:hercules-ci/flake-parts";
-
--Here I define a few variables that I need for my system specifications. There used to be more here, but I managed to optimize my configuration, and only two things remain: -
-outputs, which is needed for liblib: This exposes a common lib for NixOS and home-manager that is extended by my own personal lib functions.{
+ description = "SwarseFlake - Nix Flake for all SwarselSystems";
-
-
-inherit (self) outputs;
-lib = (nixpkgs.lib // home-manager.lib).extend (_: _: { swarselsystems = import ./lib { inherit self lib inputs outputs systems; }; });
-
-
-
--In this section I am creating some attributes that define general concepts of my configuration: -
- -nixosModules imports self-defined options that I only want to use on NixOS systems. All modules are held as separately as possible, to allow for easier sharing with other people mostly.homeModules imports modules that are to be used on NixOS and non-NixOS systems. These are mostly used to define outputs (monitors), keyboards and special commands for machines.packages holds packages that I am building myself. These are mostly shell scripts, but also a few others such as AppImages and firefox addons.devShells provides a development shell that can be used as a bootstrap for new installs using nix develop while inside the flake directory. It received an overhaul in 0a6cf0e feat: add checks to devShell, since when it is handled using forAllSystems and now including pre-commit-hook checks.formatter provides the formatter that is to be used on .nix files. It can be called by using nix fmt.check provides the pre-commit-hook checks that I have explained in Pre-commit-hooks (Checks).
-overlays imports a few community overlays (such as the emacs-overlay) and also three overlays of my own:
-
additions holds derivations that I am adding myself to nixpkgs - i.e. this is where the packages defined in /pkgs get added to nixpkgs.modifications holds derivations that I have performed overrides on. The list of interesting attribute overrides can be found by looking at the source code of a derivation and looking at the start of the file for lines of the form <name> ? <val>. But this can also be used to, for example, fetch a different version of a package instead.nixpkgs-stable holds the newest version of stable nixpkgs. I only use this on packages that seem broken on unstable, which are not many.zjstatus holds some options for zellij, but I have stopped using it since I prefer tmux.
-They are defined in Overlays (additions, overrides, nixpkgs-stable). The way this is handled was simplified in 647a2ae feat: simplify overlay structure; however, the old structure might be easier to understand as a reference.
-
inherit lib;
-
-# nixosModules = import ./modules/nixos { inherit lib; };
-# homeModules = import ./modules/home { inherit lib; };
-packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import ./pkgs { inherit lib pkgs; });
-formatter = lib.swarselsystems.forEachSystem (pkgs: pkgs.nixpkgs-fmt);
-overlays = import ./overlays { inherit self lib inputs; };
-
-apps = lib.swarselsystems.forAllSystems (system:
- let
- appNames = [
- "swarsel-bootstrap"
- "swarsel-install"
- "swarsel-rebuild"
- "swarsel-postinstall"
+ nixConfig = {
+ extra-substituters = [
+ "https://nix-community.cachix.org"
+ "https://cache.ngi0.nixos.org/"
];
- appSet = lib.swarselsystems.mkApps system appNames self;
- in
-
- appSet // {
- default = appSet.swarsel-bootstrap;
- }
-);
-
-devShells = lib.swarselsystems.forAllSystems (system:
- let
- pkgs = lib.swarselsystems.pkgsFor.${system};
- checks = self.checks.${system};
- in
- {
- default = pkgs.mkShell {
- # plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: {
- # buildInputs = [pkgs.nixVersions.latest pkgs.boost];
- # patches = (o.patches or []) ++ [ "${self}/nix/nix-plugins.patch" ];
- # })}/lib/nix/plugins
- NIX_CONFIG = ''
- plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
- extra-builtins-file = ${self + /nix/extra-builtins.nix}
- '';
- inherit (checks.pre-commit-check) shellHook;
-
- buildInputs = checks.pre-commit-check.enabledPackages;
- nativeBuildInputs = [
- (builtins.trace "alarm: we pinned nix_2_24 because of https://github.com/shlevy/nix-plugins/issues/20" pkgs.nixVersions.nix_2_24) # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions.
- # pkgs.nix
- pkgs.home-manager
- pkgs.git
- pkgs.just
- pkgs.age
- pkgs.ssh-to-age
- pkgs.sops
- pkgs.statix
- pkgs.deadnix
- pkgs.nixpkgs-fmt
+ extra-trusted-public-keys = [
+ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
+ "cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA="
+ ];
+ };
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+ nixpkgs-kernel.url = "github:NixOS/nixpkgs/063f43f2dbdef86376cc29ad646c45c46e93234c?narHash=sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o%3D"; #specifically pinned for kernel version
+ nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.05";
+ nixpkgs-stable24_05.url = "github:NixOS/nixpkgs/nixos-24.05";
+ nixpkgs-stable24_11.url = "github:NixOS/nixpkgs/nixos-24.11";
+ systems.url = "github:nix-systems/default";
+ home-manager = {
+ url = "github:nix-community/home-manager";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ emacs-overlay = {
+ url = "github:nix-community/emacs-overlay";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nur.url = "github:nix-community/NUR";
+ nixgl.url = "github:guibou/nixGL";
+ stylix.url = "github:danth/stylix";
+ sops-nix.url = "github:Mic92/sops-nix";
+ lanzaboote.url = "github:nix-community/lanzaboote";
+ nix-on-droid = {
+ url = "github:nix-community/nix-on-droid/release-24.05";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nixos-generators = {
+ url = "github:nix-community/nixos-generators";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nixos-hardware = {
+ url = "github:NixOS/nixos-hardware/master";
+ };
+ nix-alien = {
+ url = "github:thiagokokada/nix-alien";
+ };
+ nswitch-rcm-nix = {
+ url = "github:Swarsel/nswitch-rcm-nix";
+ };
+ nix-index-database = {
+ url = "github:nix-community/nix-index-database";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ disko = {
+ url = "github:nix-community/disko";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ impermanence.url = "github:nix-community/impermanence";
+ zjstatus = {
+ url = "github:dj95/zjstatus";
+ };
+ fw-fanctrl = {
+ url = "github:TamtamHero/fw-fanctrl/packaging/nix";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nix-darwin = {
+ url = "github:lnl7/nix-darwin";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ pre-commit-hooks = {
+ url = "github:cachix/git-hooks.nix";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nix-secrets = {
+ url = "git+ssh://git@github.com/Swarsel/nix-secrets.git?ref=main&shallow=1";
+ flake = false;
+ inputs = { };
+ };
+ vbc-nix = {
+ url = "git+ssh://git@github.com/vbc-it/vbc-nix.git?ref=main";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ nix-topology.url = "github:oddlama/nix-topology";
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ devshell = {
+ url = "github:numtide/devshell";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ };
+ outputs =
+ inputs:
+ inputs.flake-parts.lib.mkFlake { inherit inputs; } {
+ imports = [
+ ./nix/globals.nix
+ ./nix/hosts.nix
+ ./nix/topology.nix
+ ./nix/devshell.nix
+ ./nix/apps.nix
+ ./nix/packages.nix
+ ./nix/overlays.nix
+ ./nix/lib.nix
+ ./nix/templates.nix
+ ./nix/formatter.nix
+ ./nix/modules.nix
+ ./nix/iso.nix
+ ];
+ systems = [
+ "x86_64-linux"
+ "aarch64-linux"
+ "x86_64-darwin"
+ "aarch64-darwin"
];
};
- }
-);
-
-templates = import ./templates { inherit lib; };
-
-checks = lib.swarselsystems.forAllSystems (system:
- let
- pkgs = lib.swarselsystems.pkgsFor.${system};
- in
- import ./checks { inherit self inputs system pkgs; }
-);
-
-diskoConfigurations.default = import .templates/hosts/nixos/disk-config.nix;
+}
# adapted from https://github.com/oddlama/nix-config/blob/main/nix/extra-builtins.nix
+{ exec, ... }:
+let
+ assertMsg = pred: msg: pred || builtins.throw msg;
+ hasSuffix =
+ suffix: content:
+ let
+ lenContent = builtins.stringLength content;
+ lenSuffix = builtins.stringLength suffix;
+ in
+ lenContent >= lenSuffix && builtins.substring (lenContent - lenSuffix) lenContent content == suffix;
+in
+{
+ # Instead of calling sops directly here, we call a wrapper script that will cache the output
+ # in a predictable path in /tmp, which allows us to only require the password for each encrypted
+ # file once.
+ sopsImportEncrypted =
+ nixFile:
+ assert assertMsg (builtins.isPath nixFile)
+ "The file to decrypt must be given as a path (not a string) to prevent impurity.";
+ assert assertMsg (hasSuffix ".nix.enc" nixFile)
+ "The content of the decrypted file must be a nix expression and should therefore end in .nix.enc";
+ exec [
+ ./sops-decrypt-and-cache.sh
+ nixFile
+ ];
+}
+
+
+# adapted from https://github.com/oddlama/nix-config/blob/main/nix/rage-decrypt-and-cache.sh
+set -euo pipefail
+
+print_out_path=false
+if [[ $1 == "--print-out-path" ]]; then
+ print_out_path=true
+ shift
+fi
+
+file="$1"
+shift
+
+basename="${file%".enc"}"
+# store path prefix or ./ if applicable
+[[ $file == "/nix/store/"* ]] && basename="${basename#*"-"}"
+[[ $file == "./"* ]] && basename="${basename#"./"}"
+
+# Calculate a unique content-based identifier (relocations of
+# the source file in the nix store should not affect caching)
+new_name="$(sha512sum "$file")"
+new_name="${new_name:0:32}-${basename//"/"/"%"}"
+
+# Derive the path where the decrypted file will be stored
+out="/var/tmp/nix-import-encrypted/$UID/$new_name"
+umask 077
+mkdir -p "$(dirname "$out")"
+
+# Decrypt only if necessary
+if [[ ! -e $out ]]; then
+ agekey=$(sudo ssh-to-age -private-key -i /etc/ssh/sops || sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key)
+ SOPS_AGE_KEY="$agekey" sops decrypt --output "$out" "$file"
+fi
+
+# Print out path or decrypted content
+if [[ $print_out_path == true ]]; then
+ echo "$out"
+else
+ cat "$out"
+fi
+
+
+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.
+
+A breakdown of each function: +
+ ++The interesting part is in the start: +
+pkgsFor. This function reads all available systems from nixpkgs and generates pkgs for them.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.{ self, inputs, ... }:
+let
+ swarselsystems =
+ let
+ inherit (inputs) systems;
+ inherit (inputs.nixpkgs) lib;
+ in
+ rec {
+ mkIfElseList = p: yes: no: lib.mkMerge [
+ (lib.mkIf p yes)
+ (lib.mkIf (!p) no)
+ ];
+
+ mkIfElse = p: yes: no: if p then yes else no;
+
+ pkgsFor = lib.genAttrs (import systems) (system:
+ import inputs.nixpkgs {
+ inherit system;
+ overlays = [ self.overlays.default ];
+ config.allowUnfree = true;
+ }
+ );
+
+ toCapitalized = str:
+ if builtins.stringLength str == 0 then
+ ""
+ else
+ let
+ first = builtins.substring 0 1 str;
+ rest = builtins.substring 1 (builtins.stringLength str - 1) str;
+ upper = lib.toUpper first;
+ lower = lib.toLower rest;
+ in
+ upper + lower;
+
+
+ mkTrueOption = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ };
+
+ mkStrong = lib.mkOverride 60;
+
+ 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;
+ value = import "${self}/modules/${type}/${name}";
+ })
+ names);
+
+ mkProfiles = names: type: builtins.listToAttrs (map
+ (name: {
+ inherit name;
+ value = import "${self}/profiles/${type}/${name}";
+ })
+ 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
+{
+ flake = _:
+ {
+ lib = (inputs.nixpkgs.lib // inputs.home-manager.lib).extend (_: _: {
+ inherit swarselsystems;
+ });
+ };
+}
+
+
+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.
+
{ self, ... }:
+{
+ flake = _:
+ let
+ inherit (self.outputs) lib;
+ in
+ {
+ packages = lib.swarselsystems.forEachLinuxSystem (pkgs: import "${self}/pkgs" { inherit self lib pkgs; });
+ };
+}
+
+
+The structure of globals.nix.enc requires a toplevel globals.
+
# adapted from https://github.com/oddlama/nix-config/blob/main/nix/globals.nix
+{ inputs, ... }:
+{
+ flake = { config, lib, ... }:
+ {
+ globals =
+ let
+ globalsSystem = lib.evalModules {
+ prefix = [ "globals" ];
+ specialArgs = {
+ inherit lib;
+ inherit inputs;
+ inherit (config) nodes;
+ };
+ modules = [
+ ../modules/nixos/common/globals.nix
+ (
+ { lib, ... }:
+ let
+ # Try to access the extra builtin we loaded via nix-plugins.
+ # Throw an error if that doesn't exist.
+ sopsImportEncrypted =
+ assert lib.assertMsg (builtins ? extraBuiltins.sopsImportEncrypted)
+ "The extra builtin 'sopsImportEncrypted' is not available, so repo.secrets cannot be decrypted. Did you forget to add nix-plugins and point it to `./nix/extra-builtins.nix` ?";
+ builtins.extraBuiltins.sopsImportEncrypted;
+ in
+
+ {
+ imports = [
+ (sopsImportEncrypted ../secrets/repo/globals.nix.enc)
+ ];
+
+ }
+ )
+ (
+ { lib, ... }:
+ {
+ globals = lib.mkMerge (
+ lib.concatLists (
+ lib.flip lib.mapAttrsToList config.nodes (
+ name: cfg:
+ builtins.addErrorContext "while aggregating globals from nixosConfigurations.${name} into flake-level globals:" cfg.config._globalsDefs
+ )
+ )
+ );
+ }
+ )
+ ];
+ };
+ in
+ {
+ # Make sure the keys of this attrset are trivially evaluatable to avoid infinite recursion,
+ # therefore we inherit relevant attributes from the config.
+ inherit (globalsSystem.config.globals)
+ domains
+ services
+ user
+ ;
+ };
+ };
+}
+
+
+{ self, inputs, ... }:
+{
+ flake = { config, ... }:
+ let
+ inherit (self) outputs;
+ inherit (outputs) lib;
+ # lib = (inputs.nixpkgs.lib // inputs.home-manager.lib).extend (_: _: { swarselsystems = import "${self}/lib" { inherit self lib inputs outputs; inherit (inputs) systems; }; });
+
+ mkNixosHost = { minimal }: name:
+ lib.nixosSystem {
+ specialArgs = { inherit inputs outputs lib self minimal; inherit (config) globals nodes; };
+ modules = [
+ inputs.disko.nixosModules.disko
+ inputs.sops-nix.nixosModules.sops
+ inputs.impermanence.nixosModules.impermanence
+ inputs.lanzaboote.nixosModules.lanzaboote
+ inputs.nix-topology.nixosModules.default
+ inputs.home-manager.nixosModules.home-manager
+ "${self}/hosts/nixos/${name}"
+ "${self}/profiles/nixos"
+ "${self}/modules/nixos"
+ {
+ node.name = name;
+ node.secretsDir = ../hosts/nixos/${name}/secrets;
+ }
+ ];
+ };
+
+ mkDarwinHost = { minimal }: name:
+ inputs.nix-darwin.lib.darwinSystem {
+ specialArgs = { inherit inputs outputs lib self minimal; inherit (config) globals nodes; };
+ modules = [
+ # inputs.disko.nixosModules.disko
+ # inputs.sops-nix.nixosModules.sops
+ # inputs.impermanence.nixosModules.impermanence
+ # inputs.lanzaboote.nixosModules.lanzaboote
+ # inputs.fw-fanctrl.nixosModules.default
+ # inputs.nix-topology.nixosModules.default
+ inputs.home-manager.darwinModules.home-manager
+ "${self}/hosts/darwin/${name}"
+ "${self}/modules/nixos/darwin"
+ # needed for infrastructure
+ "${self}/modules/nixos/common/meta.nix"
+ "${self}/modules/nixos/common/globals.nix"
+ {
+ node.name = name;
+ node.secretsDir = ../hosts/darwin/${name}/secrets;
+ }
+ ];
+ };
+
+ mkHalfHost = name: type: pkgs: {
+ ${name} =
+ let
+ systemFunc = if (type == "home") then inputs.home-manager.lib.homeManagerConfiguration else inputs.nix-on-droid.lib.nixOnDroidConfiguration;
+ in
+ systemFunc
+ {
+ inherit pkgs;
+ extraSpecialArgs = { inherit inputs outputs lib self; };
+ modules = [ "${self}/hosts/${type}/${name}" ];
+ };
+ };
+
+ mkHalfHostConfigs = hosts: type: pkgs: lib.foldl (acc: set: acc // set) { } (lib.map (name: mkHalfHost name type pkgs) hosts);
+ nixosHosts = builtins.attrNames (lib.filterAttrs (_: type: type == "directory") (builtins.readDir "${self}/hosts/nixos"));
+ darwinHosts = builtins.attrNames (lib.filterAttrs (_: type: type == "directory") (builtins.readDir "${self}/hosts/darwin"));
+ in
+ {
+ nixosConfigurations = lib.genAttrs nixosHosts (mkNixosHost {
+ minimal = false;
+ });
+ nixosConfigurationsMinimal = lib.genAttrs nixosHosts (mkNixosHost {
+ minimal = true;
+ });
+ darwinConfigurations = lib.genAttrs darwinHosts (mkDarwinHost {
+ minimal = false;
+ });
+ darwinConfigurationsMinimal = lib.genAttrs darwinHosts (mkDarwinHost {
+ minimal = true;
+ });
+
+ # TODO: Build these for all architectures
+ homeConfigurations = mkHalfHostConfigs (lib.swarselsystems.readHosts "home") "home" lib.swarselsystems.pkgsFor.x86_64-linux;
+ nixOnDroidConfigurations = mkHalfHostConfigs (lib.swarselsystems.readHosts "android") "android" lib.swarselsystems.pkgsFor.aarch64-linux;
+
+ diskoConfigurations.default = import "${self}/files/templates/hosts/nixos/disk-config.nix";
+
+ nodes = config.nixosConfigurations // config.darwinConfigurations;
+
+ };
+}
+
+{ self, inputs, ... }:
+{
+ imports = [
+ inputs.nix-topology.flakeModule
+ ];
+
+ perSystem.topology.modules = [
+ ({ config, ... }:
+ let
+ inherit (config.lib.topology)
+ mkInternet
+ mkDevice
+ mkSwitch
+ mkRouter
+ mkConnection
+ ;
+ in
+ {
+ renderer = "elk";
+
+ networks = {
+ home-lan = {
+ name = "Home LAN";
+ cidrv4 = "192.168.1.0/24";
+ };
+ wg = {
+ name = "Wireguard Tunnel";
+ cidrv4 = "192.168.3.0/24";
+ };
+ };
+
+ nodes = {
+ internet = mkInternet {
+ connections = [
+ (mkConnection "moonside" "wan")
+ (mkConnection "pfsense" "wan")
+ (mkConnection "sync" "wan")
+ (mkConnection "toto" "bootstrapper")
+ (mkConnection "chaostheatre" "demo host")
+ ];
+ };
+
+ chaostheatre.interfaces."demo host" = { };
+ toto.interfaces."bootstrapper" = { };
+ sync.interfaces.wan = { };
+ moonside.interfaces.wan = { };
+
+ pfsense = mkRouter "pfSense" {
+ info = "HUNSN RM02";
+ image = "${self}/files/topology-images/hunsn.png";
+ interfaceGroups = [
+ [
+ "eth2"
+ "eth3"
+ "eth4"
+ "eth5"
+ "eth6"
+ ]
+ [ "wan" ]
+ ];
+ interfaces.wg = {
+ addresses = [ "192.168.3.1" ];
+ network = "wg";
+ virtual = true;
+ type = "wireguard";
+ };
+
+ connections = {
+ eth2 = mkConnection "switch-livingroom" "eth1";
+ eth4 = mkConnection "winters" "eth1";
+ eth3 = mkConnection "switch-bedroom" "eth1";
+ eth6 = mkConnection "wifi-ap" "eth1";
+ wg = mkConnection "moonside" "wg";
+ };
+ interfaces = {
+ eth2 = {
+ addresses = [ "192.168.1.1" ];
+ network = "home-lan";
+ };
+ eth3 = {
+ addresses = [ "192.168.1.1" ];
+ network = "home-lan";
+ };
+ eth4 = {
+ addresses = [ "192.168.1.1" ];
+ network = "home-lan";
+ };
+ eth6 = {
+ addresses = [ "192.168.1.1" ];
+ network = "home-lan";
+ };
+ };
+ };
+
+ winters.interfaces."eth1" = { };
+
+ wifi-ap = mkSwitch "Wi-Fi AP" {
+ info = "Huawei";
+ image = "${self}/files/topology-images/huawei.png";
+ interfaceGroups = [
+ [
+ "eth1"
+ "wifi"
+ ]
+ ];
+ };
+
+ switch-livingroom = mkSwitch "Switch Livingroom" {
+ info = "TL-SG108";
+ image = "${self}/files/topology-images/TL-SG108.png";
+ interfaceGroups = [
+ [
+ "eth1"
+ "eth2"
+ "eth3"
+ "eth4"
+ "eth5"
+ "eth6"
+ "eth7"
+ "eth8"
+ ]
+ ];
+ connections = {
+ eth2 = mkConnection "nswitch" "eth1";
+ eth7 = mkConnection "pc" "eth1";
+ eth8 = mkConnection "nbl-imba-2" "eth1";
+ };
+ };
+
+ nswitch = mkDevice "Nintendo Switch" {
+ info = "Nintendo Switch";
+ image = "${self}/files/topology-images/nintendo-switch.png";
+ interfaces.eth1 = { };
+ };
+
+ pc = mkDevice "Windows Gaming Server" {
+ info = "i7-4790k, GTX970, 32GB RAM";
+ image = "${self}/files/topology-images/pc.png";
+ interfaces.eth1 = { };
+ };
+
+ nbl-imba-2.interfaces.eth1 = { };
+
+ switch-bedroom = mkSwitch "Switch Bedroom" {
+ info = "TL-SG1005D";
+ image = "${self}/files/topology-images/TL-SG1005D.png";
+ interfaceGroups = [
+ [
+ "eth1"
+ "eth2"
+ "eth3"
+ "eth4"
+ "eth5"
+ ]
+ ];
+ connections.eth2 = mkConnection "printer" "eth1";
+ };
+
+ printer = mkDevice "Printer" {
+ info = "DELL C2665dnf";
+ image = "${self}/files/topology-images/DELL-C2665dnf.png";
+ interfaces.eth1 = { };
+ };
+
+ };
+
+ })
+
+
+ ];
+}
+
+
+
This file defines a number of checks that can either be run by calling nix flake check or while in a nix-shell or nix develop. This helps me make sure that my flake confirms to my self-imposed standards. The GitHub actions perform less checks than are being done here (they are only checking the formatting, as well as statix and deadnix)
{ self, inputs, pkgs, system, ... }:
+{ self, inputs, ... }:
{
- pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
- src = "${self}";
- hooks = {
- check-added-large-files.enable = true;
- check-case-conflicts.enable = true;
- check-executables-have-shebangs.enable = true;
- check-shebang-scripts-are-executable.enable = false;
- check-merge-conflicts.enable = true;
- deadnix.enable = true;
- detect-private-keys.enable = true;
- end-of-file-fixer.enable = true;
- fix-byte-order-marker.enable = true;
- flake-checker.enable = true;
- forbid-new-submodules.enable = true;
- mixed-line-endings.enable = true;
- nixpkgs-fmt.enable = true;
- statix.enable = true;
- trim-trailing-whitespace.enable = true;
+ imports = [
+ inputs.devshell.flakeModule
+ inputs.pre-commit-hooks.flakeModule
+ ];
- destroyed-symlinks = {
- enable = true;
- entry = "${inputs.pre-commit-hooks.checks.${system}.pre-commit-hooks}/bin/destroyed-symlinks";
+ perSystem = { pkgs, system, ... }:
+ {
+ pre-commit = {
+ check.enable = true;
+ settings = {
+ addGcRoot = true;
+ hooks = {
+ check-added-large-files.enable = true;
+ check-case-conflicts.enable = true;
+ check-executables-have-shebangs.enable = true;
+ check-shebang-scripts-are-executable.enable = false;
+ check-merge-conflicts.enable = true;
+ deadnix.enable = true;
+ detect-private-keys.enable = true;
+ end-of-file-fixer.enable = true;
+ fix-byte-order-marker.enable = true;
+ flake-checker.enable = true;
+ forbid-new-submodules.enable = true;
+ mixed-line-endings.enable = true;
+ nixpkgs-fmt.enable = true;
+ statix.enable = true;
+ trim-trailing-whitespace.enable = true;
+
+ destroyed-symlinks = {
+ enable = true;
+ entry = "${inputs.pre-commit-hooks.checks.${system}.pre-commit-hooks}/bin/destroyed-symlinks";
+ };
+
+ shellcheck = {
+ enable = true;
+ entry = "${pkgs.shellcheck}/bin/shellcheck --shell=bash";
+ };
+
+ shfmt = {
+ enable = true;
+ entry = "${pkgs.shfmt}/bin/shfmt -i 4 -sr -d -s -l";
+ };
+ };
+ };
};
- shellcheck = {
- enable = true;
- entry = "${pkgs.shellcheck}/bin/shellcheck --shell=bash";
- };
+ devshells.default = {
+ packages = [
+ (builtins.trace "alarm: we pinned nix_2_24 because of https://github.com/shlevy/nix-plugins/issues/20" pkgs.nixVersions.nix_2_24) # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions.
+ pkgs.git
+ pkgs.just
+ pkgs.age
+ pkgs.ssh-to-age
+ pkgs.sops
+ pkgs.home-manager
+ pkgs.nixpkgs-fmt
+ self.packages.${system}.swarsel-build
+ self.packages.${system}.swarsel-deploy
+ ];
- shfmt = {
- enable = true;
- entry = "${pkgs.shfmt}/bin/shfmt -i 4 -sr -d -s -l";
- };
+ commands = [
+ {
+ package = pkgs.statix;
+ help = "Lint flake";
+ }
+ {
+ package = pkgs.deadnix;
+ help = "Check flake for dead code";
+ }
+ {
+ package = pkgs.nix-tree;
+ help = "Interactively browse dependency graphs of Nix derivations";
+ }
+ {
+ package = pkgs.nvd;
+ help = "Diff two nix toplevels and show which packages were upgraded";
+ }
+ {
+ package = pkgs.nix-diff;
+ help = "Explain why two Nix derivations differ";
+ }
+ {
+ package = pkgs.nix-output-monitor;
+ help = "Nix Output Monitor (a drop-in alternative for `nix` which shows a build graph)";
+ name = "nom";
+ }
+ {
+ name = "hm";
+ help = "Manage home-manager config";
+ command = "home-manager";
+ }
+ {
+ name = "fmt";
+ help = "Format flake";
+ command = "nixpkgs-fmt --check \"$FLAKE\"";
+ }
+ {
+ name = "sd";
+ help = "Build and deploy this nix config to nodes";
+ command = "swarsel-deploy \"$@\"";
+ }
+ {
+ name = "sl";
+ help = "Build and deploy a config to nodes";
+ command = "swarsel-deploy \${1} switch";
+ }
+ {
+ name = "sw";
+ help = "Build and switch to the host's config locally";
+ command = "swarsel-deploy $(hostname) switch";
+ }
+ {
+ name = "bld";
+ help = "Build a number of configurations";
+ command = "swarel-build \"$@\"";
+ }
+ {
+ name = "c";
+ help = "Work with the flake git repository";
+ command = "git --git-dir=$FLAKE/.git --work-tree=$FLAKE/ \"$@\"";
+ }
+ ];
+ devshell.startup.pre-commit-install.text = "pre-commit install";
+
+ env = [
+ {
+ # Additionally configure nix-plugins with our extra builtins file.
+ # We need this for our repo secrets.
+ name = "NIX_CONFIG";
+ value = ''
+ plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
+ extra-builtins-file = ${self + /nix/extra-builtins.nix}
+ '';
+ }
+ ];
+ };
};
- };
}
This file defines the templates that are being exposed by the flake. These can be used by running nix flake init -t github:Swarsel/.dotfiles#<TEMPLATE_NAME>.
@@ -1783,108 +2110,261 @@ This file defines the templates that are being exposed by the flake. These can b
{ lib, ... }:
+{ self, ... }:
+{
+ flake = _: {
+ templates =
+ let
+ mkTemplates = names: builtins.listToAttrs (map
+ (name: {
+ inherit name;
+ value = {
+ path = "${self}/files/templates/${name}";
+ description = "${name} project ";
+ };
+ })
+ names);
+ templateNames = [
+ "python"
+ "rust"
+ "go"
+ "cpp"
+ "latex"
+ "default"
+ ];
+ in
+ mkTemplates templateNames;
+ };
+}
+
+
+_:
+{
+ perSystem = { pkgs, ... }: {
+ formatter = pkgs.nixpkgs-fmt;
+ };
+}
+
+
+{ self, ... }:
+{
+ flake = _:
+ let
+ inherit (self.outputs) lib;
+ in
+ {
+ nixosModules.default = import "${self}/modules/nixos" { inherit lib; };
+ homeModules = import "${self}/modules/home" { inherit lib; };
+ };
+}
+
+
+
+This file defines a number of checks that can either be run by calling nix flake check or while in a nix-shell or nix develop. This helps me make sure that my flake confirms to my self-imposed standards. The GitHub actions perform less checks than are being done here (they are only checking the formatting, as well as statix and deadnix)
+
{ self, ... }:
+{
+ perSystem = { system, ... }:
+ let
+ mkApps = system: names: self: builtins.listToAttrs (map
+ (name: {
+ inherit name;
+ value = {
+ type = "app";
+ program = "${self.packages.${system}.${name}}/bin/${name}";
+ meta = {
+ description = "Custom app ${name}.";
+ };
+ };
+ })
+ names);
+
+ appNames = [
+ "swarsel-bootstrap"
+ "swarsel-install"
+ "swarsel-rebuild"
+ "swarsel-postinstall"
+ ];
+
+ appSet = mkApps system appNames self;
+ in
+ {
+ apps = appSet // {
+ default = appSet.swarsel-bootstrap;
+ };
+ };
+}
+
++In this section I define packages that I manually want to nixpkgs. This can be useful for packages that are currently awaiting a PR or public packages that I do not want to maintain. +
+ ++As such, I also define three additional overlays: +
+ +additions
+These are for the aforementioned added packagesmodification
+These are for packages that are on nixpkgs, but do not fit my usecase, meaning I need to perform modifications on them.nixpkgs-stable
+This is simply a mirror of the most recent stable branch of nixpkgs. Useful for packages that are broken on nixpkgs, but do not need to be on bleeding edge anyways.+Also, this is where I define all of my own modules. These are mostly used for setting some host-specifics directly than opposed to through multiple options. +
+ +
+Lastly, I add some of my own library functions to be used alongside the functions provided by nixpkgs and home-manager.
+
{ self, inputs, ... }:
let
- templateNames = [
- "python"
- "rust"
- "go"
- "cpp"
- "latex"
- "default"
- ];
+ inherit (self) outputs;
+ inherit (outputs) lib;
in
-lib.swarselsystems.mkTemplates templateNames
+{
+ flake = { config, ... }:
+ {
+ overlays = {
+ default = final: prev:
+ let
+ additions = final: _: import "${self}/pkgs" { pkgs = final; inherit self lib; };
+ modifications = final: prev: {
+ vesktop = prev.vesktop.override {
+ withSystemVencord = true;
+ };
+
+ firefox = prev.firefox.override {
+ nativeMessagingHosts = [
+ prev.tridactyl-native
+ prev.browserpass
+ prev.plasma5Packages.plasma-browser-integration
+ ];
+ };
+
+ mgba = final.swarsel-mgba;
+
+ retroarch = prev.retroarch.withCores (cores: with cores; [
+ snes9x # snes
+ nestopia # nes
+ dosbox # dos
+ scummvm # scumm
+ vba-m # gb/a
+ mgba # gb/a
+ melonds # ds
+ dolphin # gc/wii
+ ]);
+ };
+
+ nixpkgs-stable = final: _: {
+ stable = import inputs.nixpkgs-stable {
+ inherit (final) system;
+ config.allowUnfree = true;
+ };
+ };
+
+ nixpkgs-kernel = final: _: {
+ kernel = import inputs.nixpkgs-kernel {
+ inherit (final) system;
+ config.allowUnfree = true;
+ };
+ };
+
+ nixpkgs-stable24_05 = final: _: {
+ stable24_05 = import inputs.nixpkgs-stable24_05 {
+ inherit (final) system;
+ config.allowUnfree = true;
+ };
+ };
+
+ nixpkgs-stable24_11 = final: _: {
+ stable24_11 = import inputs.nixpkgs-stable24_11 {
+ inherit (final) system;
+ config.allowUnfree = true;
+ };
+ };
+
+ zjstatus = _: prev: {
+ zjstatus = inputs.zjstatus.packages.${prev.system}.default;
+ };
+
+ in
+ (additions final prev)
+ // (modifications final prev)
+ // (nixpkgs-stable final prev)
+ // (nixpkgs-kernel final prev)
+ // (nixpkgs-stable24_05 final prev)
+ // (nixpkgs-stable24_11 final prev)
+ // (zjstatus final prev)
+ // (inputs.vbc-nix.overlays.default final prev)
+ // (inputs.nur.overlays.default final prev)
+ // (inputs.emacs-overlay.overlay final prev)
+ // (inputs.nix-topology.overlays.default final prev)
+ // (inputs.nixgl.overlay final prev);
+ };
+ };
+}
-This section used to be much longer, since I performed all of my imports right here in the past. Since then, I have however refactored and now my important hosts can be defined in little space. Once I have fully transitioned my server to NixOS too this section will become even smaller once more. -
- -
-Note: The preceding nixosConfigurations is found in flake.nix template. Also, the method of generating the hosts was changed in commit
-3a272b1 feat!: dynamically create hosts, and the deprecated system definitions removed in 7457109 main chore: remove deprecated static host config. See those commits for a state with a simpler config.
-
--
-And this defines darwin systems (MacOS), which I only have one of, that serves as a template mostly. -
- -
-Note: The preceding darwinConfigurations is found in flake.nix template. Also, the method of generating the hosts was changed in commit
-3a272b1 feat!: dynamically create hosts, and the deprecated system definitions removed in 7457109 main chore: remove deprecated static host config. See those commits for a state with a simpler config.
-
--
-In contrast, this defines home-manager systems, which I only have one of, that serves as a template mostly. -
- -
-# "swarsel@home-manager" = inputs.home-manager.lib.homeManagerConfiguration {
-# pkgs = lib.swarselsystems.pkgsFor.x86_64-linux;
-# extraSpecialArgs = { inherit inputs outputs; };
-# modules = homeModules ++ mixedModules ++ [
-# ./hosts/home-manager
-# ];
-# };
-
-
--Nix on Android also demands an own flake output, which is provided here. -
- -
-# magicant = inputs.nix-on-droid.lib.nixOnDroidConfiguration {
-# pkgs = lib.swarselsystems.pkgsFor.aarch64-linux;
-# modules = [
-# ./hosts/magicant
-# ];
-# };
-
-
-
-
-
+{ inputs, ... }:
+{
+ perSystem = { pkgs, system, ... }:
+ {
+ # nix build --print-out-paths --no-link .#images.<target-system>.live-iso
+ packages.live-iso = inputs.nixos-generators.nixosGenerate {
+ inherit pkgs;
+ modules = [
+ inputs.home-manager.nixosModules.home-manager
+ ./installer-config.nix
+ ];
+ format =
+ {
+ x86_64-linux = "install-iso";
+ aarch64-linux = "sd-aarch64-installer";
+ }
+ .${system};
+ };
+ };
+}
{ self, inputs, pkgs, lib, primaryUser, ... }:
+{ self, inputs, pkgs, lib, globals, ... }:
let
modulesPath = "${self}/modules";
sharedOptions = {
isBtrfs = true;
};
+ primaryUser = globals.user.name;
in
{
@@ -1956,7 +2437,7 @@ in
swarselsystems = lib.recursiveUpdate
{
- wallpaper = self + /wallpaper/lenovowp.png;
+ wallpaper = self + /files/wallpaper/lenovowp.png;
hasBluetooth = true;
hasFingerprint = true;
isImpermanence = true;
@@ -2133,8 +2614,9 @@ My work machine. Built for more security, this is the gold standard of my config
3.1.2.1.1. Main Configuration
-{ self, config, inputs, lib, primaryUser, ... }:
+{ self, config, inputs, lib, globals, ... }:
let
+ primaryUser = globals.user.name;
sharedOptions = {
isBtrfs = true;
isLinux = true;
@@ -2161,7 +2643,7 @@ in
{
info = "Framework Laptop 16, 7940HS, RX7700S, 64GB RAM";
firewall = lib.mkForce true;
- wallpaper = self + /wallpaper/lenovowp.png;
+ wallpaper = self + /files/wallpaper/lenovowp.png;
hasBluetooth = true;
hasFingerprint = true;
isImpermanence = false;
@@ -2392,8 +2874,9 @@ This is my main server that I run at home. It handles most tasks that require bi
3.1.2.2.1. Main Configuration
-{ lib, config, primaryUser, ... }:
+{ lib, config, globals, ... }:
let
+ primaryUser = globals.user.name;
sharedOptions = {
isBtrfs = false;
isLinux = true;
@@ -2506,7 +2989,7 @@ A Mac notebook that I have received from work. I use this machine for getting ac
-{ lib, ... }:
+{ lib, config, ... }:
let
inherit (config.repo.secrets.local) workUser;
in
@@ -2627,14 +3110,16 @@ All of these are processes that use little cpu but can take a lot of storage. Fo
3.1.3.1.1. Main configuration
-{ lib, config, primaryUser, ... }:
+{ lib, config, globals, ... }:
let
+ primaryUser = globals.user.name;
sharedOptions = {
isBtrfs = false;
isLinux = true;
};
inherit (config.repo.secrets.common) workHostName;
inherit (config.repo.secrets.local.syncthing) dev1 dev2 dev3 loc1;
+ serviceDomain = config.repo.secrets.common.services.domains.syncthing2;
in
{
imports = [
@@ -2679,11 +3164,12 @@ in
system.stateVersion = "23.11";
+ globals.services."syncthing-${config.networking.hostName}".domain = serviceDomain;
services = {
nginx = {
virtualHosts = {
- "sync.swarsel.win" = {
+ ${serviceDomain} = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
@@ -2739,7 +3225,7 @@ in
type = "receiveonly";
versioning = {
type = "simple";
- params.keep = "5";
+ params.keep = "5";
};
devices = [ "winters" "magicant" "${workHostName}" ];
id = "yjvni-9eaa7";
@@ -2860,10 +3346,13 @@ in
3.1.3.2.1. Main Configuration
-{ lib, config, primaryUser, ... }:
+{ lib, config, globals, ... }:
let
+ primaryUser = globals.user.name;
inherit (config.repo.secrets.common) workHostName;
inherit (config.repo.secrets.local.syncthing) dev1 dev2 dev3 loc1;
+ serviceDomain = config.repo.secrets.common.services.domains.syncthing3;
+
sharedOptions = {
isBtrfs = true;
isLinux = true;
@@ -2902,7 +3391,7 @@ in
};
topology.self.interfaces.wg = {
- addresses = ["192.168.3.4"];
+ addresses = [ "192.168.3.4" ];
renderer.hidePhysicalConnections = true;
virtual = true;
type = "wireguard";
@@ -2945,10 +3434,12 @@ in
system.stateVersion = "23.11";
+ globals.services."syncthing-${config.networking.hostName}".domain = serviceDomain;
+
services = {
nginx = {
virtualHosts = {
- "syncthing.swarsel.win" = {
+ ${serviceDomain} = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
@@ -3103,7 +3594,7 @@ in
boot = {
initrd = {
availableKernelModules = [ "xhci_pci" "virtio_pci" "virtio_scsi" "usbhid" ];
- kernelModules = [ ];
+ kernelModules = [ ];
};
kernelModules = [ ];
extraModulePackages = [ ];
@@ -3266,7 +3757,7 @@ This is a slim setup for developing base configuration. I do not track the hardw
3.1.4.1.1. Main Configuration
-{ self, inputs, pkgs, lib, primaryUser, ... }:
+{ self, inputs, pkgs, lib, ... }:
let
modulesPath = "${self}/modules";
sharedOptions = {
@@ -3289,7 +3780,7 @@ in
inputs.home-manager.nixosModules.home-manager
{
- home-manager.users."${primaryUser}".imports = [
+ home-manager.users."setup".imports = [
inputs.sops-nix.homeManagerModules.sops
"${modulesPath}/home/common/sharedsetup.nix"
"${self}/profiles/home"
@@ -3326,7 +3817,7 @@ in
swarselsystems = lib.recursiveUpdate
{
info = "~SwarselSystems~ remote install helper";
- wallpaper = self + /wallpaper/lenovowp.png;
+ wallpaper = self + /files/wallpaper/lenovowp.png;
isImpermanence = true;
isCrypted = false;
isSecureBoot = false;
@@ -3338,7 +3829,7 @@ in
}
sharedOptions;
- home-manager.users."${primaryUser}" = {
+ home-manager.users."setup" = {
home.stateVersion = lib.mkForce "23.05";
swarselsystems = lib.recursiveUpdate
{
@@ -3500,135 +3991,89 @@ in
This is a live environment ISO that I use to bootstrap new systems. It only loads a minimal configuration and no graphical interface. After booting this image on a host, find out its IP and bootstrap the system using the bootstrap utility.
-
-For added convenience, the live environment displays a helpful text on login, we define it here (will be put into /etc/issue):
-
-[32m~SwarselSystems~[0m
- IP of primary interface: [31m\4[0m
- The Password for all users & root is '[31msetup[0m'.
- Install the system remotely by running '[33mbootstrap -n <CONFIGURATION_NAME> -d <IP_FROM_ABOVE> [0m' on a machine with deployed secrets.
- Alternatively, run '[33mswarsel-install -n <CONFIGURATION_NAME>[0m' for a local install. For your convenience, an example call is in the bash history (press up on the keyboard to access).
-
-
-
-
-
-Also, an initial bash history is provided to allow for a very quick local deployment:
-
-
-
-swarsel-install -n chaostheatre
-
-
-
-
-
-{ self, pkgs, inputs, config, lib, modulesPath, primaryUser ? "swarsel", ... }:
-let
- pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh";
-in
+{ pkgs, lib, ... }:
{
- imports = [
- "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
- "${modulesPath}/installer/cd-dvd/channel.nix"
-
- "${self}/modules/iso/minimal.nix"
- "${self}/modules/nixos/common/sharedsetup.nix"
- "${self}/modules/nixos/common/topology.nix"
- "${self}/modules/home/common/sharedsetup.nix"
-
- "${self}/modules/nixos/common/globals.nix"
-
-
- inputs.home-manager.nixosModules.home-manager
- {
- home-manager.users."${primaryUser}".imports = [
- "${self}/modules/home/common/settings.nix"
- "${self}/modules/home/common/sharedsetup.nix"
- ];
- }
- ];
-
- options.node = {
- name = lib.mkOption {
- description = "Node Name.";
- type = lib.types.str;
- };
- secretsDir = lib.mkOption {
- description = "Path to the secrets directory for this node.";
- type = lib.types.path;
- default = ./.;
- };
- };
config = {
- node.name = lib.mkForce "drugstore";
- swarselsystems = {
- info = "~SwarselSystems~ installer ISO";
- };
- home-manager.users."${primaryUser}" = {
- home = {
- stateVersion = "23.05";
- file = {
- ".bash_history" = {
- source = self + /programs/bash/.bash_history;
- };
- };
- };
- swarselsystems = {
- modules.general = lib.mkForce true;
- };
- };
home-manager.users.root.home = {
stateVersion = "23.05";
file = {
".bash_history" = {
- source = self + /programs/bash/.bash_history;
+ text = ''
+ swarsel-install -n chaostheatre
+ '';
};
};
};
- # environment.etc."issue".text = "\x1B[32m~SwarselSystems~\x1B[0m\nIP of primary interface: \x1B[31m\\4\x1B[0m\nThe Password for all users & root is '\x1B[31msetup\x1B[0m'.\nInstall the system remotely by running '\x1B[33mbootstrap -n <HOSTNAME> -d <IP_FROM_ABOVE> [--impermanence] [--encryption]\x1B[0m' on a machine with deployed secrets.\nAlternatively, run '\x1B[33mswarsel-install -d <DISK> -f <flake>\x1B[0m' for a local install.\n";
- environment.etc."issue".source = "${self}/programs/etc/issue";
- networking.dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload";
-
- isoImage = {
- makeEfiBootable = true;
- makeUsbBootable = true;
- squashfsCompression = "zstd -Xcompression-level 3";
- };
-
- nixpkgs = {
- hostPlatform = lib.mkDefault "x86_64-linux";
- config.allowUnfree = true;
- };
-
- services.getty.autologinUser = lib.mkForce primaryUser;
-
- users = {
- allowNoPasswordLogin = true;
- groups.swarsel = { };
- users = {
- swarsel = {
- name = primaryUser;
- group = primaryUser;
- isNormalUser = true;
- password = "setup"; # this is overwritten after install
- openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
- extraGroups = [ "wheel" ];
- };
- root = {
- # password = lib.mkForce config.users.users.swarsel.password; # this is overwritten after install
- openssh.authorizedKeys.keys = config.users.users."${primaryUser}".openssh.authorizedKeys.keys;
- };
- };
+ nix.settings = {
+ experimental-features = [ "nix-command" "flakes" ];
};
boot = {
- loader.systemd-boot.enable = lib.mkForce true;
- loader.efi.canTouchEfiVariables = true;
+ supportedFilesystems = lib.mkForce [ "brtfs" "vfat" ];
+ loader.systemd-boot = {
+ enable = true;
+ };
+ };
+
+ services = {
+ qemuGuest.enable = true;
+ openssh = {
+ enable = true;
+ settings.PermitRootLogin = "yes";
+ authorizedKeysFiles = lib.mkForce [
+ "/etc/ssh/authorized_keys.d/%u"
+ ];
+ };
+ };
+
+ environment.systemPackages = with pkgs; [
+ curl
+ git
+ gnupg
+ rsync
+ ssh-to-age
+ sops
+ vim
+ just
+ sbctl
+ ];
+
+ programs = {
+ git.enable = true;
+ };
+
+ fileSystems."/boot".options = [ "umask=0077" ];
+
+ environment.etc."issue".text = ''
+ [32m~SwarselSystems~[0m
+ IP of primary interface: [31m\4[0m
+ The Password for all users & root is '[31msetup[0m'.
+ Install the system remotely by running '[33mbootstrap -n <CONFIGURATION_NAME> -d <IP_FROM_ABOVE> [0m' on a machine with deployed secrets.
+ Alternatively, run '[33mswarsel-install -n <CONFIGURATION_NAME>[0m' for a local install. For your convenience, an example call is in the bash history (press up on the keyboard to access).
+ '';
+
+ networking = {
+ hostName = "drugstore";
+ wireless.enable = false;
+ dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload";
+ networkmanager.enable = true;
+ };
+
+ services.getty.autologinUser = lib.mkForce "root";
+
+ users = {
+ allowNoPasswordLogin = true;
+ users = {
+ root = {
+ password = "setup"; # this is overwritten after install
+ initialHashedPassword = lib.mkForce null;
+ openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDd0XXoLfRE0AyasxscEBwMqOnLWPqwz+etGqzVNeSw/RcgnxOi903mlVjCH+jzWMSe2GVSgzgM20j/r9sfE2P1z+wq/RODFS04JM0ltUoFkkm/IDZXQ2piOk7AoVi5ajdx4EiBnXY87jvxh5cCgQltkj3ouPF7FVN/MaN21IgWYB8NgkaVGft//OplodlDQNot17c0sFMibY0HcquwmHhqKOtKM1gT98+jZl0rd1rCqXFOvkesW6FPC4nzirPai+Hizp5gncrkJOZmLLqrjVx6PfpQzqzIhoUn1YS5CpyfXnKZUgx2Oi8SENmWOZ9DxYvDklgEttob37E2bIXbUhOw/u4I3olGFgCsKL6jg0N+d5teEaCZFnzlOp0UMWiUo7lVqq7Bwl3rNka2pxEdZ9v/1+m9cJiP7h6pnKmccVGku57iGIDnsnoTrmo1qbAje+EsmPYbc+qMnTDvOdSHTOXnjsyTd+ADklvMHCUAuf6ku4ktQEhlZxU3PvYvKHa1cTCEXxLWjytIgHgTgab9M5IH29Q55LSRRQBzUdkwjOG6KhsqG+xEE6038EbXr0MGKTm01AFmeVZWewmkSLu2UdoOMiw8mTSQhQFfp2QruYHnh7oJCo7ttKT1sLoRX+TfgQm1ryn/orhReg2GFfmbiLGxaJGVNvjqCxqrIFQXx4ZDHw== cardno:22_412_399" ];
+ };
+ };
};
programs.bash.shellAliases = {
@@ -3637,10 +4082,10 @@ in
system.activationScripts.cache = {
text = ''
- mkdir -p -m=0777 /home/${primaryUser}/.local/state/nix/profiles
- mkdir -p -m=0777 /home/${primaryUser}/.local/state/home-manager/gcroots
- mkdir -p -m=0777 /home/${primaryUser}/.local/share/nix/
- printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /home/${primaryUser}/.local/share/nix/trusted-settings.json > /dev/null
+ mkdir -p -m=0777 /home/setup/.local/state/nix/profiles
+ mkdir -p -m=0777 /home/setup/.local/state/home-manager/gcroots
+ mkdir -p -m=0777 /home/setup/.local/share/nix/
+ printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /home/setup/.local/share/nix/trusted-settings.json > /dev/null
mkdir -p /root/.local/share/nix/
printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /root/.local/share/nix/trusted-settings.json > /dev/null
'';
@@ -3657,10 +4102,6 @@ in
system.stateVersion = lib.mkForce "23.05";
- networking = {
- hostName = "drugstore";
- wireless.enable = false;
- };
};
}
@@ -3677,15 +4118,14 @@ This is the "reference implementation" of a setup that runs without NixOS, only
-{ self, outputs, config, ... }:
+{ self, inputs, outputs, ... }:
{
imports = [
inputs.stylix.homeManagerModules.stylix
inputs.sops-nix.homeManagerModules.sops
inputs.nix-index-database.hmModules.nix-index
- ./modules/home/common
- "${self}/modules/home/common/sharedsetup.nix"
+ "${self}/modules/home"
];
nixpkgs = {
@@ -3703,7 +4143,7 @@ This is the "reference implementation" of a setup that runs without NixOS, only
};
programs.zsh.initContent = "
- export GPG_TTY=\"$(tty)\"
+ export GPG_TTY=\"$(tty)\"
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent
";
@@ -3711,7 +4151,7 @@ This is the "reference implementation" of a setup that runs without NixOS, only
swarselsystems = {
isLaptop = true;
isNixos = false;
- wallpaper = self + /wallpaper/surfacewp.png;
+ wallpaper = self + /files/wallpaper/surfacewp.png;
};
}
@@ -3736,9 +4176,11 @@ I also set the WLR_RENDERER_ALLOW_SOFTWARE=1 to allow this configur
3.1.4.4.1. Main configuration
-{ self, inputs, config, pkgs, lib, primaryUser, ... }:
+{ self, inputs, config, pkgs, lib, ... }:
let
+ mainUser = "demo";
sharedOptions = {
+ inherit mainUser;
isBtrfs = false;
isLinux = true;
isPublic = true;
@@ -3747,65 +4189,65 @@ let
};
};
in
-{
+ {
- imports = [
- ./hardware-configuration.nix
- ./disk-config.nix
- {
- _module.args.diskDevice = config.swarselsystems.rootDisk;
- }
- "${self}/hosts/nixos/chaostheatre/options.nix"
- inputs.home-manager.nixosModules.home-manager
- {
- home-manager.users."${primaryUser}".imports = [
- "${self}/modules/home/common/settings.nix"
- "${self}/hosts/nixos/chaostheatre/options-home.nix"
- "${self}/modules/home/common/sharedsetup.nix"
- ];
- }
- ];
+ imports = [
+ ./hardware-configuration.nix
+ ./disk-config.nix
+ {
+ _module.args.diskDevice = config.swarselsystems.rootDisk;
+ }
+ "${self}/hosts/nixos/chaostheatre/options.nix"
+ inputs.home-manager.nixosModules.home-manager
+ {
+ home-manager.users."${mainUser}".imports = [
+ "${self}/modules/home/common/settings.nix"
+ "${self}/hosts/nixos/chaostheatre/options-home.nix"
+ "${self}/modules/home/common/sharedsetup.nix"
+ ];
+ }
+ ];
- environment.variables = {
- WLR_RENDERER_ALLOW_SOFTWARE = 1;
- };
+ environment.variables = {
+ WLR_RENDERER_ALLOW_SOFTWARE = 1;
+ };
- services.qemuGuest.enable = true;
+ services.qemuGuest.enable = true;
- boot = {
- loader.systemd-boot.enable = lib.mkForce true;
- loader.efi.canTouchEfiVariables = true;
- kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
- };
+ boot = {
+ loader.systemd-boot.enable = lib.mkForce true;
+ loader.efi.canTouchEfiVariables = true;
+ kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
+ };
- networking = {
- hostName = "chaostheatre";
- firewall.enable = true;
- };
+ networking = {
+ hostName = "chaostheatre";
+ firewall.enable = true;
+ };
- swarselsystems = lib.recursiveUpdate
- {
- info = "~SwarselSystems~ demo host";
- wallpaper = self + /wallpaper/lenovowp.png;
- initialSetup = true;
- isImpermanence = true;
- isCrypted = true;
- isSecureBoot = false;
- isSwap = true;
- swapSize = "4G";
- rootDisk = "/dev/vda";
- }
- sharedOptions;
-
- home-manager.users."${primaryUser}" = {
- home.stateVersion = lib.mkForce "23.05";
swarselsystems = lib.recursiveUpdate
{
- isNixos = true;
+ info = "~SwarselSystems~ demo host";
+ wallpaper = self + /files/wallpaper/lenovowp.png;
+ initialSetup = true;
+ isImpermanence = true;
+ isCrypted = true;
+ isSecureBoot = false;
+ isSwap = true;
+ swapSize = "4G";
+ rootDisk = "/dev/vda";
}
sharedOptions;
- };
-}
+
+ home-manager.users.${mainUser} = {
+ home.stateVersion = lib.mkForce "23.05";
+ swarselsystems = lib.recursiveUpdate
+ {
+ isNixos = true;
+ }
+ sharedOptions;
+ };
+ }
@@ -3818,10 +4260,10 @@ in
# NOTE: ... is needed because dikso passes diskoFile
{ lib
-, pkgs
-, config
-, diskDevice ? config.swarselsystem.rootDisk
-, ...
+ , pkgs
+ , config
+ , diskDevice ? config.swarselsystem.rootDisk
+ , ...
}:
let
type = "btrfs";
@@ -3873,61 +4315,62 @@ let
};
};
in
-{
- disko.devices = {
- disk = {
- disk0 = {
- type = "disk";
- device = diskDevice;
- content = {
- type = "gpt";
- partitions = {
- ESP = {
- priority = 1;
- name = "ESP";
- size = "512M";
- type = "EF00";
- content = {
- type = "filesystem";
- format = "vfat";
- mountpoint = "/boot";
- mountOptions = [ "defaults" ];
- };
- };
- root = lib.mkIf (!config.swarselsystems.isCrypted) {
- size = "100%";
- content = {
- inherit type subvolumes extraArgs;
- postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
- MNTPOINT=$(mktemp -d)
- mount "/dev/disk/by-label/nixos" "$MNTPOINT" -o subvolid=5
- trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
- btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
- '';
- };
- };
- luks = lib.mkIf config.swarselsystems.isCrypted {
- size = "100%";
- content = {
- type = "luks";
- name = "cryptroot";
- passwordFile = "/tmp/disko-password"; # this is populated by bootstrap.sh
- settings = {
- allowDiscards = true;
- # https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
- crypttabExtraOpts = [
- "fido2-device=auto"
- "token-timeout=10"
- ];
+ {
+ disko.devices = {
+ disk = {
+ disk0 = {
+ type = "disk";
+ device = diskDevice;
+ content = {
+ type = "gpt";
+ partitions = {
+ ESP = {
+ priority = 1;
+ name = "ESP";
+ size = "512M";
+ type = "EF00";
+ content = {
+ type = "filesystem";
+ format = "vfat";
+ mountpoint = "/boot";
+ mountOptions = [ "defaults" ];
};
+ };
+ root = lib.mkIf (!config.swarselsystems.isCrypted) {
+ size = "100%";
content = {
inherit type subvolumes extraArgs;
postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
MNTPOINT=$(mktemp -d)
+ mount "/dev/disk/by-label/nixos" "$MNTPOINT" -o subvolid=5
+ trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
+ btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
+ '';
+ };
+ };
+ luks = lib.mkIf config.swarselsystems.isCrypted {
+ size = "100%";
+ content = {
+ type = "luks";
+ name = "cryptroot";
+ passwordFile = "/tmp/disko-password"; # this is populated by bootstrap.sh
+ settings = {
+ allowDiscards = true;
+ # https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
+ crypttabExtraOpts = [
+ "fido2-device=auto"
+ "token-timeout=10"
+ ];
+ };
+ content = {
+ inherit type subvolumes extraArgs;
+ postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
+ MNTPOINT=$(mktemp -d)
mount "/dev/mapper/cryptroot" "$MNTPOINT" -o subvolid=5
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
- '';
+ '';
+ };
};
};
};
@@ -3935,15 +4378,14 @@ in
};
};
};
- };
- fileSystems."/persist".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
- fileSystems."/home".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
+ fileSystems."/persist".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
+ fileSystems."/home".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
- environment.systemPackages = [
- pkgs.yubikey-manager
- ];
-}
+ environment.systemPackages = [
+ pkgs.yubikey-manager
+ ];
+ }
@@ -3973,3228 +4415,34 @@ in
-
-3.2. Additions and modifications
-
-
-In this section I define packages that I manually want to nixpkgs. This can be useful for packages that are currently awaiting a PR or public packages that I do not want to maintain.
-
-
-
-As such, I also define three additional overlays:
-
-
-
-additions
-These are for the aforementioned added packages
-modification
-These are for packages that are on nixpkgs, but do not fit my usecase, meaning I need to perform modifications on them.
-nixpkgs-stable
-This is simply a mirror of the most recent stable branch of nixpkgs. Useful for packages that are broken on nixpkgs, but do not need to be on bleeding edge anyways.
-
-
-
-Also, this is where I define all of my own modules. These are mostly used for setting some host-specifics directly than opposed to through multiple options.
-
-
-
-Lastly, I add some of my own library functions to be used alongside the functions provided by nixpkgs and home-manager.
-
-
-
-3.2.1. Packages
-
-
-This is the central station for self-defined packages. These are all referenced in default.nix. Wherever possible, I am keeping the shell version of these scripts in this file as well and then read it using builtin.readFile in the NixOS configurations. This lets me keep full control in this one file but also keep the separate files uncluttered.
-
-
-
-Note: The structure of generating the packages was changed in commit 2cf03a3 refactor: package and module generation. That commit can be checked out in order to see a simpler version of achieving the same thing.
-
-
-
-{ lib, pkgs, ... }:
-let
- packageNames = lib.swarselsystems.readNix "pkgs";
-in
-lib.swarselsystems.mkPackages packageNames pkgs
-
-
-
-
-
-
-3.2.1.1. pass-fuzzel
-
-
-This app allows me, in conjunction with my Yubikey, to quickly enter passwords when the need arises. Normal and TOTP passwords are supported, and they can either be printed directly or copied to the clipboard.
-
-
-
-# Adapted from https://code.kulupu.party/thesuess/home-manager/src/branch/main/modules/river.nix
-shopt -s nullglob globstar
-
-otp=0
-typeit=0
-while :; do
- case ${1:-} in
- -t | --type)
- typeit=1
- ;;
- -o | --otp)
- otp=1
- ;;
- *) break ;;
- esac
- shift
-done
-
-export PASSWORD_STORE_DIR=~/.local/share/password-store
-prefix=${PASSWORD_STORE_DIR-~/.local/share/password-store}
-if [[ $otp -eq 0 ]]; then
- password_files=("$prefix"/**/*.gpg)
-else
- password_files=("$prefix"/otp/**/*.gpg)
-fi
-password_files=("${password_files[@]#"$prefix"/}")
-password_files=("${password_files[@]%.gpg}")
-
-password=$(printf '%s\n' "${password_files[@]}" | fuzzel --dmenu "$@")
-
-[[ -n $password ]] || exit
-if [[ $otp -eq 0 ]]; then
- if [[ $typeit -eq 0 ]]; then
- pass show -c "$password" &> /tmp/pass-fuzzel
- else
- pass show "$password" | {
- IFS= read -r pass
- printf %s "$pass"
- } | wtype -
- fi
-else
- if [[ $typeit -eq 0 ]]; then
- pass otp -c "$password" &> /tmp/pass-fuzzel
- else
- pass otp "$password" | {
- IFS= read -r pass
- printf %s "$pass"
- } | wtype -
- fi
-fi
-notify-send -u critical -a pass -t 1000 "Copied/Typed Password"
-
-
-
-
-{ self, name, writeShellApplication, libnotify, pass, fuzzel, wtype }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ libnotify (pass.withExtensions (exts: [ exts.pass-otp ])) fuzzel wtype ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-
-3.2.1.2. cura5
-
-
-The version of cura used to be quite outdated in nixpkgs. I am fetching a newer AppImage here and use that instead.
-
-
-
-
-# taken from https://github.com/NixOS/nixpkgs/issues/186570#issuecomment-1627797219
-{ appimageTools, fetchurl, writeScriptBin, pkgs, ... }:
-
-
-let
- cura5 = appimageTools.wrapType2 rec {
- pname = "cura5";
- version = "5.9.0";
- src = fetchurl {
- url = "https://github.com/Ultimaker/Cura/releases/download/${version}/UltiMaker-Cura-${version}-linux-X64.AppImage";
- hash = "sha256-STtVeM4Zs+PVSRO3cI0LxnjRDhOxSlttZF+2RIXnAp4=";
- };
- extraPkgs = pkgs: with pkgs; [ ];
- };
-in
-writeScriptBin "cura" ''
- #! ${pkgs.bash}/bin/bash
- # AppImage version of Cura loses current working directory and treats all paths relative to $HOME.
- # So we convert each of the files passed as argument to an absolute path.
- # This fixes use cases like `cd /path/to/my/files; cura mymodel.stl anothermodel.stl`.
- args=()
- for a in "$@"; do
- if [ -e "$a" ]; then
- a="$(realpath "$a")"
- fi
- args+=("$a")
- done
- exec "${cura5}/bin/cura5" "''${args[@]}"
-''
-
-
-
-
-
-
-3.2.1.3. hm-specialisation
-
-
-This script allows for quick git home-manager specialisation switching.
-
-
-
-
-{ name, writeShellApplication, fzf, findutils, home-manager, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ fzf findutils home-manager ];
- text = ''
- genpath=$(home-manager generations | head -1 | awk '{print $7}')
- dirs=$(find "$genpath/specialisation" -type l 2>/dev/null; [ -d "$genpath" ] && echo "$genpath")
- "$(echo "$dirs" | fzf --prompt="Choose home-manager specialisation to activate")"/activate
- '';
-}
-
-
-
-
-
-
-
-3.2.1.4. cdw
-
-
-This script allows for quick git worktree switching.
-
-
-
-
-{ name, writeShellApplication, fzf, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ fzf ];
- text = ''
- cd "$(git worktree list | fzf | awk '{print $1}')"
- '';
-}
-
-
-
-
-
-
-
-3.2.1.5. cdb
-
-
-This script allows for quick git branch switching.
-
-
-
-{ name, writeShellApplication, fzf, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ fzf ];
- text = ''
- git checkout "$(git branch --list | grep -v "^\*" | fzf | awk '{print $1}')"
- '';
-}
-
-
-
-
-
-
-3.2.1.6. bak
-
-
-This script lets me quickly backup files by appending .bak to the filename.
-
-
-
-
-{ name, writeShellApplication, ... }:
-
-writeShellApplication {
- inherit name;
- text = ''
- cp -r "$1"{,.bak}
- '';
-}
-
-
-
-
-
-
-
-3.2.1.7. timer
-
-
-This app starts a configuratble timer and uses TTS to say something once the timer runs out.
-
-
-
-
-{ name, writeShellApplication, speechd, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ speechd ];
- text = ''
- sleep "$1"; while true; do spd-say "$2"; sleep 0.5; done;
- '';
-}
-
-
-
-
-
-
-3.2.1.8. 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.
-
-
-
-wait=0
-while :; do
- case ${1:-} in
- -w | --wait)
- wait=1
- ;;
- *) break ;;
- esac
- shift
-done
-
-STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep kittyterm || true)
-if [ "$STR" == "" ]; then
- swaymsg '[title="kittyterm"]' scratchpad show
- emacsclient -c -a "" "$@"
- swaymsg '[title="kittyterm"]' scratchpad show
-else
- if [[ $wait -eq 0 ]]; then
- emacsclient -n -c -a "" "$@"
- else
- emacsclient -c -a "" "$@"
- fi
-fi
-
-
-
-
-{ self, name, writeShellApplication, emacs30-pgtk, sway, jq }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ emacs30-pgtk sway jq ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-
-3.2.1.9. 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.
-
-
-
-
-# Adapted from https://github.com/bennofs/nix-index/blob/master/command-not-found.sh
-command_not_found_handle() {
- if [ -n "${MC_SID-}" ] || ! [ -t 1 ]; then
- >&2 echo "$1: command not found"
- return 127
- fi
-
- echo -n "searching nix-index..."
- ATTRS=$(@nix-locate@ --minimal --no-group --type x --type s --top-level --whole-name --at-root "/bin/$1")
-
- case $(echo -n "$ATTRS" | grep -c "^") in
- 0)
- >&2 echo -ne "$(@tput@ el1)\r"
- >&2 echo "$1: command not found"
- ;;
- *)
- >&2 echo -ne "$(@tput@ el1)\r"
- >&2 echo "The program ‘$(@tput@ setaf 4)$1$(@tput@ sgr0)’ is currently not installed."
- >&2 echo "It is provided by the following derivation(s):"
- while read -r ATTR; do
- ATTR=${ATTR%.out}
- >&2 echo " $(@tput@ setaf 12)nixpkgs#$(@tput@ setaf 4)$ATTR$(@tput@ sgr0)"
- done <<< "$ATTRS"
- ;;
- esac
-
- return 127
-}
-
-command_not_found_handler() {
- command_not_found_handle "$@"
- return $?
-}
-
-
-
-
-
-3.2.1.10. 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.
-
-
-
-kitty=0
-element=0
-vesktop=0
-spotifyplayer=0
-while :; do
- case ${1:-} in
- -k | --kitty)
- kitty=1
- ;;
- -e | --element)
- element=1
- ;;
- -d | --vesktop)
- vesktop=1
- ;;
- -s | --spotifyplayer)
- spotifyplayer=1
- ;;
- *) break ;;
- esac
- shift
-done
-
-if [[ $kitty -eq 1 ]]; then
- STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep kittyterm || true)
- CHECK=$(swaymsg -t get_tree | grep kittyterm || true)
- if [ "$CHECK" == "" ]; then
- exec kitty -T kittyterm -o confirm_os_window_close=0 zellij attach --create kittyterm &
- sleep 1
- fi
- if [ "$STR" == "" ]; then
- exec swaymsg '[title="kittyterm"]' scratchpad show
- else
- exec swaymsg '[title="kittyterm"]' scratchpad show
- fi
-elif [[ $element -eq 1 ]]; then
- STR=$(swaymsg -t get_tree | grep Element || true)
- if [ "$STR" == "" ]; then
- exec element-desktop
- else
- exec swaymsg '[app_id=Element]' kill
- fi
-elif [[ $vesktop -eq 1 ]]; then
- STR=$(swaymsg -t get_tree | grep vesktop || true)
- if [ "$STR" == "" ]; then
- exec vesktop
- else
- exec swaymsg '[app_id=vesktop]' kill
- fi
-elif [[ $spotifyplayer -eq 1 ]]; then
- STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep spotifytui || true)
- CHECK=$(swaymsg -t get_tree | grep spotifytui || true)
- if [ "$CHECK" == "" ]; then
- exec kitty -T spotifytui -o confirm_os_window_close=0 spotify_player &
- sleep 1
- fi
- if [ "$STR" == "" ]; then
- exec swaymsg '[title="spotifytui"]' scratchpad show
- else
- exec swaymsg '[title="spotifytui"]' scratchpad show
- fi
-fi
-
-
-
-
-{ self, name, writeShellApplication, kitty, element-desktop, vesktop, spotify-player, jq }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ kitty element-desktop vesktop spotify-player jq ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-
-3.2.1.11. swarselzellij
-
-
-KITTIES=$(($(pgrep -P 1 kitty | wc -l) - 1))
-
-if ((KITTIES < 1)); then
- exec kitty -o confirm_os_window_close=0 zellij attach --create main
-else
- exec kitty -o confirm_os_window_close=0 zellij attach --create "temp $KITTIES"
-fi
-
-
-
-
-{ self, name, writeShellApplication, kitty }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ kitty ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-
-3.2.1.12. 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.
-
-
-
-CFG=$(git --git-dir="$HOME"/.dotfiles/.git --work-tree="$HOME"/.dotfiles/ status -s | wc -l)
-CSE=$(git --git-dir="$DOCUMENT_DIR_PRIV"/CSE_TUWIEN/.git --work-tree="$DOCUMENT_DIR_PRIV"/CSE_TUWIEN/ status -s | wc -l)
-PASS=$(($(git --git-dir="$HOME"/.local/share/password-store/.git --work-tree="$HOME"/.local/share/password-store/ status -s | wc -l) + $(git --git-dir="$HOME"/.local/share/password-store/.git --work-tree="$HOME"/.local/share/password-store/ diff origin/main..HEAD | wc -l)))
-
-if [[ $CFG != 0 ]]; then
- CFG_STR='CONFIG'
-else
- CFG_STR=''
-fi
-
-if [[ $CSE != 0 ]]; then
- CSE_STR=' CSE'
-else
- CSE_STR=''
-fi
-
-if [[ $PASS != 0 ]]; then
- PASS_STR=' PASS'
-else
- PASS_STR=''
-fi
-
-OUT="$CFG_STR""$CSE_STR""$PASS_STR"
-echo "$OUT"
-
-
-
-
-{ self, name, writeShellApplication, git }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ git ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-
-3.2.1.13. opacitytoggle
-
-
-This app quickly toggles between 5% and 0% transparency.
-
-
-
-if swaymsg opacity plus 0.01 -q; then
- swaymsg opacity 1
-else
- swaymsg opacity 0.95
-fi
-
-
-
-
-{ self, name, writeShellApplication, sway }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ sway ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-3.2.1.14. 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.
-
-
-
-set -euo pipefail
-
-OLD_TRANSID=$(sudo btrfs subvolume find-new /mnt/root-blank 9999999)
-OLD_TRANSID=${OLD_TRANSID#transid marker was }
-
-sudo btrfs subvolume find-new "/mnt/root" "$OLD_TRANSID" |
- sed '$d' |
- cut -f17- -d' ' |
- sort |
- uniq |
- while read -r path; do
- path="/$path"
- if [ -L "$path" ]; then
- : # The path is a symbolic link, so is probably handled by NixOS already
- elif [ -d "$path" ]; then
- : # The path is a directory, ignore
- else
- echo "$path"
- fi
- done
-
-
-
-
-{ self, name, writeShellApplication }:
-writeShellApplication {
- inherit name;
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-3.2.1.15. 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.
-
-
-
-
-{ name, writeShellApplication, jq, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ jq ];
- text = ''
- count=$(curl -u Swarsel:"$(cat "$XDG_RUNTIME_DIR/secrets/github_notif")" https://api.github.com/notifications | jq '. | length')
-
- if [[ "$count" != "0" ]]; then
- echo "{\"text\":\"$count\"}"
- fi
- '';
-}
-
-
-
-
-
-3.2.1.16. fullscreen
-
-
-This application moves the wl-mirror app to the T workspace and makes it fullscreen there.
-
-
-
-{ name, writeShellApplication, sway, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ sway ];
- text = ''
- swaymsg '[app_id=at.yrlf.wl_mirror] move to workspace 14:T'
- swaymsg '[app_id=at.yrlf.wl_mirror] fullscreen'
- '';
-}
-
-
-
-
-
-3.2.1.17. screenshare
-
-
-
-headless="false"
-while [[ $# -gt 0 ]]; do
- case "$1" in
- -h)
- headless="true"
- ;;
- *)
- echo "Invalid option detected."
- ;;
- esac
- shift
-done
-
-SHARESCREEN="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$(hostname)".config.home-manager.users."$(whoami)".swarselsystems.sharescreen)"
-
-if [[ $headless == "true" ]]; then
- wl-mirror "$SHARESCREEN"
-else
- wl-mirror "$SHARESCREEN" &
- sleep 0.1
- swaymsg '[app_id=at.yrlf.wl_mirror] move to workspace 14:T'
- swaymsg '[app_id=at.yrlf.wl_mirror] fullscreen'
-fi
-
-
-
-
-
-{ self, name, writeShellApplication, sway }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ sway ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-3.2.1.18. swarsel-bootstrap
-
-
-This program sets up a new NixOS host remotely. It also takes care of secret management on the new host.
-
-
-
-# highly inspired by https://github.com/EmergentMind/nix-config/blob/dev/scripts/bootstrap-nixos.sh
-set -eo pipefail
-
-target_hostname=""
-target_destination=""
-target_user="swarsel"
-ssh_port="22"
-persist_dir=""
-disk_encryption=0
-temp=$(mktemp -d)
-
-function help_and_exit() {
- echo
- echo "Remotely installs SwarselSystem on a target machine including secret deployment."
- echo
- echo "USAGE: $0 -n <target_hostname> -d <target_destination> [OPTIONS]"
- echo
- echo "ARGS:"
- echo " -n <target_hostname> specify target_hostname of the target host to deploy the nixos config on."
- echo " -d <target_destination> specify ip or url to the target host."
- echo " target during install process."
- echo
- echo "OPTIONS:"
- echo " -u <target_user> specify target_user with sudo access. nix-config will be cloned to their home."
- echo " Default='${target_user}'."
- echo " --port <ssh_port> specify the ssh port to use for remote access. Default=${ssh_port}."
- echo " --debug Enable debug mode."
- echo " -h | --help Print this help."
- exit 0
-}
-
-function cleanup() {
- rm -rf "$temp"
-}
-trap cleanup exit
-
-function red() {
- echo -e "\x1B[31m[!] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[31m[!] $($2) \x1B[0m"
- fi
-}
-function green() {
- echo -e "\x1B[32m[+] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[32m[+] $($2) \x1B[0m"
- fi
-}
-function yellow() {
- echo -e "\x1B[33m[*] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[33m[*] $($2) \x1B[0m"
- fi
-}
-
-function yes_or_no() {
- echo -en "\x1B[32m[+] $* [y/n] (default: y): \x1B[0m"
- while true; do
- read -rp "" yn
- yn=${yn:-y}
- case $yn in
- [Yy]*) return 0 ;;
- [Nn]*) return 1 ;;
- esac
- done
-}
-
-function update_sops_file() {
- key_name=$1
- key_type=$2
- key=$3
-
- if [ ! "$key_type" == "hosts" ] && [ ! "$key_type" == "users" ]; then
- red "Invalid key type passed to update_sops_file. Must be either 'hosts' or 'users'."
- exit 1
- fi
- cd "${git_root}"
-
- SOPS_FILE=".sops.yaml"
- sed -i "{
- # Remove any * and & entries for this host
- /[*&]$key_name/ d;
- # Inject a new age: entry
- # n matches the first line following age: and p prints it, then we transform it while reusing the spacing
- /age:/{n; p; s/\(.*- \*\).*/\1$key_name/};
- # Inject a new hosts or user: entry
- /&$key_type/{n; p; s/\(.*- &\).*/\1$key_name $key/}
- }" $SOPS_FILE
- green "Updating .sops.yaml"
- cd -
-}
-
-while [[ $# -gt 0 ]]; do
- case "$1" in
- -n)
- shift
- target_hostname=$1
- ;;
- -d)
- shift
- target_destination=$1
- ;;
- -u)
- shift
- target_user=$1
- ;;
- --port)
- shift
- ssh_port=$1
- ;;
- --debug)
- set -x
- ;;
- -h | --help) help_and_exit ;;
- *)
- echo "Invalid option detected."
- help_and_exit
- ;;
- esac
- shift
-done
-
-green "~SwarselSystems~ remote installer"
-green "Reading system information for $target_hostname ..."
-
-DISK="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.rootDisk)"
-green "Root Disk: $DISK"
-
-CRYPTED="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isCrypted)"
-if [[ $CRYPTED == "true" ]]; then
- green "Encryption: ✓"
- disk_encryption=1
-else
- red "Encryption: X"
- disk_encryption=0
-fi
-
-IMPERMANENCE="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isImpermanence)"
-if [[ $IMPERMANENCE == "true" ]]; then
- green "Impermanence: ✓"
- persist_dir="/persist"
-else
- red "Impermanence: X"
- persist_dir=""
-fi
-
-SWAP="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isSwap)"
-if [[ $SWAP == "true" ]]; then
- green "Swap: ✓"
-else
- red "Swap: X"
-fi
-
-SECUREBOOT="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isSecureBoot)"
-if [[ $SECUREBOOT == "true" ]]; then
- green "Secure Boot: ✓"
-else
- red "Secure Boot: X"
-fi
-
-ssh_cmd="ssh -oport=${ssh_port} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -t $target_user@$target_destination"
-# ssh_root_cmd=$(echo "$ssh_cmd" | sed "s|${target_user}@|root@|") # uses @ in the sed switch to avoid it triggering on the $ssh_key value
-ssh_root_cmd=${ssh_cmd/${target_user}@/root@}
-scp_cmd="scp -oport=${ssh_port} -o StrictHostKeyChecking=no"
-
-if [[ -z ${FLAKE} ]]; then
- FLAKE=/home/"$target_user"/.dotfiles
-fi
-if [ ! -d "$FLAKE" ]; then
- cd /home/"$target_user"
- yellow "Flake directory not found - cloning repository from GitHub"
- git clone git@github.com:Swarsel/.dotfiles.git || (yellow "Could not clone repository via SSH - defaulting to HTTPS" && git clone https://github.com/Swarsel/.dotfiles.git)
- FLAKE=/home/"$target_user"/.dotfiles
-fi
-
-cd "$FLAKE"
-git_root=$(git rev-parse --show-toplevel)
-# ------------------------
-green "Wiping known_hosts of $target_destination"
-sed -i "/$target_hostname/d; /$target_destination/d" ~/.ssh/known_hosts
-# ------------------------
-green "Preparing a new ssh_host_ed25519_key pair for $target_hostname."
-# Create the directory where sshd expects to find the host keys
-install -d -m755 "$temp/$persist_dir/etc/ssh"
-# Generate host ssh key pair without a passphrase
-ssh-keygen -t ed25519 -f "$temp/$persist_dir/etc/ssh/ssh_host_ed25519_key" -C root@"$target_hostname" -N ""
-# Set the correct permissions so sshd will accept the key
-chmod 600 "$temp/$persist_dir/etc/ssh/ssh_host_ed25519_key"
-echo "Adding ssh host fingerprint at $target_destination to ~/.ssh/known_hosts"
-# This will fail if we already know the host, but that's fine
-ssh-keyscan -p "$ssh_port" "$target_destination" >> ~/.ssh/known_hosts || true
-# ------------------------
-# when using luks, disko expects a passphrase on /tmp/disko-password, so we set it for now and will update the passphrase later
-# via the config
-if [ "$disk_encryption" -eq 1 ]; then
- while true; do
- green "Set disk encryption passphrase:"
- read -rs luks_passphrase
- green "Please confirm passphrase:"
- read -rs luks_passphrase_confirm
- if [[ $luks_passphrase == "$luks_passphrase_confirm" ]]; then
- $ssh_root_cmd "/bin/sh -c 'echo $luks_passphrase > /tmp/disko-password'"
- break
- else
- red "Passwords do not match"
- fi
- done
-fi
-# ------------------------
-green "Generating hardware-config.nix for $target_hostname and adding it to the nix-config."
-$ssh_root_cmd "nixos-generate-config --force --no-filesystems --root /mnt"
-
-green "Injecting initialSetup"
-$ssh_root_cmd "sed -i '/ boot.extraModulePackages /a \ swarselsystems.initialSetup = true;' /mnt/etc/nixos/hardware-configuration.nix"
-
-mkdir -p "$FLAKE"/hosts/nixos/"$target_hostname"
-$scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix "${git_root}"/hosts/nixos/"$target_hostname"/hardware-configuration.nix
-# ------------------------
-
-green "Deploying minimal NixOS installation on $target_destination"
-SHELL=/bin/sh nix run github:nix-community/nixos-anywhere -- --ssh-port "$ssh_port" --extra-files "$temp" --flake .#"$target_hostname" root@"$target_destination"
-
-echo "Updating ssh host fingerprint at $target_destination to ~/.ssh/known_hosts"
-ssh-keyscan -p "$ssh_port" "$target_destination" >> ~/.ssh/known_hosts || true
-# ------------------------
-
-while true; do
- read -rp "Press Enter to continue once the remote host has finished booting."
- if nc -z "$target_destination" "${ssh_port}" 2> /dev/null; then
- green "$target_destination is booted. Continuing..."
- break
- else
- yellow "$target_destination is not yet ready."
- fi
-done
-
-# ------------------------
-
-if [[ $SECUREBOOT == "true" ]]; then
- green "Setting up secure boot keys"
- $ssh_root_cmd "mkdir -p /var/lib/sbctl"
- read -ra scp_call <<< "${scp_cmd}"
- sudo "${scp_call[@]}" -r /var/lib/sbctl root@"$target_destination":/var/lib/
- $ssh_root_cmd "sbctl enroll-keys --ignore-immutable --microsoft || true"
-fi
-# ------------------------
-green "Disabling initialSetup"
-sed -i '/swarselsystems\.initialSetup = true;/d' "$git_root"/hosts/nixos/"$target_hostname"/hardware-configuration.nix
-
-if [ -n "$persist_dir" ]; then
- $ssh_root_cmd "cp /etc/machine-id $persist_dir/etc/machine-id || true"
- $ssh_root_cmd "cp -R /etc/ssh/ $persist_dir/etc/ssh/ || true"
-fi
-# ------------------------
-green "Generating an age key based on the new ssh_host_ed25519_key."
-target_key=$(
- ssh-keyscan -p "$ssh_port" -t ssh-ed25519 "$target_destination" 2>&1 |
- grep ssh-ed25519 |
- cut -f2- -d" " ||
- (
- red "Failed to get ssh key. Host down?"
- exit 1
- )
-)
-host_age_key=$(nix shell nixpkgs#ssh-to-age.out -c sh -c "echo $target_key | ssh-to-age")
-
-if grep -qv '^age1' <<< "$host_age_key"; then
- red "The result from generated age key does not match the expected format."
- yellow "Result: $host_age_key"
- yellow "Expected format: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- exit 1
-else
- echo "$host_age_key"
-fi
-
-green "Updating nix-secrets/.sops.yaml"
-update_sops_file "$target_hostname" "hosts" "$host_age_key"
-yellow ".sops.yaml has been updated. There may be superfluous entries, you might need to edit manually."
-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}"/secrets/*/secrets.yaml
-# --------------------------
-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
-$scp_cmd root@"$target_destination":/etc/ssh/ssh_host_ed25519_key root@"$target_destination":/home/"$target_user"/.ssh/ssh_host_ed25519_key
-$ssh_root_cmd "mkdir -p /home/$target_user/.ssh; chown $target_user:users /home/$target_user/.ssh/ssh_host_ed25519_key"
-# __________________________
-
-if yes_or_no "Add ssh host fingerprints for git upstream repositories? (This is needed for building the full config)"; then
- green "Adding ssh host fingerprints for git{lab,hub}"
- $ssh_cmd "mkdir -p /home/$target_user/.ssh/; ssh-keyscan -t ssh-ed25519 gitlab.com github.com swagit.swarsel.win >> /home/$target_user/.ssh/known_hosts"
- $ssh_root_cmd "mkdir -p /root/.ssh/; ssh-keyscan -t ssh-ed25519 gitlab.com github.com swagit.swarsel.win >> /root/.ssh/known_hosts"
-fi
-# --------------------------
-
-if yes_or_no "Do you want to copy your full nix-config and nix-secrets to $target_hostname?"; then
- green "Adding ssh host fingerprint at $target_destination to ~/.ssh/known_hosts"
- ssh-keyscan -p "$ssh_port" "$target_destination" >> ~/.ssh/known_hosts || true
- green "Copying full nix-config to $target_hostname"
- cd "${git_root}"
- just sync "$target_user" "$target_destination"
-
- if [ -n "$persist_dir" ]; then
- $ssh_root_cmd "cp -r /home/$target_user/.dotfiles $persist_dir/.dotfiles || true"
- $ssh_root_cmd "cp -r /home/$target_user/.ssh $persist_dir/.ssh || true"
- fi
-
- if yes_or_no "Do you want to rebuild immediately?"; then
- green "Rebuilding nix-config on $target_hostname"
- yellow "Reminder: The password is 'setup'"
- $ssh_root_cmd "mkdir -p /root/.local/share/nix/; printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' > /root/.local/share/nix/trusted-settings.json"
- $ssh_cmd -oForwardAgent=yes "cd .dotfiles && sudo nixos-rebuild --show-trace --flake .#$target_hostname switch"
- fi
-else
- echo
- green "NixOS was successfully installed!"
- echo "Post-install config build instructions:"
- echo "To copy nix-config from this machine to the $target_hostname, run the following command from ~/nix-config"
- echo "just sync $target_user $target_destination"
- echo "To rebuild, sign into $target_hostname and run the following command from ~/nix-config"
- echo "cd nix-config"
- # see above FIXME:(bootstrap)
- echo "sudo nixos-rebuild --show-trace --flake .#$target_hostname switch"
- # echo "just rebuild"
- echo
-fi
-
-if yes_or_no "You can now commit and push the nix-config, which includes the hardware-configuration.nix for $target_hostname?"; then
- cd "${git_root}"
- deadnix hosts/nixos/"$target_hostname"/hardware-configuration.nix -qe
- nixpkgs-fmt hosts/nixos/"$target_hostname"/hardware-configuration.nix
- (pre-commit run --all-files 2> /dev/null || true) &&
- git add "$git_root/hosts/nixos/$target_hostname/hardware-configuration.nix" &&
- git add "$git_root/.sops.yaml" &&
- git add "$git_root/secrets" &&
- (git commit -m "feat: deployed $target_hostname" || true) && git push
-fi
-
-
-
-
-
-{ self, name, writeShellApplication, openssh }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ openssh ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-3.2.1.19. swarsel-rebuild
-
-
-set -eo pipefail
-
-target_config="chaostheatre"
-target_user="swarsel"
-
-function help_and_exit() {
- echo
- echo "Builds SwarselSystem configuration."
- echo
- echo "USAGE: $0 [OPTIONS]"
- echo
- echo "ARGS:"
- echo " -n <target_config> specify nixos config to build."
- echo " Default: chaostheatre"
- echo " -u <target_user> specify user to deploy for."
- echo " Default: swarsel"
- echo " -h | --help Print this help."
- exit 0
-}
-
-function red() {
- echo -e "\x1B[31m[!] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[31m[!] $($2) \x1B[0m"
- fi
-}
-function green() {
- echo -e "\x1B[32m[+] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[32m[+] $($2) \x1B[0m"
- fi
-}
-function yellow() {
- echo -e "\x1B[33m[*] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[33m[*] $($2) \x1B[0m"
- fi
-}
-
-while [[ $# -gt 0 ]]; do
- case "$1" in
- -n)
- shift
- target_config=$1
- ;;
- -u)
- shift
- target_user=$1
- ;;
- -h | --help) help_and_exit ;;
- *)
- echo "Invalid option detected."
- help_and_exit
- ;;
- esac
- shift
-done
-
-cd /home/"$target_user"
-
-if [ ! -d /home/"$target_user"/.dotfiles ]; then
- green "Cloning repository from GitHub"
- git clone https://github.com/Swarsel/.dotfiles.git
-else
- red "A .dotfiles repository is in the way. Please (re-)move the repository and try again."
- exit 1
-fi
-
-local_keys=$(ssh-add -L || true)
-pub_key=$(cat /home/"$target_user"/.dotfiles/secrets/keys/ssh/yubikey.pub)
-read -ra pub_arr <<< "$pub_key"
-
-cd .dotfiles
-if [[ $local_keys != *"${pub_arr[1]}"* ]]; then
- yellow "The ssh key for this configuration is not available."
- green "Adjusting flake.nix so that the configuration is buildable"
- sed -i '/nix-secrets = {/,/^[[:space:]]*};/d' flake.nix
- sed -i '/vbc-nix = {/,/^[[:space:]]*};/d' flake.nix
- sed -i '/[[:space:]]*\/\/ (inputs.vbc-nix.overlays.default final prev)/d' overlays/default.nix
- rm modules/home/common/env.nix
- rm modules/home/common/gammastep.nix
- rm modules/home/common/git.nix
- rm modules/home/common/mail.nix
- rm modules/home/common/yubikey.nix
- rm modules/nixos/server/restic.nix
- rm modules/nixos/common/home-manager-extra.nix
- rm hosts/nixos/sync/default.nix
- rm -rf modules/nixos/server
- rm -rf modules/home/server
- nix flake update vbc-nix
- git add .
-else
- green "Valid SSH key found! Continuing with installation"
-fi
-sudo nixos-generate-config --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/
-git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
-
-green "Installing flake $target_config"
-sudo nixos-rebuild --show-trace --flake .#"$target_config" boot
-yellow "Please keep in mind that this is only a demo of the configuration. Things might break unexpectedly."
-
-
-
-
-
-
-{ self, name, writeShellApplication, git }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ git ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-3.2.1.20. swarsel-install
-
-
-Autoformatting always puts the EOF with indentation, which makes shfmt check fail. When editing this block, unindent them manually.
-
-
-
-set -eo pipefail
-
-target_config="chaostheatre"
-target_hostname="chaostheatre"
-target_user="swarsel"
-persist_dir=""
-target_disk="/dev/vda"
-disk_encryption=0
-
-function help_and_exit() {
- echo
- echo "Locally installs SwarselSystem on this machine."
- echo
- echo "USAGE: $0 -n <target_config> -d <target_disk> [OPTIONS]"
- echo
- echo "ARGS:"
- echo " -n <target_config> specify the nixos config to deploy."
- echo " Default: chaostheatre"
- echo " -d <target_disk> specify disk to install on."
- echo " Default: /dev/vda"
- echo " -u <target_user> specify user to deploy for."
- echo " Default: swarsel"
- echo " -h | --help Print this help."
- exit 0
-}
-
-function red() {
- echo -e "\x1B[31m[!] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[31m[!] $($2) \x1B[0m"
- fi
-}
-function green() {
- echo -e "\x1B[32m[+] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[32m[+] $($2) \x1B[0m"
- fi
-}
-function yellow() {
- echo -e "\x1B[33m[*] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[33m[*] $($2) \x1B[0m"
- fi
-}
-
-while [[ $# -gt 0 ]]; do
- case "$1" in
- -n)
- shift
- target_config=$1
- target_hostname=$1
- ;;
- -u)
- shift
- target_user=$1
- ;;
- -d)
- shift
- target_disk=$1
- ;;
- -h | --help) help_and_exit ;;
- *)
- echo "Invalid option detected."
- help_and_exit
- ;;
- esac
- shift
-done
-
-function cleanup() {
- sudo rm -rf .cache/nix
- sudo rm -rf /root/.cache/nix
-}
-trap cleanup exit
-
-green "~SwarselSystems~ local installer"
-
-cd /home/"$target_user"
-
-sudo rm -rf /root/.cache/nix
-sudo rm -rf .cache/nix
-sudo rm -rf .dotfiles
-
-green "Cloning repository from GitHub"
-git clone https://github.com/Swarsel/.dotfiles.git
-
-local_keys=$(ssh-add -L || true)
-pub_key=$(cat /home/"$target_user"/.dotfiles/secrets/keys/ssh/yubikey.pub)
-read -ra pub_arr <<< "$pub_key"
-
-cd .dotfiles
-if [[ $local_keys != *"${pub_arr[1]}"* ]]; then
- yellow "The ssh key for this configuration is not available."
- green "Adjusting flake.nix so that the configuration is buildable ..."
- sed -i '/nix-secrets = {/,/^[[:space:]]*};/d' flake.nix
- sed -i '/vbc-nix = {/,/^[[:space:]]*};/d' flake.nix
- sed -i '/[[:space:]]*\/\/ (inputs.vbc-nix.overlays.default final prev)/d' overlays/default.nix
- rm modules/home/common/env.nix
- rm modules/home/common/gammastep.nix
- rm modules/home/common/git.nix
- rm modules/home/common/mail.nix
- rm modules/home/common/yubikey.nix
- rm modules/nixos/server/restic.nix
- rm modules/nixos/common/home-manager-extra.nix
- rm hosts/nixos/sync/default.nix
- rm -rf modules/nixos/server
- rm -rf modules/home/server
- cat > hosts/nixos/chaostheatre/options.nix << EOF
- { self, lib, ... }:
- {
- options = {
- swarselsystems = {
- modules = {
- home-managerExtra = lib.mkEnableOption "dummy option for chaostheatre";
- };
- };
- };
- }
-EOF
- cat > hosts/nixos/chaostheatre/options-home.nix << EOF
- { self, lib, ... }:
- {
- options = {
- swarselsystems = {
- modules = {
- yubikey = lib.mkEnableOption "dummy option for chaostheatre";
- env = lib.mkEnableOption "dummy option for chaostheatre";
- git = lib.mkEnableOption "dummy option for chaostheatre";
- mail = lib.mkEnableOption "dummy option for chaostheatre";
- gammastep = lib.mkEnableOption "dummy option for chaostheatre";
- };
- };
- };
- }
-EOF
- nix flake update vbc-nix
- git add .
-else
- green "Valid SSH key found! Continuing with installation"
-fi
-
-green "Reading system information for $target_config ..."
-DISK="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.rootDisk)"
-green "Root Disk in config: $DISK - Root Disk passed in cli: $target_disk"
-
-CRYPTED="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isCrypted)"
-if [[ $CRYPTED == "true" ]]; then
- green "Encryption: ✓"
- disk_encryption=1
-else
- red "Encryption: X"
- disk_encryption=0
-fi
-
-IMPERMANENCE="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isImpermanence)"
-if [[ $IMPERMANENCE == "true" ]]; then
- green "Impermanence: ✓"
- persist_dir="/persist"
-else
- red "Impermanence: X"
- persist_dir=""
-fi
-
-SWAP="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isSwap)"
-if [[ $SWAP == "true" ]]; then
- green "Swap: ✓"
-else
- red "Swap: X"
-fi
-
-SECUREBOOT="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isSecureBoot)"
-if [[ $SECUREBOOT == "true" ]]; then
- green "Secure Boot: ✓"
-else
- red "Secure Boot: X"
-fi
-
-if [ "$disk_encryption" -eq 1 ]; then
- while true; do
- green "Set disk encryption passphrase:"
- read -rs luks_passphrase
- green "Please confirm passphrase:"
- read -rs luks_passphrase_confirm
- if [[ $luks_passphrase == "$luks_passphrase_confirm" ]]; then
- echo "$luks_passphrase" > /tmp/disko-password
- break
- else
- red "Passwords do not match"
- fi
- done
-fi
-
-green "Setting up disk ..."
-if [[ $target_config == "chaostheatre" ]]; then
- sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/v1.10.0 -- --mode destroy,format,mount --flake .#"$target_config" --yes-wipe-all-disks --arg diskDevice "$target_disk"
-else
- sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount --flake .#"$target_config" --yes-wipe-all-disks
-fi
-sudo mkdir -p /mnt/"$persist_dir"/home/"$target_user"/
-sudo cp -r /home/"$target_user"/.dotfiles /mnt/"$persist_dir"/home/"$target_user"/
-sudo chown -R 1000:100 /mnt/"$persist_dir"/home/"$target_user"
-
-green "Generating hardware configuration ..."
-sudo nixos-generate-config --root /mnt --no-filesystems --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/
-
-green "Injecting initialSetup ..."
-sudo sed -i '/ boot.extraModulePackages /a \ swarselsystems.initialSetup = true;' /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
-
-git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
-sudo mkdir -p /root/.local/share/nix/
-printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | sudo tee /root/.local/share/nix/trusted-settings.json > /dev/null
-green "Installing flake $target_config"
-sudo nixos-install --flake .#"$target_config"
-green "Installation finished! Reboot to see changes"
-
-
-
-
-
-
-{ self, name, writeShellApplication, git }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ git ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-3.2.1.21. swarsel-postinstall
-
-
-set -eo pipefail
-
-target_config="chaostheatre"
-target_user="swarsel"
-
-function help_and_exit() {
- echo
- echo "Locally installs SwarselSystem on this machine."
- echo
- echo "USAGE: $0 -d <disk> [OPTIONS]"
- echo
- echo "ARGS:"
- echo " -d <disk> specify disk to install on."
- echo " -n <target_config> specify the nixos config to deploy."
- echo " Default: chaostheatre"
- echo " Default: chaostheatre"
- echo " -u <target_user> specify user to deploy for."
- echo " Default: swarsel"
- echo " -h | --help Print this help."
- exit 0
-}
-
-function green() {
- echo -e "\x1B[32m[+] $1 \x1B[0m"
- if [ -n "${2-}" ]; then
- echo -e "\x1B[32m[+] $($2) \x1B[0m"
- fi
-}
-
-while [[ $# -gt 0 ]]; do
- case "$1" in
- -n)
- shift
- target_config=$1
- ;;
- -u)
- shift
- target_user=$1
- ;;
- -h | --help) help_and_exit ;;
- *)
- echo "Invalid option detected."
- help_and_exit
- ;;
- esac
- shift
-done
-
-function cleanup() {
- sudo rm -rf .cache/nix
- sudo rm -rf /root/.cache/nix
-}
-trap cleanup exit
-
-sudo rm -rf .cache/nix
-sudo rm -rf /root/.cache/nix
-
-green "~SwarselSystems~ remote post-installer"
-
-cd /home/"$target_user"/.dotfiles
-
-SECUREBOOT="$(nix eval ~/.dotfiles#nixosConfigurations."$target_config".config.swarselsystems.isSecureBoot)"
-
-if [[ $SECUREBOOT == "true" ]]; then
- green "Setting up secure boot keys"
- sudo mkdir -p /var/lib/sbctl
- sbctl create-keys || true
- sbctl enroll-keys --ignore-immutable --microsoft || true
-fi
-
-green "Disabling initialSetup"
-sed -i '/swarselsystems\.initialSetup = true;/d' /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
-sudo nixos-rebuild --flake .#"$target_config" switch
-green "Post-install finished!"
-
-
-
-
-
-
-{ self, name, writeShellApplication, git }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ git ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-3.2.1.22. t2ts
-
-
-{ name, writeShellApplication, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ ];
- text = ''
- date -d"$1" +%s
- '';
-}
-
-
-
-
-
-
-3.2.1.23. ts2t
-
-
-{ name, writeShellApplication, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ ];
- text = ''
- date -d @"$1" 2>/dev/null || date -r "$1"
- '';
-}
-
-
-
-
-
-
-3.2.1.24. vershell
-
-
-{ name, writeShellApplication, ... }:
-
-writeShellApplication {
- inherit name;
- runtimeInputs = [ ];
- text = ''
- nix shell github:nixos/nixpkgs/"$1"#"$2";
- '';
-}
-
-
-
-
-
-
-3.2.1.25. eontimer
-
-
-{ lib
-, python3
-, fetchFromGitHub
-, makeDesktopItem
-, writeShellScript
-, ...
-}:
-let
- wrapper = writeShellScript "eontimer-wrapper" ''
- export QT_QPA_PLATFORM=xcb
- exec @out@/bin/EonTimer
- '';
-in
-python3.pkgs.buildPythonApplication rec {
- pname = "eontimer";
- version = "3.0.0-rc.6";
- pyproject = true;
-
- src = fetchFromGitHub {
- owner = "DasAmpharos";
- repo = "EonTimer";
- rev = version;
- hash = "sha256-+XN/VGGlEg2gVncRZrWDOZ2bfxt8xyIu22F2wHlG6YI=";
- };
-
- build-system = [
- python3.pkgs.setuptools
- python3.pkgs.wheel
- ];
-
- dependencies = with python3.pkgs; [
- altgraph
- certifi
- charset-normalizer
- idna
- libsass
- macholib
- packaging
- pillow
- pipdeptree
- platformdirs
- pyinstaller
- pyinstaller-hooks-contrib
- pyside6
- requests
- setuptools
- shiboken6
- urllib3
- ];
-
- nativeBuildInputs = [
- python3.pkgs.pyinstaller
- ];
-
- buildPhase = ''
- runHook preBuild
-
- pyinstaller --clean --noconfirm EonTimer.spec
-
- runHook postBuild
- '';
-
- installPhase = ''
- runHook preInstall
-
- mkdir -p $out/bin
- mkdir -p $out/share/applications
- cp dist/EonTimer $out/bin/
- install -Dm755 -T ${wrapper} $out/bin/eontimer
- substituteInPlace $out/bin/eontimer --subst-var out
-
- runHook postInstall
- '';
-
- postInstall = ''
- install -Dm755 -t $out/share/applications ${
- makeDesktopItem {
- name = "eontimer";
- desktopName = "EonTimer";
- comment = "Start EonTimer";
- exec = "eontimer";
- }
- }/share/applications/eontimer.desktop
- '';
-
-
-
- meta = {
- description = "Pokémon RNG Timer";
- homepage = "https://github.com/DasAmpharos/EonTimer";
- license = lib.licenses.mit;
- maintainers = with lib.maintainers; [ ];
- mainProgram = "eon-timer";
- };
-}
-
-
-
-
-
-
-3.2.1.26. project
-
-
-set -euo pipefail
-
-if [ ! -d "$(pwd)/.git" ]; then
- git init
-fi
-nix flake init --template "$FLAKE"#"$1"
-direnv allow
-
-
-
-
-{ self, name, writeShellApplication }:
-writeShellApplication {
- inherit name;
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-3.2.1.27. fhs
-
-
-{ name, pkgs, ... }:
-let
- base = pkgs.appimageTools.defaultFhsEnvArgs;
-in
-pkgs.buildFHSEnv (base // {
- name = "fhs";
- targetPkgs = pkgs: (base.targetPkgs pkgs) ++ [ pkgs.pkg-config ];
- profile = "export FHS=1";
- runScript = "zsh";
- extraOutputsToInstall = [ "dev" ];
-})
-
-
-
-
-
-3.2.1.28. swarsel-displaypower
-
-
-A crude script to power on all displays that might be attached. Needed because sometimes displays do not awake from sleep.
-
-
-
-swaymsg "output * power on" > /dev/null 2>&1 || true
-swaymsg "output * dpms on" > /dev/null 2>&1 || true
-
-
-
-
-{ self, name, writeShellApplication, sway }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ sway ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-
-3.2.1.29. swarsel-mgba
-
-
-AppImage version of mgba in which the lua scripting works.
-
-
-
-
-{ appimageTools, fetchurl, ... }:
-let
- pname = "mgba";
- version = "0.10.4";
- src = fetchurl {
- url = "https://github.com/mgba-emu/mgba/releases/download/${version}/mGBA-${version}-appimage-x64.appimage";
- hash = "sha256-rDihDfuA8DqxvCe6UeavCzpjeU+fSqUbFnyTNC2dc1I=";
- };
- appimageContents = appimageTools.extractType2 { inherit pname version src; };
-in
-appimageTools.wrapType2 {
- inherit pname version src;
- extraInstallCommands = ''
- install -Dm444 ${appimageContents}/io.mgba.mGBA.desktop -t $out/share/applications
- substituteInPlace $out/share/applications/io.mgba.mGBA.desktop \
- --replace-fail 'Exec=mgba-qt %f' 'Exec=mgba'
- cp -r ${appimageContents}/usr/share/icons $out/share
- '';
-
-}
-
-
-
-
-
-
-3.2.1.30. swarsel-deploy
-
-
-# heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix
-{ name, bc, nix-output-monitor, writeShellApplication, ... }:
-writeShellApplication {
- runtimeInputs = [ bc nix-output-monitor ];
- inherit name;
- text = ''
- set -euo pipefail
- shopt -s lastpipe # allow cmd | readarray
-
- function die() {
- echo "error: $*" >&2
- exit 1
- }
- function show_help() {
- echo 'Usage: deploy [OPTIONS] <host,...> [ACTION]'
- echo "Builds, pushes and activates nixosConfigurations on target systems."
- echo ""
- echo 'ACTION:'
- echo ' switch [default] Switch immediately to the new configuration and make it the boot default'
- echo ' boot Make the configuration the new boot default'
- echo " test Activate the configuration but don't make it the boot default"
- echo " dry-activate Don't activate, just show what would be done"
- echo ""
- echo 'OPTIONS: [passed to nix build]'
- }
-
- function time_start() {
- T_START=$(date +%s.%N)
- }
-
- function time_next() {
- T_END=$(date +%s.%N)
- T_LAST=$(${bc}/bin/bc <<< "scale=1; ($T_END - $T_START)/1")
- T_START="$T_END"
- }
-
- USER_FLAKE_DIR=$(git rev-parse --show-toplevel 2> /dev/null || pwd) ||
- die "Could not determine current working directory. Something went very wrong."
- [[ -e "$USER_FLAKE_DIR/flake.nix" ]] ||
- die "Could not determine location of your project's flake.nix. Please run this at or below your main directory containing the flake.nix."
- cd "$USER_FLAKE_DIR"
-
- [[ $# -gt 0 ]] || {
- show_help
- exit 1
- }
-
- OPTIONS=()
- POSITIONAL_ARGS=()
- while [[ $# -gt 0 ]]; do
- case "$1" in
- "help" | "--help" | "-help" | "-h")
- show_help
- exit 1
- ;;
-
- -*) OPTIONS+=("$1") ;;
- *) POSITIONAL_ARGS+=("$1") ;;
- esac
- shift
- done
-
- [[ ''${#POSITIONAL_ARGS[@]} -ge 1 ]] ||
- die "Missing argument: <hosts...>"
- [[ ''${#POSITIONAL_ARGS[@]} -le 2 ]] ||
- die "Too many arguments given."
-
- tr , '\n' <<< "''${POSITIONAL_ARGS[0]}" | sort -u | readarray -t HOSTS
- ACTION="''${POSITIONAL_ARGS[1]-switch}"
-
- # Expand flake paths for hosts definitions
- declare -A TOPLEVEL_FLAKE_PATHS
- for host in "''${HOSTS[@]}"; do
- TOPLEVEL_FLAKE_PATHS["$host"]=".#nixosConfigurations.$host.config.system.build.toplevel"
- done
-
- time_start
-
- # Get outputs of all derivations (should be cached)
- declare -A TOPLEVEL_STORE_PATHS
- for host in "''${HOSTS[@]}"; do
- toplevel="''${TOPLEVEL_FLAKE_PATHS["$host"]}"
- # Make sudo call to get prompt out of the way
- sudo echo "[1;36m Building [m📦 [34m$host[m"
- nix build --no-link "''${OPTIONS[@]}" --show-trace --log-format internal-json -v "$toplevel" |& ${nix-output-monitor}/bin/nom --json ||
- die "Failed to get derivation path for $host from ''${TOPLEVEL_FLAKE_PATHS["$host"]}"
- TOPLEVEL_STORE_PATHS["$host"]=$(nix build --no-link --print-out-paths "''${OPTIONS[@]}" "$toplevel")
- time_next
- echo "[1;32m Built [m✅ [34m$host[m [33m''${TOPLEVEL_STORE_PATHS["$host"]}[m [90min ''${T_LAST}s[m"
- done
-
- current_host=$(hostname)
-
- for host in "''${HOSTS[@]}"; do
- store_path="''${TOPLEVEL_STORE_PATHS["$host"]}"
-
- if [ "$host" = "$current_host" ]; then
- echo -e "\033[1;36m Running locally for $host... \033[m"
- ssh_prefix="sudo"
- else
- echo -e "\033[1;36m Copying \033[m➡️ \033[34m$host\033[m"
- nix copy --to "ssh://$host" "$store_path"
- time_next
- echo -e "\033[1;32m Copied \033[m✅ \033[34m$host\033[m \033[90min ''${T_LAST}s\033[m"
- ssh_prefix="ssh $host --"
- fi
-
- echo -e "\033[1;36m Applying \033[m⚙️ \033[34m$host\033[m"
- prev_system=$($ssh_prefix readlink -e /nix/var/nix/profiles/system)
- $ssh_prefix /run/current-system/sw/bin/nix-env --profile /nix/var/nix/profiles/system --set "$store_path" ||
- die "Failed to set system profile"
- $ssh_prefix "$store_path"/bin/switch-to-configuration "$ACTION" ||
- echo "Error while activating new system" >&2
-
- if [[ -n $prev_system ]]; then
- $ssh_prefix nvd --color always diff "$prev_system" "$store_path" || true
- fi
-
- time_next
- echo -e "\033[1;32m Applied \033[m✅ \033[34m$host\033[m \033[90min ''${T_LAST}s\033[m"
- done
- '';
-}
-
-
-
-
-
-
-3.2.1.31. 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.
-
-
-
-HISTFILE="$HOME"/.histfile
-
-last_ssh_cmd=$(grep -E "ssh " "$HISTFILE" | sed -E 's/^: [0-9]+:[0-9]+;//' | grep "^ssh " | tail -1)
-host=$(echo "$last_ssh_cmd" | sed -E 's/.*ssh ([^@ ]+@)?([^ ]+).*/\2/')
-
-if [[ -n $host ]]; then
- echo "Removing SSH host key for: $host"
- ssh-keygen -R "$host"
-else
- echo "No valid SSH command found in history."
-fi
-
-
-
-
-{ self, name, writeShellApplication, openssh }:
-writeShellApplication {
- inherit name;
- runtimeInputs = [ openssh ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
-}
-
-
-
-
-
-
-3.2.2. Overlays (additions, overrides, nixpkgs-stable)
-
-
-This file now holds all of the "nixpkgs-changes" that I am using across the configurations. Most notable here are the modifications, where I am editing derivations according to my needs.
-
-
-
-When adding a new entry here, do not forget to add it in the default output of this file, otherwise it will not be exposed to the rest of the system.
-
-
-
-{ self, inputs, lib, ... }:
-
-let
- additions = final: _: import "${self}/pkgs" { pkgs = final; inherit lib; };
-
- modifications = final: prev: {
- vesktop = prev.vesktop.override {
- withSystemVencord = true;
- };
-
- firefox = prev.firefox.override {
- nativeMessagingHosts = [
- prev.tridactyl-native
- prev.browserpass
- prev.plasma5Packages.plasma-browser-integration
- ];
- };
-
- mgba = final.swarsel-mgba;
-
- retroarch = prev.retroarch.withCores (cores: with cores; [
- snes9x # snes
- nestopia # nes
- dosbox # dos
- scummvm # scumm
- vba-m # gb/a
- mgba # gb/a
- melonds # ds
- dolphin # gc/wii
- ]);
-
-
-
- };
-
- nixpkgs-stable = final: _: {
- stable = import inputs.nixpkgs-stable {
- inherit (final) system;
- config.allowUnfree = true;
- };
- };
-
- nixpkgs-kernel = final: _: {
- kernel = import inputs.nixpkgs-kernel {
- inherit (final) system;
- config.allowUnfree = true;
- };
- };
-
- nixpkgs-stable24_05 = final: _: {
- stable24_05 = import inputs.nixpkgs-stable24_05 {
- inherit (final) system;
- config.allowUnfree = true;
- };
- };
-
- nixpkgs-stable24_11 = final: _: {
- stable24_11 = import inputs.nixpkgs-stable24_11 {
- inherit (final) system;
- config.allowUnfree = true;
- };
- };
-
- zjstatus = _: prev: {
- zjstatus = inputs.zjstatus.packages.${prev.system}.default;
- };
-
-in
-{
- default =
- final: prev:
-
- (additions final prev)
- // (modifications final prev)
- // (nixpkgs-stable final prev)
- // (nixpkgs-kernel final prev)
- // (nixpkgs-stable24_05 final prev)
- // (nixpkgs-stable24_11 final prev)
- // (zjstatus final prev)
- // (inputs.vbc-nix.overlays.default final prev)
- // (inputs.nur.overlays.default final prev)
- // (inputs.emacs-overlay.overlay final prev)
- // (inputs.nix-topology.overlays.default final prev)
- // (inputs.nixgl.overlay final prev);
-
-}
-
-
-
-
-
-
-3.2.3. Profiles
-
-
-In this section I define custom modules under the swarsel attribute. These are mostly used to define settings specific to a host. I keep these settings confined to either home-manager or nixos to maintain compatibility with non-NixOS machines.
-
-
-
-Note: The structure of generating the packages was changed in commit 2cf03a3 refactor: package and module generation. That commit can be checked out in order to see a simpler version of achieving the same thing.
-
-
-
-3.2.3.1. NixOS
-
-
-Modules that need to be loaded on the NixOS level. Note that these will not be available on systems that are not running NixOS.
-
-
-
-{ lib, ... }:
-let
- profileNames = lib.swarselsystems.readNix "profiles/nixos";
-in
-{
- imports = lib.swarselsystems.mkImports profileNames "profiles/nixos";
-}
-
-
-
-
-3.2.3.1.1. Personal
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.personal = lib.mkEnableOption "is this a personal host";
- config = lib.mkIf config.swarselsystems.profiles.personal {
- swarselsystems.modules = {
- packages = lib.mkDefault true;
- general = lib.mkDefault true;
- home-manager = lib.mkDefault true;
- home-managerExtra = lib.mkDefault true;
- xserver = lib.mkDefault true;
- users = lib.mkDefault true;
- env = lib.mkDefault true;
- security = lib.mkDefault true;
- systemdTimeout = lib.mkDefault true;
- hardware = lib.mkDefault true;
- pulseaudio = lib.mkDefault true;
- pipewire = lib.mkDefault true;
- network = lib.mkDefault true;
- time = lib.mkDefault true;
- commonSops = lib.mkDefault true;
- pii = lib.mkDefault true;
- stylix = lib.mkDefault true;
- programs = lib.mkDefault true;
- zsh = lib.mkDefault true;
- syncthing = lib.mkDefault true;
- blueman = lib.mkDefault true;
- networkDevices = lib.mkDefault true;
- gvfs = lib.mkDefault true;
- interceptionTools = lib.mkDefault true;
- swayosd = lib.mkDefault true;
- ppd = lib.mkDefault true;
- yubikey = lib.mkDefault true;
- ledger = lib.mkDefault true;
- keyboards = lib.mkDefault true;
- login = lib.mkDefault true;
- nix-ld = lib.mkDefault true;
- impermanence = lib.mkDefault true;
- nvd = lib.mkDefault true;
- gnome-keyring = lib.mkDefault true;
- sway = lib.mkDefault true;
- xdg-portal = lib.mkDefault true;
- distrobox = lib.mkDefault true;
- appimage = lib.mkDefault true;
- lid = lib.mkDefault true;
- lowBattery = lib.mkDefault true;
- lanzaboote = lib.mkDefault true;
-
- optional = {
- gaming = lib.mkDefault true;
- virtualbox = lib.mkDefault true;
- autologin = lib.mkDefault true;
- nswitch-rcm = lib.mkDefault true;
- };
-
- server = {
- ssh = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.2. Chaostheatre
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.chaostheatre = lib.mkEnableOption "is this a chaostheatre host";
- config = lib.mkIf config.swarselsystems.profiles.chaostheatre {
- swarselsystems.modules = {
- packages = lib.mkDefault true;
- general = lib.mkDefault true;
- home-manager = lib.mkDefault true;
- home-managerExtra = lib.mkDefault false;
- xserver = lib.mkDefault true;
- users = lib.mkDefault true;
- env = lib.mkDefault true;
- security = lib.mkDefault true;
- systemdTimeout = lib.mkDefault true;
- hardware = lib.mkDefault true;
- pulseaudio = lib.mkDefault true;
- pipewire = lib.mkDefault true;
- network = lib.mkDefault true;
- time = lib.mkDefault true;
- commonSops = lib.mkDefault true;
- stylix = lib.mkDefault true;
- programs = lib.mkDefault true;
- zsh = lib.mkDefault true;
- syncthing = lib.mkDefault true;
- blueman = lib.mkDefault true;
- networkDevices = lib.mkDefault true;
- gvfs = lib.mkDefault true;
- interceptionTools = lib.mkDefault true;
- swayosd = lib.mkDefault true;
- ppd = lib.mkDefault true;
- yubikey = lib.mkDefault true;
- ledger = lib.mkDefault true;
- keyboards = lib.mkDefault true;
- login = lib.mkDefault true;
- nix-ld = lib.mkDefault true;
- impermanence = lib.mkDefault true;
- nvd = lib.mkDefault true;
- gnome-keyring = lib.mkDefault true;
- sway = lib.mkDefault true;
- xdg-portal = lib.mkDefault true;
- distrobox = lib.mkDefault true;
- appimage = lib.mkDefault true;
- lid = lib.mkDefault true;
- lowBattery = lib.mkDefault true;
- lanzaboote = lib.mkDefault true;
-
- optional = {
- autologin = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.3. toto
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.toto = lib.mkEnableOption "is this a toto (setup) host";
- config = lib.mkIf config.swarselsystems.profiles.toto {
- swarselsystems.modules = {
- general = lib.mkDefault true;
- home-manager = lib.mkDefault true;
- home-managerExtra = lib.mkDefault true;
- xserver = lib.mkDefault true;
- users = lib.mkDefault true;
- commonSops = lib.mkDefault true;
- impermanence = lib.mkDefault true;
- lanzaboote = lib.mkDefault true;
- server = {
- ssh = lib.mkDefault true;
- };
- optional = {
- autologin = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.4. Work
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.work = lib.mkEnableOption "is this a work host";
- config = lib.mkIf config.swarselsystems.profiles.work {
- swarselsystems.modules = {
- optional = {
- work = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.5. Framework
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.framework = lib.mkEnableOption "is this a framework brand host";
- config = lib.mkIf config.swarselsystems.profiles.framework {
- swarselsystems.modules = {
- optional = {
- framework = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.6. AMD CPU
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.amdcpu = lib.mkEnableOption "is this a host with amd cpu";
- config = lib.mkIf config.swarselsystems.profiles.amdcpu {
- swarselsystems.modules = {
- optional = {
- amdcpu = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.7. AMD GPU
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.amdgpu = lib.mkEnableOption "is this a host with amd gpu";
- config = lib.mkIf config.swarselsystems.profiles.amdgpu {
- swarselsystems.modules = {
- optional = {
- amdgpu = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.8. Hibernation
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.hibernation = lib.mkEnableOption "is this a host using hibernation";
- config = lib.mkIf config.swarselsystems.profiles.hibernation {
- swarselsystems.modules = {
- optional = {
- hibernation = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.9. BTRFS
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.btrfs = lib.mkEnableOption "is this a host using btrfs";
- config = lib.mkIf config.swarselsystems.profiles.btrfs {
- swarselsystems.modules = {
- optional = {
- btrfs = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.10. Local Server
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.server.local = lib.mkEnableOption "is this a local server";
- config = lib.mkIf config.swarselsystems.profiles.server.local {
- swarselsystems = {
- modules = {
- general = lib.mkDefault true;
- pii = lib.mkDefault true;
- home-manager = lib.mkDefault true;
- home-managerExtra = lib.mkDefault true;
- xserver = lib.mkDefault true;
- time = lib.mkDefault true;
- users = lib.mkDefault true;
- server = {
- general = lib.mkDefault true;
- packages = lib.mkDefault true;
- sops = lib.mkDefault true;
- nfs = lib.mkDefault true;
- nginx = lib.mkDefault true;
- ssh = lib.mkDefault true;
- kavita = lib.mkDefault true;
- restic = lib.mkDefault true;
- jellyfin = lib.mkDefault true;
- navidrome = lib.mkDefault true;
- spotifyd = lib.mkDefault true;
- mpd = lib.mkDefault true;
- postgresql = lib.mkDefault true;
- matrix = lib.mkDefault true;
- nextcloud = lib.mkDefault true;
- immich = lib.mkDefault true;
- paperless = lib.mkDefault true;
- transmission = lib.mkDefault true;
- syncthing = lib.mkDefault true;
- monitoring = lib.mkDefault true;
- emacs = lib.mkDefault true;
- freshrss = lib.mkDefault true;
- jenkins = lib.mkDefault false;
- kanidm = lib.mkDefault true;
- firefly = lib.mkDefault true;
- koillection = lib.mkDefault true;
- radicale = lib.mkDefault true;
- atuin = lib.mkDefault true;
- };
- };
- };
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.11. OCI Sync Server
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.server.sync = lib.mkEnableOption "is this a oci sync server";
- config = lib.mkIf config.swarselsystems.profiles.server.sync {
- swarselsystems = {
- modules = {
- general = lib.mkDefault true;
- nix-ld = lib.mkDefault true;
- pii = lib.mkDefault true;
- home-manager = lib.mkDefault true;
- home-managerExtra = lib.mkDefault true;
- xserver = lib.mkDefault true;
- time = lib.mkDefault true;
- users = lib.mkDefault true;
- server = {
- general = lib.mkDefault true;
- packages = lib.mkDefault true;
- sops = lib.mkDefault true;
- nginx = lib.mkDefault true;
- ssh = lib.mkDefault true;
- forgejo = lib.mkDefault true;
- ankisync = lib.mkDefault true;
- };
- };
- };
- };
-
-}
-
-
-
-
-
-
-3.2.3.1.12. Moonside
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.server.moonside = lib.mkEnableOption "is this a moonside server";
- config = lib.mkIf config.swarselsystems.profiles.server.moonside {
- swarselsystems = {
- modules = {
- general = lib.mkDefault true;
- pii = lib.mkDefault true;
- home-manager = lib.mkDefault true;
- home-managerExtra = lib.mkDefault true;
- xserver = lib.mkDefault true;
- time = lib.mkDefault true;
- users = lib.mkDefault true;
- impermanence = lib.mkDefault true;
- server = {
- general = lib.mkDefault true;
- packages = lib.mkDefault true;
- sops = lib.mkDefault true;
- nginx = lib.mkDefault true;
- ssh = lib.mkDefault true;
- oauth2Proxy = lib.mkDefault true;
- croc = lib.mkDefault true;
- microbin = lib.mkDefault true;
- shlink = lib.mkDefault true;
- };
- };
- };
- };
-
-}
-
-
-
-
-
-
-
-3.2.3.2. home-manager
-
-
-This holds modules that are to be used on most hosts. These are also the most important options to configure, as these allow me easy access to monitor, keyboard, and other setups.
-
-
-
-{ lib, ... }:
-let
- profileNames = lib.swarselsystems.readNix "profiles/home";
-in
-{
- imports = lib.swarselsystems.mkImports profileNames "profiles/home";
-}
-
-
-
-
-3.2.3.2.1. Personal
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.personal = lib.mkEnableOption "is this a personal host";
- config = lib.mkIf config.swarselsystems.profiles.personal {
- swarselsystems.modules = {
- packages = lib.mkDefault true;
- ownpackages = lib.mkDefault true;
- general = lib.mkDefault true;
- nixgl = lib.mkDefault true;
- sops = lib.mkDefault true;
- yubikey = lib.mkDefault true;
- ssh = lib.mkDefault true;
- stylix = lib.mkDefault true;
- desktop = lib.mkDefault true;
- symlink = lib.mkDefault true;
- env = lib.mkDefault true;
- programs = lib.mkDefault true;
- nix-index = lib.mkDefault true;
- passwordstore = lib.mkDefault true;
- direnv = lib.mkDefault true;
- eza = lib.mkDefault true;
- atuin = lib.mkDefault true;
- git = lib.mkDefault true;
- fuzzel = lib.mkDefault true;
- starship = lib.mkDefault true;
- kitty = lib.mkDefault true;
- zsh = lib.mkDefault true;
- zellij = lib.mkDefault true;
- tmux = lib.mkDefault true;
- mail = lib.mkDefault true;
- emacs = lib.mkDefault true;
- waybar = lib.mkDefault true;
- firefox = lib.mkDefault true;
- gnome-keyring = lib.mkDefault true;
- kdeconnect = lib.mkDefault true;
- mako = lib.mkDefault true;
- swayosd = lib.mkDefault true;
- yubikeytouch = lib.mkDefault true;
- sway = lib.mkDefault true;
- kanshi = lib.mkDefault true;
- gpgagent = lib.mkDefault true;
- gammastep = lib.mkDefault true;
-
- optional = {
- gaming = lib.mkDefault true;
- };
- };
- };
-
-}
-
-
-
-
-
-
-3.2.3.2.2. Chaostheatre
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.chaostheatre = lib.mkEnableOption "is this a chaostheatre host";
- config = lib.mkIf config.swarselsystems.profiles.chaostheatre {
- swarselsystems.modules = {
- packages = lib.mkDefault true;
- ownpackages = lib.mkDefault true;
- general = lib.mkDefault true;
- nixgl = lib.mkDefault true;
- sops = lib.mkDefault true;
- yubikey = lib.mkDefault false;
- ssh = lib.mkDefault true;
- stylix = lib.mkDefault true;
- desktop = lib.mkDefault true;
- symlink = lib.mkDefault true;
- env = lib.mkDefault false;
- programs = lib.mkDefault true;
- nix-index = lib.mkDefault true;
- direnv = lib.mkDefault true;
- eza = lib.mkDefault true;
- git = lib.mkDefault false;
- fuzzel = lib.mkDefault true;
- starship = lib.mkDefault true;
- kitty = lib.mkDefault true;
- zsh = lib.mkDefault true;
- zellij = lib.mkDefault true;
- tmux = lib.mkDefault true;
- mail = lib.mkDefault false;
- emacs = lib.mkDefault true;
- waybar = lib.mkDefault true;
- firefox = lib.mkDefault true;
- gnome-keyring = lib.mkDefault true;
- kdeconnect = lib.mkDefault true;
- mako = lib.mkDefault true;
- swayosd = lib.mkDefault true;
- yubikeytouch = lib.mkDefault true;
- sway = lib.mkDefault true;
- kanshi = lib.mkDefault true;
- gpgagent = lib.mkDefault true;
- gammastep = lib.mkDefault false;
- };
- };
-
-}
-
-
-
-
-
-
-3.2.3.2.3. toto
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.toto = lib.mkEnableOption "is this a toto (setup) host";
- config = lib.mkIf config.swarselsystems.profiles.toto {
- swarselsystems.modules = {
- general = lib.mkDefault true;
- sops = lib.mkDefault true;
- ssh = lib.mkDefault true;
- };
- };
-
-}
-
-
-
-
-
-
-3.2.3.2.4. Work
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.work = lib.mkEnableOption "is this a work host";
- config = lib.mkIf config.swarselsystems.profiles.work {
- swarselsystems.modules = {
- optional = {
- work = lib.mkDefault true;
- };
- };
- };
-
-}
-
-
-
-
-
-
-3.2.3.2.5. Framework
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.framework = lib.mkEnableOption "is this a framework brand host";
- config = lib.mkIf config.swarselsystems.profiles.framework {
- swarselsystems.modules = {
- optional = {
- framework = lib.mkDefault true;
- };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.3.2.6. Darwin
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.darwin = lib.mkEnableOption "is this a darwin host";
- config = lib.mkIf config.swarselsystems.profiles.darwin {
- swarselsystems.modules = {
- general = lib.mkDefault true;
- };
- };
-
-}
-
-
-
-
-
-
-3.2.3.2.7. Local Server
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.profiles.server.local = lib.mkEnableOption "is this a local server";
- config = lib.mkIf config.swarselsystems.profiles.server.local {
- swarselsystems.modules = {
- general = lib.mkDefault true;
- server = {
- dotfiles = lib.mkDefault true;
- };
- };
- };
-
-}
-
-
-
-
-
-
-
-
-3.2.4. 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.
-
-
-
-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 nixosConfigurations or 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.
-
-
-TODO
-
-
-
-{ self, lib, systems, inputs, ... }:
-{
-
- mkIfElseList = p: yes: no: lib.mkMerge [
- (lib.mkIf p yes)
- (lib.mkIf (!p) no)
- ];
-
- mkIfElse = p: yes: no: if p then yes else no;
-
- forAllSystems = lib.genAttrs [
- "x86_64-linux"
- "aarch64-linux"
- "x86_64-darwin"
- "aarch64-darwin"
- ];
-
- pkgsFor = lib.genAttrs (import systems) (system:
- import inputs.nixpkgs {
- inherit system;
- overlays = [ self.overlays.default ];
- config.allowUnfree = true;
- }
- );
-
- toCapitalized = str:
- if builtins.stringLength str == 0 then
- ""
- else
- let
- first = builtins.substring 0 1 str;
- rest = builtins.substring 1 (builtins.stringLength str - 1) str;
- upper = lib.toUpper first;
- lower = lib.toLower rest;
- in
- upper + lower;
-
-
- # mkUser = name: {
- # config.users.users.${name} = {
- # group = name;
- # isSystemUser = true;
- # };
-
- # config.users.groups.${name} = {};
- # };
-
- mkTrueOption = lib.mkOption {
- type = lib.types.bool;
- default = true;
- };
-
- mkStrong = lib.mkOverride 60;
-
- getSecret = filename: lib.strings.trim (builtins.readFile "${filename}");
-
- forEachSystem = f: lib.genAttrs (import systems) (system: f lib.swarselsystems.pkgsFor.${system});
- forEachLinuxSystem = f: lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (system: f lib.swarselsystems.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}"));
-
- mkApps = system: names: self: builtins.listToAttrs (map
- (name: {
- inherit name;
- value = {
- type = "app";
- program = "${self.packages.${system}.${name}}/bin/${name}";
- meta = {
- description = "Custom app ${name}.";
- };
- };
- })
- names);
-
- mkPackages = names: pkgs: builtins.listToAttrs (map
- (name: {
- inherit name;
- value = pkgs.callPackage "${self}/pkgs/${name}" { inherit self name; };
- })
- names);
-
-
- mkModules = names: type: builtins.listToAttrs (map
- (name: {
- inherit name;
- value = import "${self}/modules/${type}/${name}";
- })
- names);
-
- mkProfiles = names: type: builtins.listToAttrs (map
- (name: {
- inherit name;
- value = import "${self}/profiles/${type}/${name}";
- })
- names);
-
- mkTemplates = names: builtins.listToAttrs (map
- (name: {
- inherit name;
- value = {
- path = "${self}/templates/${name}";
- description = "${name} project ";
- };
- })
- 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" ];
- };
-
-}
-
-
-
-
-
-3.2.5. Auxiliary files
-
-
-
-3.2.5.1. extra-builtins
-
-
-# adapted from https://github.com/oddlama/nix-config/blob/main/nix/extra-builtins.nix
-{ exec, ... }:
-let
- assertMsg = pred: msg: pred || builtins.throw msg;
- hasSuffix =
- suffix: content:
- let
- lenContent = builtins.stringLength content;
- lenSuffix = builtins.stringLength suffix;
- in
- lenContent >= lenSuffix && builtins.substring (lenContent - lenSuffix) lenContent content == suffix;
-in
-{
- # Instead of calling sops directly here, we call a wrapper script that will cache the output
- # in a predictable path in /tmp, which allows us to only require the password for each encrypted
- # file once.
- sopsImportEncrypted =
- nixFile:
- assert assertMsg (builtins.isPath nixFile)
- "The file to decrypt must be given as a path (not a string) to prevent impurity.";
- assert assertMsg (hasSuffix ".nix.enc" nixFile)
- "The content of the decrypted file must be a nix expression and should therefore end in .nix.enc";
- exec [
- ./sops-decrypt-and-cache.sh
- nixFile
- ];
-}
-
-
-
-
-
-
-3.2.5.2. sops-decrypt-and-cache
-
-
-# adapted from https://github.com/oddlama/nix-config/blob/main/nix/rage-decrypt-and-cache.sh
-set -euo pipefail
-
-print_out_path=false
-if [[ $1 == "--print-out-path" ]]; then
- print_out_path=true
- shift
-fi
-
-file="$1"
-shift
-
-basename="${file%".enc"}"
-# store path prefix or ./ if applicable
-[[ $file == "/nix/store/"* ]] && basename="${basename#*"-"}"
-[[ $file == "./"* ]] && basename="${basename#"./"}"
-
-# Calculate a unique content-based identifier (relocations of
-# the source file in the nix store should not affect caching)
-new_name="$(sha512sum "$file")"
-new_name="${new_name:0:32}-${basename//"/"/"%"}"
-
-# Derive the path where the decrypted file will be stored
-out="/var/tmp/nix-import-encrypted/$UID/$new_name"
-umask 077
-mkdir -p "$(dirname "$out")"
-
-# Decrypt only if necessary
-if [[ ! -e $out ]]; then
- agekey=$(sudo ssh-to-age -private-key -i /etc/ssh/sops || sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key)
- SOPS_AGE_KEY="$agekey" sops decrypt --output "$out" "$file"
-fi
-
-# Print out path or decrypted content
-if [[ $print_out_path == true ]]; then
- echo "$out"
-else
- cat "$out"
-fi
-
-
-
-
-
-3.2.5.3. nix-topology
-
-
-{ config, ... }:
-let
- inherit (config.lib.topology)
- mkInternet
- mkDevice
- mkSwitch
- mkRouter
- mkConnection
- ;
-in
-{
- renderer = "elk";
-
- networks = {
- home-lan = {
- name = "Home LAN";
- cidrv4 = "192.168.1.0/24";
- };
- wg = {
- name = "Wireguard Tunnel";
- cidrv4 = "192.168.3.0/24";
- };
- };
-
- nodes = {
- internet = mkInternet {
- connections = [
- (mkConnection "moonside" "wan")
- (mkConnection "pfsense" "wan")
- (mkConnection "sync" "wan")
- (mkConnection "toto" "bootstrapper")
- (mkConnection "drugstore" "installer image")
- (mkConnection "chaostheatre" "demo host")
- ];
- };
-
- chaostheatre.interfaces."demo host" = { };
- drugstore.interfaces."installer image" = { };
- toto.interfaces."bootstrapper" = { };
- sync.interfaces.wan = { };
- moonside.interfaces.wan = { };
-
- pfsense = mkRouter "pfSense" {
- info = "HUNSN RM02";
- image = ../topology/images/hunsn.png;
- interfaceGroups = [
- [
- "eth2"
- "eth3"
- "eth4"
- "eth5"
- "eth6"
- ]
- [ "wan" ]
- ];
- interfaces.wg0 = {
- addresses = [ "192.168.3.1" ];
- network = "wg";
- virtual = true;
- type = "wireguard";
- };
-
- connections = {
- eth2 = mkConnection "switch-livingroom" "eth1";
- eth4 = mkConnection "winters" "eth1";
- eth3 = mkConnection "switch-bedroom" "eth1";
- eth6 = mkConnection "wifi-ap" "eth1";
- wg = mkConnection "moonside" "wg";
- };
- interfaces = {
- eth2 = {
- addresses = [ "192.168.1.1" ];
- network = "home-lan";
- };
- eth3 = {
- addresses = [ "192.168.1.1" ];
- network = "home-lan";
- };
- eth4 = {
- addresses = [ "192.168.1.1" ];
- network = "home-lan";
- };
- eth6 = {
- addresses = [ "192.168.1.1" ];
- network = "home-lan";
- };
- };
- };
-
- winters.interfaces."eth1" = { };
-
- wifi-ap = mkSwitch "Wi-Fi AP" {
- info = "Huawei";
- image = ../topology/images/huawei.png;
- interfaceGroups = [
- [
- "eth1"
- "wifi"
- ]
- ];
- };
-
- switch-livingroom = mkSwitch "Switch Livingroom" {
- info = "TL-SG108";
- image = ../topology/images/TL-SG108.png;
- interfaceGroups = [
- [
- "eth1"
- "eth2"
- "eth3"
- "eth4"
- "eth5"
- "eth6"
- "eth7"
- "eth8"
- ]
- ];
- connections = {
- eth2 = mkConnection "nswitch" "eth1";
- eth7 = mkConnection "pc" "eth1";
- eth8 = mkConnection "nbl-imba-2" "eth1";
- };
- };
-
- nswitch = mkDevice "Nintendo Switch" {
- info = "Nintendo Switch";
- image = ../topology/images/nintendo-switch.png;
- interfaces.eth1 = { };
- };
-
- pc = mkDevice "Windows Gaming Server" {
- info = "i7-4790k, GTX970, 32GB RAM";
- image = ../topology/images/pc.png;
- interfaces.eth1 = { };
- };
-
- nbl-imba-2.interfaces.eth1 = { };
-
- switch-bedroom = mkSwitch "Switch Bedroom" {
- info = "TL-SG1005D";
- image = ../topology/images/TL-SG1005D.png;
- interfaceGroups = [
- [
- "eth1"
- "eth2"
- "eth3"
- "eth4"
- "eth5"
- ]
- ];
- connections.eth2 = mkConnection "printer" "eth1";
- };
-
- printer = mkDevice "Printer" {
- info = "DELL C2665dnf";
- image = ../topology/images/DELL-C2665dnf.png;
- interfaces.eth1 = { };
- };
-
- };
-
-}
-
-
-
-
-
-
-3.2.5.4. Globals
-
-
-{ inputs, ... }:
-{
- flake =
- {
- config,
- lib,
- ...
- }:
- {
- globals =
- let
- globalsSystem = lib.evalModules {
- prefix = [ "globals" ];
- specialArgs = {
- inherit lib;
- inherit inputs;
- inherit (config) nodes;
- };
- modules = [
- ../modules/nixos/common/globals.nix
- (
- { lib, ... }:
- {
- globals = lib.mkMerge (
- lib.concatLists (
- lib.flip lib.mapAttrsToList config.nodes (
- name: cfg:
- builtins.addErrorContext "while aggregating globals from nixosConfigurations.${name} into flake-level globals:" cfg.config._globalsDefs
- )
- )
- );
- }
- )
- ];
- };
- in
- {
- # Make sure the keys of this attrset are trivially evaluatable to avoid infinite recursion,
- # therefore we inherit relevant attributes from the config.
- inherit (globalsSystem.config.globals)
- domains
- services
- macs
- myuser
- root
- ;
- };
- };
-}
-
-
-
-
-
-
-
-3.3. NixOS
+3.2. NixOS
Here we have NixOS options. All options are split into smaller files that are loaded by the general default.nix. Common files are used by all user hosts equally, optionals need to be added to the machine's default.nix on a case-by-case basis.
+
+
+{ lib, ... }:
+let
+ importNames = lib.swarselsystems.readNix "modules/nixos";
+in
+ {
+ imports = lib.swarselsystems.mkImports importNames "modules/nixos";
+ }
+
+
+
-3.3.1. Common
+3.2.1. Common
These are system-level settings specific to NixOS machines. All settings that are required on all machines go here.
-3.3.1.1. Imports, non-server settings
+3.2.1.1. Imports
This section is for setting things that should be used on hosts that are using the default NixOS configuration. This means that servers should NOT import this, as much of these imported modules are user-configured.
@@ -7206,20 +4454,176 @@ let
importNames = lib.swarselsystems.readNix "modules/nixos/common";
modulesPath = "${self}/modules";
in
-{
- imports = lib.swarselsystems.mkImports importNames "modules/nixos/common" ++ [
- "${modulesPath}/home/common/sharedsetup.nix"
- ];
+ {
+ imports = lib.swarselsystems.mkImports importNames "modules/nixos/common" ++ [
+ "${modulesPath}/home/common/sharedsetup.nix"
+ ];
-}
+ }
+
+
+
+
+
+3.2.1.2. Share configuration between nodes (automatically active)
+
+
+# adapted from https://github.com/oddlama/nix-config/blob/main/modules/distributed-config.nix
+{ config, lib, outputs, ... }:
+let
+ nodeName = config.node.name;
+ mkForwardedOption =
+ path:
+ lib.mkOption {
+ type = lib.mkOptionType {
+ name = "Same type that the receiving option `${lib.concatStringsSep "." path}` normally accepts.";
+ merge =
+ _loc: defs:
+ builtins.filter (x: builtins.isAttrs x -> ((x._type or "") != "__distributed_config_empty")) (
+ map (x: x.value) defs
+ );
+ };
+ default = {
+ _type = "__distributed_config_empty";
+ };
+ description = ''
+ Anything specified here will be forwarded to `${lib.concatStringsSep "." path}`
+ on the given node. Forwarding happens as-is to the raw values,
+ so validity can only be checked on the receiving node.
+ '';
+ };
+
+ forwardedOptions = [
+ [
+ "services"
+ "nginx"
+ "upstreams"
+ ]
+ [
+ "services"
+ "nginx"
+ "virtualHosts"
+ ]
+ ];
+
+ attrsForEachOption =
+ f: lib.foldl' (acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path (f path))) { } forwardedOptions;
+in
+ {
+ options.nodes = lib.mkOption {
+ description = "Options forwarded to the given node.";
+ default = { };
+ type = lib.types.attrsOf (
+ lib.types.submodule {
+ options = attrsForEachOption mkForwardedOption;
+ }
+ );
+ };
+
+ config =
+ let
+ getConfig =
+ path: otherNode:
+ let
+ cfg = outputs.nixosConfigurations.${otherNode}.config.nodes.${nodeName} or null;
+ in
+ lib.optionals (cfg != null) (lib.getAttrFromPath path cfg);
+ mergeConfigFromOthers = path: lib.mkMerge (lib.concatMap (getConfig path) (lib.attrNames outputs.nixosConfigurations));
+ in
+ attrsForEachOption mergeConfigFromOthers;
+ }
+
+
+
+
+
+3.2.1.3. Global options (automatically active)
+
+
+{ lib, options, ... }:
+let
+ inherit (lib)
+ mkOption
+ types
+ ;
+in
+ {
+ options = {
+ globals = mkOption {
+ default = { };
+ type = types.submodule {
+ options = {
+ user = {
+ name = mkOption {
+ type = types.str;
+ };
+ work = mkOption {
+ type = types.str;
+ };
+ };
+
+
+ services = mkOption {
+ type = types.attrsOf (
+ types.submodule {
+ options = {
+ domain = mkOption {
+ type = types.str;
+ };
+ };
+ }
+ );
+ };
+
+ domains = {
+ main = mkOption {
+ type = types.str;
+ };
+ };
+ };
+ };
+ };
+
+ _globalsDefs = mkOption {
+ type = types.unspecified;
+ default = options.globals.definitions;
+ readOnly = true;
+ internal = true;
+ };
+ };
+ }
+
+
+
+
+
+3.2.1.4. Meta options (automatically active)
+
+
+{ lib, ... }:
+{
+ options = {
+ node = {
+ secretsDir = lib.mkOption {
+ description = "Path to the secrets directory for this node.";
+ type = lib.types.path;
+ default = ./.;
+ };
+ name = lib.mkOption {
+ description = "Node Name.";
+ type = lib.types.str;
+ };
+ };
+ };
+}
-3.3.1.2. Shared Configuration Options
+3.2.1.5. Shared Configuration Options (automatically active)
I usually use mutableUsers = false in my NixOS configuration. However, on a new system where sops-keys have not been deployed, this would immediately lock me out of the system. Hence this flag can be used until sops-keys are created.
@@ -7258,8 +4662,30 @@ I usually use mutableUsers = false in my NixOS configuration. Howev
+
+3.2.1.6. Topology (automatically active)
+
+
+{ self, lib, config, ... }:
+{
+ options.swarselsystems.info = lib.mkOption {
+ type = lib.types.str;
+ default = "";
+ };
+ config.topology = {
+ id = config.node.name;
+ self = {
+ hardware.info = config.swarselsystems.info;
+ icon = lib.mkIf config.swarselsystems.isLaptop "devices.laptop";
+ };
+ };
+}
+
+
+
+
-3.3.1.3. General NixOS settings (stateVersion)
+3.2.1.7. General NixOS settings (nix, stateVersion)
We disable the warnings that trigger when rebuilding with a dirty flake. At this point, I am also disabling channels and pinning the flake registry - the latter lets me use the local version of nixpkgs for commands like nix shell (without it, we will always download the newest version of nixpkgs for these commands).
@@ -7320,46 +4746,51 @@ A breakdown of the flags being set:
let
flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs;
in
- {
- settings = {
- experimental-features = [
- "nix-command"
- "flakes"
- "ca-derivations"
- "cgroups"
- "pipe-operators"
- ];
- trusted-users = [ "@wheel" "${config.swarselsystems.mainUser}" ];
- connect-timeout = 5;
- bash-prompt-prefix = "[33m$SHLVL:\\w [0m";
- bash-prompt = "$(if [[ $? -gt 0 ]]; then printf \"[31m\"; else printf \"[32m\"; fi)\[\e[1m\]λ\[\e[0m\] [0m";
- fallback = true;
- min-free = 128000000;
- max-free = 1000000000;
- flake-registry = "";
- auto-optimise-store = true;
- warn-dirty = false;
- max-jobs = 1;
- use-cgroups = lib.mkIf config.swarselsystems.isLinux true;
+ {
+ settings = {
+ experimental-features = [
+ "nix-command"
+ "flakes"
+ "ca-derivations"
+ "cgroups"
+ "pipe-operators"
+ ];
+ trusted-users = [ "@wheel" "${config.swarselsystems.mainUser}" ];
+ connect-timeout = 5;
+ bash-prompt-prefix = "[33m$SHLVL:\\w [0m";
+ bash-prompt = "$(if [[ $? -gt 0 ]]; then printf \"[31m\"; else printf \"[32m\"; fi)\[\e[1m\]λ\[\e[0m\] [0m";
+ fallback = true;
+ min-free = 128000000;
+ max-free = 1000000000;
+ flake-registry = "";
+ auto-optimise-store = true;
+ warn-dirty = false;
+ max-jobs = 1;
+ use-cgroups = lib.mkIf config.swarselsystems.isLinux true;
+ };
+ gc = {
+ automatic = true;
+ dates = "weekly";
+ options = "--delete-older-than 10d";
+ };
+ optimise = {
+ automatic = true;
+ dates = "weekly";
+ };
+ channel.enable = false;
+ registry = rec {
+ nixpkgs.flake = inputs.nixpkgs;
+ p = nixpkgs;
+ };
+ nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs;
};
- gc = {
- automatic = true;
- dates = "weekly";
- options = "--delete-older-than 10d";
- };
- optimise = {
- automatic = true;
- dates = "weekly";
- };
- channel.enable = false;
- registry = rec {
- nixpkgs.flake = inputs.nixpkgs;
- p = nixpkgs;
- };
- nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs;
- };
services.dbus.implementation = "broker";
+
+ systemd.services.nix-daemon = {
+ environment.TMPDIR = "/var/tmp";
+ };
+
system.stateVersion = lib.mkDefault "23.05";
};
}
@@ -7367,163 +4798,395 @@ A breakdown of the flags being set:
-
-3.3.1.4. Share configuration between nodes
-
+
+3.2.1.8. Setup home-manager base
+
+
+We enable the use of home-manager as a NixoS module. A nice trick here is the extraSpecialArgs = inputs line, which enables the use of seflf in most parts of the configuration. This is useful to refer to the root of the flake (which is otherwise quite hard while maintaining flake purity).
+
+
-# adapted from https://github.com/oddlama/nix-config/blob/main/modules/distributed-config.nix
-{ config, lib, outputs, ... }:
+{ self, inputs, config, lib, outputs, globals, nodes, ... }:
let
- nodeName = config.node.name;
- mkForwardedOption =
- path:
- lib.mkOption {
- type = lib.mkOptionType {
- name = "Same type that the receiving option `${lib.concatStringsSep "." path}` normally accepts.";
- merge =
- _loc: defs:
- builtins.filter (x: builtins.isAttrs x -> ((x._type or "") != "__distributed_config_empty")) (
- map (x: x.value) defs
- );
- };
- default = {
- _type = "__distributed_config_empty";
- };
- description = ''
- Anything specified here will be forwarded to `${lib.concatStringsSep "." path}`
- on the given node. Forwarding happens as-is to the raw values,
- so validity can only be checked on the receiving node.
- '';
- };
-
- forwardedOptions = [
- [
- "services"
- "nginx"
- "upstreams"
- ]
- [
- "services"
- "nginx"
- "virtualHosts"
- ]
- ];
-
- attrsForEachOption =
- f: lib.foldl' (acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path (f path))) { } forwardedOptions;
+ mainUser = globals.user.name;
in
-{
- options.nodes = lib.mkOption {
- description = "Options forwarded to the given node.";
- default = { };
- type = lib.types.attrsOf (
- lib.types.submodule {
- options = attrsForEachOption mkForwardedOption;
- }
- );
- };
+ {
+ options.swarselsystems.modules.home-manager = lib.mkEnableOption "home-manager";
+ config = lib.mkIf config.swarselsystems.modules.home-manager {
+ home-manager = lib.mkIf config.swarselsystems.withHomeManager {
+ useGlobalPkgs = true;
+ useUserPackages = true;
+ verbose = true;
+ users."${mainUser}".imports = [
+ "${self}/profiles/home"
+ "${self}/modules/home"
+ ];
+ sharedModules = [
+ inputs.nix-index-database.hmModules.nix-index
+ inputs.sops-nix.homeManagerModules.sops
+ {
+ home.stateVersion = lib.mkDefault config.system.stateVersion;
+ }
+ ];
+ extraSpecialArgs = { inherit (inputs) self nixgl; inherit inputs outputs globals nodes; };
+ };
+ };
+ }
+
+
+
+
+
+3.2.1.9. User setup, Make users non-mutable
+
+
+This ensures that all user-configuration happens here in the config file.
+In case of using a fully setup system, this makes also sure that no further user level modifications can be made using CLI utilities (e.g. usermod etc.). Everything must be defined in the flake.
+
- config =
- let
- getConfig =
- path: otherNode:
- let
- cfg = outputs.nixosConfigurations.${otherNode}.config.nodes.${nodeName} or null;
- in
- lib.optionals (cfg != null) (lib.getAttrFromPath path cfg);
- mergeConfigFromOthers = path: lib.mkMerge (lib.concatMap (getConfig path) (lib.attrNames outputs.nixosConfigurations));
- in
- attrsForEachOption mergeConfigFromOthers;
+
+For that reason, make sure that sops-nix is properly working before setting the initialSetup flag, otherwise you might lose user access.
+
+
+
+{ self, pkgs, config, lib, ... }:
+let
+ sopsFile = self + /secrets/general/secrets.yaml;
+in
+ {
+ options.swarselsystems.modules.users = lib.mkEnableOption "user config";
+ config = lib.mkIf config.swarselsystems.modules.users {
+ sops.secrets.swarseluser = lib.mkIf (!config.swarselsystems.isPublic) { inherit sopsFile; neededForUsers = true; };
+
+ users = {
+ mutableUsers = lib.mkIf (!config.swarselsystems.initialSetup) false;
+ users."${config.swarselsystems.mainUser}" = {
+ isNormalUser = true;
+ description = "Leon S";
+ password = lib.mkIf config.swarselsystems.initialSetup "setup";
+ hashedPasswordFile = lib.mkIf (!config.swarselsystems.initialSetup) config.sops.secrets.swarseluser.path;
+ extraGroups = [ "networkmanager" "syncthing" "docker" "wheel" "lp" "audio" "video" "vboxusers" "libvirtd" "scanner" ];
+ packages = with pkgs; [ ];
+ };
+ };
+ };
+ }
+
+
+
+
+
+3.2.1.10. Setup login keymap
+
+
+Next, we setup the keymap in case we are not in a graphical session. At this point, I always resort to us/altgr-intl, as it is comfortable to use and I do not write too much German anyways.
+
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.modules.xserver = lib.mkEnableOption "xserver keymap";
+ config = lib.mkIf config.swarselsystems.modules.packages {
+ services.xserver = {
+ xkb = {
+ layout = "us";
+ variant = "altgr-intl";
+ };
+ };
+ };
}
-
-3.3.1.5. Global options
-
+
+3.2.1.11. Time, locale settings
+
+
+Setup timezone and locale. I want to use the US layout, but have the rest adapted to my country and timezone. Also, there is an issue with running Windows/Linux dualboot on the same machine where the hardware clock desyncs between the two OS'es. We fix that bug here as well.
+
+
-{ lib, options, ... }:
-let
- inherit (lib)
- mkOption
- types
- ;
-
-in
+{ lib, config, ... }:
{
- options = {
- globals = mkOption {
- default = { };
- type = types.submodule {
- options = {
- root = {
- hashedPassword = mkOption {
- type = types.str;
- description = "My root user's password hash.";
- };
- };
-
- myuser = {
- name = mkOption {
- type = types.str;
- description = "My unix username.";
- };
- hashedPassword = mkOption {
- type = types.str;
- description = "My unix password hash.";
- };
- };
-
-
- services = mkOption {
- type = types.attrsOf (
- types.submodule {
- options = {
- domain = mkOption {
- type = types.str;
- description = "The domain under which this service can be reached";
- };
- };
- }
- );
- };
-
- domains = {
- me = mkOption {
- type = types.str;
- description = "My main domain.";
- };
-
- personal = mkOption {
- type = types.str;
- description = "My personal domain.";
- };
- };
-
- macs = mkOption {
- default = { };
- type = types.attrsOf types.str;
- description = "Known MAC addresses for external devices.";
- };
- };
- };
+ options.swarselsystems.modules.time = lib.mkEnableOption "time config";
+ config = lib.mkIf config.swarselsystems.modules.time {
+ time = {
+ timeZone = "Europe/Vienna";
+ # hardwareClockInLocalTime = true;
};
- _globalsDefs = mkOption {
- type = types.unspecified;
- default = options.globals.definitions;
- readOnly = true;
- internal = true;
+ i18n = {
+ defaultLocale = "en_US.UTF-8";
+ extraLocaleSettings = {
+ LC_ADDRESS = "de_AT.UTF-8";
+ LC_IDENTIFICATION = "de_AT.UTF-8";
+ LC_MEASUREMENT = "de_AT.UTF-8";
+ LC_MONETARY = "de_AT.UTF-8";
+ LC_NAME = "de_AT.UTF-8";
+ LC_NUMERIC = "de_AT.UTF-8";
+ LC_PAPER = "de_AT.UTF-8";
+ LC_TELEPHONE = "de_AT.UTF-8";
+ LC_TIME = "de_AT.UTF-8";
+ };
};
};
}
+
+
+
+
+
+3.2.1.12. PII management
+
+
+# largely based on https://github.com/oddlama/nix-config/blob/main/modules/secrets.nix
+{ config, inputs, lib, ... }:
+let
+
+ # If the given expression is a bare set, it will be wrapped in a function,
+ # so that the imported file can always be applied to the inputs, similar to
+ # how modules can be functions or sets.
+ constSet = x: if builtins.isAttrs x then (_: x) else x;
+
+ # Try to access the extra builtin we loaded via nix-plugins.
+ # Throw an error if that doesn't exist.
+ sopsImportEncrypted =
+ assert lib.assertMsg (builtins ? extraBuiltins.sopsImportEncrypted)
+ "The extra builtin 'sopsImportEncrypted' is not available, so repo.secrets cannot be decrypted. Did you forget to add nix-plugins and point it to `<flakeRoot>/nix/extra-builtins.nix` ?";
+ builtins.extraBuiltins.sopsImportEncrypted;
+
+ # This "imports" an encrypted .nix.age file by evaluating the decrypted content.
+ importEncrypted =
+ path:
+ constSet (
+ if builtins.pathExists path then
+ sopsImportEncrypted path
+ else
+ { }
+ );
+in
+{
+ options = {
+ repo = {
+ secretFiles = lib.mkOption {
+ default = { };
+ type = lib.types.attrsOf lib.types.path;
+ example = lib.literalExpression "{ local = ./pii.nix.enc; }";
+ description = ''
+ This file manages the origin for this machine's repository-secrets. Anything that is
+ technically not a secret in the classical sense (i.e. that it has to be protected
+ after it has been deployed), but something you want to keep secret from the public;
+ Anything that you wouldn't want people to see on GitHub, but that can live unencrypted
+ on your own devices. Consider it a more ergonomic nix alternative to using git-crypt.
+
+ All of these secrets may (and probably will be) put into the world-readable nix-store
+ on the build and target hosts. You'll most likely want to store personally identifiable
+ information here, such as:
+ - MAC Addreses
+ - Static IP addresses
+ - Your full name (when configuring your users)
+ - Your postal address (when configuring e.g. home-assistant)
+ - ...
+
+ Each path given here must be an sops-encrypted .nix file. For each attribute `<name>`,
+ the corresponding file will be decrypted, imported and exposed as {option}`repo.secrets.<name>`.
+ '';
+ };
+
+ secrets = lib.mkOption {
+ readOnly = true;
+ default = lib.mapAttrs (_: x: importEncrypted x inputs) config.repo.secretFiles;
+ type = lib.types.unspecified;
+ description = "Exposes the loaded repo secrets. This option is read-only.";
+ };
+ };
+ swarselsystems.modules.pii = lib.mkEnableOption "enable pii management";
+ };
+ config = lib.mkIf config.swarselsystems.modules.pii {
+ repo.secretFiles =
+ let
+ local = config.node.secretsDir + "/pii.nix.enc";
+ in
+ (lib.optionalAttrs (lib.pathExists local) { inherit local; }) // {
+ common = ../../../secrets/repo/pii.nix.enc;
+ };
+ };
+ }
+
+
+
+
+
+
+3.2.1.13. Lanzaboote (secure boot)
+
+
+This dynamically uses systemd boot or Lanzaboote depending on `config.swarselsystems.initialSetup` and `config.swarselsystems.isSecureBoot`.
+
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.modules.lanzaboote = lib.mkEnableOption "lanzaboote config";
+ config = lib.mkIf config.swarselsystems.modules.lanzaboote {
+ boot = {
+ loader = {
+ efi.canTouchEfiVariables = true;
+ systemd-boot.enable = lib.swarselsystems.mkIfElse (config.swarselsystems.initialSetup || !config.swarselsystems.isSecureBoot) (lib.mkForce true) (lib.mkForce false);
+ };
+ lanzaboote = lib.mkIf (!config.swarselsystems.initialSetup && config.swarselsystems.isSecureBoot) {
+ enable = true;
+ pkiBundle = "/var/lib/sbctl";
+ configurationLimit = 6;
+ };
+ };
+ };
+}
+
+
+
+
+
+3.2.1.14. Impermanence
+
+
+This is where the impermanence magic happens. When this is enabled, the root directory is rolled back to a blanket state on each reboot.
+
+
+
+Normally, doing that also resets the lecture that happens on the first use of sudo, so we disable that at this point. Also, here we can set files to be persisted. Do note that you should still pay attention to files that need sudo access, as these need to be copied manually.
+
+
+
+{ config, lib, ... }:
+let
+ mapperTarget = lib.swarselsystems.mkIfElse config.swarselsystems.isCrypted "/dev/mapper/cryptroot" "/dev/disk/by-label/nixos";
+ inherit (config.swarselsystems) isImpermanence isCrypted;
+in
+{
+ options.swarselsystems.modules.impermanence = lib.mkEnableOption "impermanence config";
+ config = lib.mkIf config.swarselsystems.modules.impermanence {
+
+
+ security.sudo.extraConfig = lib.mkIf isImpermanence ''
+ # rollback results in sudo lectures after each reboot
+ Defaults lecture = never
+ '';
+
+ # This script does the actual wipe of the system
+ # So if it doesn't run, the btrfs system effectively acts like a normal system
+ # Taken from https://github.com/NotAShelf/nyx/blob/2a8273ed3f11a4b4ca027a68405d9eb35eba567b/modules/core/common/system/impermanence/default.nix
+ boot.tmp.useTmpfs = lib.mkIf (!isImpermanence) true;
+ boot.initrd.systemd = lib.mkIf isImpermanence {
+ enable = true;
+ services.rollback = {
+ description = "Rollback BTRFS root subvolume to a pristine state";
+ wantedBy = [ "initrd.target" ];
+ # make sure it's done after encryption
+ # i.e. LUKS/TPM process
+ after = lib.swarselsystems.mkIfElseList isCrypted [ "systemd-cryptsetup@cryptroot.service" ] [ "dev-disk-by\\x2dlabel-nixos.device" ];
+ requires = lib.mkIf (!isCrypted) [ "dev-disk-by\\x2dlabel-nixos.device" ];
+ # mount the root fs before clearing
+ before = [ "sysroot.mount" ];
+ unitConfig.DefaultDependencies = "no";
+ serviceConfig.Type = "oneshot";
+ script = ''
+ mkdir -p /mnt
+
+ # We first mount the btrfs root to /mnt
+ # so we can manipulate btrfs subvolumes.
+ mount -o subvolid=5 -t btrfs ${mapperTarget} /mnt
+ btrfs subvolume list -o /mnt/root
+
+ # While we're tempted to just delete /root and create
+ # a new snapshot from /root-blank, /root is already
+ # populated at this point with a number of subvolumes,
+ # which makes `btrfs subvolume delete` fail.
+ # So, we remove them first.
+ #
+ # /root contains subvolumes:
+ # - /root/var/lib/portables
+ # - /root/var/lib/machines
+
+ btrfs subvolume list -o /mnt/root |
+ cut -f9 -d' ' |
+ while read subvolume; do
+ echo "deleting /$subvolume subvolume..."
+ btrfs subvolume delete "/mnt/$subvolume"
+ done &&
+ echo "deleting /root subvolume..." &&
+ btrfs subvolume delete /mnt/root
+
+ echo "restoring blank /root subvolume..."
+ btrfs subvolume snapshot /mnt/root-blank /mnt/root
+
+ # Once we're done rolling back to a blank snapshot,
+ # we can unmount /mnt and continue on the boot process.
+ umount /mnt
+ '';
+ };
+ };
+
+
+ environment.persistence."/persist" = lib.mkIf isImpermanence {
+ hideMounts = true;
+ directories =
+ [
+ "/etc/nix"
+ "/etc/NetworkManager/system-connections"
+ "/var/lib/nixos"
+ "/var/tmp"
+ {
+ directory = "/var/tmp/nix-import-encrypted"; # Decrypted repo-secrets can be kept
+ mode = "1777";
+ }
+ # "/etc/secureboot"
+ ];
+
+ files = [
+ "/etc/ssh/ssh_host_ed25519_key"
+ "/etc/ssh/ssh_host_ed25519_key.pub"
+ "/etc/machine-id"
+ ];
+ };
+ };
+
+}
+
+
+
+
+
+
+3.2.2. Client
+
+
+
+3.2.2.1. Imports
+
+
+This section is for setting things that should be used on hosts that are using the default NixOS configuration. This means that servers should NOT import this, as much of these imported modules are user-configured.
+
+
+
+{ lib, inputs, ... }:
+let
+ importNames = lib.swarselsystems.readNix "modules/nixos/client";
+in
+{
+ imports = lib.swarselsystems.mkImports importNames "modules/nixos/client" ++ [
+ inputs.stylix.nixosModules.stylix
+ inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm
+ ];
+}
+
-3.3.1.6. System Packages
+3.2.2.2. System Packages
Mostly used to install some compilers and lsp's that I want to have available when not using a devShell flake. Most other packages should go in Installed packages.
@@ -7618,124 +5281,8 @@ Mostly used to install some compilers and lsp's that I want to have available wh
-
-3.3.1.7. Setup home-manager base
-
-
-We enable the use of home-manager as a NixoS module. A nice trick here is the extraSpecialArgs = inputs line, which enables the use of seflf in most parts of the configuration. This is useful to refer to the root of the flake (which is otherwise quite hard while maintaining flake purity).
-
-
-
-{ inputs, config, lib, ... }:
-{
-
- options.swarselsystems.modules.home-manager = lib.mkEnableOption "home-manager";
- config = lib.mkIf config.swarselsystems.modules.home-manager {
- home-manager = lib.mkIf config.swarselsystems.withHomeManager {
- useGlobalPkgs = true;
- useUserPackages = true;
- verbose = true;
- sharedModules = [
- inputs.nix-index-database.hmModules.nix-index
- inputs.sops-nix.homeManagerModules.sops
- {
- home.stateVersion = lib.mkDefault config.system.stateVersion;
- }
- ];
- extraSpecialArgs = { inherit (inputs) self; };
- };
- };
-}
-
-
-
-
-
-3.3.1.8. Setup home-manager specialArgs
-
-
-This sets up the nix-secrets extraSpeciaArgs. This should not be present on the chaostheatre configuration, which is why I split this section into its own file, which makes removal easier when setting that system up.
-
-
-
-{ inputs, config, lib, ... }:
-{
- options.swarselsystems.modules.home-managerExtra = lib.mkEnableOption "home-manager extras for non-chaostheatre";
- config = lib.mkIf config.swarselsystems.modules.home-managerExtra {
- home-manager = lib.mkIf config.swarselsystems.withHomeManager {
- extraSpecialArgs = { inherit (inputs) nix-secrets nixgl; };
- };
- };
-}
-
-
-
-
-
-3.3.1.9. Setup login keymap
-
-
-Next, we setup the keymap in case we are not in a graphical session. At this point, I always resort to us/altgr-intl, as it is comfortable to use and I do not write too much German anyways.
-
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.modules.xserver = lib.mkEnableOption "xserver keymap";
- config = lib.mkIf config.swarselsystems.modules.packages {
- services.xserver = {
- xkb = {
- layout = "us";
- variant = "altgr-intl";
- };
- };
- };
-}
-
-
-
-
-
-3.3.1.10. User setup, Make users non-mutable
-
-
-This ensures that all user-configuration happens here in the config file.
-In case of using a fully setup system, this makes also sure that no further user level modifications can be made using CLI utilities (e.g. usermod etc.). Everything must be defined in the flake.
-
-
-
-For that reason, make sure that sops-nix is properly working before setting the initialSetup flag, otherwise you might lose user access.
-
-
-
-{ self, pkgs, config, lib, ... }:
-let
- sopsFile = self + /secrets/general/secrets.yaml;
-in
-{
- options.swarselsystems.modules.users = lib.mkEnableOption "user config";
- config = lib.mkIf config.swarselsystems.modules.users {
- sops.secrets.swarseluser = lib.mkIf (!config.swarselsystems.isPublic) { inherit sopsFile; neededForUsers = true; };
-
- users = {
- mutableUsers = lib.mkIf (!config.swarselsystems.initialSetup) false;
- users."${config.swarselsystems.mainUser}" = {
- isNormalUser = true;
- description = "Leon S";
- password = lib.mkIf config.swarselsystems.initialSetup "setup";
- hashedPasswordFile = lib.mkIf (!config.swarselsystems.initialSetup) config.sops.secrets.swarseluser.path;
- extraGroups = [ "networkmanager" "syncthing" "docker" "wheel" "lp" "audio" "video" "vboxusers" "libvirtd" "scanner" ];
- packages = with pkgs; [ ];
- };
- };
- };
-}
-
-
-
-
-3.3.1.11. Environment setup
+3.2.2.3. Environment setup
Next, we will setup some environment variables that need to be set on the system-side. We apply some compatibility options for chromium apps on wayland, enable the wordlist and make metadata reading possible for my file explorer (nautilus).
@@ -7766,7 +5313,7 @@ Next, we will setup some environment variables that need to be set on the system
-3.3.1.12. Security
+3.2.2.4. Security
Needed for control over system-wide privileges etc. Also I make sure that the root user has access to SSH_AUTH_SOCK (without this, root will not be able to read my nix-secrets repository).
@@ -7800,7 +5347,7 @@ Needed for control over system-wide privileges etc. Also I make sure that the ro
-3.3.1.13. Reduce systemd timeouts
+3.2.2.5. Reduce systemd timeouts
There is a persistent bug over Linux kernels that makes the user wait 1m30s on system shutdown due to the reason a stop job is running for session 1 of user .... I do not want to wait that long and am confident no important data is lost by doing this.
@@ -7823,7 +5370,7 @@ There is a persistent bug over Linux kernels that makes the user wait 1m30s on s
-3.3.1.14. Hardware settings
+3.2.2.6. Hardware settings
Enable OpenGL, Sound, Bluetooth and various drivers.
@@ -7883,7 +5430,7 @@ Enable OpenGL, Sound, Bluetooth and various drivers.
-3.3.1.15. Pulseaudio
+3.2.2.7. Pulseaudio
This is only used on systems not running Pipewire.
@@ -7907,7 +5454,7 @@ This is only used on systems not running Pipewire.
-3.3.1.16. Pipewire
+3.2.2.8. Pipewire
Pipewire handles communication on Wayland. This enables several sound tools as well as screen sharing in combinaton with xdg-desktop-portal-wlr.
@@ -7939,21 +5486,80 @@ Pipewire handles communication on Wayland. This enables several sound tools as w
-3.3.1.17. Common network settings
+3.2.2.9. Common network settings
Here I only enable networkmanager and a few default networks. The rest of the network config is done separately in System specific configuration.
-{ lib, config, ... }:
+{ self, lib, config, ... }:
+let
+ certsSopsFile = self + /secrets/certs/secrets.yaml;
+ inherit (config.swarselsystems) mainUser;
+ iwd = config.networking.networkmanager.wifi.backend == "iwd";
+in
{
options.swarselsystems = {
modules.network = lib.mkEnableOption "network config";
firewall = lib.swarselsystems.mkTrueOption;
};
config = lib.mkIf config.swarselsystems.modules.network {
+
+ sops = {
+ secrets = lib.mkIf (!config.swarselsystems.isPublic) {
+ ernest = { };
+ frauns = { };
+ hotspot = { };
+ eduid = { };
+ edupass = { };
+ handyhotspot = { };
+ vpnuser = { };
+ vpnpass = { };
+ wireguardpriv = { };
+ wireguardpub = { };
+ wireguardendpoint = { };
+ stashuser = { };
+ stashpass = { };
+ githubforgeuser = { };
+ githubforgepass = { };
+ gitlabforgeuser = { };
+ gitlabforgepass = { };
+ "sweden-aes-128-cbc-udp-dns-crl-verify.pem" = { sopsFile = certsSopsFile; owner = mainUser; };
+ "sweden-aes-128-cbc-udp-dns-ca.pem" = { sopsFile = certsSopsFile; owner = mainUser; };
+ };
+ templates = lib.mkIf (!config.swarselsystems.isPublic) {
+ "network-manager.env".content = ''
+ ERNEST=${config.sops.placeholder.ernest}
+ FRAUNS=${config.sops.placeholder.frauns}
+ HOTSPOT=${config.sops.placeholder.hotspot}
+ EDUID=${config.sops.placeholder.eduid}
+ EDUPASS=${config.sops.placeholder.edupass}
+ HANDYHOTSPOT=${config.sops.placeholder.handyhotspot}
+ VPNUSER=${config.sops.placeholder.vpnuser}
+ VPNPASS=${config.sops.placeholder.vpnpass}
+ WIREGUARDPRIV=${config.sops.placeholder.wireguardpriv}
+ WIREGUARDPUB=${config.sops.placeholder.wireguardpub}
+ WIREGUARDENDPOINT=${config.sops.placeholder.wireguardendpoint}
+ '';
+ };
+ };
+
networking = {
+ wireless.iwd = {
+ enable = true;
+ settings = {
+ IPv6 = {
+ Enabled = true;
+ };
+ Settings = {
+ AutoConnect = true;
+ };
+ DriverQuirks = {
+ UseDefaultInterface = true;
+ };
+ };
+ };
nftables.enable = lib.mkDefault true;
enableIPv6 = lib.mkDefault true;
firewall = {
@@ -7970,6 +5576,7 @@ Here I only enable networkmanager and a few default networks. The r
networkmanager = {
enable = true;
+ wifi.backend = "iwd";
ensureProfiles = lib.mkIf (!config.swarselsystems.isPublic) {
environmentFiles = [
"${config.sops.templates."network-manager.env".path}"
@@ -8023,10 +5630,11 @@ Here I only enable networkmanager and a few default networks. The r
eduroam = {
"802-1x" = {
- eap = "ttls;";
+ eap = if (!iwd) then "ttls;" else "peap;";
identity = "$EDUID";
password = "$EDUPASS";
phase2-auth = "mschapv2";
+ anonymous-identity = lib.mkIf iwd "anonymous@student.tuwien.ac.at";
};
connection = {
id = "eduroam";
@@ -8201,91 +5809,8 @@ Here I only enable networkmanager and a few default networks. The r
-
-3.3.1.18. Time, locale settings
-
-
-Setup timezone and locale. I want to use the US layout, but have the rest adapted to my country and timezone. Also, there is an issue with running Windows/Linux dualboot on the same machine where the hardware clock desyncs between the two OS'es. We fix that bug here as well.
-
-
-
-{ lib, config, ... }:
-{
- options.swarselsystems.modules.time = lib.mkEnableOption "time config";
- config = lib.mkIf config.swarselsystems.modules.time {
- time = {
- timeZone = "Europe/Vienna";
- # hardwareClockInLocalTime = true;
- };
-
- i18n = {
- defaultLocale = "en_US.UTF-8";
- extraLocaleSettings = {
- LC_ADDRESS = "de_AT.UTF-8";
- LC_IDENTIFICATION = "de_AT.UTF-8";
- LC_MEASUREMENT = "de_AT.UTF-8";
- LC_MONETARY = "de_AT.UTF-8";
- LC_NAME = "de_AT.UTF-8";
- LC_NUMERIC = "de_AT.UTF-8";
- LC_PAPER = "de_AT.UTF-8";
- LC_TELEPHONE = "de_AT.UTF-8";
- LC_TIME = "de_AT.UTF-8";
- };
- };
- };
-}
-
-
-
-
-
-3.3.1.19. Meta options
-
-
-{ lib, ... }:
-{
- options = {
- node = {
- secretsDir = lib.mkOption {
- description = "Path to the secrets directory for this node.";
- type = lib.types.path;
- default = ./.;
- };
- name = lib.mkOption {
- description = "Node Name.";
- type = lib.types.str;
- };
- };
- };
-}
-
-
-
-
-
-3.3.1.20. Topology
-
-
-{ self, lib, config, ... }:
-{
- options.swarselsystems.info = lib.mkOption {
- type = lib.types.str;
- default = "";
- };
- config.topology = {
- id = config.node.name;
- self = {
- hardware.info = config.swarselsystems.info;
- icon = lib.mkIf config.swarselsystems.isLaptop "devices.laptop";
- };
- };
-}
-
-
-
-
-3.3.1.21. sops
+3.2.2.10. sops
I use sops-nix to handle secrets that I want to have available on my machines at all times. Procedure to add a new machine:
@@ -8299,148 +5824,28 @@ I use sops-nix to handle secrets that I want to have available on my machines at
-{ self, config, lib, ... }:
-let
- certsSopsFile = self + /secrets/certs/secrets.yaml;
- inherit (config.swarselsystems) mainUser homeDir;
-in
+{ config, lib, ... }:
{
- options.swarselsystems.modules.commonSops = lib.mkEnableOption "sops config";
- config = lib.mkIf config.swarselsystems.modules.commonSops {
+ options.swarselsystems.modules.sops = lib.mkEnableOption "sops config";
+ config = lib.mkIf config.swarselsystems.modules.sops {
sops = {
- age.sshKeyPaths = lib.swarselsystems.mkIfElseList config.swarselsystems.isBtrfs [ "/persist/.ssh/sops" "/persist/.ssh/ssh_host_ed25519_key" ] [ "${homeDir}/.ssh/sops" "/etc/ssh/ssh_host_ed25519_key" ];
- defaultSopsFile = lib.swarselsystems.mkIfElseList config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${homeDir}/.dotfiles/secrets/general/secrets.yaml";
+ # 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 = [ "${config.swarselsystems.homeDir}/.ssh/sops" "/etc/ssh/sops" "/etc/ssh/ssh_host_ed25519_key" ];
+ # defaultSopsFile = lib.swarselsystems.mkIfElseList config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${config.swarselsystems.flakePath}/secrets/general/secrets.yaml";
+ defaultSopsFile = "${config.swarselsystems.flakePath}/secrets/general/secrets.yaml";
validateSopsFiles = false;
- secrets = lib.mkIf (!config.swarselsystems.isPublic) {
- ernest = { };
- frauns = { };
- hotspot = { };
- eduid = { };
- edupass = { };
- handyhotspot = { };
- vpnuser = { };
- vpnpass = { };
- wireguardpriv = { };
- wireguardpub = { };
- wireguardendpoint = { };
- stashuser = { };
- stashpass = { };
- githubforgeuser = { };
- githubforgepass = { };
- gitlabforgeuser = { };
- gitlabforgepass = { };
- "sweden-aes-128-cbc-udp-dns-crl-verify.pem" = { sopsFile = certsSopsFile; owner = mainUser; };
- "sweden-aes-128-cbc-udp-dns-ca.pem" = { sopsFile = certsSopsFile; owner = mainUser; };
- };
- templates = lib.mkIf (!config.swarselsystems.isPublic) {
- "network-manager.env".content = ''
- ERNEST=${config.sops.placeholder.ernest}
- FRAUNS=${config.sops.placeholder.frauns}
- HOTSPOT=${config.sops.placeholder.hotspot}
- EDUID=${config.sops.placeholder.eduid}
- EDUPASS=${config.sops.placeholder.edupass}
- HANDYHOTSPOT=${config.sops.placeholder.handyhotspot}
- VPNUSER=${config.sops.placeholder.vpnuser}
- VPNPASS=${config.sops.placeholder.vpnpass}
- WIREGUARDPRIV=${config.sops.placeholder.wireguardpriv}
- WIREGUARDPUB=${config.sops.placeholder.wireguardpub}
- WIREGUARDENDPOINT=${config.sops.placeholder.wireguardendpoint}
- '';
- };
};
};
}
-
-
-
-
-
-3.3.1.22. PII management
-
-
-# largely based on https://github.com/oddlama/nix-config/blob/main/modules/secrets.nix
-{ config, inputs, lib, ... }:
-let
-
- # If the given expression is a bare set, it will be wrapped in a function,
- # so that the imported file can always be applied to the inputs, similar to
- # how modules can be functions or sets.
- constSet = x: if builtins.isAttrs x then (_: x) else x;
-
- # Try to access the extra builtin we loaded via nix-plugins.
- # Throw an error if that doesn't exist.
- sopsImportEncrypted =
- assert lib.assertMsg (builtins ? extraBuiltins.sopsImportEncrypted)
- "The extra builtin 'sopsImportEncrypted' is not available, so repo.secrets cannot be decrypted. Did you forget to add nix-plugins and point it to `<flakeRoot>/nix/extra-builtins.nix` ?";
- builtins.extraBuiltins.sopsImportEncrypted;
-
- # This "imports" an encrypted .nix.age file by evaluating the decrypted content.
- importEncrypted =
- path:
- constSet (
- if builtins.pathExists path then
- sopsImportEncrypted path
- else
- { }
- );
-in
-{
- options = {
- repo = {
- secretFiles = lib.mkOption {
- default = { };
- type = lib.types.attrsOf lib.types.path;
- example = lib.literalExpression "{ local = ./pii.nix.enc; }";
- description = ''
- This file manages the origin for this machine's repository-secrets. Anything that is
- technically not a secret in the classical sense (i.e. that it has to be protected
- after it has been deployed), but something you want to keep secret from the public;
- Anything that you wouldn't want people to see on GitHub, but that can live unencrypted
- on your own devices. Consider it a more ergonomic nix alternative to using git-crypt.
-
- All of these secrets may (and probably will be) put into the world-readable nix-store
- on the build and target hosts. You'll most likely want to store personally identifiable
- information here, such as:
- - MAC Addreses
- - Static IP addresses
- - Your full name (when configuring your users)
- - Your postal address (when configuring e.g. home-assistant)
- - ...
-
- Each path given here must be an sops-encrypted .nix file. For each attribute `<name>`,
- the corresponding file will be decrypted, imported and exposed as {option}`repo.secrets.<name>`.
- '';
- };
-
- secrets = lib.mkOption {
- readOnly = true;
- default = lib.mapAttrs (_: x: importEncrypted x inputs) config.repo.secretFiles;
- type = lib.types.unspecified;
- description = "Exposes the loaded repo secrets. This option is read-only.";
- };
- };
- swarselsystems.modules.pii = lib.mkEnableOption "enable pii management";
- };
- config = lib.mkIf config.swarselsystems.modules.pii {
- repo.secretFiles =
- let
- local = config.node.secretsDir + "/pii.nix.enc";
- in
- (lib.optionalAttrs (lib.pathExists local) { inherit local; }) // {
- common = ../../../secrets/repo/pii.nix.enc;
- };
- };
- }
-
-3.3.1.23. Theme (stylix)
+3.2.2.11. Theme (stylix)
-3.3.1.24. Programs (including zsh setup)
+3.2.2.12. Programs (including zsh setup)
Some programs profit from being installed through dedicated NixOS settings on system-level; these go here. Notably the zsh setup goes here and cannot be deleted under any circumstances.
@@ -8492,7 +5897,7 @@ Some programs profit from being installed through dedicated NixOS settings on sy
-3.3.1.24.1. zsh
+3.2.2.12.1. zsh
Here I disable global completion to prevent redundant compinit calls and cache invalidation that slow down shell startup (enabled on the home-manager side).
@@ -8517,7 +5922,7 @@ Here I disable global completion to prevent redundant compinit calls and cache i
-3.3.1.24.2. syncthing
+3.2.2.12.2. syncthing
{ lib, config, pkgs, ... }:
@@ -8586,14 +5991,14 @@ in
-3.3.1.25. Services
+3.2.2.13. Services
Setting up some hardware services as well as keyboard related settings. Here we make sure that we can use the CAPS key as a ESC/CTRL double key, which is a lifesaver.
-3.3.1.25.1. blueman
+3.2.2.13.1. blueman
Enables the blueman service including the nice system tray icon.
@@ -8613,7 +6018,7 @@ Enables the blueman service including the nice system tray icon.
-3.3.1.25.2. Network devices
+3.2.2.13.2. Network devices
In this section we enable compatibility with several network devices I have at home, mainly printers and scanners.
@@ -8664,7 +6069,7 @@ Avahi is the service used for the network discovery.
-3.3.1.25.3. enable GVfs
+3.2.2.13.3. enable GVfs
This is being set to allow myself to use all functions of nautilus in NixOS
@@ -8683,7 +6088,7 @@ This is being set to allow myself to use all functions of nautilus in NixOS
-3.3.1.25.4. interception-tools: Make CAPS work as ESC/CTRL
+3.2.2.13.4. interception-tools: Make CAPS work as ESC/CTRL
This is a super-convenient package that lets my remap my CAPS key to ESC if pressed shortly, and CTRL if being held.
@@ -8727,7 +6132,7 @@ This is a super-convenient package that lets my remap my CAPS key t
-3.3.1.25.5. power-profiles-daemon
+3.2.2.13.5. power-profiles-daemon
This enables power profile management. The available modes are:
@@ -8756,7 +6161,7 @@ Most of the time I am using power-saver, however, it is good to be
-3.3.1.25.6. SwayOSD
+3.2.2.13.6. SwayOSD
{ lib, pkgs, config, ... }:
@@ -8787,11 +6192,11 @@ Most of the time I am using power-saver, however, it is good to be
-3.3.1.26. Hardware compatibility settings (Yubikey, Ledger, Keyboards) - udev rules
+3.2.2.14. Hardware compatibility settings (Yubikey, Ledger, Keyboards) - udev rules
-3.3.1.26.1. Yubikey
+3.2.2.14.1. Yubikey
This takes care of the main Yubikey related configuration on the NixOS side - note that the starting of the gpg-agent is done in the sway settings, to also perform this step of the setup for non NixOS-machines at the same time.
@@ -8831,7 +6236,7 @@ Also, since I use a GPG key in sops, it seems that scdaemon creates an instance
-3.3.1.26.2. Ledger
+3.2.2.14.2. Ledger
This performs the necessary configuration to support this hardware.
@@ -8855,7 +6260,7 @@ This performs the necessary configuration to support this hardware.
-3.3.1.26.3. Keyboards
+3.2.2.14.3. Keyboards
This loads some udev rules that I need for my split keyboards.
@@ -8879,7 +6284,7 @@ This loads some udev rules that I need for my split keyboards.
-3.3.1.27. System Login
+3.2.2.15. System Login
This section houses the greetd related settings. I do not really want to use a display manager, but it is useful to have setup in some ways - in my case for starting sway on system startup. Notably the default user login setting that is commented out here goes into the system specific settings, make sure to update it there
@@ -8914,7 +6319,7 @@ This section houses the greetd related settings. I do not really want to use a d
-3.3.1.28. nix-ld
+3.2.2.16. nix-ld
This provides libraries for binaries that are not patched for use on NixOS. This really makes the biggest gripe with NixOS go away, that being having to run a binary that is only found in a single spot. It is most of the times possible to patch such a file, but this makes such a situation take much less time to resolve.
@@ -9046,115 +6451,8 @@ When a program does not work, start with nix-ldd <program>. T
-
-3.3.1.29. Impermanence
-
-
-This is where the impermanence magic happens. When this is enabled, the root directory is rolled back to a blanket state on each reboot.
-
-
-
-Normally, doing that also resets the lecture that happens on the first use of sudo, so we disable that at this point. Also, here we can set files to be persisted. Do note that you should still pay attention to files that need sudo access, as these need to be copied manually.
-
-
-
-{ config, lib, ... }:
-let
- mapperTarget = lib.swarselsystems.mkIfElse config.swarselsystems.isCrypted "/dev/mapper/cryptroot" "/dev/disk/by-label/nixos";
- inherit (config.swarselsystems) isImpermanence isCrypted;
-in
-{
- options.swarselsystems.modules.impermanence = lib.mkEnableOption "impermanence config";
- config = lib.mkIf config.swarselsystems.modules.impermanence {
-
- security.sudo.extraConfig = lib.mkIf isImpermanence ''
- # rollback results in sudo lectures after each reboot
- Defaults lecture = never
- '';
-
- # This script does the actual wipe of the system
- # So if it doesn't run, the btrfs system effectively acts like a normal system
- # Taken from https://github.com/NotAShelf/nyx/blob/2a8273ed3f11a4b4ca027a68405d9eb35eba567b/modules/core/common/system/impermanence/default.nix
-
- boot.initrd.systemd.enable = lib.mkIf isImpermanence true;
-
- boot.initrd.systemd.services.rollback = lib.mkIf isImpermanence {
- description = "Rollback BTRFS root subvolume to a pristine state";
- wantedBy = [ "initrd.target" ];
- # make sure it's done after encryption
- # i.e. LUKS/TPM process
- after = lib.swarselsystems.mkIfElseList isCrypted [ "systemd-cryptsetup@cryptroot.service" ] [ "dev-disk-by\\x2dlabel-nixos.device" ];
- requires = lib.mkIf (!isCrypted) [ "dev-disk-by\\x2dlabel-nixos.device" ];
- # mount the root fs before clearing
- before = [ "sysroot.mount" ];
- unitConfig.DefaultDependencies = "no";
- serviceConfig.Type = "oneshot";
- script = ''
- mkdir -p /mnt
-
- # We first mount the btrfs root to /mnt
- # so we can manipulate btrfs subvolumes.
- mount -o subvolid=5 -t btrfs ${mapperTarget} /mnt
- btrfs subvolume list -o /mnt/root
-
- # While we're tempted to just delete /root and create
- # a new snapshot from /root-blank, /root is already
- # populated at this point with a number of subvolumes,
- # which makes `btrfs subvolume delete` fail.
- # So, we remove them first.
- #
- # /root contains subvolumes:
- # - /root/var/lib/portables
- # - /root/var/lib/machines
-
- btrfs subvolume list -o /mnt/root |
- cut -f9 -d' ' |
- while read subvolume; do
- echo "deleting /$subvolume subvolume..."
- btrfs subvolume delete "/mnt/$subvolume"
- done &&
- echo "deleting /root subvolume..." &&
- btrfs subvolume delete /mnt/root
-
- echo "restoring blank /root subvolume..."
- btrfs subvolume snapshot /mnt/root-blank /mnt/root
-
- # Once we're done rolling back to a blank snapshot,
- # we can unmount /mnt and continue on the boot process.
- umount /mnt
- '';
- };
-
-
- environment.persistence."/persist" = lib.mkIf isImpermanence {
- hideMounts = true;
- directories =
- [
- "/etc/nix"
- "/etc/NetworkManager/system-connections"
- "/var/lib/nixos"
- {
- directory = "/var/tmp/nix-import-encrypted"; # Decrypted repo-secrets can be kept
- mode = "1777";
- }
- # "/etc/secureboot"
- ];
-
- files = [
- "/etc/ssh/ssh_host_ed25519_key"
- "/etc/ssh/ssh_host_ed25519_key.pub"
- "/etc/machine-id"
- ];
- };
- };
-
-}
-
-
-
-
-3.3.1.30. Summary of nixos-rebuild diff
+3.2.2.17. Summary of nixos-rebuild diff
This snipped is added to the activation script that is run after every rebuild and shows what packages have been added and removed. This is actually not the optimal place to add that snipped, but the correct spot is in some perl file that I have not had the leisure to take a look at yet.
@@ -9179,7 +6477,7 @@ This snipped is added to the activation script that is run after every rebuild a
-3.3.1.31. gnome-keyring
+3.2.2.18. gnome-keyring
Used for storing sessions in e.g. Nextcloud. Using this on a system level keeps the login information when logging out of the session as well.
@@ -9202,7 +6500,7 @@ Used for storing sessions in e.g. Nextcloud. Using this on a system level keeps
-3.3.1.32. Sway
+3.2.2.19. Sway
This is used to better integrate Sway into the system on NixOS hosts. On the home-manager side, the package attribute will be null for such an host, using the systems derivation instead.
@@ -9238,7 +6536,7 @@ This is used to better integrate Sway into the system on NixOS hosts. On the hom
-3.3.1.33. xdg-portal
+3.2.2.20. xdg-portal
This allows me to use screen sharing on Wayland. The implementation is a bit crude and only the whole screen can be shared. However, most of the time that is all I need to do anyways.
@@ -9270,7 +6568,7 @@ This allows me to use screen sharing on Wayland. The implementation is a bit cru
-3.3.1.34. Podmam (distrobox)
+3.2.2.21. Podmam (distrobox)
I am using distrobox to quickly circumvent isses that I cannot immediately solve on NixOS. It is always the goal to quickly get things working on NixOS, but this prevents me from getting completely stuck.
@@ -9298,7 +6596,7 @@ I am using distrobox to quickly circumvent isses that I cannot immediately solve
-3.3.1.35. Appimage
+3.2.2.22. Appimage
Adds the necessary tools to allow .appimage programs easily.
@@ -9321,7 +6619,7 @@ Adds the necessary tools to allow .appimage programs easily.
-3.3.1.36. Handle lid switch correctly
+3.2.2.23. Handle lid switch correctly
This turns off the display when the lid is closed.
@@ -9370,7 +6668,7 @@ This turns off the display when the lid is closed.
-3.3.1.37. Low battery notification
+3.2.2.24. Low battery notification
Since I hide the waybar completely during normal operation, I run the risk of not noticing when my battery is about to run out. This module sends a notification when the battery level falls below 10%. Written by cafkafk.
@@ -9410,28 +6708,24 @@ Since I hide the waybar completely during normal operation, I run the risk of no
-
-3.3.1.38. Lanzaboote
-
+
+3.2.2.25. Auto-login
+
-This dynamically uses systemd boot or Lanzaboote depending on `config.swarselsystems.initialSetup` and `config.swarselsystems.isSecureBoot`.
+Auto login for the initial session.
{ lib, config, ... }:
+let
+ inherit (config.swarselsystems) mainUser;
+in
{
- options.swarselsystems.modules.lanzaboote = lib.mkEnableOption "lanzaboote config";
- config = lib.mkIf config.swarselsystems.modules.lanzaboote {
- boot = {
- loader = {
- efi.canTouchEfiVariables = true;
- systemd-boot.enable = lib.swarselsystems.mkIfElse (config.swarselsystems.initialSetup || !config.swarselsystems.isSecureBoot) (lib.mkForce true) (lib.mkForce false);
- };
- lanzaboote = lib.mkIf (!config.swarselsystems.initialSetup && config.swarselsystems.isSecureBoot) {
- enable = true;
- pkiBundle = "/var/lib/sbctl";
- configurationLimit = 6;
- };
+ options.swarselsystems.modules.autologin = lib.mkEnableOption "optional autologin settings";
+ config = lib.mkIf config.swarselsystems.modules.autologin {
+ services = {
+ getty.autologinUser = mainUser;
+ greetd.settings.initial_session.user = mainUser;
};
};
}
@@ -9441,11 +6735,11 @@ This dynamically uses systemd boot or Lanzaboote depending on `config.swarselsys
-3.3.2. Server
+3.2.3. Server
-3.3.2.1. Imports
+3.2.3.1. Imports
First, we enable the use of home-manager as a NixoS module.
@@ -9460,30 +6754,19 @@ Also, the system state version is set here. No need to touch it.
-{ self, lib, ... }:
+{ lib, ... }:
let
importNames = lib.swarselsystems.readNix "modules/nixos/server";
- modulesPath = "${self}/modules";
in
{
- imports = lib.swarselsystems.mkImports importNames "modules/nixos/server" ++ [
- "${modulesPath}/nixos/common/settings.nix"
- "${modulesPath}/nixos/common/home-manager.nix"
- "${modulesPath}/nixos/common/home-manager-extra.nix"
- "${modulesPath}/nixos/common/xserver.nix"
- "${modulesPath}/nixos/common/time.nix"
- "${modulesPath}/nixos/common/users.nix"
- "${modulesPath}/nixos/common/nix-ld.nix"
- "${modulesPath}/nixos/common/sharedsetup.nix"
- "${modulesPath}/home/common/sharedsetup.nix"
- ];
+ imports = lib.swarselsystems.mkImports importNames "modules/nixos/server";
}
-3.3.2.2. General NixOS Server settings
+3.2.3.2. General NixOS Server settings
Here we just define some aliases for rebuilding the system, and we allow some insecure packages that are needed by some server derivations. It would be more elegant to define these in the respective module, but nixpkgs needs to be defined before we can evaluate modules within it, so this must be a top-level configuration.
@@ -9532,7 +6815,7 @@ in
-3.3.2.3. System Packages
+3.2.3.3. System Packages
{ lib, config, pkgs, ... }:
@@ -9557,30 +6840,14 @@ in
-
-3.3.2.4. sops
-
-
-{ config, lib, ... }:
-{
- options.swarselsystems.modules.server.sops = lib.mkEnableOption "enable sops on server";
- config = lib.mkIf config.swarselsystems.modules.server.sops {
- sops = {
- age.sshKeyPaths = lib.mkDefault [ "/etc/ssh/sops" ];
- defaultSopsFile = lib.mkDefault "${config.swarselsystems.flakePath}/secrets/winters/secrets.yaml";
- validateSopsFiles = false;
- };
- };
-}
-
-
-
-
-3.3.2.5. nfs/samba (smb)
+3.2.3.4. nfs/samba (smb)
-{ lib, config, pkgs, ... }:
+{ lib, config, pkgs, globals, ... }:
+let
+ nfsUser = globals.user.name;
+in
{
options.swarselsystems.modules.server.nfs = lib.mkEnableOption "enable nfs on server";
config = lib.mkIf config.swarselsystems.modules.server.nfs {
@@ -9611,7 +6878,7 @@ in
path = "/Vault/Eternor";
writable = "true";
comment = "Eternor";
- "valid users" = "Swarsel";
+ "valid users" = nfsUser;
};
};
@@ -9636,10 +6903,14 @@ in
-3.3.2.6. NGINX
+3.2.3.5. NGINX
{ pkgs, lib, config, ... }:
+let
+ inherit (config.repo.secrets.common) dnsProvider;
+ inherit (config.repo.secrets.common.mail) address3;
+in
{
options.swarselsystems.modules.server.nginx = lib.mkEnableOption "enable nginx on server";
config = lib.mkIf config.swarselsystems.modules.server.nginx {
@@ -9659,8 +6930,8 @@ in
acceptTerms = true;
preliminarySelfsigned = false;
defaults = {
- email = "mrswarsel@gmail.com";
- dnsProvider = "cloudflare";
+ inherit dnsProvider;
+ email = address3;
environmentFile = "${config.sops.templates."certs.secret".path}";
};
};
@@ -9681,7 +6952,7 @@ in
-3.3.2.7. ssh
+3.2.3.6. ssh
Here I am forcing startWhenNeeded to false so that the value will not be set to true in containers = this would be a problem because it would delay ssh host key generation.
@@ -9725,49 +6996,49 @@ Here I am forcing startWhenNeeded to false so that the value will n
-3.3.2.8. kavita
+3.2.3.7. kavita
{ self, lib, config, pkgs, ... }:
let
+ servicePort = 8080;
serviceName = "kavita";
serviceUser = "kavita";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
- servicePort = 8080;
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
environment.systemPackages = with pkgs; [
calibre
];
- users.users."${serviceUser}" = {
+ users.users.${serviceUser} = {
extraGroups = [ "users" ];
};
sops.secrets.kavita = { owner = serviceUser; };
- networking.firewall.allowedTCPPorts = [ 8080 ];
+ networking.firewall.allowedTCPPorts = [ servicePort ];
- topology.self.services.kavita = {
+ topology.self.services.${serviceName} = {
name = "Kavita";
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/kavita.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
- services.kavita = {
+ services.${serviceName} = {
enable = true;
user = serviceUser;
settings.Port = servicePort;
tokenKeyFile = config.sops.secrets.kavita.path;
- dataDir = "/Vault/data/kavita";
+ dataDir = "/Vault/data/${serviceName}";
};
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -9796,20 +7067,20 @@ in
-3.3.2.9. jellyfin
+3.2.3.8. jellyfin
{ pkgs, lib, config, ... }:
let
- serviceDomain = "screen.swarsel.win";
servicePort = 8096;
serviceName = "jellyfin";
serviceUser = "jellyfin";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
- users.users."${serviceUser}" = {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
+ users.users.${serviceUser} = {
extraGroups = [ "video" "render" "users" ];
};
nixpkgs.config.packageOverrides = pkgs: {
@@ -9828,7 +7099,7 @@ in
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName}.domain = serviceDomain;
- services.jellyfin = {
+ services.${serviceName} = {
enable = true;
user = serviceUser;
openFirewall = true; # this works only for the default ports
@@ -9836,7 +7107,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -9866,20 +7137,20 @@ in
-3.3.2.10. navidrome
+3.2.3.9. navidrome
{ pkgs, config, lib, ... }:
let
- serviceDomain = "sound.swarsel.win";
servicePort = 4040;
serviceName = "navidrome";
serviceUser = "navidrome";
serviceGroup = serviceUser;
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
environment.systemPackages = with pkgs; [
pciutils
alsa-utils
@@ -9888,13 +7159,13 @@ in
users = {
groups = {
- "${serviceGroup}" = {
+ ${serviceGroup} = {
gid = 61593;
};
};
users = {
- "${serviceUser}" = {
+ ${serviceUser} = {
isSystemUser = true;
uid = 61593;
group = serviceGroup;
@@ -9907,11 +7178,11 @@ in
enableAllFirmware = lib.mkForce true;
};
- networking.firewall.allowedTCPPorts = [ 4040 ];
+ networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.${serviceName}.domain = serviceDomain;
- services.navidrome = {
+ services.${serviceName} = {
enable = true;
openFirewall = true;
settings = {
@@ -9953,7 +7224,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -9979,19 +7250,19 @@ in
in
{
"/" = {
- proxyPass = "http://navidrome";
+ proxyPass = "http://${serviceName}";
proxyWebsockets = true;
inherit extraConfig;
};
"/share" = {
- proxyPass = "http://navidrome";
+ proxyPass = "http://${serviceName}";
proxyWebsockets = true;
setOauth2Headers = false;
bypassAuth = true;
inherit extraConfig;
};
"/rest" = {
- proxyPass = "http://navidrome";
+ proxyPass = "http://${serviceName}";
proxyWebsockets = true;
setOauth2Headers = false;
bypassAuth = true;
@@ -10010,7 +7281,7 @@ in
-3.3.2.11. spotifyd
+3.2.3.10. spotifyd
{ lib, config, ... }:
@@ -10021,13 +7292,13 @@ let
serviceGroup = serviceUser;
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
- users.groups."${serviceGroup}" = {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
+ users.groups.${serviceGroup} = {
gid = 65136;
};
- users.users."${serviceUser}" = {
+ users.users.${serviceUser} = {
isSystemUser = true;
uid = 65136;
group = serviceGroup;
@@ -10059,29 +7330,35 @@ in
-3.3.2.12. mpd
+3.2.3.11. mpd
{ self, lib, config, pkgs, ... }:
+let
+ servicePort = 3254;
+ serviceUser = "mpd";
+ serviceGroup = serviceUser;
+ serviceName = "mpd";
+in
{
- options.swarselsystems.modules.server.mpd = lib.mkEnableOption "enable mpd on server";
- config = lib.mkIf config.swarselsystems.modules.server.mpd {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users = {
groups = {
mpd = { };
};
users = {
- mpd = {
+ ${serviceUser} = {
isSystemUser = true;
- group = "mpd";
+ group = serviceGroup;
extraGroups = [ "audio" "utmp" ];
};
};
};
sops = {
- secrets.mpdpass = { owner = "mpd"; };
+ secrets.mpdpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
};
environment.systemPackages = with pkgs; [
@@ -10090,19 +7367,19 @@ in
mpv
];
- topology.self.services.mpd = {
- name = "MPD";
- info = "http://localhost:3254";
- icon = "${self}/topology/images/mpd.png";
+ topology.self.services.${serviceName} = {
+ name = lib.toUpper serviceName;
+ info = "http://localhost:${builtins.toString servicePort}";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
- services.mpd = {
+ services.${serviceName} = {
enable = true;
musicDirectory = "/media";
- user = "mpd";
- group = "mpd";
+ user = serviceUser;
+ group = serviceGroup;
network = {
- port = 3254;
+ port = servicePort;
listenAddress = "any";
};
credentials = [
@@ -10125,7 +7402,7 @@ in
-3.3.2.13. pipewire
+3.2.3.12. pipewire
{ lib, config, ... }:
@@ -10153,7 +7430,7 @@ in
-3.3.2.14. postgresql
+3.2.3.13. postgresql
{ config, lib, pkgs, ... }:
@@ -10162,13 +7439,13 @@ let
postgresVersion = 14;
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
services = {
- postgresql = {
+ ${serviceName} = {
enable = true;
package = pkgs."postgresql_${builtins.toString postgresVersion}";
- dataDir = "/Vault/data/postgresql/${builtins.toString postgresVersion}";
+ dataDir = "/Vault/data/${serviceName}/${builtins.toString postgresVersion}";
};
};
};
@@ -10178,22 +7455,23 @@ in
-3.3.2.15. matrix
+3.2.3.14. matrix
{ lib, config, pkgs, ... }:
let
- matrixDomain = "swatrix.swarsel.win";
+ servicePort = 8008;
serviceName = "matrix";
- synapsePort = 8008;
- synapseUser = "matrix-synapse";
+ serviceDomain = config.repo.secrets.common.services.domains.matrix;
+ serviceUser = "matrix-synapse";
+
+ federationPort = 8448;
whatsappPort = 29318;
telegramPort = 29317;
signalPort = 29328;
-
- baseUrl = "https://${matrixDomain}";
+ baseUrl = "https://${serviceDomain}";
clientConfig."m.homeserver".base_url = baseUrl;
- serverConfig."m.server" = "${matrixDomain}:443";
+ serverConfig."m.server" = "${serviceDomain}:443";
mkWellKnown = data: ''
default_type application/json;
add_header Access-Control-Allow-Origin *;
@@ -10201,8 +7479,8 @@ let
'';
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
environment.systemPackages = with pkgs; [
matrix-synapse
lottieconverter
@@ -10211,24 +7489,24 @@ in
sops = {
secrets = {
- matrixsharedsecret = { owner = synapseUser; };
- mautrixtelegram_as = { owner = synapseUser; };
- mautrixtelegram_hs = { owner = synapseUser; };
- mautrixtelegram_api_id = { owner = synapseUser; };
- mautrixtelegram_api_hash = { owner = synapseUser; };
+ matrixsharedsecret = { owner = serviceUser; };
+ mautrixtelegram_as = { owner = serviceUser; };
+ mautrixtelegram_hs = { owner = serviceUser; };
+ mautrixtelegram_api_id = { owner = serviceUser; };
+ mautrixtelegram_api_hash = { owner = serviceUser; };
};
templates = {
"matrix_user_register.sh".content = ''
- register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:${builtins.toString synapsePort}
+ register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:${builtins.toString servicePort}
'';
matrixshared = {
- owner = synapseUser;
+ owner = serviceUser;
content = ''
registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret}
'';
};
mautrixtelegram = {
- owner = synapseUser;
+ owner = serviceUser;
content = ''
MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as}
MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs}
@@ -10239,7 +7517,7 @@ in
};
};
- networking.firewall.allowedTCPPorts = [ 8008 8448 ];
+ networking.firewall.allowedTCPPorts = [ servicePort federationPort ];
systemd = {
timers."restart-bridges" = {
@@ -10270,7 +7548,7 @@ in
};
};
- globals.services.${serviceName}.domain = matrixDomain;
+ globals.services.${serviceName}.domain = serviceDomain;
services = {
postgresql = {
@@ -10303,20 +7581,21 @@ in
enable = true;
dataDir = "/Vault/data/matrix-synapse";
settings = {
- app_service_config_files = let
- inherit (config.services.matrix-synapse) dataDir;
- in
+ app_service_config_files =
+ let
+ inherit (config.services.matrix-synapse) dataDir;
+ in
[
- "${dataDir}/telegram-registration.yaml"
- "${dataDir}/whatsapp-registration.yaml"
- "${dataDir}/signal-registration.yaml"
- "${dataDir}/doublepuppet.yaml"
- ];
- server_name = matrixDomain;
- public_baseurl = "https://${matrixDomain}";
+ "${dataDir}/telegram-registration.yaml"
+ "${dataDir}/whatsapp-registration.yaml"
+ "${dataDir}/signal-registration.yaml"
+ "${dataDir}/doublepuppet.yaml"
+ ];
+ server_name = serviceDomain;
+ public_baseurl = "https://${serviceDomain}";
listeners = [
{
- port = synapsePort;
+ port = servicePort;
bind_addresses = [
"0.0.0.0"
# "::1"
@@ -10344,8 +7623,8 @@ in
registerToSynapse = false;
settings = {
homeserver = {
- address = "http://localhost:${builtins.toString synapsePort}";
- domain = matrixDomain;
+ address = "http://localhost:${builtins.toString servicePort}";
+ domain = serviceDomain;
};
appservice = {
address = "http://localhost:${builtins.toString telegramPort}";
@@ -10370,7 +7649,7 @@ in
telegram_link_preview = true;
permissions = {
"*" = "relaybot";
- "@swarsel:${matrixDomain}" = "admin";
+ "@swarsel:${serviceDomain}" = "admin";
};
animated_sticker = {
target = "gif";
@@ -10390,8 +7669,8 @@ in
registerToSynapse = false;
settings = {
homeserver = {
- address = "http://localhost:${builtins.toString synapsePort}";
- domain = matrixDomain;
+ address = "http://localhost:${builtins.toString servicePort}";
+ domain = serviceDomain;
};
appservice = {
address = "http://localhost:${builtins.toString whatsappPort}";
@@ -10416,7 +7695,7 @@ in
};
};
login_shared_secret_map = {
- matrixDomain = "as_token:doublepuppet";
+ ${serviceDomain} = "as_token:doublepuppet";
};
sync_manual_marked_unread = true;
send_presence_on_typing = true;
@@ -10426,7 +7705,7 @@ in
extev_polls = true;
permissions = {
"*" = "relay";
- "@swarsel:${matrixDomain}" = "admin";
+ "@swarsel:${serviceDomain}" = "admin";
};
};
};
@@ -10437,8 +7716,8 @@ in
registerToSynapse = false;
settings = {
homeserver = {
- address = "http://localhost:${builtins.toString synapsePort}";
- domain = matrixDomain;
+ address = "http://localhost:${builtins.toString servicePort}";
+ domain = serviceDomain;
};
appservice = {
address = "http://localhost:${builtins.toString signalPort}";
@@ -10452,12 +7731,12 @@ in
bridge = {
displayname_template = "{{or .ContactName .ProfileName .PhoneNumber}} (Signal)";
login_shared_secret_map = {
- matrixDomain = "as_token:doublepuppet";
+ ${serviceDomain} = "as_token:doublepuppet";
};
caption_in_message = true;
permissions = {
"*" = "relay";
- "@swarsel:${matrixDomain}" = "admin";
+ "@swarsel:${serviceDomain}" = "admin";
};
};
};
@@ -10470,14 +7749,14 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
- "192.168.1.2:${builtins.toString synapsePort}" = { };
+ "192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = {
- "${matrixDomain}" = {
+ "${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
@@ -10529,19 +7808,22 @@ in
-3.3.2.16. nextcloud
+3.2.3.15. nextcloud
{ pkgs, lib, config, ... }:
let
- serviceDomain = "stash.swarsel.win";
+ inherit (config.repo.secrets.local.nextcloud) adminuser;
+
+ servicePort = 80;
serviceUser = "nextcloud";
serviceGroup = serviceUser;
serviceName = "nextcloud";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops.secrets = {
nextcloudadminpass = {
@@ -10560,7 +7842,7 @@ in
globals.services.${serviceName}.domain = serviceDomain;
services = {
- nextcloud = {
+ ${serviceName} = {
enable = true;
settings = {
trusted_proxies = [ "0.0.0.0" ];
@@ -10568,8 +7850,8 @@ in
};
package = pkgs.nextcloud31;
hostName = serviceDomain;
- home = "/Vault/data/nextcloud";
- datadir = "/Vault/data/nextcloud";
+ home = "/Vault/data/${serviceName}";
+ datadir = "/Vault/data/${serviceName}";
https = true;
configureRedis = true;
maxUploadSize = "4G";
@@ -10578,7 +7860,7 @@ in
};
extraAppsEnable = true;
config = {
- adminuser = "admin";
+ inherit adminuser;
adminpassFile = config.sops.secrets.nextcloudadminpass.path;
dbtype = "sqlite";
};
@@ -10587,9 +7869,9 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
- "192.168.1.2:80" = { };
+ "192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
@@ -10613,28 +7895,28 @@ in
-3.3.2.17. immich
+3.2.3.16. immich
{ lib, config, globals, ... }:
let
- serviceDomain = "shots.swarsel.win";
servicePort = 3001;
serviceUser = "immich";
serviceName = "immich";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
- users.users."${serviceUser}" = {
+ users.users.${serviceUser} = {
extraGroups = [ "video" "render" "users" ];
};
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName}.domain = serviceDomain;
- services.immich = {
+ services.${serviceName} = {
enable = true;
host = "0.0.0.0";
port = servicePort;
@@ -10649,7 +7931,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -10689,7 +7971,7 @@ in
-3.3.2.18. paperless (tika, gotenberg)
+3.2.3.17. paperless (tika, gotenberg)
This is my personal document management system. It automatically pulls documents from several sources, the only manual step for physical documents is to put them in my scanner and use email delivery.
@@ -10700,19 +7982,23 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of
-{ lib, pkgs, config, ... }:
+{ lib, pkgs, config, globals, ... }:
let
- serviceDomain = "scan.swarsel.win";
servicePort = 28981;
serviceUser = "paperless";
serviceGroup = serviceUser;
serviceName = "paperless";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
+ tikaPort = 9998;
+ gotenbergPort = 3002;
+ kanidmDomain = globals.services.kanidm.domain;
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
- users.users."${serviceUser}" = {
+ users.users.${serviceUser} = {
extraGroups = [ "users" ];
};
@@ -10730,25 +8016,25 @@ in
globals.services.${serviceName}.domain = serviceDomain;
services = {
- paperless = {
+ ${serviceName} = {
enable = true;
mediaDir = "/Vault/Eternor/Paperless";
- dataDir = "/Vault/data/paperless";
+ dataDir = "/Vault/data/${serviceName}";
user = serviceUser;
port = servicePort;
passwordFile = config.sops.secrets.paperless_admin.path;
address = "0.0.0.0";
settings = {
PAPERLESS_OCR_LANGUAGE = "deu+eng";
- PAPERLESS_URL = "https://scan.swarsel.win";
+ PAPERLESS_URL = "https://${serviceDomain}";
PAPERLESS_OCR_USER_ARGS = builtins.toJSON {
optimize = 1;
invalidate_digital_signatures = true;
pdfa_image_compression = "lossless";
};
PAPERLESS_TIKA_ENABLED = "true";
- PAPERLESS_TIKA_ENDPOINT = "http://localhost:9998";
- PAPERLESS_TIKA_GOTENBERG_ENDPOINT = "http://localhost:3002";
+ PAPERLESS_TIKA_ENDPOINT = "http://localhost:${builtins.toString tikaPort}";
+ PAPERLESS_TIKA_GOTENBERG_ENDPOINT = "http://localhost:${builtins.toString gotenbergPort}";
PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect";
PAPERLESS_SOCIALACCOUNT_PROVIDERS = builtins.toJSON {
openid_connect = {
@@ -10760,7 +8046,7 @@ in
client_id = "paperless";
# secret will be added by paperless-web.service (see below)
#secret = "";
- settings.server_url = "https://sso.swarsel.win/oauth2/openid/${client_id}/.well-known/openid-configuration";
+ settings.server_url = "https://${kanidmDomain}/oauth2/openid/${client_id}/.well-known/openid-configuration";
}
];
};
@@ -10770,7 +8056,7 @@ in
tika = {
enable = true;
- port = 9998;
+ port = tikaPort;
openFirewall = false;
listenAddress = "127.0.0.1";
enableOcr = true;
@@ -10779,7 +8065,7 @@ in
gotenberg = {
enable = true;
package = pkgs.stable.gotenberg;
- port = 3002;
+ port = gotenbergPort;
bindIP = "127.0.0.1";
timeout = "600s";
chromium.package = pkgs.stable.chromium;
@@ -10799,7 +8085,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -10833,12 +8119,14 @@ in
-3.3.2.19. transmission
+3.2.3.18. transmission
{ self, pkgs, lib, config, ... }:
let
- serviceDomain = "store.swarsel.win";
+ serviceName = "transmission";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
lidarrUser = "lidarr";
lidarrGroup = lidarrUser;
lidarrPort = 8686;
@@ -10856,8 +8144,8 @@ let
prowlarrPort = 9696;
in
{
- options.swarselsystems.modules.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
- config = lib.mkIf config.swarselsystems.modules.server.transmission {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} and friends on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
# this user/group section is probably unneeded
users = {
@@ -10916,7 +8204,7 @@ in
readarr = {
name = "Readarr";
info = "https://${serviceDomain}/readarr";
- icon = "${self}/topology/images/readarr.png";
+ icon = "${self}/files/topology-images/readarr.png";
};
sonarr.info = "https://${serviceDomain}/sonarr";
lidarr.info = "https://${serviceDomain}/lidarr";
@@ -11020,40 +8308,43 @@ in
-3.3.2.20. syncthing
+3.2.3.19. syncthing
{ lib, config, ... }:
let
inherit (config.repo.secrets.common) workHostName;
- serviceDomain = "storync.swarsel.win";
+
servicePort = 8384;
serviceUser = "syncthing";
serviceGroup = serviceUser;
serviceName = "syncthing";
+ serviceDomain = config.repo.secrets.common.services.domains.syncthing1;
+
+ cfg = config.services.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
- users.users."${serviceUser}" = {
+ users.users.${serviceUser} = {
extraGroups = [ "users" ];
group = serviceGroup;
isSystemUser = true;
};
- users.groups."${serviceGroup}" = { };
+ users.groups.${serviceGroup} = { };
networking.firewall.allowedTCPPorts = [ servicePort ];
- globals.services.${serviceName}.domain = serviceDomain;
+ globals.services."${serviceName}-${config.networking.hostName}".domain = serviceDomain;
- services.syncthing = {
+ services.${serviceName} = rec {
enable = true;
user = serviceUser;
group = serviceGroup;
- dataDir = "/Vault/data/syncthing";
- configDir = "/Vault/data/syncthing/.config/syncthing";
+ dataDir = "/Vault/data/${serviceName}";
+ configDir = "${cfg.dataDir}/.config/${serviceName}";
guiAddress = "0.0.0.0:${builtins.toString servicePort}";
openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery
relay.enable = false;
@@ -11075,14 +8366,14 @@ in
};
folders = {
"Default Folder" = lib.mkForce {
- path = "/Vault/data/syncthing/Sync";
+ path = "${cfg.dataDir}/Sync";
type = "receiveonly";
versioning = null;
devices = [ "sync@oracle" "magicant" "${workHostName}" "moonside@oracle" ];
id = "default";
};
"Obsidian" = {
- path = "/Vault/data/syncthing/Obsidian";
+ path = "${cfg.dataDir}/Obsidian";
type = "receiveonly";
versioning = {
type = "simple";
@@ -11092,7 +8383,7 @@ in
id = "yjvni-9eaa7";
};
"Org" = {
- path = "/Vault/data/syncthing/Org";
+ path = "${cfg.dataDir}/Org";
type = "receiveonly";
versioning = {
type = "simple";
@@ -11102,7 +8393,7 @@ in
id = "a7xnl-zjj3d";
};
"Vpn" = {
- path = "/Vault/data/syncthing/Vpn";
+ path = "${cfg.dataDir}/Vpn";
type = "receiveonly";
versioning = {
type = "simple";
@@ -11112,7 +8403,7 @@ in
id = "hgp9s-fyq3p";
};
# "Documents" = {
- # path = "/Vault/data/syncthing/Documents";
+ # path = "${cfg.dataDir}/Documents";
# type = "receiveonly";
# versioning = {
# type = "simple";
@@ -11127,7 +8418,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -11156,7 +8447,7 @@ in
-3.3.2.21. restic
+3.2.3.20. restic
This manages backups for my pictures and obsidian files.
@@ -11222,37 +8513,42 @@ in
-3.3.2.22. monitoring (Grafana)
+3.2.3.21. monitoring (Grafana, Prometheus)
This section exposes several metrics that I use to check the health of my server. I need to expand on the exporters section at some point, but for now I have everything I need.
-{ self, lib, config, ... }:
+{ self, lib, config, globals, ... }:
let
- serviceDomain = "status.swarsel.win";
+
servicePort = 3000;
serviceUser = "grafana";
- prometheusUser = "prometheus";
serviceGroup = serviceUser;
+ serviceName = "grafana";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
+ prometheusPort = 9090;
+ prometheusUser = "prometheus";
prometheusGroup = prometheusUser;
- moduleName = "monitoring";
+ nextcloudUser = config.repo.secrets.local.nextcloud.adminuser;
grafanaUpstream = "grafana";
prometheusUpstream = "prometheus";
- prometheusPort = 9090;
prometheusWebRoot = "prometheus";
+ kanidmDomain = globals.services.kanidm.domain;
in
{
- options.swarselsystems.modules.server."${moduleName}" = lib.mkEnableOption "enable ${moduleName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${moduleName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops = {
secrets = {
grafanaadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
prometheusadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
kanidm-grafana-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
- prometheus-admin-hash = { owner = prometheusUser; group = prometheusGroup; mode = "0440"; };
+ prometheus-admin-hash = { sopsFile = self + /secrets/winters/secrets2.yaml; owner = prometheusUser; group = prometheusGroup; mode = "0440"; };
+
};
templates = {
"web-config" = {
@@ -11273,7 +8569,7 @@ in
extraGroups = [ "nextcloud" ];
};
- "${serviceUser}" = {
+ ${serviceUser} = {
extraGroups = [ "users" ];
};
};
@@ -11282,12 +8578,12 @@ in
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
topology.self.services.prometheus.info = "https://${serviceDomain}/${prometheusWebRoot}";
- globals.services.${moduleName}.domain = serviceDomain;
+ globals.services.${serviceName}.domain = serviceDomain;
services = {
- grafana = {
+ ${serviceName} = {
enable = true;
- dataDir = "/Vault/data/grafana";
+ dataDir = "/Vault/data/${serviceName}";
provision = {
enable = true;
datasources.settings = {
@@ -11344,9 +8640,9 @@ in
client_secret = "$__file{${config.sops.secrets.kanidm-grafana-client.path}}";
scopes = "openid email profile";
login_attribute_path = "preferred_username";
- auth_url = "https://sso.swarsel.win/ui/oauth2";
- token_url = "https://sso.swarsel.win/oauth2/token";
- api_url = "https://sso.swarsel.win/oauth2/openid/grafana/userinfo";
+ auth_url = "https://${kanidmDomain}/ui/oauth2";
+ token_url = "https://${kanidmDomain}/oauth2/token";
+ api_url = "https://${kanidmDomain}/oauth2/openid/grafana/userinfo";
use_pkce = true;
use_refresh_token = true;
# Allow mapping oauth2 roles to server admin
@@ -11358,7 +8654,7 @@ in
prometheus = {
enable = true;
- webExternalUrl = "https://status.swarsel.win/${prometheusWebRoot}";
+ webExternalUrl = "https://${serviceDomain}/${prometheusWebRoot}";
port = prometheusPort;
listenAddress = "0.0.0.0";
globalConfig = {
@@ -11418,8 +8714,8 @@ in
nextcloud = lib.mkIf config.swarselsystems.modules.server.nextcloud {
enable = true;
port = 9205;
- url = "https://stash.swarsel.win/ocs/v2.php/apps/serverinfo/api/v1/info";
- username = "admin";
+ url = "https://${serviceDomain}/ocs/v2.php/apps/serverinfo/api/v1/info";
+ username = nextcloudUser;
passwordFile = config.sops.secrets.nextcloudadminpass.path;
};
};
@@ -11470,7 +8766,7 @@ in
-3.3.2.23. Jenkins
+3.2.3.22. Jenkins
This is a WIP Jenkins instance. It is used to automatically build a new system when pushes to the main repository are detected. I have turned this service off for now however, as I actually prefer to start my builds manually.
@@ -11479,26 +8775,26 @@ This is a WIP Jenkins instance. It is used to automatically build a new system w
{ pkgs, lib, config, ... }:
let
- serviceDomain = "servant.swarsel.win";
servicePort = 8088;
serviceName = "jenkins";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
services.jenkins = {
enable = true;
withCLI = true;
- port = 8088;
+ port = servicePort;
packages = [ pkgs.stdenv pkgs.git pkgs.jdk17 config.programs.ssh.package pkgs.nix ];
listenAddress = "0.0.0.0";
- home = "/Vault/apps/jenkins";
+ home = "/Vault/apps/${serviceName}";
};
services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -11528,7 +8824,7 @@ in
-3.3.2.24. Emacs elfeed (RSS Server)
+3.2.3.23. Emacs elfeed (RSS Server)
This was an approach of hosting an RSS server from within emacs. That would have been useful as it would have allowed me to allow my feeds from any device. However, it proved impossible to do bidirectional syncing, so I abandoned this configuration in favor of FreshRSS.
@@ -11536,13 +8832,17 @@ This was an approach of hosting an RSS server from within emacs. That would have
{ lib, config, ... }:
+let
+ serviceName = "emacs";
+ servicePort = 9812;
+in
{
- options.swarselsystems.modules.server.emacs = lib.mkEnableOption "enable emacs server on server";
- config = lib.mkIf config.swarselsystems.modules.server.emacs {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} server on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
- networking.firewall.allowedTCPPorts = [ 9812 ];
+ networking.firewall.allowedTCPPorts = [ servicePort ];
- services.emacs = {
+ services.${serviceName} = {
enable = true;
install = true;
startWithGraphical = false;
@@ -11556,18 +8856,18 @@ This was an approach of hosting an RSS server from within emacs. That would have
-3.3.2.25. FreshRSS
+3.2.3.24. FreshRSS
FreshRSS is a more 'classical' RSS aggregator that I can just host as a distinct service. This also has its upsides because I jave more control over the state this way.
-It serves both a Greader API at https://signpost.swarsel.win/api/greader.php, as well as a Fever API at https://signpost.swarsel.win/api/fever.php.
+It serves both a Greader API at https://${servicename}/api/greader.php, as well as a Fever API at https://${servicename}/api/fever.php.
-I am using this with CapyReader on my phone, set it up as a FreshRSS account with Server URL =https://signpost.swarsel.win/api/greader.php
+I am using this with CapyReader on my phone, set it up as a FreshRSS account with Server URL =https://${servicename}/api/greader.php
@@ -11577,22 +8877,25 @@ FreshRSS claims to support HTTP header auth, but at least it does not work with
{ self, lib, config, ... }:
let
+ inherit (config.repo.secrets.local.freshrss) defaultUser;
+
+ servicePort = 80;
serviceName = "freshrss";
- serviceDomain = "signpost.swarsel.win";
serviceUser = "freshrss";
serviceGroup = serviceName;
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
- options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server";
- config = lib.mkIf config.swarselsystems.modules.server.freshrss {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
- users.users."${serviceUser}" = {
+ users.users.${serviceUser} = {
extraGroups = [ "users" ];
group = serviceGroup;
isSystemUser = true;
};
- users.groups."${serviceGroup}" = { };
+ users.groups.${serviceGroup} = { };
sops = {
secrets = {
@@ -11606,7 +8909,7 @@ in
# content = ''
# DATA_PATH=${config.services.freshrss.dataDir}
# OIDC_ENABLED=1
- # OIDC_PROVIDER_METADATA_URL=https://sso.swarsel.win/.well-known/openid-configuration
+ # OIDC_PROVIDER_METADATA_URL=https://${kanidmDomain}/.well-known/openid-configuration
# OIDC_CLIENT_ID=freshrss
# OIDC_CLIENT_SECRET=${config.sops.placeholder.kanidm-freshrss-client}
# OIDC_CLIENT_CRYPTO_KEY=${config.sops.placeholder.oidc-crypto-key}
@@ -11624,18 +8927,18 @@ in
topology.self.services.${serviceName} = {
name = "FreshRSS";
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/freshrss.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
- services.freshrss = {
+ services.${serviceName} = {
+ inherit defaultUser;
enable = true;
virtualHost = serviceDomain;
baseUrl = "https://${serviceDomain}";
authType = "form";
dataDir = "/Vault/data/tt-rss";
- defaultUser = "Swarsel";
passwordFile = config.sops.secrets.fresh.path;
};
@@ -11645,9 +8948,9 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
- "192.168.1.2:80" = { };
+ "192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
@@ -11678,29 +8981,31 @@ in
-3.3.2.26. forgejo (git server)
+3.2.3.25. forgejo (git server)
-{ lib, config, pkgs, ... }:
+{ lib, config, pkgs, globals, ... }:
let
- serviceDomain = "swagit.swarsel.win";
servicePort = 3000;
serviceUser = "forgejo";
serviceGroup = serviceUser;
serviceName = "forgejo";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
+ kanidmDomain = globals.services.kanidm.domain;
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
networking.firewall.allowedTCPPorts = [ servicePort ];
- users.users."${serviceUser}" = {
+ users.users.${serviceUser} = {
group = serviceGroup;
isSystemUser = true;
};
- users.groups."${serviceGroup}" = { };
+ users.groups.${serviceGroup} = { };
sops.secrets = {
kanidm-forgejo-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
@@ -11708,7 +9013,7 @@ in
globals.services.${serviceName}.domain = serviceDomain;
- services.forgejo = {
+ services.${serviceName} = {
enable = true;
user = serviceUser;
group = serviceGroup;
@@ -11750,13 +9055,13 @@ in
};
};
- systemd.services.forgejo = {
+ systemd.services.${serviceName} = {
serviceConfig.RestartSec = "60"; # Retry every minute
preStart =
let
exe = lib.getExe config.services.forgejo.package;
providerName = "kanidm";
- clientId = "forgejo";
+ clientId = serviceName;
args = lib.escapeShellArgs (
lib.concatLists [
[
@@ -11773,7 +9078,7 @@ in
]
[
"--auto-discover-url"
- "https://sso.swarsel.win/oauth2/openid/${clientId}/.well-known/openid-configuration"
+ "https://${kanidmDomain}/oauth2/openid/${clientId}/.well-known/openid-configuration"
]
[
"--scopes"
@@ -11808,7 +9113,7 @@ in
services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -11838,18 +9143,20 @@ in
-3.3.2.27. Anki Sync Server
+3.2.3.26. Anki Sync Server
-{ lib, config, ... }:
+{ self, lib, config, globals, ... }:
let
- serviceDomain = "synki.swarsel.win";
servicePort = 27701;
serviceName = "ankisync";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
+ ankiUser = globals.user.name;
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
networking.firewall.allowedTCPPorts = [ servicePort ];
@@ -11857,6 +9164,7 @@ in
topology.self.services.${serviceName} = {
name = lib.mkForce "Anki Sync Server";
+ icon = "${self}/files/topology-images/${serviceName}.png";
info = "https://${serviceDomain}";
};
@@ -11869,7 +9177,7 @@ in
openFirewall = true;
users = [
{
- username = "Swarsel";
+ username = ankiUser;
passwordFile = config.sops.secrets.swarsel.path;
}
];
@@ -11877,7 +9185,7 @@ in
services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -11907,7 +9215,7 @@ in
-3.3.2.28. kanidm
+3.2.3.27. kanidm
The forgejo configuration is a little broken and will show a 500 error when signing in through kanidm. However, when pressing back and refreshing the page, I am logged in. Currently I cannot be bothered to fix this.
@@ -11919,30 +9227,37 @@ 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://sso.swarsel.win/oauth2/openid/nextcloud/.well-known/oauth-authorization-server, with clienID being the client name as specified in kanidm.
+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.
{ self, lib, pkgs, config, globals, ... }:
let
certsSopsFile = self + /secrets/certs/secrets.yaml;
- serviceDomain = "sso.swarsel.win";
+
servicePort = 8300;
serviceUser = "kanidm";
serviceGroup = serviceUser;
serviceName = "kanidm";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
oauth2ProxyDomain = globals.services.oauth2Proxy.domain;
+ immichDomain = globals.services.immich.domain;
+ paperlessDomain = globals.services.paperless.domain;
+ forgejoDomain = globals.services.forgejo.domain;
+ grafanaDomain = globals.services.grafana.domain;
+ nextcloudDomain = globals.services.nextcloud.domain;
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
- users.users."${serviceUser}" = {
+ users.users.${serviceUser} = {
group = serviceGroup;
isSystemUser = true;
};
- users.groups."${serviceGroup}" = { };
+ users.groups.${serviceGroup} = { };
sops = {
secrets = {
@@ -11965,7 +9280,7 @@ in
globals.services.${serviceName}.domain = serviceDomain;
services = {
- kanidm = {
+ ${serviceName} = {
package = pkgs.kanidmWithSecretProvisioning;
enableServer = true;
serverSettings = {
@@ -12010,12 +9325,12 @@ in
immich = {
displayName = "Immich";
originUrl = [
- "https://shots.swarsel.win/auth/login"
- "https://shots.swarsel.win/user-settings"
+ "https://${immichDomain}/auth/login"
+ "https://${immichDomain}/user-settings"
"app.immich:///oauth-callback"
- "https://shots.swarsel.win/api/oauth/mobile-redirect"
+ "https://${immichDomain}/api/oauth/mobile-redirect"
];
- originLanding = "https://shots.swarsel.win/";
+ originLanding = "https://${immichDomain}/";
basicSecretFile = config.sops.secrets.kanidm-immich.path;
preferShortUsername = true;
enableLegacyCrypto = true; # can use RS256 / HS256, not ES256
@@ -12027,8 +9342,8 @@ in
};
paperless = {
displayName = "Paperless";
- originUrl = "https://scan.swarsel.win/accounts/oidc/kanidm/login/callback/";
- originLanding = "https://scan.swarsel.win/";
+ originUrl = "https://${paperlessDomain}/accounts/oidc/kanidm/login/callback/";
+ originLanding = "https://${paperlessDomain}/";
basicSecretFile = config.sops.secrets.kanidm-paperless.path;
preferShortUsername = true;
scopeMaps."paperless.access" = [
@@ -12039,8 +9354,8 @@ in
};
forgejo = {
displayName = "Forgejo";
- originUrl = "https://swagit.swarsel.win/user/oauth2/kanidm/callback";
- originLanding = "https://swagit.swarsel.win/";
+ originUrl = "https://${forgejoDomain}/user/oauth2/kanidm/callback";
+ originLanding = "https://${forgejoDomain}/";
basicSecretFile = config.sops.secrets.kanidm-forgejo.path;
scopeMaps."forgejo.access" = [
"openid"
@@ -12058,8 +9373,8 @@ in
};
grafana = {
displayName = "Grafana";
- originUrl = "https://status.swarsel.win/login/generic_oauth";
- originLanding = "https://status.swarsel.win/";
+ originUrl = "https://${grafanaDomain}/login/generic_oauth";
+ originLanding = "https://${grafanaDomain}/";
basicSecretFile = config.sops.secrets.kanidm-grafana.path;
preferShortUsername = true;
scopeMaps."grafana.access" = [
@@ -12078,8 +9393,8 @@ in
};
nextcloud = {
displayName = "Nextcloud";
- originUrl = " https://stash.swarsel.win/apps/sociallogin/custom_oidc/kanidm";
- originLanding = "https://stash.swarsel.win/";
+ originUrl = " https://${nextcloudDomain}/apps/sociallogin/custom_oidc/kanidm";
+ originLanding = "https://${nextcloudDomain}/";
basicSecretFile = config.sops.secrets.kanidm-nextcloud.path;
allowInsecureClientDisablePkce = true;
scopeMaps."nextcloud.access" = [
@@ -12140,12 +9455,12 @@ in
};
systemd.services = {
- kanidm.serviceConfig.RestartSec = "30";
+ ${serviceName}.serviceConfig.RestartSec = "30";
};
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -12174,18 +9489,23 @@ in
-3.3.2.29. oauth2-proxy
+3.2.3.28. oauth2-proxy
{ lib, config, globals, ... }:
let
+ servicePort = 3004;
+ serviceUser = "oauth2-proxy";
+ serviceGroup = serviceUser;
+ serviceName = "oauth2-proxy";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
kanidmDomain = globals.services.kanidm.domain;
- oauth2ProxyDomain = "soauth.swarsel.win";
- oauth2ProxyPort = 3004;
+ mainDomain = globals.domains.main;
in
{
options = {
- swarselsystems.modules.server.oauth2Proxy = lib.mkEnableOption "enable oauth2-proxy on server";
+ swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
# largely based on https://github.com/oddlama/nix-config/blob/main/modules/oauth2-proxy.nix
services.nginx.virtualHosts = lib.mkOption {
type = lib.types.attrsOf (
@@ -12293,12 +9613,12 @@ in
);
};
};
- config = lib.mkIf config.swarselsystems.modules.server.oauth2Proxy {
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops = {
secrets = {
- "oauth2-cookie-secret" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
- "kanidm-oauth2-proxy-client" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
+ "oauth2-cookie-secret" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
+ "kanidm-oauth2-proxy-client" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
};
templates = {
@@ -12307,34 +9627,34 @@ in
OAUTH2_PROXY_CLIENT_SECRET="${config.sops.placeholder.kanidm-oauth2-proxy-client}"
OAUTH2_PROXY_COOKIE_SECRET=${config.sops.placeholder.oauth2-cookie-secret}
'';
- owner = "oauth2-proxy";
- group = "oauth2-proxy";
+ owner = serviceUser;
+ group = serviceGroup;
mode = "0440";
};
};
};
- networking.firewall.allowedTCPPorts = [ oauth2ProxyPort ];
+ networking.firewall.allowedTCPPorts = [ servicePort ];
- globals.services.oauth2Proxy.domain = oauth2ProxyDomain;
+ globals.services.oauth2Proxy.domain = serviceDomain;
services = {
- oauth2-proxy = {
+ ${serviceName} = {
enable = true;
cookie = {
- domain = ".swarsel.win";
+ domain = ".${mainDomain}";
secure = true;
expire = "900m";
secret = null; # set by service EnvironmentFile
};
clientSecret = null; # set by service EnvironmentFile
reverseProxy = true;
- httpAddress = "0.0.0.0:${builtins.toString oauth2ProxyPort}";
- redirectURL = "https://${oauth2ProxyDomain}/oauth2/callback";
+ httpAddress = "0.0.0.0:${builtins.toString servicePort}";
+ redirectURL = "https://${serviceDomain}/oauth2/callback";
setXauthrequest = true;
extraConfig = {
code-challenge-method = "S256";
- whitelist-domain = ".swarsel.win";
+ whitelist-domain = ".${mainDomain}";
set-authorization-header = true;
pass-access-token = true;
skip-jwt-bearer-tokens = true;
@@ -12347,16 +9667,16 @@ in
loginURL = "https://${kanidmDomain}/ui/oauth2";
redeemURL = "https://${kanidmDomain}/oauth2/token";
validateURL = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy/userinfo";
- clientID = "oauth2-proxy";
+ clientID = serviceName;
email.domains = [ "*" ];
};
};
systemd.services = {
- oauth2-proxy = {
+ ${serviceName} = {
# after = [ "kanidm.service" ];
serviceConfig = {
- RuntimeDirectory = "oauth2-proxy";
+ RuntimeDirectory = serviceName;
RuntimeDirectoryMode = "0750";
UMask = "007"; # TODO remove once https://github.com/oauth2-proxy/oauth2-proxy/issues/2141 is fixed
RestartSec = "60"; # Retry every minute
@@ -12369,20 +9689,20 @@ in
services.nginx = {
upstreams = {
- oauth2-proxy = {
+ ${serviceName} = {
servers = {
- "localhost:${builtins.toString oauth2ProxyPort}" = { };
+ "localhost:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = {
- "${oauth2ProxyDomain}" = {
+ "${serviceDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
locations = {
"/" = {
- proxyPass = "http://oauth2-proxy";
+ proxyPass = "http://${serviceName}";
};
};
extraConfig = ''
@@ -12399,44 +9719,53 @@ in
-3.3.2.30. Firefly-III
+3.2.3.29. Firefly-III
{ self, lib, config, ... }:
let
+ servicePort = 80;
+ serviceUser = "firefly-iii";
+ serviceGroup = serviceUser;
+ serviceName = "firefly-iii";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
+ nginxGroup = "nginx";
+
cfg = config.services.firefly-iii;
- serviceDomain = "stonks.swarsel.win";
- fireflyUser = "firefly-iii";
- serviceName = "firefly";
in
{
- options.swarselsystems.modules.server.firefly = lib.mkEnableOption "enable firefly-iii on server";
- config = lib.mkIf config.swarselsystems.modules.server.firefly {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
- users.users.firefly-iii = {
- group = "nginx";
- isSystemUser = true;
+ users = {
+ groups.${serviceGroup} = { };
+ users.${serviceUser} = {
+ group = lib.mkForce serviceGroup;
+ extraGroups = lib.mkIf cfg.enableNginx [ nginxGroup ];
+ isSystemUser = true;
+ };
};
sops = {
secrets = {
- "firefly-iii-app-key" = { owner = fireflyUser; group = "nginx"; mode = "0440"; };
+ "firefly-iii-app-key" = { owner = serviceUser; group = if cfg.enableNginx then nginxGroup else serviceGroup; mode = "0440"; };
};
};
- topology.self.services.firefly-iii = {
+ topology.self.services.${serviceName} = {
name = "Firefly-III";
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/firefly-iii.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
services = {
- firefly-iii = {
+ ${serviceName} = {
enable = true;
- user = fireflyUser;
- group = if cfg.enableNginx then "nginx" else fireflyUser;
- dataDir = "/Vault/data/firefly-iii";
+ user = serviceUser;
+ group = if cfg.enableNginx then nginxGroup else serviceGroup;
+ dataDir = "/Vault/data/${serviceName}";
settings = {
TZ = config.repo.secrets.common.location.timezone;
APP_URL = "https://${serviceDomain}";
@@ -12473,9 +9802,9 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
- "192.168.1.2:80" = { };
+ "192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
@@ -12508,23 +9837,24 @@ in
-3.3.2.31. Koillection
+3.2.3.30. Koillection
{ self, lib, config, ... }:
let
- serviceDomain = "swag.swarsel.win";
serviceUser = "koillection";
serviceDB = "koillection";
serviceName = "koillection";
servicePort = 2282;
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
postgresUser = config.systemd.services.postgresql.serviceConfig.User; # postgres
postgresPort = config.services.postgresql.settings.port; # 5432
containerRev = "sha256:96693e41a6eb2aae44f96033a090378270f024ddf4e6095edf8d57674f21095d";
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops.secrets = {
koillection-db-password = { owner = postgresUser; group = postgresUser; mode = "0440"; };
@@ -12534,7 +9864,7 @@ in
topology.self.services.${serviceName} = {
name = lib.swarselsystems.toCapitalized serviceName;
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
@@ -12610,7 +9940,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -12636,23 +9966,23 @@ in
-3.3.2.32. Atuin
+3.2.3.31. Atuin
{ lib, config, ... }:
let
- serviceDomain = "shellhistory.swarsel.win";
servicePort = 8888;
serviceName = "atuin";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName}.domain = serviceDomain;
- services.atuin = {
+ services.${serviceName} = {
enable = true;
host = "0.0.0.0";
port = servicePort;
@@ -12662,7 +9992,7 @@ in
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -12693,24 +10023,25 @@ in
-3.3.2.33. Radicale
+3.2.3.32. Radicale
{ self, lib, config, ... }:
let
inherit (config.repo.secrets.local.radicale) user1;
sopsFile = self + /secrets/winters/secrets2.yaml;
- serviceDomain = "schedule.swarsel.win";
+
servicePort = 8000;
serviceName = "radicale";
serviceUser = "radicale";
serviceGroup = serviceUser;
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
- cfg = config.services."${serviceName}";
+ cfg = config.services.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops = {
secrets.radicale-user = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
@@ -12730,7 +10061,7 @@ in
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName}.domain = serviceDomain;
- services.radicale = {
+ services.${serviceName} = {
enable = true;
settings = {
server = {
@@ -12773,11 +10104,10 @@ in
];
networking.firewall.allowedTCPPorts = [ servicePort ];
- networking.firewall.allowedUDPPorts = [ servicePort ];
nodes.moonside.services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
@@ -12809,12 +10139,11 @@ in
-3.3.2.34. croc
+3.2.3.33. croc
{ self, lib, config, pkgs, ... }:
let
- serviceDomain = "send.swarsel.win";
servicePorts = [
9009
9010
@@ -12823,12 +10152,13 @@ let
9013
];
serviceName = "croc";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
cfg = config.services.croc;
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops = {
secrets = {
@@ -12848,12 +10178,12 @@ in
topology.self.services.${serviceName} = {
name = lib.swarselsystems.toCapitalized serviceName;
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
- services.croc = {
+ services.${serviceName} = {
enable = true;
ports = servicePorts;
pass = config.sops.secrets.croc-password.path;
@@ -12862,7 +10192,7 @@ in
systemd.services = {
- "${serviceName}" = {
+ ${serviceName} = {
serviceConfig = {
ExecStart = lib.mkForce "${pkgs.croc}/bin/croc ${lib.optionalString cfg.debug "--debug"} relay --ports ${
lib.concatMapStringsSep "," toString cfg.ports}";
@@ -12883,27 +10213,27 @@ in
-3.3.2.35. microbin
+3.2.3.34. microbin
{ self, lib, config, ... }:
let
- serviceDomain = "scratch.swarsel.win";
servicePort = 8777;
serviceName = "microbin";
serviceUser = "microbin";
serviceGroup = serviceUser;
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
- cfg = config.services."${serviceName}";
+ cfg = config.services.${serviceName};
in
{
- options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ options.swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
users = {
- groups."${serviceGroup}" = { };
+ groups.${serviceGroup} = { };
- users."${serviceUser}" = {
+ users.${serviceUser} = {
isSystemUser = true;
group = serviceGroup;
};
@@ -12933,11 +10263,11 @@ in
topology.self.services.${serviceName} = {
name = lib.swarselsystems.toCapitalized serviceName;
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
- services."${serviceName}" = {
+ services.${serviceName} = {
enable = true;
passwordFile = config.sops.templates.microbin-env.path;
dataDir = "/var/lib/microbin";
@@ -12972,7 +10302,7 @@ in
};
systemd.services = {
- "${serviceName}" = {
+ ${serviceName} = {
serviceConfig = {
DynamicUser = lib.mkForce false;
User = serviceUser;
@@ -12989,7 +10319,7 @@ in
services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"localhost:${builtins.toString servicePort}" = { };
};
@@ -13020,25 +10350,26 @@ in
-3.3.2.36. shlink
+3.2.3.35. shlink
{ self, lib, config, ... }:
let
- serviceDomain = "s.swarsel.win";
servicePort = 8081;
serviceName = "shlink";
+ serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
+
containerRev = "sha256:1a697baca56ab8821783e0ce53eb4fb22e51bb66749ec50581adc0cb6d031d7a";
in
{
options = {
- swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
+ swarselsystems.modules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
};
- config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
+ config = lib.mkIf config.swarselsystems.modules.server.${serviceName} {
sops = {
secrets = {
- shlink-api = { };
+ shlink-api = { };
};
templates = {
@@ -13050,7 +10381,7 @@ in
};
};
- virtualisation.oci-containers.containers."shlink" = {
+ virtualisation.oci-containers.containers.${serviceName} = {
image = "shlinkio/shlink@${containerRev}";
environment = {
"DEFAULT_DOMAIN" = serviceDomain;
@@ -13076,13 +10407,13 @@ in
topology.self.services.${serviceName} = {
name = lib.swarselsystems.toCapitalized serviceName;
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
services.nginx = {
upstreams = {
- "${serviceName}" = {
+ ${serviceName} = {
servers = {
"localhost:${builtins.toString servicePort}" = { };
};
@@ -13109,30 +10440,42 @@ in
-3.3.3. Darwin
+3.2.4. Darwin
-3.3.3.1. Imports
+3.2.4.1. Imports
This section sets up all the imports that are used in the home-manager section.
-_:
+{ self, lib, config, outputs, globals, ... }:
+let
+ macUser = globals.user.work;
+in
{
+ imports = [
+ ];
- nix.settings.experimental-features = "nix-command flakes";
- nixpkgs = {
- hostPlatform = "x86_64-darwin";
- overlays = [ outputs.overlays.default ];
- config = {
- allowUnfree = true;
+ options.swarselsystems.modules.darwin.general = lib.mkEnableOption "darwin config";
+ config = lib.mkIf config.swarselsystems.modules.darwin.general {
+ nix.settings.experimental-features = "nix-command flakes";
+ nixpkgs = {
+ hostPlatform = "x86_64-darwin";
+ overlays = [ outputs.overlays.default ];
+ config = {
+ allowUnfree = true;
+ };
};
- };
- system.stateVersion = 4;
+ home-manager.users."${macUser}".imports = [
+ "${self}/modules/home/darwin"
+ ];
+
+ system.stateVersion = 4;
+ };
}
@@ -13140,7 +10483,7 @@ This section sets up all the imports that are used in the home-manager section.
-3.3.4. Optional
+3.2.5. Optional
These sets of configuration do not need to be deployed on every host, for a multitude of reasons.
@@ -13171,7 +10514,7 @@ in
-3.3.4.1. gaming
+3.2.5.1. gaming
This opens a few gaming ports and installs the steam configuration suite for gaming. There are more options in Gaming (home-manager side).
@@ -13225,7 +10568,7 @@ This opens a few gaming ports and installs the steam configuration suite for gam
-3.3.4.2. VirtualBox
+3.2.5.2. VirtualBox
This sets the VirtualBox configuration. Guest should not be enabled if not direly needed, it will make rebuilds unbearably slow. I only use this privately to run an old editor that does not run well under wine, so I put it into it's own specialisation.
@@ -13265,7 +10608,7 @@ This sets the VirtualBox configuration. Guest should not be enabled if not direl
-3.3.4.3. VmWare
+3.2.5.3. VmWare
This sets the VirtualBox configuration. Guest should not be enabled if not direly needed, it will make rebuilds unbearably slow.
@@ -13285,33 +10628,8 @@ This sets the VirtualBox configuration. Guest should not be enabled if not direl
-
-3.3.4.4. Auto-login
-
-
-Auto login for the initial session.
-
-
-
-{ lib, config, ... }:
-let
- inherit (config.swarselsystems) mainUser;
-in
-{
- options.swarselsystems.modules.optional.autologin = lib.mkEnableOption "optional autologin settings";
- config = lib.mkIf config.swarselsystems.modules.optional.autologin {
- services = {
- getty.autologinUser = mainUser;
- greetd.settings.initial_session.user = mainUser;
- };
- };
-}
-
-
-
-
-3.3.4.5. nswitch-rcm
+3.2.5.4. nswitch-rcm
This smashes Atmosphere 1.3.2 on the switch, which is what I am currenty using.
@@ -13336,15 +10654,18 @@ This smashes Atmosphere 1.3.2 on the switch, which is what I am currenty using.
-3.3.4.6. Framework
+3.2.5.5. Framework
This holds configuration that is specific to framework laptops.
-{ lib, config, ... }:
+{ lib, config, inputs, ... }:
{
+ imports = [
+ inputs.fw-fanctrl.nixosModules.default
+ ];
options.swarselsystems.modules.optional.framework = lib.mkEnableOption "optional framework machine settings";
config = lib.mkIf config.swarselsystems.modules.optional.framework {
services = {
@@ -13375,7 +10696,7 @@ This holds configuration that is specific to framework laptops.
-3.3.4.7. AMD CPU
+3.2.5.6. AMD CPU
{ lib, config, ... }:
@@ -13392,7 +10713,7 @@ This holds configuration that is specific to framework laptops.
-3.3.4.8. AMD GPU
+3.2.5.7. AMD GPU
{ lib, config, ... }:
@@ -13415,7 +10736,7 @@ This holds configuration that is specific to framework laptops.
-3.3.4.9. Hibernation
+3.2.5.8. Hibernation
{ lib, config, ... }:
@@ -13447,7 +10768,7 @@ This holds configuration that is specific to framework laptops.
-3.3.4.10. BTRFS
+3.2.5.9. BTRFS
{ lib, config, ... }:
@@ -13464,7 +10785,7 @@ This holds configuration that is specific to framework laptops.
-3.3.4.11. work
+3.2.5.10. work
Options that I need specifically at work. There are more options at Work (home-manager side).
@@ -13474,6 +10795,7 @@ Options that I need specifically at work. There are more options at { self, lib, pkgs, config, ... }:
let
inherit (config.swarselsystems) mainUser homeDir xdgDir;
+ iwd = config.networking.networkmanager.wifi.backend == "iwd";
owner = mainUser;
sopsFile = self + /secrets/work/secrets.yaml;
swarselService = name: description: execStart: {
@@ -13522,6 +10844,8 @@ in
"govchost"
"govcnetwork"
"govcpool"
+ "baseuser"
+ "basepw"
];
in
{
@@ -13533,6 +10857,12 @@ in
})
secretNames
);
+ templates = {
+ "network-manager-work.env".content = ''
+ BASEUSER=${config.sops.placeholder.baseuser}
+ BASEPASS=${config.sops.placeholder.basepw}
+ '';
+ };
};
boot.initrd = {
@@ -13570,7 +10900,48 @@ in
networking = {
inherit (config.swarselsystems) hostName fqdn;
- networkmanager.wifi.scanRandMacAddress = false;
+
+ networkmanager = {
+ wifi.scanRandMacAddress = false;
+ ensureProfiles = {
+ environmentFiles = [
+ "${config.sops.templates."network-manager-work.env".path}"
+ ];
+ profiles = {
+ VBC = {
+ "802-1x" = {
+ eap = if (!iwd) then "ttls;" else "peap;";
+ identity = "$BASEUSER";
+ password = "$BASEPASS";
+ phase2-auth = "mschapv2";
+ };
+ connection = {
+ id = "VBC";
+ type = "wifi";
+ };
+ ipv4 = { method = "auto"; };
+ ipv6 = {
+ addr-gen-mode = "default";
+ method = "auto";
+ };
+ proxy = { };
+ wifi = {
+ cloned-mac-address = "permanent";
+ mac-address = "E8:65:38:52:63:FF";
+ mac-address-randomization = "1";
+ mode = "infrastructure";
+ ssid = "VBC";
+ };
+ wifi-security = {
+ auth-alg = "open";
+ key-mgmt = "wpa-eap";
+ };
+ };
+ };
+ };
+ };
+
+
firewall = {
enable = lib.mkDefault true;
trustedInterfaces = [ "virbr0" ];
@@ -13639,7 +11010,7 @@ in
openssh = {
enable = true;
extraConfig = ''
- '';
+ '';
};
syncthing = {
@@ -13685,86 +11056,6 @@ in
# };
};
-}
-
-
-
-
-
-3.3.4.12. Minimal Install
-
-
-These options are really only to be used on the iso image in order to run nixos-anywhere.
-
-
-
-{ lib, pkgs, ... }:
-{
-
- nix.settings = {
- experimental-features = [ "nix-command" "flakes" ];
- warn-dirty = false;
- };
-
- boot = {
- # initrd.systemd.enable = true;
- kernelPackages = pkgs.linuxPackages_latest;
- supportedFilesystems = lib.mkForce [ "brtfs" "vfat" ];
- loader = {
- efi.canTouchEfiVariables = true;
- systemd-boot = {
- enable = true;
- configurationLimit = lib.mkDefault 5;
- consoleMode = lib.mkDefault "max";
- };
- };
- };
-
- services = {
- qemuGuest.enable = true;
- openssh = {
- enable = true;
- ports = lib.mkDefault [ 22 ];
- settings.PermitRootLogin = "yes";
- authorizedKeysFiles = lib.mkForce [
- "/etc/ssh/authorized_keys.d/%u"
- ];
- };
- };
-
- security.sudo.extraConfig = ''
- Defaults env_keep+=SSH_AUTH_SOCK
- Defaults lecture = never
- '';
-
- security.pam = {
- sshAgentAuth.enable = true;
- services = {
- sudo.u2fAuth = true;
- };
- };
-
- environment.systemPackages = with pkgs; [
- curl
- git
- gnupg
- rsync
- ssh-to-age
- sops
- vim
- just
- sbctl
- ];
-
- programs = {
- git.enable = true;
- };
-
- fileSystems."/boot".options = [ "umask=0077" ];
-
- networking.networkmanager.enable = true;
-
-
}
@@ -13773,18 +11064,30 @@ These options are really only to be used on the iso image in order to run nixos-
-3.4. Home-manager
+3.3. Home-manager
The general structure is the same as in the NixOS section.
+
+
+{ lib, ... }:
+let
+ importNames = lib.swarselsystems.readNix "modules/home";
+in
+{
+ imports = lib.swarselsystems.mkImports importNames "modules/home";
+}
+
+
+
-3.4.1. Common
+3.3.1. Common
-3.4.1.1. Imports
+3.3.1.1. Imports
This section sets up all the imports that are used in the home-manager section.
@@ -13803,7 +11106,7 @@ in
-3.4.1.2. Shared Configuration Options (holds firefox & stylix config parts)
+3.3.1.2. Shared Configuration Options (holds firefox & stylix config parts)
Provides settings related to nix-darwin systems. At the moment, I am only making use of a isDarwin flag.
@@ -13854,7 +11157,7 @@ This is where the theme for the whole OS is defined. Originally, this noweb-ref
};
wallpaper = lib.mkOption {
type = lib.types.path;
- default = "${self}/wallpaper/lenovowp.png";
+ default = "${self}/files/wallpaper/lenovowp.png";
};
sharescreen = lib.mkOption {
type = lib.types.str;
@@ -13873,7 +11176,7 @@ This is where the theme for the whole OS is defined. Originally, this noweb-ref
type = lib.types.attrs;
default = {
enable = true;
- base16Scheme = "${self}/programs/stylix/swarsel.yaml";
+ base16Scheme = "${self}/files/stylix/swarsel.yaml";
polarity = "dark";
opacity.popups = 0.5;
cursor = {
@@ -13928,7 +11231,7 @@ This is where the theme for the whole OS is defined. Originally, this noweb-ref
firefox = lib.mkOption {
type = lib.types.attrs;
default = {
- userChrome = builtins.readFile "${self}/programs/firefox/chrome/userChrome.css";
+ userChrome = builtins.readFile "${self}/files/firefox/chrome/userChrome.css";
extensions = {
packages = with pkgs.nur.repos.rycee.firefox-addons; [
tridactyl
@@ -14099,7 +11402,7 @@ This is where the theme for the whole OS is defined. Originally, this noweb-ref
-3.4.1.3. General home-manager-settings
+3.3.1.3. General home-manager-settings
Again, we adapt nix to our needs, enable the home-manager command for non-NixOS machines (NixOS machines are using it as a module) and setting user information that I always keep the same.
@@ -14158,7 +11461,7 @@ in
-3.4.1.4. nixGL
+3.3.1.4. nixGL
This integrates nixGL into home-manager. NixGL provies OpenGL and Vulkan APIs to nix installed utilities. This is needed for graphical applications on non-NixOS systems.
@@ -14207,7 +11510,7 @@ It can be set to either:
-3.4.1.5. Installed packages
+3.3.1.5. Installed packages
Here are defined some packages that I would like to use across all my machines. Most of these should not require further setup. Notably the cura package is severely outdated on nixpkgs, so I just fetch a more recent AppImage and run that instead.
@@ -14222,7 +11525,7 @@ Programming languages and default lsp's are defined here:
-3.4.1.5.1. Packaged
+3.3.1.5.1. Packaged
This holds packages that I can use as provided, or with small modifications (as in the texlive package that needs special configuration).
@@ -14310,7 +11613,7 @@ This holds packages that I can use as provided, or with small modifications (as
obsidian
spotify
vesktop # discord client
- nextcloud-client
+ # nextcloud-client # enables a systemd service that I do not want
spotify-player
element-desktop
nicotine-plus
@@ -14419,7 +11722,7 @@ This holds packages that I can use as provided, or with small modifications (as
-3.4.1.5.2. Self-defined
+3.3.1.5.2. Self-defined
This is just a separate container for derivations defined in Packages. This is a good idea so that I do not lose track of package names I have defined myself, as this was once a problem in the past already.
@@ -14466,7 +11769,7 @@ This is just a separate container for derivations defined in
-3.4.1.6. sops
+3.3.1.6. sops
I use sops-nix to handle secrets that I want to have available on my machines at all times. Procedure to add a new machine:
@@ -14493,7 +11796,7 @@ in
{
options.swarselsystems.modules.sops = lib.mkEnableOption "sops settings";
config = lib.mkIf config.swarselsystems.modules.sops {
- sops = {
+ sops = {
age.sshKeyPaths = [ "${homeDir}/.ssh/sops" "${homeDir}/.ssh/ssh_host_ed25519_key" ];
defaultSopsFile = lib.swarselsystems.mkIfElseList config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${homeDir}/.dotfiles/secrets/general/secrets.yaml";
@@ -14514,7 +11817,7 @@ in
-3.4.1.7. Yubikey
+3.3.1.7. Yubikey
{ lib, config, nixosConfig, ... }:
@@ -14522,7 +11825,7 @@ in
options.swarselsystems.modules.yubikey = lib.mkEnableOption "yubikey settings";
config = lib.mkIf config.swarselsystems.modules.yubikey {
- pam.yubico.authorizedYubiKeys = {
+ pam.yubico.authorizedYubiKeys = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) {
ids = [
nixosConfig.repo.secrets.common.yubikeys.dev1
nixosConfig.repo.secrets.common.yubikeys.dev2
@@ -14535,7 +11838,7 @@ in
-3.4.1.8. SSH Machines
+3.3.1.8. SSH Machines
It is very convenient to have SSH aliases in place for machines that I use. This is mainly used for some server machines and some university clusters. We also enable agent forwarding to have our Yubikey SSH key accessible on the remote host.
@@ -14591,7 +11894,7 @@ It is very convenient to have SSH aliases in place for machines that I use. This
-3.4.1.9. Theme (stylix)
+3.3.1.9. Theme (stylix)
These section allows home-manager to allow theme settings, and handles some other appearance-related settings like cursor styles. Interestingly, system icons (adwaita) still need to be setup on system-level, and will break if defined here.
@@ -14623,7 +11926,7 @@ This section has been notably empty ever since switching to stylix. Only Emacs i
-3.4.1.10. Desktop Entries, MIME types (xdg)
+3.3.1.10. Desktop Entries, MIME types (xdg)
Some programs lack a dmenu launcher - I define them myself here.
@@ -14742,7 +12045,7 @@ TODO: Non-NixOS machines (=sp3) should not use these by default, but instead the
-3.4.1.11. Linking dotfiles (Symlinks home.file)
+3.3.1.11. Linking dotfiles (Symlinks home.file)
This section should be used in order to symlink already existing configuration files using `home.file` and setting session variables using `home.sessionVariables`.
@@ -14764,29 +12067,29 @@ Also in firefox `about:config > toolkit.legacyUserProfileCustomizations.style
config = lib.mkIf config.swarselsystems.modules.symlink {
home.file = {
"init.el" = lib.mkDefault {
- source = self + /programs/emacs/init.el;
+ source = self + /files/emacs/init.el;
target = ".emacs.d/init.el";
};
"early-init.el" = {
- source = self + /programs/emacs/early-init.el;
+ source = self + /files/emacs/early-init.el;
target = ".emacs.d/early-init.el";
};
# on NixOS, Emacs does not find the aspell dicts easily. Write the configuration manually
".aspell.conf" = {
- source = self + /programs/config/.aspell.conf;
+ source = self + /files/config/.aspell.conf;
target = ".aspell.conf";
};
".gitmessage" = {
- source = self + /programs/git/.gitmessage;
+ source = self + /files/git/.gitmessage;
target = ".gitmessage";
};
};
xdg.configFile = {
- "tridactyl/tridactylrc".source = self + /programs/firefox/tridactyl/tridactylrc;
- "tridactyl/themes/base16-codeschool.css".source = self + /programs/firefox/tridactyl/themes/base16-codeschool.css;
- "tridactyl/themes/swarsel.css".source = self + /programs/firefox/tridactyl/themes/swarsel.css;
- "swayidle/config".source = self + /programs/swayidle/config;
+ "tridactyl/tridactylrc".source = self + /files/firefox/tridactyl/tridactylrc;
+ "tridactyl/themes/base16-codeschool.css".source = self + /files/firefox/tridactyl/themes/base16-codeschool.css;
+ "tridactyl/themes/swarsel.css".source = self + /files/firefox/tridactyl/themes/swarsel.css;
+ "swayidle/config".source = self + /files/swayidle/config;
};
};
}
@@ -14795,17 +12098,18 @@ Also in firefox `about:config > toolkit.legacyUserProfileCustomizations.style
-3.4.1.12. Sourcing environment variables
+3.3.1.12. Sourcing environment variables
Sets environment variables. Here I am only setting the EDITOR variable, most variables are set in the Sway section.
-{ lib, config, nixosConfig, ... }:
+{ lib, config, nixosConfig, globals, ... }:
let
inherit (nixosConfig.repo.secrets.common.mail) address1 address2 address3 address4 allMailAddresses;
inherit (nixosConfig.repo.secrets.common) fullName;
+ crocDomain = globals.services.croc.domain;
in
{
options.swarselsystems.modules.env = lib.mkEnableOption "env settings";
@@ -14813,11 +12117,11 @@ in
home.sessionVariables = {
EDITOR = "e -w";
DISPLAY = ":0";
- CROC_RELAY = "send.swarsel.win";
+ CROC_RELAY = crocDomain;
SWARSEL_LO_RES = config.swarselsystems.lowResolution;
SWARSEL_HI_RES = config.swarselsystems.highResolution;
};
- systemd.user.sessionVariables = {
+ systemd.user.sessionVariables = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) {
SWARSEL_MAIL1 = address1;
SWARSEL_MAIL2 = address2;
SWARSEL_MAIL3 = address3;
@@ -14832,7 +12136,7 @@ in
-3.4.1.13. General Programs: bottom, imv, sioyek, bat, carapace, wlogout, swayr, yt-dlp, mpv, jq, nix-index, ripgrep, pandoc, fzf, zoxide
+3.3.1.13. General Programs: bottom, imv, sioyek, bat, carapace, wlogout, swayr, yt-dlp, mpv, jq, nix-index, ripgrep, pandoc, fzf, zoxide
This section is for programs that require no further configuration. zsh Integration is enabled by default for these.
@@ -14875,7 +12179,7 @@ This section is for programs that require no further configuration. zsh Integrat
-3.4.1.14. nix-index
+3.3.1.14. nix-index
nix-index provides a way to find out which packages are provided by which derivations. By default it also comes with a replacement for command-not-found.sh, however, the implementation is based on a channel based setup. I like consistency, so I replace the command with one that provides a flakes-based output.
@@ -14890,7 +12194,7 @@ nix-index provides a way to find out which packages are provided by which deriva
let
commandNotFound = pkgs.runCommandLocal "command-not-found.sh" { } ''
mkdir -p $out/etc/profile.d
- substitute ${self + /scripts/command-not-found.sh} \
+ substitute ${self + /files/scripts/command-not-found.sh} \
$out/etc/profile.d/command-not-found.sh \
--replace-fail @nix-locate@ ${pkgs.nix-index}/bin/nix-locate \
--replace-fail @tput@ ${pkgs.ncurses}/bin/tput
@@ -14911,7 +12215,7 @@ nix-index provides a way to find out which packages are provided by which deriva
-3.4.1.15. password-store
+3.3.1.15. password-store
Enables password store with the pass-otp extension which allows me to store and generate one-time-passwords.
@@ -14936,7 +12240,7 @@ Enables password store with the pass-otp extension which allows me
-3.4.1.16. direnv
+3.3.1.16. direnv
Enables direnv, which I use for nearly all of my nix dev flakes.
@@ -14959,7 +12263,7 @@ Enables direnv, which I use for nearly all of my nix dev flakes.
-3.4.1.17. eza
+3.3.1.17. eza
Eza provides me with a better ls command and some other useful aliases.
@@ -14986,10 +12290,13 @@ Eza provides me with a better ls command and some other useful alia
-3.4.1.18. atuin
+3.3.1.18. atuin
-{ lib, config, ... }:
+{ lib, config, globals, ... }:
+let
+ atuinDomain = globals.services.atuin.domain;
+in
{
options.swarselsystems.modules.atuin = lib.mkEnableOption "atuin settings";
config = lib.mkIf config.swarselsystems.modules.atuin {
@@ -14999,7 +12306,7 @@ Eza provides me with a better ls command and some other useful alia
settings = {
auto_sync = true;
sync_frequency = "5m";
- sync_address = "https://shellhistory.swarsel.win";
+ sync_address = "https://${atuinDomain}";
};
};
};
@@ -15009,17 +12316,19 @@ Eza provides me with a better ls command and some other useful alia
-3.4.1.19. git
+3.3.1.19. git
Here I set up my git config, automatic signing of commits, useful aliases for my ost used commands (for when I am not using Magit) as well as a git template defined in Linking dotfiles.
-{ lib, config, nixosConfig, ... }:
+{ lib, config, nixosConfig, globals, ... }:
let
inherit (nixosConfig.repo.secrets.common.mail) address1;
inherit (nixosConfig.repo.secrets.common) fullName;
+
+ gitUser = globals.user.name;
in
{
options.swarselsystems.modules.git = lib.mkEnableOption "git settings";
@@ -15043,15 +12352,15 @@ in
key = "0x76FD3810215AE097";
signByDefault = true;
};
- userEmail = lib.mkDefault address1;
- userName = fullName;
+ userEmail = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) (lib.mkDefault address1);
+ userName = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) fullName;
difftastic.enable = true;
lfs.enable = true;
includes = [
{
contents = {
github = {
- user = "Swarsel";
+ user = gitUser;
};
commit = {
template = "~/.gitmessage";
@@ -15067,7 +12376,7 @@ in
-3.4.1.20. Fuzzel
+3.3.1.20. Fuzzel
Here I only need to set basic layout options - the rest is being managed by stylix.
@@ -15096,7 +12405,7 @@ Here I only need to set basic layout options - the rest is being managed by styl
-3.4.1.21. Starship
+3.3.1.21. Starship
Starship makes my zsh look cooler! I have symbols for most programming languages and toolchains, also I build my own powerline.
@@ -15232,7 +12541,7 @@ Starship makes my zsh look cooler! I have symbols for most programm
-3.4.1.22. Kitty
+3.3.1.22. Kitty
Kitty is the terminal emulator of choice for me, it is nice to configure using nix, fast, and has a nice style.
@@ -15263,7 +12572,7 @@ The theme is handled by stylix.
-3.4.1.23. zsh
+3.3.1.23. zsh
zsh is the most convenient shell for me and it happens to be super neat to configure within home manager.
@@ -15436,7 +12745,7 @@ in
-3.4.1.24. zellij
+3.3.1.24. zellij
{ self, lib, config, pkgs, ... }:
@@ -15453,8 +12762,8 @@ in
];
xdg.configFile = {
- "zellij/config.kdl".text = import "${self}/programs/zellij/config.kdl.nix" { inherit config; };
- "zellij/layouts/default.kdl".text = import "${self}/programs/zellij/layouts/default.kdl.nix" { inherit config pkgs; };
+ "zellij/config.kdl".text = import "${self}/files/zellij/config.kdl.nix" { inherit config; };
+ "zellij/layouts/default.kdl".text = import "${self}/files/zellij/layouts/default.kdl.nix" { inherit config pkgs; };
};
};
@@ -15464,7 +12773,7 @@ in
-3.4.1.25. tmux
+3.3.1.25. tmux
{ lib, config, pkgs, ... }:
@@ -15573,7 +12882,7 @@ in
-3.4.1.26. Mail
+3.3.1.26. Mail
Normally I use 4 mail accounts - here I set them all up. Three of them are Google accounts (sadly), which are a chore to setup. The last is just a sender account that I setup SMTP for here.
@@ -15606,7 +12915,7 @@ in
# this is needed so that mbsync can use the passwords from sops
systemd.user.services.mbsync.Unit.After = [ "sops-nix.service" ];
- accounts = lib.mkIf (!config.swarselsystems.isPublic) {
+ accounts = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) {
email = {
maildirBasePath = "Mail";
accounts = {
@@ -15729,7 +13038,7 @@ in
-3.4.1.27. Home-manager: Emacs
+3.3.1.27. Home-manager: Emacs
By using the emacs-overlay NixOS module, I can install all Emacs packages that I want to use right through NixOS. This is done by passing my init.el file to the configuration which will then be parsed upon system rebuild, looking for use-package sections in the Elisp code. Also I define here the style of Emacs that I want to run - I am going with native Wayland Emacs here (emacs-pgtk). All of the nice options such as tree-sitter support are enabled by default, so I do not need to adjust the build process.
@@ -15755,7 +13064,7 @@ in
programs.emacs = {
enable = true;
package = pkgs.emacsWithPackagesFromUsePackage {
- config = self + /programs/emacs/init.el;
+ config = self + /files/emacs/init.el;
package = pkgs.emacs-git-pgtk;
alwaysEnsure = true;
alwaysTangle = true;
@@ -15824,7 +13133,7 @@ in
-3.4.1.28. Waybar
+3.3.1.28. Waybar
Again I am just using the first bar option here that I was able to find good understandable documentation for. Of note is that the `cpu` section's `format` is not defined here, but in section 1 (since not every machine has the same number of cores)
@@ -15847,7 +13156,7 @@ The rest of the related configuration is found here:
-{ self, config, lib, ... }:
+{ self, config, lib, pkgs, ... }:
let
generateIcons = n: lib.concatStringsSep " " (builtins.map (x: "{icon" + toString x + "}") (lib.range 0 (n - 1)));
modulesLeft = [
@@ -15928,28 +13237,28 @@ in
"custom/pseudobat" = lib.mkIf (!config.swarselsystems.isLaptop) {
format = "";
- on-click-right = "wlogout -p layer-shell";
+ on-click-right = "${pkgs.wlogout}/bin/wlogout -p layer-shell";
};
"custom/configwarn" = {
- exec = "waybarupdate";
+ exec = "${pkgs.waybarupdate}/bin/waybarupdate";
interval = 60;
};
"custom/scratchpad-indicator" = {
interval = 3;
- exec = "swaymsg -t get_tree | jq 'recurse(.nodes[]) | first(select(.name==\"__i3_scratch\")) | .floating_nodes | length | select(. >= 1)'";
+ exec = "${pkgs.swayfx}/bin/swaymsg -t get_tree | ${pkgs.jq}/bin/jq 'recurse(.nodes[]) | first(select(.name==\"__i3_scratch\")) | .floating_nodes | length | select(. >= 1)'";
format = "{} ";
- on-click = "swaymsg 'scratchpad show'";
- on-click-right = "swaymsg 'move scratchpad'";
+ on-click = "${pkgs.swayfx}/bin/swaymsg 'scratchpad show'";
+ on-click-right = "${pkgs.swayfx}/bin/swaymsg 'move scratchpad'";
};
"custom/github" = {
format = "{} ";
return-type = "json";
interval = 60;
- exec = "github-notifications";
- on-click = "xdg-open https://github.com/notifications";
+ exec = "${pkgs.github-notifications}/bin/github-notifications";
+ on-click = "${pkgs.xdg-utils}/bin/xdg-open https://github.com/notifications";
};
idle_inhibitor = {
@@ -16084,8 +13393,8 @@ in
];
};
scroll-step = 1;
- on-click = "pamixer -t";
- on-click-right = "pavucontrol";
+ on-click = "${pkgs.pamixer}/bin/pamixer -t";
+ on-click-right = "${pkgs.pavucontrol}/bin/pavucontrol";
};
memory = {
@@ -16099,13 +13408,13 @@ in
interval = 5;
format-icons = [ "▁" "▂" "▃" "▄" "▅" "▆" "▇" "█" ];
# on-click-right= "com.github.stsdc.monitor";
- on-click-right = "kitty -o confirm_os_window_close=0 btm";
+ on-click-right = "${pkgs.kitty}/bin/kitty -o confirm_os_window_close=0 btm";
};
"custom/vpn" = {
format = "()";
exec = "echo '{\"class\": \"connected\"}'";
- exec-if = "test -d /proc/sys/net/ipv4/conf/tun0";
+ exec-if = "${pkgs.toybox}/bin/test -d /proc/sys/net/ipv4/conf/tun0";
return-type = "json";
interval = 5;
};
@@ -16153,7 +13462,7 @@ in
};
};
};
- style = builtins.readFile (self + /programs/waybar/style.css);
+ style = builtins.readFile (self + /files/waybar/style.css);
};
};
}
@@ -16162,7 +13471,7 @@ in
-3.4.1.29. Firefox
+3.3.1.29. Firefox
Setting up firefox along with some policies that are important to me (mostly disabling telemetry related stuff as well as Pocket). I also enable some integrations that enable super useful packages, namely tridactyl and browserpass.
@@ -16336,14 +13645,14 @@ I used to build the firefox addon bypass-paywalls-clean myself here
-3.4.1.30. Services
+3.3.1.30. Services
Services that can be defined through home-manager should be defined here.
-3.4.1.30.1. gnome-keyring
+3.3.1.30.1. gnome-keyring
Used for storing sessions in e.g. Nextcloud
@@ -16364,7 +13673,7 @@ Used for storing sessions in e.g. Nextcloud
-3.4.1.30.2. KDE Connect
+3.3.1.30.2. KDE Connect
This enables phone/computer communication, including sending clipboard, files etc. Sadly on Wayland many of the features are broken (like remote control).
@@ -16387,7 +13696,7 @@ This enables phone/computer communication, including sending clipboard, files et
-3.4.1.30.3. Mako
+3.3.1.30.3. Mako
Desktop notifications!
@@ -16438,7 +13747,7 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
-3.4.1.30.4. SwayOSD
+3.3.1.30.4. SwayOSD
{ lib, config, ... }:
@@ -16456,7 +13765,7 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
-3.4.1.30.5. yubikey-touch-detector
+3.3.1.30.5. yubikey-touch-detector
{ lib, config, pkgs, ... }:
@@ -16497,7 +13806,7 @@ The `extraConfig` section here CANNOT be reindented. This has something to do wi
-3.4.1.31. Sway
+3.3.1.31. Sway
I am currently using SwayFX, which adds some nice effects to sway, like rounded corners and hiding the separator between title and content of a window.
@@ -16722,10 +14031,10 @@ Currently, I am too lazy to explain every option here, but most of it is very se
# output = lib.mapAttrs' lib.swarselsystems.eachMonitor monitors;
output = {
"${config.swarselsystems.sharescreen}" = {
- bg = "${self}/wallpaper/lenovowp.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/lenovowp.png ${config.stylix.imageScalingMode}";
};
"Philips Consumer Electronics Company PHL BDM3270 AU11806002320" = {
- bg = "${self}/wallpaper/standwp.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/standwp.png ${config.stylix.imageScalingMode}";
};
};
input = config.swarselsystems.standardinputs;
@@ -16918,7 +14227,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se
-3.4.1.32. Kanshi
+3.3.1.32. Kanshi
{ lib, config, ... }:
@@ -17014,7 +14323,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se
-3.4.1.33. gpg-agent
+3.3.1.33. gpg-agent
Settinfs that are needed for the gpg-agent. Also we are enabling emacs support for unlocking my Yubikey here.
@@ -17068,7 +14377,7 @@ in
-3.4.1.34. gammastep
+3.3.1.34. gammastep
This service changes the screen hue at night. I am not sure if that really does something, but I like the color anyways.
@@ -17082,7 +14391,7 @@ in
{
options.swarselsystems.modules.gammastep = lib.mkEnableOption "gammastep settings";
config = lib.mkIf config.swarselsystems.modules.gammastep {
- services.gammastep = {
+ services.gammastep = lib.mkIf (config.swarselsystems.isNixos && !config.swarselsystems.isPublic) {
enable = true;
provider = "manual";
inherit longitude latitude;
@@ -17095,11 +14404,11 @@ in
-3.4.2. Server
+3.3.2. Server
-3.4.2.1. Imports
+3.3.2.1. Imports
This section sets up all the imports that are used in the home-manager section.
@@ -17122,7 +14431,7 @@ in
-3.4.2.2. Symlinking dotfiles
+3.3.2.2. Symlinking dotfiles
This section should be used in order to symlink already existing configuration files using `home.file` and setting session variables using `home.sessionVariables`.
@@ -17139,7 +14448,7 @@ As for the `home.sessionVariables`, it should be noted that environment variable
config = lib.mkIf config.swarselsystems.modules.server.dotfiles {
home.file = {
"init.el" = lib.mkForce {
- source = self + /programs/emacs/server.el;
+ source = self + /files/emacs/server.el;
target = ".emacs.d/init.el";
};
};
@@ -17151,11 +14460,11 @@ As for the `home.sessionVariables`, it should be noted that environment variable
-3.4.3. Darwin
+3.3.3. Darwin
-3.4.3.1. Imports
+3.3.3.1. Imports
This section sets up all the imports that are used in the home-manager section.
@@ -17163,13 +14472,10 @@ This section sets up all the imports that are used in the home-manager section.
{ self, ... }:
-let
- modulesPath = "${self}/modules";
-in
{
imports = [
- "${modulesPath}/home/common/settings.nix"
- "${modulesPath}/home/common/sharedsetup.nix"
+ "${self}/modules/home/common/settings.nix"
+ "${self}/modules/home/common/sharedsetup.nix"
];
}
@@ -17178,7 +14484,7 @@ in
-3.4.4. Optional
+3.3.4. Optional
Akin to the optional NixOS modules.
@@ -17196,7 +14502,7 @@ in
-3.4.4.1. Gaming
+3.3.4.1. Gaming
The rest of the settings is at gaming.
@@ -17248,7 +14554,7 @@ The rest of the settings is at
-3.4.4.2. Work
+3.3.4.2. Work
The rest of the settings is at work. Here, I am setting up the different firefox profiles that I need for the SSO sites that I need to access at work as well as a few ssh shorthands.
@@ -17285,13 +14591,13 @@ in
wayland.windowManager.sway.config = {
output = {
"Applied Creative Technology Transmitter QUATTRO201811" = {
- bg = "${self}/wallpaper/navidrome.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/navidrome.png ${config.stylix.imageScalingMode}";
};
"Hewlett Packard HP Z24i CN44250RDT" = {
- bg = "${self}/wallpaper/op6wp.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/op6wp.png ${config.stylix.imageScalingMode}";
};
"HP Inc. HP 732pk CNC4080YL5" = {
- bg = "${self}/wallpaper/botanicswp.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/botanicswp.png ${config.stylix.imageScalingMode}";
};
};
};
@@ -17696,7 +15002,7 @@ in
-3.4.4.3. Framework
+3.3.4.3. Framework
This holds configuration that is specific to framework laptops.
@@ -17717,6 +15023,2616 @@ This holds configuration that is specific to framework laptops.
};
};
}
+
+
+
+
+
+
+
+3.4. Packages
+
+
+This is the central station for self-defined packages. These are all referenced in default.nix. Wherever possible, I am keeping the shell version of these scripts in this file as well and then read it using builtin.readFile in the NixOS configurations. This lets me keep full control in this one file but also keep the separate files uncluttered.
+
+
+
+Note: The structure of generating the packages was changed in commit 2cf03a3 refactor: package and module generation. That commit can be checked out in order to see a simpler version of achieving the same thing.
+
+
+
+{ self, lib, pkgs, ... }:
+let
+ mkPackages = names: pkgs: builtins.listToAttrs (map
+ (name: {
+ inherit name;
+ value = pkgs.callPackage "${self}/pkgs/${name}" { inherit self name; };
+ })
+ names);
+ packageNames = lib.swarselsystems.readNix "pkgs";
+in
+mkPackages packageNames pkgs
+
+
+
+
+
+
+3.4.1. pass-fuzzel
+
+
+This app allows me, in conjunction with my Yubikey, to quickly enter passwords when the need arises. Normal and TOTP passwords are supported, and they can either be printed directly or copied to the clipboard.
+
+
+
+# Adapted from https://code.kulupu.party/thesuess/home-manager/src/branch/main/modules/river.nix
+shopt -s nullglob globstar
+
+otp=0
+typeit=0
+while :; do
+ case ${1:-} in
+ -t | --type)
+ typeit=1
+ ;;
+ -o | --otp)
+ otp=1
+ ;;
+ *) break ;;
+ esac
+ shift
+done
+
+export PASSWORD_STORE_DIR=~/.local/share/password-store
+prefix=${PASSWORD_STORE_DIR-~/.local/share/password-store}
+if [[ $otp -eq 0 ]]; then
+ password_files=("$prefix"/**/*.gpg)
+else
+ password_files=("$prefix"/otp/**/*.gpg)
+fi
+password_files=("${password_files[@]#"$prefix"/}")
+password_files=("${password_files[@]%.gpg}")
+
+password=$(printf '%s\n' "${password_files[@]}" | fuzzel --dmenu "$@")
+
+[[ -n $password ]] || exit
+if [[ $otp -eq 0 ]]; then
+ if [[ $typeit -eq 0 ]]; then
+ pass show -c "$password" &> /tmp/pass-fuzzel
+ else
+ pass show "$password" | {
+ IFS= read -r pass
+ printf %s "$pass"
+ } | wtype -
+ fi
+else
+ if [[ $typeit -eq 0 ]]; then
+ pass otp -c "$password" &> /tmp/pass-fuzzel
+ else
+ pass otp "$password" | {
+ IFS= read -r pass
+ printf %s "$pass"
+ } | wtype -
+ fi
+fi
+notify-send -u critical -a pass -t 1000 "Copied/Typed Password"
+
+
+
+
+{ self, name, writeShellApplication, libnotify, pass, fuzzel, wtype }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ libnotify (pass.withExtensions (exts: [ exts.pass-otp ])) fuzzel wtype ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+
+3.4.2. cura5
+
+
+The version of cura used to be quite outdated in nixpkgs. I am fetching a newer AppImage here and use that instead.
+
+
+
+
+# taken from https://github.com/NixOS/nixpkgs/issues/186570#issuecomment-1627797219
+{ appimageTools, fetchurl, writeScriptBin, pkgs, ... }:
+
+
+let
+ cura5 = appimageTools.wrapType2 rec {
+ pname = "cura5";
+ version = "5.9.0";
+ src = fetchurl {
+ url = "https://github.com/Ultimaker/Cura/releases/download/${version}/UltiMaker-Cura-${version}-linux-X64.AppImage";
+ hash = "sha256-STtVeM4Zs+PVSRO3cI0LxnjRDhOxSlttZF+2RIXnAp4=";
+ };
+ extraPkgs = pkgs: with pkgs; [ ];
+ };
+in
+writeScriptBin "cura" ''
+ #! ${pkgs.bash}/bin/bash
+ # AppImage version of Cura loses current working directory and treats all paths relative to $HOME.
+ # So we convert each of the files passed as argument to an absolute path.
+ # This fixes use cases like `cd /path/to/my/files; cura mymodel.stl anothermodel.stl`.
+ args=()
+ for a in "$@"; do
+ if [ -e "$a" ]; then
+ a="$(realpath "$a")"
+ fi
+ args+=("$a")
+ done
+ exec "${cura5}/bin/cura5" "''${args[@]}"
+''
+
+
+
+
+
+
+3.4.3. hm-specialisation
+
+
+This script allows for quick git home-manager specialisation switching.
+
+
+
+
+{ name, writeShellApplication, fzf, findutils, home-manager, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ fzf findutils home-manager ];
+ text = ''
+ genpath=$(home-manager generations | head -1 | awk '{print $7}')
+ dirs=$(find "$genpath/specialisation" -type l 2>/dev/null; [ -d "$genpath" ] && echo "$genpath")
+ "$(echo "$dirs" | fzf --prompt="Choose home-manager specialisation to activate")"/activate
+ '';
+}
+
+
+
+
+
+
+
+3.4.4. cdw
+
+
+This script allows for quick git worktree switching.
+
+
+
+
+{ name, writeShellApplication, fzf, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ fzf ];
+ text = ''
+ cd "$(git worktree list | fzf | awk '{print $1}')"
+ '';
+}
+
+
+
+
+
+
+
+3.4.5. cdb
+
+
+This script allows for quick git branch switching.
+
+
+
+{ name, writeShellApplication, fzf, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ fzf ];
+ text = ''
+ git checkout "$(git branch --list | grep -v "^\*" | fzf | awk '{print $1}')"
+ '';
+}
+
+
+
+
+
+
+3.4.6. bak
+
+
+This script lets me quickly backup files by appending .bak to the filename.
+
+
+
+
+{ name, writeShellApplication, ... }:
+
+writeShellApplication {
+ inherit name;
+ text = ''
+ cp -r "$1"{,.bak}
+ '';
+}
+
+
+
+
+
+
+
+3.4.7. timer
+
+
+This app starts a configuratble timer and uses TTS to say something once the timer runs out.
+
+
+
+
+{ name, writeShellApplication, speechd, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ speechd ];
+ text = ''
+ sleep "$1"; while true; do spd-say "$2"; sleep 0.5; done;
+ '';
+}
+
+
+
+
+
+
+3.4.8. 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.
+
+
+
+wait=0
+while :; do
+ case ${1:-} in
+ -w | --wait)
+ wait=1
+ ;;
+ *) break ;;
+ esac
+ shift
+done
+
+STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep kittyterm || true)
+if [ "$STR" == "" ]; then
+ swaymsg '[title="kittyterm"]' scratchpad show
+ emacsclient -c -a "" "$@"
+ swaymsg '[title="kittyterm"]' scratchpad show
+else
+ if [[ $wait -eq 0 ]]; then
+ emacsclient -n -c -a "" "$@"
+ else
+ emacsclient -c -a "" "$@"
+ fi
+fi
+
+
+
+
+{ self, name, writeShellApplication, emacs30-pgtk, sway, jq }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ emacs30-pgtk sway jq ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+
+3.4.9. 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.
+
+
+
+
+# Adapted from https://github.com/bennofs/nix-index/blob/master/command-not-found.sh
+command_not_found_handle() {
+ if [ -n "${MC_SID-}" ] || ! [ -t 1 ]; then
+ >&2 echo "$1: command not found"
+ return 127
+ fi
+
+ echo -n "searching nix-index..."
+ ATTRS=$(@nix-locate@ --minimal --no-group --type x --type s --top-level --whole-name --at-root "/bin/$1")
+
+ case $(echo -n "$ATTRS" | grep -c "^") in
+ 0)
+ >&2 echo -ne "$(@tput@ el1)\r"
+ >&2 echo "$1: command not found"
+ ;;
+ *)
+ >&2 echo -ne "$(@tput@ el1)\r"
+ >&2 echo "The program ‘$(@tput@ setaf 4)$1$(@tput@ sgr0)’ is currently not installed."
+ >&2 echo "It is provided by the following derivation(s):"
+ while read -r ATTR; do
+ ATTR=${ATTR%.out}
+ >&2 echo " $(@tput@ setaf 12)nixpkgs#$(@tput@ setaf 4)$ATTR$(@tput@ sgr0)"
+ done <<< "$ATTRS"
+ ;;
+ esac
+
+ return 127
+}
+
+command_not_found_handler() {
+ command_not_found_handle "$@"
+ return $?
+}
+
+
+
+
+
+3.4.10. 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.
+
+
+
+kitty=0
+element=0
+vesktop=0
+spotifyplayer=0
+while :; do
+ case ${1:-} in
+ -k | --kitty)
+ kitty=1
+ ;;
+ -e | --element)
+ element=1
+ ;;
+ -d | --vesktop)
+ vesktop=1
+ ;;
+ -s | --spotifyplayer)
+ spotifyplayer=1
+ ;;
+ *) break ;;
+ esac
+ shift
+done
+
+if [[ $kitty -eq 1 ]]; then
+ STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep kittyterm || true)
+ CHECK=$(swaymsg -t get_tree | grep kittyterm || true)
+ if [ "$CHECK" == "" ]; then
+ exec kitty -T kittyterm -o confirm_os_window_close=0 zellij attach --create kittyterm &
+ sleep 1
+ fi
+ if [ "$STR" == "" ]; then
+ exec swaymsg '[title="kittyterm"]' scratchpad show
+ else
+ exec swaymsg '[title="kittyterm"]' scratchpad show
+ fi
+elif [[ $element -eq 1 ]]; then
+ STR=$(swaymsg -t get_tree | grep Element || true)
+ if [ "$STR" == "" ]; then
+ exec element-desktop
+ else
+ exec swaymsg '[app_id=Element]' kill
+ fi
+elif [[ $vesktop -eq 1 ]]; then
+ STR=$(swaymsg -t get_tree | grep vesktop || true)
+ if [ "$STR" == "" ]; then
+ exec vesktop
+ else
+ exec swaymsg '[app_id=vesktop]' kill
+ fi
+elif [[ $spotifyplayer -eq 1 ]]; then
+ STR=$(swaymsg -t get_tree | jq -r 'recurse(.nodes[]) | select(.name == "__i3_scratch")' | grep spotifytui || true)
+ CHECK=$(swaymsg -t get_tree | grep spotifytui || true)
+ if [ "$CHECK" == "" ]; then
+ exec kitty -T spotifytui -o confirm_os_window_close=0 spotify_player &
+ sleep 1
+ fi
+ if [ "$STR" == "" ]; then
+ exec swaymsg '[title="spotifytui"]' scratchpad show
+ else
+ exec swaymsg '[title="spotifytui"]' scratchpad show
+ fi
+fi
+
+
+
+
+{ self, name, writeShellApplication, kitty, element-desktop, vesktop, spotify-player, jq }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ kitty element-desktop vesktop spotify-player jq ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+
+3.4.11. swarselzellij
+
+
+KITTIES=$(($(pgrep -P 1 kitty | wc -l) - 1))
+
+if ((KITTIES < 1)); then
+ exec kitty -o confirm_os_window_close=0 zellij attach --create main
+else
+ exec kitty -o confirm_os_window_close=0 zellij attach --create "temp $KITTIES"
+fi
+
+
+
+
+{ self, name, writeShellApplication, kitty }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ kitty ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+
+3.4.12. 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.
+
+
+
+CFG=$(git --git-dir="$HOME"/.dotfiles/.git --work-tree="$HOME"/.dotfiles/ status -s | wc -l)
+CSE=$(git --git-dir="$DOCUMENT_DIR_PRIV"/CSE_TUWIEN/.git --work-tree="$DOCUMENT_DIR_PRIV"/CSE_TUWIEN/ status -s | wc -l)
+PASS=$(($(git --git-dir="$HOME"/.local/share/password-store/.git --work-tree="$HOME"/.local/share/password-store/ status -s | wc -l) + $(git --git-dir="$HOME"/.local/share/password-store/.git --work-tree="$HOME"/.local/share/password-store/ diff origin/main..HEAD | wc -l)))
+
+if [[ $CFG != 0 ]]; then
+ CFG_STR='CONFIG'
+else
+ CFG_STR=''
+fi
+
+if [[ $CSE != 0 ]]; then
+ CSE_STR=' CSE'
+else
+ CSE_STR=''
+fi
+
+if [[ $PASS != 0 ]]; then
+ PASS_STR=' PASS'
+else
+ PASS_STR=''
+fi
+
+OUT="$CFG_STR""$CSE_STR""$PASS_STR"
+echo "$OUT"
+
+
+
+
+{ self, name, writeShellApplication, git }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ git ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+
+3.4.13. opacitytoggle
+
+
+This app quickly toggles between 5% and 0% transparency.
+
+
+
+if swaymsg opacity plus 0.01 -q; then
+ swaymsg opacity 1
+else
+ swaymsg opacity 0.95
+fi
+
+
+
+
+{ self, name, writeShellApplication, sway }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ sway ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+3.4.14. 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.
+
+
+
+set -euo pipefail
+
+OLD_TRANSID=$(sudo btrfs subvolume find-new /mnt/root-blank 9999999)
+OLD_TRANSID=${OLD_TRANSID#transid marker was }
+
+sudo btrfs subvolume find-new "/mnt/root" "$OLD_TRANSID" |
+ sed '$d' |
+ cut -f17- -d' ' |
+ sort |
+ uniq |
+ while read -r path; do
+ path="/$path"
+ if [ -L "$path" ]; then
+ : # The path is a symbolic link, so is probably handled by NixOS already
+ elif [ -d "$path" ]; then
+ : # The path is a directory, ignore
+ else
+ echo "$path"
+ fi
+ done
+
+
+
+
+{ self, name, writeShellApplication }:
+writeShellApplication {
+ inherit name;
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+3.4.15. 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.
+
+
+
+
+{ name, writeShellApplication, jq, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ jq ];
+ text = ''
+ count=$(curl -u Swarsel:"$(cat "$XDG_RUNTIME_DIR/secrets/github_notif")" https://api.github.com/notifications | jq '. | length')
+
+ if [[ "$count" != "0" ]]; then
+ echo "{\"text\":\"$count\"}"
+ fi
+ '';
+}
+
+
+
+
+
+3.4.16. fullscreen
+
+
+This application moves the wl-mirror app to the T workspace and makes it fullscreen there.
+
+
+
+{ name, writeShellApplication, sway, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ sway ];
+ text = ''
+ swaymsg '[app_id=at.yrlf.wl_mirror] move to workspace 14:T'
+ swaymsg '[app_id=at.yrlf.wl_mirror] fullscreen'
+ '';
+}
+
+
+
+
+
+3.4.17. screenshare
+
+
+
+headless="false"
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -h)
+ headless="true"
+ ;;
+ *)
+ echo "Invalid option detected."
+ ;;
+ esac
+ shift
+done
+
+SHARESCREEN="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$(hostname)".config.home-manager.users."$(whoami)".swarselsystems.sharescreen)"
+
+if [[ $headless == "true" ]]; then
+ wl-mirror "$SHARESCREEN"
+else
+ wl-mirror "$SHARESCREEN" &
+ sleep 0.1
+ swaymsg '[app_id=at.yrlf.wl_mirror] move to workspace 14:T'
+ swaymsg '[app_id=at.yrlf.wl_mirror] fullscreen'
+fi
+
+
+
+
+
+{ self, name, writeShellApplication, sway }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ sway ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+3.4.18. swarsel-bootstrap
+
+
+This program sets up a new NixOS host remotely. It also takes care of secret management on the new host.
+
+
+
+# highly inspired by https://github.com/EmergentMind/nix-config/blob/dev/files/scripts/bootstrap-nixos.sh
+set -eo pipefail
+
+target_hostname=""
+target_destination=""
+target_user="swarsel"
+ssh_port="22"
+persist_dir=""
+disk_encryption=0
+temp=$(mktemp -d)
+
+function help_and_exit() {
+ echo
+ echo "Remotely installs SwarselSystem on a target machine including secret deployment."
+ echo
+ echo "USAGE: $0 -n <target_hostname> -d <target_destination> [OPTIONS]"
+ echo
+ echo "ARGS:"
+ echo " -n <target_hostname> specify target_hostname of the target host to deploy the nixos config on."
+ echo " -d <target_destination> specify ip or url to the target host."
+ echo " target during install process."
+ echo
+ echo "OPTIONS:"
+ echo " -u <target_user> specify target_user with sudo access. nix-config will be cloned to their home."
+ echo " Default='${target_user}'."
+ echo " --port <ssh_port> specify the ssh port to use for remote access. Default=${ssh_port}."
+ echo " --debug Enable debug mode."
+ echo " -h | --help Print this help."
+ exit 0
+}
+
+function cleanup() {
+ rm -rf "$temp"
+}
+trap cleanup exit
+
+function red() {
+ echo -e "\x1B[31m[!] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[31m[!] $($2) \x1B[0m"
+ fi
+}
+function green() {
+ echo -e "\x1B[32m[+] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[32m[+] $($2) \x1B[0m"
+ fi
+}
+function yellow() {
+ echo -e "\x1B[33m[*] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[33m[*] $($2) \x1B[0m"
+ fi
+}
+
+function yes_or_no() {
+ echo -en "\x1B[32m[+] $* [y/n] (default: y): \x1B[0m"
+ while true; do
+ read -rp "" yn
+ yn=${yn:-y}
+ case $yn in
+ [Yy]*) return 0 ;;
+ [Nn]*) return 1 ;;
+ esac
+ done
+}
+
+function update_sops_file() {
+ key_name=$1
+ key_type=$2
+ key=$3
+
+ if [ ! "$key_type" == "hosts" ] && [ ! "$key_type" == "users" ]; then
+ red "Invalid key type passed to update_sops_file. Must be either 'hosts' or 'users'."
+ exit 1
+ fi
+ cd "${git_root}"
+
+ SOPS_FILE=".sops.yaml"
+ sed -i "{
+ # Remove any * and & entries for this host
+ /[*&]$key_name/ d;
+ # Inject a new age: entry
+ # n matches the first line following age: and p prints it, then we transform it while reusing the spacing
+ /age:/{n; p; s/\(.*- \*\).*/\1$key_name/};
+ # Inject a new hosts or user: entry
+ /&$key_type/{n; p; s/\(.*- &\).*/\1$key_name $key/}
+ }" $SOPS_FILE
+ green "Updating .sops.yaml"
+ cd -
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -n)
+ shift
+ target_hostname=$1
+ ;;
+ -d)
+ shift
+ target_destination=$1
+ ;;
+ -u)
+ shift
+ target_user=$1
+ ;;
+ --port)
+ shift
+ ssh_port=$1
+ ;;
+ --debug)
+ set -x
+ ;;
+ -h | --help) help_and_exit ;;
+ *)
+ echo "Invalid option detected."
+ help_and_exit
+ ;;
+ esac
+ shift
+done
+
+green "~SwarselSystems~ remote installer"
+green "Reading system information for $target_hostname ..."
+
+DISK="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.rootDisk)"
+green "Root Disk: $DISK"
+
+CRYPTED="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isCrypted)"
+if [[ $CRYPTED == "true" ]]; then
+ green "Encryption: ✓"
+ disk_encryption=1
+else
+ red "Encryption: X"
+ disk_encryption=0
+fi
+
+IMPERMANENCE="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isImpermanence)"
+if [[ $IMPERMANENCE == "true" ]]; then
+ green "Impermanence: ✓"
+ persist_dir="/persist"
+else
+ red "Impermanence: X"
+ persist_dir=""
+fi
+
+SWAP="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isSwap)"
+if [[ $SWAP == "true" ]]; then
+ green "Swap: ✓"
+else
+ red "Swap: X"
+fi
+
+SECUREBOOT="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isSecureBoot)"
+if [[ $SECUREBOOT == "true" ]]; then
+ green "Secure Boot: ✓"
+else
+ red "Secure Boot: X"
+fi
+
+ssh_cmd="ssh -oport=${ssh_port} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -t $target_user@$target_destination"
+# ssh_root_cmd=$(echo "$ssh_cmd" | sed "s|${target_user}@|root@|") # uses @ in the sed switch to avoid it triggering on the $ssh_key value
+ssh_root_cmd=${ssh_cmd/${target_user}@/root@}
+scp_cmd="scp -oport=${ssh_port} -o StrictHostKeyChecking=no"
+
+if [[ -z ${FLAKE} ]]; then
+ FLAKE=/home/"$target_user"/.dotfiles
+fi
+if [ ! -d "$FLAKE" ]; then
+ cd /home/"$target_user"
+ yellow "Flake directory not found - cloning repository from GitHub"
+ git clone git@github.com:Swarsel/.dotfiles.git || (yellow "Could not clone repository via SSH - defaulting to HTTPS" && git clone https://github.com/Swarsel/.dotfiles.git)
+ FLAKE=/home/"$target_user"/.dotfiles
+fi
+
+cd "$FLAKE"
+git_root=$(git rev-parse --show-toplevel)
+# ------------------------
+green "Wiping known_hosts of $target_destination"
+sed -i "/$target_hostname/d; /$target_destination/d" ~/.ssh/known_hosts
+# ------------------------
+green "Preparing a new ssh_host_ed25519_key pair for $target_hostname."
+# Create the directory where sshd expects to find the host keys
+install -d -m755 "$temp/$persist_dir/etc/ssh"
+# Generate host ssh key pair without a passphrase
+ssh-keygen -t ed25519 -f "$temp/$persist_dir/etc/ssh/ssh_host_ed25519_key" -C root@"$target_hostname" -N ""
+# Set the correct permissions so sshd will accept the key
+chmod 600 "$temp/$persist_dir/etc/ssh/ssh_host_ed25519_key"
+echo "Adding ssh host fingerprint at $target_destination to ~/.ssh/known_hosts"
+# This will fail if we already know the host, but that's fine
+ssh-keyscan -p "$ssh_port" "$target_destination" >> ~/.ssh/known_hosts || true
+# ------------------------
+# when using luks, disko expects a passphrase on /tmp/disko-password, so we set it for now and will update the passphrase later
+# via the config
+if [ "$disk_encryption" -eq 1 ]; then
+ while true; do
+ green "Set disk encryption passphrase:"
+ read -rs luks_passphrase
+ green "Please confirm passphrase:"
+ read -rs luks_passphrase_confirm
+ if [[ $luks_passphrase == "$luks_passphrase_confirm" ]]; then
+ $ssh_root_cmd "/bin/sh -c 'echo $luks_passphrase > /tmp/disko-password'"
+ break
+ else
+ red "Passwords do not match"
+ fi
+ done
+fi
+# ------------------------
+green "Generating hardware-config.nix for $target_hostname and adding it to the nix-config."
+$ssh_root_cmd "nixos-generate-config --force --no-filesystems --root /mnt"
+
+green "Injecting initialSetup"
+$ssh_root_cmd "sed -i '/ boot.extraModulePackages /a \ swarselsystems.initialSetup = true;' /mnt/etc/nixos/hardware-configuration.nix"
+
+mkdir -p "$FLAKE"/hosts/nixos/"$target_hostname"
+$scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix "${git_root}"/hosts/nixos/"$target_hostname"/hardware-configuration.nix
+# ------------------------
+
+green "Deploying minimal NixOS installation on $target_destination"
+SHELL=/bin/sh nix run github:nix-community/nixos-anywhere -- --ssh-port "$ssh_port" --extra-files "$temp" --flake .#"$target_hostname" root@"$target_destination"
+
+echo "Updating ssh host fingerprint at $target_destination to ~/.ssh/known_hosts"
+ssh-keyscan -p "$ssh_port" "$target_destination" >> ~/.ssh/known_hosts || true
+# ------------------------
+
+while true; do
+ read -rp "Press Enter to continue once the remote host has finished booting."
+ if nc -z "$target_destination" "${ssh_port}" 2> /dev/null; then
+ green "$target_destination is booted. Continuing..."
+ break
+ else
+ yellow "$target_destination is not yet ready."
+ fi
+done
+
+# ------------------------
+
+if [[ $SECUREBOOT == "true" ]]; then
+ green "Setting up secure boot keys"
+ $ssh_root_cmd "mkdir -p /var/lib/sbctl"
+ read -ra scp_call <<< "${scp_cmd}"
+ sudo "${scp_call[@]}" -r /var/lib/sbctl root@"$target_destination":/var/lib/
+ $ssh_root_cmd "sbctl enroll-keys --ignore-immutable --microsoft || true"
+fi
+# ------------------------
+green "Disabling initialSetup"
+sed -i '/swarselsystems\.initialSetup = true;/d' "$git_root"/hosts/nixos/"$target_hostname"/hardware-configuration.nix
+
+if [ -n "$persist_dir" ]; then
+ $ssh_root_cmd "cp /etc/machine-id $persist_dir/etc/machine-id || true"
+ $ssh_root_cmd "cp -R /etc/ssh/ $persist_dir/etc/ssh/ || true"
+fi
+# ------------------------
+green "Generating an age key based on the new ssh_host_ed25519_key."
+target_key=$(
+ ssh-keyscan -p "$ssh_port" -t ssh-ed25519 "$target_destination" 2>&1 |
+ grep ssh-ed25519 |
+ cut -f2- -d" " ||
+ (
+ red "Failed to get ssh key. Host down?"
+ exit 1
+ )
+)
+host_age_key=$(nix shell nixpkgs#ssh-to-age.out -c sh -c "echo $target_key | ssh-to-age")
+
+if grep -qv '^age1' <<< "$host_age_key"; then
+ red "The result from generated age key does not match the expected format."
+ yellow "Result: $host_age_key"
+ yellow "Expected format: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ exit 1
+else
+ echo "$host_age_key"
+fi
+
+green "Updating nix-secrets/.sops.yaml"
+update_sops_file "$target_hostname" "hosts" "$host_age_key"
+yellow ".sops.yaml has been updated. There may be superfluous entries, you might need to edit manually."
+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}"/secrets/*/secrets.yaml
+# --------------------------
+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
+$scp_cmd root@"$target_destination":/etc/ssh/ssh_host_ed25519_key root@"$target_destination":/home/"$target_user"/.ssh/ssh_host_ed25519_key
+$ssh_root_cmd "mkdir -p /home/$target_user/.ssh; chown $target_user:users /home/$target_user/.ssh/ssh_host_ed25519_key"
+# __________________________
+
+if yes_or_no "Add ssh host fingerprints for git upstream repositories? (This is needed for building the full config)"; then
+ green "Adding ssh host fingerprints for git{lab,hub}"
+ $ssh_cmd "mkdir -p /home/$target_user/.ssh/; ssh-keyscan -t ssh-ed25519 gitlab.com github.com swagit.swarsel.win >> /home/$target_user/.ssh/known_hosts"
+ $ssh_root_cmd "mkdir -p /root/.ssh/; ssh-keyscan -t ssh-ed25519 gitlab.com github.com swagit.swarsel.win >> /root/.ssh/known_hosts"
+fi
+# --------------------------
+
+if yes_or_no "Do you want to copy your full nix-config and nix-secrets to $target_hostname?"; then
+ green "Adding ssh host fingerprint at $target_destination to ~/.ssh/known_hosts"
+ ssh-keyscan -p "$ssh_port" "$target_destination" >> ~/.ssh/known_hosts || true
+ green "Copying full nix-config to $target_hostname"
+ cd "${git_root}"
+ just sync "$target_user" "$target_destination"
+
+ if [ -n "$persist_dir" ]; then
+ $ssh_root_cmd "cp -r /home/$target_user/.dotfiles $persist_dir/.dotfiles || true"
+ $ssh_root_cmd "cp -r /home/$target_user/.ssh $persist_dir/.ssh || true"
+ fi
+
+ if yes_or_no "Do you want to rebuild immediately?"; then
+ green "Rebuilding nix-config on $target_hostname"
+ yellow "Reminder: The password is 'setup'"
+ $ssh_root_cmd "mkdir -p /root/.local/share/nix/; printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' > /root/.local/share/nix/trusted-settings.json"
+ $ssh_cmd -oForwardAgent=yes "cd .dotfiles && sudo nixos-rebuild --show-trace --flake .#$target_hostname switch"
+ fi
+else
+ echo
+ green "NixOS was successfully installed!"
+ echo "Post-install config build instructions:"
+ echo "To copy nix-config from this machine to the $target_hostname, run the following command from ~/nix-config"
+ echo "just sync $target_user $target_destination"
+ echo "To rebuild, sign into $target_hostname and run the following command from ~/nix-config"
+ echo "cd nix-config"
+ # see above FIXME:(bootstrap)
+ echo "sudo nixos-rebuild --show-trace --flake .#$target_hostname switch"
+ # echo "just rebuild"
+ echo
+fi
+
+if yes_or_no "You can now commit and push the nix-config, which includes the hardware-configuration.nix for $target_hostname?"; then
+ cd "${git_root}"
+ deadnix hosts/nixos/"$target_hostname"/hardware-configuration.nix -qe
+ nixpkgs-fmt hosts/nixos/"$target_hostname"/hardware-configuration.nix
+ (pre-commit run --all-files 2> /dev/null || true) &&
+ git add "$git_root/hosts/nixos/$target_hostname/hardware-configuration.nix" &&
+ git add "$git_root/.sops.yaml" &&
+ git add "$git_root/secrets" &&
+ (git commit -m "feat: deployed $target_hostname" || true) && git push
+fi
+
+
+
+
+
+{ self, name, writeShellApplication, openssh }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ openssh ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+3.4.19. swarsel-rebuild
+
+
+set -eo pipefail
+
+target_config="chaostheatre"
+target_user="swarsel"
+
+function help_and_exit() {
+ echo
+ echo "Builds SwarselSystem configuration."
+ echo
+ echo "USAGE: $0 [OPTIONS]"
+ echo
+ echo "ARGS:"
+ echo " -n <target_config> specify nixos config to build."
+ echo " Default: chaostheatre"
+ echo " -u <target_user> specify user to deploy for."
+ echo " Default: swarsel"
+ echo " -h | --help Print this help."
+ exit 0
+}
+
+function red() {
+ echo -e "\x1B[31m[!] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[31m[!] $($2) \x1B[0m"
+ fi
+}
+function green() {
+ echo -e "\x1B[32m[+] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[32m[+] $($2) \x1B[0m"
+ fi
+}
+function yellow() {
+ echo -e "\x1B[33m[*] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[33m[*] $($2) \x1B[0m"
+ fi
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -n)
+ shift
+ target_config=$1
+ ;;
+ -u)
+ shift
+ target_user=$1
+ ;;
+ -h | --help) help_and_exit ;;
+ *)
+ echo "Invalid option detected."
+ help_and_exit
+ ;;
+ esac
+ shift
+done
+
+cd /home/"$target_user"
+
+if [ ! -d /home/"$target_user"/.dotfiles ]; then
+ green "Cloning repository from GitHub"
+ git clone https://github.com/Swarsel/.dotfiles.git
+else
+ red "A .dotfiles repository is in the way. Please (re-)move the repository and try again."
+ exit 1
+fi
+
+local_keys=$(ssh-add -L || true)
+pub_key=$(cat /home/"$target_user"/.dotfiles/secrets/keys/ssh/yubikey.pub)
+read -ra pub_arr <<< "$pub_key"
+
+cd .dotfiles
+if [[ $local_keys != *"${pub_arr[1]}"* ]]; then
+ yellow "The ssh key for this configuration is not available."
+ green "Adjusting flake.nix so that the configuration is buildable"
+ sed -i '/nix-secrets = {/,/^[[:space:]]*};/d' flake.nix
+ sed -i '/vbc-nix = {/,/^[[:space:]]*};/d' flake.nix
+ sed -i '/[[:space:]]*\/\/ (inputs.vbc-nix.overlays.default final prev)/d' overlays/default.nix
+ rm modules/home/common/env.nix
+ rm modules/home/common/gammastep.nix
+ rm modules/home/common/git.nix
+ rm modules/home/common/mail.nix
+ rm modules/home/common/yubikey.nix
+ rm modules/nixos/server/restic.nix
+ rm hosts/nixos/sync/default.nix
+ rm -rf modules/nixos/server
+ rm -rf modules/home/server
+ nix flake update vbc-nix
+ git add .
+else
+ green "Valid SSH key found! Continuing with installation"
+fi
+sudo nixos-generate-config --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/
+git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
+
+green "Installing flake $target_config"
+sudo nixos-rebuild --show-trace --flake .#"$target_config" boot
+yellow "Please keep in mind that this is only a demo of the configuration. Things might break unexpectedly."
+
+
+
+
+
+
+{ self, name, writeShellApplication, git }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ git ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+3.4.20. swarsel-install
+
+
+Autoformatting always puts the EOF with indentation, which makes shfmt check fail. When editing this block, unindent them manually.
+
+
+
+set -eo pipefail
+
+target_config="chaostheatre"
+target_hostname="chaostheatre"
+target_user="swarsel"
+persist_dir=""
+target_disk="/dev/vda"
+disk_encryption=0
+
+function help_and_exit() {
+ echo
+ echo "Locally installs SwarselSystem on this machine."
+ echo
+ echo "USAGE: $0 -n <target_config> -d <target_disk> [OPTIONS]"
+ echo
+ echo "ARGS:"
+ echo " -n <target_config> specify the nixos config to deploy."
+ echo " Default: chaostheatre"
+ echo " -d <target_disk> specify disk to install on."
+ echo " Default: /dev/vda"
+ echo " -u <target_user> specify user to deploy for."
+ echo " Default: swarsel"
+ echo " -h | --help Print this help."
+ exit 0
+}
+
+function red() {
+ echo -e "\x1B[31m[!] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[31m[!] $($2) \x1B[0m"
+ fi
+}
+function green() {
+ echo -e "\x1B[32m[+] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[32m[+] $($2) \x1B[0m"
+ fi
+}
+function yellow() {
+ echo -e "\x1B[33m[*] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[33m[*] $($2) \x1B[0m"
+ fi
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -n)
+ shift
+ target_config=$1
+ target_hostname=$1
+ ;;
+ -u)
+ shift
+ target_user=$1
+ ;;
+ -d)
+ shift
+ target_disk=$1
+ ;;
+ -h | --help) help_and_exit ;;
+ *)
+ echo "Invalid option detected."
+ help_and_exit
+ ;;
+ esac
+ shift
+done
+
+function cleanup() {
+ sudo rm -rf .cache/nix
+ sudo rm -rf /root/.cache/nix
+}
+trap cleanup exit
+
+green "~SwarselSystems~ local installer"
+
+cd /home/"$target_user"
+
+sudo rm -rf /root/.cache/nix
+sudo rm -rf .cache/nix
+sudo rm -rf .dotfiles
+
+green "Cloning repository from GitHub"
+git clone https://github.com/Swarsel/.dotfiles.git
+
+local_keys=$(ssh-add -L || true)
+pub_key=$(cat /home/"$target_user"/.dotfiles/secrets/keys/ssh/yubikey.pub)
+read -ra pub_arr <<< "$pub_key"
+
+cd .dotfiles
+if [[ $local_keys != *"${pub_arr[1]}"* ]]; then
+ yellow "The ssh key for this configuration is not available."
+ green "Adjusting flake.nix so that the configuration is buildable ..."
+ sed -i '/nix-secrets = {/,/^[[:space:]]*};/d' flake.nix
+ sed -i '/vbc-nix = {/,/^[[:space:]]*};/d' flake.nix
+ sed -i '/[[:space:]]*\/\/ (inputs.vbc-nix.overlays.default final prev)/d' overlays/default.nix
+ rm modules/home/common/env.nix
+ rm modules/home/common/gammastep.nix
+ rm modules/home/common/git.nix
+ rm modules/home/common/mail.nix
+ rm modules/home/common/yubikey.nix
+ rm modules/nixos/server/restic.nix
+ rm hosts/nixos/sync/default.nix
+ rm -rf modules/nixos/server
+ rm -rf modules/home/server
+ cat > hosts/nixos/chaostheatre/options-home.nix << EOF
+ { self, lib, ... }:
+ {
+ options = {
+ swarselsystems = {
+ modules = {
+ yubikey = lib.mkEnableOption "dummy option for chaostheatre";
+ env = lib.mkEnableOption "dummy option for chaostheatre";
+ git = lib.mkEnableOption "dummy option for chaostheatre";
+ mail = lib.mkEnableOption "dummy option for chaostheatre";
+ gammastep = lib.mkEnableOption "dummy option for chaostheatre";
+ };
+ };
+ };
+ }
+EOF
+ nix flake update vbc-nix
+ git add .
+else
+ green "Valid SSH key found! Continuing with installation"
+fi
+
+green "Reading system information for $target_config ..."
+DISK="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.rootDisk)"
+green "Root Disk in config: $DISK - Root Disk passed in cli: $target_disk"
+
+CRYPTED="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isCrypted)"
+if [[ $CRYPTED == "true" ]]; then
+ green "Encryption: ✓"
+ disk_encryption=1
+else
+ red "Encryption: X"
+ disk_encryption=0
+fi
+
+IMPERMANENCE="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isImpermanence)"
+if [[ $IMPERMANENCE == "true" ]]; then
+ green "Impermanence: ✓"
+ persist_dir="/persist"
+else
+ red "Impermanence: X"
+ persist_dir=""
+fi
+
+SWAP="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isSwap)"
+if [[ $SWAP == "true" ]]; then
+ green "Swap: ✓"
+else
+ red "Swap: X"
+fi
+
+SECUREBOOT="$(nix eval ~/.dotfiles#nixosConfigurations."$target_hostname".config.swarselsystems.isSecureBoot)"
+if [[ $SECUREBOOT == "true" ]]; then
+ green "Secure Boot: ✓"
+else
+ red "Secure Boot: X"
+fi
+
+if [ "$disk_encryption" -eq 1 ]; then
+ while true; do
+ green "Set disk encryption passphrase:"
+ read -rs luks_passphrase
+ green "Please confirm passphrase:"
+ read -rs luks_passphrase_confirm
+ if [[ $luks_passphrase == "$luks_passphrase_confirm" ]]; then
+ echo "$luks_passphrase" > /tmp/disko-password
+ break
+ else
+ red "Passwords do not match"
+ fi
+ done
+fi
+
+green "Setting up disk ..."
+if [[ $target_config == "chaostheatre" ]]; then
+ sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/v1.10.0 -- --mode destroy,format,mount --flake .#"$target_config" --yes-wipe-all-disks --arg diskDevice "$target_disk"
+else
+ sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount --flake .#"$target_config" --yes-wipe-all-disks
+fi
+sudo mkdir -p /mnt/"$persist_dir"/home/"$target_user"/
+sudo cp -r /home/"$target_user"/.dotfiles /mnt/"$persist_dir"/home/"$target_user"/
+sudo chown -R 1000:100 /mnt/"$persist_dir"/home/"$target_user"
+
+green "Generating hardware configuration ..."
+sudo nixos-generate-config --root /mnt --no-filesystems --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/
+
+green "Injecting initialSetup ..."
+sudo sed -i '/ boot.extraModulePackages /a \ swarselsystems.initialSetup = true;' /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
+
+git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
+sudo mkdir -p /root/.local/share/nix/
+printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | sudo tee /root/.local/share/nix/trusted-settings.json > /dev/null
+green "Installing flake $target_config"
+sudo nixos-install --flake .#"$target_config"
+green "Installation finished! Reboot to see changes"
+
+
+
+
+
+
+{ self, name, writeShellApplication, git }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ git ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+3.4.21. swarsel-postinstall
+
+
+set -eo pipefail
+
+target_config="chaostheatre"
+target_user="swarsel"
+
+function help_and_exit() {
+ echo
+ echo "Locally installs SwarselSystem on this machine."
+ echo
+ echo "USAGE: $0 -d <disk> [OPTIONS]"
+ echo
+ echo "ARGS:"
+ echo " -d <disk> specify disk to install on."
+ echo " -n <target_config> specify the nixos config to deploy."
+ echo " Default: chaostheatre"
+ echo " Default: chaostheatre"
+ echo " -u <target_user> specify user to deploy for."
+ echo " Default: swarsel"
+ echo " -h | --help Print this help."
+ exit 0
+}
+
+function green() {
+ echo -e "\x1B[32m[+] $1 \x1B[0m"
+ if [ -n "${2-}" ]; then
+ echo -e "\x1B[32m[+] $($2) \x1B[0m"
+ fi
+}
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -n)
+ shift
+ target_config=$1
+ ;;
+ -u)
+ shift
+ target_user=$1
+ ;;
+ -h | --help) help_and_exit ;;
+ *)
+ echo "Invalid option detected."
+ help_and_exit
+ ;;
+ esac
+ shift
+done
+
+function cleanup() {
+ sudo rm -rf .cache/nix
+ sudo rm -rf /root/.cache/nix
+}
+trap cleanup exit
+
+sudo rm -rf .cache/nix
+sudo rm -rf /root/.cache/nix
+
+green "~SwarselSystems~ remote post-installer"
+
+cd /home/"$target_user"/.dotfiles
+
+SECUREBOOT="$(nix eval ~/.dotfiles#nixosConfigurations."$target_config".config.swarselsystems.isSecureBoot)"
+
+if [[ $SECUREBOOT == "true" ]]; then
+ green "Setting up secure boot keys"
+ sudo mkdir -p /var/lib/sbctl
+ sbctl create-keys || true
+ sbctl enroll-keys --ignore-immutable --microsoft || true
+fi
+
+green "Disabling initialSetup"
+sed -i '/swarselsystems\.initialSetup = true;/d' /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix
+sudo nixos-rebuild --flake .#"$target_config" switch
+green "Post-install finished!"
+
+
+
+
+
+
+{ self, name, writeShellApplication, git }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ git ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+3.4.22. t2ts
+
+
+{ name, writeShellApplication, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ ];
+ text = ''
+ date -d"$1" +%s
+ '';
+}
+
+
+
+
+
+
+3.4.23. ts2t
+
+
+{ name, writeShellApplication, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ ];
+ text = ''
+ date -d @"$1" 2>/dev/null || date -r "$1"
+ '';
+}
+
+
+
+
+
+
+3.4.24. vershell
+
+
+{ name, writeShellApplication, ... }:
+
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ ];
+ text = ''
+ nix shell github:nixos/nixpkgs/"$1"#"$2";
+ '';
+}
+
+
+
+
+
+
+3.4.25. eontimer
+
+
+{ lib
+, python3
+, fetchFromGitHub
+, makeDesktopItem
+, writeShellScript
+, ...
+}:
+let
+ wrapper = writeShellScript "eontimer-wrapper" ''
+ export QT_QPA_PLATFORM=xcb
+ exec @out@/bin/EonTimer
+ '';
+in
+python3.pkgs.buildPythonApplication rec {
+ pname = "eontimer";
+ version = "3.0.0-rc.6";
+ pyproject = true;
+
+ src = fetchFromGitHub {
+ owner = "DasAmpharos";
+ repo = "EonTimer";
+ rev = version;
+ hash = "sha256-+XN/VGGlEg2gVncRZrWDOZ2bfxt8xyIu22F2wHlG6YI=";
+ };
+
+ build-system = [
+ python3.pkgs.setuptools
+ python3.pkgs.wheel
+ ];
+
+ dependencies = with python3.pkgs; [
+ altgraph
+ certifi
+ charset-normalizer
+ idna
+ libsass
+ macholib
+ packaging
+ pillow
+ pipdeptree
+ platformdirs
+ pyinstaller
+ pyinstaller-hooks-contrib
+ pyside6
+ requests
+ setuptools
+ shiboken6
+ urllib3
+ ];
+
+ nativeBuildInputs = [
+ python3.pkgs.pyinstaller
+ ];
+
+ buildPhase = ''
+ runHook preBuild
+
+ pyinstaller --clean --noconfirm EonTimer.spec
+
+ runHook postBuild
+ '';
+
+ installPhase = ''
+ runHook preInstall
+
+ mkdir -p $out/bin
+ mkdir -p $out/share/applications
+ cp dist/EonTimer $out/bin/
+ install -Dm755 -T ${wrapper} $out/bin/eontimer
+ substituteInPlace $out/bin/eontimer --subst-var out
+
+ runHook postInstall
+ '';
+
+ postInstall = ''
+ install -Dm755 -t $out/share/applications ${
+ makeDesktopItem {
+ name = "eontimer";
+ desktopName = "EonTimer";
+ comment = "Start EonTimer";
+ exec = "eontimer";
+ }
+ }/share/applications/eontimer.desktop
+ '';
+
+
+
+ meta = {
+ description = "Pokémon RNG Timer";
+ homepage = "https://github.com/DasAmpharos/EonTimer";
+ license = lib.licenses.mit;
+ maintainers = with lib.maintainers; [ ];
+ mainProgram = "eon-timer";
+ };
+}
+
+
+
+
+
+
+3.4.26. project
+
+
+set -euo pipefail
+
+if [ ! -d "$(pwd)/.git" ]; then
+ git init
+fi
+nix flake init --template "$FLAKE"#"$1"
+direnv allow
+
+
+
+
+{ self, name, writeShellApplication }:
+writeShellApplication {
+ inherit name;
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+3.4.27. fhs
+
+
+{ name, pkgs, ... }:
+let
+ base = pkgs.appimageTools.defaultFhsEnvArgs;
+in
+pkgs.buildFHSEnv (base // {
+ name = "fhs";
+ targetPkgs = pkgs: (base.targetPkgs pkgs) ++ [ pkgs.pkg-config ];
+ profile = "export FHS=1";
+ runScript = "zsh";
+ extraOutputsToInstall = [ "dev" ];
+})
+
+
+
+
+
+3.4.28. swarsel-displaypower
+
+
+A crude script to power on all displays that might be attached. Needed because sometimes displays do not awake from sleep.
+
+
+
+swaymsg "output * power on" > /dev/null 2>&1 || true
+swaymsg "output * dpms on" > /dev/null 2>&1 || true
+
+
+
+
+{ self, name, writeShellApplication, sway }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ sway ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+
+3.4.29. swarsel-mgba
+
+
+AppImage version of mgba in which the lua scripting works.
+
+
+
+
+{ appimageTools, fetchurl, ... }:
+let
+ pname = "mgba";
+ version = "0.10.4";
+ src = fetchurl {
+ url = "https://github.com/mgba-emu/mgba/releases/download/${version}/mGBA-${version}-appimage-x64.appimage";
+ hash = "sha256-rDihDfuA8DqxvCe6UeavCzpjeU+fSqUbFnyTNC2dc1I=";
+ };
+ appimageContents = appimageTools.extractType2 { inherit pname version src; };
+in
+appimageTools.wrapType2 {
+ inherit pname version src;
+ extraInstallCommands = ''
+ install -Dm444 ${appimageContents}/io.mgba.mGBA.desktop -t $out/share/applications
+ substituteInPlace $out/share/applications/io.mgba.mGBA.desktop \
+ --replace-fail 'Exec=mgba-qt %f' 'Exec=mgba'
+ cp -r ${appimageContents}/usr/share/icons $out/share
+ '';
+
+}
+
+
+
+
+
+
+3.4.30. swarsel-deploy
+
+
+# heavily inspired from https://github.com/oddlama/nix-config/blob/d42cbde676001a7ad8a3cace156e050933a4dcc3/pkgs/deploy.nix
+{ name, bc, nix-output-monitor, writeShellApplication, ... }:
+writeShellApplication {
+ runtimeInputs = [ bc nix-output-monitor ];
+ inherit name;
+ text = ''
+ set -euo pipefail
+ shopt -s lastpipe # allow cmd | readarray
+
+ function die() {
+ echo "error: $*" >&2
+ exit 1
+ }
+ function show_help() {
+ echo 'Usage: deploy [OPTIONS] <host,...> [ACTION]'
+ echo "Builds, pushes and activates nixosConfigurations on target systems."
+ echo ""
+ echo 'ACTION:'
+ echo ' switch [default] Switch immediately to the new configuration and make it the boot default'
+ echo ' boot Make the configuration the new boot default'
+ echo " test Activate the configuration but don't make it the boot default"
+ echo " dry-activate Don't activate, just show what would be done"
+ echo ""
+ echo 'OPTIONS: [passed to nix build]'
+ }
+
+ function time_start() {
+ T_START=$(date +%s.%N)
+ }
+
+ function time_next() {
+ T_END=$(date +%s.%N)
+ T_LAST=$(${bc}/bin/bc <<< "scale=1; ($T_END - $T_START)/1")
+ T_START="$T_END"
+ }
+
+ USER_FLAKE_DIR=$(git rev-parse --show-toplevel 2> /dev/null || pwd) ||
+ die "Could not determine current working directory. Something went very wrong."
+ [[ -e "$USER_FLAKE_DIR/flake.nix" ]] ||
+ die "Could not determine location of your project's flake.nix. Please run this at or below your main directory containing the flake.nix."
+ cd "$USER_FLAKE_DIR"
+
+ [[ $# -gt 0 ]] || {
+ show_help
+ exit 1
+ }
+
+ OPTIONS=()
+ POSITIONAL_ARGS=()
+ while [[ $# -gt 0 ]]; do
+ case "$1" in
+ "help" | "--help" | "-help" | "-h")
+ show_help
+ exit 1
+ ;;
+
+ -*) OPTIONS+=("$1") ;;
+ *) POSITIONAL_ARGS+=("$1") ;;
+ esac
+ shift
+ done
+
+ [[ ''${#POSITIONAL_ARGS[@]} -ge 1 ]] ||
+ die "Missing argument: <hosts...>"
+ [[ ''${#POSITIONAL_ARGS[@]} -le 2 ]] ||
+ die "Too many arguments given."
+
+ tr , '\n' <<< "''${POSITIONAL_ARGS[0]}" | sort -u | readarray -t HOSTS
+ ACTION="''${POSITIONAL_ARGS[1]-switch}"
+
+ # Expand flake paths for hosts definitions
+ declare -A TOPLEVEL_FLAKE_PATHS
+ for host in "''${HOSTS[@]}"; do
+ TOPLEVEL_FLAKE_PATHS["$host"]=".#nixosConfigurations.$host.config.system.build.toplevel"
+ done
+
+ time_start
+
+ # Get outputs of all derivations (should be cached)
+ declare -A TOPLEVEL_STORE_PATHS
+ for host in "''${HOSTS[@]}"; do
+ toplevel="''${TOPLEVEL_FLAKE_PATHS["$host"]}"
+ # Make sudo call to get prompt out of the way
+ sudo echo "[1;36m Building [m📦 [34m$host[m"
+ nix build --no-link "''${OPTIONS[@]}" --show-trace --log-format internal-json -v "$toplevel" |& ${nix-output-monitor}/bin/nom --json ||
+ die "Failed to get derivation path for $host from ''${TOPLEVEL_FLAKE_PATHS["$host"]}"
+ TOPLEVEL_STORE_PATHS["$host"]=$(nix build --no-link --print-out-paths "''${OPTIONS[@]}" "$toplevel")
+ time_next
+ echo "[1;32m Built [m✅ [34m$host[m [33m''${TOPLEVEL_STORE_PATHS["$host"]}[m [90min ''${T_LAST}s[m"
+ done
+
+ current_host=$(hostname)
+
+ for host in "''${HOSTS[@]}"; do
+ store_path="''${TOPLEVEL_STORE_PATHS["$host"]}"
+
+ if [ "$host" = "$current_host" ]; then
+ echo -e "\033[1;36m Running locally for $host... \033[m"
+ ssh_prefix="sudo"
+ else
+ echo -e "\033[1;36m Copying \033[m➡️ \033[34m$host\033[m"
+ nix copy --to "ssh://$host" "$store_path"
+ time_next
+ echo -e "\033[1;32m Copied \033[m✅ \033[34m$host\033[m \033[90min ''${T_LAST}s\033[m"
+ ssh_prefix="ssh $host --"
+ fi
+
+ echo -e "\033[1;36m Applying \033[m⚙️ \033[34m$host\033[m"
+ prev_system=$($ssh_prefix readlink -e /nix/var/nix/profiles/system)
+ $ssh_prefix /run/current-system/sw/bin/nix-env --profile /nix/var/nix/profiles/system --set "$store_path" ||
+ die "Failed to set system profile"
+ $ssh_prefix "$store_path"/bin/switch-to-configuration "$ACTION" ||
+ echo "Error while activating new system" >&2
+
+ if [[ -n $prev_system ]]; then
+ $ssh_prefix nvd --color always diff "$prev_system" "$store_path" || true
+ fi
+
+ time_next
+ echo -e "\033[1;32m Applied \033[m✅ \033[34m$host\033[m \033[90min ''${T_LAST}s\033[m"
+ done
+ '';
+}
+
+
+
+
+
+
+3.4.31. swarsel-build
+
+
+{ name, nix-output-monitor, writeShellApplication, ... }:
+writeShellApplication {
+ runtimeInputs = [ nix-output-monitor ];
+ inherit name;
+ text = ''
+ set -euo pipefail
+ [[ "$#" -ge 1 ]] \
+ || { echo "usage: build <HOST>..." >&2; exit 1; }
+ HOSTS=()
+ for h in "$@"; do
+ HOSTS+=(".#nixosConfigurations.$h.config.system.build.toplevel")
+ done
+ nom build --no-link --print-out-paths --show-trace "''${HOSTS[@]}"
+ '';
+}
+
+
+
+
+
+
+3.4.32. 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.
+
+
+
+HISTFILE="$HOME"/.histfile
+
+last_ssh_cmd=$(grep -E "ssh " "$HISTFILE" | sed -E 's/^: [0-9]+:[0-9]+;//' | grep "^ssh " | tail -1)
+host=$(echo "$last_ssh_cmd" | sed -E 's/.*ssh ([^@ ]+@)?([^ ]+).*/\2/')
+
+if [[ -n $host ]]; then
+ echo "Removing SSH host key for: $host"
+ ssh-keygen -R "$host"
+else
+ echo "No valid SSH command found in history."
+fi
+
+
+
+
+{ self, name, writeShellApplication, openssh }:
+writeShellApplication {
+ inherit name;
+ runtimeInputs = [ openssh ];
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
+}
+
+
+
+
+
+
+3.5. Profiles
+
+
+In this section I define custom modules under the swarsel attribute. These are mostly used to define settings specific to a host. I keep these settings confined to either home-manager or nixos to maintain compatibility with non-NixOS machines.
+
+
+
+Note: The structure of generating the packages was changed in commit 2cf03a3 refactor: package and module generation. That commit can be checked out in order to see a simpler version of achieving the same thing.
+
+
+
+3.5.1. NixOS
+
+
+Modules that need to be loaded on the NixOS level. Note that these will not be available on systems that are not running NixOS.
+
+
+
+{ lib, ... }:
+let
+ profileNames = lib.swarselsystems.readNix "profiles/nixos";
+in
+{
+ imports = lib.swarselsystems.mkImports profileNames "profiles/nixos";
+}
+
+
+
+
+3.5.1.1. Personal
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.personal = lib.mkEnableOption "is this a personal host";
+ config = lib.mkIf config.swarselsystems.profiles.personal {
+ swarselsystems.modules = {
+ packages = lib.mkDefault true;
+ general = lib.mkDefault true;
+ home-manager = lib.mkDefault true;
+ xserver = lib.mkDefault true;
+ users = lib.mkDefault true;
+ env = lib.mkDefault true;
+ security = lib.mkDefault true;
+ systemdTimeout = lib.mkDefault true;
+ hardware = lib.mkDefault true;
+ pulseaudio = lib.mkDefault true;
+ pipewire = lib.mkDefault true;
+ network = lib.mkDefault true;
+ time = lib.mkDefault true;
+ sops = lib.mkDefault true;
+ pii = lib.mkDefault true;
+ stylix = lib.mkDefault true;
+ programs = lib.mkDefault true;
+ zsh = lib.mkDefault true;
+ syncthing = lib.mkDefault true;
+ blueman = lib.mkDefault true;
+ networkDevices = lib.mkDefault true;
+ gvfs = lib.mkDefault true;
+ interceptionTools = lib.mkDefault true;
+ swayosd = lib.mkDefault true;
+ ppd = lib.mkDefault true;
+ yubikey = lib.mkDefault true;
+ ledger = lib.mkDefault true;
+ keyboards = lib.mkDefault true;
+ login = lib.mkDefault true;
+ nix-ld = lib.mkDefault true;
+ impermanence = lib.mkDefault true;
+ nvd = lib.mkDefault true;
+ gnome-keyring = lib.mkDefault true;
+ sway = lib.mkDefault true;
+ xdg-portal = lib.mkDefault true;
+ distrobox = lib.mkDefault true;
+ appimage = lib.mkDefault true;
+ lid = lib.mkDefault true;
+ lowBattery = lib.mkDefault true;
+ lanzaboote = lib.mkDefault true;
+ autologin = lib.mkDefault true;
+
+ optional = {
+ gaming = lib.mkDefault true;
+ virtualbox = lib.mkDefault true;
+ nswitch-rcm = lib.mkDefault true;
+ };
+
+ server = {
+ ssh = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.2. Chaostheatre
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.chaostheatre = lib.mkEnableOption "is this a chaostheatre host";
+ config = lib.mkIf config.swarselsystems.profiles.chaostheatre {
+ swarselsystems.modules = {
+ packages = lib.mkDefault true;
+ general = lib.mkDefault true;
+ home-manager = lib.mkDefault true;
+ xserver = lib.mkDefault true;
+ users = lib.mkDefault true;
+ env = lib.mkDefault true;
+ security = lib.mkDefault true;
+ systemdTimeout = lib.mkDefault true;
+ hardware = lib.mkDefault true;
+ pulseaudio = lib.mkDefault true;
+ pipewire = lib.mkDefault true;
+ network = lib.mkDefault true;
+ time = lib.mkDefault true;
+ sops = lib.mkDefault false;
+ stylix = lib.mkDefault true;
+ programs = lib.mkDefault true;
+ zsh = lib.mkDefault true;
+ syncthing = lib.mkDefault true;
+ blueman = lib.mkDefault true;
+ networkDevices = lib.mkDefault true;
+ gvfs = lib.mkDefault true;
+ interceptionTools = lib.mkDefault true;
+ swayosd = lib.mkDefault true;
+ ppd = lib.mkDefault true;
+ yubikey = lib.mkDefault true;
+ ledger = lib.mkDefault true;
+ keyboards = lib.mkDefault true;
+ login = lib.mkDefault true;
+ nix-ld = lib.mkDefault true;
+ impermanence = lib.mkDefault true;
+ nvd = lib.mkDefault true;
+ gnome-keyring = lib.mkDefault true;
+ sway = lib.mkDefault true;
+ xdg-portal = lib.mkDefault true;
+ distrobox = lib.mkDefault true;
+ appimage = lib.mkDefault true;
+ lid = lib.mkDefault true;
+ lowBattery = lib.mkDefault true;
+ lanzaboote = lib.mkDefault true;
+ autologin = lib.mkDefault true;
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.3. toto
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.toto = lib.mkEnableOption "is this a toto (setup) host";
+ config = lib.mkIf config.swarselsystems.profiles.toto {
+ swarselsystems.modules = {
+ general = lib.mkDefault true;
+ home-manager = lib.mkDefault true;
+ xserver = lib.mkDefault true;
+ users = lib.mkDefault true;
+ sops = lib.mkDefault true;
+ impermanence = lib.mkDefault true;
+ lanzaboote = lib.mkDefault true;
+ autologin = lib.mkDefault true;
+ server = {
+ ssh = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.4. Work
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.work = lib.mkEnableOption "is this a work host";
+ config = lib.mkIf config.swarselsystems.profiles.work {
+ swarselsystems.modules = {
+ optional = {
+ work = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.5. Framework
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.framework = lib.mkEnableOption "is this a framework brand host";
+ config = lib.mkIf config.swarselsystems.profiles.framework {
+ swarselsystems.modules = {
+ optional = {
+ framework = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.6. AMD CPU
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.amdcpu = lib.mkEnableOption "is this a host with amd cpu";
+ config = lib.mkIf config.swarselsystems.profiles.amdcpu {
+ swarselsystems.modules = {
+ optional = {
+ amdcpu = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.7. AMD GPU
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.amdgpu = lib.mkEnableOption "is this a host with amd gpu";
+ config = lib.mkIf config.swarselsystems.profiles.amdgpu {
+ swarselsystems.modules = {
+ optional = {
+ amdgpu = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.8. Hibernation
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.hibernation = lib.mkEnableOption "is this a host using hibernation";
+ config = lib.mkIf config.swarselsystems.profiles.hibernation {
+ swarselsystems.modules = {
+ optional = {
+ hibernation = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.9. BTRFS
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.btrfs = lib.mkEnableOption "is this a host using btrfs";
+ config = lib.mkIf config.swarselsystems.profiles.btrfs {
+ swarselsystems.modules = {
+ optional = {
+ btrfs = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.1.10. Local Server
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.server.local = lib.mkEnableOption "is this a local server";
+ config = lib.mkIf config.swarselsystems.profiles.server.local {
+ swarselsystems = {
+ modules = {
+ general = lib.mkDefault true;
+ pii = lib.mkDefault true;
+ home-manager = lib.mkDefault true;
+ xserver = lib.mkDefault true;
+ time = lib.mkDefault true;
+ users = lib.mkDefault true;
+ sops = lib.mkDefault true;
+ server = {
+ general = lib.mkDefault true;
+ packages = lib.mkDefault true;
+ nfs = lib.mkDefault true;
+ nginx = lib.mkDefault true;
+ ssh = lib.mkDefault true;
+ kavita = lib.mkDefault true;
+ restic = lib.mkDefault true;
+ jellyfin = lib.mkDefault true;
+ navidrome = lib.mkDefault true;
+ spotifyd = lib.mkDefault true;
+ mpd = lib.mkDefault true;
+ postgresql = lib.mkDefault true;
+ matrix = lib.mkDefault true;
+ nextcloud = lib.mkDefault true;
+ immich = lib.mkDefault true;
+ paperless = lib.mkDefault true;
+ transmission = lib.mkDefault true;
+ syncthing = lib.mkDefault true;
+ grafana = lib.mkDefault true;
+ emacs = lib.mkDefault true;
+ freshrss = lib.mkDefault true;
+ jenkins = lib.mkDefault false;
+ kanidm = lib.mkDefault true;
+ firefly-iii = lib.mkDefault true;
+ koillection = lib.mkDefault true;
+ radicale = lib.mkDefault true;
+ atuin = lib.mkDefault true;
+ };
+ };
+ };
+ };
+
+}
+
+
+
+
+
+
+3.5.1.11. OCI Sync Server
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.server.sync = lib.mkEnableOption "is this a oci sync server";
+ config = lib.mkIf config.swarselsystems.profiles.server.sync {
+ swarselsystems = {
+ modules = {
+ general = lib.mkDefault true;
+ nix-ld = lib.mkDefault true;
+ pii = lib.mkDefault true;
+ home-manager = lib.mkDefault true;
+ xserver = lib.mkDefault true;
+ time = lib.mkDefault true;
+ users = lib.mkDefault true;
+ sops = lib.mkDefault true;
+ server = {
+ general = lib.mkDefault true;
+ packages = lib.mkDefault true;
+ nginx = lib.mkDefault true;
+ ssh = lib.mkDefault true;
+ forgejo = lib.mkDefault true;
+ ankisync = lib.mkDefault true;
+ };
+ };
+ };
+ };
+
+}
+
+
+
+
+
+
+3.5.1.12. Moonside
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.server.moonside = lib.mkEnableOption "is this a moonside server";
+ config = lib.mkIf config.swarselsystems.profiles.server.moonside {
+ swarselsystems = {
+ modules = {
+ general = lib.mkDefault true;
+ pii = lib.mkDefault true;
+ home-manager = lib.mkDefault true;
+ xserver = lib.mkDefault true;
+ time = lib.mkDefault true;
+ users = lib.mkDefault true;
+ impermanence = lib.mkDefault true;
+ sops = lib.mkDefault true;
+ server = {
+ general = lib.mkDefault true;
+ packages = lib.mkDefault true;
+ nginx = lib.mkDefault true;
+ ssh = lib.mkDefault true;
+ oauth2-proxy = lib.mkDefault true;
+ croc = lib.mkDefault true;
+ microbin = lib.mkDefault true;
+ shlink = lib.mkDefault true;
+ };
+ };
+ };
+ };
+
+}
+
+
+
+
+
+
+
+3.5.2. home-manager
+
+
+This holds modules that are to be used on most hosts. These are also the most important options to configure, as these allow me easy access to monitor, keyboard, and other setups.
+
+
+
+{ lib, ... }:
+let
+ profileNames = lib.swarselsystems.readNix "profiles/home";
+in
+{
+ imports = lib.swarselsystems.mkImports profileNames "profiles/home";
+}
+
+
+
+
+3.5.2.1. Personal
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.personal = lib.mkEnableOption "is this a personal host";
+ config = lib.mkIf config.swarselsystems.profiles.personal {
+ swarselsystems.modules = {
+ packages = lib.mkDefault true;
+ ownpackages = lib.mkDefault true;
+ general = lib.mkDefault true;
+ nixgl = lib.mkDefault true;
+ sops = lib.mkDefault true;
+ yubikey = lib.mkDefault true;
+ ssh = lib.mkDefault true;
+ stylix = lib.mkDefault true;
+ desktop = lib.mkDefault true;
+ symlink = lib.mkDefault true;
+ env = lib.mkDefault true;
+ programs = lib.mkDefault true;
+ nix-index = lib.mkDefault true;
+ passwordstore = lib.mkDefault true;
+ direnv = lib.mkDefault true;
+ eza = lib.mkDefault true;
+ atuin = lib.mkDefault true;
+ git = lib.mkDefault true;
+ fuzzel = lib.mkDefault true;
+ starship = lib.mkDefault true;
+ kitty = lib.mkDefault true;
+ zsh = lib.mkDefault true;
+ zellij = lib.mkDefault true;
+ tmux = lib.mkDefault true;
+ mail = lib.mkDefault true;
+ emacs = lib.mkDefault true;
+ waybar = lib.mkDefault true;
+ firefox = lib.mkDefault true;
+ gnome-keyring = lib.mkDefault true;
+ kdeconnect = lib.mkDefault true;
+ mako = lib.mkDefault true;
+ swayosd = lib.mkDefault true;
+ yubikeytouch = lib.mkDefault true;
+ sway = lib.mkDefault true;
+ kanshi = lib.mkDefault true;
+ gpgagent = lib.mkDefault true;
+ gammastep = lib.mkDefault true;
+
+ optional = {
+ gaming = lib.mkDefault true;
+ };
+ };
+ };
+
+}
+
+
+
+
+
+
+3.5.2.2. Chaostheatre
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.chaostheatre = lib.mkEnableOption "is this a chaostheatre host";
+ config = lib.mkIf config.swarselsystems.profiles.chaostheatre {
+ swarselsystems.modules = {
+ packages = lib.mkDefault true;
+ ownpackages = lib.mkDefault true;
+ general = lib.mkDefault true;
+ nixgl = lib.mkDefault true;
+ sops = lib.mkDefault true;
+ yubikey = lib.mkDefault false;
+ ssh = lib.mkDefault true;
+ stylix = lib.mkDefault true;
+ desktop = lib.mkDefault true;
+ symlink = lib.mkDefault true;
+ env = lib.mkDefault false;
+ programs = lib.mkDefault true;
+ nix-index = lib.mkDefault true;
+ direnv = lib.mkDefault true;
+ eza = lib.mkDefault true;
+ git = lib.mkDefault false;
+ fuzzel = lib.mkDefault true;
+ starship = lib.mkDefault true;
+ kitty = lib.mkDefault true;
+ zsh = lib.mkDefault true;
+ zellij = lib.mkDefault true;
+ tmux = lib.mkDefault true;
+ mail = lib.mkDefault false;
+ emacs = lib.mkDefault true;
+ waybar = lib.mkDefault true;
+ firefox = lib.mkDefault true;
+ gnome-keyring = lib.mkDefault true;
+ kdeconnect = lib.mkDefault true;
+ mako = lib.mkDefault true;
+ swayosd = lib.mkDefault true;
+ yubikeytouch = lib.mkDefault true;
+ sway = lib.mkDefault true;
+ kanshi = lib.mkDefault true;
+ gpgagent = lib.mkDefault true;
+ gammastep = lib.mkDefault false;
+ };
+ };
+
+}
+
+
+
+
+
+
+3.5.2.3. toto
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.toto = lib.mkEnableOption "is this a toto (setup) host";
+ config = lib.mkIf config.swarselsystems.profiles.toto {
+ swarselsystems.modules = {
+ general = lib.mkDefault true;
+ sops = lib.mkDefault true;
+ ssh = lib.mkDefault true;
+ };
+ };
+
+}
+
+
+
+
+
+
+3.5.2.4. Work
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.work = lib.mkEnableOption "is this a work host";
+ config = lib.mkIf config.swarselsystems.profiles.work {
+ swarselsystems.modules = {
+ optional = {
+ work = lib.mkDefault true;
+ };
+ };
+ };
+
+}
+
+
+
+
+
+
+3.5.2.5. Framework
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.framework = lib.mkEnableOption "is this a framework brand host";
+ config = lib.mkIf config.swarselsystems.profiles.framework {
+ swarselsystems.modules = {
+ optional = {
+ framework = lib.mkDefault true;
+ };
+ };
+
+ };
+
+}
+
+
+
+
+
+
+3.5.2.6. Darwin
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.darwin = lib.mkEnableOption "is this a darwin host";
+ config = lib.mkIf config.swarselsystems.profiles.darwin {
+ swarselsystems.modules = {
+ general = lib.mkDefault true;
+ };
+ };
+
+}
+
+
+
+
+
+
+3.5.2.7. Local Server
+
+
+{ lib, config, ... }:
+{
+ options.swarselsystems.profiles.server.local = lib.mkEnableOption "is this a local server";
+ config = lib.mkIf config.swarselsystems.profiles.server.local {
+ swarselsystems.modules = {
+ general = lib.mkDefault true;
+ server = {
+ dotfiles = lib.mkDefault true;
+ };
+ };
+ };
+
+}
+
@@ -21192,7 +21108,7 @@ This sets up the dashboard, which is really quite useless. But, it
dashboard-set-footer nil
dashboard-banner-logo-title "Welcome to SwarsEmacs!"
dashboard-image-banner-max-height 300
- dashboard-startup-banner "~/.dotfiles/wallpaper/swarsel.png"
+ dashboard-startup-banner "~/.dotfiles/files/wallpaper/swarsel.png"
dashboard-projects-backend 'projectile
dashboard-projects-switch-function 'magit-status
dashboard-set-navigator t
@@ -22846,9 +22762,17 @@ base0F: "5EC4FF" # #5EC4FF passt
6.13. .gitmessage
+
+The double source block is intended here to circumvent a org-babel convenience where the first n empty lines of each source block are not taken into the final file. For the .gitmessage I want an empty newline to type into, so this is what I use to achieve that.
+
+
-# max. 50 chars is here: #
+
+
+
+
+# max. 50 chars is here: #
# <type>[optional scope]: <description>
# types: feat, fix, build, chore, ci, docs, style, refactor, perf, test
# ! indicates a breaking change.
@@ -23688,8 +23612,8 @@ Otherwise, the files that are possibly of biggest interest are found here:
- [SwarselSystems.org](../SwarselSystems.org)
- [flake.nix](../flake.nix)
-- [early-init.el](../programs/emacs/early-init.el)
-- [init.el](../programs/emacs/init.el)
+- [early-init.el](../files/emacs/early-init.el)
+- [init.el](../files/emacs/init.el)
### Getting started
@@ -23751,7 +23675,7 @@ Alternatively, to install this from any NixOS live ISO, run `nix run --experimen
|🚪 **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/programs/emacs/init.el) |
+|✒️ **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) |
@@ -23926,7 +23850,7 @@ If you feel that I forgot to pay you tribute for code that I used in this reposi
diff --git a/modules/home/common/emacs.nix b/modules/home/common/emacs.nix
index f1e3ba5..865ace7 100644
--- a/modules/home/common/emacs.nix
+++ b/modules/home/common/emacs.nix
@@ -13,7 +13,7 @@ in
programs.emacs = {
enable = true;
package = pkgs.emacsWithPackagesFromUsePackage {
- config = self + /programs/emacs/init.el;
+ config = self + /files/emacs/init.el;
package = pkgs.emacs-git-pgtk;
alwaysEnsure = true;
alwaysTangle = true;
diff --git a/modules/home/common/nix-index.nix b/modules/home/common/nix-index.nix
index 0ac40f2..b23b1c1 100644
--- a/modules/home/common/nix-index.nix
+++ b/modules/home/common/nix-index.nix
@@ -6,7 +6,7 @@
let
commandNotFound = pkgs.runCommandLocal "command-not-found.sh" { } ''
mkdir -p $out/etc/profile.d
- substitute ${self + /scripts/command-not-found.sh} \
+ substitute ${self + /files/scripts/command-not-found.sh} \
$out/etc/profile.d/command-not-found.sh \
--replace-fail @nix-locate@ ${pkgs.nix-index}/bin/nix-locate \
--replace-fail @tput@ ${pkgs.ncurses}/bin/tput
diff --git a/modules/home/common/sharedsetup.nix b/modules/home/common/sharedsetup.nix
index 2d15169..7fd614a 100644
--- a/modules/home/common/sharedsetup.nix
+++ b/modules/home/common/sharedsetup.nix
@@ -25,7 +25,7 @@
};
wallpaper = lib.mkOption {
type = lib.types.path;
- default = "${self}/wallpaper/lenovowp.png";
+ default = "${self}/files/wallpaper/lenovowp.png";
};
sharescreen = lib.mkOption {
type = lib.types.str;
@@ -44,7 +44,7 @@
type = lib.types.attrs;
default = {
enable = true;
- base16Scheme = "${self}/programs/stylix/swarsel.yaml";
+ base16Scheme = "${self}/files/stylix/swarsel.yaml";
polarity = "dark";
opacity.popups = 0.5;
cursor = {
@@ -99,7 +99,7 @@
firefox = lib.mkOption {
type = lib.types.attrs;
default = {
- userChrome = builtins.readFile "${self}/programs/firefox/chrome/userChrome.css";
+ userChrome = builtins.readFile "${self}/files/firefox/chrome/userChrome.css";
extensions = {
packages = with pkgs.nur.repos.rycee.firefox-addons; [
tridactyl
diff --git a/modules/home/common/sway.nix b/modules/home/common/sway.nix
index c48f398..29148fd 100644
--- a/modules/home/common/sway.nix
+++ b/modules/home/common/sway.nix
@@ -212,10 +212,10 @@
# output = lib.mapAttrs' lib.swarselsystems.eachMonitor monitors;
output = {
"${config.swarselsystems.sharescreen}" = {
- bg = "${self}/wallpaper/lenovowp.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/lenovowp.png ${config.stylix.imageScalingMode}";
};
"Philips Consumer Electronics Company PHL BDM3270 AU11806002320" = {
- bg = "${self}/wallpaper/standwp.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/standwp.png ${config.stylix.imageScalingMode}";
};
};
input = config.swarselsystems.standardinputs;
diff --git a/modules/home/common/symlink.nix b/modules/home/common/symlink.nix
index 15d8636..a0f1e89 100644
--- a/modules/home/common/symlink.nix
+++ b/modules/home/common/symlink.nix
@@ -4,29 +4,29 @@
config = lib.mkIf config.swarselsystems.modules.symlink {
home.file = {
"init.el" = lib.mkDefault {
- source = self + /programs/emacs/init.el;
+ source = self + /files/emacs/init.el;
target = ".emacs.d/init.el";
};
"early-init.el" = {
- source = self + /programs/emacs/early-init.el;
+ source = self + /files/emacs/early-init.el;
target = ".emacs.d/early-init.el";
};
# on NixOS, Emacs does not find the aspell dicts easily. Write the configuration manually
".aspell.conf" = {
- source = self + /programs/config/.aspell.conf;
+ source = self + /files/config/.aspell.conf;
target = ".aspell.conf";
};
".gitmessage" = {
- source = self + /programs/git/.gitmessage;
+ source = self + /files/git/.gitmessage;
target = ".gitmessage";
};
};
xdg.configFile = {
- "tridactyl/tridactylrc".source = self + /programs/firefox/tridactyl/tridactylrc;
- "tridactyl/themes/base16-codeschool.css".source = self + /programs/firefox/tridactyl/themes/base16-codeschool.css;
- "tridactyl/themes/swarsel.css".source = self + /programs/firefox/tridactyl/themes/swarsel.css;
- "swayidle/config".source = self + /programs/swayidle/config;
+ "tridactyl/tridactylrc".source = self + /files/firefox/tridactyl/tridactylrc;
+ "tridactyl/themes/base16-codeschool.css".source = self + /files/firefox/tridactyl/themes/base16-codeschool.css;
+ "tridactyl/themes/swarsel.css".source = self + /files/firefox/tridactyl/themes/swarsel.css;
+ "swayidle/config".source = self + /files/swayidle/config;
};
};
}
diff --git a/modules/home/common/waybar.nix b/modules/home/common/waybar.nix
index ec5cee8..af2204f 100644
--- a/modules/home/common/waybar.nix
+++ b/modules/home/common/waybar.nix
@@ -304,7 +304,7 @@ in
};
};
};
- style = builtins.readFile (self + /programs/waybar/style.css);
+ style = builtins.readFile (self + /files/waybar/style.css);
};
};
}
diff --git a/modules/home/common/zellij.nix b/modules/home/common/zellij.nix
index 19e9e7f..e2b80c0 100644
--- a/modules/home/common/zellij.nix
+++ b/modules/home/common/zellij.nix
@@ -12,8 +12,8 @@
];
xdg.configFile = {
- "zellij/config.kdl".text = import "${self}/programs/zellij/config.kdl.nix" { inherit config; };
- "zellij/layouts/default.kdl".text = import "${self}/programs/zellij/layouts/default.kdl.nix" { inherit config pkgs; };
+ "zellij/config.kdl".text = import "${self}/files/zellij/config.kdl.nix" { inherit config; };
+ "zellij/layouts/default.kdl".text = import "${self}/files/zellij/layouts/default.kdl.nix" { inherit config pkgs; };
};
};
diff --git a/modules/home/optional/work.nix b/modules/home/optional/work.nix
index 069e979..32beefd 100644
--- a/modules/home/optional/work.nix
+++ b/modules/home/optional/work.nix
@@ -28,13 +28,13 @@ in
wayland.windowManager.sway.config = {
output = {
"Applied Creative Technology Transmitter QUATTRO201811" = {
- bg = "${self}/wallpaper/navidrome.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/navidrome.png ${config.stylix.imageScalingMode}";
};
"Hewlett Packard HP Z24i CN44250RDT" = {
- bg = "${self}/wallpaper/op6wp.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/op6wp.png ${config.stylix.imageScalingMode}";
};
"HP Inc. HP 732pk CNC4080YL5" = {
- bg = "${self}/wallpaper/botanicswp.png ${config.stylix.imageScalingMode}";
+ bg = "${self}/files/wallpaper/botanicswp.png ${config.stylix.imageScalingMode}";
};
};
};
diff --git a/modules/home/server/symlink.nix b/modules/home/server/symlink.nix
index bbacf96..27c3bf6 100644
--- a/modules/home/server/symlink.nix
+++ b/modules/home/server/symlink.nix
@@ -4,7 +4,7 @@
config = lib.mkIf config.swarselsystems.modules.server.dotfiles {
home.file = {
"init.el" = lib.mkForce {
- source = self + /programs/emacs/server.el;
+ source = self + /files/emacs/server.el;
target = ".emacs.d/init.el";
};
};
diff --git a/modules/nixos/server/ankisync.nix b/modules/nixos/server/ankisync.nix
index 881841b..d3db63a 100644
--- a/modules/nixos/server/ankisync.nix
+++ b/modules/nixos/server/ankisync.nix
@@ -16,7 +16,7 @@ in
topology.self.services.${serviceName} = {
name = lib.mkForce "Anki Sync Server";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
info = "https://${serviceDomain}";
};
diff --git a/modules/nixos/server/croc.nix b/modules/nixos/server/croc.nix
index 8570169..86dbe89 100644
--- a/modules/nixos/server/croc.nix
+++ b/modules/nixos/server/croc.nix
@@ -34,7 +34,7 @@ in
topology.self.services.${serviceName} = {
name = lib.swarselsystems.toCapitalized serviceName;
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
diff --git a/modules/nixos/server/firefly-iii.nix b/modules/nixos/server/firefly-iii.nix
index 6c8b92b..2b5c313 100644
--- a/modules/nixos/server/firefly-iii.nix
+++ b/modules/nixos/server/firefly-iii.nix
@@ -32,7 +32,7 @@ in
topology.self.services.${serviceName} = {
name = "Firefly-III";
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
diff --git a/modules/nixos/server/freshrss.nix b/modules/nixos/server/freshrss.nix
index 09c6502..6454fb7 100644
--- a/modules/nixos/server/freshrss.nix
+++ b/modules/nixos/server/freshrss.nix
@@ -50,7 +50,7 @@ in
topology.self.services.${serviceName} = {
name = "FreshRSS";
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
diff --git a/modules/nixos/server/kavita.nix b/modules/nixos/server/kavita.nix
index 75cda1b..2fe9752 100644
--- a/modules/nixos/server/kavita.nix
+++ b/modules/nixos/server/kavita.nix
@@ -23,7 +23,7 @@ in
topology.self.services.${serviceName} = {
name = "Kavita";
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
diff --git a/modules/nixos/server/koillection.nix b/modules/nixos/server/koillection.nix
index 3ab45f4..07b45b1 100644
--- a/modules/nixos/server/koillection.nix
+++ b/modules/nixos/server/koillection.nix
@@ -22,7 +22,7 @@ in
topology.self.services.${serviceName} = {
name = lib.swarselsystems.toCapitalized serviceName;
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
diff --git a/modules/nixos/server/microbin.nix b/modules/nixos/server/microbin.nix
index a089d54..99efa1a 100644
--- a/modules/nixos/server/microbin.nix
+++ b/modules/nixos/server/microbin.nix
@@ -45,7 +45,7 @@ in
topology.self.services.${serviceName} = {
name = lib.swarselsystems.toCapitalized serviceName;
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
diff --git a/modules/nixos/server/mpd.nix b/modules/nixos/server/mpd.nix
index 3965a5b..9212229 100644
--- a/modules/nixos/server/mpd.nix
+++ b/modules/nixos/server/mpd.nix
@@ -35,7 +35,7 @@ in
topology.self.services.${serviceName} = {
name = lib.toUpper serviceName;
info = "http://localhost:${builtins.toString servicePort}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
services.${serviceName} = {
diff --git a/modules/nixos/server/shlink.nix b/modules/nixos/server/shlink.nix
index ace9e4d..d1615a9 100644
--- a/modules/nixos/server/shlink.nix
+++ b/modules/nixos/server/shlink.nix
@@ -52,7 +52,7 @@ in
topology.self.services.${serviceName} = {
name = lib.swarselsystems.toCapitalized serviceName;
info = "https://${serviceDomain}";
- icon = "${self}/topology/images/${serviceName}.png";
+ icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName}.domain = serviceDomain;
diff --git a/modules/nixos/server/transmission.nix b/modules/nixos/server/transmission.nix
index c71bda0..9c3376d 100644
--- a/modules/nixos/server/transmission.nix
+++ b/modules/nixos/server/transmission.nix
@@ -80,7 +80,7 @@ in
readarr = {
name = "Readarr";
info = "https://${serviceDomain}/readarr";
- icon = "${self}/topology/images/readarr.png";
+ icon = "${self}/files/topology-images/readarr.png";
};
sonarr.info = "https://${serviceDomain}/sonarr";
lidarr.info = "https://${serviceDomain}/lidarr";
diff --git a/nix/hosts.nix b/nix/hosts.nix
index 336c46c..8f94eb4 100644
--- a/nix/hosts.nix
+++ b/nix/hosts.nix
@@ -84,7 +84,7 @@
homeConfigurations = mkHalfHostConfigs (lib.swarselsystems.readHosts "home") "home" lib.swarselsystems.pkgsFor.x86_64-linux;
nixOnDroidConfigurations = mkHalfHostConfigs (lib.swarselsystems.readHosts "android") "android" lib.swarselsystems.pkgsFor.aarch64-linux;
- diskoConfigurations.default = import "${self}/templates/hosts/nixos/disk-config.nix";
+ diskoConfigurations.default = import "${self}/files/templates/hosts/nixos/disk-config.nix";
nodes = config.nixosConfigurations // config.darwinConfigurations;
diff --git a/nix/installer-config.nix b/nix/installer-config.nix
new file mode 100644
index 0000000..86b533d
--- /dev/null
+++ b/nix/installer-config.nix
@@ -0,0 +1,111 @@
+{ pkgs, lib, ... }:
+{
+
+ config = {
+ home-manager.users.root.home = {
+ stateVersion = "23.05";
+ file = {
+ ".bash_history" = {
+ text = ''
+ swarsel-install -n chaostheatre
+ '';
+ };
+ };
+ };
+
+ nix.settings = {
+ experimental-features = [ "nix-command" "flakes" ];
+ };
+
+ boot = {
+ supportedFilesystems = lib.mkForce [ "brtfs" "vfat" ];
+ loader.systemd-boot = {
+ enable = true;
+ };
+ };
+
+ services = {
+ qemuGuest.enable = true;
+ openssh = {
+ enable = true;
+ settings.PermitRootLogin = "yes";
+ authorizedKeysFiles = lib.mkForce [
+ "/etc/ssh/authorized_keys.d/%u"
+ ];
+ };
+ };
+
+ environment.systemPackages = with pkgs; [
+ curl
+ git
+ gnupg
+ rsync
+ ssh-to-age
+ sops
+ vim
+ just
+ sbctl
+ ];
+
+ programs = {
+ git.enable = true;
+ };
+
+ fileSystems."/boot".options = [ "umask=0077" ];
+
+ environment.etc."issue".text = ''
+ [32m~SwarselSystems~[0m
+ IP of primary interface: [31m\4[0m
+ The Password for all users & root is '[31msetup[0m'.
+ Install the system remotely by running '[33mbootstrap -n -d [0m' on a machine with deployed secrets.
+ Alternatively, run '[33mswarsel-install -n [0m' for a local install. For your convenience, an example call is in the bash history (press up on the keyboard to access).
+ '';
+
+ networking = {
+ hostName = "drugstore";
+ wireless.enable = false;
+ dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload";
+ networkmanager.enable = true;
+ };
+
+ services.getty.autologinUser = lib.mkForce "root";
+
+ users = {
+ allowNoPasswordLogin = true;
+ users = {
+ root = {
+ password = "setup"; # this is overwritten after install
+ initialHashedPassword = lib.mkForce null;
+ openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDd0XXoLfRE0AyasxscEBwMqOnLWPqwz+etGqzVNeSw/RcgnxOi903mlVjCH+jzWMSe2GVSgzgM20j/r9sfE2P1z+wq/RODFS04JM0ltUoFkkm/IDZXQ2piOk7AoVi5ajdx4EiBnXY87jvxh5cCgQltkj3ouPF7FVN/MaN21IgWYB8NgkaVGft//OplodlDQNot17c0sFMibY0HcquwmHhqKOtKM1gT98+jZl0rd1rCqXFOvkesW6FPC4nzirPai+Hizp5gncrkJOZmLLqrjVx6PfpQzqzIhoUn1YS5CpyfXnKZUgx2Oi8SENmWOZ9DxYvDklgEttob37E2bIXbUhOw/u4I3olGFgCsKL6jg0N+d5teEaCZFnzlOp0UMWiUo7lVqq7Bwl3rNka2pxEdZ9v/1+m9cJiP7h6pnKmccVGku57iGIDnsnoTrmo1qbAje+EsmPYbc+qMnTDvOdSHTOXnjsyTd+ADklvMHCUAuf6ku4ktQEhlZxU3PvYvKHa1cTCEXxLWjytIgHgTgab9M5IH29Q55LSRRQBzUdkwjOG6KhsqG+xEE6038EbXr0MGKTm01AFmeVZWewmkSLu2UdoOMiw8mTSQhQFfp2QruYHnh7oJCo7ttKT1sLoRX+TfgQm1ryn/orhReg2GFfmbiLGxaJGVNvjqCxqrIFQXx4ZDHw== cardno:22_412_399" ];
+ };
+ };
+ };
+
+ programs.bash.shellAliases = {
+ "swarsel-install" = "nix run github:Swarsel/.dotfiles#swarsel-install --";
+ };
+
+ system.activationScripts.cache = {
+ text = ''
+ mkdir -p -m=0777 /home/setup/.local/state/nix/profiles
+ mkdir -p -m=0777 /home/setup/.local/state/home-manager/gcroots
+ mkdir -p -m=0777 /home/setup/.local/share/nix/
+ printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /home/setup/.local/share/nix/trusted-settings.json > /dev/null
+ mkdir -p /root/.local/share/nix/
+ printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /root/.local/share/nix/trusted-settings.json > /dev/null
+ '';
+ };
+ systemd = {
+ services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ];
+ targets = {
+ sleep.enable = false;
+ suspend.enable = false;
+ hibernate.enable = false;
+ hybrid-sleep.enable = false;
+ };
+ };
+
+ system.stateVersion = lib.mkForce "23.05";
+
+ };
+}
diff --git a/nix/iso.nix b/nix/iso.nix
index a0b4e95..b31f999 100644
--- a/nix/iso.nix
+++ b/nix/iso.nix
@@ -1,126 +1,19 @@
-{ self, pkgs, inputs, config, lib, modulesPath, ... }:
-let
- pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh";
-in
+{ inputs, ... }:
{
-
- imports = [
- "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
- "${modulesPath}/installer/cd-dvd/channel.nix"
-
- "${self}/modules/iso/minimal.nix"
- "${self}/modules/nixos/common/sharedsetup.nix"
- "${self}/modules/nixos/common/topology.nix"
- "${self}/modules/home/common/sharedsetup.nix"
-
- "${self}/modules/nixos/common/globals.nix"
-
-
- inputs.home-manager.nixosModules.home-manager
+ perSystem = { pkgs, system, ... }:
{
- home-manager.users."setup".imports = [
- "${self}/modules/home/common/settings.nix"
- "${self}/modules/home/common/sharedsetup.nix"
- ];
- }
- ];
-
- config = {
- swarselsystems = {
- info = "~SwarselSystems~ installer ISO";
- };
- home-manager.users."setup" = {
- home = {
- stateVersion = "23.05";
- file = {
- ".bash_history" = {
- source = self + /programs/bash/.bash_history;
- };
- };
- };
- swarselsystems = {
- modules.general = lib.mkForce true;
+ # nix build --print-out-paths --no-link .#images..live-iso
+ packages.live-iso = inputs.nixos-generators.nixosGenerate {
+ inherit pkgs;
+ modules = [
+ inputs.home-manager.nixosModules.home-manager
+ ./installer-config.nix
+ ];
+ format =
+ {
+ x86_64-linux = "install-iso";
+ aarch64-linux = "sd-aarch64-installer";
+ }.${system};
};
};
- home-manager.users.root.home = {
- stateVersion = "23.05";
- file = {
- ".bash_history" = {
- source = self + /programs/bash/.bash_history;
- };
- };
- };
-
- # environment.etc."issue".text = "\x1B[32m~SwarselSystems~\x1B[0m\nIP of primary interface: \x1B[31m\\4\x1B[0m\nThe Password for all users & root is '\x1B[31msetup\x1B[0m'.\nInstall the system remotely by running '\x1B[33mbootstrap -n -d [--impermanence] [--encryption]\x1B[0m' on a machine with deployed secrets.\nAlternatively, run '\x1B[33mswarsel-install -d -f \x1B[0m' for a local install.\n";
- environment.etc."issue".source = "${self}/programs/etc/issue";
- networking.dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload";
-
- isoImage = {
- makeEfiBootable = true;
- makeUsbBootable = true;
- squashfsCompression = "zstd -Xcompression-level 3";
- };
-
- nixpkgs = {
- hostPlatform = lib.mkDefault "x86_64-linux";
- config.allowUnfree = true;
- };
-
- services.getty.autologinUser = lib.mkForce "setup";
-
- users = {
- allowNoPasswordLogin = true;
- groups.swarsel = { };
- users = {
- setup = {
- name = "setup";
- group = "setup";
- isNormalUser = true;
- password = "setup"; # this is overwritten after install
- openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
- extraGroups = [ "wheel" ];
- };
- root = {
- # password = lib.mkForce config.users.users.swarsel.password; # this is overwritten after install
- openssh.authorizedKeys.keys = config.users.users."setup".openssh.authorizedKeys.keys;
- };
- };
- };
-
- boot = {
- loader.systemd-boot.enable = lib.mkForce true;
- loader.efi.canTouchEfiVariables = true;
- };
-
- programs.bash.shellAliases = {
- "swarsel-install" = "nix run github:Swarsel/.dotfiles#swarsel-install --";
- };
-
- system.activationScripts.cache = {
- text = ''
- mkdir -p -m=0777 /home/setup/.local/state/nix/profiles
- mkdir -p -m=0777 /home/setup/.local/state/home-manager/gcroots
- mkdir -p -m=0777 /home/setup/.local/share/nix/
- printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /home/setup/.local/share/nix/trusted-settings.json > /dev/null
- mkdir -p /root/.local/share/nix/
- printf '{\"extra-substituters\":{\"https://nix-community.cachix.org\":true,\"https://nix-community.cachix.org https://cache.ngi0.nixos.org/\":true},\"extra-trusted-public-keys\":{\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=\":true,\"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.ngi0.nixos.org-1:KqH5CBLNSyX184S9BKZJo1LxrxJ9ltnY2uAs5c/f1MA=\":true}}' | tee /root/.local/share/nix/trusted-settings.json > /dev/null
- '';
- };
- systemd = {
- services.sshd.wantedBy = lib.mkForce [ "multi-user.target" ];
- targets = {
- sleep.enable = false;
- suspend.enable = false;
- hibernate.enable = false;
- hybrid-sleep.enable = false;
- };
- };
-
- system.stateVersion = lib.mkForce "23.05";
-
- networking = {
- hostName = "drugstore";
- wireless.enable = false;
- };
- };
}
diff --git a/nix/templates.nix b/nix/templates.nix
index ded942a..3b811c7 100644
--- a/nix/templates.nix
+++ b/nix/templates.nix
@@ -7,7 +7,7 @@
(name: {
inherit name;
value = {
- path = "${self}/templates/${name}";
+ path = "${self}/files/templates/${name}";
description = "${name} project ";
};
})
diff --git a/nix/topology.nix b/nix/topology.nix
index 2fec00a..469e6ba 100644
--- a/nix/topology.nix
+++ b/nix/topology.nix
@@ -47,7 +47,7 @@
pfsense = mkRouter "pfSense" {
info = "HUNSN RM02";
- image = "${self}/topology-images/hunsn.png";
+ image = "${self}/files/topology-images/hunsn.png";
interfaceGroups = [
[
"eth2"
@@ -96,7 +96,7 @@
wifi-ap = mkSwitch "Wi-Fi AP" {
info = "Huawei";
- image = "${self}/topology-images/huawei.png";
+ image = "${self}/files/topology-images/huawei.png";
interfaceGroups = [
[
"eth1"
@@ -107,7 +107,7 @@
switch-livingroom = mkSwitch "Switch Livingroom" {
info = "TL-SG108";
- image = "${self}/topology-images/TL-SG108.png";
+ image = "${self}/files/topology-images/TL-SG108.png";
interfaceGroups = [
[
"eth1"
@@ -129,13 +129,13 @@
nswitch = mkDevice "Nintendo Switch" {
info = "Nintendo Switch";
- image = "${self}/topology-images/nintendo-switch.png";
+ image = "${self}/files/topology-images/nintendo-switch.png";
interfaces.eth1 = { };
};
pc = mkDevice "Windows Gaming Server" {
info = "i7-4790k, GTX970, 32GB RAM";
- image = "${self}/topology-images/pc.png";
+ image = "${self}/files/topology-images/pc.png";
interfaces.eth1 = { };
};
@@ -143,7 +143,7 @@
switch-bedroom = mkSwitch "Switch Bedroom" {
info = "TL-SG1005D";
- image = "${self}/topology-images/TL-SG1005D.png";
+ image = "${self}/files/topology-images/TL-SG1005D.png";
interfaceGroups = [
[
"eth1"
@@ -158,7 +158,7 @@
printer = mkDevice "Printer" {
info = "DELL C2665dnf";
- image = "${self}/topology-images/DELL-C2665dnf.png";
+ image = "${self}/files/topology-images/DELL-C2665dnf.png";
interfaces.eth1 = { };
};
diff --git a/pkgs/e/default.nix b/pkgs/e/default.nix
index 94a201d..7043846 100644
--- a/pkgs/e/default.nix
+++ b/pkgs/e/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ emacs30-pgtk sway jq ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/fs-diff/default.nix b/pkgs/fs-diff/default.nix
index de6a2e6..978ac41 100644
--- a/pkgs/fs-diff/default.nix
+++ b/pkgs/fs-diff/default.nix
@@ -1,5 +1,5 @@
{ self, name, writeShellApplication }:
writeShellApplication {
inherit name;
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/opacitytoggle/default.nix b/pkgs/opacitytoggle/default.nix
index 4c65c9f..d6c547b 100644
--- a/pkgs/opacitytoggle/default.nix
+++ b/pkgs/opacitytoggle/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ sway ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/pass-fuzzel/default.nix b/pkgs/pass-fuzzel/default.nix
index 48afb79..ae34790 100644
--- a/pkgs/pass-fuzzel/default.nix
+++ b/pkgs/pass-fuzzel/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ libnotify (pass.withExtensions (exts: [ exts.pass-otp ])) fuzzel wtype ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/project/default.nix b/pkgs/project/default.nix
index de6a2e6..978ac41 100644
--- a/pkgs/project/default.nix
+++ b/pkgs/project/default.nix
@@ -1,5 +1,5 @@
{ self, name, writeShellApplication }:
writeShellApplication {
inherit name;
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/screenshare/default.nix b/pkgs/screenshare/default.nix
index 4c65c9f..d6c547b 100644
--- a/pkgs/screenshare/default.nix
+++ b/pkgs/screenshare/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ sway ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/sshrm/default.nix b/pkgs/sshrm/default.nix
index 6c3749b..31f6957 100644
--- a/pkgs/sshrm/default.nix
+++ b/pkgs/sshrm/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ openssh ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/swarsel-bootstrap/default.nix b/pkgs/swarsel-bootstrap/default.nix
index 6c3749b..31f6957 100644
--- a/pkgs/swarsel-bootstrap/default.nix
+++ b/pkgs/swarsel-bootstrap/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ openssh ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/swarsel-displaypower/default.nix b/pkgs/swarsel-displaypower/default.nix
index 4c65c9f..d6c547b 100644
--- a/pkgs/swarsel-displaypower/default.nix
+++ b/pkgs/swarsel-displaypower/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ sway ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/swarsel-install/default.nix b/pkgs/swarsel-install/default.nix
index 6799593..41cc1ea 100644
--- a/pkgs/swarsel-install/default.nix
+++ b/pkgs/swarsel-install/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ git ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/swarsel-postinstall/default.nix b/pkgs/swarsel-postinstall/default.nix
index 6799593..41cc1ea 100644
--- a/pkgs/swarsel-postinstall/default.nix
+++ b/pkgs/swarsel-postinstall/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ git ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/swarsel-rebuild/default.nix b/pkgs/swarsel-rebuild/default.nix
index 6799593..41cc1ea 100644
--- a/pkgs/swarsel-rebuild/default.nix
+++ b/pkgs/swarsel-rebuild/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ git ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/swarselcheck/default.nix b/pkgs/swarselcheck/default.nix
index 11d0aa5..7504de3 100644
--- a/pkgs/swarselcheck/default.nix
+++ b/pkgs/swarselcheck/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ kitty element-desktop vesktop spotify-player jq ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/swarselzellij/default.nix b/pkgs/swarselzellij/default.nix
index f2f8fb1..1615bef 100644
--- a/pkgs/swarselzellij/default.nix
+++ b/pkgs/swarselzellij/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ kitty ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/pkgs/waybarupdate/default.nix b/pkgs/waybarupdate/default.nix
index 6799593..41cc1ea 100644
--- a/pkgs/waybarupdate/default.nix
+++ b/pkgs/waybarupdate/default.nix
@@ -2,5 +2,5 @@
writeShellApplication {
inherit name;
runtimeInputs = [ git ];
- text = builtins.readFile "${self}/scripts/${name}.sh";
+ text = builtins.readFile "${self}/files/scripts/${name}.sh";
}
diff --git a/programs/bash/.bash_history b/programs/bash/.bash_history
deleted file mode 100644
index 3e879d2..0000000
--- a/programs/bash/.bash_history
+++ /dev/null
@@ -1 +0,0 @@
-swarsel-install -n chaostheatre
diff --git a/programs/emacs/custom.el b/programs/emacs/custom.el
deleted file mode 100644
index cdcad2f..0000000
--- a/programs/emacs/custom.el
+++ /dev/null
@@ -1,36 +0,0 @@
-;; (custom-set-variables
- ;; custom-set-variables was added by Custom.
- ;; If you edit it by hand, you could mess it up, so be careful.
- ;; Your init file should contain only one such instance.
- ;; If there is more than one, they won't work right.
- ;; '(custom-safe-themes
- ;; '("7ec8fd456c0c117c99e3a3b16aaf09ed3fb91879f6601b1ea0eeaee9c6def5d9"
- ;; "badd1a5e20bd0c29f4fe863f3b480992c65ef1fa63951f59aa5d6b129a3f9c4c"
- ;; "2e05569868dc11a52b08926b4c1a27da77580daa9321773d92822f7a639956ce"
- ;; default))
- ;; '(send-mail-function 'sendmail-send-it))
-;; (custom-set-faces
-;; ;; custom-set-faces was added by Custom.
-;; ;; If you edit it by hand, you could mess it up, so be careful.
-;; ;; Your init file should contain only one such instance.
-;; ;; If there is more than one, they won't work right.
-;; '(evil-goggles-change-face ((t (:inherit diff-removed))))
-;; '(evil-goggles-delete-face ((t (:inherit diff-removed))))
-;; '(evil-goggles-paste-face ((t (:inherit diff-added))))
-;; '(evil-goggles-undo-redo-add-face ((t (:inherit diff-added))))
-;; '(evil-goggles-undo-redo-change-face ((t (:inherit diff-changed))))
-;; '(evil-goggles-undo-redo-remove-face ((t (:inherit diff-removed))))
-;; '(evil-goggles-yank-face ((t (:inherit diff-changed))))
-;; '(flycheck-posframe-border-face ((t (:foreground "darkgrey"))))
-;; '(ivy-current-match ((t (:extend t :background "dark cyan" :foreground "black"))))
-;; '(org-block ((t (:inherit fixed-pitch :extend t :background "#20282F"))))
-;; '(org-block-begin-line ((t (:inherit org-block :extend t :background "#20282F" :foreground "DeepSkyBlue4" :weight bold)))))
-;; (custom-set-faces
- ;; custom-set-faces was added by Custom.
- ;; If you edit it by hand, you could mess it up, so be careful.
- ;; Your init file should contain only one such instance.
- ;; If there is more than one, they won't work right.
- ;; '(highlight-indent-guides-even-face ((t (:background "gray10"))))
- ;; '(highlight-indent-guides-odd-face ((t (:background "gray20"))))
- ;; '(highlight-indent-guides-stack-even-face ((t (:background "gray40"))))
- ;; '(highlight-indent-guides-stack-odd-face ((t (:background "gray50")))))
diff --git a/programs/etc/issue b/programs/etc/issue
deleted file mode 100644
index f05e80d..0000000
--- a/programs/etc/issue
+++ /dev/null
@@ -1,5 +0,0 @@
-[32m~SwarselSystems~[0m
- IP of primary interface: [31m\4[0m
- The Password for all users & root is '[31msetup[0m'.
- Install the system remotely by running '[33mbootstrap -n -d [0m' on a machine with deployed secrets.
- Alternatively, run '[33mswarsel-install -n [0m' for a local install. For your convenience, an example call is in the bash history (press up on the keyboard to access).
diff --git a/programs/firefox/tridactyl/themes/base16-codeschool.css b/programs/firefox/tridactyl/themes/base16-codeschool.css
deleted file mode 100644
index b61c643..0000000
--- a/programs/firefox/tridactyl/themes/base16-codeschool.css
+++ /dev/null
@@ -1,153 +0,0 @@
-:root { /* Codeschool by Chris Kempson (http://chriskempson.com) */
- --base00: #232c31;
- --base01: #1c3657;
- --base02: #2a343a;
- --base03: #3f4944;
- --base04: #84898c;
- --base05: #9ea7a6;
- --base06: #a7cfa3;
- --base07: #b5d8f6;
- --base08: #2a5491;
- --base09: #43820d;
- --base0A: #a03b1e;
- --base0B: #237986;
- --base0C: #b02f30;
- --base0D: #484d79;
- --base0E: #c59820;
- --base0F: #c98344;
-
- --tridactyl-fg: var(--base05);
- --tridactyl-bg: var(--base00);
- --tridactyl-url-fg: var(--base08);
- --tridactyl-url-bg: var(--base00);
- --tridactyl-highlight-box-bg: var(--base0B);
- --tridactyl-highlight-box-fg: var(--base00);
-
- /* Hint character tags */
- --tridactyl-hintspan-fg: var(--base00) !important;
- --tridactyl-hintspan-bg: var(--base0A) !important;
-
- /* Element Highlights */
- --tridactyl-hint-active-fg: none;
- --tridactyl-hint-active-bg: none;
- --tridactyl-hint-active-outline: none;
- --tridactyl-hint-bg: none;
- --tridactyl-hint-outline: none;
-}
-
-#command-line-holder { order: 1;
- border: 2px solid var(--base0B);
- color: var(--tridactyl-bg);
-}
-
-#tridactyl-input { padding: 1rem;
- color: var(--tridactyl-fg);
- width: 90%;
- font-size: 1.5rem;
- line-height: 1.5;
- background: var(--tridactyl-bg);
- padding-left: unset;
- padding: 1rem;
-}
-
-#completions table { font-size: 0.8rem;
- font-weight: 200;
- border-spacing: 0;
- table-layout: fixed;
- padding: 1rem;
- padding-top: 1rem;
- padding-bottom: 1rem;
-}
-
-#completions > div { max-height: calc(70 * var(--option-height));
- min-height: calc(10 * var(--option-height));
-}
-
-/* COMPLETIONS */
-
-#completions { --option-height: 1.4em;
- color: var(--tridactyl-fg);
- background: var(--tridactyl-bg);
- display: inline-block;
- font-size: unset;
- font-weight: 200;
- overflow: hidden;
- width: 100%;
- border-top: unset;
- order: 2;
-}
-
-/* Olie doesn't know how CSS inheritance works */
-#completions .HistoryCompletionSource { max-height: unset;
- min-height: unset;
-}
-
-#completions .HistoryCompletionSource table { width: 100%;
- font-size: 9pt;
- border-spacing: 0;
- table-layout: fixed;
-}
-
-/* redundancy 2: redundancy 2: more redundancy */
-#completions .BmarkCompletionSource { max-height: unset;
- min-height: unset;
-}
-
-#completions table tr td.prefix,#completions table tr td.privatewindow,#completions table tr td.container,#completions table tr td.icon { display: true;
-}
-
-#completions .BufferCompletionSource table { width: unset;
- font-size: unset;
- border-spacing: unset;
- table-layout: unset;
-}
-
-#completions table tr .title { width: 50%;
-}
-
-#completions table tr { white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#completions .sectionHeader { background: unset;
- font-weight: 200;
- border-bottom: unset;
- padding: 1rem !important;
- padding-left: unset;
- padding-bottom: 0.2rem;
-}
-
-#cmdline_iframe { position: fixed !important;
- bottom: unset;
- top: 25% !important;
- left: 10% !important;
- z-index: 2147483647 !important;
- width: 80% !important;
- box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 20px !important;
-}
-
-.TridactylStatusIndicator { position: fixed !important;
- bottom: 0 !important;
- background: var(--tridactyl-bg) !important;
- border: unset !important;
- border: 1px var(--base0B) solid !important;
- font-size: 12pt !important;
- /*font-weight: 200 !important;*/
- padding: 0.8ex !important;
-}
-
-#completions .focused { background: var(--base0B);
- color: var(--base00);
-}
-
-#completions .focused .url { background: var(--base0B);
- color: var(--base00);
-}
-/* #Ocean-normal { */
-/* border-color: green !important; */
-/* } */
-
-/* #Ocean-insert { */
-/* border-color: yellow !important; */
-/* } */
diff --git a/programs/server/prometheus/web.config b/programs/server/prometheus/web.config
deleted file mode 100644
index 19d9d31..0000000
--- a/programs/server/prometheus/web.config
+++ /dev/null
@@ -1,2 +0,0 @@
-basic_auth_users:
- admin: $2a$12$UFCdK2B67OM.p51ON8eKLOxQ4Ek9jruJPtaLE4Owc4Ukf7jGx//LC