Compare commits

...

23 commits

Author SHA1 Message Date
Leon Schwarzäugl
ec6ae25e9b fix[work]: fix aws,cdr commands, easier git switch in emacs
Some checks failed
Flake check / Check flake (push) Has been cancelled
2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
46f2ec8b96 wip 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
6abf5ce39b chore: update flake; rename hosts; setup hintbooth 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
b78c83b575 chore[client]: reorganize sway keybinds 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
3391febda2 feat: add remote disk decryption over ssh 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
66a543abf7 feat: add quickpass 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
6b01f9d032 chore[client]: better pii management 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
ddd3dbf267 feat[server]: improve kanidm config 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
56c1f35548 feat[server]: improve nginx config 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
4473255269 feat[client]: manage zellij using nix 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
8838f98658 feat[client]: automatically create emacs org files 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
47377f7a96 feat: improve formatting 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
4a6cbd763f feat[client]: initialize syncthingtray on install 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
9252e9c546 chore: fix typos; build niri less eagerly 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
31447d9a3f chore: decomission milkywell 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
cea15be44d feat[server]: add initial router config 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
719d92c178 feat[server]: preparations for router config 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
729defa8b1 fix: bootstrap script not working with nix-plugins 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
c3b8102546 feat: build configurations dynamically for arch 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
d187cdf35f fix[wip]: navidrome jukebox 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
0caef3e587 feat: use nixos-extra-modules 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
7ef0ebf5e7 feat[server]: add garage 2025-11-19 21:49:30 +01:00
Leon Schwarzäugl
a263b4177a chore: rename hosts 2025-11-19 21:49:30 +01:00
164 changed files with 13598 additions and 4586 deletions

21
.github/README.md vendored
View file

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

View file

@ -7,6 +7,7 @@ keys:
- &swarsel 4BE7925262289B476DBBC17B76FD3810215AE097 - &swarsel 4BE7925262289B476DBBC17B76FD3810215AE097
- &hosts - &hosts
- &winters age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63 - &winters age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63
- &hintbooth age1hsumymvh5mkqlaynrp9lv2w696yk3wtjzlyfmrpeuvh9u2tlwceqh3563x
- &bakery age1mjgw3nxlnqdj04mgjz3wn7fj2nl2nxla4p2r2fn4nkvayfgp09pqllxzyh - &bakery age1mjgw3nxlnqdj04mgjz3wn7fj2nl2nxla4p2r2fn4nkvayfgp09pqllxzyh
- &toto age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl - &toto age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl
- &surface age1zlnxraee6tddr07xn59mx5rdexw8qxryd53eqlsajasfhfy78fkq705dfg - &surface age1zlnxraee6tddr07xn59mx5rdexw8qxryd53eqlsajasfhfy78fkq705dfg
@ -20,6 +21,7 @@ creation_rules:
- *swarsel - *swarsel
age: age:
- *winters - *winters
- *hintbooth
- *bakery - *bakery
- *toto - *toto
- *surface - *surface
@ -32,6 +34,7 @@ creation_rules:
- *swarsel - *swarsel
age: age:
- *winters - *winters
- *hintbooth
- *bakery - *bakery
- *toto - *toto
- *surface - *surface
@ -44,78 +47,97 @@ creation_rules:
- *swarsel - *swarsel
age: age:
- *nbl - *nbl
- *hintbooth
- *bakery - *bakery
- *toto - *toto
- *surface - *surface
- *winters - *winters
- *moonside - *moonside
- path_regex: secrets/pyramid/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *swarsel
age:
- *nbl
- path_regex: secrets/moonside/secrets.yaml
key_groups:
- pgp:
- *swarsel
age:
- *moonside
- path_regex: secrets/bakery/secrets.yaml
key_groups:
- pgp:
- *swarsel
age:
- *bakery
- path_regex: secrets/winters/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *swarsel
age:
- *winters
- path_regex: secrets/work/[^/]+\.(yaml|json|env|ini)$ - path_regex: secrets/work/[^/]+\.(yaml|json|env|ini)$
key_groups: key_groups:
- pgp: - pgp:
- *swarsel - *swarsel
age: age:
- *nbl - *nbl
- path_regex: secrets/milkywell/[^/]+\.(yaml|json|env|ini)$
key_groups: - path_regex: secrets/pyramid/[^/]+\.(yaml|json|env|ini)$
- pgp:
- *swarsel
age:
- *milkywell
- path_regex: hosts/nixos/pyramid/secrets/pii.nix.enc
key_groups: key_groups:
- pgp: - pgp:
- *swarsel - *swarsel
age: age:
- *nbl - *nbl
- path_regex: hosts/nixos/winters/secrets/pii.nix.enc - path_regex: hosts/nixos/x86_64-linux/pyramid/secrets/pii.nix.enc
key_groups:
- pgp:
- *swarsel
age:
- *nbl
- path_regex: secrets/moonside/secrets.yaml
key_groups:
- pgp:
- *swarsel
age:
- *moonside
- path_regex: hosts/nixos/aarch64-linux/moonside/secrets/pii.nix.enc
key_groups:
- pgp:
- *swarsel
age:
- *moonside
- path_regex: secrets/bakery/secrets.yaml
key_groups:
- pgp:
- *swarsel
age:
- *bakery
- path_regex: hosts/nixos/x86_64-linux/bakery/secrets/pii.nix.enc
key_groups:
- pgp:
- *swarsel
age:
- *bakery
- path_regex: secrets/winters/[^/]+\.(yaml|json|env|ini)$
key_groups:
- pgp:
- *swarsel
age:
- *winters
- path_regex: hosts/nixos/x86_64-linux/winters/secrets/pii.nix.enc
key_groups: key_groups:
- pgp: - pgp:
- *swarsel - *swarsel
age: age:
- *winters - *winters
- *moonside - *moonside
- path_regex: hosts/nixos/milkywell/secrets/pii.nix.enc
- path_regex: secrets/milkywell/[^/]+\.(yaml|json|env|ini)$
key_groups: key_groups:
- pgp: - pgp:
- *swarsel - *swarsel
age: age:
- *milkywell - *milkywell
- path_regex: hosts/nixos/bakery/secrets/pii.nix.enc - path_regex: hosts/nixos/aarch64-linux/milkywell/secrets/pii.nix.enc
key_groups: key_groups:
- pgp: - pgp:
- *swarsel - *swarsel
age: age:
- *bakery - *milkywell
- path_regex: hosts/nixos/moonside/secrets/pii.nix.enc
- path_regex: hosts/nixos/x86_64-linux/summers/secrets/
key_groups:
- pgp:
- *swarsel
- path_regex: hosts/nixos/x86_64-linux/hintbooth/secrets/
key_groups: key_groups:
- pgp: - pgp:
- *swarsel - *swarsel
age: age:
- *moonside - *hintbooth
- path_regex: hosts/darwin/nbm-imba-166/secrets/pii.nix.enc - path_regex: hosts/darwin/nbm-imba-166/secrets/pii.nix.enc
key_groups: key_groups:
- pgp: - pgp:

File diff suppressed because it is too large Load diff

View file

@ -162,6 +162,17 @@ create a new one."
(define-key minibuffer-local-filename-completion-map (define-key minibuffer-local-filename-completion-map
[C-backspace] #'up-directory) [C-backspace] #'up-directory)
(defun swarsel/consult-magit-repos ()
(interactive)
(require 'magit)
(let* ((repos (magit-list-repos))
(repo (consult--read repos
:prompt "Magit repo: "
:require-match t
:history 'my/consult-magit-repos-history
:sort t)))
(magit-status repo)))
(defun swarsel/org-mode-setup () (defun swarsel/org-mode-setup ()
(variable-pitch-mode 1) (variable-pitch-mode 1)
(add-hook 'org-tab-first-hook 'org-end-of-line) (add-hook 'org-tab-first-hook 'org-end-of-line)
@ -272,6 +283,7 @@ create a new one."
"l" '(:ignore l :which-key "links") "l" '(:ignore l :which-key "links")
"lc" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (org-overview) )) :which-key "SwarselSystems.org") "lc" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (org-overview) )) :which-key "SwarselSystems.org")
"le" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "Emacs") ) (org-overview) (org-cycle) )) :which-key "Emacs.org") "le" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "Emacs") ) (org-overview) (org-cycle) )) :which-key "Emacs.org")
"lr" '(swarsel/consult-magit-repos :which-key "List repos")
"ln" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "System") ) (org-overview) (org-cycle))) :which-key "Nixos.org") "ln" '((lambda () (interactive) (progn (find-file swarsel-swarsel-org-filepath) (goto-char (org-find-exact-headline-in-buffer "System") ) (org-overview) (org-cycle))) :which-key "Nixos.org")
"lp" '((lambda () (interactive) (projectile-switch-project)) :which-key "switch project") "lp" '((lambda () (interactive) (projectile-switch-project)) :which-key "switch project")
"lg" '((lambda () (interactive) (magit-list-repositories)) :which-key "list git repos") "lg" '((lambda () (interactive) (magit-list-repositories)) :which-key "list git repos")
@ -321,6 +333,7 @@ create a new one."
"C-c D" 'crux-duplicate-and-comment-current-line-or-region "C-c D" 'crux-duplicate-and-comment-current-line-or-region
"<DUMMY-m>" 'swarsel/last-buffer "<DUMMY-m>" 'swarsel/last-buffer
"M-\\" 'indent-region "M-\\" 'indent-region
"M-r" 'swarsel/consult-magit-repos
"<Paste>" 'yank "<Paste>" 'yank
"<Cut>" 'kill-region "<Cut>" 'kill-region
"<Copy>" 'kill-ring-save "<Copy>" 'kill-ring-save
@ -1040,6 +1053,10 @@ create a new one."
(add-hook 'org-present-mode-quit-hook 'swarsel/org-present-end) (add-hook 'org-present-mode-quit-hook 'swarsel/org-present-end)
(add-hook 'org-present-after-navigate-functions 'swarsel/org-present-slide) (add-hook 'org-present-after-navigate-functions 'swarsel/org-present-slide)
(defun org-babel-execute:markdown (body params)
"Just return BODY unchanged, allowing noweb expansion."
body)
(use-package nix-mode (use-package nix-mode
:after lsp-mode :after lsp-mode
:ensure t :ensure t
@ -1237,8 +1254,8 @@ create a new one."
(use-package magit (use-package magit
:config :config
(setq magit-repository-directories `((,swarsel-work-projects-directory . 1) (setq magit-repository-directories `((,swarsel-work-projects-directory . 3)
(,swarsel-private-projects-directory . 1) (,swarsel-private-projects-directory . 3)
("~/.dotfiles/" . 0))) ("~/.dotfiles/" . 0)))
:custom :custom
(magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) ; stay in the same window (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) ; stay in the same window

View file

@ -0,0 +1,12 @@
shopt -s nullglob globstar
notify-send "$(env | grep -E 'WAYLAND|SWAY')"
password="$1"
pass show "$password" | {
IFS= read -r pass
printf %s "$pass"
} | wtype -
notify-send -u critical -a pass -t 1000 "Typed Password"

View file

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

View file

@ -1,8 +1,9 @@
set -eo pipefail set -eo pipefail
target_config="chaostheatre" target_config="hotel"
target_hostname="chaostheatre" target_hostname="hotel"
target_user="swarsel" target_user="swarsel"
target_arch=""
persist_dir="" persist_dir=""
target_disk="/dev/vda" target_disk="/dev/vda"
disk_encryption=0 disk_encryption=0
@ -15,11 +16,12 @@ function help_and_exit() {
echo echo
echo "ARGS:" echo "ARGS:"
echo " -n <target_config> specify the nixos config to deploy." echo " -n <target_config> specify the nixos config to deploy."
echo " Default: chaostheatre" echo " Default: hotel"
echo " -d <target_disk> specify disk to install on." echo " -d <target_disk> specify disk to install on."
echo " Default: /dev/vda" echo " Default: /dev/vda"
echo " -u <target_user> specify user to deploy for." echo " -u <target_user> specify user to deploy for."
echo " Default: swarsel" echo " Default: swarsel"
echo " -a <target_arch> specify target architecture."
echo " -h | --help Print this help." echo " -h | --help Print this help."
exit 0 exit 0
} }
@ -58,6 +60,10 @@ while [[ $# -gt 0 ]]; do
shift shift
target_disk=$1 target_disk=$1
;; ;;
-a)
shift
target_arch=$1
;;
-h | --help) help_and_exit ;; -h | --help) help_and_exit ;;
*) *)
echo "Invalid option detected." echo "Invalid option detected."
@ -73,6 +79,11 @@ function cleanup() {
} }
trap cleanup exit trap cleanup exit
if [[ $target_arch == "" || $target_hostname == "" ]]; then
red "error: target_arch or target_hostname not set."
help_and_exit
fi
green "~SwarselSystems~ local installer" green "~SwarselSystems~ local installer"
cd /home/"$target_user" cd /home/"$target_user"
@ -152,7 +163,7 @@ if [ "$disk_encryption" -eq 1 ]; then
fi fi
green "Setting up disk ..." green "Setting up disk ..."
if [[ $target_config == "chaostheatre" ]]; then if [[ $target_config == "hotel" ]]; then
sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/v1.10.0 -- --mode destroy,format,mount --flake .#"$target_config" --yes-wipe-all-disks --arg diskDevice "$target_disk" 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 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 sudo nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount --flake .#"$target_config" --yes-wipe-all-disks
@ -162,9 +173,9 @@ sudo cp -r /home/"$target_user"/.dotfiles /mnt/"$persist_dir"/home/"$target_user
sudo chown -R 1000:100 /mnt/"$persist_dir"/home/"$target_user" sudo chown -R 1000:100 /mnt/"$persist_dir"/home/"$target_user"
green "Generating hardware configuration ..." green "Generating hardware configuration ..."
sudo nixos-generate-config --root /mnt --no-filesystems --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/ sudo nixos-generate-config --root /mnt --no-filesystems --dir /home/"$target_user"/.dotfiles/hosts/nixos/"$target_arch"/"$target_config"/
git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_config"/hardware-configuration.nix git add /home/"$target_user"/.dotfiles/hosts/nixos/"$target_arch"/"$target_config"/hardware-configuration.nix
sudo mkdir -p /root/.local/share/nix/ 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 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" green "Installing flake $target_config"

View file

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

View file

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

3763
flake.lock generated

File diff suppressed because it is too large Load diff

View file

@ -94,10 +94,15 @@
url = "github:sodiboo/niri-flake"; url = "github:sodiboo/niri-flake";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nixos-extra-modules = {
url = "github:oddlama/nixos-extra-modules";
inputs.nixpkgs.follows = "nixpkgs";
};
microvm = { microvm = {
url = "github:astro/microvm.nix"; url = "github:astro/microvm.nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
treefmt-nix.url = "github:numtide/treefmt-nix";
}; };
outputs = outputs =

View file

