Compare commits

..

814 Commits

Author SHA1 Message Date
1f4494d333 fix postfix hopefully 2026-01-28 15:09:47 -06:00
85255adb2c fix postfix hopefully 2026-01-28 14:10:10 -06:00
f251a6f5c7 fix postfix hopefully 2026-01-28 13:48:37 -06:00
1f84cf19c7 fix postfix hopefully 2026-01-28 12:28:14 -06:00
0e49c1b9ee add japanese fonts and input 2026-01-09 23:10:42 -06:00
3ff5251b15 add yveltal back to device list 2026-01-09 20:23:13 -06:00
007c66c007 device list on syncthing 2026-01-09 20:17:00 -06:00
d37a0ce652 updates for mew setup 2026-01-09 20:00:08 -06:00
5ab6c9e4c8 add anki 2026-01-09 19:46:02 -06:00
fccec4d504 add anki 2026-01-09 19:45:49 -06:00
8feda54866 updates for mew setup 2026-01-09 19:18:15 -06:00
7179e6f047 mew added 2026-01-09 18:50:18 -06:00
1da9d994de add new host 2026-01-09 18:02:44 -06:00
e213c64481 add key for ipad 2026-01-09 00:02:43 -06:00
49ac3c2bf5 add ipad to syncthing client 2026-01-08 16:32:21 -06:00
8acebb13cc add ipad to syncthing fixed 2026-01-08 16:28:56 -06:00
ff08538bae add ipad to syncthing 2026-01-08 16:26:40 -06:00
494ac6cf57 switch back to listen address 2025-12-30 13:53:50 -06:00
4cfddd2c7e updates 2025-12-30 13:30:18 -06:00
60509f93f0 fix proxys 2025-12-27 21:02:34 -06:00
96d8fd1129 bind dns to interfact rather then ip 2025-12-13 13:20:55 -06:00
39264279e0 add cobblemon to motd 2025-12-04 20:59:21 -06:00
07c9533255 fix ssh message 2025-12-04 20:32:30 -06:00
015f416169 finish cobblemon, add to glance 2025-12-04 20:30:00 -06:00
35d8c83423 fix postfix 2025-12-04 20:13:38 -06:00
b488af297a fixin cobblemon, and new version warning finally GOD 2025-12-04 20:10:35 -06:00
dbb5560793 fixin cobblemon 2025-12-04 20:01:52 -06:00
7bcfef3ccf enable cobblemon and modded mc in general 2025-12-04 19:57:06 -06:00
a1fd3b3af2 fix postfix 2025-12-04 19:44:13 -06:00
a45d9014dd 25.11 2025-12-04 19:39:07 -06:00
80451e9430 added cobblemon 2025-12-04 19:37:52 -06:00
df1a77f73e added cobblemon 2025-12-04 19:37:40 -06:00
6f51671dbb updates 2025-11-25 19:28:49 -06:00
a238d2b61c updates 2025-11-20 16:56:11 -06:00
62dd3f5d7c darwin updates 2025-11-17 15:43:55 -06:00
8b8dc8cde8 show casing shit 2025-11-17 15:37:38 -06:00
3047ff97b4 add wallpapers 2025-11-12 22:11:01 -06:00
1c963f5563 fin udiskie 2025-11-12 21:48:02 -06:00
c02f2853c1 add icons, didnt do anything lmao 2025-11-12 21:47:12 -06:00
d73a561b9d add udiskie for automount 2025-11-12 21:11:10 -06:00
7d97acfdfb add udiskie for automount 2025-11-12 21:10:22 -06:00
cfb55f980d fix zdot till stable update 2025-11-12 00:36:23 -06:00
1a67b02d7c make gpg work with yubi smartcard 2025-11-12 00:19:07 -06:00
0196b1d8b2 a whole lotta shit 2025-11-12 00:14:50 -06:00
d7a6a85841 add folder for new device 2025-11-11 22:04:48 -06:00
cc7aca0fce fix gitea 2025-11-11 20:17:13 -06:00
6b393c7e4f add default branch 2025-11-11 20:15:35 -06:00
c9bcda6043 fix relative path in dotdir 2025-11-11 19:29:37 -06:00
7ce43bf8e7 add cifs client side mounts 2025-11-11 19:28:22 -06:00
5a451bcaa1 add cifs client side mounts 2025-11-11 19:08:56 -06:00
b4bba876ae ssh temp fix for stable rn 2025-11-11 17:36:06 -06:00
005d0451f5 testing ssh 2025-11-11 17:33:52 -06:00
d20a1787c2 testing ssh 2025-11-11 17:25:42 -06:00
6bb1a13741 test id file 2025-11-11 17:15:27 -06:00
b21060e78d fix snowbelle specific home man config 2025-11-11 17:10:51 -06:00
8caa3b6fe7 ssh changes 2025-11-11 17:04:24 -06:00
6fb6dc7abb add blake ssh key 2025-11-11 16:50:42 -06:00
4a6eb5059c add blake ssh key 2025-11-11 16:49:10 -06:00
d92a192a7f random shit 2025-11-11 16:34:13 -06:00
51c3ae6d1e fin secureboot support 2025-11-11 16:29:31 -06:00
2ea0b96230 add secure boot support 2025-11-11 15:55:18 -06:00
f7ece5059d add secure boot support 2025-11-11 15:51:22 -06:00
b84a2d7628 change wallpaper back 2025-11-11 15:35:29 -06:00
b78a43d40a add fastfetch 2025-11-08 12:15:03 -06:00
f5ff1a6639 attempt to fix flatpaks not appearing in tofi 2025-11-07 20:54:57 -06:00
0534a04108 mime shit 2025-11-07 18:55:05 -06:00
4af26da42f add flatpaks with nix-flatpak, but like right this time 2025-11-07 18:38:37 -06:00
d014733441 add flatpaks with nix-flatpak 2025-11-07 18:22:05 -06:00
38c0191ad2 clean up gitea config from testing 2025-11-07 17:22:35 -06:00
2bbbd49a07 fix ssh config 2025-11-07 17:21:00 -06:00
38a22b5255 update ssh config 2025-11-07 17:17:01 -06:00
a787a7dfc5 fin gitea testing 2025-11-07 17:10:37 -06:00
4349ccb132 fix ssh, back to built in 2025-11-07 17:09:29 -06:00
96920b6b3d attempt to use systemssh 2025-11-07 16:35:13 -06:00
b97d7e4cb1 just add a second entry for local access 2025-11-07 16:23:01 -06:00
59927a4e3d testing local access 2025-11-07 16:21:06 -06:00
076653fd15 remove local url 2025-11-07 16:19:49 -06:00
63dcc450b6 change reverseproxy for gitea 2025-11-07 16:19:32 -06:00
c15704eb22 add local root url 2025-11-07 16:19:32 -06:00
85f7a2889c restructure slippi into gaming subdir 2025-11-07 15:35:58 -06:00
6bfea61ffe restructure slippi into gaming subdir 2025-11-07 15:35:45 -06:00
4e0cc2a322 hope this is the right binary lmao 2025-11-07 15:06:54 -06:00
7ef99c8dd1 add userspace tools and passwdless sudo 2025-11-07 15:05:42 -06:00
1655c0a867 add nh, a nix cli helper tool 2025-11-07 14:54:33 -06:00
724c63f9ff add shortcut to goto ~/.nix 2025-11-07 04:21:22 -06:00
5813db8160 rearrange common nix config, add optimising and garbage collecting 2025-11-07 04:18:09 -06:00
cdf8403991 restructure programs (yes again okay like shut up), reorg standard packages, add obs : ) 2025-11-07 03:54:32 -06:00
10488b90c9 adjust default packages 2025-11-07 03:38:03 -06:00
bcb1b88861 add motd alias 2025-11-07 03:13:49 -06:00
e27be65861 explain gcc import 2025-11-07 03:10:34 -06:00
0e0e58b909 slippi sucess! 2025-11-07 02:59:34 -06:00
4e3a31cf87 more config shullfing, browsers moved, slippi added WOOO 2025-11-07 02:17:58 -06:00
58e68a003a cleaning up my mess so hopefully this shit builds 2025-11-07 01:41:48 -06:00
82d61d54eb add even more programs 2025-11-07 01:34:30 -06:00
fa981032d4 add even more programs 2025-11-07 01:34:26 -06:00
5090fa9cd4 add even more programs 2025-11-07 01:34:06 -06:00
125d639f9f add even more programs 2025-11-07 01:33:20 -06:00
9ad80827ee add a whole shit ton of programs 2025-11-07 01:14:38 -06:00
f0fa2540b5 remove icon for non urgent messages 2025-11-07 00:35:21 -06:00
0bfe74abb7 fix icon paths 2025-11-07 00:33:56 -06:00
766e20ffc4 update icon paths 2025-11-07 00:29:47 -06:00
178fba9c84 remove unused scripts, renamed the rest, updated zsh conf to reflect this 2025-11-07 00:22:42 -06:00
eef41bbca8 fucking with tofi 2025-11-06 23:53:44 -06:00
a0c728f147 tofi adjustments 2025-11-06 23:48:15 -06:00
35645a3e9c fixed launch option comment 2025-11-06 23:29:40 -06:00
67002a94dd finally figured out the cursors, needed to use the setcursor commadn in hyprctl 2025-11-06 23:11:37 -06:00
6beb28477f add hypr specific? 2025-11-06 22:42:07 -06:00
dc03836ac0 with the right name this time 2025-11-06 22:40:12 -06:00
646ba6d63f try w/o pointer cursor just vars 2025-11-06 22:39:19 -06:00
e34b5161d4 this is the one, add the links 2025-11-06 22:38:15 -06:00
81c59857e5 this is the one I swear the env vars will work 2025-11-06 22:36:24 -06:00
7576364d43 happy middle ground 2025-11-06 22:30:22 -06:00
f31eefe6eb fuck this custom cursor shit 2025-11-06 22:26:01 -06:00
788155194f finished troubleshooting a ghost 2025-11-06 22:15:37 -06:00
777c4f3192 fix paths... again 2025-11-06 22:10:49 -06:00
e7ed3e584d fix paths 2025-11-06 22:07:53 -06:00
af9d2553d5 try and add cursors 2025-11-06 22:04:43 -06:00
14c67a8bb3 test failed, large sad 2025-11-06 00:26:41 -06:00
97d2610240 fprintd test 2025-11-06 00:22:37 -06:00
2e36efa1c3 cleanup 2025-11-06 00:11:13 -06:00
8a781d6b2a fix bb alias 2025-11-06 00:06:25 -06:00
c8a036edc2 all hardcoded paths in home man 2025-11-06 00:05:12 -06:00
f0a8d8f0fb remove more hard coded paths 2025-11-05 23:58:04 -06:00
303c759bb4 remove hard coded paths 2025-11-05 23:51:05 -06:00
c243c4393f adjust popup settings 2025-11-05 23:45:06 -06:00
de4822bc68 make dunst declaritive 2025-11-05 23:30:42 -06:00
ed3046e18a wrap up suspend-then-hibernate 2025-11-05 23:14:26 -06:00
e3546caeb5 i think i finally figured out hibernate then sleep 2025-11-05 22:53:27 -06:00
cc083128a3 testing timeout 2025-11-05 22:23:24 -06:00
9faad0e16c add proper target 2025-11-05 22:21:05 -06:00
e50f503270 wait its something else 2025-11-05 22:18:46 -06:00
8a502bdf15 didnt work lmao 2025-11-05 22:17:53 -06:00
32d737f011 attempt to use suspend then hibrnate again 2025-11-05 22:16:51 -06:00
7f84ae360c add theming for qt 2025-11-05 22:15:46 -06:00
bce6234c10 add qalculate-qt 2025-11-05 22:13:38 -06:00
7572b52d6f please? 2025-11-05 21:56:42 -06:00
68ca7ff5f8 i swear this time 2025-11-05 21:54:50 -06:00
51d9300990 fix clipboard once and for all 2025-11-05 21:51:59 -06:00
183eb27980 fix controller 2025-11-05 21:38:12 -06:00
3f689d46f4 all renames 2025-11-05 21:34:52 -06:00
2a576d8d39 did it, add all sinks 2025-11-05 21:30:34 -06:00
e92206ae43 this is the one 2025-11-05 21:25:15 -06:00
733145692f maybe? 2025-11-05 21:12:19 -06:00
ad8b20fd0c actually install the fucking wl-clipboard idiot 2025-11-05 21:00:23 -06:00
d9c20efa16 make nvf use wl-copy 2025-11-05 20:52:31 -06:00
3bbe306485 add clipboard 2025-11-05 20:48:56 -06:00
f9ac7944b3 add explicit pipewire config 2025-11-05 19:33:15 -06:00
eff39f2218 add explicit pipewire config 2025-11-05 19:33:07 -06:00
cdbb5f913d add gaming 2025-11-05 19:09:55 -06:00
e329c17546 add gaming 2025-11-05 19:05:56 -06:00
85c8b9ec1c restructure desktop with option config wrappers 2025-11-05 18:41:33 -06:00
96fd9d96c1 restructure desktop with option config wrappers 2025-11-05 18:41:07 -06:00
090889dff2 restructure desktop with option config wrappers 2025-11-05 18:40:34 -06:00
8c4a82a73f restructure desktop with option config wrappers 2025-11-05 18:40:25 -06:00
f448ce43ec add userspace tools for intel 2025-11-05 18:31:13 -06:00
2fb0dc4c50 fix refs to graphics 2025-11-05 18:28:15 -06:00
2ed9add88e more stupid shit 2025-11-05 18:27:20 -06:00
881d4dd78a punc error lmao 2025-11-05 18:26:48 -06:00
ad487e6715 update nvidia module to graphics and add support for amd and intel 2025-11-05 18:25:55 -06:00
f107cf19c7 update nvidia module to graphics and add support for amd and intel 2025-11-05 18:24:30 -06:00
f5bc0400ae change cert to one for blakedheld.xyz 2025-11-04 23:52:17 -06:00
96ca6c6ea0 hopeing 2025-11-04 23:43:29 -06:00
610513edb7 change extraUpFlags to extraSetFlags across the board 2025-11-04 23:18:56 -06:00
f49978d587 add extraSetFlags to tailscale config 2025-11-04 23:15:39 -06:00
cb4234630b ts test 2025-11-04 23:13:05 -06:00
992616c1ca testing ts 2025-11-04 23:12:19 -06:00
7b39e418c9 add advertisement to snowbelle itself 2025-11-04 23:08:21 -06:00
adf9d1ee4a could fix it all 2025-11-04 22:58:38 -06:00
0c4aed6591 add some packages 2025-11-04 22:54:41 -06:00
1f8fe59423 put it back? 2025-11-04 22:53:18 -06:00
0fc620e7da fix tm 2025-11-04 22:53:18 -06:00
245f06fd3a remove timemachine 2025-11-04 22:53:18 -06:00
d39fb7af39 add sudo insults 2025-11-04 00:53:55 -06:00
6ddebc86d7 add config wrapper for stylix wallpaper 2025-11-04 00:48:03 -06:00
e2047cba7b final test of mixed stable and unstable 2025-11-04 00:03:35 -06:00
d7ae540ebf make this dumb unstable and stable shit work 2025-11-04 00:02:26 -06:00
0fae0e72d3 hardware config removal test 2025-11-03 22:48:41 -06:00
3304d04d9d dear lord PLEASE 2025-11-03 22:35:46 -06:00
e54f91bcd9 fix tofi-drun 2025-11-03 21:34:29 -06:00
4d38c79dfa updates! 2025-11-03 21:33:52 -06:00
946413ada0 big home manager dotfile restructure 2025-11-03 21:13:26 -06:00
4c9b1651bf big home manager dotfile restructure 2025-11-03 21:13:05 -06:00
0fc3f1f501 big home manager dotfile restructure 2025-11-03 21:12:34 -06:00
9b758fdd96 add ignore patterns to syncthing 2025-11-03 20:35:18 -06:00
225d102cea fix lf 2025-11-03 20:21:27 -06:00
38b298fcd6 break core out to own config 2025-11-03 20:13:15 -06:00
a9579a7bf9 break core out to own config 2025-11-03 20:06:14 -06:00
1192cef3ed break core out to own config 2025-11-03 20:03:21 -06:00
8eae778b23 break core out to own config 2025-11-03 20:03:00 -06:00
61fb81abef update wallpaper to yveltal, me likes 2025-11-03 19:59:53 -06:00
03c0b51343 change wallpaper again lmao 2025-11-03 19:37:04 -06:00
647c94bd6e cleanup enables, change wallpaper 2025-11-03 19:23:29 -06:00
e21db6c245 configure btop with stylix 2025-11-02 12:42:29 -06:00
97b66bbb33 configure stylix and allow default to remain, autoenable is now on 2025-11-02 12:42:18 -06:00
edafa28c3e configure stylix 2025-11-02 12:27:08 -06:00
400ac5212f add firefox 2025-11-02 10:20:11 -06:00
c1182d8521 fix stylix imports 2025-11-02 09:59:10 -06:00
b0bcc1040e break tailscale into 2 configs for server and client 2025-11-02 09:58:23 -06:00
b08cb2ea82 break tailscale into 2 configs for server and client 2025-11-02 09:58:21 -06:00
021c4a9172 add dig to nixos common packages 2025-11-02 09:48:41 -06:00
dcf958c0a8 add howdy to tuigreet 2025-11-02 09:48:13 -06:00
037a9b08e3 change greetd to tty2 to supress console output in passwd box 2025-11-01 21:51:56 -05:00
11f247bac8 change greetd to tty2 to supress console output in passwd box 2025-11-01 21:41:22 -05:00
dd34c532d0 add dunst 2025-11-01 21:39:12 -05:00
8b2dd3829a add dunst 2025-11-01 21:37:45 -05:00
0b6e0b7577 syncthing fin 2025-11-01 21:31:26 -05:00
0038a61fff git nonsense 2025-11-01 21:30:49 -05:00
5c1e292f60 testing git ssh with yubi 2025-11-01 21:07:07 -05:00
fc0f270c34 test 2025-11-01 21:06:23 -05:00
9f22aef6af test 2025-11-01 21:06:11 -05:00
f04911def2 add declatrive cert and pem to secrets 2025-11-01 21:05:39 -05:00
329f156f87 syncthing adjustments, adding yveltal 2025-11-01 21:03:20 -05:00
f43f3b1749 add yveltal to syncthing on holocron 2025-11-01 21:01:53 -05:00
d4bcd95d52 add syncthing 2025-11-01 21:00:46 -05:00
f1e9914ea1 add syncthing 2025-11-01 20:33:29 -05:00
419d86342d add tofi 2025-11-01 19:13:08 -05:00
b5b9633c3c add tofi 2025-11-01 19:09:58 -05:00
93e1150a56 add tofi 2025-11-01 19:09:24 -05:00
ba40661f5e add host specific home manager config for snowbelle 2025-11-01 17:56:01 -05:00
a6d2c0030d remove sshDefaultConfig till 25.11 drops 2025-11-01 17:51:59 -05:00
458090e795 add power switch handling to host specific config 2025-11-01 17:51:03 -05:00
4078ed0d21 add config wrappers to everything in home manager 2025-11-01 17:49:49 -05:00
4a995d51c3 add config wrappers to everything in home manager 2025-11-01 17:47:19 -05:00
84b7477cff a little restructuring of home manager to focus on host specific configs 2025-11-01 12:33:27 -05:00
ba2bcba53b add yubikey signin 2025-10-31 00:29:20 -05:00
ec252348fd didnt need 2025-10-30 23:36:10 -05:00
5a20416be1 rename tuigreet to new package name 2025-10-30 22:55:36 -05:00
83bdbd296f add pikacig 2025-10-30 22:52:32 -05:00
b48bd36fd7 actually start waybar lmao 2025-10-30 22:49:00 -05:00
728425868c restructure to actually import waybar with home man 2025-10-30 22:47:08 -05:00
69d748c3ff add waybar and librewolf 2025-10-30 22:40:47 -05:00
4e59f2d8ca add waybar and librewolf 2025-10-30 22:36:04 -05:00
817f2b29a3 add hyprcursor settings 2025-10-29 22:41:51 -05:00
c1ae4d7060 dunno 2025-10-28 22:35:10 -05:00
fd4119a579 add greetd 2025-10-28 22:34:06 -05:00
fb64e3406b add greetd 2025-10-28 22:33:54 -05:00
1268291250 add userspace yubi tools 2025-10-28 22:18:25 -05:00
5e3155b465 fix perms 2025-10-25 14:39:45 -05:00
de0117edff yveltal init 2025-10-25 14:36:52 -05:00
700943ab97 laied out the groundwork for hyprland 2025-10-25 12:14:34 -05:00
6fa11eea8f add hypr stuff and remove current_system var fromflake 2025-10-25 10:55:00 -05:00
2d1d85ddc6 laying ground work for hyprland and yveltal 2025-10-24 21:40:13 -05:00
7a371f3b1e fuck it nah its only 30 min 2025-10-23 22:40:30 -05:00
bf8c4d050d make smart tests less frequent 2025-10-23 22:36:47 -05:00
1832c5ac83 clean up and finish syncthing to holocron 2025-10-23 22:33:11 -05:00
6f1c74d243 add syncthing to proxy and glance 2025-10-23 22:16:25 -05:00
d1dde74c4f add holocron folder ID 2025-10-23 22:02:02 -05:00
05607c2b48 add syncthing to holocron 2025-10-23 21:57:50 -05:00
eea735134d add syncthing to holocron 2025-10-23 21:55:44 -05:00
d9f06234fd add syncthing to holocron 2025-10-23 21:55:18 -05:00
f4b505d1d1 update 2025-10-23 19:30:03 -05:00
24ac2aca51 disable ensure perms 2025-10-22 22:20:20 -05:00
4881ac5808 fix zfs 2025-10-22 22:12:54 -05:00
b7fb67f939 add ffmpeg to sonarr and radarr 2025-10-22 21:50:35 -05:00
32f37c7c2e add automatic smart testing 2025-10-19 15:06:10 -05:00
0a31b25d83 test email 2025-10-19 14:49:15 -05:00
acc28d9278 add email notifs to zfs and smart 2025-10-19 14:44:35 -05:00
ae04500e63 postfix with gmail 2025-10-19 14:33:36 -05:00
f463b76253 try with apple 2025-10-19 14:13:23 -05:00
5298430415 try with apple email 2025-10-19 14:11:47 -05:00
14f790e67a update options to support new syntax 2025-10-19 14:06:42 -05:00
6ca265e97b add postfix 2025-10-19 13:59:06 -05:00
7b11dbdcfa give copyparty access to archives 2025-10-19 13:32:31 -05:00
652f005769 restructure homemanager to support multiplatforms 2025-10-19 03:40:04 -05:00
2149a58293 finish new backups and restructure gameservers 2025-10-18 18:58:59 -05:00
62a813eb81 no sudo bro wtf? 2025-10-18 18:44:21 -05:00
f11dbc52bc no awk 2025-10-18 18:43:18 -05:00
3e216701e0 final touches backups now start the db backups automatcially 2025-10-18 18:41:23 -05:00
f72e067a4e ensure immich gets backed up 2025-10-18 18:22:37 -05:00
39336740e1 ensure postgres backups exist 2025-10-18 18:18:03 -05:00
c8e7d0ac7f touch up mc backups 2025-10-18 18:09:36 -05:00
4991af44c3 fin backups 2025-10-18 17:58:05 -05:00
7fd8610476 fin backups 2025-10-18 17:57:38 -05:00
3eb9c9b402 backups shenanagians 2025-10-18 17:06:33 -05:00
f2c320d9ee fix immich 2025-10-18 15:09:50 -05:00
76d3410702 new backup browser 2025-10-18 15:00:50 -05:00
256b532938 deadass fix it this time 2025-10-18 14:29:58 -05:00
27fb031175 fix perms script 2025-10-18 14:23:46 -05:00
eef0c8cf27 fix timing 2025-10-18 14:01:34 -05:00
643ab0958c restructure backups 2025-10-18 13:51:23 -05:00
f597616843 update new backups 2025-10-18 12:58:00 -05:00
e4378fc6fe tee hee 2025-10-18 02:29:14 -05:00
bb65d89c39 add reformatted backups as test 2025-10-18 02:04:48 -05:00
93a3b83127 qtesting home man structure for macos support 2025-10-18 01:11:38 -05:00
2f77f3b3a3 gameserver backups 2025-10-17 21:10:42 -05:00
13a5def7d7 game server backups 2025-10-17 20:37:01 -05:00
40f047eb1e fix path 2025-10-17 20:10:34 -05:00
3cba1640e0 timemachine changes 2025-10-17 20:07:31 -05:00
3b12bf7081 fix path 2025-10-17 20:04:53 -05:00
06ec73de0b database backup refining 2025-10-17 20:03:56 -05:00
6d3ae434a5 so much shit my b, adding db backups tho 2025-10-17 19:42:39 -05:00
1cc6abb89a testing use of unstable 2025-10-17 16:11:31 -05:00
25122a4c9c restructure hosts 2025-10-17 16:03:44 -05:00
d4f55ea042 macos shit 2025-10-17 15:14:22 -05:00
52d96b7b2d test fin gn 2025-10-17 03:26:38 -05:00
598abd3c51 xdg os check 2025-10-17 03:25:17 -05:00
f5f1ad4580 sorry but this ones just lots of shit 2025-10-17 03:10:20 -05:00
26d060e672 add yubikey config 2025-10-16 21:48:44 -05:00
a3424c1158 adjust timers for specific timer 2025-10-16 21:14:49 -05:00
1083c6c3e4 finalize ensure perms 2025-10-16 21:12:25 -05:00
0f2750b644 final adjustments to the slop 2025-10-16 20:36:42 -05:00
32a6d09113 add ensure perms 2025-10-16 20:28:44 -05:00
0fd7319de6 add archives group 2025-10-16 20:02:17 -05:00
8438c58c19 add env 2025-10-16 00:45:32 -05:00
18679fc6ca fix perms 2025-10-16 00:37:45 -05:00
2ad827e5fd better i hope 2025-10-16 00:08:57 -05:00
311ac16dfc add ssh keys 2025-10-16 00:05:15 -05:00
270f3cc9ee spring cleaning 2025-10-15 23:46:45 -05:00
3f0ae38007 colors again 2025-10-15 23:24:38 -05:00
137ee537a8 finalize colors 2025-10-15 23:21:52 -05:00
1118071813 finalize zsh 2025-10-15 23:07:01 -05:00
0450772e62 move ssh out to its own file and add zsh 2025-10-15 22:59:55 -05:00
89b6380859 move ssh out to its own file and add zsh 2025-10-15 22:58:39 -05:00
26401360d8 add other homes update paths 2025-10-15 21:35:24 -05:00
f72a26d827 add xdg 2025-10-15 21:27:34 -05:00
9fabb9143e restructure home manager 2025-10-15 20:48:38 -05:00
cc23884880 fixed the relase info 2025-10-15 20:31:37 -05:00
989ae8a432 fix 2025-10-15 20:29:27 -05:00
9d38741068 add nix release 2025-10-15 20:28:16 -05:00
aebc51cc2e fix formatting on service list 2025-10-15 20:25:06 -05:00
b868f691d8 add masks to shares 2025-10-15 19:23:38 -05:00
40077f3c6c add nfs-utils 2025-10-15 18:27:43 -05:00
dd5c53a979 powertop 2025-10-15 12:07:44 -05:00
dbf4ce2834 add power management 2025-10-15 11:20:14 -05:00
c55e813b52 fix motd auto run 2025-10-15 08:44:17 -05:00
9934e12985 fix motd run on login instead of print 2025-10-15 08:42:39 -05:00
d2cbb8dc81 print motd 2025-10-15 08:38:05 -05:00
da7c4fe652 add seaches to nix pkgs and options as well as hm options to glance search 2025-10-15 08:34:28 -05:00
ce3b8bf27a fr this time deadass on god for on it all 2025-10-14 23:48:54 -05:00
cee4da2a1d indents lol 2025-10-14 23:48:00 -05:00
a1118ba84f gn o/ <3 2025-10-14 23:47:09 -05:00
f25c552f76 going to sleep 2025-10-14 23:46:15 -05:00
09991e9684 finished motd 2025-10-14 23:34:50 -05:00
9347a392f1 better? 2025-10-14 23:29:40 -05:00
7a8a9e1c03 done 2025-10-14 23:22:24 -05:00
c84b11c4c4 done 2025-10-14 23:18:07 -05:00
835782ff53 hehe 2025-10-14 23:16:08 -05:00
7925577fe4 nah fr tho this time 2025-10-14 22:48:38 -05:00
65fdac2492 now fr 2025-10-14 22:42:25 -05:00
0c4008b544 fin for real? 2025-10-14 22:40:02 -05:00
4d3935527b add motd to everyone! 2025-10-14 22:29:43 -05:00
e32bdff7a8 fin 2025-10-14 22:25:25 -05:00
8321e6fe2c fix colors 2025-10-14 22:23:16 -05:00
69a671559a its done, deadass this time 2025-10-14 21:51:53 -05:00
e8a54ec95c deadass this time 2025-10-14 21:48:25 -05:00
7a211acea3 fix motd 2025-10-14 21:43:17 -05:00
1e8b341977 fix motd 2025-10-14 21:38:46 -05:00
a92f00a2ac testing motd 2025-10-14 21:30:11 -05:00
86d3855734 testing new motd 2025-10-14 21:27:07 -05:00
0057e3f757 testing 2025-10-14 21:25:41 -05:00
28856a1328 add motd 2025-10-14 21:06:17 -05:00
1782467549 adjust perms for copyparty 2025-10-14 20:45:55 -05:00
9c4f5716a2 real ip 2025-10-14 15:59:55 -05:00
d75853b9ee real ip 2025-10-14 15:55:53 -05:00
b688978b54 add config to copyparty 2025-10-14 15:46:16 -05:00
acadff6243 add copyparty 2025-10-14 13:27:16 -05:00
c01b0d8a99 add copyparty 2025-10-14 13:21:59 -05:00
9f6d24f885 add copyparty 2025-10-14 13:19:24 -05:00
8c19c9a228 add copyparty 2025-10-14 13:18:31 -05:00
06587673c0 restructure zfs 2025-10-14 12:21:06 -05:00
a960e1a018 fix mount points 2025-10-14 10:44:59 -05:00
5b83fe0f1d change glance to use duck duck go 2025-10-14 10:32:14 -05:00
a3e8019878 rename file share to holocron 2025-10-14 10:25:03 -05:00
182cab6bf3 restructure user 2025-10-14 00:20:29 -05:00
782ebcf4e3 restructured user 2025-10-14 00:10:18 -05:00
ea2be0de28 restructured user 2025-10-14 00:09:11 -05:00
977d97fc0d steady state b4 bed 2025-10-13 22:45:54 -05:00
8ec44dab44 added system to dirs 2025-10-13 22:25:43 -05:00
962f44f05e FUCK YOU MODULES HOMELAB RULES 2025-10-13 22:18:10 -05:00
6682df4338 deadass this time ^ 2025-10-13 21:54:43 -05:00
3fa91f0670 test swapping to new nvf branch B/C the FUCKING WEAKLLSJHFK L:HAS 2025-10-13 21:48:08 -05:00
9f7a97c6d9 big restructure, getting there prayers for rebuild fix #? 2025-10-13 21:36:34 -05:00
7da8407475 big restructure, getting there prayers for rebuild fix #4 2025-10-13 21:32:13 -05:00
d4eefb864e big restructure, getting there prayers for rebuild fix #2 2025-10-13 21:31:09 -05:00
c02dafd0d1 big restructure, getting there prayers for rebuild 2025-10-13 21:29:04 -05:00
9128bf3d66 qbit permissions up 2025-10-13 20:53:00 -05:00
042787770e trashy! 2025-10-13 20:06:47 -05:00
afb451d3cc lfrc symlink 2025-10-13 20:05:19 -05:00
1d1a13d9ce add lf 2025-10-13 18:40:20 -05:00
ba38794ef4 add basic stat monitoring to backup script 2025-10-13 17:35:54 -05:00
30302af17b add stats to backups 2025-10-13 17:27:13 -05:00
2f627902f3 update "${services}" 2025-10-13 16:25:33 -05:00
3b2460f97a add formatter 2025-10-13 15:54:29 -05:00
c73adbe26f keymaps! 2025-10-13 15:37:40 -05:00
59476285df update vim config 2025-10-13 15:17:04 -05:00
68ee7894a0 add nvf 2025-10-13 15:04:14 -05:00
dc5c5038b9 zsh test fin 2025-10-13 12:02:49 -05:00
61e8436dd9 update proxy config 2025-10-12 22:24:09 -05:00
cae85ef2e6 tls insecure 2025-10-12 21:22:14 -05:00
6226177c08 troubleshooting certs 2025-10-12 20:13:51 -05:00
593449d0c3 troubleshooting 2025-10-12 20:12:53 -05:00
c1e56790c5 finallyy? 2025-10-12 20:11:00 -05:00
3acd59d938 i fixed it 2025-10-12 20:00:31 -05:00
758ab5beb1 fix backup script to fucking work bro exit 0 my ass and add mode selector 2025-10-12 19:19:23 -05:00
39c108b3ee add podman compose 2025-10-12 19:01:52 -05:00
cd55d1d7cf troubleshoot suwayomi 2025-10-12 18:21:26 -05:00
f76c6862ba add suwayomi 2025-10-12 16:41:29 -05:00
abcad5c9f2 adding yacreader 2025-10-12 16:09:41 -05:00
b89c6a14cc add uptime kuma integration 2025-10-12 15:35:14 -05:00
86582c0dcc add uptime kuma integration 2025-10-12 15:30:36 -05:00
460d79c107 add status monitor to glance 2025-10-12 15:05:08 -05:00
394d12a7b2 clean up glance and try and add minecraft monitor 2025-10-12 14:55:09 -05:00
2cc42a5800 I think get it working lmao 2025-10-12 14:16:31 -05:00
4c6f6ee68d troubleshoot key site 2025-10-12 14:14:46 -05:00
15d82a44fb caddy testing 2025-10-12 14:13:09 -05:00
5168f5fc3e removed nginx and altered caddy (build script changes too) 2025-10-12 13:57:35 -05:00
d58262a043 rm nginx, adjust caddy for testing, redo rebuild script 2025-10-12 13:44:28 -05:00
2db7081bfc 355 current 2025-10-12 12:06:38 25.05.20251006.20c4598 6.12.50 * 2025-10-12 12:21:38 -05:00
bad309eb60 355 current 2025-10-12 12:06:38 25.05.20251006.20c4598 6.12.50 * 2025-10-12 12:09:54 -05:00
6ca3f8fedc 354 current 2025-10-12 12:04:23 25.05.20251006.20c4598 6.12.50 * 2025-10-12 12:06:40 -05:00
cd4cd68e96 353 current 2025-10-12 12:02:06 25.05.20251006.20c4598 6.12.50 * 2025-10-12 12:04:25 -05:00
f6379435b8 352 current 2025-10-12 12:00:03 25.05.20251006.20c4598 6.12.50 * 2025-10-12 12:02:08 -05:00
36213c47c9 351 current 2025-10-12 11:59:13 25.05.20251006.20c4598 6.12.50 * 2025-10-12 12:00:06 -05:00
ff096a520a 350 current 2025-10-12 11:58:18 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:59:16 -05:00
00ab2ae68c 349 current 2025-10-12 11:50:40 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:58:20 -05:00
b4bf817c5e 348 current 2025-10-12 11:49:03 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:50:42 -05:00
2b3b12b6a1 347 current 2025-10-12 11:48:00 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:49:06 -05:00
87ed8a6337 346 current 2025-10-12 11:43:32 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:48:03 -05:00
c2a543f83b 346 current 2025-10-12 11:43:32 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:46:50 -05:00
fcbf908b15 345 current 2025-10-12 11:39:59 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:43:35 -05:00
1657efcae7 344 current 2025-10-12 10:51:52 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:40:02 -05:00
ee51577189 344 current 2025-10-12 10:51:52 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:38:46 -05:00
6609922170 344 current 2025-10-12 10:51:52 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:37:58 -05:00
35be9990ba 344 current 2025-10-12 10:51:52 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:37:17 -05:00
cacb342117 344 current 2025-10-12 10:51:52 25.05.20251006.20c4598 6.12.50 * 2025-10-12 11:36:56 -05:00
23384e35ed 343 current 2025-10-12 10:50:02 25.05.20251006.20c4598 6.12.50 * 2025-10-12 10:51:56 -05:00
0897deae29 342 current 2025-10-12 10:45:09 25.05.20251006.20c4598 6.12.50 * 2025-10-12 10:50:05 -05:00
63bd01d083 341 current 2025-10-12 10:38:28 25.05.20251006.20c4598 6.12.50 * 2025-10-12 10:45:12 -05:00
5ed18c1110 340 current 2025-10-11 23:47:35 25.05.20251006.20c4598 6.12.50 * 2025-10-12 10:38:30 -05:00
f948a521c1 340 current 2025-10-11 23:47:35 25.05.20251006.20c4598 6.12.50 * 2025-10-12 10:24:29 -05:00
01982724ab 340 current 2025-10-11 23:47:35 25.05.20251006.20c4598 6.12.50 * 2025-10-12 00:20:19 -05:00
4e22635c6a 340 current 2025-10-11 23:47:35 25.05.20251006.20c4598 6.12.50 * 2025-10-12 00:17:48 -05:00
f53c815437 340 current 2025-10-11 23:47:35 25.05.20251006.20c4598 6.12.50 * 2025-10-12 00:16:27 -05:00
74ec8a9bd6 340 current 2025-10-11 23:47:35 25.05.20251006.20c4598 6.12.50 * 2025-10-11 23:59:35 -05:00
953994d724 339 current 2025-10-11 23:44:28 25.05.20251006.20c4598 6.12.50 * 2025-10-11 23:47:38 -05:00
066d5ef4b6 338 current 2025-10-11 21:54:50 25.05.20251006.20c4598 6.12.50 * 2025-10-11 23:44:31 -05:00
406dafcd48 338 current 2025-10-11 21:54:50 25.05.20251006.20c4598 6.12.50 * 2025-10-11 23:42:54 -05:00
d40192598f adding audiobooksheld 2025-10-11 23:39:48 -05:00
d416a2f495 338 current 2025-10-11 21:54:50 25.05.20251006.20c4598 6.12.50 * 2025-10-11 23:39:30 -05:00
135cf3101f 337 current 2025-10-11 20:25:59 25.05.20251006.20c4598 6.12.50 * 2025-10-11 21:54:52 -05:00
2f8046a022 337 current 2025-10-11 20:25:59 25.05.20251006.20c4598 6.12.50 * 2025-10-11 21:51:39 -05:00
c7e81bdc6a 337 current 2025-10-11 20:25:59 25.05.20251006.20c4598 6.12.50 * 2025-10-11 21:49:41 -05:00
ddeef85822 336 current 2025-10-11 20:24:22 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:26:02 -05:00
0059e6637c 335 current 2025-10-11 20:23:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:24:24 -05:00
1814824239 334 current 2025-10-11 20:16:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:23:09 -05:00
e161686a73 334 current 2025-10-11 20:16:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:20:55 -05:00
ba73f3163e 334 current 2025-10-11 20:16:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:19:59 -05:00
09b23d71f5 333 current 2025-10-11 20:08:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:16:55 -05:00
4e183acd6f 332 current 2025-10-11 20:07:14 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:08:55 -05:00
339d04c8fe 331 current 2025-10-11 20:05:53 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:07:17 -05:00
60206f942e 330 current 2025-10-11 20:03:49 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:05:56 -05:00
1ba1a158c7 329 current 2025-10-11 20:02:36 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:03:51 -05:00
cdad146bd3 328 current 2025-10-11 20:00:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:02:38 -05:00
7803ab838e 327 current 2025-10-11 19:59:24 25.05.20251006.20c4598 6.12.50 * 2025-10-11 20:00:29 -05:00
abc79b3ab1 326 current 2025-10-11 19:57:36 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:59:26 -05:00
527c1d705f 325 current 2025-10-11 19:55:21 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:57:38 -05:00
8903f8ac0e 324 current 2025-10-11 19:52:06 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:55:23 -05:00
e488f23b4c 323 current 2025-10-11 19:51:33 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:52:08 -05:00
88a7316d99 322 current 2025-10-11 19:48:34 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:51:35 -05:00
04ebc668ce 321 current 2025-10-11 19:47:16 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:48:37 -05:00
24afedc523 320 current 2025-10-11 19:42:29 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:47:18 -05:00
5c7659a5e9 320 current 2025-10-11 19:42:29 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:44:42 -05:00
e663e247e5 319 current 2025-10-11 19:39:47 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:42:31 -05:00
62f00a06b8 318 current 2025-10-11 19:37:14 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:39:50 -05:00
6829124a9f 317 current 2025-10-11 19:17:32 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:37:16 -05:00
95fb611c01 317 current 2025-10-11 19:17:32 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:36:24 -05:00
9e24635731 317 current 2025-10-11 19:17:32 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:35:38 -05:00
c9840ed29e 317 current 2025-10-11 19:17:32 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:35:09 -05:00
9bfae91d90 316 current 2025-10-11 19:11:22 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:17:34 -05:00
094678a2b1 316 current 2025-10-11 19:11:22 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:16:20 -05:00
2fc940a186 316 current 2025-10-11 19:11:22 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:15:22 -05:00
601a6d0d4e 315 current 2025-10-11 19:03:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:11:25 -05:00
7b925a2eb8 315 current 2025-10-11 19:03:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:10:20 -05:00
34eaca1383 314 current 2025-10-11 18:09:02 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:03:55 -05:00
c5f55f359b 314 current 2025-10-11 18:09:02 25.05.20251006.20c4598 6.12.50 * 2025-10-11 19:02:09 -05:00
0c8d7af971 314 current 2025-10-11 18:09:02 25.05.20251006.20c4598 6.12.50 * 2025-10-11 18:57:14 -05:00
728176d27b 314 current 2025-10-11 18:09:02 25.05.20251006.20c4598 6.12.50 * 2025-10-11 18:54:41 -05:00
384b18b575 313 current 2025-10-11 18:01:55 25.05.20251006.20c4598 6.12.50 * 2025-10-11 18:08:36 -05:00
21ecf083d2 312 current 2025-10-11 17:54:46 25.05.20251006.20c4598 6.12.50 * 2025-10-11 18:02:03 -05:00
cb340e679c 311 current 2025-10-11 17:44:24 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:54:48 -05:00
476a2106e1 310 current 2025-10-11 17:42:26 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:44:27 -05:00
03cff3b3e0 309 current 2025-10-11 17:35:20 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:42:29 -05:00
d759a3e747 308 current 2025-10-11 17:30:56 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:35:22 -05:00
9fca78ed4c 307 current 2025-10-11 17:27:31 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:30:59 -05:00
634e450ba1 306 current 2025-10-11 17:04:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:27:34 -05:00
bcfdcad1b2 306 current 2025-10-11 17:04:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:26:32 -05:00
cbaa2b9eb9 306 current 2025-10-11 17:04:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:25:08 -05:00
3f0900ed10 306 current 2025-10-11 17:04:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:24:32 -05:00
7326275c09 305 current 2025-10-11 16:58:36 25.05.20251006.20c4598 6.12.50 * 2025-10-11 17:04:40 -05:00
0ede6674dd 304 current 2025-10-11 16:50:34 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:58:38 -05:00
5c53a81353 303 current 2025-10-11 16:41:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:50:36 -05:00
e4bdf3af43 302 current 2025-10-11 16:40:25 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:41:54 -05:00
82dbb34bd0 301 current 2025-10-11 16:34:19 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:40:28 -05:00
ada2bf81db 301 current 2025-10-11 16:34:19 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:37:13 -05:00
a17626a9cb 300 current 2025-10-11 15:30:33 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:34:22 -05:00
dbca751466 300 current 2025-10-11 15:30:33 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:31:50 -05:00
91f82d7dc3 300 current 2025-10-11 15:30:33 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:31:12 -05:00
c637b6802b 300 current 2025-10-11 15:30:33 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:29:03 -05:00
f0ec85cc03 300 current 2025-10-11 15:30:33 25.05.20251006.20c4598 6.12.50 * 2025-10-11 16:28:13 -05:00
47ab6fa142 299 current 2025-10-11 14:41:20 25.05.20251006.20c4598 6.12.50 * 2025-10-11 15:30:35 -05:00
11028080bb 299 current 2025-10-11 14:41:20 25.05.20251006.20c4598 6.12.50 * 2025-10-11 15:27:52 -05:00
49528805a5 299 current 2025-10-11 14:41:20 25.05.20251006.20c4598 6.12.50 * 2025-10-11 15:24:56 -05:00
bbda7104ba 299 current 2025-10-11 14:41:20 25.05.20251006.20c4598 6.12.50 * 2025-10-11 15:23:15 -05:00
32904bd35e 299 current 2025-10-11 14:41:20 25.05.20251006.20c4598 6.12.50 * 2025-10-11 15:21:49 -05:00
b5bbb6fd8e 299 current 2025-10-11 14:41:20 25.05.20251006.20c4598 6.12.50 * 2025-10-11 15:07:17 -05:00
6819b00e6b 298 current 2025-10-11 14:26:58 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:41:22 -05:00
1911315178 298 current 2025-10-11 14:26:58 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:36:37 -05:00
79b903403b 298 current 2025-10-11 14:26:58 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:33:49 -05:00
634b09fc42 298 current 2025-10-11 14:26:58 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:31:03 -05:00
01fe78bffe 298 current 2025-10-11 14:26:58 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:30:28 -05:00
790e358869 297 current 2025-10-11 13:48:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:27:01 -05:00
895b5d1add 297 current 2025-10-11 13:48:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:25:45 -05:00
de6b452d78 297 current 2025-10-11 13:48:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:23:01 -05:00
09603e8e30 297 current 2025-10-11 13:48:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 14:20:33 -05:00
eec5b89396 296 current 2025-10-11 13:35:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:48:39 -05:00
4ba44f7248 296 current 2025-10-11 13:35:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:45:50 -05:00
c749475fa9 296 current 2025-10-11 13:35:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:43:17 -05:00
6347aeab13 296 current 2025-10-11 13:35:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:41:27 -05:00
f9f598827a 295 current 2025-10-11 13:20:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:35:42 -05:00
0335d89b2f 295 current 2025-10-11 13:20:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:33:54 -05:00
b69c92e6db 295 current 2025-10-11 13:20:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:33:06 -05:00
0077c9028a 295 current 2025-10-11 13:20:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:32:29 -05:00
c0e581ff08 295 current 2025-10-11 13:20:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:27:48 -05:00
5ecb7775ae 295 current 2025-10-11 13:20:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:27:04 -05:00
3d7cad4fea 295 current 2025-10-11 13:20:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:25:06 -05:00
952b0cc69a 294 current 2025-10-11 12:58:57 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:20:30 -05:00
2f86551967 294 current 2025-10-11 12:58:57 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:18:56 -05:00
43e489ff52 294 current 2025-10-11 12:58:57 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:01:06 -05:00
3470cb1bbc 293 current 2025-10-11 12:20:27 25.05.20251006.20c4598 6.12.50 * 2025-10-11 13:00:29 -05:00
d46d270ad0 292 current 2025-10-11 12:17:54 25.05.20251006.20c4598 6.12.50 * 2025-10-11 12:20:29 -05:00
7205a6b00e 291 current 2025-10-11 12:01:16 25.05.20251006.20c4598 6.12.50 * 2025-10-11 12:17:56 -05:00
d49ed2acc3 291 current 2025-10-11 12:01:16 25.05.20251006.20c4598 6.12.50 * 2025-10-11 12:16:04 -05:00
89c1be5186 290 current 2025-10-11 11:39:41 25.05.20251006.20c4598 6.12.50 * 2025-10-11 12:01:18 -05:00
7d02cf9b19 290 current 2025-10-11 11:39:41 25.05.20251006.20c4598 6.12.50 * 2025-10-11 12:00:03 -05:00
d7aabfaa4b 290 current 2025-10-11 11:39:41 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:53:51 -05:00
2eafe082ba 290 current 2025-10-11 11:39:41 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:52:48 -05:00
efda5e5598 290 current 2025-10-11 11:39:41 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:51:18 -05:00
1eb60294cb 290 current 2025-10-11 11:39:41 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:48:30 -05:00
2031aa443f 290 current 2025-10-11 11:39:41 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:47:35 -05:00
7f56e043e7 290 current 2025-10-11 11:39:41 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:43:34 -05:00
0d78ee24a0 289 current 2025-10-11 11:25:44 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:39:44 -05:00
fec6c6c146 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:25:47 -05:00
7bd47ff538 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:24:45 -05:00
0f0f838c1b 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:24:08 -05:00
247ab094d5 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:20:39 -05:00
6508ed6159 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:15:58 -05:00
d924c98656 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:14:03 -05:00
8c33edf4dd 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:11:48 -05:00
d4200497a7 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:11:18 -05:00
d4b38ba1e7 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:10:21 -05:00
fa62f88352 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:05:20 -05:00
c818ac0e34 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 11:00:36 -05:00
a96471232e 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:58:20 -05:00
fe35a1ef86 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:54:55 -05:00
e211775905 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:53:34 -05:00
1055e10921 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:51:05 -05:00
ee7745f83f 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:49:01 -05:00
3e2ada161a 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:48:10 -05:00
51934f6577 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:46:10 -05:00
a27f922c5b 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:45:04 -05:00
7c5d2df922 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:44:26 -05:00
a3b3441b64 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:42:59 -05:00
ea5501723a 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:36:40 -05:00
347b4e9f74 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:36:01 -05:00
fd553ec4ca 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:29:08 -05:00
65af57f6d9 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:28:37 -05:00
53a3bd0261 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:28:01 -05:00
4206dbbb35 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:27:16 -05:00
4f62d2746d 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:26:40 -05:00
6b01510afb 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:25:39 -05:00
3b4d0e3152 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:24:01 -05:00
f51570624b 288 current 2025-10-11 10:03:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:22:54 -05:00
0cb49c0c42 287 current 2025-10-11 09:51:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:03:02 -05:00
f3127697ca 287 current 2025-10-11 09:51:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 10:02:20 -05:00
846d531ad3 287 current 2025-10-11 09:51:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:55:24 -05:00
58007d7743 287 current 2025-10-11 09:51:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:54:14 -05:00
d258d95057 286 current 2025-10-11 09:36:17 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:51:41 -05:00
8d5743c0bc 286 current 2025-10-11 09:36:17 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:49:52 -05:00
f4b71070ce 286 current 2025-10-11 09:36:17 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:48:26 -05:00
badcab048c 286 current 2025-10-11 09:36:17 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:45:38 -05:00
730bf26b93 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:36:19 -05:00
d333b3186b 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:32:15 -05:00
12936f35e2 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:31:40 -05:00
f50139dfca 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:28:20 -05:00
f5625cc963 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:26:10 -05:00
2854340455 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:23:57 -05:00
1533db75f4 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:22:42 -05:00
6fe75b1221 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:21:40 -05:00
50e70d1cd1 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:20:52 -05:00
83e60189b6 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:19:43 -05:00
6a92cae6f7 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:19:16 -05:00
9e30589699 285 current 2025-10-11 08:57:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 09:15:18 -05:00
e6039316db 284 current 2025-10-11 08:13:32 25.05.20251006.20c4598 6.12.50 * 2025-10-11 08:57:32 -05:00
0f5b1d83b5 283 current 2025-10-11 06:19:49 25.05.20251006.20c4598 6.12.50 * 2025-10-11 08:13:35 -05:00
0fb8657c2e 282 current 2025-10-11 06:07:58 25.05.20251006.20c4598 6.12.50 * 2025-10-11 06:19:51 -05:00
59dd4bbe70 281 current 2025-10-11 05:45:24 25.05.20251006.20c4598 6.12.50 * 2025-10-11 06:08:01 -05:00
9e00aeca04 280 current 2025-10-11 05:36:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:45:31 -05:00
0c6c2562f3 280 current 2025-10-11 05:36:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:42:30 -05:00
4bac164d92 280 current 2025-10-11 05:36:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:41:34 -05:00
afccaa5886 280 current 2025-10-11 05:36:52 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:40:29 -05:00
6a60ce6b85 279 current 2025-10-11 05:35:16 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:36:55 -05:00
bf908ac917 278 current 2025-10-11 05:22:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:35:19 -05:00
7ceb225b06 278 current 2025-10-11 05:22:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:30:57 -05:00
6b291ecd40 278 current 2025-10-11 05:22:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:29:41 -05:00
64d7b799be 278 current 2025-10-11 05:22:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:28:00 -05:00
33bfd2ed4f 277 current 2025-10-11 05:18:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:22:10 -05:00
5ad52957fa 276 current 2025-10-11 05:12:51 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:18:02 -05:00
b3aa8fe80a 275 current 2025-10-11 05:11:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:12:54 -05:00
d43f12cdd2 274 current 2025-10-11 05:02:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:11:42 -05:00
ff90df08d0 274 current 2025-10-11 05:02:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:10:43 -05:00
3fd4bb375e 274 current 2025-10-11 05:02:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:09:57 -05:00
a2ebf1dd31 274 current 2025-10-11 05:02:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:08:59 -05:00
1bab984f02 274 current 2025-10-11 05:02:07 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:08:32 -05:00
9fc91817fd 273 current 2025-10-11 04:43:13 25.05.20251006.20c4598 6.12.50 * 2025-10-11 05:02:10 -05:00
4be5721730 272 current 2025-10-11 04:36:05 25.05.20251006.20c4598 6.12.50 * 2025-10-11 04:43:15 -05:00
d45e598a2f 271 current 2025-10-11 04:20:39 25.05.20251006.20c4598 6.12.50 * 2025-10-11 04:36:08 -05:00
b2e4ee7e6b 270 current 2025-10-11 03:40:05 25.05.20251006.20c4598 6.12.50 * 2025-10-11 04:20:42 -05:00
1f2d75d848 270 current 2025-10-11 03:40:05 25.05.20251006.20c4598 6.12.50 * 2025-10-11 04:04:15 -05:00
b51aca18c7 270 current 2025-10-11 03:40:05 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:40:50 -05:00
d7e1708f65 269 current 2025-10-11 03:39:33 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:40:08 -05:00
a04fa13800 268 current 2025-10-11 03:24:47 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:39:36 -05:00
48c6d04db3 268 current 2025-10-11 03:24:47 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:25:27 -05:00
ff4f6904fd 267 current 2025-10-11 03:22:34 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:24:55 -05:00
d377cda9a9 267 current 2025-10-11 03:22:34 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:23:06 -05:00
88bdb0b48c 266 current 2025-10-11 03:12:18 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:22:46 -05:00
e9b193afc2 266 current 2025-10-11 03:12:18 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:16:37 -05:00
463250c092 265 current 2025-10-11 03:09:55 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:12:24 -05:00
0485e78610 264 current 2025-10-11 03:06:37 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:10:02 -05:00
ce6847fd36 263 current 2025-10-11 02:55:17 25.05.20251006.20c4598 6.12.50 * 2025-10-11 03:06:43 -05:00
502e53377f 262 current 2025-10-11 02:49:09 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:55:24 -05:00
f54922caf7 262 current 2025-10-11 02:49:09 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:50:10 -05:00
fc6b0e9390 261 current 2025-10-11 02:26:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:49:16 -05:00
dc4948063e 261 current 2025-10-11 02:26:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:40:43 -05:00
4abe7423c8 261 current 2025-10-11 02:26:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:39:30 -05:00
1d7ac94c5d 261 current 2025-10-11 02:26:00 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:39:09 -05:00
7d5c027da6 260 current 2025-10-11 02:24:48 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:26:07 -05:00
180d78430b 259 current 2025-10-11 02:18:02 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:24:55 -05:00
26eac1e2a7 259 current 2025-10-11 02:18:02 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:19:17 -05:00
793ffda17a 258 current 2025-10-11 01:50:08 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:18:05 -05:00
3e37b91846 258 current 2025-10-11 01:50:08 25.05.20251006.20c4598 6.12.50 * 2025-10-11 02:12:52 -05:00
5258bd62d8 257 current 2025-10-11 01:15:03 25.05.20251006.20c4598 6.12.50 * 2025-10-11 01:50:30 -05:00
39e44c0ade 257 current 2025-10-11 01:15:03 25.05.20251006.20c4598 6.12.50 * 2025-10-11 01:48:51 -05:00
cc673dde8e 257 current 2025-10-11 01:15:03 25.05.20251006.20c4598 6.12.50 * 2025-10-11 01:41:47 -05:00
e3c9bd23ee 257 current 2025-10-11 01:15:03 25.05.20251006.20c4598 6.12.50 * 2025-10-11 01:40:17 -05:00
2fccc66805 257 current 2025-10-11 01:15:03 25.05.20251006.20c4598 6.12.50 * 2025-10-11 01:39:34 -05:00
b78ba63ab5 256 current 2025-10-11 00:38:56 25.05.20251006.20c4598 6.12.50 * 2025-10-11 01:15:07 -05:00
d6260546ca 255 current 2025-10-11 00:13:49 25.05.20251006.20c4598 6.12.50 * 2025-10-11 00:38:58 -05:00
477d0bea34 255 current 2025-10-11 00:13:49 25.05.20251006.20c4598 6.12.50 * 2025-10-11 00:37:49 -05:00
aed29a27de 255 current 2025-10-11 00:13:49 25.05.20251006.20c4598 6.12.50 * 2025-10-11 00:33:02 -05:00
d0c59fa764 255 current 2025-10-11 00:13:49 25.05.20251006.20c4598 6.12.50 * 2025-10-11 00:20:09 -05:00
42f5eb9c1a 254 current 2025-10-10 23:53:30 25.05.20251006.20c4598 6.12.50 * 2025-10-11 00:13:51 -05:00
b677b2f547 253 current 2025-10-10 23:51:29 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:53:34 -05:00
0632c3735e 252 current 2025-10-10 23:46:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:51:33 -05:00
6b919051d9 252 current 2025-10-10 23:46:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:49:44 -05:00
b6a56848b0 251 current 2025-10-10 23:44:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:46:55 -05:00
848a8ec406 251 current 2025-10-10 23:44:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:46:01 -05:00
00992dd0a2 250 current 2025-10-10 23:43:41 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:44:55 -05:00
a4b0c2b91c 249 current 2025-10-10 23:12:14 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:43:44 -05:00
7eda531e01 249 current 2025-10-10 23:12:14 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:42:39 -05:00
a8fecf2c26 249 current 2025-10-10 23:12:14 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:41:04 -05:00
f2f1b9cba5 249 current 2025-10-10 23:12:14 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:37:32 -05:00
b5fc9b38e4 249 current 2025-10-10 23:12:14 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:36:22 -05:00
4332cbf69b 249 current 2025-10-10 23:12:14 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:24:00 -05:00
4bc74cf035 249 current 2025-10-10 23:12:14 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:14:49 -05:00
622974ad88 248 current 2025-10-10 23:08:55 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:12:17 -05:00
fa229e997d 248 current 2025-10-10 23:08:55 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:09:27 -05:00
0e4786a464 247 current 2025-10-10 23:01:56 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:08:58 -05:00
83612a7f87 247 current 2025-10-10 23:01:56 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:08:05 -05:00
4cf4edff26 247 current 2025-10-10 23:01:56 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:05:09 -05:00
9a589ab24a 246 current 2025-10-10 22:49:32 25.05.20251006.20c4598 6.12.50 * 2025-10-10 23:02:00 -05:00
53bf7fd64e 246 current 2025-10-10 22:49:32 25.05.20251006.20c4598 6.12.50 * 2025-10-10 22:55:53 -05:00
d61beb3f7b 245 current 2025-10-10 22:45:03 25.05.20251006.20c4598 6.12.50 * 2025-10-10 22:49:34 -05:00
09991aa67d 244 current 2025-10-10 22:38:41 25.05.20251006.20c4598 6.12.50 * 2025-10-10 22:45:06 -05:00
a8f2cd7331 243 current 2025-10-10 22:37:51 25.05.20251006.20c4598 6.12.50 * 2025-10-10 22:38:44 -05:00
b9a8012a48 242 current 2025-10-10 22:36:02 25.05.20251006.20c4598 6.12.50 * 2025-10-10 22:37:53 -05:00
bc76eb71c3 241 current 2025-10-10 22:34:34 25.05.20251006.20c4598 6.12.50 * 2025-10-10 22:36:04 -05:00
7ff5c40f32 240 current 2025-10-10 21:55:37 25.05.20251006.20c4598 6.12.50 * 2025-10-10 22:34:48 -05:00
fd5ef2c7e0 240 current 2025-10-10 21:55:37 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:57:42 -05:00
fe54d9896b 239 current 2025-10-10 21:53:16 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:55:39 -05:00
4f4341165e 238 current 2025-10-10 21:51:26 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:53:21 -05:00
a59b331bbe 237 current 2025-10-10 21:49:29 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:51:31 -05:00
699c0d1f29 236 current 2025-10-10 21:46:09 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:49:34 -05:00
6b70ab5f69 235 current 2025-10-10 21:42:12 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:46:14 -05:00
15bf851f33 234 current 2025-10-10 21:36:10 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:42:18 -05:00
6cf3e58600 234 current 2025-10-10 21:36:10 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:38:27 -05:00
e564e632b3 233 current 2025-10-10 21:35:34 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:36:12 -05:00
fec251a4c3 232 current 2025-10-10 21:34:31 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:35:43 -05:00
aa29d58e9d 231 current 2025-10-10 21:32:35 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:34:33 -05:00
e8fb6f383f 230 current 2025-10-10 21:30:12 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:32:37 -05:00
3064a404e0 229 current 2025-10-10 21:25:49 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:30:15 -05:00
65a8654165 228 current 2025-10-10 21:22:38 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:25:51 -05:00
1876238748 227 current 2025-10-10 21:18:19 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:22:41 -05:00
13cfe73b65 226 current 2025-10-10 21:05:33 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:18:21 -05:00
56d7504a79 225 current 2025-10-10 21:01:34 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:05:35 -05:00
23170eb4fc 224 current 2025-10-10 20:58:53 25.05.20251006.20c4598 6.12.50 * 2025-10-10 21:01:37 -05:00
7eb729d29a 223 current 2025-10-10 20:52:33 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:58:55 -05:00
015045c56f 223 current 2025-10-10 20:52:33 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:53:11 -05:00
fa1d1310c9 222 current 2025-10-10 20:51:09 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:52:40 -05:00
0d9679ae0a 221 current 2025-10-10 20:48:25 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:51:14 -05:00
11b7545928 220 current 2025-10-10 20:46:18 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:48:28 -05:00
afbef1bf7d 219 current 2025-10-10 20:44:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:46:20 -05:00
0fe813201a 218 current 2025-10-10 20:40:59 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:44:08 -05:00
0bcf16b127 217 current 2025-10-10 20:18:09 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:41:01 -05:00
3a7f4de155 216 current 2025-10-10 04:43:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:18:11 -05:00
10f2b436f0 216 current 2025-10-10 04:43:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:11:16 -05:00
4bc8f56956 216 current 2025-10-10 04:43:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:10:21 -05:00
08a3d16a83 216 current 2025-10-10 04:43:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:08:42 -05:00
a8dddf8cbb 216 current 2025-10-10 04:43:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:08:13 -05:00
16d62f5ed2 216 current 2025-10-10 04:43:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:06:54 -05:00
f754badc78 216 current 2025-10-10 04:43:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 20:05:43 -05:00
ac642a20b1 216 current 2025-10-10 04:43:06 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:59:12 -05:00
f9ed9ab55f 215 current 2025-10-10 04:30:17 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:43:08 -05:00
9fb05656cc 214 current 2025-10-10 04:13:05 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:30:20 -05:00
910b2125ae 214 current 2025-10-10 04:13:05 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:29:35 -05:00
743858c6d1 214 current 2025-10-10 04:13:05 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:21:23 -05:00
f9764fb3a6 213 current 2025-10-10 04:10:50 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:13:07 -05:00
73d57f7441 213 current 2025-10-10 04:10:50 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:11:25 -05:00
f28c9ea93d 212 current 2025-10-10 03:46:48 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:10:56 -05:00
85e6635bb7 212 current 2025-10-10 03:46:48 25.05.20251006.20c4598 6.12.50 * 2025-10-10 04:00:23 -05:00
8ce6cf9f89 212 current 2025-10-10 03:46:48 25.05.20251006.20c4598 6.12.50 * 2025-10-10 03:47:38 -05:00
208a21efd5 211 current 2025-10-10 03:14:57 25.05.20251006.20c4598 6.12.50 * 2025-10-10 03:46:50 -05:00
d0065f8053 210 current 2025-10-10 02:55:45 25.05.20251006.20c4598 6.12.50 * 2025-10-10 03:15:01 -05:00
877e70cd48 210 current 2025-10-10 02:55:45 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:56:37 -05:00
576c83eabd 209 current 2025-10-10 02:45:03 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:55:47 -05:00
2df106c25f 209 current 2025-10-10 02:45:03 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:48:44 -05:00
52d12ceb26 208 current 2025-10-10 02:29:51 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:45:06 -05:00
c080e647cc 207 current 2025-10-10 02:23:15 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:29:54 -05:00
4ddb17b6d3 206 current 2025-10-10 02:17:13 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:23:17 -05:00
96e173ee29 205 current 2025-10-10 02:16:29 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:17:15 -05:00
13fb00dd10 204 current 2025-10-10 00:57:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:16:32 -05:00
d607de1418 204 current 2025-10-10 00:57:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:14:50 -05:00
8181a339ae 204 current 2025-10-10 00:57:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:11:11 -05:00
adc334eab5 204 current 2025-10-10 00:57:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:08:55 -05:00
9f03fa499d 204 current 2025-10-10 00:57:52 25.05.20251006.20c4598 6.12.50 * 2025-10-10 02:07:12 -05:00
dd896748ab fucking minecraft 😭 2025-10-10 02:06:54 -05:00
1e8039d1c1 203 current 2025-10-10 00:56:13 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:57:54 -05:00
5183e20efc 202 current 2025-10-10 00:53:49 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:56:15 -05:00
7093c119cb 201 current 2025-10-10 00:48:28 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:53:51 -05:00
af4f75b21b 201 current 2025-10-10 00:48:28 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:52:00 -05:00
6095e030ed 200 current 2025-10-10 00:25:07 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:48:30 -05:00
2a75a2ad38 200 current 2025-10-10 00:25:07 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:29:51 -05:00
e38d40ac75 200 current 2025-10-10 00:25:07 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:29:02 -05:00
91828c067d 199 current 2025-10-10 00:21:25 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:25:09 -05:00
33a934662f 198 current 2025-10-09 23:52:36 25.05.20251006.20c4598 6.12.50 * 2025-10-10 00:21:27 -05:00
023d5b655a 197 current 2025-10-09 23:49:39 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:52:38 -05:00
84a4e3bed0 197 current 2025-10-09 23:49:39 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:50:07 -05:00
2304b157a4 196 current 2025-10-09 23:45:38 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:49:42 -05:00
1155ad26a4 196 current 2025-10-09 23:45:38 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:46:55 -05:00
ad35c325b0 195 current 2025-10-09 23:30:33 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:45:41 -05:00
05c5d89d2f 195 current 2025-10-09 23:30:33 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:31:08 -05:00
4406adfb60 194 current 2025-10-09 23:29:38 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:30:41 -05:00
d09f66d0b6 193 current 2025-10-09 23:00:13 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:29:48 -05:00
de682fa7f1 193 current 2025-10-09 23:00:13 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:23:22 -05:00
16a8405b43 192 current 2025-10-09 22:47:26 25.05.20251006.20c4598 6.12.50 * 2025-10-09 23:00:16 -05:00
0d134cfdbf 191 current 2025-10-09 22:11:00 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:47:29 -05:00
fb8c17fc6d 191 current 2025-10-09 22:11:00 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:45:13 -05:00
c5858ecfe3 191 current 2025-10-09 22:11:00 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:42:08 -05:00
0adff079c0 191 current 2025-10-09 22:11:00 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:38:56 -05:00
69a1eede6b 191 current 2025-10-09 22:11:00 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:32:26 -05:00
6d3b619eb6 190 current 2025-10-09 22:00:15 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:11:02 -05:00
434f8c20a8 190 current 2025-10-09 22:00:15 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:05:20 -05:00
b7e5687f62 190 current 2025-10-09 22:00:15 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:03:20 -05:00
77f90324b5 190 current 2025-10-09 22:00:15 25.05.20251006.20c4598 6.12.50 * 2025-10-09 22:01:31 -05:00
779c87510a adding uptime-kuma 2025-10-09 21:59:49 -05:00
b75a1c6d32 189 current 2025-10-09 21:50:35 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:59:29 -05:00
e394f284d6 188 current 2025-10-09 21:49:39 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:50:41 -05:00
5c01f6a490 187 current 2025-10-09 21:44:05 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:49:42 -05:00
b8fd18d881 187 current 2025-10-09 21:44:05 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:44:37 -05:00
653da27815 186 current 2025-10-09 21:26:53 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:44:07 -05:00
394d399d8b 186 current 2025-10-09 21:26:53 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:27:15 -05:00
ddb638436a 185 current 2025-10-09 21:25:33 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:26:56 -05:00
ceffcfde58 185 current 2025-10-09 21:25:33 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:25:57 -05:00
413057f9ed 184 current 2025-10-09 21:19:25 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:25:37 -05:00
e77bb9ae08 184 current 2025-10-09 21:19:25 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:24:35 -05:00
442af621f9 184 current 2025-10-09 21:19:25 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:23:17 -05:00
96da0a67c5 183 current 2025-10-09 20:51:03 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:19:28 -05:00
5421f468e9 183 current 2025-10-09 20:51:03 25.05.20251006.20c4598 6.12.50 * 2025-10-09 21:17:56 -05:00
be5286810f 182 current 2025-10-09 20:41:39 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:51:06 -05:00
8adc8308dc 182 current 2025-10-09 20:41:39 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:50:25 -05:00
2fc255549b 182 current 2025-10-09 20:41:39 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:49:58 -05:00
03c60c8a96 182 current 2025-10-09 20:41:39 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:48:57 -05:00
8e4db00903 182 current 2025-10-09 20:41:39 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:47:36 -05:00
5b1dd5e6ae 181 current 2025-10-09 20:18:51 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:41:41 -05:00
96340dffb6 181 current 2025-10-09 20:18:51 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:38:26 -05:00
673da9fdf9 180 current 2025-10-09 20:07:23 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:18:54 -05:00
1a63b6b497 180 current 2025-10-09 20:07:23 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:17:25 -05:00
7522fc1802 179 current 2025-10-09 19:52:17 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:07:25 -05:00
6537cf5426 179 current 2025-10-09 19:52:17 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:06:42 -05:00
a827a87597 179 current 2025-10-09 19:52:17 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:06:04 -05:00
bdbdfa7df4 179 current 2025-10-09 19:52:17 25.05.20251006.20c4598 6.12.50 * 2025-10-09 20:03:33 -05:00
e6afad411c 179 current 2025-10-09 19:52:17 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:52:46 -05:00
ea0e162a93 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:52:20 -05:00
6c230bdbd3 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:49:25 -05:00
b63ce5b4fb 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:48:39 -05:00
1676374c61 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:48:02 -05:00
4d7e37f700 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:46:56 -05:00
19424d0f28 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:46:10 -05:00
477c7c9767 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:45:18 -05:00
8b787309fe 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:44:05 -05:00
ac4f2dad23 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:41:02 -05:00
923d05073c 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:39:29 -05:00
93efb4074b 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:37:30 -05:00
6b2ab6bf20 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:35:37 -05:00
07e2a3c562 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:34:45 -05:00
9fb0d1a972 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:33:26 -05:00
3d092dd529 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:32:43 -05:00
12f3e3767a 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:31:27 -05:00
21e77f36b2 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:30:29 -05:00
0791c92e04 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:29:59 -05:00
7393c5047c 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:18:19 -05:00
228918dd93 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:16:43 -05:00
4725d90910 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 * 2025-10-09 19:14:35 -05:00
6fe95330e7 adding home stack 2025-10-09 19:12:58 -05:00
b8de16f444 removing backup 2025-10-09 18:20:42 -05:00
2771 changed files with 12161 additions and 2709 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@
.keyring/
.nixos-switch-log
users/blake/dotfiles/zsh/zplug
users/blake/dots/zsh/zplug
users/blake/dotfiles/zsh/.zsh_history
users/blake/dotfiles/zsh/.zcompdump

