From 916bb9c21856a43a810cb90c9bd43afec0ffec05 Mon Sep 17 00:00:00 2001 From: Swarsel Date: Thu, 19 Dec 2024 13:55:21 +0100 Subject: [PATCH] docs: improve README --- .github/README.md | 170 ++++-- index.html | 1268 +++++++++++++++++++++++++++++++++------------ 2 files changed, 1058 insertions(+), 380 deletions(-) diff --git a/.github/README.md b/.github/README.md index 364d34a1..db500e8a 100644 --- a/.github/README.md +++ b/.github/README.md @@ -3,7 +3,7 @@ ###### Disclaimer -You probably do not want to use this setup verbatim. This is made to fit my specific use cases, some of these settings will not make sense on other hosts. Also, nothing is ever stable here and changes are made on a daily basis. +You probably do not want to use this setup verbatim. This is made to fit my specific use cases, and I do not guarantee best practises everywhere. Changes are made on a daily basis. That being said, there is a lot of general configuration that you *probably* can use without changes; if you only want to use this repository as a starting point for your own configuration, you should be fine. See below for more information. Also, if you see something that can be done more efficiently or better in general, please let me know! :) @@ -11,32 +11,92 @@ That being said, there is a lot of general configuration that you *probably* can -| | | -|---------------|----------------------| -| **Shell:** | zsh | -| **DM:** | greetd | -| **WM:** | SwayFX | -| **Bar:** | Waybar | -| **Editor:** | Emacs | -| **Terminal:** | kitty | -| **Launcher:** | fuzzel | -| **Alerts:** | mako | -| **Browser:** | firefox | -| **Theme:** | city-lights | - -The files that are possibly of biggest interest are found here: +| | | +|---------------|---------------------------------| +| **Shell:** | zsh | +| **DM:** | greetd | +| **WM:** | SwayFX | +| **Bar:** | Waybar | +| **Editor:** | Emacs | +| **Terminal:** | kitty | +| **Launcher:** | fuzzel | +| **Alerts:** | mako | +| **Browser:** | firefox | +| **Theme:** | city-lights (managed by stylix) | + +## Overview + +- Literate configuration for Nix and Emacs ([SwarselSystems.org](../SwarselSystems.org)) +- Configuration based on flakes for personal hosts as well as servers on: + - [NixOS](https://github.com/NixOS/nixpkgs)) + - [home-manager](https://github.com/nix-community/home-manager) only (no full NixOS) with support from [nixGL](https://github.com/nix-community/nixGL) + - [nix-darwin](https://github.com/LnL7/nix-darwin) + - [nix-on-droid](https://github.com/nix-community/nix-on-droid) +- Streamlined configuration and deployment pipeline: + - Framework for [packages](https://github.com/Swarsel/.dotfiles/blob/main/pkgs/default.nix), [overlays](https://github.com/Swarsel/.dotfiles/blob/main/overlays/default.nix), and [modules](https://github.com/Swarsel/.dotfiles/tree/main/modules) + - Dynamically generated host configurations + - Limited local installer (no secrets handling) with a supported demo build + - Fully autonomous remote deployment using [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) and [disko](https://github.com/nix-community/disko) (with secrets handling) + - Improved nix tooling +- Support for advanced features: + - Secrets handling using [sops-nix](https://github.com/Mic92/sops-nix) (pls don't pwn ❤️) + - Management of non-file-based secrets using private repo + - Full Yubikey support + - LUKS-encryption + - Secure boot using [lanzaboote](https://github.com/nix-community/lanzaboote) + - BTRFS-based [Impermanence](https://github.com/nix-community/impermanence) + + +## Documentation + +If you are mainly interested in how I configured this system, check out this page: + +[SwarselSystems literate configuration](https://swarsel.github.io/.dotfiles/) + +This file will take you through my design process, in varying amounts of detail. + +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) -This is a nix flakes based setup that manages multiple hosts, including mixed (NixOS with home-manager as a submodule) as well as standalone home-manager configurations, also using some overlays etc. There even is a configuration for an Android build. It is all wrapped in literal configuration .org files, because that allows me to have easy access without actually having to remember where the specific configuration files are all located. -Have fun! +## Getting started -### General Nix tips -Sadly all things nix feel a bit underdocumented (even though it mostly is not). Below is a small list of tips that I thought could be helpful if you are new to the nix ecosystem: +### Demo configuration +If you just want to see if this configuration is for you, run this command on any system that has `nix` installed: + +``` shell +nix run --experimental-features 'nix-command flakes' github:Swarsel/.dotfiles#install -- -u +``` + +This will install the `chaostheatre` configuration on your system, which is a de-facto mirror of my main configuration with secret-based settings removed. +Please keep in mind that this limited installer will make local changes to the cloned repository in order to be able to install it (otherwise the builder would fail at fetching my private secrets repository). As such, this should only be used to evaluate the system - if you want to use it longterm, you will need to create a fork and make some changes. + +## Deployment + +The deployment process for this configuration is mostly automated, there are only a few steps that are needed to be done manually: + +0) Fork this repo, and write your own host config at `hosts/nixos//default.nix` (you can use one of the other configurations as a template. Also see https://github.com/Swarsel/.dotfiles/tree/main/modules for a list of all additional options). At the very least, you should replace the `secrets/` directory with your own secrets and replace the SSH public keys with your own ones. I personally recommend to use the literate configuration and `org-babel-tangle-file` in Emacs, but you can also simply edit the separate `.nix` files. +1) Have a system with `nix` available booted (this does not need to be installed, i.e. you can use a NixOS installer image; a custom minimal installer ISO can be built by running `just iso` in the root of this repo) +2) Make sure that your Yubikey is plugged in or that you have your SSH key available (and configured) +3) Run + +``` shell +nix run --experimental-features 'nix-command flakes' github:Swarsel/.dotfiles#install -- -n -d +``` + +Alternatively (if you already have this configuration installed), you can also run `bootstrap -n -d ` (this runs the same program as the command above). +4) Follow the installers instructions: + - you will have to choose a disk encryption password (if you want that feature) + - you will have to confirm once that the target system has rebooted + - you will have to enter the root password once during the final system install +5) That should be it! The installer will take care of setting up disks, secrets, and the rest of the hardware configuration! You will still have to sign in manually to some webservices etc. + +## General Nix tips 8 useful links +Below is a small list of tips that should be helpful no matter if you are new to the nix ecosystem: - Once you have the experimental feature `nix-command` enabled, you can temporarily install any package using `nix shell nixpkgs#` - this can be e.g. useful if you accidentally removed home-manager from your packages on a non-NixOS machine. - The `nix [...]` commands are generally very useful, more info can be found here: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix @@ -44,40 +104,42 @@ Sadly all things nix feel a bit underdocumented (even though it mostly is not). - https://search.nixos.org/packages - https://search.nixos.org/options - https://nix-community.github.io/home-manager/options.html / https://mipmip.github.io/home-manager-option-search/ +- Flake output reference: https://nixos-and-flakes.thiscute.world/other-usage-of-flakes/outputs + - or more general, the [NixOS & Flakes Book](https://nixos-and-flakes.thiscute.world/) - Also useful is the [NixOS wiki](https://nixos.wiki/wiki/Main_Page), but some pages are outdated, so use with some care +- You can find public repositories with modules at https://nur.nix-community.org/ (you should check what you are installing however): + - I like to use this for rycee's firefox extensions: https://nur.nix-community.org/repos/rycee/ - When you are trying to setup a new configuration part, GitHub code search can really help you to find a working configuration. -- getting packages not maintained in a standard repository can be done in most cases easily with fetchFromGithub (https://ryantm.github.io/nixpkgs/builders/fetchers/) -- I have gathered some configuration snippets here: [Wiki.org](../Wiki.org). I will update this whenever I come across an interesting bit. - -### Deployment -Below is a rough general guide to setup this system on a new NixOS host. **Again**, this is not recommended as this is a personal configuration. This also might not be the most efficient way to deploy a new Nix system, but it should work in the general case. - -For a pure Home-Manager configuration, you need a few different steps. The biggest change is that you then want to call `home-manager --flake .#@ switch` as the last step instead of `nixos-rebuild [...]`. A complete general guide for that case cannot really be given since you are most likely setting up the flake on a existing machine that already has a lot of configuration. If you are setting up a new system, I would recommend to use NixOS unless circumstances force you to use something else. - -###### To do that: -1) adapt [SwarselSystems.org](../SwarselSystems.org) - 1) adapt system specific options: - - Make a copy of "System/System Specific Configurations/TEMPLATE". - - Adapt all references to TEMPLATE to your host- and usernames etc - pay special attention to the header lines in each nix source block, i.e. the "#+begin_src nix [...] :tangle profiles/TEMPLATE/[...]" lines. - - - Add the settings needed for your specific machine. - 2) adapt flake: - - add a configuration block to "Noweb-Ref blocks/flake.nix/nixosConfigurations" (for example, you can copy one of the other blocks), - - adapt the paths to the files you chose to tangle to. - - adjust the "Inputs & Inputs@Outputs" and "let" sections if needed. - - (Use "[...]/homeConfigurations" instead if adding a home-manager config.) -2) Make sure Nix.org was actually tangled. -- **Beware:** This assumes you have access to a way of tangling an .org file (for most people this will mean having a working Emacs). If you do not have that, see below. -###### If you have no way of tangling .org files -In that case make a copy of the /.dotfiles/profiles/TEMPLATE folder and adapt each file manually according to the above, then edit the /.dotfiles/flake.nix manually. -##### Basic system setup -0) Make sure you have an internet connection (ethernet or for Wi-Fi e.g. call `nmcli`/`nmtui`) -1) `nix --experimental-features 'nix-command flakes' shell nixpkgs#git` -2) `git clone https://github.com/Swarsel/dotfiles.git` -3) `cp /etc/nixos/hardware-configuration.nix ~/.dotfiles/profiles/` -4) `git -C ~/.dotfiles add ~/dotfiles/profiles/` -5) `sudo nixos-rebuild --flake ~/.dotfiles/# boot` -6) Reboot. - - This build will take a while (mostly because it fully builds Emacs), so do not worry too much :) - - If you want to use sops-nix for secrets management, you need to provide your own key as well as a key for each host you are going to create. Then you need to adapt `.sops.yaml` to account for these keys and the directory where you are going to store the secrets. You can edit the secrets using `sops` using your key for authentication. You also need to edit the respective sections of the configuration to account for these locations. - - In case you get a dependency error for some of the `firefox-addons`, just comment out those specific extensions and try to uncomment them again a few days later. Sometimes when these packages are updated, the old .xpi file is deleted by the addon developer and the download link breaks. It is usually updated swiftly. If you do not want to wait, you can also package the addon yourself - there is one example in the files how this is done in general. +- getting packages at a different version than your target (or not packaged at all) can be done in most cases easily with fetchFromGithub (https://ryantm.github.io/nixpkgs/builders/fetchers/) +- you can easily install old revisions of packages using https://lazamar.co.uk/nix-versions/. You can conveniently spawn a shell with a chosen package available using `vershell `. Just make sure to pick a revision that has flakes enabled, otherwise you will need the legacy way of spawning the shell (see the link for more info) +- List of nerdfonts: https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/data/fonts/nerd-fonts/manifests/fonts.json +- List of pre-commit-hooks: https://devenv.sh/reference/options/#pre-commithooks +- Stylix configuration options: https://danth.github.io/stylix/ +- Waybar configuration: https://github.com/Alexays/Waybar/wiki + + +## Attributions, Acknowledgements, Inspirations, etc. + +These are in random order (also known as 'the order in which I discovered them'). I would like to express my gratitude to: + +- All the great people who have contributed code for the nix-community, with special mentions for (this list is unfairly incomplete): + - [guibou](https://github.com/guibou/) + - [Mic92](https://github.com/Mic92/sops-nix) + - [lassulus](https://github.com/lassulus) + - [danth](https://github.com/danth/) + - [LnL7](https://github.com/LnL7) + - [t184256](https://github.com/t184256) + - [bennofs](https://github.com/bennofs) +- All the people who have inspired me with their configurations (sadly also highly incomplete): + - [theSuess](https://github.com/theSuess) with their [home-manager](https://code.kulupu.party/thesuess/home-manager) + - [hlissner](https://github.com/hlissner) with their [dotfiles](https://github.com/hlissner/dotfiles) + - [drduh](https://github.com/drduh/YubiKey-Guide) with their [YubiKey-Guide](https://github.com/drduh/YubiKey-Guide) + - [AntonHakansson](https://github.com/AntonHakansson) with their [nixos-config](https://github.com/AntonHakansson/nixos-config?tab=readme-ov-file) + - [Guekka](https://github.com/Guekka/) with their [blog](https://guekka.github.io/) + - [NotAShelf](https://github.com/NotAShelf) with their [nyx](https://github.com/NotAShelf/nyx) + - [Misterio77](https://github.com/Misterio77) with their [nix-config](https://github.com/Misterio77/nix-config) + - [0xdade](https://github.com/0xdade) with their [blog](https://0xda.de/blog/) + - [EmergentMind](https://github.com/EmergentMind) with their [nix-config](https://github.com/EmergentMind/nix-config) + - [librephoenix](https://github.com/librephoenix) with their [nixos-config](https://github.com/librephoenix/nixos-config) + +If you feel that I forgot to pay you tribute for code that I used in this repository, please shoot me a message and I will fix it :) diff --git a/index.html b/index.html index 7b80982f..6731700b 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + SwarselSystems: NixOS + Emacs Configuration @@ -205,9 +205,9 @@