@ -1,4 +1,4 @@
{ self, outputs, ... }: { self, ... }:
{ {
imports = [ imports = [
@ -8,12 +8,6 @@
"${self}/modules/nixos/common/meta.nix" "${self}/modules/nixos/common/meta.nix"
]; ];
nixpkgs = {
overlays = [ outputs.overlays.default ];
config = {
allowUnfree = true;
};
};
services.xcape = { services.xcape = {
enable = true; enable = true;

View file

@ -38,12 +38,9 @@ in
}; };
networking = { networking = {
nftables.enable = lib.mkForce false;
hostName = "moonside";
enableIPv6 = false;
domain = "subnet03291956.vcn03291956.oraclevcn.com"; domain = "subnet03291956.vcn03291956.oraclevcn.com";
firewall = { firewall = {
allowedTCPPorts = [ 80 443 8384 ]; allowedTCPPorts = [ 8384 ];
}; };
wireguard = { wireguard = {
enable = true; enable = true;
@ -132,7 +129,7 @@ in
swarselsystems = { swarselsystems = {
flakePath = "/root/.dotfiles"; flakePath = "/root/.dotfiles";
info = "VM.Standard.A1.Flex, 4 OCPUs, 24GB RAM"; info = "VM.Standard.A1.Flex, 4 vCPUs, 24GB RAM";
isImpermanence = true; isImpermanence = true;
isSecureBoot = false; isSecureBoot = false;
isCrypted = false; isCrypted = false;
@ -152,11 +149,12 @@ in
}; };
swarselmodules.server = { swarselmodules.server = {
oauth2-proxy = lib.mkDefault true; oauth2-proxy = true;
croc = lib.mkDefault true; croc = true;
microbin = lib.mkDefault true; microbin = true;
shlink = lib.mkDefault true; shlink = true;
slink = lib.mkDefault true; slink = true;
syncthing = lib.mkDefault true; syncthing = true;
diskEncryption = lib.mkForce false;
}; };
} }

View file

@ -1,5 +1,5 @@
{ {
"data": "ENC[AES256_GCM,data:Wk3OGKwcuY72VLL+SBYXZUqxTQ8SlYroF4H81YDGMUZu6gt6ialXNvAsZSmYyFNh+3p+ejvzqMO5mxbvAI9tKAvbdamtfO4Pi3A+sNvJ9XSLE9iLAdfWeoT2qLqGPgkXI1SGDof+FP5yIb36C8Um9P4hE3zaE+UdJBk0qgzlc1Zlq2Pdg0TGU6wwJQkRhZIDun1wabeqGWjLrBqUa9VPfNB1El63q/1rhP5v3m6tI7dXt0SQArTtbPWkkHHYPehObG6Q5s4Cm2QrWGpbK+R6xe5F+nEv4+dOuSkZgOB2HsOjzenjp/slqoZTCJYnKT5IDkFQaj5G8YftySyNE/OguMW6atCgulSygwaeuFsnjMNxxsHssrTndNe22jpTTrh2Odp9BT7oRiZPPR8zj/Z3hpLYca24X4oSlZLD0PFEExQNir6V7eT0gH6Paj7wz2rYeYKB8focatLNAwug7L6lWxnr/pw8IXCrfx4ZHw7VYn4hf/KF4isrPju6XW0u2wuiIVlJfOUXZXONmJULB6biftgZapveIMy1oHaabyuIIxkKGParhSUfj6/8/qPVftVFYotdlAy9oNRpZ8JG8z8Sf34etu9Fi7uzcZySKU9e8cU43o6kAo+r39RHRDuhUmYP0ocN2bdlTAkhPoFccK2A1Qx+W/+EwQr55mb5NCH95AVh2QX0SwWgD79FV7EYGN7iVEc+duV5YH8Qy37f6ebehQy+mZGFqCZ5s7Cqy7ChypB476qDqh82qp4K5Uv2NwoF7TT9REzjU0cbRseFbC77AgEUNvfHpHvLBTsw5Y4963GefSKltNHxKROboBfLkaGFHNOlQ8sHIY+vd5Y=,iv:g9iNn/sH7CtxcT4SeI8/DFG8BPIIoseYTuprGEQPqJ8=,tag:SuV+seYm30JAMN7QbdDl9g==,type:str]", "data": "ENC[AES256_GCM,data:RTj0FFJudZusWh2SuAPBHhpYEU20GmWbeZZSCG/vKCz83iUEJxpZ0lSDm71BN1Di7sz+VchcbWxkUjc+SV9paFOtuRKMPynW5n/HTyp/ub3y8oPUN4AjxiRnvfzh8Qxd/vnmxd6lSh2HxMlOqJURN0JY3D3g+tpHyTIvFUWef6HgzLNZCXDnP3HJzbIY53VPj9f+DsdxtFwU5OHkWd8gH2D4XuPPetN0Iv2HaR9+dvlVrbKEXgElgdENkU+ED78TFxvabk1hqPZqXhsfORF/5RpwF15ip5iSlVWPTwMdBREqCsHRiA+u5F9nwJ5C70U1wz39J40CJoa9oihIxyAmN3dktD0JuY0jiqyxwTRFZXYh7Ioe4CksaET0P7LbTa7+BpctgoBqvmnhM3ZDNcSZMNcCbtX98V30UqEPBoTn3kRYvg/1C1SycR96bVW/AiHMiIzD93dNw2gUWdyQX9xtHvgdxLo3U20pJhjMEcsk9V98H6lPiLp3lltrjAX35RsG5R629W8/WVOGoUQn9nX/y6m9VFKoUPf8/M7tvlxDT9A/QBQQvShdA4AM0K8mdNzb85ac5In+43gWDRXWQPPf72e5gL5nPIqPcZvAcoLHsYFH5ebr7VUaUbHm890jQDoNvtezZ1w9nRlZNGVTwdvwWB3rfzorzwCAKLhkFv6ATUYimP0tiHPOz0MxTQKXg12rtyPXbh8bwjhg0kdIlwljAYnYUKiX7SVSeYq7TQksQIiH83JwxCGrL4xjMWZhNkrg3KQUrEMHHaMbNCZvb5M2nMceBo6eA2zi5qYA9sLVnLTrlwx+3Wl7uFBv+9Z+8qvGg3adpGrtJTJjVf+cig01gzao5WrJtT9q4YD1tOHnWfBhwI9/3ny2A0WlyjlY/fS8WUiOmyhl/6N+ukdffzDZQOcTGf1QD0zO+9FYPqYhxr8eGKRHAB0R81Q5y+ORTLwXJ7EhRIK2f45FJisRIsiR+VTsI2cqy7n9HtubY8jQPxLMLnxuUqTu/OjtUMCcbJO8iqYDxWf6NlCZuTaLsQuUPWvO5uUelQpDmN6HhxSGKD9XG4M7/zCuCWNhKWoH0Z9xfw==,iv:Bs1fdmD4jbM/9hiPHxu+yENrVrwFsmhJ5J38W5+4PtM=,tag:UBpHq3ldgdVORaRxuswzVQ==,type:str]",
"sops": { "sops": {
"age": [ "age": [
{ {
@ -7,8 +7,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2YjdYNFF5Q1VzQTZ0WU1z\nN2R6cEVObU9RMXdpd2x0Mjh2cmpvY0VvNjE4CmF5Sm1vZWRoOTFIY2pkQUVRQ3FY\nVEd3eGpCbGQ3cUpvTE9JdjJMWnQvckEKLS0tIFRpZDZ1ZGZKaXpObFhZVlNqV0hB\nT20rRGV6S3gvWkZLUzQzVVNGQWNGVkUK0bAeRuI0vb7MJTtpxuD56nwZAk39sHAa\njEhntqsV9ts1Vbw2f0mZEqDdzd64NTtDm/YIwygZ2udV27mXNhVUVw==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2YjdYNFF5Q1VzQTZ0WU1z\nN2R6cEVObU9RMXdpd2x0Mjh2cmpvY0VvNjE4CmF5Sm1vZWRoOTFIY2pkQUVRQ3FY\nVEd3eGpCbGQ3cUpvTE9JdjJMWnQvckEKLS0tIFRpZDZ1ZGZKaXpObFhZVlNqV0hB\nT20rRGV6S3gvWkZLUzQzVVNGQWNGVkUK0bAeRuI0vb7MJTtpxuD56nwZAk39sHAa\njEhntqsV9ts1Vbw2f0mZEqDdzd64NTtDm/YIwygZ2udV27mXNhVUVw==\n-----END AGE ENCRYPTED FILE-----\n"
} }
], ],
"lastmodified": "2025-07-08T00:23:59Z", "lastmodified": "2025-11-10T23:16:52Z",
"mac": "ENC[AES256_GCM,data:Db2w9giZy+TyXp2hpMN1h7ZgBaJ4WiAN2P6IFaoXufOlxT2uwulbzDMYFoUm9jcdFc8zqnYCvttosJIzyjevY5up9gDarzTu+43XFrTxYqPdgRBzzvxSeXmKqDnngAvv/qOWfzt7TG1IzpyytHX/DEPHvPM9dWgut/1K6Eq94Hs=,iv:WoWAAjse1kyn9IGX4kqCl3zvq4kXEMkfTjAi2j5OCFs=,tag:xco/8fudn2kCLnFa8mUIsA==,type:str]", "mac": "ENC[AES256_GCM,data:CuwVt8/XKRMUHs1rh7Yf4Bk5tWXqTz0HXUiEEjuLhj1TRuMWs6aTC1h9uTMoybP+FmjKeRTar1E8dgUmoheFUGaBFqxd1Kx/FmNeJVLhUOPgmT9XOIjEjTNnzOoaMsYvfhP+AnLKgx+CfOsLnLMOqdKEggx1t5jNfiI2rXqOdfI=,iv:4Mc3WcgMg3z99dERJk+EF4hPpgGZo4mfMt6X45zgp5I=,tag:MP0YDtR1Wq3088WVzXS+8A==,type:str]",
"pgp": [ "pgp": [
{ {
"created_at": "2025-06-13T20:12:55Z", "created_at": "2025-06-13T20:12:55Z",
@ -17,6 +17,6 @@
} }
], ],
"unencrypted_suffix": "_unencrypted", "unencrypted_suffix": "_unencrypted",
"version": "3.10.2" "version": "3.11.0"
} }
} }

View file

@ -1,50 +0,0 @@
{ lib, minimal, ... }:
{
imports = [
./hardware-configuration.nix
./disk-config.nix
];
boot = {
loader.systemd-boot.enable = true;
tmp.cleanOnBoot = true;
};
networking = {
nftables.enable = lib.mkForce false;
hostName = "milkywell";
enableIPv6 = true;
domain = "subnet03112148.vcn03112148.oraclevcn.com";
};
topology.self = {
icon = "devices.cloud-server";
};
hardware = {
enableAllFirmware = lib.mkForce false;
};
swarselsystems = {
info = "VM.Standard.E2.1.Micro";
isImpermanence = true;
isSecureBoot = false;
isCrypted = true;
isSwap = true;
rootDisk = "/dev/sda";
swapSize = "4G";
isBtrfs = true;
isLinux = true;
isNixos = true;
};
} // lib.optionalAttrs (!minimal) {
swarselprofiles = {
server = true;
};
swarselmodules.server = {
forgejo = lib.mkDefault false;
ankisync = lib.mkDefault false;
};
}

View file

@ -1,22 +0,0 @@
{
"data": "ENC[AES256_GCM,data:4mDIWJ+WBn4c3US7Gby15hCtYYS6gYR1asm3SafO6/qyPKrcfKN42d2iIZEIPEq5yVj6OKt7ccFjQI2q3p8Dpb+HNYzHeGRcwBXKPL5hbVziP7Ik8pAYib7klUSmMelqOkc0aS1kyRyQzpvQoA6T7vNqEdm8kBR4SRs=,iv:7ZTbZh7TnCnfZ33g88Bsk3TISfhxz3+4cB1KiFucCMM=,tag:QgPChPUmZiB4AhH2xXturA==,type:str]",
"sops": {
"age": [
{
"recipient": "age1glge4e97vgqzh332mqs5990vteezu2m8k4wq3z35jk0q8czw3gks2d7a3h",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1ZWxybEZUcjlIdmtOS3Az\nbGt2czliWHBlUWNsNDA0cTJLeXdFOXE1NHh3CllaWGh1ZEZINDhPMUdCZUQ3Ritj\ncTdpRFRHaFdBa3NPWk40WjVlaTlrQmMKLS0tIEZnYkc3Z2hzZXV1eGlsaktyckVT\nbTIrZ3BvZDNkRGpoZ2ZncVlwZysxMW8KU0vsVA9gG63M1ecqk918QHh7P+MSbKaM\nRv/HVAvCzNcMFwPUC7zF0jN0FpAl7eNGkniUMCzGyXHty4anSDyt1g==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-06-11T13:01:41Z",
"mac": "ENC[AES256_GCM,data:urkp4cEP8fzSvroewVTbVfFK4O03qKnd+Ch3ASJAo1xu++y+fuFFyRcvrY57xU32H+mK2ipSkl2FkeTYB2fNDpXzTIyCWGQPZ4i3doqmFkV1UPjjov8Cc/LY7eRQYj84pF9sFRMdAwtaUL3Kd4Ab45mO1fy7KYAW57zuUeZks/o=,iv:efnEEPHFu2EtRSyob3ozjHz4L1YHJ0AqzLb566pg5ZQ=,tag:VnrO5QFhdQFe9/7aJ9C/qw==,type:str]",
"pgp": [
{
"created_at": "2025-06-11T12:59:00Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTARAAvlrXaui4wqN1kgpfcZMf53RsJYbZp6//miZzas2xKVW3\nyvtubrrYBrHGPEnUuoHexsN4xiQ0zayOn+eLrbv5+8/jhjL6cxtv894+iHYcgkD7\nDc9M4f57Lf7qF9lGTo1pgPKRf2GbHbHfDgUjz5XcIUD0WAz0PCkGQqutP5daw7wV\nMo+fKm6yOxb+e89rlOUY26/LSy+5WMIoQ03tcWu92UZeVRvtEL2LIDQJ3+gCEBrL\nPI0SU84tIl1At1TkKhJkcZ9axn0vOc+LzhcdZ3K5AkAlvnx6/+KdFiVj7xQNQyfN\nJJs3U1HKDca0R6efTRveEoi5nWew2FPGmRfOD34DorokM46Ol0l1c4gL+2LjvPUj\ntEG3slBFoKYbPuj6GSA2H3U2LcgVbPtZggr7VN7d4bLiqT/PkUa2jjAcsqyb+Twc\ng9nmCiWFvrGR76dpvSdx6oO6O/etMcWT9A4fYMPStXcnT32N4q+qrV/+nFZm4BLp\nWvDYkgVWmiAwYTcwuAHS12yH9ymEQMRanSNyzRqjax+GVN70B5nNU5sn8Ch0ex7Q\n6qJZq1j+i/OtNITvnnCdOxefntM4UZzyeyqvU+rZx40KepyVD2XFWkp+9abev0iL\nVbJK5PmNRRxqLaRWxJu2f/Jb86hy60XjCcsWGxuo67ZReRWOHIuyQB15tr3DdReF\nAgwDC9FRLmchgYQBD/49wGPgfs1G4Y0qcAoqZWbdpbcqCwYEzlRK1DJdjFTtE8LO\n+IpA03seoy7qCAp3v86qg7YwjydA+vCJUk7FRFbLiesKDxS1ZRwZSWHuM/v46rj4\nJoTqOPjuJDzed8dFdl4082PrQ0z+dXjsK/ua6d6eQRw6JEgpTLbv7f6Ru4RyM93h\n3wUodncoqcyZ/Wy7qLKCy10CTaD/RRpVrKt18J0L17Qbevmap6tqRZI11GWBnb+R\nqChAvuBQnhN19+MxgJ9AC20SqUht2pBvUXAhWf9vEGoygWR2kXuxyxK2XYu26zXa\nBb33xNAd2BZ/zr7fDnwjROkhRJ0YWk4GqaUCfo3zmT/OtHUzoyIvi0um7obOPzUk\n6RJw3q3siiUXavvTvgJMhCySwzHLtrPGYzCiHfkQc555yRqoz1XrdZOoQyba288y\niMFVzrIp+jlN+shNfsumGIgtogiYl3yI+Ecib7ozwIXDyOmBfsGUFLZkleGXWoH+\n/ZU3stAVFsSzOVkw656NWgsAEnqP1T7TGBMP1vibDPNZBp9aExA+1XLyVbr7sFJG\nWT9ypYorj7hF3UW1Ep/1fmcYovXICieKPR8sLVdWrPxRXArezfoqMAFhxdw6y87n\nQUrOTy8XOwsERmMOWhcU54NgdU21MDI3/sgh20KznNUU1iIOPQgfeobJ0rR/htJe\nAYaaMHhkJvSkiuXBKJIaz125xQrKvwLpB+OsuezPhT5Qn4MZUEoUa5Ft1GhiDqWM\nSB8o70nlAcw0CFvNlsYRZdVY5FACj81B1H6JH5eNUx6f2FVhcO61kc60LJvzug==\n=zX1v\n-----END PGP MESSAGE-----",
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.10.2"
}
}

View file

@ -0,0 +1,36 @@
{ lib, minimal, ... }:
{
imports = [
./hardware-configuration.nix
./disk-config.nix
];
swarselsystems = {
info = "HUNSN RM02, 8GB RAM";
flakePath = "/root/.dotfiles";
isImpermanence = true;
isSecureBoot = true;
isCrypted = true;
isBtrfs = true;
isLinux = true;
isNixos = true;
rootDisk = "/dev/sda";
swapSize = "8G";
networkKernelModules = [ "igb" ];
};
} // lib.optionalAttrs (!minimal) {
swarselprofiles = {
server = true;
router = false;
};
swarselmodules = {
server = {
nginx = lib.mkForce false; # we get this from the server profile
};
};
}

View file

@ -1,8 +1,4 @@
# NOTE: ... is needed because dikso passes diskoFile { lib, config, ... }:
{ lib
, config
, ...
}:
let let
type = "btrfs"; type = "btrfs";
extraArgs = [ "-L" "nixos" "-f" ]; # force overwrite extraArgs = [ "-L" "nixos" "-f" ]; # force overwrite
@ -74,7 +70,7 @@ in
mountOptions = [ "defaults" ]; mountOptions = [ "defaults" ];
}; };
}; };
root = { root = lib.mkIf (!config.swarselsystems.isCrypted) {
size = "100%"; size = "100%";
content = { content = {
inherit type subvolumes extraArgs; inherit type subvolumes extraArgs;
@ -86,6 +82,31 @@ in
''; '';
}; };
}; };
luks = lib.mkIf config.swarselsystems.isCrypted {
size = "100%";
content = {
type = "luks";
name = "cryptroot";
passwordFile = "/tmp/disko-password"; # this is populated by bootstrap.sh
settings = {
allowDiscards = true;
# https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
crypttabExtraOpts = [
"fido2-device=auto"
"token-timeout=10"
];
};
content = {
inherit type subvolumes extraArgs;
postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
MNTPOINT=$(mktemp -d)
mount "/dev/mapper/cryptroot" "$MNTPOINT" -o subvolid=5
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
'';
};
};
};
}; };
}; };
}; };

View file

@ -1,12 +1,14 @@
{ config, lib, modulesPath, ... }: { { config, lib, modulesPath, ... }:
imports = [
(modulesPath + "/profiles/qemu-guest.nix") {
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
]; ];
boot = { boot = {
initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" ]; initrd.availableKernelModules = [ "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
initrd.kernelModules = [ ]; initrd.kernelModules = [ ];
kernelModules = [ "kvm-amd" ];
extraModulePackages = [ ]; extraModulePackages = [ ];
}; };
@ -15,8 +17,8 @@
# still possible to use this option, but it's recommended to use it in conjunction # still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`. # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
# networking.interfaces.ens3.useDHCP = lib.mkDefault true; # networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
} }

