Compare commits
777
Commits
d4f55ea042
..
trunk
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7d27d8ea1 | ||
|
|
52641b8b10 | ||
|
|
256a9684fe | ||
|
|
6f74b4aff3 | ||
|
|
ae9a50f11e | ||
|
|
8c9ff95e68 | ||
|
|
b21b81caf4 | ||
|
|
17631704b1 | ||
|
|
cf29da55dc | ||
|
|
4d512e6f6c | ||
|
|
3dbcfe9ff1 | ||
|
|
d196fed0d8 | ||
|
|
491721aed3 | ||
|
|
faceb9d0ca | ||
|
|
8832a4495b | ||
|
|
3e268f4b22 | ||
|
|
c9d30a962c | ||
|
|
7176ce59d2 | ||
|
|
47c160200f | ||
|
|
5e6d4b6344 | ||
|
|
409d84b530 | ||
|
|
60e745a3d9 | ||
|
|
c9dc8a0def | ||
|
|
071b6f0e66 | ||
|
|
0d48663d81 | ||
|
|
c56e020dec | ||
|
|
5af6c6242b | ||
|
|
08c829a708 | ||
|
|
939fb8d96b | ||
|
|
6b43e1e1d6 | ||
|
|
8915ff714f | ||
|
|
ec9ba4f0e5 | ||
|
|
b481fd9c6b | ||
|
|
dbf21fa3e9 | ||
|
|
5c928aac70 | ||
|
|
074fec8677 | ||
|
|
503b850943 | ||
|
|
eff0c765c0 | ||
|
|
b5deb4334f | ||
|
|
785bdc4b32 | ||
|
|
a483ea764e | ||
|
|
f232163920 | ||
|
|
aec377046e | ||
|
|
d22c274a52 | ||
|
|
b4ab71c8cd | ||
|
|
7dde6470a4 | ||
|
|
11ab7440fa | ||
|
|
72107e2339 | ||
|
|
b21eeb5b66 | ||
|
|
4b9a6bf8cc | ||
|
|
7113725038 | ||
|
|
d9885a92d5 | ||
|
|
1138e567e6 | ||
|
|
e66dfa5d61 | ||
|
|
03c1d94677 | ||
|
|
d7c8c9e6fe | ||
|
|
4a887023b9 | ||
|
|
4debf084fe | ||
|
|
b885fc14ab | ||
|
|
53b2a66d8e | ||
|
|
38fd7ec62e | ||
|
|
01906fc345 | ||
|
|
f45b902e58 | ||
|
|
9fa860c86c | ||
|
|
d9864bbebf | ||
|
|
7d23d676bf | ||
|
|
08fa7027d8 | ||
|
|
3e97b5cd67 | ||
|
|
92a71ec2ba | ||
|
|
9f626a0f8e | ||
|
|
d6c5d3ded4 | ||
|
|
cc76377b37 | ||
|
|
2ada0e3e3a | ||
|
|
7f74cd42b4 | ||
|
|
843f85e23e | ||
|
|
54f224a598 | ||
|
|
e4ebae88fe | ||
|
|
688c96ae9a | ||
|
|
9396da0b8d | ||
|
|
4016df88a5 | ||
|
|
c0b661f83c | ||
|
|
a6b7d7f318 | ||
|
|
9e475209e5 | ||
|
|
556adde3a3 | ||
|
|
0cc81e1126 | ||
|
|
0f0857dd7c | ||
|
|
6873fe64cb | ||
|
|
603fbdc9ba | ||
|
|
18bfb424f5 | ||
|
|
64e56a615e | ||
|
|
671f157b8d | ||
|
|
9736a86d9e | ||
|
|
e958a81b04 | ||
|
|
88819be7e7 | ||
|
|
288724e86c | ||
|
|
583c997a62 | ||
|
|
c2599ae219 | ||
|
|
b2d33de709 | ||
|
|
e21b3e7814 | ||
|
|
ec24d8c518 | ||
|
|
5466f8eb44 | ||
|
|
b5b544b83f | ||
|
|
966780e7c4 | ||
|
|
24d104ad60 | ||
|
|
4a79e6e3a1 | ||
|
|
a1cbc554d8 | ||
|
|
cc4f628ea6 | ||
|
|
2fc89120a8 | ||
|
|
11d6dde229 | ||
|
|
af2fc02d97 | ||
|
|
3382f30b9d | ||
|
|
3252c941aa | ||
|
|
5447afbf61 | ||
|
|
a5f624b6b7 | ||
|
|
af3a35cdec | ||
|
|
4e0c40e83b | ||
|
|
6ab43ae093 | ||
|
|
2e3b829118 | ||
|
|
ed0f761f7b | ||
|
|
888946cbc2 | ||
|
|
9fd96c57d6 | ||
|
|
8d4fcda2ce | ||
|
|
ff4759a368 | ||
|
|
7f1db3ec3a | ||
|
|
e5b8d6eb94 | ||
|
|
67527c2ef9 | ||
|
|
9659dcf9ef | ||
|
|
79a04d45a4 | ||
|
|
887b8f3953 | ||
|
|
e36095c1d7 | ||
|
|
f36d67b29a | ||
|
|
58c7919936 | ||
|
|
34254ffd93 | ||
|
|
649de1ce1a | ||
|
|
3db2962b85 | ||
|
|
a27d6b11c0 | ||
|
|
bd37a7bbd4 | ||
|
|
7f0e96b058 | ||
|
|
776e68e1e6 | ||
|
|
1ded87909f | ||
|
|
479a8b2e03 | ||
|
|
1e206de4c0 | ||
|
|
df71394956 | ||
|
|
4c89bf0f72 | ||
|
|
dd3c2f817f | ||
|
|
89ee4bdfd4 | ||
|
|
5746e0144f | ||
|
|
7297aaa8fb | ||
|
|
adec4a5c2e | ||
|
|
41211b41bb | ||
|
|
b18c04df36 | ||
|
|
32a5121936 | ||
|
|
5b9d15b2ce | ||
|
|
adcdfd604c | ||
|
|
a23a211d89 | ||
|
|
78e0b6723b | ||
|
|
84ba07b035 | ||
|
|
59ac5e92d9 | ||
|
|
7505abb756 | ||
|
|
6dca018d13 | ||
|
|
a52b181b27 | ||
|
|
36cf6156e1 | ||
|
|
ae0c4a9df2 | ||
|
|
9e3955a0f9 | ||
|
|
32efe6cb40 | ||
|
|
0ab66f480b | ||
|
|
e8d3dbfc74 | ||
|
|
6343f90947 | ||
|
|
1ac6fc6e66 | ||
|
|
0ecbead350 | ||
|
|
b5fe99371f | ||
|
|
b24a3df88c | ||
|
|
82cb5a742c | ||
|
|
77067724ce | ||
|
|
182e5abbbf | ||
|
|
8abbd70e3d | ||
|
|
39eb846407 | ||
|
|
d47a7580ed | ||
|
|
e93f8cd4ee | ||
|
|
dd3bd26b60 | ||
|
|
9a204bce60 | ||
|
|
36a6ec23b3 | ||
|
|
279340f744 | ||
|
|
b4201cfeb4 | ||
|
|
f444756575 | ||
|
|
6f3999c1f9 | ||
|
|
351613d392 | ||
|
|
ffaf77793f | ||
|
|
4d3ef01876 | ||
|
|
779a6c4f41 | ||
|
|
ab2f0a6e6a | ||
|
|
a8811af514 | ||
|
|
c175baefbf | ||
|
|
168f95d219 | ||
|
|
e91ab96980 | ||
|
|
357a5b9c09 | ||
|
|
2fe99b250f | ||
|
|
5216b65607 | ||
|
|
2c87bff5cd | ||
|
|
bbb70a66ed | ||
|
|
2241045cbb | ||
|
|
9d3f5bfaae | ||
|
|
5b5a6bcd1c | ||
|
|
e2ef9cbad1 | ||
|
|
5b31c91d28 | ||
|
|
37f263e984 | ||
|
|
1b4dee14ed | ||
|
|
233e1a4773 | ||
|
|
a743bbbc30 | ||
|
|
3d74ff5556 | ||
|
|
6b16a885e3 | ||
|
|
14f5e3e2dc | ||
|
|
4ccb658ca8 | ||
|
|
74bc8e7f3f | ||
|
|
0e55f4e2f0 | ||
|
|
6b0744330b | ||
|
|
a97b7fb2c3 | ||
|
|
4b537c7fe8 | ||
|
|
2c7e21f64d | ||
|
|
23c7358939 | ||
|
|
c1ae91491a | ||
|
|
982d208b13 | ||
|
|
f07bbbef01 | ||
|
|
7c18ecebab | ||
|
|
5890c3e461 | ||
|
|
41df12b164 | ||
|
|
18c19b2823 | ||
|
|
66d17dfde1 | ||
|
|
5bb3d44c8c | ||
|
|
11d3fcd8ec | ||
|
|
fcb8961c69 | ||
|
|
85a97ddb47 | ||
|
|
c11c04394c | ||
|
|
ff5cb7a865 | ||
|
|
fcd957443a | ||
|
|
1606dd97d4 | ||
|
|
7c58261db8 | ||
|
|
f7fecbe8ad | ||
|
|
310b332178 | ||
|
|
087365d239 | ||
|
|
a34c177b69 | ||
|
|
0edc17ecde | ||
|
|
05fcf51fbd | ||
|
|
76fbf8ff9c | ||
|
|
5354a9ad0d | ||
|
|
45b1ded302 | ||
|
|
fa15da2778 | ||
|
|
09fd696b1d | ||
|
|
406b923226 | ||
|
|
9aef75b7ba | ||
|
|
53598b5997 | ||
|
|
1c5c21612a | ||
|
|
01e420aa8d | ||
|
|
a422358acd | ||
|
|
d5f619ce4d | ||
|
|
981a7b0c4a | ||
|
|
6509775612 | ||
|
|
f82f08098c | ||
|
|
9265c4f4b1 | ||
|
|
f94dbf9d0d | ||
|
|
437bf5939f | ||
|
|
d426607907 | ||
|
|
67392b4a45 | ||
|
|
c37ff5dd4c | ||
|
|
3283cac3e8 | ||
|
|
e0e298b63f | ||
|
|
1953f417dd | ||
|
|
bd8c18b76b | ||
|
|
c02b5a997a | ||
|
|
4ef203bcc4 | ||
|
|
c908cb3d00 | ||
|
|
d7362dee01 | ||
|
|
028c06cad3 | ||
|
|
c1dce7bab1 | ||
|
|
e225cde934 | ||
|
|
105550e5f1 | ||
|
|
164a67b968 | ||
|
|
f960c8226c | ||
|
|
cb3ea8d9aa | ||
|
|
3de20a07f8 | ||
|
|
a1c365128f | ||
|
|
2fc0cb525d | ||
|
|
898a752414 | ||
|
|
e319a94240 | ||
|
|
ec5f561b98 | ||
|
|
1195c8a65c | ||
|
|
88740fe1e1 | ||
|
|
f12641e063 | ||
|
|
8f3000cde0 | ||
|
|
a030e09887 | ||
|
|
46dcb607d8 | ||
|
|
c84484257c | ||
|
|
f2b1c99a85 | ||
|
|
f814db20fe | ||
|
|
84a775a0cb | ||
|
|
b15a146bee | ||
|
|
4a1d300112 | ||
|
|
1d000537aa | ||
|
|
1af229350d | ||
|
|
9a628121ae | ||
|
|
16c9b425c1 | ||
|
|
e7323bd7d6 | ||
|
|
a5a01250c1 | ||
|
|
83c83e6bc8 | ||
|
|
37796783ad | ||
|
|
f24687c060 | ||
|
|
f9af5f71fe | ||
|
|
98e8ccd17c | ||
|
|
22bdee4af6 | ||
|
|
bb33a9470a | ||
|
|
36a022ef0a | ||
|
|
d7a55abee2 | ||
|
|
7d0fb6ab9b | ||
|
|
a587da82d5 | ||
|
|
4f7950922d | ||
|
|
1335254681 | ||
|
|
24eccf83e2 | ||
|
|
e34a41ee7d | ||
|
|
f97d97a570 | ||
|
|
4d552be249 | ||
|
|
3c5f6cedeb | ||
|
|
b91a72f6c8 | ||
|
|
4f117ac83f | ||
|
|
0d73aa3087 | ||
|
|
27555fe856 | ||
|
|
402a9cb771 | ||
|
|
fd7e99c6f1 | ||
|
|
bdd11a2e31 | ||
|
|
8588d7a90d | ||
|
|
3937764ab1 | ||
|
|
6e3e135a95 | ||
|
|
cada87bb75 | ||
|
|
934544883a | ||
|
|
5ad154ec37 | ||
|
|
2ed9cb285d | ||
|
|
5b4ee10875 | ||
|
|
ed4a898f83 | ||
|
|
7302648b57 | ||
|
|
6fdc826b2a | ||
|
|
31683a89ed | ||
|
|
aef547aefc | ||
|
|
c86fe27ea7 | ||
|
|
6dc36a7295 | ||
|
|
17a4e2f138 | ||
|
|
7fddefba21 | ||
|
|
9dd2015202 | ||
|
|
faf9343022 | ||
|
|
6059b4ef57 | ||
|
|
02e9dacab5 | ||
|
|
3ec8db578d | ||
|
|
a24f033d12 | ||
|
|
8e0d283df0 | ||
|
|
5cc23aa500 | ||
|
|
d78601bf02 | ||
|
|
b87423350b | ||
|
|
b7002121ea | ||
|
|
21cef8c106 | ||
|
|
d2bbf6b287 | ||
|
|
5aaa24798d | ||
|
|
3c7c2b7599 | ||
|
|
646e263591 | ||
|
|
4a0c476599 | ||
|
|
958fd9519d | ||
|
|
9ca91b0445 | ||
|
|
ebfb46082f | ||
|
|
d7af3ae96f | ||
|
|
d2fec2e53d | ||
|
|
bcb37120e0 | ||
|
|
31d59f89a9 | ||
|
|
fe112cb380 | ||
|
|
d84db54669 | ||
|
|
e781ca769b | ||
|
|
ba07db9dbf | ||
|
|
d77ba8c4a1 | ||
|
|
6f1a27648d | ||
|
|
2b3c0e71d5 | ||
|
|
08fb5b3adf | ||
|
|
cb98b17f44 | ||
|
|
2bfabc246a | ||
|
|
d3e5528951 | ||
|
|
4a02453b74 | ||
|
|
b3ab37b40b | ||
|
|
1194076dc2 | ||
|
|
1b1244d2db | ||
|
|
9c967dd96a | ||
|
|
5fd3cfa3cd | ||
|
|
87eeda1744 | ||
|
|
00ca8596cb | ||
|
|
ebfd5df134 | ||
|
|
4bb8ecb146 | ||
|
|
4edd79feac | ||
|
|
aafb198c42 | ||
|
|
0b15109b85 | ||
|
|
875f016242 | ||
|
|
2530341c1f | ||
|
|
2df4812035 | ||
|
|
6312d24aa9 | ||
|
|
7d97fdee7a | ||
|
|
6d194f8103 | ||
|
|
a0980ffd87 | ||
|
|
c64fbb845c | ||
|
|
1148340fad | ||
|
|
2c14ad4a2a | ||
|
|
8f7868b0a4 | ||
|
|
681ef9ae6e | ||
|
|
64d4f36d4d | ||
|
|
559d5615ea | ||
|
|
c6af375164 | ||
|
|
320a4be81c | ||
|
|
37bc3712dd | ||
|
|
0dd7cf5cd6 | ||
|
|
c631ad5e05 | ||
|
|
594132d038 | ||
|
|
9b4d196371 | ||
|
|
f425ca7fd4 | ||
|
|
d6a7761524 | ||
|
|
e3a85a83dd | ||
|
|
83e0903edb | ||
|
|
7bda8925e8 | ||
|
|
ce4ccab1c0 | ||
|
|
d663a17046 | ||
|
|
782e73745f | ||
|
|
223d7f8fec | ||
|
|
2f1bbf3e62 | ||
|
|
db0e912139 | ||
|
|
fe1242a5fd | ||
|
|
56b0db801e | ||
|
|
909b25c217 | ||
|
|
9ea854565d | ||
|
|
837b38594a | ||
|
|
08c91e1671 | ||
|
|
4826f78894 | ||
|
|
d6f208de92 | ||
|
|
2b309abe9e | ||
|
|
4188371e9a | ||
|
|
6c88add21a | ||
|
|
5466cd4a27 | ||
|
|
c93e3ed8ae | ||
|
|
93563ba2d8 | ||
|
|
a41407b123 | ||
|
|
9ae3b7e98e | ||
|
|
3f9a9eedc0 | ||
|
|
b344da8950 | ||
|
|
d1300baadd | ||
|
|
0b975a2f18 | ||
|
|
4100adbc0b | ||
|
|
5bf33a9c6b | ||
|
|
e0775ca7e6 | ||
|
|
66b5af02b1 | ||
|
|
47dfb00e43 | ||
|
|
9f8104e7b8 | ||
|
|
8563489682 | ||
|
|
1ec90889e4 | ||
|
|
6dd0ab1eea | ||
|
|
9b3d344fb5 | ||
|
|
6eb4ddf0a5 | ||
|
|
1a609d14dc | ||
|
|
f6011be1d1 | ||
|
|
48cac1436a | ||
|
|
6dcd5201b5 | ||
|
|
8b2659ded5 | ||
|
|
b1aa39af57 | ||
|
|
9a1b1a99c6 | ||
|
|
a9a2e17261 | ||
|
|
d81be14cfb | ||
|
|
f918502587 | ||
|
|
08b4a7de24 | ||
|
|
48b0ea202f | ||
|
|
dcd8459904 | ||
|
|
0e6ec014eb | ||
|
|
089a38bdcf | ||
|
|
8a3292d81c | ||
|
|
c303142659
|
||
|
|
9112d9402d
|
||
|
|
1c48ba8c9d
|
||
|
|
9620100aa1
|
||
|
|
c02f808d49
|
||
|
|
c364d6dd74 | ||
|
|
04b7752ac8 | ||
|
|
d1de74d177 | ||
|
|
aef886a880 | ||
|
|
c9193fc7bd | ||
|
|
f6230480f5 | ||
|
|
d81469e9bc | ||
|
|
1f4494d333 | ||
|
|
85255adb2c | ||
|
|
f251a6f5c7 | ||
|
|
1f84cf19c7 | ||
|
|
0e49c1b9ee | ||
|
|
3ff5251b15 | ||
|
|
007c66c007 | ||
|
|
d37a0ce652 | ||
|
|
5ab6c9e4c8 | ||
|
|
fccec4d504 | ||
|
|
8feda54866 | ||
|
|
7179e6f047 | ||
|
|
1da9d994de | ||
|
|
e213c64481 | ||
|
|
49ac3c2bf5 | ||
|
|
8acebb13cc | ||
|
|
ff08538bae | ||
|
|
494ac6cf57 | ||
|
|
4cfddd2c7e | ||
|
|
60509f93f0 | ||
|
|
96d8fd1129 | ||
|
|
39264279e0 | ||
|
|
07c9533255 | ||
|
|
015f416169 | ||
|
|
35d8c83423 | ||
|
|
b488af297a | ||
|
|
dbb5560793 | ||
|
|
7bcfef3ccf | ||
|
|
a1fd3b3af2 | ||
|
|
a45d9014dd | ||
|
|
80451e9430 | ||
|
|
df1a77f73e | ||
|
|
6f51671dbb | ||
|
|
a238d2b61c | ||
|
|
62dd3f5d7c
|
||
|
|
8b8dc8cde8 | ||
|
|
3047ff97b4 | ||
|
|
1c963f5563 | ||
|
|
c02f2853c1 | ||
|
|
d73a561b9d | ||
|
|
7d97acfdfb | ||
|
|
cfb55f980d | ||
|
|
1a67b02d7c | ||
|
|
0196b1d8b2 | ||
|
|
d7a6a85841 | ||
|
|
cc7aca0fce | ||
|
|
6b393c7e4f | ||
|
|
c9bcda6043 | ||
|
|
7ce43bf8e7 | ||
|
|
5a451bcaa1 | ||
|
|
b4bba876ae | ||
|
|
005d0451f5 | ||
|
|
d20a1787c2 | ||
|
|
6bb1a13741 | ||
|
|
b21060e78d | ||
|
|
8caa3b6fe7 | ||
|
|
6fb6dc7abb | ||
|
|
4a6eb5059c | ||
|
|
d92a192a7f | ||
|
|
51c3ae6d1e | ||
|
|
2ea0b96230 | ||
|
|
f7ece5059d | ||
|
|
b84a2d7628 | ||
|
|
b78a43d40a | ||
|
|
f5ff1a6639 | ||
|
|
0534a04108 | ||
|
|
4af26da42f | ||
|
|
d014733441 | ||
|
|
38c0191ad2 | ||
|
|
2bbbd49a07 | ||
|
|
38a22b5255 | ||
|
|
a787a7dfc5 | ||
|
|
4349ccb132 | ||
|
|
96920b6b3d | ||
|
|
b97d7e4cb1 | ||
|
|
59927a4e3d | ||
|
|
076653fd15 | ||
|
|
63dcc450b6 | ||
|
|
c15704eb22 | ||
|
|
85f7a2889c | ||
|
|
6bfea61ffe | ||
|
|
4e0cc2a322 | ||
|
|
7ef99c8dd1 | ||
|
|
1655c0a867 | ||
|
|
724c63f9ff | ||
|
|
5813db8160 | ||
|
|
cdf8403991 | ||
|
|
10488b90c9 | ||
|
|
bcb1b88861 | ||
|
|
e27be65861 | ||
|
|
0e0e58b909 | ||
|
|
4e3a31cf87 | ||
|
|
58e68a003a | ||
|
|
82d61d54eb | ||
|
|
fa981032d4 | ||
|
|
5090fa9cd4 | ||
|
|
125d639f9f | ||
|
|
9ad80827ee | ||
|
|
f0fa2540b5 | ||
|
|
0bfe74abb7 | ||
|
|
766e20ffc4 | ||
|
|
178fba9c84 | ||
|
|
eef41bbca8 | ||
|
|
a0c728f147 | ||
|
|
35645a3e9c | ||
|
|
67002a94dd | ||
|
|
6beb28477f | ||
|
|
dc03836ac0 | ||
|
|
646ba6d63f | ||
|
|
e34b5161d4 | ||
|
|
81c59857e5 | ||
|
|
7576364d43 | ||
|
|
f31eefe6eb | ||
|
|
788155194f | ||
|
|
777c4f3192 | ||
|
|
e7ed3e584d | ||
|
|
af9d2553d5 | ||
|
|
14c67a8bb3 | ||
|
|
97d2610240 | ||
|
|
2e36efa1c3 | ||
|
|
8a781d6b2a | ||
|
|
c8a036edc2 | ||
|
|
f0a8d8f0fb | ||
|
|
303c759bb4 | ||
|
|
c243c4393f | ||
|
|
de4822bc68 | ||
|
|
ed3046e18a | ||
|
|
e3546caeb5 | ||
|
|
cc083128a3 | ||
|
|
9faad0e16c | ||
|
|
e50f503270 | ||
|
|
8a502bdf15 | ||
|
|
32d737f011 | ||
|
|
7f84ae360c | ||
|
|
bce6234c10 | ||
|
|
7572b52d6f | ||
|
|
68ca7ff5f8 | ||
|
|
51d9300990 | ||
|
|
183eb27980 | ||
|
|
3f689d46f4 | ||
|
|
2a576d8d39 | ||
|
|
e92206ae43 | ||
|
|
733145692f | ||
|
|
ad8b20fd0c | ||
|
|
d9c20efa16 | ||
|
|
3bbe306485 | ||
|
|
f9ac7944b3 | ||
|
|
eff39f2218 | ||
|
|
cdbb5f913d | ||
|
|
e329c17546 | ||
|
|
85c8b9ec1c | ||
|
|
96fd9d96c1 | ||
|
|
090889dff2 | ||
|
|
8c4a82a73f | ||
|
|
f448ce43ec | ||
|
|
2fb0dc4c50 | ||
|
|
2ed9add88e | ||
|
|
881d4dd78a | ||
|
|
ad487e6715 | ||
|
|
f107cf19c7 | ||
|
|
f5bc0400ae | ||
|
|
96ca6c6ea0 | ||
|
|
610513edb7 | ||
|
|
f49978d587 | ||
|
|
cb4234630b | ||
|
|
992616c1ca | ||
|
|
7b39e418c9 | ||
|
|
adf9d1ee4a | ||
|
|
0c4aed6591 | ||
|
|
1f8fe59423 | ||
|
|
0fc620e7da | ||
|
|
245f06fd3a | ||
|
|
d39fb7af39 | ||
|
|
6ddebc86d7 | ||
|
|
e2047cba7b | ||
|
|
d7ae540ebf | ||
|
|
0fae0e72d3 | ||
|
|
3304d04d9d | ||
|
|
e54f91bcd9 | ||
|
|
4d38c79dfa | ||
|
|
946413ada0 | ||
|
|
4c9b1651bf | ||
|
|
0fc3f1f501 | ||
|
|
9b758fdd96 | ||
|
|
225d102cea | ||
|
|
38b298fcd6 | ||
|
|
a9579a7bf9 | ||
|
|
1192cef3ed | ||
|
|
8eae778b23 | ||
|
|
61fb81abef | ||
|
|
03c0b51343 | ||
|
|
647c94bd6e | ||
|
|
e21db6c245 | ||
|
|
97b66bbb33 | ||
|
|
edafa28c3e | ||
|
|
400ac5212f | ||
|
|
c1182d8521 | ||
|
|
b0bcc1040e | ||
|
|
b08cb2ea82 | ||
|
|
021c4a9172 | ||
|
|
dcf958c0a8 | ||
|
|
037a9b08e3 | ||
|
|
11f247bac8 | ||
|
|
dd34c532d0 | ||
|
|
8b2dd3829a | ||
|
|
0b6e0b7577 | ||
|
|
0038a61fff | ||
|
|
5c1e292f60 | ||
|
|
fc0f270c34 | ||
|
|
9f22aef6af | ||
|
|
f04911def2 | ||
|
|
329f156f87 | ||
|
|
f43f3b1749 | ||
|
|
d4bcd95d52 | ||
|
|
f1e9914ea1 | ||
|
|
419d86342d | ||
|
|
b5b9633c3c | ||
|
|
93e1150a56 | ||
|
|
ba40661f5e | ||
|
|
a6d2c0030d | ||
|
|
458090e795 | ||
|
|
4078ed0d21 | ||
|
|
4a995d51c3 | ||
|
|
84b7477cff | ||
|
|
ba2bcba53b | ||
|
|
ec252348fd | ||
|
|
5a20416be1 | ||
|
|
83bdbd296f | ||
|
|
b48bd36fd7 | ||
|
|
728425868c | ||
|
|
69d748c3ff | ||
|
|
4e59f2d8ca | ||
|
|
817f2b29a3 | ||
|
|
c1ae4d7060 | ||
|
|
fd4119a579 | ||
|
|
fb64e3406b | ||
|
|
1268291250 | ||
|
|
5e3155b465 | ||
|
|
de0117edff | ||
|
|
700943ab97 | ||
|
|
6fa11eea8f | ||
|
|
2d1d85ddc6 | ||
|
|
7a371f3b1e | ||
|
|
bf8c4d050d | ||
|
|
1832c5ac83 | ||
|
|
6f1c74d243 | ||
|
|
d1dde74c4f | ||
|
|
05607c2b48 | ||
|
|
eea735134d | ||
|
|
d9f06234fd | ||
|
|
f4b505d1d1 | ||
|
|
24ac2aca51 | ||
|
|
4881ac5808 | ||
|
|
b7fb67f939 | ||
|
|
32f37c7c2e | ||
|
|
0a31b25d83 | ||
|
|
acc28d9278 | ||
|
|
ae04500e63 | ||
|
|
f463b76253 | ||
|
|
5298430415 | ||
|
|
14f790e67a | ||
|
|
6ca265e97b | ||
|
|
7b11dbdcfa | ||
|
|
652f005769 | ||
|
|
2149a58293 | ||
|
|
62a813eb81 | ||
|
|
f11dbc52bc | ||
|
|
3e216701e0 | ||
|
|
f72e067a4e | ||
|
|
39336740e1 | ||
|
|
c8e7d0ac7f | ||
|
|
4991af44c3 | ||
|
|
7fd8610476 | ||
|
|
3eb9c9b402 | ||
|
|
f2c320d9ee | ||
|
|
76d3410702 | ||
|
|
256b532938 | ||
|
|
27fb031175 | ||
|
|
eef0c8cf27 | ||
|
|
643ab0958c | ||
|
|
f597616843 | ||
|
|
e4378fc6fe | ||
|
|
bb65d89c39 | ||
|
|
93a3b83127 | ||
|
|
2f77f3b3a3 | ||
|
|
13a5def7d7 | ||
|
|
40f047eb1e | ||
|
|
3cba1640e0 | ||
|
|
3b12bf7081 | ||
|
|
06ec73de0b | ||
|
|
6d3ae434a5 | ||
|
|
1cc6abb89a | ||
|
|
25122a4c9c |
+1
-1
@@ -1,4 +1,4 @@
|
||||
|
||||
.DS_Store
|
||||
.keyring
|
||||
.keyring/
|
||||
.nixos-switch-log
|
||||
|
||||
@@ -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/archives/servers/snowbelle}"
|
||||
|
||||
# --- 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."
|
||||
|
||||
Executable
+136
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env bash
|
||||
# this will one day be an interactive install bootstrap script for my nix config!
|
||||
# right now this shall be treated as psudocode but also just a list of steps for installing
|
||||
# without further adoo:
|
||||
#
|
||||
# 1. boot target device into nixos installer iso
|
||||
# 2. `sudo -i``
|
||||
# 3. `git clone https://git.blakedheld.xyz/blake/nix.git bootstrap_nix`
|
||||
# 4. if new host use `ls -l /dev/disk/by-id/` to get the id of the target disk and update the related line in the disko config for that host (or partition the target disk manually however you wish)
|
||||
# 5. run the disko install command `nix run github:nix-community/disko -- --mode destroy,format,mount --flake bootstrap_nix#hostname` to just format the disk(s)
|
||||
# 6. generate hardware config `nixos-generate-config --root /mnt`
|
||||
# 7. create directories for keys `mkdir -p /mnt/etc/sops` `mkdir -p /mnt/home/blake/.config/sops/age`
|
||||
# 8. move nix config to home dir `mv /bootstrap_nix /mnt/home/blake/.nix`
|
||||
# 9. copy age keys.txt to previously made dirs `echo "<key>" | tee /mnt/etc/sops/keys.txt /mnt/home/blake/.config/sops/age/keys.txt > dev/null`
|
||||
# 10. install the os (let it fail, fix it, repeat, etc) `nixos-install --flake /mnt/home/blake/.nix#hostname`
|
||||
# 11. set the root password
|
||||
# 12. reboot and dont forget to `sudo chown -R blake:blake /home/blake`
|
||||
# 13. change nix repo upstream to ssh `cd ~/.nix && git remote remove origin && git remote add origin ssh://gitea@git.blakedheld.xyz:7567/blake/nix.git`
|
||||
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
AGE_KEY_FILE="/keys.txt"
|
||||
|
||||
echo "nixos bootstrap installer =="
|
||||
|
||||
# --- input ---
|
||||
read -rp "hostname: " HOSTNAME
|
||||
#read -rp "age key (will not be echoed): " AGE_KEY
|
||||
if [[ ! -f "$AGE_KEY_FILE" ]]; then
|
||||
echo "cannot find age keyfile"
|
||||
exit 1
|
||||
fi
|
||||
AGE_KEY="$(cat "$AGE_KEY_FILE")"
|
||||
|
||||
echo
|
||||
|
||||
echo
|
||||
echo "install mode:"
|
||||
echo " 1) disko (auto partition/format/mount)"
|
||||
echo " 2) manual (you already mounted disks)"
|
||||
read -rp "choice [1/2]: " MODE
|
||||
echo
|
||||
if [[ -d /bootstrap_nix ]]; then
|
||||
echo "repo already exists, skipping clone"
|
||||
else
|
||||
echo "cloning nix config..."
|
||||
git clone https://git.blakedheld.xyz/blake/nix.git /bootstrap_nix
|
||||
fi
|
||||
|
||||
cd /bootstrap_nix
|
||||
|
||||
# fix origin
|
||||
git remote remove origin
|
||||
git remote add origin ssh://gitea@git.blakedheld.xyz:7567/blake/nix.git
|
||||
|
||||
# --- disk setup ---
|
||||
if [[ "$MODE" == "1" ]]; then
|
||||
echo
|
||||
echo "running disko (THIS WILL DESTROY DISKS)..."
|
||||
echo "make sure /dev/disk/by-id is correct in your host config!"
|
||||
|
||||
# nix run github:nix-community/disko --extra-experimental-features "nix-command flakes" -- \
|
||||
# --mode destroy,format,mount \
|
||||
# --flake .#"${HOSTNAME}"
|
||||
|
||||
nix run github:nix-community/disko --extra-experimental-features "nix-command flakes" -- \
|
||||
--mode destroy,format,mount \
|
||||
--yes-wipe-all-disks \
|
||||
/bootstrap_nix/hosts/nixos/$HOSTNAME/disko.nix
|
||||
|
||||
elif [[ "$MODE" == "2" ]]; then
|
||||
echo
|
||||
echo "MANUAL MODE SELECTED"
|
||||
echo "WARNING: you must have already partitioned + mounted disks to /mnt"
|
||||
read -rp "press ENTER to continue once disks are mounted..."
|
||||
|
||||
else
|
||||
echo "invalid selection"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- generate hardware config ---
|
||||
echo
|
||||
echo "generating hardware config..."
|
||||
nixos-generate-config --root /mnt
|
||||
|
||||
# --- setup directories ---
|
||||
echo "creating sops/age directories..."
|
||||
mkdir -p /mnt/etc/sops
|
||||
mkdir -p /mnt/home/blake/.config/sops/age
|
||||
|
||||
# --- move config ---
|
||||
echo "moving nix config into /mnt/home/blake/.nix ..."
|
||||
cp -r /bootstrap_nix /mnt/home/blake/.nix
|
||||
|
||||
echo "moving hardware into /mnt/home/blake/.nix/hosts/nixos/$HOSTNAME ..."
|
||||
cp /mnt/etc/nixos/hardware-configuration.nix /mnt/home/blake/.nix/hosts/nixos/$HOSTNAME
|
||||
cd /mnt/home/blake/.nix
|
||||
git add /mnt/home/blake/.nix/hosts/nixos/$HOSTNAME
|
||||
|
||||
|
||||
# --- write age key ---
|
||||
echo "writing age key..."
|
||||
echo "$AGE_KEY" | tee \
|
||||
/mnt/etc/sops/keys.txt \
|
||||
/mnt/home/blake/.config/sops/age/keys.txt \
|
||||
> /dev/null
|
||||
|
||||
# --- install ---
|
||||
echo
|
||||
echo "running nixos-install..."
|
||||
set +e
|
||||
nixos-install --root /mnt --flake /mnt/home/blake/.nix#"${HOSTNAME}"
|
||||
INSTALL_EXIT=$?
|
||||
set -e
|
||||
|
||||
if [[ $INSTALL_EXIT -ne 0 ]]; then
|
||||
echo
|
||||
echo "install failed. fix issues and re-run nixos-install manually if needed."
|
||||
exit $INSTALL_EXIT
|
||||
fi
|
||||
|
||||
# --- post install ---
|
||||
echo
|
||||
echo "installation complete!"
|
||||
echo "set root password if needed, then reboot."
|
||||
echo "after reboot: sudo chown -R blake:blake /home/blake"
|
||||
|
||||
nixos-enter --root /mnt -- run --login bash <<'EOF'
|
||||
set -e
|
||||
chown -R blake:blake /home/blake
|
||||
nixos-rebuild switch --flake /home/blake/.nix
|
||||
systemd-cryptenroll --tpm2-device=auto /dev/nvme0n1p2
|
||||
EOF
|
||||
|
||||
echo "fin."
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cd /home/blake/.nix
|
||||
git remote remove origin
|
||||
git remote add origin ssh://gitea@git.holocron.blue:7567/blake/nix.git
|
||||
git fetch
|
||||
git branch --set-upstream-to=origin/trunk trunk
|
||||
@@ -26,6 +26,8 @@ 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
|
||||
@@ -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
|
||||
Generated
+1070
-138
File diff suppressed because it is too large
Load Diff
@@ -4,76 +4,165 @@
|
||||
{
|
||||
description = "blakes nix config";
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-25.05";
|
||||
nixpkgs.url = "nixpkgs/nixos-26.05";
|
||||
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
|
||||
nix-darwin = {
|
||||
url = "github:LnL7/nix-darwin";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
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";
|
||||
url = "github:nix-community/home-manager/release-26.05";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
home-manager-unstable = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
};
|
||||
plasma-manager = {
|
||||
url = "github:nix-community/plasma-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
inputs.home-manager.follows = "home-manager-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";
|
||||
};
|
||||
nixos-wsl = {
|
||||
url = "github:nix-community/NixOS-WSL/main";
|
||||
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";
|
||||
};
|
||||
nvf = {
|
||||
url = "github:notashelf/nvf/v0.8";
|
||||
url = "github:notashelf/nvf";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
autoaspm = {
|
||||
url = "github:notthebee/AutoASPM";
|
||||
url = "git+https://git.notthebe.ee/notthebee/AutoASPM.git";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
stylix = {
|
||||
url = "github:nix-community/stylix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
};
|
||||
copyparty.url = "github:9001/copyparty";
|
||||
slippi = {
|
||||
url = "github:lytedev/slippi-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||
};
|
||||
srcds-nix.url = "github:ihaveamac/srcds-nix";
|
||||
};
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
nixpkgs-unstable,
|
||||
nix-darwin,
|
||||
nix-homebrew,
|
||||
nixos-wsl,
|
||||
plasma-manager,
|
||||
...
|
||||
} @ inputs: let
|
||||
systems = {
|
||||
x86_64 = "x86_64-linux";
|
||||
arm64 = "aarch64-linux";
|
||||
darwin = "aarch64-darwin";
|
||||
x86_64-linux = "x86_64-linux";
|
||||
aarch64-linux = "aarch64-linux";
|
||||
aarch64-darwin = "aarch64-darwin";
|
||||
};
|
||||
unstableOverlay = final: prev: {
|
||||
unstable = import nixpkgs-unstable {
|
||||
#system = prev.system;
|
||||
system = prev.stdenv.hostPlatform.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
# legacy
|
||||
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;
|
||||
system = systems.x86_64-linux;
|
||||
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
|
||||
modules = [
|
||||
./hosts/snowbelle/configuration.nix
|
||||
{nixpkgs.overlays = [unstableOverlay];}
|
||||
./hosts/nixos/snowbelle/configuration.nix
|
||||
inputs.home-manager.nixosModules.default
|
||||
];
|
||||
};
|
||||
vaniville = nixpkgs.lib.nixosSystem {
|
||||
system = systems.x86_64;
|
||||
yveltal = nixpkgs-unstable.lib.nixosSystem {
|
||||
system = systems.x86_64-linux;
|
||||
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
|
||||
modules = [
|
||||
./hosts/vaniville/configuration.nix
|
||||
{nixpkgs.overlays = [unstableOverlay];}
|
||||
./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-linux;
|
||||
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
|
||||
modules = [
|
||||
{nixpkgs.overlays = [unstableOverlay];}
|
||||
./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-linux;
|
||||
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
|
||||
modules = [
|
||||
{nixpkgs.overlays = [unstableOverlay];}
|
||||
./hosts/nixos/vaniville/configuration.nix
|
||||
inputs.home-manager.nixosModules.default
|
||||
];
|
||||
};
|
||||
lumiose = nixpkgs.lib.nixosSystem {
|
||||
system = systems.x86_64-linux;
|
||||
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
|
||||
modules = [
|
||||
{nixpkgs.overlays = [unstableOverlay];}
|
||||
./hosts/nixos/lumiose/configuration.nix
|
||||
inputs.home-manager.nixosModules.default
|
||||
inputs.disko.nixosModules.disko
|
||||
];
|
||||
};
|
||||
wsl = nixpkgs.lib.nixosSystem {
|
||||
system = systems.x86_64-linux;
|
||||
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
|
||||
modules = [
|
||||
{nixpkgs.overlays = [unstableOverlay];}
|
||||
./hosts/nixos/wsl/configuration.nix
|
||||
nixos-wsl.nixosModules.default
|
||||
inputs.home-manager.nixosModules.default
|
||||
];
|
||||
};
|
||||
};
|
||||
darwinConfigurations = {
|
||||
CEN-IT-07 = nix-darwin.lib.darwinSystem {
|
||||
system = systems.darwin;
|
||||
specialArgs = {inherit inputs stable_pkgs unstable_pkgs;};
|
||||
cen-it-07 = nix-darwin.lib.darwinSystem {
|
||||
system = systems.aarch64-darwin;
|
||||
specialArgs = {inherit inputs stable_pkgs unstable_pkgs nix-homebrew;};
|
||||
modules = [
|
||||
./hosts/cen-it-07/configuration.nix
|
||||
{nixpkgs.overlays = [unstableOverlay];}
|
||||
./hosts/darwin/cen-it-07/configuration.nix
|
||||
inputs.home-manager.darwinModules.default
|
||||
];
|
||||
};
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
inputs.nix-homebrew.darwinModules.nix-homebrew
|
||||
../default.nix
|
||||
../../../modules/darwin
|
||||
];
|
||||
|
||||
# home grown nixos modules
|
||||
darwin = {
|
||||
syncthing.enable = true;
|
||||
tailscale.enable = true;
|
||||
nextdns.enable = true;
|
||||
yubikey.enable = true;
|
||||
work.enable = true;
|
||||
apps.enable = true;
|
||||
cyber.enable = true;
|
||||
gaming.enable = true;
|
||||
};
|
||||
|
||||
# import home grown host specific home-manager modules
|
||||
home-manager.users.bhelderman.imports = [
|
||||
../../../users/blake/hosts/cen-it-07.nix
|
||||
];
|
||||
|
||||
users = {
|
||||
users = {
|
||||
bhelderman = {
|
||||
shell = pkgs.zsh;
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBrNHm/n7BrA8Vz0Lsc3fZQ5QJOm01InFvrzEDuD4BoD me@blakedheld.xyz"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBK0AGJfZGyqW8/krvQV+PL7axcDW/EnKyHy9M8wryQx klefki"
|
||||
"ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBPdC9cCX8awvA19Ri65fvbYjZYe8X1Ef+nOZAIv92AS6u4SkJYqOvPYfqRHXORNDpbzjTV6nackyCKvV5EO4niv4MFIgdkEQwuVHcYX32/dOsWdDoeXBT/l2sFFM7JESwQ== blake@zygarde"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOVsjLEbnW/KeFXogppi0AP6ZbCZpObu7zFeRV/aLkP9 blake@lugia"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# base system package install list
|
||||
environment.systemPackages = with pkgs; [
|
||||
neovide
|
||||
];
|
||||
|
||||
nix-homebrew = {
|
||||
enable = true; # install homebrew
|
||||
enableRosetta = true; # install homebrew for rosetta as well
|
||||
#autoMigrate = true;
|
||||
user = "bhelderman"; # user owning homebrew prefix
|
||||
|
||||
trust = {
|
||||
formulae = [];
|
||||
casks = [];
|
||||
commands = [];
|
||||
taps = ["rogeriopradoj/cask-peazip"];
|
||||
};
|
||||
};
|
||||
|
||||
homebrew = {
|
||||
enable = true;
|
||||
# removes anything in homebrew not explicitly specified
|
||||
onActivation = {
|
||||
cleanup = "zap";
|
||||
autoUpdate = false;
|
||||
upgrade = true;
|
||||
};
|
||||
|
||||
taps = [
|
||||
"rogeriopradoj/cask-peazip"
|
||||
];
|
||||
|
||||
brews = [
|
||||
"mas"
|
||||
"coreutils"
|
||||
"ctpv"
|
||||
"media-info"
|
||||
];
|
||||
casks = [
|
||||
"kitty"
|
||||
"linearmouse"
|
||||
"betterdisplay"
|
||||
"rectangle"
|
||||
"peazip"
|
||||
];
|
||||
masApps = {
|
||||
# "name" = app_id_number;
|
||||
"hiddenbar" = 1452453066;
|
||||
"testflight" = 899247664;
|
||||
};
|
||||
};
|
||||
# for mas to not throw rebuild fit
|
||||
|
||||
# since darwin needs root now (will be removed in future)
|
||||
system.primaryUser = "bhelderman";
|
||||
|
||||
power = {
|
||||
sleep = {
|
||||
computer = 30;
|
||||
display = 5;
|
||||
allowSleepByPowerButton = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
/*
|
||||
instructions for first time setup for macos here
|
||||
1. install the nix package manager with: `sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install)`
|
||||
2. install xcode tools with `xcode-select --install`
|
||||
3. allow full disk access to terminal
|
||||
4. xfer or git clone flake to ~/.nix
|
||||
5. sign into icloud and by extension app store for mas
|
||||
6. rename some shell rc files with `sudo mv /etc/bashrc /etc/bashrc.before-nix-darwin && sudo mv /etc/zshrc /etc/zshrc.before-nix-darwin`
|
||||
7. install nix-darwin with: `nix run --extra-experimental-features "nix-command flakes" nix-darwin -- switch --flake ~/.nix#host`
|
||||
8. nh should be installed now so enjoy and use `nh darwin switch`
|
||||
*/
|
||||
|
||||
imports = [
|
||||
];
|
||||
|
||||
# general macos system settings
|
||||
# base system package install list
|
||||
environment.systemPackages = with pkgs; [
|
||||
wget
|
||||
sl
|
||||
curl
|
||||
rsync
|
||||
git
|
||||
age
|
||||
fzf
|
||||
usbutils
|
||||
pciutils
|
||||
python3
|
||||
lf
|
||||
btop
|
||||
pinentry_mac
|
||||
];
|
||||
|
||||
users.users.bhelderman = {
|
||||
home = "/Users/bhelderman";
|
||||
# optional extras, e.g. shell, uid, etc.
|
||||
};
|
||||
|
||||
# define home-manager user
|
||||
home-manager = {
|
||||
extraSpecialArgs = {inherit inputs;};
|
||||
backupFileExtension = "bak";
|
||||
useUserPackages = true;
|
||||
useGlobalPkgs = false;
|
||||
users = {
|
||||
"bhelderman" = import ../../users/blake/home_darwin.nix;
|
||||
};
|
||||
};
|
||||
|
||||
# set timezone
|
||||
time.timeZone = "America/Chicago";
|
||||
|
||||
# allow proprietary packages
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# enable flakes
|
||||
nix.settings.experimental-features = ["nix-command" "flakes"];
|
||||
|
||||
system = {
|
||||
stateVersion = 6;
|
||||
defaults = {
|
||||
trackpad = {
|
||||
Clicking = true;
|
||||
TrackpadThreeFingerDrag = true;
|
||||
TrackpadFourFingerVertSwipeGesture = 2;
|
||||
TrackpadRightClick = true;
|
||||
TrackpadFourFingerHorizSwipeGesture = 2;
|
||||
TrackpadPinch = true;
|
||||
TrackpadRotate = true;
|
||||
TrackpadTwoFingerDoubleTapGesture = true;
|
||||
TrackpadTwoFingerFromRightEdgeSwipeGesture = 3;
|
||||
};
|
||||
universalaccess = {
|
||||
mouseDriverCursorSize = 3.0;
|
||||
};
|
||||
NSGlobalDomain = {
|
||||
AppleICUForce24HourTime = true;
|
||||
AppleInterfaceStyle = "Dark";
|
||||
NSAutomaticCapitalizationEnabled = false;
|
||||
NSDocumentSaveNewDocumentsToCloud = false;
|
||||
};
|
||||
WindowManager = {
|
||||
EnableStandardClickToShowDesktop = false;
|
||||
GloballyEnabled = false; # disable stage manager
|
||||
};
|
||||
controlcenter = {
|
||||
BatteryShowPercentage = true;
|
||||
Bluetooth = true;
|
||||
Display = false;
|
||||
FocusModes = false;
|
||||
NowPlaying = false;
|
||||
Sound = false;
|
||||
};
|
||||
menuExtraClock = {
|
||||
ShowDate = 1;
|
||||
ShowDayOfWeek = true;
|
||||
Show24Hour = true;
|
||||
ShowSeconds = true;
|
||||
};
|
||||
dock = {
|
||||
autohide = true;
|
||||
largesize = 16;
|
||||
mineffect = "genie";
|
||||
minimize-to-application = true;
|
||||
orientation = "bottom";
|
||||
scroll-to-open = true;
|
||||
show-recents = false;
|
||||
showAppExposeGestureEnabled = true;
|
||||
};
|
||||
finder = {
|
||||
AppleShowAllExtensions = true;
|
||||
NewWindowTarget = "Home";
|
||||
ShowPathbar = true;
|
||||
ShowStatusBar = true;
|
||||
};
|
||||
hitoolbox.AppleFnUsageType = "Change Input Source";
|
||||
iCal = {
|
||||
"first day of week" = "Monday";
|
||||
};
|
||||
loginwindow = {
|
||||
LoginwindowText = "howdy o/";
|
||||
GuestEnabled = false;
|
||||
};
|
||||
screencapture.type = "png";
|
||||
screensaver = {
|
||||
askForPassword = true;
|
||||
askForPasswordDelay = 15;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
|
||||
imports = [
|
||||
inputs.autoaspm.nixosModules.default
|
||||
];
|
||||
|
||||
# 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;
|
||||
|
||||
# power management
|
||||
services.autoaspm.enable = true;
|
||||
powerManagement.powertop.enable = true;
|
||||
|
||||
# enable flakes
|
||||
nix.settings.experimental-features = ["nix-command" "flakes"];
|
||||
users.defaultUserShell = pkgs.zsh;
|
||||
|
||||
# passwordless rebuild
|
||||
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"];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
unstable_pkgs,
|
||||
...
|
||||
}: {
|
||||
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;
|
||||
users.root = {
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO06en1r4+zg8JMGPq7WiZeh/DBUvfhDJX3e+J5Z5Ttk blake@snowbelle"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP0FLKK9yEPYpGuCjoX0e7Ky/zTPfzDk7IkrR3tOmELP blake@vaniville"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# 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
|
||||
smartmontools
|
||||
unstable.siomon
|
||||
];
|
||||
|
||||
# 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"];
|
||||
}
|
||||
{
|
||||
command = "/run/current-system/sw/bin/rsync";
|
||||
options = ["NOPASSWD"];
|
||||
}
|
||||
{
|
||||
command = "/etc/profiles/per-user/blake/bin/lf";
|
||||
options = ["NOPASSWD"];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
extraConfig = ''
|
||||
Defaults insults
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
modulesPath,
|
||||
stable_pkgs,
|
||||
unstable_pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
#./hardware-configuration.nix
|
||||
./disko.nix
|
||||
../../nixos
|
||||
../../../users/blake
|
||||
../../../modules/system
|
||||
../../../modules/fileshares/holocron
|
||||
../../../modules/homelab
|
||||
#../../../modules/gameservers/srcds
|
||||
../../../modules/gameservers/minecraft_recpro
|
||||
../../../modules/gameservers/minecraft_modded
|
||||
../../../modules/gameservers/valheim
|
||||
];
|
||||
|
||||
home-manager.users.blake.imports = [
|
||||
../../../users/blake/hosts/lumiose.nix
|
||||
];
|
||||
|
||||
system = {
|
||||
ssh.enable = true;
|
||||
sops.enable = true;
|
||||
podman.enable = true;
|
||||
yubikey.enable = true;
|
||||
graphics = {
|
||||
enable = true;
|
||||
vendor = "amd";
|
||||
};
|
||||
keepalive = {
|
||||
enable = true;
|
||||
url = "https://up.holocron.blue/api/push/7DAcvsedwB?status=up&msg=fuckingvibing&ping=";
|
||||
};
|
||||
};
|
||||
|
||||
homelab = {
|
||||
enable = true;
|
||||
base_domain = "lumiose.holocron.blue";
|
||||
host_ip = "10.10.0.11";
|
||||
gitea.enable = false;
|
||||
glance.enable = true;
|
||||
immich = {
|
||||
enable = true;
|
||||
data_dir = "/holocron/srv/immich";
|
||||
backup = false;
|
||||
};
|
||||
vaultwarden.enable = false;
|
||||
#searx.enable = true;
|
||||
# home assistant
|
||||
home.enable = true;
|
||||
homebox.enable = true;
|
||||
# network
|
||||
tailscale.enable = true;
|
||||
caddy = {
|
||||
enable = true;
|
||||
keys = false;
|
||||
};
|
||||
dnsmasq.enable = true;
|
||||
# mediastack
|
||||
mediastack.enable = true;
|
||||
qbittorrent.vpn_inf = "enp34s0.69";
|
||||
# system
|
||||
backups.enable = true;
|
||||
motd.enable = true;
|
||||
msmtp.enable = true;
|
||||
uptime-kuma.enable = true;
|
||||
# # ai
|
||||
# ollama.enable = false;
|
||||
# open-webui.enable = false;
|
||||
wyoming.enable = true;
|
||||
};
|
||||
|
||||
holocron = {
|
||||
# copyparty.enable = false;
|
||||
syncthing.enable = true;
|
||||
ensure_perms.enable = false;
|
||||
offsite.enable = true;
|
||||
zfs.enable = true;
|
||||
smb.enable = true;
|
||||
nfs.enable = true;
|
||||
};
|
||||
|
||||
gameservers = {
|
||||
minecraft_recpro.enable = true;
|
||||
minecraft_modded.enable = false;
|
||||
valheim.enable = true;
|
||||
};
|
||||
|
||||
# boot (systemd is going on me)
|
||||
boot.loader.systemd-boot.enable = true; # systemd your pretty cool ya know
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
boot.initrd.systemd.enable = true; # better logging
|
||||
|
||||
# setup hostname and networking stack
|
||||
services.resolved = {
|
||||
enable = true;
|
||||
settings = {
|
||||
Resolve = {
|
||||
FallbackDNS = ["1.1.1.1" "9.9.9.9"];
|
||||
DNSOverTLS = "opportunistic";
|
||||
};
|
||||
};
|
||||
};
|
||||
networking = {
|
||||
hostName = "lumiose"; # hostname
|
||||
hostId = "007f0200";
|
||||
getaddrinfo = {
|
||||
enable = true;
|
||||
precedence = {
|
||||
"::ffff:0:0/96" = 100;
|
||||
};
|
||||
};
|
||||
networkmanager = {
|
||||
enable = true; # the goat
|
||||
dns = "systemd-resolved"; # the backup dancer!
|
||||
ensureProfiles.profiles = {
|
||||
vpn = {
|
||||
ipv4 = {
|
||||
method = "manual";
|
||||
addresses = "10.69.0.11/24";
|
||||
gateway = "10.69.0.1";
|
||||
};
|
||||
ethernet.mac-address = "02:ea:6c:3c:9f:cd";
|
||||
connection.type = "vlan";
|
||||
connection.id = "vpn";
|
||||
connection.interface-name = "enp34s0.69"; # or just "vpn-vlan"
|
||||
vlan.interface-name = "enp34s0.69"; # or just "vpn-vlan"
|
||||
vlan.parent = "enp34s0";
|
||||
vlan.id = 69;
|
||||
#ipv4.dns = "9.9.9.9";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hardware.bluetooth.enable = true;
|
||||
|
||||
# Open ports in the firewall.
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80 # set - http
|
||||
111 # set - portmapper for nfs
|
||||
443 # set - https
|
||||
137 # set - smb
|
||||
138 # set - smb
|
||||
139 # set - smb
|
||||
445 # set - smb
|
||||
1198
|
||||
1883 # set - mqtt
|
||||
2049 # set - nfs
|
||||
2222 # srv - syncthing
|
||||
5201 # iperf3
|
||||
];
|
||||
|
||||
networking.firewall.allowedUDPPorts = [51820];
|
||||
# Or disable the firewall altogether.
|
||||
networking.firewall.enable = true;
|
||||
|
||||
# hardware stuff
|
||||
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = ["kvm-amd"];
|
||||
boot.kernelParams = ["ipv6.disable=1"];
|
||||
boot.extraModulePackages = [];
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
|
||||
system.stateVersion = "25.05"; # stays here : )
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
disko.devices = {
|
||||
disk = {
|
||||
main = {
|
||||
type = "disk";
|
||||
device = "/dev/disk/by-id/nvme-SAMSUNG_MZVLB256HAHQ-000H2_S499NX0M112943"; # 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
stable_pkgs,
|
||||
unstable_pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
# Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
../../nixos
|
||||
../../../users/blake
|
||||
../../../modules/system
|
||||
../../../modules/homelab
|
||||
#../../../modules/fileshares/holocron
|
||||
#../../../modules/gameservers/minecraft_recpro
|
||||
../../../modules/gameservers/minecraft_modded
|
||||
];
|
||||
|
||||
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;
|
||||
vendor = "nvidia";
|
||||
};
|
||||
keepalive = {
|
||||
enable = true;
|
||||
url = "https://up.holocron.blue/api/push/kMoYviAuCL?status=up&msg=bigchilling&ping=";
|
||||
};
|
||||
};
|
||||
# holocron = {
|
||||
# ensure_perms.enable = true;
|
||||
# zfs.enable = true;
|
||||
# smb.enable = true;
|
||||
# nfs.enable = true;
|
||||
# };
|
||||
|
||||
homelab = {
|
||||
enable = true;
|
||||
base_domain = "snowbelle.holocron.blue";
|
||||
# services
|
||||
gitea.enable = false;
|
||||
glance.enable = false;
|
||||
immich.enable = false;
|
||||
vaultwarden.enable = false;
|
||||
#searx.enable = true;
|
||||
# home assistant
|
||||
home.enable = false;
|
||||
# network
|
||||
tailscale.enable = true;
|
||||
caddy.enable = false;
|
||||
dnsmasq.enable = false;
|
||||
# mediastack
|
||||
mediastack.enable = false;
|
||||
# system
|
||||
backups.enable = false;
|
||||
motd.enable = false;
|
||||
uptime-kuma.enable = false;
|
||||
# ai
|
||||
#ollama.enable = false;
|
||||
#open-webui.enable = false;
|
||||
wyoming.enable = false;
|
||||
};
|
||||
|
||||
gameservers = {
|
||||
# minecraft_recpro.enable = true;
|
||||
minecraft_modded = {
|
||||
enable = true;
|
||||
url = "raceraskedforthisenjoyyall.recoil.pro";
|
||||
};
|
||||
};
|
||||
|
||||
# boot (systemd is going on me)
|
||||
boot.loader.systemd-boot.enable = true; # systemd your pretty cool ya know
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
boot.initrd.systemd.enable = true; # better logging
|
||||
|
||||
# setup hostname and networking stack
|
||||
services.resolved = {
|
||||
enable = true;
|
||||
#fallbackDns = ["1.1.1.1" "9.9.9.9"];
|
||||
settings.Resolve.DNSOverTLS = "opportunistic";
|
||||
};
|
||||
networking = {
|
||||
hostName = "snowbelle"; # hostname
|
||||
hostId = "3e6e7055"; # zfs wants this
|
||||
networkmanager = {
|
||||
enable = true; # the goat
|
||||
dns = "systemd-resolved"; # the backup dancer!
|
||||
ensureProfiles.profiles = {
|
||||
vpn = {
|
||||
ethernet.mac-address = "7a:e4:07:8d:22:76";
|
||||
connection.type = "vlan";
|
||||
connection.id = "vpn";
|
||||
connection.interface-name = "enp89s0.69"; # or just "vpn-vlan"
|
||||
vlan.interface-name = "enp89s0.69"; # or just "vpn-vlan"
|
||||
vlan.parent = "enp89s0";
|
||||
vlan.id = 69;
|
||||
#ipv4.dns = "9.9.9.9";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
hardware.bluetooth.enable = true;
|
||||
|
||||
# Open ports in the firewall.
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80 # set - http
|
||||
111 # set - portmapper for nfs
|
||||
139 # set - smb
|
||||
443 # set - https
|
||||
445 # set - cifs
|
||||
5201
|
||||
1198
|
||||
1883 # set - mqtt
|
||||
2049 # set - nfs
|
||||
2222 # srv - syncthing
|
||||
7100 # srv - jellyfin
|
||||
7101 # srv - audiobookshelf
|
||||
7102 # srv - yacreader
|
||||
7103 # srv - qbittorrent
|
||||
7104 # srv - prowlarr
|
||||
7105 # srv - bazarr
|
||||
7106 # srv - sonarr
|
||||
7107 # srv - radarr
|
||||
7120 # srv - flaresolverr
|
||||
5701 # srv - archivebox
|
||||
7502 # srv - kiwix
|
||||
7567 # srv - gitea ssh
|
||||
7700 # srv - glance
|
||||
7701 # srv - vaultwarden
|
||||
7702 # srv - immich
|
||||
7703 # srv - gitea
|
||||
7704 # srv - hass
|
||||
7705 # srv - zigbee2mqtt
|
||||
7901 # srv - uptime kuma
|
||||
7902 # srv - copyparty
|
||||
25777 # srv - minecraft
|
||||
25565 # ^ ^ ^
|
||||
25566 # | | |
|
||||
25567 # | | |
|
||||
];
|
||||
|
||||
networking.firewall.allowedUDPPorts = [51820];
|
||||
# Or disable the firewall altogether.
|
||||
networking.firewall.enable = true;
|
||||
|
||||
system.stateVersion = "25.05"; # stays here : )
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs,
|
||||
stable_pkgs,
|
||||
unstable_pkgs,
|
||||
...
|
||||
}: let
|
||||
vpsip4 = "100.100.1.10";
|
||||
snowbelle_ip = "10.10.0.10";
|
||||
lumiose_ip = "10.10.0.11";
|
||||
|
||||
homelab = config.homelab;
|
||||
in {
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../nixos
|
||||
../../../users/blake
|
||||
../../../modules/system
|
||||
../../../modules/homelab
|
||||
#../../../modules/holocron
|
||||
];
|
||||
|
||||
home-manager.users.blake.imports = [
|
||||
../../../users/blake/hosts/vaniville.nix
|
||||
];
|
||||
|
||||
system = {
|
||||
tailscale.enable = false;
|
||||
};
|
||||
homelab = {
|
||||
enable = true;
|
||||
base_domain = "vaniville.holocron.blue";
|
||||
host_ip = "100.100.1.10";
|
||||
ddns.enable = true;
|
||||
uptime-kuma = {
|
||||
enable = true;
|
||||
url = "up.holocron.blue";
|
||||
};
|
||||
caddy = {
|
||||
enable = true;
|
||||
keys = true;
|
||||
};
|
||||
backups = {
|
||||
enable = true;
|
||||
databases = false;
|
||||
homelab = true;
|
||||
backup_repo = "/var/lib/backups/homelab";
|
||||
offsite_dir = "lifeboat/vaniville/homelab";
|
||||
};
|
||||
gitea.enable = true;
|
||||
vaultwarden.enable = true;
|
||||
home.enable = false;
|
||||
};
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
efi.canTouchEfiVariables = true;
|
||||
grub = {
|
||||
enable = true;
|
||||
forceInstall = true;
|
||||
};
|
||||
};
|
||||
kernel.sysctl = {
|
||||
"net.ipv4.ip_forward" = 1;
|
||||
};
|
||||
};
|
||||
|
||||
# define shell
|
||||
programs.zsh.enable = true;
|
||||
users.defaultUserShell = pkgs.zsh;
|
||||
|
||||
# packages reccomended by linode
|
||||
environment.systemPackages = with pkgs; [
|
||||
inetutils
|
||||
mtr
|
||||
sysstat
|
||||
];
|
||||
|
||||
# services.resolved = {
|
||||
# enable = true;
|
||||
# settings = {
|
||||
# Resolve = {
|
||||
# FallbackDNS = ["1.1.1.1" "9.9.9.9"];
|
||||
# DNSOverTLS = "opportunistic";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
|
||||
# setup the network forwarding this host is designed for
|
||||
# general networking config
|
||||
networking = {
|
||||
hostName = "vaniville"; # Define your hostname.
|
||||
usePredictableInterfaceNames = false;
|
||||
useDHCP = false;
|
||||
interfaces.eth0.useDHCP = true; # public ipv4 interface
|
||||
|
||||
# the proper way to forward ports on nixos, need to figure it out locally then try to get it working over vps
|
||||
nat = {
|
||||
enable = true;
|
||||
externalInterface = "eth0"; # your PUBLIC_IF
|
||||
internalInterfaces = ["tailscale0"];
|
||||
# maybe one day i will figure out the forward ports proper
|
||||
forwardPorts = [
|
||||
# { sourcePort = 80; destination = "10.10.0.10:80"; proto = "tcp"; } # http
|
||||
# { sourcePort = 443; destination = "10.10.0.10:443"; proto = "tcp"; } # https
|
||||
# { sourcePort = 25777; destination = "10.10.0.10:25777"; proto = "tcp"; } # minecraft
|
||||
# { sourcePort = 25777; destination = "10.10.0.10:25777"; proto = "udp"; } # minecraft
|
||||
# { sourcePort = 7567; destination = "10.10.0.10:7567"; proto = "tcp"; } # git
|
||||
|
||||
# Rustdesk ports
|
||||
# { sourcePort = 21115; destination = "10.10.0.10:21115"; proto = "tcp"; }
|
||||
# { sourcePort = 21116; destination = "10.10.0.10:21116"; proto = "tcp"; }
|
||||
# { sourcePort = 21116; destination = "10.10.0.10:21116"; proto = "udp"; }
|
||||
# { sourcePort = 21118; destination = "10.10.0.10:21118"; proto = "tcp"; }
|
||||
# { sourcePort = 21117; destination = "10.10.0.10:21117"; proto = "tcp"; }
|
||||
# { sourcePort = 21119; destination = "10.10.0.10:21119"; proto = "tcp"; }
|
||||
];
|
||||
};
|
||||
|
||||
# what actually does the forwarding
|
||||
firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [22 80 443 25777 25579 7567 21115 21116 21117 21118 21119];
|
||||
# tailscale will also need its UDP port open:
|
||||
allowedUDPPorts = [config.services.tailscale.port 2456 2457 25777 21116 25580];
|
||||
trustedInterfaces = ["tailscale0"];
|
||||
/*
|
||||
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination ${snowbelle_ip}:80 # http
|
||||
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination ${snowbelle_ip}:443 # https
|
||||
|
||||
iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 80 -d ${snowbelle_ip}/32 -j SNAT --to-source ${vpsip4} # http
|
||||
iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 443 -d ${snowbelle_ip}/32 -j SNAT --to-source ${vpsip4} # https
|
||||
*/
|
||||
|
||||
# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 7567 -j DNAT --to-destination ${lumiose_ip}:7567 # gitea ssh
|
||||
# iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 7567 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # gitea ssh
|
||||
|
||||
extraCommands = ''
|
||||
# Clear any previous rules if you are iterating
|
||||
iptables -t nat -F
|
||||
|
||||
# DNAT: internet -> homelab over tailscale
|
||||
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25777 -j DNAT --to-destination ${lumiose_ip}:25777 # recpro mc
|
||||
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 25777 -j DNAT --to-destination ${lumiose_ip}:25777 # recpro mc
|
||||
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25579 -j DNAT --to-destination ${snowbelle_ip}:25579 # craftoria mc
|
||||
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 25580 -j DNAT --to-destination ${snowbelle_ip}:25580 # craftoria mc voice chat
|
||||
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 2456 -j DNAT --to-destination ${lumiose_ip}:2456 # valheim server
|
||||
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 2457 -j DNAT --to-destination ${lumiose_ip}:2457 # valheim server
|
||||
|
||||
# SNAT: ensure replies go back through VPS tailscale IP
|
||||
iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 25777 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # recpro mc
|
||||
iptables -t nat -A POSTROUTING -o tailscale0 -p udp --dport 25777 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # recpro mc
|
||||
iptables -t nat -A POSTROUTING -o tailscale0 -p tcp --dport 25579 -d ${snowbelle_ip}/32 -j SNAT --to-source ${vpsip4} # craftoria mc
|
||||
iptables -t nat -A POSTROUTING -o tailscale0 -p udp --dport 25580 -d ${snowbelle_ip}/32 -j SNAT --to-source ${vpsip4} # craftoria mc voicechat
|
||||
iptables -t nat -A POSTROUTING -o tailscale0 -p udp --dport 2456 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # valheim server
|
||||
iptables -t nat -A POSTROUTING -o tailscale0 -p udp --dport 2457 -d ${lumiose_ip}/32 -j SNAT --to-source ${vpsip4} # valheim server
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
# enable tailscale for to forward over!
|
||||
services.tailscale = {
|
||||
enable = true;
|
||||
useRoutingFeatures = "server";
|
||||
extraSetFlags = [
|
||||
"--advertise-exit-node"
|
||||
];
|
||||
};
|
||||
|
||||
# forwarding for caddy
|
||||
services.caddy = {
|
||||
globalConfig = ''
|
||||
auto_https ignore_loaded_certs
|
||||
'';
|
||||
virtualHosts = {
|
||||
# for central uptime monitoring
|
||||
"up.${homelab.public_domain}".extraConfig = ''
|
||||
reverse_proxy 127.0.0.1:7901
|
||||
'';
|
||||
# below is basically just manually reverse proxying everything in the homelab
|
||||
# this is instead of forwarding all 80 & 443 traffic to have more explicit
|
||||
# publishing things to the open web
|
||||
"media.${homelab.public_domain}".extraConfig = ''
|
||||
reverse_proxy ${lumiose_ip}:7100
|
||||
'';
|
||||
"photos.${homelab.public_domain}".extraConfig = ''
|
||||
reverse_proxy ${lumiose_ip}:7702
|
||||
'';
|
||||
"hass.${homelab.public_domain}".extraConfig = ''
|
||||
reverse_proxy ${lumiose_ip}:7704 {
|
||||
header_up Host {host}
|
||||
header_up X-Real-IP {remote_host}
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
header_up X-Forwarded-Proto https
|
||||
}
|
||||
'';
|
||||
# now hosted on vaniville!
|
||||
# "pass.${homelab.public_domain}".extraConfig = ''
|
||||
# reverse_proxy 127.0.0.1:7701
|
||||
# '';
|
||||
# "git.${homelab.public_domain}".extraConfig = ''
|
||||
# reverse_proxy localhost:7703
|
||||
# '';
|
||||
};
|
||||
};
|
||||
|
||||
system.stateVersion = "25.05"; # Did you read the comment?
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot.kernelParams = [ "console=ttyS0,19200n8" ];
|
||||
boot.loader.grub.device = "nodev";
|
||||
boot.loader.timeout = 10;
|
||||
boot.loader.grub.extraConfig = ''
|
||||
serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1;
|
||||
terminal_input serial;
|
||||
terminal_output serial
|
||||
'';
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/sda";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/sdb"; }
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
{ config, lib, stable_pkgs, unstable_pkgs, ... }:
|
||||
|
||||
let
|
||||
pkgs = stable_pkgs.x86_64;
|
||||
unstable = unstable_pkgs.x86_64;
|
||||
in
|
||||
{
|
||||
imports =
|
||||
[
|
||||
./hardware-configuration.nix
|
||||
../../nixos
|
||||
../../../users/blake
|
||||
../../../modules/system
|
||||
#../../../modules/homelab
|
||||
];
|
||||
|
||||
home-manager.users.blake.imports = [
|
||||
../../../users/blake/hosts/wsl.nix
|
||||
];
|
||||
|
||||
wsl = {
|
||||
enable = true;
|
||||
defaultUser = "blake";
|
||||
};
|
||||
|
||||
system = {
|
||||
ssh.enable = true;
|
||||
sops.enable = true;
|
||||
};
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
efi.canTouchEfiVariables = true;
|
||||
grub = {
|
||||
enable = true;
|
||||
forceInstall = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# define shell
|
||||
programs.zsh.enable = true;
|
||||
users.defaultUserShell = pkgs.zsh;
|
||||
|
||||
# packages reccomended by linode
|
||||
environment.systemPackages = with pkgs; [
|
||||
];
|
||||
|
||||
# setup the network forwarding this host is designed for
|
||||
# general networking config
|
||||
networking = {
|
||||
hostName = "zygarde"; # Define your hostname.
|
||||
};
|
||||
|
||||
system.stateVersion = "25.05"; # Did you read the comment?
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
{
|
||||
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 = false;
|
||||
tailscale.enable = true;
|
||||
syncthing.enable = true;
|
||||
flatpak.enable = true;
|
||||
graphics = {
|
||||
enable = true;
|
||||
vendor = "intel";
|
||||
};
|
||||
};
|
||||
desktop = {
|
||||
pipewire.enable = true;
|
||||
hypr.enable = false;
|
||||
greetd.enable = true;
|
||||
kde.enable = true;
|
||||
};
|
||||
gaming = {
|
||||
steam.enable = true;
|
||||
lutris.enable = false;
|
||||
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.settings.Sleep = {
|
||||
HibernateDelaySec = "30m";
|
||||
};
|
||||
|
||||
# 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;
|
||||
settings = {
|
||||
Resolve = {
|
||||
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;
|
||||
}
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
{ config, lib, stable_pkgs, unstable_pkgs, ... }:
|
||||
|
||||
let
|
||||
pkgs = stable_pkgs.x86_64;
|
||||
unstable = unstable_pkgs.x86_64;
|
||||
in
|
||||
{
|
||||
imports =
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
../../hosts
|
||||
../../users/blake
|
||||
../../modules/system
|
||||
../../modules/holocron
|
||||
../../modules/homelab
|
||||
../../modules/homelab/minecraft_recpro
|
||||
];
|
||||
|
||||
system = {
|
||||
ssh.enable = true;
|
||||
backups.enable = true;
|
||||
backups.repo = "/holocron/archives/servers/snowbelle";
|
||||
sops.enable = true;
|
||||
podman.enable = true;
|
||||
yubikey.enable = true;
|
||||
syncthing.enable = true;
|
||||
tailscale.enable = true;
|
||||
nvidia.enable = true;
|
||||
};
|
||||
holocron = {
|
||||
copyparty.enable = true;
|
||||
ensure_perms.enable = true;
|
||||
zfs.enable = true;
|
||||
smb.enable = true;
|
||||
nfs.enable = true;
|
||||
};
|
||||
homelab = {
|
||||
enable = true;
|
||||
motd.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;
|
||||
};
|
||||
|
||||
# boot (systemd is going on me)
|
||||
boot.loader.systemd-boot.enable = true; # systemd your pretty cool ya know
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
boot.initrd.systemd.enable = true; # better logging
|
||||
|
||||
# setup hostname and networking stack
|
||||
services.resolved = {
|
||||
enable = true;
|
||||
fallbackDns = [ "1.1.1.1" "9.9.9.9" ];
|
||||
dnsovertls = "opportunistic";
|
||||
};
|
||||
networking = {
|
||||
hostName = "snowbelle"; # hostname
|
||||
hostId = "3e6e7055"; # zfs wants this
|
||||
networkmanager = {
|
||||
enable = true; # the goat
|
||||
dns = "systemd-resolved"; # the backup dancer!
|
||||
ensureProfiles.profiles = {
|
||||
vpn = {
|
||||
ethernet.mac-address = "7a:e4:07:8d:22:76";
|
||||
connection.type = "vlan";
|
||||
connection.id = "vpn";
|
||||
connection.interface-name = "enp89s0.69"; # or just "vpn-vlan"
|
||||
vlan.interface-name = "enp89s0.69"; # or just "vpn-vlan"
|
||||
vlan.parent = "enp89s0";
|
||||
vlan.id = 69;
|
||||
#ipv4.dns = "9.9.9.9";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
hardware.bluetooth.enable = true;
|
||||
|
||||
|
||||
|
||||
# Open ports in the firewall.
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80 # set - http
|
||||
111 # set - portmapper for nfs
|
||||
139 # set - smb
|
||||
443 # set - https
|
||||
445 # set - cifs
|
||||
1198
|
||||
1883 # set - mqtt
|
||||
2049 # set - nfs
|
||||
2222 # srv - syncthing
|
||||
7100 # srv - jellyfin
|
||||
7101 # srv - audiobookshelf
|
||||
7102 # srv - yacreader
|
||||
7103 # srv - qbittorrent
|
||||
7104 # srv - prowlarr
|
||||
7105 # srv - bazarr
|
||||
7106 # srv - sonarr
|
||||
7107 # srv - radarr
|
||||
7120 # srv - flaresolverr
|
||||
5701 # srv - archivebox
|
||||
7502 # srv - kiwix
|
||||
7567 # srv - gitea ssh
|
||||
7700 # srv - glance
|
||||
7701 # srv - vaultwarden
|
||||
7702 # srv - immich
|
||||
7703 # srv - gitea
|
||||
7704 # srv - hass
|
||||
7705 # srv - zigbee2mqtt
|
||||
7901 # srv - uptime kuma
|
||||
7902 # srv - copyparty
|
||||
25777 # srv - minecraft
|
||||
25565 # ^ ^ ^
|
||||
25566 # | | |
|
||||
25567 # | | |
|
||||
];
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
||||
# Or disable the firewall altogether.
|
||||
networking.firewall.enable = true;
|
||||
|
||||
system.stateVersion = "25.05"; # Did you read the comment?
|
||||
|
||||
}
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
{ config, lib, stable_pkgs, unstable_pkgs, ... }:
|
||||
|
||||
let
|
||||
pkgs = stable_pkgs.x86_64;
|
||||
unstable = unstable_pkgs.x86_64;
|
||||
in
|
||||
{
|
||||
imports =
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
../../users/users.nix
|
||||
../../modules/system
|
||||
];
|
||||
|
||||
modules = {
|
||||
system = {
|
||||
tailscale.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
# use the systemd-boot EFI boot loader.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
# setup hostname and networking stack
|
||||
networking.hostName = "vaniville"; # Define your hostname.
|
||||
networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
|
||||
|
||||
# set timezone
|
||||
time.timeZone = "America/Chicago";
|
||||
|
||||
# define shell
|
||||
programs.zsh.enable = true;
|
||||
users.defaultUserShell = pkgs.zsh;
|
||||
|
||||
# package install list
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
rsync
|
||||
wget
|
||||
git
|
||||
iptables
|
||||
nettools
|
||||
neofetch
|
||||
btop
|
||||
];
|
||||
|
||||
# allow proprietary packages
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
|
||||
# enable flakes
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
|
||||
# Open ports in the firewall.
|
||||
networking.firewall.enable = true;
|
||||
networking.firewall.extraCommands = ''
|
||||
HOMELAB_IP="10.10.0.10" # destination address
|
||||
PUBLIC_IF="eth0" # vps public interface
|
||||
TAILSCALE_IF="tailscale0" # tailscale interface
|
||||
|
||||
# flush rules (avoid dupes)
|
||||
iptables -F
|
||||
iptables -t nat -F
|
||||
iptables -t mangle -F
|
||||
iptables -X
|
||||
|
||||
# set defualt policies
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
|
||||
# allow loopback
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
iptables -A OUTPUT -o lo -j ACCEPT
|
||||
|
||||
# allow replys
|
||||
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
# allow vps outbound
|
||||
iptables -A OUTPUT -o eth0 -j ACCEPT
|
||||
|
||||
# general settings
|
||||
sysctl -w net.ipv4.ip_forward=1 # enable ip forwarding
|
||||
iptables -t nat -A POSTROUTING -o $TAILSCALE_IF -j MASQUERADE # postrouting masquerade (outgoing packets appear to come from vps tailscale ip)
|
||||
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # allows pings
|
||||
iptables -A INPUT -p tcp --dport 22 -j ACCEPT # allows ssh
|
||||
|
||||
|
||||
# --- minecraft ---
|
||||
# port: 25777 tcp & udp
|
||||
# prerouting:
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 25777 -j DNAT --to-destination $HOMELAB_IP:25777 # tcp packets on port 25777
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p udp --dport 25777 -j DNAT --to-destination $HOMELAB_IP:25777 # udp packets on port 25777
|
||||
# forwards:
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 25777 -j ACCEPT # vps -> homelab: tcp on port 25777
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p udp --dport 25777 -j ACCEPT # vps -> homelab: udp on port 25777
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 25777 -j ACCEPT # homelab -> vps: tcp on port 25777
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p udp --sport 25777 -j ACCEPT # homelab -> vps: udp on port 25777
|
||||
|
||||
# --- reverse proxy ---
|
||||
# ports: 80 & 443 tcp
|
||||
# prerouting:
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 80 -j DNAT --to-destination $HOMELAB_IP:80 # tcp packets on port 80
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 443 -j DNAT --to-destination $HOMELAB_IP:443 # tcp packets on port 443
|
||||
# forwards:
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 80 -j ACCEPT # vps -> homelab: tcp on port 80
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 80 -j ACCEPT # homelab -> vps: tcp on port 80
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 443 -j ACCEPT # vps -> homelab: tcp on port 443
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 443 -j ACCEPT # homelab -> vps: tcp on port 443
|
||||
|
||||
# --- gitea ssh ---
|
||||
# port: 7567 tcp
|
||||
# prerouting:
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 7567 -j DNAT --to-destination $HOMELAB_IP:7567 # tcp packets on port 7567
|
||||
# forwards:
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 7567 -j ACCEPT # vps -> homelab: tcp on port 7567
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 7567 -j ACCEPT # homelab -> vps: tcp on port 7567
|
||||
|
||||
# --- rustdesk ---
|
||||
# ports 2114-2119
|
||||
# hbbs ports
|
||||
# 21115 tcp (nat type test)
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21115 -j DNAT --to-destination $HOMELAB_IP:21115 # tcp packets on port 21115
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21115 -j ACCEPT # vps -> homelab: tcp on port 21115
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21115 -j ACCEPT # homelab -> vps: tcp on port 21115
|
||||
# 21116 tcp&udp (id registration, heartbeat, TCP hole punching)
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21116 -j DNAT --to-destination $HOMELAB_IP:21116 # tcp packets on port 21116
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21116 -j ACCEPT # vps -> homelab: tcp on port 21116
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21116 -j ACCEPT # homelab -> vps: tcp on port 21116
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p udp --dport 21116 -j DNAT --to-destination $HOMELAB_IP:21116 # udp packets on port 21116
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p udp --dport 21116 -j ACCEPT # vps -> homelab: tcp on port 21116
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p udp --sport 21116 -j ACCEPT # homelab -> vps: tcp on port 21116
|
||||
# 21118 tcp (web client support)
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21118 -j DNAT --to-destination $HOMELAB_IP:21118 # tcp packets on port 21118
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21118 -j ACCEPT # vps -> homelab: tcp on port 21118
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21118 -j ACCEPT # homelab -> vps: tcp on port 21118
|
||||
# hbbr ports
|
||||
# 21117 tcp (relay services)
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21117 -j DNAT --to-destination $HOMELAB_IP:21117 # tcp packets on port 21117
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21117 -j ACCEPT # vps -> homelab: tcp on port 21117
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21117 -j ACCEPT # homelab -> vps: tcp on port 21117
|
||||
# 21119 tcp (web client support)
|
||||
iptables -t nat -A PREROUTING -i $PUBLIC_IF -p tcp --dport 21119 -j DNAT --to-destination $HOMELAB_IP:21119 # tcp packets on port 21119
|
||||
iptables -A FORWARD -i $PUBLIC_IF -o $TAILSCALE_IF -p tcp --dport 21119 -j ACCEPT # vps -> homelab: tcp on port 21119
|
||||
iptables -A FORWARD -i $TAILSCALE_IF -o $PUBLIC_IF -p tcp --sport 21119 -j ACCEPT
|
||||
'';
|
||||
|
||||
|
||||
system.stateVersion = "25.05"; # Did you read the comment?
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "apps";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
options.darwin.${service} = {
|
||||
enable = lib.mkEnableOption "installs generally wanted apps";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# open-webui
|
||||
# ];
|
||||
|
||||
homebrew = {
|
||||
brews = [
|
||||
"iperf3"
|
||||
"p7zip"
|
||||
"sl"
|
||||
"cowsay"
|
||||
"apfel"
|
||||
"yt-dlp"
|
||||
"ffmpeg"
|
||||
"ffmpeg-full"
|
||||
];
|
||||
casks = [
|
||||
"gnucash"
|
||||
"utm"
|
||||
"libreoffice"
|
||||
"firefox"
|
||||
"zen"
|
||||
"grandperspective"
|
||||
"spotify"
|
||||
"obs"
|
||||
"gimp"
|
||||
"audacity"
|
||||
"anki"
|
||||
"rustdesk"
|
||||
"mullvad-vpn"
|
||||
"transmission"
|
||||
"finetune"
|
||||
"yacreader"
|
||||
"keepassxc"
|
||||
"thunderbird"
|
||||
"musicbrainz-picard"
|
||||
];
|
||||
masApps = {
|
||||
"pages" = 361309726;
|
||||
"numbers" = 361304891;
|
||||
"keynote" = 361285480;
|
||||
"bitwarden" = 1352778147;
|
||||
"darkreader" = 1438243180;
|
||||
"ghostery" = 6504861501;
|
||||
"privacy" = 6449850851;
|
||||
"flo" = 6529533140;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
service = "cyber";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
options.darwin.${service} = {
|
||||
enable = lib.mkEnableOption "install cyber sec apps";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
metasploit
|
||||
];
|
||||
|
||||
homebrew = {
|
||||
brews = [
|
||||
"nmap"
|
||||
"rustscan"
|
||||
"masscan"
|
||||
"nikto"
|
||||
"aircrack-ng"
|
||||
"hashcat"
|
||||
"john"
|
||||
"sqlmap"
|
||||
"gobuster"
|
||||
"ffuf"
|
||||
|
||||
];
|
||||
casks = [
|
||||
"wireshark-app"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./tailscale
|
||||
./nextdns
|
||||
./syncthing
|
||||
./yubikey
|
||||
./work
|
||||
./apps
|
||||
./cyber
|
||||
./gaming
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "gaming";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
options.darwin.${service} = {
|
||||
enable = lib.mkEnableOption "installs generally wanted apps";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# uhhh
|
||||
# ];
|
||||
|
||||
homebrew = {
|
||||
brews = [
|
||||
];
|
||||
casks = [
|
||||
"steam"
|
||||
"prismlauncher"
|
||||
"discord"
|
||||
# "runelite"
|
||||
# "jagex"
|
||||
];
|
||||
masApps = {
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
service = "nextdns";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
options.darwin.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.${service} = {
|
||||
enable = true;
|
||||
arguments = [
|
||||
"-profile 527db2"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
service = "sops";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
imports = [inputs.sops-nix.nixosModules.sops];
|
||||
|
||||
options.darwin.sops = {
|
||||
enable = lib.mkEnableOption "enables sops";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# enable and configure sops for secrets
|
||||
sops = {
|
||||
defaultSopsFile = ../../../secrets/secrets.yaml;
|
||||
defaultSopsFormat = "yaml";
|
||||
age.keyFile = "/etc/sops/keys.txt";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
service = "syncthing";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
|
||||
options.darwin.${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 {
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# syncthing
|
||||
# syncthingtray
|
||||
# ];
|
||||
#
|
||||
homebrew = {
|
||||
# brews = [
|
||||
# "syncthing"
|
||||
# ];
|
||||
casks = [
|
||||
"syncthing-app"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
service = "tailscale";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
options.darwin.tailscale = {
|
||||
enable = lib.mkEnableOption "enables tailscale";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# services.tailscale = {
|
||||
# enable = true;
|
||||
# #overrideLocalDns = true;
|
||||
# #authKeyFile = authkey_file;
|
||||
# };
|
||||
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# tailscale-gui
|
||||
# ];
|
||||
|
||||
# homebrew = {
|
||||
# casks = [
|
||||
# "tailscale-app"
|
||||
# ];
|
||||
# };
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
service = "work";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
options.darwin.work = {
|
||||
enable = lib.mkEnableOption "installs apps for work";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# services.tailscale = {
|
||||
# enable = true;
|
||||
# #overrideLocalDns = true;
|
||||
# #authKeyFile = authkey_file;
|
||||
# };
|
||||
|
||||
homebrew = {
|
||||
casks = [
|
||||
"asana"
|
||||
"microsoft-teams"
|
||||
"microsoft-office"
|
||||
"jump-desktop"
|
||||
"wifiman"
|
||||
"adobe-acrobat-pro"
|
||||
];
|
||||
masApps = {
|
||||
"configurator" = 1037126344;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
service = "yubikey";
|
||||
cfg = config.darwin.${service};
|
||||
in {
|
||||
options.darwin.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# yubikey-personalization
|
||||
# yubikey-manager
|
||||
# yubikey-piv-tool
|
||||
# ];
|
||||
|
||||
homebrew = {
|
||||
brews = [
|
||||
"yubico-piv-tool"
|
||||
];
|
||||
casks = [
|
||||
"yubico-authenticator"
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./pipewire
|
||||
./hypr
|
||||
./greetd
|
||||
./gaming
|
||||
./kde
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
inputs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
inputs.slippi.nixosModules.default # gcc drivers
|
||||
./steam
|
||||
./lutris
|
||||
./proton_ge
|
||||
./gamemode
|
||||
./mangohud
|
||||
];
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
cfg = config.desktop.kde;
|
||||
in {
|
||||
options.desktop.kde = {
|
||||
enable = lib.mkEnableOption "enable kde on nixos side";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# enable kde plasma
|
||||
services = {
|
||||
desktopManager.plasma6.enable = true;
|
||||
#displayManager.sddm.enable = true;
|
||||
#displayManager.sddm.wayland.enable = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
# KDE Utilities
|
||||
kdePackages.discover # Optional: Software center for Flatpaks/firmware updates
|
||||
kdePackages.kcalc # Calculator
|
||||
kdePackages.kcharselect # Character map
|
||||
kdePackages.kclock # Clock app
|
||||
kdePackages.kcolorchooser # Color picker
|
||||
kdePackages.kolourpaint # Simple paint program
|
||||
kdePackages.ksystemlog # System log viewer
|
||||
kdePackages.sddm-kcm # SDDM configuration module
|
||||
kdiff3 # File/directory comparison tool
|
||||
|
||||
# Hardware/System Utilities (Optional)
|
||||
kdePackages.isoimagewriter # Write hybrid ISOs to USB
|
||||
kdePackages.partitionmanager # Disk and partition management
|
||||
hardinfo2 # System benchmarks and hardware info
|
||||
wayland-utils # Wayland diagnostic tools
|
||||
wl-clipboard # Wayland copy/paste support
|
||||
vlc # Media player
|
||||
];
|
||||
|
||||
environment.plasma6.excludePackages = with pkgs; [
|
||||
kdePackages.elisa # Music player
|
||||
kdePackages.kdepim-runtime # Akonadi agents
|
||||
kdePackages.kmahjongg
|
||||
#kdePackages.kmines
|
||||
kdePackages.konversation # IRC client
|
||||
kdePackages.kpat # Solitaire
|
||||
kdePackages.ksudoku
|
||||
kdePackages.ktorrent
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
# services show up in glance in reverse import order lmao
|
||||
imports = [
|
||||
./nfs
|
||||
./smb
|
||||
./zfs
|
||||
./syncthing
|
||||
./offsite
|
||||
# ./copyparty
|
||||
./perms
|
||||
];
|
||||
|
||||
# # define the groups used for backups and archives
|
||||
# users.users.archives = {
|
||||
# isSystemUser = true;
|
||||
# group = "archives";
|
||||
# };
|
||||
#
|
||||
# users.groups.archives = {gid = 727;};
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "offsite";
|
||||
cfg = config.holocron.${service};
|
||||
sec = config.sops.secrets;
|
||||
in {
|
||||
options.holocron.offsite = {
|
||||
enable = lib.mkEnableOption "enables backup script for holocron fileshare";
|
||||
paths = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [
|
||||
"/holocron/srv"
|
||||
"/holocron/users"
|
||||
];
|
||||
description = "list of paths to backup";
|
||||
};
|
||||
offsite_user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat";
|
||||
description = "user to connect to offsite host with";
|
||||
};
|
||||
offsite_target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat.holocron.blue";
|
||||
description = "ip or domain for offsite backups";
|
||||
};
|
||||
offsite_dir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat/holocron";
|
||||
description = "path to rsync offsite backups to";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.${service} = {
|
||||
description = "holocron daily sync";
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
Group = "archives";
|
||||
};
|
||||
|
||||
script = ''
|
||||
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
|
||||
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
|
||||
-e "${pkgs.openssh}/bin/ssh -o StrictHostKeyChecking=no" \
|
||||
${builtins.concatStringsSep " " cfg.paths} \
|
||||
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.${service} = {
|
||||
description = "timer for ${service}";
|
||||
|
||||
wantedBy = ["timers.target"];
|
||||
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 05:00:00";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -29,20 +29,23 @@ in {
|
||||
# Fix ownership for archives directory
|
||||
echo "starting ${archives_path}"
|
||||
chown -Rc root:archives ${archives_path}
|
||||
chmod -Rc 2770 ${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}
|
||||
chmod -Rc 2770 ${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"
|
||||
chmod -Rc 700 "$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"
|
||||
@@ -0,0 +1,130 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
# define smb shares
|
||||
let
|
||||
cfg = config.holocron.smb;
|
||||
smb_shares = {
|
||||
global = {
|
||||
# time machine specifc config, must be global
|
||||
"fruit:aapl" = "yes";
|
||||
"fruit:nfs_aces" = "no";
|
||||
"fruit:metadata" = "stream";
|
||||
"fruit:model" = "TimeCapsule";
|
||||
"fruit:posix_rename" = "yes";
|
||||
"fruit:veto_appledouble" = "no";
|
||||
"fruit:wipe_intentionally_left_blank_rfork" = "yes";
|
||||
"fruit:delete_empty_adfiles" = "yes";
|
||||
"vfs objects" = "catia fruit streams_xattr";
|
||||
"ea support" = "yes";
|
||||
"spotlight" = "no";
|
||||
"multicast dns register" = "no";
|
||||
"min protocol" = "SMB2";
|
||||
};
|
||||
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";
|
||||
# time machine specifc config
|
||||
"fruit:time machine" = "yes";
|
||||
"fruit:time machine max size" = "5T";
|
||||
"case sensitive" = "yes";
|
||||
"default case" = "lower";
|
||||
"preserve case" = "no";
|
||||
"short preserve case" = "no";
|
||||
"create mask" = "0660";
|
||||
"directory mask" = "0770";
|
||||
"force group" = "blake";
|
||||
};
|
||||
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";
|
||||
};
|
||||
nvr = {
|
||||
path = "/holocron/nvr";
|
||||
writable = true;
|
||||
guestOk = false;
|
||||
browseable = true;
|
||||
"valid users" = "archives";
|
||||
"public" = "no";
|
||||
"writeable" = "yes";
|
||||
"force user" = "archives";
|
||||
# time machine specifc config
|
||||
"create mask" = "0660";
|
||||
"directory mask" = "0770";
|
||||
"force group" = "archives";
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.holocron.smb = {
|
||||
enable = lib.mkEnableOption "enables smb";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# enable smb with all shares
|
||||
services.samba = {
|
||||
enable = true;
|
||||
package = pkgs.sambaFull;
|
||||
settings = smb_shares;
|
||||
};
|
||||
|
||||
# ensure time machine can discover the share without `tmutil`
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
nssmdns4 = true;
|
||||
publish.enable = true;
|
||||
publish.userServices = true;
|
||||
extraServiceFiles = {
|
||||
timemachine = ''
|
||||
<?xml version="1.0" standalone='no'?>
|
||||
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
|
||||
<service-group>
|
||||
<name replace-wildcards="yes">%h</name>
|
||||
<service>
|
||||
<type>_smb._tcp</type>
|
||||
<port>445</port>
|
||||
</service>
|
||||
<service>
|
||||
<type>_device-info._tcp</type>
|
||||
<port>0</port>
|
||||
<txt-record>model=TimeCapsule8,119</txt-record>
|
||||
</service>
|
||||
<service>
|
||||
<type>_adisk._tcp</type>
|
||||
<port>0</port>
|
||||
<txt-record>dk0=adVN=timemachine,adVF=0x82</txt-record>
|
||||
<txt-record>sys=waMa=0,adVF=0x100</txt-record>
|
||||
</service>
|
||||
</service-group>
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "syncthing";
|
||||
cfg = config.holocron.${service};
|
||||
sec = config.sops.secrets;
|
||||
url = "syncthing.${config.networking.hostName}.holocron.blue";
|
||||
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}/lumiose/key".path;
|
||||
cert = sec."${service}/lumiose/cert".path;
|
||||
settings = {
|
||||
devices = {
|
||||
"piplup" = {id = "OV4NUQK-3YHRL5R-SIZGTNL-7VZFFUX-FOJ6NTS-C7ROXR7-I2Q2W7G-QERO7AO";};
|
||||
"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 = "UEWNSUZ-AX75M5Y-OA4FURY-ORMEXFA-XUXU4LU-LEUYKVW-IDM2GQC-4UR4YAL";};
|
||||
};
|
||||
folders = {
|
||||
"holocron" = {
|
||||
path = "/holocron/users/blake/holocron";
|
||||
devices = ["piplup" "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}/lumiose/key" = {
|
||||
owner = "blake";
|
||||
group = "blake";
|
||||
};
|
||||
"${service}/lumiose/cert" = {
|
||||
owner = "blake";
|
||||
group = "blake";
|
||||
};
|
||||
};
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [config.services.syncthing.dataDir];};
|
||||
};
|
||||
|
||||
services.caddy.virtualHosts."${url}" = {
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
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}";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.holocron.zfs;
|
||||
sec = config.sops.secrets;
|
||||
in {
|
||||
options.holocron.zfs = {
|
||||
enable = lib.mkEnableOption "enables zfs";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# set network host id
|
||||
|
||||
# enable zfs support
|
||||
boot.kernelModules = ["zfs"];
|
||||
boot.supportedFilesystems = ["zfs"];
|
||||
boot.zfs.forceImportRoot = false;
|
||||
# boot.initrd.services.zfs.enable = true;
|
||||
# boot.zfs.requestEncryptionCredentials = true;
|
||||
|
||||
# arc cache size
|
||||
boot.kernelParams = ["zfs.zfs_arc_max=12884901888"];
|
||||
|
||||
# pools to import
|
||||
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 = {
|
||||
test = false;
|
||||
mail = {
|
||||
enable = true;
|
||||
recipient = "blake";
|
||||
sender = "alerts@blakedheld.xyz";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# enable zfs
|
||||
services.zfs = {
|
||||
autoScrub.enable = true;
|
||||
autoScrub.interval = "weekly";
|
||||
autoSnapshot = {
|
||||
enable = true;
|
||||
frequent = 4; # 15 min snapshots
|
||||
hourly = 24; # hourly snapshots
|
||||
daily = 7; # daily snapshots
|
||||
weekly = 4; # weekly snapshots
|
||||
monthly = 12; # monthly snapshots
|
||||
};
|
||||
# email notifs
|
||||
zed = {
|
||||
enableMail = true;
|
||||
settings = {
|
||||
ZED_EMAIL_ADDR = ["root" "blake"];
|
||||
# send notification if scrub succeeds
|
||||
ZED_NOTIFY_VERBOSE = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# install userspace tools for smart
|
||||
environment.systemPackages = with pkgs; [smartmontools];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "cs2";
|
||||
cfg = config.gameservers.${service};
|
||||
in {
|
||||
options.gameservers.${service} = {
|
||||
enable = lib.mkEnableOption "Counter Strike 2 server";
|
||||
data_dir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/gameservers/cs2";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 27015;
|
||||
};
|
||||
tv_port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 27016;
|
||||
};
|
||||
hostname = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "recoil.pro CS2";
|
||||
};
|
||||
map = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "de_dust2";
|
||||
};
|
||||
max_players = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10;
|
||||
};
|
||||
backup = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
};
|
||||
backup_repo = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/holocron/archives/gameservers/cs2";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.users.cs2 = {
|
||||
isSystemUser = true;
|
||||
group = "cs2";
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
};
|
||||
|
||||
users.groups.cs2 = {};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
steamcmd
|
||||
steam-run
|
||||
rcon
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${cfg.data_dir} 0770 cs2 cs2 -"
|
||||
"d ${cfg.data_dir}/server 0770 cs2 cs2 -"
|
||||
];
|
||||
|
||||
environment.etc."cs2/server.cfg".text = ''
|
||||
hostname "${cfg.hostname}"
|
||||
sv_lan 0
|
||||
rcon_password "$(<${config.sops.secrets."cs2/rcon".path})"
|
||||
mp_autoteambalance 1
|
||||
mp_limitteams 2
|
||||
'';
|
||||
|
||||
systemd.services.cs2-update = {
|
||||
description = "Update CS2 server";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "cs2";
|
||||
};
|
||||
script = ''
|
||||
${pkgs.steamcmd}/bin/steamcmd \
|
||||
+force_install_dir ${cfg.data_dir}/server \
|
||||
+login anonymous \
|
||||
+app_update 730 validate \
|
||||
+quit
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.cs2-server = {
|
||||
description = "Counter Strike 2 Dedicated Server";
|
||||
after = [
|
||||
"network.target"
|
||||
"cs2-update.service"
|
||||
];
|
||||
requires = [
|
||||
"cs2-update.service"
|
||||
];
|
||||
wantedBy = ["multi-user.target"];
|
||||
serviceConfig = {
|
||||
User = "cs2";
|
||||
Group = "cs2";
|
||||
WorkingDirectory = "${cfg.data_dir}";
|
||||
Restart = "always";
|
||||
ExecStart = pkgs.writeShellScript "cs2-start" ''
|
||||
export GSLT=$(cat ${config.sops.secrets."cs2/gslt".path})
|
||||
exec ${pkgs.steam-run}/bin/steam-run -- \
|
||||
${cfg.data_dir}/server/game/bin/linuxsteamrt64/cs2 \
|
||||
-dedicated \
|
||||
-usercon \
|
||||
-console \
|
||||
-port ${toString cfg.port} \
|
||||
-tv_port ${toString cfg.tv_port} \
|
||||
-maxplayers_override ${toString cfg.max_players} \
|
||||
+game_type 0 \
|
||||
+game_mode 1 \
|
||||
+mapgroup mg_active \
|
||||
+map ${cfg.map} \
|
||||
+sv_setsteamaccount "$GSLT" \
|
||||
+exec /etc/gameserver/cs2/server.cfg
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [cfg.port cfg.tv_port];
|
||||
networking.firewall.allowedUDPPorts = [cfg.port cfg.tv_port];
|
||||
|
||||
# backups cs2 server with borg!
|
||||
services.borgbackup.jobs.${service} = {
|
||||
archiveBaseName = service;
|
||||
repo = cfg.backup_repo;
|
||||
paths = cfg.data_dir;
|
||||
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
|
||||
};
|
||||
};
|
||||
|
||||
# manage secrets with sops
|
||||
sops.secrets = {
|
||||
"${service}/gslt" = {
|
||||
owner = service;
|
||||
group = service;
|
||||
};
|
||||
"${service}/rcon" = {
|
||||
owner = service;
|
||||
group = service;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "cs2";
|
||||
cfg = config.gameservers.${service};
|
||||
in {
|
||||
options.gameservers.${service} = {
|
||||
enable = lib.mkEnableOption "Counter Strike 2 server";
|
||||
data_dir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/gameservers/cs2";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 27015;
|
||||
};
|
||||
tv_port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 27016;
|
||||
};
|
||||
hostname = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "recoil.pro CS2";
|
||||
};
|
||||
map = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "de_dust2";
|
||||
};
|
||||
max_players = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10;
|
||||
};
|
||||
backup = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
};
|
||||
backup_repo = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/holocron/archives/gameservers/cs2";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.users.cs2 = {
|
||||
isSystemUser = true;
|
||||
group = "cs2";
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
};
|
||||
|
||||
users.groups.cs2 = {};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
steamcmd
|
||||
steam-run
|
||||
rcon
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${cfg.data_dir} 0770 cs2 cs2 -"
|
||||
"d ${cfg.data_dir}/server 0770 cs2 cs2 -"
|
||||
];
|
||||
|
||||
environment.etc."cs2/server.cfg".text = ''
|
||||
hostname "${cfg.hostname}"
|
||||
sv_lan 0
|
||||
rcon_password "$(<${config.sops.secrets."cs2/rcon".path})"
|
||||
mp_autoteambalance 1
|
||||
mp_limitteams 2
|
||||
'';
|
||||
|
||||
systemd.services.cs2-update = {
|
||||
description = "Update CS2 server";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "cs2";
|
||||
};
|
||||
script = ''
|
||||
${pkgs.steamcmd}/bin/steamcmd \
|
||||
+force_install_dir ${cfg.data_dir}/server \
|
||||
+login anonymous \
|
||||
+app_update 730 validate \
|
||||
+quit
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.cs2-server = {
|
||||
description = "Counter Strike 2 Dedicated Server";
|
||||
after = [
|
||||
"network.target"
|
||||
"cs2-update.service"
|
||||
];
|
||||
requires = [
|
||||
"cs2-update.service"
|
||||
];
|
||||
wantedBy = ["multi-user.target"];
|
||||
serviceConfig = {
|
||||
User = "cs2";
|
||||
Group = "cs2";
|
||||
WorkingDirectory = "${cfg.data_dir}/server";
|
||||
Restart = "always";
|
||||
ExecStart = pkgs.writeShellScript "cs2-start" ''
|
||||
export GSLT=$(cat ${config.sops.secrets."cs2/gslt".path})
|
||||
exec ${pkgs.steam-run}/bin/steam-run -- \
|
||||
${cfg.data_dir}/server/game/cs2.sh \
|
||||
-dedicated \
|
||||
-usercon \
|
||||
-console \
|
||||
-port ${toString cfg.port} \
|
||||
-tv_port ${toString cfg.tv_port} \
|
||||
-maxplayers_override ${toString cfg.max_players} \
|
||||
+game_type 0 \
|
||||
+game_mode 1 \
|
||||
+mapgroup mg_active \
|
||||
+map ${cfg.map} \
|
||||
+sv_setsteamaccount "$GSLT" \
|
||||
+exec /etc/gameserver/cs2/server.cfg
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [cfg.port cfg.tv_port];
|
||||
networking.firewall.allowedUDPPorts = [cfg.port cfg.tv_port];
|
||||
|
||||
# backups cs2 server with borg!
|
||||
services.borgbackup.jobs.${service} = {
|
||||
archiveBaseName = service;
|
||||
repo = cfg.backup_repo;
|
||||
paths = cfg.data_dir;
|
||||
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
|
||||
};
|
||||
};
|
||||
|
||||
# manage secrets with sops
|
||||
sops.secrets = {
|
||||
"${service}/gslt" = {
|
||||
owner = service;
|
||||
group = service;
|
||||
};
|
||||
"${service}/rcon" = {
|
||||
owner = service;
|
||||
group = service;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
{
|
||||
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";
|
||||
# };
|
||||
linggango = {
|
||||
data_dir = "/var/lib/gameservers/minecraft_modded/linggango";
|
||||
start_file = "start.sh";
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.gameservers.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "modded.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_gs = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = ["craftoria"];
|
||||
};
|
||||
backup_repo = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/backup/gameservers/minecraft/modded";
|
||||
description = "path to take hourly backups to with borg!";
|
||||
};
|
||||
offsite_user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat";
|
||||
description = "user to connect to offsite host with";
|
||||
};
|
||||
offsite_target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat.holocron.blue";
|
||||
description = "ip or domain for offsite backups";
|
||||
};
|
||||
offsite_dir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat/holocron/archives/gameservers";
|
||||
description = "path to rsync offsite backups to";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.groups.minecraft = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# 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"];
|
||||
path = [pkgs.openjdk21];
|
||||
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}";
|
||||
ExecStart = "${pkgs.openjdk21}/bin/java -Xms4G -Xmx24G @libraries/net/minecraftforge/forge/1.20.1-47.4.20/unix_args.txt \"$@\"";
|
||||
Restart = "on-failure";
|
||||
KillMode = "process";
|
||||
};
|
||||
wantedBy = ["multi-user.target"];
|
||||
})
|
||||
servers;
|
||||
|
||||
environment.systemPackages = with pkgs; [openjdk21 mcrcon borgbackup sshpass tree rsync];
|
||||
|
||||
# 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 = [25579];
|
||||
networking.firewall.allowedUDPPorts = [25580]; #voicechat
|
||||
|
||||
sops.secrets = {
|
||||
"borg_passwd" = {
|
||||
owner = "root";
|
||||
group = "root";
|
||||
};
|
||||
"lifeboat_rsync" = {
|
||||
owner = "root";
|
||||
group = "archives";
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
|
||||
# helpful and for scripts
|
||||
users.groups.archives = {gid = 727;};
|
||||
|
||||
# backups minecraft_modded 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";
|
||||
postHook = ''
|
||||
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
|
||||
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
|
||||
-e "ssh -o StrictHostKeyChecking=no" \
|
||||
${toString cfg.backup_repo} \
|
||||
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
|
||||
'';
|
||||
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
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
{
|
||||
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_gs = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = ["velocity" "smp" "superflat" "bento"];
|
||||
};
|
||||
backup_repo = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/holocron/archives/gameservers/minecraft/recpro_stack";
|
||||
description = "path to take hourly backups to with borg!";
|
||||
};
|
||||
offsite_user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat";
|
||||
description = "user to connect to offsite host with";
|
||||
};
|
||||
offsite_target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat.holocron.blue";
|
||||
description = "ip or domain for offsite backups";
|
||||
};
|
||||
offsite_dir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat/holocron/archives/gameservers";
|
||||
description = "path to rsync offsite backups to";
|
||||
};
|
||||
};
|
||||
|
||||
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.openjdk25}/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";
|
||||
postHook = ''
|
||||
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
|
||||
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
|
||||
-e "ssh -o StrictHostKeyChecking=no" \
|
||||
${toString cfg.backup_repo} \
|
||||
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
|
||||
'';
|
||||
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
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
nixservice = "podman-valheim";
|
||||
service = "valheim";
|
||||
cfg = config.gameservers.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in {
|
||||
options.gameservers.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
# set port options
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 2456;
|
||||
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/gameservers/${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)";
|
||||
};
|
||||
motd_gs = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = ["podman-valheim"];
|
||||
};
|
||||
backup = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "enable backups for ${service}";
|
||||
};
|
||||
backup_repo = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/backup/gameservers/valheim";
|
||||
description = "path to take hourly backups to with borg!";
|
||||
};
|
||||
offsite_user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat";
|
||||
description = "user to connect to offsite host with";
|
||||
};
|
||||
offsite_target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat.holocron.blue";
|
||||
description = "ip or domain for offsite backups";
|
||||
};
|
||||
offsite_dir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "lifeboat/holocron/archives/gameservers";
|
||||
description = "path to rsync offsite backups to";
|
||||
};
|
||||
};
|
||||
|
||||
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 = [];
|
||||
};
|
||||
|
||||
virtualisation.oci-containers.containers = {
|
||||
${service} = {
|
||||
image = "ghcr.io/community-valheim-tools/valheim-server";
|
||||
autoStart = true;
|
||||
extraOptions = [
|
||||
"--cap-add=sys_nice"
|
||||
"--stop-timeout=120"
|
||||
];
|
||||
ports = [
|
||||
"2456-2457:2456-2457/udp"
|
||||
"2456:80/tcp"
|
||||
];
|
||||
volumes = [
|
||||
"${cfg.data_dir}/config:/config"
|
||||
"${cfg.data_dir}/data:/opt/valheim"
|
||||
];
|
||||
environment = {
|
||||
SERVER_NAME = "recpro";
|
||||
SERVER_PASS = "recoil727pro";
|
||||
#WORLD_NAME = "";
|
||||
STATUS_HTTP = "true";
|
||||
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];
|
||||
networking.firewall.allowedUDPPorts = [2456 2457];
|
||||
|
||||
# backups valhiem with borg!
|
||||
services.borgbackup.jobs.${service} = {
|
||||
archiveBaseName = service;
|
||||
repo = cfg.backup_repo;
|
||||
paths = cfg.data_dir;
|
||||
compression = "auto,zstd";
|
||||
#preHook = "systemctl start mysql-backup.service";
|
||||
postHook = ''
|
||||
${pkgs.sshpass}/bin/sshpass -f ${sec."lifeboat_rsync".path} \
|
||||
${pkgs.rsync}/bin/rsync -aHAX --partial --numeric-ids --info=progress2,name1,stats2 --delete \
|
||||
-e "ssh -o StrictHostKeyChecking=no" \
|
||||
${toString cfg.backup_repo} \
|
||||
${cfg.offsite_user}@${cfg.offsite_target}::${cfg.offsite_dir}
|
||||
'';
|
||||
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
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
# services show up in glance in reverse import order lmao
|
||||
imports = [
|
||||
./nfs
|
||||
./smb
|
||||
./zfs
|
||||
./copyparty
|
||||
./perms
|
||||
];
|
||||
|
||||
# define the groups used for backups and archives
|
||||
users.groups.archives = {gid = 727;};
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
{
|
||||
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";
|
||||
};
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
{
|
||||
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"];
|
||||
|
||||
# enable smart monitoring
|
||||
services.smartd.enable = true;
|
||||
|
||||
# enable zfs
|
||||
services.zfs = {
|
||||
autoScrub.enable = true;
|
||||
autoScrub.interval = "weekly";
|
||||
};
|
||||
|
||||
# install userspace tools for acl's
|
||||
environment.systemPackages = with pkgs; [ nfs-utils ];
|
||||
|
||||
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"];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
# the order determines the order in glance :3
|
||||
imports = [
|
||||
./ollama
|
||||
./open-webui
|
||||
];
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "ollama";
|
||||
cfg = config.homelab.${service};
|
||||
homelab = config.homelab;
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
# set port options
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 7710;
|
||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
};
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "ollama.${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;
|
||||
shell = pkgs.bash;
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [];
|
||||
};
|
||||
|
||||
# declare the gitea service
|
||||
services.${service} = {
|
||||
enable = true;
|
||||
host = "0.0.0.0";
|
||||
port = cfg.port;
|
||||
openFirewall = true;
|
||||
syncModels = true;
|
||||
loadModels = [
|
||||
"deepseek-r1:7b"
|
||||
"deepseek-r1:14b"
|
||||
];
|
||||
};
|
||||
|
||||
# override umask to make permissions work out
|
||||
systemd.services.${service}.serviceConfig = {
|
||||
UMask = lib.mkForce "0007";
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [cfg.port];
|
||||
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
reverse_proxy localhost:${toString cfg.port} {
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# add to backups
|
||||
homelab.backups.baks = {
|
||||
${service} = {
|
||||
paths = [cfg.data_dir "/var/lib/private"];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "open-webui";
|
||||
cfg = config.homelab.${service};
|
||||
homelab = config.homelab;
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
# set port options
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 7711;
|
||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
};
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "ai.${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;
|
||||
shell = pkgs.bash;
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [];
|
||||
};
|
||||
|
||||
# declare the gitea service
|
||||
services.${service} = {
|
||||
enable = true;
|
||||
host = "0.0.0.0";
|
||||
port = cfg.port;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
# override umask to make permissions work out
|
||||
systemd.services.${service}.serviceConfig = {
|
||||
UMask = lib.mkForce "0007";
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [cfg.port];
|
||||
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
reverse_proxy localhost:${toString cfg.port} {
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# add to glance
|
||||
homelab.glance.links.services = [
|
||||
{
|
||||
title = service;
|
||||
url = "https://ai.${homelab.base_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 "/var/lib/private"];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -3,16 +3,13 @@
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
}: let
|
||||
service = "";
|
||||
cfg = config.modules.services.${service};
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
options.modules.services.${service} = {
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
# set port options
|
||||
@@ -41,10 +38,13 @@ 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;
|
||||
@@ -58,7 +58,7 @@ in
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" ];
|
||||
extraGroups = ["media"];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
@@ -85,9 +85,11 @@ in
|
||||
|
||||
# add to caddy for reverse proxy
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
serverAliases = [ "${service}.${homelab.public_domain}" ];
|
||||
serverAliases = ["${service}.${homelab.public_domain}"];
|
||||
# use explicitly defined tls cert
|
||||
# tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
|
||||
extraConfig = ''
|
||||
tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
@@ -118,9 +120,9 @@ in
|
||||
# };
|
||||
|
||||
# add to backups
|
||||
system.backups.baks = {
|
||||
homelab.backups.baks = {
|
||||
${service} = {
|
||||
paths = [ cfg.data_dir ];
|
||||
paths = [cfg.data_dir];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.homelab.nomad;
|
||||
in {
|
||||
options.homelab.nomad = {
|
||||
enable = lib.mkEnableOption "enable in house project nomad";
|
||||
tz = lib.mkOption {
|
||||
default = "America/Chicago";
|
||||
type = lib.types.str;
|
||||
description = "set timezone";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# the order determines the order in glance :3
|
||||
imports = [
|
||||
./kiwix
|
||||
./maps
|
||||
./kolibri
|
||||
];
|
||||
homelab.kiwix.enable = lib.mkDefault true;
|
||||
homelab.maps.enable = lib.mkDefault true;
|
||||
homelab.kolibri.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "kiwix";
|
||||
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 = 7730;
|
||||
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 = "kiwix-serve";
|
||||
};
|
||||
};
|
||||
|
||||
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"];
|
||||
};
|
||||
|
||||
# helpful and for scripts
|
||||
environment.systemPackages = with pkgs; [kiwix-tools];
|
||||
|
||||
# enable the ${service} service
|
||||
services.kiwix-serve = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
port = cfg.port;
|
||||
user = service;
|
||||
group = service;
|
||||
libraryPath = "${cfg.data_dir}/library.xml";
|
||||
extraArgs = {
|
||||
};
|
||||
};
|
||||
|
||||
# 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 = ["${service}.${homelab.public_domain}"];
|
||||
# use explicitly defined tls cert
|
||||
# tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# add to glance (local service)
|
||||
homelab.glance.links.nomad = [
|
||||
{
|
||||
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];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
+25
-49
@@ -1,77 +1,53 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
|
||||
let
|
||||
cfg = config.homelab;
|
||||
in
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.homelab;
|
||||
in {
|
||||
options.homelab = {
|
||||
enable = lib.mkEnableOption "enable homelab services and configuration";
|
||||
media_user = lib.mkOption {
|
||||
default = "media";
|
||||
type = lib.types.str;
|
||||
description = "user for media file permissions";
|
||||
};
|
||||
media_group = lib.mkOption {
|
||||
default = "media";
|
||||
type = lib.types.str;
|
||||
description = "group for media file permissions";
|
||||
};
|
||||
tz = lib.mkOption {
|
||||
default = "America/Chicago";
|
||||
type = lib.types.str;
|
||||
description = "set timezone";
|
||||
};
|
||||
base_domain = lib.mkOption {
|
||||
default = "snowbelle.lan";
|
||||
default = "lumiose.holocron.blue";
|
||||
type = lib.types.str;
|
||||
description = "base domain used for reverse proxy";
|
||||
};
|
||||
public_domain = lib.mkOption {
|
||||
default = "blakedheld.xyz";
|
||||
default = "holocron.blue";
|
||||
type = lib.types.str;
|
||||
description = "base domain used for reverse proxy";
|
||||
description = "public domain used for reverse proxy";
|
||||
};
|
||||
host_ip = lib.mkOption {
|
||||
default = "10.10.0.10";
|
||||
default = "10.10.0.11";
|
||||
type = lib.types.str;
|
||||
description = "base domain used for reverse proxy";
|
||||
description = "base ip used for reverse proxy";
|
||||
};
|
||||
};
|
||||
|
||||
# the order determines the order in glance :3
|
||||
imports = [
|
||||
./motd
|
||||
./glance
|
||||
./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
|
||||
#./ai
|
||||
./mediastack
|
||||
./services
|
||||
./system
|
||||
#./nomad
|
||||
./network
|
||||
];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users = {
|
||||
groups.${cfg.media_group} = {
|
||||
gid = 700;
|
||||
};
|
||||
users.${cfg.media_user} = {
|
||||
uid = 700;
|
||||
isSystemUser = true;
|
||||
group = cfg.media_group;
|
||||
};
|
||||
# define the groups used for backups and archives
|
||||
users.users.archives = {
|
||||
isSystemUser = true;
|
||||
group = "archives";
|
||||
};
|
||||
|
||||
users.groups.archives = {gid = 727;};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
{ pkgs, config, lib, inputs, ... }:
|
||||
|
||||
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" ];
|
||||
};
|
||||
|
||||
# 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 ];
|
||||
|
||||
# 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 to backups
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir "/var/lib/redis-immich" ]; };
|
||||
};
|
||||
};
|
||||
}
|
||||
+24
-26
@@ -1,12 +1,13 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "audiobookshelf";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,19 +44,18 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
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;
|
||||
# home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" ];
|
||||
extraGroups = ["media"];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
@@ -64,7 +64,7 @@ in
|
||||
openFirewall = true;
|
||||
user = service;
|
||||
group = service;
|
||||
# dataDir = cfg.data_dir;
|
||||
# dataDir = cfg.data_dir;
|
||||
host = "0.0.0.0";
|
||||
port = cfg.port;
|
||||
};
|
||||
@@ -72,34 +72,32 @@ in
|
||||
# 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}" ];
|
||||
#serverAliases = ["abs.${homelab.public_domain}"];
|
||||
extraConfig = ''
|
||||
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||
tls internal
|
||||
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}"; }];
|
||||
homelab.glance.links.mediastack = [
|
||||
{
|
||||
title = service;
|
||||
url = "https://abs.${homelab.base_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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
+21
-21
@@ -1,12 +1,13 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "bazarr";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,9 +44,8 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -55,7 +55,7 @@ in
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" ];
|
||||
extraGroups = ["media"];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
@@ -72,28 +72,28 @@ in
|
||||
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}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# 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}"; }];
|
||||
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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.homelab.mediastack;
|
||||
in {
|
||||
options.homelab.mediastack = {
|
||||
enable = lib.mkEnableOption "enable the mediastack";
|
||||
media_user = lib.mkOption {
|
||||
default = "media";
|
||||
type = lib.types.str;
|
||||
description = "user for media file permissions";
|
||||
};
|
||||
media_group = lib.mkOption {
|
||||
default = "media";
|
||||
type = lib.types.str;
|
||||
description = "group for media file permissions";
|
||||
};
|
||||
tz = lib.mkOption {
|
||||
default = "America/Chicago";
|
||||
type = lib.types.str;
|
||||
description = "set timezone";
|
||||
};
|
||||
};
|
||||
|
||||
# the order determines the order in glance :3
|
||||
imports = [
|
||||
./yacreader
|
||||
./bazarr
|
||||
./qbittorrent
|
||||
./prowlarr
|
||||
./lidarr
|
||||
./radarr
|
||||
./sonarr
|
||||
./audiobookshelf
|
||||
./navidrome
|
||||
./jellyfin
|
||||
./flaresolverr
|
||||
];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users = {
|
||||
groups.${cfg.media_group} = {
|
||||
gid = 700;
|
||||
};
|
||||
users.${cfg.media_user} = {
|
||||
uid = 700;
|
||||
isSystemUser = true;
|
||||
group = cfg.media_group;
|
||||
};
|
||||
};
|
||||
homelab.jellyfin.enable = lib.mkDefault true;
|
||||
homelab.yacreader.enable = lib.mkDefault true;
|
||||
homelab.qbittorrent.enable = lib.mkDefault true;
|
||||
homelab.bazarr.enable = lib.mkDefault true;
|
||||
homelab.prowlarr.enable = lib.mkDefault true;
|
||||
homelab.radarr.enable = lib.mkDefault true;
|
||||
homelab.sonarr.enable = lib.mkDefault true;
|
||||
homelab.lidarr.enable = lib.mkDefault true;
|
||||
homelab.audiobookshelf.enable = lib.mkDefault true;
|
||||
homelab.navidrome.enable = lib.mkDefault true;
|
||||
homelab.flaresolverr.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
+9
-12
@@ -1,12 +1,13 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "flaresolverr";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,9 +44,8 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -68,13 +68,10 @@ in
|
||||
Group = service;
|
||||
};
|
||||
|
||||
# # 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}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
+24
-22
@@ -1,12 +1,14 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "jellyfin";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
host = config.networking.hostName;
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,9 +45,8 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -55,12 +56,13 @@ in
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" "video" "render" ];
|
||||
extraGroups = ["media" "video" "render"];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
services.${service} = {
|
||||
enable = true;
|
||||
package = pkgs.unstable.jellyfin;
|
||||
openFirewall = true;
|
||||
user = service;
|
||||
group = service;
|
||||
@@ -72,29 +74,29 @@ in
|
||||
UMask = lib.mkForce "0007";
|
||||
};
|
||||
|
||||
# # open firewall
|
||||
# networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||
|
||||
# add to caddy for reverse proxy
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
serverAliases = [ "media.${homelab.public_domain}" ];
|
||||
serverAliases = ["media.${homelab.public_domain}"];
|
||||
extraConfig = ''
|
||||
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# 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}"; }];
|
||||
homelab.glance.links.mediastack = [
|
||||
{
|
||||
title = service;
|
||||
url = "https://media.${host}.${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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "lidarr";
|
||||
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 = 7109;
|
||||
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 {
|
||||
# required
|
||||
environment.systemPackages = with pkgs; [ffmpeg_6-headless yt-dlp];
|
||||
|
||||
# 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;
|
||||
};
|
||||
|
||||
# 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 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];};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "navidrome";
|
||||
cfg = config.homelab.${service};
|
||||
homelab = config.homelab;
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
# set port options
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 7108;
|
||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
};
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "music.${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;
|
||||
# plugins = [
|
||||
# ];
|
||||
environmentFile = "${cfg.data_dir}/navidrome.env";
|
||||
settings = {
|
||||
Address = "0.0.0.0";
|
||||
Port = cfg.port;
|
||||
MusicFolder = "/holocron/media/music";
|
||||
EnableInsightsCollector = false;
|
||||
LyricsPriority = "nd-lyrics";
|
||||
Plugins = {
|
||||
Enabled = true;
|
||||
#Folder = lib.mkForce "${cfg.data_dir}/plugins";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# override umask to make permissions work out
|
||||
systemd.services.${service}.serviceConfig = {
|
||||
UMask = lib.mkForce "0007";
|
||||
EnvironmentFile = "${cfg.data_dir}/navidrome.env";
|
||||
};
|
||||
|
||||
# add to caddy for reverse proxy
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
#serverAliases = ["abs.${homelab.public_domain}"];
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port} {
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# add to glance public service
|
||||
homelab.glance.links.mediastack = [
|
||||
{
|
||||
title = service;
|
||||
url = "https://music.${homelab.base_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];};
|
||||
};
|
||||
};
|
||||
}
|
||||
+23
-21
@@ -1,12 +1,13 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "prowlarr";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,9 +44,8 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -55,7 +55,7 @@ in
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" ];
|
||||
extraGroups = ["media"];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
@@ -74,28 +74,30 @@ in
|
||||
Group = service;
|
||||
};
|
||||
|
||||
# # 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}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# 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}"; }];
|
||||
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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {
|
||||
paths = [cfg.data_dir "/var/lib/private"];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
+27
-36
@@ -1,12 +1,13 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "qbittorrent";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -16,11 +17,11 @@ in
|
||||
default = 7103;
|
||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
};
|
||||
# torrenting_port = lib.mkOption {
|
||||
# type = lib.types.int;
|
||||
# default = ;
|
||||
# description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
# };
|
||||
# torrenting_port = lib.mkOption {
|
||||
# type = lib.types.int;
|
||||
# default = ;
|
||||
# description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
# };
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "qbit.${homelab.base_domain}";
|
||||
@@ -53,11 +54,10 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# ensure media dirs existence
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /holocron/media/downloads 2775 qbittorrent media -"
|
||||
];
|
||||
];
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -74,10 +74,10 @@ in
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
user = service;
|
||||
group = lib.mkForce "media"; # override for permissions
|
||||
group = lib.mkForce "media"; # override for permissions
|
||||
profileDir = cfg.data_dir;
|
||||
webuiPort = cfg.port;
|
||||
# torrentingPort = cfg.torrenting_port;
|
||||
# torrentingPort = cfg.torrenting_port;
|
||||
};
|
||||
|
||||
# override umask to make permissions work out
|
||||
@@ -102,37 +102,28 @@ in
|
||||
iptables -A QBIT -j DROP
|
||||
'';
|
||||
|
||||
# boilerplate for if you ever want to try to get this working again
|
||||
# ------------------------------------------------------------------------------
|
||||
# # add systemd service to VPN network namespace
|
||||
# vpnConfinement = {
|
||||
# enable = true;
|
||||
# vpnNamespace = "wgmex";
|
||||
# };
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# # 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}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# 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}"; }];
|
||||
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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
+25
-21
@@ -1,12 +1,14 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "radarr";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,9 +45,11 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# required
|
||||
environment.systemPackages = with pkgs; [ffmpeg_6-headless];
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -55,7 +59,7 @@ in
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" ];
|
||||
extraGroups = ["media"];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
@@ -73,32 +77,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 ];
|
||||
|
||||
# add to caddy for reverse proxy
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
extraConfig = ''
|
||||
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# 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}"; }];
|
||||
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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
+23
-20
@@ -1,12 +1,13 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "sonarr";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,9 +44,11 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# required
|
||||
environment.systemPackages = with pkgs; [ffmpeg_6-headless];
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -55,7 +58,7 @@ in
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" ];
|
||||
extraGroups = ["media"];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
@@ -75,28 +78,28 @@ in
|
||||
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}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# 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}"; }];
|
||||
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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
+26
-24
@@ -1,12 +1,13 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "yacreader";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,12 +44,11 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# install the binary
|
||||
environment.systemPackages = with pkgs; [ yacreader ];
|
||||
environment.systemPackages = with pkgs; [yacreader];
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -58,14 +58,14 @@ in
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" ];
|
||||
extraGroups = ["media"];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
systemd.services.${service} = {
|
||||
description = "${service} library server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["network.target"];
|
||||
|
||||
serviceConfig = {
|
||||
UMask = lib.mkForce "0007";
|
||||
@@ -81,29 +81,31 @@ in
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||
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}
|
||||
tls internal
|
||||
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 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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
{ 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"; 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";
|
||||
};
|
||||
};
|
||||
|
||||
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";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
# add to backups
|
||||
system.backups.baks = lib.listToAttrs (
|
||||
lib.mapAttrsToList (srv_name: cfg:
|
||||
{
|
||||
name = srv_name; # attribute key
|
||||
value = { paths = [ cfg.data_dir ]; }; # attribute value
|
||||
}
|
||||
) servers
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "caddy";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -16,6 +18,11 @@ in
|
||||
default = "/var/lib/${service}";
|
||||
description = "set data directory for ${service}";
|
||||
};
|
||||
keys = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "host keys directory";
|
||||
};
|
||||
backup = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
@@ -28,7 +35,6 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = {};
|
||||
|
||||
@@ -48,16 +54,30 @@ in
|
||||
user = service;
|
||||
group = service;
|
||||
dataDir = cfg.data_dir;
|
||||
package = pkgs.caddy.withPlugins {
|
||||
plugins = [
|
||||
"github.com/caddy-dns/cloudflare@v0.2.4"
|
||||
];
|
||||
hash = "sha256-dQvk6ezY6TQ1J7PjhCXnThF/SqVgPwBO8/RXzHCY+js=";
|
||||
# Replace with the hash from the build error the first time you build.
|
||||
};
|
||||
email = "me@blakedheld.xyz";
|
||||
|
||||
globalConfig = ''
|
||||
auto_https ignore_loaded_certs
|
||||
acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
|
||||
'';
|
||||
|
||||
virtualHosts."key.${homelab.public_domain}" = {
|
||||
extraConfig = ''
|
||||
root * /var/www/keys
|
||||
file_server
|
||||
'';
|
||||
# static page for hosting key files
|
||||
virtualHosts = {
|
||||
"keys.${homelab.base_domain}" = lib.mkIf cfg.keys {
|
||||
serverAliases = ["keys.${homelab.public_domain}"];
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
root /var/www/keys
|
||||
file_server browse
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -70,10 +90,13 @@ in
|
||||
# override umask to make permissions work out
|
||||
systemd.services.${service}.serviceConfig = {
|
||||
UMask = lib.mkForce "0007";
|
||||
# make cloudflare token readable
|
||||
EnvironmentFile = sec."cloudflare/api_token_caddy".path;
|
||||
#LoadCredential = "CLOUDFLARE_API_TOKEN:${sec."cloudflare/api_token_caddy".path}";
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
|
||||
sops.secrets = {
|
||||
"ssl_blakedheld_crt" = {
|
||||
@@ -86,17 +109,41 @@ in
|
||||
group = "caddy";
|
||||
path = "/etc/ssl/blakedheld.xyz.key";
|
||||
};
|
||||
"cloudflare/api_token_caddy" = {
|
||||
owner = "caddy";
|
||||
group = "caddy";
|
||||
};
|
||||
"klefki_pub.asc" = {
|
||||
owner = "caddy";
|
||||
group = "caddy";
|
||||
path = "/var/www/keys/klefki_pub.asc";
|
||||
};
|
||||
"caddy_root.crt" = {
|
||||
owner = "caddy";
|
||||
group = "caddy";
|
||||
path = "/var/www/keys/caddy_root.crt";
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."caddy/browse.html".text = ''
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>keyring</title>
|
||||
<style>
|
||||
footer { display: none !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{template "listing" .}}
|
||||
</body>
|
||||
</html>
|
||||
'';
|
||||
|
||||
# add to backups
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "cloudflare-ddns";
|
||||
cfg = config.homelab.ddns;
|
||||
sec = config.sops.secrets;
|
||||
in {
|
||||
options.homelab.ddns = {
|
||||
enable = lib.mkEnableOption "enables ddns with cloudflare";
|
||||
motd = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = service;
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.${service} = {
|
||||
enable = true;
|
||||
credentialsFile = sec."cloudflare/api_token".path;
|
||||
domains = [
|
||||
# recoil.pro
|
||||
"recoil.pro"
|
||||
"*.recoil.pro"
|
||||
"mc.recoil.pro"
|
||||
"smp.recoil.pro"
|
||||
"superflat.recoil.pro"
|
||||
"skyblock.recoil.pro"
|
||||
"cobblemon.recoil.pro"
|
||||
"valheim.recoil.pro"
|
||||
|
||||
# blakedheld.xyz
|
||||
#"blakedheld.xyz"
|
||||
#"*.blakedheld.xyz"
|
||||
#"git.blakedheld.xyz"
|
||||
#"up.blakedheld.xyz"
|
||||
|
||||
# holocron.blue
|
||||
#"holocron.blue"
|
||||
#"*.holocron.blue"
|
||||
"git.holocron.blue"
|
||||
"pass.holocron.blue"
|
||||
"photos.holocron.blue"
|
||||
"media.holocron.blue"
|
||||
"up.holocron.blue"
|
||||
# mc servers
|
||||
"mine.holocron.blue"
|
||||
"smp.holocron.blue"
|
||||
"skyblock.holocron.blue"
|
||||
"superflat.holocron.blue"
|
||||
];
|
||||
};
|
||||
|
||||
# declare authkey secrets
|
||||
sops.secrets = {
|
||||
"cloudflare/api_token" = {
|
||||
owner = "cloudflare-ddns";
|
||||
group = "cloudflare-ddns";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
# the order determines the order in glance :3
|
||||
imports = [
|
||||
./dnsmasq
|
||||
./caddy
|
||||
./tailscale
|
||||
./ddns
|
||||
];
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "dnsmasq";
|
||||
cfg = config.homelab.${service};
|
||||
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}";
|
||||
};
|
||||
upstream = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "10.10.0.1";
|
||||
description = "set upstream dns server for ${service} (default: $cfg.upstream}";
|
||||
};
|
||||
motd = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = service;
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# enable the ${service} service
|
||||
services.${service} = {
|
||||
enable = true;
|
||||
alwaysKeepRunning = true;
|
||||
settings = {
|
||||
no-resolv = true;
|
||||
listen-address = config.homelab.host_ip; # your LAN IP
|
||||
#interface = "enp89s0";
|
||||
bind-interfaces = true;
|
||||
# address = [
|
||||
# "/snowbelle.blakedheld.xyz/10.10.0.10"
|
||||
# "/lumiose.blakedheld.xyz/10.10.0.10"
|
||||
# "/bebe.blakedheld.xyz/10.10.0.1"
|
||||
# ];
|
||||
server = [
|
||||
# upstream dns
|
||||
cfg.upstream
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.dnsmasq.serviceConfig = {
|
||||
RestartSec = "5s";
|
||||
StartLimitBurst = 10;
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [cfg.port];
|
||||
networking.firewall.allowedUDPPorts = [cfg.port];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "tailscale";
|
||||
cfg = config.homelab.tailscale;
|
||||
sec = config.sops.secrets;
|
||||
in {
|
||||
options.homelab.tailscale = {
|
||||
enable = lib.mkEnableOption "enables tailscale";
|
||||
motd = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "tailscaled";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.${service} = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
useRoutingFeatures = "both";
|
||||
authKeyFile = sec."tailscale_authkey".path;
|
||||
extraSetFlags = [
|
||||
"--advertise-routes=${config.homelab.host_ip}/32,10.10.0.1/32,10.10.0.5/32,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";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
# the order determines the order in glance :3
|
||||
imports = [
|
||||
./home
|
||||
./glance
|
||||
./vaultwarden
|
||||
./gitea
|
||||
./immich
|
||||
./homebox
|
||||
#./searxng
|
||||
];
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "gitea";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -48,9 +50,8 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -62,6 +63,10 @@ in
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [];
|
||||
# if you wanna attempt system ssh again
|
||||
#openssh.authorizedKeys.keyFiles = [
|
||||
# "${cfg.data_dir}/.ssh/authorized_keys"
|
||||
#];
|
||||
};
|
||||
|
||||
# declare the gitea service
|
||||
@@ -70,23 +75,33 @@ in
|
||||
user = "gitea";
|
||||
group = "gitea";
|
||||
stateDir = cfg.data_dir;
|
||||
appName = "gitea";
|
||||
appName = "gitea";
|
||||
settings = {
|
||||
server = {
|
||||
ROOT_URL = "https://git.blakedheld.xyz";
|
||||
DOMAIN = "git.blakedheld.xyz";
|
||||
# http config
|
||||
ROOT_URL = "https://git.${homelab.public_domain}";
|
||||
DOMAIN = "git.${homelab.public_domain}";
|
||||
HTTP_PORT = cfg.port;
|
||||
# local network config
|
||||
#LOCAL_ROOT_URL = "https://git.snowbelle.lan";
|
||||
ALLOW_LOCALNETWORKS = true;
|
||||
ALLOWED_DOMAINS = homelab.host_ip;
|
||||
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;
|
||||
ALLOW_LOCALNETWORKS = true;
|
||||
ALLOWED_DOMAINS = "10.10.0.10";
|
||||
SKIP_TLS_VERIFY = true;
|
||||
|
||||
DEFAULT_PUSH_CREATE_PRIVATE = true;
|
||||
};
|
||||
};
|
||||
database = {
|
||||
passwordFile = "${toString config.sops.secrets."gitea_database_password".path}";
|
||||
passwordFile = "${toString sec."gitea_database_password".path}";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -96,25 +111,33 @@ in
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [ cfg.port cfg.ssh_port ];
|
||||
networking.firewall.allowedTCPPorts = [cfg.port cfg.ssh_port];
|
||||
|
||||
# add to caddy for reverse proxy
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
serverAliases = [ "git.${homelab.public_domain}" ];
|
||||
services.caddy.virtualHosts."git.${homelab.public_domain}" = {
|
||||
extraConfig = ''
|
||||
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||
reverse_proxy localhost:${toString cfg.port} {
|
||||
}
|
||||
'';
|
||||
};
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
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}"; }];
|
||||
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 = {
|
||||
@@ -125,8 +148,8 @@ in
|
||||
};
|
||||
|
||||
# add to backups
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -4,23 +4,21 @@
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
/*
|
||||
this is a wrapper module for glance that allows you to
|
||||
to pass monitor entries in with nix, all declaratively!
|
||||
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; }];
|
||||
| <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};
|
||||
@@ -29,8 +27,7 @@ let
|
||||
|
||||
uptimekuma_url = "localhost:7901";
|
||||
uptimekuma_page = "glance";
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -67,24 +64,28 @@ in
|
||||
links = {
|
||||
services = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default = [ ];
|
||||
default = [];
|
||||
description = "list of links for ${service}";
|
||||
};
|
||||
mediastack = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default = [ ];
|
||||
default = [];
|
||||
description = "list of links for ${service}";
|
||||
};
|
||||
system = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default = [ ];
|
||||
default = [];
|
||||
description = "list of links for ${service}";
|
||||
};
|
||||
network = 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;
|
||||
@@ -98,7 +99,7 @@ in
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ ];
|
||||
extraGroups = [];
|
||||
};
|
||||
|
||||
services.${service} = {
|
||||
@@ -120,12 +121,13 @@ in
|
||||
};
|
||||
};
|
||||
branding = {
|
||||
#logo-url = "/assets/icons/${config.networking.hostName}.png";
|
||||
logo-url = "/assets/icons/snowbelle.png";
|
||||
favicon-url = "/assets/icons/favicon.ico";
|
||||
};
|
||||
pages = [
|
||||
{
|
||||
name = "snowbelle";
|
||||
name = config.networking.hostName;
|
||||
hide-desktop-navigation = true;
|
||||
columns = [
|
||||
{
|
||||
@@ -140,13 +142,25 @@ in
|
||||
servers = [
|
||||
{
|
||||
type = "local";
|
||||
name = "snowbelle";
|
||||
name = config.networking.hostName;
|
||||
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;};
|
||||
"/" = {
|
||||
name = "root";
|
||||
hide = false;
|
||||
};
|
||||
"/holocron" = {
|
||||
name = "holocron";
|
||||
hide = false;
|
||||
};
|
||||
"/holocron/media" = {
|
||||
name = "media";
|
||||
hide = false;
|
||||
};
|
||||
"/holocron/vault" = {
|
||||
name = "vault";
|
||||
hide = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
@@ -203,17 +217,17 @@ in
|
||||
{
|
||||
title = "nixos options";
|
||||
shortcut = "!no";
|
||||
url = "https://search.nixos.org/options?channel=25.05&query={QUERY}";
|
||||
url = "https://search.nixos.org/options?channel=26.05&query={QUERY}";
|
||||
}
|
||||
{
|
||||
title = "nixos packages";
|
||||
shortcut = "!np";
|
||||
url = "https://search.nixos.org/packages?channel=25.05&query={QUERY}";
|
||||
url = "https://search.nixos.org/packages?channel=26.05&query={QUERY}";
|
||||
}
|
||||
{
|
||||
title = "home-manager options";
|
||||
shortcut = "!hm";
|
||||
url = "https://home-manager-options.extranix.com/?query={QUERY}&release=release-25.05";
|
||||
url = "https://home-manager-options.extranix.com/?query={QUERY}&release=release-26.05";
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -235,6 +249,12 @@ in
|
||||
title = "system";
|
||||
sites = cfg.links.system;
|
||||
}
|
||||
{
|
||||
type = "monitor";
|
||||
cache = "1m";
|
||||
title = "network";
|
||||
sites = cfg.links.network;
|
||||
}
|
||||
{
|
||||
type = "custom-api";
|
||||
title = "recpro";
|
||||
@@ -242,6 +262,13 @@ in
|
||||
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 = "linggango";
|
||||
# url = "https://api.mcstatus.io/v2/status/java/raceraskedforthisenjoyyall.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>";
|
||||
# }
|
||||
];
|
||||
}
|
||||
{
|
||||
@@ -307,25 +334,96 @@ in
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
# serverAliases = [ "${homelab.public_domain}" ];
|
||||
extraConfig = ''
|
||||
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# add to backups
|
||||
system.backups.baks = {
|
||||
homelab.backups.baks = {
|
||||
${service} = {
|
||||
paths = [ cfg.data_dir ];
|
||||
paths = [cfg.data_dir "/var/lib/private"];
|
||||
};
|
||||
};
|
||||
|
||||
# add to vaniville services to glance
|
||||
homelab.glance.links.services = [
|
||||
{
|
||||
title = "vaultwarden";
|
||||
url = "https://pass.${homelab.public_domain}";
|
||||
error-url = "https://pass.vaniville.${homelab.public_domain}";
|
||||
check-url = "https://pass.${homelab.public_domain}";
|
||||
icon = "di:vaultwarden";
|
||||
}
|
||||
{
|
||||
title = "gitea";
|
||||
url = "https://git.${homelab.public_domain}";
|
||||
error-url = "https://git.vaniville.${homelab.public_domain}";
|
||||
check-url = "https://git.${homelab.public_domain}";
|
||||
icon = "di:gitea";
|
||||
}
|
||||
];
|
||||
|
||||
homelab.glance.links.system = [
|
||||
{
|
||||
title = "vaniville uptime";
|
||||
url = "https://up.${homelab.public_domain}";
|
||||
error-url = "https://up.vaniville.${homelab.public_domain}";
|
||||
check-url = "https://up.${homelab.public_domain}";
|
||||
icon = "di:uptime-kuma";
|
||||
}
|
||||
];
|
||||
|
||||
# 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; }];
|
||||
homelab.glance.links.network = [
|
||||
{
|
||||
title = "shauna";
|
||||
url = "https://shauna.holocron.blue";
|
||||
error-url = "https://10.0.0.1";
|
||||
check-url = "https://10.0.0.1";
|
||||
icon = "di:unifi";
|
||||
allow-insecure = true;
|
||||
}
|
||||
{
|
||||
title = "lifeboat";
|
||||
url = "https://lifeboat.holocron.blue";
|
||||
error-url = "https://100.101.11.5";
|
||||
check-url = "https://100.101.11.5";
|
||||
icon = "di:unifi";
|
||||
allow-insecure = true;
|
||||
}
|
||||
{
|
||||
title = "korrina";
|
||||
url = "https://korrina.holocron.blue";
|
||||
error-url = "https://100.101.11.1";
|
||||
check-url = "https://100.101.11.1";
|
||||
icon = "di:unifi";
|
||||
allow-insecure = true;
|
||||
}
|
||||
{
|
||||
title = "linode";
|
||||
url = "https://cloud.linode.com/linodes";
|
||||
error-url = "https://status.linode.com";
|
||||
check-url = "https://cloud.linode.com/linodes";
|
||||
icon = "di:linode";
|
||||
allow-insecure = true;
|
||||
}
|
||||
{
|
||||
title = "tailscale";
|
||||
url = "https://console.tailscale.com/admin/machines";
|
||||
error-url = "https://status.tailscale.com/";
|
||||
check-url = "https://console.tailscale.com/admin/machines";
|
||||
icon = "di:tailscale";
|
||||
allow-insecure = true;
|
||||
}
|
||||
{
|
||||
title = "nextdns";
|
||||
url = "https://my.nextdns.io";
|
||||
error-url = "https://test.nextdns.io";
|
||||
check-url = "https://my.nextdns.io/527db2/setup";
|
||||
icon = "di:nextdns";
|
||||
allow-insecure = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.homelab.home;
|
||||
in {
|
||||
options.homelab.home = {
|
||||
enable = lib.mkEnableOption "enable the smarthome stack";
|
||||
};
|
||||
|
||||
# the order determines the order in glance :3
|
||||
imports = [
|
||||
./zigbee2mqtt
|
||||
./mosquitto
|
||||
./homeassistant
|
||||
./wyoming
|
||||
];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
homelab.hass.enable = lib.mkDefault true;
|
||||
homelab.mosquitto.enable = lib.mkDefault true;
|
||||
homelab.zigbee2mqtt.enable = lib.mkDefault true;
|
||||
homelab.wyoming.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
+32
-27
@@ -1,13 +1,16 @@
|
||||
{ pkgs, config, lib, inputs, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
nixservice = "home-assistant";
|
||||
service = "hass";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -44,9 +47,8 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -71,10 +73,6 @@ in
|
||||
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;
|
||||
@@ -89,34 +87,42 @@ in
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [ cfg.port 8123 ];
|
||||
networking.firewall.allowedTCPPorts = [cfg.port 8123 21063 21064];
|
||||
networking.firewall.allowedUDPPorts = [5353];
|
||||
|
||||
# add to caddy for reverse proxy
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
serverAliases = [ "${service}.${homelab.public_domain}" ];
|
||||
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}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port} {
|
||||
|
||||
header_up Host {host}
|
||||
header_up X-Real-IP {remote_host}
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
header_up X-Forwarded-Proto https
|
||||
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# 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}"; }];
|
||||
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
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
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
|
||||
@@ -158,4 +164,3 @@ in
|
||||
## };
|
||||
# };
|
||||
|
||||
|
||||
+16
-14
@@ -1,12 +1,14 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "mosquitto";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,9 +45,8 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -65,15 +66,16 @@ in
|
||||
port = 1883;
|
||||
address = "0.0.0.0";
|
||||
users.zigbee = {
|
||||
acl = [ "readwrite #" ];
|
||||
acl = ["readwrite #"];
|
||||
hashedPassword = "$7$101$140powz2MtsRawFT$ydndjal9wCAywIWtUEAh/IusdfDFvnHMupTFjdS7Ad/EjsEIbJgHrLY9waCe4Z3142XieuxMrXUDjMTp2qwyiw==";
|
||||
};
|
||||
# use with no auth
|
||||
# settings.allow_anonymous = true;
|
||||
# acl = [ "pattern readwrite #" ];
|
||||
# omitPasswordAuth = true;
|
||||
# settings.allow_anonymous = true;
|
||||
# acl = [ "pattern readwrite #" ];
|
||||
# omitPasswordAuth = true;
|
||||
}
|
||||
];
|
||||
|
||||
# override umask to make permissions work out
|
||||
systemd.services.${service}.serviceConfig = {
|
||||
UMask = lib.mkForce "0007";
|
||||
@@ -82,7 +84,7 @@ in
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||
networking.firewall.allowedTCPPorts = [cfg.port];
|
||||
|
||||
sops.secrets = {
|
||||
"${service}_hashed_passwd" = {
|
||||
@@ -92,8 +94,8 @@ in
|
||||
};
|
||||
|
||||
# add to backups
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "wyoming";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
# set port options
|
||||
faster_whisper_port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 7706;
|
||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
};
|
||||
piper_port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 7707;
|
||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# enable the ${service} service
|
||||
services.${service} = {
|
||||
faster-whisper = {
|
||||
servers = {
|
||||
vanessa = {
|
||||
enable = true;
|
||||
language = "en";
|
||||
uri = "tcp://0.0.0.0:${toString cfg.faster_whisper_port}";
|
||||
model = "medium";
|
||||
device = "auto";
|
||||
};
|
||||
};
|
||||
};
|
||||
piper = {
|
||||
servers = {
|
||||
vanessa = {
|
||||
enable = true;
|
||||
uri = "tcp://0.0.0.0:${toString cfg.piper_port}";
|
||||
voice = "en_US-amy-medium";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [cfg.faster_whisper_port cfg.piper_port];
|
||||
};
|
||||
}
|
||||
+46
-41
@@ -1,12 +1,14 @@
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "zigbee2mqtt";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in
|
||||
{
|
||||
in {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
@@ -43,9 +45,8 @@ in
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
# declare ${service} group
|
||||
users.groups.${service} = { gid = lib.mkForce cfg.ids; };
|
||||
users.groups.${service} = {gid = lib.mkForce cfg.ids;};
|
||||
|
||||
# declare ${service} user
|
||||
users.users.${service} = {
|
||||
@@ -63,28 +64,29 @@ in
|
||||
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;
|
||||
};
|
||||
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;
|
||||
experimental_event_entities = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -95,25 +97,28 @@ in
|
||||
Group = service;
|
||||
};
|
||||
|
||||
# # open firewall
|
||||
networking.firewall.allowedTCPPorts = [ cfg.port ];
|
||||
# # open firewall
|
||||
networking.firewall.allowedTCPPorts = [cfg.port];
|
||||
|
||||
# add to caddy for reverse proxy
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
serverAliases = [ "z2m.${homelab.public_domain}" ];
|
||||
serverAliases = ["z2m.${homelab.public_domain}"];
|
||||
extraConfig = ''
|
||||
tls ${sec."ssl_blakedheld_crt".path} ${sec."ssl_blakedheld_key".path}
|
||||
tls internal
|
||||
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}"; }];
|
||||
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" = {
|
||||
@@ -123,8 +128,8 @@ in
|
||||
};
|
||||
|
||||
# add to backups
|
||||
system.backups.baks = {
|
||||
${service} = { paths = [ cfg.data_dir ]; };
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
+37
-71
@@ -2,23 +2,20 @@
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
service = "copyparty";
|
||||
cfg = config.holocron.${service};
|
||||
service = "homebox";
|
||||
cfg = config.homelab.${service};
|
||||
sec = config.sops.secrets;
|
||||
homelab = config.homelab;
|
||||
in {
|
||||
imports = [inputs.copyparty.nixosModules.default];
|
||||
|
||||
options.holocron.${service} = {
|
||||
options.homelab.${service} = {
|
||||
enable = lib.mkEnableOption "enables ${service}";
|
||||
|
||||
# set port options
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 7902;
|
||||
default = 7709;
|
||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
};
|
||||
url = lib.mkOption {
|
||||
@@ -41,10 +38,13 @@ 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 {
|
||||
nixpkgs.overlays = [inputs.copyparty.overlays.default];
|
||||
# declare ${service} group
|
||||
users.groups.${service} = {
|
||||
gid = lib.mkForce cfg.ids;
|
||||
@@ -58,7 +58,6 @@ in {
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [ "media" "blake" ];
|
||||
};
|
||||
|
||||
# enable the ${service} service
|
||||
@@ -67,73 +66,39 @@ in {
|
||||
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;
|
||||
};
|
||||
};
|
||||
HBOX_WEB_PORT = toString cfg.port;
|
||||
HBOX_STORAGE_CONN_STRING = "file://${cfg.data_dir}";
|
||||
HBOX_STORAGE_PREFIX_PATH = "data";
|
||||
HBOX_DATABASE_DRIVER = "sqlite3";
|
||||
HBOX_DATABASE_SQLITE_PATH = "${cfg.data_dir}/data/homebox.db?_pragma=busy_timeout=999&_pragma=journal_mode=WAL&_fk=1";
|
||||
HBOX_OPTIONS_ALLOW_REGISTRATION = "false";
|
||||
HBOX_OPTIONS_GITHUB_RELEASE_CHECK = "false";
|
||||
HBOX_MODE = "production";
|
||||
HOME = cfg.data_dir;
|
||||
TMPDIR = "${cfg.data_dir}/tmp";
|
||||
};
|
||||
};
|
||||
|
||||
# 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} {
|
||||
}
|
||||
tls internal
|
||||
reverse_proxy 127.0.0.1:${toString cfg.port}
|
||||
'';
|
||||
};
|
||||
|
||||
# add to glance (local service)
|
||||
homelab.glance.links.system = [
|
||||
homelab.glance.links.services = [
|
||||
{
|
||||
title = service;
|
||||
url = "https://${cfg.url}";
|
||||
@@ -142,16 +107,17 @@ in {
|
||||
icon = "di:${service}";
|
||||
}
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
"${service}_passwd" = {
|
||||
owner = service;
|
||||
group = service;
|
||||
};
|
||||
};
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
# sops.secrets = {
|
||||
# "${service}_" = {
|
||||
# owner = ;
|
||||
# group = ;
|
||||
# };
|
||||
# };
|
||||
|
||||
# add to backups
|
||||
system.backups.baks = {
|
||||
homelab.backups.baks = {
|
||||
${service} = {
|
||||
paths = [cfg.data_dir];
|
||||
};
|
||||
@@ -0,0 +1,148 @@
|
||||
{
|
||||
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";
|
||||
};
|
||||
library_sync_dir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/holocron/users/blake/pictures/library";
|
||||
description = "set directory to automatically rsync library to storage pool";
|
||||
};
|
||||
};
|
||||
|
||||
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 = pkgs.unstable.immich;
|
||||
openFirewall = true;
|
||||
user = service;
|
||||
group = service;
|
||||
mediaLocation = cfg.data_dir;
|
||||
host = "0.0.0.0";
|
||||
port = cfg.port;
|
||||
settings = null;
|
||||
};
|
||||
|
||||
# too lazy to add an option, this is on the storage pool now anyway
|
||||
# systemd.services.immich_library_sync = {
|
||||
# description = "twice daily sync immich library to holocron";
|
||||
# serviceConfig = {
|
||||
# Type = "oneshot";
|
||||
# User = "root";
|
||||
# };
|
||||
#
|
||||
# script = ''
|
||||
# ${pkgs.rsync}/bin/rsync -avh --info=progress2 --delete \
|
||||
# --chown=blake:blake \
|
||||
# /var/lib/immich/library/blake/ \
|
||||
# /holocron/users/blake/pictures/library/
|
||||
# '';
|
||||
# };
|
||||
#
|
||||
# systemd.timers.immich_library_sync = {
|
||||
# wantedBy = ["timers.target"];
|
||||
# timerConfig = {
|
||||
# OnBootSec = "5m";
|
||||
# OnUnitActiveSec = "12h";
|
||||
# Persistent = true;
|
||||
# };
|
||||
# };
|
||||
|
||||
# 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 internal
|
||||
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.postgresql.ensureDatabases = [service]; # set to all databases defined in esure databases
|
||||
|
||||
# add to backups
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = ["/var/lib/redis-immich" "/var/backup/postgresql/immich.sql.zstd"];};
|
||||
#${service} = {paths = [cfg.data_dir "/var/lib/redis-immich" "/var/backup/postgresql/immich.sql.zstd"];};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "radicale";
|
||||
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 = "cal.${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;
|
||||
};
|
||||
|
||||
# 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}"];
|
||||
# use explicitly defined tls cert
|
||||
# tls /etc/ssl/blakedheld.xyz.crt /etc/ssl/blakedheld.xyz.key
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
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];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
service = "searx";
|
||||
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 = 7709;
|
||||
description = "set port for ${service} (default: ${toString cfg.port}";
|
||||
};
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "search.${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;
|
||||
shell = pkgs.bash;
|
||||
home = cfg.data_dir;
|
||||
createHome = true;
|
||||
group = service;
|
||||
extraGroups = [];
|
||||
};
|
||||
|
||||
# declare the gitea service
|
||||
services.${service} = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server.port = cfg.port;
|
||||
server.bind_address = "0.0.0.0";
|
||||
#server.secret_key = "$SEARX_SECRET_KEY";
|
||||
engines = [
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# override umask to make permissions work out
|
||||
systemd.services.${service}.serviceConfig = {
|
||||
UMask = lib.mkForce "0007";
|
||||
};
|
||||
|
||||
# open firewall
|
||||
networking.firewall.allowedTCPPorts = [cfg.port];
|
||||
|
||||
services.caddy.virtualHosts."${cfg.url}" = {
|
||||
extraConfig = ''
|
||||
tls internal
|
||||
reverse_proxy localhost:${toString cfg.port} {
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# add to glance
|
||||
homelab.glance.links.services = [
|
||||
{
|
||||
title = service;
|
||||
url = "https://search.${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;
|
||||
};
|
||||
};
|
||||
|
||||
# add to backups
|
||||
homelab.backups.baks = {
|
||||
${service} = {paths = [cfg.data_dir];};
|
||||
};
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user