Table of Contents

  • 2. Noweb-Ref blocks and supplementary files
  • 3. flake.nix @@ -229,23 +229,29 @@

    Table of Contents

  • 4.2. Additions and modifications @@ -269,8 +275,10 @@

    Table of Contents

  • 4.2.1.15. github-notifications
  • 4.2.1.16. screenshare
  • 4.2.1.17. bootstrap
  • -
  • 4.2.1.18. t2ts
  • -
  • 4.2.1.19. ts2t
  • +
  • 4.2.1.18. swarsel-install
  • +
  • 4.2.1.19. t2ts
  • +
  • 4.2.1.20. ts2t
  • +
  • 4.2.1.21. vershell
  • 4.2.2. Overlays (additions, overrides, nixpkgs-stable)
  • @@ -375,7 +383,7 @@

    Table of Contents

  • 4.3.2.10. navidrome
  • 4.3.2.11. spotifyd
  • 4.3.2.12. mpd
  • -
  • 4.3.2.13. pipewire
  • +
  • 4.3.2.13. pipewire
  • 4.3.2.14. matrix
  • 4.3.2.15. nextcloud
  • 4.3.2.16. immich
  • @@ -386,8 +394,9 @@

    Table of Contents

  • 4.3.2.21. monitoring
  • 4.3.2.22. Jenkins
  • 4.3.2.23. Emacs elfeed (RSS Server)
  • -
  • 4.3.2.24. forgejo (git server)
  • -
  • 4.3.2.25. Anki Sync Server
  • +
  • 4.3.2.24. FreshRSS
  • +
  • 4.3.2.25. forgejo (git server)
  • +
  • 4.3.2.26. Anki Sync Server
  • 4.3.3. Darwin @@ -663,7 +672,7 @@

    Table of Contents

  • 5.4.44. Calendar
  • 5.4.45. Dashboard: emacs startup screen
  • 5.4.46. vterm
  • -
  • 5.4.47. multiple cursors
  • +
  • 5.4.47. multiple cursors
  • @@ -672,7 +681,7 @@

    Table of Contents

    -This file has 53086 words spanning 13798 lines and was last revised on 2024-12-15 23:45:43 +0100. +This file has 56301 words spanning 14353 lines and was last revised on 2024-12-19 14:30:50 +0100.

    @@ -725,7 +734,7 @@

    1

    -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: 2024-12-15 23:45:43 +0100) +My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2024-12-19 14:30:50 +0100)

    @@ -891,11 +900,11 @@

    2 -
    -

    2.2. Server Emacs config

    -
    +
    +

    2.2. Server Emacs config

    +

    -On my server, I use a reduced, self-contained emacs configuration that only serves as an elfeed sync server. +On my server, I use a reduced, self-contained emacs configuration that only serves as an elfeed sync server. This is currently unused, however, I am keeping this in here for now as a reference. The big problem here was the bidirectional syncing using bjm/elfeed-updater. As I am using this both on a laptop client (using elfeed) as well as on a mobile phone (using elfeed-cljsrn over elfeed-web), I set up a Syncthing service to take care of the feeds as well as the db state. However, I could only either achieve changes propagating properly from the laptop to the server or from the phone to the server. Both would not work. This current state represents the state where from-laptop changes would propagate. To allow from-phone changes, change (elfeed-db-load) in bjm/elfeed-updater to (elfeed-db-save).

    @@ -969,18 +978,14 @@

    2.2. Server Emacs conf (defun bjm/elfeed-updater () "Wrapper to load the elfeed db from disk before opening" (interactive) - (elfeed-db-save) - (quit-window) - (elfeed-db-load) - (elfeed) - (elfeed-search-update--force) - (elfeed-update)) + (elfeed-db-load)) -(run-with-timer 0 (* 30 60) 'bjm/elfeed-updater) +(run-with-timer 0 (* 1 60) 'bjm/elfeed-updater) (setq httpd-port 9812) (setq httpd-host "0.0.0.0") (setq httpd-root "/root/.emacs.d/elpa/elfeed-web-20240729.1741/") +(setq elfeed-db-directory "/var/lib/syncthing/.elfeed/db/") (httpd-start) (elfeed-web-start) @@ -989,11 +994,11 @@

    2.2. Server Emacs conf

    -
    -

    2.3. tridactylrc

    -
    +
    +

    2.3. tridactylrc

    +

    -This is the configuration file for tridactyl, which provides keyboard-driven navigation in firefox +This is the configuration file for tridactyl, which provides keyboard-driven navigation in firefox. Pay attention to the warnings in this file; depending on your browsing behaviour, you might expose yourself to some vulnerabilities by copying this configuration.

    @@ -1100,9 +1105,9 @@

    2.3. tridactylrc

    -
    -

    2.4. Waybar style.css

    -
    +
    +

    2.4. Waybar style.css

    +

    This is the stylesheet used by waybar.

    @@ -1612,6 +1617,19 @@

    3 homeManagerModules = import ./modules/home; packages = forEachSystem (pkgs: import ./pkgs { inherit pkgs; }); + apps = forAllSystems (system: { + default = self.apps.${system}.bootstrap; + + bootstrap = { + type = "app"; + program = "${self.packages.${system}.bootstrap}/bin/bootstrap"; + }; + + install = { + type = "app"; + program = "${self.packages.${system}.swarsel-install}/bin/swarsel-install"; + }; + }); devShells = forAllSystems ( system: let @@ -1786,8 +1804,21 @@

    3 disko provides declarative disk partitioning, which I use for impermanence as well as nixos-anywhere.
  • Impermanence Some of my machines are using a btrfs filesystem that wipes the root directory on each reboot. This forces me to pay more attention in keeping my system declarative as well as helping me keeping the system uncluttered. However, it is a chore to make sure that important files are not deleted. This flake helps with this problem, allowing me to select files and directories for persisting.
  • +
  • zjstatus +This provides utilities for customizing a statusbar in zellij. Currently unused as I prefer tmux for now and might be removed in the future.
  • +
  • fw-fanctrl +This provides access to the internal fans of Frameworks laptops. This is a bit more nice to use than directly using ectool.
  • +
  • nix-darwin +After learning that MacOS systems can also be configured using nix, I managed to get access to an old MacBook for testing. This allows to set most general settings that can otherwise be set using the Mac GUI.
  • +
  • pre-commit-hooks +Provides access to several checks that can be hooked to be run before several stages in the process.
  • +
  • nix-secrets +This is a private repository that I use for settings in modules that do not expose a secretsFile (or similar) option. An example is the LastFM.ApiKey option in navidrome: +LastFM.ApiKey = builtins.readFile "${secretsDirectory}/navidrome/lastfm-secret";
  • - +

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

    @@ -2022,6 +2053,19 @@ 

    3 homeManagerModules = import ./modules/home; packages = forEachSystem (pkgs: import ./pkgs { inherit pkgs; }); +apps = forAllSystems (system: { + default = self.apps.${system}.bootstrap; + + bootstrap = { + type = "app"; + program = "${self.packages.${system}.bootstrap}/bin/bootstrap"; + }; + + install = { + type = "app"; + program = "${self.packages.${system}.swarsel-install}/bin/swarsel-install"; + }; +}); devShells = forAllSystems ( system: let @@ -2141,169 +2185,27 @@

    3

    4. System

    +

    +This holds most of the NixOS side of configuration. +

    4.1. System specific configuration

    -This section mainly exists house different `configuration.nix` files for system level configurations of NixOS systems as well as `home.nix` for user level configurations on all systems. +This section mainly exists house different `default.nix` files to define some modules that should be loaded on respective systems. +Every host is housed in the hosts/ directory, which is then subdivided by each respective system (nixos/, home-manager/, nix-on-droid/, darwin/). As described earlier, some of these configurations (nixos and darwin) can be defined automatically in this flake. For home-manager and nix-on-droid, the system architecture must be defined manually.

    4.1.1. Physical hosts

    -
    -
    -
    4.1.1.1. live (ISO)
    -
    -
    -
    { self, inputs, config, pkgs, lib, modulesPath, ... }:
    -let
    -  pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh";
    -in
    -{
    -
    -  imports = [
    -
    -  inputs.lanzaboote.nixosModules.lanzaboote
    -  inputs.disko.nixosModules.disko
    -  inputs.impermanence.nixosModules.impermanence
    -  inputs.sops-nix.nixosModules.sops
    -  "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
    -  "${modulesPath}/installer/cd-dvd/channel.nix"
    -
    -  "${self}/profiles/iso//minimal.nix"
    -
    -  ];
    -
    -
    -  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 "swarsel";
    -
    -  users = {
    -    groups.swarsel = {};
    -    users = {
    -      swarsel = {
    -        name = "swarsel";
    -        group = "swarsel";
    -        isNormalUser = true;
    -        shell = pkgs.zsh;
    -        password = "setup"; # this is overwritten after install
    -        openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
    -      };
    -      root = {
    -        shell = pkgs.zsh;
    -        password = lib.mkForce config.users.users.swarsel.password; # this is overwritten after install
    -        openssh.authorizedKeys.keys = config.users.users.swarsel.openssh.authorizedKeys.keys;
    -      };
    -    };
    -  };
    -
    -  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 = "live";
    -    wireless.enable = false;
    -  };
    -
    -}
    -
    -
    -
    -
    -
    -
    -
    -
    4.1.1.2. Home-manager only (non-NixOS)
    -

    -This is the "reference implementation" of a setup that runs without NixOS, only relying on home-manager. I try to test this every now and then and keep it supported. However, manual steps are needed to get the system to work fully, depending on what distribution you are running on. +This is a list of all physical machines that I maintain.

    - -
    -
    { self, inputs, outputs, config, ... }:
    -{
    -
    -  imports = builtins.attrValues outputs.homeManagerModules;
    -
    -  nixpkgs = {
    -    overlays = [ outputs.overlays.default ];
    -    config = {
    -      allowUnfree = true;
    -    };
    -  };
    -
    -  services.xcape = {
    -    enable = true;
    -    mapExpression = {
    -      Control_L = "Escape";
    -    };
    -  };
    -
    -  programs.zsh.initExtra = "
    -  export GPG_TTY=\"$(tty)\"
    -  export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
    -  gpgconf --launch gpg-agent
    -        ";
    -
    -  swarselsystems = {
    -    isLaptop = true;
    -    isNixos = false;
    -    wallpaper = self + /wallpaper/surfacewp.png;
    -    temperatureHwmon = {
    -      isAbsolutePath = true;
    -      path = "/sys/devices/platform/thinkpad_hwmon/hwmon/";
    -      input-filename = "temp1_input";
    -    };
    -    monitors = {
    -      main = {
    -        name = "California Institute of Technology 0x1407 Unknown";
    -        mode = "1920x1080"; # TEMPLATE
    -        scale = "1";
    -        position = "2560,0";
    -        workspace = "2:二";
    -        output = "eDP-1";
    -      };
    -    };
    -    inputs = {
    -      "1:1:AT_Translated_Set_2_keyboard" = {
    -        xkb_layout = "us";
    -        xkb_options = "grp:win_space_toggle";
    -        xkb_variant = "altgr-intl";
    -      };
    -    };
    -    keybindings = { };
    -  };
    -
    -}
    -
    -
    -
    -
    -
    -
    4.1.1.3. nbl-imba-2 (Framework Laptop 16)
    +
    4.1.1.1. nbl-imba-2 (Framework Laptop 16)

    My work machine. Built for more security, this is the gold standard of my configurations at the moment. @@ -2403,6 +2305,8 @@

    4 isLaptop = true; isNixos = true; isBtrfs = true; + flakePath = "/home/swarsel/.dotfiles"; + cpuCount = 16; # temperatureHwmon = { # isAbsolutePath = true; # path = "/sys/devices/platform/thinkpad_hwmon/hwmon/"; @@ -2534,8 +2438,12 @@
    4
    -
    4.1.1.4. Winters (Server)
    +
    4.1.1.2. Winters (Server)
    +

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

    +
    { self, inputs, outputs, config, ... }:
     let
    @@ -2602,6 +2510,7 @@ 
    4 transmission = true; syncthing = true; monitoring = true; + freshrss = true; }; }; @@ -2613,8 +2522,12 @@
    4
    -
    4.1.1.5. nbm-imba-166 (MacBook Pro)
    +
    4.1.1.3. nbm-imba-166 (MacBook Pro)
    +

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

    +
    { self, inputs, outputs, ... }:
     let
    @@ -2654,8 +2567,12 @@ 
    4
    -
    4.1.1.6. Magicant (Phone)
    +
    4.1.1.4. Magicant (Phone)
    +

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

    +
     { pkgs, ... }: {
    @@ -2669,6 +2586,10 @@ 
    4 man gnupg curl + deadnix + statix + nixpgks-fmt + nvd ]; etcBackupExtension = ".bak"; @@ -2680,7 +2601,6 @@
    4 motd = null; }; - android-integration = { termux-open.enable = true; xdg-open.enable = true; @@ -2717,8 +2637,105 @@

    4 I have removed most of the machines from this section. What remains are some hosts that I have deployed on OCI (mostly sync for medium-important data) and one other machine that I left for now as a reference.

    +
    +
    4.1.2.1. Toto (QEMU VM)
    +
    +
    +
    { self, inputs, outputs, config, pkgs, lib, ... }:
    +let
    +  profilesPath = "${self}/profiles";
    +in
    +{
    +
    +  imports =  [
    +    inputs.disko.nixosModules.disko
    +    "${self}/hosts/nixos/toto/disk-config.nix"
    +    {
    +      _module.args = {
    +        withSwap = false;
    +      };
    +    }
    +    ./hardware-configuration.nix
    +
    +    inputs.sops-nix.nixosModules.sops
    +
    +    "${profilesPath}/optional/nixos/autologin.nix"
    +    "${profilesPath}/common/nixos/settings.nix"
    +    "${profilesPath}/common/nixos/home-manager.nix"
    +    "${profilesPath}/common/nixos/xserver.nix"
    +    "${profilesPath}/common/nixos/users.nix"
    +    "${profilesPath}/common/nixos/sops.nix"
    +    "${profilesPath}/server/nixos/ssh.nix"
    +
    +    inputs.home-manager.nixosModules.home-manager
    +    {
    +      home-manager.users.swarsel.imports =  [
    +        inputs.sops-nix.homeManagerModules.sops
    +        "${profilesPath}/common/home/settings.nix"
    +        "${profilesPath}/common/home/sops.nix"
    +        "${profilesPath}/common/home/ssh.nix"
    +
    +      ] ++ (builtins.attrValues outputs.homeManagerModules);
    +    }
    +  ] ++ (builtins.attrValues outputs.nixosModules);
    +
    +
    +  nixpkgs = {
    +    overlays = [ outputs.overlays.default ];
    +    config = {
    +      allowUnfree = true;
    +    };
    +  };
    +
    +  environment.systemPackages = with pkgs; [
    +    curl
    +    git
    +    gnupg
    +    rsync
    +    ssh-to-age
    +    sops
    +    vim
    +    just
    +  ];
    +
    +  system.stateVersion = lib.mkForce "23.05";
    +
    +  boot = {
    +    loader.systemd-boot.enable = lib.mkForce true;
    +    loader.efi.canTouchEfiVariables = true;
    +    supportedFilesystems = [ "btrfs" ];
    +    kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
    +  };
    +
    +
    +  networking = {
    +    hostName = "toto";
    +    firewall.enable = false;
    +  };
    +
    +  swarselsystems = {
    +    wallpaper = self + /wallpaper/lenovowp.png;
    +    impermanence = false;
    +    isBtrfs = false;
    +    initialSetup = true;
    +  };
    +
    +  home-manager.users.swarsel.swarselsystems = {
    +    isLaptop = false;
    +    isNixos = true;
    +    isBtrfs = false;
    +    flakePath = "/home/swarsel/.dotfiles";
    +  };
    +
    +}
    +
    +
    +
    +
    +
    +
    -
    4.1.2.1. Sync (OCI)
    +
    4.1.2.2. Sync (OCI)

    This machine mainly acts as an external sync helper. It manages the following things: @@ -2737,7 +2754,7 @@

    4
    -
    4.1.2.1.1. NixOS
    +
    4.1.2.2.1. NixOS
    { self, inputs, outputs, lib, ... }:
    @@ -2828,7 +2845,6 @@ 
    4 enable = true; forgejo = true; ankisync = true; - emacs = true; }; }; @@ -2840,7 +2856,238 @@
    4
    -
    +
    +

    4.1.3. Utility hosts

    +
    +
    +
    +
    4.1.3.1. drugstore (ISO)
    +
    +

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

    + +
    +
    { self, pkgs, inputs, config, lib, modulesPath, ... }:
    +let
    +  pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh";
    +in
    +{
    +
    +  imports = [
    +
    +  inputs.lanzaboote.nixosModules.lanzaboote
    +  inputs.disko.nixosModules.disko
    +  inputs.impermanence.nixosModules.impermanence
    +  inputs.sops-nix.nixosModules.sops
    +  "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
    +  "${modulesPath}/installer/cd-dvd/channel.nix"
    +
    +  "${self}/profiles/iso/minimal.nix"
    +
    +  ];
    +
    +  environment.etc."issue".text = "\\4\n";
    +  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 "swarsel";
    +
    +  users = {
    +    allowNoPasswordLogin = true;
    +    groups.swarsel = {};
    +    users = {
    +      swarsel = {
    +        name = "swarsel";
    +        group = "swarsel";
    +        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.swarsel.openssh.authorizedKeys.keys;
    +      };
    +    };
    +  };
    +
    +  boot = {
    +    loader.systemd-boot.enable = lib.mkForce true;
    +    loader.efi.canTouchEfiVariables = true;
    +  };
    +
    +  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;
    +  };
    +
    +}
    +
    +
    +
    +
    +
    +
    +
    +
    4.1.3.2. Home-manager only (non-NixOS)
    +
    +

    +This is the "reference implementation" of a setup that runs without NixOS, only relying on home-manager. I try to test this every now and then and keep it supported. However, manual steps are needed to get the system to work fully, depending on what distribution you are running on. +

    + +
    +
    { self, inputs, outputs, config, ... }:
    +{
    +
    +  imports = builtins.attrValues outputs.homeManagerModules;
    +
    +  nixpkgs = {
    +    overlays = [ outputs.overlays.default ];
    +    config = {
    +      allowUnfree = true;
    +    };
    +  };
    +
    +  services.xcape = {
    +    enable = true;
    +    mapExpression = {
    +      Control_L = "Escape";
    +    };
    +  };
    +
    +  programs.zsh.initExtra = "
    +  export GPG_TTY=\"$(tty)\"
    +  export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
    +  gpgconf --launch gpg-agent
    +        ";
    +
    +  swarselsystems = {
    +    isLaptop = true;
    +    isNixos = false;
    +    wallpaper = self + /wallpaper/surfacewp.png;
    +    temperatureHwmon = {
    +      isAbsolutePath = true;
    +      path = "/sys/devices/platform/thinkpad_hwmon/hwmon/";
    +      input-filename = "temp1_input";
    +    };
    +    monitors = {
    +      main = {
    +        name = "California Institute of Technology 0x1407 Unknown";
    +        mode = "1920x1080"; # TEMPLATE
    +        scale = "1";
    +        position = "2560,0";
    +        workspace = "2:二";
    +        output = "eDP-1";
    +      };
    +    };
    +    inputs = {
    +      "1:1:AT_Translated_Set_2_keyboard" = {
    +        xkb_layout = "us";
    +        xkb_options = "grp:win_space_toggle";
    +        xkb_variant = "altgr-intl";
    +      };
    +    };
    +    keybindings = { };
    +  };
    +
    +}
    +
    +
    +
    +
    +
    +
    +
    +
    4.1.3.3. ChaosTheatre (Demo)
    +
    +

    +My work machine. Built for more security, this is the gold standard of my configurations at the moment. +

    + + +
    +
    { self, inputs, outputs, config, pkgs, lib, ... }:
    +let
    +  profilesPath = "${self}/profiles";
    +in
    +{
    +
    +  imports = outputs.nixModules ++ [
    +
    +    ./hardware-configuration.nix
    +
    +    "${profilesPath}/optional/nixos/autologin.nix"
    +
    +    inputs.home-manager.nixosModules.home-manager
    +    {
    +      home-manager.users.swarsel.imports =  outputs.mixedModules ++ (builtins.attrValues outputs.homeManagerModules);
    +    }
    +  ] ++ (builtins.attrValues outputs.nixosModules);
    +
    +
    +  nixpkgs = {
    +    overlays = [ outputs.overlays.default ];
    +    config = {
    +      allowUnfree = true;
    +    };
    +  };
    +
    +
    +  boot = {
    +    loader.systemd-boot.enable = lib.mkForce true;
    +    loader.efi.canTouchEfiVariables = true;
    +    kernelPackages = lib.mkDefault pkgs.linuxPackages_latest;
    +  };
    +
    +  networking = {
    +    hostName = "chaostheatre";
    +    firewall.enable = true;
    +  };
    +
    +
    +  swarselsystems = {
    +    wallpaper = self + /wallpaper/lenovowp.png;
    +    initialSetup = true;
    +    isPublic = true;
    +  };
    +
    +  home-manager.users.swarsel.swarselsystems = {
    +    isNixos = true;
    +    isPublic = true;
    +    flakePath = "/home/swarsel/.dotfiles";
    +  };
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    4.2. Additions and modifications

    @@ -2892,8 +3139,10 @@

    4 "github-notifications" "screenshare" "bootstrap" + "swarsel-install" "t2ts" "ts2t" + "vershell" ]; mkPackages = names: builtins.listToAttrs (map (name: { inherit name; @@ -3612,6 +3861,31 @@
    4 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) @@ -3649,22 +3923,151 @@
    4 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" -git_root=$(git rev-parse --show-toplevel) +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/etc/ssh" +# Generate host ssh key pair without a passphrase +ssh-keygen -t ed25519 -f "$temp/etc/ssh/ssh_host_ed25519_key" -C root@"$target_hostname" -N "" +# Set the correct permissions so sshd will accept the key +chmod 600 "$temp/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 +green "Preparing a temporary password for disko." +green "[Optional] Set disk encryption passphrase:" +read -rs luks_passphrase +if [ -n "$luks_passphrase" ]; then + $ssh_root_cmd "/bin/sh -c 'echo $luks_passphrase > /tmp/disko-password'" +else + $ssh_root_cmd "/bin/sh -c 'echo passphrase > /tmp/disko-password'" +fi +# ------------------------ green "Generating hardware-config.nix for $target_hostname and adding it to the nix-config." -$ssh_root_cmd "nixos-generate-config --no-filesystems --root /mnt" -mkdir profiles/"$target_hostname" -$scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix "${git_root}"/profiles/"$target_hostname"/hardware-configuration.nix +$ssh_root_cmd "nixos-generate-config --force --no-filesystems --root /mnt" +mkdir -p "$FLAKE"/hosts/nixos/"$target_hostname" +$scp_cmd root@"$target_destination":/mnt/etc/nixos/hardware-configuration.nix "${git_root}"/hosts/nixos/"$target_hostname"/hardware-configuration.nix +# ------------------------ +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 +# ------------------------ +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" +$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 "chown $target_user:users /home/swarsel/.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 yes_or_no "Do you want to rebuild immediately?"; then + green "Rebuilding nix-config on $target_hostname" + $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

    +
    { writeShellApplication, openssh }:
     
    @@ -3677,8 +4080,114 @@ 
    4

    +
    +
    4.2.1.18. swarsel-install
    +
    +

    +This program sets up a new NixOS host. +

    + +
    +
    set -eo pipefail
    +
    +target_flake="chaostheatre"
    +target_user="swarsel"
    +
    +function help_and_exit() {
    +    echo
    +    echo "Remotely installs NixOS on a target machine using this nix-config."
    +    echo
    +    echo "USAGE: $0 [OPTIONS]"
    +    echo
    +    echo "ARGS:"
    +    echo "  -f <target_flake>                       specify flake to deploy the nixos config of."
    +    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
    +}
    +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
    +    -f)
    +        shift
    +        target_flake=$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
    +fi
    +
    +local_keys=$(ssh-add -L || true)
    +pub_key=$(cat /home/"$target_user"/.dotfiles/secrets/keys/ssh/nbl-imba-2.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
    +    git add flake.nix
    +fi
    +sudo nixos-generate-config --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_flake"/
    +git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_flake"/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}}' > /root/.local/share/nix/trusted-settings.json
    +green "Installing flake $target_flake"
    +sudo nixos-rebuild --show-trace --flake .#"$target_flake" boot
    +yellow "Please keep in mind that this is only a demo of the configuration. Things might break unexpectedly."
    +git restore --staged /home/"$target_user"/.dotfiles/hosts/nixos/"$target_flake"/hardware-configuration.nix
    +git restore /home/"$target_user"/.dotfiles/hosts/nixos/"$target_flake"/hardware-configuration.nix
    +git restore --staged /home/"$target_user"/.dotfiles/flake.nix
    +git restore /home/"$target_user"/.dotfiles/flake.nix
    +
    +
    + + + +
    +
    { writeShellApplication, git }:
    +
    +writeShellApplication {
    +  name = "swarsel-install";
    +  runtimeInputs = [ git ];
    +  text = builtins.readFile ../../scripts/swarsel-install.sh;
    +}
    +
    +
    +
    +
    -
    4.2.1.18. t2ts
    +
    4.2.1.19. t2ts

    This script allows for quick git branch switching. @@ -3700,7 +4209,7 @@

    4
    -
    4.2.1.19. ts2t
    +
    4.2.1.20. ts2t

    This script allows for quick git branch switching. @@ -3717,6 +4226,28 @@

    4 ''; } + +
    +
    +
    +
    +
    4.2.1.21. vershell
    +
    +

    +This script allows for quick git branch switching. +

    + +
    +
    { writeShellApplication }:
    +
    +writeShellApplication {
    +  name = "vershell";
    +  runtimeInputs = [ ];
    +  text = ''
    +    nix shell github:nixos/nixpkgs/"$1"#"$2";
    +  '';
    +}
    +
     
    @@ -3729,6 +4260,9 @@

    4 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. +

    { inputs, ... }:
    @@ -3810,7 +4344,7 @@ 

    4
    4.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 +Modules that need to be loaded on the NixOS level. Note that these will not be available on systems that are not running NixOS.

    @@ -3901,6 +4435,7 @@
    4 type = types.bool; default = true; }; + options.swarselsystems.isPublic = lib.mkEnableOption "is a public machine (no secrets)"; options.swarselsystems.initialSetup = lib.mkEnableOption "initial setup (no sops keys available)"; options.swarselsystems.server.enable = lib.mkEnableOption "is a server machine"; options.swarselsystems.server.kavita = lib.mkEnableOption "enable kavita on server"; @@ -3920,6 +4455,7 @@
    4 options.swarselsystems.server.emacs = lib.mkEnableOption "enable emacs server on server"; options.swarselsystems.server.forgejo = lib.mkEnableOption "enable forgejo on server"; options.swarselsystems.server.ankisync = lib.mkEnableOption "enable ankisync on server"; + options.swarselsystems.server.freshrss = lib.mkEnableOption "enable freshrss on server"; }

    @@ -3928,6 +4464,10 @@
    4
    4.2.3.1.4. Input
    +

    +This section is for everything input-related on the NixOS side. At the moment, this is only used to define shell aliases for servers. +

    +
    { lib, ... }:
     let
    @@ -4227,7 +4767,12 @@ 
    4
    { lib, config, ... }:
     {
    +  options.swarselsystems.flakePath = lib.mkOption {
    +    type = lib.types.str;
    +    default = "";
    +  };
       options.swarselsystems.isNixos = lib.mkEnableOption "nixos host";
    +  options.swarselsystems.isPublic = lib.mkEnableOption "is a public machine (no secrets)";
       config.swarselsystems.startup = lib.mkIf (!config.swarselsystems.isNixos) [
         {
           command = "sleep 60 && nixGL nextcloud --background";
    @@ -4262,11 +4807,14 @@ 
    4
    4.2.3.2.7. darwin
    +

    +Provides settings related to nix-darwin systems. At the moment, I am only making use of a isDarwin flag. +

    +
    { lib, ... }:
     {
       options.swarselsystems.isDarwin = lib.mkEnableOption "darwin host";
    -
     }
     
    @@ -4683,6 +5231,10 @@
    4 # nix package database nix-index + nixos-generators + + # commit hooks + pre-commit # proc info acpi @@ -4770,7 +5322,7 @@
    4
    4.3.1.4. Setup home-manager

    -First, we enable the use of home-manager as a NixoS modul. +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).

    @@ -4790,7 +5342,7 @@
    4
    4.3.1.5. 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 extremly comfortable to use +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.

    @@ -4812,18 +5364,24 @@
    4

    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.

    { pkgs, config, lib, ... }:
     {
    -  sops.secrets.swarseluser = { neededForUsers = true; };
    +  sops.secrets.swarseluser = lib.mkIf (!config.swarselsystems.isPublic) { neededForUsers = true; };
     
       users = {
         mutableUsers = lib.mkIf (!config.swarselsystems.initialSetup) false;
         users.swarsel = {
           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; [ ];
    @@ -4866,7 +5424,7 @@ 
    4
    4.3.1.8. Security

    -Needed for control over system-wide privileges etc. +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).

    @@ -4881,6 +5439,9 @@
    4 }; security.polkit.enable = true; + security.sudo.extraConfig = '' + Defaults env_keep+=SSH_AUTH_SOCK + ''; }
    @@ -5031,7 +5592,7 @@
    4
    4.3.1.14. Common network settings

    -Here I only enable networkmanager. Most of the 'real' network config is done in System specific configuration. +Here I only enable networkmanager and a few default networks. The rest of the network config is done separately in System specific configuration.

    @@ -5054,7 +5615,7 @@
    4 networkmanager = { enable = true; - ensureProfiles = { + ensureProfiles = lib.mkIf (!config.swarselsystems.isPublic) { environmentFiles = [ "${config.sops.templates."network-manager.env".path}" ]; @@ -5342,9 +5903,9 @@
    4 ]; in { - sops = { + sops = lib.mkIf (!config.swarselsystems.isPublic) { - age.sshKeyPaths = mkIfElse config.swarselsystems.isBtrfs [ "/persist/.ssh/sops" ] [ "${config.users.users.swarsel.home}/.ssh/sops" ]; + age.sshKeyPaths = mkIfElse config.swarselsystems.isBtrfs [ "/persist/.ssh/sops" ] [ "${config.users.users.swarsel.home}/.ssh/sops" "/etc/ssh/ssh_host_ed25519_key" ]; defaultSopsFile = mkIfElse config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${config.users.users.swarsel.home}/.dotfiles/secrets/general/secrets.yaml"; validateSopsFiles = false; @@ -6073,7 +6634,7 @@
    4 system.activationScripts.diff = { supportsDryActivation = true; text = '' - ${pkgs.nvd}/bin/nvd --nix-bin-dir=${pkgs.nix}/bin diff \ + ${pkgs.nvd}/bin/nvd --color=always --nix-bin-dir=${pkgs.nix}/bin diff \ /run/current-system "$systemConfig" ''; }; @@ -6342,6 +6903,7 @@
    4 ./emacs.nix ./forgejo.nix ./ankisync.nix + ./freshrss.nix ]; }
    @@ -6395,6 +6957,7 @@
    4 ssh-to-age git emacs + vim ]; }
    @@ -6409,7 +6972,7 @@
    4 { sops = { age.sshKeyPaths = lib.mkDefault [ "/etc/ssh/sops" ]; - defaultSopsFile = lib.mkDefault "${config.swarselsystems.flakePath}/secrets/server/winters/secrets.yaml"; + defaultSopsFile = lib.mkDefault "${config.swarselsystems.flakePath}/secrets/winters/secrets.yaml"; validateSopsFiles = false; }; @@ -6851,9 +7414,9 @@
    4
    -
    -
    4.3.2.13. pipewire
    -
    +
    +
    4.3.2.13. pipewire
    +
    { lib, config, ... }:
     {
    @@ -7597,11 +8160,11 @@ 
    4 devices = [ "magicant" "nbl-imba-2" ]; id = "hgr3d-pfu3w"; }; - ".elfeed" = { - path = "/Vault/data/syncthing/.elfeed"; - devices = [ "sync (@oracle)" "magicant" "nbl-imba-2" ]; - id = "h7xbs-fs9v1"; - }; + # ".elfeed" = { + # path = "/Vault/data/syncthing/.elfeed"; + # devices = [ "sync (@oracle)" "magicant" "nbl-imba-2" ]; + # id = "h7xbs-fs9v1"; + # }; }; }; }; @@ -7633,6 +8196,10 @@
    4
    4.3.2.20. restic
    +

    +Once this is finished, it will house a restic client that manages automatic backups of my image library. Before I get to this however, I first need to organice my pictures in the first place. +

    +
    { lib, config, ... }:
     {
    @@ -7649,6 +8216,10 @@ 
    4
    4.3.2.21. monitoring
    +

    +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, ... }:
     {
    @@ -7817,6 +8388,10 @@ 
    4
    4.3.2.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. +

    +
    { pkgs, lib, config, ... }:
     {
    @@ -7860,6 +8435,10 @@ 
    4
    4.3.2.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. +

    +
    { lib, config, ... }:
     {
    @@ -7873,20 +8452,55 @@ 
    4 startWithGraphical = false; }; + }; + +} +
    +
    +
    +
    +
    +
    4.3.2.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. +

    + +
    +
    { lib, config, ... }:
    +{
    +  config = lib.mkIf config.swarselsystems.server.freshrss {
    +
    +    users.users.freshrss = {
    +      extraGroups = [ "users" ];
    +      group = "freshrss";
    +      isSystemUser = true;
    +    };
    +
    +    users.groups.freshrss = {};
    +
    +    sops.secrets.fresh = { owner = "freshrss"; };
    +
    +    services.freshrss = {
    +      enable = true;
    +      virtualHost = "signpost.swarsel.win";
    +      baseUrl = "https://signpost.swarsel.win";
    +      # authType = "none";
    +      dataDir = "/Vault/data/tt-rss";
    +      defaultUser = "Swarsel";
    +      passwordFile = config.sops.secrets.fresh.path;
    +    };
    +
         services.nginx = {
           virtualHosts = {
             "signpost.swarsel.win" = {
    -          enableACME = false;
    -          forceSSL = false;
    +          enableACME = true;
    +          forceSSL = true;
               acmeRoot = null;
    -          locations = {
    -            "/" = {
    -              proxyPass = "http://localhost:9812";
    -              extraConfig = ''
    -                client_max_body_size 0;
    -              '';
    -            };
    -          };
             };
           };
         };
    @@ -7897,9 +8511,9 @@ 
    4
    -
    -
    4.3.2.24. forgejo (git server)
    -
    +
    +
    4.3.2.25. forgejo (git server)
    +
    { lib, config, ... }:
     {
    @@ -7951,9 +8565,9 @@ 
    4.3.2.24. forgejo (git
    -
    -
    4.3.2.25. Anki Sync Server
    -
    +
    +
    4.3.2.26. Anki Sync Server
    +
    { lib, config, ... }:
     {
    @@ -8375,6 +8989,11 @@ 
    4 }; }; + security.sudo.extraConfig = '' + Defaults env_keep+=SSH_AUTH_SOCK + Defaults lecture = never + ''; + security.pam = { sshAgentAuth.enable = true; services = { @@ -8384,6 +9003,8 @@
    4 environment.systemPackages = with pkgs; [ curl + git + gnupg rsync ssh-to-age sops @@ -8393,7 +9014,6 @@
    4 programs = { git.enable = true; - zsh.enable = lib.mkDefault true; }; fileSystems."/boot".options = [ "umask=0077" ]; @@ -8499,7 +9119,7 @@
    4 stateVersion = lib.mkDefault "23.05"; keyboard.layout = "us"; sessionVariables = { - FLAKE = "$HOME/.dotfiles"; + FLAKE = "${config.home.homeDirectory}/.dotfiles"; }; }; } @@ -8558,11 +9178,11 @@
    4 nmap lsof nvd - nh nix-output-monitor hyprpicker # color picker findutils units + vim # nix alejandra @@ -8724,6 +9344,9 @@
    4 hm-specialisation t2ts ts2t + vershell + + bootstrap (pkgs.writeScriptBin "project" '' #! ${pkgs.bash}/bin/bash @@ -8794,8 +9417,8 @@
    4 ]; in { - sops = { - age.sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/sops" ]; + sops = lib.mkIf (!config.swarselsystems.isPublic) { + age.sshKeyPaths = [ "${config.home.homeDirectory}/.ssh/sops" "${config.home.homeDirectory}/.ssh/ssh_host_ed25519_key" ]; defaultSopsFile = mkIfElse config.swarselsystems.isBtrfs "/persist/.dotfiles/secrets/general/secrets.yaml" "${config.home.homeDirectory}/.dotfiles/secrets/general/secrets.yaml"; validateSopsFiles = false; @@ -8805,7 +9428,7 @@
    4 leon = { path = "/run/user/1000/secrets/leon"; }; swarselmail = { path = "/run/user/1000/secrets/swarselmail"; }; github_notif = { path = "/run/user/1000/secrets/github_notif"; }; - # caldav = { path = "${config.home.homeDirectory}/.emacs.d/.caldav"; }; + u2f_keys = { path = "${config.home.homeDirectory}/.config/Yubico/u2f_keys"; }; }; }; } @@ -9127,13 +9750,16 @@
    4

    -
    _:
    +
    { pkgs, ... }:
     {
       programs = {
         bottom.enable = true;
         imv.enable = true;
         sioyek.enable = true;
    -    bat.enable = true;
    +    bat = {
    +      enable = true;
    +      extraPackages = with pkgs.bat-extras; [ batdiff batman batgrep batwatch ];
    +    };
         carapace.enable = true;
         wlogout.enable = true;
         swayr.enable = true;
    @@ -9490,23 +10116,25 @@ 
    4 shellAliases = lib.recursiveUpdate { hg = "history | grep"; - hmswitch = "cd ~/.dotfiles; home-manager --flake .#$(whoami)@$(hostname) switch; cd -;"; - nswitch = "cd ~/.dotfiles; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; - nswitch-stay = "cd ~/.dotfiles; git restore flake.lock; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;"; - edithome = "e -w ~/.dotfiles/SwarselSystems.org"; + hmswitch = "home-manager --flake ${config.swarselsystems.flakePath}#$(whoami)@$(hostname) switch |& nom"; + nswitch = "sudo nixos-rebuild --flake ${config.swarselsystems.flakePath}#$(hostname) --show-trace --log-format internal-json -v switch |& nom --json"; + nboot = "sudo nixos-rebuild --flake ${config.swarselsystems.flakePath}#$(hostname) --show-trace --log-format internal-json -v boot |& nom --json"; magit = "emacsclient -nc -e \"(magit-status)\""; config = "git --git-dir=$HOME/.cfg/ --work-tree=$HOME"; g = "git"; - c = "git --git-dir=$HOME/.dotfiles/.git --work-tree=$HOME/.dotfiles/"; + c = "git --git-dir=$FLAKE/.git --work-tree=$FLAKE/"; passpush = "cd ~/.local/share/password-store; git add .; git commit -m 'pass file changes'; git push; cd -;"; passpull = "cd ~/.local/share/password-store; git pull; cd -;"; hotspot = "nmcli connection up local; nmcli device wifi hotspot;"; cd = "z"; - cdr = "cd \"$( (find /home/swarsel/Documents/GitHub -maxdepth 1 && echo /home/swarsel/.dotfiles) | fzf )\""; + cd-orig = "cd"; + cat-orig = "cat"; + cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\""; nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; fs-diff = "sudo mount -o subvol=/ /dev/mapper/cryptroot /mnt ; fs-diff"; - lt = "ls -lath"; - oldshell = "nix shell github:nixos/nixpkgs/\"$1\" \"$2\""; + lt = "eza -las modified --total-size"; + boot-diff = "nix store diff-closures /run/*-system"; + gen-diff = "nix profile diff-closures --profile /nix/var/nix/profiles/system"; } config.swarselsystems.shellAliases; autosuggestion.enable = true; @@ -9528,7 +10156,11 @@
    4 save = 10000; size = 10000; }; - historySubstringSearch.enable = true; + historySubstringSearch = { + enable = true; + searchDownKey = "^[OB"; + searchUpKey = "^[OA"; + }; plugins = [ { name = "fzf-tab"; @@ -9930,26 +10562,26 @@
    4

    -
    { config, ... }:
    +
    { lib, config, ... }:
     {
    -  programs.mbsync = {
    +  programs.mbsync = lib.mkIf (!config.swarselsystems.isPublic) {
         enable = true;
       };
    -  services.mbsync = {
    +  services.mbsync = lib.mkIf (!config.swarselsystems.isPublic) {
         enable = true;
       };
       # this is needed so that mbsync can use the passwords from sops
    -  systemd.user.services.mbsync.Unit.After = [ "sops-nix.service" ];
    +  systemd.user.services.mbsync.Unit.After = lib.mkIf (!config.swarselsystems.isPublic) [ "sops-nix.service" ];
     
    -  programs.msmtp = {
    +  programs.msmtp = lib.mkIf (!config.swarselsystems.isPublic) {
         enable = true;
       };
     
    -  programs.mu = {
    +  programs.mu = lib.mkIf (!config.swarselsystems.isPublic) {
         enable = true;
       };
     
    -  accounts.email = {
    +  accounts.email = lib.mkIf (!config.swarselsystems.isPublic) {
         maildirBasePath = "Mail";
         accounts.leon = {
           primary = true;
    @@ -9957,7 +10589,6 @@ 
    4 userName = "leon.schwarzaeugl@gmail.com"; realName = "Leon Schwarzäugl"; passwordCommand = "cat ${config.sops.secrets.leon.path}"; - # passwordCommand = "gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.local/share/password-store/mail/mbsync/leon.schwarzaeugl@gmail.com.gpg"; gpg = { key = "0x76FD3810215AE097"; signByDefault = true; @@ -9985,7 +10616,7 @@
    4 }; }; - accounts.swarsel = { + accounts.swarsel = lib.mkIf (!config.swarselsystems.isPublic) { address = "leon@swarsel.win"; userName = "8227dc594dd515ce232eda1471cb9a19"; realName = "Leon Schwarzäugl"; @@ -10007,13 +10638,12 @@
    4 }; }; - accounts.nautilus = { + accounts.nautilus = lib.mkIf (!config.swarselsystems.isPublic) { primary = false; address = "nautilus.dw@gmail.com"; userName = "nautilus.dw@gmail.com"; realName = "Nautilus"; passwordCommand = "cat ${config.sops.secrets.nautilus.path}"; - # passwordCommand = "gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.local/share/password-store/mail/mbsync/nautilus.dw@gmail.com.gpg"; imap.host = "imap.gmail.com"; smtp.host = "smtp.gmail.com"; msmtp.enable = true; @@ -10034,12 +10664,11 @@
    4 }; }; }; - accounts.mrswarsel = { + accounts.mrswarsel = lib.mkIf (!config.swarselsystems.isPublic) { primary = false; address = "mrswarsel@gmail.com"; userName = "mrswarsel@gmail.com"; realName = "Swarsel"; - # passwordCommand = "gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.local/share/password-store/mail/mbsync/mrswarsel@gmail.com.gpg"; passwordCommand = "cat ${config.sops.secrets.mrswarsel.path}"; imap.host = "imap.gmail.com"; smtp.host = "smtp.gmail.com"; @@ -10079,8 +10708,12 @@
    4

    -
    { self, pkgs, ... }:
    +
    { self, lib, config, pkgs, ... }:
     {
    +
    +  # needed for elfeed
    +  sops.secrets.fever = lib.mkIf (!config.swarselsystems.isPublic) { path = "${config.home.homeDirectory}/.emacs.d/.fever"; };
    +
       # enable emacs overlay for bleeding edge features
       # also read init.el file and install use-package packages
       programs.emacs = {
    @@ -11193,7 +11826,7 @@ 
    4

    -
    { pkgs, ... }:
    +
    { self, pkgs, ... }:
     {
       services.gpg-agent = {
         enable = true;
    @@ -11206,7 +11839,26 @@ 
    4 allow-loopback-pinentry allow-emacs-pinentry ''; + sshKeys = [ + "4BE7925262289B476DBBC17B76FD3810215AE097" + ]; + }; + + programs.gpg = { + enable = true; + publicKeys = [ + { + source = "${self}/secrets/keys/gpg/gpg-public-key-0x76FD3810215AE097.asc"; + trust = 5; + } + ]; }; + + # assure correct permissions + systemd.user.tmpfiles.rules = [ + "d /home/swarsel/.gnupg 700 swarsel users" + ]; + }
    @@ -12312,7 +12964,7 @@

    5 "mc" '((lambda () (interactive) (swarsel/open-calendar)) :which-key "calendar") "mp" '(popper-toggle :which-key "popper") "md" '(dirvish :which-key "dirvish") - "mr" '(elfeed :which-key "elfeed") + "mr" '(bjm/elfeed-load-db-and-open :which-key "elfeed") "o" '(:ignore o :which-key "org") "op" '((lambda () (interactive) (org-present)) :which-key "org-present") "oa" '((lambda () (interactive) (org-agenda)) :which-key "org-agenda") @@ -14115,62 +14767,26 @@

    5
    -;; (setq elfeed-feeds
    -;;       '("https://www.coindesk.com/arc/outboundfeeds/rss/"
    -;;         "https://feed.phenx.de/lootscraper_gog_game.xml"
    -;;         "https://feed.phenx.de/lootscraper_ubisoft_game.xml"
    -;;         "https://hnrss.org/frontpage"
    -;;         "https://www.derstandard.at/rss/inland"
    -;;         "https://www.derstandard.at/rss/international"
    -;;         "https://www.derstandard.at/rss/kultur"
    -;;         "https://www.derstandard.at/rss/wissenschaft"
    -;;         "https://www.rfc-editor.org/rfcrss.xml"
    -;;         "https://waitbutwhy.com/feed"
    -;;         "https://steamcommunity.com/groups/freegamesfinders/rss/"))
    -
    -(use-package elfeed
    -  :ensure t
    -  :bind (:map elfeed-search-mode-map
    -                                        ;              ("A" . bjm/elfeed-show-all)
    -                                        ;              ("E" . bjm/elfeed-show-emacs)
    -                                        ;              ("D" . bjm/elfeed-show-daily)
    -              ("q" . bjm/elfeed-save-db-and-bury)))
    -
    -
    -(require 'elfeed)
    -
    -;; Load elfeed-org
    -(use-package elfeed-org
    -  :config
    -  (elfeed-org)
    -  (setq rmh-elfeed-org-files (list "~/.elfeed/elfeed.org"))
    -  )
    +(use-package elfeed)
     
     (use-package elfeed-goodies)
     (elfeed-goodies/setup)
     
    -(use-package elfeed-web)
    -
    -;;functions to support syncing .elfeed between machines
    -;;makes sure elfeed reads index from disk before launching
    -(defun bjm/elfeed-load-db-and-open ()
    -  "Wrapper to load the elfeed db from disk before opening"
    -  (interactive)
    -  (elfeed-db-load)
    -  (elfeed)
    -  (elfeed-search-update--force)
    -  (elfeed-update))
    -
    -;;write to disk when quiting
    -(defun bjm/elfeed-save-db-and-bury ()
    -  "Wrapper to save the elfeed db to disk before burying buffer"
    -  (interactive)
    -  (elfeed-db-save)
    -  (quit-window))
    +(setq elfeed-db-directory "~/.elfeed/db/")
     
     
    -(global-set-key (kbd "C-c w") 'bjm/elfeed-load-db-and-open)
    +(use-package elfeed-protocol
    +  :after elfeed)
     
    +(elfeed-protocol-enable)
    +(setq elfeed-use-curl t)
    +(setq elfeed-set-timeout 36000)
    +(setq elfeed-protocol-enabled-protocols '(fever))
    +(setq elfeed-protocol-fever-update-unread-only t)
    +(setq elfeed-protocol-fever-fetch-category-as-tag t)
    +(setq elfeed-protocol-feeds '(("fever+https://Swarsel@signpost.swarsel.win"
    +                               :api-url "https://signpost.swarsel.win/api/fever.php"
    +                               :password-file "~/.emacs.d/.fever")))
     
     (define-key elfeed-show-mode-map (kbd ";") 'visual-fill-column-mode)
     (define-key elfeed-show-mode-map (kbd "j") 'elfeed-goodies/split-show-next)
    @@ -15660,9 +16276,9 @@ 

    5

    -
    -

    5.4.47. multiple cursors

    -
    +
    +

    5.4.47. multiple cursors

    +
     (use-package multiple-cursors)
    @@ -15676,7 +16292,7 @@ 

    5.4.47. multiple curso

    Author: Leon Schwarzäugl

    -

    Created: 2024-12-15 So 23:45

    +

    Created: 2024-12-19 Do 14:30

    Validate