View file

@ -0,0 +1,22 @@
{
"data": "ENC[AES256_GCM,data:RwbQZyqU0OjA/wD3o0HppPWFjfHNAHsGF8DzdJrXZLlE5RPUigHWtMLcX+2bNd0DpS3r7WHCSyiu+mmg6GWFiE6wAOBU1Q19BpQ8k3oTt8sP3N4/5PfzYcXlHRfwxmB9/pv8YCi5+cOU5ExWiQ+kC767UbgPIC2ugUD6tkP14KkhW0EGgEhF3elBfOGrSHGgjltgIFMYm/WKZjM=,iv:EBpghMcCGd/wow68V3zoDfzwywDGwmlqn3btNHrfxbk=,tag:jvSZyRIQ7BmQdKc6YEBIZQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1hsumymvh5mkqlaynrp9lv2w696yk3wtjzlyfmrpeuvh9u2tlwceqh3563x",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0VHAxaWdiV1VlWEY2UktF\ncE96UHJnWGNpY0ZFUmZVSi9xSXpBMmI2S1VFCjB6cWtDTTJrNFhZRC9yUHRYdUpS\naytwOUJ4NTRxTmJmc0R0Wmh5dFVKbzQKLS0tIHQ2NUtqRjh6MVF6VHJFSHVFTFFD\nNWh0MDVjekFDUWZvTUZNK0Z4M0lJbVEKGZk1BvZsNTkIor5rTcpi2UE4W/BqNMWU\nIAe3irNN6p1si2zebrCEyiaJYuaVn7uYVwXcscJlNTfkr9szm8TjSA==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-11-10T01:10:14Z",
"mac": "ENC[AES256_GCM,data:NSUKiOFGZyTb9U6e8cJoOJPAMfnk5iuw7pLK0JJzdwf4pI1aMSqjSDylQ5EqqbdFKZKRmaIjjHSpcJep6q0TRFA6wOznHWyv/UCECGwqZrS3EXgcQF5lZl7NVXPPSsMZgPReEVQcMtMivatPrfksEeCaam4WC/M+dqd2d2RrOXI=,iv:KnBNepDoaQeQ9MSrSN6dkrbS6YqkMYMpmXFd5v+oWoI=,tag:vPhsazyi8d3ugGoW8Z1Asg==,type:str]",
"pgp": [
{
"created_at": "2025-11-11T17:51:27Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTAQ//cwoYXkjChyIyDP0dmqquRMAv7AsLz2IVVKcdGzqKWR/z\nx7owbhfGFaNCU/x8TWs3mUFBNnLIUQmuSWUuI30VMmFVjXQ9sybCZUCk5oFLD53+\nVPPb/KsAO06it8T0NxAlsXqe7n9fz1P16mFpMx8N1yb5s+GYG/C3UGATwJTJQn8+\nwob0NHfN/6qsZP5PzMgKlUiqc3YF+eB71KTHNDmT3l5sGsoNi0erZwNZc4VA0zn8\nPsFYodW9Mya1XUanJvrYKo9eRfrlpaUKGzn6GVlMJsZU0gNpKZepMubbev3+B1GR\nn6V+ViYWd8U9UTatuHy+aRcwEZfpXq7uKTTTdihECjNkHYSfXmUF9mjq6u5U0Lck\nykhElFADx+YEBJuavQabvYGu8fJx9DfJseNVwIv0M6hqLdg2CNMUQ1l1Q9weizeZ\nxLjme1LTlCUinJGN07CE0J9qP8syWRJYD9seP9Qc/b1IY2D8dGdgOTzO8Fx8vI+M\nOV+Q3T0Chn/f0lw2Xzu40MphB3eamt5cq0JeLQuwQHjUml0rGpi7bIj8PxeAgMkX\nXFzSokYTHGRJz2UblLnITfMaVYcu9HYHXxXIsZliaRBs2AlscyCCSQFjnEAEywlo\n9kvh49sjWztb0yGqHRAxdmJ+Sm5fCqP0huaTMXkC3zy4h0oeJte36Us0VxKk1HqF\nAgwDC9FRLmchgYQBD/oCYXtBTr276kjOMWs3WqDYMLUDbWM8d6b86HYgYvtwQy0z\nXgASNtWQsMMyIEiReSqv2H9jtTTqbUK93ALW2X7GmEvUIvmW64g1AfHKhmPw//Li\nKMxtK6sFVS/WSEYoaZarkZDwOpNx3+BnriQEHiMi21vWxCqluZFSDdls0ca2oXvF\nK9GpBUD8v5+l2EWhq5+4nxHKrDx0g+mjtZPJPRsJ1u0tisdkhRXauOvRHEymZ3mX\nRTee3FNR1t6YpXY811lX9yemXkdsSB4pzKWNQgk6U7WDkGcVaGNw0R8pS7F3YnRE\nFSJhKnhb9Bd6CX/zEV+IwEgY1yPfiEMX0bvIrcEJYgUg618YQbQPushxVk10+c66\nZJ+99g06tdyt+u8E9GpoujnoRjRWsEqElkZntd66fPuDm99qx+RHlF/1Likp/nPL\n4oIknDJu8wwoIBCtoQcWyaiNCa0Fo/HR6txyOt6tTqpwhnDGJP9UfYlKWt07CFar\nQLgZfJbHhetjXoRHMAs+WargN8KV7QGMGbQdPE+VwlZI4bKRSipH+rdDn+v50FQG\ndvFd7WRnWmTaG2W3cOLFH4pWc2MPnnxj0IHDI3U9olcCyuWAF12yC1HYuFuWeG+K\nokxmS1T1E0jIP9u8NTJBmLdjC+6U5y1ZvSZlIWB12OzBEpP7jl8uOVbD/AR4GtJe\nAf4EdsxTBocS50aRxxAOq5t3kaoTu36n1dbGDfb8k10bsBiQb6zJ+xtNQgWxNEeO\nb6YGIyglD06Wmm6C5LOyQ46KIzuFXB8irMJexApopLwIZ+jCnn0Nb1mO6DXHUw==\n=kTmR\n-----END PGP MESSAGE-----",
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.11.0"
}
}

View file

@ -25,10 +25,17 @@ in
}; };
networking = { networking = {
hostName = "chaostheatre"; hostName = "hotel";
firewall.enable = true; firewall.enable = true;
}; };
swarselmodules = {
server = {
network = lib.mkForce false;
diskEncryption = lib.mkForce false;
};
};
swarselsystems = { swarselsystems = {
info = "~SwarselSystems~ demo host"; info = "~SwarselSystems~ demo host";
wallpaper = self + /files/wallpaper/lenovowp.png; wallpaper = self + /files/wallpaper/lenovowp.png;
@ -47,7 +54,7 @@ in
} // lib.optionalAttrs (!minimal) { } // lib.optionalAttrs (!minimal) {
swarselprofiles = { swarselprofiles = {
chaostheatre = true; hotel = true;
minimal = true; minimal = true;
}; };
} }

View file

@ -0,0 +1,100 @@
{ inputs, lib, config, minimal, nodes, globals, ... }:
{
imports = [
./hardware-configuration.nix
./disk-config.nix
];
boot = {
loader.systemd-boot.enable = true;
loader.efi.canTouchEfiVariables = true;
};
swarselsystems = {
info = "ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM";
flakePath = "/root/.dotfiles";
isImpermanence = true;
isSecureBoot = true;
isCrypted = true;
isBtrfs = true;
isLinux = true;
isNixos = true;
withMicroVMs = false;
};
} // lib.optionalAttrs (!minimal) {
swarselprofiles = {
server = true;
};
swarselmodules = {
optional = {
microvmHost = true;
};
server = {
diskEncryption = lib.mkForce false; # TODO: disable
nfs = false;
nginx = false;
kavita = false;
restic = false;
jellyfin = false;
navidrome = false;
spotifyd = false;
mpd = false;
postgresql = false;
matrix = false;
nextcloud = false;
immich = false;
paperless = false;
transmission = false;
syncthing = false;
grafana = false;
emacs = false;
freshrss = false;
jenkins = false;
kanidm = false;
firefly-iii = false;
koillection = false;
radicale = false;
atuin = false;
forgejo = false;
ankisync = false;
homebox = false;
opkssh = false;
garage = false;
};
};
microvm.vms =
let
mkMicrovm = guestName: {
${guestName} = {
backend = "microvm";
autostart = true;
modules = [
./guests/${guestName}.nix
{
node.secretsDir = ./secrets/${guestName};
}
];
microvm = {
system = "x86_64-linux";
# baseMac = config.repo.secrets.local.networking.interfaces.lan.mac;
# interfaces.vlan-services = { };
};
specialArgs = {
inherit (config) nodes globals;
inherit lib;
inherit inputs minimal;
};
};
};
in
lib.mkIf (!minimal && config.swarselsystems.withMicroVMs) (
{ }
// mkMicrovm "guest1"
);
}

View file

@ -0,0 +1,118 @@
{ lib, config, ... }:
let
type = "btrfs";
extraArgs = [ "-L" "nixos" "-f" ]; # force overwrite
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [
"subvol=root"
"compress=zstd"
"noatime"
];
};
"/home" = lib.mkIf config.swarselsystems.isImpermanence {
mountpoint = "/home";
mountOptions = [
"subvol=home"
"compress=zstd"
"noatime"
];
};
"/persist" = lib.mkIf config.swarselsystems.isImpermanence {
mountpoint = "/persist";
mountOptions = [
"subvol=persist"
"compress=zstd"
"noatime"
];
};
"/log" = lib.mkIf config.swarselsystems.isImpermanence {
mountpoint = "/var/log";
mountOptions = [
"subvol=log"
"compress=zstd"
"noatime"
];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"subvol=nix"
"compress=zstd"
"noatime"
];
};
"/swap" = lib.mkIf config.swarselsystems.isSwap {
mountpoint = "/.swapvol";
swap.swapfile.size = config.swarselsystems.swapSize;
};
};
in
{
disko.devices = {
disk = {
disk0 = {
type = "disk";
device = config.swarselsystems.rootDisk;
content = {
type = "gpt";
partitions = {
ESP = {
priority = 1;
name = "ESP";
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "defaults" ];
};
};
root = lib.mkIf (!config.swarselsystems.isCrypted) {
size = "100%";
content = {
inherit type subvolumes extraArgs;
postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
MNTPOINT=$(mktemp -d)
mount "/dev/disk/by-label/nixos" "$MNTPOINT" -o subvolid=5
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
'';
};
};
luks = lib.mkIf config.swarselsystems.isCrypted {
size = "100%";
content = {
type = "luks";
name = "cryptroot";
passwordFile = "/tmp/disko-password"; # this is populated by bootstrap.sh
settings = {
allowDiscards = true;
# https://github.com/hmajid2301/dotfiles/blob/a0b511c79b11d9b4afe2a5e2b7eedb2af23e288f/systems/x86_64-linux/framework/disks.nix#L36
crypttabExtraOpts = [
"fido2-device=auto"
"token-timeout=10"
];
};
content = {
inherit type subvolumes extraArgs;
postCreateHook = lib.mkIf config.swarselsystems.isImpermanence ''
MNTPOINT=$(mktemp -d)
mount "/dev/mapper/cryptroot" "$MNTPOINT" -o subvolid=5
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
btrfs subvolume snapshot -r $MNTPOINT/root $MNTPOINT/root-blank
'';
};
};
};
};
};
};
};
};
fileSystems."/persist".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
fileSystems."/home".neededForBoot = lib.mkIf config.swarselsystems.isImpermanence true;
}

View file

@ -0,0 +1,25 @@
{ lib, minimal, ... }:
{
swarselsystems = {
info = "ASUS Z10PA-D8, 2* Intel Xeon E5-2650 v4, 128GB RAM";
};
} // lib.optionalAttrs (!minimal) {
swarselprofiles = {
server = false;
};
swarselmodules = {
optional = {
microvmGuest = false;
};
};
microvm = {
mem = 1024 * 4;
vcpu = 2;
};
}

View file