View File

@@ -1,203 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# --- SUDO CHECK ---
if [ "$EUID" -ne 0 ]; then
echo "This script requires root privileges. Re-running with sudo..."
exec sudo "$0" "$@"
fi
# --- HANDLE OPTIONS ---
BORG_PASSPHRASE=""
SHOW_FOLDERS_ONLY=false
SHOW_FILES=false # Default to showing files and directories
while getopts "k:fp" opt; do
case "$opt" in
k)
BORG_PASSPHRASE=$(<"$OPTARG")
if [ -z "$BORG_PASSPHRASE" ]; then
echo "Error: The key file is empty."
exit 1
fi
echo "Using passphrase from key file: $OPTARG"
;;
f)
SHOW_FOLDERS_ONLY=true
echo "Only directories will be shown in fzf by default."
SHOW_FILES=false
;;
p)
SHOW_FILES=true
echo "Both files and directories will be shown in fzf."
;;
*)
echo "Usage: $0 [-k passphrase_file] [-f] [-p] <repo>"
exit 1
;;
esac
done
shift $((OPTIND - 1))
# --- FALLBACK TO /run/secrets/borg_passwd IF NO KEY FILE ---
if [ -z "$BORG_PASSPHRASE" ]; then
if [ $# -eq 0 ]; then
BORG_PASSPHRASE=$(<"/run/secrets/borg_passwd")
echo "Using passphrase from /run/secrets/borg_passwd"
else
# Prompt user for passphrase if neither -k nor /run/secrets/borg_passwd is available
read -s -p "Enter Borg repository passphrase: " BORG_PASSPHRASE
echo
fi
fi
export BORG_PASSPHRASE
# --- DEFAULT REPO ---
REPO="${1:-/holocron/backups}"
# --- CHECK REQUIRED COMMANDS ---
for cmd in borg fzf find tree cp mkdir; do
command -v "$cmd" >/dev/null || { echo "Error: '$cmd' is required but not installed."; exit 1; }
done
# --- LIST ARCHIVES (sorted, newest last) ---
mapfile -t archives < <(borg list --format="{archive}{NL}" "$REPO" | sort -r)
if [ ${#archives[@]} -eq 0 ]; then
echo "No archives found in $REPO"
exit 1
fi
# --- FZF ARCHIVE SELECT ---
selected=$(printf '%s\n' "${archives[@]}" | fzf --prompt="Select archive: " --height=40% --border)
if [ -z "$selected" ]; then
echo "No archive selected."
exit 1
fi
echo "Selected archive: $selected"
# --- GENERATE A UNIQUE, SHORTER MOUNT POINT ---
MOUNT_POINT="/tmp/$(uuidgen | sha256sum | head -c 2)-restore-${selected}"
mkdir -p "$MOUNT_POINT"
# --- MOUNT ARCHIVE ---
echo "Mounting '$selected' to $MOUNT_POINT..."
borg mount "$REPO::$selected" "$MOUNT_POINT"
if [ ! -d "$MOUNT_POINT" ]; then
echo "Error: mount failed."
exit 1
fi
# --- LIST FILES AND DIRECTORIES ---
echo "Scanning files and directories..."
if command -v fd >/dev/null 2>&1; then
# List both files and directories with fd
if [ "$SHOW_FILES" = true ]; then
files=$(fd . "$MOUNT_POINT" | sort) # Show both files and directories
else
files=$(fd --type d . "$MOUNT_POINT" | sort) # Only directories
fi
else
# Fall back to find if fd is not available
if [ "$SHOW_FILES" = true ]; then
files=$(find "$MOUNT_POINT" | sort) # Show both files and directories
else
files=$(find "$MOUNT_POINT" -type d | sort) # Only directories
fi
fi
if [ -z "$files" ]; then
echo "No files or directories found in archive."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 1
fi
# --- FZF FILE/DIRECTORY SELECTION ---
if [ "$SHOW_FILES" = true ]; then
# If showing files and directories, we pass everything to fzf
selected_items=$(printf '%s\n' "$files" | sed "s|$MOUNT_POINT/||" | tac | fzf \
--multi \
--height=50% \
--border \
--prompt="Select files or directories to restore: " \
--preview "tree -C -L 5 $MOUNT_POINT/$(dirname {})" \
--preview-window=right:50% \
--delimiter='/' \
--with-nth=1..)
else
# If only showing directories, pass directories to fzf
selected_items=$(printf '%s\n' "$files" | sed "s|$MOUNT_POINT/||" | tac | fzf \
--multi \
--height=50% \
--border \
--prompt="Select directories to restore: " \
--preview "tree -C -d -L 3 $MOUNT_POINT/$(dirname {})" \
--preview-window=right:50% \
--delimiter='/' \
--with-nth=1..)
fi
if [ -z "$selected_items" ]; then
echo "No items selected. Exiting."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 0
fi
# --- SUMMARY OF SELECTED ITEMS ---
echo "Selected items:"
for item in $selected_items; do
echo " $item"
done
# --- OPTIONS MENU (concise) ---
# Default to option 1 if no input is given
echo "Select restore destination: 1) Restore to ./${selected}_restore 2) Restore to original dirs 3) Quit"
read -p "Enter your choice (1/2/3) [default: 1]: " choice
# Default to option 1 if user presses Enter without providing input
choice="${choice:-1}"
# --- SET RESTORE DESTINATION BASED ON USER CHOICE ---
case "$choice" in
1)
DEST="./${selected}_restore"
;;
2)
DEST="$MOUNT_POINT"
;;
3)
echo "Quitting. No items restored."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 0
;;
*)
echo "Invalid choice. Exiting."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 1
;;
esac
mkdir -p "$DEST"
# --- RESTORE SELECTED ITEMS (FILES OR DIRECTORIES) ---
echo "Restoring selected items..."
while IFS= read -r item; do
dest_path="$DEST/$item"
mkdir -p "$(dirname "$dest_path")"
if [ -d "$MOUNT_POINT/$item" ]; then
cp -r "$MOUNT_POINT/$item" "$dest_path"
else
cp -a "$MOUNT_POINT/$item" "$dest_path"
fi
echo "Restored: $item"
done <<< "$selected_items"
# --- CLEANUP ---
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
echo "Restore complete."

