Compare commits

..

123 Commits

Author SHA1 Message Date
820bb2de5b lib: River IP update
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h4m34s
Installer / Build installer (push) Successful in 5m54s
2025-01-01 19:14:04 +00:00
7d3ad52a44 devshell: Add git config safe.directory for build-n-switch
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h2m7s
2024-12-23 10:32:13 +00:00
2cdb98e898 nixos/common: Disable channels
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 53m0s
2024-12-12 12:38:01 +00:00
b717b1ceb4 nixos/gui: Add /dev/player0 VID
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h1m16s
2024-12-11 17:17:33 +00:00
f31ce61c2b Update borgthin
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 2h31m34s
2024-11-30 19:31:58 +00:00
aec22942f7 Update latest Linux kernel to 6.12 2024-11-30 19:31:43 +00:00
fc8676c3bb devshell: Remove deprecated Nix command stuff 2024-11-30 19:19:23 +00:00
2915e42a1d ci: Group CI jobs
Some checks failed
CI / Check, build and cache nixfiles (push) Failing after 33m39s
2024-11-30 18:05:22 +00:00
5783d3a51e Update nixpkgs-stable to 24.11 2024-11-30 17:45:59 +00:00
2fe94bba23 nixos/git: Add longer timeout for Gitea actions runner
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 2h29m25s
2024-11-27 12:29:04 +00:00
4b42960d26 home-manager/gui: Update alacritty import setting to new section
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 3h1m26s
2024-11-26 23:19:58 +00:00
56e9abf945 ci: Build and grab path for jobs in separate calls
Some checks failed
CI / Check, build and cache Nix flake (push) Has been cancelled
The old build-n-parse seemed to output null sometimes.....
2024-11-26 22:45:19 +00:00
4e2c2f92f0 nixos/middleman: Remove config for Matrix sliding sync proxy
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 6m29s
2024-11-26 22:15:53 +00:00
caa208b288 nixos/netboot: Use older version of iPXE for now
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 6m33s
2024-11-26 22:01:42 +00:00
9e6f885c17 ci: Tweak log messages 2024-11-26 22:00:17 +00:00
d8ca87bfd8 pkgs: Remove glfw-wayland-minecraft
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 6m15s
2024-11-26 21:23:50 +00:00
e9467e0cc7 ci: Build and cache CI jobs individually
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 6m27s
2024-11-26 12:37:47 +00:00
6c98ef8944 Revert "nixos/home/routing-common: Move Tailscale to home routers"
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 1h15m14s
This reverts commit 7c05b6158f.
2024-11-26 00:04:43 +00:00
18981e240b nixos/nvme: Update to libnvme v1.11.1 to fix LTS kernels 2024-11-25 23:58:15 +00:00
df7e5953eb Update nixpkgs-unstable (and other inputs)
Some checks failed
CI / Check, build and cache Nix flake (push) Has been cancelled
2024-11-25 23:10:24 +00:00
71d1c3f9c2 Ensure borgbackup cache / config is persisted
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 32m28s
2024-11-16 18:46:09 +00:00
1453a755c3 Add (now unused) Enshrouded server 2024-11-16 18:08:10 +00:00
970af805e9 home-manager/gui: Swap swaysome container binds
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 23m18s
2024-11-08 11:47:35 +00:00
383e9a9b1e home-manager/gui: Add swaysome
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 23m43s
2024-11-07 18:21:09 +00:00
26a16d0629 home-manager/gui: Disable ligatures in kitty
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 29m30s
2024-11-06 13:16:56 +00:00
208de7654e home-manager/gui: Use rofi-wayland 2024-11-06 13:16:51 +00:00
f577e7d58a nixos/routing-common: Increase bandwidth for CAKE
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 28m44s
2024-10-31 22:27:55 +00:00
6130ee73be nixos/tower: Add brightness keybinds
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 29m59s
2024-10-26 20:24:27 +01:00
5d827aa00c home-manager/gui: Add xdg-utils to home.packages 2024-10-26 18:32:24 +01:00
173ffc0044 home-manager/gui: Add "Activate Linux" watermark
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 30m5s
2024-10-16 11:32:14 +01:00
b113f2f48d home-manager/gui: Add Git LFS
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 28m47s
2024-09-04 21:53:26 +01:00
7c67eaff21 nixos/colony: Add qclk management container
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 34m42s
2024-09-01 19:22:03 +01:00
d1f1b84e82 Use fork of ragenix 2024-09-01 14:03:27 +01:00
e3cb2adbb6 nixos/castle: Add recursive-nix feature 2024-09-01 14:03:05 +01:00
736c406eb5 Update nixpkgs-mine for mautrix-whatsapp 0.10.9
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 27m54s
2024-08-26 11:59:28 +01:00
8e9b750ac8 nixos: Set up remote printing
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 27m42s
2024-08-20 10:36:21 +01:00
51c5578840 nixos/stream: Add OctoPrint
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 2m16s
2024-08-20 01:03:49 +01:00
e174af45f6 nixos/castle: Emulate ARM 2024-08-17 12:39:36 +01:00
198e7188bd home-manager/gui: Use upstream unstable nixpkgs' chromium
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 27m18s
2024-08-13 12:15:33 +01:00
571f8f1504 home-manager/gui: Add xournalpp
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 18m42s
2024-07-31 11:28:24 +01:00
64c3fe682c nixos/home/routing-common: Only run Tailscale on active router
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 26m33s
2024-07-31 10:20:19 +01:00
7c05b6158f nixos/home/routing-common: Move Tailscale to home routers
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 18m12s
2024-07-22 16:22:08 +01:00
c9ab90547f Fix installer workflow short rev
Some checks failed
Installer / Build installer (push) Successful in 4m23s
CI / Check, build and cache Nix flake (push) Has been cancelled
2024-07-21 13:01:03 +01:00
63d929c8e8 nixos: Include mutable flake in every system
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 17m41s
Installer / Build installer (push) Successful in 4m20s
2024-07-21 12:37:32 +01:00
bbb87a2d69 devshell: Add deploy-multi command
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 17m26s
2024-07-21 00:33:16 +01:00
e5d5847b89 nixos/middleman: Disable zstd in nginx for now
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 25m3s
2024-07-20 22:41:01 +01:00
9e7294e871 nixos/shill: Rename atticd mount to harmonia 2024-07-20 21:19:25 +01:00
69216c6b4c Use harmonia instead of attic for binary cache
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 2h1m7s
2024-07-20 19:04:51 +01:00
1ea172e690 nixos/vaultwarden: Use non-privileged port
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 18m41s
2024-07-19 18:06:14 +01:00
b7be45715e nixos/britway: Update headscale config
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 14m11s
2024-07-15 22:58:49 +01:00
3522a7078b Re-update nixpkgs 2024-07-15 22:58:42 +01:00
b44f0e74e8 Disable modrinth-app 2024-07-15 00:25:05 +01:00
7c57f00b27 nixos/britway: Update Headscale
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 2h14m36s
2024-07-14 22:04:03 +01:00
c9d36ec65b home-manager/gui: New cursor theme
Some checks failed
CI / Check, build and cache Nix flake (push) Has been cancelled
2024-07-14 21:49:37 +01:00
d8f97b9316 Update inputs 2024-07-14 21:21:43 +01:00
d5bb2f6787 nixos/routing-common: Start / stop radvd only for IPv6
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 16m56s
2024-07-11 00:16:33 +01:00
ced82fc002 Update river public IP
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 17m47s
2024-07-10 20:26:38 +01:00
3535d2fd90 nixos/shill: Use MemoryMax instead of MemoryMin
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 17m4s
2024-07-07 12:02:50 +01:00
4e207c3397 nixos/colony: Disable KSM for now 2024-07-07 11:57:45 +01:00
bc4e75a6a5 nixos/middleman: Fix Element config.json
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 17m37s
2024-07-05 16:30:34 +01:00
2ae922f3e8 home-manager/gui: Adjust brightness for wallpapers
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 17m51s
2024-07-04 18:07:41 +01:00
f263fdca3e nixos/castle: Add left monitor wallpaper
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 18m6s
2024-07-02 22:22:10 +01:00
1232e9cb30 Update nixpkgs
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 49m21s
2024-07-02 12:07:52 +01:00
fbb29162ca nixos/colony: Enable KSM 2024-07-01 14:43:07 +01:00
7ab57a12b7 Reduce core count for CI
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 1h27m30s
Installer / Build installer (push) Successful in 4m44s
2024-06-30 15:02:21 +01:00
4e947d4b1e nixos/unifi: Set up UniFi controller
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 40m53s
2024-06-30 12:21:21 +01:00
b68e82ae03 nixos: Move castle to home
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 42m12s
2024-06-30 04:01:56 +01:00
91489551b9 nixos: Working castle NVMe-oF root 2024-06-30 03:59:46 +01:00
86c99c2cbb nixos/build: Add Intel NIC drivers and increased timeout 2024-06-30 03:38:48 +01:00
7e2dfc21c6 nixos/sfh: Working containers
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 44m19s
2024-06-30 01:52:52 +01:00
9ac63220d5 nixos/installer: Add NFS client
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 42m53s
Installer / Build installer (push) Successful in 5m15s
2024-06-30 00:07:12 +01:00
ffa5d19854 home-manager/common: Add nix-tree package
Some checks failed
Installer / Build installer (push) Has been cancelled
CI / Check, build and cache Nix flake (push) Has been cancelled
2024-06-29 23:42:31 +01:00
19fb29213e nixos/netboot: Mount /boot via kernel command line 2024-06-29 23:41:01 +01:00
f9870abc9e Working "shill From Home" full network boot 2024-06-29 23:12:21 +01:00
84ca556c47 nixos: Initial netbooting installer
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 34m36s
Installer / Build installer (push) Successful in 4m34s
2024-06-24 00:42:26 +01:00
9f2651e352 nixos/installer: Disable GUI stuff 2024-06-23 19:00:29 +01:00
bce876ec42 Add release token to installer workflow
Some checks failed
CI / Check, build and cache Nix flake (push) Has been cancelled
Installer / Build installer (push) Successful in 6m0s
2024-06-22 16:24:30 +01:00
bc8adcecad Update river public IP 2024-06-22 15:26:48 +01:00
8878ce56c4 nixos/kelder: MTU fix + disable all local redirects
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 33m1s
2024-06-21 21:42:17 +01:00
dd9439b7fa nixos/shill: Add jam container
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 33m30s
2024-06-20 23:43:07 +01:00
bc9f266ef0 nixos/containers: Remove workaround for systemd-nspawn@ drop-in 2024-06-20 23:37:43 +01:00
1b083d298b nixos/castle: Re-add boardie
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 32m55s
2024-06-18 23:29:48 +01:00
83ba26735e nixos/colony: Add extra disk to darts VM
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 6m28s
2024-06-15 20:05:27 +01:00
50bd96ccdf nixos/chatterbox: Add ffmpeg to mautrix bridges
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 32m8s
2024-06-10 13:27:02 +01:00
a133cfb189 nixos/installer: Use my nixpkgs
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 33m39s
2024-06-09 01:49:18 +01:00
051e68254e nixos/chatterbox: Add Instagram bridge 2024-06-09 01:46:00 +01:00
3fa8ab43ef nixos/chatterbox: Add Messenger bridge 2024-06-08 23:08:27 +01:00
c6720f87c1 nixos/chatterbox: Add WhatsApp bridge 2024-06-08 22:16:02 +01:00
55ecdddadb home-manager/gui: Fix screensaver top output, add cowsay to fortune
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 1m20s
2024-06-07 16:45:35 +01:00
9b5173a587 home-manager/gui: More screensavers and options
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 1m5s
2024-06-07 15:27:20 +01:00
73f5a690bb home-manager/gui: Add cmatrix and TTE screensavers
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 1m23s
2024-06-07 03:11:55 +01:00
54db751e23 pkgs: Add terminaltexteffects 2024-06-07 02:36:12 +01:00
85299b65dc home-manager/gui: Working randomised doomsaver 2024-06-07 02:26:27 +01:00
45bda5b588 pkgs/chocolate-doom2xx: Add -demoloopi flag
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 32m58s
2024-06-06 14:39:09 +01:00
9114f5ce74 home-manager/gui: Add Doom lock screen
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 33m7s
2024-06-06 02:30:22 +01:00
3925c1090e pkgs: Add window2layer and swaylock-plugin 2024-06-06 02:08:35 +01:00
e74538a1a9 pkgs: Add chocolate-doom2xx 2024-06-06 02:02:28 +01:00
b8ee21b6e8 nixos/home/routing-common: More Disney+ IPv6 workarounds 2024-06-05 20:21:48 +01:00
41fd54cfad nixos/whale2: Update to netavark backend
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 31m25s
2024-06-03 18:29:36 +01:00
1df34e0515 lib: Update latest kernel
Some checks failed
CI / Check, build and cache Nix flake (push) Successful in 33m0s
Installer / Build installer (push) Failing after 5m31s
2024-06-01 17:21:27 +01:00
ce0c194761 Update all inputs (JackOS 24.06 "Carbrain")
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 32m36s
2024-06-01 14:30:35 +01:00
a5e51ddd6b nixos/home: Filter out Disney+ IPv6 DNS queries
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 36m4s
2024-05-16 21:05:48 +01:00
746e0b9dc4 nixos/castle: Fix PipeWire latency config
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 58s
2024-05-11 16:10:15 +01:00
77600a64fc nixos/gui: Add udev rules for FT
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 34m43s
2024-05-11 00:46:13 +01:00
c6d5705097 nixos/jackflix: Add PhotoPrism
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 34m59s
2024-05-06 00:57:52 +01:00
6eefe97764 lib: Update river public IP
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 35m59s
2024-04-13 15:04:52 +01:00
4bc4fe3ee8 Update my nixpkgs (spdk 24.01) 2024-04-13 15:02:54 +01:00
57ec2bfc1b nixos/home/routing-common: Make keepalived ping more resilient
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 33m37s
2024-04-05 15:22:10 +01:00
d9d1150feb Update nixpkgs and home-manager
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 1h21m12s
2024-04-04 19:08:12 +01:00
92896d8e52 nixos/stream: Un-hardcode deploy host
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 35m24s
2024-03-25 11:20:58 +00:00
477ffca33e nixos/common: Update registry to point to nixpkgs flake 2024-03-25 11:17:30 +00:00
fdc65c544e nixos/home/routing-common: Add ping test to keepalived
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 35m51s
2024-03-24 13:32:03 +00:00
945302b7c0 lib: Update river IP 2024-03-24 12:45:43 +00:00
5ccf19cab8 nixos/colony: Fix LVM activatio dependency cycle
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 35m28s
2024-03-23 13:25:32 +00:00
7b61dd7f03 nixos/colony: Enable PCIe AER 2024-03-23 12:45:59 +00:00
682865a0e1 nixos/l2mesh: Add option to enable UDP encapsulation 2024-03-23 12:14:26 +00:00
a0e4cf2479 lib: Bump JackOS version
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 24m28s
2024-03-22 21:23:18 +00:00
a5880d66f4 home-manager/gui: Use python3Packages instead of python310Packages
All checks were successful
CI / Check, build and cache Nix flake (push) Successful in 1h12m52s
2024-03-21 23:32:01 +00:00
27a4583879 pkgs/modrinth-app: Fix deps hash
Some checks failed
CI / Check, build and cache Nix flake (push) Has been cancelled
2024-03-21 23:10:42 +00:00
fdbf5f8aca lib: Update river IP 2024-03-21 21:16:01 +00:00
40c491aa14 nixos/home/routing-common: Add MSS clamping to work around PMTUD
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 1h4m53s
2024-03-21 20:42:06 +00:00
1a8740fb9c nixos/home/routing-common: Increase RTT for CAKE 2024-03-21 20:41:28 +00:00
f857e751b5 nixos/home/routing-common: Restart kea on failure 2024-03-21 20:40:38 +00:00
155 changed files with 4306 additions and 3960 deletions

View File

@@ -6,11 +6,11 @@ on:
jobs:
check:
name: Check, build and cache Nix flake
name: Check, build and cache nixfiles
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v23
- uses: cachix/install-nix-action@v27
with:
# Gitea will supply a token in GITHUB_TOKEN, which this action will
# try to pass to Nix when downloading from GitHub
@@ -18,22 +18,30 @@ jobs:
extra_nix_config: |
# Make sure we're using sandbox
sandbox-fallback = false
# Big C++ projects fill up memory...
cores = 6
extra-substituters = https://nix-cache.nul.ie/main
extra-trusted-public-keys = main:mMChkG8LwXrFirVfudqjSHasK1jV31OVElYD3eImYl8=
- name: Set up attic
run: |
nix run .#nixpkgs.mine.x86_64-linux.attic-client -- \
login --set-default colony https://nix-cache.nul.ie "${{ secrets.NIX_CACHE_TOKEN }}"
extra-substituters = https://nix-cache.nul.ie
extra-trusted-public-keys = nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4=
- name: Check flake
run: nix flake check
- name: Build the world
run: nix flake check --no-build
- name: Build (and cache) the world
id: build
env:
HARMONIA_SSH_KEY: ${{ secrets.HARMONIA_SSH_KEY }}
run: |
path=$(nix build --no-link .#ci.x86_64-linux --json | jq -r .[0].outputs.out)
echo "path=$path" >> "$GITHUB_OUTPUT"
- name: Push to cache
run: |
nix run .#nixpkgs.mine.x86_64-linux.attic-client -- \
push main ${{ steps.build.outputs.path }}
nix eval --json --apply "builtins.attrNames" .#ci.x86_64-linux | jq -cr '.[]' | while read job; do
echo "::group::Build $job"
nix build --no-link .#ci.x86_64-linux."$job"
echo "::endgroup::"
echo "::group::Cache $job"
ci/push-to-cache.sh "$(nix eval --raw .#ci.x86_64-linux."$job")"
echo "::endgroup::"
done
echo "Building and caching CI derivation"
nix build --no-link .#ciDrv.x86_64-linux
UPDATE_PROFILE=1 ci/push-to-cache.sh "$(nix eval --raw .#ciDrv.x86_64-linux)"

View File

@@ -14,22 +14,20 @@ jobs:
uses: https://github.com/actions/setup-go@v4
with:
go-version: '>=1.20.1'
- uses: cachix/install-nix-action@v23
- uses: cachix/install-nix-action@v27
with:
github_access_token: ${{ secrets.GH_PULL_TOKEN }}
extra_nix_config: |
# Make sure we're using sandbox
sandbox-fallback = false
extra-substituters = https://nix-cache.nul.ie/main
extra-trusted-public-keys = main:mMChkG8LwXrFirVfudqjSHasK1jV31OVElYD3eImYl8=
- name: Set up attic
extra-substituters = https://nix-cache.nul.ie
extra-trusted-public-keys = nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4=
- name: Set up vars
id: setup
run: |
nix run .#nixpkgs.mine.x86_64-linux.attic-client -- \
login --set-default colony https://nix-cache.nul.ie "${{ secrets.NIX_CACHE_TOKEN }}"
echo "short_rev=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
- name: Build installer ISO
run: |
nix build .#nixfiles.config.nixos.systems.installer.configuration.config.my.buildAs.iso
@@ -39,12 +37,13 @@ jobs:
run: |
nix build .#nixfiles.config.nixos.systems.installer.configuration.config.my.buildAs.netbootArchive
ln -s "$(readlink result)" \
jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar
jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar.zst
- name: Create release
uses: https://gitea.com/actions/release-action@main
with:
title: Latest installer
api_key: '${{ secrets.RELEASE_TOKEN }}'
files: |
jackos-installer-${{ steps.setup.outputs.short_rev }}.iso
jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar
jackos-installer-netboot-${{ steps.setup.outputs.short_rev }}.tar.zst

1
.keys/harmonia.pub Normal file
View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKXRXkYnBf2opIjN+bXE7HmhUpa4hyXJUGmBT+MRccT4 harmonia

1
ci/known_hosts Normal file
View File

@@ -0,0 +1 @@
object-ctr.ams1.int.nul.ie ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdHbZErWLmTPO/aEWB1Fup/aGMf31Un5Wk66FJwTz/8

31
ci/push-to-cache.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/bin/sh
set -e
REMOTE_STORE=/var/lib/harmonia
SSH_HOST="harmonia@object-ctr.ams1.int.nul.ie"
SSH_KEY=/tmp/harmonia.key
STORE_URI="ssh-ng://$SSH_HOST?ssh-key=$SSH_KEY&remote-store=$REMOTE_STORE"
remote_cmd() {
ssh -i "$SSH_KEY" "$SSH_HOST" env HOME=/run/harmonia NIX_REMOTE="$REMOTE_STORE" "$@"
}
umask_old=$(umask)
umask 0066
echo "$HARMONIA_SSH_KEY" | base64 -d > "$SSH_KEY"
umask $umask_old
mkdir -p ~/.ssh
cp ci/known_hosts ~/.ssh/
path="$1"
echo "Pushing $path to cache..."
nix copy --no-check-sigs --to "$STORE_URI" "$path"
if [ -n "$UPDATE_PROFILE" ]; then
echo "Updating profile..."
remote_cmd nix-env -p "$REMOTE_STORE"/nix/var/nix/profiles/nixfiles --set "$path"
echo "Collecting garbage..."
remote_cmd nix-collect-garbage --delete-older-than 60d
fi

View File

@@ -52,7 +52,7 @@ in
name = "json2nix";
category = "utilities";
help = "Convert JSON to formatted Nix";
command = "nix eval --impure --expr 'builtins.fromJSON (builtins.readFile /dev/stdin)' | ${pkgs.nixfmt}/bin/nixfmt";
command = "nix eval --impure --expr 'builtins.fromJSON (builtins.readFile /dev/stdin)' | ${pkgs.nixfmt-rfc-style}/bin/nixfmt";
}
{
@@ -77,7 +77,12 @@ in
name = "build-n-switch";
category = "tasks";
help = "Shortcut to nixos-rebuild for this flake";
command = ''doas nixos-rebuild --flake . "$@"'';
command = ''
# HACK: Upstream changes in Git + Nix makes this necessary
# https://github.com/NixOS/nix/issues/10202
doas git config --global --add safe.directory "$PWD"
doas nixos-rebuild --flake . "$@"
'';
}
{
name = "run-vm";
@@ -106,8 +111,8 @@ in
{
name = "build-netboot";
category = "tasks";
help = "Build NixOS configuration as netboot archive";
command = ''nix build "''${@:2}" ".#nixfiles.config.nixos.systems.\"$1\".configuration.config.my.buildAs.netbootArchive"'';
help = "Build NixOS configuration as netboot tree";
command = ''nix build "''${@:2}" ".#nixfiles.config.nixos.systems.\"$1\".configuration.config.my.buildAs.netbootTree"'';
}
{
name = "build-home";
@@ -115,29 +120,17 @@ in
help = "Build home-manager configuration";
command = ''nix build "''${@:2}" ".#homeConfigurations.\"$1\".activationPackage"'';
}
{
name = "update-inputs";
category = "tasks";
help = "Update flake inputs";
command = ''
args=()
for f in "$@"; do
args+=(--update-input "$f")
done
nix flake lock "''${args[@]}"
'';
}
{
name = "update-nixpkgs";
category = "tasks";
help = "Update nixpkgs flake inputs";
command = ''update-inputs nixpkgs-{unstable,stable,mine,mine-stable}'';
command = ''nix flake update nixpkgs-{unstable,stable,mine,mine-stable}'';
}
{
name = "update-home-manager";
category = "tasks";
help = "Update home-manager flake inputs";
command = ''update-inputs home-manager-{unstable,stable}'';
command = ''nix flake update home-manager-{unstable,stable}'';
}
{
name = "update-installer";
@@ -145,5 +138,15 @@ in
help = "Update installer tag (to trigger new release)";
command = ''git tag -f installer && git push -f origin installer'';
}
{
name = "deploy-multi";
category = "tasks";
help = "Deploy multiple flakes at once";
command = ''
for f in $@; do
deploy "$O" $f
done
'';
}
];
}

View File

@@ -11,7 +11,7 @@ in
NIX_USER_CONF_FILES = toString (pkgs.writeText "nix.conf"
''
experimental-features = nix-command flakes ca-derivations repl-flake
experimental-features = nix-command flakes ca-derivations
connect-timeout = 5
fallback = true
${lib.my.c.nix.cache.conf}
@@ -24,10 +24,10 @@ in
coreutils
nixVersions.stable
rage
wireguard-tools
(pkgs.writeShellScriptBin "deploy" ''
exec ${deploy-rs.deploy-rs}/bin/deploy --skip-checks "$@"
'')
home-manager
attic-client
];
}

452
flake.lock generated
View File

