Compare commits
792 Commits
wg-dev
...
wip-nix-fa
Author | SHA1 | Date | |
---|---|---|---|
084541da4c | |||
f7a82a845c | |||
2bdef04552 | |||
2822a6f0dd | |||
ab6e362f0c | |||
3816393e06 | |||
4c6c470c86 | |||
409a4db232 | |||
c73684557e | |||
44067f6570 | |||
466e7a9ecd | |||
6b2d189771 | |||
6ef729bbaf | |||
8f424dcd5a | |||
7fb7f72bc0 | |||
67536e3c1f | |||
715de37954 | |||
c8035abddf | |||
ef1cdac6b4 | |||
e37a7d85b3 | |||
36f6c72183 | |||
20a1aeb5b3 | |||
9ba0833d5f | |||
15f353f883 | |||
27af0002c8 | |||
9265252e04 | |||
11a53c402d | |||
464f439f4a | |||
a4dbf18d7a | |||
1579e089e9 | |||
4ce0c23c19 | |||
9710d55c6a | |||
4b014af4b1 | |||
4379addf9e | |||
5c7eceeb55 | |||
50aa16df81 | |||
b1e943c9bb | |||
be5fae369f | |||
40e22533fb | |||
03c5f82dbf | |||
e90bbfe551 | |||
92033c8414 | |||
16f0424631 | |||
6fd1ce1f61 | |||
a7c325c8e1 | |||
fc7814e6cd | |||
245e6c93cd | |||
ec073592ed | |||
617525a317 | |||
1098d121b4 | |||
821c631b1d | |||
96347ad7ac | |||
4f933cc0fa | |||
03615ce244 | |||
7d613d90d8 | |||
afd52014d1 | |||
dd6e1c5e38 | |||
d0d7994c2f | |||
b5da7a86fa | |||
f2e1bb6b86 | |||
fe0f6988bd | |||
c402a265cd | |||
d5643a6a5d | |||
e757e35065 | |||
953dd98b0f | |||
c9c1181242 | |||
f9888fe8d6 | |||
036145e6ba | |||
5b647a1a90 | |||
7c486492c8 | |||
890b41f563 | |||
ca36fe1b96 | |||
d2df668c9e | |||
b7921ac41b | |||
c304367e21 | |||
2ad33a49df | |||
0b4efd2ab2 | |||
0745e9fc06 | |||
e0267b5669 | |||
b3c7aac8c5 | |||
c788596c45 | |||
f807d7c0a2 | |||
6ab5dd8a8f | |||
52b8cd0209 | |||
6865331b48 | |||
dd00a2fe6e | |||
4ee02151f4 | |||
00bf2f79cc | |||
04a6055d06 | |||
15a7793f0d | |||
f714bd8281 | |||
73b2594d9b | |||
a55dc5332d | |||
86108518da | |||
0f1ad0f3c9 | |||
bcd7a6f646 | |||
92c2eb8383 | |||
879d01ac2e | |||
0448df51e3 | |||
8e3eed7d51 | |||
88a70b41f1 | |||
6f59254a22 | |||
4023960dc0 | |||
fff9f9d49a | |||
eecb98e2ee | |||
5838603953 | |||
c6ebcfe66e | |||
d7402ae170 | |||
bd7ca20361 | |||
f5ef1e96ca | |||
6267e7f966 | |||
120a41b169 | |||
aa0991bd6c | |||
af2f97d61e | |||
5b8f13d9cc | |||
62b39bf01e | |||
0d8307e877 | |||
9b1a2ae9bb | |||
b8b805765b | |||
84eae20765 | |||
4a10c5f729 | |||
c2696c1cd9 | |||
c23e4dc9c7 | |||
ea6f45555c | |||
687db545b4 | |||
24d1d13d0a | |||
2ada436634 | |||
e5ad0862fb | |||
057b9e3fed | |||
1bcfccf7e3 | |||
170eeeacc4 | |||
a402822084 | |||
80ecdcc4f9 | |||
0864790bb7 | |||
478747a96e | |||
771dc2e1ce | |||
4a316d4b91 | |||
0ff8154e96 | |||
af03b3f6e8 | |||
5819f07181 | |||
122f3fa5cc | |||
ece612ea70 | |||
f27f994090 | |||
473999c001 | |||
d1de9efde1 | |||
50c3f04714 | |||
49bad8f186 | |||
fd9f500e97 | |||
386651044e | |||
55a6c828f2 | |||
7ecebd7521 | |||
7b299176e3 | |||
4da9cb5ac8 | |||
f068da709f | |||
5b21257e4f | |||
d77a12ce7b | |||
153d2a1047 | |||
2a528a5d8e | |||
b8f090be93 | |||
b16902bec1 | |||
c919372324 | |||
60371585e4 | |||
20cb850fb5 | |||
c6470918de | |||
c0f374bd80 | |||
5a0760a571 | |||
757ab79724 | |||
81148b7b42 | |||
429d0c53e7 | |||
6cf1bc5a28 | |||
768b340c93 | |||
d9901aa161 | |||
be2098c18a | |||
ee7d99289a | |||
bb569b1668 | |||
34524ea3e4 | |||
71025329e7 | |||
ca4d1e3b9d | |||
284b698015 | |||
bc50daf685 | |||
47dcfb9cba | |||
2bd99f6e51 | |||
8beac8df2f | |||
58db553c84 | |||
2ea3776d84 | |||
d596d005ca | |||
e92db138ef | |||
5fed127c23 | |||
db49f0461c | |||
73bb7827c0 | |||
a624571b22 | |||
53cbe5c8da | |||
46de7b7e0d | |||
d7be5da483 | |||
902e351085 | |||
9e8e1d82a6 | |||
a05184f956 | |||
36ad2d5421 | |||
b0f62830a5 | |||
f970679266 | |||
c7f4661c1c | |||
e8306831c5 | |||
41b1a013d7 | |||
f785ccd351 | |||
48744dcaaa | |||
9373864b60 | |||
c16c9dfe0b | |||
292a411fb3 | |||
2d17826731 | |||
34dedcff57 | |||
de297f22be | |||
4b47b76461 | |||
3effd59c9b | |||
a3d0691d99 | |||
44647e0d36 | |||
da1053d635 | |||
273b1b84e3 | |||
0b6b98bba6 | |||
8886177c23 | |||
7e343bfc05 | |||
f72bdb6f3a | |||
5666a05ef0 | |||
05daf738fc | |||
35b4cc779f | |||
c7d111a318 | |||
7e5eb6324d | |||
95cb5624ca | |||
55c305812d | |||
600f6eb56c | |||
fd6f8493a7 | |||
f10f1ee7b1 | |||
67395bdcd3 | |||
90ceeede74 | |||
32a704b1b8 | |||
a591be98d4 | |||
82e028e37d | |||
a531676d0d | |||
7f7543ee78 | |||
8d0e3e0db3 | |||
bf352d184c | |||
81a6600f54 | |||
9fde167e71 | |||
4e180e11df | |||
902166e45a | |||
797bc4e188 | |||
536f0aedc3 | |||
b855df902f | |||
80ce49c579 | |||
408059420d | |||
a3102c9395 | |||
6760fcf1f4 | |||
a90898491e | |||
059940d8e7 | |||
98aafead94 | |||
cef2591425 | |||
f8663cd827 | |||
af1ee1734d | |||
5375cab716 | |||
162b3f5674 | |||
a729f91d21 | |||
a273b559e2 | |||
785b375671 | |||
24cba0c856 | |||
df1db5d01c | |||
6749b64bca | |||
d3e4bdfcd5 | |||
799cd4373f | |||
2efa6d1e27 | |||
a1470956a5 | |||
556c20bc04 | |||
cf5f58dda6 | |||
fd30f7abbc | |||
6f8c299c69 | |||
bbf7aac062 | |||
7d1fd2f30a | |||
472987f164 | |||
784c2145f3 | |||
4ced02b0b2 | |||
0000afb315 | |||
31fa21bd20 | |||
9510817604 | |||
4a84de3ee4 | |||
ab42a4cc5a | |||
f6537b083a | |||
5ff1d014b8 | |||
fa41e6c402 | |||
1b4306e649 | |||
af8a8358bd | |||
464c6c56c5 | |||
8e314e8b73 | |||
198029f95f | |||
1d646459ab | |||
8f3bab3636 | |||
a909a93c29 | |||
6aaa724abf | |||
a1c721d5b4 | |||
4002a57e03 | |||
74a0b0d125 | |||
cd3b4dde7b | |||
a9d384688a | |||
fffd6f4204 | |||
324485d105 | |||
7cb8b144b2 | |||
c2bb97e7e6 | |||
3cbdc03369 | |||
5c7fa591a0 | |||
18c54e8b04 | |||
1416856fb6 | |||
2a5bc6f612 | |||
c56a6a8c24 | |||
f5a4bdedaf | |||
114a45f347 | |||
d53344d527 | |||
561447de70 | |||
b6f918c32f | |||
9cc12fab5d | |||
5cda3b2805 | |||
4afd56ff4c | |||
029ba43bd6 | |||
00e4078300 | |||
94b4f78e39 | |||
3fd89ec91b | |||
4085828575 | |||
1a972927b6 | |||
5f3ec42f57 | |||
28aaeb051f | |||
9d252d095e | |||
4e5e4219ec | |||
824dd7c1f5 | |||
b840a0d61c | |||
36bcecfd68 | |||
c3a5fb9394 | |||
30507c3564 | |||
2b66ffc58a | |||
48d96c1f36 | |||
cdf61755a3 | |||
dd1dc69530 | |||
481f54ea2f | |||
511752fab5 | |||
40ed7cff1b | |||
5e7f914354 | |||
8c9c6ec979 | |||
0dec8b6d5b | |||
7eaffc9fa0 | |||
b7c1a6331d | |||
d6868d58e6 | |||
1edb1fc8b6 | |||
52d768a162 | |||
7a685d8de9 | |||
838c6d7dc8 | |||
8d20dcadd1 | |||
9d706df5b5 | |||
06f1f1e9ea | |||
2fbbe7fd78 | |||
24d23f7903 | |||
0394aa65e9 | |||
5090c4e88c | |||
081114da65 | |||
c943442c94 | |||
02b7586ffa | |||
02dd629616 | |||
25dcb7f89a | |||
88f1d63b6e | |||
d36e269edd | |||
40af8b95fd | |||
582a003739 | |||
df60be8c61 | |||
e8b4c36442 | |||
2f699737f5 | |||
4a3d24be3f | |||
10feb319fe | |||
fde1e5d872 | |||
b2fcf6fdfd | |||
dcc2eb265d | |||
5f1036118f | |||
8ac4869f10 | |||
226425bbef | |||
518c3afd07 | |||
90dee85664 | |||
26fc283fd9 | |||
d0430ce1e9 | |||
368a52b91e | |||
d90dacee1f | |||
a6e2b3bc5c | |||
8863a3c674 | |||
fa8d6dbb9f | |||
e5e79a6b60 | |||
95f7eeeb5c | |||
29d638c68b | |||
7d22a5466f | |||
b747742e23 | |||
5907d9fa42 | |||
67fe8d4666 | |||
22ca253ae0 | |||
c9e02bfd8a | |||
03b58b3cab | |||
ae01c17c05 | |||
677e6e679b | |||
3eb47a9a8d | |||
f11e443678 | |||
9faf1bb52c | |||
e599724811 | |||
c0b03950dc | |||
8f8ec090c4 | |||
e174eaeff0 | |||
8b32f2f231 | |||
f12b7afa1e | |||
080bd856ec | |||
548a95a7e1 | |||
2d7c5b9fa5 | |||
e696cb96b6 | |||
83cb29aeeb | |||
34b148f6cc | |||
44c2f8bcc0 | |||
9c18aa2765 | |||
4458a74e4c | |||
1a18ed533b | |||
18eec98cae | |||
82c386a6a4 | |||
634dc318cd | |||
6eaaeeb91a | |||
94be4a7551 | |||
b4a20da78a | |||
bb68506839 | |||
77e2af0ed9 | |||
126f3e4922 | |||
73afceb8c6 | |||
371af5939e | |||
27fd81ad80 | |||
d82b4b0f62 | |||
7b28023e08 | |||
2b9db897a1 | |||
6124cb9b36 | |||
b0394d877d | |||
14d8230821 | |||
e94e338040 | |||
354ce378f6 | |||
a90b5b53db | |||
eee3e138ff | |||
f61cd17e99 | |||
3e0b0a0f02 | |||
2ee34e9af3 | |||
f9a998eb92 | |||
7c05d221d6 | |||
93012664e5 | |||
c424f7ac3b | |||
088b6f1b9a | |||
96575acf3a | |||
1e05119adc | |||
e81df0ac86 | |||
b19492ba23 | |||
8b26fa1303 | |||
c0883dc777 | |||
6b3a71aadf | |||
8d0d20757e | |||
66ca822ac1 | |||
db7a414030 | |||
87050a0500 | |||
bf53e3628a | |||
d35f938806 | |||
d719eb0f11 | |||
0861edd7f9 | |||
b6bf8720c9 | |||
0fbc10fce3 | |||
772f1070e7 | |||
50c6e406bc | |||
41020b2c0d | |||
590a239f7d | |||
bcbc57f5ef | |||
0d3adcdc5c | |||
d19907a38d | |||
9ac0e0e4fc | |||
c9af5bf9b4 | |||
bc85169e3d | |||
7b9b3344a0 | |||
f6ca6210f9 | |||
19cfc86d1a | |||
227d159c66 | |||
a6becb8c42 | |||
2a5398beb3 | |||
0f12ed68f7 | |||
0c050d1953 | |||
2fc1fe7510 | |||
8d705af7a0 | |||
e91ec2c35e | |||
5fbf66fb15 | |||
97d50629e9 | |||
5f8699fcef | |||
7ce957c3af | |||
d7612d5034 | |||
5ff7bf0c69 | |||
2495200b67 | |||
4c499629f5 | |||
7b9f54dd54 | |||
bda932c3df | |||
3f96f4af82 | |||
1c4e2f97fe | |||
594a729968 | |||
5c8bb55cec | |||
6eb2a3d67f | |||
ddc41bc9d8 | |||
7d833ebf76 | |||
bfc0eadfaa | |||
ff1cbcc16b | |||
fd81e35c31 | |||
9a8d8a20bd | |||
cd1d22e7b9 | |||
2c0e93826d | |||
cab346f3ad | |||
568a72f6a4 | |||
a2decaff9c | |||
23411ed973 | |||
8ef9f7a485 | |||
12846732b9 | |||
e84079e84c | |||
45ffd9246d | |||
ed3935318d | |||
8052f62796 | |||
413903d03c | |||
6d1eae2200 | |||
4d51c34ad2 | |||
bc50a8c489 | |||
ee8e33b795 | |||
8afb6406a1 | |||
7ac1ee66ad | |||
8a47eb92ed | |||
b87934d5f8 | |||
293eab8225 | |||
abdbb83e10 | |||
4a96fa233a | |||
4bd73ddca3 | |||
dc74bca06a | |||
42523b75a8 | |||
79736a4a0a | |||
111946eb1d | |||
09f3bfc944 | |||
b8fc75ebd6 | |||
8de015f098 | |||
6da85f6d8f | |||
2dc6da476b | |||
453f40d0a8 | |||
14b20fd9c2 | |||
2df1b20f02 | |||
56e7e9a7cc | |||
2f9fad503c | |||
3439ca34b8 | |||
24e6e6cacc | |||
0ee9f2026c | |||
5e3c2636db | |||
cd0a046776 | |||
27edee0bbf | |||
56734fe5da | |||
832a572d56 | |||
3c96f6d418 | |||
86b23e8183 | |||
2bb9115f35 | |||
065d045640 | |||
d3eaa69261 | |||
6151eee8d5 | |||
483a1d1780 | |||
567c7993b6 | |||
f6eeab5650 | |||
2824671bde | |||
efcaef2c35 | |||
25707eb79e | |||
18679cd8c3 | |||
09923b60ea | |||
3100189172 | |||
715ac42f13 | |||
a9810e7343 | |||
4f352c5725 | |||
17f35a3619 | |||
89d4f3eec3 | |||
44419d71a5 | |||
02e597a862 | |||
00f995aec9 | |||
368eb2c29b | |||
5f793523d1 | |||
33bee7ac2e | |||
84af8aca3c | |||
a0f00313a7 | |||
6603115192 | |||
ac968e1589 | |||
2d4fc4f274 | |||
1d72e13a98 | |||
d9667653e7 | |||
8c6bf07102 | |||
634520a1e9 | |||
13be5a1731 | |||
30288cd67f | |||
87e2509af4 | |||
8736ca478b | |||
cb3960fb21 | |||
6e24a1ff28 | |||
91eae95b32 | |||
f5c88853ee | |||
0009e5ca4c | |||
0403d5c03e | |||
db6ba61429 | |||
881d2f79ed | |||
47abdfb831 | |||
3831c6f087 | |||
d3f7a036ce | |||
0454abacd9 | |||
4f8d476ebf | |||
1cb2c5225f | |||
7af970f38c | |||
6f86e61a00 | |||
3ea3776281 | |||
a7eb8dd6fa | |||
c1a1f51ca2 | |||
32824cfade | |||
51fc61b211 | |||
7b9795ea3d | |||
5f3e481fe4 | |||
86219d7006 | |||
381da74e6c | |||
24c70c3683 | |||
bfec531fa2 | |||
de11edffa5 | |||
294f167df0 | |||
e536e3c718 | |||
17d14dbac2 | |||
94981ef335 | |||
3cd244be76 | |||
f100595257 | |||
e84da827c2 | |||
42f9fa029d | |||
40fee97b06 | |||
3cc8292d8b | |||
9261d30a34 | |||
3eb3a8db5a | |||
97129268f0 | |||
fa39a965ca | |||
7da979503b | |||
3b32c26026 | |||
cad25306e7 | |||
4d7414c941 | |||
b29b8bdec7 | |||
a7d081bfcb | |||
5ca208d07f | |||
6c605944c5 | |||
02b6e17449 | |||
770db96ec6 | |||
ff356fdd49 | |||
eec89e2cc1 | |||
d69d8f64f3 | |||
4ee2562202 | |||
08b1ece56e | |||
26b978dcf2 | |||
b22c2e094c | |||
b40775f97c | |||
a27a72646c | |||
100ddad40e | |||
d8b6d419b6 | |||
1bde38bf72 | |||
a06c81643c | |||
15fd7bf4a5 | |||
0a25ef544f | |||
a6b824d3c4 | |||
79ee47bada | |||
be06e61bfb | |||
3b4884fcf1 | |||
4319dc58eb | |||
3122434908 | |||
dae7785ee2 | |||
d54f8b1e93 | |||
27f3b2bd76 | |||
b417f60769 | |||
df2d5b6d01 | |||
3e6278fa21 | |||
a66b257644 | |||
ef66d2ec72 | |||
e21dbd507d | |||
64878bee67 | |||
557a080ffc | |||
8ecb17ed3e | |||
c4874c85b1 | |||
563a75e9b2 | |||
7f002b8718 | |||
79e2bd2913 | |||
95161b55cd | |||
d91759068c | |||
c23c496066 | |||
824630f7d1 | |||
f8e8d23857 | |||
8484bb7978 | |||
57105c6861 | |||
3758044e7b | |||
bfaf098c31 | |||
0e99b296bc | |||
089f86d5e4 | |||
d0e1241bd1 | |||
c1a0a08b76 | |||
e8748ce0a0 | |||
7cf9b342cc | |||
8739851f48 | |||
d945b43f6b | |||
fcc3ea1e39 | |||
7722acecee | |||
bdd70f8fa2 | |||
571a0a9d06 | |||
ccf4f66dd9 | |||
b38e5403a5 | |||
09af041745 | |||
cb5131746f | |||
2fbd0f8ee1 | |||
bfd5630e21 | |||
026f5dee4d | |||
b59be8338a | |||
ab4bbc2224 | |||
156fcd1bf2 | |||
576d2c32f0 | |||
bb63a594ab | |||
25739ec2ba | |||
f148334b58 | |||
da537ea8ea | |||
18d224dc34 | |||
3a6ee8708e | |||
983bf93d8f | |||
40cc8f5d1c | |||
cce03a5dc8 | |||
38fd171713 | |||
84c78d9256 | |||
973203d85e | |||
f9174dd2aa | |||
98dfc3aa5a | |||
27b56b1a12 | |||
6e9220d2bb | |||
0ddcfcaa23 | |||
a4cb6645b4 | |||
2492ed2ca7 | |||
f49d2a1e0e | |||
0dc3f4f7f2 | |||
0bed4d0ada | |||
f3e8af3fdb | |||
af542ec05f | |||
399a1d2052 | |||
bb6e5611d4 | |||
d5901afb8e | |||
c11f5a1401 | |||
5b220f3fec | |||
8bf41ea858 | |||
df861a3ef0 | |||
d6754b6cac | |||
b03d7f7fb0 | |||
008b186479 | |||
914f9b3703 | |||
ed7ec4a371 | |||
2d338201a5 | |||
a8aad1f98f | |||
2d06b93118 | |||
60547204a8 | |||
3d763a0021 | |||
ad474873e2 | |||
dd35136ac0 | |||
cfe6e9c20a | |||
0f3f0933b1 | |||
f8440e3811 | |||
829460a076 | |||
9ecd0adcbe | |||
ad92a2e158 | |||
5f5891d241 | |||
cf475c4696 | |||
992194a1f0 | |||
bad6a7bfee | |||
66d5e204be | |||
ce35330923 | |||
bdab1aa7e3 | |||
080c8dbe3d | |||
a31fe44624 | |||
59187a0ec0 | |||
03fbf42680 | |||
f3b2a98874 | |||
2e9084c9ef | |||
0907240fda | |||
7d670facd4 | |||
61e5704fd6 | |||
fd0723169f | |||
a725d42bf5 | |||
c03cea2d4e | |||
f43d6bff92 | |||
43a8ca90a7 | |||
dac6046828 | |||
e2a6ae22dc | |||
f2ee43d1ef | |||
3d80b46570 | |||
e7d383604a | |||
7d504892be | |||
d7a2bf9d26 | |||
d6184a7b6d | |||
851c15aa6d |
21
README.md
21
README.md
@@ -1,3 +1,7 @@
|
|||||||
|