View File

@@ -1,173 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# --- SUDO CHECK ---
if [ "$EUID" -ne 0 ]; then
echo "This script requires root privileges. Re-running with sudo..."
exec sudo "$0" "$@"
fi
# --- HANDLE -k OPTION FOR KEY FILE ---
BORG_PASSPHRASE=""
while getopts "k:" opt; do
case "$opt" in
k)
BORG_PASSPHRASE=$(<"$OPTARG")
if [ -z "$BORG_PASSPHRASE" ]; then
echo "Error: The key file is empty."
exit 1
fi
echo "Using passphrase from key file: $OPTARG"
;;
*)
echo "Usage: $0 [-k passphrase_file] <repo>"
exit 1
;;
esac
done
shift $((OPTIND - 1))
# --- FALLBACK TO /run/secrets/borg_passwd IF NO KEY FILE ---
if [ -z "$BORG_PASSPHRASE" ]; then
if [ -f "/run/secrets/borg_passwd" ]; then
BORG_PASSPHRASE=$(<"/run/secrets/borg_passwd")
echo "Using passphrase from /run/secrets/borg_passwd"
else
# Prompt user for passphrase if neither -k nor /run/secrets/borg_passwd is available
read -s -p "Enter Borg repository passphrase: " BORG_PASSPHRASE
echo
fi
fi
export BORG_PASSPHRASE
# --- DEFAULT REPO ---
REPO="${1:-/holocron/backups}"
# --- CHECK REQUIRED COMMANDS ---
for cmd in borg fzf find tree cp mkdir; do
command -v "$cmd" >/dev/null || { echo "Error: '$cmd' is required but not installed."; exit 1; }
done
# --- LIST ARCHIVES (sorted, newest last) ---
mapfile -t archives < <(borg list --format="{archive}{NL}" "$REPO" | sort)
if [ ${#archives[@]} -eq 0 ]; then
echo "No archives found in $REPO"
exit 1
fi
# --- FZF ARCHIVE SELECT ---
selected=$(printf '%s\n' "${archives[@]}" | fzf --prompt="Select archive: " --height=40% --border --reverse)
if [ -z "$selected" ]; then
echo "No archive selected."
exit 1
fi
echo "Selected archive: $selected"
# --- GENERATE A UNIQUE, SHORTER MOUNT POINT ---
MOUNT_POINT="/tmp/borg-mount-${selected}-$(uuidgen | sha256sum | head -c 6)"
mkdir -p "$MOUNT_POINT"
# --- MOUNT ARCHIVE ---
echo "Mounting '$selected' to $MOUNT_POINT..."
borg mount "$REPO::$selected" "$MOUNT_POINT"
if [ ! -d "$MOUNT_POINT" ]; then
echo "Error: mount failed."
exit 1
fi
# --- LIST FILES AND DIRECTORIES ---
echo "Scanning files and directories..."
if command -v fd >/dev/null 2>&1; then
# List files and directories using fd (can handle both files and dirs)
files=$(fd --type f --type d . "$MOUNT_POINT" | sort)
else
# Fall back to find if fd is not available
files=$(find "$MOUNT_POINT" -type f -o -type d | sort)
fi
if [ -z "$files" ]; then
echo "No files or directories found in archive."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 1
fi
# --- HIERARCHICAL FZF FILE/DIRECTORY SELECTION (REVERSED) ---
# We reverse the order of files to display the latest (newest) files/folders at the top.
selected_files=$(printf '%s\n' "$files" | sed "s|$MOUNT_POINT/||" | tac | fzf \
--multi \
--height=50% \
--border \
--prompt="Select files or directories to restore: " \
--preview "tree -C -L 5 $MOUNT_POINT/$(dirname {})" \
--preview-window=right:50% \
--delimiter='/' \
--with-nth=1..)
if [ -z "$selected_files" ]; then
echo "No files or directories selected. Exiting."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 0
fi
# --- SUMMARY OF SELECTED FILES/DIRECTORIES ---
echo "Selected files and directories:"
for file in $selected_files; do
echo " $file"
done
# --- OPTIONS MENU (concise) ---
# Default to option 1 if no input is given
echo "Select restore destination: 1) Restore to ./${selected}_restore 2) Restore to original dirs 3) Quit"
read -p "Enter your choice (1/2/3) [default: 1]: " choice
# Default to option 1 if user presses Enter without providing input
choice="${choice:-1}"
# --- SET RESTORE DESTINATION BASED ON USER CHOICE ---
case "$choice" in
1)
DEST="./${selected}_restore"
;;
2)
DEST="$MOUNT_POINT"
;;
3)
echo "Quitting. No files restored."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 0
;;
*)
echo "Invalid choice. Exiting."
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
exit 1
;;
esac
mkdir -p "$DEST"
# --- RESTORE FILES AND DIRECTORIES ---
echo "Restoring selected files and directories..."
while IFS= read -r file; do
# Path is already stripped of /tmp, so no need for further modification
dest_path="$DEST/$file"
mkdir -p "$(dirname "$dest_path")"
# If it's a directory, we use cp -r to ensure the directory structure is restored
if [ -d "$MOUNT_POINT/$file" ]; then
cp -r "$MOUNT_POINT/$file" "$dest_path"
else
cp -a "$MOUNT_POINT/$file" "$dest_path"
fi
echo "Restored: $file"
done <<< "$selected_files"
# --- CLEANUP ---
borg umount "$MOUNT_POINT"
rm -rf "$MOUNT_POINT"
echo "Restore complete."

View File

@@ -1,64 +0,0 @@
#!/usr/bin/env bash
# borg-browser.sh — fzf-based Borg archive browser with passphrase prompt
[ "$EUID" -ne 0 ] && { echo "Please run as root."; exec sudo "$0" "$@"; }
REPO="/holocron/backups"
# Prompt once for Borg passphrase
read -rs -p "Borg passphrase: " BORG_PASSPHRASE
echo
export BORG_PASSPHRASE
# Pick an archive
ARCHIVE=$(borg list --short "$REPO" | fzf --prompt="Select archive: ") || {
unset BORG_PASSPHRASE
exit
}
[ -z "$ARCHIVE" ] && { unset BORG_PASSPHRASE; exit; }
# Function to browse directories hierarchically
browse_borg_dir() {
local prefix="$1"
while true; do
# Get immediate children of the current path
ITEMS=$(borg list --format='{path}{NL}' "$REPO::$ARCHIVE" \
| awk -v p="$prefix" -F/ '
BEGIN{n=split(p,a,"/")}
index($0,p)==1 && NF>n {
if (NF==n+1) print $NF;
else print $(n+1)"/";
}' \
| sort -u)
[ -z "$ITEMS" ] && { echo "No items found in $prefix"; return; }
SELECTION=$(echo -e "../\n$ITEMS" | fzf --prompt="${prefix:-/}> ")
case "$SELECTION" in
"../")
prefix="${prefix%/*}"
prefix="${prefix%/}"
;;
"")
return
;;
*/)
prefix="${prefix:+$prefix/}${SELECTION%/}"
;;
*)
local fullpath="${prefix:+$prefix/}$SELECTION"
echo "Selected file: $fullpath"
read -rp "Extract it here? [y/N]: " yn
if [[ $yn =~ ^[Yy]$ ]]; then
borg extract "$REPO::$ARCHIVE" "$fullpath"
fi
return
;;
esac
done
}
browse_borg_dir ""
unset BORG_PASSPHRASE

View File

@@ -17,6 +17,10 @@ TARGET=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
-m|--media)
OWNER=":media"
shift
;;
-o|--owner)
OWNER="$2"
shift 2

46
bin/rebuild Executable file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
set -euo pipefail
#echo "searching generations"
# your hostname (flake target)
hostname="$(hostname)"
#old_gen=$(nixos-rebuild list-generations | grep current | awk '{print $1}')
#gen=$((old_gen + 1))
#echo "gen $old_gen --> gen $gen"
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
nix_dir="$HOME/.nix"
logfile="$nix_dir/.nixos-switch-log"
pushd "$nix_dir" >/dev/null
# function to get current nixos generation
#get_current_generation() {
# nixos-rebuild list-generations
#}
echo "diffs:"
git diff
echo ""
echo "files:"
git status --short
read -rp "commit message: " commit_msg
echo "rebuilding nixos with flake.nix..."
#if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then
#if ! nh os switch 2>&1 | tee "$logfile"; then
if ! sudo nixos-rebuild switch --flake .#"$hostname" 2>&1 | tee "$logfile"; then
echo "rebuild failed; exited with no commit"
exit 1
fi
#if sed -n '3p' flake.nix | grep -q '^# generation:'; then
# # replace the comment on line 3
# sed -i "3s|^# generation:.*|# generation: $gen, timestamp: $timestamp|" flake.nix
#else
# # insert comment on line 3
# sed -i "3i# generation: $gen, timestamp: $timestamp" flake.nix
#fi
echo "committing..."
git add $nix_dir
git commit -m "$commit_msg"
echo "flake rebuild and commit fin"

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
pushd ~/.nix
# nvim flake.nix
# alejandra . &>/dev/null
# git diff -U0 *.nix
# add generation comment to flake.nix
gen=$(nixos-rebuild list-generations | grep current)
if sed -n '3p' flake.nix | grep -q '^# generation:'; then
# replace the comment on line 3
sed -i "3s/^# generation:.*/# generation: $gen/" flake.nix
else
# insert comment on line 3
sed -i "3i# generation: $gen" flake.nix
fi
git diff -U0 $(find . -name '*.nix')
echo "nixos rebuilding..."
#sudo nixos-rebuild switch --flake ~/.nix#snowbelle &>.nixos-switch-log || (
# cat .nixos-switch-log | grep --color error && false)
sudo nixos-rebuild switch --flake ~/.nix#snowbelle 2>&1 | tee .nixos-switch-log | grep --color=always -E "error|$" && true
git commit -am "$gen"
popd

1420
flake.lock generated

File diff suppressed because it is too large Load Diff

150
flake.nix
View File

@@ -1,52 +1,134 @@
# flake for blakes nixos config
# define new devices in outputs
# generation: 178 current 2025-10-09 16:19:44 25.05.20251006.20c4598 6.12.50 *
# generation: 378, timestamp: 2025-10-12 19:57:35
{
description = "blakes nix config";
inputs = {
nixpkgs.url = "nixpkgs/nixos-25.05";
nixpkgs.url = "nixpkgs/nixos-25.11";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
nix-darwin = {
url = "github:nix-darwin/nix-darwin/master";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
home-manager = {
url = "github:nix-community/home-manager/release-25.05";
url = "github:nix-community/home-manager/release-25.11";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager-unstable = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
nix-homebrew.url = "github:zhaofengli/nix-homebrew";
nix-flatpak.url = "github:gmodena/nix-flatpak/?ref=latest";
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
disko = {
url = "github:nix-community/disko/latest";
inputs.nixpkgs.follows = "nixpkgs";
};
lanzaboote = {
url = "github:nix-community/lanzaboote/v0.4.3";
inputs.nixpkgs.follows = "nixpkgs";
};
watershot = {
url = "github:Kirottu/watershot";
inputs.nixpkgs.follows = "nixpkgs";
};
vpn-confinement = {
url = "github:Maroka-chan/VPN-Confinement";
};
};
outputs = { self, nixpkgs, nixpkgs-unstable, ... }@inputs:
let
systems = {
x86_64 = "x86_64-linux";
arm64 = "aarch64-linux";
darwin = "aarch64-darwin";
};
stable_pkgs = builtins.mapAttrs (k: v: import nixpkgs { system = v; }) systems;
unstable_pkgs = builtins.mapAttrs (k: v: import nixpkgs-unstable { system = v; }) systems;
in
{
nixosConfigurations = {
snowbelle = nixpkgs.lib.nixosSystem {
system = systems.x86_64;
specialArgs = { inherit inputs stable_pkgs unstable_pkgs; };
modules = [
./hosts/snowbelle/configuration.nix
inputs.home-manager.nixosModules.default
inputs.vpn-confinement.nixosModules.default
];
};
vaniville = nixpkgs.lib.nixosSystem {
system = systems.x86_64;
specialArgs = { inherit inputs stable_pkgs unstable_pkgs; };
modules = [
./hosts/vaniville/configuration.nix
inputs.home-manager.nixosModules.default
];
};
};
nvf = {
url = "github:notashelf/nvf/v0.8";
inputs.nixpkgs.follows = "nixpkgs";
};
autoaspm = {
url = "git+https://git.notthebe.ee/notthebee/AutoASPM.git";
inputs.nixpkgs.follows = "nixpkgs";
};
stylix = {
url = "github:nix-community/stylix";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
copyparty.url = "github:9001/copyparty";
slippi = {
url = "github:lytedev/slippi-nix";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
};
outputs = {
self,
nixpkgs,
nixpkgs-unstable,
nix-darwin,
nix-homebrew,
...
} @ inputs: let
systems = {
x86_64 = "x86_64-linux";
arm64 = "aarch64-linux";
darwin = "aarch64-darwin";
};
stable_pkgs = builtins.mapAttrs (k: v: import nixpkgs {system = v;}) systems;
unstable_pkgs = builtins.mapAttrs (k: v: import nixpkgs-unstable {system = v;}) systems;
in {
nixosConfigurations = {
snowbelle = nixpkgs.lib.nixosSystem {
system = systems.x86_64;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
./hosts/nixos/snowbelle/configuration.nix
inputs.home-manager.nixosModules.default
];
};
yveltal = nixpkgs-unstable.lib.nixosSystem {
system = systems.x86_64;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
./hosts/nixos/yveltal/configuration.nix
./hosts/nixos/yveltal/disko.nix
inputs.home-manager-unstable.nixosModules.default
inputs.disko.nixosModules.disko
];
};
mew = nixpkgs-unstable.lib.nixosSystem {
system = systems.x86_64;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
./hosts/nixos/mew/configuration.nix
./hosts/nixos/mew/disko.nix
inputs.home-manager-unstable.nixosModules.default
inputs.disko.nixosModules.disko
];
};
vaniville = nixpkgs.lib.nixosSystem {
system = systems.x86_64;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
modules = [
./hosts/nixos/vaniville/configuration.nix
inputs.home-manager.nixosModules.default
];
};
};
darwinConfigurations = {
CEN-IT-07 = nix-darwin.lib.darwinSystem {
system = systems.darwin;
specialArgs = {inherit inputs stable_pkgs unstable_pkgs nix-homebrew;};
modules = [
#./hosts/darwin/cen-it-07/configuration.nix
inputs.home-manager.darwinModules.default
nix-homebrew.darwinModules.nix-homebrew
{
nix-homebrew = {
enable = true; # install homebrew
enableRosetta = true; # install homebrew for rosetta as well
autoMigrate = true;
user = "bhelderman"; # user owning homebrew prefix
};
}
];
};
};
};
}

40
hosts/darwin/default.nix Normal file
View File

@@ -0,0 +1,40 @@
{
pkgs,
config,
lib,
inputs,
...
}: {
imports = [
];
# base system package install list
environment.systemPackages = with pkgs; [
wget
curl
rsync
git
age
fzf
neofetch
usbutils
pciutils
python3
vim
lf
btop
powertop
];
# set timezone
time.timeZone = "America/Chicago";
# allow proprietary packages
nixpkgs.config.allowUnfree = true;
# enable flakes
nix.settings.experimental-features = ["nix-command" "flakes"];
users.defaultUserShell = pkgs.zsh;
}

120
hosts/nixos/default.nix Normal file
View File

@@ -0,0 +1,120 @@
{
pkgs,
config,
lib,
inputs,
...
}: {
imports = [
inputs.autoaspm.nixosModules.default
];
# set timezone
time.timeZone = "America/Chicago";
nix = {
# garbage collect & remove builds older then 14 days
gc = {
automatic = true;
dates = "daily";
options = "--delete-older-than 14d";
persistent = true;
};
# optimise nix store, dedupe and such
optimise = {
automatic = true;
dates = [ "daily" ];
};
# the goats
settings = {
substituters = [
"https://cache.nixos.org"
];
trusted-public-keys = [
];
experimental-features = lib.mkDefault [
"nix-command"
"flakes"
];
};
};
# allow proprietary packages
nixpkgs = {
config = {
allowUnfree = true;
allowUnfreePredicate = _: true;
};
};
# power management
services.autoaspm.enable = true;
powerManagement.powertop.enable = true;
# things are better this way
users.defaultUserShell = pkgs.zsh;
# base system package install list
environment.systemPackages = with pkgs; [
wget
curl
dig
nmap
rsync
iperf3
jq
git
age
vim
ncdu
btop
powertop
iotop
cifs-utils
usbutils
pciutils
lm_sensors
];
# nice to have passwordless sudo
security.sudo = {
extraRules = [
{
users = ["blake"];
commands = [
{
command = "/run/current-system/sw/bin/nixos-rebuild";
options = ["NOPASSWD"];
}
{
command = "/run/current-system/sw/bin/systemctl";
options = ["NOPASSWD"];
}
{
command = "/run/current-system/sw/bin/journalctl";
options = ["NOPASSWD"];
}
{
command = "/run/current-system/sw/bin/tailscale";
options = ["NOPASSWD"];
}
{
command = "/etc/profiles/per-user/blake/bin/nom";
options = ["NOPASSWD"];
}
{
command = "/etc/profiles/per-user/blake/bin/nom-build";
options = ["NOPASSWD"];
}
{
command = "/etc/profiles/per-user/blake/bin/nom-shell";
options = ["NOPASSWD"];
}
];
}
];
extraConfig = ''
Defaults insults
'';
};
}

View File

@@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = ""; # disk id here
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
#keyFile = "/tmp/secret.key";
};
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}

View File

@@ -0,0 +1,113 @@
{
pkgs,
config,
lib,
modulesPath,
inputs,
stable_pkgs,
unstable_pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
(modulesPath + "/installer/scan/not-detected.nix")
#./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/desktop
../../../modules/system
];
# home grown nixos modules
system = {
secure_boot.enable = false;
cifs_mounts.enable = true;
udiskie.enable = true;
ssh.enable = true;
sops.enable = true;
japanese.enable = true;
yubikey.enable = true;
yubikey.lock_on_remove = false;
tailscale.enable = true;
syncthing.enable = true;
flatpak.enable = true;
graphics = {
enable = true;
vendor = "amd";
};
};
desktop = {
pipewire.enable = true;
hypr.enable = true;
greetd.enable = true;
};
gaming = {
steam.enable = true;
lutris.enable = true;
proton_ge.enable = true;
gamemode.enable = true;
mangohud.enable = true;
};
# import home grown host specific home-manager modules
home-manager.users.blake.imports = [
../../../users/blake/hosts/yveltal.nix
];
# fix power buttons
# move this to a laptops file at some point
services.logind.settings.Login = {
HandlePowerKey = "suspend-then-hibernate";
HandleLidSwitch = "suspend-then-hibernate";
};
# sets the delay before hibernation for ^
systemd.sleep.extraConfig = ''
HibernateDelaySec=1800
'';
# boot (systemd is growing on me)
boot = {
kernelModules = [ "kvm-amd" ];
extraModulePackages = [];
loader = {
systemd-boot.enable = true; # systemd your pretty cool ya know
efi.canTouchEfiVariables = true;
};
initrd = {
systemd.enable = true; # better logging
availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod" "ahci"];
kernelModules = [];
};
};
# setup hostname and networking stack
networking = {
hostName = "mew"; # hostname
useDHCP = lib.mkDefault true;
interfaces = {
wlp7s0.useDHCP = lib.mkDefault true;
};
firewall = {
enable = true;
allowedTCPPorts = [22];
allowedUDPPorts = [51820]; # wireguard
};
networkmanager = {
enable = true; # the goat
dns = "systemd-resolved"; # the backup dancer!
};
};
services.resolved = {
enable = true;
fallbackDns = ["1.1.1.1" "9.9.9.9"];
dnsovertls = "opportunistic";
};
hardware.bluetooth.enable = true;
system.stateVersion = "25.05"; # stays here : )
# hardware shit
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

70
hosts/nixos/mew/disko.nix Normal file
View File

@@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/nvme-MTFDHBA512TDV-1AZ1AABHA_UJUND0170FW7O0"; # disk id here
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
#keyFile = "/tmp/secret.key";
};
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}

View File