@@ -8,14 +8,14 @@
"ragenix",
"nixpkgs"
],
"systems": "systems_6"
"systems": "systems_7"
},
"locked": {
"lastModified": 1707830867,
"narHash": "sha256-PAdwm5QqdlwIqGrfzzvzZubM+FXtilekQ/FA0cI49/o=",
"lastModified": 1723293904,
"narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=",
"owner": "ryantm",
"repo": "agenix",
"rev": "8cb01a0e717311680e0cbca06a76cbceba6f3ed6",
"rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
"type": "github"
},
"original": {
@@ -24,69 +24,43 @@
"type": "github"
}
},
"attic": {
"inputs": {
"crane": "crane",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs-unstable"
],
"nixpkgs-stable": [
"nixpkgs-stable"
]
},
"locked": {
"lastModified": 1707922053,
"narHash": "sha256-wSZjK+rOXn+UQiP1NbdNn5/UW6UcBxjvlqr2wh++MbM=",
"owner": "zhaofengli",
"repo": "attic",
"rev": "6eabc3f02fae3683bffab483e614bebfcd476b21",
"type": "github"
},
"original": {
"owner": "zhaofengli",
"repo": "attic",
"type": "github"
}
},
"boardie": {
"inputs": {
"devshell": "devshell",
"flake-utils": "flake-utils_3",
"flake-utils": "flake-utils_2",
"nixpkgs": [
"nixpkgs-unstable"
],
"poetry2nix": "poetry2nix"
},
"locked": {
"lastModified": 1682289679,
"narHash": "sha256-DbhSJ6y62VAO2VsJwoz3VsxCEP/4KMeFVs0wIz6Im04=",
"owner": "devplayer0",
"repo": "boardie",
"rev": "e4b977f75bf7b4f656a691efca492ae057672a77",
"type": "github"
"lastModified": 1718746012,
"narHash": "sha256-sp9vGl3vWXvD/C2JeMDi5nbW6CkKIC3Q2JMGKwexYEs=",
"ref": "refs/heads/master",
"rev": "ea24100bd4a914b9e044a2085a3785a6bd3a3833",
"revCount": 5,
"type": "git",
"url": "https://git.nul.ie/dev/boardie"
},
"original": {
"owner": "devplayer0",
"repo": "boardie",
"type": "github"
"type": "git",
"url": "https://git.nul.ie/dev/boardie"
}
},
"borgthin": {
"inputs": {
"devshell": "devshell_2",
"flake-utils": "flake-utils_6",
"flake-utils": "flake-utils_5",
"nixpkgs": [
"nixpkgs-mine"
]
},
"locked": {
"lastModified": 1692446555,
"narHash": "sha256-Uzl8TiGKVBCjwYhkprSwbcu8xlcQwnDNIqsk9rM+P9w=",
"lastModified": 1732994213,
"narHash": "sha256-3v8cTsPB+TIdWmc1gmRNd0Mi0elpfi39CXRsA/2x/Oo=",
"owner": "devplayer0",
"repo": "borg",
"rev": "44a3dc19b014ebc8d33db0b3e145ed7bfc9a0cb7",
"rev": "795f5009445987d42f32de1b49fdeb2d88326a64",
"type": "github"
},
"original": {
@@ -96,39 +70,12 @@
}
},
"crane": {
"inputs": {
"nixpkgs": [
"attic",
"nixpkgs"
]
},
"locked": {
"lastModified": 1702918879,
"narHash": "sha256-tWJqzajIvYcaRWxn+cLUB9L9Pv4dQ3Bfit/YjU5ze3g=",
"lastModified": 1725409566,
"narHash": "sha256-PrtLmqhM6UtJP7v7IGyzjBFhbG4eOAHT6LPYOFmYfbk=",
"owner": "ipetkov",
"repo": "crane",
"rev": "7195c00c272fdd92fc74e7d5a0a2844b9fadb2fb",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"crane_2": {
"inputs": {
"nixpkgs": [
"ragenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1708794349,
"narHash": "sha256-jX+B1VGHT0ruHHL5RwS8L21R6miBn4B6s9iVyUJsJJY=",
"owner": "ipetkov",
"repo": "crane",
"rev": "2c94ff9a6fbeb9f3ea0107f28688edbe9c81deaa",
"rev": "7e4586bad4e3f8f97a9271def747cf58c4b68f3c",
"type": "github"
},
"original": {
@@ -162,18 +109,18 @@
},
"deploy-rs": {
"inputs": {
"flake-compat": "flake-compat_2",
"flake-compat": "flake-compat",
"nixpkgs": [
"nixpkgs-unstable"
],
"utils": "utils"
},
"locked": {
"lastModified": 1708091384,
"narHash": "sha256-dTGGw2y8wvfjr+J9CjQbfdulOq72hUG17HXVNxpH1yE=",
"lastModified": 1727447169,
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "0a0187794ac7f7a1e62cda3dabf8dc041f868790",
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
"type": "github"
},
"original": {
@@ -184,15 +131,15 @@
},
"devshell": {
"inputs": {
"flake-utils": "flake-utils_2",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1678957337,
"narHash": "sha256-Gw4nVbuKRdTwPngeOZQOzH/IFowmz4LryMPDiJN/ah4=",
"lastModified": 1717408969,
"narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=",
"owner": "numtide",
"repo": "devshell",
"rev": "3e0e60ab37cd0bf7ab59888f5c32499d851edb47",
"rev": "1ebbe68d57457c8cae98145410b164b5477761f4",
"type": "github"
},
"original": {
@@ -203,7 +150,7 @@
},
"devshell-tools": {
"inputs": {
"flake-utils": "flake-utils_11",
"flake-utils": "flake-utils_9",
"nixpkgs": "nixpkgs_4"
},
"locked": {
@@ -222,7 +169,7 @@
},
"devshell_2": {
"inputs": {
"flake-utils": "flake-utils_5",
"flake-utils": "flake-utils_4",
"nixpkgs": "nixpkgs_3"
},
"locked": {
@@ -241,17 +188,16 @@
},
"devshell_3": {
"inputs": {
"flake-utils": "flake-utils_7",
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1710156081,
"narHash": "sha256-4PMY6aumJi5dLFjBzF5O4flKXmadMNq3AGUHKYfchh0=",
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"owner": "numtide",
"repo": "devshell",
"rev": "bc68b058dc7e6d4d6befc4ec6c60082b6e844b7d",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"type": "github"
},
"original": {
@@ -261,22 +207,6 @@
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1696426674,
@@ -293,12 +223,15 @@
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
@@ -309,7 +242,7 @@
},
"flake-utils_10": {
"inputs": {
"systems": "systems_7"
"systems": "systems_10"
},
"locked": {
"lastModified": 1705309234,
@@ -326,42 +259,6 @@
}
},
"flake-utils_11": {
"inputs": {
"systems": "systems_8"
},
"locked": {
"lastModified": 1709126324,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_12": {
"inputs": {
"systems": "systems_9"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_13": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
@@ -377,12 +274,15 @@
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
@@ -393,14 +293,14 @@
},
"flake-utils_3": {
"inputs": {
"systems": "systems"
"systems": "systems_3"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
@@ -410,24 +310,6 @@
}
},
"flake-utils_4": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_5": {
"locked": {
"lastModified": 1642700792,
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
@@ -442,7 +324,7 @@
"type": "github"
}
},
"flake-utils_6": {
"flake-utils_5": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
@@ -457,16 +339,31 @@
"type": "github"
}
},
"flake-utils_7": {
"flake-utils_6": {
"inputs": {
"systems": "systems_4"
"systems": "systems_6"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_7": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
@@ -477,14 +374,14 @@
},
"flake-utils_8": {
"inputs": {
"systems": "systems_5"
"systems": "systems_8"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
@@ -494,12 +391,15 @@
}
},
"flake-utils_9": {
"inputs": {
"systems": "systems_9"
},
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"lastModified": 1709126324,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
"type": "github"
},
"original": {
@@ -537,16 +437,16 @@
]
},
"locked": {
"lastModified": 1706981411,
"narHash": "sha256-cLbLPTL1CDmETVh4p0nQtvoF+FSEjsnJTFpTxhXywhQ=",
"lastModified": 1732466619,
"narHash": "sha256-T1e5oceypZu3Q8vzICjv1X/sGs9XfJRMW5OuXHgpB3c=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "652fda4ca6dafeb090943422c34ae9145787af37",
"rev": "f3111f62a23451114433888902a55cf0692b408d",
"type": "github"
},
"original": {
"id": "home-manager",
"ref": "release-23.11",
"ref": "release-24.11",
"type": "indirect"
}
},
@@ -557,11 +457,11 @@
]
},
"locked": {
"lastModified": 1710714957,
"narHash": "sha256-eZCxuF58YWgaJMMRrn8oRkwRhxooe5kBS/s2wRVr9PA=",
"lastModified": 1732884235,
"narHash": "sha256-r8j6R3nrvwbT1aUp4EPQ1KC7gm0pu9VcV1aNaB+XG6Q=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "7b3fca5adcf6c709874a8f2e0c364fe9c58db989",
"rev": "819f682269f4e002884702b87e445c82840c68f2",
"type": "github"
},
"original": {
@@ -571,11 +471,11 @@
},
"impermanence": {
"locked": {
"lastModified": 1708968331,
"narHash": "sha256-VUXLaPusCBvwM3zhGbRIJVeYluh2uWuqtj4WirQ1L9Y=",
"lastModified": 1731242966,
"narHash": "sha256-B3C3JLbGw0FtLSWCjBxU961gLNv+BOOBC6WvstKLYMw=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "a33ef102a02ce77d3e39c25197664b7a636f9c30",
"rev": "3ed3f0eaae9fcc0a8331e77e9319c8a4abd8a71a",
"type": "github"
},
"original": {
@@ -584,19 +484,41 @@
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"boardie",
"poetry2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1703863825,
"narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "5163432afc817cf8bd1f031418d1869e4c9d5547",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nixGL": {
"inputs": {
"flake-utils": "flake-utils_9",
"flake-utils": "flake-utils_7",
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1685908677,
"narHash": "sha256-E4zUPEUFyVWjVm45zICaHRpfGepfkE9Z2OECV9HXfA4=",
"lastModified": 1713543440,
"narHash": "sha256-lnzZQYG0+EXl/6NkGpyIz+FEOc/DSEG57AP1VsdeNrM=",
"owner": "nix-community",
"repo": "nixGL",
"rev": "489d6b095ab9d289fe11af0219a9ff00fe87c7c5",
"rev": "310f8e49a149e4c9ea52f1adf70cdc768ec53f8a",
"type": "github"
},
"original": {
@@ -607,11 +529,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1677383253,
"narHash": "sha256-UfpzWfSxkfXHnb4boXZNaKsAcUrZT9Hw+tao1oZxd08=",
"lastModified": 1704161960,
"narHash": "sha256-QGua89Pmq+FBAro8NriTuoO/wNaUtugt29/qqA8zeeM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9952d6bc395f5841262b006fbace8dd7e143b634",
"rev": "63143ac2c9186be6d9da6035fa22620018c85932",
"type": "github"
},
"original": {
@@ -623,11 +545,11 @@
},
"nixpkgs-mine": {
"locked": {
"lastModified": 1710779423,
"narHash": "sha256-p6g1xu9UOCKgptKJUibxWvz+E5kzcbd4YdP0pWeTD8U=",
"lastModified": 1732985787,
"narHash": "sha256-6rSJ9L4QywpHLi/xvpOHdTuPm6/eOJcXxnYzDbP3U1k=",
"owner": "devplayer0",
"repo": "nixpkgs",
"rev": "9bcb3776d5c7ba6faf192761df3d3924f563de14",
"rev": "a28c46933ef5038fb7a2dd483b85152a539c7969",
"type": "github"
},
"original": {
@@ -639,11 +561,11 @@
},
"nixpkgs-mine-stable": {
"locked": {
"lastModified": 1710779149,
"narHash": "sha256-PPVvbwvboZpgWHDFqwLJgWoMmwKEjcv0uebKv21T+pE=",
"lastModified": 1732985894,
"narHash": "sha256-YYuQQCcSF6KjgtAenZJiBmqt5jqP3UvYgC424VQ+22s=",
"owner": "devplayer0",
"repo": "nixpkgs",
"rev": "3bc78f86abcc2e234b92beb0dd98f29c7ae88808",
"rev": "e0a3f4e2bbc5f7b681e344b389dcbab23f2e92a8",
"type": "github"
},
"original": {
@@ -655,26 +577,26 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1710695816,
"narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=",
"lastModified": 1732824227,
"narHash": "sha256-fYNXgpu1AEeLyd3fQt4Ym0tcVP7cdJ8wRoqJ+CtTRyY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "614b4613980a522ba49f0d194531beddbb7220d3",
"rev": "c71ad5c34d51dcbda4c15f44ea4e4aa6bb6ac1e9",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-23.11",
"ref": "nixos-24.11",
"type": "indirect"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1710631334,
"narHash": "sha256-rL5LSYd85kplL5othxK5lmAtjyMOBg390sGBTb3LRMM=",
"lastModified": 1732758367,
"narHash": "sha256-RzaI1RO0UXqLjydtz3GAXSTzHkpb/lLD1JD8a0W4Wpo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c75037bbf9093a2acb617804ee46320d6d1fea5a",
"rev": "fa42b5a5f401aab8a32bd33c9a4de0738180dc59",
"type": "github"
},
"original": {
@@ -685,15 +607,16 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1681756206,
"narHash": "sha256-7B2Jc1zosXvZJKlxTPBlGew0LeX/7cxguG/d3syc1JI=",
"lastModified": 1718632497,
"narHash": "sha256-YtlyfqOdYMuu7gumZtK0Kg7jr4OKfHUhJkZfNUryw68=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6eceb07c28016ec50dd683fda94995702b67e855",
"rev": "c58b4a9118498c1055c5908a5bbe666e56abe949",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"repo": "nixpkgs",
"type": "github"
}
@@ -748,15 +671,18 @@
},
"poetry2nix": {
"inputs": {
"flake-utils": "flake-utils_4",
"nixpkgs": "nixpkgs_2"
"flake-utils": "flake-utils_3",
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs_2",
"systems": "systems_4",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1681532901,
"narHash": "sha256-9ZN/gaCOlkx53km4J2QkLQh4bS+6UCBsjdi87kw6+jc=",
"lastModified": 1718726452,
"narHash": "sha256-w4hJSYvACz0i5XHtxc6XNyHwbxpisN13M2kA2Y7937o=",
"owner": "nix-community",
"repo": "poetry2nix",
"rev": "2e66fd2623eccb3086e52929c2cefd882faac8a8",
"rev": "53e534a08c0cd2a9fa7587ed1c3e7f6aeb804a2c",
"type": "github"
},
"original": {
@@ -768,35 +694,35 @@
"ragenix": {
"inputs": {
"agenix": "agenix",
"crane": "crane_2",
"flake-utils": "flake-utils_10",
"crane": "crane",
"flake-utils": "flake-utils_8",
"nixpkgs": [
"nixpkgs-unstable"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1709831932,
"narHash": "sha256-WsP8rOFa/SqYNbVtYJ/l2mWWOgyDTJFbITMV8tv0biI=",
"owner": "yaxitech",
"lastModified": 1731774781,
"narHash": "sha256-vwsUUYOIs8J6weeSK1n1mbZf8fgvygGUMsadx0JmG70=",
"owner": "devplayer0",
"repo": "ragenix",
"rev": "06de099ef02840ec463419f12de73729d458e1eb",
"rev": "ec4115da7b67c783b1091811e17dbcba50edd1c6",
"type": "github"
},
"original": {
"owner": "yaxitech",
"owner": "devplayer0",
"ref": "add-rekey-one-flag",
"repo": "ragenix",
"type": "github"
}
},
"root": {
"inputs": {
"attic": "attic",
"boardie": "boardie",
"borgthin": "borgthin",
"deploy-rs": "deploy-rs",
"devshell": "devshell_3",
"flake-utils": "flake-utils_8",
"flake-utils": "flake-utils_6",
"home-manager-stable": "home-manager-stable",
"home-manager-unstable": "home-manager-unstable",
"impermanence": "impermanence",
@@ -811,21 +737,17 @@
},
"rust-overlay": {
"inputs": {
"flake-utils": [
"ragenix",
"flake-utils"
],
"nixpkgs": [
"ragenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1708740535,
"narHash": "sha256-NCTw235XwSDbeTAtAwg/hOeNOgwYhVq7JjDdbkOgBeA=",
"lastModified": 1725675754,
"narHash": "sha256-hXW3csqePOcF2e/PYnpXj72KEYyNj2HzTrVNmS/F7Ug=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "9b24383d77f598716fa0cbb8b48c97249f5ee1af",
"rev": "8cc45e678e914a16c8e224c3237fb07cf21e5e54",
"type": "github"
},
"original": {
@@ -836,7 +758,7 @@
},
"sbt": {
"inputs": {
"flake-utils": "flake-utils_13",
"flake-utils": "flake-utils_11",
"nixpkgs": "nixpkgs_5"
},
"locked": {
@@ -856,22 +778,22 @@
"sharry": {
"inputs": {
"devshell-tools": "devshell-tools",
"flake-utils": "flake-utils_12",
"flake-utils": "flake-utils_10",
"nixpkgs": [
"nixpkgs-unstable"
],
"sbt": "sbt"
},
"locked": {
"lastModified": 1710796573,
"narHash": "sha256-23fLZFNacZU/skc8i7JExHfD//Mpkslhga6f5ATTqBA=",
"owner": "devplayer0",
"lastModified": 1720592125,
"narHash": "sha256-vR89LefkY8mBPWxDTQ8SNg6Z7/J6Yga80T4kSb6MNdk=",
"owner": "eikek",
"repo": "sharry",
"rev": "4e7a87880ba0807afd5d21706ce383b8b8727990",
"rev": "604b20517150599cb05dbe178cd35cd10659aa4c",
"type": "github"
},
"original": {
"owner": "devplayer0",
"owner": "eikek",
"repo": "sharry",
"type": "github"
}
@@ -891,6 +813,21 @@
"type": "github"
}
},
"systems_10": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
@@ -931,9 +868,8 @@
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
"id": "systems",
"type": "indirect"
}
},
"systems_5": {
@@ -1011,9 +947,31 @@
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"boardie",
"poetry2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1718522839,
"narHash": "sha256-ULzoKzEaBOiLRtjeY3YoGFJMwWSKRYOic6VNw2UyTls=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "68eb1dc333ce82d0ab0c0357363ea17c31ea1f81",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_3"
"systems": "systems_5"
},
"locked": {
"lastModified": 1701680307,

View File

@@ -7,37 +7,34 @@
devshell.inputs.nixpkgs.follows = "nixpkgs-unstable";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
nixpkgs-stable.url = "nixpkgs/nixos-23.11";
nixpkgs-stable.url = "nixpkgs/nixos-24.11";
nixpkgs-mine.url = "github:devplayer0/nixpkgs/devplayer0";
nixpkgs-mine-stable.url = "github:devplayer0/nixpkgs/devplayer0-stable";
home-manager-unstable.url = "home-manager";
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
home-manager-stable.url = "home-manager/release-23.11";
home-manager-stable.url = "home-manager/release-24.11";
home-manager-stable.inputs.nixpkgs.follows = "nixpkgs-stable";
# Stuff used by the flake for build / deployment
ragenix.url = "github:yaxitech/ragenix";
# ragenix.url = "github:yaxitech/ragenix";
ragenix.url = "github:devplayer0/ragenix/add-rekey-one-flag";
ragenix.inputs.nixpkgs.follows = "nixpkgs-unstable";
deploy-rs.url = "github:serokell/deploy-rs";
deploy-rs.inputs.nixpkgs.follows = "nixpkgs-unstable";
# Stuff used by systems
impermanence.url = "github:nix-community/impermanence";
boardie.url = "github:devplayer0/boardie";
boardie.url = "git+https://git.nul.ie/dev/boardie";
boardie.inputs.nixpkgs.follows = "nixpkgs-unstable";
nixGL.url = "github:nix-community/nixGL";
nixGL.inputs.nixpkgs.follows = "nixpkgs-unstable";
# Packages not in nixpkgs
# sharry.url = "github:eikek/sharry";
sharry.url = "github:devplayer0/sharry";
sharry.url = "github:eikek/sharry";
sharry.inputs.nixpkgs.follows = "nixpkgs-unstable";
borgthin.url = "github:devplayer0/borg";
borgthin.inputs.nixpkgs.follows = "nixpkgs-mine";
attic.url = "github:zhaofengli/attic";
attic.inputs.nixpkgs.follows = "nixpkgs-unstable";
attic.inputs.nixpkgs-stable.follows = "nixpkgs-stable";
};
outputs =
@@ -52,7 +49,7 @@
...
}:
let
inherit (builtins) mapAttrs replaceStrings;
inherit (builtins) mapAttrs replaceStrings elem;
inherit (lib) mapAttrs' filterAttrs nameValuePair recurseIntoAttrs evalModules;
inherit (lib.flake) flattenTree eachDefaultSystem;
inherit (lib.my) mkDefaultSystemsPkgs flakePackageOverlay;
@@ -96,7 +93,6 @@
inputs.ragenix.overlays.default
inputs.deploy-rs.overlay
(flakePackageOverlay inputs.home-manager-unstable system)
inputs.attic.overlays.default
];
}))
pkgsFlakes;
@@ -108,6 +104,16 @@
pkgsLibOverlay
myPkgsOverlay
];
config = {
# RMS forgive me...
# Normally this is set modularly, but sometimes we need to use other pkgs
allowUnfreePredicate = p: elem (lib.getName p) [
"widevine-cdm"
"chromium-unwrapped"
"chromium"
];
};
}))
pkgsFlakes;
@@ -116,9 +122,9 @@
nixos/installer.nix
nixos/boxes/colony
nixos/boxes/tower
nixos/boxes/castle
nixos/boxes/home/stream.nix
nixos/boxes/home/palace
nixos/boxes/home/castle
nixos/boxes/britway
nixos/boxes/kelder
@@ -198,8 +204,9 @@
systems' = mapAttrs' (n: v: nameValuePair "system-${n}" v) systems;
packages' = mapAttrs' (n: v: nameValuePair "package-${n}" v) packages;
in
pkgs.linkFarm "ci" (homes' // systems' // packages' // {
homes' // systems' // packages' // {
inherit shell;
});
};
ciDrv = pkgs.linkFarm "ci" ci;
}));
}

View File

@@ -199,17 +199,20 @@ in
file
tree
pwgen
minicom
iperf3
mosh
wget
hyx
whois
ldns
minicom
mtr
hyx
ncdu
jq
yq-go
nix-tree
];
sessionVariables = {

View File

@@ -0,0 +1,28 @@
# XTerm's default colors
# Default colors
[colors.primary]
background = '#000000'
foreground = '#ffffff'
# Normal colors
[colors.normal]
black = '#000000'
red = '#cd0000'
green = '#00cd00'
yellow = '#cdcd00'
blue = '#0000ee'
magenta = '#cd00cd'
cyan = '#00cdcd'
white = '#e5e5e5'
# Bright colors
[colors.bright]
black = '#7f7f7f'
red = '#ff0000'
green = '#00ff00'
yellow = '#ffff00'
blue = '#5c5cff'
magenta = '#ff00ff'
cyan = '#00ffff'
white = '#ffffff'

View File

@@ -1,6 +1,6 @@
{ lib, pkgs, config, ... }:
{ lib, pkgs', pkgs, config, ... }:
let
inherit (lib) genAttrs mkIf mkMerge mkForce;
inherit (lib) genAttrs mkIf mkMerge mkForce mapAttrs mkOptionDefault;
inherit (lib.my) mkBoolOpt';
cfg = config.my.gui;
@@ -10,6 +10,23 @@ let
name = "Monocraft";
size = 10;
};
doomWad = pkgs.fetchurl {
url = "https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad";
hash = "sha256-HX1DvlAeZ9kn5BXguPPinDvzMHXoWXIYFvZSpSbKx3E=";
};
doomsaver = pkgs.runCommand "doomsaver" {
inherit (pkgs) windowtolayer;
chocoDoom = pkgs.chocolate-doom2xx;
python = pkgs.python3.withPackages (ps: [ ps.filelock ]);
inherit doomWad;
enojy = ./enojy.jpg;
} ''
mkdir -p "$out"/bin
substituteAll ${./screensaver.py} "$out"/bin/doomsaver
chmod +x "$out"/bin/doomsaver
'';
in
{
options.my.gui = {
@@ -22,21 +39,32 @@ in
{
home = {
packages = with pkgs; [
xdg-utils
font.package
(nerdfonts.override {
fonts = [ "DroidSansMono" "SourceCodePro" ];
})
nerd-fonts.sauce-code-pro
nerd-fonts.droid-sans-mono
noto-fonts-emoji
grim
slurp
swappy
python310Packages.python-lsp-server
python3Packages.python-lsp-server
nil # nix language server
zls # zig language server
rust-analyzer
cowsay
fortune
jp2a
terminaltexteffects
screenfetch
neofetch
cmatrix
doomsaver
xournalpp
];
};
@@ -51,7 +79,15 @@ in
alacritty = {
enable = true;
settings = {
font.normal.family = font.name;
general.import = [ ./alacritty-xterm.toml ];
font = {
size = font.size;
normal = {
family = font.name;
style = "Regular";
};
};
};
};
@@ -59,9 +95,29 @@ in
enable = true;
inherit font;
settings = {
background_opacity = "0.8";
background_opacity = "0.65";
tab_bar_edge = "top";
shell_integration = "no-sudo";
font_features = "${font.name} -liga";
};
};
termite = {
enable = true;
font = "${font.name} ${toString font.size}";
backgroundColor = "rgba(0, 0, 0, 0.8)";
};
foot = {
enable = true;
settings = {
main = {
font = "${font.name}:size=${toString font.size}";
};
colors = {
alpha = 0.8;
background = "000000";
};
};
};
@@ -108,6 +164,19 @@ in
};
Install.RequiredBy = [ "sway-session.target" ];
};
activate-linux = {
Unit = {
Description = "Linux activation watermark";
After = "graphical-session.target";
PartOf = "graphical-session.target";
};
Service = {
Type = "simple";
ExecStart = "${pkgs.activate-linux}/bin/activate-linux";
};
Install.RequiredBy = [ "graphical-session.target" ];
};
};
};
@@ -117,6 +186,7 @@ in
wl-clipboard
wev
wdisplays
swaysome
pavucontrol
libsecret
@@ -126,10 +196,11 @@ in
];
pointerCursor = {
package = pkgs.vanilla-dmz;
name = "Vanilla-DMZ";
size = 16;
package = pkgs.posy-cursors;
name = "Posy_Cursor";
size = 32;
gtk.enable = true;
x11.enable = true;
};
};
@@ -138,9 +209,36 @@ in
xsession.preferStatusNotifierItems = true;
wayland = {
windowManager = {
sway = {
sway =
let
cfg = config.wayland.windowManager.sway.config;
mod = cfg.modifier;
renameWs = pkgs.writeShellScript "sway-rename-ws" ''
focused_ws="$(swaymsg -t get_workspaces | jq ".[] | select(.focused)")"
focused_num="$(jq -r ".num" <<< "$focused_ws")"
focused_name="$(jq -r ".name" <<< "$focused_ws")"
placeholder="$(sed -E 's/[0-9]+: //' <<< "$focused_name")"
name="$(rofi -dmenu -p "rename ws $focused_num" -theme+entry+placeholder "\"$placeholder\"")"
if [ -n "$name" ]; then
swaymsg rename workspace "$focused_name" to "$focused_num: $name"
fi
'';
clearWsName = pkgs.writeShellScript "sway-clear-ws-name" ''
focused_ws="$(swaymsg -t get_workspaces | jq ".[] | select(.focused)")"
focused_num="$(jq -r ".num" <<< "$focused_ws")"
focused_name="$(jq -r ".name" <<< "$focused_ws")"
swaymsg rename workspace "$focused_name" to "$focused_num"
'';
in
{
enable = true;
xwayland = true;
extraConfigEarly = ''
set $mod ${mod}
'';
config = {
input = {
"type:touchpad" = {
@@ -155,23 +253,87 @@ in
modifier = "Mod4";
terminal = "kitty";
keybindings =
let
cfg = config.wayland.windowManager.sway.config;
mod = cfg.modifier;
in
lib.mkOptionDefault {
keybindings = mapAttrs (k: mkOptionDefault) {
"${mod}+Left" = "focus left";
"${mod}+Down" = "focus down";
"${mod}+Up" = "focus up";
"${mod}+Right" = "focus right";
"${mod}+Shift+Left" = "move left";
"${mod}+Shift+Down" = "move down";
"${mod}+Shift+Up" = "move up";
"${mod}+Shift+Right" = "move right";
"${mod}+b" = "splith";
"${mod}+v" = "splitv";
"${mod}+f" = "fullscreen toggle";
"${mod}+a" = "focus parent";
"${mod}+s" = "layout stacking";
"${mod}+w" = "layout tabbed";
"${mod}+e" = "layout toggle split";
"${mod}+Shift+space" = "floating toggle";
"${mod}+space" = "focus mode_toggle";
"${mod}+1" = "workspace number 1";
"${mod}+2" = "workspace number 2";
"${mod}+3" = "workspace number 3";
"${mod}+4" = "workspace number 4";
"${mod}+5" = "workspace number 5";
"${mod}+6" = "workspace number 6";
"${mod}+7" = "workspace number 7";
"${mod}+8" = "workspace number 8";
"${mod}+9" = "workspace number 9";
"${mod}+0" = "workspace number 10";
"${mod}+Shift+1" =
"move container to workspace number 1";
"${mod}+Shift+2" =
"move container to workspace number 2";
"${mod}+Shift+3" =
"move container to workspace number 3";
"${mod}+Shift+4" =
"move container to workspace number 4";
"${mod}+Shift+5" =
"move container to workspace number 5";
"${mod}+Shift+6" =
"move container to workspace number 6";
"${mod}+Shift+7" =
"move container to workspace number 7";
"${mod}+Shift+8" =
"move container to workspace number 8";
"${mod}+Shift+9" =
"move container to workspace number 9";
"${mod}+Shift+0" =
"move container to workspace number 10";
"${mod}+Shift+minus" = "move scratchpad";
"${mod}+minus" = "scratchpad show";
"${mod}+Return" = "exec ${cfg.terminal}";
"${mod}+r" = "mode resize";
"${mod}+d" = null;
"${mod}+l" = "exec swaylock -i ${./lock.png} -s stretch";
"${mod}+l" = "exec ${doomsaver}/bin/doomsaver";
"${mod}+q" = "kill";
"${mod}+Shift+c" = "reload";
"${mod}+Shift+q" = "exec swaynag -t warning -m 'bruh you really wanna kill sway?' -b 'ye' 'systemctl --user stop graphical-session.target && swaymsg exit'";
# rofi
"${mod}+x" = "exec ${cfg.menu}";
"${mod}+Shift+x" = "exec rofi -show drun";
"${mod}+q" = "kill";
"${mod}+Shift+q" = "exec swaynag -t warning -m 'bruh you really wanna kill sway?' -b 'ye' 'systemctl --user stop graphical-session.target && swaymsg exit'";
"${mod}+Shift+d" = ''exec grim - | swappy -f -'';
"${mod}+Shift+s" = ''exec grim -g "$(slurp)" - | swappy -f -'';
"${mod}+Shift+e" = "exec rofi -show emoji";
# Config for this doesn't seem to work :/
"${mod}+c" = ''exec rofi -show calc -calc-command "echo -n '{result}' | ${pkgs.wl-clipboard}/bin/wl-copy"'';
"${mod}+Shift+r" = "exec ${renameWs}";
"${mod}+Shift+n" = "exec ${clearWsName}";
# Screenshots
"${mod}+Shift+d" = ''exec grim - | swappy -f -'';
"${mod}+Shift+s" = ''exec grim -g "$(slurp)" - | swappy -f -'';
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-";
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%";
"XF86AudioRaiseVolume" = "exec ${pkgs.pamixer}/bin/pamixer -i 5";
"XF86AudioLowerVolume" = "exec ${pkgs.pamixer}/bin/pamixer -d 5";
@@ -188,6 +350,9 @@ in
menu = "rofi -show run";
bars = mkForce [ ];
};
extraConfig = ''
include ${./swaysome.conf}
'';
swaynag = {
enable = true;
@@ -210,17 +375,10 @@ in
};
qt = {
enable = true;
platformTheme = "gtk";
platformTheme.name = "gtk";
};
services = {
swaync = {
enable = true;
settings = {
widgets = [ "title" "dnd" "mpris" "notifications" ];
};
};
playerctld.enable = true;
spotifyd = {
enable = false;
@@ -245,6 +403,7 @@ in
diff-so-fancy.enable = true;
userEmail = "jackos1998@gmail.com";
userName = "Jack O'Sullivan";
lfs.enable = true;
extraConfig = {
pull.rebase = true;
};
@@ -252,11 +411,13 @@ in
waybar = import ./waybar.nix { inherit lib pkgs config font; };
rofi = {
package = pkgs.rofi-wayland;
enable = true;
font = "${font.name} ${toString font.size}";
plugins = with pkgs; [
plugins = with pkgs; (map (p: p.override { rofi-unwrapped = rofi-wayland-unwrapped; }) [
rofi-calc
rofi-emoji
]) ++ [
rofi-emoji-wayland
];
extraConfig = {
modes = "window,run,ssh,filebrowser,calc,emoji";
@@ -271,7 +432,7 @@ in
chromium = {
enable = true;
package = (pkgs.chromium.override { enableWideVine = true; }).overrideAttrs (old: {
package = (pkgs'.unstable.chromium.override { enableWideVine = true; }).overrideAttrs (old: {
buildCommand = ''
${old.buildCommand}
@@ -297,6 +458,15 @@ in
] (_: "chromium-browser.desktop");
};
};
my = {
swaync = {
enable = true;
settings = {
widgets = [ "title" "dnd" "mpris" "notifications" ];
};
};
};
})
(mkIf (cfg.standalone && !pkgs.stdenv.isDarwin) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -0,0 +1,209 @@
#!@python@/bin/python
import argparse
import json
import os
import random
import signal
import subprocess
import sys
import filelock
class Screensaver:
def __init__(self, cmd, env=None, weight=1):
self.cmd = cmd
self.weight = weight
if env is not None:
self.env = os.environ.copy()
for k, v in env.items():
self.env[k] = v
else:
self.env = None
self.proc = None
def start(self):
assert self.proc is None
self.proc = subprocess.Popen(self.cmd, env=self.env)
def wait(self):
assert self.proc is not None
self.proc.wait()
def stop(self, kill=False):
assert self.proc is not None
if kill:
self.proc.kill()
else:
self.proc.terminate()
class DoomSaver(Screensaver):
wad = '@doomWad@'
def __init__(self, demo_index, weight=1.5):
super().__init__(
['@chocoDoom@/bin/chocolate-doom',
'-iwad', self.wad,
'-demoloopi', str(demo_index)],
env={
'SDL_AUDIODRIVER': 'null',
'SDL_VIDEODRIVER': 'caca',
'CACA_DRIVER': 'ncurses',
},
weight=weight,
)
def stop(self):
super().stop(kill=True)
class TTESaver(Screensaver):
effects = (
'beams,binarypath,blackhole,bouncyballs,bubbles,burn,colorshift,crumble,'
'decrypt,errorcorrect,expand,fireworks,middleout,orbittingvolley,overflow,'
'pour,print,rain,randomsequence,rings,scattered,slice,slide,spotlights,'
'spray,swarm,synthgrid,unstable,vhstape,waves,wipe'
).split(',')
def __init__(self, cmd, env=None, weight=1):
super().__init__(cmd, env=env, weight=weight)
self.running = False
def start(self):
self.running = True
def wait(self):
while self.running:
effect_cmd = ['tte', random.choice(self.effects)]
print(f"$ {self.cmd} | {' '.join(effect_cmd)}")
content = subprocess.check_output(self.cmd, shell=True, env=self.env, stderr=subprocess.DEVNULL)
self.proc = subprocess.Popen(effect_cmd, stdin=subprocess.PIPE)
self.proc.stdin.write(content)
self.proc.stdin.close()
self.proc.wait()
def stop(self):
self.running = False
self.proc.terminate()
class MultiSaver:
savers = [
DoomSaver(0),
DoomSaver(1),
DoomSaver(2),
Screensaver(['cmatrix']),
TTESaver('screenfetch -N'),
TTESaver('fortune | cowsay'),
TTESaver('top -bn1 | head -n50'),
TTESaver('ss -nltu'),
TTESaver('ss -ntu'),
TTESaver('jp2a --width=100 @enojy@'),
]
state_filename = 'screensaver.json'
def __init__(self, select=None):
self.state_path = os.path.join(f'/run/user/{os.geteuid()}', self.state_filename)
self.lock = filelock.FileLock(f'{self.state_path}.lock')
if select is not None:
assert select >= 0 and select < len(self.savers), 'Invalid screensaver index'
self.selected = self.savers[select]
else:
self.selected = None
self.cleaned_up = False
def select(self):
with self.lock:
if not os.path.exists(self.state_path):
state = {'instances': []}
else:
with open(self.state_path) as f:
state = json.load(f)
if self.selected is None:
available = set(range(len(self.savers)))
new_instances = []
for instance in state['instances']:
if not os.path.exists(f"/proc/{instance['pid']}"):
continue
new_instances.append(instance)
i = instance['saver']
assert i in available
available.remove(i)
assert available, 'No screensavers left'
available = list(available)
weights = []
for i in available:
weights.append(self.savers[i].weight)
selected_i = random.choices(available, weights=weights)[0]
new_instances.append({'pid': os.getpid(), 'saver': selected_i})
state['instances'] = new_instances
# print(f'Selected saver {selected_i}')
self.selected = self.savers[selected_i]
with open(self.state_path, 'w') as f:
json.dump(state, f)
def cleanup(self):
if self.cleaned_up:
return
self.cleaned_up = True
with self.lock:
with open(self.state_path) as f:
state = json.load(f)
for i, instance in enumerate(state['instances']):
if instance['pid'] == os.getpid():
del state['instances'][i]
with open(self.state_path, 'w') as f:
json.dump(state, f)
def run(self):
assert self.selected is not None
self.selected.start()
signal.signal(signal.SIGINT, self._sighandler)
signal.signal(signal.SIGTERM, self._sighandler)
signal.signal(signal.SIGHUP, self._sighandler)
self.selected.wait()
self.cleanup()
def stop(self):
assert self.selected is not None
print('Shutting down')
self.selected.stop()
self.cleanup()
def _sighandler(self, signum, frame):
self.stop()
def main():
parser = argparse.ArgumentParser(description='Wayland terminal-based lock screen')
parser.add_argument('-l', '--locker-cmd', default='swaylock-plugin', help='swaylock-plugin command to use')
parser.add_argument('-t', '--terminal', default='alacritty', help='Terminal emulator to use')
parser.add_argument('-i', '--instance', action='store_true', help='Run as instance')
parser.add_argument('-s', '--screensaver', type=int, help='Force use of specific screensaver')
args = parser.parse_args()
if not args.instance:
cmd = [
args.locker_cmd, '--command-each',
f'@windowtolayer@/bin/windowtolayer -- {args.terminal} -e {sys.argv[0]} --instance']
if args.screensaver is not None:
cmd[-1] += f' --screensaver {args.screensaver}'
subprocess.check_call(cmd)
return
ms = MultiSaver(select=args.screensaver)
ms.select()
ms.run()
if __name__ == '__main__':
main()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

After

Width:  |  Height:  |  Size: 251 KiB

View File

@@ -0,0 +1,66 @@
# Use (un)bindcode or (un)bindsym, depending on what you used in your main sway config file.
# The `--no-warn` setting is only added to shortcuts that exist in the default config. You may want to add or remove
# that flag on some bindings depending on your config.
# Change focus between workspaces
bindsym $mod+Alt+1 exec "swaysome focus 1"
bindsym $mod+Alt+2 exec "swaysome focus 2"
bindsym $mod+Alt+3 exec "swaysome focus 3"
bindsym $mod+Alt+4 exec "swaysome focus 4"
bindsym $mod+Alt+5 exec "swaysome focus 5"
bindsym $mod+Alt+6 exec "swaysome focus 6"
bindsym $mod+Alt+7 exec "swaysome focus 7"
bindsym $mod+Alt+8 exec "swaysome focus 8"
bindsym $mod+Alt+9 exec "swaysome focus 9"
bindsym $mod+Alt+0 exec "swaysome focus 0"
# Focus workspace groups
bindsym --no-warn $mod+1 exec "swaysome focus-group 1"
bindsym --no-warn $mod+2 exec "swaysome focus-group 2"
bindsym --no-warn $mod+3 exec "swaysome focus-group 3"
bindsym --no-warn $mod+4 exec "swaysome focus-group 4"
bindsym --no-warn $mod+5 exec "swaysome focus-group 5"
bindsym --no-warn $mod+6 exec "swaysome focus-group 6"
bindsym --no-warn $mod+7 exec "swaysome focus-group 7"
bindsym --no-warn $mod+8 exec "swaysome focus-group 8"
bindsym --no-warn $mod+9 exec "swaysome focus-group 9"
bindsym --no-warn $mod+0 exec "swaysome focus-group 0"
# Move containers between workspaces
bindsym $mod+Alt+Shift+1 exec "swaysome move 1"
bindsym $mod+Alt+Shift+2 exec "swaysome move 2"
bindsym $mod+Alt+Shift+3 exec "swaysome move 3"
bindsym $mod+Alt+Shift+4 exec "swaysome move 4"
bindsym $mod+Alt+Shift+5 exec "swaysome move 5"
bindsym $mod+Alt+Shift+6 exec "swaysome move 6"
bindsym $mod+Alt+Shift+7 exec "swaysome move 7"
bindsym $mod+Alt+Shift+8 exec "swaysome move 8"
bindsym $mod+Alt+Shift+9 exec "swaysome move 9"
bindsym $mod+Alt+Shift+0 exec "swaysome move 0"
# Move containers to other workspace groups
bindsym --no-warn $mod+Shift+1 exec "swaysome move-to-group 1"
bindsym --no-warn $mod+Shift+2 exec "swaysome move-to-group 2"
bindsym --no-warn $mod+Shift+3 exec "swaysome move-to-group 3"
bindsym --no-warn $mod+Shift+4 exec "swaysome move-to-group 4"
bindsym --no-warn $mod+Shift+5 exec "swaysome move-to-group 5"
bindsym --no-warn $mod+Shift+6 exec "swaysome move-to-group 6"
bindsym --no-warn $mod+Shift+7 exec "swaysome move-to-group 7"
bindsym --no-warn $mod+Shift+8 exec "swaysome move-to-group 8"
bindsym --no-warn $mod+Shift+9 exec "swaysome move-to-group 9"
bindsym --no-warn $mod+Shift+0 exec "swaysome move-to-group 0"
# Move focused container to next output
bindsym $mod+Alt+Right exec "swaysome next-output"
# Move focused container to previous output
bindsym $mod+Alt+Left exec "swaysome prev-output"
# Move focused workspace group to next output
bindsym $mod+Shift+Alt+Right exec "swaysome workspace-group-next-output"
# Move focused workspace group to previous output
bindsym $mod+Shift+Alt+Left exec "swaysome workspace-group-prev-output"
# Init workspaces for every screen
exec "swaysome init 1"

View File

@@ -146,9 +146,9 @@ in
dnd-none = "";
};
return-type = "json";
exec = "${config.services.swaync.package}/bin/swaync-client -swb";
on-click = "${config.services.swaync.package}/bin/swaync-client -t -sw";
on-click-right = "${config.services.swaync.package}/bin/swaync-client -d -sw";
exec = "${config.my.swaync.package}/bin/swaync-client -swb";
on-click = "${config.my.swaync.package}/bin/swaync-client -t -sw";
on-click-right = "${config.my.swaync.package}/bin/swaync-client -d -sw";
escape = true;
};
};

View File

@@ -19,10 +19,10 @@ let
};
};
cfg = config.services.swaync;
cfg = config.my.swaync;
in
{
options.services.swaync = with lib.types; {
options.my.swaync = with lib.types; {
enable = mkEnableOption "Sway Notification Center";
package = mkOption {
type = package;

View File

@@ -11,6 +11,8 @@ rec {
jellyseerr = 402;
atticd = 403;
kea = 404;
keepalived_script = 405;
photoprism = 406;
};
gids = {
matrix-syncv3 = 400;
@@ -18,12 +20,14 @@ rec {
jellyseerr = 402;
atticd = 403;
kea = 404;
keepalived_script = 405;
photoprism = 406;
};
};
kernel = {
lts = pkgs: pkgs.linuxKernel.packages.linux_6_6;
latest = pkgs: pkgs.linuxKernel.packages.linux_6_8;
latest = pkgs: pkgs.linuxKernel.packages.linux_6_12;
};
nginx = rec {
@@ -94,10 +98,10 @@ rec {
nix = {
cache = rec {
substituters = [
"https://nix-cache.${pubDomain}/main"
"https://nix-cache.${pubDomain}"
];
keys = [
"main:mMChkG8LwXrFirVfudqjSHasK1jV31OVElYD3eImYl8="
"nix-cache.nul.ie-1:BzH5yMfF4HbzY1C977XzOxoPhEc9Zbu39ftPkUbH+m4="
];
conf = ''
extra-substituters = ${concatStringsSep " " substituters}
@@ -107,7 +111,7 @@ rec {
};
pubDomain = "nul.ie";
colony = {
colony = rec {
domain = "ams1.int.${pubDomain}";
pubV4 = "94.142.240.44";
prefixes = with lib.my.net.cidr; rec {
@@ -131,6 +135,9 @@ rec {
v4 = subnet 8 3 all.v4;
v6 = subnet 4 3 all.v6;
};
qclk = {
v4 = subnet 8 4 all.v4;
};
cust = {
v4 = subnet 8 100 all.v4; # single ip for routing only
@@ -144,6 +151,10 @@ rec {
v4 = "94.142.242.255/32";
v6 = subnet 8 1 cust.v6;
};
jam = {
v4 = subnet 8 4 cust.v4;
v6 = subnet 8 2 cust.v6;
};
vip1 = "94.142.241.224/30";
vip2 = "94.142.242.254/31";
@@ -156,6 +167,16 @@ rec {
home.v6 = "2a0e:97c0:4d0::/48";
};
custRouting = with lib.my.net.cidr; {
mail-vm = host 1 prefixes.cust.v4;
darts-vm = host 2 prefixes.cust.v4;
jam-ctr = host 3 prefixes.cust.v4;
};
qclk = {
wgPort = 51821;
};
firewallForwards = aa: [
{
port = "http";
@@ -169,6 +190,7 @@ rec {
port = 8448;
dst = aa.middleman.internal.ipv4.address;
}
{
port = 25565;
dst = aa.simpcraft-oci.internal.ipv4.address;
@@ -177,6 +199,7 @@ rec {
port = 25566;
dst = aa.simpcraft-staging-oci.internal.ipv4.address;
}
{
port = 25575;
dst = aa.simpcraft-oci.internal.ipv4.address;
@@ -204,6 +227,23 @@ rec {
dst = aa.simpcraft-oci.internal.ipv4.address;
proto = "udp";
}
{
port = 15636;
dst = aa.enshrouded-oci.internal.ipv4.address;
proto = "udp";
}
{
port = 15637;
dst = aa.enshrouded-oci.internal.ipv4.address;
proto = "udp";
}
{
port = qclk.wgPort;
dst = aa.qclk.internal.ipv4.address;
proto = "udp";
}
];
fstrimConfig = {
@@ -227,7 +267,7 @@ rec {
"stream"
];
routersPubV4 = [
"109.255.252.37"
"109.255.31.155"
"109.255.252.63"
];
@@ -277,6 +317,8 @@ rec {
v6 = host ((1*65536*65536*65536) + 65535) prefixes.as211024.v6;
};
};
roceBootModules = [ "ib_core" "ib_uverbs" "mlx5_core" "mlx5_ib" ];
};
britway = {
@@ -327,6 +369,7 @@ rec {
};
domain = "hentai.engineer";
ipv4MTU = 1460;
vpn = {
port = 51820;
};
@@ -340,6 +383,7 @@ rec {
deploy = ../.keys/deploy.pub;
rsyncNet = ../.keys/zh2855.rsync.net.pub;
mailcowAcme = ../.keys/mailcow-acme.pub;
harmonia = ../.keys/harmonia.pub;
};
sshHostKeys = {
mail-vm = ../.keys/mail-vm-host.pub;

View File

@@ -5,7 +5,7 @@ let
genAttrs mapAttrsToList filterAttrsRecursive nameValuePair types
mkOption mkOverride mkForce mkIf mergeEqualOption optional
showWarnings concatStringsSep flatten unique optionalAttrs
mkBefore;
mkBefore toLower;
inherit (lib.flake) defaultSystems;
in
rec {
@@ -248,10 +248,37 @@ rec {
in
{
trivial = prev.trivial // {
release = "23.12:u-${prev.trivial.release}";
codeName = "Amogus";
release = "24.12:u-${prev.trivial.release}";
codeName = "Epic";
revisionWithDefault = default: self.rev or default;
versionSuffix = ".${date}.${revCode self}:u-${revCode pkgsFlake}";
};
};
netbootKeaClientClasses = { tftpIP, hostname, systems }:
let
testIPXE = "substring(option[user-class].hex, 0, 4) == 'iPXE'";
in
(mapAttrsToList (name: mac: {
name = "nixos-${name}";
test = "(${testIPXE}) and (hexstring(pkt4.mac, ':') == '${toLower mac}')";
next-server = tftpIP;
server-hostname = hostname;
boot-file-name = "http://${hostname}/systems/${name}/menu.ipxe";
}) systems) ++ [
{
name = "ipxe";
test = testIPXE;
next-server = tftpIP;
server-hostname = hostname;
boot-file-name = "http://${hostname}/boot.ipxe";
}
{
name = "efi-x86_64";
test = "option[client-system].hex == 0x0007";
next-server = tftpIP;
server-hostname = hostname;
boot-file-name = "ipxe-x86_64.efi";
}
];
}

View File

@@ -106,7 +106,7 @@ in
{
matchConfig.Name = "as211024";
networkConfig.IPv6AcceptRA = mkForce false;
routes = map (r: { routeConfig = r; }) [
routes = [
{
Destination = lib.my.c.colony.prefixes.all.v4;
Gateway = allAssignments.estuary.as211024.ipv4.address;
@@ -123,7 +123,7 @@ in
Table = "ts-extra";
}
];
routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [
routingPolicyRules = [
{
IncomingInterface = "tailscale0";
To = lib.my.c.colony.prefixes.all.v6;

View File

@@ -80,7 +80,7 @@ in
};
};
"ts.${pubDomain}" = {
"hs.${pubDomain}" = {
locations."/" = {
proxyPass = "http://localhost:${toString config.services.headscale.port}";
proxyWebsockets = true;

View File

@@ -5,18 +5,20 @@ let
inherit (lib.my.c.britway) prefixes domain;
# Can't use overrideAttrs because we need to override `vendorHash` within `buildGoModule`
headscale = pkgs.headscale.override {
headscale' = (pkgs.headscale.override {
buildGoModule = args: pkgs.buildGoModule (args // rec {
version = "0.23.0-alpha2";
version = "0.23.0-alpha12";
src = pkgs.fetchFromGitHub {
owner = "juanfont";
repo = "headscale";
rev = "v${version}";
hash = "sha256-sz+uQyyq/5YYDe5I44x5x2nvd48swAhNlInB8KZYvDo=";
hash = "sha256-kZZK0cXnFARxblSMz01TDcBbTorkHGAwGpR+a4/mYfU=";
};
vendorHash = "sha256-u9AmJguQ5dnJpfhOeLN43apvMHuraOrJhvlEIp9RoIc=";
patches = [];
vendorHash = "sha256-EorT2AVwA3usly/LcNor6r5UIhLCdj3L4O4ilgTIC2o=";
doCheck = false;
});
});
};
advRoutes = concatStringsSep "," [
lib.my.c.home.prefixes.all.v4
@@ -39,19 +41,20 @@ in
services = {
headscale = {
enable = true;
package = headscale;
settings = {
disable_check_updates = true;
unix_socket_permission = "0770";
server_url = "https://ts.${pubDomain}";
db_type = "sqlite3";
db_path = "/var/lib/headscale/db.sqlite3";
server_url = "https://hs.${pubDomain}";
database = {
type = "sqlite3";
sqlite.path = "/var/lib/headscale/db.sqlite3";
};
noise.private_key_path = "/var/lib/headscale/noise_private.key";
ip_prefixes = with lib.my.c.tailscale.prefix; [ v4 v6 ];
dns_config = {
prefixes = with lib.my.c.tailscale.prefix; { inherit v4 v6; };
dns = {
# Use IPs that will route inside the VPN to prevent interception
# (e.g. DNS rebinding filtering)
restricted_nameservers = {
nameservers.split = {
"${domain}" = pubNameservers;
"${lib.my.c.colony.domain}" = with allAssignments.estuary.base; [
ipv4.address ipv6.address
@@ -65,7 +68,6 @@ in
};
magic_dns = true;
base_domain = "ts.${pubDomain}";
override_local_dns = false;
};
oidc = {
only_start_if_oidc_is_available = true;
@@ -85,7 +87,7 @@ in
interfaceName = "tailscale0";
extraUpFlags = [
"--operator=${config.my.user.config.name}"
"--login-server=https://ts.nul.ie"
"--login-server=https://hs.nul.ie"
"--netfilter-mode=off"
"--advertise-exit-node"
"--advertise-routes=${advRoutes}"

View File

@@ -1,7 +1,7 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.colony) domain prefixes firewallForwards;
inherit (lib.my.c.colony) domain prefixes custRouting firewallForwards;
in
{
imports = [ ./vms ];
@@ -60,8 +60,8 @@ in
kernelPackages = (lib.my.c.kernel.lts pkgs).extend (self: super: {
kernel = super.kernel.override {
structuredExtraConfig = with lib.kernel; {
#SOME_OPT = yes;
#A_MOD = module;
ACPI_APEI_PCIEAER = yes;
PCIEAER = yes;
};
};
});
@@ -150,12 +150,12 @@ in
"serial-getty@ttyS1".enable = true;
lvm-activate-main = {
description = "Activate remaining LVs";
before = [ "local-fs-pre.target" ];
unitConfig.DefaultDependencies = false;
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.lvm2.bin}/bin/vgchange -aay main";
};
wantedBy = [ "sysinit.target" ];
wantedBy = [ "local-fs-pre.target" ];
};
rsync-lvm-meta = {
@@ -252,10 +252,10 @@ in
};
ipv6Prefixes = [
{
ipv6PrefixConfig.Prefix = prefixes.vms.v6;
Prefix = prefixes.vms.v6;
}
];
routes = map (r: { routeConfig = r; }) [
routes = [
{
Destination = prefixes.ctrs.v4;
Gateway = allAssignments.shill.routing.ipv4.address;
@@ -264,10 +264,12 @@ in
Destination = prefixes.ctrs.v6;
Gateway = allAssignments.shill.internal.ipv6.address;
}
{
Destination = allAssignments.shill.internal.ipv4.address;
Gateway = allAssignments.shill.routing.ipv4.address;
}
{
Destination = lib.my.c.tailscale.prefix.v4;
Gateway = allAssignments.shill.routing.ipv4.address;
@@ -276,6 +278,15 @@ in
Destination = lib.my.c.tailscale.prefix.v6;
Gateway = allAssignments.shill.internal.ipv6.address;
}
{
Destination = prefixes.qclk.v4;
Gateway = allAssignments.shill.routing.ipv4.address;
}
{
Destination = prefixes.jam.v6;
Gateway = allAssignments.shill.internal.ipv6.address;
}
{
Destination = prefixes.oci.v4;
@@ -307,7 +318,7 @@ in
"90-vm-mail" = {
matchConfig.Name = "vm-mail";
address = [
(net.cidr.subnet 8 1 prefixes.cust.v4)
"${custRouting.mail-vm}/32"
prefixes.mail.v6
];
networkConfig = {
@@ -316,10 +327,10 @@ in
};
ipv6Prefixes = [
{
ipv6PrefixConfig.Prefix = prefixes.mail.v6;
Prefix = prefixes.mail.v6;
}
];
routes = map (r: { routeConfig = r; }) [
routes = [
{
Destination = prefixes.mail.v4;
Scope = "link";
@@ -330,7 +341,7 @@ in
"90-vm-darts" = {
matchConfig.Name = "vm-darts";
address = [
(net.cidr.subnet 8 2 prefixes.cust.v4)
"${custRouting.darts-vm}/32"
prefixes.darts.v6
];
networkConfig = {
@@ -339,10 +350,10 @@ in
};
ipv6Prefixes = [
{
ipv6PrefixConfig.Prefix = prefixes.darts.v6;
Prefix = prefixes.darts.v6;
}
];
routes = map (r: { routeConfig = r; }) [
routes = [
{
Destination = prefixes.darts.v4;
Scope = "link";

View File

@@ -29,6 +29,9 @@
};
in
{
# Kernel Same-Page Merging to attempt memory usage reduction
hardware.ksm.enable = false;
systemd = {
network = {
links = {
@@ -130,7 +133,8 @@
(vm.lvmDisk "media")
(vm.lvmDisk "minio")
(vm.lvmDisk "nix-atticd")
(vm.lvmDisk "nix-cache")
(vm.lvmDisk "jam")
]);
};
@@ -209,6 +213,7 @@
drives = [
(mkMerge [ (vm.disk "darts" "root") { frontendOpts.bootindex = 0; } ])
(vm.lvmDisk' "media" "darts-media")
(vm.lvmDisk' "ext" "darts-ext")
];
};
};

View File

@@ -9,6 +9,7 @@ in
vpns = {
l2 = {
as211024 = {
udpEncapsulation = true;
vni = 211024;
security.enable = true;
peers = {
@@ -163,11 +164,9 @@ in
};
wireguardPeers = [
{
wireguardPeerConfig = {
PublicKey = "7N9YdQaCMWWIwAnW37vrthm9ZpbnG4Lx3gheHeRYz2E=";
AllowedIPs = [ allAssignments.kelder.estuary.ipv4.address ];
PersistentKeepalive = 25;
};
}
];
};
@@ -277,11 +276,10 @@ in
};
ipv6Prefixes = [
{
ipv6PrefixConfig.Prefix = prefixes.base.v6;
Prefix = prefixes.base.v6;
}
];
routes = map (r: { routeConfig = r; }) (flatten
([
routes = flatten ([
{
Destination = prefixes.vip1;
Gateway = allAssignments.colony.routing.ipv4.address;
@@ -307,6 +305,11 @@ in
Destination = lib.my.c.tailscale.prefix.v6;
Gateway = allAssignments.colony.internal.ipv6.address;
}
{
Destination = prefixes.qclk.v4;
Gateway = allAssignments.colony.routing.ipv4.address;
}
] ++
(map (pName: [
{
@@ -317,7 +320,7 @@ in
Destination = prefixes."${pName}".v6;
Gateway = allAssignments.colony.internal.ipv6.address;
}
]) [ "vms" "ctrs" "oci" ])));
]) [ "vms" "ctrs" "oci" ]));
}
];
@@ -326,7 +329,7 @@ in
{
matchConfig.Name = "as211024";
networkConfig.IPv6AcceptRA = mkForce false;
routes = map (r: { routeConfig = r; }) [
routes = [
{
Destination = lib.my.c.home.prefixes.all.v4;
Gateway = lib.my.c.home.vips.as211024.v4;
@@ -338,10 +341,8 @@ in
matchConfig.Name = "kelder";
routes = [
{
routeConfig = {
Destination = allAssignments.kelder.estuary.ipv4.address;
Scope = "link";
};
}
];
};
@@ -393,6 +394,9 @@ in
# Safe enough to allow all SSH
tcp dport ssh accept
# jam-ctr forwards
ip daddr ${aa.shill.internal.ipv4.address} tcp dport 60022 accept
ip6 daddr ${aa.middleman.internal.ipv6.address} tcp dport { http, https, 8448 } accept
${matchInet "tcp dport { http, https } accept" "git"}
ip6 daddr ${aa.simpcraft-oci.internal.ipv6.address} tcp dport { 25565, 25575 } accept
@@ -403,6 +407,7 @@ in
ip6 daddr ${aa.valheim-oci.internal.ipv6.address} udp dport { 2456-2457 } accept
ip6 daddr ${aa.waffletail.internal.ipv6.address} udp dport 41641 accept
ip6 daddr ${aa.simpcraft-oci.internal.ipv6.address} udp dport 25565 accept
ip6 daddr ${aa.enshrouded-oci.internal.ipv6.address} udp dport { 15636-15637 } accept
return
}
chain filter-routing {

View File

@@ -2,7 +2,7 @@
let
inherit (builtins) attrNames;
inherit (lib.my) net;
inherit (lib.my.c.colony) prefixes;
inherit (lib.my.c.colony) prefixes custRouting;
authZones = attrNames config.my.pdns.auth.bind.zones;
in
@@ -153,6 +153,7 @@ in
simpcraft IN AAAA ${allAssignments.simpcraft-oci.internal.ipv6.address}
simpcraft-staging IN A ${assignments.internal.ipv4.address}
simpcraft-staging IN AAAA ${allAssignments.simpcraft-staging-oci.internal.ipv6.address}
enshrouded IN A ${assignments.internal.ipv4.address}
mail-vm IN A ${net.cidr.host 0 prefixes.mail.v4}
mail-vm IN AAAA ${net.cidr.host 1 prefixes.mail.v6}
@@ -162,6 +163,10 @@ in
andrey-cust IN A ${allAssignments.kelder.estuary.ipv4.address}
jam-cust IN A ${net.cidr.host 0 prefixes.jam.v4}
jam-fwd IN A ${allAssignments.shill.internal.ipv4.address}
jam-cust IN AAAA ${net.cidr.host 1 prefixes.jam.v6}
$TTL 3
_acme-challenge IN LUA TXT @@FILE@@

View File

@@ -35,6 +35,11 @@ in
];
url = "https://git.${pubDomain}";
tokenFile = config.age.secrets."gitea/actions-runner.env".path;
settings = {
runner = {
timeout = "8h";
};
};
};
};
};

View File

@@ -0,0 +1,105 @@
{ lib, pkgs, assignments, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.colony) prefixes custRouting;
in
{
fileSystems = {
"/mnt/jam" = {
device = "/dev/disk/by-label/jam";
fsType = "ext4";
};
"/var/lib/machines/jam" = {
device = "/mnt/jam";
options = [ "bind" ];
};
};
systemd = {
nspawn = {
jam = {
enable = true;
execConfig = {
Boot = true;
PrivateUsers = "pick";
LinkJournal = false;
};
networkConfig = {
Private = true;
VirtualEthernet = true;
};
};
};
network.networks = {
"50-ve-jam" = {
matchConfig = {
Kind = "veth";
Name = "ve-jam";
};
address = [
custRouting.jam-ctr
prefixes.jam.v6
];
networkConfig = {
IPv6AcceptRA = false;
IPv6SendRA = true;
};
ipv6Prefixes = [
{
Prefix = prefixes.jam.v6;
}
];
routes = [
{
Destination = prefixes.jam.v4;
Scope = "link";
}
];
};
};
services = {
"systemd-nspawn@jam" = {
overrideStrategy = "asDropin";
serviceConfig = {
CPUQuota = "400%";
MemoryHigh = "infinity";
MemoryMax = "4G";
};
wantedBy = [ "machines.target" ];
};
};
};
my = {
firewall =
let
jamIP = net.cidr.host 0 prefixes.jam.v4;
in
{
nat.forwardPorts."${assignments.internal.ipv4.address}" = [
{
port = 60022;
dst = jamIP;
dstPort = "ssh";
}
];
extraRules = ''
table inet filter {
chain forward {
iifname { ve-jam } oifname vms accept
iifname vms oifname { ve-jam } accept
}
}
table inet nat {
chain postrouting {
ip saddr ${jamIP} snat to ${assignments.internal.ipv4.address}
}
}
'';
};
};
}

View File

@@ -24,7 +24,7 @@ in
configuration = { lib, pkgs, config, assignments, allAssignments, ... }:
let
inherit (lib) mkMerge mkIf mkForce;
inherit (lib) genAttrs mkMerge mkIf mkForce;
inherit (lib.my) networkdAssignment;
in
{
@@ -45,9 +45,22 @@ in
owner = "matrix-synapse";
group = "matrix-synapse";
};
"chatterbox/syncv3.env" = {
owner = "matrix-syncv3";
group = "matrix-syncv3";
"chatterbox/doublepuppet.yaml" = {
owner = "matrix-synapse";
group = "matrix-synapse";
};
"chatterbox/mautrix-whatsapp.env" = {
owner = "mautrix-whatsapp";
group = "mautrix-whatsapp";
};
"chatterbox/mautrix-messenger.env" = {
owner = "mautrix-meta-messenger";
group = "mautrix-meta";
};
"chatterbox/mautrix-instagram.env" = {
owner = "mautrix-meta-instagram";
group = "mautrix-meta";
};
};
};
@@ -59,29 +72,24 @@ in
users = with lib.my.c.ids; {
users = {
matrix-syncv3 = {
isSystemUser = true;
uid = uids.matrix-syncv3;
group = "matrix-syncv3";
};
};
groups = {
matrix-syncv3.gid = gids.matrix-syncv3;
matrix-synapse.extraGroups = [
"mautrix-whatsapp"
];
};
groups = { };
};
systemd = {
network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal;
services = {
matrix-sliding-sync.serviceConfig = {
# Needs to be able to read its secrets
DynamicUser = mkForce false;
User = "matrix-syncv3";
Group = "matrix-syncv3";
};
};
services = { } // (genAttrs [ "mautrix-whatsapp" "mautrix-meta-messenger" "mautrix-meta-instagram" ] (_: {
# ffmpeg needed to convert GIFs to video
path = with pkgs; [ ffmpeg ];
}));
};
# TODO/FIXME: https://github.com/NixOS/nixpkgs/issues/336052
nixpkgs.config.permittedInsecurePackages = [ "olm-3.2.16" ];
services = {
netdata.enable = true;
matrix-synapse = {
@@ -168,19 +176,11 @@ in
app_service_config_files = [
"/var/lib/heisenbridge/registration.yml"
config.age.secrets."chatterbox/doublepuppet.yaml".path
];
};
};
matrix-sliding-sync = {
enable = true;
createDatabase = false;
environmentFile = config.age.secrets."chatterbox/syncv3.env".path;
settings = {
SYNCV3_BINDADDR = "[::]:8009";
SYNCV3_SERVER = "http://localhost:8008";
};
};
heisenbridge = {
enable = true;
@@ -195,6 +195,144 @@ in
];
};
};
mautrix-whatsapp = {
enable = true;
environmentFile = config.age.secrets."chatterbox/mautrix-whatsapp.env".path;
settings = {
homeserver = {
address = "http://localhost:8008";
domain = "nul.ie";
};
appservice = {
database = {
type = "postgres";
uri = "$MAU_WAPP_PSQL_URI";
};
id = "whatsapp2";
bot = {
username = "whatsapp2";
displayname = "WhatsApp Bridge Bot";
};
};
bridge = {
username_template = "wapp2_{{.}}";
displayname_template = "{{or .BusinessName .PushName .JID}} (WA)";
personal_filtering_spaces = true;
delivery_receipts = true;
allow_user_invite = true;
url_previews = true;
command_prefix = "!wa";
login_shared_secret_map."nul.ie" = "$MAU_WAPP_DOUBLE_PUPPET_TOKEN";
encryption = {
allow = true;
default = true;
require = true;
};
permissions = {
"@dev:nul.ie" = "admin";
};
};
};
};
mautrix-meta.instances = {
messenger = {
enable = true;
registerToSynapse = true;
dataDir = "mautrix-messenger";
environmentFile = config.age.secrets."chatterbox/mautrix-messenger.env".path;
settings = {
homeserver = {
address = "http://localhost:8008";
domain = "nul.ie";
};
appservice = {
database = {
type = "postgres";
uri = "$MAU_FBM_PSQL_URI";
};
id = "fbm2";
bot = {
username = "messenger2";
displayname = "Messenger Bridge Bot";
avatar = "mxc://maunium.net/ygtkteZsXnGJLJHRchUwYWak";
};
};
network = {
mode = "messenger";
displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (FBM)'';
};
bridge = {
username_template = "fbm2_{{.}}";
personal_filtering_spaces = true;
delivery_receipts = true;
management_room_text.welcome = "Hello, I'm a Messenger bridge bot.";
command_prefix = "!fbm";
login_shared_secret_map."nul.ie" = "$MAU_FBM_DOUBLE_PUPPET_TOKEN";
backfill = {
history_fetch_pages = 5;
};
encryption = {
allow = true;
default = true;
require = true;
};
permissions = {
"@dev:nul.ie" = "admin";
};
};
};
};
instagram = {
enable = true;
registerToSynapse = true;
dataDir = "mautrix-instagram";
environmentFile = config.age.secrets."chatterbox/mautrix-instagram.env".path;
settings = {
homeserver = {
address = "http://localhost:8008";
domain = "nul.ie";
};
appservice = {
database = {
type = "postgres";
uri = "$MAU_IG_PSQL_URI";
};
id = "instagram";
bot = {
username = "instagram";
displayname = "Instagram Bridge Bot";
avatar = "mxc://maunium.net/JxjlbZUlCPULEeHZSwleUXQv";
};
};
network = {
mode = "instagram";
displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (IG)'';
};
bridge = {
username_template = "ig_{{.}}";
personal_filtering_spaces = true;
delivery_receipts = true;
management_room_text.welcome = "Hello, I'm an Instagram bridge bot.";
command_prefix = "!ig";
login_shared_secret_map."nul.ie" = "$MAU_IG_DOUBLE_PUPPET_TOKEN";
backfill = {
history_fetch_pages = 5;
};
encryption = {
allow = true;
default = true;
require = true;
};
permissions = {
"@dev:nul.ie" = "admin";
};
};
};
};
};
};
}
(mkIf config.my.build.isDevVM {

View File

@@ -8,5 +8,6 @@
./object.nix
./toot.nix
./waffletail.nix
./qclk
];
}

View File

@@ -1,6 +1,8 @@
{ lib, ... }:
let
inherit (lib) concatStringsSep;
inherit (lib.my) net;
inherit (lib.my.c) pubDomain;
inherit (lib.my.c.colony) domain prefixes;
in
{
@@ -35,6 +37,9 @@ in
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPUv1ntVrZv5ripsKpcOAnyDQX2PHjowzyhqWK10Ml53";
files = {
"jackflix/photoprism-pass.txt" = {};
};
};
};
@@ -50,10 +55,16 @@ in
uid = uids.jellyseerr;
group = "jellyseerr";
};
photoprism = {
isSystemUser = true;
uid = uids.photoprism;
group = "photoprism";
};
};
groups = {
media.gid = 2000;
jellyseerr.gid = gids.jellyseerr;
photoprism.gid = gids.photoprism;
};
};
@@ -76,8 +87,20 @@ in
RootDirectoryStartOnly = lib.mkForce false;
RootDirectory = lib.mkForce "";
};
photoprism.serviceConfig = {
# Needs to be able to access its data
DynamicUser = mkForce false;
};
};
};
nixpkgs.config.permittedInsecurePackages = [
# FIXME: This is needed for Sonarr
"aspnetcore-runtime-wrapped-6.0.36"
"aspnetcore-runtime-6.0.36"
"dotnet-sdk-wrapped-6.0.428"
"dotnet-sdk-6.0.428"
];
services = {
netdata.enable = true;
@@ -117,6 +140,24 @@ in
};
jellyfin.enable = true;
photoprism = {
enable = true;
address = "[::]";
port = 2342;
originalsPath = "/mnt/media/photoprism/originals";
importPath = "/mnt/media/photoprism/import";
passwordFile = config.age.secrets."jackflix/photoprism-pass.txt".path;
settings = {
PHOTOPRISM_AUTH_MODE = "password";
PHOTOPRISM_ADMIN_USER = "dev";
PHOTOPRISM_APP_NAME = "/dev/player0 Photos";
PHOTOPRISM_SITE_URL = "https://photos.${pubDomain}/";
PHOTOPRISM_SITE_TITLE = "/dev/player0 Photos";
PHOTOPRISM_TRUSTED_PROXY = concatStringsSep "," (with prefixes.ctrs; [ v4 v6 ]);
PHOTOPRISM_DATABASE_DRIVER = "sqlite";
};
};
};
};
};

View File

@@ -37,7 +37,7 @@ in
tcp dport ${toString transmissionPeerPort} accept
iifname vpn return
tcp dport { 19999, 9091, 9117, 7878, 8989, 8096 } accept
tcp dport { 19999, 9091, 9117, 7878, 8989, 8096, 2342 } accept
return
}
chain input {
@@ -71,14 +71,12 @@ in
RouteTable = routeTable;
};
wireguardPeers = [
{
# AirVPN NL
wireguardPeerConfig = {
{
Endpoint = "2a00:1678:1337:2329:e5f:35d4:4404:ef9f:1637";
PublicKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk=";
PresharedKeyFile = config.age.secrets."${pskFile}".path;
AllowedIPs = [ "0.0.0.0/0" "::/0" ];
};
}
];
};
@@ -94,7 +92,7 @@ in
matchConfig.Name = "vpn";
address = [ "10.182.97.37/32" "fd7d:76ee:e68f:a993:735d:ef5e:6907:b122/128" ];
dns = [ "10.128.0.1" "fd7d:76ee:e68f:a993::1" ];
routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [
routingPolicyRules = [
{
Family = "both";
SuppressPrefixLength = 0;

View File

@@ -239,6 +239,9 @@ in
];
recommendedTlsSettings = true;
recommendedBrotliSettings = true;
# Uh so nginx is hanging with zstd enabled... maybe let's not for now
# recommendedZstdSettings = true;
clientMaxBodySize = "0";
serverTokens = true;
resolver = {

View File

@@ -2,7 +2,7 @@
let
inherit (builtins) mapAttrs toJSON;
inherit (lib) mkMerge mkDefault genAttrs flatten concatStringsSep;
inherit (lib.my.c) pubDomain;
inherit (lib.my.c) pubDomain home;
inherit (lib.my.c.nginx) proxyHeaders;
inherit (config.networking) domain;
@@ -35,7 +35,6 @@ let
# For clients
(mkWellKnown "matrix/client" (toJSON {
"m.homeserver".base_url = "https://matrix.nul.ie";
"org.matrix.msc3575.proxy".url = "https://matrix-syncv3.nul.ie";
}))
];
};
@@ -145,7 +144,7 @@ in
"pass.${pubDomain}" =
let
upstream = "http://vaultwarden-ctr.${domain}";
upstream = "http://vaultwarden-ctr.${domain}:8080";
in
{
locations = {
@@ -182,10 +181,6 @@ in
];
useACMEHost = pubDomain;
};
"matrix-syncv3.${pubDomain}" = {
locations."/".proxyPass = "http://chatterbox-ctr.${domain}:8009";
useACMEHost = pubDomain;
};
"element.${pubDomain}" =
let
@@ -206,7 +201,8 @@ in
# Currently it seems like single quotes aren't escaped like they should be...
conf = {
brand = "/dev/player0 Matrix";
showLabsSettings = true;
show_labs_settings = true;
default_country_code = "IE";
disable_guests = true;
default_server_config = {
"m.homeserver" = {
@@ -214,9 +210,8 @@ in
server_name = "nul.ie";
};
};
roomDirectory.servers = [
room_directory.servers = [
"nul.ie"
"netsoc.ie"
"matrix.org"
];
};
@@ -388,6 +383,36 @@ in
locations."/".proxyPass = "http://object-ctr.${domain}:8088";
useACMEHost = pubDomain;
};
"photos.${pubDomain}" = {
locations."/" = {
proxyPass = "http://jackflix-ctr.${domain}:2342";
proxyWebsockets = true;
extraConfig = proxyHeaders;
};
useACMEHost = pubDomain;
};
"pront.${pubDomain}" = mkMerge [
{
locations."/" = mkMerge [
{
proxyPass = "http://stream-hi.${home.domain}:5000";
proxyWebsockets = true;
extraConfig = proxyHeaders;
}
(ssoLoc "generic")
];
locations."~* ^/webcam/(.*)" = mkMerge [
{
proxyPass = "http://stream-hi.${home.domain}:5050/$1$is_args$args";
extraConfig = proxyHeaders;
}
(ssoLoc "generic")
];
useACMEHost = pubDomain;
}
(ssoServer "generic")
];
};
minio =
@@ -399,10 +424,13 @@ in
ignore_invalid_headers off;
'';
nixCacheableRegex = ''^\/(\S+\.narinfo|nar\/\S+\.nar\.\S+)$'';
nixCacheableRegex = ''^\/(\S+\.narinfo|nar\/\S+\.nar.*|serve\/.+)$'';
nixCacheHeaders = ''
add_header Cache-Control $nix_cache_control;
add_header Expires $nix_expires;
brotli on;
brotli_types application/x-nix-archive;
'';
in
{
@@ -444,9 +472,11 @@ in
"nix-cache.${pubDomain}" = {
locations = {
"/".proxyPass = "http://${host}:8069";
"/" = {
proxyPass = "http://${host}:5000";
};
"~ ${nixCacheableRegex}" = {
proxyPass = "http://${host}:8069";
proxyPass = "http://${host}:5000";
extraConfig = nixCacheHeaders;
};
};

View File

@@ -31,6 +31,13 @@ in
{
config = mkMerge [
{
fileSystems = {
"/var/lib/harmonia" = {
device = "/mnt/nix-cache";
options = [ "bind" ];
};
};
my = {
deploy.enable = false;
server.enable = true;
@@ -48,6 +55,7 @@ in
group = config.my.user.config.group;
};
"object/atticd.env" = {};
"nix-cache.key" = {};
"object/hedgedoc.env" = {};
"object/wastebin.env" = {};
};
@@ -58,6 +66,7 @@ in
9000 9001
config.services.sharry.config.bind.port
8069
5000
config.services.hedgedoc.settings.port
8088
];
@@ -68,14 +77,26 @@ in
};
};
users = with lib.my.c.ids; let inherit (config.services.atticd) user group; in {
users = with lib.my.c.ids; mkMerge [
(let inherit (config.services.atticd) user group; in {
users."${user}" = {
isSystemUser = true;
uid = uids.atticd;
group = group;
};
groups."${user}".gid = gids.atticd;
})
{
users = {
harmonia = {
shell = pkgs.bashInteractive;
openssh.authorizedKeys.keyFiles = [
lib.my.c.sshKeyFiles.harmonia
];
};
};
}
];
systemd = {
network.networks."80-container-host0" = networkdAssignment "host0" assignments.internal;
@@ -93,7 +114,9 @@ in
MINIO_BROWSER_REDIRECT_URL = "https://minio.nul.ie";
};
};
sharry = awaitPostgres;
atticd = mkMerge [
awaitPostgres
{
@@ -104,6 +127,15 @@ in
};
}
];
harmonia = {
environment.NIX_REMOTE = "/var/lib/harmonia";
preStart = ''
${config.nix.package}/bin/nix store ping
'';
serviceConfig = {
StateDirectory = "harmonia";
};
};
};
};
@@ -183,8 +215,8 @@ in
};
atticd = {
enable = true;
credentialsFile = config.age.secrets."object/atticd.env".path;
enable = false;
environmentFile = config.age.secrets."object/atticd.env".path;
settings = {
listen = "[::]:8069";
allowed-hosts = [ "nix-cache.${pubDomain}" ];
@@ -203,6 +235,14 @@ in
};
};
harmonia = {
enable = true;
signKeyPaths = [ config.age.secrets."nix-cache.key".path ];
settings = {
priority = 30;
};
};
hedgedoc = {
enable = true;
environmentFile = config.age.secrets."object/hedgedoc.env".path;
@@ -226,10 +266,10 @@ in
wastebin = {
enable = true;
settings = {
WASTEBIN_MAX_BODY_SIZE = "67108864"; # 16 MiB
WASTEBIN_MAX_BODY_SIZE = 67108864; # 16 MiB
WASTEBIN_PASSWORD_SALT = "TeGhaemeer0Siez3";
};
extraSettingsFile = config.age.secrets."object/wastebin.env".path;
secretFile = config.age.secrets."object/wastebin.env".path;
};
};
}

View File

@@ -0,0 +1,115 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.colony) domain prefixes qclk;
in
{
nixos.systems.qclk = { config, ... }: {
system = "x86_64-linux";
nixpkgs = "mine";
rendered = config.configuration.config.my.asContainer;
assignments = {
internal = {
name = "qclk-ctr";
inherit domain;
ipv4.address = net.cidr.host 10 prefixes.ctrs.v4;
ipv6 = {
iid = "::a";
address = net.cidr.host 10 prefixes.ctrs.v6;
};
};
qclk = {
ipv4 = {
address = net.cidr.host 1 prefixes.qclk.v4;
gateway = null;
};
};
};
configuration = { lib, pkgs, config, assignments, ... }:
let
inherit (lib) concatStringsSep mkMerge mkIf mkForce;
inherit (lib.my) networkdAssignment;
apiPort = 8080;
instances = [
{
host = 2;
wgKey = "D7z1FhcdxpnrGCE0wBW5PZb5BKuhCu6tcZ/5ZaYxdwQ=";
}
];
ipFor = i: net.cidr.host i.host prefixes.qclk.v4;
in
{
config = {
environment = {
systemPackages = with pkgs; [
wireguard-tools
];
};
my = {
deploy.enable = false;
server.enable = true;
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC1kcfvahYmSk8IJKaUIcGkhxf/8Yse2XnU7Qqgcglyq";
files = {
"qclk/wg.key" = {
group = "systemd-network";
mode = "440";
};
};
};
firewall = {
udp.allowed = [ qclk.wgPort ];
extraRules = ''
table inet filter {
chain input {
iifname management tcp dport ${toString apiPort} accept
}
chain forward {
iifname host0 oifname management ip saddr { ${concatStringsSep ", " lib.my.c.as211024.trusted.v4} } accept
}
}
table inet nat {
chain postrouting {
iifname host0 oifname management snat ip to ${assignments.qclk.ipv4.address}
}
}
'';
};
};
systemd = {
network = {
netdevs."30-management" = {
netdevConfig = {
Name = "management";
Kind = "wireguard";
};
wireguardConfig = {
PrivateKeyFile = config.age.secrets."qclk/wg.key".path;
ListenPort = qclk.wgPort;
};
wireguardPeers = map (i: {
PublicKey = i.wgKey;
AllowedIPs = [ (ipFor i) ];
}) instances;
};
networks = {
"30-container-host0" = networkdAssignment "host0" assignments.internal;
"30-management" = networkdAssignment "management" assignments.qclk;
};
};
};
services = { };
};
};
};
}

View File

@@ -83,7 +83,7 @@ in
DOMAIN = "https://pass.${lib.my.c.pubDomain}";
ROCKET_ADDRESS = "::";
ROCKET_PORT = 80;
ROCKET_PORT = 8080;
SMTP_HOST = "mail.nul.ie";
SMTP_FROM = "pass@nul.ie";
@@ -99,6 +99,8 @@ in
};
borgbackup.jobs.vaultwarden = {
readWritePaths = [ "/var/lib/borgbackup" "/var/cache/borgbackup" ];
paths = [ vwData ];
repo = "zh2855@zh2855.rsync.net:borg/vaultwarden2";
doInit = true;

View File

@@ -86,7 +86,7 @@ in
interfaceName = "tailscale0";
extraUpFlags = [
"--operator=${config.my.user.config.name}"
"--login-server=https://ts.nul.ie"
"--login-server=https://hs.nul.ie"
"--netfilter-mode=off"
"--advertise-exit-node"
"--advertise-routes=${advRoutes}"

View File

@@ -49,7 +49,11 @@ in
inherit (lib.my) networkdAssignment;
in
{
imports = [ "${modulesPath}/profiles/qemu-guest.nix" ];
imports = [
"${modulesPath}/profiles/qemu-guest.nix"
./containers-ext.nix
];
config = mkMerge [
{
@@ -90,8 +94,8 @@ in
device = "/dev/disk/by-label/minio";
fsType = "xfs";
};
"/mnt/atticd" = {
device = "/dev/disk/by-label/atticd";
"/mnt/nix-cache" = {
device = "/dev/disk/by-label/nix-cache";
fsType = "ext4";
};
};
@@ -136,10 +140,10 @@ in
};
ipv6Prefixes = [
{
ipv6PrefixConfig.Prefix = prefixes.ctrs.v6;
Prefix = prefixes.ctrs.v6;
}
];
routes = map (r: { routeConfig = r; }) [
routes = [
{
Destination = lib.my.c.tailscale.prefix.v4;
Gateway = allAssignments.waffletail.internal.ipv4.address;
@@ -148,6 +152,11 @@ in
Destination = lib.my.c.tailscale.prefix.v6;
Gateway = allAssignments.waffletail.internal.ipv6.address;
}
{
Destination = prefixes.qclk.v4;
Gateway = allAssignments.qclk.internal.ipv4.address;
}
];
}
];
@@ -202,11 +211,12 @@ in
object = {
bindMounts = {
"/mnt/minio".readOnly = false;
"/mnt/atticd".readOnly = false;
"/mnt/nix-cache".readOnly = false;
};
};
toot = {};
waffletail = {};
qclk = {};
};
in
mkMerge [

View File

@@ -52,6 +52,7 @@ in
valheim-oci = 2;
simpcraft-oci = 3;
simpcraft-staging-oci = 4;
enshrouded-oci = 5;
};
configuration = { lib, pkgs, modulesPath, config, assignments, allAssignments, ... }:
@@ -66,6 +67,7 @@ in
./valheim.nix
./minecraft
# ./enshrouded.nix
];
config = mkMerge [
@@ -108,46 +110,31 @@ in
oci-containers = {
backend = "podman";
};
# NixOS has switched to using netavark, which is native to podman. It's currently missing an option to
# disable iptables rules generation, which is very annoying.
containers.containersConf.settings.network.network_backend = mkForce "cni";
containers.containersConf.settings.network = {
network_backend = "netavark";
firewall_driver = "none";
};
};
environment = {
etc = {
"cni/net.d/90-colony.conflist".text = toJSON {
cniVersion = "0.4.0";
"containers/networks/colony.json".text = toJSON {
name = "colony";
plugins = [
{
type = "bridge";
bridge = "oci";
isGateway = true;
ipMasq = false;
hairpinMode = true;
ipam = {
type = "host-local";
routes = [
{ dst = "0.0.0.0/0"; }
{ dst = "::/0"; }
];
ranges = [
[
id = "0000000000000000000000000000000000000000000000000000000000000001";
driver = "bridge";
network_interface = "oci";
ipv6_enabled = true;
internal = false;
dns_enabled = false;
subnets = [
{
subnet = prefixes.oci.v4;
gateway = net.cidr.host 1 prefixes.oci.v4;
}
]
[
{
subnet = prefixes.oci.v6;
gateway = net.cidr.host 1 prefixes.oci.v6;
}
]
];
};
capabilities.ips = true;
}
];
};
};

View File

@@ -0,0 +1,35 @@
{ lib, config, allAssignments, ... }:
let
inherit (lib) concatStringsSep;
inherit (lib.my) dockerNetAssignment;
in
{
config = {
virtualisation.oci-containers.containers = {
enshrouded = {
image = "sknnr/enshrouded-dedicated-server@sha256:f163e8ba9caa2115d8a0a7b16c3696968242fb6fba82706d9a77a882df083497";
environment = {
SERVER_NAME = "UWUshrouded";
# SERVER_IP = "::"; # no IPv6?? :(
TZ = "Europe/Dublin";
};
environmentFiles = [ config.age.secrets."whale2/enshrouded.env".path ];
volumes = [
"enshrouded:/home/steam/enshrouded/savegame"
];
extraOptions = [
''--network=colony:${dockerNetAssignment allAssignments "enshrouded-oci"}''
];
};
};
my = {
secrets.files = {
"whale2/enshrouded.env" = {};
};
};
};
}

View File

@@ -123,6 +123,7 @@ in
within = "12H";
hourly = 48;
};
readWritePaths = [ "/var/lib/borgbackup" "/var/cache/borgbackup" ];
# Avoid Minecraft poking the files while we back up
preHook = rconCommand "save-off";

View File

@@ -1,7 +1,8 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.home) domain vlans prefixes;
inherit (lib.my.c) networkd;
inherit (lib.my.c.home) domain vlans prefixes vips roceBootModules;
in
{
nixos.systems.castle = {
@@ -15,7 +16,7 @@ in
ipv4 = {
address = net.cidr.host 40 prefixes.hi.v4;
mask = 22;
gateway = null;
gateway = vips.hi.v4;
};
ipv6 = {
iid = "::3:1";
@@ -35,7 +36,7 @@ in
cpu = {
amd.updateMicrocode = true;
};
opengl.extraPackages = with pkgs; [
graphics.extraPackages = with pkgs; [
intel-media-driver
];
bluetooth.enable = true;
@@ -47,7 +48,7 @@ in
timeout = 10;
};
kernelPackages = lib.my.c.kernel.latest pkgs;
kernelModules = [ "kvm-amd" ];
kernelModules = [ "kvm-amd" "dm-snapshot" ];
kernelParams = [ "amd_iommu=on" "amd_pstate=passive" ];
kernelPatches = [
# {
@@ -57,27 +58,40 @@ in
# }
];
initrd = {
availableKernelModules = [ "thunderbolt" "xhci_pci" "nvme" "ahci" "usbhid" "usb_storage" "sd_mod" ];
availableKernelModules = [
"thunderbolt" "xhci_pci" "nvme" "ahci" "usbhid" "usb_storage" "sd_mod"
"8021q"
] ++ roceBootModules;
systemd.network = {
netdevs = mkVLAN "lan-hi" vlans.hi;
networks = {
"10-et100g" = {
matchConfig.Name = "et100g";
vlan = [ "lan-hi" ];
linkConfig.RequiredForOnline = "no";
networkConfig = networkd.noL3;
};
"20-lan-hi" = networkdAssignment "lan-hi" assignments.hi;
};
};
};
binfmt.emulatedSystems = [ "aarch64-linux" "armv7l-linux" ];
};
fileSystems = {
"/boot" = {
device = "/dev/disk/by-partuuid/8ce4248a-3ee4-f44f-801f-064a628b4d6e";
fsType = "vfat";
};
"/nix" = {
device = "/dev/disk/by-partuuid/2da23a1d-2daf-d943-b91e-fc175f3dad07";
device = "/dev/nvmeof/nix";
fsType = "ext4";
};
"/persist" = {
device = "/dev/disk/by-partuuid/f4c80d4f-a022-e941-b5d1-fe2e65e444b9";
device = "/dev/nvmeof/persist";
fsType = "ext4";
neededForBoot = true;
};
"/home" = {
device = "/dev/disk/by-partuuid/992a93cf-6c9c-324b-b0ce-f8eb2d1ce10d";
device = "/dev/nvmeof/home";
fsType = "ext4";
};
};
@@ -102,7 +116,7 @@ in
};
pipewire.extraConfig.pipewire = {
"context.properties" = {
"10-buffer"."context.properties" = {
"default.clock.quantum" = 128;
"default.clock.max-quantum" = 128;
};
@@ -120,7 +134,7 @@ in
virtualisation.libvirtd.enable = true;
networking = {
domain = "h.${lib.my.c.pubDomain}";
inherit domain;
firewall.enable = false;
};
@@ -140,11 +154,14 @@ in
nix = {
gc.automatic = false;
settings = {
experimental-features = [ "recursive-nix" ];
system-features = [ "nixos-test" "benchmark" "big-parallel" "kvm" "recursive-nix" ];
};
};
systemd = {
network = {
wait-online.enable = false;
netdevs = mkMerge [
(mkVLAN "lan-hi" vlans.hi)
];
@@ -161,29 +178,20 @@ in
matchConfig.PermanentMACAddress = "24:8a:07:a8:fe:3a";
linkConfig = {
Name = "et100g";
MTUBytes = "9000";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
};
networks = {
"50-lan" = {
matchConfig.Name = "et2.5g";
DHCP = "no";
address = [ "10.16.7.1/16" ];
};
"50-et100g" = {
"30-et100g" = {
matchConfig.Name = "et100g";
vlan = [ "lan-hi" ];
networkConfig.IPv6AcceptRA = false;
};
"60-lan-hi" = mkMerge [
"40-lan-hi" = mkMerge [
(networkdAssignment "lan-hi" assignments.hi)
{
DHCP = "yes";
matchConfig.Name = "lan-hi";
linkConfig.MTUBytes = "9000";
}
# So we don't drop the IP we use to connect to NVMe-oF!
{ networkConfig.KeepConfiguration = "static"; }
];
};
};
@@ -203,10 +211,7 @@ in
packages = with pkgs; [
jacktrip
qpwgraph
# TODO: seems to be borked (infinite recursion???)
# (writeShellScriptBin "boardie" ''
# exec pw-jack ${boardie}/bin/boardie "$@"
# '')
boardie
];
};
@@ -220,6 +225,7 @@ in
HDMI-A-1 = {
transform = "270";
position = "0 0";
bg = "${./his-team-player.jpg} fill";
};
DP-1 = {
mode = "2560x1440@170Hz";
@@ -241,11 +247,19 @@ in
};
#deploy.generate.system.mode = "boot";
deploy.node.hostname = "castle.box.${config.networking.domain}";
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMlVuTzKObeaUuPocCF41IO/8X+443lzUJLuCIclt2vr";
};
nvme.uuid = "2230b066-a674-4f45-a1dc-f7727b3a9e7b";
netboot.client = {
enable = true;
};
nvme = {
uuid = "2230b066-a674-4f45-a1dc-f7727b3a9e7b";
boot = {
nqn = "nqn.2016-06.io.spdk:castle";
address = "192.168.68.80";
};
};
firewall = {
enable = false;

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

View File

@@ -94,7 +94,7 @@ in
extraOptions = [ "-A /var/log/smartd/" "--interval=600" ];
};
udev.extraRules = ''
ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_DRIVER}=="mlx5_core", ENV{ID_PATH}=="pci-0000:44:00.0", ATTR{device/sriov_numvfs}="3"
ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_DRIVER}=="mlx5_core", ENV{ID_PATH}=="pci-0000:44:00.0", ATTR{device/sriov_numvfs}="4"
'';
};
@@ -188,6 +188,13 @@ in
VLANId=${toString vlans.hi}
LinkState=yes
MACAddress=52:54:00:ac:15:a9
# sfh bridge
[SR-IOV]
VirtualFunction=3
VLANId=${toString vlans.hi}
LinkState=yes
MACAddress=52:54:00:90:34:95
'';
};
"60-lan-hi" = networkdAssignment "lan-hi" assignments.hi;

View File

@@ -66,6 +66,7 @@ in
];
services = {
fstrim.enable = true;
netdata.enable = true;
};

View File

@@ -129,6 +129,12 @@ in
hostnqn =
"nqn.2014-08.org.nvmexpress:uuid:2230b066-a674-4f45-a1dc-f7727b3a9e7b";
serial = "SPDK00000000000002";
}) ++ (nvmfBdev {
bdev = "NVMeRaidp3";
nqn = "nqn.2016-06.io.spdk:sfh";
hostnqn =
"nqn.2014-08.org.nvmexpress:uuid:85d7df36-0de0-431b-b06e-51f7c0a455b4";
serial = "SPDK00000000000003";
});
};
};

View File

@@ -2,6 +2,7 @@
imports = [
./cellar
./river.nix
./sfh
];
nixos.systems.palace.configuration = { lib, pkgs, config, systems, allAssignments, ... }:
@@ -57,11 +58,11 @@
systemd.services =
let
awaitCellar = {
after = [ "vm@cellar.service" ];
bindsTo = [ "vm@cellar.service" ];
awaitVM = system: {
after = [ "vm@${system}.service" ];
bindsTo = [ "vm@${system}.service" ];
preStart = ''
until ${pkgs.netcat}/bin/nc -w1 -z ${allAssignments.cellar.hi.ipv4.address} 22; do
until ${pkgs.netcat}/bin/nc -w1 -z ${allAssignments.${system}.hi.ipv4.address} 22; do
sleep 1
done
'';
@@ -81,13 +82,13 @@
vtapUnit = "sys-subsystem-net-devices-vm\\x2det1g0.device";
in
mkMerge [
awaitCellar
(awaitVM "cellar")
{
requires = [ vtapUnit ];
after = [ vtapUnit ];
}
];
"vm@sfh" = awaitCellar;
"vm@sfh" = (awaitVM "river");
};
my = {
@@ -182,6 +183,10 @@
index = 0;
hostBDF = "44:00.3";
};
et100g0vf3 = {
index = 1;
hostBDF = "44:00.4";
};
};
};
};

View File

@@ -10,18 +10,7 @@
let
inherit (lib.my) networkdAssignment mkVLAN;
inherit (lib.my.c) networkd;
inherit (lib.my.c.home) vlans;
lanLink = {
matchConfig = {
Driver = "mlx5_core";
PermanentMACAddress = "52:54:00:8a:8a:f2";
};
linkConfig = {
Name = "lan";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
inherit (lib.my.c.home) vlans domain prefixes roceBootModules;
in
{
imports = [
@@ -30,29 +19,17 @@
config = {
boot = {
kernelModules = [ "kvm-intel" ];
kernelModules = [ "kvm-amd" ];
kernelParams = [ "console=ttyS0,115200n8" ];
initrd = {
availableKernelModules = [
"virtio_pci" "ahci" "sr_mod" "virtio_blk"
"ib_core" "ib_uverbs" "mlx5_core" "mlx5_ib" "8021q"
"rdma_cm" "iw_cm" "ib_cm" "nvme_core" "nvme_rdma"
];
kernelModules = [ "dm-snapshot" "nvme-fabrics" ];
"8021q"
] ++ roceBootModules;
kernelModules = [ "dm-snapshot" ];
systemd = {
extraBin = with pkgs; {
dmesg = "${util-linux}/bin/dmesg";
ip = "${iproute2}/bin/ip";
};
extraConfig = ''
DefaultTimeoutStartSec=50
DefaultDeviceTimeoutSec=50
'';
network = {
enable = true;
wait-online.enable = true;
links."10-lan" = lanLink;
# Don't need to put the link config here, they're copied from main config
netdevs = mkVLAN "lan-hi" vlans.hi;
networks = {
"20-lan" = {
@@ -70,9 +47,6 @@
hardware = {
enableRedistributableFirmware = true;
cpu = {
intel.updateMicrocode = true;
};
};
fileSystems = {
@@ -96,6 +70,7 @@
boot.thin.enable = true;
dmeventd.enable = true;
};
fstrim.enable = true;
};
systemd.network = {
@@ -114,7 +89,16 @@
};
};
"10-lan" = lanLink;
"10-lan" = {
matchConfig = {
Driver = "mlx5_core";
PermanentMACAddress = "52:54:00:8a:8a:f2";
};
linkConfig = {
Name = "lan";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
};
# So we don't drop the IP we use to connect to NVMe-oF!
@@ -134,6 +118,14 @@
};
};
netboot.server = {
enable = true;
ip = assignments.lo.ipv4.address;
host = "boot.${domain}";
allowedPrefixes = with prefixes; [ hi.v4 hi.v6 lo.v4 lo.v6 ];
instances = [ "sfh" "castle" ];
};
deploy.node.hostname = "192.168.68.1";
};
};

View File

@@ -0,0 +1,5 @@
{
imports = [
./unifi.nix
];
}

View File

@@ -0,0 +1,65 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.home) domain prefixes vips hiMTU;
in
{
nixos.systems.unifi = { config, ... }: {
system = "x86_64-linux";
nixpkgs = "mine";
rendered = config.configuration.config.my.asContainer;
assignments = {
hi = {
name = "unifi-ctr";
inherit domain;
mtu = hiMTU;
ipv4 = {
address = net.cidr.host 100 prefixes.hi.v4;
mask = 22;
gateway = vips.hi.v4;
};
ipv6 = {
iid = "::5:1";
address = net.cidr.host (65536*5+1) prefixes.hi.v6;
};
};
};
configuration = { lib, config, pkgs, assignments, ... }:
let
inherit (lib) mkMerge mkIf mkForce;
inherit (lib.my) networkdAssignment;
in
{
config = {
my = {
deploy.enable = false;
server.enable = true;
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKdgcziQki/RH7E+NH2bYnzSVKaJ27905Yo5TcOjSh/U";
files = { };
};
firewall = {
tcp.allowed = [ 8443 ];
};
};
systemd = {
network.networks."80-container-host0" = networkdAssignment "host0" assignments.hi;
};
services = {
unifi = {
enable = true;
openFirewall = true;
unifiPackage = pkgs.unifi8;
mongodbPackage = pkgs.mongodb-6_0;
};
};
};
};
};
}

View File

@@ -0,0 +1,157 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.home) domain prefixes vips hiMTU roceBootModules;
in
{
imports = [ ./containers ];
config.nixos.systems.sfh = {
system = "x86_64-linux";
nixpkgs = "mine";
home-manager = "mine";
assignments = {
hi = {
inherit domain;
mtu = hiMTU;
ipv4 = {
address = net.cidr.host 81 prefixes.hi.v4;
mask = 22;
gateway = vips.hi.v4;
};
ipv6 = {
iid = "::4:2";
address = net.cidr.host (65536*4+2) prefixes.hi.v6;
};
};
};
configuration = { lib, modulesPath, pkgs, config, assignments, allAssignments, ... }:
let
inherit (lib) mapAttrs mkMerge;
inherit (lib.my) networkdAssignment;
inherit (lib.my.c) networkd;
inherit (lib.my.c.home) domain;
in
{
imports = [
"${modulesPath}/profiles/qemu-guest.nix"
];
config = {
boot = {
kernelModules = [ "kvm-amd" ];
kernelParams = [ "console=ttyS0,115200n8" ];
initrd = {
availableKernelModules = [
"virtio_pci" "ahci" "sr_mod" "virtio_blk"
] ++ roceBootModules;
kernelModules = [ "dm-snapshot" ];
systemd = {
network = {
networks = {
"20-lan-hi" = networkdAssignment "lan-hi" assignments.hi;
};
};
};
};
};
hardware = {
enableRedistributableFirmware = true;
};
fileSystems = {
"/nix" = {
device = "/dev/main/nix";
fsType = "ext4";
};
"/persist" = {
device = "/dev/main/persist";
fsType = "ext4";
neededForBoot = true;
};
};
networking = { inherit domain; };
services = {
lvm = {
boot.thin.enable = true;
dmeventd.enable = true;
};
};
systemd.network = {
links = {
"10-lan-hi" = {
matchConfig = {
Driver = "mlx5_core";
PermanentMACAddress = "52:54:00:ac:15:a9";
};
linkConfig = {
Name = "lan-hi";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
"10-lan-hi-ctrs" = {
matchConfig = {
Driver = "mlx5_core";
PermanentMACAddress = "52:54:00:90:34:95";
};
linkConfig = {
Name = "lan-hi-ctrs";
MTUBytes = toString lib.my.c.home.hiMTU;
};
};
};
networks = {
"30-lan-hi" = mkMerge [
(networkdAssignment "lan-hi" assignments.hi)
# So we don't drop the IP we use to connect to NVMe-oF!
{ networkConfig.KeepConfiguration = "static"; }
];
"30-lan-hi-ctrs" = {
matchConfig.Name = "lan-hi-ctrs";
linkConfig.RequiredForOnline = "no";
networkConfig = networkd.noL3;
};
};
};
my = {
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAAaav5Se1E/AbqEXmADryVszYfNDscyP6jrWioN57R7";
};
server.enable = true;
netboot.client = {
enable = true;
};
nvme = {
uuid = "85d7df36-0de0-431b-b06e-51f7c0a455b4";
boot = {
nqn = "nqn.2016-06.io.spdk:sfh";
address = "192.168.68.80";
};
};
containers.instances =
let
instances = {
unifi = {};
};
in
mkMerge [
instances
(mapAttrs (n: i: {
networking.macVLAN = "lan-hi-ctrs";
}) instances)
];
};
};
};
};
}

View File

@@ -148,9 +148,11 @@ in
};
};
};
nginx.enable = true;
};
networking.domain = "h.${pubDomain}";
networking = { inherit domain; };
systemd.services =
let
@@ -225,8 +227,8 @@ in
networkConfig = networkd.noL3;
extraConfig = ''
[CAKE]
Bandwidth=235M
RTTSec=10ms
Bandwidth=490M
RTTSec=50ms
PriorityQueueingPreset=besteffort
# DOCSIS preset
OverheadBytes=18
@@ -249,8 +251,8 @@ in
extraConfig = ''
[CAKE]
Parent=root
Bandwidth=24M
RTTSec=1ms
Bandwidth=48M
RTTSec=50ms
'';
}
];
@@ -274,7 +276,7 @@ in
{
matchConfig.Name = "as211024";
networkConfig.IPv6AcceptRA = mkForce false;
routes = map (r: { routeConfig = r; }) [
routes = [
{
Destination = lib.my.c.colony.prefixes.all.v4;
Gateway = allAssignments.estuary.as211024.ipv4.address;
@@ -299,7 +301,7 @@ in
{
"60-lan-hi" = {
routes = map (r: { routeConfig = r; }) [
routes = [
{
Destination = elemAt routersPubV4 otherIndex;
Gateway = net.cidr.host (otherIndex + 1) prefixes.hi.v4;
@@ -370,6 +372,16 @@ in
return
}
chain forward-early {
type filter hook forward priority -1; policy accept;
# MSS clamping to workaround IPv6 PMTUD being broken...
tcp flags syn tcp option maxseg size set rt mtu counter
# More Disney+ discrimination...
# TODO: This prefix could change (random AWS block)
ip6 daddr 2600:9000:2245::/48 drop
}
chain forward {
${lib.my.c.as211024.nftTrust}
iifname lan-untrusted jump filter-untrusted

View File

@@ -61,6 +61,19 @@ in
webserver = true;
webserver-address = "::";
webserver-allow-from = [ "127.0.0.1" "::1" ];
lua-dns-script = pkgs.writeText "pdns-script.lua" ''
-- Disney+ doesn't like our IP space...
function preresolve(dq)
local name = dq.qname:toString()
if dq.qtype == pdns.AAAA and (string.find(name, "disneyplus") or string.find(name, "disney-plus") or string.find(name , "disney.api")) then
dq.rcode = 0
return true
end
return false
end
'';
};
};
};
@@ -157,8 +170,9 @@ in
hostname = "${otherName}.${config.networking.domain}";
server = net.cidr.host (otherIndex + 1) prefixes.hi.v4;
}}
${elemAt routers 0} IN AAAA ${net.cidr.host 1 prefixes.hi.v6}
${elemAt routers 1} IN AAAA ${net.cidr.host 2 prefixes.hi.v6}
${elemAt routers 0} IN AAAA ${allAssignments."${elemAt routers 0}".as211024.ipv6.address}
${elemAt routers 1} IN AAAA ${allAssignments."${elemAt routers 1}".as211024.ipv6.address}
boot IN CNAME river-hi.${config.networking.domain}.
@ IN NS ns1
@ IN NS ns2
@@ -185,7 +199,7 @@ in
shytzel IN A ${net.cidr.host 12 prefixes.core.v4}
wave IN A ${net.cidr.host 12 prefixes.hi.v4}
wave IN AAAA ${net.cidr.host (65536+3) prefixes.hi.v6}
; wave IN AAAA ${net.cidr.host (65536+3) prefixes.hi.v6}
vibe IN A ${net.cidr.host 13 prefixes.hi.v4}
vibe IN AAAA ${net.cidr.host (65536+4) prefixes.hi.v6}

View File

@@ -1,7 +1,7 @@
index: { lib, pkgs, assignments, ... }:
index: { lib, pkgs, config, assignments, allAssignments, ... }:
let
inherit (lib) mkForce;
inherit (lib.my) net;
inherit (lib.my) net netbootKeaClientClasses;
inherit (lib.my.c.home) domain prefixes vips hiMTU;
dns-servers = [
@@ -26,7 +26,11 @@ in
};
systemd.services = {
kea-dhcp4-server.serviceConfig.DynamicUser = mkForce false;
kea-dhcp4-server.serviceConfig = {
# Sometimes interfaces might not be ready in time and Kea doesn't like that
Restart = "on-failure";
DynamicUser = mkForce false;
};
kea-dhcp-ddns-server.serviceConfig.DynamicUser = mkForce false;
};
@@ -59,6 +63,14 @@ in
always-send = true;
}
];
client-classes = netbootKeaClientClasses {
tftpIP = allAssignments.river.lo.ipv4.address;
hostname = "boot.${domain}";
systems = {
sfh = "52:54:00:a5:7e:93";
castle = "c8:7f:54:6e:17:0f";
};
};
subnet4 = [
{
id = 1;

View File

@@ -1,52 +1,83 @@
index: { lib, pkgs, config, ... }:
let
inherit (builtins) attrNames concatMap;
inherit (lib) optional;
inherit (builtins) attrNames concatMap length;
inherit (lib) optional concatMapStringsSep;
inherit (lib.my) net;
inherit (lib.my.c.home) prefixes vips;
pingScriptFor = name: ips:
let
script' = pkgs.writeShellScript
"keepalived-ping-${name}"
(concatMapStringsSep " || " (ip: "${pkgs.iputils}/bin/ping -qnc 1 -W 1 ${ip}") ips);
in
{
script = toString script';
interval = 1;
timeout = (length ips) + 1;
rise = 3;
fall = 3;
};
vlanIface = vlan: if vlan == "as211024" then vlan else "lan-${vlan}";
vrrpIPs = family: concatMap (vlan: [
vrrpIPs = family: concatMap (vlan: (optional (family == "v6") {
addr = "fe80::1/64";
dev = vlanIface vlan;
}) ++ [
{
addr = "${vips.${vlan}.${family}}/${toString (net.cidr.length prefixes.${vlan}.${family})}";
dev = vlanIface vlan;
}
] ++ (optional (family == "v6") {
addr = "fe80::1/64";
dev = vlanIface vlan;
})) (attrNames vips);
]) (attrNames vips);
mkVRRP = family: routerId: {
state = if index == 0 then "MASTER" else "BACKUP";
interface = "lan-core";
priority = 255 - index;
virtualRouterId = routerId;
virtualIps = vrrpIPs family;
extraConfig = ''
notify_master "${config.systemd.package}/bin/systemctl start radvd.service"
notify_backup "${config.systemd.package}/bin/systemctl stop radvd.service"
'';
trackScripts = [ "${family}Alive" ];
};
in
{
users = with lib.my.c.ids; {
users.keepalived_script = {
uid = uids.keepalived_script;
isSystemUser = true;
group = "keepalived_script";
};
groups.keepalived_script.gid = gids.keepalived_script;
};
services = {
keepalived = {
enable = true;
enableScriptSecurity = true;
extraGlobalDefs = ''
vrrp_version 3
nftables keepalived
'';
vrrpScripts = {
v4Alive = pingScriptFor "v4" [ "1.1.1.1" "8.8.8.8" "216.218.236.2" ];
v6Alive = pingScriptFor "v6" [ "2606:4700:4700::1111" "2001:4860:4860::8888" "2600::" ];
};
vrrpInstances = {
v4 = mkVRRP "v4" 51;
v6 = mkVRRP "v6" 52;
};
v6 = (mkVRRP "v6" 52) // {
extraConfig = ''
vrrp_sync_group main {
group {
v4
v6
}
}
notify_master "${config.systemd.package}/bin/systemctl start radvd.service" root
notify_backup "${config.systemd.package}/bin/systemctl stop radvd.service" root
'';
};
};
# Actually disable this for now, don't want to fault IPv4 just because IPv6 is broken...
# extraConfig = ''
# vrrp_sync_group main {
# group {
# v4
# v6
# }
# }
# '';
};
};
}

View File

@@ -43,6 +43,38 @@
};
};
services = {
mjpg-streamer = {
enable = true;
inputPlugin = "input_uvc.so";
outputPlugin = "output_http.so -w @www@ -n -p 5050";
};
octoprint = {
enable = true;
host = "::";
extraConfig = {
plugins = {
classicwebcam = {
snapshot = "/webcam/?action=snapshot";
stream = "/webcam/?action=stream";
streamRatio = "4:3";
};
};
serial = {
port = "/dev/ttyACM0";
baudrate = 115200;
};
temperature.profiles = [
{
bed = 60;
extruder = 215;
name = "PLA";
}
];
};
};
};
systemd.network = {
netdevs = {
"25-lan" = {
@@ -123,7 +155,7 @@
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPYTB4zeAqotrEJ8M+AiGm/s9PFsWlAodz3hYSROGuDb";
};
server.enable = true;
deploy.node.hostname = "192.168.68.2";
# deploy.node.hostname = "192.168.68.2";
};
};
};

View File

@@ -26,7 +26,7 @@ in
config = {
# Hardware acceleration for Jellyfin
hardware.opengl = {
hardware.graphics = {
enable = true;
extraPackages = with pkgs; [
vaapiIntel
@@ -78,6 +78,14 @@ in
};
};
nixpkgs.config.permittedInsecurePackages = [
# FIXME: This is needed for Sonarr
"aspnetcore-runtime-wrapped-6.0.36"
"aspnetcore-runtime-6.0.36"
"dotnet-sdk-wrapped-6.0.428"
"dotnet-sdk-6.0.428"
];
services = {
transmission = {
enable = true;

View File

@@ -2,6 +2,7 @@
let
inherit (lib) mkMerge mkIf;
inherit (lib.my) networkdAssignment;
inherit (lib.my.c.kelder) ipv4MTU;
wg = {
keyFile = "kelder/acquisition/airvpn-privkey";
@@ -72,14 +73,12 @@ in
RouteTable = routeTable;
};
wireguardPeers = [
{
# AirVPN IE
wireguardPeerConfig = {
{
Endpoint = "146.70.94.2:1637";
PublicKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk=";
PresharedKeyFile = config.age.secrets."${pskFile}".path;
AllowedIPs = [ "0.0.0.0/0" "::/0" ];
};
}
];
};
@@ -89,13 +88,14 @@ in
(networkdAssignment "host0" assignments.internal)
{
networkConfig.DNSDefaultRoute = false;
linkConfig.MTUBytes = toString ipv4MTU;
}
];
"90-vpn" = with wg; {
matchConfig.Name = "vpn";
address = [ "10.161.170.28/32" "fd7d:76ee:e68f:a993:b12d:6d15:c80a:9516/128" ];
dns = [ "10.128.0.1" "fd7d:76ee:e68f:a993::1" ];
routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [
routingPolicyRules = [
{
Family = "both";
SuppressPrefixLength = 0;

View File

@@ -92,7 +92,7 @@ in
nextcloud = {
enable = true;
package = pkgs.nextcloud28;
package = pkgs.nextcloud29;
datadir = "/mnt/storage/nextcloud";
hostName = "cloud.${domain}";
https = true;

View File

@@ -84,6 +84,7 @@ in
c
];
acquisition = "http://${allAssignments.kelder-acquisition.internal.ipv4.address}";
# This is kinda borked because Virgin Media filters DNS responses with local IPs...
localRedirect = to: ''
rewrite_by_lua_block {
if ngx.var.remote_addr == pub_ip then
@@ -103,7 +104,7 @@ in
"monitor.${domain}" = withAuth {
serverAliases = [ "monitor-local.${domain}" ];
extraConfig = localRedirect "monitor-local.${domain}";
# extraConfig = localRedirect "monitor-local.${domain}";
locations = {
"/" = {
proxyPass = "http://${allAssignments.kelder.ctrs.ipv4.address}:19999";
@@ -136,17 +137,17 @@ in
};
"torrents.${domain}" = withAuth {
serverAliases = [ "torrents-local.${domain}" ];
extraConfig = localRedirect "torrents-local.${domain}";
# extraConfig = localRedirect "torrents-local.${domain}";
locations."/".proxyPass = "${acquisition}:9091";
};
"jackett.${domain}" = withAuth {
serverAliases = [ "jackett-local.${domain}" ];
extraConfig = localRedirect "jackett-local.${domain}";
# extraConfig = localRedirect "jackett-local.${domain}";
locations."/".proxyPass = "${acquisition}:9117";
};
"radarr.${domain}" = withAuth {
serverAliases = [ "radarr-local.${domain}" ];
extraConfig = localRedirect "radarr-local.${domain}";
# extraConfig = localRedirect "radarr-local.${domain}";
locations."/" = {
proxyPass = "${acquisition}:7878";
proxyWebsockets = true;
@@ -155,7 +156,7 @@ in
};
"sonarr.${domain}" = withAuth {
serverAliases = [ "sonarr-local.${domain}" ];
extraConfig = localRedirect "sonarr-local.${domain}";
# extraConfig = localRedirect "sonarr-local.${domain}";
locations."/" = {
proxyPass = "${acquisition}:8989";
proxyWebsockets = true;

View File

@@ -1,7 +1,7 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c.kelder) domain prefixes;
inherit (lib.my.c.kelder) domain prefixes ipv4MTU;
in
{
imports = [ ./containers ];
@@ -121,8 +121,7 @@ in
samba = {
enable = true;
enableNmbd = true;
shares = {
settings = {
storage = {
path = "/mnt/storage";
browseable = "yes";
@@ -131,6 +130,8 @@ in
"directory mask" = "0775";
};
};
nmbd.enable = true;
};
samba-wsdd.enable = true;
@@ -180,12 +181,10 @@ in
};
wireguardPeers = [
{
wireguardPeerConfig = {
PublicKey = "bP1XUNxp9i8NLOXhgPaIaRzRwi5APbam44/xjvYcyjU=";
Endpoint = "estuary-vm.${lib.my.c.colony.domain}:${toString lib.my.c.kelder.vpn.port}";
Endpoint = "${allAssignments.estuary.internal.ipv4.address}:${toString lib.my.c.kelder.vpn.port}";
AllowedIPs = [ "0.0.0.0/0" ];
PersistentKeepalive = 25;
};
}
];
};
@@ -200,6 +199,7 @@ in
"50-lan" = {
matchConfig.Name = "et1g0";
DHCP = "yes";
linkConfig.MTUBytes = toString ipv4MTU;
};
"80-ctrs" = mkMerge [
(networkdAssignment "ctrs" assignments.ctrs)
@@ -212,7 +212,7 @@ in
address = with assignments.estuary; [
(with ipv4; "${address}/${toString mask}")
];
routingPolicyRules = map (r: { routingPolicyRuleConfig = r; }) [
routingPolicyRules = [
{
Family = "both";
SuppressPrefixLength = 0;
@@ -272,7 +272,7 @@ in
config.name = "kontent";
};
#deploy.node.hostname = "10.16.9.21";
# deploy.node.hostname = "192.168.0.69";
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFvUdJshXkqmchEgkZDn5rgtZ1NO9vbd6Px+S6YioWi";
files = {

View File

@@ -14,7 +14,7 @@
cpu = {
intel.updateMicrocode = true;
};
opengl.extraPackages = with pkgs; [
graphics.extraPackages = with pkgs; [
intel-media-driver
];
bluetooth.enable = true;
@@ -129,10 +129,9 @@
wifi = {
backend = "wpa_supplicant";
};
extraConfig = ''
[main]
no-auto-default=*
'';
settings = {
main.no-auto-default = "*";
};
};
};
@@ -178,7 +177,7 @@
programs = {
fish = {
shellAbbrs = {
tsup = "doas tailscale up --login-server=https://ts.nul.ie --accept-routes";
tsup = "doas tailscale up --login-server=https://hs.nul.ie --accept-routes";
};
};
};

View File

@@ -35,7 +35,7 @@ let
system = null;
# Put the inputs in specialArgs to avoid infinite recursion when modules try to do imports
specialArgs = { inherit inputs pkgsFlakes pkgsFlake allAssignments; inherit (cfg) systems; };
specialArgs = { inherit self inputs pkgsFlakes pkgsFlake allAssignments; inherit (cfg) systems; };
# `baseModules` informs the manual which modules to document
baseModules =
@@ -135,6 +135,7 @@ let
ipv6 = mkBoolOpt' false "Whether this mesh's underlay operates over IPv6.";
baseMTU = mkOpt' ints.unsigned 1500 "Base MTU to calculate VXLAN MTU with.";
l3Overhead = mkOpt' ints.unsigned 40 "Overhead of L3 header (to calculate MTU).";
udpEncapsulation = mkBoolOpt' false "Whether to encapsulate ESP frames in UDP.";
firewall = mkBoolOpt' true "Whether to generate firewall rules.";
vni = mkOpt' ints.unsigned 1 "VXLAN VNI.";
peers = mkOpt' (attrsOf (submodule l2PeerOpts)) { } "Peers.";

View File

@@ -1,7 +1,7 @@
{
nixos.systems.installer = { config, ... }: {
system = "x86_64-linux";
nixpkgs = "unstable";
nixpkgs = "mine";
docCustom = false;
rendered = config.configuration.config.my.asISO;
@@ -52,6 +52,8 @@
home.shellAliases = {
show-hw-config = "nixos-generate-config --show-hardware-config --root $INSTALL_ROOT";
};
my.gui.enable = false;
};
services = {
@@ -59,8 +61,8 @@
};
networking = {
# Will be set dynamically
hostName = "";
# Will be set dynamically, but need something to satisfy `/etc/os-release` stuff
hostName = "installer";
useNetworkd = false;
};
@@ -80,6 +82,8 @@
${pkgs.gawk}/bin/awk '{ print $1 }')"
'';
boot.supportedFilesystems.nfs = true;
environment.systemPackages = with pkgs; [
dhcpcd
lm_sensors

View File

@@ -20,6 +20,6 @@
nvme = ./nvme;
spdk = ./spdk.nix;
librespeed = ./librespeed;
wastebin = ./wastebin.nix;
netboot = ./netboot;
};
}

View File

@@ -1,6 +1,6 @@
{ lib, pkgs, extendModules, modulesPath, options, config, ... }:
let
inherit (lib) recursiveUpdate mkOption mkDefault mkIf mkMerge flatten optional;
inherit (lib) recursiveUpdate mkOption mkDefault mkIf mkMerge mkForce flatten optional;
inherit (lib.my) mkBoolOpt' dummyOption;
cfg = config.my.build;
@@ -43,15 +43,145 @@ let
modules = flatten [
"${modulesPath}/installer/netboot/netboot.nix"
allHardware
];
};
asNetboot = extendModules {
modules = flatten [
allHardware
({ pkgs, config, ... }: {
system.build.netbootArchive = pkgs.runCommand "netboot-${config.system.name}-archive.tar" { } ''
${pkgs.gnutar}/bin/tar -rvC "${config.system.build.kernel}" \
-f "$out" "${config.system.boot.loader.kernelFile}"
${pkgs.gnutar}/bin/tar -rvC "${config.system.build.netbootRamdisk}" \
-f "$out" initrd
${pkgs.gnutar}/bin/tar -rvC "${config.system.build.netbootIpxeScript}" \
-f "$out" netboot.ipxe
boot = {
loader.grub.enable = false;
initrd = {
kernelModules = [ "nbd" ];
availableKernelModules = [ "igb" "igc" ];
systemd = {
storePaths = with pkgs; [
gnused
nbd
netcat
];
extraBin = with pkgs; {
dmesg = "${util-linux}/bin/dmesg";
ip = "${iproute2}/bin/ip";
nbd-client = "${nbd}/bin/nbd-client";
};
extraConfig = ''
DefaultTimeoutStartSec=20
DefaultDeviceTimeoutSec=20
'';
network = {
enable = true;
wait-online.enable = true;
networks."10-netboot" = {
matchConfig.Name = "et-boot";
DHCP = "yes";
};
};
services = {
nbd = {
description = "NBD Root FS";
script = ''
get_cmdline() {
${pkgs.gnused}/bin/sed -rn "s/^.*$1=(\\S+).*\$/\\1/p" < /proc/cmdline
}
s="$(get_cmdline nbd_server)"
until ${pkgs.netcat}/bin/nc -zv "$s" 22; do
sleep 0.1
done
exec ${pkgs.nbd}/bin/nbd-client -systemd-mark -N "$(get_cmdline nbd_export)" "$s" /dev/nbd0
'';
unitConfig = {
IgnoreOnIsolate = "yes";
DefaultDependencies = "no";
};
serviceConfig = {
Type = "forking";
Restart = "on-failure";
RestartSec = 10;
};
wantedBy = [ "initrd-root-device.target" ];
};
};
};
};
postBootCommands = ''
# After booting, register the contents of the Nix store
# in the Nix database in the COW root.
${config.nix.package}/bin/nix-store --load-db < /nix-path-registration
# nixos-rebuild also requires a "system" profile and an
# /etc/NIXOS tag.
touch /etc/NIXOS
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
};
programs.nbd.enable = true;
fileSystems = {
"/" = {
fsType = "ext4";
device = "/dev/nbd0";
noCheck = true;
autoResize = true;
};
};
networking.useNetworkd = mkForce true;
systemd = {
network.networks."10-boot" = {
matchConfig.Name = "et-boot";
DHCP = "yes";
networkConfig.KeepConfiguration = "yes";
};
};
system.build = {
rootImage = pkgs.callPackage "${modulesPath}/../lib/make-ext4-fs.nix" {
storePaths = [ config.system.build.toplevel ];
volumeLabel = "netboot-root";
};
netbootScript = pkgs.writeText "boot.ipxe" ''
#!ipxe
kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ifname=et-boot:''${mac} nbd_server=''${next-server} ${toString config.boot.kernelParams} ''${cmdline}
initrd initrd
boot
'';
netbootTree = pkgs.linkFarm "netboot-${config.system.name}" [
{
name = config.system.boot.loader.kernelFile;
path = "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}";
}
{
name = "initrd";
path = "${config.system.build.initialRamdisk}/initrd";
}
{
name = "rootfs.ext4";
path = config.system.build.rootImage;
}
{
name = "boot.ipxe";
path = config.system.build.netbootScript;
}
];
netbootArchive = pkgs.runCommand "netboot-${config.system.name}.tar.zst" { } ''
export PATH=${pkgs.zstd}/bin:$PATH
${pkgs.gnutar}/bin/tar --dereference --zstd -cvC ${config.system.build.netbootTree} -f "$out" .
'';
};
})
];
};
@@ -77,6 +207,7 @@ in
asISO = mkAsOpt asISO "a bootable .iso image";
asContainer = mkAsOpt asContainer "a container";
asKexecTree = mkAsOpt asKexecTree "a kexec-able kernel and initrd";
asNetboot = mkAsOpt asNetboot "a netboot-able kernel initrd, and iPXE script";
buildAs = options.system.build;
};
@@ -110,7 +241,8 @@ in
iso = config.my.asISO.config.system.build.isoImage;
container = config.my.asContainer.config.system.build.toplevel;
kexecTree = config.my.asKexecTree.config.system.build.kexecTree;
netbootArchive = config.my.asKexecTree.config.system.build.netbootArchive;
netbootTree = config.my.asNetboot.config.system.build.netbootTree;
netbootArchive = config.my.asNetboot.config.system.build.netbootArchive;
};
};
};

View File

@@ -1,4 +1,4 @@
{ lib, pkgs, pkgs', inputs, config, ... }:
{ lib, pkgsFlake, pkgs, pkgs', self, inputs, config, ... }:
let
inherit (lib) mkIf mkDefault mkMerge;
inherit (lib.my) mkDefault';
@@ -12,7 +12,6 @@ in
inputs.impermanence.nixosModule
inputs.ragenix.nixosModules.age
inputs.sharry.nixosModules.default
inputs.attic.nixosModules.atticd
];
config = mkMerge [
@@ -41,6 +40,7 @@ in
nix = {
package = pkgs'.mine.nix;
channel.enable = false;
settings = with lib.my.c.nix; {
trusted-users = [ "@wheel" ];
experimental-features = [ "nix-command" "flakes" "ca-derivations" ];
@@ -53,7 +53,7 @@ in
pkgs = {
to = {
type = "path";
path = "${pkgs.path}";
path = "${pkgsFlake}";
};
exact = true;
};
@@ -127,6 +127,9 @@ in
};
};
environment.etc = {
"nixos/flake.nix".source = "/run/nixfiles/flake.nix";
};
environment.systemPackages = with pkgs; mkMerge [
[
bash-completion
@@ -142,7 +145,10 @@ in
fish.enable = mkDefault true;
# TODO: This is expecting to look up the channel for the database...
command-not-found.enable = mkDefault false;
vim.defaultEditor = true;
vim = {
enable = true;
defaultEditor = true;
};
};
services = {
@@ -209,14 +215,35 @@ in
# python.d plugin script does #!/usr/bin/env bash
path = with pkgs; [ bash ];
};
nixfiles-mutable = {
description = "Mutable nixfiles";
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = with pkgs; [ util-linux ];
script = ''
nixfilesDir="${self}"
mkdir -p /run/nixfiles{,/.rw,/.work}
mount -t overlay overlay -o lowerdir="$nixfilesDir",upperdir=/run/nixfiles/.rw,workdir=/run/nixfiles/.work /run/nixfiles
chmod -R u+w /run/nixfiles
'';
preStop = ''
umount /run/nixfiles
rm -rf /run/nixfiles
'';
wantedBy = [ "multi-user.target" ];
};
};
};
}
(mkIf config.services.kmscon.enable {
fonts.fonts = with pkgs; [
(nerdfonts.override {
fonts = [ "SourceCodePro" ];
})
nerd-fonts.sauce-code-pro
];
})
];

View File

@@ -1,6 +1,6 @@
{ lib, pkgs, options, config, systems, ... }:
let
inherit (builtins) attrNames attrValues all hashString toJSON;
inherit (builtins) attrNames attrValues all hashString toJSON any;
inherit (lib)
groupBy' mapAttrsToList optionalString optional concatMapStringsSep filterAttrs mkOption mkDefault mkIf mkMerge;
inherit (lib.my) mkOpt' mkBoolOpt';
@@ -98,6 +98,7 @@ let
};
networking = {
bridge = mkOpt' (nullOr str) null "Network bridge to connect to.";
macVLAN = mkOpt' (nullOr str) null "Network interface to make MACVLAN interface from.";
};
};
};
@@ -115,26 +116,19 @@ in
assertion = config.systemd.network.enable;
message = "Containers currently require systemd-networkd!";
}
{
assertion = all (i: i.networking.bridge == null || i.networking.macVLAN == null) (attrValues cfg.instances);
message = "Only bridge OR MACVLAN can be set";
}
];
# TODO: Better security
my.firewall.trustedInterfaces =
mapAttrsToList
(n: _: "ve-${n}")
(filterAttrs (_: c: c.networking.bridge == null) cfg.instances);
(filterAttrs (_: c: c.networking.bridge == null && c.networking.macVLAN == null) cfg.instances);
systemd = mkMerge ([
{
# By symlinking to the original systemd-nspawn@.service for every instance we force the unit generator to
# create overrides instead of replacing the unit entirely
packages = [
(pkgs.linkFarm "systemd-nspawn-containers" (map (n: {
name = "etc/systemd/system/systemd-nspawn@${n}.service";
path = "${pkgs.systemd}/example/systemd/system/systemd-nspawn@.service";
}) (attrNames cfg.instances)))
];
}
] ++ (mapAttrsToList (n: c: {
systemd = mkMerge (mapAttrsToList (n: c: {
nspawn."${n}" = {
execConfig = {
Boot = true;
@@ -165,6 +159,8 @@ in
};
networkConfig = if (c.networking.bridge != null) then {
Bridge = c.networking.bridge;
} else if (c.networking.macVLAN != null) then {
MACVLAN = "${c.networking.macVLAN}:host0";
} else {
VirtualEthernet = true;
};
@@ -182,6 +178,9 @@ in
c.containerSystem;
in
{
# To prevent creating a whole new unit file
overrideStrategy = "asDropin";
environment = {
# systemd.nspawn units can't set the root directory directly, but /run/machines/${n} is one of the search paths
root = "/run/machines/${n}";
@@ -247,7 +246,7 @@ in
Bridge = c.networking.bridge;
};
};
}) cfg.instances));
}) cfg.instances);
})
# Inside container

View File

@@ -12,7 +12,7 @@ in
config = mkIf cfg.enable {
hardware = {
opengl.enable = mkDefault true;
graphics.enable = mkDefault true;
};
systemd = {
@@ -23,13 +23,13 @@ in
security = {
polkit.enable = true;
pam.services.swaylock = {};
pam.services.swaylock-plugin = {};
};
environment.systemPackages = with pkgs; [
# for pw-jack
pipewire.jack
swaylock
swaylock-plugin
];
services = {
pipewire = {
@@ -51,6 +51,10 @@ in
SUBSYSTEM=="usb", ATTR{idVendor}=="0955", MODE="0664", GROUP="wheel"
# Nintendo
SUBSYSTEM=="usb", ATTR{idVendor}=="057e", MODE="0664", GROUP="wheel"
# FT
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", MODE="0664", GROUP="wheel"
# /dev/player0
SUBSYSTEM=="usb", ATTR{idVendor}=="6969", MODE="0664", GROUP="wheel"
'';
};
};

View File

@@ -36,18 +36,16 @@ let
espOverhead =
if (!mesh.security.enable) then 0
else
# SPI + seq + IV + pad / header + ICV
4 + 4 + (if mesh.security.encrypt then 8 else 0) + 2 + 16;
# UDP encap + SPI + seq + IV + pad / header + ICV
(if mesh.udpEncapsulation then 8 else 0) + 4 + 4 + (if mesh.security.encrypt then 8 else 0) + 2 + 16;
# UDP + VXLAN + Ethernet + L3 (IPv4/IPv6)
overhead = espOverhead + 8 + 8 + 14 + mesh.l3Overhead;
in
toString (mesh.baseMTU - overhead);
bridgeFDBs = mapAttrsToList (n: peer: {
bridgeFDBConfig = {
MACAddress = "00:00:00:00:00:00";
Destination = peer.addr;
};
}) otherPeers;
};
};
@@ -62,8 +60,12 @@ let
chain l2mesh-${name} {
${optionalString mesh.security.enable ''
udp dport isakmp accept
${if mesh.udpEncapsulation then ''
udp dport ipsec-nat-t accept
'' else ''
meta l4proto esp accept
''}
''}
${optionalString (!mesh.security.enable) (vxlanAllow mesh.vni)}
return
}
@@ -94,6 +96,7 @@ let
esp=${if mesh.security.encrypt then "aes_gcm256" else "null-sha256"}
ikev2=yes
modecfgpull=no
encapsulation=${if mesh.udpEncapsulation then "yes" else "no"}
'';
})
otherPeers);

View File

@@ -0,0 +1,232 @@
{ lib, pkgs, config, ... }:
let
inherit (lib) mkMerge mkIf mkForce genAttrs concatMapStringsSep;
inherit (lib.my) mkOpt' mkBoolOpt';
cfg = config.my.netboot;
ipxe = pkgs.ipxe.overrideAttrs (o: rec {
version = "1.21.1-unstable-2024-06-27";
src = pkgs.fetchFromGitHub {
owner = "ipxe";
repo = "ipxe";
rev = "b66e27d9b29a172a097c737ab4d378d60fe01b05";
hash = "sha256-TKZ4WjNV2oZIYNefch7E7m1JpeoC/d7O1kofoNv8G40=";
};
});
tftpRoot = pkgs.linkFarm "tftp-root" [
{
name = "ipxe-x86_64.efi";
path = "${ipxe}/ipxe.efi";
}
];
menuFile = pkgs.runCommand "menu.ipxe" {
bootHost = cfg.server.host;
} ''
substituteAll ${./menu.ipxe} "$out"
'';
bootBuilder = pkgs.substituteAll {
src = ./netboot-loader-builder.py;
isExecutable = true;
inherit (pkgs) python3;
bootspecTools = pkgs.bootspec;
nix = config.nix.package.out;
inherit (config.system.nixos) distroName;
systemName = config.system.name;
inherit (cfg.client) configurationLimit;
checkMountpoints = pkgs.writeShellScript "check-mountpoints" ''
if ! ${pkgs.util-linuxMinimal}/bin/findmnt /boot > /dev/null; then
echo "/boot is not a mounted partition. Is the path configured correctly?" >&2
exit 1
fi
'';
};
in
{
options.my.netboot = with lib.types; {
client = {
enable = mkBoolOpt' false "Whether network booting should be enabled.";
configurationLimit = mkOpt' ints.unsigned 10 "Max generations to show in boot menu.";
};
server = {
enable = mkBoolOpt' false "Whether a netboot server should be enabled.";
ip = mkOpt' str null "IP clients should connect to via TFTP.";
host = mkOpt' str config.networking.fqdn "Hostname clients should connect to over HTTP / NFS.";
allowedPrefixes = mkOpt' (listOf str) null "Prefixes clients should be allowed to connect from (NFS).";
installer = {
storeSize = mkOpt' str "16GiB" "Total allowed writable size of store.";
};
instances = mkOpt' (listOf str) [ ] "Systems to hold boot files for.";
};
};
config = mkMerge [
(mkIf cfg.client.enable {
systemd = {
services = {
mount-boot = {
description = "Mount /boot";
after = [ "systemd-networkd-wait-online.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
path = with pkgs; [ gnused ldns nfs-utils ];
script = ''
get_cmdline() {
sed -rn "s/^.*$1=(\\S+).*\$/\\1/p" < /proc/cmdline
}
host="$(get_cmdline boothost)"
if [ -z "$host" ]; then
echo "boothost kernel parameter not found!" >&2
exit 1
fi
until [ -n "$(drill -Q $host)" ]; do
sleep 0.1
done
mkdir -p /boot
mount.nfs $host:/srv/netboot/systems/${config.system.name} /boot
'';
wantedBy = [ "remote-fs.target" ];
};
};
};
boot.supportedFilesystems.nfs = true;
boot.loader = {
grub.enable = false;
systemd-boot.enable = false;
};
system = {
build.installBootLoader = bootBuilder;
boot.loader.id = "ipxe-netboot";
};
})
(mkIf cfg.server.enable {
environment = {
etc = {
"netboot/menu.ipxe".source = menuFile;
"netboot/shell.efi".source = "${pkgs.edk2-uefi-shell}/shell.efi";
};
};
systemd = {
tmpfiles.settings."10-netboot" = genAttrs
(map (i: "/srv/netboot/systems/${i}") cfg.server.instances)
(p: {
d = {
user = "root";
group = "root";
mode = "0777";
};
});
services = {
netboot-update = {
description = "Update netboot images";
after = [ "systemd-networkd-wait-online.service" ];
serviceConfig.Type = "oneshot";
path = with pkgs; [
coreutils curl jq zstd gnutar
];
script = ''
update_nixos() {
latestShort="$(curl -s https://git.nul.ie/api/v1/repos/dev/nixfiles/tags/installer \
| jq -r .commit.sha | cut -c -7)"
if [ -f nixos-installer/tag.txt ] && [ "$(< nixos-installer/tag.txt)" = "$latestShort" ]; then
echo "NixOS installer is up to date"
return
fi
echo "Updating NixOS installer to $latestShort"
mkdir -p nixos-installer
fname="jackos-installer-netboot-$latestShort.tar.zst"
downloadUrl="$(curl -s https://git.nul.ie/api/v1/repos/dev/nixfiles/releases/tags/installer | \
jq -r ".assets[] | select(.name == \"$fname\").browser_download_url")"
curl -Lo /tmp/nixos-installer-netboot.tar.zst "$downloadUrl"
tar -C nixos-installer --zstd -xf /tmp/nixos-installer-netboot.tar.zst
truncate -s "${cfg.server.installer.storeSize}" nixos-installer/rootfs.ext4
rm /tmp/nixos-installer-netboot.tar.zst
echo "$latestShort" > nixos-installer/tag.txt
}
mkdir -p /srv/netboot
cd /srv/netboot
ln -sf ${menuFile} boot.ipxe
ln -sf "${pkgs.edk2-uefi-shell}/shell.efi" "efi-shell-${config.nixpkgs.localSystem.linuxArch}.efi"
update_nixos
'';
startAt = "06:00";
wantedBy = [ "network-online.target" ];
};
nbd-server = {
serviceConfig = {
PrivateUsers = mkForce false;
CacheDirectory = "netboot";
};
};
};
};
services = {
atftpd = {
enable = true;
root = tftpRoot;
};
nginx = {
virtualHosts."${cfg.server.host}" = {
locations."/" = {
root = "/srv/netboot";
extraConfig = ''
autoindex on;
'';
};
};
};
nbd.server = {
enable = true;
extraOptions = {
allowlist = true;
};
exports = {
nixos-installer = {
path = "/srv/netboot/nixos-installer/rootfs.ext4";
extraOptions = {
copyonwrite = true;
cowdir = "/var/cache/netboot";
sparse_cow = true;
};
};
};
};
nfs = {
server = {
enable = true;
exports = ''
/srv/netboot/systems ${concatMapStringsSep " " (p: "${p}(rw,all_squash)") cfg.server.allowedPrefixes}
'';
};
};
};
my = {
tmproot.persistence.config.directories = [
"/srv/netboot"
{ directory = "/var/cache/netboot"; mode = "0700"; }
];
};
})
];
}

View File

@@ -0,0 +1,68 @@
#!ipxe
set server http://@bootHost@
# Figure out if client is 64-bit capable
cpuid --ext 29 && set arch x86_64 || set arch i386
isset ${menu-default} || set menu-default exit
:start
menu Welcome to /dev/player0's humble iPXE boot menu
item --gap -- Operating Systems
iseq ${arch} x86_64 &&
item --key n nixos NixOS installer
# iseq ${arch} x86_64 &&
# item --key a archlinux Arch Linux (archiso x86_64)
# iseq ${arch} x86_64 &&
# item --key p alpine Alpine Linux
item --gap -- Other Options
item --key e efi_shell UEFI Shell
item --key x xyz netboot.xyz
item --key c config iPXE settings
item --key s shell Drop to iPXE shell
item --key r reboot Reboot
item --key q exit Exit (and continue to next boot device)
choose --timeout 0 --default ${menu-default} selected || goto cancel
goto ${selected}
:cancel
echo You cancelled the menu, dropping you to an iPXE shell
:shell
echo Type 'exit' to go back to the menu
shell
set menu-default nixos
goto start
:failed
echo Booting failed, dropping to shell
goto shell
:reboot
reboot
:exit
exit
:config
config
set menu-default config
goto start
:efi_shell
chain ${server}/efi-shell-${arch}.efi || goto failed
:xyz
chain --autofree https://boot.netboot.xyz || goto failed
:nixos
set cmdline nbd_export=nixos-installer
chain ${server}/nixos-installer/boot.ipxe || goto failed
:archlinux
# set mirrorurl https://arch.nul.ie/
chain ${server}/arch.ipxe || goto failed
:alpine
chain ${server}/alpine.ipxe || goto failed

View File

@@ -0,0 +1,280 @@
#! @python3@/bin/python3 -B
# Based on `nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py`
import argparse
import datetime
import glob
import os
import os.path
import shutil
import subprocess
import sys
import json
from typing import NamedTuple, Dict, List
from dataclasses import dataclass
BOOT_MOUNT_POINT = '/boot'
STORE_DIR = 'nix'
# These values will be replaced with actual values during the package build
BOOTSPEC_TOOLS = '@bootspecTools@'
NIX = '@nix@'
DISTRO_NAME = '@distroName@'
SYSTEM_NAME = '@systemName@'
CONFIGURATION_LIMIT = int('@configurationLimit@')
CHECK_MOUNTPOINTS = "@checkMountpoints@"
@dataclass
class BootSpec:
init: str
initrd: str
kernel: str
kernelParams: List[str]
label: str
system: str
toplevel: str
specialisations: Dict[str, 'BootSpec']
sortKey: str
initrdSecrets: str | None = None
class SystemIdentifier(NamedTuple):
profile: str | None
generation: int
specialisation: str | None
def copy_if_not_exists(source: str, dest: str) -> None:
if not os.path.exists(dest):
shutil.copyfile(source, dest)
def generation_dir(profile: str | None, generation: int) -> str:
if profile:
return f'/nix/var/nix/profiles/system-profiles/{profile}-{generation}-link'
else:
return f'/nix/var/nix/profiles/system-{generation}-link'
def system_dir(i: SystemIdentifier) -> str:
d = generation_dir(i.profile, i.generation)
if i.specialisation:
return os.path.join(d, 'specialisation', i.specialisation)
else:
return d
def entry_key(i: SystemIdentifier) -> str:
pieces = [
'nixos',
i.profile or None,
'generation',
str(i.generation),
f'specialisation-{i.specialisation}' if i.specialisation else None,
]
return '-'.join(p for p in pieces if p)
def bootspec_from_json(bootspec_json: Dict) -> BootSpec:
specialisations = bootspec_json['org.nixos.specialisation.v1']
specialisations = {k: bootspec_from_json(v) for k, v in specialisations.items()}
systemdBootExtension = bootspec_json.get('org.nixos.systemd-boot', {})
sortKey = systemdBootExtension.get('sortKey', 'nixos')
return BootSpec(
**bootspec_json['org.nixos.bootspec.v1'],
specialisations=specialisations,
sortKey=sortKey
)
bootspecs = {}
def get_bootspec(profile: str | None, generation: int) -> BootSpec:
k = (profile, generation)
if k in bootspecs:
return bootspecs[k]
system_directory = system_dir(SystemIdentifier(profile, generation, None))
boot_json_path = os.path.realpath(f'{system_directory}/boot.json')
if os.path.isfile(boot_json_path):
boot_json_f = open(boot_json_path, 'r')
bootspec_json = json.load(boot_json_f)
else:
boot_json_str = subprocess.check_output([
f'{BOOTSPEC_TOOLS}/bin/synthesize',
'--version',
'1',
system_directory,
'/dev/stdout',
],
universal_newlines=True)
bootspec_json = json.loads(boot_json_str)
bs = bootspec_from_json(bootspec_json)
bootspecs[k] = bs
return bs
def copy_from_file(file: str, dry_run: bool = False) -> str:
store_file_path = os.path.realpath(file)
suffix = os.path.basename(store_file_path)
store_dir = os.path.basename(os.path.dirname(store_file_path))
dst_path = f'/{STORE_DIR}/{store_dir}-{suffix}'
if not dry_run:
copy_if_not_exists(store_file_path, f'{BOOT_MOUNT_POINT}{dst_path}')
return dst_path
MENU_ITEM = 'item {gen_key} {title} Generation {generation} {description}'
BOOT_ENTRY = ''':{gen_key}
kernel ${{server}}/systems/{system_name}{kernel} {kernel_params} boothost=${{boothost}}
initrd ${{server}}/systems/{system_name}{initrd}
boot
'''
def gen_entry(i: SystemIdentifier) -> (str, str):
bootspec = get_bootspec(i.profile, i.generation)
if i.specialisation:
bootspec = bootspec.specialisations[i.specialisation]
kernel = copy_from_file(bootspec.kernel)
initrd = copy_from_file(bootspec.initrd)
gen_key = entry_key(i)
title = '{name}{profile}{specialisation}'.format(
name=DISTRO_NAME,
profile=' [' + i.profile + ']' if i.profile else '',
specialisation=f' ({i.specialisation})' if i.specialisation else '')
kernel_params = f'init={bootspec.init} '
kernel_params = kernel_params + ' '.join(bootspec.kernelParams)
build_time = int(os.path.getctime(system_dir(i)))
build_date = datetime.datetime.fromtimestamp(build_time).strftime('%F')
return MENU_ITEM.format(
gen_key=gen_key,
title=title,
description=f'{bootspec.label}, built on {build_date}',
generation=i.generation,
), BOOT_ENTRY.format(
gen_key=gen_key,
generation=i.generation,
system_name=SYSTEM_NAME,
kernel=kernel,
kernel_params=kernel_params,
initrd=initrd,
)
def get_generations(profile: str | None = None) -> list[SystemIdentifier]:
gen_list = subprocess.check_output([
f'{NIX}/bin/nix-env',
'--list-generations',
'-p',
'/nix/var/nix/profiles/' + ('system-profiles/' + profile if profile else 'system')],
universal_newlines=True)
gen_lines = gen_list.split('\n')
gen_lines.pop()
configurationLimit = CONFIGURATION_LIMIT
configurations = [
SystemIdentifier(
profile=profile,
generation=int(line.split()[0]),
specialisation=None
)
for line in gen_lines
]
return configurations[-configurationLimit:]
def remove_old_files(gens: list[SystemIdentifier]) -> None:
known_paths = []
for gen in gens:
bootspec = get_bootspec(gen.profile, gen.generation)
known_paths.append(copy_from_file(bootspec.kernel, True))
known_paths.append(copy_from_file(bootspec.initrd, True))
for path in glob.iglob(f'{BOOT_MOUNT_POINT}/{STORE_DIR}/*'):
if not path in known_paths and not os.path.isdir(path):
os.unlink(path)
def get_profiles() -> list[str]:
if os.path.isdir('/nix/var/nix/profiles/system-profiles/'):
return [x
for x in os.listdir('/nix/var/nix/profiles/system-profiles/')
if not x.endswith('-link')]
else:
return []
MENU = '''#!ipxe
# Server hostname option
set boothost ${{66:string}}
set server http://${{boothost}}
:start
menu {distro} boot menu
item --gap -- Generations
{generation_items}
item --gap -- Other
item --key m main Main netboot menu
choose --timeout 5000 --default {menu_default} selected || goto cancel
goto ${{selected}}
:cancel
shell
goto start
:error
echo Booting failed, dropping to shell
shell
goto start
:main
chain ${{server}}/boot.ipxe || goto error
'''
def write_menu(gens: list[SystemIdentifier], default: SystemIdentifier) -> None:
gen_menu_items = []
gen_cmds = []
for g in gens:
bootspec = get_bootspec(g.profile, g.generation)
specialisations = [
SystemIdentifier(profile=g.profile, generation=g.generation, specialisation=s) for s in bootspec.specialisations]
for i in [g] + specialisations:
mi, cmds = gen_entry(i)
gen_menu_items.append(mi)
gen_cmds.append(cmds)
menu_file = f'{BOOT_MOUNT_POINT}/menu.ipxe'
with open(f'{menu_file}.tmp', 'w') as f:
f.write(MENU.format(
distro=DISTRO_NAME,
generation_items='\n'.join(gen_menu_items),
menu_default=entry_key(default),
))
print(file=f)
print('\n\n'.join(gen_cmds), file=f)
os.rename(f'{menu_file}.tmp', menu_file)
def install_bootloader(args: argparse.Namespace) -> None:
os.makedirs(f'{BOOT_MOUNT_POINT}/{STORE_DIR}', exist_ok=True)
gens = get_generations()
for profile in get_profiles():
gens += get_generations(profile)
gens = sorted(gens, key=lambda g: entry_key(g), reverse=True)
remove_old_files(gens)
for g in gens:
if os.path.dirname(get_bootspec(g.profile, g.generation).init) == os.path.realpath(args.default_config):
default = g
break
else:
assert False, 'No default generation found'
write_menu(gens, default)
def main() -> None:
parser = argparse.ArgumentParser(description=f'Update {DISTRO_NAME}-related netboot files')
parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help=f'The default {DISTRO_NAME} config to boot')
args = parser.parse_args()
subprocess.check_call(CHECK_MOUNTPOINTS)
install_bootloader(args)
if __name__ == '__main__':
main()

View File

@@ -5,7 +5,15 @@ let
cfg = config.my.nvme;
nvme-cli = pkgs.nvme-cli.override {
libnvme = pkgs.libnvme.overrideAttrs (o: {
libnvme = pkgs.libnvme.overrideAttrs (o: rec {
# TODO: Remove when 1.11.1 releases (see https://github.com/linux-nvme/libnvme/pull/914)
version = "1.11.1";
src = pkgs.fetchFromGitHub {
owner = "linux-nvme";
repo = "libnvme";
rev = "v${version}";
hash = "sha256-CEGr7PDOVRi210XvICH8iLYDKn8S9bGruBO4tycvsT8=";
};
patches = (if (o ? patches) then o.patches else [ ]) ++ [ ./libnvme-hostconf.patch ];
});
};
@@ -33,9 +41,26 @@ in
etc = etc "";
};
boot.initrd.systemd = mkIf (cfg.boot.nqn != null) {
boot = mkIf (cfg.boot.nqn != null) {
initrd = {
availableKernelModules = [ "rdma_cm" "iw_cm" "ib_cm" "nvme_core" "nvme_rdma" ];
kernelModules = [ "nvme-fabrics" ];
systemd = {
contents = etc "/etc/";
extraBin.nvme = "${nvme-cli}/bin/nvme";
extraBin = with pkgs; {
dmesg = "${util-linux}/bin/dmesg";
ip = "${iproute2}/bin/ip";
nvme = "${nvme-cli}/bin/nvme";
};
extraConfig = ''
DefaultTimeoutStartSec=20
DefaultDeviceTimeoutSec=20
'';
network = {
enable = true;
wait-online.enable = true;
};
services.connect-nvme = {
description = "Connect NVMe-oF";
@@ -54,5 +79,7 @@ in
};
};
};
};
};
}

View File

@@ -2,7 +2,7 @@
let
inherit (lib)
optionalString concatStringsSep concatMap concatMapStringsSep mkIf mkDefault mkMerge mkForce mkVMOverride
mkAliasDefinitions;
mkAliasDefinitions mapAttrsToList filterAttrs;
inherit (lib.my) mkOpt' mkBoolOpt' mkVMOverride';
cfg = config.my.tmproot;
@@ -147,6 +147,15 @@ in
"/var/lib/systemd"
{ directory = "/root/.cache/nix"; mode = "0700"; }
# Including these unconditionally due to infinite recursion problems...
{
directory = "/etc/lvm/archive";
mode = "0700";
}
{
directory = "/etc/lvm/backup";
mode = "0700";
}
];
files = [
"/etc/machine-id"
@@ -260,18 +269,6 @@ in
my.tmproot.persistence.config.files =
concatMap (k: [ k.path "${k.path}.pub" ]) config.services.openssh.hostKeys;
})
(mkIf config.services.lvm.enable {
my.tmproot.persistence.config.directories = [
{
directory = "/etc/lvm/archive";
mode = "0700";
}
{
directory = "/etc/lvm/backup";
mode = "0700";
}
];
})
(mkIf (config.security.acme.certs != { }) {
my.tmproot.persistence.config.directories = [
{
@@ -495,6 +492,65 @@ in
(mkIf config.services.wastebin.enable {
my.tmproot.persistence.config.directories = [ "/var/lib/private/wastebin" ];
})
(mkIf config.services.photoprism.enable {
my.tmproot.persistence.config.directories = [
{
directory = config.services.photoprism.storagePath;
mode = "0750";
user = "photoprism";
group = "photoprism";
}
];
})
(mkIf config.services.mautrix-whatsapp.enable {
my.tmproot.persistence.config.directories = [
{
directory = "/var/lib/mautrix-whatsapp";
mode = "0750";
user = "mautrix-whatsapp";
group = "mautrix-whatsapp";
}
];
})
{
my.tmproot.persistence.config.directories = mapAttrsToList (n: i: {
directory = "/var/lib/${i.dataDir}";
mode = "0750";
user = "mautrix-meta-${n}";
group = "mautrix-meta";
}) (filterAttrs (_: i: i.enable) config.services.mautrix-meta.instances);
}
(mkIf config.services.unifi.enable {
my.tmproot.persistence.config.directories = [
{
directory = "/var/lib/unifi";
mode = "0750";
user = "unifi";
group = "unifi";
}
{
directory = "/var/cache/unifi";
mode = "0750";
user = "unifi";
group = "unifi";
}
];
})
(persistSimpleSvc "octoprint")
(mkIf (config.services.borgbackup.jobs != { }) {
my.tmproot.persistence.config.directories = [
"/var/lib/borgbackup"
"/var/cache/borgbackup"
];
services.borgbackup.package = pkgs.borgbackup.overrideAttrs (o: {
makeWrapperArgs = o.makeWrapperArgs ++ [
"--set-default BORG_BASE_DIR /var/lib/borgbackup"
"--set-default BORG_CONFIG_DIR /var/lib/borgbackup/config"
"--set-default BORG_CACHE_DIR /var/cache/borgbackup"
];
});
})
]))
]);