@ -0,0 +1,28 @@
{ config, lib, modulesPath, ... }:
{
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
initrd.availableKernelModules = [ "ahci" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
initrd.kernelModules = [ ];
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
supportedFilesystems = [ "zfs" ];
zfs.extraPools = [ "Vault" ];
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,15 @@
{
"data": "ENC[AES256_GCM,data:pGWiWA==,iv:sVpYJiphhvVPEo2MUMnpjlJmvf58/UJTTVVdU9dpqzM=,tag:2AsQRCyN9Pc/hnqviCo43g==,type:str]",
"sops": {
"lastmodified": "2025-11-06T12:11:19Z",
"mac": "ENC[AES256_GCM,data:NBAgy3MNd+p8Ih6v/JuxuMWgh0k9xj5Trg7mggBE/LrxfCZg+BpbhYcmAw/FW9Du5gq3Pcynnql3dqwKlzHEtkEOcI1MJSnBSWexgLxwEtRwbTJVOqEkCxby6dcQ4HWD1ZZnwa9Q7Cg1vcPD/yZuzVUH15mFHic7s5M5Xzdfu/w=,iv:tv8CFuXJ0iqh/Vho7vSoOpfhcGfCElMLWNvjxoE3fMg=,tag:pGP3CjKFFm0UuVgSCnn4RA==,type:str]",
"pgp": [
{
"created_at": "2025-11-06T12:11:04Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTARAAwZd6dmNcZqOWY7Ro6DXCRAD2LJuzR0AA26cRRzPgTPcw\nOwvV+Nh3hBWcZb5qkjKysZKGlIxzs4f02dKI172vUyIWQ6P5skygOOOpbr9g5171\nY0XTrmemesSKNfoUhsMFMCbFUc4HUxkUK7zadLk1AiBUqZMIFtx/riFMUBS2qTpR\nuLWiebt1Dw+rwcR8rBNxXPbeclm7322YOQDLUk4sHfi0vTvn+3sfGkbJ+OcJckoD\ndjVhWFqGUAbbELoR8yHpb+Ps6RYjKRNFNros9Yx9zQ18512gxOpRSzm0MTkKFyrz\n1UYVcv4Oz4W/e4nh1z2/re5X3l/HFUzwBG6AUTrYVuRo580kkZvWYFxHT6R+goVC\n5dhkqZpowrGpDIE/C7hKLenFIcOl1Nw5wgJ4Y9EmfZzorUnjJqT1Et2b2GU0hxvY\nKny+fiDeCfNdLzJejSNNg1/whoVmHbw3Q2aBJP0NL3nmNvaykO8RSA8WmzvQa+MA\nXweflh5G9lXOdH2vwb6EelOXpxlTjI7K/43Nbw/SXf/e1FKYK5l6TscyGEcHpFux\ns4ufYkCqTgxdKZjKwh0vqbdmbPUOCe/jqBOz6s/L/sR1/+8c2iIs0JVZd1VJSvDu\nIdfDfQh4wmso8L0qpjWimmkf0Y9itLWZo/oyioIqjVQ9+Daj2mvMkbKcSa486b2F\nAgwDC9FRLmchgYQBD/9lVmkHkPz5pbJV5U0nL3h/xx0JSyt6YYtLDacW8fw135GT\nojHijHvJAd1MqbNv391LcsZ1jtnUawNf6GAkr649lRuEH/WhNitXq20Z/06v5lwt\nGDhPMMf5uh+Uwgjxbeg/PFeTKILS2VX0tjJ8yeos2jNMOrmmwIg74V6mJk03E85K\nId06e2qNjzWlESyWOCFkfLQfSOTajQWmGyil8vNglmjuZdzLSE8eL6nA0hePnfJW\nOwewWcXEzHeeJsaevKFBBDpimAqi3XbKasQbZNSSFlkmw0vzAWKw5mzcdTMseae1\nLafjem7uw2epr4HIhwCZ47pCFrKcbweZMuUY557SomIGmv93OvglnZC40AYkJuNU\nIAVwNc8W/pd+jyiHh6tMlXfQ5/n25AcylDcacxxalNcKI0emNC90TsFc6wDpLh5D\n+R6kJ7GK8tI5BwIwtGIQmFsRREKE1x+IYATtKwQskb0Rng/D6eqNEvs8pjD1nGO3\nfNTG9G8PgC07TXSKGcNGytZy/GNSW9mnFgDgoiqh29bgfoJfSTWWvwZlzFXdWm0c\nzOiV5JSDRLewaqzhsQ/etms7qJIccRD7WcvM82x7UF0VYGd92EVsZxsq2aSVlMob\nCsxNXxij3qqNHdFgUuYYDzFym3/zmmi2wltPOZl7qYMhZI9P6wCsvDpxlFv16tJc\nAaBkBf1oOnjDvJm5i62KCEcRUmphKOB6Odr9/VHkAtgjPdWCOyge7ktbcwgsPw8L\ndemiSrNAglDX9RnPST5ggShZWn1Ik2mFfocCapvGBi5Hj9I/4xG/oIKREYc=\n=Ty0h\n-----END PGP MESSAGE-----",
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
}
],
"version": "3.11.0"
}
}

View file

@ -1,5 +1,5 @@
{ {
"data": "ENC[AES256_GCM,data:i8kqmycc80NLcOirK7D20hxsWWFGNMx5d1SDueaSTmymvTb0rNMFiRoLf44c9Bc5yBySg9zRNCJ8lyc1SZH5YAqIYGN8y4nzOTxyPxT1R+Igtzm49sBdp1dK6MVCW1/xIsjDE/niV19l9LTptN7neCIEuDjB22bSMRhfVOxOiSwd2FKBeH61XACFLAz3AuVC4a+FhqsBkmLOAg7SIG0xdsyi2tjuTOCiMci9eQk8q9XkmLQC3z6vBaIBxPErkIG/fyhNBYt0Hv+37b/TFVbBL9qnGK369Ln9EUm0IarInaq9haxE18DkI5bzlJH5hw4JNjMGFz8av6rOJT5oW52yPor1RBodwUtP6YDQCQsdINIbjmAM9C0HGBY31nyy07fVT+QDcNydjT1fEXLSJTseO5E/MrRCVBioorBpG+5kBBQhRMihGeT8htVGVQpiJC7peARRfSQTUqjNH/esWTPCk0xPOXgApgPIbXBIJFj4RiH2erzN1PKPpuGZfuqbEr63VXCp6t0jttZKDEEjob1ZJMKfiqRubaz+ycg/sxFb1p+l9O21ihW8jM9huiBpVTc+mHU0ENTSstC4uB5LG6HMqV9vmqrKP4OM13vifggpQ6K9VRXebpI/t4tdRETcwWIMo/LRCmhGO4o0+1tNG+ayVDVmY/ORJu/Nrl61TtmUXxGc74Vd1sea+60LuqDHdIEs06thxFLSCVXaxa70gTlQIlVSEJBz9yaAMm7Iw4CSvLbYTXrRg6P/jIZx7rGSyC7I/kFMAPsa2KYxUUkBNd8zSoHyf8paxbgocb3yNcMtHIyNYiOXaLgr56DasJKsXTdjnuic6PLBCd9+U9o9R4wdBw4CGHZ3+3P+LexImkK9InVTm3QD9gyWtgDe66jrQMJxicixtx6hKvP0P0nmjhE6UjhfMMYV2Qu7vx1APhE62KF9y+axIlKju4kYkRhC9BHi2FuZUCFkPiPd/RRWzBTuChnKud9TWTixBtzpBI39/5e3i8f55hcG0XkUT+rMolq/hCObIczq7M2TVrZK4vUGByHXi1Vljk+K2tUZLVGq+Vpa7JUfmyp/qdUBG5FFXBBLUmAA0yjR+XxTtuZ4+M7JdgoYlzXEN8AbyBTEfVps4HJVPfwWMZaXEWqc7fwSVNlkRpIGSkbF8+tzBd0M66FtjbC9hs1P/SwwUr/ZTwJW0D8EXDUOJo2VCGpGtzHZpg5wd7qPTKL20fLVrpdfKIMeBrPtpCkv2YAzSXClAMQqMJ1DtrFr9WNeTAv0ROwkfnGIYwFpDnK3Xy3Z9V1HlZY3K/UYybzb43Dvtl0qWcSmXxKWLK0rqe3r4sWKA/gpOi8UIyCssAv5At0JO2e0yBJv7tXi+WGNZIBEy559EYdnfHty2KZTR5M/PiP5t1PMbuzUkee3voybnAioCZfGsh5Ln04ZihUHbtbxocM4yieaqBd7nryO81b1ZARoZKbASaGMc7y65pgsA1MiNnbtGIZUwlNyg1q3iZxdtkG6qgG2vCY9Z6JNXXl6RoBmbDbCaIzvid8OXvK8z0z4t0BpYQCFVb3/sEAqweUnQffstEFB,iv:+cS1MmSlZWLdRt5Ey31y6WrDAudgjHxsUbfCBUK0/Sg=,tag:byOqNWWPQmlrDWQO1tRRJQ==,type:str]", "data": "ENC[AES256_GCM,data:umKGtD7jTa+ex3ADPs1zR2o9YU2j3y3zCEupCGOsdJyicM7u0efXDI0g755RdPeNJiB/z1DPy+mAkePPq/m93CCppTq0BYyt0JJw53/j3ghCMJj7N3wUVstMUB01jewDSUc7SLay0lkhMCWbrTKsR1pwnfFRAG8C3rWXQB2EkU9FViCo8VaOfEF6Cq9ev/r+SEepT85wvoMxxIg=,iv:bgJXEoj7nRUsi4fA+bYVYvJYavS+BoDuQt2SCrX/2W8=,tag:lmOjPU0J0Qf/vcnO0owTZg==,type:str]",
"sops": { "sops": {
"age": [ "age": [
{ {
@ -11,8 +11,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNeGtTZ0ZSV0trWlQrS2dV\nSFo0dytGYXhRTjl6cDZrUU0wZ1IybDVRaFZrCmZmRmxJNmdwS0xodHdEOGU4bldU\nR1JScHAvZHhlVTBJbWExb0VpR0h2MXMKLS0tIDYwQmZpMjdYRmpBeXFNOXArN0h5\nVGN1THljeCtVV0hXenMyRVJkMjlHNEEKm+yZTT48nYr3H0Bd1OKw/CYk1kwnrBzk\nTgSQHsGXhmOyDag9cSZ4wAOmqtqSjA9bouFBuhl2lSbgpjnarvFaXQ==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNeGtTZ0ZSV0trWlQrS2dV\nSFo0dytGYXhRTjl6cDZrUU0wZ1IybDVRaFZrCmZmRmxJNmdwS0xodHdEOGU4bldU\nR1JScHAvZHhlVTBJbWExb0VpR0h2MXMKLS0tIDYwQmZpMjdYRmpBeXFNOXArN0h5\nVGN1THljeCtVV0hXenMyRVJkMjlHNEEKm+yZTT48nYr3H0Bd1OKw/CYk1kwnrBzk\nTgSQHsGXhmOyDag9cSZ4wAOmqtqSjA9bouFBuhl2lSbgpjnarvFaXQ==\n-----END AGE ENCRYPTED FILE-----\n"
} }
], ],
"lastmodified": "2025-11-04T09:26:35Z", "lastmodified": "2025-11-10T01:10:33Z",
"mac": "ENC[AES256_GCM,data:T8GqsMxfFB9s1EOeLHNzxoz23FCOnlNsBsbvMxiLq7a78xt5Xw3dVN/IWfkyiCDwfSjo+fVx2yEd5tP/B3fSN7S8WJNSe5ZywLpal/RlsCzv7ARvbVCaBx22S4az97JsR1qQUcGSvoiTH5e/0t2tBtimGJ1witbvbiGkTBp8taw=,iv:Qs26cjeMLtRhTDO91yfBo93wUKJ9zVfUbJ8o6myHGUo=,tag:FbT8emz6q1QnXdxoX6hsYQ==,type:str]", "mac": "ENC[AES256_GCM,data:4vPX9TdAGGBwzEc3W6pQj+BVKjp2kSAMB/L3QVXZbDHfvyKFWUOqwG8u8P7XDcuIrrpx65YuJp6zwexpJjg5zkU4favJt+uHD1wWC3TZcCpda6v3hGW3RduQAwVy+18JJ+PdSxHzrC4jmj+t/HIKp6Bt7qB0Z1ynrt/CdGIVxh0=,iv:zQQrl19jK823UynE3EXLgazehpWW5ltRCWKdnElVh5k=,tag:zIIgbyXSw6f6xW2CaVW88g==,type:str]",
"pgp": [ "pgp": [
{ {
"created_at": "2025-08-24T23:36:17Z", "created_at": "2025-08-24T23:36:17Z",

View file

@ -15,6 +15,13 @@
minimal = lib.mkForce true; minimal = lib.mkForce true;
}; };
swarselmodules = {
server = {
network = lib.mkForce false;
diskEncryption = lib.mkForce false;
};
};
swarselsystems = { swarselsystems = {
info = "~SwarselSystems~ remote install helper"; info = "~SwarselSystems~ remote install helper";
wallpaper = self + /files/wallpaper/lenovowp.png; wallpaper = self + /files/wallpaper/lenovowp.png;

View file

@ -1,4 +1,4 @@
{ lib, config, minimal, ... }: { lib, minimal, ... }:
{ {
imports = [ imports = [
@ -10,25 +10,29 @@
loader.efi.canTouchEfiVariables = true; loader.efi.canTouchEfiVariables = true;
}; };
globals.hosts.${config.node.name}.ipv4 = config.repo.secrets.local.ipv4; # globals.hosts.${config.node.name}.ipv4 = config.repo.secrets.local.ipv4;
# globals.networks.home.hosts.${config.node.name} = {
networking = { # ipv4 = config.repo.secrets.local.home-ipv4;
inherit (config.repo.secrets.local) hostId; # mac = config.repo.secrets.local.home-mac;
hostName = "winters"; # };
firewall.enable = true;
enableIPv6 = false;
firewall.allowedTCPPorts = [ 80 443 ];
};
swarselsystems = { swarselsystems = {
info = "ASRock J4105-ITX, 32GB RAM"; info = "ASRock J4105-ITX, 32GB RAM";
flakePath = "/root/.dotfiles"; flakePath = "/root/.dotfiles";
isImpermanence = false; isImpermanence = false;
isSecureBoot = true; isSecureBoot = false;
isCrypted = true; isCrypted = false;
isBtrfs = false; isBtrfs = false;
isLinux = true; isLinux = true;
isNixos = true; isNixos = true;
server.garage = {
data_dir = [
{
capacity = "200G";
path = "/Vault/data/garage/main";
}
];
};
}; };
} // lib.optionalAttrs (!minimal) { } // lib.optionalAttrs (!minimal) {
@ -38,6 +42,7 @@
}; };
swarselmodules.server = { swarselmodules.server = {
diskEncryption = lib.mkForce false;
nfs = lib.mkDefault true; nfs = lib.mkDefault true;
nginx = lib.mkDefault true; nginx = lib.mkDefault true;
kavita = lib.mkDefault true; kavita = lib.mkDefault true;
@ -67,6 +72,7 @@
# snipeit = lib.mkDefault false; # snipeit = lib.mkDefault false;
homebox = lib.mkDefault true; homebox = lib.mkDefault true;
opkssh = lib.mkDefault true; opkssh = lib.mkDefault true;
garage = lib.mkDefault false;
}; };
} }

View file

@ -0,0 +1,26 @@
{
"data": "ENC[AES256_GCM,data:dwoz+/DxlUbk05hmg/EwtmUkuD759sQ4iVbjHqcPpY9y2l/gzuPSJT2CMI2GbZs5SKhtlqoqZ5jHG3LwcQjgulmYHB2ThJR4ALi7usJm08q0UfMirnm6mPxjnhdhJXdO6YQ4LaRyP81txSphrl28eJwp2efz3rkUp8nAA3keL6MLZsBkdOXujOJhpreTr1mprWTA6U8aRWFBW7Y1vWvxAH3dtQ03XhYXM88pY6k+HKMvcXSsiDhvwnxG/+UYvSIHcanmboCJDYbgXZECnIGsar7ZOmbsZ3GM6X37qPJpxNmUjc4OoRaJJCcn6saH8kOJkx2rxMyzgMryuGdBq4R/m2JsvDoCPDh+gKO+luCI+hH/iduxnDgYjZAQ2gv3Q14MGNe9nvPWVfiRXXzqRf/8vDXjpnD2FFKmMSqiCvPJHRL52uwO3R2zYUrUfQgDN0Jk6nII8B64l+l69Q8Mod1J5nEMwoUOihhOsjaz6TMIUo6b0GKvxZG04Noyd7S+KuxZe1BsrxSnn7REt6qyQKqAHnMYVXpBmOxOpzhAhOrBIOz6LuqHPzmooQukuBDH/Ej2rC5hLBAFW7mvHIcTqo9sJFbnT3lYYtwLSlHBE3R26vud9pG8K2SuVdy2MWJMpLscR48V9r3nAbWsXKXLZALW38z33/UMfzTJ4g4L7Eo/4E5RXlihyL5/p8ISsoQdf6Uj718pVPTToBRBbIEMOSoJ4ntPoVxQbcpdrGO9zrqqPeZWQSE1JM8anGeZVqeMEVmZJxIbfquX8eMKJrkTroa/9HysuIi0O311F/kntoCtDOYCd3mYPcT8UnZHW3wuG7lqYRd15i/eaMhj3z1eTWoZ40R8w+2TaQB+TjyoLoGGzHvyktI5UkYiaMwa2FoFz40tz5YdZ8aODLQhwJc1mv3Fm0VLudXm7NUcfc4tr35EKbDg1wKtUS13VMSHjbi8ANbTB3nBvpBsPKtD12BTqaP4Q0HJipdnDbcwas/MoG27rFO5+q8+cb82IgjSpCeekrIgUY1wsnOyR3j3ByITp8jfmCRMF1vjKifKr0pgREF1dW59VQ33TvUyjfveQV0ixeV+vM9QueQsUVFzeqYTagsPSM/Czx/UNo8hyG1ze0p+acoOb257Q/Um8nkj3iNPAzx3WN6IdjJkpN1Ldp1SvU5qd3o3DDcSw2ztz8usBkH91BrBaV9MYGH/FSM/HL2CfTZoZodP1VqKFi1Hl3pHHyPEagvoJp1ayUZqmymKu4x1wFxC5FMUXjWUwWZZx1PIOwOtf8pLqVd6FySJlwG/MA4Bfxcnc+eSZ1EYcuHU3ziGbtGiB0eqWXA0fhUwIHHUFnV7H8NoRaJnbDS+kviFdTQKvoF3OmymEwhaq/Oak0ZQk8NLHC7KTQ6xVCb7bBtLpkBdXFE3YB5ltXvEYvSL02qX9i6oBf8GRi4Tl+k6zca6QVJzHG4hU8Nh3cxXBmF2IIY4JiKy0YlsVXCg7OHEWMEl4qT09dAsrDcKQC205YRF7XO8AXimENFQM2Nr/moadk2SF3D2DuJEE2HnSBk4H2tVlMNns32MpTFBZwbf3JOIHJV9CFyVSjhjuNjVjMK4vVdpnEzhmnaKjDqMnuRGNZmrl6p8gKM26KlWcYpIclQkPxy1pY1iFINxGH4YEGdAztpx1YhBkQNkQT492InrPA/PE5XFStP4WsKsLW72lhSVgH8D27S76yGihXyaVXXfd0VF5Fx/gUnbd7fph4Vi1VtFonhfK+ctHg==,iv:aQoC+pr7OoTyTT0FE4MbENfzfJ0Beq1Lsz9G1jnFQPs=,tag:JuYmfDP2foCVDH8CwfL4fQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBET1RmRTM5OUxJMGNyWUZK\nMXFqUWF2ZHhOZ1pxa0RDbkNzWnVzVFFCbTJrCm1oU25haDl5eFg5T1VzOXByai84\ndTR6TGREVnBHNlV4S254dzh2Z1lvK2sKLS0tIGFLaWJFQ2VwaWtxaURqNDU2ekRQ\na09Hbm4vNnVQaEV1aGtqTTVOUWN2b28KQaoPc/UKaeQ72GdlbtWFdALywHcUkewf\nK5pEz41pzDKOjatypm9X8ZEIEarjOHIZgMpazVM4i1PRUUefSE0phw==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNeGtTZ0ZSV0trWlQrS2dV\nSFo0dytGYXhRTjl6cDZrUU0wZ1IybDVRaFZrCmZmRmxJNmdwS0xodHdEOGU4bldU\nR1JScHAvZHhlVTBJbWExb0VpR0h2MXMKLS0tIDYwQmZpMjdYRmpBeXFNOXArN0h5\nVGN1THljeCtVV0hXenMyRVJkMjlHNEEKm+yZTT48nYr3H0Bd1OKw/CYk1kwnrBzk\nTgSQHsGXhmOyDag9cSZ4wAOmqtqSjA9bouFBuhl2lSbgpjnarvFaXQ==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-11-10T01:10:47Z",
"mac": "ENC[AES256_GCM,data:2gKEGIYctY7g7mL7lay1T7XmxGdsRzz/dIC1p98zDTnIoBrq5mf5CV/FjAGi5jDsmEMoCSUTWFaT/0Wq3nmRC+OyjL3/Hsit+HJDBVbyf/mY+zs2UQd3KVYoxmpDeAJ1E9s8ygxEu5lJGzacWbJ9BggKUUnywXYfNg0fS7ntjUw=,iv:5xedOuJ3VFm4pEjXyVBM9Iwe5pK1dYP4nTRkk7exrvo=,tag:sEVygcLMqkI9CWQDjoaEqQ==,type:str]",
"pgp": [
{
"created_at": "2025-08-24T23:36:17Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTARAAwf7TLx0TR1HBhh57CyIQLw8ztc9oblKAW/V7bSlQM/wR\nIwQTcTi3azdI9yewDRO30rIr++FEapdGVdpXoqQ8zcl49VjwDux6wzF3bsmR5Goc\nlTkDd0bmz8RBfsK+6efXiRqo3C0yP2ZTOh3PSOvsXKbYS6wY3TvNBdGnAYrfOvEw\nmBFRhn6uakw3zjVUngB1di07DH3y0wEb/r6+Mzoswzg4DqT1SAdDkfS9dpn9h3MW\n3NBesYlOukLrNA5Toi6x/fmE2lrPHt5QxPdvfvKe5ye4myZ/gBn1mdejB6U9nOsk\nRCJFMosjBH7jIpwokTjUT6Vs+zs8yrF+gbP82H4RVfZymMfdZoU/pTfYe1Mwg6Yi\ntlHyiRBgSPBY8Doa2hM8/yvmfHVMqSQf8uXltz2VC7JUGD6P0QbDLpqY3URmHg/q\nwN3zYJLlSIkU6Z7oivTjfg0dR32Z80lCdZDQf+OQsRtCUi169Fgxr7+HhdxJyj49\nFIb6CR0DHW4vsEj1GPAa0Q4uMfCxLiSZfesY8myoCtlVo7oeqx787KicJB5PryHr\nyZweKd7tXO9g8LNJtECTZ81y2/sCfSZPBia6M4oz56pIFK4jhYCY3iPnWIS77axu\n5MmqZNOP06obp87nt1ea51BmXkaYxmSPoQ5R29CeYU+m9q+kKvizncgsCl/O7U6F\nAgwDC9FRLmchgYQBEADJo2kPzrxLHptsr6aoIxfYNrQ7JJM3FAZ7do5YvAbQsl5t\ny45qZ4+qWIEMRXwji2TvgSg8/ylnZfN2+rTHdtNJkDdJ2sX+RDr8pm7L3VS2Zhjf\nIp1SdPd5cm/3QupegzUR+kcPa+gPM4asGSytIkAnnpev/DCnLsrqiejdosTDj9dn\nFtPKJKSUBzJSNRxBSpM9L+cTU1qyMT024D5Qvq6vBOjFI1YV3LSfVXQe7OZxxxVX\naChkGR1v3UjndQ4Yv9hamJJ81lRLeIcVEOpOPxLHJX76AJUqP3fR/+m2Poah8bFF\n+yIdSp2jyWOoU60We72fvlEwxsTLl8Zani+xX2ckkUCe+wsiGJLch4Df1pepxpef\nb95wZ9L0msRdHY8vRQYapde/ju8CUHgywVX7+YH3EF1bJSnUOBmyOA76v9ir09am\n49g+VomkWUuzPJ2VYQXXH6d/qn/sm9Z9yxy7e1eh5m+9cd42b4sMdW6ZCTMAtGJF\nPX0SiOMR6S0hjKVBcfcyNoT/wo7wqEl4mYDpoCy10K0nYRn+ggJnIZEJzBWibMYH\nDWUDyuQIYLjOBAchFatXyMtbc8qDorYelLX7amPRDSiDhhj6Y5nYMJtUSwfTLwkN\nrI0Q4bjE+fgNACCqPoq/BDFZotcr1b664ZUJqgnTBPKZ5OnmW/iFkOfzu4fF9tJe\nAcekEPwsFbugu2bZ0Hs5Rl/Dh9p4L9gceuMiwJ3oYGA5cwXFCeVZLNqSDLy4upVX\nnXRaMzBNGgWo4geDq5JL10Mh7/1d4GGVxdts8RGdI8zUFTPV3GOaPEHeNyIO+g==\n=2UMI\n-----END PGP MESSAGE-----",
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.11.0"
}
}

5043
index.html

File diff suppressed because it is too large Load diff

View file

@ -1,36 +1,32 @@
{ self, config, pkgs, lib, ... }: { self, config, pkgs, lib, ... }:
let let
pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh"; pubKeys = lib.filesystem.listFilesRecursive "${self}/secrets/keys/ssh";
stateVersion = lib.mkDefault "23.05";
homeFiles = {
".bash_history" = {
text = ''
swarsel-install -n hotel
'';
};
};
in in
{ {
config = { config = {
home-manager.users.root.home = { home-manager.users.root.home = {
stateVersion = "23.05"; inherit stateVersion;
file = { file = homeFiles;
".bash_history" = {
text = ''
swarsel-install -n chaostheatre
'';
};
};
}; };
home-manager.users.swarsel = { home-manager.users.swarsel = {
home = { home = {
username = "swarsel"; username = "swarsel";
homeDirectory = lib.mkDefault "/home/swarsel"; homeDirectory = lib.mkDefault "/home/swarsel";
stateVersion = lib.mkDefault "23.05"; inherit stateVersion;
keyboard.layout = "us"; keyboard.layout = "us";
sessionVariables = { sessionVariables = {
FLAKE = "/home/swarsel/.dotfiles"; FLAKE = "/home/swarsel/.dotfiles";
}; };
file = { file = homeFiles;
".bash_history" = {
text = ''
swarsel-install -n chaostheatre
'';
};
};
}; };
}; };
@ -48,10 +44,6 @@ in
nix = { nix = {
channel.enable = false; channel.enable = false;
package = pkgs.nixVersions.nix_2_28; package = pkgs.nixVersions.nix_2_28;
# extraOptions = ''
# plugin-files = ${pkgs.dev.nix-plugins}/lib/nix/plugins
# extra-builtins-file = ${../nix/extra-builtins.nix}
# '';
extraOptions = '' extraOptions = ''
plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: { plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: {
buildInputs = [config.nix.package pkgs.boost]; buildInputs = [config.nix.package pkgs.boost];
@ -103,6 +95,7 @@ in
environment.etc."issue".text = '' environment.etc."issue".text = ''
~SwarselSystems~ ~SwarselSystems~
IP of primary interface: \4 IP of primary interface: \4
These IPs were also found: \4{eth0} \4{eth1} \4{eth2} \4{eth3} \4{eth4} \4{eth5} \4{wlan0}
The Password for all users & root is 'setup'. The Password for all users & root is 'setup'.
Install the system remotely by running 'bootstrap -n <CONFIGURATION_NAME> -d <IP_FROM_ABOVE> ' on a machine with deployed secrets. Install the system remotely by running 'bootstrap -n <CONFIGURATION_NAME> -d <IP_FROM_ABOVE> ' on a machine with deployed secrets.
Alternatively, run 'swarsel-install -n <CONFIGURATION_NAME>' for a local install. For your convenience, an example call is in the bash history (press up on the keyboard to access). Alternatively, run 'swarsel-install -n <CONFIGURATION_NAME>' for a local install. For your convenience, an example call is in the bash history (press up on the keyboard to access).
@ -113,6 +106,7 @@ in
wireless.enable = false; wireless.enable = false;
# dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload"; # dhcpcd.runHook = "${pkgs.utillinux}/bin/agetty --reload";
networkmanager.enable = true; networkmanager.enable = true;
usePredictableInterfaceNames = false;
}; };
services.getty.autologinUser = lib.mkForce "root"; services.getty.autologinUser = lib.mkForce "root";
@ -139,6 +133,8 @@ in
programs.bash.shellAliases = { programs.bash.shellAliases = {
"swarsel-install" = "nix run github:Swarsel/.dotfiles#swarsel-install --"; "swarsel-install" = "nix run github:Swarsel/.dotfiles#swarsel-install --";
"swarsel-net-manufacturer" = "lspci -nn | grep -i 'network\\|ethernet'";
"swarsel-kernel-module" = "lspci -k -d";
}; };
system.activationScripts.cache = { system.activationScripts.cache = {

View file

@ -10,12 +10,9 @@ check-trace:
update: update:
nix flake update nix flake update
iso: iso CONFIG="live-iso":
rm -rf result rm -rf result
nix build .#nixosConfigurations.iso.config.system.build.isoImage && ln -sf result/iso/*.iso latest.iso nix build --print-out-paths .#live-iso
iso-flake FLAKE SYSTEM="x86_64" FORMAT="iso":
nixos-generate --flake .#{{FLAKE}} -f {{FORMAT}} --system {{SYSTEM}}
iso-install DRIVE: iso iso-install DRIVE: iso
sudo dd if=$(eza --sort changed result/iso/*.iso | tail -n1) of={{DRIVE}} bs=4M status=progress oflag=sync sudo dd if=$(eza --sort changed result/iso/*.iso | tail -n1) of={{DRIVE}} bs=4M status=progress oflag=sync
@ -25,3 +22,6 @@ dd DRIVE ISO:
sync USER HOST: sync USER HOST:
rsync -rltv --filter=':- .gitignore' -e "ssh -l {{USER}}" . {{USER}}@{{HOST}}:.dotfiles/ rsync -rltv --filter=':- .gitignore' -e "ssh -l {{USER}}" . {{USER}}@{{HOST}}:.dotfiles/
bootstrap DEST CONFIG ARCH="x86_64-linux":
nix develop .#deploy --command zsh -c "swarsel-bootstrap -n {{CONFIG}} -d {{DEST}} -a {{ARCH}}"

View file

@ -7,6 +7,7 @@
pass-fuzzel pass-fuzzel
cdw cdw
cdb cdb
cdr
bak bak
timer timer
e e
@ -31,8 +32,6 @@
sshrm sshrm
endme endme
git-replace git-replace
rustdesk-vbc
]; ];
}; };
} }

View file

@ -1,6 +1,6 @@
{ self, lib, config, pkgs, globals, inputs, ... }: { self, lib, config, pkgs, globals, inputs, ... }:
let let
inherit (config.swarselsystems) homeDir isPublic isNixos; inherit (config.swarselsystems) homeDir mainUser isPublic isNixos;
inherit (config.repo.secrets.common.emacs) radicaleUser; inherit (config.repo.secrets.common.emacs) radicaleUser;
in in
{ {
@ -9,6 +9,31 @@ in
# needed for elfeed # needed for elfeed
# enable emacs overlay for bleeding edge features # enable emacs overlay for bleeding edge features
# also read init.el file and install use-package packages # also read init.el file and install use-package packages
home.activation.setupEmacsOrgFiles =
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
set -eu
if [ ! -d ${homeDir}/Org ]; then
${pkgs.coreutils}/bin/install -d -m 0755 ${homeDir}/Org
${pkgs.coreutils}/bin/chown ${mainUser}:syncthing ${homeDir}/Org
fi
# create dummy files to make Emacs calendar work
# these have low modified dates and should be marked as sync-conflicts
for file in "Tasks" "Archive" "Journal"; do
if [ ! -f ${homeDir}/Org/"$file".org ]; then
${pkgs.coreutils}/bin/touch --time=access --time=modify -t 197001010000.00 ${homeDir}/Org/"$file".org
${pkgs.coreutils}/bin/chown ${mainUser}:syncthing ${homeDir}/Org/"$file".org
fi
done
# when the configuration is build again, these sync-conflicts will be cleaned up
for file in $(find ${homeDir}/Org/ -name "*sync-conflict*"); do
${pkgs.coreutils}/bin/rm "$file"
done
'';
programs.emacs = { programs.emacs = {
enable = true; enable = true;
package = pkgs.emacsWithPackagesFromUsePackage { package = pkgs.emacsWithPackagesFromUsePackage {

View file

@ -39,7 +39,7 @@
exec = [ "${pkgs.swaybg}/bin/swaybg --output '${config.swarselsystems.sharescreen}' --image ${config.swarselsystems.wallpaper} --mode ${config.stylix.imageScalingMode}" ]; exec = [ "${pkgs.swaybg}/bin/swaybg --output '${config.swarselsystems.sharescreen}' --image ${config.swarselsystems.wallpaper} --mode ${config.stylix.imageScalingMode}" ];
outputs = [ outputs = [
{ {
criteria = "eDP-2"; criteria = config.swarselsystems.sharescreen;
status = "enable"; status = "enable";
scale = 1.0; scale = 1.0;
} }

View file

@ -4,11 +4,25 @@
config = lib.mkIf config.swarselmodules.kitty { config = lib.mkIf config.swarselmodules.kitty {
programs.kitty = { programs.kitty = {
enable = true; enable = true;
keybindings = { }; keybindings =
let
bindWithModifier = lib.mapAttrs' (key: lib.nameValuePair ("ctrl+shift" + key));
in
bindWithModifier {
"page_up" = "scroll_page_up";
"up" = "scroll_page_up";
"page_down" = "scroll_page_down";
"down" = "scroll_page_down";
"w" = "no_op";
};
settings = { settings = {
scrollback_lines = 10000; cursor_blink_interval = 0;
disable_ligatures = "cursor";
enable_audio_bell = false; enable_audio_bell = false;
notify_on_cmd_finish = "always 20"; notify_on_cmd_finish = "always 20";
open_url_with = "xdg-open";
scrollback_lines = 100000;
scrollback_pager_history_size = 512;
}; };
}; };
}; };

View file

@ -1,7 +1,8 @@
{ config, pkgs, lib, vars, ... }: { config, pkgs, lib, vars, ... }:
{ {
options.swarselmodules.niri = lib.mkEnableOption "niri settings"; options.swarselmodules.niri = lib.mkEnableOption "niri settings";
config = lib.mkIf config.swarselmodules.niri { config = lib.mkIf config.swarselmodules.niri
{
programs.niri = { programs.niri = {
package = pkgs.niri-unstable; # which package to use for niri validation package = pkgs.niri-unstable; # which package to use for niri validation
@ -202,5 +203,11 @@
}; };
}; };
} // {
programs.niri = lib.mkIf (!config.swarselmodules.niri) {
package = null;
config = null;
settings = null;
};
}; };
} }

View file

@ -1,4 +1,4 @@
{ self, lib, pkgs, config, ... }: { self, outputs, lib, pkgs, config, ... }:
let let
inherit (config.swarselsystems) mainUser flakePath isNixos isLinux; inherit (config.swarselsystems) mainUser flakePath isNixos isLinux;
in in
@ -47,7 +47,24 @@ in
}; };
}; };
nixpkgs.overlays = lib.mkIf isNixos (lib.mkForce null); nixpkgs = lib.mkIf (!isNixos) {
overlays = [
outputs.overlays.default
(final: prev:
let
additions = final: _: import "${self}/pkgs/config" {
inherit self config lib;
pkgs = final;
homeConfig = config;
};
in
additions final prev
)
];
config = {
allowUnfree = true;
};
};
programs = { programs = {
# home-manager.enable = lib.mkIf (!isNixos) true; # home-manager.enable = lib.mkIf (!isNixos) true;

View file

@ -1,4 +1,4 @@
{ lib, config, ... }: { lib, config, nixosConfig ? config, ... }:
{ {
options.swarselmodules.ssh = lib.mkEnableOption "ssh settings"; options.swarselmodules.ssh = lib.mkEnableOption "ssh settings";
config = lib.mkIf config.swarselmodules.ssh { config = lib.mkIf config.swarselmodules.ssh {
@ -22,43 +22,7 @@
controlPath = "~/.ssh/master-%r@%n:%p"; controlPath = "~/.ssh/master-%r@%n:%p";
controlPersist = "no"; controlPersist = "no";
}; };
"pfsense" = { } // nixosConfig.repo.secrets.common.ssh.hosts;
hostname = "192.168.1.1";
user = "root";
};
"bakery" = {
hostname = "192.168.1.136";
user = "root";
};
"dgx" = {
hostname = "192.168.48.200";
user = "swarsel";
};
"winters" = {
hostname = "192.168.178.24";
user = "root";
};
"minecraft" = {
hostname = "130.61.119.129";
user = "opc";
};
"milkywell" = {
hostname = "193.122.53.173";
user = "root";
};
"moonside" = {
hostname = "130.61.238.239";
user = "root";
};
"songdiver" = {
hostname = "89.168.100.65";
user = "ubuntu";
};
"pkv" = {
hostname = "46.232.248.161";
user = "root";
};
};
}; };
}; };
} }

View file

@ -125,83 +125,83 @@ in
in in
lib.recursiveUpdate lib.recursiveUpdate
{ {
"${modifier}+q" = "kill";
"${modifier}+f" = "exec firefox";
"${modifier}+Shift+f" = "exec swaymsg fullscreen";
"${modifier}+Space" = "exec fuzzel";
"${modifier}+Shift+Space" = "floating toggle";
"${modifier}+e" = "exec emacsclient -nquc -a emacs -e \"(dashboard-open)\"";
"${modifier}+m" = "exec swaymsg workspace back_and_forth";
"${modifier}+a" = "exec swarselcheck -s";
"${modifier}+x" = "exec swarselcheck -k";
"${modifier}+d" = "exec swarselcheck -d";
"${modifier}+w" = "exec swarselcheck -e";
"${modifier}+Shift+t" = "exec opacitytoggle";
"${modifier}+Shift+F12" = "move scratchpad";
"${modifier}+F12" = "scratchpad show";
"${modifier}+Shift+c" = "exec qalculate-gtk";
"${modifier}+c" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-org-capture)'";
"${modifier}+t" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-org-agenda)'";
"${modifier}+Shift+m" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-mu4e)'";
"${modifier}+Shift+a" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-swarsel/open-calendar)'";
"${modifier}+p" = "exec pass-fuzzel";
"${modifier}+o" = "exec pass-fuzzel --otp";
"${modifier}+Shift+p" = "exec pass-fuzzel --type";
"${modifier}+Shift+o" = "exec pass-fuzzel --otp --type";
"${modifier}+Ctrl+p" = "exec 1password --quick-acces";
# "${modifier}+Escape" = "mode $exit";
"${modifier}+Shift+Escape" = "exec kitty -o confirm_os_window_close=0 btm";
"${modifier}+Escape" = "exec wlogout";
"${modifier}+h" = "exec hyprpicker | wl-copy";
"${modifier}+s" = "exec grim -g \"$(slurp)\" -t png - | wl-copy -t image/png";
"${modifier}+Shift+s" = "exec slurp | grim -g - Pictures/Screenshots/$(date +'screenshot_%Y-%m-%d-%H%M%S.png')";
"${modifier}+Shift+v" = "exec wf-recorder -g '$(slurp -f %o -or)' -f ~/Videos/screenrecord_$(date +%Y-%m-%d-%H%M%S).mkv";
"${modifier}+1" = "workspace 1:";
"${modifier}+Shift+1" = "move container to workspace 1:";
"${modifier}+2" = "workspace 2:";
"${modifier}+Shift+2" = "move container to workspace 2:";
"${modifier}+3" = "workspace 3:";
"${modifier}+Shift+3" = "move container to workspace 3:";
"${modifier}+4" = "workspace 4:";
"${modifier}+Shift+4" = "move container to workspace 4:";
"${modifier}+5" = "workspace 5:";
"${modifier}+Shift+5" = "move container to workspace 5:";
"${modifier}+6" = "workspace 6:";
"${modifier}+Shift+6" = "move container to workspace 6:";
"${modifier}+7" = "workspace 7:";
"${modifier}+Shift+7" = "move container to workspace 7:";
"${modifier}+8" = "workspace 8:";
"${modifier}+Shift+8" = "move container to workspace 8:";
"${modifier}+9" = "workspace 9:";
"${modifier}+Shift+9" = "move container to workspace 9:";
"${modifier}+0" = "workspace 10:"; "${modifier}+0" = "workspace 10:";
"${modifier}+Shift+0" = "move container to workspace 10:"; "${modifier}+1" = "workspace 1:";
"${modifier}+Ctrl+m" = "workspace 11:M"; "${modifier}+2" = "workspace 2:";
"${modifier}+Ctrl+Shift+m" = "move container to workspace 11:M"; "${modifier}+3" = "workspace 3:";
"${modifier}+Ctrl+s" = "workspace 12:S"; "${modifier}+4" = "workspace 4:";
"${modifier}+Ctrl+Shift+s" = "move container to workspace 12:S"; "${modifier}+5" = "workspace 5:";
"${modifier}+Ctrl+e" = "workspace 13:E"; "${modifier}+6" = "workspace 6:";
"${modifier}+7" = "workspace 7:";
"${modifier}+8" = "workspace 8:";
"${modifier}+9" = "workspace 9:";
"${modifier}+Ctrl+Shift+c" = "reload";
"${modifier}+Ctrl+Shift+e" = "move container to workspace 13:E"; "${modifier}+Ctrl+Shift+e" = "move container to workspace 13:E";
"${modifier}+Ctrl+t" = "workspace 14:T";
"${modifier}+Ctrl+Shift+t" = "move container to workspace 14:T";
"${modifier}+Ctrl+l" = "workspace 15:L";
"${modifier}+Ctrl+Shift+l" = "move container to workspace 15:L";
"${modifier}+Ctrl+f" = "workspace 16:F";
"${modifier}+Ctrl+Shift+f" = "move container to workspace 16:F"; "${modifier}+Ctrl+Shift+f" = "move container to workspace 16:F";
"${modifier}+Left" = "focus left"; "${modifier}+Ctrl+Shift+l" = "move container to workspace 15:L";
"${modifier}+Right" = "focus right"; "${modifier}+Ctrl+Shift+m" = "move container to workspace 11:M";
"${modifier}+Ctrl+Shift+r" = "exec swarsel-displaypower";
"${modifier}+Ctrl+Shift+s" = "move container to workspace 12:S";
"${modifier}+Ctrl+Shift+t" = "move container to workspace 14:T";
"${modifier}+Ctrl+e" = "workspace 13:E";
"${modifier}+Ctrl+f" = "workspace 16:F";
"${modifier}+Ctrl+l" = "workspace 15:L";
"${modifier}+Ctrl+m" = "workspace 11:M";
"${modifier}+Ctrl+p" = "exec 1password --quick-acces";
"${modifier}+Ctrl+s" = "workspace 12:S";
"${modifier}+Ctrl+t" = "workspace 14:T";
"${modifier}+Down" = "focus down"; "${modifier}+Down" = "focus down";
"${modifier}+Up" = "focus up"; "${modifier}+Escape" = "exec wlogout";
"${modifier}+F12" = "scratchpad show";
"${modifier}+Left" = "focus left";
"${modifier}+Return" = "exec swarselzellij";
"${modifier}+Right" = "focus right";
"${modifier}+Shift+0" = "move container to workspace 10:";
"${modifier}+Shift+1" = "move container to workspace 1:";
"${modifier}+Shift+2" = "move container to workspace 2:";
"${modifier}+Shift+3" = "move container to workspace 3:";
"${modifier}+Shift+4" = "move container to workspace 4:";
"${modifier}+Shift+5" = "move container to workspace 5:";
"${modifier}+Shift+6" = "move container to workspace 6:";
"${modifier}+Shift+7" = "move container to workspace 7:";
"${modifier}+Shift+8" = "move container to workspace 8:";
"${modifier}+Shift+9" = "move container to workspace 9:";
"${modifier}+Shift+Down" = "move down 40px";
"${modifier}+Shift+Escape" = "exec kitty -o confirm_os_window_close=0 btm";
"${modifier}+Shift+F12" = "move scratchpad";
"${modifier}+Shift+Left" = "move left 40px"; "${modifier}+Shift+Left" = "move left 40px";
"${modifier}+Shift+Right" = "move right 40px"; "${modifier}+Shift+Right" = "move right 40px";
"${modifier}+Shift+Down" = "move down 40px"; "${modifier}+Shift+Space" = "floating toggle";
"${modifier}+Shift+Up" = "move up 40px"; "${modifier}+Shift+Up" = "move up 40px";
"${modifier}+Ctrl+Shift+c" = "reload"; "${modifier}+Shift+a" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-swarsel/open-calendar)'";
"${modifier}+Ctrl+Shift+r" = "exec swarsel-displaypower"; "${modifier}+Shift+c" = "exec qalculate-gtk";
"${modifier}+Shift+e" = "exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'"; "${modifier}+Shift+e" = "exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
"${modifier}+Shift+f" = "exec swaymsg fullscreen";
"${modifier}+Shift+m" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-mu4e)'";
"${modifier}+Shift+o" = "exec pass-fuzzel --otp --type";
"${modifier}+Shift+p" = "exec pass-fuzzel --type";
"${modifier}+Shift+s" = "exec slurp | grim -g - Pictures/Screenshots/$(date +'screenshot_%Y-%m-%d-%H%M%S.png')";
"${modifier}+Shift+t" = "exec opacitytoggle";
"${modifier}+Shift+v" = "exec wf-recorder -g '$(slurp -f %o -or)' -f ~/Videos/screenrecord_$(date +%Y-%m-%d-%H%M%S).mkv";
"${modifier}+Space" = "exec fuzzel";
"${modifier}+Up" = "focus up";
"${modifier}+a" = "exec swarselcheck -s";
"${modifier}+c" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-org-capture)'";
"${modifier}+d" = "exec swarselcheck -d";
"${modifier}+e" = "exec emacsclient -nquc -a emacs -e \"(dashboard-open)\"";
"${modifier}+f" = "exec firefox";
"${modifier}+h" = "exec hyprpicker | wl-copy";
"${modifier}+m" = "exec swaymsg workspace back_and_forth";
"${modifier}+o" = "exec pass-fuzzel --otp";
"${modifier}+p" = "exec pass-fuzzel";
"${modifier}+q" = "kill";
"${modifier}+r" = "mode resize"; "${modifier}+r" = "mode resize";
"${modifier}+s" = "exec grim -g \"$(slurp)\" -t png - | wl-copy -t image/png";
"${modifier}+t" = "exec emacsclient -cF '((name . \"Emacs Popup Anchor\"))' -e '(prot-window-popup-org-agenda)'";
"${modifier}+w" = "exec swarselcheck -e";
"${modifier}+x" = "exec swarselcheck -k";
# "${modifier}+Escape" = "mode $exit";
# "${modifier}+Return" = "exec kitty"; # "${modifier}+Return" = "exec kitty";
"${modifier}+Return" = "exec swarselzellij";
"XF86AudioRaiseVolume" = "exec swayosd-client --output-volume raise"; "XF86AudioRaiseVolume" = "exec swayosd-client --output-volume raise";
"XF86AudioLowerVolume" = "exec swayosd-client --output-volume lower"; "XF86AudioLowerVolume" = "exec swayosd-client --output-volume lower";
"XF86AudioMute" = "exec swayosd-client --output-volume mute-toggle"; "XF86AudioMute" = "exec swayosd-client --output-volume mute-toggle";

View file

@ -0,0 +1,120 @@
{ lib, config, pkgs, ... }:
{
options.swarselmodules.syncthing-tray = lib.mkEnableOption "enable syncthing applet for tray";
config = lib.mkIf config.swarselmodules.syncthing-tray {
home.activation.setupSyncthingIni =
let
syncthingApiEnvVarName = "SYNCTHING_API_KEY";
syncthingIni = {
file = "${config.home.homeDirectory}/.config/syncthingtray.ini";
content = ''
[General]
v=2.0.2
[qt]
customfont=false
customicontheme=false
customlocale=false
custompalette=false
customstylesheet=false
customwidgetstyle=false
font="Cantarell,11,-1,5,400,0,0,0,0,0,0,0,0,0,0,1"
icontheme=hicolor
iconthemepath=
locale=en_US
palette="@Variant(\0\0\0\x44\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff jj\x86\x86\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff\xff\xff\xff\xff\xff\xff\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff\0\0\0\0\0\0\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\xc0\xc0nn\xce\xce\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff jj\x86\x86\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\xff\xff\xff\xff\xff\xff\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff\0\0\0\0\0\0\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\x66\x66\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\xc0\xc0nn\xce\xce\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff jj\x86\x86\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\0\0::ff\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff\xff\xff\xff\xff\xff\xff\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff\x1d\x1d%%,,\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0\x1\x1\xff\xff\0\0\0\0\0\0\0\0\x1\x2\xff\xffP\x14\xff\xff\x65\x65\0\0\x1\x1\xff\xff\xa0\xa0\xb3\xb3\xc5\xc5\0\0\x1\x1\xff\xff^^\xc4\xc4\xff\xff\0\0\x1\x1\xff\xff\xc0\xc0nn\xce\xce\0\0\x1\x1\xff\xff\x17\x17\x1d\x1d##\0\0)"
plugindir=
stylesheetpath=
trpath=
widgetstyle=
[startup]
considerForReconnect=false
considerLauncherForReconnect=false
showButton=false
showLauncherButton=false
stopOnMetered=false
stopServiceOnMetered=false
syncthingArgs="serve --no-browser --logflags=3"
syncthingAutostart=false
syncthingPath=syncthing
syncthingUnit=syncthing.service
systemUnit=false
useLibSyncthing=false
[tray]
connections\1\apiKey=@ByteArray(''$${syncthingApiEnvVarName})
connections\1\authEnabled=falsex
connections\1\autoConnect=true
connections\1\devStatsPollInterval=60000
connections\1\diskEventLimit=200
connections\1\errorsPollInterval=30000
connections\1\httpsCertPath=${config.home.homeDirectory}/.config/syncthing/https-cert.pem
connections\1\label=Primary instance
connections\1\localPath=
connections\1\longPollingTimeout=0
connections\1\password=
connections\1\pauseOnMetered=false
connections\1\reconnectInterval=30000
connections\1\requestTimeout=0
connections\1\statusComputionFlags=123
connections\1\syncthingUrl=http://${config.services.syncthing.guiAddress}
connections\1\trafficPollInterval=5000
connections\1\userName=
connections\size=1
dbusNotifications=true
distinguishTrayIcons=false
frameStyle=16
ignoreInavailabilityAfterStart=15
notifyOnDisconnect=true
notifyOnErrors=true
notifyOnLauncherErrors=true
notifyOnLocalSyncComplete=false
notifyOnNewDeviceConnects=false
notifyOnNewDirectoryShared=false
notifyOnRemoteSyncComplete=false
positioning\assumedIconPos=@Point(0 0)
positioning\useAssumedIconPosition=false
positioning\useCursorPos=true
preferIconsFromTheme=false
showDownloads=false
showSyncthingNotifications=true
showTabTexts=true
showTraffic=true
statusIcons="#ff26b6db,#ff0882c8,#ffffffff;#ffdb3c26,#ffc80828,#ffffffff;#ffc9ce3b,#ffebb83b,#ffffffff;#ff2d9d69,#ff2d9d69,#ffffffff;#ff26b6db,#ff0882c8,#ffffffff;#ff26b6db,#ff0882c8,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff"
statusIconsRenderSize=@Size(32 32)
statusIconsStrokeWidth=0
tabPos=1
trayIcons="#ff26b6db,#ff0882c8,#ffffffff;#ffdb3c26,#ffc80828,#ffffffff;#ffc9ce3b,#ffebb83b,#ffffffff;#ff2d9d69,#ff2d9d69,#ffffffff;#ff26b6db,#ff0882c8,#ffffffff;#ff26b6db,#ff0882c8,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff;#ffa9a9a9,#ff58656c,#ffffffff"
trayIconsRenderSize=@Size(32 32)
trayIconsStrokeWidth=0
trayMenuSize=@Size(575 475)
usePaletteForStatusIcons=false
usePaletteForTrayIcons=false
windowType=0
[webview]
customCommand=
disabled=false
mode=0
'';
};
in
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
set -eu
if [ ! -f ${syncthingIni.file} ]; then
cat >${syncthingIni.file} <<'EOF'
${syncthingIni.content}
EOF
export ${syncthingApiEnvVarName}=$(cat /run/syncthing-init/api_key)
${lib.getExe pkgs.envsubst} -i ${syncthingIni.file} -o ${syncthingIni.file}
unset ${syncthingApiEnvVarName}
fi
'';
};
}

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,43 @@
programs.zellij = { programs.zellij = {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
settings = {
pane_frames = false;
simplified_ui = false;
default_shell = "zsh";
copy_on_select = true;
on_force_close = "detach";
show_startup_tips = false;
support_kitty_keyboard_protocol = true;
default_layout = "swarsel";
layout_dir = "${config.home.homeDirectory}/.config/zellij/layouts";
theme_dir = "${config.home.homeDirectory}/.config/zellij/themes";
scrollback_lines_to_serialize = config.programs.kitty.settings.scrollback_lines;
session_serialization = true;
copy_command =
if pkgs.stdenv.hostPlatform.isLinux then
"wl-copy"
else if pkgs.stdenv.hostPlatform.isDarwin then
"pbcopy"
else
"";
ui.pane_frames = {
rounded_corners = true;
hide_session_name = true;
};
plugins = {
tab-bar.path = "tab-bar";
status-bar.path = "status-bar";
strider.path = "strider";
compact-bar.path = "compact-bar";
# configuration.path = "configuration";
# filepicker.path = "strider";
# plugin-manager.path = "plugin-manager";
# session-manager.path = "session-manager";
# welcome-screen.path = "session-manager";
};
};
}; };
home.packages = with pkgs; [ home.packages = with pkgs; [
@ -12,8 +49,8 @@
]; ];
xdg.configFile = { xdg.configFile = {
"zellij/config.kdl".text = import "${self}/files/zellij/config.kdl.nix" { inherit config; }; # "zellij/config.kdl".text = import "${self}/files/zellij/config.kdl.nix" { inherit config; };
"zellij/layouts/default.kdl".text = import "${self}/files/zellij/layouts/default.kdl.nix" { inherit config pkgs; }; "zellij/layouts/swarsel.kdl".text = import "${self}/files/zellij/layouts/swarsel.kdl.nix" { inherit config pkgs; };
}; };
}; };

View file

@ -23,6 +23,7 @@ in
hg = "history | grep"; hg = "history | grep";
hmswitch = lib.mkIf (!isNixos) "${lib.getExe pkgs.home-manager} --flake ${flakePath}#$(hostname) switch |& nom"; hmswitch = lib.mkIf (!isNixos) "${lib.getExe pkgs.home-manager} --flake ${flakePath}#$(hostname) switch |& nom";
nswitch = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) switch; cd -;"; nswitch = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) switch; cd -;";
ntest = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) test; cd -;";
nboot = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) boot; cd -;"; nboot = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) boot; cd -;";
ndry = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) dry-activate; cd -;"; ndry = lib.mkIf isNixos "cd ${flakePath}; swarsel-deploy $(hostname) dry-activate; cd -;";
magit = "emacsclient -nc -e \"(magit-status)\""; magit = "emacsclient -nc -e \"(magit-status)\"";
@ -34,7 +35,8 @@ in
hotspot = "nmcli connection up local; nmcli device wifi hotspot;"; hotspot = "nmcli connection up local; nmcli device wifi hotspot;";
youtube-dl = "yt-dlp"; youtube-dl = "yt-dlp";
cat-orig = "cat"; cat-orig = "cat";
cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\""; # cdr = "cd \"$( (find $DOCUMENT_DIR_WORK $DOCUMENT_DIR_PRIV -maxdepth 1 && echo $FLAKE) | fzf )\"";
cdr = "source cdr";
nix-ldd-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; nix-ldd-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd";
nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd"; nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd";
nix-ldd-locate = "nix-locate --minimal --top-level -w "; nix-ldd-locate = "nix-locate --minimal --top-level -w ";

View file

@ -1,14 +1,17 @@
{ self, config, pkgs, lib, vars, nixosConfig ? config, ... }: { self, inputs, config, pkgs, lib, vars, nixosConfig ? config, ... }:
let let
inherit (config.swarselsystems) homeDir; inherit (config.swarselsystems) homeDir mainUser;
inherit (nixosConfig.repo.secrets.local.mail) allMailAddresses; inherit (nixosConfig.repo.secrets.local.mail) allMailAddresses;
inherit (nixosConfig.repo.secrets.local.work) mailAddress; inherit (nixosConfig.repo.secrets.local.work) mailAddress;
certsSopsFile = self + /secrets/certs/secrets.yaml;
in in
{ {
options.swarselmodules.optional.work = lib.mkEnableOption "optional work settings"; options.swarselmodules.optional.work = lib.mkEnableOption "optional work settings";
config = lib.mkIf config.swarselmodules.optional.work config = lib.mkIf config.swarselmodules.optional.work
{ ({
home.packages = with pkgs; [ home = {
packages = with pkgs; [
stable.teams-for-linux stable.teams-for-linux
shellcheck shellcheck
dig dig
@ -21,8 +24,13 @@ in
# openstackclient # openstackclient
vscode vscode
];
rustdesk-vbc
];
sessionVariables = {
AWS_CA_BUNDLE = nixosConfig.sops.secrets.harica-root-ca.path;
};
};
systemd.user.sessionVariables = { systemd.user.sessionVariables = {
DOCUMENT_DIR_WORK = lib.mkForce "${homeDir}/Documents/Work"; DOCUMENT_DIR_WORK = lib.mkForce "${homeDir}/Documents/Work";
} // lib.optionalAttrs (!config.swarselsystems.isPublic) { } // lib.optionalAttrs (!config.swarselsystems.isPublic) {
@ -105,6 +113,23 @@ in
# }; # };
# }; # };
wayland.windowManager.sway =
let
inherit (nixosConfig.repo.secrets.local.work) user1 user1Long domain1 mailAddress;
in
{
config = {
keybindings =
let
inherit (config.wayland.windowManager.sway.config) modifier;
in
{
"${modifier}+Shift+d" = "exec ${pkgs.quickpass}/bin/quickpass work/adm/${user1}/${user1Long}@${domain1}";
"${modifier}+Shift+i" = "exec ${pkgs.quickpass}/bin/quickpass work/${mailAddress}";
};
};
};
stylix = { stylix = {
targets.firefox.profileNames = targets.firefox.profileNames =
let let
@ -627,6 +652,15 @@ in
}; };
}; };
} // lib.optionalAttrs (inputs ? sops) {
sops.secrets = lib.mkIf (!config.swarselsystems.isPublic && !config.swarselsystems.isNixos) {
harica-root-ca = {
sopsFile = certsSopsFile;
path = "${homeDir}/.aws/certs/harica-root.pem";
owner = mainUser;
};
}; };
});
} }

View file

@ -4,7 +4,8 @@ let
in in
{ {
options.swarselmodules.${moduleName} = lib.mkEnableOption "${moduleName} settings"; options.swarselmodules.${moduleName} = lib.mkEnableOption "${moduleName} settings";
config = lib.mkIf config.swarselmodules.${moduleName} { config = lib.mkIf config.swarselmodules.${moduleName}
{
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
wl-clipboard wl-clipboard
@ -15,11 +16,15 @@ in
xwayland-satellite-unstable xwayland-satellite-unstable
]; ];
niri-flake.cache.enable = true;
programs.niri = { programs.niri = {
enable = true; enable = true;
package = pkgs.niri-unstable; # the actual niri that will be installed and used package = pkgs.niri-unstable; # the actual niri that will be installed and used
}; };
} // {
niri-flake.cache.enable = true;
programs.niri = {
package = null;
};
}; };
} }

View file

@ -2,12 +2,15 @@
let let
inherit (config.swarselsystems) mainUser homeDir; inherit (config.swarselsystems) mainUser homeDir;
devices = config.swarselsystems.syncthing.syncDevices; devices = config.swarselsystems.syncthing.syncDevices;
servicePort = 8384;
in in
{ {
options.swarselmodules.syncthing = lib.mkEnableOption "syncthing config"; options.swarselmodules.syncthing = lib.mkEnableOption "syncthing config";
config = lib.mkIf config.swarselmodules.syncthing { config = lib.mkIf config.swarselmodules.syncthing {
services.syncthing = { services.syncthing = {
enable = true; enable = true;
systemService = true;
guiAddress = "127.0.0.1:${builtins.toString servicePort}";
package = pkgs.syncthing; package = pkgs.syncthing;
user = mainUser; user = mainUser;
dataDir = homeDir; dataDir = homeDir;

View file

@ -4,6 +4,91 @@ let
mkOption mkOption
types types
; ;
networkOptions = netSubmod: {
cidrv4 = mkOption {
type = types.nullOr types.net.cidrv4;
description = "The CIDRv4 of this network";
default = null;
};
subnetMask4 = mkOption {
type = types.nullOr types.net.ipv4;
description = "The dotted decimal form of the subnet mask of this network";
readOnly = true;
default = lib.swarselsystems.cidrToSubnetMask netSubmod.config.cidrv4;
};
cidrv6 = mkOption {
type = types.nullOr types.net.cidrv6;
description = "The CIDRv6 of this network";
default = null;
};
hosts = mkOption {
default = { };
type = types.attrsOf (
types.submodule (hostSubmod: {
options = {
id = mkOption {
type = types.int;
description = "The id of this host in the network";
};
mac = mkOption {
type = types.nullOr types.net.mac;
description = "The MAC of the interface on this host that belongs to this network.";
default = null;
};
ipv4 = mkOption {
type = types.nullOr types.net.ipv4;
description = "The IPv4 of this host in this network";
readOnly = true;
default =
if netSubmod.config.cidrv4 == null then
null
else
lib.net.cidr.host hostSubmod.config.id netSubmod.config.cidrv4;
};
ipv6 = mkOption {
type = types.nullOr types.net.ipv6;
description = "The IPv6 of this host in this network";
readOnly = true;
default =
if netSubmod.config.cidrv6 == null then
null
else
lib.net.cidr.host hostSubmod.config.id netSubmod.config.cidrv6;
};
cidrv4 = mkOption {
type = types.nullOr types.str; # FIXME: this is not types.net.cidr because it would zero out the host part
description = "The IPv4 of this host in this network, including CIDR mask";
readOnly = true;
default =
if netSubmod.config.cidrv4 == null then
null
else
lib.net.cidr.hostCidr hostSubmod.config.id netSubmod.config.cidrv4;
};
cidrv6 = mkOption {
type = types.nullOr types.str; # FIXME: this is not types.net.cidr because it would zero out the host part
description = "The IPv6 of this host in this network, including CIDR mask";
readOnly = true;
default =
if netSubmod.config.cidrv6 == null then
null
else
lib.net.cidr.hostCidr hostSubmod.config.id netSubmod.config.cidrv6;
};
};
})
);
};
};
in in
{ {
options = { options = {
@ -39,12 +124,44 @@ in
); );
}; };
networks = mkOption {
default = { };
type = types.attrsOf (
types.submodule (netSubmod: {
options = networkOptions netSubmod // {
vlans = mkOption {
default = { };
type = types.attrsOf (
types.submodule (vlanNetSubmod: {
options = networkOptions vlanNetSubmod // {
id = mkOption {
type = types.ints.between 1 4094;
description = "The VLAN id";
};
name = mkOption {
description = "The name of this VLAN";
default = vlanNetSubmod.config._module.args.name;
type = types.str;
};
};
})
);
};
};
})
);
};
hosts = mkOption { hosts = mkOption {
type = types.attrsOf ( type = types.attrsOf (
types.submodule { types.submodule {
options = { options = {
ipv4 = mkOption { defaultGateway4 = mkOption {
type = types.str; type = types.nullOr types.net.ipv4;
};
defaultGateway6 = mkOption {
type = types.nullOr types.net.ipv6;
}; };
}; };
} }

View file

@ -1,8 +1,10 @@
{ lib, config, globals, ... }: { self, lib, config, globals, ... }:
let let
inherit (config.swarselsystems) mainUser homeDir; inherit (config.swarselsystems) mainUser homeDir;
inherit (config.repo.secrets.common.emacs) radicaleUser; inherit (config.repo.secrets.common.emacs) radicaleUser;
modules = config.home-manager.users.${mainUser}.swarselmodules; modules = config.home-manager.users.${mainUser}.swarselmodules;
certsSopsFile = self + /secrets/certs/secrets.yaml;
in in
{ {
config = lib.mkIf config.swarselsystems.withHomeManager { config = lib.mkIf config.swarselsystems.withHomeManager {
@ -22,6 +24,8 @@ in
github-nixpkgs-review-token = { owner = mainUser; }; github-nixpkgs-review-token = { owner = mainUser; };
}) // (lib.optionalAttrs modules.emacs { }) // (lib.optionalAttrs modules.emacs {
emacs-radicale-pw = { owner = mainUser; }; emacs-radicale-pw = { owner = mainUser; };
}) // (lib.optionalAttrs modules.optional.work {
harica-root-ca = { sopsFile = certsSopsFile; path = "${homeDir}/.aws/certs/harica-root.pem"; owner = mainUser; };
}) // (lib.optionalAttrs modules.anki { }) // (lib.optionalAttrs modules.anki {
anki-user = { owner = mainUser; }; anki-user = { owner = mainUser; };
anki-pw = { owner = mainUser; }; anki-pw = { owner = mainUser; };

View file

@ -1,4 +1,4 @@
{ self, inputs, config, lib, outputs, globals, nodes, minimal, configName, ... }: { self, inputs, config, lib, homeLib, outputs, globals, nodes, minimal, configName, ... }:
{ {
options.swarselmodules.home-manager = lib.mkEnableOption "home-manager"; options.swarselmodules.home-manager = lib.mkEnableOption "home-manager";
config = lib.mkIf config.swarselmodules.home-manager { config = lib.mkIf config.swarselmodules.home-manager {
@ -7,6 +7,7 @@
useUserPackages = true; useUserPackages = true;
verbose = true; verbose = true;
backupFileExtension = "hm-bak"; backupFileExtension = "hm-bak";
overwriteBackup = true;
users.${config.swarselsystems.mainUser}.imports = [ users.${config.swarselsystems.mainUser}.imports = [
inputs.nix-index-database.homeModules.nix-index inputs.nix-index-database.homeModules.nix-index
inputs.sops-nix.homeManagerModules.sops inputs.sops-nix.homeManagerModules.sops
@ -29,7 +30,11 @@
home.stateVersion = lib.mkDefault config.system.stateVersion; home.stateVersion = lib.mkDefault config.system.stateVersion;
} }
]; ];
extraSpecialArgs = { inherit (inputs) self nixgl; inherit inputs outputs globals nodes minimal configName; }; extraSpecialArgs = {
inherit (inputs) self nixgl;
inherit inputs outputs globals nodes minimal configName;
lib = homeLib;
};
}; };
}; };
} }

View file

@ -1,5 +1,5 @@
# largely based on https://github.com/oddlama/nix-config/blob/main/modules/secrets.nix # largely based on https://github.com/oddlama/nix-config/blob/main/modules/secrets.nix
{ config, inputs, lib, minimal, ... }: { config, inputs, lib, ... }:
let let
# If the given expression is a bare set, it will be wrapped in a function, # 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 # so that the imported file can always be applied to the inputs, similar to
@ -65,7 +65,7 @@ in
let let
local = config.node.secretsDir + "/pii.nix.enc"; local = config.node.secretsDir + "/pii.nix.enc";
in in
(lib.optionalAttrs (lib.pathExists local && !minimal) { inherit local; }) // lib.optionalAttrs (!minimal) { (lib.optionalAttrs (lib.pathExists local) { inherit local; }) // lib.optionalAttrs true {
common = ../../../secrets/repo/pii.nix.enc; common = ../../../secrets/repo/pii.nix.enc;
}; };
}; };

View file

@ -107,7 +107,19 @@ in
system.stateVersion = lib.mkDefault "23.05"; system.stateVersion = lib.mkDefault "23.05";
nixpkgs = { nixpkgs = {
overlays = [ outputs.overlays.default ]; overlays = [
outputs.overlays.default
(final: prev:
let
additions = final: _: import "${self}/pkgs/config" {
inherit self config lib;
pkgs = final;
homeConfig = config.home-manager.users.${config.swarselsystems.mainUser};
};
in
additions final prev
)
];
config = { config = {
allowUnfree = true; allowUnfree = true;
}; };

View file

@ -7,58 +7,5 @@
# "${self}/modules/nixos" # "${self}/modules/nixos"
# ]; # ];
config = lib.mkIf config.swarselmodules.optional.microvmGuest config = lib.mkIf config.swarselmodules.optional.microvmGuest
{ { };
# imports = [
# inputs.microvm.nixosModules.microvm
# "${self}/profiles/nixos"
# "${self}/modules/nixos"
# ];
boot.kernelParams = [ "systemd.hostname=${config.networking.hostName}" ];
node.name = config;
documentation.enable = lib.mkForce false;
microvm = {
guest.enable = lib.mkForce true;
hypervisor = lib.mkDefault "qemu";
mem = lib.mkDefault 1024 * 4;
vcpu = lib.mkDefault 4;
optimize.enable = false;
writableStoreOverlay = "/nix/.rw-store";
# interfaces = flip lib.mapAttrsToList guestCfg.microvm.interfaces (
# _: { mac, hostLink, ...}:
# {
# type = "macvtap";
# id = "vm-${replaceStrings [ ":" ] [ "" ] mac}";
# inherit mac;
# macvtap = {
# link = hostLink;
# mode = "bridge";
# };
# }
# );
shares =
[
{
source = "/nix/store";
mountPoint = "/nix/.ro-store";
tag = "ro-store";
proto = "virtiofs";
}
];
};
# systemd.network.networks = lib.flip lib.concatMapAttrs guestCfg.microvm.interfaces (
# name:
# { mac, ... }:
# {
# "10-${name}".matchConfig = mkForce {
# MACAddress = mac;
# };
# }
# );
};
} }

View file

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

View file

@ -5,7 +5,7 @@ let
servicePort = 27701; servicePort = 27701;
serviceName = "ankisync"; serviceName = "ankisync";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
ankiUser = globals.user.name; ankiUser = globals.user.name;
in in

View file

@ -3,7 +3,7 @@ let
servicePort = 8888; servicePort = 8888;
serviceName = "atuin"; serviceName = "atuin";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -0,0 +1,77 @@
{ self, pkgs, lib, config, globals, minimal, ... }:
let
localIp = globals.networks.home.hosts.${config.node.name}.ipv4;
subnetMask = globals.networks.home.subnetMask4;
gatewayIp = globals.hosts.${config.node.name}.defaultGateway4;
hostKeyPath = "/etc/secrets/initrd/ssh_host_ed25519_key";
in
{
options.swarselmodules.server.diskEncryption = lib.mkEnableOption "enable disk encryption config";
options.swarselsystems.networkKernelModules = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
};
config = lib.mkIf (config.swarselmodules.server.diskEncryption && config.swarselsystems.isCrypted) {
system.activationScripts.ensureInitrdHostkey = lib.mkIf (config.swarselprofiles.server || minimal) {
text = ''
[[ -e ${hostKeyPath} ]] || ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -N "" -f ${hostKeyPath}
'';
deps = [ "users" ];
};
environment.persistence."/persist" = lib.mkIf (config.swarselsystems.isImpermanence && (config.swarselprofiles.server || minimal)) {
files = [ hostKeyPath ];
};
boot = lib.mkIf (config.swarselprofiles.server || minimal) {
kernelParams = lib.mkIf (!config.swarselsystems.isLaptop) [
"ip=${localIp}::${gatewayIp}:${subnetMask}:${config.networking.hostName}::none"
];
initrd = {
availableKernelModules = config.swarselsystems.networkKernelModules;
network = {
enable = true;
udhcpc.enable = lib.mkIf config.swarselsystems.isLaptop true;
flushBeforeStage2 = true;
ssh = {
enable = true;
port = 2222; # avoid hostkey changed nag
authorizedKeyFiles = [
(self + /secrets/keys/ssh/yubikey.pub)
(self + /secrets/keys/ssh/magicant.pub)
];
hostKeys = [ hostKeyPath ];
};
# postCommands = ''
# echo 'cryptsetup-askpass || echo "Unlock was successful; exiting SSH session" && exit 1' >> /root/.profile
# '';
};
systemd = {
initrdBin = with pkgs; [
cryptsetup
];
services = {
unlock-luks = {
wantedBy = [ "initrd.target" ];
after = [ "network.target" ];
before = [ "systemd-cryptsetup@cryptroot.service" ];
path = [ "/bin" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
echo "systemctl default" >> /root/.profile
'';
};
};
};
};
};
};
}

View file

@ -5,7 +5,7 @@ let
serviceGroup = serviceUser; serviceGroup = serviceUser;
serviceName = "firefly-iii"; serviceName = "firefly-iii";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
nginxGroup = "nginx"; nginxGroup = "nginx";

View file

@ -7,7 +7,7 @@ let
serviceGroup = serviceUser; serviceGroup = serviceUser;
serviceName = "forgejo"; serviceName = "forgejo";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
kanidmDomain = globals.services.kanidm.domain; kanidmDomain = globals.services.kanidm.domain;
in in

View file

@ -5,7 +5,7 @@ let
serviceUser = "freshrss"; serviceUser = "freshrss";
serviceGroup = serviceName; serviceGroup = serviceName;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
inherit (config.swarselsystems) sopsFile; inherit (config.swarselsystems) sopsFile;
in in

View file

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

View file

@ -3,7 +3,7 @@ let
servicePort = 7745; servicePort = 7745;
serviceName = "homebox"; serviceName = "homebox";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -4,7 +4,7 @@ let
serviceUser = "immich"; serviceUser = "immich";
serviceName = "immich"; serviceName = "immich";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -4,7 +4,7 @@ let
serviceName = "jellyfin"; serviceName = "jellyfin";
serviceUser = "jellyfin"; serviceUser = "jellyfin";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -3,7 +3,7 @@ let
servicePort = 8088; servicePort = 8088;
serviceName = "jenkins"; serviceName = "jenkins";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -8,7 +8,7 @@ let
serviceGroup = serviceUser; serviceGroup = serviceUser;
serviceName = "kanidm"; serviceName = "kanidm";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
oauth2ProxyDomain = globals.services.oauth2Proxy.domain; oauth2ProxyDomain = globals.services.oauth2Proxy.domain;
immichDomain = globals.services.immich.domain; immichDomain = globals.services.immich.domain;
@ -20,8 +20,18 @@ let
certBase = "/etc/ssl"; certBase = "/etc/ssl";
certsDir = "${certBase}/certs"; certsDir = "${certBase}/certs";
privateDir = "${certBase}/private"; privateDir = "${certBase}/private";
certPath = "${certsDir}/${serviceName}.crt"; certPathBase = "${certsDir}/${serviceName}.crt";
keyPath = "${privateDir}/${serviceName}.key"; certPath =
if config.swarselsystems.isImpermanence then
"/persist${certPathBase}"
else
"${certPathBase}";
keyPathBase = "${privateDir}/${serviceName}.key";
keyPath =
if config.swarselsystems.isImpermanence then
"/persist${keyPathBase}"
else
"${keyPathBase}";
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@ -54,6 +64,16 @@ in
globals.services.${serviceName}.domain = serviceDomain; globals.services.${serviceName}.domain = serviceDomain;
environment.persistence."/persist" = lib.mkIf config.swarselsystems.isImpermanence {
files = [
certPathBase
keyPathBase
];
};
system.activationScripts."createPersistentStorageDirs" = lib.mkIf config.swarselsystems.isImpermanence {
deps = [ "generateSSLCert-${serviceName}" "users" "groups" ];
};
system.activationScripts."generateSSLCert-${serviceName}" = system.activationScripts."generateSSLCert-${serviceName}" =
let let
daysValid = 3650; daysValid = 3650;
@ -64,13 +84,15 @@ in
set -eu set -eu
${pkgs.coreutils}/bin/install -d -m 0755 ${certsDir} ${pkgs.coreutils}/bin/install -d -m 0755 ${certsDir}
${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0755 /persist${certsDir}" else ""}
${pkgs.coreutils}/bin/install -d -m 0750 ${privateDir} ${pkgs.coreutils}/bin/install -d -m 0750 ${privateDir}
${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0750 /persist${privateDir}" else ""}
need_gen=0 need_gen=0
if [ ! -f "${certPath}" ] || [ ! -f "${keyPath}" ]; then if [ ! -f "${certPathBase}" ] || [ ! -f "${keyPathBase}" ]; then
need_gen=1 need_gen=1
else else
enddate="$(${pkgs.openssl}/bin/openssl x509 -noout -enddate -in "${certPath}" | cut -d= -f2)" enddate="$(${pkgs.openssl}/bin/openssl x509 -noout -enddate -in "${certPathBase}" | cut -d= -f2)"
end_epoch="$(${pkgs.coreutils}/bin/date -d "$enddate" +%s)" end_epoch="$(${pkgs.coreutils}/bin/date -d "$enddate" +%s)"
now_epoch="$(${pkgs.coreutils}/bin/date +%s)" now_epoch="$(${pkgs.coreutils}/bin/date +%s)"
seconds_left=$(( end_epoch - now_epoch )) seconds_left=$(( end_epoch - now_epoch ))
@ -92,7 +114,10 @@ in
chown ${serviceUser}:${serviceGroup} "${certPath}" "${keyPath}" chown ${serviceUser}:${serviceGroup} "${certPath}" "${keyPath}"
fi fi
''; '';
deps = [ "etc" ]; deps = [
"etc"
(lib.mkIf config.swarselsystems.isImpermanence "specialfs")
];
}; };
services = { services = {
@ -103,9 +128,9 @@ in
domain = serviceDomain; domain = serviceDomain;
origin = "https://${serviceDomain}"; origin = "https://${serviceDomain}";
# tls_chain = config.sops.secrets.kanidm-self-signed-crt.path; # tls_chain = config.sops.secrets.kanidm-self-signed-crt.path;
tls_chain = certPath; tls_chain = certPathBase;
# tls_key = config.sops.secrets.kanidm-self-signed-key.path; # tls_key = config.sops.secrets.kanidm-self-signed-key.path;
tls_key = keyPath; tls_key = keyPathBase;
bindaddress = "0.0.0.0:${toString servicePort}"; bindaddress = "0.0.0.0:${toString servicePort}";
trust_x_forward_for = true; trust_x_forward_for = true;
}; };

View file

@ -6,7 +6,7 @@ let
serviceName = "kavita"; serviceName = "kavita";
serviceUser = "kavita"; serviceUser = "kavita";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -6,7 +6,7 @@ let
servicePort = 2282; servicePort = 2282;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceDir = "/Vault/data/koillection"; serviceDir = "/Vault/data/koillection";
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
postgresUser = config.systemd.services.postgresql.serviceConfig.User; # postgres postgresUser = config.systemd.services.postgresql.serviceConfig.User; # postgres
postgresPort = config.services.postgresql.settings.port; # 5432 postgresPort = config.services.postgresql.settings.port; # 5432

View file

@ -6,7 +6,7 @@ let
serviceName = "matrix"; serviceName = "matrix";
serviceDomain = config.repo.secrets.common.services.domains.matrix; serviceDomain = config.repo.secrets.common.services.domains.matrix;
serviceUser = "matrix-synapse"; serviceUser = "matrix-synapse";
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
federationPort = 8448; federationPort = 8448;
whatsappPort = 29318; whatsappPort = 29318;

View file

@ -5,7 +5,7 @@ let
serviceGroup = serviceUser; serviceGroup = serviceUser;
serviceName = "grafana"; serviceName = "grafana";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
prometheusPort = 9090; prometheusPort = 9090;
prometheusUser = "prometheus"; prometheusUser = "prometheus";

View file

@ -5,7 +5,7 @@ let
serviceUser = "navidrome"; serviceUser = "navidrome";
serviceGroup = serviceUser; serviceGroup = serviceUser;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@ -41,6 +41,27 @@ in
globals.services.${serviceName}.domain = serviceDomain; globals.services.${serviceName}.domain = serviceDomain;
services.snapserver = {
enable = true;
settings = {
stream = {
port = 1704;
source = "pipe:///tmp/snapfifo?name=default";
bind_to_address = "0.0.0.0";
};
};
};
systemd.services = {
${serviceName}.serviceConfig = {
PrivateDevices = lib.mkForce false;
PrivateUsers = lib.mkForce false;
RestrictRealtime = lib.mkForce false;
SystemCallFilter = lib.mkForce null;
RootDirectory = lib.mkForce null;
};
};
services.${serviceName} = { services.${serviceName} = {
enable = true; enable = true;
openFirewall = true; openFirewall = true;
@ -55,8 +76,9 @@ in
EnableTranscodingConfig = true; EnableTranscodingConfig = true;
Scanner.GroupAlbumReleases = true; Scanner.GroupAlbumReleases = true;
ScanSchedule = "@every 24h"; ScanSchedule = "@every 24h";
MPVPath = "${pkgs.mpv}/bin/mpv"; # MPVPath = "";
MPVCommandTemplate = "mpv --audio-device=%d --no-audio-display --pause %f"; # MPVCommandTemplate = "${pkgs.mpv}/bin/mpv --audio-device=%d --input-ipc-server=%s --no-audio-display --log-file=/tmp/mpv.log --pause %f";
# MPVCmdTemplate = "${pkgs.mpv}/bin/mpv --no-audio-display --pause %f --input-ipc-server=%s --audio-channels=stereo --audio-samplerate=48000 --audio-format=s16 --ao=pcm --ao-pcm-file=/tmp/snapfifo --log-file=/tmp/mpv.log";
ReverseProxyWhitelist = "0.0.0.0/0"; ReverseProxyWhitelist = "0.0.0.0/0";
ReverseProxyUserHeader = "X-User"; ReverseProxyUserHeader = "X-User";
Jukebox = { Jukebox = {

View file

@ -0,0 +1,26 @@
{ lib, config, ... }:
{
options.swarselmodules.server.network = lib.mkEnableOption "enable server network config";
config = lib.mkIf config.swarselmodules.server.network {
globals.networks.home.hosts.${config.node.name} = {
inherit (config.repo.secrets.local.networking.networks.home) id;
mac = config.repo.secrets.local.networking.networks.home.mac or null;
};
globals.hosts.${config.node.name} = {
inherit (config.repo.secrets.local.networking) defaultGateway4;
};
networking = {
inherit (config.repo.secrets.local.networking) hostId;
hostName = config.node.name;
nftables.enable = lib.mkDefault false;
enableIPv6 = lib.mkDefault true;
firewall = {
enable = lib.mkDefault true;
};
};
};
}

View file

@ -8,7 +8,9 @@ let
serviceGroup = serviceUser; serviceGroup = serviceUser;
serviceName = "nextcloud"; serviceName = "nextcloud";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
nextcloudVersion = "32";
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@ -29,7 +31,7 @@ in
trusted_proxies = [ "0.0.0.0" ]; trusted_proxies = [ "0.0.0.0" ];
overwriteprotocol = "https"; overwriteprotocol = "https";
}; };
package = pkgs.nextcloud31; package = pkgs."nextcloud${nextcloudVersion}";
hostName = serviceDomain; hostName = serviceDomain;
home = "/Vault/data/${serviceName}"; home = "/Vault/data/${serviceName}";
datadir = "/Vault/data/${serviceName}"; datadir = "/Vault/data/${serviceName}";
@ -37,7 +39,7 @@ in
configureRedis = true; configureRedis = true;
maxUploadSize = "4G"; maxUploadSize = "4G";
extraApps = { extraApps = {
inherit (pkgs.nextcloud31Packages.apps) mail calendar contacts cospend phonetrack polls tasks sociallogin; inherit (pkgs."nextcloud${nextcloudVersion}Packages".apps) mail calendar contacts cospend phonetrack polls tasks sociallogin;
}; };
extraAppsEnable = true; extraAppsEnable = true;
config = { config = {

View file

@ -3,9 +3,60 @@ let
inherit (config.repo.secrets.common) dnsProvider; inherit (config.repo.secrets.common) dnsProvider;
inherit (config.repo.secrets.common.mail) address3; inherit (config.repo.secrets.common.mail) address3;
serviceUser = "nginx";
serviceGroup = serviceUser;
sslBasePath = "/etc/ssl";
dhParamsPathBase = "${sslBasePath}/dhparams.pem";
dhParamsPath =
if config.swarselsystems.isImpermanence then
"/persist/${dhParamsPathBase}"
else
"${dhParamsPathBase}";
in in
{ {
options.swarselmodules.server.nginx = lib.mkEnableOption "enable nginx on server"; options.swarselmodules.server.nginx = lib.mkEnableOption "enable nginx on server";
options.services.nginx = {
recommendedSecurityHeaders = lib.mkEnableOption "additional security headers by default in each location block.";
virtualHosts = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule {
options.locations = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule (submod: {
options = {
recommendedSecurityHeaders = lib.mkOption {
type = lib.types.bool;
default = config.services.nginx.recommendedSecurityHeaders;
description = "Whether to add additional security headers to this location.";
};
X-Frame-Options = lib.mkOption {
type = lib.types.str;
default = "DENY";
description = "The value to use for X-Frame-Options";
};
};
config = lib.mkIf submod.config.recommendedSecurityHeaders {
extraConfig = lib.mkBefore ''
# Enable HTTP Strict Transport Security (HSTS)
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
# Minimize information leaked to other domains
add_header Referrer-Policy "origin-when-cross-origin";
add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options "${submod.config.X-Frame-Options}";
add_header X-Content-Type-Options "nosniff";
'';
};
})
);
};
}
);
};
};
config = lib.mkIf config.swarselmodules.server.nginx { config = lib.mkIf config.swarselmodules.server.nginx {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
lego lego
@ -18,23 +69,67 @@ in
''; '';
}; };
users.groups.acme.members = [ "nginx" ];
security.acme = { security.acme = {
acceptTerms = true; acceptTerms = true;
defaults = { defaults = {
inherit dnsProvider; inherit dnsProvider;
email = address3; email = address3;
environmentFile = "${config.sops.templates."certs.secret".path}"; environmentFile = "${config.sops.templates."certs.secret".path}";
reloadServices = [ "nginx" ];
dnsPropagationCheck = true;
}; };
}; };
networking.firewall.allowedTCPPorts = [ 80 443 ];
environment.persistence."/persist" = lib.mkIf config.swarselsystems.isImpermanence {
files = [ dhParamsPathBase ];
};
services.nginx = { services.nginx = {
enable = true; enable = true;
user = serviceUser;
group = serviceGroup;
statusPage = true; statusPage = true;
recommendedProxySettings = true; recommendedProxySettings = true;
recommendedTlsSettings = true; recommendedTlsSettings = true;
recommendedOptimisation = true; recommendedOptimisation = true;
recommendedGzipSettings = true; recommendedGzipSettings = true;
# virtualHosts are defined in the respective sections recommendedBrotliSettings = true;
recommendedSecurityHeaders = true;
sslCiphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:!aNULL";
sslDhparam = dhParamsPathBase;
virtualHosts.fallback = {
default = true;
rejectSSL = true;
locations."/".extraConfig = ''
deny all;
'';
};
};
system.activationScripts."createPersistentStorageDirs" = lib.mkIf config.swarselsystems.isImpermanence {
deps = [ "generateDHParams" "users" "groups" ];
};
system.activationScripts."generateDHParams" =
{
text = ''
set -eu
${pkgs.coreutils}/bin/install -d -m 0755 ${sslBasePath}
${if config.swarselsystems.isImpermanence then "${pkgs.coreutils}/bin/install -d -m 0755 /persist${sslBasePath}" else ""}
if [ ! -f "${dhParamsPathBase}" ]; then
${pkgs.openssl}/bin/openssl dhparam -out ${dhParamsPath} 4096
chmod 0644 ${dhParamsPath}
chown ${serviceUser}:${serviceGroup} ${dhParamsPath}
fi
'';
deps = [
"etc"
(lib.mkIf config.swarselsystems.isImpermanence "specialfs")
];
}; };
}; };
} }

View file

@ -7,7 +7,7 @@ let
serviceGroup = serviceUser; serviceGroup = serviceUser;
serviceName = "paperless"; serviceName = "paperless";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
tikaPort = 9998; tikaPort = 9998;
gotenbergPort = 3002; gotenbergPort = 3002;

View file

@ -7,7 +7,7 @@ let
serviceUser = "radicale"; serviceUser = "radicale";
serviceGroup = serviceUser; serviceGroup = serviceUser;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName}; serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4; serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
cfg = config.services.${serviceName}; cfg = config.services.${serviceName};
in in

View file

@ -0,0 +1,56 @@
{ lib, config, ... }:
let
serviceName = "router";
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
systemd.network = {
wait-online.anyInterface = true;
networks = {
"30-lan0" = {
matchConfig.Name = "lan0";
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
ConfigureWithoutCarrier = true;
};
};
"30-lan1" = {
matchConfig.Name = "lan1";
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
ConfigureWithoutCarrier = true;
};
};
"30-lan2" = {
matchConfig.Name = "lan2";
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
ConfigureWithoutCarrier = true;
};
};
"30-lan3" = {
matchConfig.Name = "lan3";
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
ConfigureWithoutCarrier = true;
};
};
"10-wan" = {
matchConfig.Name = "wan";
networkConfig = {
# start a DHCP Client for IPv4 Addressing/Routing
DHCP = "ipv4";
DNSOverTLS = true;
DNSSEC = true;
IPv6PrivacyExtensions = false;
IPForward = true;
};
# make routing on this interface a dependency for network-online.target
linkConfig.RequiredForOnline = "routable";
};
};
};
};
}

View file

@ -16,6 +16,7 @@ in
environment.shellAliases = lib.recursiveUpdate environment.shellAliases = lib.recursiveUpdate
{ {
nswitch = "cd ${flakePath}; swarsel-deploy $(hostname) switch; cd -;"; nswitch = "cd ${flakePath}; swarsel-deploy $(hostname) switch; cd -;";
ntest = "cd ${flakePath}; swarsel-deploy $(hostname) test; cd -;";
nboot = "cd ${flakePath}; swarsel-deploy $(hostname) boot; cd -;"; nboot = "cd ${flakePath}; swarsel-deploy $(hostname) boot; cd -;";
ndry = "cd ${flakePath}; swarsel-deploy $(hostname) dry-activate; cd -;"; ndry = "cd ${flakePath}; swarsel-deploy $(hostname) dry-activate; cd -;";
} }

Some files were not shown because too many files have changed in this diff Show more