@@ -1,4 +1,4 @@
{ config, lib, stable_pkgs, unstable_pkgs, ... }:
{ config, lib, inputs, stable_pkgs, unstable_pkgs, ... }:
let
pkgs = stable_pkgs.x86_64;
@@ -8,50 +8,66 @@ in
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
../../users/users.nix
../../modules/system/default.nix
../../modules/homelab/default.nix
../../nixos
../../../users/blake
../../../modules/system
../../../modules/holocron
../../../modules/homelab
../../../modules/gameservers/minecraft_recpro
../../../modules/gameservers/minecraft_modded
];
modules = {
system = {
ssh.enable = true;
backups.enable = true;
backups.repo = "/holocron/backups";
sops.enable = true;
docker.enable = true;
syncthing.enable = true;
tailscale.enable = true;
vpns.enable = false;
vpns.wg_mex = false;
vpn-confinement.enable = false;
nvidia.enable = true;
};
homelab = {
home-manager.users.blake.imports = [
../../../users/blake/hosts/snowbelle.nix
];
system = {
ssh.enable = true;
sops.enable = true;
podman.enable = true;
yubikey.enable = true;
graphics = {
enable = true;
zfs.enable = true;
smb.enable = true;
nfs.enable = true;
nginx-proxy.enable = true;
};
services = {
jellyfin.enable = true;
vaultwarden.enable = true;
gitea.enable = true;
qbittorrent.enable = true;
immich.enable = true;
prowlarr.enable = true;
flaresolverr.enable = true;
bazarr.enable = true;
radarr.enable = true;
sonarr.enable = true;
vendor = "nvidia";
};
};
# configure users & groups
users = {
blake.enable = true; # main user, home manager
defaultUserShell = pkgs.zsh; # the goat
holocron = {
syncthing.enable = true;
copyparty.enable = false;
ensure_perms.enable = false;
zfs.enable = true;
smb.enable = true;
nfs.enable = true;
};
homelab = {
enable = true;
tailscale.enable = true;
dnsmasq.enable = true;
backups.enable = true;
motd.enable = true;
postfix.enable = true;
gitea.enable = true;
glance.enable = true;
immich.enable = true;
hass.enable = true;
jellyfin.enable = true;
audiobookshelf.enable = true;
yacreader.enable = true;
qbittorrent.enable = true;
sonarr.enable = true;
radarr.enable = true;
bazarr.enable = true;
prowlarr.enable = true;
flaresolverr.enable = true;
zigbee2mqtt.enable = true;
mosquitto.enable = true;
caddy.enable = true;
uptime-kuma.enable = true;
vaultwarden.enable = true;
};
gameservers = {
minecraft_recpro.enable = true;
minecraft_modded.enable = true;
};
# boot (systemd is going on me)
@@ -87,45 +103,10 @@ in
};
# set timezone
time.timeZone = "America/Chicago";
# define shell
programs.zsh.enable = true;
# package install list
environment.systemPackages = with pkgs; [
git
age
rsync
wget
curl
fzf
fd
tree
vim
lf
tmux
btop
neofetch
usbutils
inetutils
iptables
];
hardware.bluetooth.enable = true;
# allow proprietary packages
nixpkgs.config.allowUnfree = true;
# ld fix
programs.nix-ld.enable = true;
programs.nix-ld.libraries = with pkgs; [
# Add any missing dynamic libraries for unpackaged
# programs here, NOT in environment.systemPackages
];
# enable flakes
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Open ports in the firewall.
networking.firewall.allowedTCPPorts = [
@@ -157,6 +138,7 @@ in
7704 # srv - hass
7705 # srv - zigbee2mqtt
7901 # srv - uptime kuma
7902 # srv - copyparty
25777 # srv - minecraft
25565 # ^ ^ ^
25566 # | | |
@@ -167,7 +149,7 @@ in
# Or disable the firewall altogether.
networking.firewall.enable = true;
system.stateVersion = "25.05"; # Did you read the comment?
system.stateVersion = "25.05"; # stays here : )
}

View File

@@ -8,25 +8,16 @@ in
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
../../users/blake/blake.nix
../../modules/system/system.nix
../../users/users.nix
../../modules/system
];
modules = {
system = {
ssh.enable = true;
docker.enable = true;
syncthing.enable = false;
tailscale.enable = true;
nvidia.enable = false;
};
homelab = {
docker.ddns.enable = true;
};
};
# enable user
users.blake.enable = true;
# use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
@@ -64,7 +55,7 @@ in
# Open ports in the firewall.
networking.firewall.enable = true;
networking.firewall.extraCommands = ''
HOMELAB_IP="10.10.0.30" # destination address
HOMELAB_IP="10.10.0.10" # destination address
PUBLIC_IF="eth0" # vps public interface
TAILSCALE_IF="tailscale0" # tailscale interface

View File

@@ -0,0 +1,112 @@
{
pkgs,
config,
lib,
modulesPath,
inputs,
stable_pkgs,
unstable_pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
(modulesPath + "/installer/scan/not-detected.nix")
#./hardware-configuration.nix
../../nixos
../../../users/blake
../../../modules/desktop
../../../modules/system
];
# home grown nixos modules
system = {
secure_boot.enable = true;
cifs_mounts.enable = true;
udiskie.enable = true;
ssh.enable = true;
sops.enable = true;
yubikey.enable = true;
yubikey.lock_on_remove = true;
tailscale.enable = true;
syncthing.enable = true;
flatpak.enable = true;
graphics = {
enable = true;
vendor = "intel";
};
};
desktop = {
pipewire.enable = true;
hypr.enable = true;
greetd.enable = true;
};
gaming = {
steam.enable = true;
lutris.enable = true;
proton_ge.enable = true;
gamemode.enable = true;
mangohud.enable = true;
};
# import home grown host specific home-manager modules
home-manager.users.blake.imports = [
../../../users/blake/hosts/yveltal.nix
];
# fix power buttons
# move this to a laptops file at some point
services.logind.settings.Login = {
HandlePowerKey = "suspend-then-hibernate";
HandleLidSwitch = "suspend-then-hibernate";
};
# sets the delay before hibernation for ^
systemd.sleep.extraConfig = ''
HibernateDelaySec=1800
'';
# boot (systemd is growing on me)
boot = {
kernelModules = ["kvm-intel"];
extraModulePackages = [];
loader = {
systemd-boot.enable = true; # systemd your pretty cool ya know
efi.canTouchEfiVariables = true;
};
initrd = {
systemd.enable = true; # better logging
availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod"];
kernelModules = [];
};
};
# setup hostname and networking stack
networking = {
hostName = "yveltal"; # hostname
useDHCP = lib.mkDefault true;
interfaces = {
wlp0s20f3.useDHCP = lib.mkDefault true;
};
firewall = {
enable = true;
allowedTCPPorts = [22];
allowedUDPPorts = [51820]; # wireguard
};
networkmanager = {
enable = true; # the goat
dns = "systemd-resolved"; # the backup dancer!
};
};
services.resolved = {
enable = true;
fallbackDns = ["1.1.1.1" "9.9.9.9"];
dnsovertls = "opportunistic";
};
hardware.bluetooth.enable = true;
system.stateVersion = "25.05"; # stays here : )
# hardware shit
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/disk/by-id/nvme-PC_SN530_NVMe_WDC_512GB_210513807733"; # disk id here
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "crypted";
# disable settings.keyFile if you want to use interactive password entry
#passwordFile = "/tmp/secret.key"; # Interactive
settings = {
allowDiscards = true;
#keyFile = "/tmp/secret.key";
};
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"@root" = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@home" = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
"@swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "32G";
};
};
};
};
};
};
};
};
};
};
}

View File

@@ -0,0 +1,13 @@
{
pkgs,
config,
lib,
...
}: {
imports = [
./pipewire
./hypr
./greetd
./gaming
];
}

View File

@@ -0,0 +1,16 @@
{
pkgs,
config,
inputs,
lib,
...
}: {
imports = [
inputs.slippi.nixosModules.default # gcc drivers
./steam
./lutris
./proton_ge
./gamemode
./mangohud
];
}

View File

@@ -0,0 +1,20 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.gamemode;
in {
options.gaming.gamemode = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
# enable gamemode for game optimizations
# requires setting launch option `gamemoderun %command%`
programs.gamemode.enable = true;
};
}

View File

@@ -0,0 +1,19 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.lutris;
in {
options.gaming.lutris = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
lutris
wine
];
};
}

View File

@@ -0,0 +1,20 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.mangohud;
in {
options.gaming.mangohud = {
enable = lib.mkEnableOption "enable lutris";
};
config = lib.mkIf cfg.enable {
# preformance overlay
# requires setting launch option `mangohud %command%`
environment.systemPackages = with pkgs; [
mangohud
];
};
}

View File

@@ -0,0 +1,24 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.proton_ge;
in {
options.gaming.proton_ge = {
enable = lib.mkEnableOption "enable proton ge";
};
# this is an imperitive install after rebuild run `protonup`
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
protonup-ng
];
# tells `protonup` what path to use
environment.sessionVariables = {
STEAM_EXTRA_COMPACT_TOOLS_PATHS = "/home/blake/.steam/root/compatibilitytools.d";
};
};
}

View File

@@ -0,0 +1,22 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.gaming.steam;
in {
options.gaming.steam = {
enable = lib.mkEnableOption "enable steam";
};
config = lib.mkIf cfg.enable {
programs.steam = {
enable = true;
gamescopeSession.enable = true; # requires setting launch option `gamescope <options> -- %command%`
remotePlay.openFirewall = true; # open ports for remote play
#dedicatedServer.openFirewall = true; # open ports for source dedicated server
protontricks.enable = true;
};
};
}

View File

@@ -0,0 +1,34 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.desktop.greetd;
in {
options.desktop.greetd = {
enable = lib.mkEnableOption "enable greetd with tuigreet";
};
config = lib.mkIf cfg.enable {
services.greetd = {
enable = true;
# tuigreet command to run
settings = {
default_session = {
user = "greeter";
command = "${pkgs.tuigreet}/bin/tuigreet -c Hyprland -t --greeting \"howdy o/\" --user-menu --remember --remember-user-session --power-shutdown \"systemctl poweroff\" --power-reboot \"systemctl reboot\"";
};
};
};
# allow yubikey signin with u2f
security.pam.services.greetd.u2fAuth = true;
# ensure the user exists
users.users.greeter = {
isSystemUser = true;
description = "user for greetd";
};
};
}

View File

@@ -0,0 +1,22 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.desktop.hypr;
in {
options.desktop.hypr = {
enable = lib.mkEnableOption "enable hypr on nixos side";
};
config = lib.mkIf cfg.enable {
# enable hyprland
programs.hyprland.enable = true;
# give hyprlock perms to unlock
security.pam.services.hyprlock = {
enable = true;
};
};
}

View File

@@ -0,0 +1,136 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.desktop.pipewire;
in {
options.desktop.pipewire = {
enable = lib.mkEnableOption "enable pipewire for sound!";
};
config = lib.mkIf cfg.enable {
security.rtkit.enable = true;
environment.systemPackages = with pkgs; [
qpwgraph # patching software
pavucontrol # volume mixer
pulsemixer
];
services.pipewire = {
enable = true;
alsa = {
enable = true;
support32Bit = true;
};
pulse.enable = true;
jack.enable = true;
wireplumber = {
enable = true;
extraConfig = {
"90-yveltal-renames" = {
"monitor.alsa.rules" = [
# audio sinks
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink";
}
];
actions = {
"update-props" = {
"node.description" = "Speakers / 3.5mm";
"node.nick" = "Speakers / 3.5mm";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI1__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 1";
"node.nick" = "HDMI / DP 1";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI2__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 2";
"node.nick" = "HDMI / DP 2";
};
};
}
{
matches = [
{
"node.name" = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI3__sink";
}
];
actions = {
"update-props" = {
"node.description" = "HDMI / DP 3";
"node.nick" = "HDMI / DP 3";
};
};
}
# audio sources
{
matches = [
{
"node.name" = "alsa_input.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Headset__source";
}
];
actions = {
"update-props" = {
"node.description" = "3.5mm Mic";
"node.nick" = "3.5mm Mic";
};
};
}
{
matches = [
{
"node.name" = "alsa_input.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Mic1__source";
}
];
actions = {
"update-props" = {
"node.description" = "Laptop Mic";
"node.nick" = "Laptop Mic";
};
};
}
# audio controllers
{
matches = [
{
"device.name" = "alsa_card.pci-0000_00_1f.3-platform-skl_hda_dsp_generic";
}
];
actions = {
"update-props" = {
"node.description" = "Laptop Controller";
"node.nick" = "Laptop Controller";
};
};
}
];
};
};
};
};
};
}

View File

@@ -0,0 +1,156 @@
{
pkgs,
config,
lib,
...
}: let
service = "minecraft_modded";
cfg = config.gameservers.${service};
sec = config.sops.secrets;
servers = {
cobblemon = {
data_dir = "/var/lib/gameservers/minecraft_modded/cobblemon";
start_file = "start.sh";
};
};
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "enables ${service}";
url = lib.mkOption {
type = lib.types.str;
default = "mc.recoil.pro";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = 25565;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = false;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "velocity";
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/gameservers/minecraft/modded";
description = "path to take hourly backups to with borg!";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} user
users.users.minecraft = lib.mkDefault {
description = "minecraft server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
shell = pkgs.bash;
group = "minecraft";
extraGroups = [];
};
systemd.tmpfiles.rules =
lib.attrsets.mapAttrsToList (
name: cfg: "d ${cfg.data_dir} 0770 minecraft minecraft -"
)
servers;
# Create a systemd service per server running in tmux
systemd.services =
lib.attrsets.mapAttrs (name: srv: {
description = "minecraft_recpro: ${name}";
after = ["network.target"];
wants = ["network.target"];
serviceConfig = {
User = "minecraft";
Group = "minecraft";
WorkingDirectory = srv.data_dir;
UMask = "0007";
ExecStart = "${pkgs.openjdk21}/bin/java -Xms4G -Xmx12G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true @libraries/net/neoforged/neoforge/21.1.211/unix_args.txt";
#ExecStart = "${srv.data_dir}/${srv.start_file}";
Restart = "on-failure";
KillMode = "process";
};
wantedBy = ["multi-user.target"];
})
servers;
environment.systemPackages = with pkgs; [openjdk21 mcrcon];
# services.mysql = {
# enable = true;
# package = pkgs.mariadb;
# ensureDatabases = ["minecraft_recpro_db"];
# ensureUsers = [
# {
# name = "minecraft";
# ensurePermissions = {"minecraft_recpro_db.*" = "ALL PRIVILEGES";};
# }
# ];
# initialScript = pkgs.writeText "minecraft_recpro-init.sql" ''
# CREATE USER IF NOT EXISTS 'minecraft_recpro'@'localhost' IDENTIFIED BY 'IKNOWTHISISBADIJUSTNEEDTHISTOWORKRNPLS';
# GRANT ALL PRIVILEGES ON minecraft_recpro_db.* TO 'minecraft_recpro'@'localhost';
# FLUSH PRIVILEGES;
# '';
# };
# open firewall
networking.firewall.allowedTCPPorts = [25778];
# sops.secrets = {
# "velocity_forwarding" = {
# owner = "minecraft";
# group = "minecraft";
# path = "/var/lib/gameservers/minecraft_recpro/velocity/forwarding.secret";
# mode = "0400";
# };
# "minecraft_recpro_db_passwd" = {
# owner = "mysql";
# group = "mysql";
# };
# };
# backups minecraft_recpro with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = lib.flatten (
lib.attrValues (
lib.mapAttrs (_: srv:
[srv.data_dir]
++ (
if builtins.hasAttr "db_dump" srv
then [srv.db_dump]
else []
))
servers
)
);
compression = "auto,zstd";
#preHook = "systemctl start mysql-backup.service";
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
};
}

View File

@@ -0,0 +1,170 @@
{
pkgs,
config,
lib,
...
}: let
service = "minecraft_recpro";
cfg = config.gameservers.${service};
sec = config.sops.secrets;
servers = {
velocity = {
data_dir = "/var/lib/gameservers/minecraft_recpro/velocity";
db_dump = "/var/backup/mysql/${service}_db.zst";
ram = "2G";
};
smp = {
data_dir = "/var/lib/gameservers/minecraft_recpro/smp";
ram = "12G";
};
superflat = {
data_dir = "/var/lib/gameservers/minecraft_recpro/superflat";
ram = "4G";
};
bento = {
data_dir = "/var/lib/gameservers/minecraft_recpro/bento";
ram = "2G";
};
};
in {
options.gameservers.${service} = {
enable = lib.mkEnableOption "enables ${service}";
url = lib.mkOption {
type = lib.types.str;
default = "mc.recoil.pro";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/gameservers/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = 25565;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = false;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "velocity";
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/gameservers/minecraft/recpro_stack";
description = "path to take hourly backups to with borg!";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.minecraft = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.minecraft = {
description = "minecraft server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
shell = pkgs.bash;
group = "minecraft";
extraGroups = [];
};
systemd.tmpfiles.rules =
lib.attrsets.mapAttrsToList (
name: cfg: "d ${cfg.data_dir} 0770 minecraft minecraft -"
)
servers;
# Create a systemd service per server running in tmux
systemd.services =
lib.attrsets.mapAttrs (name: srv: {
description = "minecraft_recpro: ${name}";
after = ["network.target"];
wants = ["network.target"];
serviceConfig = {
User = "minecraft";
Group = "minecraft";
WorkingDirectory = srv.data_dir;
UMask = "0007";
ExecStart = "${pkgs.openjdk21}/bin/java -Xmx${srv.ram} -jar server.jar nogui";
Restart = "on-failure";
KillMode = "process";
};
wantedBy = ["multi-user.target"];
})
servers;
environment.systemPackages = with pkgs; [openjdk21 mcrcon];
services.mysql = {
enable = true;
package = pkgs.mariadb;
ensureDatabases = ["minecraft_recpro_db"];
ensureUsers = [
{
name = "minecraft";
ensurePermissions = {"minecraft_recpro_db.*" = "ALL PRIVILEGES";};
}
];
initialScript = pkgs.writeText "minecraft_recpro-init.sql" ''
CREATE USER IF NOT EXISTS 'minecraft_recpro'@'localhost' IDENTIFIED BY 'IKNOWTHISISBADIJUSTNEEDTHISTOWORKRNPLS';
GRANT ALL PRIVILEGES ON minecraft_recpro_db.* TO 'minecraft_recpro'@'localhost';
FLUSH PRIVILEGES;
'';
};
# open firewall
networking.firewall.allowedTCPPorts = [25777 25565 25566 25567];
sops.secrets = {
"velocity_forwarding" = {
owner = "minecraft";
group = "minecraft";
path = "/var/lib/gameservers/minecraft_recpro/velocity/forwarding.secret";
mode = "0400";
};
"minecraft_recpro_db_passwd" = {
owner = "mysql";
group = "mysql";
};
};
# backups minecraft_recpro with borg!
services.borgbackup.jobs.${service} = {
archiveBaseName = service;
repo = cfg.backup_repo;
paths = lib.flatten (
lib.attrValues (
lib.mapAttrs (_: srv:
[srv.data_dir]
++ (
if builtins.hasAttr "db_dump" srv
then [srv.db_dump]
else []
))
servers
)
);
compression = "auto,zstd";
preHook = "systemctl start mysql-backup.service";
startAt = "*-*-* *:00:00";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${config.sops.secrets."borg_passwd".path}";
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
hourly = 24;
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
};
}

View File

@@ -0,0 +1,160 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
service = "copyparty";
cfg = config.holocron.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
imports = [inputs.copyparty.nixosModules.default];
options.holocron.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7902;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
};
config = lib.mkIf cfg.enable {
nixpkgs.overlays = [inputs.copyparty.overlays.default];
# declare ${service} group
users.groups.${service} = {
gid = lib.mkForce cfg.ids;
};
# declare ${service} user
users.users.${service} = {
description = lib.mkForce "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [ "media" "blake" "archives" ];
};
# enable the ${service} service
services.${service} = {
enable = true;
user = service;
group = service;
settings = {
i = "0.0.0.0";
p = [7902];
rproxy = 1;
};
accounts = {
blake = {
passwordFile = sec."copyparty_passwd".path;
};
};
groups = {
media = ["blake"];
};
volumes = {
"/archives" = {
path = "/holocron/archives";
access = {
r = "*";
A = "blake";
};
flags = {
chmod_f = 660;
chmod_d = 770;
#gid = ?;
};
};
"/media" = {
path = "/holocron/media";
access = {
r = "*";
w = "@media";
A = "blake";
};
flags = {
chmod_f = 660;
chmod_d = 770;
gid = "700";
};
};
"/users/blake" = {
path = "/holocron/users/blake";
access = {
A = "blake";
};
flags = {
chmod_f = 660;
chmod_d = 770;
gid = "1000";
};
};
};
};
# open firewall
networking.firewall.allowedTCPPorts = [cfg.port];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["${service}.${homelab.public_domain}"];
extraConfig = ''
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
reverse_proxy 127.0.0.1:${toString cfg.port} {
}
'';
};
# add to glance (local service)
homelab.glance.links.system = [
{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
sops.secrets = {
"${service}_passwd" = {
owner = service;
group = service;
};
};
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir];
};
};
};
}

View File

@@ -0,0 +1,21 @@
{
pkgs,
config,
lib,
inputs,
...
}: {
# services show up in glance in reverse import order lmao
imports = [
./nfs
./smb
./zfs
./syncthing
./copyparty
./perms
];
# define the groups used for backups and archives
users.groups.archives = {gid = 727;};
}

View File