|
||||||
|
|
||||||
|
# .❄️≡We|_c0m3 7o m`/ f14k≡❄️.
|
||||||
|
|
||||||
## What's Here
|
## What's Here
|
||||||
|
|
||||||
this is the top-level repo from which i configure/deploy all my NixOS machines:
|
this is the top-level repo from which i configure/deploy all my NixOS machines:
|
||||||
@@ -6,18 +10,18 @@ this is the top-level repo from which i configure/deploy all my NixOS machines:
|
|||||||
- server
|
- server
|
||||||
- mobile phone (Pinephone)
|
- mobile phone (Pinephone)
|
||||||
|
|
||||||
everything outside of <./hosts/> and <./secrets/> is intended for export, to be importable for use by 3rd parties.
|
everything outside of [hosts/](./hosts/) and [secrets/](./secrets/) is intended for export, to be importable for use by 3rd parties.
|
||||||
the only hard dependency for my exported pkgs/modules should be [nixpkgs][nixpkgs].
|
the only hard dependency for my exported pkgs/modules should be [nixpkgs][nixpkgs].
|
||||||
building <./hosts/> will require [sops][sops].
|
building [hosts/](./hosts/) will require [sops][sops].
|
||||||
|
|
||||||
you might specifically be interested in these files (elaborated further in #key-points-of-interest):
|
you might specifically be interested in these files (elaborated further in #key-points-of-interest):
|
||||||
- [`sxmo-utils`](./pkgs/additional/sxmo-utils/default.nix)
|
- [`sxmo-utils`](./pkgs/additional/sxmo-utils/default.nix)
|
||||||
- [example SXMO deployment](./hosts/modules/gui/sxmo/default.nix)
|
- [example SXMO deployment](./hosts/modules/gui/sxmo/default.nix)
|
||||||
- [my implementation of impermanence](./modules/persist/default.nix)
|
- [my implementation of impermanence](./modules/persist/default.nix)
|
||||||
- my way of deploying dotfiles/configuring programs per-user:
|
- my way of deploying dotfiles/configuring programs per-user:
|
||||||
- <./modules/fs/default.nix>
|
- [modules/fs/](./modules/fs/default.nix)
|
||||||
- <./modules/programs.nix>
|
- [modules/programs/](./modules/programs/default.nix)
|
||||||
- <./modules/users.nix>
|
- [modules/users.nix](./modules/users.nix)
|
||||||
|
|
||||||
[nixpkgs]: https://github.com/NixOS/nixpkgs
|
[nixpkgs]: https://github.com/NixOS/nixpkgs
|
||||||
[sops]: https://github.com/Mic92/sops-nix
|
[sops]: https://github.com/Mic92/sops-nix
|
||||||
@@ -94,11 +98,16 @@ i.e. you might find value in using these in your own config:
|
|||||||
- persist things to encrypted storage which is unlocked at login time (pam_mount).
|
- persist things to encrypted storage which is unlocked at login time (pam_mount).
|
||||||
- "persist" cache directories -- to free up RAM -- but auto-wipe them on mount
|
- "persist" cache directories -- to free up RAM -- but auto-wipe them on mount
|
||||||
and encrypt them to ephemeral keys so they're unreadable post shutdown/unmount.
|
and encrypt them to ephemeral keys so they're unreadable post shutdown/unmount.
|
||||||
- `modules/programs.nix`
|
- `modules/programs/`
|
||||||
- like nixpkgs' `programs` options, but allows both system-wide or per-user deployment.
|
- like nixpkgs' `programs` options, but allows both system-wide or per-user deployment.
|
||||||
- allows `fs` and `persist` config values to be gated behind program deployment:
|
- allows `fs` and `persist` config values to be gated behind program deployment:
|
||||||
- e.g. `/home/<user>/.mozilla/firefox` is persisted only for users who
|
- e.g. `/home/<user>/.mozilla/firefox` is persisted only for users who
|
||||||
`sane.programs.firefox.enableFor.user."<user>" = true;`
|
`sane.programs.firefox.enableFor.user."<user>" = true;`
|
||||||
|
- allows aggressive sandboxing any program:
|
||||||
|
- `sane.programs.firefox.sandbox.method = "bwrap"; # sandbox with bubblewrap`
|
||||||
|
- `sane.programs.firefox.sandbox.whitelistWayland = true; # allow it to render a wayland window`
|
||||||
|
- `sane.programs.firefox.sandbox.extraHomePaths = [ "Downloads" ]; # allow it read/write access to ~/Downloads`
|
||||||
|
- integrated with `fs` and `persist` modules so that programs' config files and persisted data stores are linked into the sandbox w/o any extra involvement.
|
||||||
- `modules/users.nix`
|
- `modules/users.nix`
|
||||||
- convenience layer atop the above modules so that you can just write
|
- convenience layer atop the above modules so that you can just write
|
||||||
`fs.".config/git"` instead of `fs."/home/colin/.config/git"`
|
`fs.".config/git"` instead of `fs."/home/colin/.config/git"`
|
||||||
|
42
TODO.md
42
TODO.md
@@ -1,15 +1,14 @@
|
|||||||
## BUGS
|
## BUGS
|
||||||
- nixpkgs date is incorrect (1970.01.01...)
|
|
||||||
- ringer (i.e. dino incoming call) doesn't prevent moby from sleeping
|
- ringer (i.e. dino incoming call) doesn't prevent moby from sleeping
|
||||||
- `nix` operations from lappy hang when `desko` is unreachable
|
- `nix` operations from lappy hang when `desko` is unreachable
|
||||||
- could at least direct the cache to `http://desko-hn:5001`
|
- could at least direct the cache to `http://desko-hn:5001`
|
||||||
|
|
||||||
## REFACTORING:
|
## REFACTORING:
|
||||||
|
- consolidate ~/dev and ~/ref
|
||||||
|
- ~/dev becomes a link to ~/ref/cat/mine
|
||||||
- fold hosts/common/home/ssh.nix -> hosts/common/users/colin.nix
|
- fold hosts/common/home/ssh.nix -> hosts/common/users/colin.nix
|
||||||
|
|
||||||
### sops/secrets
|
### sops/secrets
|
||||||
- attach secrets to the thing they're used by (sane.programs)
|
|
||||||
- rework secrets to leverage `sane.fs`
|
- rework secrets to leverage `sane.fs`
|
||||||
- remove sops activation script as it's covered by my systemd sane.fs impl
|
- remove sops activation script as it's covered by my systemd sane.fs impl
|
||||||
|
|
||||||
@@ -22,7 +21,6 @@
|
|||||||
- bump nodejs version in lemmy-ui
|
- bump nodejs version in lemmy-ui
|
||||||
- add updateScripts to all my packages in nixpkgs
|
- add updateScripts to all my packages in nixpkgs
|
||||||
- fix lightdm-mobile-greeter for newer libhandy
|
- fix lightdm-mobile-greeter for newer libhandy
|
||||||
- port zecwallet-lite to a from-source build
|
|
||||||
- REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617>
|
- REVIEW/integrate jellyfin dataDir config: <https://github.com/NixOS/nixpkgs/pull/233617>
|
||||||
|
|
||||||
#### upstreaming to non-nixpkgs repos
|
#### upstreaming to non-nixpkgs repos
|
||||||
@@ -34,23 +32,27 @@
|
|||||||
- validate duplicity backups!
|
- validate duplicity backups!
|
||||||
- encrypt more ~ dirs (~/archives, ~/records, ..?)
|
- encrypt more ~ dirs (~/archives, ~/records, ..?)
|
||||||
- best to do this after i know for sure i have good backups
|
- best to do this after i know for sure i have good backups
|
||||||
- have `sane.programs` be wrapped such that they run in a cgroup?
|
- /mnt/desko/home, etc, shouldn't include secrets (~/private)
|
||||||
- at least, only give them access to the portion of the fs they *need*.
|
- 95% of its use is for remote media access and stuff which isn't in VCS (~/records)
|
||||||
- Android takes approach of giving each app its own user: could hack that in here.
|
- port all sane.programs to be sandboxed
|
||||||
- **systemd-run** takes a command and runs it in a temporary scope (cgroup)
|
- enforce that all `environment.packages` has a sandbox profile (or explicitly opts out)
|
||||||
- presumably uses the same options as systemd services
|
- revisit "non-sandboxable" apps and check that i'm not actually just missing mountpoints
|
||||||
- see e.g. <https://github.com/NixOS/nixpkgs/issues/113903#issuecomment-857296349>
|
- LL_FS_RW=/ isn't enough -- need all mount points like `=/:/proc:/sys:...`.
|
||||||
- flatpak does this, somehow
|
- ensure non-bin package outputs are linked for sandboxed apps
|
||||||
- apparmor? SElinux? (desktop) "portals"?
|
- i.e. `outputs.man`, `outputs.debug`, `outputs.doc`, ...
|
||||||
- see Spectrum OS; Alyssa Ross; etc
|
- lock down dbus calls within the sandbox
|
||||||
- bubblewrap-based sandboxing: <https://github.com/nixpak/nixpak>
|
- otherwise anyone can `systemd-run --user ...` to potentially escape a sandbox
|
||||||
|
- <https://github.com/flatpak/xdg-dbus-proxy>
|
||||||
|
- remove `.ssh` access from Firefox!
|
||||||
|
- limit access to `~/knowledge/secrets` through an agent that requires GUI approval, so a firefox exploit can't steal all my logins
|
||||||
|
- port sane-sandboxed to a compiled language (hare?)
|
||||||
|
- it adds like 50-70ms launch time _on my laptop_. i'd hate to know how much that is on the pinephone.
|
||||||
|
- make dconf stuff less monolithic
|
||||||
|
- i.e. per-app dconf profiles for those which need it. possible static config.
|
||||||
- canaries for important services
|
- canaries for important services
|
||||||
- e.g. daily email checks; daily backup checks
|
- e.g. daily email checks; daily backup checks
|
||||||
- integrate `nix check` into Gitea actions?
|
- integrate `nix check` into Gitea actions?
|
||||||
|
|
||||||
### faster/better deployments
|
|
||||||
- remove audacity's dependency on webkitgtk (via wxwidgets)
|
|
||||||
|
|
||||||
### user experience
|
### user experience
|
||||||
- install apps:
|
- install apps:
|
||||||
- display QR codes for WiFi endpoints: <https://linuxphoneapps.org/apps/noappid.wisperwind.wifi2qr/>
|
- display QR codes for WiFi endpoints: <https://linuxphoneapps.org/apps/noappid.wisperwind.wifi2qr/>
|
||||||
@@ -70,6 +72,7 @@
|
|||||||
- Shootin Stars (Godot; not in nixpkgs) <https://gitlab.com/greenbeast/shootin-stars>
|
- Shootin Stars (Godot; not in nixpkgs) <https://gitlab.com/greenbeast/shootin-stars>
|
||||||
- numberlink (generic name for Flow Free). not packaged in Nix
|
- numberlink (generic name for Flow Free). not packaged in Nix
|
||||||
- Neverball (https://neverball.org/screenshots.php). nix: as `neverball`
|
- Neverball (https://neverball.org/screenshots.php). nix: as `neverball`
|
||||||
|
- blurble (https://linuxphoneapps.org/games/app.drey.blurble/). nix: not as of 2024-02-05
|
||||||
|
|
||||||
#### moby
|
#### moby
|
||||||
- fix cpuidle (gets better power consumption): <https://xnux.eu/log/077.html>
|
- fix cpuidle (gets better power consumption): <https://xnux.eu/log/077.html>
|
||||||
@@ -89,7 +92,6 @@
|
|||||||
- moby: theme GTK apps (i.e. non-adwaita styles)
|
- moby: theme GTK apps (i.e. non-adwaita styles)
|
||||||
- especially, make the menubar collapsible
|
- especially, make the menubar collapsible
|
||||||
- try Gradience tool specifically for theming adwaita? <https://linuxphoneapps.org/apps/com.github.gradienceteam.gradience/>
|
- try Gradience tool specifically for theming adwaita? <https://linuxphoneapps.org/apps/com.github.gradienceteam.gradience/>
|
||||||
- phog: remove the gnome-shell runtime dependency to save hella closure size
|
|
||||||
|
|
||||||
#### non-moby
|
#### non-moby
|
||||||
- RSS: integrate a paywall bypass
|
- RSS: integrate a paywall bypass
|
||||||
@@ -111,13 +113,13 @@
|
|||||||
- could change junk filter from "no DKIM success" to explicit "DKIM failed"
|
- could change junk filter from "no DKIM success" to explicit "DKIM failed"
|
||||||
|
|
||||||
### perf
|
### perf
|
||||||
|
- debug nixos-rebuild times
|
||||||
|
- i bet sane.programs adds a LOT of time, with how it automatically creates an attrs for EVERY package in nixpkgs.
|
||||||
- add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled
|
- add `pkgs.impure-cached.<foo>` package set to build things with ccache enabled
|
||||||
- every package here can be auto-generated, and marked with some env var so that it doesn't pollute the pure package set
|
- every package here can be auto-generated, and marked with some env var so that it doesn't pollute the pure package set
|
||||||
- would be super handy for package prototyping!
|
- would be super handy for package prototyping!
|
||||||
- fix desko so it doesn't dispatch so many build jobs to servo by default
|
|
||||||
|
|
||||||
## NEW FEATURES:
|
## NEW FEATURES:
|
||||||
- migrate MAME cabinet to nix
|
- migrate MAME cabinet to nix
|
||||||
- boot it from PXE from servo?
|
- boot it from PXE from servo?
|
||||||
- enable IPv6
|
- enable IPv6
|
||||||
- package lemonade lemmy app: <https://linuxphoneapps.org/apps/ml.mdwalters.lemonade/>
|
|
||||||
|
BIN
doc/hello.gif
Normal file
BIN
doc/hello.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 127 KiB |
128
flake.lock
generated
128
flake.lock
generated
@@ -1,5 +1,23 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1698882062,
|
||||||
|
"narHash": "sha256-HkhafUayIqxXyHH1X8d9RDl1M2CkFgZLjKD3MzabiEo=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "8c9fa2545007b49a5db5f650ae91f227672c3877",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"mobile-nixos": {
|
"mobile-nixos": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
@@ -17,13 +35,67 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nix-fast-build": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"treefmt-nix": "treefmt-nix"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1703607026,
|
||||||
|
"narHash": "sha256-Emh0BPoqlS4ntp2UJrwydXfIP4qIMF0VBB2FUE3/M/E=",
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "nix-fast-build",
|
||||||
|
"rev": "4376b8a33b217ee2f78ba3dcff01a3e464d13a46",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "nix-fast-build",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1698890957,
|
||||||
|
"narHash": "sha256-DJ+SppjpPBoJr0Aro9TAcP3sxApCSieY6BYBCoWGUX8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c082856b850ec60cda9f0a0db2bc7bd8900d708c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"dir": "lib",
|
||||||
|
"lastModified": 1698611440,
|
||||||
|
"narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "0cbe9f69c234a7700596e943bfae7ef27a31b735",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"dir": "lib",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs-next-unpatched": {
|
"nixpkgs-next-unpatched": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1705233677,
|
"lastModified": 1708992120,
|
||||||
"narHash": "sha256-eq3VE8QGJsunqqF/BlLslWE1gASp4Hlgp0c78coxat0=",
|
"narHash": "sha256-t/8QV+lEroW5fK44w5oEUalIM0eYYVGs833AHDCIl4s=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "724e39ebb9b8eda97f17d423f66fbc5a991f4f8d",
|
"rev": "6daf4de0662e1d895d220a4a4ddb356eb000abe9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -35,27 +107,27 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-stable": {
|
"nixpkgs-stable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1705033721,
|
"lastModified": 1708819810,
|
||||||
"narHash": "sha256-K5eJHmL1/kev6WuqyqqbS1cdNnSidIZ3jeqJ7GbrYnQ=",
|
"narHash": "sha256-1KosU+ZFXf31GPeCBNxobZWMgHsSOJcrSFA6F2jhzdE=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "a1982c92d8980a0114372973cbdfe0a307f1bdea",
|
"rev": "89a2a12e6c8c6a56c72eb3589982c8e2f89c70ea",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "release-23.05",
|
"ref": "release-23.11",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-unpatched": {
|
"nixpkgs-unpatched": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1705254014,
|
"lastModified": 1708995544,
|
||||||
"narHash": "sha256-4RrVNEqxeji4vqDgzSl7JoCD6a0ag5LF9zXFndtqrpE=",
|
"narHash": "sha256-YJgLopKOKVTggnKzjX4OiAS22hx/vNv397DcsAyTZgY=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "6c08fe3ccf437d8b26bec010fd925ddd6bb0d0d5",
|
"rev": "5bd8df40204f47a12263f3614c72cd5b6832a9a0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -68,6 +140,7 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"mobile-nixos": "mobile-nixos",
|
"mobile-nixos": "mobile-nixos",
|
||||||
|
"nix-fast-build": "nix-fast-build",
|
||||||
"nixpkgs-next-unpatched": "nixpkgs-next-unpatched",
|
"nixpkgs-next-unpatched": "nixpkgs-next-unpatched",
|
||||||
"nixpkgs-unpatched": "nixpkgs-unpatched",
|
"nixpkgs-unpatched": "nixpkgs-unpatched",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
@@ -82,11 +155,11 @@
|
|||||||
"nixpkgs-stable": "nixpkgs-stable"
|
"nixpkgs-stable": "nixpkgs-stable"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1705201153,
|
"lastModified": 1708987867,
|
||||||
"narHash": "sha256-y0/a4IMDZrc7lAkR7Gcm5R3W2iCBiARHnYZe6vkmiNE=",
|
"narHash": "sha256-k2lDaDWNTU5sBVHanYzjDKVDmk29RHIgdbbXu5sdzBA=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "70dd0d521f7849338e487a219c1a07c429a66d77",
|
"rev": "a1c8de14f60924fafe13aea66b46157f0150f4cf",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -95,6 +168,27 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"treefmt-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nix-fast-build",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1698438538,
|
||||||
|
"narHash": "sha256-AWxaKTDL3MtxaVTVU5lYBvSnlspOS0Fjt8GxBgnU0Do=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"rev": "5deb8dc125a9f83b65ca86cf0c8167c46593e0b1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"uninsane-dot-org": {
|
"uninsane-dot-org": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -102,11 +196,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1704082841,
|
"lastModified": 1707981105,
|
||||||
"narHash": "sha256-4g3lePnUALb8B1m3rEDD6rrZAq2pTN4qaSnStbd676U=",
|
"narHash": "sha256-YCU1eNslBHabjP+OCY+BxPycEFO9SRUts10MrN9QORE=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "4a1fa488e64e6c87c6c951e3fafb2684692f64d3",
|
"rev": "bb10cd8853d05191e4d62947d93687c462e92c30",
|
||||||
"revCount": 234,
|
"revCount": 235,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.uninsane.org/colin/uninsane"
|
"url": "https://git.uninsane.org/colin/uninsane"
|
||||||
},
|
},
|
||||||
|
146
flake.nix
146
flake.nix
@@ -57,6 +57,10 @@
|
|||||||
url = "github:nixos/mobile-nixos?ref=d25d3b87e7f300d8066e31d792337d9cd7ecd23b";
|
url = "github:nixos/mobile-nixos?ref=d25d3b87e7f300d8066e31d792337d9cd7ecd23b";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
|
nix-fast-build = {
|
||||||
|
# https://github.com/Mic92/nix-fast-build
|
||||||
|
url = "github:Mic92/nix-fast-build";
|
||||||
|
};
|
||||||
sops-nix = {
|
sops-nix = {
|
||||||
# <https://github.com/Mic92/sops-nix>
|
# <https://github.com/Mic92/sops-nix>
|
||||||
# used to distribute secrets to my hosts
|
# used to distribute secrets to my hosts
|
||||||
@@ -77,6 +81,7 @@
|
|||||||
nixpkgs-unpatched,
|
nixpkgs-unpatched,
|
||||||
nixpkgs-next-unpatched ? nixpkgs-unpatched,
|
nixpkgs-next-unpatched ? nixpkgs-unpatched,
|
||||||
mobile-nixos,
|
mobile-nixos,
|
||||||
|
nix-fast-build,
|
||||||
sops-nix,
|
sops-nix,
|
||||||
uninsane-dot-org,
|
uninsane-dot-org,
|
||||||
...
|
...
|
||||||
@@ -98,19 +103,29 @@
|
|||||||
inherit variant nixpkgs;
|
inherit variant nixpkgs;
|
||||||
self = patchNixpkgs variant nixpkgs;
|
self = patchNixpkgs variant nixpkgs;
|
||||||
} // {
|
} // {
|
||||||
# provide values that nixpkgs ordinarily sources from the flake.lock file,
|
# sourceInfo includes fields (square brackets for the ones which are not always present):
|
||||||
# inaccessible to it here because of the import-from-derivation.
|
# - [dirtyRev]
|
||||||
# rev and shortRev seem to not always exist (e.g. if the working tree is dirty),
|
# - [dirtyShortRev]
|
||||||
# so those are made conditional.
|
# - lastModified
|
||||||
|
# - lastModifiedDate
|
||||||
|
# - narHash
|
||||||
|
# - outPath
|
||||||
|
# - [rev]
|
||||||
|
# - [revCount]
|
||||||
|
# - [shortRev]
|
||||||
|
# - submodules
|
||||||
#
|
#
|
||||||
# these values impact the name of a produced nixos system. having date/rev in the
|
# these values are used within nixpkgs:
|
||||||
# `readlink /run/current-system` store path helps debuggability.
|
# - to give a friendly name to the nixos system (`readlink /run/current-system` -> `...nixos-system-desko-24.05.20240227.dirty`)
|
||||||
inherit (self) lastModifiedDate lastModified;
|
# - to alias `import <nixpkgs>` so that nix uses the system's nixpkgs when called externally (supposedly).
|
||||||
} // optionalAttrs (self ? rev) {
|
#
|
||||||
inherit (self) rev;
|
# these values seem to exist both within the `sourceInfo` attrset and at the top-level.
|
||||||
} // optionalAttrs (self ? shortRev) {
|
# for a list of all implicit flake outputs (which is what these seem to be):
|
||||||
inherit (self) shortRev;
|
# $ nix-repl
|
||||||
};
|
# > lf .
|
||||||
|
# > <tab>
|
||||||
|
inherit (self) sourceInfo;
|
||||||
|
} // self.sourceInfo;
|
||||||
|
|
||||||
nixpkgs' = patchNixpkgs "master" nixpkgs-unpatched;
|
nixpkgs' = patchNixpkgs "master" nixpkgs-unpatched;
|
||||||
nixpkgsCompiledBy = system: nixpkgs'.legacyPackages."${system}";
|
nixpkgsCompiledBy = system: nixpkgs'.legacyPackages."${system}";
|
||||||
@@ -190,17 +205,18 @@
|
|||||||
# hence the weird redundancy.
|
# hence the weird redundancy.
|
||||||
default = final: prev: self.overlays.pkgs final prev;
|
default = final: prev: self.overlays.pkgs final prev;
|
||||||
sane-all = final: prev: import ./overlays/all.nix final prev;
|
sane-all = final: prev: import ./overlays/all.nix final prev;
|
||||||
disable-flakey-tests = final: prev: import ./overlays/disable-flakey-tests.nix final prev;
|
|
||||||
pkgs = final: prev: import ./overlays/pkgs.nix final prev;
|
pkgs = final: prev: import ./overlays/pkgs.nix final prev;
|
||||||
pins = final: prev: import ./overlays/pins.nix final prev;
|
pins = final: prev: import ./overlays/pins.nix final prev;
|
||||||
preferences = final: prev: import ./overlays/preferences.nix final prev;
|
preferences = final: prev: import ./overlays/preferences.nix final prev;
|
||||||
optimizations = final: prev: import ./overlays/optimizations.nix final prev;
|
|
||||||
passthru = final: prev:
|
passthru = final: prev:
|
||||||
let
|
let
|
||||||
mobile = (import "${mobile-nixos}/overlay/overlay.nix");
|
mobile = (import "${mobile-nixos}/overlay/overlay.nix");
|
||||||
uninsane = uninsane-dot-org.overlays.default;
|
uninsane = uninsane-dot-org.overlays.default;
|
||||||
|
# TODO: why do i have to use `self.inputs.nix-fast-build` instead of just `nix-fast-build` here?
|
||||||
|
nix-fast-build = (_: prev: self.inputs.nix-fast-build.packages."${prev.stdenv.system}" or {});
|
||||||
in
|
in
|
||||||
(mobile final prev)
|
(mobile final prev)
|
||||||
|
// (nix-fast-build final prev)
|
||||||
// (uninsane final prev)
|
// (uninsane final prev)
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
@@ -257,18 +273,43 @@
|
|||||||
pkgs = self.legacyPackages."x86_64-linux";
|
pkgs = self.legacyPackages."x86_64-linux";
|
||||||
sanePkgs = import ./pkgs { inherit pkgs; };
|
sanePkgs = import ./pkgs { inherit pkgs; };
|
||||||
deployScript = host: addr: action: pkgs.writeShellScript "deploy-${host}" ''
|
deployScript = host: addr: action: pkgs.writeShellScript "deploy-${host}" ''
|
||||||
nix build '.#nixosConfigurations.${host}.config.system.build.toplevel' --out-link ./result-${host} "$@"
|
host="${host}"
|
||||||
sudo nix sign-paths -r -k /run/secrets/nix_serve_privkey $(readlink ./result-${host})
|
addr="${addr}"
|
||||||
|
action="${if action != null then action else ""}"
|
||||||
|
runOnTarget() {
|
||||||
|
# run the command ($@) on the machine we're deploying to.
|
||||||
|
# if that's a remote machine, then do it via ssh, else local shell.
|
||||||
|
if [ -n "$addr" ]; then
|
||||||
|
ssh "$addr" "$@"
|
||||||
|
else
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# XXX: this triggers another config eval & (potentially) build.
|
nix build ".#nixosConfigurations.$host.config.system.build.toplevel" --out-link "./result-$host" "$@"
|
||||||
# if the config changed between these invocations, the above signatures might not apply to the deployed config.
|
storePath="$(readlink ./result-$host)"
|
||||||
# let the user handle that edge case by re-running this whole command.
|
|
||||||
# N.B.: `--fast` option here is critical to cross-compiled deployments: without it the build machine will try to invoke the host machine's `nix` binary.
|
# mimic `nixos-rebuild --target-host`, in effect:
|
||||||
# TODO: solve this by replacing the nixos-build invocation with:
|
# - nix-copy-closure ...
|
||||||
# - nix-copy-closure --to $host $result
|
# - nix-env --set ...
|
||||||
# - on target: nix-env set -p /nix/var/nix/profiles/system $result
|
# - switch-to-configuration <boot|dry-activate|switch|test|>
|
||||||
# - on target: $result/bin/switch-to-configuration
|
# avoid the actual `nixos-rebuild` for a few reasons:
|
||||||
nixos-rebuild --flake '.#${host}' ${action} --target-host colin@${addr} --use-remote-sudo "$@" --fast
|
# - fewer nix evals
|
||||||
|
# - more introspectability and debuggability
|
||||||
|
# - sandbox friendliness (especially: `git` doesn't have to be run as root)
|
||||||
|
|
||||||
|
if [ -n "$addr" ]; then
|
||||||
|
sudo nix store sign -r -k /run/secrets/nix_serve_privkey "$storePath"
|
||||||
|
# add more `-v` for more verbosity (up to 5).
|
||||||
|
# builders-use-substitutes false: optimizes so that the remote machine doesn't try to get paths from its substituters.
|
||||||
|
# we already have all paths here, and the remote substitution is slow to check and SERIOUSLY flaky on moby in particular.
|
||||||
|
nix copy -vv --option builders-use-substitutes false --to "ssh-ng://$addr" "$storePath"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$action" ]; then
|
||||||
|
runOnTarget sudo nix-env -p /nix/var/nix/profiles/system --set "$storePath"
|
||||||
|
runOnTarget sudo "$storePath/bin/switch-to-configuration" "$action"
|
||||||
|
fi
|
||||||
'';
|
'';
|
||||||
deployApp = host: addr: action: {
|
deployApp = host: addr: action: {
|
||||||
type = "app";
|
type = "app";
|
||||||
@@ -342,7 +383,11 @@
|
|||||||
- `nix run '.#update.feeds'`
|
- `nix run '.#update.feeds'`
|
||||||
- updates metadata for all feeds
|
- updates metadata for all feeds
|
||||||
- `nix run '.#init-feed' <url>`
|
- `nix run '.#init-feed' <url>`
|
||||||
- `nix run '.#deploy.{desko,lappy,moby,servo}[-light][.test]' [nixos-rebuild args ...]`
|
- `nix run '.#deploy.{desko,lappy,moby,servo}[-light|-test]' [nix args ...]`
|
||||||
|
- build and deploy the host
|
||||||
|
- `nix run '.#preDeploy.{desko,lappy,moby,servo}[-light]' [nix args ...]`
|
||||||
|
- copy closures to a host, but don't activate it
|
||||||
|
- or `nix run '.#preDeploy'` to target all hosts
|
||||||
- `nix run '.#check'`
|
- `nix run '.#check'`
|
||||||
- make sure all systems build; NUR evaluates
|
- make sure all systems build; NUR evaluates
|
||||||
|
|
||||||
@@ -371,12 +416,47 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
deploy = {
|
deploy = {
|
||||||
|
desko = deployApp "desko" "desko" "switch";
|
||||||
|
desko-light = deployApp "desko-light" "desko" "switch";
|
||||||
lappy = deployApp "lappy" "lappy" "switch";
|
lappy = deployApp "lappy" "lappy" "switch";
|
||||||
lappy-light = deployApp "lappy-light" "lappy" "switch";
|
lappy-light = deployApp "lappy-light" "lappy" "switch";
|
||||||
moby = deployApp "moby" "moby" "switch";
|
moby = deployApp "moby" "moby" "switch";
|
||||||
moby-light = deployApp "moby-light" "moby" "switch";
|
moby-light = deployApp "moby-light" "moby" "switch";
|
||||||
moby-test = deployApp "moby" "moby" "test";
|
moby-test = deployApp "moby" "moby" "test";
|
||||||
servo = deployApp "servo" "servo" "switch";
|
servo = deployApp "servo" "servo" "switch";
|
||||||
|
|
||||||
|
# like `nixos-rebuild --flake . switch`
|
||||||
|
self = deployApp "$(hostname)" "" "switch";
|
||||||
|
self-light = deployApp "$(hostname)-light" "" "switch";
|
||||||
|
|
||||||
|
type = "app";
|
||||||
|
program = builtins.toString (pkgs.writeShellScript "deploy-all" ''
|
||||||
|
nix run '.#deploy.lappy'
|
||||||
|
nix run '.#deploy.moby'
|
||||||
|
nix run '.#deploy.desko'
|
||||||
|
nix run '.#deploy.servo'
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
preDeploy = {
|
||||||
|
# build the host and copy the runtime closure to that host, but don't activate it.
|
||||||
|
desko = deployApp "desko" "desko" null;
|
||||||
|
desko-light = deployApp "desko-light" "desko" null;
|
||||||
|
lappy = deployApp "lappy" "lappy" null;
|
||||||
|
lappy-light = deployApp "lappy-light" "lappy" null;
|
||||||
|
moby = deployApp "moby" "moby" null;
|
||||||
|
moby-light = deployApp "moby-light" "moby" null;
|
||||||
|
servo = deployApp "servo" "servo" null;
|
||||||
|
type = "app";
|
||||||
|
program = builtins.toString (pkgs.writeShellScript "predeploy-all" ''
|
||||||
|
# copy the -light variants first; this might be run while waiting on a full build. or the full build failed.
|
||||||
|
nix run '.#preDeploy.moby-light' -- "$@"
|
||||||
|
nix run '.#preDeploy.lappy-light' -- "$@"
|
||||||
|
nix run '.#preDeploy.desko-light' -- "$@"
|
||||||
|
nix run '.#preDeploy.lappy' -- "$@"
|
||||||
|
nix run '.#preDeploy.servo' -- "$@"
|
||||||
|
nix run '.#preDeploy.moby' -- "$@"
|
||||||
|
nix run '.#preDeploy.desko' -- "$@"
|
||||||
|
'');
|
||||||
};
|
};
|
||||||
|
|
||||||
sync = {
|
sync = {
|
||||||
@@ -397,8 +477,8 @@
|
|||||||
# can run this from any device that has ssh access to desko and servo
|
# can run this from any device that has ssh access to desko and servo
|
||||||
type = "app";
|
type = "app";
|
||||||
program = builtins.toString (pkgs.writeShellScript "sync-to-desko" ''
|
program = builtins.toString (pkgs.writeShellScript "sync-to-desko" ''
|
||||||
sudo mount /mnt/desko-home
|
sudo mount /mnt/desko/home
|
||||||
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compat /mnt/servo-media/Music /mnt/desko-home/Music "$@"
|
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compat /mnt/servo/media/Music /mnt/desko/home/Music "$@"
|
||||||
'');
|
'');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -407,8 +487,8 @@
|
|||||||
# can run this from any device that has ssh access to lappy and servo
|
# can run this from any device that has ssh access to lappy and servo
|
||||||
type = "app";
|
type = "app";
|
||||||
program = builtins.toString (pkgs.writeShellScript "sync-to-lappy" ''
|
program = builtins.toString (pkgs.writeShellScript "sync-to-lappy" ''
|
||||||
sudo mount /mnt/lappy-home
|
sudo mount /mnt/lappy/home
|
||||||
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compress --compat /mnt/servo-media/Music /mnt/lappy-home/Music "$@"
|
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compress --compat /mnt/servo/media/Music /mnt/lappy/home/Music "$@"
|
||||||
'');
|
'');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -417,9 +497,11 @@
|
|||||||
# can run this from any device that has ssh access to moby and servo
|
# can run this from any device that has ssh access to moby and servo
|
||||||
type = "app";
|
type = "app";
|
||||||
program = builtins.toString (pkgs.writeShellScript "sync-to-moby" ''
|
program = builtins.toString (pkgs.writeShellScript "sync-to-moby" ''
|
||||||
sudo mount /mnt/moby-home
|
sudo mount /mnt/moby/home
|
||||||
|
sudo mount /mnt/desko/home
|
||||||
|
${pkgs.rsync}/bin/rsync -arv --exclude servo-macros /mnt/moby/home/Pictures/ /mnt/desko/home/Pictures/moby/
|
||||||
# N.B.: limited by network/disk -> reduce job count to improve pause/resume behavior
|
# N.B.: limited by network/disk -> reduce job count to improve pause/resume behavior
|
||||||
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compress --compat --jobs 4 /mnt/servo-media/Music /mnt/moby-home/Music "$@"
|
${pkgs.sane-scripts.sync-music}/bin/sane-sync-music --compress --compat --jobs 4 /mnt/servo/media/Music /mnt/moby/home/Music "$@"
|
||||||
'');
|
'');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -28,14 +28,14 @@
|
|||||||
sane.nixcache.substituters.desko = false;
|
sane.nixcache.substituters.desko = false;
|
||||||
sane.nixcache.remote-builders.desko = false;
|
sane.nixcache.remote-builders.desko = false;
|
||||||
|
|
||||||
sane.gui.sway.enable = true;
|
sane.programs.sway.enableFor.user.colin = true;
|
||||||
sane.programs.iphoneUtils.enableFor.user.colin = true;
|
sane.programs.iphoneUtils.enableFor.user.colin = true;
|
||||||
sane.programs.steam.enableFor.user.colin = true;
|
sane.programs.steam.enableFor.user.colin = true;
|
||||||
|
|
||||||
# sane.programs.devPkgs.enableFor.user.colin = true;
|
# sane.programs.devPkgs.enableFor.user.colin = true;
|
||||||
|
|
||||||
sane.programs.signal-desktop.config.autostart = true;
|
|
||||||
sane.programs."gnome.geary".config.autostart = true;
|
sane.programs."gnome.geary".config.autostart = true;
|
||||||
|
sane.programs.signal-desktop.config.autostart = true;
|
||||||
|
|
||||||
boot.loader.efi.canTouchEfiVariables = false;
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
fileSystems."/tmp".options = [ "size=64G" ];
|
fileSystems."/tmp".options = [ "size=64G" ];
|
||||||
|
|
||||||
fileSystems."/nix" = {
|
fileSystems."/nix" = {
|
||||||
# device = "/dev/disk/by-uuid/0ab0770b-7734-4167-88d9-6e4e20bb2a56";
|
|
||||||
device = "/dev/disk/by-uuid/845d85bf-761d-431b-a406-e6f20909154f";
|
device = "/dev/disk/by-uuid/845d85bf-761d-431b-a406-e6f20909154f";
|
||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
options = [
|
options = [
|
||||||
@@ -16,7 +15,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" = {
|
||||||
# device = "/dev/disk/by-uuid/41B6-BAEF";
|
|
||||||
device = "/dev/disk/by-uuid/5049-9AFD";
|
device = "/dev/disk/by-uuid/5049-9AFD";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
@@ -12,10 +12,12 @@
|
|||||||
sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip;
|
sane.services.wg-home.ip = config.sane.hosts.by-name."lappy".wg-home.ip;
|
||||||
|
|
||||||
# sane.guest.enable = true;
|
# sane.guest.enable = true;
|
||||||
sane.gui.sway.enable = true;
|
|
||||||
boot.loader.efi.canTouchEfiVariables = false;
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||||
|
|
||||||
|
sane.programs.sway.enableFor.user.colin = true;
|
||||||
|
sane.programs."gnome.geary".config.autostart = true;
|
||||||
|
sane.programs.signal-desktop.config.autostart = true;
|
||||||
sane.programs.stepmania.enableFor.user.colin = true;
|
sane.programs.stepmania.enableFor.user.colin = true;
|
||||||
|
|
||||||
sops.secrets.colin-passwd.neededForUsers = true;
|
sops.secrets.colin-passwd.neededForUsers = true;
|
||||||
|
@@ -14,24 +14,4 @@
|
|||||||
device = "/dev/disk/by-uuid/BD79-D6BB";
|
device = "/dev/disk/by-uuid/BD79-D6BB";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
|
|
||||||
# fileSystems."/nix" = {
|
|
||||||
# device = "/dev/disk/by-uuid/5a7fa69c-9394-8144-a74c-6726048b129f";
|
|
||||||
# fsType = "btrfs";
|
|
||||||
# };
|
|
||||||
|
|
||||||
# fileSystems."/boot" = {
|
|
||||||
# device = "/dev/disk/by-uuid/4302-1685";
|
|
||||||
# fsType = "vfat";
|
|
||||||
# };
|
|
||||||
|
|
||||||
# fileSystems."/" = {
|
|
||||||
# device = "none";
|
|
||||||
# fsType = "tmpfs";
|
|
||||||
# options = [
|
|
||||||
# "mode=755"
|
|
||||||
# "size=1G"
|
|
||||||
# "defaults"
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.gui.sxmo = {
|
sane.gui.sxmo = {
|
||||||
greeter = "greetd-sway-gtkgreet";
|
|
||||||
noidle = true; #< power button requires 1s hold, which makes it impractical to be dealing with.
|
noidle = true; #< power button requires 1s hold, which makes it impractical to be dealing with.
|
||||||
settings = {
|
settings = {
|
||||||
# XXX: make sure the user is part of the `input` group!
|
# XXX: make sure the user is part of the `input` group!
|
||||||
|
@@ -25,10 +25,14 @@
|
|||||||
sane.services.wg-home.enable = true;
|
sane.services.wg-home.enable = true;
|
||||||
sane.services.wg-home.ip = config.sane.hosts.by-name."moby".wg-home.ip;
|
sane.services.wg-home.ip = config.sane.hosts.by-name."moby".wg-home.ip;
|
||||||
|
|
||||||
|
# for some reason desko -> moby deploys are super flaky when desko is also a nixcache (not true of desko -> lappy deploys, though!)
|
||||||
|
# > unable to download 'http://desko:5001/<hash>.narinfo': Server returned nothing (no headers, no data) (52)
|
||||||
|
sane.nixcache.substituters.desko = false;
|
||||||
|
|
||||||
# XXX colin: phosh doesn't work well with passwordless login,
|
# XXX colin: phosh doesn't work well with passwordless login,
|
||||||
# so set this more reliable default password should anything go wrong
|
# so set this more reliable default password should anything go wrong
|
||||||
users.users.colin.initialPassword = "147147";
|
users.users.colin.initialPassword = "147147";
|
||||||
services.getty.autologinUser = "root"; # allows for emergency maintenance?
|
# services.getty.autologinUser = "root"; # allows for emergency maintenance?
|
||||||
|
|
||||||
sops.secrets.colin-passwd.neededForUsers = true;
|
sops.secrets.colin-passwd.neededForUsers = true;
|
||||||
|
|
||||||
@@ -45,7 +49,7 @@
|
|||||||
|
|
||||||
# sane.programs.ntfy-sh.config.autostart = true;
|
# sane.programs.ntfy-sh.config.autostart = true;
|
||||||
sane.programs.dino.config.autostart = true;
|
sane.programs.dino.config.autostart = true;
|
||||||
sane.programs.signal-desktop.config.autostart = true;
|
# sane.programs.signal-desktop.config.autostart = true; # TODO: enable once electron stops derping.
|
||||||
# sane.programs."gnome.geary".config.autostart = true;
|
# sane.programs."gnome.geary".config.autostart = true;
|
||||||
# sane.programs.calls.config.autostart = true;
|
# sane.programs.calls.config.autostart = true;
|
||||||
sane.programs.mpv.config.vo = "wlshm"; #< see hosts/common/programs/mpv.nix for details
|
sane.programs.mpv.config.vo = "wlshm"; #< see hosts/common/programs/mpv.nix for details
|
||||||
|
@@ -50,6 +50,7 @@
|
|||||||
sane.persist.stores."ext" = {
|
sane.persist.stores."ext" = {
|
||||||
origin = "/mnt/pool/persist";
|
origin = "/mnt/pool/persist";
|
||||||
storeDescription = "external HDD storage";
|
storeDescription = "external HDD storage";
|
||||||
|
defaultMethod = "bind"; #< TODO: change to "symlink"?
|
||||||
};
|
};
|
||||||
|
|
||||||
# increase /tmp space (defaults to 50% of RAM) for building large nix things.
|
# increase /tmp space (defaults to 50% of RAM) for building large nix things.
|
||||||
@@ -83,13 +84,14 @@
|
|||||||
|
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: this is overly broad; only need media and share directories to be persisted
|
# TODO: this is overly broad; only need media and share directories to be persisted
|
||||||
{ user = "colin"; group = "users"; path = "/var/lib/uninsane"; }
|
{ user = "colin"; group = "users"; path = "/var/lib/uninsane"; method = "bind"; }
|
||||||
];
|
];
|
||||||
# force some problematic directories to always get correct permissions:
|
# force some problematic directories to always get correct permissions:
|
||||||
sane.fs."/var/lib/uninsane/media".dir.acl = {
|
sane.fs."/var/lib/uninsane/media".dir.acl = {
|
||||||
user = "colin"; group = "media"; mode = "0775";
|
user = "colin"; group = "media"; mode = "0775";
|
||||||
};
|
};
|
||||||
sane.fs."/var/lib/uninsane/media/archive".dir = {};
|
sane.fs."/var/lib/uninsane/media/archive".dir = {};
|
||||||
|
# this is file.text instead of symlink.text so that it may be read over a remote mount (where consumers might not have any /nix/store/.../README.md path)
|
||||||
sane.fs."/var/lib/uninsane/media/archive/README.md".file.text = ''
|
sane.fs."/var/lib/uninsane/media/archive/README.md".file.text = ''
|
||||||
this directory is for media i wish to remove from my library,
|
this directory is for media i wish to remove from my library,
|
||||||
but keep for a short time in case i reverse my decision.
|
but keep for a short time in case i reverse my decision.
|
||||||
@@ -108,6 +110,7 @@
|
|||||||
sane.fs."/var/lib/uninsane/media/Videos/Film".dir = {};
|
sane.fs."/var/lib/uninsane/media/Videos/Film".dir = {};
|
||||||
sane.fs."/var/lib/uninsane/media/Videos/Shows".dir = {};
|
sane.fs."/var/lib/uninsane/media/Videos/Shows".dir = {};
|
||||||
sane.fs."/var/lib/uninsane/media/Videos/Talks".dir = {};
|
sane.fs."/var/lib/uninsane/media/Videos/Talks".dir = {};
|
||||||
|
# this is file.text instead of symlink.text so that it may be read over a remote mount (where consumers might not have any /nix/store/.../README.md path)
|
||||||
sane.fs."/var/lib/uninsane/datasets/README.md".file.text = ''
|
sane.fs."/var/lib/uninsane/datasets/README.md".file.text = ''
|
||||||
this directory may seem redundant with ../media/datasets. it isn't.
|
this directory may seem redundant with ../media/datasets. it isn't.
|
||||||
this directory exists on SSD, allowing for speedy access to specific datasets when necessary.
|
this directory exists on SSD, allowing for speedy access to specific datasets when necessary.
|
||||||
|
@@ -24,18 +24,6 @@ in
|
|||||||
sane.ports.openFirewall = true;
|
sane.ports.openFirewall = true;
|
||||||
sane.ports.openUpnp = true;
|
sane.ports.openUpnp = true;
|
||||||
|
|
||||||
# view refused packets with: `sudo journalctl -k`
|
|
||||||
# networking.firewall.logRefusedPackets = true;
|
|
||||||
|
|
||||||
# these useDHCP lines are legacy from the auto-generated config. might be safe to remove now?
|
|
||||||
networking.useDHCP = false;
|
|
||||||
networking.interfaces.eth0.useDHCP = true;
|
|
||||||
# XXX colin: probably don't need this. wlan0 won't be populated unless i touch a value in networking.interfaces.wlan0
|
|
||||||
networking.wireless.enable = false;
|
|
||||||
|
|
||||||
# this is needed to forward packets from the VPN to the host
|
|
||||||
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
|
|
||||||
|
|
||||||
# unless we add interface-specific settings for each VPN, we have to define nameservers globally.
|
# unless we add interface-specific settings for each VPN, we have to define nameservers globally.
|
||||||
# networking.nameservers = [
|
# networking.nameservers = [
|
||||||
# "1.1.1.1"
|
# "1.1.1.1"
|
||||||
|
@@ -13,7 +13,7 @@ in
|
|||||||
lib.mkIf false
|
lib.mkIf false
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ inherit user group; mode = "0700"; path = svc-dir; }
|
{ inherit user group; mode = "0700"; path = svc-dir; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
services.calibre-web.enable = true;
|
services.calibre-web.enable = true;
|
||||||
|
@@ -30,8 +30,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.ext = [
|
sane.persist.sys.byStore.ext = [
|
||||||
# /var/lib/monero/lmdb is what consumes most of the space
|
{ user = "bitcoind-mainnet"; group = "bitcoind-mainnet"; path = "/var/lib/bitcoind-mainnet"; method = "bind"; }
|
||||||
{ user = "bitcoind-mainnet"; group = "bitcoind-mainnet"; path = "/var/lib/bitcoind-mainnet"; }
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# sane.ports.ports."8333" = {
|
# sane.ports.ports."8333" = {
|
||||||
|
@@ -73,7 +73,7 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.ext = [
|
sane.persist.sys.byStore.ext = [
|
||||||
{ user = "clightning"; group = "clightning"; mode = "0710"; path = "/var/lib/clightning"; }
|
{ user = "clightning"; group = "clightning"; mode = "0710"; path = "/var/lib/clightning"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
# `lightning-cli` finds its RPC file via `~/.lightning/bitcoin/lightning-rpc`, to message the daemon
|
# `lightning-cli` finds its RPC file via `~/.lightning/bitcoin/lightning-rpc`, to message the daemon
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
{
|
{
|
||||||
sane.persist.sys.byStore.ext = [
|
sane.persist.sys.byStore.ext = [
|
||||||
# /var/lib/monero/lmdb is what consumes most of the space
|
# /var/lib/monero/lmdb is what consumes most of the space
|
||||||
{ user = "monero"; group = "monero"; path = "/var/lib/monero"; }
|
{ user = "monero"; group = "monero"; path = "/var/lib/monero"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
services.monero.enable = true;
|
services.monero.enable = true;
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
# tor hidden service hostnames aren't deterministic, so persist.
|
# tor hidden service hostnames aren't deterministic, so persist.
|
||||||
# might be able to get away with just persisting /var/lib/tor/onion, not sure.
|
# might be able to get away with just persisting /var/lib/tor/onion, not sure.
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "tor"; group = "tor"; mode = "0710"; path = "/var/lib/tor"; }
|
{ user = "tor"; group = "tor"; mode = "0710"; path = "/var/lib/tor"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
# tor: `tor.enable` doesn't start a relay, exit node, proxy, etc. it's minimal.
|
# tor: `tor.enable` doesn't start a relay, exit node, proxy, etc. it's minimal.
|
||||||
|
@@ -45,7 +45,7 @@ in
|
|||||||
lib.mkIf false
|
lib.mkIf false
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "ejabberd"; group = "ejabberd"; path = "/var/lib/ejabberd"; }
|
{ user = "ejabberd"; group = "ejabberd"; path = "/var/lib/ejabberd"; method = "bind"; }
|
||||||
];
|
];
|
||||||
sane.ports.ports = lib.mkMerge ([
|
sane.ports.ports = lib.mkMerge ([
|
||||||
{
|
{
|
||||||
|
@@ -127,10 +127,11 @@
|
|||||||
services.dovecot2.modules = [
|
services.dovecot2.modules = [
|
||||||
pkgs.dovecot_pigeonhole # enables sieve execution (?)
|
pkgs.dovecot_pigeonhole # enables sieve execution (?)
|
||||||
];
|
];
|
||||||
services.dovecot2.sieveScripts = {
|
services.dovecot2.sieve = {
|
||||||
|
extensions = [ "fileinto" ];
|
||||||
# if any messages fail to pass (or lack) DKIM, move them to Junk
|
# if any messages fail to pass (or lack) DKIM, move them to Junk
|
||||||
# XXX the key name ("after") is only used to order sieve execution/ordering
|
# XXX the key name ("after") is only used to order sieve execution/ordering
|
||||||
after = builtins.toFile "ensuredkim.sieve" ''
|
scripts.after = builtins.toFile "ensuredkim.sieve" ''
|
||||||
require "fileinto";
|
require "fileinto";
|
||||||
|
|
||||||
if not header :contains "Authentication-Results" "dkim=pass" {
|
if not header :contains "Authentication-Results" "dkim=pass" {
|
||||||
@@ -139,4 +140,6 @@
|
|||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.services.dovecot2.serviceConfig.RestartSec = lib.mkForce "15s"; # nixos defaults this to 1s
|
||||||
}
|
}
|
||||||
|
@@ -20,9 +20,9 @@ in
|
|||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: mode? could be more granular
|
# TODO: mode? could be more granular
|
||||||
{ user = "opendkim"; group = "opendkim"; path = "/var/lib/opendkim"; }
|
{ user = "opendkim"; group = "opendkim"; path = "/var/lib/opendkim"; method = "bind"; }
|
||||||
{ user = "root"; group = "root"; path = "/var/lib/postfix"; }
|
{ user = "root"; group = "root"; path = "/var/lib/postfix"; method = "bind"; }
|
||||||
{ user = "root"; group = "root"; path = "/var/spool/mail"; }
|
{ user = "root"; group = "root"; path = "/var/spool/mail"; method = "bind"; }
|
||||||
# *probably* don't need these dirs:
|
# *probably* don't need these dirs:
|
||||||
# "/var/lib/dhparams" # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/dhparams.nix
|
# "/var/lib/dhparams" # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/dhparams.nix
|
||||||
# "/var/lib/dovecot"
|
# "/var/lib/dovecot"
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
# to query the quota/status:
|
# to query the quota/status:
|
||||||
# - `sudo btrfs qgroup show -re /var/export/playground`
|
# - `sudo btrfs qgroup show -re /var/export/playground`
|
||||||
sane.persist.sys.byStore.ext = [
|
sane.persist.sys.byStore.ext = [
|
||||||
{ user = "root"; group = "export"; mode = "0775"; path = "/var/export/playground"; }
|
{ user = "root"; group = "export"; mode = "0775"; path = "/var/export/playground"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
sane.fs."/var/export/README.md" = {
|
sane.fs."/var/export/README.md" = {
|
||||||
|
@@ -91,7 +91,7 @@ let
|
|||||||
authFailJson = pkgs.writeText "sftp-auth-fail.json" (builtins.toJSON authResponseFail);
|
authFailJson = pkgs.writeText "sftp-auth-fail.json" (builtins.toJSON authResponseFail);
|
||||||
unwrappedAuthProgram = pkgs.static-nix-shell.mkBash {
|
unwrappedAuthProgram = pkgs.static-nix-shell.mkBash {
|
||||||
pname = "sftpgo_external_auth_hook";
|
pname = "sftpgo_external_auth_hook";
|
||||||
src = ./.;
|
srcRoot = ./.;
|
||||||
pkgs = [ "coreutils" ];
|
pkgs = [ "coreutils" ];
|
||||||
};
|
};
|
||||||
authProgram = pkgs.writeShellScript "sftpgo-auth-hook" ''
|
authProgram = pkgs.writeShellScript "sftpgo-auth-hook" ''
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
mode = "0400";
|
mode = "0400";
|
||||||
};
|
};
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "freshrss"; group = "freshrss"; path = "/var/lib/freshrss"; }
|
{ user = "freshrss"; group = "freshrss"; path = "/var/lib/freshrss"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
services.freshrss.enable = true;
|
services.freshrss.enable = true;
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: mode? could be more granular
|
# TODO: mode? could be more granular
|
||||||
{ user = "git"; group = "gitea"; path = "/var/lib/gitea"; }
|
{ user = "git"; group = "gitea"; path = "/var/lib/gitea"; method = "bind"; }
|
||||||
];
|
];
|
||||||
services.gitea.enable = true;
|
services.gitea.enable = true;
|
||||||
services.gitea.user = "git"; # default is 'gitea'
|
services.gitea.user = "git"; # default is 'gitea'
|
||||||
@@ -100,6 +100,24 @@
|
|||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://127.0.0.1:3000";
|
proxyPass = "http://127.0.0.1:3000";
|
||||||
};
|
};
|
||||||
|
# gitea serves all `raw` files as content-type: plain, but i'd like to serve them as their actual content type.
|
||||||
|
# or at least, enough to make specific pages viewable (serving unoriginal content as arbitrary content type is dangerous).
|
||||||
|
locations."~ ^/colin/phone-case-cq/raw/.*.html" = {
|
||||||
|
proxyPass = "http://127.0.0.1:3000";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_hide_header Content-Type;
|
||||||
|
default_type text/html;
|
||||||
|
add_header Content-Type text/html;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
locations."~ ^/colin/phone-case-cq/raw/.*.js" = {
|
||||||
|
proxyPass = "http://127.0.0.1:3000";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_hide_header Content-Type;
|
||||||
|
default_type text/html;
|
||||||
|
add_header Content-Type text/javascript;
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sane.dns.zones."uninsane.org".inet.CNAME."git" = "native";
|
sane.dns.zones."uninsane.org".inet.CNAME."git" = "native";
|
||||||
|
@@ -12,7 +12,7 @@ lib.mkIf false # i don't actively use ipfs anymore
|
|||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: mode? could be more granular
|
# TODO: mode? could be more granular
|
||||||
{ user = "261"; group = "261"; path = "/var/lib/ipfs"; }
|
{ user = "261"; group = "261"; path = "/var/lib/ipfs"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 4001 ];
|
networking.firewall.allowedTCPPorts = [ 4001 ];
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: mode? we only need this to save Indexer creds ==> migrate to config?
|
# TODO: mode? we only need this to save Indexer creds ==> migrate to config?
|
||||||
{ user = "root"; group = "root"; path = "/var/lib/jackett"; }
|
{ user = "root"; group = "root"; path = "/var/lib/jackett"; method = "bind"; }
|
||||||
];
|
];
|
||||||
services.jackett.enable = true;
|
services.jackett.enable = true;
|
||||||
|
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "jellyfin"; group = "jellyfin"; mode = "0700"; path = "/var/lib/jellyfin"; }
|
{ user = "jellyfin"; group = "jellyfin"; mode = "0700"; path = "/var/lib/jellyfin"; method = "bind"; }
|
||||||
];
|
];
|
||||||
sane.fs."/var/lib/jellyfin/config/logging.json" = {
|
sane.fs."/var/lib/jellyfin/config/logging.json" = {
|
||||||
# "Emby.Dlna" logging: <https://jellyfin.org/docs/general/networking/dlna>
|
# "Emby.Dlna" logging: <https://jellyfin.org/docs/general/networking/dlna>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.ext = [
|
sane.persist.sys.byStore.ext = [
|
||||||
{ user = "colin"; group = "users"; path = "/var/lib/kiwix"; }
|
{ user = "colin"; group = "users"; path = "/var/lib/kiwix"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
sane.services.kiwix-serve = {
|
sane.services.kiwix-serve = {
|
||||||
|
@@ -5,7 +5,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ inherit user group; mode = "0700"; path = stateDir; }
|
{ inherit user group; mode = "0700"; path = stateDir; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
services.komga.enable = true;
|
services.komga.enable = true;
|
||||||
|
@@ -78,8 +78,8 @@ in {
|
|||||||
# CLI args: <https://git.asonix.dog/asonix/pict-rs#user-content-running>
|
# CLI args: <https://git.asonix.dog/asonix/pict-rs#user-content-running>
|
||||||
systemd.services.pict-rs.serviceConfig.ExecStart = lib.mkForce (lib.concatStringsSep " " [
|
systemd.services.pict-rs.serviceConfig.ExecStart = lib.mkForce (lib.concatStringsSep " " [
|
||||||
"${lib.getBin pict-rs}/bin/pict-rs run"
|
"${lib.getBin pict-rs}/bin/pict-rs run"
|
||||||
"--media-max-frame-count" (builtins.toString (30*60*60))
|
"--media-video-max-frame-count" (builtins.toString (30*60*60))
|
||||||
"--media-process-timeout 120"
|
"--media-process-timeout 120"
|
||||||
"--media-enable-full-video true" # allow audio
|
"--media-video-allow-audio" # allow audio
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "matrix-synapse"; group = "matrix-synapse"; path = "/var/lib/matrix-synapse"; }
|
{ user = "matrix-synapse"; group = "matrix-synapse"; path = "/var/lib/matrix-synapse"; method = "bind"; }
|
||||||
];
|
];
|
||||||
services.matrix-synapse.enable = true;
|
services.matrix-synapse.enable = true;
|
||||||
services.matrix-synapse.settings = {
|
services.matrix-synapse.settings = {
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
lib.mkIf false
|
lib.mkIf false
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "matrix-synapse"; group = "matrix-synapse"; path = "/var/lib/mx-puppet-discord"; }
|
{ user = "matrix-synapse"; group = "matrix-synapse"; path = "/var/lib/mx-puppet-discord"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
services.matrix-synapse.settings.app_service_config_files = [
|
services.matrix-synapse.settings.app_service_config_files = [
|
||||||
|
@@ -103,7 +103,7 @@ in
|
|||||||
|
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: mode?
|
# TODO: mode?
|
||||||
{ user = "matrix-appservice-irc"; group = "matrix-appservice-irc"; path = "/var/lib/matrix-appservice-irc"; }
|
{ user = "matrix-appservice-irc"; group = "matrix-appservice-irc"; path = "/var/lib/matrix-appservice-irc"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
# XXX: matrix-appservice-irc PreStart tries to chgrp the registration.yml to matrix-synapse,
|
# XXX: matrix-appservice-irc PreStart tries to chgrp the registration.yml to matrix-synapse,
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
lib.mkIf false # disabled 2024/01/11: i don't use it, and pkgs.mautrix-signal had some API changes
|
lib.mkIf false # disabled 2024/01/11: i don't use it, and pkgs.mautrix-signal had some API changes
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "mautrix-signal"; group = "mautrix-signal"; path = "/var/lib/mautrix-signal"; }
|
{ user = "mautrix-signal"; group = "mautrix-signal"; path = "/var/lib/mautrix-signal"; method = "bind"; }
|
||||||
{ user = "signald"; group = "signald"; path = "/var/lib/signald"; }
|
{ user = "signald"; group = "signald"; path = "/var/lib/signald"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
# allow synapse to read the registration file
|
# allow synapse to read the registration file
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "navidrome"; group = "navidrome"; path = "/var/lib/navidrome"; }
|
{ user = "navidrome"; group = "navidrome"; path = "/var/lib/navidrome"; method = "bind"; }
|
||||||
];
|
];
|
||||||
services.navidrome.enable = true;
|
services.navidrome.enable = true;
|
||||||
services.navidrome.settings = {
|
services.navidrome.settings = {
|
||||||
|
@@ -169,8 +169,8 @@ in
|
|||||||
security.acme.defaults.email = "admin.acme@uninsane.org";
|
security.acme.defaults.email = "admin.acme@uninsane.org";
|
||||||
|
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "acme"; group = "acme"; path = "/var/lib/acme"; }
|
{ user = "acme"; group = "acme"; path = "/var/lib/acme"; method = "bind"; }
|
||||||
{ user = "colin"; group = "users"; path = "/var/www/sites"; }
|
{ user = "colin"; group = "users"; path = "/var/www/sites"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
# let's encrypt default chain looks like:
|
# let's encrypt default chain looks like:
|
||||||
|
@@ -34,7 +34,7 @@ in
|
|||||||
# not 100% necessary to persist this, but ntfy does keep a 12hr (by default) cache
|
# not 100% necessary to persist this, but ntfy does keep a 12hr (by default) cache
|
||||||
# for pushing notifications to users who become offline.
|
# for pushing notifications to users who become offline.
|
||||||
# ACLs also live here.
|
# ACLs also live here.
|
||||||
{ user = "ntfy-sh"; group ="ntfy-sh"; path = "/var/lib/ntfy-sh"; }
|
{ user = "ntfy-sh"; group ="ntfy-sh"; path = "/var/lib/ntfy-sh"; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
services.ntfy-sh.enable = true;
|
services.ntfy-sh.enable = true;
|
||||||
|
@@ -49,7 +49,7 @@ in
|
|||||||
type = types.package;
|
type = types.package;
|
||||||
default = pkgs.static-nix-shell.mkPython3Bin {
|
default = pkgs.static-nix-shell.mkPython3Bin {
|
||||||
pname = "ntfy-waiter";
|
pname = "ntfy-waiter";
|
||||||
src = ./.;
|
srcRoot = ./.;
|
||||||
pkgs = [ "ntfy-sh" ];
|
pkgs = [ "ntfy-sh" ];
|
||||||
};
|
};
|
||||||
description = ''
|
description = ''
|
||||||
|
@@ -6,7 +6,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = lib.mkIf cfg.enable [
|
sane.persist.sys.byStore.plaintext = lib.mkIf cfg.enable [
|
||||||
{ user = "pict-rs"; group = "pict-rs"; path = cfg.dataDir; }
|
{ user = "pict-rs"; group = "pict-rs"; path = cfg.dataDir; method = "bind"; }
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.services.pict-rs.serviceConfig = {
|
systemd.services.pict-rs.serviceConfig = {
|
||||||
|
@@ -15,7 +15,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "pleroma"; group = "pleroma"; path = "/var/lib/pleroma"; }
|
{ user = "pleroma"; group = "pleroma"; path = "/var/lib/pleroma"; method = "bind"; }
|
||||||
];
|
];
|
||||||
services.pleroma.enable = true;
|
services.pleroma.enable = true;
|
||||||
services.pleroma.secretConfigFile = config.sops.secrets.pleroma_secrets.path;
|
services.pleroma.secretConfigFile = config.sops.secrets.pleroma_secrets.path;
|
||||||
|
@@ -8,7 +8,7 @@ in
|
|||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: mode?
|
# TODO: mode?
|
||||||
{ user = "postgres"; group = "postgres"; path = "/var/lib/postgresql"; }
|
{ user = "postgres"; group = "postgres"; path = "/var/lib/postgresql"; method = "bind"; }
|
||||||
];
|
];
|
||||||
services.postgresql.enable = true;
|
services.postgresql.enable = true;
|
||||||
|
|
||||||
|
@@ -57,7 +57,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "prosody"; group = "prosody"; path = "/var/lib/prosody"; }
|
{ user = "prosody"; group = "prosody"; path = "/var/lib/prosody"; method = "bind"; }
|
||||||
];
|
];
|
||||||
sane.ports.ports."5000" = {
|
sane.ports.ports."5000" = {
|
||||||
protocol = [ "tcp" ];
|
protocol = [ "tcp" ];
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
{ user = "slskd"; group = "slskd"; path = "/var/lib/slskd"; }
|
{ user = "slskd"; group = "slskd"; path = "/var/lib/slskd"; method = "bind"; }
|
||||||
];
|
];
|
||||||
sops.secrets."slskd_env" = {
|
sops.secrets."slskd_env" = {
|
||||||
owner = config.users.users.slskd.name;
|
owner = config.users.users.slskd.name;
|
||||||
|
@@ -1,14 +1,37 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# 2023/09/06: nixpkgs `transmission` defaults to old 3.00
|
||||||
|
# 2024/02/15: some torrent trackers whitelist clients; everyone is still on 3.00 for some reason :|
|
||||||
|
# some do this via peer-id (e.g. baka); others via user-agent (e.g. MAM).
|
||||||
|
# peer-id format is essentially the same between 3.00 and 4.x (just swap the MAJOR/MINOR/PATCH numbers).
|
||||||
|
# user-agent format has changed. `Transmission/3.00` (old) v.s. `TRANSMISSION/MAJ.MIN.PATCH` (new).
|
||||||
|
realTransmission = pkgs.transmission_4;
|
||||||
|
realVersion = {
|
||||||
|
major = lib.versions.major realTransmission.version;
|
||||||
|
minor = lib.versions.minor realTransmission.version;
|
||||||
|
patch = lib.versions.patch realTransmission.version;
|
||||||
|
};
|
||||||
|
package = realTransmission.overrideAttrs (upstream: {
|
||||||
|
# `cmakeFlags = [ "-DTR_VERSION_MAJOR=3" ]`, etc, doesn't seem to take effect.
|
||||||
|
postPatch = (upstream.postPatch or "") + ''
|
||||||
|
substituteInPlace CMakeLists.txt \
|
||||||
|
--replace-fail 'TR_VERSION_MAJOR "${realVersion.major}"' 'TR_VERSION_MAJOR "3"' \
|
||||||
|
--replace-fail 'TR_VERSION_MINOR "${realVersion.minor}"' 'TR_VERSION_MINOR "0"' \
|
||||||
|
--replace-fail 'TR_VERSION_PATCH "${realVersion.patch}"' 'TR_VERSION_PATCH "0"' \
|
||||||
|
--replace-fail 'set(TR_USER_AGENT_PREFIX "''${TR_SEMVER}")' 'set(TR_USER_AGENT_PREFIX "3.00")'
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
in
|
||||||
{
|
{
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: mode? we need this specifically for the stats tracking in .config/
|
# TODO: mode? we need this specifically for the stats tracking in .config/
|
||||||
{ user = "transmission"; group = config.users.users.transmission.group; path = "/var/lib/transmission"; }
|
{ user = "transmission"; group = config.users.users.transmission.group; path = "/var/lib/transmission"; method = "bind"; }
|
||||||
];
|
];
|
||||||
users.users.transmission.extraGroups = [ "media" ];
|
users.users.transmission.extraGroups = [ "media" ];
|
||||||
|
|
||||||
services.transmission.enable = true;
|
services.transmission.enable = true;
|
||||||
services.transmission.package = pkgs.transmission_4; #< 2023/09/06: nixpkgs `transmission` defaults to old 3.00
|
services.transmission.package = package;
|
||||||
#v setting `group` this way doesn't tell transmission to `chown` the files it creates
|
#v setting `group` this way doesn't tell transmission to `chown` the files it creates
|
||||||
# it's a nixpkgs setting which just runs the transmission daemon as this group
|
# it's a nixpkgs setting which just runs the transmission daemon as this group
|
||||||
services.transmission.group = "media";
|
services.transmission.group = "media";
|
||||||
@@ -20,6 +43,8 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
services.transmission.settings = {
|
services.transmission.settings = {
|
||||||
|
# DOCUMENTATION/options list: <https://github.com/transmission/transmission/blob/main/docs/Editing-Configuration-Files.md#options>
|
||||||
|
|
||||||
# message-level = 3; #< enable for debug logging. 0-3, default is 2.
|
# message-level = 3; #< enable for debug logging. 0-3, default is 2.
|
||||||
# 0.0.0.0 => allow rpc from any host: we gate it via firewall and auth requirement
|
# 0.0.0.0 => allow rpc from any host: we gate it via firewall and auth requirement
|
||||||
rpc-bind-address = "0.0.0.0";
|
rpc-bind-address = "0.0.0.0";
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
{ lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./feeds.nix
|
./feeds.nix
|
||||||
@@ -9,11 +9,13 @@
|
|||||||
./ids.nix
|
./ids.nix
|
||||||
./machine-id.nix
|
./machine-id.nix
|
||||||
./net
|
./net
|
||||||
./nix-path
|
./nix
|
||||||
./persist.nix
|
./persist.nix
|
||||||
|
./polyunfill.nix
|
||||||
./programs
|
./programs
|
||||||
./secrets.nix
|
./secrets.nix
|
||||||
./ssh.nix
|
./ssh.nix
|
||||||
|
./systemd.nix
|
||||||
./users
|
./users
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -30,63 +32,6 @@
|
|||||||
# time.timeZone = "America/Los_Angeles";
|
# time.timeZone = "America/Los_Angeles";
|
||||||
time.timeZone = "Etc/UTC"; # DST is too confusing for me => use a stable timezone
|
time.timeZone = "Etc/UTC"; # DST is too confusing for me => use a stable timezone
|
||||||
|
|
||||||
nix.extraOptions = ''
|
|
||||||
# see: `man nix.conf`
|
|
||||||
# useful when a remote builder has a faster internet connection than me
|
|
||||||
builders-use-substitutes = true # default: false
|
|
||||||
# maximum seconds to wait when connecting to binary substituter
|
|
||||||
connect-timeout = 3 # default: 0
|
|
||||||
# download-attempts = 5 # default: 5
|
|
||||||
# allow `nix flake ...` command
|
|
||||||
experimental-features = nix-command flakes
|
|
||||||
# whether to build from source when binary substitution fails
|
|
||||||
fallback = true # default: false
|
|
||||||
# whether to keep building dependencies if any other one fails
|
|
||||||
keep-going = true # default: false
|
|
||||||
# whether to keep build-only dependencies of GC roots (e.g. C compiler) when doing GC
|
|
||||||
keep-outputs = true # default: false
|
|
||||||
# how many lines to show from failed build
|
|
||||||
log-lines = 30 # default: 10
|
|
||||||
# narinfo-cache-negative-ttl = 3600 # default: 3600
|
|
||||||
# whether to use ~/.local/state/nix/profile instead of ~/.nix-profile, etc
|
|
||||||
use-xdg-base-directories = true # default: false
|
|
||||||
# whether to warn if repository has uncommited changes
|
|
||||||
warn-dirty = false # default: true
|
|
||||||
'';
|
|
||||||
# hardlinks identical files in the nix store to save 25-35% disk space.
|
|
||||||
# unclear _when_ this occurs. it's not a service.
|
|
||||||
# does the daemon continually scan the nix store?
|
|
||||||
# does the builder use some content-addressed db to efficiently dedupe?
|
|
||||||
nix.settings.auto-optimise-store = true;
|
|
||||||
# TODO: see if i can remove this?
|
|
||||||
nix.settings.trusted-users = [ "root" ];
|
|
||||||
|
|
||||||
services.journald.extraConfig = ''
|
|
||||||
# docs: `man journald.conf`
|
|
||||||
# merged journald config is deployed to /etc/systemd/journald.conf
|
|
||||||
[Journal]
|
|
||||||
# disable journal compression because the underlying fs is compressed
|
|
||||||
Compress=no
|
|
||||||
'';
|
|
||||||
|
|
||||||
systemd.services.nix-daemon.serviceConfig = {
|
|
||||||
# the nix-daemon manages nix builders
|
|
||||||
# kill nix-daemon subprocesses when systemd-oomd detects an out-of-memory condition
|
|
||||||
# see:
|
|
||||||
# - nixos PR that enabled systemd-oomd: <https://github.com/NixOS/nixpkgs/pull/169613>
|
|
||||||
# - systemd's docs on these properties: <https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#ManagedOOMSwap=auto%7Ckill>
|
|
||||||
#
|
|
||||||
# systemd's docs warn that without swap, systemd-oomd might not be able to react quick enough to save the system.
|
|
||||||
# see `man oomd.conf` for further tunables that may help.
|
|
||||||
#
|
|
||||||
# alternatively, apply this more broadly with `systemd.oomd.enableSystemSlice = true` or `enableRootSlice`
|
|
||||||
# TODO: also apply this to the guest user's slice (user-1100.slice)
|
|
||||||
# TODO: also apply this to distccd
|
|
||||||
ManagedOOMMemoryPressure = "kill";
|
|
||||||
ManagedOOMSwap = "kill";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
system.activationScripts.nixClosureDiff = {
|
system.activationScripts.nixClosureDiff = {
|
||||||
supportsDryActivation = true;
|
supportsDryActivation = true;
|
||||||
text = ''
|
text = ''
|
||||||
@@ -102,34 +47,14 @@
|
|||||||
text = ''
|
text = ''
|
||||||
# send a notification to any sway users logged in, that the system has been activated/upgraded.
|
# send a notification to any sway users logged in, that the system has been activated/upgraded.
|
||||||
# this probably doesn't work if more than one sway session exists on the system.
|
# this probably doesn't work if more than one sway session exists on the system.
|
||||||
_notifyActiveSwaySock="$(echo /run/user/*/sway-ipc.*.sock)"
|
_notifyActiveSwaySock="$(echo /run/user/*/sway-ipc*.sock)"
|
||||||
if [ -e "$_notifyActiveSwaySock" ]; then
|
if [ -e "$_notifyActiveSwaySock" ]; then
|
||||||
SWAYSOCK="$_notifyActiveSwaySock" ${pkgs.sway}/bin/swaymsg -- exec \
|
SWAYSOCK="$_notifyActiveSwaySock" ${config.sane.programs.sway.packageUnwrapped}/bin/swaymsg -- exec \
|
||||||
"${pkgs.libnotify}/bin/notify-send 'nixos activated' 'version: $(cat $systemConfig/nixos-version)'"
|
"${pkgs.libnotify}/bin/notify-send 'nixos activated' 'version: $(cat $systemConfig/nixos-version)'"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# disable non-required packages like nano, perl, rsync, strace
|
|
||||||
environment.defaultPackages = [];
|
|
||||||
|
|
||||||
# dconf docs: <https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/desktop_migration_and_administration_guide/profiles>
|
|
||||||
# this lets programs temporarily write user-level dconf settings (aka gsettings).
|
|
||||||
# they're written to ~/.config/dconf/user, unless `DCONF_PROFILE` is set to something other than the default of /etc/dconf/profile/user
|
|
||||||
# find keys/values with `dconf dump /`
|
|
||||||
programs.dconf.enable = true;
|
|
||||||
programs.dconf.packages = [
|
|
||||||
(pkgs.writeTextFile {
|
|
||||||
name = "dconf-user-profile";
|
|
||||||
destination = "/etc/dconf/profile/user";
|
|
||||||
text = ''
|
|
||||||
user-db:user
|
|
||||||
system-db:site
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
];
|
|
||||||
# sane.programs.glib.enableFor.user.colin = true; # for `gsettings`
|
|
||||||
|
|
||||||
# link debug symbols into /run/current-system/sw/lib/debug
|
# link debug symbols into /run/current-system/sw/lib/debug
|
||||||
# hopefully picked up by gdb automatically?
|
# hopefully picked up by gdb automatically?
|
||||||
environment.enableDebugInfo = true;
|
environment.enableDebugInfo = true;
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
# where to find good stuff?
|
# where to find good stuff?
|
||||||
|
# - universal search/directory: <https://podcastindex.org>
|
||||||
# - podcasts w/ a community: <https://lemmyverse.net/communities?query=podcast>
|
# - podcasts w/ a community: <https://lemmyverse.net/communities?query=podcast>
|
||||||
# - podcast rec thread: <https://lemmy.ml/post/1565858>
|
# - podcast rec thread: <https://lemmy.ml/post/1565858>
|
||||||
#
|
#
|
||||||
@@ -72,16 +73,14 @@ let
|
|||||||
(fromDb "feeds.feedburner.com/80000HoursPodcast" // rat)
|
(fromDb "feeds.feedburner.com/80000HoursPodcast" // rat)
|
||||||
(fromDb "feeds.feedburner.com/dancarlin/history" // rat)
|
(fromDb "feeds.feedburner.com/dancarlin/history" // rat)
|
||||||
(fromDb "feeds.feedburner.com/radiolab" // pol) # Radiolab -- also available here, but ONLY OVER HTTP: <http://feeds.wnyc.org/radiolab>
|
(fromDb "feeds.feedburner.com/radiolab" // pol) # Radiolab -- also available here, but ONLY OVER HTTP: <http://feeds.wnyc.org/radiolab>
|
||||||
(fromDb "feeds.libsyn.com/421877" // rat) # Less Wrong Curated
|
|
||||||
(fromDb "feeds.megaphone.fm/behindthebastards" // pol) # also Maggie Killjoy
|
(fromDb "feeds.megaphone.fm/behindthebastards" // pol) # also Maggie Killjoy
|
||||||
# (fromDb "feeds.megaphone.fm/hubermanlab" // uncat) # Daniel Huberman on sleep
|
|
||||||
(fromDb "feeds.megaphone.fm/recodedecode" // tech) # The Verge - Decoder
|
(fromDb "feeds.megaphone.fm/recodedecode" // tech) # The Verge - Decoder
|
||||||
(fromDb "feeds.simplecast.com/54nAGcIl" // pol) # The Daily
|
(fromDb "feeds.simplecast.com/54nAGcIl" // pol) # The Daily
|
||||||
(fromDb "feeds.simplecast.com/82FI35Px" // pol) # Ezra Klein Show
|
(fromDb "feeds.simplecast.com/82FI35Px" // pol) # Ezra Klein Show
|
||||||
(fromDb "feeds.simplecast.com/wgl4xEgL" // rat) # Econ Talk
|
(fromDb "feeds.simplecast.com/wgl4xEgL" // rat) # Econ Talk
|
||||||
(fromDb "feeds.simplecast.com/xKJ93w_w" // uncat) # Atlas Obscura
|
(fromDb "feeds.simplecast.com/xKJ93w_w" // uncat) # Atlas Obscura
|
||||||
# (fromDb "feeds.simplecast.com/l2i9YnTd" // tech // pol) # Hard Fork (NYtimes tech)
|
|
||||||
(fromDb "feeds.transistor.fm/acquired" // tech)
|
(fromDb "feeds.transistor.fm/acquired" // tech)
|
||||||
|
(fromDb "fulltimenix.com" // tech)
|
||||||
(fromDb "lexfridman.com/podcast" // rat)
|
(fromDb "lexfridman.com/podcast" // rat)
|
||||||
(fromDb "mapspodcast.libsyn.com" // uncat) # Multidisciplinary Association for Psychedelic Studies
|
(fromDb "mapspodcast.libsyn.com" // uncat) # Multidisciplinary Association for Psychedelic Studies
|
||||||
(fromDb "omegataupodcast.net" // tech) # 3/4 German; 1/4 eps are English
|
(fromDb "omegataupodcast.net" // tech) # 3/4 German; 1/4 eps are English
|
||||||
@@ -89,7 +88,6 @@ let
|
|||||||
(fromDb "omny.fm/shows/the-dollop-with-dave-anthony-and-gareth-reynolds") # The Dollop history/comedy
|
(fromDb "omny.fm/shows/the-dollop-with-dave-anthony-and-gareth-reynolds") # The Dollop history/comedy
|
||||||
(fromDb "originstories.libsyn.com" // uncat)
|
(fromDb "originstories.libsyn.com" // uncat)
|
||||||
(fromDb "podcast.posttv.com/itunes/post-reports.xml" // pol)
|
(fromDb "podcast.posttv.com/itunes/post-reports.xml" // pol)
|
||||||
# (fromDb "podcast.thelinuxexp.com" // tech) # low-brow linux/foss PR announcements
|
|
||||||
(fromDb "politicalorphanage.libsyn.com" // pol)
|
(fromDb "politicalorphanage.libsyn.com" // pol)
|
||||||
(fromDb "reverseengineering.libsyn.com/rss" // tech) # UnNamed Reverse Engineering Podcast
|
(fromDb "reverseengineering.libsyn.com/rss" // tech) # UnNamed Reverse Engineering Podcast
|
||||||
(fromDb "rss.acast.com/deconstructed") # The Intercept - Deconstructed
|
(fromDb "rss.acast.com/deconstructed") # The Intercept - Deconstructed
|
||||||
@@ -103,13 +101,17 @@ let
|
|||||||
(fromDb "sscpodcast.libsyn.com" // rat) # Astral Codex Ten
|
(fromDb "sscpodcast.libsyn.com" // rat) # Astral Codex Ten
|
||||||
(fromDb "talesfromthebridge.buzzsprout.com" // tech) # Sci-Fi? has Peter Watts; author of No Moods, Ads or Cutesy Fucking Icons (rifters.com)
|
(fromDb "talesfromthebridge.buzzsprout.com" // tech) # Sci-Fi? has Peter Watts; author of No Moods, Ads or Cutesy Fucking Icons (rifters.com)
|
||||||
(fromDb "techwontsave.us" // pol) # rec by Cory Doctorow
|
(fromDb "techwontsave.us" // pol) # rec by Cory Doctorow
|
||||||
# (fromDb "trashfuturepodcast.podbean.com" // pol) # rec by Cory Doctorow, but way rambly
|
|
||||||
(fromDb "wakingup.libsyn.com" // pol) # Sam Harris
|
(fromDb "wakingup.libsyn.com" // pol) # Sam Harris
|
||||||
(fromDb "werenotwrong.fireside.fm" // pol)
|
(fromDb "werenotwrong.fireside.fm" // pol)
|
||||||
|
|
||||||
|
# (fromDb "feeds.libsyn.com/421877" // rat) # Less Wrong Curated
|
||||||
|
# (fromDb "feeds.megaphone.fm/hubermanlab" // uncat) # Daniel Huberman on sleep
|
||||||
|
# (fromDb "feeds.simplecast.com/l2i9YnTd" // tech // pol) # Hard Fork (NYtimes tech)
|
||||||
|
# (fromDb "podcast.thelinuxexp.com" // tech) # low-brow linux/foss PR announcements
|
||||||
# (fromDb "rss.art19.com/your-welcome" // pol) # Michael Malice - Your Welcome -- also available here: <https://origin.podcastone.com/podcast?categoryID2=2232>
|
# (fromDb "rss.art19.com/your-welcome" // pol) # Michael Malice - Your Welcome -- also available here: <https://origin.podcastone.com/podcast?categoryID2=2232>
|
||||||
# (fromDb "rss.prod.firstlook.media/deconstructed/podcast.rss" // pol) #< possible URL rot
|
# (fromDb "rss.prod.firstlook.media/deconstructed/podcast.rss" // pol) #< possible URL rot
|
||||||
# (fromDb "rss.prod.firstlook.media/intercepted/podcast.rss" // pol) #< possible URL rot
|
# (fromDb "rss.prod.firstlook.media/intercepted/podcast.rss" // pol) #< possible URL rot
|
||||||
|
# (fromDb "trashfuturepodcast.podbean.com" // pol) # rec by Cory Doctorow, but way rambly
|
||||||
# (mkPod "https://anchor.fm/s/21bc734/podcast/rss" // pol // infrequent) # Emerge: making sense of what's next -- <https://www.whatisemerging.com/emergepodcast>
|
# (mkPod "https://anchor.fm/s/21bc734/podcast/rss" // pol // infrequent) # Emerge: making sense of what's next -- <https://www.whatisemerging.com/emergepodcast>
|
||||||
# (mkPod "https://audioboom.com/channels/5097784.rss" // tech) # Lateral with Tom Scott
|
# (mkPod "https://audioboom.com/channels/5097784.rss" // tech) # Lateral with Tom Scott
|
||||||
# (mkPod "https://feeds.megaphone.fm/RUNMED9919162779" // pol // infrequent) # The Witch Trials of J.K. Rowling: <https://www.thefp.com/witchtrials>
|
# (mkPod "https://feeds.megaphone.fm/RUNMED9919162779" // pol // infrequent) # The Witch Trials of J.K. Rowling: <https://www.thefp.com/witchtrials>
|
||||||
@@ -117,12 +119,13 @@ let
|
|||||||
];
|
];
|
||||||
|
|
||||||
texts = [
|
texts = [
|
||||||
|
(fromDb "acoup.blog/feed") # history, states. author: <https://historians.social/@bretdevereaux/following>
|
||||||
(fromDb "amosbbatto.wordpress.com" // tech)
|
(fromDb "amosbbatto.wordpress.com" // tech)
|
||||||
(fromDb "applieddivinitystudies.com" // rat)
|
(fromDb "applieddivinitystudies.com" // rat)
|
||||||
(fromDb "artemis.sh" // tech)
|
(fromDb "artemis.sh" // tech)
|
||||||
(fromDb "ascii.textfiles.com" // tech) # Jason Scott
|
(fromDb "ascii.textfiles.com" // tech) # Jason Scott
|
||||||
(fromDb "austinvernon.site" // tech)
|
(fromDb "austinvernon.site" // tech)
|
||||||
(fromDb "balajis.com" // pol) # Balaji
|
# (fromDb "balajis.com" // pol) # Balaji
|
||||||
(fromDb "ben-evans.com/benedictevans" // pol)
|
(fromDb "ben-evans.com/benedictevans" // pol)
|
||||||
(fromDb "bitbashing.io" // tech)
|
(fromDb "bitbashing.io" // tech)
|
||||||
(fromDb "bitsaboutmoney.com" // uncat)
|
(fromDb "bitsaboutmoney.com" // uncat)
|
||||||
@@ -144,6 +147,7 @@ let
|
|||||||
(fromDb "interconnected.org/home/feed" // rat) # Matt Webb -- engineering-ish, but dreamy
|
(fromDb "interconnected.org/home/feed" // rat) # Matt Webb -- engineering-ish, but dreamy
|
||||||
(fromDb "jeffgeerling.com" // tech)
|
(fromDb "jeffgeerling.com" // tech)
|
||||||
(fromDb "jefftk.com" // tech)
|
(fromDb "jefftk.com" // tech)
|
||||||
|
(fromDb "kill-the-newsletter.com/feeds/joh91bv7am2pnznv.xml" // pol) # Matt Levine - Money Stuff
|
||||||
(fromDb "kosmosghost.github.io/index.xml" // tech)
|
(fromDb "kosmosghost.github.io/index.xml" // tech)
|
||||||
# (fromDb "lesswrong.com" // rat)
|
# (fromDb "lesswrong.com" // rat)
|
||||||
(fromDb "linmob.net" // tech)
|
(fromDb "linmob.net" // tech)
|
||||||
@@ -188,7 +192,6 @@ let
|
|||||||
(mkSubstack "samkriss" // humor // infrequent)
|
(mkSubstack "samkriss" // humor // infrequent)
|
||||||
(mkText "http://benjaminrosshoffman.com/feed" // pol // weekly)
|
(mkText "http://benjaminrosshoffman.com/feed" // pol // weekly)
|
||||||
(mkText "http://boginjr.com/feed" // tech // infrequent)
|
(mkText "http://boginjr.com/feed" // tech // infrequent)
|
||||||
(mkText "https://acoup.blog/feed" // rat // weekly)
|
|
||||||
(mkText "https://anish.lakhwara.com/home.html" // tech // weekly)
|
(mkText "https://anish.lakhwara.com/home.html" // tech // weekly)
|
||||||
(mkText "https://forum.merveilles.town/rss.xml" // pol // infrequent) #quality RSS list here: <https://forum.merveilles.town/thread/57/share-your-rss-feeds%21-6/>
|
(mkText "https://forum.merveilles.town/rss.xml" // pol // infrequent) #quality RSS list here: <https://forum.merveilles.town/thread/57/share-your-rss-feeds%21-6/>
|
||||||
# (mkText "https://github.com/Kaiteki-Fedi/Kaiteki/commits/master.atom" // tech // infrequent)
|
# (mkText "https://github.com/Kaiteki-Fedi/Kaiteki/commits/master.atom" // tech // infrequent)
|
||||||
@@ -197,7 +200,7 @@ let
|
|||||||
(mkText "https://nixos.org/blog/announcements-rss.xml" // tech // infrequent) # more nixos stuff here, but unclear how to subscribe: <https://nixos.org/blog/categories.html>
|
(mkText "https://nixos.org/blog/announcements-rss.xml" // tech // infrequent) # more nixos stuff here, but unclear how to subscribe: <https://nixos.org/blog/categories.html>
|
||||||
(mkText "https://nixos.org/blog/stories-rss.xml" // tech // weekly)
|
(mkText "https://nixos.org/blog/stories-rss.xml" // tech // weekly)
|
||||||
# (mkText "https://til.simonwillison.net/tils/feed.atom" // tech // weekly)
|
# (mkText "https://til.simonwillison.net/tils/feed.atom" // tech // weekly)
|
||||||
(mkText "https://www.bloomberg.com/opinion/authors/ARbTQlRLRjE/matthew-s-levine.rss" // pol // weekly) # Matt Levine
|
# (mkText "https://www.bloomberg.com/opinion/authors/ARbTQlRLRjE/matthew-s-levine.rss" // pol // weekly) # Matt Levine (preview/paywalled)
|
||||||
(mkText "https://www.stratechery.com/rss" // pol // weekly) # Ben Thompson
|
(mkText "https://www.stratechery.com/rss" // pol // weekly) # Ben Thompson
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -219,6 +222,7 @@ let
|
|||||||
];
|
];
|
||||||
|
|
||||||
images = [
|
images = [
|
||||||
|
(fromDb "catandgirl.com" // img // humor)
|
||||||
(fromDb "miniature-calendar.com" // img // art // daily)
|
(fromDb "miniature-calendar.com" // img // art // daily)
|
||||||
(fromDb "pbfcomics.com" // img // humor)
|
(fromDb "pbfcomics.com" // img // humor)
|
||||||
(fromDb "poorlydrawnlines.com/feed" // img // humor)
|
(fromDb "poorlydrawnlines.com/feed" // img // humor)
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
# docs
|
# docs
|
||||||
# - x-systemd options: <https://www.freedesktop.org/software/systemd/man/systemd.mount.html>
|
# - x-systemd options: <https://www.freedesktop.org/software/systemd/man/systemd.mount.html>
|
||||||
|
# - fuse options: `man mount.fuse`
|
||||||
|
|
||||||
{ lib, pkgs, sane-lib, ... }:
|
{ lib, pkgs, sane-lib, ... }:
|
||||||
|
|
||||||
@@ -8,13 +9,22 @@ let
|
|||||||
common = [
|
common = [
|
||||||
"_netdev"
|
"_netdev"
|
||||||
"noatime"
|
"noatime"
|
||||||
"user" # allow any user with access to the device to mount the fs
|
# user: allow any user with access to the device to mount the fs.
|
||||||
|
# note that this requires a suid `mount` binary; see: <https://zameermanji.com/blog/2022/8/5/using-fuse-without-root-on-linux/>
|
||||||
|
"user"
|
||||||
"x-systemd.requires=network-online.target"
|
"x-systemd.requires=network-online.target"
|
||||||
"x-systemd.after=network-online.target"
|
"x-systemd.after=network-online.target"
|
||||||
"x-systemd.mount-timeout=10s" # how long to wait for mount **and** how long to wait for unmount
|
"x-systemd.mount-timeout=10s" # how long to wait for mount **and** how long to wait for unmount
|
||||||
];
|
];
|
||||||
auto = [ "x-systemd.automount" ];
|
# x-systemd.automount: mount the fs automatically *on first access*.
|
||||||
noauto = [ "noauto" ]; # don't mount as part of remote-fs.target
|
# creates a `path-to-mount.automount` systemd unit.
|
||||||
|
automount = [ "x-systemd.automount" ];
|
||||||
|
# noauto: don't mount as part of remote-fs.target.
|
||||||
|
# N.B.: `remote-fs.target` is a dependency of multi-user.target, itself of graphical.target.
|
||||||
|
# hence, omitting `noauto` can slow down boots.
|
||||||
|
noauto = [ "noauto" ];
|
||||||
|
# lazyMount: defer mounting until first access from userspace
|
||||||
|
lazyMount = noauto ++ automount;
|
||||||
wg = [
|
wg = [
|
||||||
"x-systemd.requires=wireguard-wg-home.service"
|
"x-systemd.requires=wireguard-wg-home.service"
|
||||||
"x-systemd.after=wireguard-wg-home.service"
|
"x-systemd.after=wireguard-wg-home.service"
|
||||||
@@ -22,19 +32,34 @@ let
|
|||||||
|
|
||||||
ssh = common ++ [
|
ssh = common ++ [
|
||||||
"identityfile=/home/colin/.ssh/id_ed25519"
|
"identityfile=/home/colin/.ssh/id_ed25519"
|
||||||
"allow_other"
|
"allow_other" # allow users other than the one who mounts it to access it. needed, if systemd is the one mounting this fs (as root)
|
||||||
|
# allow_root: allow root to access files on this fs (if mounted by non-root, else it can always access them).
|
||||||
|
# N.B.: if both allow_root and allow_other are specified, then only allow_root takes effect.
|
||||||
|
# "allow_root"
|
||||||
|
# default_permissions: enforce local permissions check. CRUCIAL if using `allow_other`.
|
||||||
|
# w/o this, permissions mode of sshfs is like:
|
||||||
|
# - sshfs runs all remote commands as the remote user.
|
||||||
|
# - if a local user has local permissions to the sshfs mount, then their file ops are sent blindly across the tunnel.
|
||||||
|
# - `allow_other` allows *any* local user to access the mount, and hence any local user can now freely become the remote mapped user.
|
||||||
|
# with default_permissions, sshfs doesn't tunnel file ops from users until checking that said user could perform said op on an equivalent local fs.
|
||||||
"default_permissions"
|
"default_permissions"
|
||||||
];
|
];
|
||||||
sshColin = ssh ++ [
|
sshColin = ssh ++ [
|
||||||
|
# follow_symlinks: remote files which are symlinks are presented to the local system as ordinary files (as the target of the symlink).
|
||||||
|
# if the symlink target does not exist, the presentation is unspecified.
|
||||||
|
# symlinks which point outside the mount ARE followed. so this is more capable than `transform_symlinks`
|
||||||
|
"follow_symlinks"
|
||||||
|
# symlinks on the remote fs which are absolute paths are presented to the local system as relative symlinks pointing to the expected data on the remote fs.
|
||||||
|
# only symlinks which would point inside the mountpoint are translated.
|
||||||
"transform_symlinks"
|
"transform_symlinks"
|
||||||
"idmap=user"
|
"idmap=user"
|
||||||
"uid=1000"
|
"uid=1000"
|
||||||
"gid=100"
|
"gid=100"
|
||||||
];
|
];
|
||||||
sshRoot = ssh ++ [
|
# sshRoot = ssh ++ [
|
||||||
# we don't transform_symlinks because that breaks the validity of remote /nix stores
|
# # we don't transform_symlinks because that breaks the validity of remote /nix stores
|
||||||
"sftp_server=/run/wrappers/bin/sudo\\040/run/current-system/sw/libexec/sftp-server"
|
# "sftp_server=/run/wrappers/bin/sudo\\040/run/current-system/sw/libexec/sftp-server"
|
||||||
];
|
# ];
|
||||||
# in the event of hunt NFS mounts, consider:
|
# in the event of hunt NFS mounts, consider:
|
||||||
# - <https://unix.stackexchange.com/questions/31979/stop-broken-nfs-mounts-from-locking-a-directory>
|
# - <https://unix.stackexchange.com/questions/31979/stop-broken-nfs-mounts-from-locking-a-directory>
|
||||||
|
|
||||||
@@ -57,13 +82,17 @@ let
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
remoteHome = host: {
|
remoteHome = host: {
|
||||||
fileSystems."/mnt/${host}-home" = {
|
fileSystems."/mnt/${host}/home" = {
|
||||||
device = "colin@${host}:/home/colin";
|
device = "colin@${host}:/home/colin";
|
||||||
fsType = "fuse.sshfs";
|
fsType = "fuse.sshfs";
|
||||||
options = fsOpts.sshColin ++ fsOpts.noauto;
|
options = fsOpts.sshColin ++ fsOpts.lazyMount;
|
||||||
noCheck = true;
|
noCheck = true;
|
||||||
};
|
};
|
||||||
sane.fs."/mnt/${host}-home" = sane-lib.fs.wantedDir;
|
sane.fs."/mnt/${host}/home" = sane-lib.fs.wanted {
|
||||||
|
dir.acl.user = "colin";
|
||||||
|
dir.acl.group = "users";
|
||||||
|
dir.acl.mode = "0700";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
lib.mkMerge [
|
lib.mkMerge [
|
||||||
@@ -103,34 +132,38 @@ lib.mkMerge [
|
|||||||
# device = "servo-hn:/";
|
# device = "servo-hn:/";
|
||||||
# noCheck = true;
|
# noCheck = true;
|
||||||
# fsType = "nfs";
|
# fsType = "nfs";
|
||||||
# options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
|
# options = fsOpts.nfs ++ fsOpts.automount ++ fsOpts.wg;
|
||||||
# };
|
# };
|
||||||
fileSystems."/mnt/servo-nfs/media" = {
|
fileSystems."/mnt/servo/media" = {
|
||||||
device = "servo-hn:/media";
|
device = "servo-hn:/media";
|
||||||
noCheck = true;
|
noCheck = true;
|
||||||
fsType = "nfs";
|
fsType = "nfs";
|
||||||
options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
|
options = fsOpts.nfs ++ fsOpts.lazyMount ++ fsOpts.wg;
|
||||||
};
|
};
|
||||||
fileSystems."/mnt/servo-nfs/playground" = {
|
sane.fs."/mnt/servo/media" = sane-lib.fs.wanted {
|
||||||
|
dir.acl.user = "colin";
|
||||||
|
dir.acl.group = "users";
|
||||||
|
dir.acl.mode = "0750";
|
||||||
|
};
|
||||||
|
fileSystems."/mnt/servo/playground" = {
|
||||||
device = "servo-hn:/playground";
|
device = "servo-hn:/playground";
|
||||||
noCheck = true;
|
noCheck = true;
|
||||||
fsType = "nfs";
|
fsType = "nfs";
|
||||||
options = fsOpts.nfs ++ fsOpts.auto ++ fsOpts.wg;
|
options = fsOpts.nfs ++ fsOpts.lazyMount ++ fsOpts.wg;
|
||||||
|
};
|
||||||
|
sane.fs."/mnt/servo/playground" = sane-lib.fs.wanted {
|
||||||
|
dir.acl.user = "colin";
|
||||||
|
dir.acl.group = "users";
|
||||||
|
dir.acl.mode = "0750";
|
||||||
};
|
};
|
||||||
# fileSystems."/mnt/servo-media-nfs" = {
|
|
||||||
# device = "servo-hn:/media";
|
|
||||||
# noCheck = true;
|
|
||||||
# fsType = "nfs";
|
|
||||||
# options = fsOpts.common ++ fsOpts.auto;
|
|
||||||
# };
|
|
||||||
sane.fs."/mnt/servo-media" = sane-lib.fs.wantedSymlinkTo "/mnt/servo-nfs/media";
|
|
||||||
|
|
||||||
environment.pathsToLink = [
|
# environment.pathsToLink = [
|
||||||
# needed to achieve superuser access for user-mounted filesystems (see optionsRoot above)
|
# # needed to achieve superuser access for user-mounted filesystems (see sshRoot above)
|
||||||
# we can only link whole directories here, even though we're only interested in pkgs.openssh
|
# # we can only link whole directories here, even though we're only interested in pkgs.openssh
|
||||||
"/libexec"
|
# "/libexec"
|
||||||
];
|
# ];
|
||||||
|
|
||||||
|
programs.fuse.userAllowOther = true; #< necessary for `allow_other` or `allow_root` options.
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
pkgs.sshfs-fuse
|
pkgs.sshfs-fuse
|
||||||
];
|
];
|
||||||
|
@@ -28,6 +28,13 @@
|
|||||||
# "systemd.log_level=debug"
|
# "systemd.log_level=debug"
|
||||||
# "systemd.log_target=console"
|
# "systemd.log_target=console"
|
||||||
|
|
||||||
|
# moby has to run recent kernels (defined elsewhere).
|
||||||
|
# meanwhile, kernel variation plays some minor role in things like sandboxing (landlock) and capabilities.
|
||||||
|
# simpler to keep near the latest kernel on all devices,
|
||||||
|
# and also makes certain that any weird system-level bugs i see aren't likely to be stale kernel bugs.
|
||||||
|
# servo needs zfs though, which doesn't support every kernel.
|
||||||
|
boot.kernelPackages = lib.mkDefault pkgs.zfs.latestCompatibleLinuxPackages;
|
||||||
|
|
||||||
# hack in the `boot.shell_on_fail` arg since that doesn't always seem to work.
|
# hack in the `boot.shell_on_fail` arg since that doesn't always seem to work.
|
||||||
boot.initrd.preFailCommands = "allowShell=1";
|
boot.initrd.preFailCommands = "allowShell=1";
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./keyring
|
./fs.nix
|
||||||
./mime.nix
|
./mime.nix
|
||||||
./ssh.nix
|
./ssh.nix
|
||||||
./xdg-dirs.nix
|
./xdg-dirs.nix
|
||||||
|
42
hosts/common/home/fs.nix
Normal file
42
hosts/common/home/fs.nix
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
sane.user.persist.byStore.plaintext = [
|
||||||
|
"archive"
|
||||||
|
"dev"
|
||||||
|
# TODO: records should be private
|
||||||
|
"records"
|
||||||
|
"ref"
|
||||||
|
"tmp"
|
||||||
|
"use"
|
||||||
|
"Books/local"
|
||||||
|
"Music"
|
||||||
|
"Pictures/albums"
|
||||||
|
"Pictures/cat"
|
||||||
|
"Pictures/from"
|
||||||
|
"Pictures/Screenshots" #< XXX: something is case-sensitive about this?
|
||||||
|
"Pictures/Photos"
|
||||||
|
"Videos/local"
|
||||||
|
|
||||||
|
# these are persisted simply to save on RAM.
|
||||||
|
# ~/.cache/nix can become several GB.
|
||||||
|
# mesa_shader_cache is < 10 MB.
|
||||||
|
# TODO: integrate with sane.programs.sandbox?
|
||||||
|
".cache/mesa_shader_cache"
|
||||||
|
".cache/nix"
|
||||||
|
];
|
||||||
|
sane.user.persist.byStore.private = [
|
||||||
|
"knowledge"
|
||||||
|
];
|
||||||
|
|
||||||
|
# convenience
|
||||||
|
sane.user.fs.".persist/private".symlink.target = config.sane.persist.stores.private.origin;
|
||||||
|
sane.user.fs.".persist/plaintext".symlink.target = config.sane.persist.stores.plaintext.origin;
|
||||||
|
sane.user.fs.".persist/ephemeral".symlink.target = config.sane.persist.stores.cryptClearOnBoot.origin;
|
||||||
|
|
||||||
|
sane.user.fs."nixos".symlink.target = "dev/nixos";
|
||||||
|
|
||||||
|
sane.user.fs."Books/servo".symlink.target = "/mnt/servo/media/Books";
|
||||||
|
sane.user.fs."Videos/servo".symlink.target = "/mnt/servo/media/Videos";
|
||||||
|
# sane.user.fs."Music/servo".symlink.target = "/mnt/servo/media/Music";
|
||||||
|
sane.user.fs."Pictures/servo-macros".symlink.target = "/mnt/servo/media/Pictures/macros";
|
||||||
|
}
|
@@ -1,17 +0,0 @@
|
|||||||
{ config, pkgs, sane-lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
init-keyring = pkgs.static-nix-shell.mkBash {
|
|
||||||
pname = "init-keyring";
|
|
||||||
src = ./.;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sane.user.persist.byStore.private = [ ".local/share/keyrings" ];
|
|
||||||
|
|
||||||
sane.user.fs."private/.local/share/keyrings/default" = {
|
|
||||||
generated.command = [ "${init-keyring}/bin/init-keyring" ];
|
|
||||||
wantedBy = [ config.sane.fs."/home/colin/private".unit ];
|
|
||||||
wantedBeforeBy = [ ]; # don't created this as part of `multi-user.target`
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env nix-shell
|
|
||||||
#!nix-shell -i bash
|
|
||||||
# initializes the default libsecret keyring (used by gnome-keyring) if not already initialized.
|
|
||||||
# this initializes it to be plaintext/unencrypted.
|
|
||||||
|
|
||||||
ringdir=/home/colin/private/.local/share/keyrings
|
|
||||||
if test -f "$ringdir/default"
|
|
||||||
then
|
|
||||||
echo 'keyring already initialized: not doing anything'
|
|
||||||
else
|
|
||||||
keyring="$ringdir/Default_keyring.keyring"
|
|
||||||
|
|
||||||
echo 'initializing default user keyring:' "$keyring.new"
|
|
||||||
echo '[keyring]' > "$keyring.new"
|
|
||||||
echo 'display-name=Default keyring' >> "$keyring.new"
|
|
||||||
echo 'lock-on-idle=false' >> "$keyring.new"
|
|
||||||
echo 'lock-after=false' >> "$keyring.new"
|
|
||||||
chown colin:users "$keyring.new"
|
|
||||||
# closest to an atomic update we can achieve
|
|
||||||
mv "$keyring.new" "$keyring" && echo -n "Default_keyring" > "$ringdir/default"
|
|
||||||
fi
|
|
@@ -1,4 +1,5 @@
|
|||||||
{ config, lib, ...}:
|
# TODO: move into modules/users.nix
|
||||||
|
{ config, lib, pkgs, ...}:
|
||||||
|
|
||||||
let
|
let
|
||||||
# [ ProgramConfig ]
|
# [ ProgramConfig ]
|
||||||
@@ -6,6 +7,9 @@ let
|
|||||||
(p: p.enabled)
|
(p: p.enabled)
|
||||||
(builtins.attrValues config.sane.programs);
|
(builtins.attrValues config.sane.programs);
|
||||||
|
|
||||||
|
# [ ProgramConfig ]
|
||||||
|
enabledProgramsWithPackage = builtins.filter (p: p.package != null) enabledPrograms;
|
||||||
|
|
||||||
# [ { "<mime-type>" = { prority, desktop } ]
|
# [ { "<mime-type>" = { prority, desktop } ]
|
||||||
enabledWeightedMimes = builtins.map weightedMimes enabledPrograms;
|
enabledWeightedMimes = builtins.map weightedMimes enabledPrograms;
|
||||||
|
|
||||||
@@ -21,23 +25,70 @@ let
|
|||||||
|
|
||||||
# [ { priority, desktop } ... ] -> Self
|
# [ { priority, desktop } ... ] -> Self
|
||||||
sortOneMimeType = associations: builtins.sort
|
sortOneMimeType = associations: builtins.sort
|
||||||
(l: r: assert l.priority != r.priority; l.priority < r.priority)
|
(l: r: lib.throwIf
|
||||||
|
(l.priority == r.priority)
|
||||||
|
"${l.desktop} and ${r.desktop} share a preferred mime type with identical priority ${builtins.toString l.priority} (and so the desired association is ambiguous)"
|
||||||
|
(l.priority < r.priority)
|
||||||
|
)
|
||||||
associations;
|
associations;
|
||||||
sortMimes = mimes: builtins.mapAttrs (_k: sortOneMimeType) mimes;
|
sortMimes = mimes: builtins.mapAttrs (_k: sortOneMimeType) mimes;
|
||||||
|
# { "<mime-type>"} = [ { priority, desktop } ... ]; } -> { "<mime-type>" = [ "<desktop>" ... ]; }
|
||||||
removePriorities = mimes: builtins.mapAttrs
|
removePriorities = mimes: builtins.mapAttrs
|
||||||
(_k: associations: builtins.map (a: a.desktop) associations)
|
(_k: associations: builtins.map (a: a.desktop) associations)
|
||||||
mimes;
|
mimes;
|
||||||
|
# { "<mime-type>" = [ "<desktop>" ... ]; } -> { "<mime-type>" = "<desktop1>;<desktop2>;..."; }
|
||||||
|
formatDesktopLists = mimes: builtins.mapAttrs
|
||||||
|
(_k: desktops: lib.concatStringsSep ";" desktops)
|
||||||
|
mimes;
|
||||||
|
|
||||||
|
mimeappsListPkg = pkgs.writeTextDir "share/applications/mimeapps.list" (
|
||||||
|
lib.generators.toINI { } {
|
||||||
|
"Default Applications" = formatDesktopLists (removePriorities (sortMimes (mergeMimes enabledWeightedMimes)));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
localShareApplicationsPkg = (pkgs.symlinkJoin {
|
||||||
|
name = "user-local-share-applications";
|
||||||
|
paths = builtins.map
|
||||||
|
(p: "${p.package}")
|
||||||
|
(enabledProgramsWithPackage ++ [ { package=mimeappsListPkg; } ]);
|
||||||
|
}).overrideAttrs (orig: {
|
||||||
|
# like normal symlinkJoin, but don't error if the path doesn't exist
|
||||||
|
buildCommand = ''
|
||||||
|
mkdir -p $out/share/applications
|
||||||
|
for i in $(cat $pathsPath); do
|
||||||
|
if [ -e "$i/share/applications" ]; then
|
||||||
|
${pkgs.buildPackages.xorg.lndir}/bin/lndir -silent $i/share/applications $out/share/applications
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
postBuild = ''
|
||||||
|
# rebuild `mimeinfo.cache`, used by file openers to show the list of *all* apps, not just the user's defaults.
|
||||||
|
${pkgs.buildPackages.desktop-file-utils}/bin/update-desktop-database $out/share/applications
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# the xdg mime type for a file can be found with:
|
# the xdg mime type for a file can be found with:
|
||||||
# - `xdg-mime query filetype path/to/thing.ext`
|
# - `xdg-mime query filetype path/to/thing.ext`
|
||||||
# the default handler for a mime type can be found with:
|
# the default handler for a mime type can be found with:
|
||||||
# - `xdg-mime query default <mimetype>` (e.g. x-scheme-handler/http)
|
# - `xdg-mime query default <mimetype>` (e.g. x-scheme-handler/http)
|
||||||
|
# the nix-configured handler can be found `nix-repl > :lf . > hostConfigs.desko.xdg.mime.defaultApplications`
|
||||||
|
#
|
||||||
|
# glib/gio is queried via glib.bin output:
|
||||||
|
# - `gio mime x-scheme-handler/https`
|
||||||
|
# - `gio open <path_or_url>`
|
||||||
|
# - `gio launch </path/to/app.desktop>`
|
||||||
#
|
#
|
||||||
# we can have single associations or a list of associations.
|
# we can have single associations or a list of associations.
|
||||||
# there's also options to *remove* [non-default] associations from specific apps
|
# there's also options to *remove* [non-default] associations from specific apps
|
||||||
xdg.mime.enable = true;
|
# N.B.: don't use nixos' `xdg.mime` option becaue that caues `/share/applications` to be linked into the whole system,
|
||||||
xdg.mime.defaultApplications = removePriorities (sortMimes (mergeMimes enabledWeightedMimes));
|
# which limits what i can do around sandboxing. getting the default associations to live in ~/ makes it easier to expose
|
||||||
|
# the associations to apps selectively.
|
||||||
|
# xdg.mime.enable = true;
|
||||||
|
# xdg.mime.defaultApplications = removePriorities (sortMimes (mergeMimes enabledWeightedMimes));
|
||||||
|
|
||||||
|
sane.user.fs.".local/share/applications".symlink.target = "${localShareApplicationsPkg}/share/applications";
|
||||||
}
|
}
|
||||||
|
@@ -36,10 +36,4 @@
|
|||||||
wg-home.endpoint = "uninsane.org:51820";
|
wg-home.endpoint = "uninsane.org:51820";
|
||||||
lan-ip = "10.78.79.51";
|
lan-ip = "10.78.79.51";
|
||||||
};
|
};
|
||||||
|
|
||||||
sane.hosts.by-name."supercap" = {
|
|
||||||
ssh.authorized = false;
|
|
||||||
ssh.host_pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHf/mqqkX45EWAcquV04MC3SUljTApdclH1gjI19F+PA";
|
|
||||||
lan-ip = "10.78.79.232";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,8 @@
|
|||||||
sane.ids.bitcoind-mainnet.gid = 2418;
|
sane.ids.bitcoind-mainnet.gid = 2418;
|
||||||
sane.ids.clightning.uid = 2419;
|
sane.ids.clightning.uid = 2419;
|
||||||
sane.ids.clightning.gid = 2419;
|
sane.ids.clightning.gid = 2419;
|
||||||
|
sane.ids.nix-serve.uid = 2420;
|
||||||
|
sane.ids.nix-serve.gid = 2420;
|
||||||
|
|
||||||
sane.ids.colin.uid = 1000;
|
sane.ids.colin.uid = 1000;
|
||||||
sane.ids.guest.uid = 1100;
|
sane.ids.guest.uid = 1100;
|
||||||
|
@@ -7,6 +7,24 @@
|
|||||||
./upnp.nix
|
./upnp.nix
|
||||||
./vpn.nix
|
./vpn.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
systemd.network.enable = true;
|
||||||
|
networking.useNetworkd = true;
|
||||||
|
|
||||||
|
# view refused/dropped packets with: `sudo journalctl -k`
|
||||||
|
# networking.firewall.logRefusedPackets = true;
|
||||||
|
# networking.firewall.logRefusedUnicastsOnly = false;
|
||||||
|
networking.firewall.logReversePathDrops = true;
|
||||||
|
# linux will drop inbound packets if it thinks a reply to that packet wouldn't exit via the same interface (rpfilter).
|
||||||
|
# that heuristic fails for complicated VPN-style routing, especially with SNAT.
|
||||||
|
# networking.firewall.checkReversePath = false; # or "loose" to keep it partially.
|
||||||
|
# networking.firewall.enable = false; #< set false to debug
|
||||||
|
|
||||||
|
# this is needed to forward packets from the VPN to the host.
|
||||||
|
# this is required separately by servo and by any `sane-vpn` users,
|
||||||
|
# however Nix requires this be set centrally, in only one location (i.e. here)
|
||||||
|
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
|
||||||
|
|
||||||
# the default backend is "wpa_supplicant".
|
# the default backend is "wpa_supplicant".
|
||||||
# wpa_supplicant reliably picks weak APs to connect to.
|
# wpa_supplicant reliably picks weak APs to connect to.
|
||||||
# see: <https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/474>
|
# see: <https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/474>
|
||||||
|
@@ -1,15 +1,35 @@
|
|||||||
{ ... }:
|
# things to consider when changing these parameters:
|
||||||
|
# - temporary VPN access (`sane-vpn up ...`)
|
||||||
|
# - servo `ovpns` namespace (it *relies* on /etc/resolv.conf mentioning 127.0.0.53)
|
||||||
|
# - jails: `firejail --net=br-ovpnd-us --noprofile --dns=46.227.67.134 ping 1.1.1.1`
|
||||||
|
#
|
||||||
|
# components:
|
||||||
|
# - /etc/nsswitch.conf:
|
||||||
|
# - glibc uses this to provide `getaddrinfo`, i.e. host -> ip address lookup
|
||||||
|
# call directly with `getent ahostsv4 www.google.com`
|
||||||
|
# - `nss` (a component of glibc) is modular: names mentioned in that file are `dlopen`'d (i think that's the mechanism)
|
||||||
|
# in NixOS, that means _they have to be on LDPATH_.
|
||||||
|
# - `nscd` is used by NixOS simply to proxy nss requests.
|
||||||
|
# here, /etc/nsswitch.conf consumers contact nscd via /var/run/nscd/socket.
|
||||||
|
# in this way, only `nscd` needs to have the nss modules on LDPATH.
|
||||||
|
# - /etc/resolv.conf
|
||||||
|
# - contains the DNS servers for a system.
|
||||||
|
# - historically, NetworkManager would update this file as you switch networks.
|
||||||
|
# - modern implementations hardcodes `127.0.0.53` and then systemd-resolved proxies everything (and caches).
|
||||||
|
#
|
||||||
|
# namespacing:
|
||||||
|
# - each namespace can use a different /etc/resolv.conf to specify different DNS servers (see `firejail --dns=...`)
|
||||||
|
# - nscd breaks namespacing: the host nscd is unaware of the guest's /etc/resolv.conf, and so direct's the guest's DNS requests to the host's servers.
|
||||||
|
# - this is fixed by either `firejail --blacklist=/var/run/nscd/socket`, or disabling nscd altogether.
|
||||||
|
{ lib, ... }:
|
||||||
{
|
{
|
||||||
# use systemd's stub resolver.
|
# use systemd's stub resolver.
|
||||||
# /etc/resolv.conf isn't sophisticated enough to use different servers per net namespace (or link).
|
# /etc/resolv.conf isn't sophisticated enough to use different servers per net namespace (or link).
|
||||||
# instead, running the stub resolver on a known address in the root ns lets us rewrite packets
|
# instead, running the stub resolver on a known address in the root ns lets us rewrite packets
|
||||||
# in the ovnps namespace to use the provider's DNS resolvers.
|
# in servo's ovnps namespace to use the provider's DNS resolvers.
|
||||||
# a weakness is we can only query 1 NS at a time (unless we were to clone the packets?)
|
# a weakness is we can only query 1 NS at a time (unless we were to clone the packets?)
|
||||||
# there also seems to be some cache somewhere that's shared between the two namespaces.
|
# TODO: rework servo's netns to use `firejail`, which is capable of spoofing /etc/resolv.conf.
|
||||||
# i think this is a libc thing. might need to leverage proper cgroups to _really_ kill it.
|
services.resolved.enable = true; #< to disable, set ` = lib.mkForce false`, as other systemd features default to enabling `resolved`.
|
||||||
# - getent ahostsv4 www.google.com
|
|
||||||
# - try fix: <https://serverfault.com/questions/765989/connect-to-3rd-party-vpn-server-but-dont-use-it-as-the-default-route/766290#766290>
|
|
||||||
services.resolved.enable = true;
|
|
||||||
# without DNSSEC:
|
# without DNSSEC:
|
||||||
# - dig matrix.org => works
|
# - dig matrix.org => works
|
||||||
# - curl https://matrix.org => works
|
# - curl https://matrix.org => works
|
||||||
@@ -32,6 +52,16 @@
|
|||||||
# nsncd is the Name Service NON-Caching Daemon. it's a drop-in that doesn't cache;
|
# nsncd is the Name Service NON-Caching Daemon. it's a drop-in that doesn't cache;
|
||||||
# this is OK on the host -- because systemd-resolved caches. it's probably sub-optimal
|
# this is OK on the host -- because systemd-resolved caches. it's probably sub-optimal
|
||||||
# in the netns and we query upstream DNS more often than needed. hm.
|
# in the netns and we query upstream DNS more often than needed. hm.
|
||||||
# TODO: run a separate recursive resolver in each namespace.
|
# services.nscd.enableNsncd = true;
|
||||||
services.nscd.enableNsncd = true;
|
|
||||||
|
# disabling nscd LOSES US SOME FUNCTIONALITY. in particular, only the glibc-builtin modules are accessible via /etc/resolv.conf.
|
||||||
|
# - dns: glibc-bultin
|
||||||
|
# - files: glibc-builtin
|
||||||
|
# - myhostname: systemd
|
||||||
|
# - mymachines: systemd
|
||||||
|
# - resolve: systemd
|
||||||
|
# in practice, i see no difference with nscd disabled.
|
||||||
|
# disabling nscd VASTLY simplifies netns and process isolation. see explainer at top of file.
|
||||||
|
services.nscd.enable = false;
|
||||||
|
system.nssModules = lib.mkForce [];
|
||||||
}
|
}
|
||||||
|
@@ -1,89 +1,56 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
# to add a new OVPN VPN:
|
# to add a new OVPN VPN:
|
||||||
# - generate a privkey `wg genkey`
|
# - generate a privkey `wg genkey`
|
||||||
# - add this key to `sops secrets/universal.yaml`
|
# - add this key to `sops secrets/universal.yaml`
|
||||||
# - upload pubkey to OVPN.com
|
# - upload pubkey to OVPN.com (`cat wg.priv | wg pubkey`)
|
||||||
# - generate config @ OVPN.com
|
# - generate config @ OVPN.com
|
||||||
# - copy the Address, PublicKey, Endpoint from OVPN's config
|
# - copy the Address, PublicKey, Endpoint from OVPN's config
|
||||||
# N.B.: maximum interface name in Linux is 15 characters.
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
def-wg-vpn = name: { endpoint, publicKey, address, dns, privateKeyFile }: {
|
def-ovpn = name: { endpoint, publicKey, addrV4, id }: {
|
||||||
# networking.wg-quick.interfaces."${name}" = {
|
sane.vpn."ovpnd-${name}" = {
|
||||||
# inherit address privateKeyFile dns;
|
inherit endpoint publicKey addrV4 id;
|
||||||
# peers = [
|
|
||||||
# {
|
|
||||||
# allowedIPs = [
|
|
||||||
# "0.0.0.0/0"
|
|
||||||
# "::/0"
|
|
||||||
# ];
|
|
||||||
# inherit endpoint publicKey;
|
|
||||||
# }
|
|
||||||
# ];
|
|
||||||
# # to start: `systemctl start wg-quick-${name}`
|
|
||||||
# autostart = false;
|
|
||||||
# };
|
|
||||||
systemd.network.netdevs."${name}" = {
|
|
||||||
# see: `man 5 systemd.netdev`
|
|
||||||
wireguardConfig = {
|
|
||||||
PrivateKeyFile = privateKeyFile;
|
|
||||||
};
|
|
||||||
wireguardPeers = [{
|
|
||||||
AllowedIPs = [
|
|
||||||
"0.0.0.0/0"
|
|
||||||
"::/0"
|
|
||||||
];
|
|
||||||
Endpoint = endpoint;
|
|
||||||
PublicKey = publicKey;
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
systemd.network.networks."${name}" = {
|
|
||||||
# see: `man 5 systemd.network`
|
|
||||||
matchConfig.Name = name;
|
|
||||||
networkConfig.Address = address;
|
|
||||||
networkConfig.DNS = dns;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
def-ovpn = name: { endpoint, publicKey, address }: def-wg-vpn "ovpnd-${name}" {
|
|
||||||
inherit endpoint publicKey address;
|
|
||||||
privateKeyFile = config.sops.secrets."wg/ovpnd_${name}_privkey".path;
|
privateKeyFile = config.sops.secrets."wg/ovpnd_${name}_privkey".path;
|
||||||
dns = [
|
dns = [
|
||||||
"46.227.67.134"
|
"46.227.67.134"
|
||||||
"192.165.9.158"
|
"192.165.9.158"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sops.secrets."wg/ovpnd_${name}_privkey" = {
|
||||||
|
# needs to be readable by systemd-network or else it says "Ignoring network device" and doesn't expose it to networkctl.
|
||||||
|
owner = "systemd-network";
|
||||||
|
};
|
||||||
|
};
|
||||||
in lib.mkMerge [
|
in lib.mkMerge [
|
||||||
(def-ovpn "us" {
|
(def-ovpn "us" {
|
||||||
endpoint = "vpn31.prd.losangeles.ovpn.com:9929";
|
endpoint = "vpn31.prd.losangeles.ovpn.com:9929";
|
||||||
publicKey = "VW6bEWMOlOneta1bf6YFE25N/oMGh1E1UFBCfyggd0k=";
|
publicKey = "VW6bEWMOlOneta1bf6YFE25N/oMGh1E1UFBCfyggd0k=";
|
||||||
address = [
|
id = 1;
|
||||||
"172.27.237.218/32"
|
addrV4 = "172.27.237.218";
|
||||||
"fd00:0000:1337:cafe:1111:1111:ab00:4c8f/128"
|
# addrV6 = "fd00:0000:1337:cafe:1111:1111:ab00:4c8f";
|
||||||
];
|
|
||||||
})
|
|
||||||
# NB: us-* share the same wg key and link-local addrs, but distinct public addresses
|
|
||||||
(def-ovpn "us-atl" {
|
|
||||||
endpoint = "vpn18.prd.atlanta.ovpn.com:9929";
|
|
||||||
publicKey = "Dpg/4v5s9u0YbrXukfrMpkA+XQqKIFpf8ZFgyw0IkE0=";
|
|
||||||
address = [
|
|
||||||
"172.21.182.178/32"
|
|
||||||
"fd00:0000:1337:cafe:1111:1111:cfcb:27e3/128"
|
|
||||||
];
|
|
||||||
})
|
})
|
||||||
|
# TODO: us-atl disabled until i can give it a different link-local address and wireguard key than us-mi
|
||||||
|
# (def-ovpn "us-atl" {
|
||||||
|
# endpoint = "vpn18.prd.atlanta.ovpn.com:9929";
|
||||||
|
# publicKey = "Dpg/4v5s9u0YbrXukfrMpkA+XQqKIFpf8ZFgyw0IkE0=";
|
||||||
|
# address = [
|
||||||
|
# "172.21.182.178/32"
|
||||||
|
# "fd00:0000:1337:cafe:1111:1111:cfcb:27e3/128"
|
||||||
|
# ];
|
||||||
|
# })
|
||||||
(def-ovpn "us-mi" {
|
(def-ovpn "us-mi" {
|
||||||
endpoint = "vpn34.prd.miami.ovpn.com:9929";
|
endpoint = "vpn34.prd.miami.ovpn.com:9929";
|
||||||
publicKey = "VtJz2irbu8mdkIQvzlsYhU+k9d55or9mx4A2a14t0V0=";
|
publicKey = "VtJz2irbu8mdkIQvzlsYhU+k9d55or9mx4A2a14t0V0=";
|
||||||
address = [
|
id = 2;
|
||||||
"172.21.182.178/32"
|
addrV4 = "172.21.182.178";
|
||||||
"fd00:0000:1337:cafe:1111:1111:cfcb:27e3/128"
|
# addrV6 = "fd00:0000:1337:cafe:1111:1111:cfcb:27e3";
|
||||||
];
|
|
||||||
})
|
})
|
||||||
(def-ovpn "ukr" {
|
(def-ovpn "ukr" {
|
||||||
endpoint = "vpn96.prd.kyiv.ovpn.com:9929";
|
endpoint = "vpn96.prd.kyiv.ovpn.com:9929";
|
||||||
publicKey = "CjZcXDxaaKpW8b5As1EcNbI6+42A6BjWahwXDCwfVFg=";
|
publicKey = "CjZcXDxaaKpW8b5As1EcNbI6+42A6BjWahwXDCwfVFg=";
|
||||||
address = [
|
id = 3;
|
||||||
"172.18.180.159/32"
|
addrV4 = "172.18.180.159";
|
||||||
"fd00:0000:1337:cafe:1111:1111:ec5c:add3/128"
|
# addrV6 = "fd00:0000:1337:cafe:1111:1111:ec5c:add3";
|
||||||
];
|
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
{ pkgs, sane-lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
# allow `nix-shell` (and probably nix-index?) to locate our patched and custom packages
|
|
||||||
nix.nixPath = [
|
|
||||||
"nixpkgs=${pkgs.path}"
|
|
||||||
# note the import starts at repo root: this allows `./overlay/default.nix` to access the stuff at the root
|
|
||||||
# "nixpkgs-overlays=${../../..}/hosts/common/nix-path/overlay"
|
|
||||||
# as long as my system itself doesn't rely on NIXPKGS at runtime, we can point the overlays to git
|
|
||||||
# to avoid switching so much during development
|
|
||||||
"nixpkgs-overlays=/home/colin/dev/nixos/hosts/common/nix-path/overlay"
|
|
||||||
];
|
|
||||||
|
|
||||||
# ensure new deployments have a source of this repo with which they can bootstrap.
|
|
||||||
environment.etc."nixos".source = ../../..;
|
|
||||||
}
|
|
84
hosts/common/nix/default.nix
Normal file
84
hosts/common/nix/default.nix
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
nix.settings = {
|
||||||
|
# see: `man nix.conf`
|
||||||
|
|
||||||
|
# useful when a remote builder has a faster internet connection than me.
|
||||||
|
# note that this also applies to `nix copy --to`, though.
|
||||||
|
# i think any time a remote machine wants a path, this means we ask them to try getting it themselves before we supply it.
|
||||||
|
builders-use-substitutes = true; # default: false
|
||||||
|
|
||||||
|
# maximum seconds to wait when connecting to binary substituter
|
||||||
|
connect-timeout = 3; # default: 0
|
||||||
|
|
||||||
|
# download-attempts = 5; # default: 5
|
||||||
|
|
||||||
|
# allow `nix flake ...` command
|
||||||
|
experimental-features = [ "nix-command" "flakes "];
|
||||||
|
|
||||||
|
# whether to build from source when binary substitution fails
|
||||||
|
fallback = true; # default: false
|
||||||
|
|
||||||
|
# whether to keep building dependencies if any other one fails
|
||||||
|
keep-going = true; # default: false
|
||||||
|
|
||||||
|
# whether to keep build-only dependencies of GC roots (e.g. C compiler) when doing GC
|
||||||
|
keep-outputs = true; # default: false
|
||||||
|
|
||||||
|
# how many lines to show from failed build
|
||||||
|
log-lines = 30; # default: 10
|
||||||
|
|
||||||
|
# how many substitution downloads to perform in parallel.
|
||||||
|
# i wonder if parallelism is causing moby's substitutions to fail?
|
||||||
|
max-substitution-jobs = 6; # default: 16
|
||||||
|
|
||||||
|
# narinfo-cache-negative-ttl = 3600 # default: 3600
|
||||||
|
# whether to use ~/.local/state/nix/profile instead of ~/.nix-profile, etc
|
||||||
|
use-xdg-base-directories = true; # default: false
|
||||||
|
|
||||||
|
# whether to warn if repository has uncommited changes
|
||||||
|
warn-dirty = false; # default: true
|
||||||
|
|
||||||
|
# hardlinks identical files in the nix store to save 25-35% disk space.
|
||||||
|
# unclear _when_ this occurs. it's not a service.
|
||||||
|
# does the daemon continually scan the nix store?
|
||||||
|
# does the builder use some content-addressed db to efficiently dedupe?
|
||||||
|
auto-optimise-store = true;
|
||||||
|
|
||||||
|
# allow #!nix-shell scripts to locate my patched nixpkgs & custom packages.
|
||||||
|
# this line might become unnecessary: see <https://github.com/NixOS/nixpkgs/pull/273170>
|
||||||
|
nix-path = config.nix.nixPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
# allow `nix-shell` (and probably nix-index?) to locate our patched and custom packages.
|
||||||
|
# this is actually a no-op, and the real action happens in assigning `nix.settings.nix-path`.
|
||||||
|
nix.nixPath = [
|
||||||
|
"nixpkgs=${pkgs.path}"
|
||||||
|
# note the import starts at repo root: this allows `./overlay/default.nix` to access the stuff at the root
|
||||||
|
# "nixpkgs-overlays=${../../..}/hosts/common/nix-path/overlay"
|
||||||
|
# as long as my system itself doesn't rely on NIXPKGS at runtime, we can point the overlays to git
|
||||||
|
# to avoid switching so much during development
|
||||||
|
"nixpkgs-overlays=/home/colin/dev/nixos/hosts/common/nix/overlay"
|
||||||
|
];
|
||||||
|
|
||||||
|
# ensure new deployments have a source of this repo with which they can bootstrap.
|
||||||
|
environment.etc."nixos".source = ../../..;
|
||||||
|
|
||||||
|
systemd.services.nix-daemon.serviceConfig = {
|
||||||
|
# the nix-daemon manages nix builders
|
||||||
|
# kill nix-daemon subprocesses when systemd-oomd detects an out-of-memory condition
|
||||||
|
# see:
|
||||||
|
# - nixos PR that enabled systemd-oomd: <https://github.com/NixOS/nixpkgs/pull/169613>
|
||||||
|
# - systemd's docs on these properties: <https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#ManagedOOMSwap=auto%7Ckill>
|
||||||
|
#
|
||||||
|
# systemd's docs warn that without swap, systemd-oomd might not be able to react quick enough to save the system.
|
||||||
|
# see `man oomd.conf` for further tunables that may help.
|
||||||
|
#
|
||||||
|
# alternatively, apply this more broadly with `systemd.oomd.enableSystemSlice = true` or `enableRootSlice`
|
||||||
|
# TODO: also apply this to the guest user's slice (user-1100.slice)
|
||||||
|
# TODO: also apply this to distccd
|
||||||
|
ManagedOOMMemoryPressure = "kill";
|
||||||
|
ManagedOOMSwap = "kill";
|
||||||
|
};
|
||||||
|
}
|
@@ -1,13 +1,14 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
sane.persist.stores.private.origin = "/home/colin/private";
|
# store /home/colin/a/b in /mnt/persist/private/a/b instead of /mnt/persist/private/home/colin/a/b
|
||||||
# store /home/colin/a/b in /home/private/a/b instead of /home/private/home/colin/a/b
|
|
||||||
sane.persist.stores.private.prefix = "/home/colin";
|
sane.persist.stores.private.prefix = "/home/colin";
|
||||||
|
|
||||||
|
sane.persist.sys.byStore.initrd = [
|
||||||
|
"/var/log"
|
||||||
|
];
|
||||||
sane.persist.sys.byStore.plaintext = [
|
sane.persist.sys.byStore.plaintext = [
|
||||||
# TODO: these should be private.. somehow
|
# TODO: these should be private.. somehow
|
||||||
"/var/log"
|
|
||||||
"/var/backup" # for e.g. postgres dumps
|
"/var/backup" # for e.g. postgres dumps
|
||||||
];
|
];
|
||||||
sane.persist.sys.byStore.cryptClearOnBoot = [
|
sane.persist.sys.byStore.cryptClearOnBoot = [
|
||||||
|
45
hosts/common/polyunfill.nix
Normal file
45
hosts/common/polyunfill.nix
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# strictly *decrease* the scope of the default nixos installation/config
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
# disable non-required packages like nano, perl, rsync, strace
|
||||||
|
environment.defaultPackages = [];
|
||||||
|
|
||||||
|
# remove all the non-existent default directories from XDG_DATA_DIRS, XDG_CONFIG_DIRS to simplify debugging.
|
||||||
|
# this is defaulted in <repo:nixos/nixpkgs:nixos/modules/programs/environment.nix>,
|
||||||
|
# without being gated by any higher config.
|
||||||
|
environment.profiles = lib.mkForce [
|
||||||
|
"/etc/profiles/per-user/$USER"
|
||||||
|
"/run/current-system/sw"
|
||||||
|
];
|
||||||
|
|
||||||
|
# NIXPKGS_CONFIG defaults to "/etc/nix/nixpkgs-config.nix", for idfk why.
|
||||||
|
# that's never existed on my system and everything does fine without it set empty (no nixpkgs API to forcibly *unset* it).
|
||||||
|
environment.variables.NIXPKGS_CONFIG = lib.mkForce "";
|
||||||
|
# XDG_CONFIG_DIRS defaults to "/etc/xdg", which doesn't exist.
|
||||||
|
# in practice, pam appends the values i want to XDG_CONFIG_DIRS, though this approach causes an extra leading `:`
|
||||||
|
environment.sessionVariables.XDG_CONFIG_DIRS = lib.mkForce [];
|
||||||
|
# XCURSOR_PATH: defaults to `[ "$HOME/.icons" "$HOME/.local/share/icons" ]`, neither of which i use, just adding noise.
|
||||||
|
# see: <repo:nixos/nixpkgs:nixos/modules/config/xdg/icons.nix>
|
||||||
|
environment.sessionVariables.XCURSOR_PATH = lib.mkForce [];
|
||||||
|
|
||||||
|
# disable nixos' portal module, otherwise /share/applications gets linked into the system and complicates things (sandboxing).
|
||||||
|
# instead, i manage portals myself via the sane.programs API (e.g. sane.programs.xdg-desktop-portal).
|
||||||
|
xdg.portal.enable = false;
|
||||||
|
xdg.menus.enable = false; #< links /share/applications, and a bunch of other empty (i.e. unused) dirs
|
||||||
|
|
||||||
|
# xdg.autostart.enable defaults to true, and links /etc/xdg/autostart into the environment, populated with .desktop files.
|
||||||
|
# see: <repo:nixos/nixpkgs:nixos/modules/config/xdg/autostart.nix>
|
||||||
|
# .desktop files are a questionable way to autostart things: i generally prefer a service manager for that.
|
||||||
|
xdg.autostart.enable = false;
|
||||||
|
|
||||||
|
# nix.channel.enable: populates `/nix/var/nix/profiles/per-user/root/channels`, `/root/.nix-channels`, `$HOME/.nix-defexpr/channels`
|
||||||
|
# <repo:nixos/nixpkgs:nixos/modules/config/nix-channel.nix>
|
||||||
|
# TODO: may want to recreate NIX_PATH, nix.settings.nix-path
|
||||||
|
nix.channel.enable = false;
|
||||||
|
|
||||||
|
# environment.stub-ld: populate /lib/ld-linux.so with an object that unconditionally errors on launch,
|
||||||
|
# so as to inform when trying to run a non-nixos binary?
|
||||||
|
# IMO that's confusing: i thought /lib/ld-linux.so was some file actually required by nix.
|
||||||
|
environment.stub-ld.enable = false;
|
||||||
|
}
|
@@ -15,7 +15,7 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
package = pkgs.abaddon.overrideAttrs (upstream: {
|
packageUnwrapped = pkgs.abaddon.overrideAttrs (upstream: {
|
||||||
patches = (upstream.patches or []) ++ [
|
patches = (upstream.patches or []) ++ [
|
||||||
(pkgs.fetchpatch {
|
(pkgs.fetchpatch {
|
||||||
url = "https://git.uninsane.org/colin/abaddon/commit/eb551f188d34679f75adcbc83cb8d5beb4d19fd6.patch";
|
url = "https://git.uninsane.org/colin/abaddon/commit/eb551f188d34679f75adcbc83cb8d5beb4d19fd6.patch";
|
||||||
@@ -87,7 +87,7 @@ in
|
|||||||
|
|
||||||
services.abaddon = {
|
services.abaddon = {
|
||||||
description = "unofficial Discord chat client";
|
description = "unofficial Discord chat client";
|
||||||
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
|
wantedBy = lib.mkIf cfg.config.autostart [ "graphical-session.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${cfg.package}/bin/abaddon";
|
ExecStart = "${cfg.package}/bin/abaddon";
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
|
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
sane.programs.aerc = {
|
sane.programs.aerc = {
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "inplace";
|
||||||
|
sandbox.net = "clearnet";
|
||||||
secrets.".config/aerc/accounts.conf" = ../../../secrets/common/aerc_accounts.conf.bin;
|
secrets.".config/aerc/accounts.conf" = ../../../secrets/common/aerc_accounts.conf.bin;
|
||||||
mime.associations."x-scheme-handler/mailto" = "aerc.desktop";
|
mime.associations."x-scheme-handler/mailto" = "aerc.desktop";
|
||||||
};
|
};
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.alacritty = {
|
sane.programs.alacritty = {
|
||||||
|
sandbox.enable = false;
|
||||||
env.TERMINAL = lib.mkDefault "alacritty";
|
env.TERMINAL = lib.mkDefault "alacritty";
|
||||||
fs.".config/alacritty/alacritty.toml".symlink.text = ''
|
fs.".config/alacritty/alacritty.toml".symlink.text = ''
|
||||||
[font]
|
[font]
|
||||||
|
@@ -1,10 +1,42 @@
|
|||||||
{ ... }:
|
# debug with:
|
||||||
|
# - `animatch --debug`
|
||||||
|
# - `gdb animatch`
|
||||||
|
# try:
|
||||||
|
# - `animatch --fullscreen`
|
||||||
|
# - `animatch --windowed`
|
||||||
|
# the other config options (e.g. verbose logging -- which doesn't seem to do anything) have to be configured via .ini file
|
||||||
|
# ```ini
|
||||||
|
# # ~/.config/Holy Pangolin/Animatch/SuperDerpy.ini
|
||||||
|
# [SuperDerpy]
|
||||||
|
# debug=1
|
||||||
|
# disableTouch=1
|
||||||
|
# [game]
|
||||||
|
# verbose=1
|
||||||
|
# ```
|
||||||
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.animatch = {
|
sane.programs.animatch = {
|
||||||
|
packageUnwrapped = with pkgs; animatch.override {
|
||||||
|
# allegro has no native wayland support, and so by default crashes when run without Xwayland.
|
||||||
|
# enable the allegro SDL backend, and achieve Wayland support via SDL's Wayland support.
|
||||||
|
# TODO: see about upstreaming this to nixpkgs?
|
||||||
|
allegro5 = allegro5.overrideAttrs (upstream: {
|
||||||
|
buildInputs = upstream.buildInputs ++ [
|
||||||
|
SDL2
|
||||||
|
];
|
||||||
|
cmakeFlags = upstream.cmakeFlags ++ [
|
||||||
|
"-DALLEGRO_SDL=on"
|
||||||
|
];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
|
||||||
persist.byStore.plaintext = [
|
persist.byStore.plaintext = [
|
||||||
# game progress
|
# ".config/Holy Pangolin/Animatch" #< used for SuperDerpy config (e.g. debug, disableTouch, fullscreen, enable sound, etc). SuperDerpy.ini
|
||||||
".config/Holy Pangolin/Animatch"
|
".local/share/Holy Pangolin/Animatch" #< used for game state (level clears). SuperDerpy.ini
|
||||||
".local/share/Holy Pangolin/Animatch" # i think this one might be wrong
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.audacity = {
|
sane.programs.audacity = {
|
||||||
package = pkgs.audacity.override {
|
packageUnwrapped = pkgs.audacity.override {
|
||||||
# wxGTK32 uses webkitgtk-4.0.
|
# wxGTK32 uses webkitgtk-4.0.
|
||||||
# audacity doesn't actually need webkit though, so diable to reduce closure
|
# audacity doesn't actually need webkit though, so diable to reduce closure
|
||||||
wxGTK32 = pkgs.wxGTK32.override {
|
wxGTK32 = pkgs.wxGTK32.override {
|
||||||
@@ -9,6 +9,19 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.autodetectCliPaths = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
# support media imports via file->open dir to some common media directories
|
||||||
|
"tmp"
|
||||||
|
"Music"
|
||||||
|
# audacity needs the entire config dir mounted if running in a sandbox
|
||||||
|
".config/audacity"
|
||||||
|
];
|
||||||
|
|
||||||
# disable first-run splash screen
|
# disable first-run splash screen
|
||||||
fs.".config/audacity/audacity.cfg".file.text = ''
|
fs.".config/audacity/audacity.cfg".file.text = ''
|
||||||
PrefsVersion=1.1.1r1
|
PrefsVersion=1.1.1r1
|
||||||
|
@@ -87,7 +87,14 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.programs.bemenu = {
|
sane.programs.bemenu = {
|
||||||
package = pkgs.bemenu.overrideAttrs (upstream: {
|
sandbox.method = "bwrap"; # landlock works, but requires *all* of /run/user/$ID to be granted.
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
".cache/fontconfig" #< else it complains, and is *way* slower
|
||||||
|
];
|
||||||
|
|
||||||
|
packageUnwrapped = pkgs.bemenu.overrideAttrs (upstream: {
|
||||||
nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [
|
nativeBuildInputs = (upstream.nativeBuildInputs or []) ++ [
|
||||||
pkgs.makeWrapper
|
pkgs.makeWrapper
|
||||||
];
|
];
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# bonsai docs: <https://sr.ht/~stacyharper/bonsai/>
|
# bonsai docs: <https://sr.ht/~stacyharper/bonsai/>
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.sane.gui.sxmo.bonsaid;
|
cfg = config.sane.programs.bonsai;
|
||||||
|
|
||||||
delayType = with lib; types.submodule {
|
delayType = with lib; types.submodule {
|
||||||
options = {
|
options = {
|
||||||
@@ -88,74 +88,43 @@ let
|
|||||||
mergeOneOption loc defs
|
mergeOneOption loc defs
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
# transitionType = with lib; types.submodule {
|
|
||||||
# options = {
|
|
||||||
# type = mkOption {
|
|
||||||
# type = types.enum [ "delay" "event" "exec" ];
|
|
||||||
# };
|
|
||||||
# delay_duration = mkOption {
|
|
||||||
# type = types.nullOr types.int;
|
|
||||||
# default = null;
|
|
||||||
# description = ''
|
|
||||||
# used for "delay" types only.
|
|
||||||
# nanoseconds until the event is finalized.
|
|
||||||
# '';
|
|
||||||
# };
|
|
||||||
# event_name = mkOption {
|
|
||||||
# type = types.nullOr types.str;
|
|
||||||
# default = null;
|
|
||||||
# description = ''
|
|
||||||
# name of event which this transition applies to.
|
|
||||||
# '';
|
|
||||||
# };
|
|
||||||
# transitions = mkOption {
|
|
||||||
# type = types.nullOr (types.listOf transitionType);
|
|
||||||
# default = null;
|
|
||||||
# description = ''
|
|
||||||
# list of transitions out of this state.
|
|
||||||
# '';
|
|
||||||
# };
|
|
||||||
# command = mkOption {
|
|
||||||
# type = types.nullOr (types.listOf types.str);
|
|
||||||
# default = null;
|
|
||||||
# description = ''
|
|
||||||
# used for "exec" types only.
|
|
||||||
# command to run when the event is triggered.
|
|
||||||
# '';
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = with lib; {
|
sane.programs.bonsai = {
|
||||||
sane.gui.sxmo.bonsaid.package = mkOption {
|
configOption = with lib; mkOption {
|
||||||
type = types.package;
|
default = {};
|
||||||
default = pkgs.bonsai;
|
type = types.submodule {
|
||||||
};
|
options = {
|
||||||
sane.gui.sxmo.bonsaid.transitions = mkOption {
|
transitions = mkOption {
|
||||||
type = types.listOf transitionType;
|
type = types.listOf transitionType;
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
sane.gui.sxmo.bonsaid.configFile = mkOption {
|
configFile = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
default = pkgs.writeText "bonsai_tree.json" (builtins.toJSON cfg.transitions);
|
default = pkgs.writeText "bonsai_tree.json" (builtins.toJSON cfg.config.transitions);
|
||||||
description = ''
|
description = ''
|
||||||
configuration file to pass to bonsai.
|
configuration file to pass to bonsai.
|
||||||
usually auto-generated from the sibling options; exposed mainly for debugging or convenience.
|
usually auto-generated from the sibling options; exposed mainly for debugging or convenience.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = lib.mkIf config.sane.gui.sxmo.enable {
|
};
|
||||||
sane.user.services.bonsaid = {
|
};
|
||||||
description = "programmable input dispatcher";
|
|
||||||
|
services.bonsaid = {
|
||||||
|
description = "bonsai: programmable input dispatcher";
|
||||||
|
after = [ "graphical-session.target" ];
|
||||||
|
wantedBy = [ "graphical-session.target" ];
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
${pkgs.coreutils}/bin/rm -f $XDG_RUNTIME_DIR/bonsai
|
${pkgs.coreutils}/bin/rm -f $XDG_RUNTIME_DIR/bonsai
|
||||||
exec ${cfg.package}/bin/bonsaid -t ${cfg.configFile}
|
exec ${cfg.package}/bin/bonsaid -t ${cfg.config.configFile}
|
||||||
'';
|
'';
|
||||||
serviceConfig.Type = "simple";
|
serviceConfig = {
|
||||||
serviceConfig.Restart = "always";
|
Type = "simple";
|
||||||
serviceConfig.RestartSec = "5s";
|
Restart = "always";
|
||||||
|
RestartSec = "5s";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
@@ -1,6 +1,17 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
sane.programs.brave = {
|
sane.programs.brave = {
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "inplace"; # /opt/share/brave.com vendor-style packaging
|
||||||
|
sandbox.net = "all";
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
"dev" # for developing anything web-related
|
||||||
|
"tmp"
|
||||||
|
];
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistDri = true;
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
|
||||||
persist.byStore.cryptClearOnBoot = [
|
persist.byStore.cryptClearOnBoot = [
|
||||||
".cache/BraveSoftware"
|
".cache/BraveSoftware"
|
||||||
".config/BraveSoftware"
|
".config/BraveSoftware"
|
||||||
|
35
hosts/common/programs/bubblewrap.nix
Normal file
35
hosts/common/programs/bubblewrap.nix
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
sane.programs.bubblewrap = {
|
||||||
|
sandbox.enable = false; # don't sandbox the sandboxer :)
|
||||||
|
packageUnwrapped = pkgs.bubblewrap.overrideAttrs (base: {
|
||||||
|
# patches = (base.patches or []) ++ [
|
||||||
|
# (pkgs.fetchpatch {
|
||||||
|
# url = "https://git.uninsane.org/colin/bubblewrap/commit/9843f9b2b5f086563fd37250658d69350a2939be.patch";
|
||||||
|
# name = "enable debug logging and add a bunch more tracing";
|
||||||
|
# hash = "sha256-AlDsqddaBahhqGibZlCjgmChuK7mmxDt0aYHNgY05OI=";
|
||||||
|
# })
|
||||||
|
# ];
|
||||||
|
postPatch = (base.postPatch or "") + ''
|
||||||
|
# bwrap doesn't like to be invoked with any capabilities, which is troublesome if i
|
||||||
|
# want to do things like ship CAP_NET_ADMIN,CAP_NET_RAW in the ambient set for tools like Wireshark.
|
||||||
|
# but this limitation of bwrap is artificial and at first look is just a scenario the author probably
|
||||||
|
# never expected: patch out the guard check.
|
||||||
|
#
|
||||||
|
# see: <https://github.com/containers/bubblewrap/issues/397>
|
||||||
|
#
|
||||||
|
# note that invoking bwrap with capabilities in the 'init' namespace does NOT grant the sandboxed process
|
||||||
|
# capabilities in the 'init' namespace. it's a limitation of namespaces that namespaced processes can
|
||||||
|
# never receive capabilities in their parent namespace.
|
||||||
|
substituteInPlace bubblewrap.c --replace \
|
||||||
|
'die ("Unexpected capabilities but not setuid, old file caps config?");' \
|
||||||
|
'// die ("Unexpected capabilities but not setuid, old file caps config?");'
|
||||||
|
|
||||||
|
# enable debug printing
|
||||||
|
# substituteInPlace utils.h --replace \
|
||||||
|
# '#define __debug__(x)' \
|
||||||
|
# '#define __debug__(x) printf x'
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
@@ -44,7 +44,7 @@ in
|
|||||||
services.gnome-calls = {
|
services.gnome-calls = {
|
||||||
# TODO: prevent gnome-calls from daemonizing when started manually
|
# TODO: prevent gnome-calls from daemonizing when started manually
|
||||||
description = "gnome-calls daemon to monitor incoming SIP calls";
|
description = "gnome-calls daemon to monitor incoming SIP calls";
|
||||||
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
|
wantedBy = lib.mkIf cfg.config.autostart [ "graphical-session.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
# add --verbose for more debugging
|
# add --verbose for more debugging
|
||||||
ExecStart = "${cfg.package}/bin/gnome-calls --daemon";
|
ExecStart = "${cfg.package}/bin/gnome-calls --daemon";
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.chatty = {
|
sane.programs.chatty = {
|
||||||
# package = chattyNoOauth;
|
# packageUnwrapped = chattyNoOauth;
|
||||||
package = pkgs.chatty-latest;
|
packageUnwrapped = pkgs.chatty-latest;
|
||||||
suggestedPrograms = [ "gnome-keyring" ];
|
suggestedPrograms = [ "gnome-keyring" ];
|
||||||
persist.byStore.private = [
|
persist.byStore.private = [
|
||||||
".local/share/chatty" # matrix avatars and files
|
".local/share/chatty" # matrix avatars and files
|
||||||
|
@@ -1,11 +1,22 @@
|
|||||||
{ config, pkgs, ... }:
|
{ config, pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.conky = {
|
sane.programs.conky = {
|
||||||
|
# TODO: non-sandboxed `conky` still ships via `sxmo-utils`, but unused
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.net = "clearnet"; #< for the scripts it calls (weather)
|
||||||
|
sandbox.extraPaths = [
|
||||||
|
"/sys/class/power_supply"
|
||||||
|
"/sys/devices" # needed by battery_estimate
|
||||||
|
# "/sys/devices/cpu"
|
||||||
|
# "/sys/devices/system"
|
||||||
|
];
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
|
||||||
fs.".config/conky/conky.conf".symlink.target =
|
fs.".config/conky/conky.conf".symlink.target =
|
||||||
let
|
let
|
||||||
battery_estimate = pkgs.static-nix-shell.mkBash {
|
battery_estimate = pkgs.static-nix-shell.mkBash {
|
||||||
pname = "battery_estimate";
|
pname = "battery_estimate";
|
||||||
src = ./.;
|
srcRoot = ./.;
|
||||||
};
|
};
|
||||||
in pkgs.substituteAll {
|
in pkgs.substituteAll {
|
||||||
src = ./conky.conf;
|
src = ./conky.conf;
|
||||||
@@ -15,20 +26,14 @@
|
|||||||
|
|
||||||
services.conky = {
|
services.conky = {
|
||||||
description = "conky dynamic desktop background";
|
description = "conky dynamic desktop background";
|
||||||
wantedBy = [ "default.target" ];
|
after = [ "graphical-session.target" ];
|
||||||
# XXX: should be part of graphical-session.target, but whatever mix of greetd/sway
|
# partOf = [ "graphical-session.target" ]; # propagate stop/restart signal from graphical-session to this unit
|
||||||
# i'm using means that target's never reached...
|
wantedBy = [ "graphical-session.target" ];
|
||||||
# wantedBy = [ "graphical-session.target" ];
|
|
||||||
# partOf = [ "graphical-session.target" ];
|
|
||||||
|
|
||||||
serviceConfig.ExecStart = "${config.sane.programs.conky.package}/bin/conky";
|
serviceConfig.ExecStart = "${config.sane.programs.conky.package}/bin/conky";
|
||||||
serviceConfig.Type = "simple";
|
serviceConfig.Type = "simple";
|
||||||
serviceConfig.Restart = "on-failure";
|
serviceConfig.Restart = "on-failure";
|
||||||
serviceConfig.RestartSec = "10s";
|
serviceConfig.RestartSec = "10s";
|
||||||
# serviceConfig.Slice = "session.slice";
|
|
||||||
|
|
||||||
# don't start conky until after sway
|
|
||||||
preStart = ''test -n "$SWAYSOCK"'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
sane.programs.cozy = {
|
sane.programs.cozy = {
|
||||||
|
sandbox.method = "bwrap"; # landlock gives: _multiprocessing.SemLock: Permission Denied
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistDbus = [ "user" ]; # mpris
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
"Books/local"
|
||||||
|
"Books/servo"
|
||||||
|
];
|
||||||
|
|
||||||
# cozy uses a sqlite db for its config and exposes no CLI options other than --help and --debug
|
# cozy uses a sqlite db for its config and exposes no CLI options other than --help and --debug
|
||||||
persist.byStore.plaintext = [
|
persist.byStore.plaintext = [
|
||||||
".local/share/cozy" # sqlite db (config & index?)
|
".local/share/cozy" # sqlite db (config & index?)
|
||||||
|
33
hosts/common/programs/dconf.nix
Normal file
33
hosts/common/programs/dconf.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# dconf docs: <https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/desktop_migration_and_administration_guide/profiles>
|
||||||
|
# this lets programs temporarily write user-level dconf settings (aka gsettings).
|
||||||
|
# they're written to ~/.config/dconf/user, unless `DCONF_PROFILE` is set to something other than the default of /etc/dconf/profile/user
|
||||||
|
# find keys/values with `dconf dump /`
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.sane.programs.dconf;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sane.programs.dconf = {
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
persist.byStore.private = [
|
||||||
|
".config/dconf"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.dconf = lib.mkIf cfg.enabled {
|
||||||
|
# note that `programs.dconf` doesn't allow specifying the dconf package.
|
||||||
|
enable = true;
|
||||||
|
packages = [
|
||||||
|
(pkgs.writeTextFile {
|
||||||
|
name = "dconf-user-profile";
|
||||||
|
destination = "/etc/dconf/profile/user";
|
||||||
|
text = ''
|
||||||
|
user-db:user
|
||||||
|
system-db:site
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
@@ -9,13 +9,16 @@
|
|||||||
./assorted.nix
|
./assorted.nix
|
||||||
./audacity.nix
|
./audacity.nix
|
||||||
./bemenu.nix
|
./bemenu.nix
|
||||||
|
./bonsai.nix
|
||||||
./brave.nix
|
./brave.nix
|
||||||
|
./bubblewrap.nix
|
||||||
./calls.nix
|
./calls.nix
|
||||||
./cantata.nix
|
./cantata.nix
|
||||||
./catt.nix
|
./catt.nix
|
||||||
./chatty.nix
|
./chatty.nix
|
||||||
./conky
|
./conky
|
||||||
./cozy.nix
|
./cozy.nix
|
||||||
|
./dconf.nix
|
||||||
./dialect.nix
|
./dialect.nix
|
||||||
./dino.nix
|
./dino.nix
|
||||||
./element-desktop.nix
|
./element-desktop.nix
|
||||||
@@ -23,30 +26,38 @@
|
|||||||
./evince.nix
|
./evince.nix
|
||||||
./feedbackd.nix
|
./feedbackd.nix
|
||||||
./firefox.nix
|
./firefox.nix
|
||||||
|
./firejail.nix
|
||||||
./flare-signal.nix
|
./flare-signal.nix
|
||||||
./fontconfig.nix
|
./fontconfig.nix
|
||||||
./fractal.nix
|
./fractal.nix
|
||||||
|
./frozen-bubble.nix
|
||||||
./fwupd.nix
|
./fwupd.nix
|
||||||
./g4music.nix
|
./g4music.nix
|
||||||
./gajim.nix
|
./gajim.nix
|
||||||
|
./gdbus.nix
|
||||||
./geary.nix
|
./geary.nix
|
||||||
./git.nix
|
./git.nix
|
||||||
./gnome-feeds.nix
|
./gnome-feeds.nix
|
||||||
./gnome-keyring.nix
|
./gnome-keyring
|
||||||
|
./gnome-maps.nix
|
||||||
./gnome-weather.nix
|
./gnome-weather.nix
|
||||||
./go2tv.nix
|
./go2tv.nix
|
||||||
./gpodder.nix
|
./gpodder.nix
|
||||||
|
./grimshot.nix
|
||||||
./gthumb.nix
|
./gthumb.nix
|
||||||
./gtkcord4.nix
|
./gtkcord4.nix
|
||||||
|
./handbrake.nix
|
||||||
./helix.nix
|
./helix.nix
|
||||||
./imagemagick.nix
|
./imagemagick.nix
|
||||||
./jellyfin-media-player.nix
|
./jellyfin-media-player.nix
|
||||||
|
./kdenlive.nix
|
||||||
./komikku.nix
|
./komikku.nix
|
||||||
./koreader
|
./koreader
|
||||||
./libreoffice.nix
|
./libreoffice.nix
|
||||||
./lemoa.nix
|
./lemoa.nix
|
||||||
./loupe.nix
|
./loupe.nix
|
||||||
./mako.nix
|
./mako.nix
|
||||||
|
./megapixels.nix
|
||||||
./mepo.nix
|
./mepo.nix
|
||||||
./mimeo
|
./mimeo
|
||||||
./mopidy.nix
|
./mopidy.nix
|
||||||
@@ -56,16 +67,21 @@
|
|||||||
./neovim.nix
|
./neovim.nix
|
||||||
./newsflash.nix
|
./newsflash.nix
|
||||||
./nheko.nix
|
./nheko.nix
|
||||||
|
./nicotine-plus.nix
|
||||||
./nix-index.nix
|
./nix-index.nix
|
||||||
./notejot.nix
|
./notejot.nix
|
||||||
./ntfy-sh.nix
|
./ntfy-sh.nix
|
||||||
./obsidian.nix
|
./obsidian.nix
|
||||||
./offlineimap.nix
|
./offlineimap.nix
|
||||||
./open-in-mpv.nix
|
./open-in-mpv.nix
|
||||||
|
./pipewire.nix
|
||||||
./planify.nix
|
./planify.nix
|
||||||
|
./portfolio-filemanager.nix
|
||||||
./playerctl.nix
|
./playerctl.nix
|
||||||
./rhythmbox.nix
|
./rhythmbox.nix
|
||||||
./ripgrep.nix
|
./ripgrep.nix
|
||||||
|
./rofi
|
||||||
|
./sane-scripts.nix
|
||||||
./sfeed.nix
|
./sfeed.nix
|
||||||
./signal-desktop.nix
|
./signal-desktop.nix
|
||||||
./splatmoji.nix
|
./splatmoji.nix
|
||||||
@@ -73,19 +89,30 @@
|
|||||||
./spotify.nix
|
./spotify.nix
|
||||||
./steam.nix
|
./steam.nix
|
||||||
./stepmania.nix
|
./stepmania.nix
|
||||||
|
./strings.nix
|
||||||
./sublime-music.nix
|
./sublime-music.nix
|
||||||
./supertuxkart.nix
|
./supertuxkart.nix
|
||||||
|
./sway
|
||||||
./sway-autoscaler
|
./sway-autoscaler
|
||||||
|
./swaylock.nix
|
||||||
./swaynotificationcenter.nix
|
./swaynotificationcenter.nix
|
||||||
./tangram.nix
|
./tangram.nix
|
||||||
./tor-browser-bundle-bin.nix
|
./tor-browser.nix
|
||||||
./tuba.nix
|
./tuba.nix
|
||||||
|
./unl0kr
|
||||||
./vlc.nix
|
./vlc.nix
|
||||||
|
./waybar
|
||||||
|
./waylock.nix
|
||||||
./wike.nix
|
./wike.nix
|
||||||
./wine.nix
|
./wine.nix
|
||||||
|
./wireplumber.nix
|
||||||
./wireshark.nix
|
./wireshark.nix
|
||||||
./wob.nix
|
./wob
|
||||||
./xarchiver.nix
|
./xarchiver.nix
|
||||||
|
./xdg-desktop-portal.nix
|
||||||
|
./xdg-desktop-portal-gtk.nix
|
||||||
|
./xdg-desktop-portal-wlr.nix
|
||||||
|
./xdg-utils.nix
|
||||||
./zeal.nix
|
./zeal.nix
|
||||||
./zecwallet-lite.nix
|
./zecwallet-lite.nix
|
||||||
./zsh
|
./zsh
|
||||||
|
@@ -1,7 +1,13 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.dialect = {
|
sane.programs.dialect = {
|
||||||
package = pkgs.dialect.overrideAttrs (upstream: {
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "inplace"; # share/search_providers/ calls back into the binary, weird wrap semantics
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.net = "clearnet";
|
||||||
|
suggestedPrograms = [ "dconf" ]; #< to persist settings
|
||||||
|
|
||||||
|
packageUnwrapped = pkgs.dialect.overrideAttrs (upstream: {
|
||||||
# TODO: send upstream
|
# TODO: send upstream
|
||||||
# TODO: figure out how to get audio working
|
# TODO: figure out how to get audio working
|
||||||
# TODO: move to runtimeDependencies?
|
# TODO: move to runtimeDependencies?
|
||||||
|
@@ -45,11 +45,34 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.net = "clearnet";
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistDbus = [ "user" ]; # notifications
|
||||||
|
sandbox.whitelistDri = true; #< not strictly necessary, but we need all the perf we can get on moby
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
"Music"
|
||||||
|
"Pictures/albums"
|
||||||
|
"Pictures/cat"
|
||||||
|
"Pictures/from"
|
||||||
|
"Pictures/Photos"
|
||||||
|
"Pictures/Screenshots"
|
||||||
|
"Pictures/servo-macros"
|
||||||
|
"Videos/local"
|
||||||
|
"Videos/servo"
|
||||||
|
"tmp"
|
||||||
|
];
|
||||||
|
|
||||||
persist.byStore.private = [ ".local/share/dino" ];
|
persist.byStore.private = [ ".local/share/dino" ];
|
||||||
|
|
||||||
services.dino = {
|
services.dino = {
|
||||||
description = "dino XMPP client";
|
description = "dino XMPP client";
|
||||||
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
|
after = [ "graphical-session.target" ];
|
||||||
|
# partOf = [ "graphical-session.target" ];
|
||||||
|
wantedBy = lib.mkIf cfg.config.autostart [ "graphical-session.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${cfg.package}/bin/dino";
|
ExecStart = "${cfg.package}/bin/dino";
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
|
@@ -7,14 +7,36 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.element-desktop = {
|
sane.programs.element-desktop = {
|
||||||
package = pkgs.element-desktop.override {
|
packageUnwrapped = pkgs.element-desktop.override {
|
||||||
# use pre-build electron because otherwise it takes 4 hrs to build from source.
|
# use pre-build electron because otherwise it takes 4 hrs to build from source.
|
||||||
electron = pkgs.electron-bin;
|
electron = pkgs.electron-bin;
|
||||||
};
|
};
|
||||||
|
suggestedPrograms = [
|
||||||
|
"gnome-keyring"
|
||||||
|
"xwayland"
|
||||||
|
];
|
||||||
|
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.net = "clearnet";
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistDbus = [ "user" ]; # notifications
|
||||||
|
sandbox.whitelistDri = true;
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
"Music"
|
||||||
|
"Pictures/albums"
|
||||||
|
"Pictures/cat"
|
||||||
|
"Pictures/from"
|
||||||
|
"Pictures/Photos"
|
||||||
|
"Pictures/Screenshots"
|
||||||
|
"Pictures/servo-macros"
|
||||||
|
"Videos/local"
|
||||||
|
"Videos/servo"
|
||||||
|
"tmp"
|
||||||
|
];
|
||||||
|
|
||||||
# creds/session keys, etc
|
# creds/session keys, etc
|
||||||
persist.byStore.private = [ ".config/Element" ];
|
persist.byStore.private = [ ".config/Element" ];
|
||||||
|
|
||||||
suggestedPrograms = [ "gnome-keyring" ];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,19 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.epiphany = {
|
sane.programs.epiphany = {
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "inplace"; # /share/epiphany/default-bookmarks.rdf refers back to /share; dbus files to /libexec
|
||||||
|
sandbox.net = "clearnet";
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
# default sandboxing breaks rendering in weird ways. sites are super zoomed in / not scaled.
|
||||||
|
# enabling DRI/DRM (as below) seems to fix that.
|
||||||
|
sandbox.whitelistDri = true;
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
".config/epiphany" #< else it gets angry at launch
|
||||||
|
"tmp"
|
||||||
|
];
|
||||||
|
|
||||||
# XXX(2023/07/08): running on moby without `WEBKIT_DISABLE_SANDBOX...` fails, with:
|
# XXX(2023/07/08): running on moby without `WEBKIT_DISABLE_SANDBOX...` fails, with:
|
||||||
# - `bwrap: Can't make symlink at /var/run: File exists`
|
# - `bwrap: Can't make symlink at /var/run: File exists`
|
||||||
# this could be due to:
|
# this could be due to:
|
||||||
@@ -22,13 +35,14 @@
|
|||||||
#
|
#
|
||||||
# TODO: consider `WEBKIT_USE_SINGLE_WEB_PROCESS=1` for better perf
|
# TODO: consider `WEBKIT_USE_SINGLE_WEB_PROCESS=1` for better perf
|
||||||
# - this runs all tabs in 1 process. which is fine, if i'm not a heavy multi-tabber
|
# - this runs all tabs in 1 process. which is fine, if i'm not a heavy multi-tabber
|
||||||
package = pkgs.epiphany.overrideAttrs (upstream: {
|
packageUnwrapped = pkgs.epiphany.overrideAttrs (upstream: {
|
||||||
preFixup = ''
|
preFixup = ''
|
||||||
gappsWrapperArgs+=(
|
gappsWrapperArgs+=(
|
||||||
--set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS "1"
|
--set WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS "1"
|
||||||
);
|
);
|
||||||
'' + (upstream.preFixup or "");
|
'' + (upstream.preFixup or "");
|
||||||
});
|
});
|
||||||
|
suggestedPrograms = [ "dconf" ]; #< for persisting e.g. "Set as Default Browser" prompt question
|
||||||
persist.byStore.private = [
|
persist.byStore.private = [
|
||||||
".cache/epiphany"
|
".cache/epiphany"
|
||||||
".local/share/epiphany"
|
".local/share/epiphany"
|
||||||
|
@@ -1,4 +1,10 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
sane.programs.evince.mime.associations."application/pdf" = "org.gnome.Evince.desktop";
|
sane.programs.evince = {
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.autodetectCliPaths = true;
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
|
||||||
|
mime.associations."application/pdf" = "org.gnome.Evince.desktop";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.programs.feedbackd = {
|
sane.programs.feedbackd = {
|
||||||
package = pkgs.rmDbusServices pkgs.feedbackd;
|
packageUnwrapped = pkgs.rmDbusServices pkgs.feedbackd;
|
||||||
|
|
||||||
configOption = with lib; mkOption {
|
configOption = with lib; mkOption {
|
||||||
type = types.submodule {
|
type = types.submodule {
|
||||||
@@ -24,6 +24,11 @@ in
|
|||||||
default = {};
|
default = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.whitelistDbus = [ "user" ];
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
|
||||||
# N.B.: feedbackd will load ~/.config/feedbackd/themes/default.json by default
|
# N.B.: feedbackd will load ~/.config/feedbackd/themes/default.json by default
|
||||||
# - but using that would forbid `parent-theme = "default"`
|
# - but using that would forbid `parent-theme = "default"`
|
||||||
# the default theme ships support for these events:
|
# the default theme ships support for these events:
|
||||||
@@ -92,7 +97,7 @@ in
|
|||||||
|
|
||||||
services.feedbackd = {
|
services.feedbackd = {
|
||||||
description = "feedbackd audio/vibration/led controller";
|
description = "feedbackd audio/vibration/led controller";
|
||||||
wantedBy = [ "default.target" ];
|
wantedBy = [ "default.target" ]; #< should technically be `sound.target`, but that doesn't seem to get auto-started?
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${cfg.package}/libexec/feedbackd";
|
ExecStart = "${cfg.package}/libexec/feedbackd";
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
|
@@ -38,7 +38,7 @@ let
|
|||||||
# defaultSettings = firefoxSettings;
|
# defaultSettings = firefoxSettings;
|
||||||
defaultSettings = librewolfSettings;
|
defaultSettings = librewolfSettings;
|
||||||
|
|
||||||
package = (pkgs.wrapFirefox cfg.browser.browser {
|
packageUnwrapped = (pkgs.wrapFirefox cfg.browser.browser {
|
||||||
# inherit the default librewolf.cfg
|
# inherit the default librewolf.cfg
|
||||||
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg
|
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg
|
||||||
inherit (cfg.browser) extraPrefsFiles libName;
|
inherit (cfg.browser) extraPrefsFiles libName;
|
||||||
@@ -107,12 +107,31 @@ let
|
|||||||
}).overrideAttrs (base: {
|
}).overrideAttrs (base: {
|
||||||
# de-associate `ctrl+shift+c` from activating the devtools.
|
# de-associate `ctrl+shift+c` from activating the devtools.
|
||||||
# based on <https://stackoverflow.com/a/54260938>
|
# based on <https://stackoverflow.com/a/54260938>
|
||||||
|
# TODO: could use `zip -f` to only update the one changed file, instead of rezipping everything.
|
||||||
buildCommand = (base.buildCommand or "") + ''
|
buildCommand = (base.buildCommand or "") + ''
|
||||||
mkdir omni
|
mkdir omni
|
||||||
${pkgs.buildPackages.unzip}/bin/unzip $out/lib/${cfg.browser.libName}/browser/omni.ja -d omni
|
|
||||||
|
echo "omni.ja BEFORE:"
|
||||||
|
ls -l $(readlink $out/lib/${cfg.browser.libName}/browser/omni.ja)
|
||||||
|
|
||||||
|
echo "unzipping omni.ja"
|
||||||
|
# N.B. `zip` exits non-zero even on successful extraction, if the file didn't 100% obey spec
|
||||||
|
${pkgs.buildPackages.unzip}/bin/unzip $out/lib/${cfg.browser.libName}/browser/omni.ja -d omni || true
|
||||||
|
|
||||||
|
echo "removing old omni.ja"
|
||||||
rm $out/lib/${cfg.browser.libName}/browser/omni.ja
|
rm $out/lib/${cfg.browser.libName}/browser/omni.ja
|
||||||
|
|
||||||
|
echo "patching omni.ja"
|
||||||
${pkgs.buildPackages.gnused}/bin/sed -i s'/devtools-commandkey-inspector = C/devtools-commandkey-inspector = VK_F12/' omni/localization/en-US/devtools/startup/key-shortcuts.ftl
|
${pkgs.buildPackages.gnused}/bin/sed -i s'/devtools-commandkey-inspector = C/devtools-commandkey-inspector = VK_F12/' omni/localization/en-US/devtools/startup/key-shortcuts.ftl
|
||||||
|
|
||||||
|
echo "re-zipping omni.ja"
|
||||||
pushd omni; ${pkgs.buildPackages.zip}/bin/zip $out/lib/${cfg.browser.libName}/browser/omni.ja -r ./*; popd
|
pushd omni; ${pkgs.buildPackages.zip}/bin/zip $out/lib/${cfg.browser.libName}/browser/omni.ja -r ./*; popd
|
||||||
|
|
||||||
|
echo "omni.ja AFTER:"
|
||||||
|
ls -l $out/lib/${cfg.browser.libName}/browser/omni.ja
|
||||||
|
|
||||||
|
# runHook postFixup to allow sane.programs sandbox wrappers to wrap the binaries
|
||||||
|
runHook postFixup
|
||||||
'';
|
'';
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -189,6 +208,7 @@ in
|
|||||||
enable = lib.mkDefault config.services.i2p.enable;
|
enable = lib.mkDefault config.services.i2p.enable;
|
||||||
};
|
};
|
||||||
open-in-mpv = {
|
open-in-mpv = {
|
||||||
|
# test: `open-in-mpv 'mpv:///open?url=https://www.youtube.com/watch?v=dQw4w9WgXcQ'`
|
||||||
package = pkgs.firefox-extensions.open-in-mpv;
|
package = pkgs.firefox-extensions.open-in-mpv;
|
||||||
enable = lib.mkDefault config.sane.programs.open-in-mpv.enabled;
|
enable = lib.mkDefault config.sane.programs.open-in-mpv.enabled;
|
||||||
};
|
};
|
||||||
@@ -212,7 +232,38 @@ in
|
|||||||
})
|
})
|
||||||
({
|
({
|
||||||
sane.programs.firefox = {
|
sane.programs.firefox = {
|
||||||
inherit package;
|
inherit packageUnwrapped;
|
||||||
|
sandbox.method = "bwrap"; # landlock works, but requires all of /proc to be linked
|
||||||
|
sandbox.wrapperType = "inplace"; # probably wrappedDerivation could work too.
|
||||||
|
sandbox.net = "all";
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistDbus = [ "user" ]; # mpris
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
"dev" # for developing anything web-related
|
||||||
|
# for uploads/downloads.
|
||||||
|
# it still needs these paths despite using the portal's file-chooser :?
|
||||||
|
"tmp"
|
||||||
|
"Pictures/albums"
|
||||||
|
"Pictures/cat"
|
||||||
|
"Pictures/from"
|
||||||
|
"Pictures/Photos"
|
||||||
|
"Pictures/Screenshots"
|
||||||
|
"Pictures/servo-macros"
|
||||||
|
] ++ lib.optionals cfg.addons.browserpass-extension.enable [
|
||||||
|
# browserpass needs these paths:
|
||||||
|
# - knowledge/secrets/accounts: where the encrypted account secrets live
|
||||||
|
# at least one of:
|
||||||
|
# - .config/sops: for the sops key which can decrypt account secrets
|
||||||
|
# - .ssh: to unlock the sops key, if not unlocked (`sane-secrets-unlock`)
|
||||||
|
# TODO: find a way to not expose ~/.ssh to firefox
|
||||||
|
# - unlock sops at login (or before firefox launch)?
|
||||||
|
# - see if ssh has a more formal type of subkey system?
|
||||||
|
".ssh/id_ed25519"
|
||||||
|
# ".config/sops"
|
||||||
|
"knowledge/secrets/accounts"
|
||||||
|
];
|
||||||
|
fs.".config/sops".dir = lib.mkIf cfg.addons.browserpass-extension.enable {}; #< needs to be created, not *just* added to the sandbox
|
||||||
|
|
||||||
suggestedPrograms = [
|
suggestedPrograms = [
|
||||||
"open-in-mpv"
|
"open-in-mpv"
|
||||||
@@ -267,7 +318,11 @@ in
|
|||||||
// source: <https://kparal.wordpress.com/2019/10/31/disabling-kinetic-scrolling-in-firefox/>
|
// source: <https://kparal.wordpress.com/2019/10/31/disabling-kinetic-scrolling-in-firefox/>
|
||||||
defaultPref("apz.gtk.kinetic_scroll.enabled", false);
|
defaultPref("apz.gtk.kinetic_scroll.enabled", false);
|
||||||
|
|
||||||
// auto-dispatch mpv:// URIs to xdg-open without prompting.
|
// open external URIs/files via xdg-desktop-portal.
|
||||||
|
defaultPref("widget.use-xdg-desktop-portal.mime-handler", 1);
|
||||||
|
defaultPref("widget.use-xdg-desktop-portal.open-uri", 1);
|
||||||
|
|
||||||
|
// auto-open mpv:// URIs without prompting.
|
||||||
// can do this with other protocols too (e.g. matrix?). see about:config for common handlers.
|
// can do this with other protocols too (e.g. matrix?). see about:config for common handlers.
|
||||||
defaultPref("network.protocol-handler.external.mpv", true);
|
defaultPref("network.protocol-handler.external.mpv", true);
|
||||||
// element:// for Element matrix client
|
// element:// for Element matrix client
|
||||||
@@ -275,7 +330,6 @@ in
|
|||||||
// matrix: for Nheko matrix client
|
// matrix: for Nheko matrix client
|
||||||
defaultPref("network.protocol-handler.external.matrix", true);
|
defaultPref("network.protocol-handler.external.matrix", true);
|
||||||
'';
|
'';
|
||||||
fs."${cfg.browser.dotDir}/default".dir = {};
|
|
||||||
# instruct Firefox to put the profile in a predictable directory (so we can do things like persist just it).
|
# instruct Firefox to put the profile in a predictable directory (so we can do things like persist just it).
|
||||||
# XXX: the directory *must* exist, even if empty; Firefox will not create the directory itself.
|
# XXX: the directory *must* exist, even if empty; Firefox will not create the directory itself.
|
||||||
fs."${cfg.browser.dotDir}/profiles.ini".symlink.text = ''
|
fs."${cfg.browser.dotDir}/profiles.ini".symlink.text = ''
|
||||||
@@ -288,24 +342,28 @@ in
|
|||||||
[General]
|
[General]
|
||||||
StartWithLastProfile=1
|
StartWithLastProfile=1
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
})
|
# TODO: env.PASSWORD_STORE_DIR only needs to be present within the browser session.
|
||||||
(mkIf config.sane.programs.firefox.enabled {
|
env.PASSWORD_STORE_DIR = "/home/colin/knowledge/secrets/accounts";
|
||||||
# TODO: move the persistence into the sane.programs API (above)
|
# alternative to PASSWORD_STORE_DIR, but firejail doesn't handle this symlink well
|
||||||
|
# fs.".password-store".symlink.target = lib.mkIf cfg.addons.browserpass-extension.enable "knowledge/secrets/accounts";
|
||||||
|
|
||||||
# flush the cache to disk to avoid it taking up too much tmp.
|
# flush the cache to disk to avoid it taking up too much tmp.
|
||||||
sane.user.persist.byPath."${cfg.browser.cacheDir}".store =
|
persist.byPath."${cfg.browser.cacheDir}".store =
|
||||||
if (cfg.persistData != null) then
|
if (cfg.persistData != null) then
|
||||||
cfg.persistData
|
cfg.persistData
|
||||||
else
|
else
|
||||||
"cryptClearOnBoot"
|
"cryptClearOnBoot"
|
||||||
;
|
;
|
||||||
|
|
||||||
sane.user.persist.byPath."${cfg.browser.dotDir}/default".store =
|
persist.byPath."${cfg.browser.dotDir}/default".store =
|
||||||
if (cfg.persistData != null) then
|
if (cfg.persistData != null) then
|
||||||
cfg.persistData
|
cfg.persistData
|
||||||
else
|
else
|
||||||
"cryptClearOnBoot"
|
"cryptClearOnBoot"
|
||||||
;
|
;
|
||||||
|
};
|
||||||
|
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
8
hosts/common/programs/firejail.nix
Normal file
8
hosts/common/programs/firejail.nix
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{ lib, config, ... }:
|
||||||
|
{
|
||||||
|
sane.programs.firejail = {};
|
||||||
|
|
||||||
|
programs.firejail = lib.mkIf config.sane.programs.firejail.enabled {
|
||||||
|
enable = true; #< install the suid binary
|
||||||
|
};
|
||||||
|
}
|
@@ -62,8 +62,8 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
sane.programs.flare-signal = {
|
sane.programs.flare-signal = {
|
||||||
package = pkgs.flare-signal-nixified;
|
packageUnwrapped = pkgs.flare-signal-nixified;
|
||||||
# package = pkgs.flare-signal;
|
# packageUnwrapped = pkgs.flare-signal;
|
||||||
persist.byStore.private = [
|
persist.byStore.private = [
|
||||||
# everything: conf, state, files, all opaque
|
# everything: conf, state, files, all opaque
|
||||||
".local/share/flare"
|
".local/share/flare"
|
||||||
|
@@ -28,6 +28,17 @@ let
|
|||||||
wantedNerdfonts;
|
wantedNerdfonts;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
sane.programs.fontconfig = {
|
||||||
|
sandbox.method = "bwrap"; # TODO:sandbox: untested
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.autodetectCliPaths = "existingOrParent"; #< this might be overkill; or, how many programs reference fontconfig internally?
|
||||||
|
|
||||||
|
persist.byStore.plaintext = [
|
||||||
|
# < 10 MiB
|
||||||
|
".cache/fontconfig"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
fonts = lib.mkIf config.sane.programs.fontconfig.enabled {
|
fonts = lib.mkIf config.sane.programs.fontconfig.enabled {
|
||||||
fontconfig.enable = true;
|
fontconfig.enable = true;
|
||||||
fontconfig.defaultFonts = {
|
fontconfig.defaultFonts = {
|
||||||
|
@@ -23,9 +23,30 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.programs.fractal = {
|
sane.programs.fractal = {
|
||||||
package = pkgs.fractal-nixified.optimized;
|
packageUnwrapped = pkgs.fractal-nixified.optimized;
|
||||||
# package = pkgs.fractal-latest;
|
# packageUnwrapped = pkgs.fractal-latest;
|
||||||
# package = pkgs.fractal-next;
|
# packageUnwrapped = pkgs.fractal-next;
|
||||||
|
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.net = "clearnet";
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistDbus = [ "user" ]; # notifications
|
||||||
|
sandbox.whitelistDri = true; # otherwise video playback buuuuurns CPU
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
# still needs these paths despite it using the portal's file-chooser :?
|
||||||
|
"Music"
|
||||||
|
"Pictures/albums"
|
||||||
|
"Pictures/cat"
|
||||||
|
"Pictures/from"
|
||||||
|
"Pictures/Photos"
|
||||||
|
"Pictures/Screenshots"
|
||||||
|
"Pictures/servo-macros"
|
||||||
|
"Videos/local"
|
||||||
|
"Videos/servo"
|
||||||
|
"tmp"
|
||||||
|
];
|
||||||
|
|
||||||
configOption = with lib; mkOption {
|
configOption = with lib; mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
@@ -47,8 +68,11 @@ in
|
|||||||
suggestedPrograms = [ "gnome-keyring" ];
|
suggestedPrograms = [ "gnome-keyring" ];
|
||||||
|
|
||||||
services.fractal = {
|
services.fractal = {
|
||||||
description = "auto-start and maintain fractal Matrix connection";
|
description = "fractal Matrix client";
|
||||||
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
|
after = [ "graphical-session.target" ];
|
||||||
|
# partOf = [ "graphical-session.target" ];
|
||||||
|
wantedBy = lib.mkIf cfg.config.autostart [ "graphical-session.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${cfg.package}/bin/fractal";
|
ExecStart = "${cfg.package}/bin/fractal";
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
|
23
hosts/common/programs/frozen-bubble.nix
Normal file
23
hosts/common/programs/frozen-bubble.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# source code: <https://github.com/kthakore/frozen-bubble>
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
sane.programs.frozen-bubble = {
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.net = "clearnet"; # net play
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
|
||||||
|
packageUnwrapped = pkgs.frozen-bubble.overrideAttrs (upstream: {
|
||||||
|
# patch so it stores its dot-files not in root ~.
|
||||||
|
postPatch = (upstream.postPatch or "") + ''
|
||||||
|
substituteInPlace lib/Games/FrozenBubble/Stuff.pm \
|
||||||
|
--replace-fail '$FBHOME = "$ENV{HOME}/.frozen-bubble"' '$FBHOME = "$ENV{HOME}/.local/share/frozen-bubble"'
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
persist.byStore.plaintext = [
|
||||||
|
".local/share/frozen-bubble" # preferences, high scores
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
{
|
{
|
||||||
|
sane.programs.fwupd = {};
|
||||||
services.fwupd = lib.mkIf config.sane.programs.fwupd.enabled {
|
services.fwupd = lib.mkIf config.sane.programs.fwupd.enabled {
|
||||||
# enables the dbus service, which i think the frontend speaks to.
|
# enables the dbus service, which i think the frontend speaks to.
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@@ -8,6 +8,15 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
sane.programs.g4music = {
|
sane.programs.g4music = {
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.whitelistAudio = true;
|
||||||
|
sandbox.whitelistDbus = [ "user" ]; # mpris
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
"Music"
|
||||||
|
];
|
||||||
|
|
||||||
persist.byStore.plaintext = [
|
persist.byStore.plaintext = [
|
||||||
# index?
|
# index?
|
||||||
".cache/com.github.neithern.g4music"
|
".cache/com.github.neithern.g4music"
|
||||||
|
11
hosts/common/programs/gdbus.nix
Normal file
11
hosts/common/programs/gdbus.nix
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
sane.programs.gdbus = {
|
||||||
|
packageUnwrapped = pkgs.linkIntoOwnPackage pkgs.glib "bin/gdbus";
|
||||||
|
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.whitelistDbus = [ "user" ]; #< XXX: maybe future users will also want system access
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@@ -19,6 +19,25 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.net = "clearnet";
|
||||||
|
sandbox.whitelistDbus = [ "user" ]; # notifications
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.extraPaths = [
|
||||||
|
# geary sandboxes *itself* with bwrap, and dbus-proxy which, confusingly, causes it to *require* these paths.
|
||||||
|
# TODO: these could maybe be mounted empty. or maybe there's an env-var to disable geary's dbus-proxy.
|
||||||
|
"/sys/block"
|
||||||
|
"/sys/bus"
|
||||||
|
"/sys/class"
|
||||||
|
"/sys/dev"
|
||||||
|
"/sys/devices"
|
||||||
|
"/sys/fs"
|
||||||
|
];
|
||||||
|
# if sandbox.method == "landlock", then these dirs must exist in the sandbox, even if empty.
|
||||||
|
# fs.".config/geary".dir = {};
|
||||||
|
# fs.".local/share/folks".dir = {};
|
||||||
|
|
||||||
slowToBuild = true; # uses webkitgtk 4.1
|
slowToBuild = true; # uses webkitgtk 4.1
|
||||||
persist.byStore.private = [
|
persist.byStore.private = [
|
||||||
# attachments, and email -- contained in a sqlite db
|
# attachments, and email -- contained in a sqlite db
|
||||||
@@ -68,8 +87,11 @@ in
|
|||||||
secrets.".config/geary/account_02/geary.ini" = ../../../secrets/common/geary_account_02.ini.bin;
|
secrets.".config/geary/account_02/geary.ini" = ../../../secrets/common/geary_account_02.ini.bin;
|
||||||
|
|
||||||
services.geary = {
|
services.geary = {
|
||||||
description = "Geary email client";
|
description = "geary email client";
|
||||||
wantedBy = lib.mkIf cfg.config.autostart [ "default.target" ];
|
after = [ "graphical-session.target" ];
|
||||||
|
# partOf = [ "graphical-session.target" ];
|
||||||
|
wantedBy = lib.mkIf cfg.config.autostart [ "graphical-session.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${cfg.package}/bin/geary";
|
ExecStart = "${cfg.package}/bin/geary";
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
|
@@ -6,7 +6,32 @@ let
|
|||||||
mkCfg = lib.generators.toINI { };
|
mkCfg = lib.generators.toINI { };
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
sane.programs.git.fs.".config/git/config".symlink.text = mkCfg {
|
sane.programs.git = {
|
||||||
|
packageUnwrapped = (pkgs.git.override {
|
||||||
|
# build without gitweb support, as that installs to share/git,
|
||||||
|
# which causes trouble trying to make the sandboxer
|
||||||
|
perlSupport = false;
|
||||||
|
}).overrideAttrs (upstream: {
|
||||||
|
postInstall = upstream.postInstall + ''
|
||||||
|
# git-jump is a symlink from bin/git-jump -> share/contrib/git-jump,
|
||||||
|
# which causes trouble trying to make the sandboxer
|
||||||
|
rm "$out/bin/git-jump"
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.net = "clearnet";
|
||||||
|
sandbox.whitelistPwd = true;
|
||||||
|
sandbox.autodetectCliPaths = true; # necessary for git-upload-pack
|
||||||
|
sandbox.extraHomePaths = [
|
||||||
|
# even with `whitelistPwd`, git has to crawl *up* the path -- which isn't necessarily in the sandbox -- to locate parent .git files
|
||||||
|
"dev"
|
||||||
|
"knowledge"
|
||||||
|
"nixos"
|
||||||
|
"ref"
|
||||||
|
".ssh/id_ed25519" # for ssh-auth'd remotes
|
||||||
|
];
|
||||||
|
fs.".config/git/config".symlink.text = mkCfg {
|
||||||
# top-level options documented:
|
# top-level options documented:
|
||||||
# - <https://git-scm.com/docs/git-config#_variables>
|
# - <https://git-scm.com/docs/git-config#_variables>
|
||||||
|
|
||||||
@@ -40,4 +65,5 @@ in
|
|||||||
|
|
||||||
stash.showPatch = true;
|
stash.showPatch = true;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
{
|
|
||||||
sane.programs.gnome-keyring = {
|
|
||||||
package = pkgs.gnome.gnome-keyring;
|
|
||||||
};
|
|
||||||
# adds gnome-keyring as a xdg-data-portal (xdg.portal)
|
|
||||||
services.gnome.gnome-keyring = lib.mkIf config.sane.programs.gnome-keyring.enabled {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
}
|
|
64
hosts/common/programs/gnome-keyring/default.nix
Normal file
64
hosts/common/programs/gnome-keyring/default.nix
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.sane.programs.gnome-keyring;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
sane.programs.gnome-keyring = {
|
||||||
|
packageUnwrapped = pkgs.rmDbusServices pkgs.gnome.gnome-keyring;
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "wrappedDerivation";
|
||||||
|
sandbox.whitelistDbus = [ "user" ];
|
||||||
|
sandbox.extraRuntimePaths = [
|
||||||
|
"keyring/control"
|
||||||
|
];
|
||||||
|
sandbox.capabilities = [
|
||||||
|
# ipc_lock: used to `mlock` the secrets so they don't get swapped out.
|
||||||
|
# this is optional, and systemd likely doesn't propagate it anyway
|
||||||
|
"ipc_lock"
|
||||||
|
];
|
||||||
|
|
||||||
|
persist.byStore.private = [
|
||||||
|
# N.B.: BE CAREFUL WITH THIS.
|
||||||
|
# gnome-keyring-daemon likes to turn symlinks into dirs. i.e. if it detects that `~/.local/share/keyrings` is a symlink
|
||||||
|
# it WILL try to `unlink` it and recreate it as an empty directory.
|
||||||
|
# the only reason i can get away with a symlink here is because gkd is sandboxed... with ~/.local/share/keyrings as an explicit mountpoint instead of as a symlink.
|
||||||
|
# remove the sandbox, and this breaks.
|
||||||
|
".local/share/keyrings"
|
||||||
|
];
|
||||||
|
|
||||||
|
fs.".local/share/keyrings/default" = {
|
||||||
|
file.text = "Default_keyring.keyring"; #< no trailing newline
|
||||||
|
wantedBy = [ config.sane.fs."${config.sane.persist.stores.private.origin}".unit ];
|
||||||
|
wantedBeforeBy = [ #< don't create this as part of `multi-user.target`
|
||||||
|
"gnome-keyring.service" # TODO: sane.programs should declare this dependency for us
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# N.B.: certain keyring names have special significance
|
||||||
|
# `login.keyring` is forcibly encrypted to the user's password, so that pam gnome-keyring can unlock it on login.
|
||||||
|
# - it does this re-encryption forcibly, any time it wants to write to the keyring.
|
||||||
|
fs.".local/share/keyrings/Default_keyring.keyring" = {
|
||||||
|
file.text = ''
|
||||||
|
[keyring]
|
||||||
|
display-name=Default keyring
|
||||||
|
lock-on-idle=false
|
||||||
|
lock-after=false
|
||||||
|
'';
|
||||||
|
wantedBy = [ config.sane.fs."${config.sane.persist.stores.private.origin}".unit ];
|
||||||
|
wantedBeforeBy = [ #< don't create this as part of `multi-user.target`
|
||||||
|
"gnome-keyring.service"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.gnome-keyring = {
|
||||||
|
description = "gnome-keyring-daemon: secret provider";
|
||||||
|
after = [ "graphical-session.target" ];
|
||||||
|
wantedBy = [ "graphical-session.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/bin/gnome-keyring-daemon --start --foreground --components=secrets";
|
||||||
|
Type = "simple";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "20s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
20
hosts/common/programs/gnome-maps.nix
Normal file
20
hosts/common/programs/gnome-maps.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
sane.programs."gnome.gnome-maps" = {
|
||||||
|
sandbox.method = "bwrap";
|
||||||
|
sandbox.wrapperType = "inplace"; #< dbus files
|
||||||
|
sandbox.whitelistDri = true; # for perf
|
||||||
|
sandbox.whitelistDbus = [
|
||||||
|
"system" # system is required for non-portal location services
|
||||||
|
"user" #< not sure if "user" is necessary?
|
||||||
|
];
|
||||||
|
sandbox.whitelistWayland = true;
|
||||||
|
sandbox.net = "clearnet";
|
||||||
|
sandbox.usePortal = false; # TODO: set up portal-based location services
|
||||||
|
|
||||||
|
persist.byStore.plaintext = [ ".cache/shumate" ];
|
||||||
|
persist.byStore.private = [
|
||||||
|
({ path = ".local/share/maps-places.json"; type = "file"; })
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user