View File

@@ -82,6 +82,10 @@ in
# NOTE: As the "outermost" module is still being evaluated in NixOS land, special params (e.g. pkgs) won't be
# passed to it
home-manager.users.${user'.name} = mkAliasDefinitions options.my.user.homeConfig;
systemd.services.nixfiles-mutable.script = ''
chown -R ${user'.name} /run/nixfiles
'';
}
(mkIf (cfg.passwordSecret != null) {
my = {

View File

@@ -1,35 +0,0 @@
{ lib, pkgs, config, ... }:
let
inherit (lib) mkIf mkDefault;
inherit (lib.my) mkOpt' mkBoolOpt';
cfg = config.services.wastebin;
in
{
options.services.wastebin = with lib.types; {
enable = mkBoolOpt' false "Whether to enable wastebin.";
package = mkOpt' package pkgs.wastebin "Package to use.";
settings = mkOpt' (attrsOf str) { } "Environment variable settings.";
extraSettingsFile = mkOpt' (nullOr str) null "Extra environment file (e.g. for signing key).";
};
config = mkIf cfg.enable {
services.wastebin.settings = {
WASTEBIN_ADDRESS_PORT = mkDefault "[::]:8088";
WASTEBIN_DATABASE_PATH = mkDefault "/var/lib/wastebin/db.sqlite3";
};
systemd.services.wastebin = {
description = "wastebin minimal pastebin";
after = [ "network.target" ];
environment = cfg.settings;
serviceConfig = {
EnvironmentFile = mkIf (cfg.extraSettingsFile != null) cfg.extraSettingsFile;
DynamicUser = true;
StateDirectory = "wastebin";
ExecStart = "${cfg.package}/bin/wastebin";
};
wantedBy = [ "multi-user.target" ];
};
};
}

View File

@@ -0,0 +1,49 @@
{ lib, stdenv, autoreconfHook, pkg-config, SDL, SDL_mixer, SDL_net
, fetchFromGitHub, fetchpatch, python3 }:
stdenv.mkDerivation rec {
pname = "chocolate-doom";
version = "2.3.0";
src = fetchFromGitHub {
owner = "chocolate-doom";
repo = pname;
rev = "${pname}-${version}";
sha256 = "sha256-1uw/1CYKBvDNgT5XxRBY24Evt3f4Y6YQ6bScU+KNHgM=";
};
patches = [
# Pull upstream patch to fix build against gcc-10:
# https://github.com/chocolate-doom/chocolate-doom/pull/1257
(fetchpatch {
name = "fno-common.patch";
url = "https://github.com/chocolate-doom/chocolate-doom/commit/a8fd4b1f563d24d4296c3e8225c8404e2724d4c2.patch";
sha256 = "1dmbygn952sy5n8qqp0asg11pmygwgygl17lrj7i0fxa0nrhixhj";
})
./demoloopi.patch
];
outputs = [ "out" "man" ];
postPatch = ''
patchShebangs --build man/{simplecpp,docgen}
'';
nativeBuildInputs = [
autoreconfHook
pkg-config
# for documentation
python3
];
buildInputs = [ (SDL.override { cacaSupport = true; }) SDL_mixer SDL_net ];
enableParallelBuilding = true;
meta = {
homepage = "http://chocolate-doom.org/";
description = "A Doom source port that accurately reproduces the experience of Doom as it was played in the 1990s";
license = lib.licenses.gpl2Plus;
platforms = lib.platforms.unix;
hydraPlatforms = lib.platforms.linux; # darwin times out
maintainers = with lib.maintainers; [ ];
};
}

View File

@@ -0,0 +1,91 @@
diff --git a/src/doom/d_main.c b/src/doom/d_main.c
index 65a39a10..3f799b0f 100644
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -483,6 +483,8 @@ void D_DoomLoop (void)
// DEMO LOOP
//
int demosequence;
+int demoloopi;
+char demoloopname[9];
int pagetic;
char *pagename;
@@ -524,6 +526,8 @@ void D_AdvanceDemo (void)
//
void D_DoAdvanceDemo (void)
{
+ int havedemo4;
+
players[consoleplayer].playerstate = PST_LIVE; // not reborn
advancedemo = false;
usergame = false; // no save / end game here
@@ -539,10 +543,14 @@ void D_DoAdvanceDemo (void)
// However! There is an alternate version of Final Doom that
// includes a fixed executable.
- if (gameversion == exe_ultimate || gameversion == exe_final)
+ havedemo4 = gameversion == exe_ultimate || gameversion == exe_final;
+ if (havedemo4)
demosequence = (demosequence+1)%7;
else
demosequence = (demosequence+1)%6;
+
+ if (demoloopi < 0 || demoloopi > (havedemo4 ? 3 : 2))
+ I_Error("Invalid demo loop start %d", demoloopi);
switch (demosequence)
{
@@ -558,17 +566,11 @@ void D_DoAdvanceDemo (void)
else
S_StartMusic (mus_intro);
break;
- case 1:
- G_DeferedPlayDemo(DEH_String("demo1"));
- break;
case 2:
pagetic = 200;
gamestate = GS_DEMOSCREEN;
pagename = DEH_String("CREDIT");
break;
- case 3:
- G_DeferedPlayDemo(DEH_String("demo2"));
- break;
case 4:
gamestate = GS_DEMOSCREEN;
if ( gamemode == commercial)
@@ -587,12 +589,14 @@ void D_DoAdvanceDemo (void)
pagename = DEH_String("HELP2");
}
break;
+ case 1:
+ case 3:
case 5:
- G_DeferedPlayDemo(DEH_String("demo3"));
- break;
// THE DEFINITIVE DOOM Special Edition demo
case 6:
- G_DeferedPlayDemo(DEH_String("demo4"));
+ DEH_snprintf(demoloopname, 9, "demo%d", demoloopi + 1);
+ G_DeferedPlayDemo(demoloopname);
+ demoloopi = (demoloopi+1) % (havedemo4 ? 4 : 3);
break;
}
@@ -1891,7 +1895,15 @@ void D_DoomMain (void)
G_TimeDemo (demolumpname);
D_DoomLoop (); // never returns
}
-
+
+ p = M_CheckParmWithArgs("-demoloopi", 1);
+ if (p)
+ {
+ demoloopi = atoi(myargv[p+1]);
+ } else {
+ demoloopi = 0;
+ }
+
if (startloadgame >= 0)
{
M_StringCopy(file, P_SaveGameFile(startloadgame), sizeof(file));

View File

@@ -7,7 +7,9 @@ in
monocraft' = callPackage ./monocraft.nix { };
vfio-pci-bind = callPackage ./vfio-pci-bind.nix { };
librespeed-go = callPackage ./librespeed-go.nix { };
modrinth-app = callPackage ./modrinth-app { };
wastebin = callPackage ./wastebin { };
glfw-minecraft = callPackage ./glfw-minecraft { };
# modrinth-app = callPackage ./modrinth-app { };
chocolate-doom2xx = callPackage ./chocolate-doom2xx { };
windowtolayer = callPackage ./windowtolayer.nix { };
swaylock-plugin = callPackage ./swaylock-plugin.nix { };
terminaltexteffects = callPackage ./terminaltexteffects.nix { };
}

View File

@@ -1,6 +0,0 @@
{ lib, glfw-wayland-minecraft, ... }:
glfw-wayland-minecraft.overrideAttrs (o: {
patches = [
./suppress-wayland-errors.patch
];
})

View File

@@ -1,43 +0,0 @@
diff --git a/src/wl_window.c b/src/wl_window.c
index 7c509896..db9a6451 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -2115,25 +2115,21 @@ void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title)
void _glfwSetWindowIconWayland(_GLFWwindow* window,
int count, const GLFWimage* images)
{
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the window icon");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the window icon\n");
}
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos)
{
// A Wayland client is not aware of its position, so just warn and leave it
// as (0, 0)
-
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not provide the window position");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not provide the window position\n");
}
void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos)
{
// A Wayland client can not set its position, so just warn
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the window position");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the window position\n");
}
void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height)
@@ -2359,8 +2355,7 @@ void _glfwRequestWindowAttentionWayland(_GLFWwindow* window)
void _glfwFocusWindowWayland(_GLFWwindow* window)
{
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the input focus");
+ fprintf(stderr, "!!! Ignoring Error: Wayland: The platform does not support setting the input focus\n");
}
void _glfwSetWindowMonitorWayland(_GLFWwindow* window,

View File

@@ -81,7 +81,7 @@ rustPlatform.buildRustPackage rec {
dontFixup = true;
outputHashMode = "recursive";
outputHash = "sha256-9HtTdIotG3sNIlWhd76v7Ia6P69ufp/FFqZfINXSkVc=";
outputHash = "sha256-Txttk8qZpDsAuiF8laKbZss/KEoT1Z+oepbj2s4XjE8=";
};
preBuild = ''

41
pkgs/swaylock-plugin.nix Normal file
View File

@@ -0,0 +1,41 @@
{ lib, stdenv, fetchFromGitHub, fetchpatch
, meson, ninja, pkg-config, scdoc, wayland-scanner
, wayland, wayland-protocols, libxkbcommon, cairo, gdk-pixbuf, pam
}:
stdenv.mkDerivation rec {
pname = "swaylock-plugin";
version = "1dd15b6";
src = fetchFromGitHub {
owner = "mstoeckl";
repo = pname;
rev = "1dd15b6ecbe91be7a3dc4a0fa9514fb166fb2e07";
hash = "sha256-xWyDDT8sXAL58HtA9ifzCenKMmOZquzXZaz3ttGGJuY=";
};
strictDeps = true;
depsBuildBuild = [ pkg-config ];
nativeBuildInputs = [ meson ninja pkg-config scdoc wayland-scanner ];
buildInputs = [ wayland wayland-protocols libxkbcommon cairo gdk-pixbuf pam ];
mesonFlags = [
"-Dpam=enabled" "-Dgdk-pixbuf=enabled" "-Dman-pages=enabled"
];
env.NIX_CFLAGS_COMPILE = "-Wno-maybe-uninitialized";
meta = with lib; {
description = "Screen locker for Wayland -- fork with background plugin support";
longDescription = ''
Fork of swaylock, a screen locking utility for Wayland compositors.
With swaylock-plugin, you can for your lockscreen background display
the animated output from any wallpaper program that implements the
wlr-layer-shell-unstable-v1 protocol.
'';
inherit (src.meta) homepage;
mainProgram = "swaylock";
license = licenses.mit;
platforms = platforms.linux;
maintainers = with maintainers; [ devplayer0 ];
};
}

View File

@@ -0,0 +1,19 @@
{ lib
, python3Packages
, fetchPypi
}:
python3Packages.buildPythonApplication rec {
pname = "terminaltexteffects";
version = "0.10.1";
pyproject = true;
src = fetchPypi {
inherit pname version;
hash = "sha256-NyWPfdgLeXAxKPJOzB7j4aT+zjrURN59CGcv0Vt99y0=";
};
build-system = with python3Packages; [
poetry-core
];
}

2161
pkgs/wastebin/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +0,0 @@
{ lib
, fetchFromGitHub
, rustPlatform
}:
rustPlatform.buildRustPackage rec {
pname = "wastebin";
version = "2.4.2";
src = fetchFromGitHub {
owner = "matze";
repo = pname;
rev = version;
hash = "sha256-9SsNtIZfRK9HwWaqlsuSCs7eNK/7KnzDtCe0fFslXwA=";
};
cargoLock = {
lockFile = ./Cargo.lock;
outputHashes = {
"rusqlite_migration-1.1.0" = "sha256-FpIwgISYWEg7IQxG4tJ3u6b8+qanaqanZrq0Bz5WlLs=";
};
};
}

18
pkgs/windowtolayer.nix Normal file
View File

@@ -0,0 +1,18 @@
{ lib
, fetchFromGitLab
, rustPlatform
}:
rustPlatform.buildRustPackage rec {
pname = "windowtolayer";
version = "a5b89c3c";
src = fetchFromGitLab {
domain = "gitlab.freedesktop.org";
owner = "mstoeckl";
repo = pname;
rev = "a5b89c3c047297fd574932860a6c89e9ea02ba5d";
hash = "sha256-rssL2XkbTqUvJqfUFhzULeE4/VBzjeBC5iZWSJ8MJ+M=";
};
cargoHash = "sha256-XHmLsx9qdjlBz4xJFFiO24bR9CMw1o5368K+YMpMIBA=";
}

View File

@@ -1,10 +1,10 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBJYzdr
b1d2aEtVd3lVb3NBamRwVFpTaTRjZFlCczk4MVIwQUoxWklwN0NrCmFFekpPYUlO
YlgvVlQ2WDR6amZDN0ZSY0Q3WWtTME5pUmhQeks1c3dGOVUKLT4gWDI1NTE5IHVK
bUZvUVAvL0NmQzFkY3BuYm1wMjcwbFpLRUNpZjJCaW15SEVDUDV0REkKRXFMQ2d1
NlFBejBvTlJrcUtCYWZxSDBkbmxIdExBNTU0aC8zRW5OVWllVQotPiBDLWdyZWFz
ZSBkeC4oTFUgO0FtJG9+RyB2IF1QXGhxVwpJS213MXBRMWY1cXlHZwotLS0gRUF2
ZkswNlhvcDhTc2tybCs1dldwa2l6SDZZVmNkNUNjNGlkV1ZVa09pOAp88dxHGxVU
vuFQO6JcroY9MF5Te/YV+wMc3hVxksibMnH1TWGh207prwcOWNOEz2iEkZY=
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBrMXND
Zm1ma0FoNE5lWTFNTGlyeUQzdUZxMkxyVlU0cWdrcTJEakhDVXg4ClkyczJDR1FL
eXE3QWFTM0wyeDNvL1gvcmx6eGE4elNuZW9wRHhJZ3Aya2cKLT4gWDI1NTE5IDhO
S2JWNDhlclpERFFUTktyUG5HbnNxcVQvWmphOGp1cmNpK0NGZWVTejQKN0dybHl5
eHhicFNpUHQ3WFZDQS90NG5VZW5zVm8rcUxCdkZkOFVqdVFzRQotPiBBLWdyZWFz
ZSBaIDMiRCBYO1g6IF9EawpJZwotLS0geXhWb1FORm00RVJoMm4zQjhBT0hERyt3
ekM1YXNzdTgzUTVMeHNsNDUwbwqSjgIVhg9bqtIydYC1FCA4ly2gurTcb1SUCMG8
XA9WAx1jv05xje+U97tRTTongJEW5vw=
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,15 +1,17 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBLVlg2
ZUdtUlFUQXBLT3B5YmkycWJnMXJyKzltbyt6K2dJK1RBUm5ydWwwCmRUdjJFSEYz
Wnp4cGtzTXZwc0s0SUJQUjRlOUJlQUoyQ3BETXZmY0ppWG8KLT4gWDI1NTE5IGR5
QUJzeG1DQTRLUmRwNnNSRUJRSFFtUDl5VjB0clVLYUp3R1g4TEVKaTgKb09tVlhF
R0tmcmIxMHVHcG80RGxRTEhBcngvT3MrdnNPbmpCTlRyZW5xQQotPiA6RzEtZ3Jl
YXNlCldSUlN2ejB0MGpyUHYzNS9OQmJTK3MvcXRDakdBVlhuUEt6SFE4QmhnWVN0
V1JMOE1oaEp5QQotLS0gYW1OMTcxNWJrUndmR2h0ZmRDWk5CYnJjc29pSERUMnNk
d2VhTGdpOW4yUQrEeH2E9m0YycuW60QrdlRetO1kNU5FaKXRQt46iA9lACIWD4rC
Cx6WxhCBgz3hvm9x6iuYiiQxZzgJNK7qXcV2MBeQdivazeEbC7blAKVPhwD/dl+b
PzBDXRXG3c3jMjeZFT69fIBGJfZrrLGKpTALVE4dTVXmQmVVQDTp19IC+jUXHBti
Pj6Dpc7452s8zPkzZyRbasO9b4PYTwq8IHT6X7ITwbzZZm8gexDYe2SzRZ5VcPz3
El+yoULZ92WbXPSQIP/Slx4BEZjmsQS+sm0N8AnBRNZkWVbHPF9IZRg3VjDAn2i8
F3un5js=
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBjQmZr
VDl4TVlzK0lCc0YwdFM3TEptU3Q3cWZ1d0FJQUI4Q1g1TVNyOENFCkU4NE5lYVhI
d3B0amFJT1A1RTRSaUdUSmZ1WmU1SkVhTU9sdFZJR0p6UXcKLT4gWDI1NTE5IG5O
RG1SQnZtSUk0SThNYkRpOHFPS29kbjdUenZyYjBBSTJKdXNUaGpYMG8KME8waXJ0
NWR2NHoyUkN1UUJoaVRxYXVMZlNvTHZqRmYvS2h4QjZpZm5NZwotPiBPclJULlkt
Z3JlYXNlIEVdKEBXIDUgXTBzIi58TwpweFJEcUFpR0x2WWhiVDlOTFArenhjNXBB
dVo2d1JQWEJyVHlTRnUzdUlFUE45RWlLU3ZRS0c4UWs5Nm1qVHorCko1RVdqOVdz
aVAwY09KOUx4WktIVFBQclFXdFJZMTNVWHNKcTZFbDU5Q0xLaExvNVdlZ0pTczUr
SkVDTzhDUysKCi0tLSA2VGJMM2lrNkViaU0wcnArSG9PemJrQ3lrUFNnRDRVeE1p
V3lxeG1iN3I4Ckf36lD/b7agsT0qW8eGDnxsVor8hEmLBSa35/eeAxqMd0xPvQko
REzIxPuEHRQM5dE4s4H/mySTC/AVsiwfcMrnOXInm4o3MNAC9PREcef4NBOP3IMl
Mcoifar27EXs21XdXw/lLOVNDX7oDKZh1zXVX4lFTcRW0v8abbwchvuTiayKePMG
DrcyFsj4jiwpJ5MmY/Q+n0lZmoAlAJkeTHRUptJxGMq+pWVEGMa8p1vUdrVwWq7G
YYO5lPlms01BFJfUsysh07HY1HPkOyFHeEkviZtt4N8hopx0pP4fyAZYYdrBAIdt
CLpQFQ==
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,13 +1,12 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyAyMWox
cEFDWWUrVzJSM1o2azJqei9HV2xFY25oQXV5SzM3akxEaUJiN1J3CjkrQVhjWHY5
Uk01eGp5Q0RKNVREVXJVZytndTM0SXNZSGIvUVp1TnRiNXMKLT4gWDI1NTE5IFZn
WjAyR1RMajEyMnFSYnNGT2EyekROVWNoakFJQVZxaFc0YThOMHVyanMKWldrdlAv
cVg0OTFHL2loeGJ3RHA0MnlnckN3czF4RUgyc1NjYXVOSXF5cwotPiBvTFQtZ3Jl
YXNlIDRsSDp6eikgT1ojIGEzOFZMIFc3MUZGCkttZ3ZLNGxucnlJc01kRXFZTGpC
eCsvRzl5WnFUMUIyTWNVWGk4SjQyN3V0bXQ4VzFuM1RjSzVMcDJkaW1JYXMKQkE4
YWI1Mmg3MkpjdVpVYWJkczJQMnM1SVMvNkZhOXBDVEZPCi0tLSB3SVIyU3M5RHBE
VFRtMFU4OUFLbkNjbkJmVmhlc2VsYzdsd0pFaFkrUmkwCs+h2KlXoyZ8U++A9wmV
kh4N2YyI/a84yPGDNoFdSlXaU8jxUzolnadImXSXyB4CroqQLvGEbkZZlWqPLVfh
Iav7Ja8=
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBETE9p
VVVHeThGT3daNW1xZjBDblFwQWozQ2VSUmR3NlJVak12YXdWUDNNCitTWnBHd1Mv
L2ViUWJvR0dtckpTQnRNMWZtazZHQ0tON0RhM0Z3cTlYVUUKLT4gWDI1NTE5IGhV
ZEFqcW9CcHUya0s5dmgxc1JqUWRicmpXTllIckxaWjhtYzMrOFp0R2MKNUcxVllk
WWJ2cEkzdXdiVFNDQVN2cUVNRnlMQ1BZWEx0QTI2M0FKSHE1ZwotPiBHaCJASk9u
LWdyZWFzZSBsIFxuClVieGM0alFSdmttVjVsNDZIT2hjSTdWc1Z2VXRIUC9BbXNL
MXArcHI2eDM4QWwyeXhtMU41cEtLQ2tkVllJdjkKTjMvNENSNXd1UjV2bGQzbnJx
U3RubVRxQXVSSzJXbG5uQmcKLS0tIFFIeEVhR29qY3FBaUlJd1M4K3FvdDNybHZB
MmVMZGxyYUYxVDNydjZLbXMKiPpxBn4WtzaH2iTFfjayYgNFPa0Mi6tIH0LOqkAj
RyHNF/6vgWlmnivbhP+74dVaqR8IwUdFQN7S8/fx7eW/7qvtlg==
-----END AGE ENCRYPTED FILE-----

View File

@@ -0,0 +1,33 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBSS3E0
YWsxbHZXQXo1R3BzL1BDdERxN3d2ek5acFZWK3F6andTeGVacVNVCnhPR3I4dXFV
dFd0N2lsTU5NOCtsM3Z1YUdIaER4YjlrdkNXT1g4dGZXNFkKLT4gWDI1NTE5IDBQ
cHBYSG04eHA1ZG9KN1Q5bFk0eXk0T0o4c2pLVUdNbEtWaDdwckdJVmcKd3lkZmVY
cDc3dGdXSWViNGlMVW9jZENUWXd5MVNheStiVU1adG5MNEpnNAotPiBfJWZ0eWtP
LWdyZWFzZSA/VGRDTT5kSCB4QH05QF96eyAtfUpxQ1ggZU5FQEhZbGMKa2xDUlMw
Wml2QldxcS96YXVJT0hPVStqelhmUEd4K2R3ZDM4Uk83MXV6VlVoKzRiMWhxVlJx
Ykg4ZTJ6SSswTQpTdjYzUkhMWjFwblhzRWV4bFZOVnRjRGMveDFaUTJWM3diK3lj
MUE3dFlhUEVENAotLS0gd2lKQ05PRUF1b1RzZEs0ckY0eFlPaFFBNHRQZ01rZzBV
SW01L0VzUUpYSQrJxWuL6pjjZs+hCS0f6DTNwW6HSD33bUwdBpyTCLeLMyDT646H
4pjAhrVjVH1kgBFmuCjTP+SrD2bie/WhkQPSYrG7qygcmXbdNXlJn1tluEedDLzK
djbOaSuohlgneGw9Z00Zkm8rz//2NSB89+WiWuT5/6Pm/d6763FteRI1LsPOyWx2
vmTZMIcuclmrGn611T1kKR87R5AkaZ6xyhkOrOvWrb7BktmA69Kd9r5fXyxnLRZD
W6vPm4EJLo0b1a4DWlnIvFTy5I6e2fFT9h2+rU1qITn5fwQD5aAYdL8W8ELIEJ98
zYNxpbepHY5fBpHOGvOKM4AAO/R2pjaDaK7DRIFhSx/1RJLJvigXFd7YKl0WWn3w
PGK/YxXnhtxnZngEPrnwf3JPj+zQ3RwKDx/v12s+KTbfQu6sGvw3MhDwYsFrRn+J
T/jqlcZ/RodnxDngMnJCzc+YPkCJ/yAiot1DthVdpW0mWFiPsZvzN3co7t+6nopR
WYnSjp5igjHbO/E3zXQ8qRlOvXSp6zspOIv9AETq49felAxXF7uz28lMnBeCReVq
4hzBII+wDTR1Y/itKcOGm5mTdyvLF4qKRZFJFiJ3ATGZDEYh2dCrO2juaL4VczCl
+qwt9gYF+pOgY4ekOtW6BpvOGZ591LHTMWoP52O0MnZADU8GHkh66AvMDemQGumj
7qI6kI49Rwr5CoDMds5XlUBKlzeLgZLSo46FJghWOOQaiFiXWVQ+jYZpZPkgGjkU
wDkrnbdglkdPO93bT2drkNbPWziHRkV505lGk1s4zCvsUPMH0D6KYkA6o/hCum4B
IK8Sj215CmjQv5LYBwzHTNRusksXDu/+Ud5FpKCNw34aKblLIEPJNSk1BWLwyLzM
oCNTiI490ZBh3vcnXpHZorS1Hxzb536SW03l0Z6q1Izn/vfzhZ7HbFY4qS9Qe+je
Cvx+upRzt+mIQt8edbhrC1twfo/6whuvpT1HqGQDUr62+4zqVJ3lbccmXRX6uOAq
sfK9if7qo0wkfWqa4RutO008ocVSKt0JjDOUpGHHP9Z95NRMyKJiOlv7dgVwWEid
J8YMxexAgkmjByzwt1CBC7XizEHl09ZyjJrzN420NMRzaG3C6PY82cnKdbXNfEM2
0dlN/xUTaOG1dAjdlgr2oMA5o0jFptr3hTFcoOQ/va1zkkNDHvfgjzri9HSID0bP
kE0Akj6H9457cyo+xI+gD+2CtJW37TR/A7GLrzc+BDdDNZWtJz8t7oU0STL38h0d
rfHgC8uFj7Ozh0nvsPbviwHCw6F+Z3lOT2qaFjzWKMuhnB8s3C//vmMFCfY2XglJ
Tmcz+A==
-----END AGE ENCRYPTED FILE-----

View File

@@ -0,0 +1,14 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBBTHhU
TVdvcWhvb0c3NjlTT1JBWlRaRXBYSlFySFJhQVZHRUsxcTFVT1ZzCmVaZW1ucTRG
MVN0VnZEWndlVS9iclNhRlB2dkZPT241dHRxcjBRc1BpVncKLT4gWDI1NTE5IGh1
aitYSmVudUZPS0FHbUliUjFCWXJaTWI1RzRlK1Q0ZlpQNmRwN0haemcKaHhQS1JO
UVYxYUU1OTR0dXJhTm1EMGdER0hYUXVRd2VmNURwTEdVV09tVQotPiAnbHAtZ3Jl
YXNlIH0gLCJ9IDwhIEB2QW0lfSkKMUJLd21ubDVQdWJOR1VvCi0tLSB3N2dJV2o1
WGF2TENYNE8vSzI2UzVPZW01RzRtK1VCaUVKemN1RzVhaGlvChPEVtylQsq+EWK4
X6HxFl3JY+M9clfpicNlSqUjPcB3roEMpD9BmGcG46nVSZVDguVjPzwTltAGE72Q
Q4RP8/yhssA2rrLEuWz+JKcaASF/yEmu9QBILrWBIWz0rQyHfTRvBC9d83MdHS5f
DQl1abC7Lv8imVm0pJ9vthvB56mXlGgm16fnsd/UhgMQSWZuVLSitaoDEFCz/LWi
QAUKYTRVL2UcomgHsQqMx+2g3HT0RYQu1Ud3M5rT9eMSSqPG7IzyjNA3HmH5dw/4
EdnilIaW7c6k1RAYMFY270E6qlxqdQ==
-----END AGE ENCRYPTED FILE-----

View File

@@ -0,0 +1,15 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USB1QUhX
dTlNY3h2SElIMytCTGlmY2syMmlTL1VMeDFnanN2UE9QK3RvRlUwCkVMM3ZKMU52
ZmIrZ1VxUDNWZm1lU2MrWnpkUzBLcDB5cUFCSXZmQ3RXR0UKLT4gWDI1NTE5IE5W
cE5uSlpRd3dIRXEyRnpSZ0VHZ253OE1ZVTd1OTJQYkZVd1NRdnh2aE0KNTFTaHJM
OE9tc0VkMHFHUGN2dFZVSGFBdTh5Tzk0TGU4SWwzYTBOb3FtdwotPiB9WnwtZ3Jl
YXNlIHZVYHxaIEBSbmZ9XiAhfF52YCNwCld0K0RCTFlQamNLeitWM0kwUnVJdXFV
QjNFcEYxWFBkVjJ3QlAwTGVvTE1GTkxCTEdDcmlZMC9xbUcrSHp2V3cKdzJLb011
aEM3a0V4eXBTMjhnCi0tLSBOWHozZTRjRldrOXBmM05BZ1lPRDYwaDFCcHBPNHhQ
SzlaWGM2RXY1THI4Cj4RzG3G1yGkmDyqxCBciqMNPAQYge4mXOib7mqOuyIbkT+k
qrJ8fLnW7Jbnb7+Rzr7BAEC5/dpOfjkyY9JPeg0FRutlkKyPIhRMAEhSsNvUFzXg
uwNbnSBI+9Str6nTKI5c9IWT5eT/8zsKwtK1/pr39mApRY/y6NlA5X7ZRIFeku3K
6I/bCI5cT0qhIMJbF5D0KiCnMCnMdmRLrwLzM2zcJoisxRAvj4dNfLktsUQOauZ+
Gta96qQkAewvrdfz8Z4lTYJQmEqeOs1vTA6sAMf4iLp5EhPE0jN0n6D8v7Lq7+2b
-----END AGE ENCRYPTED FILE-----

View File

@@ -0,0 +1,14 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBJbWVs
bkt4a1RBaU14cjJzRm9KUGhydnZlWGU0NGVYK0NmWXRsclpjVUU0CmNiVDJTODFw
TnloNW1LMUliVmlnUGt0SFFzWmxVTWxZQ3crNWVHVy9IL0EKLT4gWDI1NTE5IDcw
TUQva3UxN3o1MXJ5QmVmQWVmeTFLejVwOVdQZks3a0dVQUJTdUdZdzgKajBFK2dX
R1NNR3l5d010MnJGUktNWldwVjY2cDIwbU1laEMwOWJITEg0NAotPiBeLS1ncmVh
c2UgJjhQIF0pcSB4Ci90SVhIZzRGVlcrd0hRCi0tLSBKdVgwZ0pidC93aEFscm9w
Mm5GbEc3RDdZRDRpeTdONHpWN0xHYXkvVU5zCjjFfwumbetHbq8MKrBIx18YXmny
z+0ifVbksJhYLYk7hViSUDy+F3RRad23dSPvDdd7JCEpj+2PvcezBLkwfUkFdQe7
uQhUJJ9c62oKSX7PMbQeW1tyX10SVkt/P20z6HPXvBlY715lsXspjZERi+DheZk0
ZDc3dPYMeyoAIWicf40ZxH8C6rWl5HOLIaTMbCOKwpD+wPjpzeZHat605YWReFxR
Yd3cKCRqSb2QdAdtZ0XUDSPl7HVwkw0xobCsvtPzmObA3YbLopBq7Dvrvh7XW5ns
BPlTaI8WnrI03CplGP00
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,13 +1,12 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USB2WFY2
MzFnVFYvb0wzc3grRDBrUi9teW1tNmx5dVBIRVc5OUdlcjdvTDJFCmpJL2tlYXND
bVJKbzd2S3JkSFVMdG40MS84V0lPTVJSNHVBQlNXSkN1eTAKLT4gWDI1NTE5IFBM
ZGo3L2VlNUZqOEE1UHBuMHdqc1pyYlQ3R29ucE9pajU0bHMzamlXRDAKcG1Qdmw2
cUlncDFWNXBOWnpIeDNZSFA3d1E1bjNaVVpKU3lMRjRaSHNtMAotPiB2XUh8eF4t
Z3JlYXNlICUrO0cxIH4gaTRoIF81SEpTN0Q5CnpWdEZpb1hZa2t5YkE5RnJFMHVZ
WkhkQ2o0eWtyOE9ueDJkeGd2aUhmLzRUUGs1aUc1NURIOTYxczZhOEVmT0EKd2xk
TXFHN051d25PQmtNUVZkVEFGUVliZjdmZDF3RWFkaEhNTzd3ZVd5N3dlNzQKLS0t
IGZDR1Mxd24zOW05bitzQnN5WWVOOGtCNEc5aXIraEF4eXFUQm5CZUdCV2MKd44C
/Trgg0OEZ89/jqbj56z/Hia1Ka3ZsEv6bXPI/kcRvFDBFTgtvG3KWCgMBtTUHXzY
TKBPoQqrUf7plH7a/mTx3KR+4Y+yF+1i86s7TzYjD8d1xfFH3BsVtg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USAwa1k3
S3dka3ZjcVdIQ2hSN0xsb0hTNEhneXFYS3BXNWZDVlBNc2toQ25vCldqSlMrT0hB
Rkg2aDZUYlY4U1E4Y2djMVdwT1VsbGdpUm12Z3gzditmMncKLT4gWDI1NTE5IG13
YXF4WWdmNFRPR1JDWkk4OFZkSjdzRS9BbXVzSC9YNG5FRnpqUXJZVk0KV0tOSG9N
c2VVWE10WkxUZXpqZjBZZUQyWE14TUFsdStMeWVlcFdJaTRVUQotPiBWaHxWdCYt
Z3JlYXNlIDYgdDsgcW97Ii5yIE95Clhqa3RVUmJENngwTDNoR3BCNjlaTkVYc2JR
ZWQwb2FOVy9sc2d5MmtkeUhkajJBOFE3TWJTOWViWVlJSTkxWQotLS0gN01aNGdm
VjR0ai96VzRqb3QzYU4yRzVCby8ycVhXVlpubVptam5mYldoOAoZnbsXB5we9BQ5
AXQ08mXmMxRMg9iH7qgyCVc1ywR/uo5Fcefhuw23TyluRkYt7tZ9yiuFJIx5Znsr
QEqaBioL1UfePVyDLi8LcBvUgnnx5uN05hUvTOt6gqaE
-----END AGE ENCRYPTED FILE-----

View File

@@ -1,30 +1,28 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBuQjBY
K1ZTUzR0SmFoYUZLdzUzNUt2M1B4RFdPZzFkcW8rMWJLUjVHOUN3Cjd3ZHdMSzdp
OWswditVWUhYNjZCdjV6M1d6U3pNak5hUlZjTHNqSkZPSk0KLT4gWDI1NTE5IGNG
ZytHazJQWTExMjNkZWV2aDUwcnZjUGcwcXRkZWl0M0F2R2JpUVlJekUKWTFlbkEz
YlN6dkgrMmFFcmlZMjQ0b2oySjlEMC85cUF5QlA4NGF3blBKRQotPiA8M1hbWS1n
cmVhc2UgOmlZJFYmJgo3UExzUHhSVi9lbVRjNW4xTnVaUTVGSGVDNzRUNlJ2TnVu
U0wrWU5kd3dyR2phcUNVUHJCYjdzeWhjNVFOV011CmZMOVN0WDk5eUg3ajhwbStQ
aHExT0EwblpreTBXVHh6Zk1HRkhzcmFQNnoyVUlaeStMUkgKLS0tIG1aY3Zadko3
V3pDMGswSDZCeit4SVhSRCsrZVRVZVkvQkNsQWN1MXFMUGcKcK74YULWqWw9VvkI
NH38VHfDPW5ueSiyHHKn8MI9YosPr/TmkwgKd/DOIMVB74ahPalo1QUeg+eaBVnq
Uncsbx5ecW3JswthkAhiktWHcdHmioGD6hCcgbWtfA3VvbAYc2gtAF2plfDVH6BD
c8veai3B15ZmDmq3b62sgVA9JUgbFaB1eRqcaPXmNgQJR4c8J+CZWXGQ/TKMqtAg
chCDuczjLX8IxhMPF1gdCggSt5GtMhY47fpZJRbBUw01l8koqjm63KvEeg2ejFGU
+tXonI4jm2JUxlDTqmNSrVpmAgtPoEPszHc+GsnyNjAz4IXMm5UrQAZyDPgxtwQW
ZAn0IdOB8rSL/AnRGUpPrecuauINQjONe8CapijjJPQK7g1AHscfxr+OJD1j2eV3
O6TNlz8vKW4t/V7CUf46ykxxExhA0mKJ53ksaXy2+HWoro2+c4nao/bEld5gt08U
uCpJtjPKB64X6vdzbY21/l87VRDyxbb3poENfrXlawqS0Z7i2gAbHN5EuiMv+35o
sBaR0BfcbTn6VagC3i8HEEOO964FrW65pkqmGJcJMgUdcZSl+Y7gHMjWyodqGPOY
evT6xj4iyeM49vXynV2vrJRu5rr02hOS/8rPphV9c9q9ju5n8xbhS6IiybAelPwt
sa+xM+w0n+fxVksiXeFj7qD1LDN4+kwqhYP9SlzbA4fT3AkYYrxthTww4IFAweyQ
IJkpVL0/IZEIEfRzpr0lWLprAaoyPc64pecl0z/gBJDgz1kSG6iEh6K4qx7ahGde
kBBpS2I2ZsdBkvmQxDSM7tYYBzPxcUNZlSFOIeUy3Xl+OGPlKgtMofbnjV8AFqUf
tOpgKpLUEkTgXbGUKBxHLj+8pbw7zOFp4sJ00i48ZzLP5D9jom+jS19wGshRc7cH
dK92CctvrfndQ85yO0vqlyOdMTqjh/z3P2KmhL5SW6P51q5mseTvj7FNM7331DTs
rq7XWaBLE61eWWQ/dZKnqh5YbkSlU1+08Rl6H/vCU5hTC8fht3KTQSWPofkrP+5f
We/Pe62LyhV/MbLRA0nmU7Sf4IAnpHfa4kLtlYeB3xiqKd0McM//qzjuk5NoIgE4
nL0T8YXdGt8K01w+nt+j5bo5gFoRz5+1/ZZ9BgN2DOo4SClYnJWQ/x80X061yJ33
0SGv4eAC3vFi6xE=
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBvdjZT
WWFyNzdXVENweXlVT1kxNElaUDFUSG1DSGMybTZlN3VKVDNNMGdBCklDRk9oaXdT
MEhrR1VTcGE2NWwzdW9NQklwcGFsd1BWSXBpa1YzREdTUUUKLT4gWDI1NTE5IFN4
Nlg1OXFNMjVzbDlRME01WW5iMTZvU05hUTExNnB4MFpUQ1QreXFXbmMKb3BzamRT
OVM0TWZIdkJnYlByRjRQUXNtQWtXS1FXRVlFTkpSNHFVTWV3OAotPiBpQy1ncmVh
c2UgJT9RYi1YewpadEZzVUpqc3F4U09zUQotLS0gWkg5ZWlxYUJGMUVDd2o0TTJT
OTk0WlJ2aE96Z3FGNmQrNEx6Z3N5UkRxbwrp1nF8mtgoTEYfQ/aE7KgzFOei1PVt
cLAh3v7wo7C3lxhBOL0v8ToIAVgSoGP6cj9/4k7+9GngpOgot0IOdoXsThVdcg7w
soDjArsSWDYn6Th0yZf+trSXfA24BKIS5qQnAMT2ivQQtO9Kqxko2Zj6+wZO4LEj
DEr7cqRCWVFfvPLJurkfbCRjGlW2rKMlJotnLMYTE+Ot5SlSwVic5Nu3inGx1U/a
gKjCPfWw1h0Gus6PKXpSq8wGrGp+ov4ocpDmumbgh/E0D82JtBBPoWojxuGSFzrm
UDKrgx7MObGbjwkj5Xd+SDdKytjNqV+9g8GdRYVGhIr3muLn2JJlKKw/eD4Now86
tPB3ms/E1N0HR/LoQ/Y65WeuHKgv55CZMWauC/1ECxVS/jDAXnQ2lAqFlzmU1ItQ
4EefV7FRWxgMeMOIVKOCus03Js4yZp+5byjJ7+O3MRrOED9/M60B60zXhvPDtwb3
D5sFtC0ZBZT1+d4pUnEnLzSjM8DTf9as1uoNSuzh6ASiSiepAhdKMNtS8xzo85bf
Yw2WxiXQfSyN2xWWjSH/YQUXKZRBNATxB0FRMaa1TOFKo0dDYOAu83bY7wwAwSvZ
zCZ1QepCCjiWe7ujd9HMPWDgnvd47c8teSYgjX0T4nCEk7EbNpUcrDXcz78ZKAlm
VNuu8C5oi5Lk7972SBLj6yLpj27FDMagSvX30k1sMoHcKGiKnkSkdw56B+yHwLYL
Iic2mxklXggIYLo1gNq0tQskp/I0dFGUzAF1AblLw0b9Gqj/fHwHtkx/Q5n+NE82
jSVVRTI444cMlXKnyk2sVKKOWR60WXQWs/GdH5Oln42tmFT6yZk8OV7RopLPUXx2
4jwwWvVOrAMhmTwJDbzUwEIm/nfay7wzJinjNod67u0muq79OP9k0pRB6u3mSYZ4
ZX3RhRoIYiYHCDrw0e8eWKjlhzaA7tI+diHdC62SR1cUbYbRrLiXrU+ZPjG2qDTI
eAI8/wUMSHNyXdBejLRZHy7l38LKzAG3SSWBtNuCpAiP/QWCFL4UyEMlQ3Fmmzp/
FDgNLldzhOMDK8eqGAgG+qVRaK+30SJc2/ydjilg2H/KxK8C4F7Q+ul3QV+p66KF
D0h1JpWxSRhK5St01FdtFigSsA2QBg4kP87gGFmI/y05jbj/XjG7D3BQtBbRnKVG
uQ==
-----END AGE ENCRYPTED FILE-----

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