@@ -1,15 +1,18 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}:
# define nfs exports
let
cfg = config.modules.homelab.nfs;
cfg = config.holocron.nfs;
nfs_exports = ''
/holocron/vault *(rw,sync,no_subtree_check,no_root_squash)
/holocron/media *(ro,sync,no_subtree_check)
'';
in
{
options.modules.homelab.nfs = {
#/holocron/users *(rw,sync,no_subtree_check,no_root_squash)
in {
options.holocron.nfs = {
enable = lib.mkEnableOption "enables nfs";
};

View File

@@ -0,0 +1,65 @@
{
config,
pkgs,
lib,
...
}: let
service = "ensure_perms";
cfg = config.holocron.${service};
# define variables for paths
archives_path = "/holocron/archives";
media_path = "/holocron/media";
users_path = "/holocron/users";
in {
options.holocron.ensure_perms = {
enable = lib.mkEnableOption "enables perms ensurence script";
};
config = lib.mkIf cfg.enable {
# service to run periodically to reset the perms on all zpools
# everything works fine without this, just for peace of mind
# and to clean up the ownership from the arr stack in /holocron/media
systemd.services.${service} = {
description = "ensure file permissions for archives, media and user folders";
serviceConfig = {
Type = "oneshot";
ExecStart = pkgs.writeShellScript "ensure_perms" ''
# Fix ownership for archives directory
echo "starting ${archives_path}"
chown -Rc root:archives ${archives_path}
find "${archives_path}" -type d -exec chmod 2770 "$@" {} +
find "${archives_path}" -type f -exec chmod 660 "$@" {} +
# Fix ownership for media directory
echo "starting ${media_path}"
chown -Rc root:media ${media_path}
find "${media_path}" -type d -exec chmod 2770 "$@" {} +
find "${media_path}" -type f -exec chmod 660 "$@" {} +
# Fix user directories
for user_dir in ${users_path}/*; do
if [ -d "$user_dir" ]; then
user=$(basename "$user_dir")
echo "starting $user_dir"
chown -Rc $user:$user $user_dir
find $user_dir -type d -exec chmod 2770 "$@" {} +
find $user_dir -type f -exec chmod 660 "$@" {} +
fi
done
echo "fin"
'';
};
};
systemd.timers.${service} = {
description = "run script to ensure_perms daily";
wantedBy = ["timers.target"];
timerConfig = {
OnCalendar = "03:30";
Persistent = true;
};
};
};
}

View File

@@ -0,0 +1,59 @@
{
pkgs,
config,
lib,
...
}:
# define smb shares
let
cfg = config.holocron.smb;
smb_shares = {
archives = {
path = "/holocron/archives";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0775";
"directory mask" = "0775";
};
timemachine = {
browseable = true;
"path" = "/holocron/archives/timemachine";
#"valid users" = "blake";
"public" = "no";
"writeable" = "yes";
#"force user" = "blake";
"fruit:aapl" = "yes";
"fruit:time machine" = "yes";
"vfs objects" = "catia fruit streams_xattr";
};
users = {
path = "/holocron/users";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0660";
"directory mask" = "0770";
};
media = {
path = "/holocron/media";
browseable = true;
writable = true;
guestOk = false;
"create mask" = "0775";
"directory mask" = "0775";
};
};
in {
options.holocron.smb = {
enable = lib.mkEnableOption "enables smb";
};
config = lib.mkIf cfg.enable {
# enable smb with all shares
services.samba = {
enable = true;
settings = smb_shares;
};
};
}

View File

@@ -0,0 +1,87 @@
{
pkgs,
config,
lib,
...
}: let
service = "syncthing";
cfg = config.holocron.${service};
sec = config.sops.secrets;
url = "syncthing.snowbelle.lan";
homelab = config.homelab;
in {
options.holocron.${service} = {
enable = lib.mkEnableOption "enables syncthing";
};
config = lib.mkIf cfg.enable {
services.syncthing = {
enable = true;
user = "blake";
group = "blake";
dataDir = "/var/lib/syncthing";
guiAddress = "0.0.0.0:2222";
openDefaultPorts = true;
#extraFlags = ["--no-default-folder"];
key = sec."${service}/snowbelle/key".path;
cert = sec."${service}/snowbelle/cert".path;
settings = {
devices = {
"lugia" = {id = "BKKSFPH-YEOVVAB-DTT7KK3-UDKAEJ2-PC6ECG7-Y76ZIVP-JRYMMXS-RTZYVQ3";};
"zygarde" = {id = "UYLTF52-VVKUR7F-JN33HQZ-RFNWGL3-JER52LA-GZD2LPJ-QIFEE7K-MNMZRQ5";};
"yveltal" = {id = "ZVSQ4WJ-7OICYOZ-3ECES4X-KH37IPB-TKHKUJG-BSEGXVM-AHYY5C3-VKG44AX";};
"CEN-IT-07" = {id = "DPYKA4Z-3PX7JB2-FBEOXXX-SC7TLT2-QC5P2IR-SXOPJGX-QO3DMII-5B7UCA4";};
"CEN-IT-00007" = {id = "XBPXGYU-DUJSLDH-6BDNF4D-CO2COC3-N3FM6W5-IHZOJBM-Z2N77RI-IVAV5AH";};
};
folders = {
"holocron" = {
path = "/holocron/users/blake/holocron";
devices = ["lugia" "zygarde" "CEN-IT-07" "CEN-IT-00007" "yveltal"];
id = "5voxg-c3he2";
versioning = {
type = "staggered";
fsPath = "/holocron/users/blake/holocron/.stversions";
params = {
cleanInterval = "3600";
maxAge = "0";
};
};
};
};
options = {
urAccepted = -1;
};
};
};
sops.secrets = {
"${service}/snowbelle/key" = {
owner = "blake";
group = "blake";
};
"${service}/snowbelle/cert" = {
owner = "blake";
group = "blake";
};
};
homelab.backups.baks = {
${service} = { paths = [ config.services.syncthing.dataDir ]; };
};
services.caddy.virtualHosts."${url}" = {
extraConfig = ''
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
reverse_proxy 127.0.0.1:2222
'';
};
# add to glance (local service)
homelab.glance.links.system = [{
title = service;
url = "https://${url}";
error-url = "http://${homelab.host_ip}:2222";
check-url = "http://${homelab.host_ip}:2222";
icon = "di:${service}"; }];
};
}

View File

@@ -0,0 +1,78 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.holocron.zfs;
in {
options.holocron.zfs = {
enable = lib.mkEnableOption "enables zfs";
};
config = lib.mkIf cfg.enable {
# set network host id
networking.hostId = "3e6e7055";
# enable zfs support
boot.kernelModules = ["zfs"];
boot.supportedFilesystems = ["zfs"];
# arc cache size
boot.kernelParams = [ "zfs.zfs_arc_max=12884901888" ];
# pools to import
#boot.zfs.extraPools = [ "holocron" "holocron/archives" "/holocron/media" "/holocron/users" ];
#boot.zfs.extraPools = [ "holocron" ];
# enable smart monitoring
services.smartd = {
enable = true;
autodetect = true;
defaults.monitored = "-a -o on -s (S/../.././05|L/../01/./05)";
notifications.mail = {
enable = true;
sender = "zfs@snowbelle.lan";
};
};
# enable zfs
services.zfs = {
autoScrub.enable = true;
autoScrub.interval = "weekly";
# email notifs
zed = {
enableMail = true;
settings = {
ZED_EMAIL_ADDR = ["root"];
# send notification if scrub succeeds
ZED_NOTIFY_VERBOSE = true;
};
};
};
# install userspace tools for acl's
environment.systemPackages = with pkgs; [smartmontools];
fileSystems."/holocron" = {
device = "holocron";
fsType = "zfs";
options = ["nofail"];
};
fileSystems."/holocron/archives" = {
device = "holocron/archives";
fsType = "zfs";
options = ["nofail"];
};
fileSystems."/holocron/users" = {
device = "holocron/users";
fsType = "zfs";
options = ["nofail"];
};
fileSystems."/holocron/media" = {
device = "holocron/media";
fsType = "zfs";
options = ["nofail"];
};
};
}

View File

@@ -0,0 +1,123 @@
{
pkgs,
config,
lib,
...
}: let
service = "";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = <port>;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {
gid = lib.mkForce cfg.ids;
};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = ["media"];
};
# enable the ${service} service
services.${service} = {
enable = true;
openFirewall = true;
user = service;
group = service;
dataDir = cfg.data_dir;
settings = {
server.port = cfg.port;
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
# User = service;
# Group = service;
};
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["${service}.${homelab.public_domain}"];
extraConfig = ''
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
#---------------------------------------------------------------------------
# # add to glance (public service)
# homelab.glance.links.<category> = [{
# title = service;
# url = "https://${service}.${homelab.public_domain}";
# error-url = "http://${homelab.host_ip}:${toString cfg.port}";
# check-url = "http://${homelab.host_ip}:${toString cfg.port}";
# icon = "di:${service}"; }];
#---------------------------------------------------------------------------
# # add to glance (local service)
# homelab.glance.links.<category> = [{
# title = service;
# url = "https://${cfg.url}";
# error-url = "http://${homelab.host_ip}:${toString cfg.port}";
# check-url = "http://${homelab.host_ip}:${toString cfg.port}";
# icon = "di:${service}"; }];
#---------------------------------------------------------------------------
#
# sops.secrets = {
# "${service}_" = {
# owner = ;
# group = ;
# };
# };
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir];
};
};
};
}

View File

@@ -2,12 +2,12 @@
let
service = "bazarr";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -36,6 +36,10 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
@@ -50,7 +54,7 @@ in
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
group = service;
extraGroups = [ "media" ];
};
@@ -58,8 +62,8 @@ in
services.${service} = {
enable = true;
openFirewall = true;
user = "${service}";
group = "${service}";
user = service;
group = service;
listenPort = cfg.port;
};
@@ -71,17 +75,25 @@ in
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
# add to glance
homelab.glance.links.mediastack = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -2,12 +2,12 @@
let
service = "flaresolverr";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -36,6 +36,10 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
@@ -48,7 +52,7 @@ in
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
group = "${service}";
group = service;
};
# enable the ${service} service
@@ -60,21 +64,19 @@ in
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
User = "${service}";
Group = "${service}";
User = service;
Group = service;
};
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
};
}

View File

@@ -2,12 +2,12 @@
let
service = "prowlarr";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -36,6 +36,10 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
@@ -50,7 +54,7 @@ in
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
group = service;
extraGroups = [ "media" ];
};
@@ -66,24 +70,32 @@ in
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
User = "${service}";
Group = "${service}";
User = service;
Group = service;
};
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
# add to glance
homelab.glance.links.mediastack = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -2,12 +2,12 @@
let
service = "radarr";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -36,9 +36,16 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# required
environment.systemPackages = with pkgs; [ffmpeg_6-headless];
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
@@ -50,7 +57,7 @@ in
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
group = service;
extraGroups = [ "media" ];
};
@@ -58,8 +65,8 @@ in
services.${service} = {
enable = true;
openFirewall = true;
user = "${service}";
group = "${service}";
user = service;
group = service;
dataDir = cfg.data_dir;
settings = {
server.port = cfg.port;
@@ -69,24 +76,32 @@ in
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
# User = "${service}";
# Group = "${service}";
# User = service;
# Group = service;
};
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
# add to glance
homelab.glance.links.mediastack = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -2,12 +2,12 @@
let
service = "sonarr";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -36,10 +36,17 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# required
environment.systemPackages = with pkgs; [ffmpeg_6-headless];
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
@@ -50,7 +57,7 @@ in
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
group = service;
extraGroups = [ "media" ];
};
@@ -58,8 +65,8 @@ in
services.${service} = {
enable = true;
openFirewall = true;
user = "${service}";
group = "${service}";
user = service;
group = service;
dataDir = cfg.data_dir;
settings = {
server.port = cfg.port;
@@ -74,17 +81,26 @@ in
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
# tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
# add to glance
homelab.glance.links.mediastack = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -0,0 +1,105 @@
{ pkgs, config, lib, ... }:
let
service = "audiobookshelf";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in
{
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7101;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "abs.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
# home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [ "media" ];
};
# enable the ${service} service
services.${service} = {
enable = true;
openFirewall = true;
user = service;
group = service;
# dataDir = cfg.data_dir;
host = "0.0.0.0";
port = cfg.port;
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
# User = service;
# Group = service;
};
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "abs.${homelab.public_domain}" ];
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy 127.0.0.1:${toString cfg.port} {
}
'';
};
# add to glance public service
homelab.glance.links.mediastack = [{
title = service;
url = "https://abs.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -0,0 +1,89 @@
{
config,
lib,
pkgs,
...
}:
/*
to restore mysql/marinadb database:
mysql -u root -p -e "DROP DATABASE IF EXISTS <database_name>;" # delete old db if still lingering
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS <database_name>;" # create empty db w/ correct name
zstd -dc <path_to_backup> | mysql -u root -p <database_name>
to restore a postgres database:
sudo -u postgres psql -c "DROP DATABASE IF EXISTS <database_name>;" # delete old db if lingering (prolly wont work)
sudo -u postgres psql -c "CREATE DATABASE <database_name>;" # create empty db w/ correct name
zstd -dc <path_to_backup> | sudo -u postgres psql -d immich # restore from the dump
*/
let
cfg = config.homelab.backups;
sec = config.sops.secrets;
in {
options.homelab.backups = {
enable = lib.mkEnableOption "enables borg backups for state files and db backup services";
baks = lib.mkOption {
type = lib.types.attrsOf (lib.types.attrsOf (lib.types.listOf lib.types.path));
default = {};
description = "backup jobs, nested attribute sets should be <bak_name> = paths [<list_of_paths>]";
};
backup_repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/archives/homelab";
description = "path to take daily backups to with borg!";
};
};
config = lib.mkIf cfg.enable {
# backups homelab with borg
services.borgbackup.jobs.homelab = lib.mkIf (cfg.baks != {}) {
archiveBaseName = "homelab";
repo = cfg.backup_repo;
paths = lib.flatten (lib.attrsets.mapAttrsToList (_: arg: arg.paths) cfg.baks);
compression = "auto,zstd";
startAt = "03:30";
group = "archives";
encryption.mode = "repokey-blake2";
encryption.passCommand = "cat ${sec."borg_passwd".path}";
preHook = ''
systemctl start mysql-backup.service
systemctl start $(systemctl list-unit-files 'postgresqlBackup-*.service' --no-legend --no-pager | cut -d' ' -f1)
'';
extraArgs = ["--verbose" "--show-rc" "--umask" "0007"];
extraCreateArgs = ["--list" "--stats" "--filter" "AME"];
prune.keep = {
within = "1d"; # Keep all archives from the last day
daily = 7;
weekly = 12;
monthly = -1; # Keep at least one archive for each month
};
};
# mysql backups currently minecraft_recpro is the only thing using this
services.mysqlBackup = lib.mkIf (config.services.mysql.ensureDatabases != []) {
enable = true;
location = "/var/backup/mysql";
user = "root";
calendar = "daily"; # goes fast, included in back up with server dirs at **:00
compressionAlg = "zstd";
databases = config.services.mysql.ensureDatabases; # set to all databases defined in esure databases
};
# postgresql backups currently immich is the only user
services.postgresqlBackup = lib.mkIf (config.services.postgresql.ensureDatabases != []) {
enable = true;
location = "/var/backup/postgresql";
compression = "zstd"; # optional: "xz", "zstd", "none"
startAt = "daily"; # the dump is included in a backup taken at 4:00
databases = config.services.postgresql.ensureDatabases; # set to all databases defined in esure databases
};
# helpful and for scripts
environment.systemPackages = with pkgs; [borgbackup tree];
sops.secrets = {
"borg_passwd" = {
owner = "root";
group = "root";
};
};
};
}

View File

@@ -0,0 +1,102 @@
{ pkgs, config, lib, ... }:
let
service = "caddy";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in
{
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# enable the ${service} service
services.${service} = {
enable = true;
user = service;
group = service;
dataDir = cfg.data_dir;
email = "me@blakedheld.xyz";
globalConfig = ''
auto_https ignore_loaded_certs
'';
virtualHosts."key.${homelab.public_domain}" = {
extraConfig = ''
root * /var/www/keys
file_server
'';
};
};
# enable acme for auto ssl certs with lets encrypt
security.acme = {
acceptTerms = true;
defaults.email = "me@blakedheld.xyz";
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# open firewall
networking.firewall.allowedTCPPorts = [ 80 443 ];
sops.secrets = {
"ssl_blakedheld_crt" = {
owner = "caddy";
group = "caddy";
path = "/etc/ssl/blakedheld.xyz.crt";
};
"ssl_blakedheld_key" = {
owner = "caddy";
group = "caddy";
path = "/etc/ssl/blakedheld.xyz.key";
};
"klefki_pub.asc" = {
owner = "caddy";
group = "caddy";
path = "/var/www/keys/klefki_pub.asc";
};
};
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -2,10 +2,10 @@
let
cfg = config.modules.homelab;
cfg = config.homelab;
in
{
options.modules.homelab = {
options.homelab = {
enable = lib.mkEnableOption "enable homelab services and configuration";
media_user = lib.mkOption {
default = "media";
@@ -27,13 +27,43 @@ in
type = lib.types.str;
description = "base domain used for reverse proxy";
};
public_domain = lib.mkOption {
default = "blakedheld.xyz";
type = lib.types.str;
description = "base domain used for reverse proxy";
};
host_ip = lib.mkOption {
default = "10.10.0.10";
type = lib.types.str;
description = "base domain used for reverse proxy";
};
};
# the order determines the order in glance :3
imports = [
./services
./shares/nfs.nix
./shares/smb.nix
./shares/zfs.nix
./motd
./dnsmasq
./backups
./glance
./postfix
./caddy
./home/zigbee2mqtt
./vaultwarden
./gitea
./home/homeassistant
./immich
./arr/bazarr
./arr/prowlarr
./arr/radarr
./qbittorrent
./arr/sonarr
./yacreader
./audiobookshelf
./jellyfin
./arr/flaresolverr
./home/mosquitto
./uptime-kuma
./tailscale
];
config = lib.mkIf cfg.enable {
@@ -47,5 +77,6 @@ in
group = cfg.media_group;
};
};
};
}

View File

@@ -0,0 +1,42 @@
{
pkgs,
config,
lib,
...
}: let
service = "dnsmasq";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
port = lib.mkOption {
type = lib.types.int;
default = 53;
description = "set port for ${service} (default: ${toString cfg.port}";
};
};
config = lib.mkIf cfg.enable {
# enable the ${service} service
services.${service} = {
enable = true;
settings = {
listen-address = "10.10.0.10"; # your LAN IP
#interface = "enp89s0";
bind-interfaces = true;
address = "/snowbelle.lan/10.10.0.10";
server = [ # upstream dns
"9.9.9.9"
"1.1.1.1"
];
};
};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
networking.firewall.allowedUDPPorts = [ cfg.port ];
};
}

View File

@@ -1,13 +1,13 @@
{ pkgs, config, lib, ... }:
{ pkgs, nixpkgs-unstable, config, lib, ... }:
let
service = "gitea";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -41,6 +41,10 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
@@ -56,8 +60,12 @@ in
shell = pkgs.bash;
home = cfg.data_dir;
createHome = true;
group = "${service}";
group = service;
extraGroups = [];
# if you wanna attempt system ssh again
#openssh.authorizedKeys.keyFiles = [
# "${cfg.data_dir}/.ssh/authorized_keys"
#];
};
# declare the gitea service
@@ -69,12 +77,26 @@ in
appName = "gitea";
settings = {
server = {
# http config
ROOT_URL = "https://git.blakedheld.xyz";
DOMAIN = "git.blakedheld.xyz";
HTTP_PORT = cfg.port;
# local network config
#LOCAL_ROOT_URL = "https://git.snowbelle.lan";
ALLOW_LOCALNETWORKS = true;
ALLOWED_DOMAINS = "10.10.0.10";
SKIP_TLS_VERIFY = true;
# configure for system ssh (trying to use the systms on nix sucks)
SSH_PORT = cfg.ssh_port;
START_SSH_SERVER = true;
# SSH_PORT = 22;
# START_SSH_SERVER = false;
# SSH_ROOT_PATH = "${cfg.data_dir}/.ssh";
# SSH_CREATE_AUTHORIZED_KEYS_FILE = true;
# actual git config
DEFAULT_BRANCH = "trunk";
ENABLE_PUSH_CREATE_USER = true;
DEFAULT_PUSH_CREATE_PRIVATE = true;
};
};
database = {
@@ -90,32 +112,41 @@ in
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port cfg.ssh_port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."git.${homelab.public_domain}" = {
extraConfig = ''
reverse_proxy localhost:${toString cfg.port} {
}
'';
};
# external reverse proxy entry
services.nginx.virtualHosts."git.blakedheld.xyz" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy localhost:${toString cfg.port} {
}
'';
};
# add to glance
homelab.glance.links.services = [{
title = service;
url = "https://git.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# manage secrets with sops
sops.secrets = {
"${service}_database_password" = {
owner = "${service}";
group = "${service}";
owner = service;
group = service;
};
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -0,0 +1,338 @@
{
pkgs,
config,
lib,
...
}:
/*
this is a wrapper module for glance that allows you to
to pass monitor entries in with nix, all declaratively!
| <8yy> |
V V
# add to glance
homelab.glance.links.mediastack = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
allow-insecure = true; }];
*/
let
service = "glance";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
uptimekuma_url = "localhost:7901";
uptimekuma_page = "glance";
in
{
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7700;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
links = {
services = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
default = [ ];
description = "list of links for ${service}";
};
mediastack = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
default = [ ];
description = "list of links for ${service}";
};
system = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
default = [ ];
description = "list of links for ${service}";
};
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {
gid = lib.mkForce cfg.ids;
};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [ ];
};
services.${service} = {
enable = true;
openFirewall = true;
settings = {
server = {
host = "0.0.0.0";
port = cfg.port;
assets-path = "${cfg.data_dir}/assets";
};
# theme = {custom-css-file = "/assets/user.css";};
auth = {
secret-key = "+mYVAc1uO85hUUz5Ij6Lpelv1RqiLlneYqZD5Jv45buoF2+LZtIt2okRrbFCppiRQbqXkGoRMtSI0bROg4uFUw==";
users = {
blake = {
password-hash = "$2a$10$RwPCkcto35DCp4vNTDpH6.G3TpecPJ/zUL1jI93uzr.lg6v233Sie";
};
};
};
branding = {
logo-url = "/assets/icons/snowbelle.png";
favicon-url = "/assets/icons/favicon.ico";
};
pages = [
{
name = "snowbelle";
hide-desktop-navigation = true;
columns = [
{
size = "small";
widgets = [
{
type = "calendar";
first-day-of-week = "monday";
}
{
type = "server-stats";
servers = [
{
type = "local";
name = "snowbelle";
hide-mountpoints-by-default = true;
mountpoints = {
"/" = {name = "root"; hide = false;};
"/holocron" = {name = "holocron"; hide = false;};
"/holocron/media" = {name = "media"; hide = false;};
"/holocron/vault" = {name = "vault"; hide = false;};
};
}
];
}
{
type = "clock";
hour-format = "24h";
timezones = [
{
timezone = "America/Chicago";
label = "HTX";
}
{
timezone = "America/Denver";
label = "AF";
}
];
}
{
type = "twitch-channels";
channels = [
"SaltSSBM"
"thewaffle77"
"ironmouse"
"linustech"
];
}
];
}
{
size = "full";
widgets = [
{
type = "search";
autofocus = true;
search-engine = "https://duckduckgo.com/?q={QUERY}";
new-tab = true;
bangs = [
{
title = "youtube";
shortcut = "!y";
url = "https://www.youtube.com/results?search_query={QUERY}";
}
{
title = "google";
shortcut = "!g";
url = "https://www.google.com/search?q={QUERY}";
}
{
title = "github";
shortcut = "!gh";
url = "https://github.com/search?q={QUERY}&type=repositories";
}
{
title = "nixos options";
shortcut = "!no";
url = "https://search.nixos.org/options?channel=25.05&query={QUERY}";
}
{
title = "nixos packages";
shortcut = "!np";
url = "https://search.nixos.org/packages?channel=25.05&query={QUERY}";
}
{
title = "home-manager options";
shortcut = "!hm";
url = "https://home-manager-options.extranix.com/?query={QUERY}&release=release-25.05";
}
];
}
{
type = "monitor";
cache = "1m";
title = "services";
sites = cfg.links.services;
}
{
type = "monitor";
cache = "1m";
title = "mediastack";
sites = cfg.links.mediastack;
}
{
type = "monitor";
cache = "1m";
title = "system";
sites = cfg.links.system;
}
{
type = "custom-api";
title = "recpro";
url = "https://api.mcstatus.io/v2/status/java/mc.recoil.pro";
cache = "5s";
template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>";
}
{
type = "custom-api";
title = "cobblemon";
url = "https://api.mcstatus.io/v2/status/java/cobblemon.recoil.pro";
cache = "5s";
template = "<div style=\"display:flex; align-items:center; gap:12px;\">\n <div style=\"width:40px; height:40px; flex-shrink:0; border-radius:4px; display:flex; justify-content:center; align-items:center; overflow:hidden;\">\n {{ if .JSON.Bool \"online\" }}\n <img src=\"{{ .JSON.String \"icon\" | safeURL }}\" width=\"64\" height=\"64\" style=\"object-fit:contain;\">\n {{ else }}\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" style=\"width:32px; height:32px; opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ end }}\n </div>\n\n <div style=\"flex-grow:1; min-width:0;\">\n <a class=\"size-h4 block text-truncate color-highlight\">\n {{ .JSON.String \"host\" }}\n {{ if .JSON.Bool \"online\" }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-positive); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Online\"\n ></span>\n {{ else }}\n <span\n style=\"width: 8px; height: 8px; border-radius: 50%; background-color: var(--color-negative); display: inline-block; vertical-align: middle;\"\n data-popover-type=\"text\"\n data-popover-text=\"Offline\"\n ></span>\n {{ end }}\n </a>\n\n <ul class=\"list-horizontal-text\">\n <li>\n {{ if .JSON.Bool \"online\" }}\n <span>{{ .JSON.String \"version.name_clean\" }}</span>\n {{ else }}\n <span>Offline</span>\n {{ end }}\n </li>\n {{ if .JSON.Bool \"online\" }}\n <li data-popover-type=\"html\">\n <div data-popover-html>\n {{ range .JSON.Array \"players.list\" }}{{ .String \"name_clean\" }}<br>{{ end }}\n </div>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n {{ .JSON.Int \"players.online\" | formatNumber }}/{{ .JSON.Int \"players.max\" | formatNumber }} players\n </p>\n </li>\n {{ else }}\n <li>\n <p style=\"display:inline-flex;align-items:center;\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" class=\"size-6\" style=\"height:1em;vertical-align:middle;margin-right:0.5em;opacity:0.5;\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n 0 players\n </p>\n </li>\n {{ end }}\n </ul>\n </div>\n</div>";
}
];
}
{
size = "small";
widgets = [
{
type = "weather";
location = "Pearland, Texas, United States";
units = "imperial";
hour-format = "24h";
}
{
type = "markets";
markets = [
{
symbol = "SPY";
name = "S&P 500";
}
{
symbol = "XMR-USD";
name = "Monero";
}
{
symbol = "NVDA";
name = "NVIDIA";
}
{
symbol = "AAPL";
name = "Apple";
}
{
symbol = "MSFT";
name = "Microsoft";
}
];
}
{
type = "releases";
cache = "1d";
repositories = [
"glanceapp/glance"
"go-gitea/gitea"
"immich-app/immich"
"syncthing/syncthing"
];
}
];
}
];
}
];
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
User = service;
Group = service;
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
# serverAliases = [ "${homelab.public_domain}" ];
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to backups
homelab.backups.baks = {
${service} = {
paths = [ cfg.data_dir ];
};
};
# add to udr to glance
homelab.glance.links.system = [{
title = "bebe";
url = "https://bebe.lan";
error-url = "https://10.10.0.1";
check-url = "https://10.10.0.1";
icon = "di:unifi";
allow-insecure = true; }];
};
}

View File

@@ -0,0 +1,161 @@
{ pkgs, config, lib, inputs, ... }:
let
nixservice = "home-assistant";
service = "hass";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in
{
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7704;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "podman-hass";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# still suss as fuck bro man fuck
virtualisation.oci-containers.containers = {
hass = {
image = "homeassistant/home-assistant:stable";
autoStart = true;
extraOptions = [
"--pull=newer"
"--network=host"
];
volumes = [
"${cfg.data_dir}:/config"
];
# ports = [
# "0.0.0.0:7704:8123"
# "0.0.0.0:4141:4141"
# ];
environment = {
TZ = homelab.tz;
PUID = toString config.users.users.${service}.uid;
PGID = toString config.users.groups.${service}.gid;
};
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port 8123 ];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "${service}.${homelab.public_domain}" ];
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to glance
homelab.glance.links.services = [{
title = "home assistant";
url = "https://hass.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${nixservice}"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}
# here lies my tough, and I mean fucking tough, swing at
# getting this to work bare metal, ggs ill see you again
# - didnt take long
# --------------------------------------------------------------------------------
# # enable the ${service} service
# services.${nixservice} = {
# enable = true;
# package = inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.home-assistant;
# extraComponents = [
# # required for onboarding
# "analytics"
# "google_translate"
# "met"
# "radio_browser"
# "shopping_list"
# "isal"
# "default_config"
# "mqtt"
# ];
# extraPackages = python3Packages: with python3Packages; [
# psycopg2
# universal-silabs-flasher
# getmac
# zha
# ha-silabs-firmware-client
# paho-mqtt
# aiomqtt
# aiounifi
# ibeacon-ble
# ];
# # imperative config
# config = null;
# lovelaceConfig = null;
# configDir = cfg.data_dir;
# # declartive poggers!
## config = {
## # Includes dependencies for a basic setup
## default_config = {};
## };
# };

View File

@@ -0,0 +1,99 @@
{ pkgs, config, lib, ... }:
let
service = "mosquitto";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in
{
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 1883;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# declare ${service} user
users.users.${service} = {
description = lib.mkForce "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# enable the ${service} service
services.mosquitto.enable = true;
services.mosquitto.listeners = [
{
port = 1883;
address = "0.0.0.0";
users.zigbee = {
acl = [ "readwrite #" ];
hashedPassword = "$7$101$140powz2MtsRawFT$ydndjal9wCAywIWtUEAh/IusdfDFvnHMupTFjdS7Ad/EjsEIbJgHrLY9waCe4Z3142XieuxMrXUDjMTp2qwyiw==";
};
# use with no auth
# settings.allow_anonymous = true;
# acl = [ "pattern readwrite #" ];
# omitPasswordAuth = true;
}
];
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
User = service;
Group = service;
};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
sops.secrets = {
"${service}_hashed_passwd" = {
owner = service;
group = service;
};
};
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -0,0 +1,130 @@
{ pkgs, config, lib, ... }:
let
service = "zigbee2mqtt";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in
{
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7705;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "z2m.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [];
};
# enable the ${service} service
services.${service} = {
enable = true;
dataDir = cfg.data_dir;
settings = {
mqtt = {
base_topic = "zigbee2mqtt";
client_id = "zigbee2mqtt";
server = "mqtt://localhost:1883";
user = "!/run/secrets/mosquitto_passwd.yaml user";
password = "!/run/secrets/mosquitto_passwd.yaml password";
keepalive = 20;
};
serial = {
port = "/dev/serial/by-id/usb-Itead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_V2_4a4e75d63653ef1198d728e0174bec31-if00-port0";
adapter = "ember";
};
advanced = {
channel = 11;
};
frontend = {
enabled = true;
port = cfg.port;
};
homeassistant = {
enabled = true;
};
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
User = service;
Group = service;
};
# # open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "z2m.${homelab.public_domain}" ];
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to glance
homelab.glance.links.services = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
sops.secrets = {
"mosquitto_passwd.yaml" = {
owner = service;
group = service;
};
};
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -0,0 +1,120 @@
{
pkgs,
config,
lib,
inputs,
unstable_pkgs,
...
}: let
service = "immich";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7702;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "photos.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "immich-server";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = ["video" "render" "blake"];
};
# enable the ${service} service
services.${service} = {
enable = true;
#package = inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.immich;
package = unstable_pkgs.x86_64.immich;
openFirewall = true;
user = service;
group = service;
mediaLocation = cfg.data_dir;
host = "0.0.0.0";
port = cfg.port;
settings = null;
#settings.server.externalDomain = "https://photos.blakedheld.xyz";
};
# override umask to make permissions work out
# systemd.services."${toString service}-server".serviceConfig = {
# UMask = lib.mkForce "0007";
# };
# systemd.services."${toString service}-machine-learning".serviceConfig = {
# UMask = lib.mkForce "0007";
# };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = ["photos.${homelab.public_domain}"];
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to glance
homelab.glance.links.services = [
{
title = service;
url = "https://photos.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}";
}
];
# add postgresql database that is automatically created to the backup list
#services.postgresqlBackup.databases = ["immich"]; # set to all databases defined in esure databases
services.postgresql.ensureDatabases = [service]; # set to all databases defined in esure databases
# add to backups
homelab.backups.baks = {
${service} = {paths = [cfg.data_dir "/var/lib/redis-immich" "/var/backup/postgresql/immich.sql.zstd"];};
};
};
}

View File

@@ -2,12 +2,12 @@
let
service = "jellyfin";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -36,6 +36,10 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
@@ -50,7 +54,7 @@ in
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
group = service;
extraGroups = [ "media" "video" "render" ];
};
@@ -58,8 +62,8 @@ in
services.${service} = {
enable = true;
openFirewall = true;
user = "${service}";
group = "${service}";
user = service;
group = service;
dataDir = cfg.data_dir;
};
@@ -71,33 +75,26 @@ in
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
# external reverse proxy entry
services.nginx.virtualHosts."media.blakedheld.xyz" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "media.${homelab.public_domain}" ];
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# sops.secrets = {
# "${service}_" = {
# owner = "${service}";
# group = "${service}";
# };
# };
# add to glance
homelab.glance.links.mediastack = [{
title = service;
url = "https://media.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -0,0 +1,98 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) mkIf mkOption types filterAttrs mapAttrsToList;
cfg = config.homelab.motd;
# collect services to display
motd_list =
mapAttrsToList (_: v: v.motd)
(filterAttrs (_: v: v ? motd && v.motd != null) config.homelab);
in {
options.homelab.motd = {
enable = mkOption {
type = types.bool;
default = true;
description = "enable motd script";
};
};
config = mkIf cfg.enable {
environment.etc."motd".text = ''
#!/usr/bin/env bash
active=$'\033[1;34m'
inactive=$'\033[1;31m'
headings=$'\033[1;35m'
bold=$'\e[1m'
reset=$'\033[0m'
memory=`free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100 / $2 }'`
load1=`cat /proc/loadavg | awk {'print $1'}`
load5=`cat /proc/loadavg | awk {'print $2'}`
load15=`cat /proc/loadavg | awk {'print $3'}`
uptime=`cat /proc/uptime | cut -f1 -d.`
up_days=$((uptime/60/60/24))
up_hours=$((uptime/60/60%24))
up_mins=$((uptime/60%60))
up_secs=$((uptime%60))
nixos_version=$(nixos-version | sed -E 's/^([0-9]{2}\.[0-9]{2}).*\(([^)]+)\)$/\1 (\2)/')
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print 100 - $8 "%"}')
mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
mem_avail=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
mem_used=$((mem_total - mem_avail))
mem_percent=$((100 * mem_used / mem_total))
uptime_fmt=$(uptime -p 2>/dev/null || cat /proc/uptime | awk '{print int($1/3600)"h "int(($1%3600)/60)"m"}')
printf "$bold welcome to $(hostname)!$reset\n"
printf "\n"
printf "$bold * %-20s$reset %s\n" "Release" "$nixos_version"
printf "$bold * %-20s$reset %s\n" "Kernel" "$(uname -rs)"
printf "\n"
printf "$bold * %-20s$reset %s\n" "CPU usage" "$load1, $load5, $load15 (1, 5, 15 min)"
printf "$bold * %-20s$reset %s\n" "Memory" "$memory"
printf "$bold * %-20s$reset %s\n" "System uptime" "$up_days days $up_hours hours $up_mins minutes $up_secs seconds"
echo
# --- services ---
echo -e "''${headings}homelab services:''${reset}"
${lib.concatStringsSep "\n" (map (service: ''
if systemctl list-units --type=service --all | grep -q "${service}"; then
status=$(systemctl is-active ${service} 2>/dev/null)
if [ "$status" = "active" ]; then
printf "%-32s%s\n" " ''${active}[${service}]''${reset}" "running"
else
printf "%-32s%s\n" " ''${active}[${service}]''${reset}" "not running"
fi
else
printf "%-32s%s\n" " ''${active}[${service}]''${reset}" "not found"
fi
'')
motd_list)}
echo
# --- gameservers ---
echo -e "''${headings}gameservers:''${reset}"
for service in velocity smp superflat bento cobblemon; do
status=$(systemctl is-active $service 2>/dev/null)
if [ "$status" = "active" ]; then
printf "%-32s%s\n" " ''${active}[$service]''${reset}" "running"
else
printf "%-32s%s\n" " ''${active}[$service]''${reset}" "not running"
fi
done
echo
'';
environment.etc."motd".mode = "0755";
programs.zsh.interactiveShellInit = ''
/etc/motd
'';
};
}

View File

@@ -0,0 +1,99 @@
{
pkgs,
config,
lib,
...
}: let
service = "postfix";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 587;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
# users.groups.${service} = {
# gid = lib.mkForce cfg.ids;
# };
#
# # declare ${service} user
# users.users.${service} = {
# description = "${service} server user";
# uid = lib.mkForce cfg.ids;
# isSystemUser = true;
# home = cfg.data_dir;
# createHome = true;
# group = service;
# extraGroups = [];
# };
# enable the ${service} service
services.postfix = {
enable = true;
settings.main = {
relayhost = ["smtp.gmail.com:${toString cfg.port}"];
smtp_tls_security_level = "may";
smtp_sasl_auth_enable = "yes";
smtp_sasl_security_options = "noanonymous";
smtp_sasl_password_maps = "texthash:${config.sops.secrets."postfix_passwd".path}";
# optional: Forward mails to root (e.g. from cron jobs, smartd)
# to me privately and to my work email:
virtual_alias_maps = "inline:{ {root=me@blakedheld.xyz, throwedspam@gmail.com} }";
};
};
# override umask to make permissions work out
# systemd.services.${service}.serviceConfig = {
# UMask = lib.mkForce "0007";
# User = service;
# Group = service;
#};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
sops.secrets = {
"${service}_passwd" = {
owner = config.services.postfix.user;
group = config.services.postfix.group;
};
};
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir];
};
};
};
}

View File

@@ -0,0 +1,100 @@
{
pkgs,
config,
lib,
...
}: let
service = "postfix";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 587;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
# users.groups.${service} = {
# gid = lib.mkForce cfg.ids;
# };
#
# # declare ${service} user
# users.users.${service} = {
# description = "${service} server user";
# uid = lib.mkForce cfg.ids;
# isSystemUser = true;
# home = cfg.data_dir;
# createHome = true;
# group = service;
# extraGroups = [];
# };
# enable the ${service} service
services.postfix = {
enable = true;
relayHost = "smtp.mail.me.com";
relayPort = cfg.port;
config = {
smtp_tls_security_level = "may";
smtp_sasl_auth_enable = "yes";
smtp_sasl_security_options = "";
smtp_sasl_password_maps = "texthash:${config.sops.secrets."postfix_passwd".path}";
# optional: Forward mails to root (e.g. from cron jobs, smartd)
# to me privately and to my work email:
virtual_alias_maps = "inline:{ {root=me@blakedheld.xyz} }";
};
};
# override umask to make permissions work out
# systemd.services.${service}.serviceConfig = {
# UMask = lib.mkForce "0007";
# User = service;
# Group = service;
#};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
sops.secrets = {
"${service}_passwd" = {
owner = config.services.postfix.user;
group = config.services.postfix.group;
};
};
# add to backups
homelab.backups.baks = {
${service} = {
paths = [cfg.data_dir];
};
};
};
}

View File

@@ -2,12 +2,12 @@
let
service = "qbittorrent";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -46,12 +46,18 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# ensure media dirs existence
systemd.tmpfiles.rules = [
"d /holocron/media/downloads 2775 qbittorrent media -"
];
# declare ${service} user
users.users.${service} = {
@@ -60,16 +66,15 @@ in
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
extraGroups = [ "media" ];
group = "media";
};
# enable the qbittorrent service
services.${service} = {
enable = true;
openFirewall = true;
user = "${service}";
group = "${service}";
user = service;
group = lib.mkForce "media"; # override for permissions
profileDir = cfg.data_dir;
webuiPort = cfg.port;
# torrentingPort = cfg.torrenting_port;
@@ -109,17 +114,25 @@ in
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls internal
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
# add to glance
homelab.glance.links.mediastack = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -1,111 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.services.gitea;
ids = 2703;
default_port = 3000;
data_dir = "/var/lib/gitea";
in
{
options.modules.services.gitea = {
enable = lib.mkEnableOption "enables gitea";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7703;
description = "set port for gitea (default: ${toString default_port}";
};
# set ssh port
ssh_port = lib.mkOption {
type = lib.types.int;
default = 7567;
description = "set port for gitea (default: 2222";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for gitea";
};
};
config = lib.mkIf cfg.enable {
# declare gitea group
users.groups.gitea = { gid = ids; };
# declare gitea user
users.users.gitea = {
description = lib.mkForce "gitea server user";
uid = ids;
isSystemUser = true;
shell = pkgs.bash;
home = "/var/lib/gitea";
createHome = true;
group = "gitea";
extraGroups = [];
};
# enable the gitea service
services.gitea = {
enable = true;
user = "gitea";
group = "gitea";
stateDir = data_dir;
appName = "gitea";
settings = {
server = {
DOMAIN = "git.blakedheld.xyz";
HTTP_PORT = cfg.port;
SSH_PORT = cfg.ssh_port;
START_SSH_SERVER = true;
ENABLE_PUSH_CREATE_USER = true;
};
};
database = {
passwordFile = "${toString config.sops.secrets."gitea_database_password".path}";
};
};
# override umask to make permissions work out
systemd.services.gitea.serviceConfig = { UMask = lib.mkForce "0007"; };
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port cfg.ssh_port ];
# internal reverse proxy entry
services.nginx.virtualHosts."git.snowbelle.lan" = {
enableACME = false;
forceSSL = true;
sslCertificate = config.sops.secrets."ssl_blakedheld_crt".path;
sslCertificateKey = config.sops.secrets."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
# external reverse proxy entry
services.nginx.virtualHosts."git.blakedheld.xyz" = {
enableACME = true;
forceSSL = true;
# sslCertificate = config.sops.secrets."ssl_blakedheld_crt".path;
# sslCertificateKey = config.sops.secrets."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
sops.secrets = {
"gitea_database_password" = {
owner = "gitea";
group = "gitea";
# neededForUsers = true;
};
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ data_dir ];
};
}

View File

@@ -1,82 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.services.jellyfin;
ids = 701;
default_port = 8096;
data_dir = "/var/lib/jellyfin";
in
{
options.modules.services.jellyfin = {
enable = lib.mkEnableOption "enables jellyfin";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7101;
description = "set port for jellyfin (default: ${toString default_port}";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
};
};
config = lib.mkIf cfg.enable {
# declare jellyfin group
users.groups.jellyfin = { gid = ids; };
# declare jellyfin user
users.users.jellyfin = {
description = "jellyfin media server user";
uid = ids;
isSystemUser = true;
home = data_dir;
createHome = true;
group = "jellyfin";
extraGroups = [ "media" "video" "render" ];
};
# enable the jellyfin service
services.jellyfin = {
enable = true;
openFirewall = true; # Opens 8096/8920 automatically
user = "jellyfin"; # Default: jellyfin
group = "jellyfin"; # Default: jellyfin
dataDir = "/var/lib/jellyfin"; # Config + metadata storage
};
# override umask to make permissions work out
systemd.services.jellyfin.serviceConfig = { UMask = lib.mkForce "0007"; };
# open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."jellyfin.snowbelle.lan" = {
enableACME = false;
forceSSL = true;
sslCertificate = config.sops.secrets."ssl_blakedheld_crt".path;
sslCertificateKey = config.sops.secrets."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
# external reverse proxy entry
services.nginx.virtualHosts."media.blakedheld.xyz" = {
enableACME = false;
forceSSL = true;
sslCertificate = config.sops.secrets."ssl_blakedheld_crt".path;
sslCertificateKey = config.sops.secrets."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ data_dir ];
};
}

View File

@@ -1,39 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.homelab.nginx-proxy;
in
{
options.modules.homelab.nginx-proxy = {
enable = lib.mkEnableOption "enables nginx-proxy";
};
config = lib.mkIf cfg.enable {
# enable nginx proxy manager
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
# enable acme for auto ssl certs with lets encrypt
security.acme = {
acceptTerms = true;
defaults.email = "me@blakedheld.xyz";
};
# nginx secrets
sops.secrets = {
"ssl_blakedheld_crt" = {
restartUnits = [ "nginx.service" ];
owner = "nginx";
group = "nginx";
# neededForUsers = true;
};
"ssl_blakedheld_key" = {
owner = "nginx";
group = "nginx";
# neededForUsers = true;
};
};
};
}

View File

@@ -1,102 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.services.qbittorrent;
default_port = 8080;
data_dir = "/var/lib/qBittorrent";
ids = 2003;
vpn_inf = "enp89s0.69"; # vpn interfacve
in
{
options.modules.services.qbittorrent = {
enable = lib.mkEnableOption "enables qbittorrent";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7103;
description = "set port for qbittorrent (default: ${toString default_port}";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for qbittorrent";
};
};
config = lib.mkIf cfg.enable {
# declare qbittorrent group
users.groups.qbittorrent = { gid = ids; };
# declare qbittorrent user
users.users.qbittorrent = {
description = "qbittorrent server user";
uid = ids;
isSystemUser = true;
home = data_dir;
createHome = true;
group = "qbittorrent";
extraGroups = [ "media" ];
};
# enable the qbittorrent service
services.qbittorrent = {
enable = true;
openFirewall = true;
user = "qbittorrent";
group = "qbittorrent";
profileDir = data_dir;
webuiPort = cfg.port;
# torrentingPort = cfg.port;
};
# override umask to make permissions work out
systemd.services.qbittorrent = {
serviceConfig = {
UMask = lib.mkForce "0007";
};
};
networking.firewall.extraCommands = ''
iptables -F QBIT
iptables -X QBIT
iptables -N QBIT
iptables -A OUTPUT -m owner --uid-owner ${toString ids} -j QBIT
iptables -A QBIT -o ${vpn_inf} -j ACCEPT
iptables -A QBIT -p udp --dport 53 -o ${vpn_inf} -j ACCEPT
iptables -A QBIT -p tcp --dport 53 -o ${vpn_inf} -j ACCEPT
iptables -A QBIT -p tcp -d 127.0.0.1 --dport ${toString cfg.port} -j ACCEPT
iptables -A QBIT -p tcp -o enp89s0 -d 10.0.0.0/8 --dport ${toString cfg.port} -j ACCEPT
iptables -A QBIT -j DROP
'';
# ------------------------------------------------------------------------------
# # add systemd service to VPN network namespace
# vpnConfinement = {
# enable = true;
# vpnNamespace = "wgmex";
# };
# ------------------------------------------------------------------------------
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."qbit.snowbelle.lan" = {
enableACME = false;
forceSSL = true;
sslCertificate = config.sops.secrets."ssl_blakedheld_crt".path;
sslCertificateKey = config.sops.secrets."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ data_dir ];
};
}

View File

@@ -1,105 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.services.vaultwarden;
ids = 2771;
default_port = 8000;
data_dir = "/var/lib/vaultwarden";
domain = https://pass.blakedheld.xyz;
in
{
options.modules.services.vaultwarden = {
enable = lib.mkEnableOption "enables vaultwarden";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7701;
description = "set port for vaultwarden (default: ${toString default_port}";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for vaultwarden";
};
};
config = lib.mkIf cfg.enable {
# declare vaultwarden group
users.groups.vaultwarden = { gid = ids; };
# declare vaultwarden user
users.users.vaultwarden = {
description = "vaultwarden server user";
uid = ids;
isSystemUser = true;
home = "/var/lib/vaultwarden";
createHome = true;
group = "vaultwarden";
extraGroups = [ "media" ];
};
# enable the vaultwarden service
services.vaultwarden = {
enable = true;
config = {
DOMAIN = domain;
ROCKET_ADDRESS = "0.0.0.0";
ROCKET_PORT = cfg.port;
SIGNUPS_ALLOWED = true;
# ADMIN_TOKEN = "yuh";
ADMIN_TOKEN = "${toString config.sops.secrets."vaultwarden_admin_token".path}";
EXPERIMENTAL_CLIENT_FEATURE_FLAGS = "fido2-vault-credentials,autofill-overlay,autofill-v2,inline-menu-positioning-improvements,ssh-key-vault-item";
# The following flags are available:
# - "autofill-overlay": Add an overlay menu to form fields for quick access to credentials.
# - "autofill-v2": Use the new autofill implementation.
# - "browser-fileless-import": Directly import credentials from other providers without a file.
# - "extension-refresh": Temporarily enable the new extension design until general availability (should be used with the beta Chrome extension)
# - "fido2-vault-credentials": Enable the use of FIDO2 security keys as second factor.
# - "inline-menu-positioning-improvements": Enable the use of inline menu password generator and identity suggestions in the browser extension.
# - "ssh-key-vault-item": Enable the creation and use of SSH key vault items. (Needs clients >=2024.12.0)
# - "ssh-agent": Enable SSH agent support on Desktop. (Needs desktop >=2024.12.0)
};
};
# override umask to make permissions work out
systemd.services.vaultwarden.serviceConfig = { UMask = lib.mkForce "0007"; };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."pass.snowbelle.lan" = {
enableACME = false;
forceSSL = true;
sslCertificate = config.sops.secrets."ssl_blakedheld_crt".path;
sslCertificateKey = config.sops.secrets."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
# external reverse proxy entry
services.nginx.virtualHosts."pass.blakedheld.xyz" = {
enableACME = false;
forceSSL = true;
sslCertificate = config.sops.secrets."ssl_blakedheld_crt".path;
sslCertificateKey = config.sops.secrets."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
sops.secrets = {
"vaultwarden_admin_token" = {
owner = "vaultwarden";
group = "vaultwarden";
path = "/home/blake/.nix/.keyring/vaultwarden_admin_token";
};
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ data_dir ];
};
}

View File

@@ -1,20 +0,0 @@
{ pkgs, config, lib, ... }:
{
imports = [
./jellyfin
./vaultwarden
./gitea
./qbittorrent
./immich
./nginx-proxy
./arr/prowlarr
./arr/flaresolverr
./arr/bazarr
./arr/sonarr
./arr/radarr
];
}

View File

@@ -1,108 +0,0 @@
{ pkgs, config, lib, ... }:
let
service = "";
cfg = config.modules.services.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
in
{
options.modules.services.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = <port>;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
extraGroups = [ "media" ];
};
# enable the ${service} service
services.${service} = {
enable = true;
openFirewall = true;
user = "${service}";
group = "${service}";
dataDir = cfg.data_dir;
settings = {
server.port = cfg.port;
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
# User = "${service}";
# Group = "${service}";
};
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
# # external reverse proxy entry
# services.nginx.virtualHosts."${service}.blakedheld.xyz" = {
# forceSSL = true;
# sslCertificate = sec."ssl_blakedheld_crt".path;
# sslCertificateKey = sec."ssl_blakedheld_key".path;
# locations."/" = {
# proxyPass = "http://127.0.0.1:${toString cfg.port}";
# };
# };
#
# sops.secrets = {
# "${service}_" = {
# owner = "${service}";
# group = "${service}";
# };
# };
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
};
}

View File

@@ -1,102 +0,0 @@
{ pkgs, config, lib, inputs, ... }:
let
service = "immich";
cfg = config.modules.services.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
in
{
options.modules.services.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7702;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "${service}.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
extraGroups = [ "video" "render" ];
};
# enable the ${service} service
services.${service} = {
enable = true;
package = inputs.nixpkgs-unstable.legacyPackages.${pkgs.system}.immich;
openFirewall = true;
user = "${service}";
group = "${service}";
mediaLocation = cfg.data_dir;
host = "0.0.0.0";
port = cfg.port;
settings.server.externalDomain = "https://pics.blakedheld.xyz";
};
# override umask to make permissions work out
# systemd.services."${toString service}-server".serviceConfig = {
# UMask = lib.mkForce "0007";
# };
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
proxyWebsockets = true;
};
};
# external reverse proxy entry
services.nginx.virtualHosts."pics.blakedheld.xyz" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
proxyWebsockets = true;
};
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir "/var/lib/redis-immich" ];
};
}

View File

@@ -1,39 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.homelab.nginx-proxy;
in
{
options.modules.homelab.nginx-proxy = {
enable = lib.mkEnableOption "enables nginx-proxy";
};
config = lib.mkIf cfg.enable {
# enable nginx proxy manager
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
# enable acme for auto ssl certs with lets encrypt
security.acme = {
acceptTerms = true;
defaults.email = "me@blakedheld.xyz";
};
# nginx secrets
sops.secrets = {
"ssl_blakedheld_crt" = {
restartUnits = [ "nginx.service" ];
owner = "nginx";
group = "nginx";
# neededForUsers = true;
};
"ssl_blakedheld_key" = {
owner = "nginx";
group = "nginx";
# neededForUsers = true;
};
};
};
}

View File

@@ -1,33 +0,0 @@
{ pkgs, config, lib, ... }:
# define smb shares
let
cfg = config.modules.homelab.smb;
smb_shares = {
vault = {
path = "/holocron/vault";
browseable = true;
writable = true;
guestOk = false;
};
media = {
path = "/holocron/media";
browseable = true;
writable = true;
guestOk = false;
};
};
in
{
options.modules.homelab.smb = {
enable = lib.mkEnableOption "enables smb";
};
config = lib.mkIf cfg.enable {
# enable smb with all shares
services.samba = {
enable = true;
settings = smb_shares;
};
};
}

View File

@@ -1,35 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.homelab.zfs;
in
{
options.modules.homelab.zfs = {
enable = lib.mkEnableOption "enables zfs";
};
config = lib.mkIf cfg.enable {
# set network host id
networking.hostId = "3e6e7055";
# enable zfs support
boot.kernelModules = [ "zfs" ];
boot.supportedFilesystems = [ "zfs" ];
# enable smart monitoring
services.smartd.enable = true;
# enable zfs
services.zfs = {
autoScrub.enable = true;
autoScrub.interval = "weekly";
};
fileSystems."/holocron" = {
device = "holocron";
fsType = "zfs";
options = [ "nofail" ];
};
};
}

View File

@@ -0,0 +1,40 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.homelab.tailscale;
authkey_file = config.sops.secrets."tailscale_authkey".path;
in {
options.homelab.tailscale = {
enable = lib.mkEnableOption "enables tailscale";
};
config = lib.mkIf cfg.enable {
services.tailscale = {
enable = true;
openFirewall = true;
useRoutingFeatures = "both";
authKeyFile = authkey_file;
extraSetFlags = [
"--advertise-routes=10.10.0.10/32" # advertise self
"--accept-routes=false" # true is equilivant to useRoutingFeatures = "client" (breaks shit)
"--accept-dns=true" # explicitly allow resolved
];
extraUpFlags = [
];
};
# network config
networking.firewall.trustedInterfaces = ["tailscale0"];
networking.firewall.allowedUDPPorts = [config.services.tailscale.port];
# declare authkey secrets
sops.secrets = {
"tailscale_authkey" = {
owner = "root";
};
};
};
}

View File

@@ -0,0 +1,100 @@
{ pkgs, config, lib, ... }:
let
service = "uptime-kuma";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in
{
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7901;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "up.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
extraGroups = [];
};
# enable the ${service} service
services.${service} = {
enable = true;
settings =
{
PORT = toString cfg.port;
HOST = "0.0.0.0";
};
};
# override umask to make permissions work out
systemd.services.${service}.serviceConfig = {
UMask = lib.mkForce "0007";
};
# # open firewall
# networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to glance
homelab.glance.links.system = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -2,13 +2,13 @@
let
service = "vaultwarden";
cfg = config.modules.services.${service};
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.modules.homelab;
homelab = config.homelab;
domain = "https://pass.blakedheld.xyz";
in
{
options.modules.services.${service} = {
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
@@ -37,6 +37,10 @@ in
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
@@ -51,7 +55,7 @@ in
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = "${service}";
group = service;
extraGroups = [];
};
@@ -84,25 +88,23 @@ in
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
# internal reverse proxy entry
services.nginx.virtualHosts."${cfg.url}" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
};
# external reverse proxy entry
services.nginx.virtualHosts."pass.blakedheld.xyz" = {
forceSSL = true;
sslCertificate = sec."ssl_blakedheld_crt".path;
sslCertificateKey = sec."ssl_blakedheld_key".path;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.port}";
};
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
serverAliases = [ "pass.${homelab.public_domain}" ];
extraConfig = ''
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
reverse_proxy 127.0.0.1:${toString cfg.port}
'';
};
# add to glance
homelab.glance.links.services = [{
title = service;
url = "https://pass.${homelab.public_domain}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:${service}"; }];
sops.secrets = {
"${service}_admin_token" = {
owner = "${service}";
@@ -111,6 +113,8 @@ in
};
# add to backups
modules.system.backups.paths = lib.mkIf cfg.backup [ cfg.data_dir ];
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -0,0 +1,109 @@
{ pkgs, config, lib, ... }:
let
service = "yacreader";
cfg = config.homelab.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in
{
options.homelab.${service} = {
enable = lib.mkEnableOption "enables ${service}";
# set port options
port = lib.mkOption {
type = lib.types.int;
default = 7102;
description = "set port for ${service} (default: ${toString cfg.port}";
};
url = lib.mkOption {
type = lib.types.str;
default = "manga.${homelab.base_domain}";
description = "set domain for ${service}";
};
data_dir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/${service}";
description = "set data directory for ${service}";
};
ids = lib.mkOption {
type = lib.types.int;
default = cfg.port;
description = "set uid and pid of ${service} user (matches port by default)";
};
backup = lib.mkOption {
type = lib.types.bool;
default = true;
description = "enable backups for ${service}";
};
motd = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = service;
};
};
config = lib.mkIf cfg.enable {
# install the binary
environment.systemPackages = with pkgs; [ yacreader ];
# declare ${service} group
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
# declare ${service} user
users.users.${service} = {
description = "${service} server user";
uid = lib.mkForce cfg.ids;
isSystemUser = true;
home = cfg.data_dir;
createHome = true;
group = service;
extraGroups = [ "media" ];
};
# enable the ${service} service
systemd.services.${service} = {
description = "${service} library server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
UMask = lib.mkForce "0007";
User = service;
Group = service;
Restart = "always";
RestartSec = "5s";
Type = "simple";
ExecStart = "${pkgs.yacreader}/bin/YACReaderLibraryServer start --port ${toString cfg.port}";
WorkingDirectory = "/var/lib/yacreader";
TimeoutStopSec = "20s";
};
};
# open firewall
networking.firewall.allowedTCPPorts = [ cfg.port ];
# add to caddy for reverse proxy
services.caddy.virtualHosts."${cfg.url}" = {
extraConfig = ''
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
reverse_proxy 127.0.0.1:${toString cfg.port} {
}
'';
};
# add to glance local service
homelab.glance.links.mediastack = [{
title = service;
url = "https://${cfg.url}";
error-url = "http://${homelab.host_ip}:${toString cfg.port}";
check-url = "http://${homelab.host_ip}:${toString cfg.port}";
icon = "di:yac-reader"; }];
# add to backups
homelab.backups.baks = {
${service} = { paths = [ cfg.data_dir ]; };
};
};
}

View File

@@ -1,102 +0,0 @@
{ config, lib, pkgs, ... }:
let
cfg = config.modules.system.backups;
borg = "${pkgs.borgbackup}/bin/borg";
backup_paths = lib.unique config.modules.system.backups.paths;
passwd_file = config.sops.secrets."borg_passwd".path;
in
{
options.modules.system.backups = {
enable = lib.mkEnableOption "enables backups with borg";
paths = lib.mkOption {
type = lib.types.listOf lib.types.path;
default = [];
description = "list of directories to back up";
};
repo = lib.mkOption {
type = lib.types.path;
default = "/holocron/borg";
description = "borg repository path";
};
passphraseFile = lib.mkOption {
type = lib.types.path;
default = passwd_file;
description = "borg repository passphrase file";
};
};
config = lib.mkIf (cfg.enable && backup_paths != []) {
# systemd.tmpfiles.rules = [
# "d ${cfg.repo} 0755 root root"
# ];
systemd.services.backups = {
description = "backup service with borg!";
path = [ pkgs.borgbackup ];
serviceConfig = {
Type = "oneshot";
EnvironmentFile = config.modules.system.backups.passphraseFile;
# the actual script borg is using
ExecStart = pkgs.writeShellScript "borg-backup" ''
set -euo pipefail
export BORG_PASSPHRASE="$(cat ${passwd_file})"
export BORG_REPO="${cfg.repo}"
timestamp="$(date +'%Y-%m-%dT%H:%M:%S')"
# Initialize repo if it doesn't exist
if ! borg info "$BORG_REPO" >/dev/null 2>&1; then
echo "init borg repo at $BORG_REPO"
borg init --encryption=repokey "$BORG_REPO"
fi
# Create backup
echo "starting backup..."
borg create \
--verbose \
--filter AME \
--list \
--stats \
--show-rc \
--compression lz4 \
"$BORG_REPO::${toString config.networking.hostName}-$timestamp" \
${lib.concatStringsSep " " cfg.paths}
# Prune old backups according to retention policy
echo "Pruning old backups..."
borg prune -v --list "$BORG_REPO" \
--keep-daily=7 \
--keep-weekly=52 \
--keep-monthly=-1
echo "$timestamp - backup completed successfully."
'';
};
};
# create timer to run backups daily
systemd.timers.backups = {
description = "daily borg backup timer";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
};
# install borg binary
environment.systemPackages = [ pkgs.borgbackup ];
# declare secret for repo password
sops.secrets = {
"borg_passwd" = {
owner = "root";
group = "root";
};
};
};
}
# add to modules
# modules.system.backups.paths = lib.mkIf cfg.backups [ <path> ];

View File

@@ -0,0 +1,72 @@
{
pkgs,
inputs,
config,
lib,
...
}: let
cfg = config.system.cifs_mounts;
sec = config.sops.secrets;
in {
options.system.cifs_mounts = {
enable = lib.mkEnableOption "enables mounting holocron fileshare on the client side";
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
cifs-utils
];
fileSystems."/media/holocron/blake" = {
device = "//10.10.0.10/users/blake";
fsType = "cifs";
options = [
"x-systemd.automount"
"noauto"
"_netdev"
"credentials=${sec."holocron_creds".path}"
"uid=1000"
"gid=1000"
"file_mode=0664"
"dir_mode=0775"
];
};
fileSystems."/media/holocron/archives" = {
device = "//10.10.0.10/archives";
fsType = "cifs";
options = [
"x-systemd.automount"
"noauto"
"_netdev"
"credentials=${sec."holocron_creds".path}"
"uid=1000"
"gid=1000"
"file_mode=0664"
"dir_mode=0775"
];
};
fileSystems."/media/holocron/media" = {
device = "//10.10.0.10/media";
fsType = "cifs";
options = [
"x-systemd.automount"
"noauto"
"_netdev"
"credentials=${sec."holocron_creds".path}"
"uid=1000"
"gid=1000"
"file_mode=0664"
"dir_mode=0775"
];
};
# manage secrets with sops
sops.secrets = {
"holocron_creds" = {
owner = "blake";
group = "blake";
};
};
};
}

View File

@@ -1,26 +1,27 @@
{ pkgs, config, lib, ... }:
{
pkgs,
config,
lib,
...
}: {
imports = [
./ssh.nix
./backups.nix
./sops.nix
./docker.nix
./tailscale.nix
./vpns.nix
./vpn-confinement.nix
./syncthing.nix
./nvidia.nix
./ssh
./sops
./docker
./podman
./yubikey
./tailscale
./japanese
./vpns
./vpn-confinement
./syncthing
./graphics
./flatpak
./secure_boot
./cifs_mounts
./udiskie
];
modules.system.ssh.enable = lib.mkDefault true;
modules.system.backups.enable = lib.mkDefault true;
modules.system.sops.enable = lib.mkDefault true;
modules.system.docker.enable = lib.mkDefault false;
modules.system.tailscale.enable = lib.mkDefault true;
modules.system.vpns.enable = lib.mkDefault false;
modules.system.vpn-confinement.enable = lib.mkDefault false;
modules.system.syncthing.enable = lib.mkDefault false;
modules.system.nvidia.enable = lib.mkDefault false;
system.ssh.enable = lib.mkDefault true;
system.sops.enable = lib.mkDefault true;
}

View File

@@ -1,16 +1,19 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.system.docker;
cfg = config.system.docker;
in
{
options.modules.system.docker = {
options.system.docker = {
enable = lib.mkEnableOption "enables docker";
};
config = lib.mkIf cfg.enable {
virtualisation.docker = {
enable = true;
daemon.settings.features.cdi = true;
rootless.daemon.settings.features.cdi = true;
daemon.settings = {
experimental = true;
};

View File

@@ -0,0 +1,19 @@
{
pkgs,
inputs,
config,
lib,
...
}: let
cfg = config.system.flatpak;
in {
options.system.flatpak = {
enable = lib.mkEnableOption "enables nix-flatpak on nixos side";
};
imports = [inputs.nix-flatpak.nixosModules.nix-flatpak];
config = lib.mkIf cfg.enable {
services.flatpak.enable = true;
};
}

View File

@@ -0,0 +1,89 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.system.graphics;
in {
options.system.graphics = {
enable = lib.mkEnableOption "enables nvidia";
vendor = lib.mkOption {
type = lib.types.enum ["intel" "amd" "nvidia"];
default = "intel";
description = ''
set the vendor of your graphics device
supported options are "intel" "amd" "nvidia"
'';
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
hardware.graphics.enable = true;
hardware.graphics.enable32Bit = true;
}
(lib.mkIf (cfg.vendor == "intel") {
services.xserver.videoDrivers = ["modesetting"];
# userspace tools
environment.systemPackages = with pkgs; [
intel-gpu-tools
];
hardware.graphics.extraPackages = with pkgs; [
# Required for modern Intel GPUs (Xe iGPU and ARC)
intel-media-driver # VA-API (iHD) userspace
vpl-gpu-rt # oneVPL (QSV) runtime
# Optional (compute / tooling):
intel-compute-runtime # OpenCL (NEO) + Level Zero for Arc/Xe
];
environment.sessionVariables = {
LIBVA_DRIVER_NAME = "iHD"; # Prefer the modern iHD backend
};
})
(lib.mkIf (cfg.vendor == "amd") {
boot.initrd.kernelModules = ["amdgpu"];
services.xserver.videoDrivers = ["amdgpu"];
# userspace tools
environment.systemPackages = with pkgs; [
radeontop
];
# enable amd vulkan (program will choose this or regular)
hardware.graphics.extraPackages = with pkgs; [
rocmPackages.clr.icd # enable open cl (compute framework like cuda)
];
# ^ but 32 bit
hardware.graphics.extraPackages32 = with pkgs; [
];
# make hip work (extension on cli.icd ^)
systemd.tmpfiles.rules = [
"L+ /opt/rocm/hip - - - - ${pkgs.rocmPackages.clr}"
];
})
(lib.mkIf (cfg.vendor == "nvidia") {
boot.kernelModules = ["nvidia" "nvidia_modeset" "nvidia_uvm" "nvidia_drm"];
services.xserver.videoDrivers = ["nvidia"];
# enable nvidia proprietary driver
hardware.nvidia = {
modesetting.enable = true; # required
open = false; # use proprietary driver
nvidiaSettings = true; # no shit
powerManagement.enable = false; # can cause sleep issues
package = config.boot.kernelPackages.nvidiaPackages.stable;
};
# enable docker gpu passthrough
hardware.nvidia-container-toolkit.enable = true;
})
]);
}

View File

@@ -0,0 +1,52 @@
{
pkgs,
inputs,
config,
lib,
...
}: let
cfg = config.system.japanese;
in {
options.system.japanese = {
enable = lib.mkEnableOption "enables japanese tools";
};
config = lib.mkIf cfg.enable {
# japanese input
i18n.inputMethod = {
enabled = "fcitx5";
fcitx5.addons = with pkgs; [
fcitx5-mozc
fcitx5-gtk
fcitx5-qt
];
};
environment.systemPackages = with pkgs; [
fcitx5
fcitx5-configtool
];
# fonts for japanese
fonts = {
enableDefaultPackages = true;
packages = with pkgs; [
noto-fonts
noto-fonts-cjk
noto-fonts-emoji
source-han-sans
source-han-serif
];
fontconfig = {
defaultFonts = {
serif = [ "Noto Serif CJK JP" ];
sansSerif = [ "Noto Sans CJK JP" ];
monospace = [ "Noto Sans Mono CJK JP" ];
};
};
};
};
}

View File

@@ -1,37 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.system.nvidia;
in
{
options.modules.system.nvidia = {
enable = lib.mkEnableOption "enables nvidia";
};
config = lib.mkIf cfg.enable {
services.xserver.videoDrivers = [ "nvidia" ];
boot.kernelModules = [ "nvidia" "nvidia_modeset" "nvidia_uvm" "nvidia_drm" ];
# boot.kernelModules = [ "nvidia" ];
hardware.graphics = {
enable = true;
enable32Bit = true;
};
# enable nvidia proprietary driver
hardware.nvidia = {
modesetting.enable = true; # required
open = false; # use proprietary driver
nvidiaSettings = true; # no shit
powerManagement.enable = false; # can cause sleep issues
package = config.boot.kernelPackages.nvidiaPackages.stable;
};
# enable docker gpu passthrough
hardware.nvidia-container-toolkit.enable = true;
virtualisation.docker.daemon.settings.features.cdi = true;
virtualisation.docker.rootless.daemon.settings.features.cdi = true;
};
}

View File

@@ -0,0 +1,29 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.system.podman;
in {
options.system.podman = {
enable = lib.mkEnableOption "enables podman";
};
config = lib.mkIf cfg.enable {
# install the binary for compose
environment.systemPackages = with pkgs; [podman-compose];
virtualisation = {
oci-containers.backend = "podman";
podman = {
enable = true;
dockerCompat = true;
autoPrune.enable = true;
defaultNetwork.settings = {
dns_enabled = true;
};
};
};
};
}

View File

@@ -0,0 +1,43 @@
{
pkgs,
inputs,
config,
lib,
...
}: let
cfg = config.system.secure_boot;
in {
options.system.secure_boot = {
enable = lib.mkEnableOption "enables secureboot with lanzaboote";
};
imports = [inputs.lanzaboote.nixosModules.lanzaboote];
config = lib.mkIf cfg.enable {
# install userspace secureboot tools
environment.systemPackages = with pkgs; [
sbctl
e2fsprogs
];
# force disable systemd-boot so lanzaboote can be used
boot.loader.systemd-boot.enable = lib.mkForce false;
/*
this uses the project lanzaboote for secureboot (extension on systemd)
setup guide can be found here: https://github.com/nix-community/lanzaboote/blob/master/docs/QUICK_START.md
tldr:
while currently using systemd-boot
generate keys with `nix-shell -p --run "sudo sbctl create-keys"`
rebuild with this module enabled then check `sudo sbctl verify`
reboot and enable secureboot setup mode in bios
check that setup mode is enabled with `sudo sbctl status`
enroll keys with `sudo sbctl enroll-keys` use the `--microsoft` flag to incude their keys for compatibality
reboot (disable secureboot setup mode if not done automatically) then check secure boot status with `sudo bootctl status`
*/
boot.lanzaboote = {
enable = true;
pkiBundle = "/var/lib/sbctl";
};
};
}

View File

@@ -1,25 +1,27 @@
{ pkgs, config, lib, inputs, ... }:
let
cfg = config.modules.system.sops;
in
{
imports = [ inputs.sops-nix.nixosModules.sops ];
pkgs,
config,
lib,
inputs,
...
}: let
cfg = config.system.sops;
in {
imports = [inputs.sops-nix.nixosModules.sops];
options.modules.system.sops = {
options.system.sops = {
enable = lib.mkEnableOption "enables sops";
};
config = lib.mkIf cfg.enable {
# enable and configure sops for secrets
sops = {
defaultSopsFile = ../../secrets/secrets.yaml;
defaultSopsFile = ../../../secrets/secrets.yaml;
defaultSopsFormat = "yaml";
# age.keyFile = "/home/blake/.config/sops/age/keys.txt";
age.keyFile = "/etc/sops/keys.txt";
secrets = {
"blake_passwd" = lib.mkIf config.users.blake.enable {
"blake_passwd" = {
owner = "root";
group = "root";
neededForUsers = true;

View File

@@ -1,10 +1,10 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.system.ssh;
cfg = config.system.ssh;
in
{
options.modules.system.ssh = {
options.system.ssh = {
enable = lib.mkEnableOption "enables ssh";
};
@@ -13,7 +13,7 @@ in
services.openssh = {
enable = true;
settings = {
PasswordAuthentication = true;
PasswordAuthentication = false;
PermitRootLogin = "no";
X11Forwarding = false;
};

View File

@@ -1,38 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.system.syncthing;
in
{
options.modules.system.syncthing = {
enable = lib.mkEnableOption "enables syncthing";
# mode = lib.mkOption {
# type = lib.types.enum [ "server" "client" ];
# default = "client";
# description = "whether syncthing should run as a client (user) or server (system-wide).";
# };
#
# data_dir = lib.mkOption {
# type = lib.types.str;
# default = if cfg.mode == "server"
# then "/var/lib/syncthing"
# else "/home/blake/.local/state/syncthing";
# description = "optional override for syncthing data directory.";
# };
};
config = lib.mkIf cfg.enable {
# systemd.tmpfiles.rules = lib.optionals (cfg.mode == "server") ["d /var/lib/syncthing 0775 blake blake -"];
services.syncthing = {
enable = true;
# user = "blake";
# group = "blake";
# dataDir = "/var/lib/syncthing";
guiAddress = "0.0.0.0:2222";
# openDefaultPorts = true;
};
};
}

View File

@@ -0,0 +1,95 @@
{
pkgs,
config,
lib,
...
}: let
service = "syncthing";
cfg = config.system.${service};
sec = config.sops.secrets;
in {
options.system.${service} = {
enable = lib.mkEnableOption "enables syncthing";
host = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = config.networking.hostName;
};
};
config = lib.mkIf cfg.enable {
services.syncthing = {
enable = true;
user = "blake";
group = "blake";
guiAddress = "0.0.0.0:2222";
openDefaultPorts = true;
dataDir = "/home/blake/.config/syncthing";
#extraFlags = ["--no-default-folder"];
overrideFolders = false;
overrideDevices = false;
key = sec."${service}/${cfg.host}/key".path;
cert = sec."${service}/${cfg.host}/cert".path;
settings = {
devices = {
"snowbelle" = {id = "6WQ6ATA-5AT4RUM-NW67PAL-N62CPNV-ALRFG3P-5BDRO22-HWFC2Q4-5S5BDA5";};
"lugia" = {id = "BKKSFPH-YEOVVAB-DTT7KK3-UDKAEJ2-PC6ECG7-Y76ZIVP-JRYMMXS-RTZYVQ3";};
"zygarde" = {id = "UYLTF52-VVKUR7F-JN33HQZ-RFNWGL3-JER52LA-GZD2LPJ-QIFEE7K-MNMZRQ5";};
"mew" = {id = "7ZC2NAS-QONQKAL-Z54NPMB-7TRXM6M-K7Z6PZD-FG4AI4H-V7SMFJN-JOYBHQO";};
"yveltal" = {id = "ZVSQ4WJ-7OICYOZ-3ECES4X-KH37IPB-TKHKUJG-BSEGXVM-AHYY5C3-VKG44AX";};
"CEN-IT-07" = {id = "DPYKA4Z-3PX7JB2-FBEOXXX-SC7TLT2-QC5P2IR-SXOPJGX-QO3DMII-5B7UCA4";};
"CEN-IT-00007" = {id = "XBPXGYU-DUJSLDH-6BDNF4D-CO2COC3-N3FM6W5-IHZOJBM-Z2N77RI-IVAV5AH";};
};
folders = {
"holocron" = {
path = "/home/blake/holocron";
devices = ["lugia" "zygarde" "mew" "yveltal" "CEN-IT-07" "CEN-IT-00007" "snowbelle"];
id = "5voxg-c3he2";
versioning = {
type = "staggered";
fsPath = "/home/blake/holocron/.stversions";
params = {
cleanInterval = "3600";
maxAge = "0";
};
};
ignorePerms = true;
ignorePatterns = [
"// syncthing"
"/.versions"
"/.versions/**"
"/.stversions"
"/.stversions/**"
"// macos system junk"
"(?d).DS_Store"
"(?d).AppleDouble"
"(?d).LSOverride"
"(?d)Icon?"
"(?d)._*"
"(?d).Spotlight-V100"
"(?d).Trashes"
"(?d).fseventsd"
"(?d).metadata_never_index"
"(?d).com.apple.timemachine.donotpresent"
"(?d).com.apple.*"
"(?d)~*.tmp"
];
};
};
options = {
urAccepted = -1;
};
};
};
sops.secrets = {
"${service}/${cfg.host}/key" = {
owner = "blake";
group = "blake";
};
"${service}/${cfg.host}/cert" = {
owner = "blake";
group = "blake";
};
};
};
}

View File

@@ -1,30 +0,0 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.system.tailscale;
authkey_file = config.sops.secrets."tailscale_authkey".path;
in
{
options.modules.system.tailscale = {
enable = lib.mkEnableOption "enables tailscale";
};
config = lib.mkIf cfg.enable {
services.tailscale = {
enable = true;
useRoutingFeatures = "both";
authKeyFile = authkey_file;
extraUpFlags = [
"--accept-routes=false" # true is equilivant to useRoutingFeatures = "client" (breaks shit)
"--accept-dns=true" # explicitly allow resolved
];
};
# declare authkey secrets
sops.secrets = {
"tailscale_authkey" = {
owner = "root";
};
};
};
}

View File

@@ -0,0 +1,39 @@
{
pkgs,
config,
lib,
...
}: let
cfg = config.system.tailscale;
authkey_file = config.sops.secrets."tailscale_authkey".path;
in {
options.system.tailscale = {
enable = lib.mkEnableOption "enables tailscale";
};
config = lib.mkIf cfg.enable {
services.tailscale = {
enable = true;
useRoutingFeatures = "both";
#authKeyFile = authkey_file;
extraSetFlags = [
"--accept-routes=true" # true is equilivant to useRoutingFeatures = "client" (breaks shit)
"--accept-dns=true" # explicitly allow resolved
];
};
systemd.services.tailscaled = {
after = [ "remote-fs.target" ]; # keep tailscale up until remote mounts are unmounted
};
# network config
networking.firewall.trustedInterfaces = ["tailscale0"];
networking.firewall.allowedUDPPorts = [config.services.tailscale.port];
# declare authkey secrets
sops.secrets = {
"tailscale_authkey" = {
owner = "root";
};
};
};
}

View File

@@ -0,0 +1,16 @@
{
pkgs,
lib,
config,
...
}: let
cfg = config.system.udiskie;
in {
options.system.udiskie = {
enable = lib.mkEnableOption "enable udiskie for automount on nixos side";
};
config = lib.mkIf cfg.enable {
services.udisks2.enable = true;
};
}

View File

@@ -1,12 +1,17 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.system.vpn-confinement;
in
{
options.modules.system.vpn-confinement = {
pkgs,
config,
lib,
inputs,
...
}: let
cfg = config.system.vpn-confinement;
in {
imports = [inputs.vpn-confinement.nixosModules.default];
options.system.vpn-confinement = {
enable = lib.mkEnableOption "enables vpn-confinement";
# toggle for mullvad mexico w/ openvpn
vpncon_mex = lib.mkOption {
type = lib.types.bool;
@@ -16,7 +21,6 @@ in
};
config = lib.mkIf cfg.enable {
# Define VPN network namespace
vpnNamespaces.wgmex = {
enable = true;
@@ -25,17 +29,25 @@ in
"10.0.0.0/8"
];
portMappings = [
{ from = 7103; to = 7103; }
{
from = 7103;
to = 7103;
}
];
openVPNPorts = [
{
port = 51820;
protocol = "both";
}
];
openVPNPorts = [{
port = 51820;
protocol = "both";
}];
};
# secrets only if VPN is enabled
sops.secrets = {
"vpncon_mex_config" = { owner = "root"; group = "root"; };
"vpncon_mex_config" = {
owner = "root";
group = "root";
};
};
};
};
}

View File

@@ -1,10 +1,10 @@
{ pkgs, config, lib, ... }:
let
cfg = config.modules.system.vpns;
cfg = config.system.vpns;
in
{
options.modules.system.vpns = {
options.system.vpns = {
enable = lib.mkEnableOption "enables vpns";
# toggle for pia mexico w/ openvpn

View File

@@ -0,0 +1,79 @@
{
pkgs,
config,
lib,
...
}:
/*
# to enroll a yubikey with pam (works like .ssh/known_hosts)
nix-shell -p pam_u2f
mkdir -p ~/.config/Yubico
pamu2fcfg > ~/.config/Yubico/u2f_keys
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys (to add additional yubikeys)
# to test auth with pam
nix-shell -p pamtester
pamtester login <username> authenticate
pamtester sudo <username> authenticate
# to enroll yubikey with luks
`sudo systemd-cryptenroll --fido2-device=auto /dev/<disk>`
*/
let
service = "yubikey";
cfg = config.system.${service};
sec = config.sops.secrets;
homelab = config.homelab;
in {
options.system.${service} = {
enable = lib.mkEnableOption "enables ${service}";
mode = lib.mkOption {
type = lib.types.str;
default = "u2f";
description = "weather to run pam in u2f or challenge-response)";
};
lock_on_remove = lib.mkOption {
type = lib.types.bool;
default = false;
description = "enable automatic locking of device upon removal of yubikey";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
yubikey-personalization
yubikey-manager
];
# enable smartcard
services.pcscd.enable = true;
# enables it for everything
security.pam.u2f = lib.mkIf (cfg.mode == "u2f") {
enable = true;
};
# selectivlt edit what u2f is enabled for
security.pam.services = lib.mkIf (cfg.mode == "u2f") {
#login.u2fAuth = true;
#sudo.u2fAuth = true;
};
security.pam.yubico = lib.mkIf (cfg.mode == "challenge-response") {
enable = true;
debug = true;
mode = "challenge-response";
id = ["<placeholder>"];
};
services.udev.extraRules = lib.mkIf (cfg.lock_on_remove == true) ''
ACTION=="remove",\
ENV{ID_BUS}=="usb",\
ENV{ID_MODEL_ID}=="0407",\
ENV{ID_VENDOR_ID}=="1050",\
ENV{ID_VENDOR}=="Yubico",\
RUN+="${pkgs.systemd}/bin/loginctl lock-sessions"
'';
};
}

View File

@@ -1,25 +1,60 @@
#ENC[AES256_GCM,data:b7E2U/jRfXEKulR/Pba0L4Aucy3MSUPj2BU=,iv:+KC+vfB2z2AIiPr5uIC4Pbfgc44GOs6SVRZW1v80hUE=,tag:kkn3UfJwdgxYERmfiMUmjw==,type:comment]
blake_passwd: ENC[AES256_GCM,data:AfFql6/ghGhCDLOb4+QuAsDznz4hC4ilxZYCIH2sgBWX9tWXsUOgFw1k7CIhDoXIehz6YlTy0czekXPCqHL5gmIKRQTowU4svocw/Bl/Qz5CQ58RASB6YpnzOKTrwX7HCnu/ghpdMrcy2A==,iv:hMAkLcHjP0hiyCY4rhMU0Ae7jdYPa6MffEd2WGolbEo=,tag:p/6xmD8Te1RnFkp0zWw+ew==,type:str]
#ENC[AES256_GCM,data:0HBVS2AYQ2VZXY4EbMLwiSjRNyWZ57bf,iv:20SLWXpbRTLk76g5mFrhg1Z9Qasv3NoSJbK/FOiIgtk=,tag:DbUffQwrDqzy2QO64uoUeg==,type:comment]
klefki_auth_map: ENC[AES256_GCM,data:u8OBLtT/,iv:THW21BDyhyFIjcwixsAnaAODofxbuQZnpdgt9HGdDIg=,tag:zUvbOO8tLAnxdeMcWpvsdg==,type:str]
#ENC[AES256_GCM,data:ZxHtUSuOy19M0EKoT5xltFiqRg==,iv:72PJL2eG68VC4wiJFo6wL0l7AaDIsge8l/D/ZlLOWWA=,tag:Q16ztObK2AnbCCS5mRgjtA==,type:comment]
tailscale_authkey: ENC[AES256_GCM,data:SU0k3asrJd+WZ86VbC4w8TDJp+MqsbyagrzCfDcgTzO5yvBjpWAKbJ7A+VxgQvdu4+S2jMYbdrONPp3YbQ==,iv:VMYmGVk5GpUQApKKQYhdOw/cYCXrXxEZJJwHfQL4MjQ=,tag:7ruaoCDxuFQ7tE/JLJ37Xw==,type:str]
#ENC[AES256_GCM,data:bEbCic+ZDAA5ieNedCbiVbJrse17,iv:UwRYlis6NPB/RUcv+YnPxrGdbIcF4hrNiZt19YvWZNQ=,tag:m6PVlzPNnahX7X7KzMUj7A==,type:comment]
borg_passwd: ENC[AES256_GCM,data:XOMJtr+DRs7xn5Iclc49iTzK9cFJyc/fSXJjhdKa9jdN,iv:YB8z7zNYjh6NpSxQb1TfPxAYUdzThdVfNZIe6tO5grA=,tag:bO6kZ3cLJDL4IQoWmGvRdg==,type:str]
#ENC[AES256_GCM,data:lS++LQwlDVP0aYcdaaudBkKxNB3P3UBE,iv:UqGcXcX/Jvf60o409Cxj7VJCDh63uUxy45PuZbHK2l8=,tag:OXdMwuJwdN8DQaLXACpcRA==,type:comment]
ssl_blakedheld_crt: ENC[AES256_GCM,data:EvImZ3y5lrmD2P2Cehd4yAyranHRBkejbnad1qmH9KbKeLNFsTcqW4L3NDYydbKurWCWYa/jJAL/BwT2xmUhwdFlarCiTFGnLXxMFhd6Tq+5if8r6BfSLCCS4IXcXnXP4k96ZR2fdD+lnDN1ljb7pI5hekz+HoVwBoLVVrfvQvqj72Kr5rfm5ttLN21yfi5DbgfX7n9AO6X32wzpIAXxQaYIFdPpm12WMpEX+zfxjjcpOR+Xv8npbs4AlopFaZ1N8d2AlM19ChwTZm/Zmq3BQt5Z2bhGsQD/s357F5ofmSfQ8BGXdeUguLj0BtZw6zrxQlySmJMNroBxrQresE7cdeoeEagZXXxJd0S64HcvonV3jjp4s5817YWLxGD8rws2fH9Ci91DEMlI+4/U9Jb/fWz7nxXSMekpNkGRrKPm6L+3/dxpvbkv9UyQi3OVTcx642WYyFaZnP6J6qcbH+itwfuPE1Fu+fe9IlIbAopDrvau0CGisU4FhX+NYMEmFu6N/+unFyMpj9qsqS8UFAXfgvSPRQTULqcaaOK7MRVh3JGOfR9qnbbPjt+aJRrkTW7q/8OWcqvxLgPnZlpPkvsg9PjcZmwxV4ooh3FC85vsrEc8tEqzzbrSWrJRXpL2ZJxsO2AfpHICexyjJium2Dm0hfR9EP5b4ltzeqg0rBeczec7/Tckafy3cGk1jCkPoDYN857Kl6oHi/9TduYvqReKJTV8dLB256M3TBeAYNQypCGceemPtcYrAgG+yMC8tnR57k5QjXsCmT69fAlPibvZdHUxh6Hqlx9sj5WU1NhGRCQsAj362UzGsEcVoF5/zcXVf4i2yCT+axNRyK/JU4JW6GaldJQ8PV+ay5RhNHtErgP18IaY7RjwTA0PVd5G839qbHZlJXiO/EvqrVpuy7UthQlvN+9Y+YM5jQMi64ahEcdWXYSjhqnbh6cZ3xfOXK0egTpy1/xG+FXpFMIvqK2gPZrB1B1Wc0XSvpOBFxTRaWlfDYeVwDtw9QCbM/7jhD9jaopdhMoPH5J/guLxMhRtRw0CJUemnTX1KJ8dGpvDfaCdj+I7ptb7vQ0wAfU/ferpfLX07j6g8MMa4p9jzI9BtXyd9OEOtyFfV5X5Mls9FfhmNi4+ES8LmawsLiyptKKUA7db4GZ4CLJqeR3khh/sej/ESgeXTfLXlOQbIALOdfrPo1t0fDRlW0H42FhmyHeily7KCBFS/pcziTVkM1YPrfyCXH6p8hVBNJ/JYWlEoS5qAxfcXP6cS+/3L16Y5XEP2Aea02qhim02C3qIX+6CQAc5QmuMfl+itnmWdTdwpPzEwVExoUQLCNTU610mkkKtSdMe3aLzmMrfQskEwjMhfXCwVsO+HWugi7im5GAezs+3wuK8j4GYai2sMerKesl4mJXIZWTLJqG8Vj7yKMHJ5mCiOPPYQ3AL++s916kRu3gO1evxfzul7ndh1GypVbX66QZotV9/MN4wSGxw/RCRscZrM+XzmlrhiKT3uezF9KKiw9J1F3zDrtcjmIqll2WVn+U5uzPYEj6TeC5ty/q3OdhYY58U7qe84Pj5zq72bLegBMMK8sG685ylPWD5l79+3D+JGCbjRTwu2oNaIdy9wem0rl56YX+kcGQC2IQcWXcIDASVhAQjguTU/mmMzLNZb3effZ4ZNAmnWgra4hnjEqChuxKlEM7blm057K2G7HP/j82Xy9VsBOTTc0Q2KJZpdb9t+vfDUNJtNdog5w5SnObRqIkUdDrFx04tGUDp/8eqqSHZWZOLq+G4jzarn6YhvNpEote89cARCqdZGhREJFi+zeFWhguasltfSjXhQrYc2p46GlV4USKuWiyIUny5I5/HR2/0Ci5vK2wh1jZ+JC53sKxA3MHg5Udyqkt8tLK+5X5NL6F9EBCRSzCqXDCds6mGu26X5Qt10UZdLTxJs3M0x3bSbN1qJUnv6K0iKgAVw09jeXzKcVXbmFQUDJoVEErIcg1Oed8EwfJu274rF8Nfxh+29LE0CO3q/pR0P91eiUKLKK6oy9tpGnGrnRViAZS3LvVsNVdlWBSEm6WSiwM97hDH3CFqwUHPYzM830DZS6bfIL0OfT9lH5a1f7+Uywi3O3EaJaR0lr5esGJImOQG02yjCvqmdS+igFMKzdAyxQO1WSXDwHXZGTYZbhqyGYK+zc89lKdBaXiC91POQIiz5/xciXqb77YnXKeg4g==,iv:VQIqXN3r7DOVREX4fP5/OR8xECXLjYKfhd6XP3ghMaY=,tag:eVdyxrw/w5zBGxV6Tai2Pg==,type:str]
#ENC[AES256_GCM,data:3G8XqUKua1QgUxv2YJkW0fDnQPX7+v8GDC9BHg==,iv:BkESkMmMalgesy9why9eaKkOOvwSsN2EhNCRRRmZNtA=,tag:x95zt2B2M19BkzeMpAlXIg==,type:comment]
ssl_blakedheld_key: ENC[AES256_GCM,data:Jhb2yiIYlfJ8mewzohseWQYZ2pEYy8x2c9B6OH/P46roY2cljRJ3xb3e59cEkAoTvpuv8BE+fN94Zr+1BFjzsDrpf9YsaIXkH1j3wiAEd06G//KduSrJkNz6v4IxGHfASRCUE45xASvGXBWk24lUlOcsPQY7olncjdpqNQ5gxKGv1fYHfeFVgQkSZbhY87uT5DvuN2G1st7LX6cU5Fvs8GlMAKa5RhCKH1rE88wA3uNfaW0ffobmfQoUMhNlXfuIeOMw9HdYfpVxYCu5qlCLsqV/Upux8QGpfSdUnPUnHUAjdHpsU859cQjFGKaw0fpkUhLxh06z0UDUQ9000DDVYBfzmGVasSjwCJO0J1MbaZZy7Wv+XSgozl9FWeYEO+R7YN6R4K/rE2/HzxVVTmufIcinOH3oMPKrmvKFSNNCEIsDWqcGLtj5QFYxuK12Ra+rudJYPg6JnN3MYQ4W/Tlyy41zlwnayAp2xGowUJvfbxWkdsKtnY33NqRhPpM3vNWTgT+4t4HgikX1vaN5Cefre14f4wgn7N+CGCdsxrXMIfj5KL9GmdrWDtWFlkWlJtKti4AvJi5ud7iLhj31BrDRnjlNtPKMtC/YgSvVg0QxinlBAxtrovcujkd+LjNs7TvM3skUnXzU902gv+mGBce1WnywUYcUj1SLEo6qiimgiHSrk9zjLxoREWXpYILGTDY39pFQ8XnSFGaxTqcp/KvMiYlJO67qiQcKJscWi40HIkxL/tRiYoUKhGUnE3CTbvhfbDfjJkXr4vu5a26eZxDqi6xnvwF20fq0LgR9TN9VRL6v1/B+AH0O9uFceJSnKamq+N3bRFllpqkbZr7csQLRqb2UTbb03JOm1+y0dz7nJR7N4f07YmLPob8yYHjMlL9ge1kP9RWCVl9hL8hrzSavb3igzP841ckTyGX5u6v3HLssnSZb1XkBiv787/j+X/FZq7ojZu3cNBWQ+YnyRKS3RXFLDvrjGjfHhlO2loU2t4hj4YE5JLqxACLwSMcZP7ReJTp+qURLP1N157GiMItJAbKUAI8txtBV0ROcnBh8JdyYXZa5qqcP3FQrfB0HRWSWC3DWXlal44kW2tMfQdz/+pZwYhHR7L+1JpuLgFJ0N1iU3NePZDdXBY/MffRkz8JhsDCSK0yLa8hkshdIvrXB/gxS4pKbwdLUUkks3RZsLB++KOFimbC0OSkVVtsTtvvpIs3rOMHq1NDiFQghCAgjkDTq/t5wl7WNyHq+F8TpeBfTqB+so1RVJ36Ibv6BWN7+owlrLuYg+SPjW7I1EMm1wECvb+Sj9Y9WP0suexD/uqZkT0ku4goAttF2b0AU1QRtyrEPdV4fD5OtNqoEDWV3auXov0g6uJkva4Lv6KlJy3EFjOy3AvTWR3WX5+8bMUcKxa4Ehp348pfiaOBF46lMMIcWZWl5IIMQfrY7IkMuDxsjrbJy2FxQ0cPNTfrGlz/7BnqosCF2BFmIv7QuRC1HNsQn5a80IoHhGjlXXsgs+NN3Q1blDvQJBSETuB+bStoBpv5A9Ly6LpcQthy7r68815824YxJ+IWTSi3iUHFLdT2d+3s2UnLdLXaqrMt6bgCWUL/4vooYIO/GHU8/kFIbCKZ9kxixYOeMrv9caC+5iIDg2SjcR6XhvK0ZiDE09bkTD0p0/IX+xbYX2h6uVIgEcAdkLDGCKOl5V9aMSke/dhYQkbjSLj0wyWaLkRevSzKhJ2AYVOAche0D4UDTUFHG9r/pS0N8CG52SbsgR1JZyIMl4ja5kNZQJBA17N/YaIBNHgJhI5x/z6tWOSsKqW1M/U0QLCBkTFfl6KUk/WsgKZXqL6fFiOd02dDfSSyRZSqhELMD2oIjlz9soSDDPFaSzGbQS9lAR43dBuSeQHswymvUEAouYaoqf0mBEQ+BCS1oiqHOZRycFubRu1O8gu6snTeXiDwtqu/nWkcQ/s9SFpYI96loQqsYeC6kle4aMlo9/+Pb97zUmSc6BpimzIdrIk6pS9H/QrE7GTrOAjDEtqhbvwhuWafKTfMXA8pfcWTP3SwiVZI5DLxzOQcObDkUtUFozJpa5Ln8U6GNxFxnDXiiGj1VV87zyu8M6g9Hj9yNrV8A4SW3FtfhIc7A39U6A5GLmYWN6EnaLDoLKyOgJqUJIqLtzcve+TuT1tTbvbsKAl43Tr3UkTpz8t4FIaBW5GcOVuZ33kZyzJ/SWH5/N+msmEIWOxGzISvFdhooZEd2z+PFMuRo547tyTBOww37HZkaDSCnHKpZ,iv:T1sDL6oXItF2spTr4cbAjJ8WFdSHVN8cInElC5ZC2NM=,tag:OVJiimHRgHi4lJTELjx0iA==,type:str]
#ENC[AES256_GCM,data:ztRwuY0mTMDmwV5HqVR7Dmc+dCWcrVRtWZGEL1abE/WUcA==,iv:mmaWfHRiENJUGNhyUBFo1z7PdzVPH1OUZrVhkce6KV0=,tag:GKEvT0qkzTtimQXDueKPdw==,type:comment]
holocron_creds: ENC[AES256_GCM,data:2QXtXrN5w0UFn70GZOsYFPdtPwjLcuUdtkEam5aZ83N6LEDqPWJi,iv:kUS9pq5CX19vqHumc6QjY+Xpd4N+Ge7oCcQYtMFh+WM=,tag:IUA1ZVThF91EdHrwmS624g==,type:str]
#ENC[AES256_GCM,data:VdbMrwGKUKNJHw==,iv:OLwBh6KQXR/H8eRgp/hH8k3QfIkK/ydL735kx/dpc8E=,tag:N+v+ym6RMbvW4IckbiLK8Q==,type:comment]
syncthing:
gui_passwd: ENC[AES256_GCM,data:CicGIe5dT8lJVchCcE4wg3E8va3RYR8d53MISkE=,iv:8ziDDyQvU8ABaKKwYlcHmvm8Qybk4G+q5F0Ghqluu9w=,tag:YlyNPE04KD3detL1QUTrgQ==,type:str]
snowbelle:
key: ENC[AES256_GCM,data:MrAc4RXi6h4WOboZgBRjggPNGUrQwM1Vu5N5aPYBxeBZPi2ut8OApWcA9apWzYZNQTFF5QCtCpG9W+1CLJRG701PRK1Wf01r5SDI8aIXkgc2MjXuzS/y/WIqWoPK1nmtjxTYqaDR68II2tc/P7hgtf2EwYPV2JP6v6cCihADOKvXW1pBxi9kMjZGcbY54IyUrOdNauDvaZRgCSP7xtg8aWf1FlmJbiQgMW2lK/f+8rc/3OGS+ieFt35h29Khl4rhuYGB6rgTwvDaWa9g60rPzVcg6tKw+Unef99pA+CQnhVJJIejKlC07pCdqdjCUc+w0oQ69cVoucWeHqlq3xA7IvYIGi9K+OFCLmsoqjMe/wUSC/r2s/nnqbXsgVx9j8j0,iv:2FoZwwzKUky02Z34KRVP/jPhOMXnLZh841+4lybsbCY=,tag:ZL5qh3OcFjiWgqtmTCUFkw==,type:str]
cert: ENC[AES256_GCM,data:tvJX88ounzIzKmKcvEe0UtHrq51DMAIHGVZE2StqfNkn2QP+Er/geEh0wwmP9Q8+XBBjDT6oSAlWLjq6Tc1yYWSKju6Ig8GEJNDHL2UMVniBFzroSlO9hqZzbbNe1896WiwhhypvBoves7STTE7tJ2+Hzyss1BCYjcI+evGliJslq2nqxroMxIwBXfuDtxcTAeJ+SiKonY7W29NA05P1zYm6o6Td09VUS0cYWx2VUoP/8PMpeWLNciaHz8TjUeZ2Qob3pcNielu/VDqbunLvbFapqdV0hkl8gxgho+MmkC3+DXp/JDnG+vRm603wxqDECh6CNYc0CEXvM0/8gSXt6AkjATv6tBV98VeLknZkqVjBahtxrZuwquMuQbh1jD53RgsvnwB39FyFHZw29DGcUD0A7hIGnqSYVc2TXW+sgRxzXVFYsVrt1sWrYa2DpZT5zaFbps0dd194/j0SHOdf3p/4HF0GncWfTWLT89F/oAyJLio4X7yjES/DljgvmsrX0LdHnAYYAKDCWhZml3wSHBJ7Uvj1KiH2asxXkdiTPf8wulmwT+01hhBoX3QCkVYkdJpDbVddjLkwpLNyJATHctyuqzOdEMR4w5usTv9vKcgkMtbmxfWajb4lhjCpuaavkDUoI5h6eB8veXbZqAuX24bCvsLBWOVkg4qt1GGRqHx7+lfFanzMGyYYC/ufAXWD6eOOVsCjHJbHJoI16zq0HkfNpr30w+gO8hOyKgBP64anElzT3NB1sDi2GWxhSUKTDZ3rLsagPhZb3l3/u5SMf6lLWsY6IyFgPcVgY1snSOtd+PO9z9ipfyQZn4kKCtkNPPof8T58Qi7CP4KmVvbJsF67BH26SFclQLaJv5RO7e936vNwLrVhbyaclM0Vz6Y8wJvG4vW1Z4qPt6kP80NEATdrfwAr9nvZkb5rHqRWdxqIWSD5as+HPFzM/Mv0sBZ+B+CnsSv1btdB/iLacd032PGKXfZLxqGGOL1HIjM+QjSjaBTqrYcMke3GvnVfIujfdtcn9tOqGK+QYPS1CTYxWznmHloL2/WYwBY=,iv:qlIfrPxz7NvjkIXSkumfKvN0O1qq1S0T5j+37L8aReU=,tag:Qg8CYcDY/MaLWwNY566wBQ==,type:str]
yveltal:
key: ENC[AES256_GCM,data:unUnEeDhCqHUZCJtGCbj5rmrLx+9GiUTl75K3HdkI94YfCLNYCBACYu2v/7FbNIEsjVoQEA5/gKEcUHzVq6LaHM2w9GSo6tjkegdzTUgbHBJf4ssJ38z5rQkMc7tbzsA0NUHBPklz1eyjkW96HQPD0REcwA3CIc=,iv:PZ7vfhIpwPpMz4P04bewNhRuahmpukasgYb8fL/EJBE=,tag:G1HDyPAVSdm/fwqTXTT3PQ==,type:str]
cert: ENC[AES256_GCM,data:yLq2dNjdMiRj4reyZWsSqZ+1rw4DTwKBZoQHzeKb8YBn63ub4TZPlnOjSTt2DwOQwrJDNhsaeGscZ6J7rLxF/rtH6YnR8XxQuOu/NNIcZ4m9EqhsXyznSx4Q+0gamUXujRgGRVH5FNrfiFoqP3VuNghoX+NLxfX0BcVruEjbmLUWVVzY0yS0ufzxegM8WFAxuKhcr1NlhBU65TxKUtbj4vcByzWHkfLGIb5ICnGeF/p9/FvpFSavw3nLdybDLJ6EKEeaxy6t984fkuotAvk54kLbF4yt0q5mjDxy0U6xtn1hg3x03IRAPjKDRdpDmzYf4XxykEb74JX9q2zjUhb2l1ORWcZu/uKvEiuZWDJRmJ4ypOiyZOCqTvY6s2iDhEjmMKxlNr2mhuz9Hn6b3KoQjePIEd1eS/VEmo09pEuUlhlAEziVcdnpeRyWlN2xpv4ps90gLxJ1Mj9nAZwRqFOQl0V4N5OBHEqMBE1nQv4afMpGX5QF2UotTpNfka+LdKwc1iHHtpHZYmG1/LVwz3jDv4XnVLdDWojFA/8eJIWVq1BsUTYSy+Q27bsoTX4iL0Y/OAHRzXZTqYc4aiAWJoaNTNgmagZ9C03SA6qePlGe/5azI3f54rC2m1/JDUtYW3IABHSFUaVnTdWnD4GDNSYRJIknyUwXR4sE3pRD979prmgtepOyETOAVgEeUVKz1leJZ2HyyhjFU41TL0IN/sl+YPD9bC3Nmw7OsxMFGPC4l5vn64DVp7HHRSKyJvZ5fG8s4nSzyZAKomkocOpKHEuQPyyerZpL1lne/m2B/y7/W2ouAGxcawZOSU6f74mn5wM=,iv:Ggag5SNUFkhMWS0u1kwkD5tGjiMv4i041bCESl5XOdc=,tag:pPISz0eBWzHcPHsC8dVG3g==,type:str]
mew:
key: ENC[AES256_GCM,data:8i2thp667lKEXR0cIaEOLHPXWlhFS38FvbtHgni3i0dTBx9DYtJbGogNaWMlA8r2HzBHkG3Jg0nJs7IOrJWugnGLNLbvhdsxBswEndOBaed4vq+SSN6ssxdjjyFd38wlIZNZsytjPFhyRgDLJ+0rftcIQXPjBhU=,iv:IZ3zWD/ZpalOzSAJQubo/y4LcEzHMEcl+C4GB3Q/nac=,tag:IKEwIkuvHE6qrUoCEqI2Ug==,type:str]
cert: ENC[AES256_GCM,data:uvNZYmQnexXTr/Sz7vLQIJK93MmsoiJfCAL8/rLVQH0D+1nVaM472lqR5pP0qhLKuYhFUESxhAotVtqLpOWK1MfAxuk2RHv8mvbtIJkheRmsIWw7dAAABIkmgnelI03P2Tk2129I95vMM1lybu4W6m9VslwJF8X/4rCxshdbuz9mcjwxBpUEDr1V76DO3bgQUuPwizx17ON8gNd+NtRqPPaXlGrfLCFv1Fib3YFd7+WRkERki9ZO7Q0quY75G4Jseb28QaiM2BT7jfECJo4x7rMePMV303sIrF9paaUKTuSiCUsamLsi5Hwr907y2lHB9Gocwio7tnSRSRhHHcWLI8dQktzW7Flqs8+MZGZ1oJBQO7kQDefF1q4mddADimoqD9F1NsOiOmqqZRRB37alLGmRjeYBIlA6q/FgN9BAj9h0cG3oN1MUXPRGzDfggg5TLjBM2FbG/N3xgncZ2AzTPOcLtrtc0I2PYk3FFxgzpHWnjS2t7CQo/JxqdXbdy9nTHIqbrnKIQ/FtS7/p+cgQcU815UMsJm3qP+hPLCyNuziYq3Vt/X7C3eTnrqemXjEeJ/SJxb+Oul5GS1OL14dNsJllFNuj33Zep/hyQvHnf/HW7kXAfDqIP9zn85EFriAZEuaKwbHB2pkvbWKFxrpXJFhjnPFDKxGOjAmsLmil4paFKdt5hK7rp0mmoIMN+mMFbYx333llik0qk27yYTQwOR3eeCGqHODUU+izUT8NuQBezyxsEmEYu/YBcpatcYylwKgIFcC058oltsxlbxRg5Rrdk5FOqj7Uui0qwFXvYesz6Tiq/rGmcOPlcE5xw14=,iv:LePpzWGDTV1ONwt1uHUptMW1dO1SwwUKrtCEerc/DEc=,tag:a5B/7hmIxvLXU90Stcq7zA==,type:str]
#ENC[AES256_GCM,data:A0ITyGOGMIoyVOcn5JOi1RAtqUM=,iv:+wWpmFbeLiX/Ae53pj0QmnYY3MEzOMib4cqbePUKtGI=,tag:JHXvrN4bOH+oD3Q70pUuew==,type:comment]
pia_auth: ENC[AES256_GCM,data:rwAu4f5XVS4v4FCLj2zXAegIZeRPLIzUVv6TCrdfg9RGSDJYHgVAX0aFXCBQsDQju9RDycXmc9Id8IuyYN8=,iv:kEA4ADQyUI+zlQoZOKi81dw5BLE1oesqhVf6bfiLgB4=,tag:VHT2uPNW27F3KRM7ZhWdCw==,type:str]
#ENC[AES256_GCM,data:7y1mtYNfbsagqtr66kOx2rinneEW3EZaCJIXzK0qjLX36g==,iv:8ozXuBYirLbKd8sCln2xv/WjhTojY85xU0cL5NVeMlQ=,tag:mclz0GfQ9j2EGWMiQ62QmA==,type:comment]
openvpn_pia_mexico_config: ENC[AES256_GCM,data:59HQ3OZ0QKq92jI=,iv:DZTNvfi6kLXG7dsNkPcXUmXhAG2UdPZBy/L9eWNmRdE=,tag:ndxDDQNL2z1fjxFfU2VRwQ==,type:str]
#ENC[AES256_GCM,data:mbIgMJBhL8nWJzl8q2dFL8XtO1Xa1Q==,iv:caYHYp1boK9wRgCcQe40HTWT/HxAIvYe+HyaruI53Vc=,tag:S6wowhAHObEcs7z8FimZ1g==,type:comment]
wg_mex_key: ENC[AES256_GCM,data:vxDXixo6X6D33+p21L4hB0/yCH+TvMHZl991BkRsE/jdz7rzZuJF+zI7h+Q=,iv:8WR+feHXNUcat8DB2wY7wpos+P7TzgRF7rFD0fYosjY=,tag:p9b9ck0/VZjyLxtHut3n5Q==,type:str]
#ENC[AES256_GCM,data:3ATkokBKeOp97uORzaePROrKKfG94ic=,iv:MNJRh6Vrso1heqNUJc0M4xGNcMLGwcF9IzoiQ5+SS+g=,tag:xj8Actwkirvq4GE+Ly1M9w==,type:comment]
vpncon_mex_config: ENC[AES256_GCM,data:4i356X97sBoRliskmh5ewcEwZHkpo37IhPcemKVdWJgWFWtA+AhTeEo4KQ3dRA1H/n8VjVX7CKZKPDxpmHfcUlnTLT0agtOjjyjf60kWoL8noJqcbDB4wGiYT910rPToVnYMFk0H2lerYp+/n2bhg8BHxn++VlPOOZsgla4El+FNXUqhScpAawySPSF36ocdRJ3r3DuflIhnTBXxSZukMf9Ux1uaFldSG7KasCQlStKy9O2Odd2AvAuGXOHch5KecRPT3WnonQ8oDJpuxbeaosLmtJKHL9oeXHPId2Unc1GNoOpnDC3Y/xGnrPb9WFXWYOSQ/1A3mNKwnVq0FEhluVbqodES4PVIlCS0koiQJq15P15G2z0jO+OhAQrRI5vn3Fki5A==,iv:tQvTpzhl7F7niigAXl61FMHbg6QqI2R7yGD/C2lwOR4=,tag:c+CVLd6lGrAfm38pFXOXTw==,type:str]
#ENC[AES256_GCM,data:CO5nrcDbgymnEmCvuTexOBEMncuNM5lQ,iv:6HrxqSN6e7ODuz09MIFgPbIqDCKQySRDaKk5Wdu4HoQ=,tag:JBRjZeEdOg+trohfanO6Mg==,type:comment]
vaultwarden_admin_token: ENC[AES256_GCM,data:G1v3N064ci0Fw5EtTzaryailWpsv6f4w6eoHp2vjXIBtIlScdQk1Q0W+eDNRk8Wr2C3ysTXQNbyYismNsls+jeS3W+YqkKL4fnh3a5UTzQrMqvaH11n3ak0X9R9vmt+ZJXBrUrAOKJ6RPHJJSWenhjDB77kwEdQ=,iv:f8X+x/AdmZ3b3dtcSFrxGgA2tCgDRpgddjlVu3mdCmM=,tag:c0MXljVvhwOdvrb/8hWlsQ==,type:str]
#ENC[AES256_GCM,data:2ESzSsQZqKdjD7OXN8ZPThj6g9acJREe,iv:aDFPB0vs8NNo8ExLcJw7qtQvWbCb1XK6TJrHSK86qss=,tag:z+dypHAGUjEXP7Y9MHYWwg==,type:comment]
gitea_database_password: ENC[AES256_GCM,data:nhFn0/G7gW5rk996OZzlcTt7T9KMbP8MNM+ReFC8w1H9ZqBSJUbs3K+n68uQVrkOVSXE0cKpOR1VbQ+i+46z3g==,iv:bT4GRZZ83v47/EmeV2KaUFo+4qTT4T2AktFUpPiZdF4=,tag:OC9TInkAr1egM+xnBDizxw==,type:str]
#ENC[AES256_GCM,data:HJ81OxRD2xtNZKv+8oDqiT8mYpv45JMvjxU5pdmEKzl64SK3lQ==,iv:wStoC6XaZlvRPfbqti2CUbPrOOTt4KktaUp2ecVrggU=,tag:isOwKfNdQZAM+E8YQXBSFA==,type:comment]
velocity_forwarding: ENC[AES256_GCM,data:MUNhW3q0/klK51k3,iv:dGT5N+IrZfBxMIwa0mUrIKF2HJvx/uZ5o/ps6bgDNOE=,tag:KNY2LKwmmnCdWqRnxSKctw==,type:str]
minecraft_recpro_db_passwd: ENC[AES256_GCM,data:dPAkdEX0hBigo/lND2r3ShxnS4Jc5wTI2ShcKnvjig==,iv:WjPugYspUvhy6TAh5UF3etvxTZjAPe3bkgFxIkh6FDw=,tag:h9LGoxp2x8PHxcP8fEkSlA==,type:str]
#ENC[AES256_GCM,data:nbB5Cd7i/KTMCjCzcX8o1sxREZQ/gLAG,iv:iyuO2erxdJM08WHJBjKuNIXYxVhH7rfyOLTcGCcGqNQ=,tag:UeDszimXv8kQUmDetLeFqg==,type:comment]
mosquitto_hashed_passwd: ENC[AES256_GCM,data:k1Lnr8ZTDpzXMoRmRH61X41boX/D8Rm1KPh7x3/IHFo+XKIOUQns53iA+7e7Ohp8uWSthDlOk4SlRvTXdUNiEz7Zmw9LYwy7BHbwpNo2pFApAye1ORPrMrhMUkUfgBgc8oqPPyRXmmrOAFp6GBbRhg==,iv:D8wQL9iF0rqOte5X24kDTVjYUJXbZSLz0Ykbp0HqmYo=,tag:RUCgO1uKPIdumSo563cg1Q==,type:str]
mosquitto_passwd.yaml: ENC[AES256_GCM,data:9xwHiUaQ6zG/4rkRemXtbRJ/KEV4yajqyYlcXRR1eAQ2XijYOzitPjt53h3FPqp5rxl6dJerXNH5CiZZK3t1l339NxNseJFGVmIHitWJxNmGJMlG3M8r8Q==,iv:C6WWZuVkYaasB2pol3uf4Mc3d/lDEgt2pKX+dHl/Cr4=,tag:jYTC6RKF2TzDSwSUh6D8zQ==,type:str]
#ENC[AES256_GCM,data:zmSByl0De3a39qLbS99oce7ORe2BBoPa+3I05/YYxL7iBeWCP3ZK,iv:6nUTBUFpNK7Mttckqu6Wk/QJ5cP4+iL+EH4ldaIuu9s=,tag:pc5UtjbNPsVOEMCdLKgGMA==,type:comment]
#ENC[AES256_GCM,data:ZWlAWAthigdTlfHrQl1x8eSj+gv4Gj1poZfPViu1mVz/ZmUJFZyCSkdIg0CPdNNF38TE0iabBk+o7aHkFmIFz18hjVYAk4M2E034qg==,iv:jU+2E+XAILgFNyMkGZ1CMJ83q7V/yyEJwHXWw05RlHo=,tag:n8w0/ktmum5P31vMWJVxgA==,type:comment]
postfix_passwd: ENC[AES256_GCM,data:3ndIsTGPyAQELM8lptBK241a3p77fNijXma4souFKnyrkLBpZ4OP6KWuldFlWySpSG7Yme0by5gOzg==,iv:nYuJKeY4H3OfQleLo7gvheT5JHgXW3hGQvjHeEEN260=,tag:q952E/0QLC49O5Rwua0RWQ==,type:str]
#ENC[AES256_GCM,data:UcpnHZj5xr8P64PzhWVKbFy8pvFM9GCz2mDoW/6iRVqgLTL0FSn6KXep/kfLEnYiqv5ZpsVZjjXsbI5VRJfBo7w4kzX661oDU8323DfQHDkbo2g=,iv:nEApgutl5kjfZkwi9WTOwatraM3+TQqFgk5gEMw0rwA=,tag:Q4gndL+6q7jHN02QCpJDjw==,type:comment]
#ENC[AES256_GCM,data:3oMbbBSrbjrqsdiON1ENB8JeKW0=,iv:+/eL/51OA+VHbkWWSNzQId5BlxnMm+5NBA0uKw010Tk=,tag:vBJpCYmvFivBYIKatDWgHw==,type:comment]
copyparty_passwd: ENC[AES256_GCM,data:I3UYy4nJ0B6RnIp661O0VVqEmxloxxcroBKmNFcgoQ==,iv:sWkPfKqomrNaYFZbn+BeQEugRMlaqi1qJhELqfsGCik=,tag:Sgz56ZW9EY49zfwFDN7whg==,type:str]
#ENC[AES256_GCM,data:3ATkokBKeOp97uORzaePROrKKfG94ic=,iv:MNJRh6Vrso1heqNUJc0M4xGNcMLGwcF9IzoiQ5+SS+g=,tag:xj8Actwkirvq4GE+Ly1M9w==,type:comment]
vpncon_mex_config: ENC[AES256_GCM,data:4i356X97sBoRliskmh5ewcEwZHkpo37IhPcemKVdWJgWFWtA+AhTeEo4KQ3dRA1H/n8VjVX7CKZKPDxpmHfcUlnTLT0agtOjjyjf60kWoL8noJqcbDB4wGiYT910rPToVnYMFk0H2lerYp+/n2bhg8BHxn++VlPOOZsgla4El+FNXUqhScpAawySPSF36ocdRJ3r3DuflIhnTBXxSZukMf9Ux1uaFldSG7KasCQlStKy9O2Odd2AvAuGXOHch5KecRPT3WnonQ8oDJpuxbeaosLmtJKHL9oeXHPId2Unc1GNoOpnDC3Y/xGnrPb9WFXWYOSQ/1A3mNKwnVq0FEhluVbqodES4PVIlCS0koiQJq15P15G2z0jO+OhAQrRI5vn3Fki5A==,iv:tQvTpzhl7F7niigAXl61FMHbg6QqI2R7yGD/C2lwOR4=,tag:c+CVLd6lGrAfm38pFXOXTw==,type:str]
#ENC[AES256_GCM,data:ep/Z5O6RNFwTd0I5hvtk5DP9,iv:M7sclKcTR+IfCEsvz0lZaoZBRZlQsN/FhwuzFNXgVew=,tag:Ddo3Qf8tMBX9Amt7C9m5FA==,type:comment]
klefki_pub.asc: ENC[AES256_GCM,data:lGfgwhgn2xCb1cNTo0nMP8R3KSDiEn0/k6neDE2dv1DynvXsHWmZSXED6VWBjY3uMU3YtcpXGCtxTU6EiaRKiGnhxslQlBiSypAnXHeh55DZJMJJ/JM7+BCtr33LY2lusF9/aAuKO9tbdpGmu63s5ItZ1/9zMoCJwBfpQZgY2HzZoBhjwqYu2wSkOOVAMjq+jXET7nASieOZXmpQq2uDepuEDa8MP7d6G6kV2KYJPdLYYaY4U2eppEr7ALhhJidYm3P38W47JuLyu/2raG0AY2uDtCQw9d16BcJO3au+T4B4mHzPg1/cPhQ2X4dHTTGHjRZ0sT95DrEYYmcwWVKHKyiuL8WPtQmF0QBfCOPczwJajJejB4DbxEW8U2kuhuoBWr7wZe4y/nbW2hB3pcMYYXc0EXen74IttiUrvksw+hbkLaZDCJgG91SOlWSwI12UlDrJJSzOYm+ODWqK+bKyqAafQTL9xh5heM3nQlR5G6/A/8UG+0q5ZDL+IxJwe+EffJNwrL1mn4Rc3qx068udMJC+qzmft7Ljey7mfoIiwepITpii1IA/CtuEqtpe4I5MUemQ60qAw/PoVbmD8zhOcnRHCBZtQ394I5vMo1qR2a4KeBICexx3IAjpeAQYI3+MAgo/bedqpklLYjbxpv37XwinoLj9ew4hKSjAB1wRRZlswmk+GD4XKlVo8eu88RCXYrsZ2oaOD4qxrtbc7+skGm+EqxL67nLW5n9bSC2u95bFJ1386teSFhsJL9w3EFiBlQRtm5tvee/ipmr6D2W7SyfCnSxImPC4TgTwkAXziQ3XtsUtGqj0Tv1HGayaAQpYzlJaPzf7h8oanH1VaA+AgRq+RY1OjLZGHEz37jSbqhWOiIWxwJ7qFaqGB90cHq3s07qcWrDl2wUawFLTXavZ0IF3gj9KnFSIzW3+ANvedUCXOjai+zOKmpxVFZ4Bi4W3Dcbl9B+qa0Ly0NIgldi7PmqEvL3V4FnJs6WnwdagyhXOzdlKVlrAgGluucgqBpBZZfpN6uB+tdkbrqzsdMbr+H9Hwk3RUxRzAK9k+J9WRgY7eMazH0najJ1PYh9/UZJf0DKWRi2vZTlWW+6ZruJWTohOKm+7MCgvMEttIpNQfvK6+cq7p3vwPe+pmq0DznNg4LO7Uu3cXKq3zHjl08KGE04KZyfoJuZPr+XrF91AywZ03HlT2SBBaZtFld1VapccgB5DqgE1JfFg+TS4is9a8G52Ad9yh/abUmLohsnUpGdYMaj/1FmhSLM7ldHeub8CmL2vKW4f/JTuqmOxq3X5RA+qw5f946ekUz9ZF8EyGvNwaRZ2p5m0MtXQG2IKp8Q61aBSpqbMwKzTW93VycEn7L5ZsoV5eYo0rC4PMawGkfgdNzBpq4NL5bNB82l6qHnWqU7jXh611/ZV4ueX2MLSB3cyhnaFxsH9bat1jGDtUl5umNWNtvN6rWBVsClmYfBLSUCEyftGPlxzAOy6vRHGxAdCNdoiTRGgZru3aYyW9l5XhYH1aZ+dOlTOwngaqqIb3kZoPzcc9xCeZ/I/N6iVuTUI69us8y3LVL6qKa6az5zTTgumoFB5kMugPtumS1U9hzhLtm9+hY6yZVgYredgAwVVIviMAqFFZztFkPiskcwIdrPhXzoXwfuBWDaq+dF9nykjw1F9U2gyDU0YhEOtSmdIWoIma3OmdOZ/h/JbWNrwUoAirmBmWIHQTmA5Ag==,iv:btQ5xmt/AA9vW1njJH4Inj6YmOBx6pGbHbsvCMbg7fI=,tag:DuQ4Wy9wX3mPQAVLLd6t1Q==,type:str]
#ENC[AES256_GCM,data:7V0L0832xewUXU8/Bq469w==,iv:9bCzEpUcNx6qnCMomFweXgYmWwSMzdffDikjA22xu6E=,tag:F4S80e/EPXA0tS20KFRbXw==,type:comment]
id_snowbelle: ENC[AES256_GCM,data:MAw5R2fqVIctN7fB/d3hfCU7W3sxvuy2O3w3n0vD8FxK1DAhqoROlVv04joV1a+U1hof57TYc1cN2ng9BRWxadc8ZIpWakokZYVI0dUG05/hPMyxctWPkOiDd5909aaNUFC2G+Y/VrgAemyrB+AlQgokV0U3fiz+qjg055fzO7ypaeM8okON6rBnigfwetmSm60MxpdYrVlxVaniDVvKKUYZjpHU8SZ+TYj6Jmm/bVuKWOJ2DXZbmM0CeKeIgnA9HML1wSXojMv2IMGulxq5mmdaiiJTPoL1q17OA5zZkkVW3Dx1y6SbEeBAQTPG32RHseAxXK6qdU6lftRQZKyivuyjdCVfBBw/VzqTxbWjSXXsjDdK/Ti09051w6znA1uvRX65XsOq6zPKt4BNwR+yMDF+xR9AElBTHES/TDf7TRc5YDyovlH2PhGNg12Coy3zfb6WESLyaz3/GYZxF0IjvBnDkN65CRjstut0CgKXcWY8x+CuKVysU+U4c0A2ucDnsf3HuITrdIufhAwRNNZMka7LWVsaaR/tnvcf,iv:agf/LEjohw1XAXsOJJ78kiBVJnTT95IUmWzYUujSlJI=,tag:a55o9L85a9Z7gG9s5BEfIw==,type:str]
#ENC[AES256_GCM,data:ozhgyE+IyqR10KT8vI9x,iv:+ZOTucRlCZRQ9ZbxZgySPMOJ/qU4gXbhSyLAMgt4QMs=,tag:mQ3X+dqCet1Yk1gZ5pZ5gw==,type:comment]
id_snowbelle.pub: ENC[AES256_GCM,data:rQ32bqwknbVssJDN4TW72YrusMPQJRFTfpoH2M2ELsAf3DkXtchGwOSjEbeR9ezUgHkTD96rFm5JvjDFQukAOpBHfMP5aRVy6RjTtb8j7aAD+EGUEpBSAVspZKQAWAqyDQ==,iv:8bEgvJgWpu7QwsrWhkjUw3GtRI92Pn7TT0rXCQ/i2Js=,tag:EnUehKMncN5v4dZZ/es3Qw==,type:str]
#ENC[AES256_GCM,data:lS++LQwlDVP0aYcdaaudBkKxNB3P3UBE,iv:UqGcXcX/Jvf60o409Cxj7VJCDh63uUxy45PuZbHK2l8=,tag:OXdMwuJwdN8DQaLXACpcRA==,type:comment]
ssl_blakedheld_crt: ENC[AES256_GCM,data:OPrDCh56XdRLslAcx/vw9l7gvc42no+QzB9tVSLHtcHbWWqb+hefvAE6xnfMLlt5+BRuAJRvspA6kx/WfagjFuN7q3HAHPt/FcfZPCYZNT5wXZH59wtV8JkVtLKnCxqSUXrah9a/WrHkU7njzoWql53eoAXEt58mvxyxZihqZd/uwinZt/T4QsevmikIsB3LB7AQtUHfsHd13ZFAaGiA+Mnncdl6Nt5s3U4yTuUxhfmYwr2cuyL+Li5eNzdO2ZooXBySdp4Ym03rpBERuh0U8a7NNj5ZaoHW1f0AyFRRKQ7RIHHyhQNC6hL2eGqsv+hTkJCJKxOCYKW1cF9rDt6bueKAm7zk3RTw0Sk7eXaOoqulCf8vBcMf4ckfH5mFVUpSHuwc4lfIZExjggn2i7Bu7xGIOLqC1RL4S5cuhLGUxzgvCiKMcMmaZZcT+fZa5wiHzv2vaCzXuYRb1rNi0xoiAZcL65yIV0NGtP0mOFygdY2hI4R7itbcE0MGIbwdOuWkCRs19WVFchNgcV7GnZBUVKAbhFXq+GilWLufODJr4Zxc1NpxRjG4flWQl3A3jGc4+tW5Infa1n6XPmhHz6JjyPE2mVbLq4JORPHeMcN4Wbckrmio0ruJu5rV9J95HYceXJIF2dw7AgmaWEX67JCHJPbAg5n4zRrfraeMwKB7XHTMglTLbyQsw7zkqzGDpT6ztOn/uCtErEmU0LSlIcOzz8WdGnnWbReMLiUfrQwuKvJhwOpcr9t+FVAtDyjyZhL/PTDy4/qIjQNPwBiVMKzv1CV/eA1WHcYKb6oRvP2TAlh82mA5uIE1jqY9QXg1cfMl2ncnsHnv3d1iFHy3OxvmWwvve+1zzJ2jubh+1ZwKAjP/9UEq9eldyFqC86qYKYGXec5j4Q4QGrMN4AiObVI/yDnRdeWal8jM8p5cz56rgBesDX7/ljR5wjifdQ5s4Iao2exPrHAWtiJHWE1i4R1g4rB+h8piu4feZXiPh3chdxrUrxCaQK0N0nOkN6+F7y8rbd6egk9Q5xvjNlJGzJGiSQ9xhDYmnPZtUTWXL3KioIPwy2/yh+lpkG/JrUacgc+HaHO+DsXs2NhlObrcswo4zmZ1eEckwFSpl1iP5ABHTxNVY0V6pdj1+7YyB+wav8tlVfguyxLf8JV7dqVnADCV+R5D5rBikmoJdjgdZwNxO0QBaZFVLeaCSgoCVEfvSPFtL9cMnEhLhdtw+k3U53+JJYemRfdh48DAM01Na2b9q6Ey2R6YrqtONVIauMNAaKXOeaJCxJhYVBqB8yNiAOOhyJ/Wvzq/CUM1QsXHQvwbndAxmyeFc8XSo7HZZME9m11fNvcEdWfdm63BpwkrHKPzQc7sR6tKeMy7l48f1baPTNoevEd0vFeURHoOggrnyBeO4q8YdLCderFmsSOzyDP+KjDxwTE6u+4P2xMXfnjwTpxLZInV+sNPsgaMj/bBeOJr7m6IN8N3/jxgPiBTGMObiVCIzhXL/VP352xc7Vbh5ZjMvuXQIPWCodPjWV6kcK8EvanN/l0vbDh1MxMAFiqj6tRHUfB0Px0JiC263kR0vzEDI1K6qEfPmPjA8TiDo1tK,iv:qdtzMcF1iELnhrCs3SboRcAsnw/0WgcUpWWHzKHNEYc=,tag:TkUMk8Wp2OTQd8CRtS07Wg==,type:str]
#ENC[AES256_GCM,data:3G8XqUKua1QgUxv2YJkW0fDnQPX7+v8GDC9BHg==,iv:BkESkMmMalgesy9why9eaKkOOvwSsN2EhNCRRRmZNtA=,tag:x95zt2B2M19BkzeMpAlXIg==,type:comment]
ssl_blakedheld_key: ENC[AES256_GCM,data:JCjbKYU6p7CTMtnWotZWBvW7vmLQ9MAP3bejcOteLLFLDZfmNguqA5h/8s0wLbjGnbGiNnupkvyWPCkC4xhO+fVq9Jzl7+YPEZn3uKjG7vyLlbVhLsmv3BleR01jddEJv+2fn2QztP3CfbocPHm2QaQhCqgfxxvcSpy0SlN3IOKckQaQB1oDJB+nHndPLN5VGwABE+b4x1AoYltfoFvNiGam8xXu31ENOz0WPVzi0Xmw/noVoS627BK/P+ISC1KP/iGuyRiWVmF2P8dN2oAtUarC2JV63/HevmN225pszBIyEeDta2Wv2QCNBYzUsDr5NA==,iv:fPuepEZUNjGWekTCfROyMoPdsioissEqvR2gZu+2NAQ=,tag:fVPI22eUYXOSI2A/MSbsEQ==,type:str]
ssl_recpro_crt: ENC[AES256_GCM,data:CiD7qdfWzi+7iA7qCD+w3UJdpxZByk2kmpw8YW7K3C7ODuSLXPfw1tLLunN6S77M7hazgvSDVsBEOWlS6plACus6iHmm77yvpzwScv/sTpvWiMpJDmX8svrr4hg13eXSg/8h4Z9DdyxoeMgF6CWXnUvmbgauB/CRyaD9PzeKq6amL8EofneueJ0Y/1/NCxTX6mn7XJHELev9s6yOwW2nICIT3jnfpoh1M2rg4c/Ys58od/iP/FBx0ahBMHwyw4n57Jmt93xAFZH6YRaDfU7kpf3JFKXBTZ5+penOvUjtEAJzDhzrErqkPqOensWch3T8n1i4ILIqWI4myYrncbeaDl3/NuK2d4HOEiqVu8RcBP2tbBSriiDnoO8/0JQrkIbVvxEhZ8/HWJp73nx/Y9Khf0kh+y1ulIotNvTwIAgvPntSQxlC6fZWPOFcQTsZoKgvR4NiBToheqYrpr37WHAQ28BhnxVi93O2t20W72sTgGpslmpxGjuS6/OVY2Cs6HLznjnbzW1DK6QNu35nHRIHk9xgLsuKf9jFO05Gjo/ePGbJle24mLAbjZxYV/jkU6+w3SuvTK37Y1YBZ3O0aVyqThE9JeRiQ0Xd9gUkt7BtEq6rxrMByYa3S5d0PiCXsR2tlntkjVREJHZQMzsIbsPyowiD2wdGMFvjMSldQVkjrNaH4eKlc5CJpe8/7xbFeXtU1TdUA1aaJlxIMrExX5kbJj+qoNxJyymtQ0Xs+G330aAz1IIAswbrcx3KakajGKV8XzHugyqj5tD00MQYHakhWtlm30Iy+MsNn7dUpApoHxwgXfzH1T57EUN5yaR6YDgYvOs+guqjQcf/3Q7Fqd0IdR1c1aHFOiKDKJ7mgcTRr/Mmzao/RC5TpgU4IEiAB2Xinhyu+g6CT/I3jetQzsC80Kc63oXqRSC6sWURQyQ4UxUtGET3wZ6Uq0KYK8ce+Enphj9RPA29XmFJu1x6hxcBHAyZVOawrd8lTpG+x2vxJ1wAyjrUwpKKVLlToHtzCmp5UUEs2MsRd8fto+NKVEMbOSUnu3t+OHf9Cak4mvj6QFO6Q506Tp0btlPtQMm7MZ8ONFHBRWZTDIH3iI8eiGXqfDSnVDFMoDnOLaK4N+3U39Qtpc6QmN8tQ6K1af+c3+4YQHgWK7zJw/sfIq9YZXn2EV3r48daV5Bf+rihVVy/tbhZxQeJAJC72tWF7f2qQphocPakW6q7sZwQ1q5PyzNBgVeLlIAbbaLZ7oq2im9Ateobc27aApXCLIz8tbxDyOKwSCtRG+63kXZ6Mgiv5MXfHKHulC1rTHi5JA1pN1lIMe4ML1GsyqJSutJ91rVo3/skk4RNSaJUsu79lT3U6uIzBa1jPcaPaxQI6tlVuxUabFfU1Lx2e7EZMFT61b6XRhoT3VRPvJXBsNtXayieKPMcvY2i1PNuL8XdQOkzNPlj1OkigLDGrvyVHKwhinBl+nN/KkKbXaQ1Mt6OZoXVvzWggGYgHgDuyTbJa1oa5HnszZQyzhUhewHbSeGdE+FRDZigWEqoYY63UdlLc0juInSSkroN+vqzsCeQ0JspIEBcUPwNy9DH8TrKfMJyvBdSnTbchwKjC0zqjW2D3lVAAEIF1mdBdG/2dDacbBp3BNHpRu/cLA90YTt8NtNq//lYRrGO7eCl1vywuVjjmXbLN5aDq07HkJCi2cBtsp0Cioqd7Wblmad5iTcdBz5jz3j8Th8KA6RT9vxtXHL9WN0gKpdfx+WsDy+ww7D6erTUuz2RzHHxFEq4sqp2SGiwj4/uADdY9/SOARqTWbhdiq56xm9BzU3hm8R48mahHMKW9pjoUODT7IA62j4guHgtrEMwYPI7yXdvGEgA4Vx7RiW1C7xE6kiUavONoa49sLFsxZCcfldLFQYxrxEi3HIN9dzQu81e3gvPzPbHDYxe6enurrl/Mg0n+3yJp7wIYt/lzjoc3sO+XdKTXpmXfqEpUfrjXwzadYgAf/UJsgnKAeTDhaJ5Si9rQUL4vxjSKCbN2mAEaxmvQkOeKm/Y86QvrTqu7AmR9gtw9nflgbjyWqSX5OOnjSB3ZCSQx7WmBY/ri9Db7xlDxQjSH2PBhhh21fh1SHbKiAbl6M5vSduVwxpfb0O7l5TrzF7fMl7EWQufAvI4sFV5t8HhRXO3xLRhoBHZOR0JkMrvZcPHlvsbB6YfcbTCQb6RePnxOoOXwcMkw5yZVA==,iv:5KucKtHOeiviRb8AIhF54CuFx/RxxYifrQP2vvIr0zk=,tag:r5pvRK0BAO9nkgFPPUSMMw==,type:str]
#ENC[AES256_GCM,data:3G8XqUKua1QgUxv2YJkW0fDnQPX7+v8GDC9BHg==,iv:BkESkMmMalgesy9why9eaKkOOvwSsN2EhNCRRRmZNtA=,tag:x95zt2B2M19BkzeMpAlXIg==,type:comment]
ssl_recpro_key: ENC[AES256_GCM,data:ev/g2sKFia5xcgZQ3LsfT0H9AaShYwxglzZadBhvknzFVwWxXGmGfHgKD6GM01fCIFOpB2pPGiiOTpgBh2xoRnPmivsApWoxxXgdVfzEEVbuB5pHAJSHWX5EUEqeiTz83zfbJAC5FZFwlIEQTL3YiPhRzKRWwEpMyYigsZmUAv3970XlDTAxDRgaPc4eHFI2ZrEXGmevnBoHOQPwXi+JCHqSCyhbPnsuU1InIcp4PMlX4/K+WknDT0HaLonIVXds237E8lOCJFAo4Ow3/zHho2B/tBZeqcHHf4P49SaSEO1CSCzTrW+1N1n+EsPo3PPld7AZ3klnsiKltorO18GM+2L9KGg6LbTiWm6FCOk2bMIFg9q1b183SSzeDx9CzhoXefsweMdn9BFBF1BVUObHGgYE0dpme20S43C+NVTeVt9+gjOEYysx/II8m1ui0UzpW+kYRdMLFjepYHlIZRA/jUEfdVssqKsX492n9bX5TRPc/9LN/o6oDg4CZjZXPILjD+Cg1NOW5ZSJrKvbFGRVNVeVlC5+idUqnaKP0Jh6nG/8niEBIyV51YGy6/ukruHyjMiH//iG9oE2xfLwjQGTUKhERxYgKOnisHkH7b7feTQBq926BgtWP63zchkCYz9sQTh8LzmfitXEBYUpRvDdxlnZ7m6I1ssemY7bFCnx2rZEpHRg9LxDG+UNgiODwm8YvXQbL7z+DPSVzG5QdRbhlS+deYMjquLBvWpMfUrJ8HxurLyvcZiTRqRSBmhlc+08Y3/j0RaSfmDdtId0HGKvokSoB7daMpgfKeZs9ddpvmEVYto4bER0Y2xfumgUq/VuhSR/H6KhuR++8JSnDZxPS5WtoH3eVOXrDIRKadiwYzx1r9dhek55iVLZ7uF/YGhxS4DD7gFsJJk8/usLnu7PM2UsoPhfhg69CrigFZRa6I1qdPSon3ODYxlJt1KVLgyNkJqjG06t96i3NcJaIm5tZNsGRDKrU8Jh6EiSzCquGOy4oblpE7lCdK5mlHXL5a0WRiaWTUqo27qTGT7o5jskXHQw8X+/iTP6LO8GpDcL/YCpF/HpV3JiuHLifJoV3u6Cj5qFyCfxF6k7h1gXUZxdMtovpicbzHeJS+4pAnrdR6NmavjlBKDZFRa6cUY0011ZuA4HYm4SdEPTCyEzOLNsmx4iwNao/jH1sPb6hQxfQrI/2xbKJYLeGJBDagCjEOB+bo1sUaTepDVSHAGUVpb6ZdW98AUs+zOiKAhE19H1NRuRRQcyq+6fMFh1+qyIoIELiJNlKcTjv53r30gyvnbz+FPLWqqvskZhRnwrF5JFFqwZ8Rkt/sS8TCQVT3ZGfOHF3J6yApb9GKQVu3D45efUePaPrGHVtWdJmQRVpQNKDAYoxOWT6yMhHH96juDh17QrqSvD6M+NqydP2K4q6zQE4rfSkTz9xPR/O7SvLUIZ6jDKj7TfNqOIpqVLaq8wiSPB3MW75RZKiGqcyH4aiEDgpYJRatF3+qZPx3zyUD8Oh5teEWya/HdqqW24a8FdmuQvdwE+ksCpeMJrVslQNDWpwpmRgJe3Nal7/qhdxh92WBSSteHmRSoFLKDwZAUa/f6Np1SXR7sc9fNeIggDvv3Ctx8LrUWpYTae1iGcaa8bwMPiwYXs0tLF+wmQHSypcMdl9CH76jhBRM+8cBzshiCISzJ4xrVUi91or5eOtXHaUM9BOqVZb1uykU/mkWWGQqdzo5Ng9POWUBxLvR4JywSVo4BaDawRykevOjM8JZFGYLfyOk45+MRRuESJWYnjf6P3V3f8l5Ai3SL0g7q/BImZ09iC2jTib8qlRrLMMJ+OQqx45TeCwicBnmV2hqz77KYvikgYLpYQUGkFKcqpP17nXKajbkvEP+2pIQQp6GRptp0Q3TvbOSZSvBJCmr6/6AQ2EXxTKMS2caUsw2bH2btkk45epPKJY1Qg1QOcjRwCUzy0ametW85M+5a3TSKjYAT5lNDb84q2mdMwy5giSI3iglUemcNYFurVlgGcY2CJJw6xi6UiqaqGIEhU9Sn9ns0cHejtu5Uoy+jxyuNaHyuH/f3pB/jdkCzkyTrxT4j5Lpdu6+Le4MdRbn+FGVtopn0LuoqHG8FhourPmpkQxdwA2Yq9glf9MuqiHz1aDri5rDQs/fdCYffvTxEEkZMvYdNIL+m/9talRX7wS1CffCqUrglcfKZxsbvPY9pK9YSxhOmtyZ/vyRBAMlA8Daz0o0mV7czV35tTPPoD36pgo04JenFRaKopwgyQ,iv:682Ok4M7ptRiWBytvbbiDyBCKBdZ51AIn7VWA62GdBk=,tag:UWsWZnDZ10dMF2vAB8V8tA==,type:str]
sops:
age:
- recipient: age14gfh682a7m7jfp3qrulql03x5rs7yedwmxwksxrrmgjsunstyuksqx93pz
@@ -31,7 +66,7 @@ sops:
U0tmdFBuZnJES3piOTZNV0VKQmQ0eVUKCWRQ/flLzmpC64WyLoipklZBmrkpYiUg
PRu+itNolpPTHm96pe+P93g2iP0wgekG0cX21wkiU2xaLF3dY2FEIA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-10-09T00:57:39Z"
mac: ENC[AES256_GCM,data:NCsVDJnzb/x6/InOrE7Aco1bEfbcOA0t5mEQOO/tSM4uj5QjDeCTUyfzfK0A7LHdQSMvRpZLZuz7xDg/WA/QLe0F/CdA1h5HJucpop4NWN/bnJrVNIcik/YlvB6xSWojimZF9sbWZQQb2lPsn3GWt9wIHIHWlBhjIMfHHpLANq8=,iv:yQgpRv+xCvKcBYCyVac66egptSbF/8vi4TtQ5vL5xWQ=,tag:JdsI0yAecTnNO9UiE2IEwQ==,type:str]
lastmodified: "2026-01-28T21:02:05Z"
mac: ENC[AES256_GCM,data:b9aX43ViObNX29DkVNHtwkQRm26PRe2rZYhDnL1ZYLLWyaO3OGP9+rM4vHT0lyuowQ6+Ur3IMPVpUSziXYLh3mtxr0hyYy5Y1miBuIxXYLBi3oLRTW1TgZdklzFDVL3c1GT4lXEh4q9KG3dP64r9/8dvjO2iRIosZ93/l0pIi3A=,iv:/gdNfVy8UiQsIRAHh2jiha5fL+wmfgp0srxt17Ry4Xs=,tag:YdVbvpBnQSaIarGIfiTzKQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.11.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

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