Compare commits
624 Commits
wip-kaitek
...
testing/mu
Author | SHA1 | Date | |
---|---|---|---|
39496985f9 | |||
90b0535c56 | |||
760d69efc0 | |||
f8157961c8 | |||
25df2ebc28 | |||
33110dc1d9 | |||
0fa602f1dd | |||
48ff8e9ca7 | |||
366e28e199 | |||
06dcd8883a | |||
ed03f7f929 | |||
f3bec7bf0a | |||
e6adfe95fa | |||
70d1e14cf8 | |||
4752371b43 | |||
3e7c112548 | |||
a2856a3601 | |||
53d8bdc0ea | |||
94a6ca82f3 | |||
10e9daa085 | |||
e11f903aec | |||
98c2ac21fe | |||
52fe0c7523 | |||
825b3e4067 | |||
674f852393 | |||
fdb77ac588 | |||
05cb85fd9b | |||
8f0a270154 | |||
fae87d3fbc | |||
75ae16aaab | |||
8a1ea79f1f | |||
b25f270f48 | |||
e023f48c52 | |||
3d7a63e4f9 | |||
d296475e64 | |||
f031e489a3 | |||
699204c5f5 | |||
b25528ecd7 | |||
130dd3f895 | |||
fcf60bae35 | |||
5b5187bd03 | |||
43123e78cb | |||
9305d44fde | |||
ac0d7cc1e5 | |||
711778a975 | |||
590c81c5db | |||
e858afea72 | |||
4abac0162f | |||
8fa591229f | |||
a118e17b32 | |||
8afe0c0be5 | |||
aa6153aa56 | |||
69a7e2fae1 | |||
eec4e288f3 | |||
f84e451a9e | |||
dacbfa0493 | |||
fbd8a70102 | |||
17b6dc56bd | |||
f464a80541 | |||
f663243ad4 | |||
94d9348b73 | |||
6a44432d3f | |||
9047aec7e9 | |||
b702031ddf | |||
d5686426bf | |||
85e249913a | |||
d50b8c1315 | |||
336301258f | |||
645ca3764b | |||
22602283c9 | |||
39b963e87b | |||
1a5f1260e2 | |||
c18e8eddcc | |||
874c352987 | |||
0395c5b8ee | |||
f64c44716e | |||
b2b61d2889 | |||
4f05a00e4a | |||
c71346e9b8 | |||
f5576c3667 | |||
b437ddacd9 | |||
68bda8aea7 | |||
d840f947b3 | |||
d4261c45e6 | |||
6e01c59d08 | |||
9052291b31 | |||
a95884d635 | |||
0e9993923d | |||
cc12b87d0e | |||
a5393c3c84 | |||
e1cd1be48d | |||
37b931418d | |||
a3db626a00 | |||
ca239ca3e6 | |||
6c38500e52 | |||
0c4dd28bc8 | |||
47f378e7fc | |||
0648825765 | |||
5f277f8653 | |||
5929286397 | |||
8847147a9d | |||
5682a3e5f1 | |||
6bc9337b3a | |||
5058694c5b | |||
94e03467ab | |||
2ff9cc9d6c | |||
a38d66073d | |||
f486fa9eda | |||
e3faabfad7 | |||
7d4a7df2dd | |||
93177fffb3 | |||
bc482a2621 | |||
381d41e3b4 | |||
469aa50b64 | |||
6dbd107a07 | |||
ffcc1ab49a | |||
f78b06bc88 | |||
b88a20b0f4 | |||
56f484f460 | |||
151fdad014 | |||
16371a37b9 | |||
034f29a897 | |||
ef2d58a5a2 | |||
b109bc5586 | |||
434b299eca | |||
40e7a12ea3 | |||
77579733c6 | |||
861defcc6e | |||
7d62212c24 | |||
120bb23f3c | |||
ccb442c875 | |||
aa5fc023a9 | |||
487dfd3378 | |||
2180361eaf | |||
d6e34c6e98 | |||
10c7a8d779 | |||
3184c6cfb6 | |||
26c8d2d2d4 | |||
13531744d3 | |||
4fd9650ee6 | |||
529e47a5fa | |||
83b27526cb | |||
570619b097 | |||
ae8d708018 | |||
b5cab38348 | |||
bb7e2ee70a | |||
ae220ab2e1 | |||
050c8d15de | |||
af5834c3fc | |||
30ef2b651a | |||
8d185f1bbc | |||
b1a4fb9ccb | |||
8df4415218 | |||
9a6e0b4451 | |||
90fb89390e | |||
fbc747fc22 | |||
ad8da9dfa6 | |||
32036ec45e | |||
90107c024e | |||
d466c0b942 | |||
8a6460e1b0 | |||
370ae917b9 | |||
b223a3a20e | |||
f70a62def5 | |||
7863d12263 | |||
2703bda28c | |||
68982b7f2a | |||
5ed7888710 | |||
eb02b8aa23 | |||
29d3a6f9b2 | |||
e381b1d2dd | |||
592b96e436 | |||
beda2b5238 | |||
f40dfdee0c | |||
7a153903b1 | |||
c5d2549ee4 | |||
d8b2b73463 | |||
0c304e18eb | |||
38f55661c2 | |||
863f6a8c7b | |||
b3a4a95e28 | |||
554bb5a84f | |||
12308f00f1 | |||
34b013f82a | |||
2456317004 | |||
2316b4a3ce | |||
5558da55d5 | |||
09e8510d0e | |||
4b3b71bb84 | |||
bee4fb4ea3 | |||
20872d3733 | |||
7be0a33522 | |||
5f8268cecd | |||
00c22c1ca7 | |||
8e63857794 | |||
cdbfa2d177 | |||
e66692eecd | |||
18ca147b67 | |||
8f231cde33 | |||
f9c8563506 | |||
3669a05db5 | |||
618b7b934e | |||
fe2c0b47bc | |||
3b02fb5f48 | |||
355a982cf0 | |||
8ff7e22ac8 | |||
cb0c122080 | |||
d84600cfcf | |||
dc44d8098e | |||
58c6c1dd7d | |||
933996d34e | |||
2a1932d602 | |||
a6fd6a0a6d | |||
b42b6e7ce2 | |||
e9da458179 | |||
ee3793ad46 | |||
b8ab7c1fa9 | |||
cdbde672d8 | |||
08bd619ef9 | |||
c91948c565 | |||
f3ba1d488d | |||
11a2dbd684 | |||
2fb4bae804 | |||
61ce0e62e9 | |||
315d9b8703 | |||
c5a69a401f | |||
b8e42a0ada | |||
1fa7724b35 | |||
10c6801ccd | |||
8d051d319f | |||
c0a41def22 | |||
f0334db736 | |||
cd89ea884b | |||
13b937fbb7 | |||
877870a522 | |||
956545a795 | |||
cb98ac2a91 | |||
85add7c531 | |||
df379a2a38 | |||
d49ac8c175 | |||
5a4dd3b38d | |||
ed98b1702a | |||
5b5103f660 | |||
91d37f2532 | |||
66d79329d9 | |||
c6485a5e42 | |||
e54af3f571 | |||
c39170be23 | |||
a532825761 | |||
4faa6d5d5f | |||
fe09b08be2 | |||
9e53053526 | |||
56036b13c3 | |||
9ed4a13a6f | |||
1446f5e8ca | |||
118007075f | |||
25c75b10bf | |||
56637bb649 | |||
62d6c4d688 | |||
b05c256809 | |||
a30d6fd51f | |||
da3070479f | |||
287547d46c | |||
2f0bbef76b | |||
2ba1678cd8 | |||
c162225789 | |||
f052e2226d | |||
48774c8940 | |||
7a7e4c9df7 | |||
de2bb05a04 | |||
65a4aa4135 | |||
0e611ba3d4 | |||
c5b132b8c8 | |||
8d2c8d44f3 | |||
7b311eaf2d | |||
eecf51d344 | |||
eaef2f2325 | |||
fc629082e6 | |||
bbb384c70a | |||
e2f6977244 | |||
05ab747650 | |||
913c9e5fdf | |||
f0b772d688 | |||
f328043966 | |||
6758440ce3 | |||
9e4bfc2fce | |||
d3193bc051 | |||
c0b6d46575 | |||
808153f939 | |||
78dfb03c2b | |||
b1ae5b0f9c | |||
7a6bb04e86 | |||
3565e96dc5 | |||
54754de6fa | |||
281be29b90 | |||
465478271a | |||
7003f7407e | |||
890e1b17e2 | |||
34af63fab0 | |||
8e8a326dce | |||
da3c25eff6 | |||
43782ae734 | |||
2204a54456 | |||
e80e37ae29 | |||
505a5f8b47 | |||
216282a345 | |||
6f88302430 | |||
228f8c0a68 | |||
a3111d250f | |||
9976c82946 | |||
42951a1382 | |||
e5ff11d14b | |||
95e7d86cc7 | |||
21c9ce21cc | |||
65bcaa939e | |||
38cd3bdb96 | |||
8059477edd | |||
46a0e949f9 | |||
f86c6390a5 | |||
b60a7ed7d5 | |||
d29e69e18a | |||
042bd9340b | |||
c6fbbbab66 | |||
b1205e964b | |||
7d39a761cf | |||
8a0da17f05 | |||
de8f658dcd | |||
5c2f33a550 | |||
0ec48a9145 | |||
408e817c39 | |||
ba6d0b7e3d | |||
4d7d96f4a4 | |||
1a9dfe22ba | |||
8ae0d77938 | |||
b53d2f945d | |||
f67ca0bd24 | |||
d196ce29ac | |||
f03238daac | |||
f9ab3b7cf1 | |||
40bc4098ad | |||
451816f623 | |||
9dea707eea | |||
0875d5cb52 | |||
0de0749fb4 | |||
ac772e72b8 | |||
d44db610cb | |||
79b3bfc9e7 | |||
6608e2bf6d | |||
19e0bd4780 | |||
18bb89ded0 | |||
4aa3e6cf24 | |||
ee621cd132 | |||
641b32b8d0 | |||
d69db1df37 | |||
6d44c93b5a | |||
32be025ec6 | |||
ce5bfc68f5 | |||
b1773a9b54 | |||
3fe67e744f | |||
ea61d22764 | |||
d92994bcd2 | |||
a5d14a643e | |||
4c1bc06441 | |||
730b4f9d9b | |||
59f8191830 | |||
af4e70c4c5 | |||
5595da2c56 | |||
e52e2c8faa | |||
7563090dd5 | |||
bd44bd4434 | |||
430e594285 | |||
8f88085eb5 | |||
7375a55d4c | |||
878f9fbe49 | |||
5ec0ee4524 | |||
2f3eda1800 | |||
8c9c9ca6c9 | |||
42117f375b | |||
ede10dd1c8 | |||
a380e300bc | |||
3773aebac0 | |||
8a61be18e1 | |||
c07c106a68 | |||
1a159c8340 | |||
6faed74958 | |||
d4d345ca12 | |||
a5b3677adc | |||
97374fdcf4 | |||
1062a610c9 | |||
8f37edb402 | |||
99d55167f6 | |||
e2d7d63ebe | |||
d0b903d50e | |||
9d71041530 | |||
31e404b04f | |||
01a47932f7 | |||
5c6f616c97 | |||
89447d9fe9 | |||
80ac5496be | |||
ce46b3490a | |||
678958f5cf | |||
292aa042f2 | |||
b2bd8d5f89 | |||
06989c613f | |||
c6fbe3574d | |||
f790147fb0 | |||
dca68a019b | |||
fffeb95153 | |||
461398143c | |||
89aabda1a6 | |||
54f6e86e20 | |||
39ba149aab | |||
01ce23130a | |||
dc6472f39f | |||
db6dc8e08c | |||
3b0d10f05e | |||
978017b4e7 | |||
1dd3cab02b | |||
8fd42f49c2 | |||
7ec1879f90 | |||
c851f44a40 | |||
bcfd2cbdb1 | |||
c58df098d2 | |||
dfd1536d19 | |||
3e774241af | |||
a100100e79 | |||
24fa857ee0 | |||
6aa79e9e55 | |||
0fa7cdaa76 | |||
c673e1db92 | |||
4d3caf6fde | |||
2ceb2637d8 | |||
eb8cfc682f | |||
5a10805287 | |||
e73829d2e3 | |||
670063d998 | |||
868325828d | |||
09700adba2 | |||
a85a0c54c2 | |||
b7000c6d48 | |||
f210b22494 | |||
25e3c8e2f6 | |||
ce5431591c | |||
1e33b1acb8 | |||
d404f279de | |||
9b89b6d1af | |||
e0dda018ae | |||
4225315732 | |||
2863dba1e3 | |||
3cee86298e | |||
9123c98595 | |||
1098c66e8d | |||
8db30b5de9 | |||
948d169b33 | |||
313d698b97 | |||
1f3c93623f | |||
634e5a8c71 | |||
92488dd890 | |||
ba69812720 | |||
af8e11242d | |||
0aa0334465 | |||
fd48880a0a | |||
9cce427ea4 | |||
08f62152ff | |||
d0ff605f19 | |||
42ddd90796 | |||
075969540a | |||
d7d9c0b9ba | |||
57886ec3d0 | |||
fd567f8c09 | |||
ae55ddb5a7 | |||
a011abc7ef | |||
75a3e77e77 | |||
d3fa6a31f9 | |||
fdcbaae776 | |||
7027ea099c | |||
26a756f6a4 | |||
8c1149b21b | |||
436ade540f | |||
18864b2c6f | |||
2e8eaab536 | |||
3ecdcdfaaf | |||
c39d0d1667 | |||
37a7f19ecb | |||
84e57ec3d8 | |||
17d2029ba2 | |||
2e7795a938 | |||
d38f17207b | |||
065d139cbc | |||
d1aa9d190e | |||
0780b2f04c | |||
e7f05fa2ec | |||
66534fed25 | |||
bf6ac1b7ae | |||
4ea5b6244f | |||
b244e8e845 | |||
7bf962942e | |||
0edf62a31f | |||
69cad1ca55 | |||
187c2f2406 | |||
ac050ac390 | |||
c6f2eaca45 | |||
a299f111a4 | |||
fe51bb9ab4 | |||
f7da8e2218 | |||
5fe65a1c52 | |||
6801e934af | |||
f0857181c0 | |||
835036fc6a | |||
46dc2fb521 | |||
ea04b86a68 | |||
0acb2e138b | |||
0579faaf89 | |||
d80bd7d162 | |||
19f00b1ae9 | |||
1d7dc6761f | |||
44f63c31da | |||
1dd791874a | |||
aefd31b1f6 | |||
924b91564e | |||
55f82260d5 | |||
ceef35af96 | |||
27ce21cda4 | |||
6c810bc82c | |||
2228be615e | |||
4d0509af5d | |||
c0dad51c6a | |||
b6de07a731 | |||
69e9cbae96 | |||
fa131fe39f | |||
68f066229b | |||
786282d9c4 | |||
e6a88b41b2 | |||
324e9c9b56 | |||
878b5ed1b6 | |||
a91914053d | |||
d0209cb80f | |||
09d071dd53 | |||
a031beee18 | |||
1f7d4b632d | |||
ea1111331c | |||
427d17d218 | |||
ea9c201590 | |||
d9f3209d8c | |||
7bd9a0abc9 | |||
f4533ea7d6 | |||
b50150b52e | |||
10612012fb | |||
faf0cf691c | |||
a9d167cf14 | |||
dfb7c997bb | |||
7535986932 | |||
1a40daeb25 | |||
10937c93d4 | |||
2b8ff8d5ae | |||
39049c8a9c | |||
ab66c9383b | |||
c11f565226 | |||
02b5436573 | |||
fb15f84f1d | |||
60294c60c3 | |||
7da3d48272 | |||
6c1acb5b9a | |||
defcc15b03 | |||
22bcfe8853 | |||
86a15aaa83 | |||
8780f0444f | |||
cd43247d2c | |||
cf4cde548a | |||
2f08252432 | |||
431061b423 | |||
2595c0b4e0 | |||
51bf327290 | |||
bc51244c52 | |||
492506ab01 | |||
ff002c3197 | |||
117b69d39e | |||
46b0f10b9d | |||
e188db9344 | |||
85f16d9732 | |||
bc9450a0fa | |||
364f76b59e | |||
1670732475 | |||
ed50ea4b4b | |||
05559c9c39 | |||
a313f61351 | |||
d2ea4c5ffe | |||
c7252f9c96 | |||
4689d49d9f | |||
3fea4297a8 | |||
fbd99f0069 | |||
a900d9e692 | |||
d33d5a4582 | |||
9c60924513 | |||
d6b2cf8ded | |||
fbad6bda2e | |||
5bae11fcbc | |||
d28738eb0e | |||
14eaa6484e | |||
b10b6c4aab | |||
0a1c959cb5 | |||
1c16348724 | |||
73cd1d9242 | |||
fa7a2186ca | |||
f1950485e9 | |||
3dd360a817 | |||
12e6e638b8 | |||
c994fdc6b6 | |||
acf89605d1 | |||
8ef29966b3 | |||
d737acd2eb | |||
e736f81d0b | |||
7498361162 | |||
6eff3e8f11 | |||
7de4160121 | |||
3643c79786 | |||
e0de6de3da | |||
9f6eb846f9 | |||
a1c1a54e31 | |||
10db7ff8d2 | |||
0e20ca3abe | |||
156334e0ff | |||
0a69b13424 | |||
fe51c278a0 |
33
.sops.yaml
Normal file
33
.sops.yaml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
keys:
|
||||||
|
- &user_desko_colin age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x
|
||||||
|
- &user_lappy_colin age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g
|
||||||
|
- &user_servo_colin age1z8fauff34cdecr6sjkre260luzxcca05kpcwvhx988d306tpcejsp63znu
|
||||||
|
- &user_moby_colin age1zsrsvd7j6l62fjxpfd2qnhqlk8wk4p8r0dtxpe4sdgnh2474095qdu7xj9
|
||||||
|
- &host_desko age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v
|
||||||
|
- &host_lappy age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn
|
||||||
|
- &host_servo age1tzlyex2z6t88tg9h82943e39shxhmqeyr7ywhlwpdjmyqsndv3qq27x0rf
|
||||||
|
- &host_moby age18vq5ktwgeaysucvw9t67drqmg5zd5c5k3le34yqxckkfj7wqdqgsd4ejmt
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: secrets/universal*
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *user_desko_colin
|
||||||
|
- *user_lappy_colin
|
||||||
|
- *user_servo_colin
|
||||||
|
- *user_moby_colin
|
||||||
|
- *host_desko
|
||||||
|
- *host_lappy
|
||||||
|
- *host_servo
|
||||||
|
- *host_moby
|
||||||
|
- path_regex: secrets/servo*
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *user_desko_colin
|
||||||
|
- *user_servo_colin
|
||||||
|
- *host_servo
|
||||||
|
- path_regex: secrets/desko.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *user_desko_colin
|
||||||
|
- *user_lappy_colin
|
||||||
|
- *host_desko
|
23
TODO.md
23
TODO.md
@@ -1,21 +1,16 @@
|
|||||||
# features/tweaks
|
# features/tweaks
|
||||||
- enable sshfs (deskto/lappy)
|
- emoji picker application
|
||||||
- set firefox default search engine
|
- find a Masto/Pleroma app which works on mobile
|
||||||
- iron out video drivers
|
- remove hardcoded uid/gids outside of allocations.nix (used in impermanence code -- replace with username/groupname)
|
||||||
|
|
||||||
# cleanup
|
|
||||||
- remove helpers from outputs section (use `let .. in`)
|
|
||||||
|
|
||||||
|
|
||||||
# speed up cross compiling
|
# speed up cross compiling
|
||||||
https://nixos.wiki/wiki/Cross_Compiling
|
- <https://nixos.wiki/wiki/Cross_Compiling>
|
||||||
https://nixos.wiki/wiki/NixOS_on_ARM
|
- <https://nixos.wiki/wiki/NixOS_on_ARM>
|
||||||
|
```nix
|
||||||
overlays = [{ ... }: {
|
overlays = [{ ... }: {
|
||||||
nixpkgs.crossSystem.system = "aarch64-linux";
|
nixpkgs.crossSystem.system = "aarch64-linux";
|
||||||
}];
|
}];
|
||||||
|
```
|
||||||
# better secrets management? read:
|
- <https://github.com/nix-community/aarch64-build-box>
|
||||||
- decrypted at activation time: https://github.com/Mic92/sops-nix
|
- apply for access to the community arm build box
|
||||||
less promising:
|
|
||||||
- https://christine.website/blog/nixos-encrypted-secrets-2021-01-20
|
|
||||||
- git-crypt (https://github.com/bobbbay/dotfiles.git)
|
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
# Edit this configuration file to define what should be installed on
|
|
||||||
# your system. Help is available in the configuration.nix(5) man page
|
|
||||||
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
|
||||||
|
|
||||||
# USEFUL COMMANDS:
|
|
||||||
# nix show-config
|
|
||||||
# nix eval --raw <expr> => print an expression. e.g. nixpkgs.raspberrypifw prints store path to the package
|
|
||||||
# nix-option ## query options -- including their SET VALUE; similar to search: https://search.nixos.org/options
|
|
||||||
# nixos-rebuild switch --upgrade ## pull changes from the nixos channel (e.g. security updates) and rebuild
|
|
||||||
|
|
||||||
{ config, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
# enable flake support.
|
|
||||||
# the real config root lives in flake.nix
|
|
||||||
nix = {
|
|
||||||
#package = pkgs.nixFlakes;
|
|
||||||
package = pkgs.nixUnstable;
|
|
||||||
extraOptions = ''
|
|
||||||
experimental-features = nix-command flakes
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
141
flake.lock
generated
141
flake.lock
generated
@@ -1,5 +1,20 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1659877975,
|
||||||
|
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -7,11 +22,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1654113405,
|
"lastModified": 1665475263,
|
||||||
"narHash": "sha256-VpK+0QaWG2JRgB00lw77N9TjkE3ec0iMYIX1TzGpxa4=",
|
"narHash": "sha256-T4at7d+KsQNWh5rfjvOtQCaIMWjSDlSgQZKvxb+LcEY=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "ac2287df5a2d6f0a44bbcbd11701dbbf6ec43675",
|
"rev": "17208be516fc36e2ab0ceb064d931e90eb88b2a3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -21,14 +36,29 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"impermanence": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1661933071,
|
||||||
|
"narHash": "sha256-RFgfzldpbCvS+H2qwH+EvNejvqs+NhPVD5j1I7HQQPY=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "impermanence",
|
||||||
|
"rev": "def994adbdfc28974e87b0e4c949e776207d5557",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "impermanence",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"mobile-nixos": {
|
"mobile-nixos": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1654281294,
|
"lastModified": 1665711470,
|
||||||
"narHash": "sha256-hT2/u0jUOD4TFU6YyYt+5Gt+hjIeerLTyZG7ru79aDU=",
|
"narHash": "sha256-9cjKbTkxyWjswVExtIpglpvlR+iDY9/DWmXpZyzk5cY=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "mobile-nixos",
|
"repo": "mobile-nixos",
|
||||||
"rev": "d798b0b34240b18a08c22f5c0ee1f59a3ce43c01",
|
"rev": "e4b6f680b2a4f29f087a7c1299c11499d1a367b6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -39,11 +69,42 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1654275867,
|
"lastModified": 1665732960,
|
||||||
"narHash": "sha256-pt14ZE4jVPGvfB2NynGsl34pgXfOqum5YJNpDK4+b9E=",
|
"narHash": "sha256-WBZ+uSHKFyjvd0w4inbm0cNExYTn8lpYFcHEes8tmec=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "7a20c208aacf4964c19186dcad51f89165dc7ed0",
|
"rev": "4428e23312933a196724da2df7ab78eb5e67a88e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-22_05": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1665279158,
|
||||||
|
"narHash": "sha256-TpbWNzoJ5RaZ302dzvjY2o//WxtOJuYT3CnDj5N69Hs=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "b3783bcfb8ec54e0de26feccfc6cc36b8e202ed5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "release-22.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1665613119,
|
||||||
|
"narHash": "sha256-VTutbv5YKeBGWou6ladtgfx11h6et+Wlkdyh4jPJ3p0=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e06bd4b64bbfda91d74f13cb5eca89485d47528f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -52,27 +113,57 @@
|
|||||||
"type": "indirect"
|
"type": "indirect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nurpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1654367137,
|
|
||||||
"narHash": "sha256-xufB/+qvk/7rh7qrwZbzru1kTu8nsmNWBNQkYbdS84Q=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "NUR",
|
|
||||||
"rev": "86ff2d098bce1d623232f4886027a1d61317b195",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "NUR",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
|
"impermanence": "impermanence",
|
||||||
"mobile-nixos": "mobile-nixos",
|
"mobile-nixos": "mobile-nixos",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nurpkgs": "nurpkgs"
|
"nixpkgs-stable": "nixpkgs-stable",
|
||||||
|
"sops-nix": "sops-nix",
|
||||||
|
"uninsane": "uninsane"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sops-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-22_05": "nixpkgs-22_05"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1665289655,
|
||||||
|
"narHash": "sha256-j1Q9mNBhbzeJykhObiXwEGres9qvP4vH7gxdJ+ihkLI=",
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "sops-nix",
|
||||||
|
"rev": "0ce0449e6404c4ff9d1b7bd657794ae5ca54deb3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "sops-nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uninsane": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1665758541,
|
||||||
|
"narHash": "sha256-ibR8bPwHlDjavri5cNVnoo5FmFk1IfNMmQXxat5biqs=",
|
||||||
|
"ref": "refs/heads/master",
|
||||||
|
"rev": "4ad1801f6cecd678bbeae5dfe5933448dd7b3360",
|
||||||
|
"revCount": 163,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.uninsane.org/colin/uninsane"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.uninsane.org/colin/uninsane"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
180
flake.nix
180
flake.nix
@@ -1,11 +1,11 @@
|
|||||||
# docs:
|
# docs:
|
||||||
# https://nixos.wiki/wiki/Flakes
|
# - <https://nixos.wiki/wiki/Flakes>
|
||||||
# https://serokell.io/blog/practical-nix-flakes
|
# - <https://serokell.io/blog/practical-nix-flakes>
|
||||||
|
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "nixpkgs/nixos-22.05";
|
nixpkgs-stable.url = "nixpkgs/nixos-22.05";
|
||||||
# pkgs-telegram.url = "nixpkgs/33775ec9a2173a08e46edf9f46c9febadbf743e8";# 2022/04/18; telegram 3.7.3. fails: nix log /nix/store/y5kv47hnv55qknb6cnmpcyraicay79fx-telegram-desktop-3.7.3.drv: g++: fatal error: cannot execute '/nix/store/njk5sbd21305bhr7gwibxbbvgbx5lxvn-gcc-9.3.0/libexec/gcc/aarch64-unknown-linux-gnu/9.3.0/cc1plus': execv: No such file or directory
|
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||||
mobile-nixos = {
|
mobile-nixos = {
|
||||||
url = "github:nixos/mobile-nixos";
|
url = "github:nixos/mobile-nixos";
|
||||||
flake = false;
|
flake = false;
|
||||||
@@ -14,100 +14,108 @@
|
|||||||
url = "github:nix-community/home-manager/release-22.05";
|
url = "github:nix-community/home-manager/release-22.05";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
nurpkgs.url = "github:nix-community/NUR";
|
sops-nix = {
|
||||||
|
url = "github:Mic92/sops-nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
impermanence.url = "github:nix-community/impermanence";
|
||||||
|
uninsane = {
|
||||||
|
url = "git+https://git.uninsane.org/colin/uninsane";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, mobile-nixos, home-manager, nurpkgs }: {
|
outputs = { self, nixpkgs, nixpkgs-stable, mobile-nixos, home-manager, sops-nix, impermanence, uninsane }:
|
||||||
machines.uninsane = self.decl-bootable-machine { name = "uninsane"; system = "aarch64-linux"; };
|
let
|
||||||
machines.desko = self.decl-bootable-machine { name = "desko"; system = "x86_64-linux"; };
|
patchedPkgs = system: nixpkgs.legacyPackages.${system}.applyPatches {
|
||||||
machines.lappy = self.decl-bootable-machine { name = "lappy"; system = "x86_64-linux"; };
|
|
||||||
|
|
||||||
machines.moby =
|
|
||||||
let machine = self.decl-machine {
|
|
||||||
name = "moby";
|
|
||||||
system = "aarch64-linux";
|
|
||||||
extraModules = [
|
|
||||||
(import "${mobile-nixos}/lib/configuration.nix" {
|
|
||||||
device = "pine64-pinephone";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
nixosConfiguration = machine;
|
|
||||||
img = machine.config.mobile.outputs.u-boot.disk-image;
|
|
||||||
};
|
|
||||||
|
|
||||||
nixosConfigurations = builtins.mapAttrs (name: value: value.nixosConfiguration) self.machines;
|
|
||||||
imgs = builtins.mapAttrs (name: value: value.img) self.machines;
|
|
||||||
|
|
||||||
decl-machine = { name, system, extraModules ? [], basePkgs ? nixpkgs }: let
|
|
||||||
patchedPkgs = basePkgs.legacyPackages.${system}.applyPatches {
|
|
||||||
name = "nixpkgs-patched-uninsane";
|
name = "nixpkgs-patched-uninsane";
|
||||||
src = basePkgs;
|
src = nixpkgs;
|
||||||
patches = [
|
patches = import ./nixpatches/list.nix nixpkgs.legacyPackages.${system}.fetchpatch;
|
||||||
# for mobile: allow phoc to scale to non-integer values
|
|
||||||
./nixpatches/01-phosh-float-scale.patch
|
|
||||||
# for raspberry pi: allow building u-boot for rpi 4{,00}
|
|
||||||
./nixpatches/02-rpi4-uboot.patch
|
|
||||||
./nixpatches/03-whalebird-4.6.0.patch
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
nixosSystem = import (patchedPkgs + "/nixos/lib/eval-config.nix");
|
# return something which behaves like `pkgs`, for the provided system
|
||||||
|
# `local` = architecture of builder. `target` = architecture of the system beying deployed to
|
||||||
|
nixpkgsFor = local: target: import (patchedPkgs target) { crossSystem = target; localSystem = local; };
|
||||||
|
# evaluate ONLY our overlay, for the provided system
|
||||||
|
customPackagesFor = local: target: import ./pkgs/overlay.nix (nixpkgsFor local target) (nixpkgsFor local target);
|
||||||
|
decl-machine = { name, local, target }:
|
||||||
|
let
|
||||||
|
nixosSystem = import ((patchedPkgs target) + "/nixos/lib/eval-config.nix");
|
||||||
in (nixosSystem {
|
in (nixosSystem {
|
||||||
inherit system;
|
# by default the local system is the same as the target, employing emulation when they differ
|
||||||
specialArgs = { inherit home-manager; inherit nurpkgs; secrets = import ./secrets/default.nix; };
|
system = target;
|
||||||
|
specialArgs = { inherit mobile-nixos home-manager impermanence; };
|
||||||
modules = [
|
modules = [
|
||||||
./configuration.nix
|
./modules
|
||||||
./machines/${name}
|
./machines/${name}
|
||||||
(import ./helpers/set-hostname.nix name)
|
(import ./helpers/set-hostname.nix name)
|
||||||
(self.overlaysModule system)
|
home-manager.nixosModule
|
||||||
] ++ extraModules;
|
impermanence.nixosModule
|
||||||
});
|
sops-nix.nixosModules.sops
|
||||||
|
{
|
||||||
# this produces a EFI-bootable .img file (GPT with / and /boot).
|
|
||||||
# after building this, steps are:
|
|
||||||
# run `btrfs-convert --uuid copy <device>`
|
|
||||||
# boot, checkout this flake into /etc/nixos AND UPDATE THE UUIDS IT REFERENCES.
|
|
||||||
# then `nixos-rebuild ...`
|
|
||||||
decl-img = { name, system, extraModules ? [] }: (
|
|
||||||
(self.decl-machine { inherit name; inherit system; extraModules = extraModules ++ [./image.nix]; })
|
|
||||||
.config.system.build.raw
|
|
||||||
);
|
|
||||||
|
|
||||||
decl-bootable-machine = { name, system }: {
|
|
||||||
nixosConfiguration = self.decl-machine { inherit name; inherit system; };
|
|
||||||
img = self.decl-img { inherit name; inherit system; };
|
|
||||||
};
|
|
||||||
|
|
||||||
overlaysModule = system: { config, pkgs, ...}: {
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
#mobile-nixos.overlay
|
(import "${mobile-nixos}/overlay/overlay.nix")
|
||||||
nurpkgs.overlay
|
uninsane.overlay
|
||||||
(next: prev: {
|
(import ./pkgs/overlay.nix)
|
||||||
#### customized packages
|
(next: prev: rec {
|
||||||
# nixos-unstable pleroma is too far out-of-date for our db
|
# non-emulated packages build *from* local *for* target.
|
||||||
pleroma = prev.callPackage ./pkgs/pleroma { };
|
# for large packages like the linux kernel which are expensive to build under emulation,
|
||||||
# jackett doesn't allow customization of the bind address: this will probably always be here.
|
# the config can explicitly pull such packages from `pkgs.cross` to do more efficient cross-compilation.
|
||||||
jackett = next.callPackage ./pkgs/jackett { pkgs = prev; };
|
cross = (nixpkgsFor local target) // (customPackagesFor local target);
|
||||||
# fix abrupt HDD poweroffs as during reboot. patching systemd requires rebuilding nearly every package.
|
stable = import nixpkgs-stable { system = target; };
|
||||||
# systemd = import ./pkgs/systemd { pkgs = prev; };
|
# pinned packages:
|
||||||
|
electrum = stable.electrum; # 2022-10-10: build break
|
||||||
# patch rpi uboot with something that fixes USB HDD boot
|
sequoia = stable.sequoia; # 2022-10-13: build break
|
||||||
ubootRaspberryPi4_64bit = next.callPackage ./pkgs/ubootRaspberryPi4_64bit { pkgs = prev; };
|
|
||||||
|
|
||||||
#### TEMPORARY NIXOS-UNSTABLE PACKAGES
|
|
||||||
|
|
||||||
# stable telegram doesn't build, so explicitly use the stable one.
|
|
||||||
# TODO: apply this specifically to the moby build?
|
|
||||||
# tdesktop = pkgs-telegram.legacyPackages.${system}.tdesktop;
|
|
||||||
tdesktop = nixpkgs.legacyPackages.${system}.tdesktop;
|
|
||||||
|
|
||||||
#### TEMPORARY: PACKAGES WAITING TO BE UPSTREAMED
|
|
||||||
whalebird = prev.callPackage ./pkgs/whalebird { };
|
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
decl-bootable-machine = { name, local, target }: rec {
|
||||||
|
nixosConfiguration = decl-machine { inherit name local target; };
|
||||||
|
# this produces a EFI-bootable .img file (GPT with a /boot partition and a system (/ or /nix) partition).
|
||||||
|
# after building this:
|
||||||
|
# - flash it to a bootable medium (SD card, flash drive, HDD)
|
||||||
|
# - resize the root partition (use cfdisk)
|
||||||
|
# - mount the part
|
||||||
|
# - chown root:nixbld <part>/nix/store
|
||||||
|
# - chown root:root -R <part>/nix/store/*
|
||||||
|
# - chown root:root -R <part>/persist # if using impermanence
|
||||||
|
# - populate any important things (persist/, home/colin/.ssh, etc)
|
||||||
|
# - boot
|
||||||
|
# - if fs wasn't resized automatically, then `sudo btrfs filesystem resize max /`
|
||||||
|
# - checkout this flake into /etc/nixos AND UPDATE THE FS UUIDS.
|
||||||
|
# - `nixos-rebuild --flake './#<machine>' switch`
|
||||||
|
img = nixosConfiguration.config.system.build.img;
|
||||||
|
};
|
||||||
|
machines.servo = decl-bootable-machine { name = "servo"; local = "aarch64-linux"; target = "aarch64-linux"; };
|
||||||
|
machines.desko = decl-bootable-machine { name = "desko"; local = "x86_64-linux"; target = "x86_64-linux"; };
|
||||||
|
machines.lappy = decl-bootable-machine { name = "lappy"; local = "x86_64-linux"; target = "x86_64-linux"; };
|
||||||
|
machines.moby = decl-bootable-machine { name = "moby"; local = "aarch64-linux"; target = "aarch64-linux"; };
|
||||||
|
# special cross-compiled variant, to speed up deploys from an x86 box to the arm target
|
||||||
|
# note that these *do* produce different store paths, because the closure for the tools used to cross compile
|
||||||
|
# v.s. emulate differ.
|
||||||
|
# so deploying moby-cross and then moby incurs some rebuilding.
|
||||||
|
machines.moby-cross = decl-bootable-machine { name = "moby"; local = "x86_64-linux"; target = "aarch64-linux"; };
|
||||||
|
machines.rescue = decl-bootable-machine { name = "rescue"; local = "x86_64-linux"; target = "x86_64-linux"; };
|
||||||
|
in {
|
||||||
|
nixosConfigurations = builtins.mapAttrs (name: value: value.nixosConfiguration) machines;
|
||||||
|
imgs = builtins.mapAttrs (name: value: value.img) machines;
|
||||||
|
packages = let
|
||||||
|
custom-x86_64 = customPackagesFor "x86_64-linux" "x86_64-linux";
|
||||||
|
custom-aarch64 = customPackagesFor "aarch64-linux" "aarch64-linux";
|
||||||
|
nixpkgs-x86_64 = nixpkgsFor "x86_64-linux" "x86_64-linux";
|
||||||
|
nixpkgs-aarch64 = nixpkgsFor "aarch64-linux" "aarch64-linux";
|
||||||
|
in {
|
||||||
|
x86_64-linux = custom-x86_64 // {
|
||||||
|
nixpkgs = nixpkgs-x86_64;
|
||||||
|
uninsane = uninsane.packages.x86_64-linux;
|
||||||
|
};
|
||||||
|
aarch64-linux = custom-aarch64 // {
|
||||||
|
nixpkgs = nixpkgs-aarch64;
|
||||||
|
uninsane = uninsane.packages.aarch64-linux;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
# start gnome/gdm on boot
|
|
||||||
services.xserver.enable = true;
|
|
||||||
services.xserver.desktopManager.gnome.enable = true;
|
|
||||||
services.xserver.displayManager.gdm.enable = true;
|
|
||||||
|
|
||||||
# gnome does networking stuff with networkmanager
|
|
||||||
networking.useDHCP = false;
|
|
||||||
networking.networkmanager.enable = true;
|
|
||||||
networking.wireless.enable = lib.mkForce false;
|
|
||||||
}
|
|
@@ -1,16 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
environment.pathsToLink = [ "/libexec" ]; # patch for i3blocks to work
|
|
||||||
services.xserver.enable = true;
|
|
||||||
services.xserver.displayManager.defaultSession = "none+i3";
|
|
||||||
services.xserver.windowManager.i3 = {
|
|
||||||
enable = true;
|
|
||||||
extraPackages = with pkgs; [
|
|
||||||
dmenu
|
|
||||||
i3status
|
|
||||||
i3lock
|
|
||||||
i3blocks
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@@ -1,21 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
{
|
|
||||||
# docs: https://github.com/NixOS/nixpkgs/blob/nixos-22.05/nixos/modules/services/x11/desktop-managers/phosh.nix
|
|
||||||
services.xserver.desktopManager.phosh = {
|
|
||||||
enable = true;
|
|
||||||
user = "colin";
|
|
||||||
group = "users";
|
|
||||||
phocConfig = {
|
|
||||||
xwayland = "true";
|
|
||||||
# find default outputs by catting /etc/phosh/phoc.ini
|
|
||||||
outputs.DSI-1 = {
|
|
||||||
scale = 1.5;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.variables = {
|
|
||||||
# Qt apps won't always start unless this env var is set
|
|
||||||
QT_QPA_PLATFORM = "wayland";
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
# start plasma-mobile on boot
|
|
||||||
services.xserver.enable = true;
|
|
||||||
services.xserver.desktopManager.plasma5.mobile.enable = true;
|
|
||||||
services.xserver.desktopManager.plasma5.mobile.installRecommendedSoftware = false; # not all plasma5-mobile packages build for aarch64
|
|
||||||
services.xserver.displayManager.sddm.enable = true;
|
|
||||||
|
|
||||||
# Plasma does networking stuff with networkmanager, but nix configures the defaults itself
|
|
||||||
# networking.useDHCP = false;
|
|
||||||
# networking.networkmanager.enable = true;
|
|
||||||
# networking.wireless.enable = lib.mkForce false;
|
|
||||||
}
|
|
@@ -1,31 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
|
|
||||||
# docs: https://nixos.wiki/wiki/Sway
|
|
||||||
{
|
|
||||||
programs.sway = {
|
|
||||||
# we configure sway with home-manager, but this enable gets us e.g. opengl and fonts
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO: should be able to use SDDM to get interactive login
|
|
||||||
services.greetd = {
|
|
||||||
enable = true;
|
|
||||||
settings = rec {
|
|
||||||
initial_session = {
|
|
||||||
command = "${pkgs.sway}/bin/sway";
|
|
||||||
user = "colin";
|
|
||||||
};
|
|
||||||
default_session = initial_session;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# unlike other DEs, sway configures no audio stack
|
|
||||||
# administer with pw-cli, pw-mon, pw-top commands
|
|
||||||
services.pipewire = {
|
|
||||||
enable = true;
|
|
||||||
alsa.enable = true;
|
|
||||||
alsa.support32Bit = true; # ??
|
|
||||||
pulse.enable = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@@ -1,65 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
boot.initrd.availableKernelModules = [
|
|
||||||
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
|
|
||||||
"usb_storage" # rpi needed this to boot from usb storage, i think.
|
|
||||||
# "usbhid" "hid-generic" # hopefully these will fix USB HID auto-sleep ?
|
|
||||||
];
|
|
||||||
boot.initrd.kernelModules = [ ];
|
|
||||||
boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ];
|
|
||||||
# find more of these with sensors-detect
|
|
||||||
boot.kernelModules = [
|
|
||||||
"coretemp"
|
|
||||||
"kvm-intel"
|
|
||||||
"kvm-amd" # desktop
|
|
||||||
"amdgpu" # desktop
|
|
||||||
];
|
|
||||||
boot.extraModulePackages = [ ];
|
|
||||||
boot.kernelParams = [ "boot.shell_on_fail" ];
|
|
||||||
boot.consoleLogLevel = 7;
|
|
||||||
|
|
||||||
# Use the systemd-boot EFI boot loader.
|
|
||||||
boot.loader.systemd-boot.enable = true;
|
|
||||||
boot.loader.systemd-boot.configurationLimit = 40; # keep this many generations
|
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
|
||||||
|
|
||||||
# enable cross compilation
|
|
||||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
|
||||||
# nixpkgs.crossSystem.system = "aarch64-linux";
|
|
||||||
|
|
||||||
powerManagement.cpuFreqGovernor = "powersave";
|
|
||||||
hardware.enableRedistributableFirmware = true;
|
|
||||||
hardware.cpu.amd.updateMicrocode = true; # desktop
|
|
||||||
hardware.cpu.intel.updateMicrocode = true; # laptop
|
|
||||||
services.fwupd.enable = true;
|
|
||||||
# powertop will default to putting USB devices -- including HID -- to sleep after TWO SECONDS
|
|
||||||
powerManagement.powertop.enable = false;
|
|
||||||
|
|
||||||
hardware.opengl.extraPackages = [
|
|
||||||
# laptop
|
|
||||||
pkgs.intel-compute-runtime
|
|
||||||
pkgs.intel-media-driver # new
|
|
||||||
pkgs.libvdpau-va-gl # new
|
|
||||||
pkgs.vaapiIntel
|
|
||||||
# desktop
|
|
||||||
pkgs.rocm-opencl-icd
|
|
||||||
pkgs.rocm-opencl-runtime
|
|
||||||
];
|
|
||||||
hardware.opengl.driSupport = true;
|
|
||||||
# For 32 bit applications
|
|
||||||
hardware.opengl.driSupport32Bit = true;
|
|
||||||
|
|
||||||
# TODO colin: does this *do* anything?
|
|
||||||
swapDevices = [ ];
|
|
||||||
|
|
||||||
# services.snapper.configs = {
|
|
||||||
# root = {
|
|
||||||
# subvolume = "/";
|
|
||||||
# extraConfig = {
|
|
||||||
# ALLOW_USERS = "colin";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# services.snapper.snapshotInterval = "daily";
|
|
||||||
}
|
|
@@ -1,531 +0,0 @@
|
|||||||
# docs:
|
|
||||||
# https://rycee.gitlab.io/home-manager/
|
|
||||||
# https://rycee.gitlab.io/home-manager/options.html
|
|
||||||
# man home-configuration.nix
|
|
||||||
#
|
|
||||||
|
|
||||||
# system is e.g. x86_64-linux
|
|
||||||
# gui is "gnome", or null
|
|
||||||
{ lib, pkgs, system, gui, extraPackages ? [] }: {
|
|
||||||
home.stateVersion = "21.11";
|
|
||||||
home.username = "colin";
|
|
||||||
home.homeDirectory = "/home/colin";
|
|
||||||
programs.home-manager.enable = true; # this lets home-manager manage dot-files in user dirs, i think
|
|
||||||
|
|
||||||
# XDG defines things like ~/Desktop, ~/Downloads, etc.
|
|
||||||
# these clutter the home, so i mostly don't use them.
|
|
||||||
xdg.userDirs = {
|
|
||||||
enable = true;
|
|
||||||
createDirectories = false; # on headless systems, most xdg dirs are noise
|
|
||||||
desktop = "$HOME/.xdg/Desktop";
|
|
||||||
documents = "$HOME/src";
|
|
||||||
download = "$HOME/tmp";
|
|
||||||
music = "$HOME/Music";
|
|
||||||
pictures = "$HOME/Pictures";
|
|
||||||
publicShare = "$HOME/.xdg/Public";
|
|
||||||
templates = "$HOME/.xdg/Templates";
|
|
||||||
videos = "$HOME/Videos";
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.zsh = {
|
|
||||||
enable = true;
|
|
||||||
enableSyntaxHighlighting = true;
|
|
||||||
enableVteIntegration = true;
|
|
||||||
dotDir = ".config/zsh";
|
|
||||||
|
|
||||||
initExtraBeforeCompInit = ''
|
|
||||||
# p10k instant prompt
|
|
||||||
# run p10k configure to configure, but it can't write out its file :-(
|
|
||||||
POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true
|
|
||||||
'';
|
|
||||||
|
|
||||||
# prezto = oh-my-zsh fork; controls prompt, auto-completion, etc.
|
|
||||||
# see: https://github.com/sorin-ionescu/prezto
|
|
||||||
prezto = {
|
|
||||||
enable = true;
|
|
||||||
pmodules = [
|
|
||||||
"environment"
|
|
||||||
"terminal"
|
|
||||||
"editor"
|
|
||||||
"history"
|
|
||||||
"directory"
|
|
||||||
"spectrum"
|
|
||||||
"utility"
|
|
||||||
"completion"
|
|
||||||
"prompt"
|
|
||||||
"git"
|
|
||||||
];
|
|
||||||
prompt = {
|
|
||||||
theme = "powerlevel10k";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
programs.kitty.enable = true;
|
|
||||||
programs.git = {
|
|
||||||
enable = true;
|
|
||||||
userName = "colin";
|
|
||||||
userEmail = "colin@uninsane.org";
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.vim = {
|
|
||||||
enable = true;
|
|
||||||
extraConfig = ''
|
|
||||||
" wtf vim project: NOBODY LIKES MOUSE FOR VISUAL MODE
|
|
||||||
set mouse-=a
|
|
||||||
" copy/paste to system clipboard
|
|
||||||
set clipboard=unnamedplus
|
|
||||||
" <tab> completion menu settings
|
|
||||||
set wildmenu
|
|
||||||
set wildmode=longest,list,full
|
|
||||||
" highlight all matching searches (using / and ?)
|
|
||||||
set hlsearch
|
|
||||||
" allow backspace to delete empty lines in insert mode
|
|
||||||
set backspace=indent,eol,start
|
|
||||||
" built-in syntax highlighting
|
|
||||||
syntax enable
|
|
||||||
" show line/col number in bottom right
|
|
||||||
set ruler
|
|
||||||
" highlight trailing space & related syntax errors (does this work?)
|
|
||||||
let c_space_errors=1
|
|
||||||
let python_space_errors=1
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# obtain these by running `dconf dump /` after manually customizing gnome
|
|
||||||
# TODO: fix "is not of type `GVariant value'"
|
|
||||||
# dconf.settings = lib.mkIf (gui == "gnome") {
|
|
||||||
# gnome = {
|
|
||||||
# # control alt-tab behavior
|
|
||||||
# "org/gnome/desktop/wm/keybindings" = {
|
|
||||||
# switch-applications = [ "<Super>Tab" ];
|
|
||||||
# switch-applications-backward=[];
|
|
||||||
# switch-windows=["<Alt>Tab"];
|
|
||||||
# switch-windows-backward=["<Super><Alt>Tab"];
|
|
||||||
# };
|
|
||||||
# # idle power savings
|
|
||||||
# "org/gnome/settings-deamon/plugins/power" = {
|
|
||||||
# idle-brigthness = 50;
|
|
||||||
# sleep-inactive-ac-type = "nothing";
|
|
||||||
# sleep-inactive-battery-timeout = 5400; # seconds
|
|
||||||
# };
|
|
||||||
# "org/gnome/shell" = {
|
|
||||||
# favorite-apps = [
|
|
||||||
# "org.gnome.Nautilus.desktop"
|
|
||||||
# "firefox.desktop"
|
|
||||||
# "kitty.desktop"
|
|
||||||
# # "org.gnome.Terminal.desktop"
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
# "org/gnome/desktop/session" = {
|
|
||||||
# # how long until considering a session idle (triggers e.g. screen blanking)
|
|
||||||
# idle-delay = 900;
|
|
||||||
# };
|
|
||||||
# "org/gnome/desktop/interface" = {
|
|
||||||
# text-scaling-factor = 1.25;
|
|
||||||
# };
|
|
||||||
# "org/gnome/desktop/media-handling" = {
|
|
||||||
# # don't auto-mount inserted media
|
|
||||||
# automount = false;
|
|
||||||
# automount-open = false;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
# home.pointerCursor = {
|
|
||||||
# package = pkgs.vanilla-dmz;
|
|
||||||
# name = "Vanilla-DMZ";
|
|
||||||
# };
|
|
||||||
|
|
||||||
# taken from https://github.com/srid/nix-config/blob/705a70c094da53aa50cf560179b973529617eb31/nix/home/i3.nix
|
|
||||||
xsession.windowManager.i3 = lib.mkIf (gui == "i3") (
|
|
||||||
let
|
|
||||||
mod = "Mod4";
|
|
||||||
in {
|
|
||||||
enable = true;
|
|
||||||
config = {
|
|
||||||
modifier = mod;
|
|
||||||
|
|
||||||
fonts = {
|
|
||||||
names = [ "DejaVu Sans Mono" ];
|
|
||||||
style = "Bold Semi-Condensed";
|
|
||||||
size = 11.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
# terminal = "kitty";
|
|
||||||
# terminal = "${pkgs.kitty}/bin/kitty";
|
|
||||||
|
|
||||||
keybindings = {
|
|
||||||
"${mod}+Return" = "exec ${pkgs.kitty}/bin/kitty";
|
|
||||||
"${mod}+p" = "exec ${pkgs.dmenu}/bin/dmenu_run";
|
|
||||||
"${mod}+x" = "exec sh -c '${pkgs.maim}/bin/maim -s | xclip -selection clipboard -t image/png'";
|
|
||||||
"${mod}+Shift+x" = "exec sh -c '${pkgs.i3lock}/bin/i3lock -c 222222 & sleep 5 && xset dpms force of'";
|
|
||||||
|
|
||||||
# Focus
|
|
||||||
"${mod}+j" = "focus left";
|
|
||||||
"${mod}+k" = "focus down";
|
|
||||||
"${mod}+l" = "focus up";
|
|
||||||
"${mod}+semicolon" = "focus right";
|
|
||||||
|
|
||||||
# Move
|
|
||||||
"${mod}+Shift+j" = "move left";
|
|
||||||
"${mod}+Shift+k" = "move down";
|
|
||||||
"${mod}+Shift+l" = "move up";
|
|
||||||
"${mod}+Shift+semicolon" = "move right";
|
|
||||||
|
|
||||||
# multi monitor setup
|
|
||||||
# "${mod}+m" = "move workspace to output DP-2";
|
|
||||||
# "${mod}+Shift+m" = "move workspace to output DP-5";
|
|
||||||
};
|
|
||||||
|
|
||||||
# bars = [
|
|
||||||
# {
|
|
||||||
# position = "bottom";
|
|
||||||
# statusCommand = "${pkgs.i3status-rust}/bin/i3status-rs ${./i3status-rust.toml}";
|
|
||||||
# }
|
|
||||||
# ];
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
wayland.windowManager.sway = lib.mkIf (gui == "sway") {
|
|
||||||
enable = true;
|
|
||||||
wrapperFeatures.gtk = true;
|
|
||||||
config = rec {
|
|
||||||
terminal = "${pkgs.kitty}/bin/kitty";
|
|
||||||
window.border = 3; # pixel boundary between windows
|
|
||||||
|
|
||||||
# defaults; required for keybindings decl.
|
|
||||||
modifier = "Mod1";
|
|
||||||
# list of launchers: https://www.reddit.com/r/swaywm/comments/v39hxa/your_favorite_launcher/
|
|
||||||
# menu = "${pkgs.dmenu}/bin/dmenu_path";
|
|
||||||
menu = "${pkgs.fuzzel}/bin/fuzzel";
|
|
||||||
# menu = "${pkgs.albert}/bin/albert";
|
|
||||||
left = "h";
|
|
||||||
down = "j";
|
|
||||||
up = "k";
|
|
||||||
right = "l";
|
|
||||||
keybindings = {
|
|
||||||
"${modifier}+Return" = "exec ${terminal}";
|
|
||||||
"${modifier}+Shift+q" = "kill";
|
|
||||||
"${modifier}+d" = "exec ${menu}";
|
|
||||||
|
|
||||||
"${modifier}+${left}" = "focus left";
|
|
||||||
"${modifier}+${down}" = "focus down";
|
|
||||||
"${modifier}+${up}" = "focus up";
|
|
||||||
"${modifier}+${right}" = "focus right";
|
|
||||||
|
|
||||||
"${modifier}+Left" = "focus left";
|
|
||||||
"${modifier}+Down" = "focus down";
|
|
||||||
"${modifier}+Up" = "focus up";
|
|
||||||
"${modifier}+Right" = "focus right";
|
|
||||||
|
|
||||||
"${modifier}+Shift+${left}" = "move left";
|
|
||||||
"${modifier}+Shift+${down}" = "move down";
|
|
||||||
"${modifier}+Shift+${up}" = "move up";
|
|
||||||
"${modifier}+Shift+${right}" = "move right";
|
|
||||||
|
|
||||||
"${modifier}+Shift+Left" = "move left";
|
|
||||||
"${modifier}+Shift+Down" = "move down";
|
|
||||||
"${modifier}+Shift+Up" = "move up";
|
|
||||||
"${modifier}+Shift+Right" = "move right";
|
|
||||||
|
|
||||||
"${modifier}+b" = "splith";
|
|
||||||
"${modifier}+v" = "splitv";
|
|
||||||
"${modifier}+f" = "fullscreen toggle";
|
|
||||||
"${modifier}+a" = "focus parent";
|
|
||||||
|
|
||||||
"${modifier}+s" = "layout stacking";
|
|
||||||
"${modifier}+w" = "layout tabbed";
|
|
||||||
"${modifier}+e" = "layout toggle split";
|
|
||||||
|
|
||||||
"${modifier}+Shift+space" = "floating toggle";
|
|
||||||
"${modifier}+space" = "focus mode_toggle";
|
|
||||||
|
|
||||||
"${modifier}+1" = "workspace number 1";
|
|
||||||
"${modifier}+2" = "workspace number 2";
|
|
||||||
"${modifier}+3" = "workspace number 3";
|
|
||||||
"${modifier}+4" = "workspace number 4";
|
|
||||||
"${modifier}+5" = "workspace number 5";
|
|
||||||
"${modifier}+6" = "workspace number 6";
|
|
||||||
"${modifier}+7" = "workspace number 7";
|
|
||||||
"${modifier}+8" = "workspace number 8";
|
|
||||||
"${modifier}+9" = "workspace number 9";
|
|
||||||
|
|
||||||
"${modifier}+Shift+1" =
|
|
||||||
"move container to workspace number 1";
|
|
||||||
"${modifier}+Shift+2" =
|
|
||||||
"move container to workspace number 2";
|
|
||||||
"${modifier}+Shift+3" =
|
|
||||||
"move container to workspace number 3";
|
|
||||||
"${modifier}+Shift+4" =
|
|
||||||
"move container to workspace number 4";
|
|
||||||
"${modifier}+Shift+5" =
|
|
||||||
"move container to workspace number 5";
|
|
||||||
"${modifier}+Shift+6" =
|
|
||||||
"move container to workspace number 6";
|
|
||||||
"${modifier}+Shift+7" =
|
|
||||||
"move container to workspace number 7";
|
|
||||||
"${modifier}+Shift+8" =
|
|
||||||
"move container to workspace number 8";
|
|
||||||
"${modifier}+Shift+9" =
|
|
||||||
"move container to workspace number 9";
|
|
||||||
|
|
||||||
"${modifier}+Shift+minus" = "move scratchpad";
|
|
||||||
"${modifier}+minus" = "scratchpad show";
|
|
||||||
|
|
||||||
"${modifier}+Shift+c" = "reload";
|
|
||||||
"${modifier}+Shift+e" =
|
|
||||||
"exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
|
|
||||||
|
|
||||||
"${modifier}+r" = "mode resize";
|
|
||||||
} // {
|
|
||||||
# media keys
|
|
||||||
XF86MonBrightnessDown = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set 2%-"'';
|
|
||||||
XF86MonBrightnessUp = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set +2%"'';
|
|
||||||
|
|
||||||
XF86AudioRaiseVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5'";
|
|
||||||
XF86AudioLowerVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5'";
|
|
||||||
XF86AudioMute = "exec '${pkgs.pulsemixer}/bin/pulsemixer --toggle-mute'";
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
# mostly defaults:
|
|
||||||
bars = [{
|
|
||||||
mode = "dock";
|
|
||||||
hiddenState = "hide";
|
|
||||||
position = "top";
|
|
||||||
command = "${pkgs.waybar}/bin/waybar";
|
|
||||||
workspaceButtons = true;
|
|
||||||
workspaceNumbers = true;
|
|
||||||
statusCommand = "${pkgs.i3status}/bin/i3status";
|
|
||||||
fonts = {
|
|
||||||
names = [ "monospace" ];
|
|
||||||
size = 8.0;
|
|
||||||
};
|
|
||||||
trayOutput = "primary";
|
|
||||||
colors = {
|
|
||||||
background = "#000000";
|
|
||||||
statusline = "#ffffff";
|
|
||||||
separator = "#666666";
|
|
||||||
focusedWorkspace = {
|
|
||||||
border = "#4c7899";
|
|
||||||
background = "#285577";
|
|
||||||
text = "#ffffff";
|
|
||||||
};
|
|
||||||
activeWorkspace = {
|
|
||||||
border = "#333333";
|
|
||||||
background = "#5f676a";
|
|
||||||
text = "#ffffff";
|
|
||||||
};
|
|
||||||
inactiveWorkspace = {
|
|
||||||
border = "#333333";
|
|
||||||
background = "#222222";
|
|
||||||
text = "#888888";
|
|
||||||
};
|
|
||||||
urgentWorkspace = {
|
|
||||||
border = "#2f343a";
|
|
||||||
background = "#900000";
|
|
||||||
text = "#ffffff";
|
|
||||||
};
|
|
||||||
bindingMode = {
|
|
||||||
border = "#2f343a";
|
|
||||||
background = "#900000";
|
|
||||||
text = "#ffffff";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.waybar = lib.mkIf (gui == "sway") {
|
|
||||||
enable = true;
|
|
||||||
# docs: https://github.com/Alexays/Waybar/wiki/Configuration
|
|
||||||
settings = {
|
|
||||||
mainBar = {
|
|
||||||
layer = "top";
|
|
||||||
height = 40;
|
|
||||||
modules-left = ["sway/workspaces" "sway/mode"];
|
|
||||||
modules-center = ["sway/window"];
|
|
||||||
modules-right = ["custom/mediaplayer" "clock" "cpu" "network"];
|
|
||||||
"sway/window" = {
|
|
||||||
max-length = 50;
|
|
||||||
};
|
|
||||||
# include song artist/title. source: https://www.reddit.com/r/swaywm/comments/ni0vso/waybar_spotify_tracktitle/
|
|
||||||
"custom/mediaplayer" = {
|
|
||||||
exec = pkgs.writeShellScript "waybar-mediaplayer" ''
|
|
||||||
player_status=$(${pkgs.playerctl}/bin/playerctl status 2> /dev/null)
|
|
||||||
if [ "$player_status" = "Playing" ]; then
|
|
||||||
echo "$(${pkgs.playerctl}/bin/playerctl metadata artist) - $(${pkgs.playerctl}/bin/playerctl metadata title)"
|
|
||||||
elif [ "$player_status" = "Paused" ]; then
|
|
||||||
echo " $(${pkgs.playerctl}/bin/playerctl metadata artist) - $(${pkgs.playerctl}/bin/playerctl metadata title)"
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
interval = 2;
|
|
||||||
format = "{} ";
|
|
||||||
# return-type = "json";
|
|
||||||
on-click = "${pkgs.playerctl}/bin/playerctl play-pause";
|
|
||||||
on-scroll-up = "${pkgs.playerctl}/bin/playerctl next";
|
|
||||||
on-scroll-down = "${pkgs.playerctl}/bin/playerctl previous";
|
|
||||||
};
|
|
||||||
network = {
|
|
||||||
interval = 1;
|
|
||||||
format-ethernet = "{ifname}: {ipaddr}/{cidr} up: {bandwidthUpBits} down: {bandwidthDownBits}";
|
|
||||||
};
|
|
||||||
cpu = {
|
|
||||||
format = "{usage}% ";
|
|
||||||
tooltip = false;
|
|
||||||
};
|
|
||||||
clock = {
|
|
||||||
format-alt = "{:%a, %d. %b %H:%M}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# style = ''
|
|
||||||
# * {
|
|
||||||
# border: none;
|
|
||||||
# border-radius: 0;
|
|
||||||
# font-family: Source Code Pro;
|
|
||||||
# }
|
|
||||||
# window#waybar {
|
|
||||||
# background: #16191C;
|
|
||||||
# color: #AAB2BF;
|
|
||||||
# }
|
|
||||||
# #workspaces button {
|
|
||||||
# padding: 0 5px;
|
|
||||||
# }
|
|
||||||
# .custom-spotify {
|
|
||||||
# padding: 0 10px;
|
|
||||||
# margin: 0 4px;
|
|
||||||
# background-color: #1DB954;
|
|
||||||
# color: black;
|
|
||||||
# }
|
|
||||||
# '';
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
programs.firefox = lib.mkIf (gui != null) {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
profiles.default = {
|
|
||||||
bookmarks = {
|
|
||||||
fed_uninsane.url = "https://fed.uninsane.org/";
|
|
||||||
delightful.url = "https://delightful.club/";
|
|
||||||
crowdsupply.url = "https://www.crowdsupply.com/";
|
|
||||||
linux_phone_apps.url = "https://linuxphoneapps.org/mobile-compatibility/5/";
|
|
||||||
mempool.url = "https://jochen-hoenicke.de/queue";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# firefox profile support seems to be broken :shrug:
|
|
||||||
# profiles.other = {
|
|
||||||
# id = 2;
|
|
||||||
# };
|
|
||||||
|
|
||||||
# NB: these must be manually enabled in the Firefox settings on first start
|
|
||||||
# extensions can be found here: https://gitlab.com/rycee/nur-expressions/-/blob/master/pkgs/firefox-addons/addons.json
|
|
||||||
extensions = [
|
|
||||||
pkgs.nur.repos.rycee.firefox-addons.bypass-paywalls-clean
|
|
||||||
pkgs.nur.repos.rycee.firefox-addons.metamask
|
|
||||||
pkgs.nur.repos.rycee.firefox-addons.i-dont-care-about-cookies
|
|
||||||
pkgs.nur.repos.rycee.firefox-addons.sidebery
|
|
||||||
pkgs.nur.repos.rycee.firefox-addons.sponsorblock
|
|
||||||
pkgs.nur.repos.rycee.firefox-addons.ublock-origin
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
home.shellAliases = {
|
|
||||||
":q" = "exit";
|
|
||||||
# common typos
|
|
||||||
"cd.." = "cd ..";
|
|
||||||
"cd../" = "cd ../";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
home.packages = [
|
|
||||||
pkgs.btrfs-progs
|
|
||||||
pkgs.dig
|
|
||||||
pkgs.cryptsetup
|
|
||||||
pkgs.duplicity
|
|
||||||
pkgs.fatresize
|
|
||||||
pkgs.fd
|
|
||||||
pkgs.file
|
|
||||||
pkgs.gnumake
|
|
||||||
pkgs.gptfdisk
|
|
||||||
pkgs.hdparm
|
|
||||||
pkgs.htop
|
|
||||||
pkgs.iftop
|
|
||||||
pkgs.inetutils # for telnet
|
|
||||||
pkgs.iotop
|
|
||||||
pkgs.iptables
|
|
||||||
pkgs.jq
|
|
||||||
pkgs.killall
|
|
||||||
pkgs.lm_sensors # for sensors-detect
|
|
||||||
pkgs.lsof
|
|
||||||
pkgs.mix2nix
|
|
||||||
pkgs.netcat
|
|
||||||
pkgs.nixpkgs-review
|
|
||||||
pkgs.nixUnstable # TODO: still needed on 22.05?
|
|
||||||
# pkgs.nixos-generators
|
|
||||||
# pkgs.nettools
|
|
||||||
pkgs.nmap
|
|
||||||
pkgs.obsidian
|
|
||||||
pkgs.parted
|
|
||||||
pkgs.pciutils
|
|
||||||
# pkgs.ponymix
|
|
||||||
pkgs.powertop
|
|
||||||
pkgs.pulsemixer
|
|
||||||
pkgs.python3
|
|
||||||
pkgs.ripgrep
|
|
||||||
pkgs.smartmontools
|
|
||||||
pkgs.snapper
|
|
||||||
pkgs.socat
|
|
||||||
pkgs.sudo
|
|
||||||
pkgs.usbutils
|
|
||||||
pkgs.wget
|
|
||||||
pkgs.wireguard-tools
|
|
||||||
pkgs.youtube-dl
|
|
||||||
pkgs.zola
|
|
||||||
]
|
|
||||||
++ (if gui != null then
|
|
||||||
[
|
|
||||||
# GUI only
|
|
||||||
pkgs.chromium
|
|
||||||
pkgs.clinfo
|
|
||||||
pkgs.element-desktop # broken on phosh
|
|
||||||
pkgs.evince # works on phosh
|
|
||||||
pkgs.font-manager
|
|
||||||
pkgs.gimp # broken on phosh
|
|
||||||
pkgs.gnome.dconf-editor
|
|
||||||
pkgs.gnome.file-roller
|
|
||||||
pkgs.gnome.gnome-maps # works on phosh
|
|
||||||
pkgs.gnome.nautilus
|
|
||||||
pkgs.gnome-podcasts
|
|
||||||
pkgs.gnome.gnome-terminal # works on phosh
|
|
||||||
pkgs.inkscape
|
|
||||||
pkgs.libreoffice-fresh # XXX colin: maybe don't want this on mobile
|
|
||||||
pkgs.mesa-demos
|
|
||||||
pkgs.playerctl
|
|
||||||
pkgs.tdesktop # broken on phosh
|
|
||||||
pkgs.vlc # works on phosh
|
|
||||||
pkgs.whalebird # pleroma client. TODO: port kaiteki to nix: https://craftplacer.moe/projects/kaiteki/
|
|
||||||
pkgs.xterm # broken on phosh
|
|
||||||
] else [])
|
|
||||||
++ (if gui == "sway" then
|
|
||||||
[
|
|
||||||
# TODO: move this to helpers/gui/sway.nix?
|
|
||||||
pkgs.swaylock
|
|
||||||
pkgs.swayidle
|
|
||||||
pkgs.wl-clipboard
|
|
||||||
pkgs.mako # notification daemon
|
|
||||||
# pkgs.dmenu # todo: use wofi?
|
|
||||||
# user stuff
|
|
||||||
# pkgs.pavucontrol
|
|
||||||
] else [])
|
|
||||||
++ (if gui != null && system == "x86_64-linux" then
|
|
||||||
[
|
|
||||||
# x86_64 only
|
|
||||||
pkgs.signal-desktop
|
|
||||||
pkgs.spotify
|
|
||||||
pkgs.discord
|
|
||||||
] else [])
|
|
||||||
++ extraPackages;
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./fs.nix
|
|
||||||
./home-manager.nix
|
|
||||||
./nix-cache.nix
|
|
||||||
./users.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
time.timeZone = "America/Los_Angeles";
|
|
||||||
|
|
||||||
environment.variables = {
|
|
||||||
EDITOR = "vim";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@@ -1,25 +0,0 @@
|
|||||||
{ pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
fileSystems."/mnt/media-uninsane" = {
|
|
||||||
# device = "sshfs#colin@uninsane.org:/opt/uninsane/media";
|
|
||||||
device = "colin@uninsane.org:/opt/uninsane/media";
|
|
||||||
fsType = "fuse.sshfs";
|
|
||||||
options = [
|
|
||||||
"x-systemd.automount"
|
|
||||||
"_netdev"
|
|
||||||
"user"
|
|
||||||
"idmap=user"
|
|
||||||
"transform_symlinks"
|
|
||||||
"identityfile=/home/colin/.ssh/id_ed25519"
|
|
||||||
"allow_other"
|
|
||||||
"default_permissions"
|
|
||||||
"uid=1000"
|
|
||||||
"gid=1000"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.sshfs-fuse
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@@ -1,9 +0,0 @@
|
|||||||
{ home-manager, config, pkgs, ... }:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
home-manager.nixosModule
|
|
||||||
];
|
|
||||||
|
|
||||||
home-manager.useGlobalPkgs = true;
|
|
||||||
home-manager.useUserPackages = true;
|
|
||||||
}
|
|
@@ -1,16 +0,0 @@
|
|||||||
{ ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
# use our own binary cache
|
|
||||||
nix.settings = {
|
|
||||||
substituters = [
|
|
||||||
"https://nixcache.uninsane.org"
|
|
||||||
"https://nix-community.cachix.org"
|
|
||||||
"https://cache.nixos.org/"
|
|
||||||
];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"nixcache.uninsane.org:r3WILM6+QrkmsLgqVQcEdibFD7Q/4gyzD9dGT33GP70="
|
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,53 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
# installer docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix
|
|
||||||
{
|
|
||||||
# Users are exactly these specified here;
|
|
||||||
# old ones will be deleted (from /etc/passwd, etc) upon upgrade.
|
|
||||||
users.mutableUsers = false;
|
|
||||||
|
|
||||||
# docs: https://nixpkgs-manual-sphinx-markedown-example.netlify.app/generated/options-db.xml.html#users-users
|
|
||||||
users.users.colin = {
|
|
||||||
# sets group to "users" (?)
|
|
||||||
isNormalUser = true;
|
|
||||||
home = "/home/colin";
|
|
||||||
uid = 1000;
|
|
||||||
# XXX colin: this is what the installer has, but is it necessary?
|
|
||||||
# group = "users";
|
|
||||||
extraGroups = [
|
|
||||||
"wheel"
|
|
||||||
"nixbuild"
|
|
||||||
"networkmanager"
|
|
||||||
# phosh/mobile. XXX colin: unsure if necessary
|
|
||||||
"video"
|
|
||||||
"feedbackd"
|
|
||||||
"dialout" # required for modem access
|
|
||||||
];
|
|
||||||
initialPassword = lib.mkDefault "";
|
|
||||||
shell = pkgs.zsh;
|
|
||||||
# shell = pkgs.bashInteractive;
|
|
||||||
# XXX colin: create ssh key for THIS user by logging in and running:
|
|
||||||
# ssh-keygen -t ed25519
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGSDe/y0e9PSeUwYlMPjzhW0UhNsGAGsW3lCG3apxrD5 colin@colin.desktop"
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG+MZ/l5d8g5hbxMB9ed1uyvhV85jwNrSVNVxb5ujQjw colin@lappy"
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX colin@desko"
|
|
||||||
# TODO: should probably only let this authenticate to my server
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGCLCA9KbjXaXNNMJJvqbPO5KQQ64JCdG8sg88AfdKzi colin@moby"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
security.sudo = {
|
|
||||||
enable = true;
|
|
||||||
wheelNeedsPassword = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.openssh = {
|
|
||||||
enable = true;
|
|
||||||
permitRootLogin = "no";
|
|
||||||
passwordAuthentication = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO colin: move this somewhere else!
|
|
||||||
programs.vim.defaultEditor = true;
|
|
||||||
}
|
|
21
image.nix
21
image.nix
@@ -1,21 +0,0 @@
|
|||||||
{ config, lib, pkgs, modulesPath, ... }:
|
|
||||||
{
|
|
||||||
fileSystems."/" = {
|
|
||||||
# boot by label instead of unpredictable uuid
|
|
||||||
device = "/dev/disk/by-label/nixos-img";
|
|
||||||
# make-disk-image only supports ext4
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
# fileSystems."/boot".device = "/dev/vda1";
|
|
||||||
fileSystems."/boot".device = "/dev/disk/by-label/ESP";
|
|
||||||
|
|
||||||
system.build.raw = import "${toString modulesPath}/../lib/make-disk-image.nix" {
|
|
||||||
inherit lib config pkgs;
|
|
||||||
partitionTableType = "efi";
|
|
||||||
label = "nixos-img";
|
|
||||||
fsType = config.fileSystems."/".fsType;
|
|
||||||
diskSize = "auto";
|
|
||||||
format = "raw";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@@ -1,25 +1,52 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./../../helpers/universal
|
|
||||||
./../../helpers/hardware-x86_64.nix
|
|
||||||
# ./../../helpers/gui/gnome.nix
|
|
||||||
#./../../helpers/gui/i3.nix
|
|
||||||
./../../helpers/gui/sway.nix
|
|
||||||
./fs.nix
|
./fs.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
home-manager.users.colin = import ./../../helpers/home-manager-gen-colin.nix {
|
sane.gui.sway.enable = true;
|
||||||
inherit pkgs lib;
|
sane.services.duplicity.enable = true;
|
||||||
system = "x86_64-linux";
|
sane.services.nixserve.enable = true;
|
||||||
# gui = "gnome";
|
sane.services.nixserve.sopsFile = ../../secrets/desko.yaml;
|
||||||
# gui = "i3";
|
sane.impermanence.enable = true;
|
||||||
gui = "sway";
|
|
||||||
extraPackages = [
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
pkgs.electrum
|
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||||
];
|
|
||||||
|
# needed to use libimobiledevice/ifuse, for iphone sync
|
||||||
|
services.usbmuxd.enable = true;
|
||||||
|
users.users.usbmux.uid = config.sane.allocations.usbmux-uid;
|
||||||
|
users.groups.usbmux.gid = config.sane.allocations.usbmux-gid;
|
||||||
|
|
||||||
|
# default config: https://man.archlinux.org/man/snapper-configs.5
|
||||||
|
# defaults to something like:
|
||||||
|
# - hourly snapshots
|
||||||
|
# - auto cleanup; keep the last 10 hourlies, last 10 daylies, last 10 monthlys.
|
||||||
|
services.snapper.configs.nix = {
|
||||||
|
# TODO: for the impermanent setup, we'd prefer to just do /nix/persist,
|
||||||
|
# but that also requires setting up the persist dir as a subvol
|
||||||
|
subvolume = "/nix";
|
||||||
|
# TODO: ALLOW_USERS doesn't seem to work. still need `sudo snapper -c nix list`
|
||||||
|
extraConfig = ''
|
||||||
|
ALLOW_USERS = "colin";
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sops.secrets.duplicity_passphrase = {
|
||||||
|
sopsFile = ../../secrets/desko.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.steam = {
|
||||||
|
enable = true;
|
||||||
|
# not sure if needed: stole this whole snippet from the wiki
|
||||||
|
remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play
|
||||||
|
dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server
|
||||||
|
};
|
||||||
|
sane.impermanence.home-dirs = [
|
||||||
|
".steam"
|
||||||
|
".local/share/Steam"
|
||||||
|
];
|
||||||
|
|
||||||
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
|
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
|
||||||
system.stateVersion = "21.05";
|
system.stateVersion = "21.05";
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,30 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
fileSystems."/" = lib.mkDefault {
|
# root is a tmpfs so that we have an ephemeral system ("impermanence" handles the state)
|
||||||
device = "/dev/disk/by-uuid/d969ee61-12cf-4490-be07-4440c7be593f";
|
fileSystems."/" = {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"mode=755"
|
||||||
|
"size=1G"
|
||||||
|
"defaults"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# we need a /tmp for building large nix things.
|
||||||
|
# a cross-compiled kernel, particularly, will easily use 30+GB of tmp
|
||||||
|
fileSystems."/tmp" = {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"mode=777"
|
||||||
|
"size=64G"
|
||||||
|
"defaults"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
fileSystems."/nix" = {
|
||||||
|
# device = "/dev/disk/by-uuid/985a0a32-da52-4043-9df7-615adec2e4ff";
|
||||||
|
device = "/dev/disk/by-uuid/0ab0770b-7734-4167-88d9-6e4e20bb2a56";
|
||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
options = [
|
options = [
|
||||||
"compress=zstd"
|
"compress=zstd"
|
||||||
@@ -11,7 +33,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" = {
|
||||||
device = lib.mkDefault "/dev/disk/by-uuid/F826-6192";
|
# device = "/dev/disk/by-uuid/CAA7-E7D2";
|
||||||
|
device = "/dev/disk/by-uuid/41B6-BAEF";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,31 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./../../helpers/universal
|
|
||||||
./../../helpers/hardware-x86_64.nix
|
|
||||||
./../../helpers/gui/gnome.nix
|
|
||||||
./fs.nix
|
./fs.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
home-manager.users.colin = import ./../../helpers/home-manager-gen-colin.nix {
|
# sane.users.guest.enable = true;
|
||||||
inherit pkgs lib;
|
sane.gui.sway.enable = true;
|
||||||
system = "x86_64-linux";
|
sane.impermanence.enable = true;
|
||||||
gui = "gnome";
|
sane.nixcache.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
|
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||||
|
|
||||||
|
users.users.colin.initialPassword = "147147";
|
||||||
|
|
||||||
|
# default config: https://man.archlinux.org/man/snapper-configs.5
|
||||||
|
# defaults to something like:
|
||||||
|
# - hourly snapshots
|
||||||
|
# - auto cleanup; keep the last 10 hourlies, last 10 daylies, last 10 monthlys.
|
||||||
|
services.snapper.configs.nix = {
|
||||||
|
# TODO: for the impermanent setup, we'd prefer to just do /nix/persist,
|
||||||
|
# but that also requires setting up the persist dir as a subvol
|
||||||
|
subvolume = "/nix";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# TODO: only here for debugging
|
||||||
|
# services.ipfs.enable = true;
|
||||||
|
|
||||||
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
|
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
|
||||||
system.stateVersion = "21.05";
|
system.stateVersion = "21.05";
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,27 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
fileSystems."/" = lib.mkDefault {
|
# root is a tmpfs so that we have an ephemeral system ("impermanence" handles the state)
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"mode=755"
|
||||||
|
"size=1G"
|
||||||
|
"defaults"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# we need a /tmp of default size (half RAM) for building large nix things
|
||||||
|
fileSystems."/tmp" = {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"mode=777"
|
||||||
|
"defaults"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix" = {
|
||||||
device = "/dev/disk/by-uuid/75230e56-2c69-4e41-b03e-68475f119980";
|
device = "/dev/disk/by-uuid/75230e56-2c69-4e41-b03e-68475f119980";
|
||||||
fsType = "btrfs";
|
fsType = "btrfs";
|
||||||
options = [
|
options = [
|
||||||
@@ -11,7 +31,27 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" = {
|
fileSystems."/boot" = {
|
||||||
device = lib.mkDefault "/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"
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
}
|
}
|
||||||
|
@@ -1,49 +1,61 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, mobile-nixos, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./../../helpers/universal
|
./firmware.nix
|
||||||
./../../helpers/gui/phosh.nix
|
./fs.nix
|
||||||
# ./../../helpers/gui/plasma-mobile.nix
|
./kernel.nix
|
||||||
# ./../../helpers/gui/gnome.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# cross-compiled documentation is *slow*.
|
||||||
|
# no obvious way to natively compile docs (2022/09/29).
|
||||||
|
# entrypoint is nixos/modules/misc/documentation.nix
|
||||||
|
# doc building happens in nixos/doc/manual/default.nix
|
||||||
|
# TODO: we could *maybe* inject pkgs.buildPackages.xyz = cross.buildPackages.xyz?
|
||||||
|
documentation.nixos.enable = false;
|
||||||
|
|
||||||
# XXX colin: phosh doesn't work well with passwordless login
|
# XXX colin: phosh doesn't work well with passwordless login
|
||||||
users.users.colin.initialPassword = "147147";
|
users.users.colin.initialPassword = "147147";
|
||||||
|
services.getty.autologinUser = "root"; # allows for emergency maintenance?
|
||||||
|
|
||||||
home-manager.users.colin = import ./../../helpers/home-manager-gen-colin.nix {
|
# usability compromises
|
||||||
inherit pkgs lib;
|
sane.impermanence.home-dirs = [
|
||||||
system = "aarch64-linux";
|
".librewolf"
|
||||||
gui = "phosh";
|
|
||||||
extraPackages = [
|
|
||||||
# for web browsers see: https://forum.pine64.org/showthread.php?tid=13669
|
|
||||||
pkgs.angelfish # plasma mobile web browser; broken on phosh (poor wayland support)
|
|
||||||
# pkgs.plasma5Packages.index # file browser
|
|
||||||
pkgs.plasma5Packages.konsole # terminal
|
|
||||||
# pkgs.plasma5Packages.pix # picture viewer
|
|
||||||
pkgs.plasma5Packages.kalk # calculator; broken on phosh
|
|
||||||
# pkgs.plasma5Packages.buho # (plasma mobile?) note application
|
|
||||||
pkgs.plasma5Packages.kasts # podcast app; works on phosh after setting QT envar
|
|
||||||
pkgs.plasma5Packages.koko # image gallery; broken on phosh
|
|
||||||
pkgs.plasma5Packages.kwave # media player.
|
|
||||||
# pkgs.plasma5Packages.neochat # matrix client. needs qcoro => no aarch64 support
|
|
||||||
# pkgs.plasma5Packages.plasma-dialer # phone dialer
|
|
||||||
# pkgs.plasma5Packages.plasma-mobile # the whole shebang?
|
|
||||||
# pkgs.plasma5Packages.plasma-settings
|
|
||||||
pkgs.plasma5Packages.bomber # arcade game; broken on phosh
|
|
||||||
pkgs.plasma5Packages.kapman # pacman
|
|
||||||
pkgs.w3m # text-based web browser; works!
|
|
||||||
pkgs.st # suckless terminal; broken on phosh
|
|
||||||
# pkgs.alacritty # terminal; crashes phosh
|
|
||||||
];
|
];
|
||||||
};
|
|
||||||
|
|
||||||
# This value determines the NixOS release from which the default
|
# sane.home-packages.enableGuiPkgs = false; # XXX faster builds/imaging for debugging
|
||||||
# settings for stateful data, like file locations and database versions
|
sane.home-manager.extraPackages = [
|
||||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
pkgs.plasma5Packages.konsole # terminal
|
||||||
# this value at the release version of the first install of this system.
|
];
|
||||||
# Before changing this value read the documentation for this option
|
|
||||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
sane.nixcache.enable = true;
|
||||||
system.stateVersion = "21.11"; # Did you read the comment?
|
sane.impermanence.enable = true;
|
||||||
|
sane.gui.phosh.enable = true;
|
||||||
|
|
||||||
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
|
# /boot space is at a premium. default was 20.
|
||||||
|
boot.loader.generic-extlinux-compatible.configurationLimit = 10;
|
||||||
|
# mobile.bootloader.enable = false;
|
||||||
|
# mobile.boot.stage-1.enable = false;
|
||||||
|
# boot.initrd.systemd.enable = false;
|
||||||
|
# boot.initrd.services.swraid.enable = false; # attempt to fix dm_mod stuff
|
||||||
|
# disable proximity sensor.
|
||||||
|
# the filtering/calibration is bad that it causes the screen to go fully dark at times.
|
||||||
|
boot.blacklistedKernelModules = [ "stk3310" ];
|
||||||
|
|
||||||
|
# without this some GUI apps fail: `DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory`
|
||||||
|
# this is because they can't allocate enough video ram.
|
||||||
|
# the default CMA seems to be 32M. we could probably get by with as little as 64M, and safely with 128M.
|
||||||
|
# `cat /proc/meminfo` to see CmaTotal/CmaFree if interested in tuning this.
|
||||||
|
boot.kernelParams = [ "cma=256M" ];
|
||||||
|
|
||||||
|
# mobile-nixos' /lib/firmware includes:
|
||||||
|
# rtl_bt (bluetooth)
|
||||||
|
# anx7688-fw.bin (USB-C -> HDMI bridge)
|
||||||
|
# ov5640_af.bin (camera module)
|
||||||
|
# hardware.firmware = [ config.mobile.device.firmware ];
|
||||||
|
hardware.firmware = [ pkgs.rtl8723cs-firmware ];
|
||||||
|
|
||||||
|
system.stateVersion = "21.11";
|
||||||
|
|
||||||
# defined: https://www.freedesktop.org/software/systemd/man/machine-info.html
|
# defined: https://www.freedesktop.org/software/systemd/man/machine-info.html
|
||||||
# XXX colin: not sure which, if any, software makes use of this
|
# XXX colin: not sure which, if any, software makes use of this
|
||||||
@@ -53,4 +65,15 @@
|
|||||||
|
|
||||||
# enable rotation sensor
|
# enable rotation sensor
|
||||||
hardware.sensor.iio.enable = true;
|
hardware.sensor.iio.enable = true;
|
||||||
|
|
||||||
|
# from https://gitlab.manjaro.org/manjaro-arm/packages/community/phosh/alsa-ucm-pinephone
|
||||||
|
# mobile-nixos does this same thing, with *slightly different settings*.
|
||||||
|
# i trust manjaro more because the guy maintaining that is actively trying to upstream into alsa-ucm-conf.
|
||||||
|
# an alternative may be to build a custom alsa with the PinePhone config patch applied:
|
||||||
|
# - <https://github.com/alsa-project/alsa-ucm-conf/pull/134>
|
||||||
|
# that would make this be not device-specific
|
||||||
|
environment.variables.ALSA_CONFIG_UCM2 = "${./ucm2}";
|
||||||
|
systemd.services.pulseaudio.environment.ALSA_CONFIG_UCM2 = "${./ucm2}";
|
||||||
|
|
||||||
|
hardware.opengl.driSupport = true;
|
||||||
}
|
}
|
||||||
|
12
machines/moby/firmware.nix
Normal file
12
machines/moby/firmware.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
{
|
||||||
|
# we need space in the GPT header to place tow-boot.
|
||||||
|
# only actually need 1 MB, but better to over-allocate than under-allocate
|
||||||
|
sane.image.extraGPTPadding = 16 * 1024 * 1024;
|
||||||
|
sane.image.firstPartGap = 0;
|
||||||
|
system.build.img = pkgs.runCommand "nixos_full-disk-image.img" {} ''
|
||||||
|
cp -v ${config.system.build.img-without-firmware}/nixos.img $out
|
||||||
|
chmod +w $out
|
||||||
|
dd if=${pkgs.tow-boot-pinephone}/Tow-Boot.noenv.bin of=$out bs=1024 seek=8 conv=notrunc
|
||||||
|
'';
|
||||||
|
}
|
28
machines/moby/fs.nix
Normal file
28
machines/moby/fs.nix
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# root is a tmpfs so that we have an ephemeral system ("impermanence" handles the state)
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"mode=755"
|
||||||
|
"size=1G"
|
||||||
|
"defaults"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix" = {
|
||||||
|
device = "/dev/disk/by-uuid/1f1271f8-53ce-4081-8a29-60a4a6b5d6f9";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [
|
||||||
|
"compress=zstd"
|
||||||
|
"defaults"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/0299-F1E5";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
}
|
143
machines/moby/kernel.nix
Normal file
143
machines/moby/kernel.nix
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
{ lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
# use the last commit on the 5.18 branch (5.18.14)
|
||||||
|
# manjaro's changes between kernel patch versions tend to be minimal if any.
|
||||||
|
manjaroBase = "https://gitlab.manjaro.org/manjaro-arm/packages/core/linux/-/raw/25bd828cd47b1c6e09fcbcf394a649b89d2876dd";
|
||||||
|
manjaroPatch = name: sha256: {
|
||||||
|
inherit name;
|
||||||
|
patch = pkgs.fetchpatch {
|
||||||
|
inherit name;
|
||||||
|
url = "${manjaroBase}/${name}?inline=false";
|
||||||
|
inherit sha256;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# the idea for patching off Manjaro's kernel comes from jakewaksbaum:
|
||||||
|
# - https://git.sr.ht/~jakewaksbaum/pi/tree/af20aae5653545d6e67a459b59ee3e1ca8a680b0/item/kernel/default.nix
|
||||||
|
# - he later abandoned this, i think because he's using the Pinephone Pro which received mainline support.
|
||||||
|
manjaroPatches = [
|
||||||
|
(manjaroPatch
|
||||||
|
"1001-arm64-dts-allwinner-add-hdmi-sound-to-pine-devices.patch"
|
||||||
|
"sha256-DApd791A+AxB28Ven/MVAyuyVphdo8KQDx8O7oxVPnc="
|
||||||
|
)
|
||||||
|
# these patches below are critical to enable wifi (RTL8723CS)
|
||||||
|
# - the alternative is a wholly forked kernel by megi/megous:
|
||||||
|
# - https://xnux.eu/howtos/build-pinephone-kernel.html#toc-how-to-build-megi-s-pinehpone-kernel
|
||||||
|
# - i don't know if these patches are based on megi's or original
|
||||||
|
(manjaroPatch
|
||||||
|
"2001-Bluetooth-Add-new-quirk-for-broken-local-ext-features.patch"
|
||||||
|
"sha256-CExhJuUWivegxPdnzKINEsKrMFx/m/1kOZFmlZ2SEOc="
|
||||||
|
)
|
||||||
|
(manjaroPatch
|
||||||
|
"2002-Bluetooth-btrtl-add-support-for-the-RTL8723CS.patch"
|
||||||
|
"sha256-dDdvOphTcP/Aog93HyH+L9m55laTgtjndPSE4/rnzUA="
|
||||||
|
)
|
||||||
|
(manjaroPatch
|
||||||
|
"2004-arm64-dts-allwinner-enable-bluetooth-pinetab-pinepho.patch"
|
||||||
|
"sha256-o43P3WzXyHK1PF+Kdter4asuyGAEKO6wf5ixcco2kCQ="
|
||||||
|
)
|
||||||
|
# XXX: this one has a Makefile, which hardcodes /sbin/depmod:
|
||||||
|
# - drivers/staging/rtl8723cs/Makefile
|
||||||
|
# - not sure if this is problematic?
|
||||||
|
(manjaroPatch
|
||||||
|
"2005-staging-add-rtl8723cs-driver.patch"
|
||||||
|
"sha256-6ywm3dQQ5JYl60CLKarxlSUukwi4QzqctCj3tVgzFbo="
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
# pinephone uses the linux dtb at arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
|
||||||
|
# - this includes sun50i-a64.dtsi
|
||||||
|
# - and sun50i-a64-cpu-opp.dtsi
|
||||||
|
# - no need to touch the allwinner-h6 stuff: that's the SBC pine product
|
||||||
|
# - i think it's safe to ignore sun9i stuff, but i don't know what it is
|
||||||
|
kernelConfig = with lib.kernel; {
|
||||||
|
# NB: nix adds the CONFIG_ prefix to each of these.
|
||||||
|
# if you add the prefix yourself nix will IGNORE YOUR CONFIG.
|
||||||
|
RTL8723CS = module;
|
||||||
|
BT_HCIUART_3WIRE = yes;
|
||||||
|
BT_HCIUART_RTL = yes;
|
||||||
|
RTL8XXXU_UNTESTED = yes;
|
||||||
|
BT_BNEP_MC_FILTER = yes;
|
||||||
|
BT_BNEP_PROTO_FILTER = yes;
|
||||||
|
BT_HS = yes;
|
||||||
|
BT_LE = yes;
|
||||||
|
# relevant configs inherited from nixos defaults (or above additions):
|
||||||
|
# CONFIG_BT=m
|
||||||
|
# CONFIG_BT_BREDR=y
|
||||||
|
# CONFIG_BT_RFCOMM=m
|
||||||
|
# CONFIG_BT_RFCOMM_TTY=y
|
||||||
|
# CONFIG_BT_BNEP=m
|
||||||
|
# CONFIG_BT_HIDP=m
|
||||||
|
# CONFIG_BT_RTL=m
|
||||||
|
# CONFIG_BT_HCIBTUSB=m
|
||||||
|
# CONFIG_BT_HCIBTUSB_BCM=y
|
||||||
|
# CONFIG_BT_HCIBTUSB_RTL=y
|
||||||
|
# CONFIG_BT_HCIUART=m
|
||||||
|
# CONFIG_BT_HCIUART_SERDEV=y
|
||||||
|
# CONFIG_BT_HCIUART_H4=y
|
||||||
|
# CONFIG_BT_HCIUART_LL=y
|
||||||
|
# CONFIG_RTL_CARDS=m
|
||||||
|
# CONFIG_RTLWIFI=m
|
||||||
|
# CONFIG_RTLWIFI_PCI=m
|
||||||
|
# CONFIG_RTLWIFI_USB=m
|
||||||
|
# CONFIG_RTLWIFI_DEBUG=y
|
||||||
|
# CONFIG_RTL8723_COMMON=m
|
||||||
|
# CONFIG_RTLBTCOEXIST=m
|
||||||
|
# CONFIG_RTL8XXXU=m
|
||||||
|
# CONFIG_RTLLIB=m
|
||||||
|
# consider adding (from mobile-nixos):
|
||||||
|
# maybe: CONFIG_BT_HCIUART_3WIRE=y
|
||||||
|
# maybe: CONFIG_BT_HCIUART_RTL=y
|
||||||
|
# maybe: CONFIG_RTL8XXXU_UNTESTED=y
|
||||||
|
# consider adding (from manjaro):
|
||||||
|
# CONFIG_BT_6LOWPAN=m (not listed as option in nixos kernel)
|
||||||
|
# these are referenced in the rtl8723 source, but not known to config (and not in mobile-nixos config
|
||||||
|
# maybe: CONFIG_RTL_ODM_WLAN_DRIVER
|
||||||
|
# maybe: CONFIG_RTL_TRIBAND_SUPPORT
|
||||||
|
# maybe: CONFIG_SDIO_HCI
|
||||||
|
# maybe: CONFIG_USB_HCI
|
||||||
|
};
|
||||||
|
|
||||||
|
# create a kernelPatch which overrides nixos' defconfig with extra options
|
||||||
|
patchDefconfig = config: {
|
||||||
|
# defconfig options. this method comes from here:
|
||||||
|
# - https://discourse.nixos.org/t/the-correct-way-to-override-the-latest-kernel-config/533/9
|
||||||
|
name = "sane-moby-defconfig";
|
||||||
|
patch = null;
|
||||||
|
extraStructuredConfig = config;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# use Megi's kernel:
|
||||||
|
# even with the Manjaro patches, stock 5.18 has a few issues on Pinephone:
|
||||||
|
# - no battery charging
|
||||||
|
# - phone rotation sensor is off by 90 degrees
|
||||||
|
# - ambient light sensor causes screen brightness to be shakey
|
||||||
|
# - phosh greeter may not appear after wake from sleep
|
||||||
|
boot.kernelPackages = pkgs.cross.linuxPackagesFor pkgs.cross.linux-megous;
|
||||||
|
|
||||||
|
boot.kernelPatches = [
|
||||||
|
(patchDefconfig (kernelConfig //
|
||||||
|
(with lib.kernel; {
|
||||||
|
# disabling the sun5i_eink driver avoids this compilation error:
|
||||||
|
# CC [M] drivers/video/fbdev/sun5i-eink-neon.o
|
||||||
|
# aarch64-unknown-linux-gnu-gcc: error: unrecognized command line option '-mfloat-abi=softfp'
|
||||||
|
# aarch64-unknown-linux-gnu-gcc: error: unrecognized command line option '-mfpu=neon'
|
||||||
|
# make[3]: *** [../scripts/Makefile.build:289: drivers/video/fbdev/sun5i-eink-neon.o] Error 1
|
||||||
|
FB_SUN5I_EINK = no;
|
||||||
|
})
|
||||||
|
))
|
||||||
|
];
|
||||||
|
|
||||||
|
# alternatively, use nixos' kernel and add the stuff we want:
|
||||||
|
# # cross-compilation optimization:
|
||||||
|
# boot.kernelPackages =
|
||||||
|
# let p = (import nixpkgs { localSystem = "x86_64-linux"; });
|
||||||
|
# in p.pkgsCross.aarch64-multiplatform.linuxPackages_5_18;
|
||||||
|
# # non-cross:
|
||||||
|
# # boot.kernelPackages = pkgs.linuxPackages_5_18;
|
||||||
|
|
||||||
|
# boot.kernelPatches = manjaroPatches ++ [
|
||||||
|
# (patchDefconfig kernelConfig)
|
||||||
|
# ];
|
||||||
|
}
|
148
machines/moby/ucm2/PinePhone/HiFi.conf
Normal file
148
machines/moby/ucm2/PinePhone/HiFi.conf
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
SectionVerb {
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='Headphone Playback Switch' off"
|
||||||
|
cset "name='Headphone Source Playback Route' DAC"
|
||||||
|
cset "name='Line In Playback Switch' off"
|
||||||
|
cset "name='Line Out Playback Switch' off"
|
||||||
|
cset "name='Line Out Source Playback Route' Mono Differential"
|
||||||
|
cset "name='Mic1 Playback Switch' off"
|
||||||
|
cset "name='Mic2 Playback Switch' off"
|
||||||
|
cset "name='AIF1 DA0 Playback Volume' 160"
|
||||||
|
cset "name='AIF3 ADC Source Capture Route' None"
|
||||||
|
cset "name='AIF2 DAC Source Playback Route' AIF2"
|
||||||
|
cset "name='DAC Playback Switch' on"
|
||||||
|
cset "name='DAC Playback Volume' 160"
|
||||||
|
cset "name='ADC Digital DAC Playback Switch' off"
|
||||||
|
cset "name='AIF1 Slot 0 Digital DAC Playback Switch' on"
|
||||||
|
cset "name='AIF2 Digital DAC Playback Switch' off"
|
||||||
|
cset "name='DAC Reversed Playback Switch' off"
|
||||||
|
cset "name='Earpiece Playback Switch' off"
|
||||||
|
cset "name='Earpiece Source Playback Route' DACL"
|
||||||
|
|
||||||
|
cset "name='Line In Capture Switch' off"
|
||||||
|
cset "name='Mic1 Capture Switch' off"
|
||||||
|
cset "name='Mic1 Boost Volume' 7"
|
||||||
|
cset "name='Mic2 Capture Switch' off"
|
||||||
|
cset "name='Mic2 Boost Volume' 7"
|
||||||
|
cset "name='Mixer Capture Switch' off"
|
||||||
|
cset "name='Mixer Reversed Capture Switch' off"
|
||||||
|
cset "name='ADC Capture Volume' 160"
|
||||||
|
cset "name='ADC Gain Capture Volume' 7"
|
||||||
|
cset "name='AIF1 AD0 Capture Volume' 160"
|
||||||
|
cset "name='AIF1 Data Digital ADC Capture Switch' on"
|
||||||
|
cset "name='AIF2 ADC Mixer ADC Capture Switch' off"
|
||||||
|
cset "name='AIF2 ADC Mixer AIF1 DA0 Capture Switch' off"
|
||||||
|
cset "name='AIF2 ADC Mixer AIF2 DAC Rev Capture Switch' off"
|
||||||
|
cset "name='AIF2 ADC Mixer AIF1 DA0 Capture Switch' off"
|
||||||
|
cset "name='AIF2 ADC Mixer AIF1 DA0 Capture Switch' off"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionDevice."Speaker" {
|
||||||
|
Comment "Internal speaker"
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='AIF1 DA0 Stereo Playback Route' Mix Mono"
|
||||||
|
cset "name='Line Out Playback Switch' on"
|
||||||
|
cset "name='Line Out Playback Volume' 100%"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Line Out Playback Switch' off"
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
PlaybackVolume "Line Out Playback Volume"
|
||||||
|
PlaybackSwitch "Line Out Playback Switch"
|
||||||
|
PlaybackChannels 2
|
||||||
|
PlaybackPriority 300
|
||||||
|
PlaybackPCM "hw:${CardId},0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionDevice."Earpiece" {
|
||||||
|
Comment "Internal Earpiece"
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='AIF1 DA0 Stereo Playback Route' Mix Mono"
|
||||||
|
cset "name='Earpiece Playback Switch' on"
|
||||||
|
cset "name='Earpiece Playback Volume' 100%"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Earpiece Playback Switch' off"
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
PlaybackVolume "Earpiece Playback Volume"
|
||||||
|
PlaybackSwitch "Earpiece Playback Switch"
|
||||||
|
PlaybackChannels 2
|
||||||
|
PlaybackPriority 200
|
||||||
|
PlaybackPCM "hw:${CardId},0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionDevice."Mic" {
|
||||||
|
Comment "Internal Microphone"
|
||||||
|
ConflictingDevice [
|
||||||
|
"Headset"
|
||||||
|
]
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='Mic1 Capture Switch' on"
|
||||||
|
]
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Mic1 Capture Switch' off"
|
||||||
|
]
|
||||||
|
Value {
|
||||||
|
CapturePriority 100
|
||||||
|
CapturePCM "hw:${CardId},0"
|
||||||
|
CaptureChannels 2
|
||||||
|
CaptureMixerElem "ADC"
|
||||||
|
CaptureVolume "ADC Capture Volume"
|
||||||
|
CaptureSwitch "Mic1 Capture Switch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionDevice."Headset" {
|
||||||
|
Comment "Headset Microphone"
|
||||||
|
ConflictingDevice [
|
||||||
|
"Mic"
|
||||||
|
]
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='Mic2 Capture Switch' on"
|
||||||
|
]
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Mic2 Capture Switch' off"
|
||||||
|
]
|
||||||
|
Value {
|
||||||
|
CapturePriority 500
|
||||||
|
CapturePCM "hw:${CardId},0"
|
||||||
|
CaptureChannels 2
|
||||||
|
CaptureMixerElem "ADC"
|
||||||
|
CaptureVolume "ADC Capture Volume"
|
||||||
|
CaptureSwitch "Mic2 Capture Switch"
|
||||||
|
JackControl "Headset Microphone Jack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionDevice."Headphones" {
|
||||||
|
Comment "Headphones"
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='AIF1 DA0 Stereo Playback Route' Stereo"
|
||||||
|
cset "name='Headphone Playback Switch' on"
|
||||||
|
cset "name='Headphone Playback Volume' 70%"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Headphone Playback Switch' off"
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
PlaybackVolume "Headphone Playback Volume"
|
||||||
|
PlaybackSwitch "Headphone Playback Switch"
|
||||||
|
PlaybackChannels 2
|
||||||
|
PlaybackPriority 500
|
||||||
|
PlaybackPCM "hw:${CardId},0"
|
||||||
|
JackControl "Headphone Jack"
|
||||||
|
}
|
||||||
|
}
|
11
machines/moby/ucm2/PinePhone/PinePhone.conf
Normal file
11
machines/moby/ucm2/PinePhone/PinePhone.conf
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Syntax 2
|
||||||
|
|
||||||
|
SectionUseCase."HiFi" {
|
||||||
|
File "HiFi.conf"
|
||||||
|
Comment "Default"
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionUseCase."Voice Call" {
|
||||||
|
File "VoiceCall.conf"
|
||||||
|
Comment "Phone call"
|
||||||
|
}
|
153
machines/moby/ucm2/PinePhone/VoiceCall.conf
Normal file
153
machines/moby/ucm2/PinePhone/VoiceCall.conf
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
SectionVerb {
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='Headphone Playback Switch' off"
|
||||||
|
cset "name='Headphone Source Playback Route' DAC"
|
||||||
|
cset "name='Line In Playback Switch' off"
|
||||||
|
cset "name='Line Out Playback Switch' off"
|
||||||
|
cset "name='Line Out Source Playback Route' Mono Differential"
|
||||||
|
cset "name='Mic1 Playback Switch' off"
|
||||||
|
cset "name='Mic2 Playback Switch' off"
|
||||||
|
cset "name='AIF1 DA0 Playback Volume' 160"
|
||||||
|
cset "name='AIF2 DAC Playback Volume' 160"
|
||||||
|
cset "name='AIF3 ADC Source Capture Route' None"
|
||||||
|
cset "name='AIF2 DAC Source Playback Route' AIF2"
|
||||||
|
cset "name='DAC Playback Switch' on"
|
||||||
|
cset "name='DAC Playback Volume' 160"
|
||||||
|
cset "name='ADC Digital DAC Playback Switch' off"
|
||||||
|
cset "name='AIF1 Slot 0 Digital DAC Playback Switch' on"
|
||||||
|
cset "name='AIF2 Digital DAC Playback Switch' on"
|
||||||
|
cset "name='DAC Reversed Playback Switch' off"
|
||||||
|
cset "name='Earpiece Playback Switch' off"
|
||||||
|
cset "name='Earpiece Source Playback Route' DACL"
|
||||||
|
|
||||||
|
cset "name='Line In Capture Switch' off"
|
||||||
|
cset "name='Mic1 Capture Switch' off"
|
||||||
|
cset "name='Mic1 Boost Volume' 0"
|
||||||
|
cset "name='Mic1 Playback Volume' 7"
|
||||||
|
cset "name='Mic2 Capture Switch' off"
|
||||||
|
cset "name='Mic2 Boost Volume' 0"
|
||||||
|
cset "name='Mic2 Playback Volume' 7"
|
||||||
|
cset "name='Mixer Capture Switch' off"
|
||||||
|
cset "name='Mixer Reversed Capture Switch' off"
|
||||||
|
cset "name='ADC Capture Volume' 160"
|
||||||
|
cset "name='ADC Gain Capture Volume' 7"
|
||||||
|
cset "name='AIF1 AD0 Capture Volume' 160"
|
||||||
|
cset "name='AIF1 Data Digital ADC Capture Switch' on"
|
||||||
|
cset "name='AIF2 ADC Capture Volume' 160"
|
||||||
|
cset "name='AIF2 ADC Mixer ADC Capture Switch' on"
|
||||||
|
cset "name='AIF2 ADC Mixer AIF1 DA0 Capture Switch' off"
|
||||||
|
cset "name='AIF2 ADC Mixer AIF2 DAC Rev Capture Switch' off"
|
||||||
|
cset "name='AIF2 ADC Mixer AIF1 DA0 Capture Switch' off"
|
||||||
|
cset "name='AIF2 ADC Mixer AIF1 DA0 Capture Switch' off"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
PlaybackRate 8000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionDevice."Speaker" {
|
||||||
|
Comment "Internal speaker"
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='AIF1 DA0 Stereo Playback Route' Mix Mono"
|
||||||
|
cset "name='Line Out Playback Switch' on"
|
||||||
|
cset "name='Line Out Playback Volume' 100%"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Line Out Playback Switch' off"
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
PlaybackVolume "Line Out Playback Volume"
|
||||||
|
PlaybackSwitch "Line Out Playback Switch"
|
||||||
|
PlaybackChannels 2
|
||||||
|
PlaybackPriority 300
|
||||||
|
PlaybackPCM "hw:${CardId},0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionDevice."Earpiece" {
|
||||||
|
Comment "Internal Earpiece"
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='AIF1 DA0 Stereo Playback Route' Mix Mono"
|
||||||
|
cset "name='Earpiece Playback Switch' on"
|
||||||
|
cset "name='Earpiece Playback Volume' 100%"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Earpiece Playback Switch' off"
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
PlaybackVolume "Earpiece Playback Volume"
|
||||||
|
PlaybackSwitch "Earpiece Playback Switch"
|
||||||
|
PlaybackChannels 2
|
||||||
|
PlaybackPriority 500
|
||||||
|
PlaybackPCM "hw:${CardId},0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionDevice."Mic" {
|
||||||
|
Comment "Internal Microphone"
|
||||||
|
ConflictingDevice [
|
||||||
|
"Headset"
|
||||||
|
]
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='Mic1 Capture Switch' on"
|
||||||
|
]
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Mic1 Capture Switch' off"
|
||||||
|
]
|
||||||
|
Value {
|
||||||
|
CapturePriority 200
|
||||||
|
CapturePCM "hw:${CardId},0"
|
||||||
|
CaptureMixerElem "ADC"
|
||||||
|
CaptureVolume "ADC Capture Volume"
|
||||||
|
CaptureSwitch "Mic1 Capture Switch"
|
||||||
|
CaptureChannels 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionDevice."Headset" {
|
||||||
|
Comment "Headset Microphone"
|
||||||
|
ConflictingDevice [
|
||||||
|
"Mic"
|
||||||
|
]
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='Mic2 Capture Switch' on"
|
||||||
|
]
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Mic2 Capture Switch' off"
|
||||||
|
]
|
||||||
|
Value {
|
||||||
|
CapturePriority 500
|
||||||
|
CapturePCM "hw:${CardId},0"
|
||||||
|
CaptureChannels 2
|
||||||
|
CaptureMixerElem "ADC"
|
||||||
|
CaptureVolume "ADC Capture Volume"
|
||||||
|
CaptureSwitch "Mic2 Capture Switch"
|
||||||
|
JackControl "Headset Microphone Jack"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionDevice."Headphones" {
|
||||||
|
Comment "Headphones"
|
||||||
|
EnableSequence [
|
||||||
|
cset "name='AIF1 DA0 Stereo Playback Route' Stereo"
|
||||||
|
cset "name='Headphone Playback Switch' on"
|
||||||
|
cset "name='Headphone Playback Volume' 100%"
|
||||||
|
]
|
||||||
|
|
||||||
|
DisableSequence [
|
||||||
|
cset "name='Headphone Playback Switch' off"
|
||||||
|
]
|
||||||
|
|
||||||
|
Value {
|
||||||
|
PlaybackVolume "Headphone Playback Volume"
|
||||||
|
PlaybackSwitch "Headphone Playback Switch"
|
||||||
|
PlaybackChannels 2
|
||||||
|
PlaybackPriority 500
|
||||||
|
PlaybackPCM "hw:${CardId},0"
|
||||||
|
JackControl "Headphone Jack"
|
||||||
|
}
|
||||||
|
}
|
8
machines/moby/ucm2/ucm.conf
Normal file
8
machines/moby/ucm2/ucm.conf
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Syntax 3
|
||||||
|
|
||||||
|
UseCasePath {
|
||||||
|
legacy {
|
||||||
|
Directory "PinePhone"
|
||||||
|
File "PinePhone.conf"
|
||||||
|
}
|
||||||
|
}
|
16
machines/rescue/default.nix
Normal file
16
machines/rescue/default.nix
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./fs.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
|
sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ];
|
||||||
|
|
||||||
|
users.users.dhcpcd.uid = config.sane.allocations.dhcpcd-uid;
|
||||||
|
users.groups.dhcpcd.gid = config.sane.allocations.dhcpcd-gid;
|
||||||
|
|
||||||
|
# docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion
|
||||||
|
system.stateVersion = "21.05";
|
||||||
|
}
|
12
machines/rescue/fs.nix
Normal file
12
machines/rescue/fs.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-uuid/44445555-6666-7777-8888-999900001111";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/2222-3333";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
}
|
46
machines/servo/default.nix
Normal file
46
machines/servo/default.nix
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./fs.nix
|
||||||
|
./hardware.nix
|
||||||
|
./net.nix
|
||||||
|
./users.nix
|
||||||
|
./services
|
||||||
|
];
|
||||||
|
|
||||||
|
sane.home-manager.enable = true;
|
||||||
|
sane.home-manager.extraPackages = [
|
||||||
|
# for administering services
|
||||||
|
pkgs.matrix-synapse
|
||||||
|
pkgs.freshrss
|
||||||
|
];
|
||||||
|
sane.impermanence.enable = true;
|
||||||
|
sane.services.duplicity.enable = true;
|
||||||
|
sane.services.nixserve.enable = true;
|
||||||
|
|
||||||
|
# TODO: look into the EFI stuff
|
||||||
|
boot.loader.grub.enable = false;
|
||||||
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = false;
|
||||||
|
sane.image.extraBootFiles = [ pkgs.bootpart-u-boot-rpi-aarch64 ];
|
||||||
|
|
||||||
|
sops.secrets.duplicity_passphrase = {
|
||||||
|
sopsFile = ../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
|
# both transmission and ipfs try to set different net defaults.
|
||||||
|
# we just use the most aggressive of the two here:
|
||||||
|
boot.kernel.sysctl = {
|
||||||
|
"net.core.rmem_max" = "4194304"; # 4MB
|
||||||
|
};
|
||||||
|
|
||||||
|
# This value determines the NixOS release from which the default
|
||||||
|
# settings for stateful data, like file locations and database versions
|
||||||
|
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||||
|
# this value at the release version of the first install of this system.
|
||||||
|
# Before changing this value read the documentation for this option
|
||||||
|
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||||
|
system.stateVersion = "21.11"; # Did you read the comment?
|
||||||
|
}
|
||||||
|
|
69
machines/servo/fs.nix
Normal file
69
machines/servo/fs.nix
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# root is a tmpfs so that we have an ephemeral system ("impermanence" handles the state)
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"mode=755"
|
||||||
|
"size=1G"
|
||||||
|
"defaults"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# we need a /tmp for building large nix things
|
||||||
|
fileSystems."/tmp" = {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"size=40G"
|
||||||
|
"mode=777"
|
||||||
|
"defaults"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix" = {
|
||||||
|
device = "/dev/disk/by-uuid/aa272cff-0fcc-498e-a4cb-0d95fb60631b";
|
||||||
|
fsType = "btrfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/31D3-40CB";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# fileSystems."/var/lib/pleroma" = {
|
||||||
|
# device = "/opt/pleroma";
|
||||||
|
# options = [ "bind" ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
# in-memory compressed RAM (seems to be dynamically sized)
|
||||||
|
zramSwap = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# btrfs doesn't easily support swapfiles
|
||||||
|
# swapDevices = [
|
||||||
|
# { device = "/nix/persist/swapfile"; size = 4096; }
|
||||||
|
# ];
|
||||||
|
|
||||||
|
# this can be a partition. create with:
|
||||||
|
# fdisk <dev>
|
||||||
|
# n
|
||||||
|
# <default partno>
|
||||||
|
# <start>
|
||||||
|
# <end>
|
||||||
|
# t
|
||||||
|
# <partno>
|
||||||
|
# 19 # set part type to Linux swap
|
||||||
|
# w # write changes
|
||||||
|
# mkswap -L swap <part>
|
||||||
|
swapDevices = [
|
||||||
|
{
|
||||||
|
label = "swap";
|
||||||
|
# TODO: randomEncryption.enable = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@@ -1,26 +1,17 @@
|
|||||||
# this file originates from ‘nixos-generate-config’
|
# this file originates from ‘nixos-generate-config’
|
||||||
# but has been heavily modified
|
# but has been heavily modified
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# enables non-free firmware
|
|
||||||
hardware.enableRedistributableFirmware = true;
|
|
||||||
|
|
||||||
# i changed this becuse linux 5.10 didn't have rpi-400 device tree blob.
|
# i changed this becuse linux 5.10 didn't have rpi-400 device tree blob.
|
||||||
# nixos-22.05 linux 5.15 DOES have these now.
|
# nixos-22.05 linux 5.15 DOES have these now.
|
||||||
# it should be possible to remove this if desired, but i'm not sure how the rpi-specific kernel differs.
|
# it should be possible to remove this if desired, but i'm not sure how the rpi-specific kernel differs.
|
||||||
# see: https://github.com/raspberrypi/linux
|
# see: https://github.com/raspberrypi/linux
|
||||||
boot.kernelPackages = pkgs.linuxPackages_rpi4;
|
boot.kernelPackages = pkgs.linuxPackages_rpi4;
|
||||||
|
|
||||||
# NixOS defaults to grub: we don't want that.
|
|
||||||
boot.loader.grub.enable = false;
|
|
||||||
# raspberryPi boot loader creates extlinux.conf.
|
# raspberryPi boot loader creates extlinux.conf.
|
||||||
# otherwise, enable the generic-extlinux-compatible loader below.
|
# otherwise, enable the generic-extlinux-compatible loader below.
|
||||||
# note: THESE ARE MUTUALLY EXCLUSIVE. generic-extlinux-compatible causes uboot to not be built
|
# note: THESE ARE MUTUALLY EXCLUSIVE. generic-extlinux-compatible causes uboot to not be built
|
||||||
# boot.loader.generic-extlinux-compatible.enable = true;
|
|
||||||
boot.loader.raspberryPi.enable = true;
|
|
||||||
boot.loader.raspberryPi.uboot.enable = true;
|
|
||||||
boot.loader.raspberryPi.version = 4;
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [
|
boot.initrd.availableKernelModules = [
|
||||||
"bcm2711_thermal"
|
"bcm2711_thermal"
|
||||||
@@ -44,16 +35,6 @@
|
|||||||
"xhci_pci_renesas"
|
"xhci_pci_renesas"
|
||||||
];
|
];
|
||||||
# boot.initrd.compressor = "gzip"; # defaults to zstd
|
# boot.initrd.compressor = "gzip"; # defaults to zstd
|
||||||
# hack in the `boot.shell_on_fail` arg since it doesn't seem to work otherwise
|
|
||||||
boot.initrd.preFailCommands = "allowShell=1";
|
|
||||||
# default: 4 (warn). 7 is debug
|
|
||||||
boot.consoleLogLevel = 7;
|
|
||||||
# boot.kernelParams = [
|
|
||||||
# "boot.shell_on_fail"
|
|
||||||
# # "boot.trace"
|
|
||||||
# # "systemd.log_level=debug"
|
|
||||||
# # "systemd.log_target=console"
|
|
||||||
# ];
|
|
||||||
|
|
||||||
# ondemand power scaling keeps the cpu at low frequency when idle, and sets to max frequency
|
# ondemand power scaling keeps the cpu at low frequency when idle, and sets to max frequency
|
||||||
# when load is detected. (v.s. the "performance" default, which always uses the max frequency)
|
# when load is detected. (v.s. the "performance" default, which always uses the max frequency)
|
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, secrets, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
networking.domain = "uninsane.org";
|
networking.domain = "uninsane.org";
|
||||||
@@ -18,12 +18,15 @@
|
|||||||
80 # HTTP
|
80 # HTTP
|
||||||
143 # IMAP
|
143 # IMAP
|
||||||
443 # HTTPS
|
443 # HTTPS
|
||||||
465 # SMTPS (maybe not required?)
|
465 # SMTPS
|
||||||
587 # SMTPS/submission (maybe not required?)
|
587 # SMTPS/submission
|
||||||
993 # IMAPS
|
993 # IMAPS
|
||||||
|
4001 # IPFS
|
||||||
|
];
|
||||||
|
networking.firewall.allowedUDPPorts = [
|
||||||
|
1900 7359 # DLNA: https://jellyfin.org/docs/general/networking/index.html
|
||||||
|
4001 # IPFS
|
||||||
];
|
];
|
||||||
# DLNA ports: https://jellyfin.org/docs/general/networking/index.html
|
|
||||||
networking.firewall.allowedUDPPorts = [ 1900 7359 ];
|
|
||||||
|
|
||||||
# we need to use externally-visible nameservers in order for VPNs to be able to resolve hosts.
|
# we need to use externally-visible nameservers in order for VPNs to be able to resolve hosts.
|
||||||
networking.nameservers = [
|
networking.nameservers = [
|
||||||
@@ -35,7 +38,7 @@
|
|||||||
# DOCS: https://nixos.wiki/wiki/WireGuard
|
# DOCS: https://nixos.wiki/wiki/WireGuard
|
||||||
networking.wireguard.enable = true;
|
networking.wireguard.enable = true;
|
||||||
networking.wireguard.interfaces.wg0 = {
|
networking.wireguard.interfaces.wg0 = {
|
||||||
privateKey = secrets.wireguard.privateKey;
|
privateKeyFile = config.sops.secrets.wg_ovpns_privkey.path;
|
||||||
# wg is active only in this namespace.
|
# wg is active only in this namespace.
|
||||||
# run e.g. ip netns exec ovpns <some command like ping/curl/etc, it'll go through wg>
|
# run e.g. ip netns exec ovpns <some command like ping/curl/etc, it'll go through wg>
|
||||||
# sudo ip netns exec ovpns ping www.google.com
|
# sudo ip netns exec ovpns ping www.google.com
|
||||||
@@ -87,6 +90,10 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sops.secrets."wg_ovpns_privkey" = {
|
||||||
|
sopsFile = ../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
|
||||||
# HURRICANE ELECTRIC CONFIG:
|
# HURRICANE ELECTRIC CONFIG:
|
||||||
# networking.sits = {
|
# networking.sits = {
|
||||||
# hurricane = {
|
# hurricane = {
|
32
machines/servo/services/ddns-he.nix
Normal file
32
machines/servo/services/ddns-he.nix
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
systemd.services.ddns-he = {
|
||||||
|
description = "update dynamic DNS entries for HurricaneElectric";
|
||||||
|
serviceConfig = {
|
||||||
|
EnvironmentFile = config.sops.secrets.ddns_he.path;
|
||||||
|
# TODO: ProtectSystem = "strict";
|
||||||
|
# TODO: ProtectHome = "full";
|
||||||
|
# TODO: PrivateTmp = true;
|
||||||
|
};
|
||||||
|
# HE DDNS API is documented: https://dns.he.net/docs.html
|
||||||
|
script = let
|
||||||
|
crl = "${pkgs.curl}/bin/curl -4";
|
||||||
|
in ''
|
||||||
|
${crl} "https://he.uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=he.uninsane.org"
|
||||||
|
${crl} "https://native.uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=native.uninsane.org"
|
||||||
|
${crl} "https://uninsane.org:$HE_PASSPHRASE@dyn.dns.he.net/nic/update?hostname=uninsane.org"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
systemd.timers.ddns-he = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnStartupSec = "2min";
|
||||||
|
OnUnitActiveSec = "10min";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."ddns_he" = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
};
|
||||||
|
}
|
19
machines/servo/services/default.nix
Normal file
19
machines/servo/services/default.nix
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./ddns-he.nix
|
||||||
|
./freshrss.nix
|
||||||
|
./gitea.nix
|
||||||
|
./ipfs.nix
|
||||||
|
./jackett.nix
|
||||||
|
./jellyfin.nix
|
||||||
|
./matrix
|
||||||
|
./munin.nix
|
||||||
|
./navidrome.nix
|
||||||
|
./nginx.nix
|
||||||
|
./pleroma.nix
|
||||||
|
./postfix.nix
|
||||||
|
./postgres.nix
|
||||||
|
./transmission.nix
|
||||||
|
];
|
||||||
|
}
|
48
machines/servo/services/freshrss.nix
Normal file
48
machines/servo/services/freshrss.nix
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# import feeds with e.g.
|
||||||
|
# ```console
|
||||||
|
# $ nix build '.#nixpkgs.freshrss'
|
||||||
|
# $ sudo -u freshrss -g freshrss FRESHRSS_DATA_PATH=/var/lib/freshrss ./result/cli/import-for-user.php --user admin --filename /home/colin/.config/newsflashFeeds.opml
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# export feeds with
|
||||||
|
# ```console
|
||||||
|
# $ sudo -u freshrss -g freshrss FRESHRSS_DATA_PATH=/var/lib/freshrss ./result/cli/export-opml-for-user.php --user admin
|
||||||
|
# ```
|
||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
sops.secrets.freshrss_passwd = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
owner = config.users.users.freshrss.name;
|
||||||
|
mode = "400";
|
||||||
|
};
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
{ user = "freshrss"; group = "freshrss"; directory = "/var/lib/freshrss"; }
|
||||||
|
];
|
||||||
|
|
||||||
|
users.users.freshrss.uid = config.sane.allocations.freshrss-uid;
|
||||||
|
users.groups.freshrss.gid = config.sane.allocations.freshrss-gid;
|
||||||
|
services.freshrss.enable = true;
|
||||||
|
services.freshrss.baseUrl = "https://rss.uninsane.org";
|
||||||
|
services.freshrss.virtualHost = "rss.uninsane.org";
|
||||||
|
services.freshrss.passwordFile = config.sops.secrets.freshrss_passwd.path;
|
||||||
|
|
||||||
|
systemd.services.freshrss-import-feeds =
|
||||||
|
let
|
||||||
|
fresh = config.systemd.services.freshrss-config;
|
||||||
|
feeds = import ../../../modules/universal/env/feeds.nix { inherit lib; };
|
||||||
|
opml = pkgs.writeText "sane-freshrss.opml" (feeds.feedsToOpml feeds.all);
|
||||||
|
in {
|
||||||
|
inherit (fresh) wantedBy environment;
|
||||||
|
serviceConfig = {
|
||||||
|
inherit (fresh.serviceConfig) Type User Group StateDirectory WorkingDirectory
|
||||||
|
# hardening options
|
||||||
|
CapabilityBoundingSet DeviceAllow LockPersonality NoNewPrivileges PrivateDevices PrivateTmp PrivateUsers ProcSubset ProtectClock ProtectControlGroups ProtectHome ProtectHostname ProtectKernelLogs ProtectKernelModules ProtectKernelTunables ProtectProc ProtectSystem RemoveIPC RestrictNamespaces RestrictRealtime RestrictSUIDSGID SystemCallArchitectures SystemCallFilter UMask;
|
||||||
|
};
|
||||||
|
description = "import sane RSS feed list";
|
||||||
|
after = [ "freshrss-config.service" ];
|
||||||
|
script = ''
|
||||||
|
${pkgs.freshrss}/cli/import-for-user.php --user admin --filename ${opml}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
@@ -1,6 +1,11 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode? could be more granular
|
||||||
|
{ user = "git"; group = "gitea"; directory = "/var/lib/gitea"; }
|
||||||
|
];
|
||||||
|
users.groups.gitea.gid = config.sane.allocations.gitea-gid;
|
||||||
services.gitea.enable = true;
|
services.gitea.enable = true;
|
||||||
services.gitea.user = "git"; # default is 'gitea'
|
services.gitea.user = "git"; # default is 'gitea'
|
||||||
services.gitea.database.type = "postgres";
|
services.gitea.database.type = "postgres";
|
||||||
@@ -8,7 +13,7 @@
|
|||||||
services.gitea.appName = "Perfectly Sane Git";
|
services.gitea.appName = "Perfectly Sane Git";
|
||||||
services.gitea.domain = "git.uninsane.org";
|
services.gitea.domain = "git.uninsane.org";
|
||||||
services.gitea.rootUrl = "https://git.uninsane.org/";
|
services.gitea.rootUrl = "https://git.uninsane.org/";
|
||||||
services.gitea.cookieSecure = true;
|
services.gitea.settings.session.COOKIE_SECURE = true;
|
||||||
# services.gitea.disableRegistration = true;
|
# services.gitea.disableRegistration = true;
|
||||||
|
|
||||||
services.gitea.settings = {
|
services.gitea.settings = {
|
||||||
@@ -55,7 +60,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
# options: "Trace", "Debug", "Info", "Warn", "Error", "Critical"
|
# options: "Trace", "Debug", "Info", "Warn", "Error", "Critical"
|
||||||
services.gitea.log.level = "Info";
|
services.gitea.settings.log.LEVEL = "Warn";
|
||||||
|
|
||||||
systemd.services.gitea.serviceConfig = {
|
systemd.services.gitea.serviceConfig = {
|
||||||
# nix default is AF_UNIX AF_INET AF_INET6.
|
# nix default is AF_UNIX AF_INET AF_INET6.
|
69
machines/servo/services/ipfs.nix
Normal file
69
machines/servo/services/ipfs.nix
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# admin:
|
||||||
|
# - view stats:
|
||||||
|
# - sudo -u ipfs -g ipfs ipfs -c /var/lib/ipfs/ stats bw
|
||||||
|
# - sudo -u ipfs -g ipfs ipfs -c /var/lib/ipfs/ stats dht
|
||||||
|
# - sudo -u ipfs -g ipfs ipfs -c /var/lib/ipfs/ bitswap stat
|
||||||
|
# - number of open peer connections:
|
||||||
|
# - sudo -u ipfs -g ipfs ipfs -c /var/lib/ipfs/ swarm peers | wc -l
|
||||||
|
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode? could be more granular
|
||||||
|
{ user = "261"; group = "261"; directory = "/var/lib/ipfs"; }
|
||||||
|
];
|
||||||
|
# services.ipfs.enable = true;
|
||||||
|
services.kubo.localDiscovery = true;
|
||||||
|
services.kubo.swarmAddress = [
|
||||||
|
# "/dns4/ipfs.uninsane.org/tcp/4001"
|
||||||
|
# "/ip4/0.0.0.0/tcp/4001"
|
||||||
|
"/dns4/ipfs.uninsane.org/udp/4001/quic"
|
||||||
|
"/ip4/0.0.0.0/udp/4001/quic"
|
||||||
|
];
|
||||||
|
services.kubo.extraConfig = {
|
||||||
|
Addresses = {
|
||||||
|
Announce = [
|
||||||
|
# "/dns4/ipfs.uninsane.org/tcp/4001"
|
||||||
|
"/dns4/ipfs.uninsane.org/udp/4001/quic"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
Gateway = {
|
||||||
|
# the gateway can only be used to serve content already replicated on this host
|
||||||
|
NoFetch = true;
|
||||||
|
};
|
||||||
|
Swarm = {
|
||||||
|
ConnMgr = {
|
||||||
|
# maintain between LowWater and HighWater peer connections
|
||||||
|
# taken from: https://github.com/ipfs/ipfs-desktop/pull/2055
|
||||||
|
# defaults are 600-900: https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmconnmgr
|
||||||
|
LowWater = 20;
|
||||||
|
HighWater = 40;
|
||||||
|
# default is 20s. i guess more grace period = less churn
|
||||||
|
GracePeriod = "1m";
|
||||||
|
};
|
||||||
|
ResourceMgr = {
|
||||||
|
# docs: https://github.com/libp2p/go-libp2p-resource-manager#resource-scopes
|
||||||
|
Enabled = true;
|
||||||
|
Limits = {
|
||||||
|
System = {
|
||||||
|
Conns = 196;
|
||||||
|
ConnsInbound = 128;
|
||||||
|
ConnsOutbound = 128;
|
||||||
|
FD = 512;
|
||||||
|
Memory = 1073741824; # 1GiB
|
||||||
|
Streams = 1536;
|
||||||
|
StreamsInbound = 1024;
|
||||||
|
StreamsOutbound = 1024;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Transports = {
|
||||||
|
Network = {
|
||||||
|
# disable TCP, force QUIC, for lighter resources
|
||||||
|
TCP = false;
|
||||||
|
QUIC = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@@ -1,6 +1,10 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode? we only need this to save Indexer creds ==> migrate to config?
|
||||||
|
{ user = "root"; group = "root"; directory = "/var/lib/jackett"; }
|
||||||
|
];
|
||||||
services.jackett.enable = true;
|
services.jackett.enable = true;
|
||||||
|
|
||||||
systemd.services.jackett.after = ["wg0veth.service"];
|
systemd.services.jackett.after = ["wg0veth.service"];
|
14
machines/servo/services/jellyfin.nix
Normal file
14
machines/servo/services/jellyfin.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode? could be more granular
|
||||||
|
{ user = "jellyfin"; group = "jellyfin"; directory = "/var/lib/jellyfin"; }
|
||||||
|
];
|
||||||
|
|
||||||
|
# users.users.jellyfin.uid = config.sane.allocations.jellyfin-uid;
|
||||||
|
# users.groups.jellyfin.gid = config.sane.allocations.jellyfin-gid;
|
||||||
|
# TODO: re-enable after migrating media dir to /var/lib/uninsane/media
|
||||||
|
# else it's too spammy
|
||||||
|
# services.jellyfin.enable = true;
|
||||||
|
}
|
85
machines/servo/services/matrix/default.nix
Normal file
85
machines/servo/services/matrix/default.nix
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# docs: https://nixos.wiki/wiki/Matrix
|
||||||
|
# docs: https://nixos.org/manual/nixos/stable/index.html#module-services-matrix-synapse
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./discord-puppet.nix
|
||||||
|
# ./irc.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
{ user = "matrix-synapse"; group = "matrix-synapse"; directory = "/var/lib/matrix-synapse"; }
|
||||||
|
];
|
||||||
|
services.matrix-synapse.enable = true;
|
||||||
|
services.matrix-synapse.settings.log_config = ./synapse-log_level.yaml;
|
||||||
|
services.matrix-synapse.settings.server_name = "uninsane.org";
|
||||||
|
|
||||||
|
# services.matrix-synapse.enable_registration_captcha = true;
|
||||||
|
# services.matrix-synapse.enable_registration_without_verification = true;
|
||||||
|
services.matrix-synapse.settings.enable_registration = true;
|
||||||
|
# services.matrix-synapse.registration_shared_secret = "<shared key goes here>";
|
||||||
|
|
||||||
|
# default for listeners is port = 8448, tls = true, x_forwarded = false.
|
||||||
|
# we change this because the server is situated behind nginx.
|
||||||
|
services.matrix-synapse.settings.listeners = [
|
||||||
|
{
|
||||||
|
port = 8008;
|
||||||
|
bind_addresses = [ "127.0.0.1" ];
|
||||||
|
type = "http";
|
||||||
|
tls = false;
|
||||||
|
x_forwarded = true;
|
||||||
|
resources = [
|
||||||
|
{
|
||||||
|
names = [ "client" "federation" ];
|
||||||
|
compress = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.matrix-synapse.settings.admin_contact = "admin.matrix@uninsane.org";
|
||||||
|
services.matrix-synapse.settings.registrations_require_3pid = [ "email" ];
|
||||||
|
|
||||||
|
services.matrix-synapse.extraConfigFiles = [
|
||||||
|
config.sops.secrets.matrix_synapse_secrets.path
|
||||||
|
];
|
||||||
|
|
||||||
|
# services.matrix-synapse.extraConfigFiles = [builtins.toFile "matrix-synapse-extra-config" ''
|
||||||
|
# admin_contact: "admin.matrix@uninsane.org"
|
||||||
|
# registrations_require_3pid:
|
||||||
|
# - email
|
||||||
|
# email:
|
||||||
|
# smtp_host: "mx.uninsane.org"
|
||||||
|
# smtp_port: 587
|
||||||
|
# smtp_user: "matrix-synapse"
|
||||||
|
# smtp_pass: "${secrets.matrix-synapse.smtp_pass}"
|
||||||
|
# require_transport_security: true
|
||||||
|
# enable_tls: true
|
||||||
|
# notif_from: "%(app)s <notify.matrix@uninsane.org>"
|
||||||
|
# app_name: "Uninsane Matrix"
|
||||||
|
# enable_notifs: true
|
||||||
|
# validation_token_lifetime: 96h
|
||||||
|
# invite_client_location: "https://web.matrix.uninsane.org"
|
||||||
|
# subjects:
|
||||||
|
# email_validation: "[%(server_name)s] Validate your email"
|
||||||
|
# ''];
|
||||||
|
|
||||||
|
# new users may be registered on the CLI:
|
||||||
|
# register_new_matrix_user -c /nix/store/8n6kcka37jhmi4qpd2r03aj71pkyh21s-homeserver.yaml http://localhost:8008
|
||||||
|
#
|
||||||
|
# or provide an registration token then can use to register through the client.
|
||||||
|
# docs: https://github.com/matrix-org/synapse/blob/develop/docs/usage/administration/admin_api/registration_tokens.md
|
||||||
|
# first, grab your own user's access token (Help & About section in Element). then:
|
||||||
|
# curl --header "Authorization: Bearer <my_token>" localhost:8008/_synapse/admin/v1/registration_tokens
|
||||||
|
# create a token with unlimited uses:
|
||||||
|
# curl -d '{}' --header "Authorization: Bearer <my_token>" localhost:8008/_synapse/admin/v1/registration_tokens/new
|
||||||
|
# create a token with limited uses:
|
||||||
|
# curl -d '{ "uses_allowed": 1 }' --header "Authorization: Bearer <my_token>" localhost:8008/_synapse/admin/v1/registration_tokens/new
|
||||||
|
|
||||||
|
|
||||||
|
sops.secrets.matrix_synapse_secrets = {
|
||||||
|
sopsFile = ../../../../secrets/servo.yaml;
|
||||||
|
owner = config.users.users.matrix-synapse.name;
|
||||||
|
};
|
||||||
|
}
|
52
machines/servo/services/matrix/discord-puppet.nix
Normal file
52
machines/servo/services/matrix/discord-puppet.nix
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
{ user = "matrix-synapse"; group = "matrix-synapse"; directory = "/var/lib/mx-puppet-discord"; }
|
||||||
|
];
|
||||||
|
|
||||||
|
services.matrix-synapse.settings.app_service_config_files = [
|
||||||
|
# auto-created by mx-puppet-discord service
|
||||||
|
"/var/lib/mx-puppet-discord/discord-registration.yaml"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.mx-puppet-discord.enable = true;
|
||||||
|
# schema/example: <https://gitlab.com/mx-puppet/discord/mx-puppet-discord/-/blob/main/sample.config.yaml>
|
||||||
|
services.mx-puppet-discord.settings = {
|
||||||
|
bridge = {
|
||||||
|
# port = 8434
|
||||||
|
bindAddress = "127.0.0.1";
|
||||||
|
domain = "uninsane.org";
|
||||||
|
homeserverUrl = "http://127.0.0.1:8008";
|
||||||
|
# displayName = "mx-discord-puppet"; # matrix name for the bot
|
||||||
|
# matrix "groups" were an earlier version of spaces.
|
||||||
|
# maybe the puppet understands this, maybe not?
|
||||||
|
enableGroupSync = false;
|
||||||
|
};
|
||||||
|
presence = {
|
||||||
|
enabled = false;
|
||||||
|
interval = 30000;
|
||||||
|
};
|
||||||
|
provisioning = {
|
||||||
|
# allow these users to control the puppet
|
||||||
|
whitelist = [ "@colin:uninsane\\.org" ];
|
||||||
|
};
|
||||||
|
relay = {
|
||||||
|
whitelist = [ "@colin:uninsane\\.org" ];
|
||||||
|
};
|
||||||
|
selfService = {
|
||||||
|
# who's allowed to use plumbed rooms (idk what that means)
|
||||||
|
whitelist = [ "@colin:uninsane\\.org" ];
|
||||||
|
};
|
||||||
|
logging = {
|
||||||
|
# silly, debug, verbose, info, warn, error
|
||||||
|
console = "debug";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.mx-puppet-discord.serviceConfig = {
|
||||||
|
# fix up to not use /var/lib/private, but just /var/lib
|
||||||
|
DynamicUser = lib.mkForce false;
|
||||||
|
User = "matrix-synapse";
|
||||||
|
Group = "matrix-synapse";
|
||||||
|
};
|
||||||
|
}
|
97
machines/servo/services/matrix/irc.nix
Normal file
97
machines/servo/services/matrix/irc.nix
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode?
|
||||||
|
# user and group are both "matrix-appservice-irc"
|
||||||
|
{ user = "993"; group = "992"; directory = "/var/lib/matrix-appservice-irc"; }
|
||||||
|
];
|
||||||
|
|
||||||
|
services.matrix-synapse.settings.app_service_config_files = [
|
||||||
|
"/var/lib/matrix-appservice-irc/registration.yml" # auto-created by irc appservice
|
||||||
|
];
|
||||||
|
|
||||||
|
# note: Rizon allows only FOUR simultaneous IRC connections per IP: https://wiki.rizon.net/index.php?title=Connection/Session_Limit_Exemptions
|
||||||
|
# Rizon supports CertFP for auth: https://wiki.rizon.net/index.php?title=CertFP
|
||||||
|
services.matrix-appservice-irc.enable = true;
|
||||||
|
services.matrix-appservice-irc.registrationUrl = "http://127.0.0.1:8009";
|
||||||
|
# settings documented here: https://github.com/matrix-org/matrix-appservice-irc/blob/develop/config.sample.yaml
|
||||||
|
services.matrix-appservice-irc.settings = {
|
||||||
|
homeserver = {
|
||||||
|
url = "http://127.0.0.1:8008";
|
||||||
|
dropMatrixMessagesAfterSecs = 300;
|
||||||
|
domain = "uninsane.org";
|
||||||
|
enablePresence = true;
|
||||||
|
bindPort = 9999;
|
||||||
|
bindHost = "127.0.0.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
ircService = {
|
||||||
|
servers = {
|
||||||
|
"irc.rizon.net" = {
|
||||||
|
name = "Rizon";
|
||||||
|
port = 6697; # SSL port
|
||||||
|
ssl = true;
|
||||||
|
sasl = true; # appservice doesn't support NickServ identification
|
||||||
|
botConfig = {
|
||||||
|
# bot has no presence in IRC channel; only real Matrix users
|
||||||
|
enabled = false;
|
||||||
|
# nick = "UninsaneDotOrg";
|
||||||
|
nick = "uninsane";
|
||||||
|
username = "uninsane";
|
||||||
|
};
|
||||||
|
dynamicChannels = {
|
||||||
|
enabled = true;
|
||||||
|
aliasTemplate = "#irc_rizon_$CHANNEL";
|
||||||
|
};
|
||||||
|
ircClients = {
|
||||||
|
nickTemplate = "$LOCALPARTsane";
|
||||||
|
# by default, Matrix will convert messages greater than (3) lines into a pastebin-like URL to send to IRC.
|
||||||
|
lineLimit = 20;
|
||||||
|
};
|
||||||
|
matrixClients = {
|
||||||
|
userTemplate = "@irc_rizon_$NICK"; # the :uninsane.org part is appended automatically
|
||||||
|
};
|
||||||
|
|
||||||
|
# this will let this user message the appservice with `!join #<IRCChannel>` and the rest "Just Works"
|
||||||
|
"@colin:uninsane.org" = "admin";
|
||||||
|
|
||||||
|
membershipLists = {
|
||||||
|
enabled = true;
|
||||||
|
global = {
|
||||||
|
ircToMatrix = {
|
||||||
|
initial = true;
|
||||||
|
incremental = true;
|
||||||
|
requireMatrixJoined = false;
|
||||||
|
};
|
||||||
|
matrixToIrc = {
|
||||||
|
initial = true;
|
||||||
|
incremental = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# sync room description?
|
||||||
|
bridgeInfoState = {
|
||||||
|
enabled = true;
|
||||||
|
initial = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# hardcoded mappings, for when dynamicChannels fails us. TODO: probably safe to remove these.
|
||||||
|
# mappings = {
|
||||||
|
# "#chat" = {
|
||||||
|
# roomIds = [ "!GXJSOTdbtxRboGtDep:uninsane.org" ];
|
||||||
|
# };
|
||||||
|
# # BakaBT requires account registration, which i think means my user needs to be added before the appservice user
|
||||||
|
# "#BakaBT" = {
|
||||||
|
# roomIds = [ "!feZKttuYuHilqPFSkD:uninsane.org" ];
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# for per-user IRC password:
|
||||||
|
# invite @irc_rizon_NickServ:uninsane.org to a DM and type `help` => register
|
||||||
|
# invite the matrix-appservice-irc user to a DM and type `!help` => add PW to database
|
||||||
|
# passwordEncryptionKeyPath = "/path/to/privkey"; # appservice will generate its own if unspecified
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
27
machines/servo/services/matrix/synapse-log_level.yaml
Normal file
27
machines/servo/services/matrix/synapse-log_level.yaml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
version: 1
|
||||||
|
|
||||||
|
# In systemd's journal, loglevel is implicitly stored, so let's omit it
|
||||||
|
# from the message text.
|
||||||
|
formatters:
|
||||||
|
journal_fmt:
|
||||||
|
format: '%(name)s: [%(request)s] %(message)s'
|
||||||
|
|
||||||
|
filters:
|
||||||
|
context:
|
||||||
|
(): synapse.util.logcontext.LoggingContextFilter
|
||||||
|
request: ""
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
journal:
|
||||||
|
class: systemd.journal.JournalHandler
|
||||||
|
formatter: journal_fmt
|
||||||
|
filters: [context]
|
||||||
|
SYSLOG_IDENTIFIER: synapse
|
||||||
|
|
||||||
|
# default log level: INFO
|
||||||
|
root:
|
||||||
|
level: WARN
|
||||||
|
handlers: [journal]
|
||||||
|
|
||||||
|
disable_existing_loggers: False
|
||||||
|
|
12
machines/servo/services/munin.nix
Normal file
12
machines/servo/services/munin.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
services.munin-node.enable = true;
|
||||||
|
services.munin-cron = {
|
||||||
|
enable = true;
|
||||||
|
# collect data from the localhost
|
||||||
|
hosts = ''
|
||||||
|
[${config.networking.hostName}]
|
||||||
|
address localhost
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
17
machines/servo/services/navidrome.nix
Normal file
17
machines/servo/services/navidrome.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
{ user = "navidrome"; group = "navidrome"; directory = "/var/lib/private/navidrome"; }
|
||||||
|
];
|
||||||
|
services.navidrome.enable = true;
|
||||||
|
services.navidrome.settings = {
|
||||||
|
# docs: https://www.navidrome.org/docs/usage/configuration-options/
|
||||||
|
Address = "127.0.0.1";
|
||||||
|
Port = 4533;
|
||||||
|
MusicFolder = "/var/lib/uninsane/media/Music";
|
||||||
|
CovertArtPriority = "*.jpg, *.JPG, *.png, *.PNG, embedded";
|
||||||
|
AutoImportPlaylists = false;
|
||||||
|
ScanSchedule = "@every 1h";
|
||||||
|
};
|
||||||
|
}
|
@@ -6,10 +6,17 @@
|
|||||||
|
|
||||||
# web blog/personal site
|
# web blog/personal site
|
||||||
services.nginx.virtualHosts."uninsane.org" = {
|
services.nginx.virtualHosts."uninsane.org" = {
|
||||||
root = "/opt/uninsane/root";
|
root = "${pkgs.uninsane-dot-org}/share/uninsane-dot-org";
|
||||||
addSSL = true;
|
# a lot of places hardcode https://uninsane.org,
|
||||||
|
# and then when we mix http + non-https, we get CORS violations
|
||||||
|
# and things don't look right. so force SSL.
|
||||||
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
|
||||||
|
# uninsane.org/share/foo => /var/lib/uninsane/root/share/foo.
|
||||||
|
# yes, nginx does not strip the prefix when evaluating against the root.
|
||||||
|
locations."/share".root = "/var/lib/uninsane/root";
|
||||||
|
|
||||||
# allow matrix users to discover that @user:uninsane.org is reachable via matrix.uninsane.org
|
# allow matrix users to discover that @user:uninsane.org is reachable via matrix.uninsane.org
|
||||||
locations."= /.well-known/matrix/server".extraConfig =
|
locations."= /.well-known/matrix/server".extraConfig =
|
||||||
let
|
let
|
||||||
@@ -50,6 +57,13 @@
|
|||||||
# };
|
# };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# server statistics
|
||||||
|
services.nginx.virtualHosts."sink.uninsane.org" = {
|
||||||
|
addSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
root = "/var/www/munin";
|
||||||
|
};
|
||||||
|
|
||||||
# Pleroma server and web interface
|
# Pleroma server and web interface
|
||||||
services.nginx.virtualHosts."fed.uninsane.org" = {
|
services.nginx.virtualHosts."fed.uninsane.org" = {
|
||||||
addSSL = true;
|
addSSL = true;
|
||||||
@@ -210,6 +224,35 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."music.uninsane.org" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:4533";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."rss.uninsane.org" = {
|
||||||
|
addSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
# the routing is handled by freshrss.nix
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."ipfs.uninsane.org" = {
|
||||||
|
# don't default to ssl upgrades, since this may be dnslink'd from a different domain.
|
||||||
|
# ideally we'd disable ssl entirely, but some places assume it?
|
||||||
|
addSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
|
||||||
|
default = true;
|
||||||
|
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:8080";
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Ipfs-Gateway-Prefix "";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# exists only to manage certs for dovecot
|
# exists only to manage certs for dovecot
|
||||||
services.nginx.virtualHosts."imap.uninsane.org" = {
|
services.nginx.virtualHosts."imap.uninsane.org" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
@@ -234,4 +277,12 @@
|
|||||||
|
|
||||||
security.acme.acceptTerms = true;
|
security.acme.acceptTerms = true;
|
||||||
security.acme.defaults.email = "admin.acme@uninsane.org";
|
security.acme.defaults.email = "admin.acme@uninsane.org";
|
||||||
|
|
||||||
|
users.users.acme.uid = config.sane.allocations.acme-uid;
|
||||||
|
users.groups.acme.gid = config.sane.allocations.acme-gid;
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode?
|
||||||
|
{ user = "acme"; group = "acme"; directory = "/var/lib/acme"; }
|
||||||
|
{ user = "colin"; group = "users"; directory = "/var/lib/uninsane"; }
|
||||||
|
];
|
||||||
}
|
}
|
@@ -1,21 +1,26 @@
|
|||||||
# docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/pleroma.nix
|
# docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/pleroma.nix
|
||||||
#
|
#
|
||||||
# to run it in a oci-container: https://github.com/barrucadu/nixfiles/blob/master/services/pleroma.nix
|
# to run it in a oci-container: https://github.com/barrucadu/nixfiles/blob/master/services/pleroma.nix
|
||||||
{ config, pkgs, lib, secrets, ... }:
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode? could be more granular
|
||||||
|
{ user = "pleroma"; group = "pleroma"; directory = "/var/lib/pleroma"; }
|
||||||
|
];
|
||||||
|
users.users.pleroma.uid = config.sane.allocations.pleroma-uid;
|
||||||
|
users.groups.pleroma.gid = config.sane.allocations.pleroma-gid;
|
||||||
services.pleroma.enable = true;
|
services.pleroma.enable = true;
|
||||||
# TODO: we should write a config file somewhere outside the store... somehow.
|
services.pleroma.secretConfigFile = config.sops.secrets.pleroma_secrets.path;
|
||||||
services.pleroma.secretConfigFile = "/dev/null";
|
|
||||||
services.pleroma.configs = [
|
services.pleroma.configs = [
|
||||||
''
|
''
|
||||||
import Config
|
import Config
|
||||||
|
|
||||||
config :pleroma, Pleroma.Web.Endpoint,
|
config :pleroma, Pleroma.Web.Endpoint,
|
||||||
url: [host: "fed.uninsane.org", scheme: "https", port: 443],
|
url: [host: "fed.uninsane.org", scheme: "https", port: 443],
|
||||||
http: [ip: {127, 0, 0, 1}, port: 4000],
|
http: [ip: {127, 0, 0, 1}, port: 4000]
|
||||||
secret_key_base: "${secrets.pleroma.secret_key_base}",
|
# secret_key_base: "{secrets.pleroma.secret_key_base}",
|
||||||
signing_salt: "${secrets.pleroma.signing_salt}"
|
# signing_salt: "{secrets.pleroma.signing_salt}"
|
||||||
|
|
||||||
config :pleroma, :instance,
|
config :pleroma, :instance,
|
||||||
name: "Perfectly Sane",
|
name: "Perfectly Sane",
|
||||||
@@ -46,7 +51,6 @@
|
|||||||
config :pleroma, Pleroma.Repo,
|
config :pleroma, Pleroma.Repo,
|
||||||
adapter: Ecto.Adapters.Postgres,
|
adapter: Ecto.Adapters.Postgres,
|
||||||
username: "pleroma",
|
username: "pleroma",
|
||||||
password: "${secrets.pleroma.db_password}",
|
|
||||||
database: "pleroma",
|
database: "pleroma",
|
||||||
hostname: "localhost",
|
hostname: "localhost",
|
||||||
pool_size: 10,
|
pool_size: 10,
|
||||||
@@ -54,14 +58,15 @@
|
|||||||
parameters: [
|
parameters: [
|
||||||
plan_cache_mode: "force_custom_plan"
|
plan_cache_mode: "force_custom_plan"
|
||||||
]
|
]
|
||||||
|
# password: "{secrets.pleroma.db_password}",
|
||||||
|
|
||||||
# Configure web push notifications
|
# Configure web push notifications
|
||||||
config :web_push_encryption, :vapid_details,
|
config :web_push_encryption, :vapid_details,
|
||||||
subject: "mailto:notify.pleroma@uninsane.org",
|
subject: "mailto:notify.pleroma@uninsane.org"
|
||||||
public_key: "${secrets.pleroma.vapid_public_key}",
|
# public_key: "{secrets.pleroma.vapid_public_key}",
|
||||||
private_key: "${secrets.pleroma.vapid_private_key}"
|
# private_key: "{secrets.pleroma.vapid_private_key}"
|
||||||
|
|
||||||
config :joken, default_signer: "${secrets.pleroma.joken_default_signer}"
|
# config :joken, default_signer: "{secrets.pleroma.joken_default_signer}"
|
||||||
|
|
||||||
config :pleroma, :database, rum_enabled: false
|
config :pleroma, :database, rum_enabled: false
|
||||||
config :pleroma, :instance, static_dir: "/var/lib/pleroma/instance/static"
|
config :pleroma, :instance, static_dir: "/var/lib/pleroma/instance/static"
|
||||||
@@ -124,4 +129,9 @@
|
|||||||
# PrivateTmp = lib.mkForce false;
|
# PrivateTmp = lib.mkForce false;
|
||||||
# CapabilityBoundingSet = lib.mkForce "~";
|
# CapabilityBoundingSet = lib.mkForce "~";
|
||||||
# };
|
# };
|
||||||
|
|
||||||
|
sops.secrets.pleroma_secrets = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
owner = config.users.users.pleroma.name;
|
||||||
|
};
|
||||||
}
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, lib, secrets, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
submissionOptions = {
|
submissionOptions = {
|
||||||
@@ -16,6 +16,11 @@ let
|
|||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode? could be more granular
|
||||||
|
{ user = "opendkim"; group = "opendkim"; directory = "/var/lib/opendkim"; }
|
||||||
|
{ user = "root"; group = "root"; directory = "/var/lib/postfix"; }
|
||||||
|
];
|
||||||
services.postfix.enable = true;
|
services.postfix.enable = true;
|
||||||
services.postfix.hostname = "mx.uninsane.org";
|
services.postfix.hostname = "mx.uninsane.org";
|
||||||
services.postfix.origin = "uninsane.org";
|
services.postfix.origin = "uninsane.org";
|
||||||
@@ -82,10 +87,7 @@ in
|
|||||||
services.dovecot2.enablePAM = false;
|
services.dovecot2.enablePAM = false;
|
||||||
services.dovecot2.extraConfig =
|
services.dovecot2.extraConfig =
|
||||||
let
|
let
|
||||||
passwdFile = builtins.toFile "dovecot-passwd-file" ''
|
passwdFile = config.sops.secrets.dovecot_passwd.path;
|
||||||
colin:${secrets.dovecot.hashedPasswd.colin}:1000:1000::/var/mail/colin/run/current-system/sw/bin/nologin:
|
|
||||||
matrix-synapse:${secrets.dovecot.hashedPasswd.matrix-synapse}:224:224::/var/mail/colin:/run/current-system/sw/bin/nologin:
|
|
||||||
'';
|
|
||||||
in
|
in
|
||||||
''
|
''
|
||||||
passdb {
|
passdb {
|
||||||
@@ -133,4 +135,11 @@ in
|
|||||||
# pattern = "/^Subject:.*activate your account/";
|
# pattern = "/^Subject:.*activate your account/";
|
||||||
# }
|
# }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
sops.secrets.dovecot_passwd = {
|
||||||
|
sopsFile = ../../../secrets/servo.yaml;
|
||||||
|
owner = config.users.users.dovecot2.name;
|
||||||
|
# TODO: debug why mail can't be sent without this being world-readable
|
||||||
|
mode = "0444";
|
||||||
|
};
|
||||||
}
|
}
|
@@ -1,8 +1,12 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode?
|
||||||
|
{ user = "postgres"; group = "postgres"; directory = "/var/lib/postgresql"; }
|
||||||
|
];
|
||||||
services.postgresql.enable = true;
|
services.postgresql.enable = true;
|
||||||
services.postgresql.dataDir = "/opt/postgresql/13";
|
# services.postgresql.dataDir = "/opt/postgresql/13";
|
||||||
# XXX colin: for a proper deploy, we'd want to include something for Pleroma here too.
|
# XXX colin: for a proper deploy, we'd want to include something for Pleroma here too.
|
||||||
# services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
|
# services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
|
||||||
# CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD '<password goes here>';
|
# CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD '<password goes here>';
|
@@ -1,6 +1,10 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
|
sane.impermanence.service-dirs = [
|
||||||
|
# TODO: mode? we need this specifically for the stats tracking in .config/
|
||||||
|
{ user = "transmission"; group = "transmission"; directory = "/var/lib/transmission"; }
|
||||||
|
];
|
||||||
services.transmission.enable = true;
|
services.transmission.enable = true;
|
||||||
services.transmission.settings = {
|
services.transmission.settings = {
|
||||||
rpc-bind-address = "0.0.0.0";
|
rpc-bind-address = "0.0.0.0";
|
||||||
@@ -14,6 +18,8 @@
|
|||||||
rpc-whitelist-enabled = false;
|
rpc-whitelist-enabled = false;
|
||||||
|
|
||||||
# download-dir = "/opt/uninsane/media/";
|
# download-dir = "/opt/uninsane/media/";
|
||||||
|
# hopefully, make the downloads world-readable
|
||||||
|
umask = 0;
|
||||||
|
|
||||||
# force peer connections to be encrypted
|
# force peer connections to be encrypted
|
||||||
encryption = 2;
|
encryption = 2;
|
||||||
@@ -21,9 +27,15 @@
|
|||||||
# units in kBps
|
# units in kBps
|
||||||
speed-limit-down = 3000;
|
speed-limit-down = 3000;
|
||||||
speed-limit-down-enabled = true;
|
speed-limit-down-enabled = true;
|
||||||
speed-limit-up = 600;
|
speed-limit-up = 300;
|
||||||
speed-limit-up-enabled = true;
|
speed-limit-up-enabled = true;
|
||||||
|
|
||||||
|
# see: https://git.zknt.org/mirror/transmission/commit/cfce6e2e3a9b9d31a9dafedd0bdc8bf2cdb6e876?lang=bg-BG
|
||||||
|
anti-brute-force-enabled = false;
|
||||||
|
|
||||||
|
download-dir = "/var/lib/uninsane/media";
|
||||||
|
incomplete-dir = "/var/lib/uninsane/media/incomplete";
|
||||||
|
|
||||||
};
|
};
|
||||||
# transmission will by default not allow the world to read its files.
|
# transmission will by default not allow the world to read its files.
|
||||||
services.transmission.downloadDirPermissions = "775";
|
services.transmission.downloadDirPermissions = "775";
|
||||||
@@ -32,6 +44,7 @@
|
|||||||
systemd.services.transmission.serviceConfig = {
|
systemd.services.transmission.serviceConfig = {
|
||||||
# run this behind the OVPN static VPN
|
# run this behind the OVPN static VPN
|
||||||
NetworkNamespacePath = "/run/netns/ovpns";
|
NetworkNamespacePath = "/run/netns/ovpns";
|
||||||
|
LogLevelMax = "warning";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, ... }:
|
||||||
|
|
||||||
# installer docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix
|
# installer docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix
|
||||||
{
|
{
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
home = "/var/lib/gitea";
|
home = "/var/lib/gitea";
|
||||||
useDefaultShell = true;
|
useDefaultShell = true;
|
||||||
group = "gitea";
|
group = "gitea";
|
||||||
|
uid = config.sane.allocations.git-uid;
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
# sendmail access (not 100% sure if this is necessary)
|
# sendmail access (not 100% sure if this is necessary)
|
||||||
extraGroups = [ "postdrop" ];
|
extraGroups = [ "postdrop" ];
|
@@ -1,39 +0,0 @@
|
|||||||
{ pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./../../helpers/universal
|
|
||||||
./fs.nix
|
|
||||||
./hardware.nix
|
|
||||||
./net.nix
|
|
||||||
./users.nix
|
|
||||||
./services/ddns-he.nix
|
|
||||||
./services/duplicity.nix
|
|
||||||
./services/gitea.nix
|
|
||||||
./services/jackett.nix
|
|
||||||
./services/jellyfin.nix
|
|
||||||
./services/matrix.nix
|
|
||||||
./services/nginx.nix
|
|
||||||
./services/nix-serve.nix
|
|
||||||
./services/pleroma.nix
|
|
||||||
./services/postfix.nix
|
|
||||||
./services/postgres.nix
|
|
||||||
./services/transmission.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
home-manager.users.colin = import ../../helpers/home-manager-gen-colin.nix {
|
|
||||||
inherit pkgs lib;
|
|
||||||
system = "aarch64-linux";
|
|
||||||
gui = null;
|
|
||||||
extraPackages = [ pkgs.matrix-synapse ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# This value determines the NixOS release from which the default
|
|
||||||
# settings for stateful data, like file locations and database versions
|
|
||||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
|
||||||
# this value at the release version of the first install of this system.
|
|
||||||
# Before changing this value read the documentation for this option
|
|
||||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
|
||||||
system.stateVersion = "21.11"; # Did you read the comment?
|
|
||||||
}
|
|
||||||
|
|
@@ -1,37 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
fileSystems."/" = lib.mkDefault {
|
|
||||||
device = "/dev/disk/by-uuid/2be70d38-79f4-41b6-bee2-bce5a25f8f7b";
|
|
||||||
fsType = "ext4";
|
|
||||||
};
|
|
||||||
fileSystems."/boot" = {
|
|
||||||
device = lib.mkDefault "/dev/disk/by-uuid/B318-A67E";
|
|
||||||
fsType = "vfat";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
fileSystems."/var/lib/pleroma" = {
|
|
||||||
device = "/opt/pleroma";
|
|
||||||
options = [ "bind" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
fileSystems."/var/lib/transmission/Downloads" = {
|
|
||||||
device = "/opt/uninsane/media";
|
|
||||||
options = [ "bind" ];
|
|
||||||
};
|
|
||||||
fileSystems."/var/lib/transmission/.incomplete" = {
|
|
||||||
device = "/opt/uninsane/media/incomplete";
|
|
||||||
options = [ "bind" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# in-memory compressed RAM (seems to be dynamically sized)
|
|
||||||
zramSwap = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
swapDevices = [
|
|
||||||
{ device = "/swapfile"; size = 4096; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@@ -1,20 +0,0 @@
|
|||||||
{ pkgs, secrets, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
systemd.services.ddns-he = {
|
|
||||||
description = "update dynamic DNS entries for HurricaneElectric";
|
|
||||||
# HE DDNS API is documented: https://dns.he.net/docs.html
|
|
||||||
script = let
|
|
||||||
pass = secrets.ddns-he.password;
|
|
||||||
crl = "${pkgs.curl}/bin/curl -4";
|
|
||||||
in ''
|
|
||||||
${crl} "https://he.uninsane.org:${pass}@dyn.dns.he.net/nic/update?hostname=he.uninsane.org"
|
|
||||||
${crl} "https://native.uninsane.org:${pass}@dyn.dns.he.net/nic/update?hostname=native.uninsane.org"
|
|
||||||
${crl} "https://uninsane.org:${pass}@dyn.dns.he.net/nic/update?hostname=uninsane.org"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
systemd.timers.ddns-he.timerConfig = {
|
|
||||||
OnStartupSec = "2min";
|
|
||||||
OnUnitActiveSec = "10min";
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,36 +0,0 @@
|
|||||||
# docs: https://search.nixos.org/options?channel=21.11&query=duplicity
|
|
||||||
{ config, pkgs, lib, secrets, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
services.duplicity.enable = true;
|
|
||||||
services.duplicity.targetUrl = secrets.duplicity.url;
|
|
||||||
# format: PASSPHRASE=<cleartext>
|
|
||||||
# two sisters
|
|
||||||
services.duplicity.secretFile =
|
|
||||||
builtins.toFile "duplicity_env" "PASSPHRASE=${secrets.duplicity.passphrase}";
|
|
||||||
# NB: manually trigger with `systemctl start duplicity`
|
|
||||||
services.duplicity.frequency = "daily";
|
|
||||||
services.duplicity.exclude = [
|
|
||||||
# impermanent/inconsequential data:
|
|
||||||
"/dev"
|
|
||||||
"/proc"
|
|
||||||
"/run"
|
|
||||||
"/sys"
|
|
||||||
"/tmp"
|
|
||||||
# bind mounted (dupes):
|
|
||||||
"/var/lib/pleroma"
|
|
||||||
"/var/lib/transmission/Downloads"
|
|
||||||
"/var/lib/transmission/.incomplete"
|
|
||||||
# data that's not worth the cost to backup:
|
|
||||||
"/opt/uninsane/media"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.duplicity.extraFlags = [
|
|
||||||
# without --allow-source-mismatch, duplicity will abort if you change the hostname between backups
|
|
||||||
"--allow-source-mismatch"
|
|
||||||
];
|
|
||||||
|
|
||||||
# set this for the FIRST backup, then remove it to enable incremental backups
|
|
||||||
# (that the first backup *isn't* full i think is a defect)
|
|
||||||
# services.duplicity.fullIfOlderThan = "always";
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
services.jellyfin.enable = true;
|
|
||||||
}
|
|
@@ -1,175 +0,0 @@
|
|||||||
# docs: https://nixos.wiki/wiki/Matrix
|
|
||||||
# docs: https://nixos.org/manual/nixos/stable/index.html#module-services-matrix-synapse
|
|
||||||
{ config, pkgs, lib, secrets, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
services.matrix-synapse.enable = true;
|
|
||||||
services.matrix-synapse.settings.server_name = "uninsane.org";
|
|
||||||
|
|
||||||
# services.matrix-synapse.enable_registration_captcha = true;
|
|
||||||
# services.matrix-synapse.enable_registration_without_verification = true;
|
|
||||||
services.matrix-synapse.settings.enable_registration = true;
|
|
||||||
# services.matrix-synapse.registration_shared_secret = "<shared key goes here>";
|
|
||||||
|
|
||||||
# default for listeners is port = 8448, tls = true, x_forwarded = false.
|
|
||||||
# we change this because the server is situated behind nginx.
|
|
||||||
services.matrix-synapse.settings.listeners = [
|
|
||||||
{
|
|
||||||
port = 8008;
|
|
||||||
bind_addresses = [ "127.0.0.1" ];
|
|
||||||
type = "http";
|
|
||||||
tls = false;
|
|
||||||
x_forwarded = true;
|
|
||||||
resources = [
|
|
||||||
{
|
|
||||||
names = [ "client" "federation" ];
|
|
||||||
compress = false;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# services.matrix-synapse.extraConfig = ''
|
|
||||||
# registration_requires_token: true
|
|
||||||
# admin_contact: "admin.matrix@uninsane.org"
|
|
||||||
# '';
|
|
||||||
|
|
||||||
services.matrix-synapse.settings.admin_contact = "admin.matrix@uninsane.org";
|
|
||||||
services.matrix-synapse.settings.registrations_require_3pid = [ "email" ];
|
|
||||||
services.matrix-synapse.settings.email = {
|
|
||||||
smtp_host = "mx.uninsane.org";
|
|
||||||
smtp_port = 587;
|
|
||||||
smtp_user = "matrix-synapse";
|
|
||||||
smtp_pass = secrets.matrix-synapse.smtp_pass;
|
|
||||||
require_transport_security = true;
|
|
||||||
enable_tls = true;
|
|
||||||
notif_from = "%(app)s <notify.matrix@uninsane.org>";
|
|
||||||
app_name = "Uninsane Matrix";
|
|
||||||
enable_notifs = true;
|
|
||||||
validation_token_lifetime = "96h";
|
|
||||||
invite_client_location = "https://web.matrix.uninsane.org";
|
|
||||||
subjects = {
|
|
||||||
email_validation = "[%(server_name)s] Validate your email";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# services.matrix-synapse.extraConfigFiles = [builtins.toFile "matrix-synapse-extra-config" ''
|
|
||||||
# admin_contact: "admin.matrix@uninsane.org"
|
|
||||||
# registrations_require_3pid:
|
|
||||||
# - email
|
|
||||||
# email:
|
|
||||||
# smtp_host: "mx.uninsane.org"
|
|
||||||
# smtp_port: 587
|
|
||||||
# smtp_user: "matrix-synapse"
|
|
||||||
# smtp_pass: "${secrets.matrix-synapse.smtp_pass}"
|
|
||||||
# require_transport_security: true
|
|
||||||
# enable_tls: true
|
|
||||||
# notif_from: "%(app)s <notify.matrix@uninsane.org>"
|
|
||||||
# app_name: "Uninsane Matrix"
|
|
||||||
# enable_notifs: true
|
|
||||||
# validation_token_lifetime: 96h
|
|
||||||
# invite_client_location: "https://web.matrix.uninsane.org"
|
|
||||||
# subjects:
|
|
||||||
# email_validation: "[%(server_name)s] Validate your email"
|
|
||||||
# ''];
|
|
||||||
services.matrix-synapse.settings.app_service_config_files = [
|
|
||||||
"/var/lib/matrix-appservice-irc/registration.yml" # auto-created by irc appservice
|
|
||||||
];
|
|
||||||
|
|
||||||
# new users may be registered on the CLI:
|
|
||||||
# register_new_matrix_user -c /nix/store/8n6kcka37jhmi4qpd2r03aj71pkyh21s-homeserver.yaml http://localhost:8008
|
|
||||||
#
|
|
||||||
# or provide an registration token then can use to register through the client.
|
|
||||||
# docs: https://github.com/matrix-org/synapse/blob/develop/docs/usage/administration/admin_api/registration_tokens.md
|
|
||||||
# first, grab your own user's access token (Help & About section in Element). then:
|
|
||||||
# curl --header "Authorization: Bearer <my_token>" localhost:8008/_synapse/admin/v1/registration_tokens
|
|
||||||
# create a token with unlimited uses:
|
|
||||||
# curl -d '{}' --header "Authorization: Bearer <my_token>" localhost:8008/_synapse/admin/v1/registration_tokens/new
|
|
||||||
# create a token with limited uses:
|
|
||||||
# curl -d '{ "uses_allowed": 1 }' --header "Authorization: Bearer <my_token>" localhost:8008/_synapse/admin/v1/registration_tokens/new
|
|
||||||
|
|
||||||
# IRC bridging
|
|
||||||
# note: Rizon allows only FOUR simultaneous IRC connections per IP: https://wiki.rizon.net/index.php?title=Connection/Session_Limit_Exemptions
|
|
||||||
# Rizon supports CertFP for auth: https://wiki.rizon.net/index.php?title=CertFP
|
|
||||||
# services.matrix-appservice-irc.enable = true;
|
|
||||||
services.matrix-appservice-irc.registrationUrl = "http://127.0.0.1:8009";
|
|
||||||
# settings documented here: https://github.com/matrix-org/matrix-appservice-irc/blob/develop/config.sample.yaml
|
|
||||||
services.matrix-appservice-irc.settings = {
|
|
||||||
homeserver = {
|
|
||||||
url = "http://127.0.0.1:8008";
|
|
||||||
dropMatrixMessagesAfterSecs = 300;
|
|
||||||
domain = "uninsane.org";
|
|
||||||
enablePresence = true;
|
|
||||||
bindPort = 9999;
|
|
||||||
bindHost = "127.0.0.1";
|
|
||||||
};
|
|
||||||
|
|
||||||
ircService = {
|
|
||||||
servers = {
|
|
||||||
"irc.rizon.net" = {
|
|
||||||
name = "Rizon";
|
|
||||||
port = 6697; # SSL port
|
|
||||||
ssl = true;
|
|
||||||
sasl = true; # appservice doesn't support NickServ identification
|
|
||||||
botConfig = {
|
|
||||||
# bot has no presence in IRC channel; only real Matrix users
|
|
||||||
enabled = false;
|
|
||||||
# nick = "UninsaneDotOrg";
|
|
||||||
nick = "uninsane";
|
|
||||||
username = "uninsane";
|
|
||||||
};
|
|
||||||
dynamicChannels = {
|
|
||||||
enabled = true;
|
|
||||||
aliasTemplate = "#irc_rizon_$CHANNEL";
|
|
||||||
};
|
|
||||||
ircClients = {
|
|
||||||
nickTemplate = "$LOCALPARTsane";
|
|
||||||
# by default, Matrix will convert messages greater than (3) lines into a pastebin-like URL to send to IRC.
|
|
||||||
lineLimit = 20;
|
|
||||||
};
|
|
||||||
matrixClients = {
|
|
||||||
userTemplate = "@irc_rizon_$NICK"; # the :uninsane.org part is appended automatically
|
|
||||||
};
|
|
||||||
|
|
||||||
# this will let this user message the appservice with `!join #<IRCChannel>` and the rest "Just Works"
|
|
||||||
"@colin:uninsane.org" = "admin";
|
|
||||||
|
|
||||||
membershipLists = {
|
|
||||||
enabled = true;
|
|
||||||
global = {
|
|
||||||
ircToMatrix = {
|
|
||||||
initial = true;
|
|
||||||
incremental = true;
|
|
||||||
requireMatrixJoined = false;
|
|
||||||
};
|
|
||||||
matrixToIrc = {
|
|
||||||
initial = true;
|
|
||||||
incremental = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# sync room description?
|
|
||||||
bridgeInfoState = {
|
|
||||||
enabled = true;
|
|
||||||
initial = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# hardcoded mappings, for when dynamicChannels fails us. TODO: probably safe to remove these.
|
|
||||||
# mappings = {
|
|
||||||
# "#chat" = {
|
|
||||||
# roomIds = [ "!GXJSOTdbtxRboGtDep:uninsane.org" ];
|
|
||||||
# };
|
|
||||||
# # BakaBT requires account registration, which i think means my user needs to be added before the appservice user
|
|
||||||
# "#BakaBT" = {
|
|
||||||
# roomIds = [ "!feZKttuYuHilqPFSkD:uninsane.org" ];
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# for per-user IRC password:
|
|
||||||
# invite @irc_rizon_NickServ:uninsane.org to a DM and type `help` => register
|
|
||||||
# invite the matrix-appservice-irc user to a DM and type `!help` => add PW to database
|
|
||||||
# passwordEncryptionKeyPath = "/path/to/privkey"; # appservice will generate its own if unspecified
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
# docs: https://nixos.wiki/wiki/Binary_Cache
|
|
||||||
# to copy something to this machine's nix cache, do:
|
|
||||||
# nix copy --to ssh://nixcache.uninsane.org PACKAGE
|
|
||||||
{ secrets, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
services.nix-serve = {
|
|
||||||
enable = true;
|
|
||||||
secretKeyFile = builtins.toFile "nix-serve-priv-key.pem" secrets.nix-serve.cache-priv-key;
|
|
||||||
# "/var/cache-priv-key.pem";
|
|
||||||
};
|
|
||||||
}
|
|
14
modules/default.nix
Normal file
14
modules/default.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./gui
|
||||||
|
./hardware
|
||||||
|
./image.nix
|
||||||
|
./impermanence.nix
|
||||||
|
./nixcache.nix
|
||||||
|
./services/duplicity.nix
|
||||||
|
./services/nixserve.nix
|
||||||
|
./universal
|
||||||
|
];
|
||||||
|
}
|
29
modules/gui/default.nix
Normal file
29
modules/gui/default.nix
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{ lib, config, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.gui;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./gnome.nix
|
||||||
|
./phosh.nix
|
||||||
|
./plasma-mobile.nix
|
||||||
|
./sway.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
# doesn't directly create outputs. consumed by e.g. home-manager.nix module
|
||||||
|
sane.gui.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
sane.home-packages.enableGuiPkgs = lib.mkDefault true;
|
||||||
|
sane.home-manager.enable = lib.mkDefault true;
|
||||||
|
# all GUIs use network manager?
|
||||||
|
users.users.nm-iodine.uid = config.sane.allocations.nm-iodine-uid;
|
||||||
|
};
|
||||||
|
}
|
78
modules/gui/gnome.nix
Normal file
78
modules/gui/gnome.nix
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{ lib, config, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.gui.gnome;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.gui.gnome.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
sane.gui.enable = true;
|
||||||
|
|
||||||
|
users.users.avahi.uid = config.sane.allocations.avahi-uid;
|
||||||
|
users.groups.avahi.gid = config.sane.allocations.avahi-gid;
|
||||||
|
users.users.colord.uid = config.sane.allocations.colord-uid;
|
||||||
|
users.groups.colord.gid = config.sane.allocations.colord-gid;
|
||||||
|
users.users.geoclue.uid = config.sane.allocations.geoclue-uid;
|
||||||
|
users.groups.geoclue.gid = config.sane.allocations.geoclue-gid;
|
||||||
|
users.users.rtkit.uid = config.sane.allocations.rtkit-uid;
|
||||||
|
users.groups.rtkit.gid = config.sane.allocations.rtkit-gid;
|
||||||
|
|
||||||
|
# start gnome/gdm on boot
|
||||||
|
services.xserver.enable = true;
|
||||||
|
services.xserver.desktopManager.gnome.enable = true;
|
||||||
|
services.xserver.displayManager.gdm.enable = true;
|
||||||
|
|
||||||
|
# gnome does networking stuff with networkmanager
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
networking.wireless.enable = lib.mkForce false;
|
||||||
|
};
|
||||||
|
# home-mananger.users.colin extras
|
||||||
|
# obtain these by running `dconf dump /` after manually customizing gnome
|
||||||
|
# TODO: fix "is not of type `GVariant value'"
|
||||||
|
# dconf.settings = lib.mkIf (gui == "gnome") {
|
||||||
|
# gnome = {
|
||||||
|
# # control alt-tab behavior
|
||||||
|
# "org/gnome/desktop/wm/keybindings" = {
|
||||||
|
# switch-applications = [ "<Super>Tab" ];
|
||||||
|
# switch-applications-backward=[];
|
||||||
|
# switch-windows=["<Alt>Tab"];
|
||||||
|
# switch-windows-backward=["<Super><Alt>Tab"];
|
||||||
|
# };
|
||||||
|
# # idle power savings
|
||||||
|
# "org/gnome/settings-deamon/plugins/power" = {
|
||||||
|
# idle-brigthness = 50;
|
||||||
|
# sleep-inactive-ac-type = "nothing";
|
||||||
|
# sleep-inactive-battery-timeout = 5400; # seconds
|
||||||
|
# };
|
||||||
|
# "org/gnome/shell" = {
|
||||||
|
# favorite-apps = [
|
||||||
|
# "org.gnome.Nautilus.desktop"
|
||||||
|
# "firefox.desktop"
|
||||||
|
# "kitty.desktop"
|
||||||
|
# # "org.gnome.Terminal.desktop"
|
||||||
|
# ];
|
||||||
|
# };
|
||||||
|
# "org/gnome/desktop/session" = {
|
||||||
|
# # how long until considering a session idle (triggers e.g. screen blanking)
|
||||||
|
# idle-delay = 900;
|
||||||
|
# };
|
||||||
|
# "org/gnome/desktop/interface" = {
|
||||||
|
# text-scaling-factor = 1.25;
|
||||||
|
# };
|
||||||
|
# "org/gnome/desktop/media-handling" = {
|
||||||
|
# # don't auto-mount inserted media
|
||||||
|
# automount = false;
|
||||||
|
# automount-open = false;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
|
}
|
109
modules/gui/phosh.nix
Normal file
109
modules/gui/phosh.nix
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.gui.phosh;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.gui.phosh.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
sane.gui.phosh.useGreeter = mkOption {
|
||||||
|
description = ''
|
||||||
|
launch phosh via a greeter (like lightdm-mobile-greeter).
|
||||||
|
phosh is usable without a greeter, but skipping the greeter means no PAM session.
|
||||||
|
'';
|
||||||
|
default = true;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable (mkMerge [
|
||||||
|
{
|
||||||
|
sane.gui.enable = true;
|
||||||
|
|
||||||
|
users.users.avahi.uid = config.sane.allocations.avahi-uid;
|
||||||
|
users.users.colord.uid = config.sane.allocations.colord-uid;
|
||||||
|
users.users.geoclue.uid = config.sane.allocations.geoclue-uid;
|
||||||
|
users.users.rtkit.uid = config.sane.allocations.rtkit-uid;
|
||||||
|
users.groups.avahi.gid = config.sane.allocations.avahi-gid;
|
||||||
|
users.groups.colord.gid = config.sane.allocations.colord-gid;
|
||||||
|
users.groups.feedbackd.gid = config.sane.allocations.feedbackd-gid;
|
||||||
|
users.groups.geoclue.gid = config.sane.allocations.geoclue-gid;
|
||||||
|
users.groups.rtkit.gid = config.sane.allocations.rtkit-gid;
|
||||||
|
|
||||||
|
# docs: https://github.com/NixOS/nixpkgs/blob/nixos-22.05/nixos/modules/services/x11/desktop-managers/phosh.nix
|
||||||
|
services.xserver.desktopManager.phosh = {
|
||||||
|
enable = true;
|
||||||
|
user = "colin";
|
||||||
|
group = "users";
|
||||||
|
phocConfig = {
|
||||||
|
# xwayland = "true";
|
||||||
|
# find default outputs by catting /etc/phosh/phoc.ini
|
||||||
|
outputs.DSI-1 = {
|
||||||
|
scale = 1.5;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# XXX: phosh enables networkmanager by default; can probably disable these lines
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
networking.wireless.enable = lib.mkForce false;
|
||||||
|
|
||||||
|
# XXX: not clear if these are actually needed?
|
||||||
|
hardware.bluetooth.enable = true;
|
||||||
|
services.blueman.enable = true;
|
||||||
|
|
||||||
|
hardware.opengl.enable = true;
|
||||||
|
hardware.opengl.driSupport = true;
|
||||||
|
|
||||||
|
environment.variables = {
|
||||||
|
# Qt apps won't always start unless this env var is set
|
||||||
|
QT_QPA_PLATFORM = "wayland";
|
||||||
|
# electron apps (e.g. Element) should use the wayland backend
|
||||||
|
# toggle this to have electron apps (e.g. Element) use the wayland backend.
|
||||||
|
# phocConfig.xwayland should be disabled if you do this
|
||||||
|
NIXOS_OZONE_WL = "1";
|
||||||
|
};
|
||||||
|
|
||||||
|
sane.home-manager.extraPackages = with pkgs; [
|
||||||
|
phosh-mobile-settings
|
||||||
|
|
||||||
|
# TODO: see about removing this if the in-built gnome-settings bluetooth manager can work
|
||||||
|
gnome.gnome-bluetooth
|
||||||
|
];
|
||||||
|
}
|
||||||
|
(mkIf cfg.useGreeter {
|
||||||
|
services.xserver.enable = true;
|
||||||
|
# NB: setting defaultSession has the critical side-effect that it lets org.freedesktop.AccountsService
|
||||||
|
# know that our user exists. this ensures lightdm succeeds when calling /org/freedesktop/AccountsServices ListCachedUsers
|
||||||
|
# lightdm greeters get the login users from lightdm which gets it from org.freedesktop.Accounts.ListCachedUsers.
|
||||||
|
# this requires the user we want to login as to be cached.
|
||||||
|
services.xserver.displayManager.job.preStart = ''
|
||||||
|
${pkgs.systemd}/bin/busctl call org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.Accounts CacheUser s colin
|
||||||
|
'';
|
||||||
|
# services.xserver.displayManager.defaultSession = "sm.puri.Phosh"; # XXX: not sure why this doesn't propagate correctly.
|
||||||
|
services.xserver.displayManager.lightdm.extraSeatDefaults = ''
|
||||||
|
user-session = phosh
|
||||||
|
'';
|
||||||
|
services.xserver.displayManager.lightdm.greeters.gtk.enable = false; # gtk greeter overrides our own?
|
||||||
|
services.xserver.displayManager.lightdm.greeter = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.lightdm-mobile-greeter.xgreeters;
|
||||||
|
name = "lightdm-mobile-greeter";
|
||||||
|
};
|
||||||
|
# services.xserver.displayManager.lightdm.enable = true;
|
||||||
|
# # services.xserver.displayManager.lightdm.greeters.enso.enable = true; # tried (with reboot); got a mouse then died. next time was black
|
||||||
|
# # services.xserver.displayManager.lightdm.greeters.gtk.enable = true; # tried (with reboot); unusable without OSK
|
||||||
|
# # services.xserver.displayManager.lightdm.greeters.mini.enable = true; # tried (with reboot); unusable without OSK
|
||||||
|
# # services.xserver.displayManager.lightdm.greeters.pantheon.enable = true; # tried (no reboot); unusable without OSK
|
||||||
|
# services.xserver.displayManager.lightdm.greeters.slick.enable = true; # tried; unusable without OSK (a11y -> OSK doesn't work)
|
||||||
|
# # services.xserver.displayManager.lightdm.greeters.tiny.enable = true; # tried; block screen
|
||||||
|
|
||||||
|
systemd.services.phosh.wantedBy = lib.mkForce []; # disable auto-start
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
28
modules/gui/plasma-mobile.nix
Normal file
28
modules/gui/plasma-mobile.nix
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{ lib, config, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.gui.plasma-mobile;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.gui.plasma-mobile.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
sane.gui.enable = true;
|
||||||
|
# start plasma-mobile on boot
|
||||||
|
services.xserver.enable = true;
|
||||||
|
services.xserver.desktopManager.plasma5.mobile.enable = true;
|
||||||
|
services.xserver.desktopManager.plasma5.mobile.installRecommendedSoftware = false; # not all plasma5-mobile packages build for aarch64
|
||||||
|
services.xserver.displayManager.sddm.enable = true;
|
||||||
|
|
||||||
|
# Plasma does networking stuff with networkmanager, but nix configures the defaults itself
|
||||||
|
# networking.useDHCP = false;
|
||||||
|
# networking.networkmanager.enable = true;
|
||||||
|
# networking.wireless.enable = lib.mkForce false;
|
||||||
|
};
|
||||||
|
}
|
597
modules/gui/sway.nix
Normal file
597
modules/gui/sway.nix
Normal file
@@ -0,0 +1,597 @@
|
|||||||
|
{ pkgs, lib, config, ... }:
|
||||||
|
|
||||||
|
# docs: https://nixos.wiki/wiki/Sway
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.gui.sway;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.gui.sway.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
sane.gui.enable = true;
|
||||||
|
users.users.greeter.uid = config.sane.allocations.greeter-uid;
|
||||||
|
users.groups.greeter.gid = config.sane.allocations.greeter-gid;
|
||||||
|
programs.sway = {
|
||||||
|
# we configure sway with home-manager, but this enable gets us e.g. opengl and fonts
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# alternatively, could use SDDM
|
||||||
|
services.greetd = let
|
||||||
|
swayConfig = pkgs.writeText "greetd-sway-config" ''
|
||||||
|
# `-l` activates layer-shell mode.
|
||||||
|
exec "${pkgs.greetd.gtkgreet}/bin/gtkgreet -l -c sway"
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
# greetd source/docs:
|
||||||
|
# - <https://git.sr.ht/~kennylevinsen/greetd>
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
default_session = {
|
||||||
|
command = "${pkgs.sway}/bin/sway --config ${swayConfig}";
|
||||||
|
# alternatives:
|
||||||
|
# - TTY: `command = "${pkgs.greetd.greetd}/bin/agreety --cmd ${pkgs.sway}/bin/sway";`
|
||||||
|
# - autologin: `command = "${pkgs.sway}/bin/sway"; user = "colin";`
|
||||||
|
# - Dumb Login (doesn't work)": `command = "${pkgs.greetd.dlm}/bin/dlm";`
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# some programs (e.g. fractal) **require** a "Secret Service Provider"
|
||||||
|
services.gnome.gnome-keyring.enable = true;
|
||||||
|
|
||||||
|
# unlike other DEs, sway configures no audio stack
|
||||||
|
# administer with pw-cli, pw-mon, pw-top commands
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
alsa.support32Bit = true; # ??
|
||||||
|
pulse.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.bluetooth.enable = true;
|
||||||
|
services.blueman.enable = true;
|
||||||
|
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
networking.wireless.enable = lib.mkForce false;
|
||||||
|
|
||||||
|
sane.home-manager.windowManager.sway = {
|
||||||
|
enable = true;
|
||||||
|
wrapperFeatures.gtk = true;
|
||||||
|
config = rec {
|
||||||
|
terminal = "${pkgs.kitty}/bin/kitty";
|
||||||
|
window = {
|
||||||
|
border = 3; # pixel boundary between windows
|
||||||
|
hideEdgeBorders = "smart"; # don't show border if only window on workspace
|
||||||
|
};
|
||||||
|
output = {
|
||||||
|
### DESKTOP
|
||||||
|
"Samsung Electric Company S22C300 0x00007F35" = { pos = "0,0"; res = "1920x1080"; };
|
||||||
|
"Goldstar Company Ltd LG ULTRAWIDE 0x00004E94" = { pos = "1920,0"; res = "3440x1440"; };
|
||||||
|
|
||||||
|
### LAPTOP
|
||||||
|
# shen TV
|
||||||
|
"Pioneer Electronic Corporation VSX-524 0x00000101" = { pos = "0,0"; res = "1920x1080"; };
|
||||||
|
# internal display
|
||||||
|
"Unknown 0x0637 0x00000000" = { pos = "1920,0"; res = "1920x1080"; };
|
||||||
|
};
|
||||||
|
|
||||||
|
# defaults; required for keybindings decl.
|
||||||
|
modifier = "Mod1";
|
||||||
|
# list of launchers: https://www.reddit.com/r/swaywm/comments/v39hxa/your_favorite_launcher/
|
||||||
|
# menu = "${pkgs.dmenu}/bin/dmenu_path";
|
||||||
|
menu = "${pkgs.fuzzel}/bin/fuzzel";
|
||||||
|
# menu = "${pkgs.albert}/bin/albert";
|
||||||
|
left = "h";
|
||||||
|
down = "j";
|
||||||
|
up = "k";
|
||||||
|
right = "l";
|
||||||
|
# XKB key names: https://wiki.linuxquestions.org/wiki/List_of_Keysyms_Recognised_by_Xmodmap
|
||||||
|
keybindings = {
|
||||||
|
"${modifier}+Return" = "exec ${terminal}";
|
||||||
|
"${modifier}+Shift+q" = "kill";
|
||||||
|
"${modifier}+d" = "exec ${menu}";
|
||||||
|
"${modifier}+l" = "exec ${pkgs.swaylock}/bin/swaylock --indicator-idle-visible --indicator-radius 100 --indicator-thickness 30";
|
||||||
|
|
||||||
|
# "${modifier}+${left}" = "focus left";
|
||||||
|
# "${modifier}+${down}" = "focus down";
|
||||||
|
# "${modifier}+${up}" = "focus up";
|
||||||
|
# "${modifier}+${right}" = "focus right";
|
||||||
|
|
||||||
|
"${modifier}+Left" = "focus left";
|
||||||
|
"${modifier}+Down" = "focus down";
|
||||||
|
"${modifier}+Up" = "focus up";
|
||||||
|
"${modifier}+Right" = "focus right";
|
||||||
|
|
||||||
|
# "${modifier}+Shift+${left}" = "move left";
|
||||||
|
# "${modifier}+Shift+${down}" = "move down";
|
||||||
|
# "${modifier}+Shift+${up}" = "move up";
|
||||||
|
# "${modifier}+Shift+${right}" = "move right";
|
||||||
|
|
||||||
|
"${modifier}+Shift+Left" = "move left";
|
||||||
|
"${modifier}+Shift+Down" = "move down";
|
||||||
|
"${modifier}+Shift+Up" = "move up";
|
||||||
|
"${modifier}+Shift+Right" = "move right";
|
||||||
|
|
||||||
|
"${modifier}+b" = "splith";
|
||||||
|
"${modifier}+v" = "splitv";
|
||||||
|
"${modifier}+f" = "fullscreen toggle";
|
||||||
|
"${modifier}+a" = "focus parent";
|
||||||
|
|
||||||
|
"${modifier}+s" = "layout stacking";
|
||||||
|
"${modifier}+w" = "layout tabbed";
|
||||||
|
"${modifier}+e" = "layout toggle split";
|
||||||
|
|
||||||
|
"${modifier}+Shift+space" = "floating toggle";
|
||||||
|
"${modifier}+space" = "focus mode_toggle";
|
||||||
|
|
||||||
|
"${modifier}+1" = "workspace number 1";
|
||||||
|
"${modifier}+2" = "workspace number 2";
|
||||||
|
"${modifier}+3" = "workspace number 3";
|
||||||
|
"${modifier}+4" = "workspace number 4";
|
||||||
|
"${modifier}+5" = "workspace number 5";
|
||||||
|
"${modifier}+6" = "workspace number 6";
|
||||||
|
"${modifier}+7" = "workspace number 7";
|
||||||
|
"${modifier}+8" = "workspace number 8";
|
||||||
|
"${modifier}+9" = "workspace number 9";
|
||||||
|
|
||||||
|
"${modifier}+Shift+1" =
|
||||||
|
"move container to workspace number 1";
|
||||||
|
"${modifier}+Shift+2" =
|
||||||
|
"move container to workspace number 2";
|
||||||
|
"${modifier}+Shift+3" =
|
||||||
|
"move container to workspace number 3";
|
||||||
|
"${modifier}+Shift+4" =
|
||||||
|
"move container to workspace number 4";
|
||||||
|
"${modifier}+Shift+5" =
|
||||||
|
"move container to workspace number 5";
|
||||||
|
"${modifier}+Shift+6" =
|
||||||
|
"move container to workspace number 6";
|
||||||
|
"${modifier}+Shift+7" =
|
||||||
|
"move container to workspace number 7";
|
||||||
|
"${modifier}+Shift+8" =
|
||||||
|
"move container to workspace number 8";
|
||||||
|
"${modifier}+Shift+9" =
|
||||||
|
"move container to workspace number 9";
|
||||||
|
|
||||||
|
"${modifier}+Shift+minus" = "move scratchpad";
|
||||||
|
"${modifier}+minus" = "scratchpad show";
|
||||||
|
|
||||||
|
"${modifier}+Shift+c" = "reload";
|
||||||
|
"${modifier}+Shift+e" =
|
||||||
|
"exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'";
|
||||||
|
|
||||||
|
"${modifier}+r" = "mode resize";
|
||||||
|
} // {
|
||||||
|
# media keys
|
||||||
|
XF86MonBrightnessDown = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set 2%-"'';
|
||||||
|
XF86MonBrightnessUp = ''exec "${pkgs.brightnessctl}/bin/brightnessctl set +2%"'';
|
||||||
|
|
||||||
|
XF86AudioRaiseVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5'";
|
||||||
|
XF86AudioLowerVolume = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5'";
|
||||||
|
XF86AudioMute = "exec '${pkgs.pulsemixer}/bin/pulsemixer --toggle-mute'";
|
||||||
|
|
||||||
|
"${modifier}+Page_Up" = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume +5'";
|
||||||
|
"${modifier}+Page_Down" = "exec '${pkgs.pulsemixer}/bin/pulsemixer --change-volume -5'";
|
||||||
|
|
||||||
|
"${modifier}+Print" = "exec '${pkgs.sway-contrib.grimshot}/bin/grimshot copy area'";
|
||||||
|
};
|
||||||
|
|
||||||
|
# mostly defaults:
|
||||||
|
bars = [{
|
||||||
|
mode = "dock";
|
||||||
|
hiddenState = "hide";
|
||||||
|
position = "top";
|
||||||
|
command = "${pkgs.waybar}/bin/waybar";
|
||||||
|
workspaceButtons = true;
|
||||||
|
workspaceNumbers = true;
|
||||||
|
statusCommand = "${pkgs.i3status}/bin/i3status";
|
||||||
|
fonts = {
|
||||||
|
# names = [ "monospace" "Noto Color Emoji" ];
|
||||||
|
# size = 8.0;
|
||||||
|
# names = [ "Font Awesome 6 Free" "DejaVu Sans" "Hack" ];
|
||||||
|
# names = with config.fonts.fontconfig.defaultFonts; (emoji ++ monospace ++ serif ++ sansSerif);
|
||||||
|
names = with config.fonts.fontconfig.defaultFonts; (monospace ++ emoji);
|
||||||
|
size = 24.0;
|
||||||
|
};
|
||||||
|
trayOutput = "primary";
|
||||||
|
colors = {
|
||||||
|
background = "#000000";
|
||||||
|
statusline = "#ffffff";
|
||||||
|
separator = "#666666";
|
||||||
|
focusedWorkspace = {
|
||||||
|
border = "#4c7899";
|
||||||
|
background = "#285577";
|
||||||
|
text = "#ffffff";
|
||||||
|
};
|
||||||
|
activeWorkspace = {
|
||||||
|
border = "#333333";
|
||||||
|
background = "#5f676a";
|
||||||
|
text = "#ffffff";
|
||||||
|
};
|
||||||
|
inactiveWorkspace = {
|
||||||
|
border = "#333333";
|
||||||
|
background = "#222222";
|
||||||
|
text = "#888888";
|
||||||
|
};
|
||||||
|
urgentWorkspace = {
|
||||||
|
border = "#2f343a";
|
||||||
|
background = "#900000";
|
||||||
|
text = "#ffffff";
|
||||||
|
};
|
||||||
|
bindingMode = {
|
||||||
|
border = "#2f343a";
|
||||||
|
background = "#900000";
|
||||||
|
text = "#ffffff";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
sane.home-manager.programs.waybar = {
|
||||||
|
enable = true;
|
||||||
|
# docs: https://github.com/Alexays/Waybar/wiki/Configuration
|
||||||
|
# format specifiers: https://fmt.dev/latest/syntax.html#syntax
|
||||||
|
settings = {
|
||||||
|
mainBar = {
|
||||||
|
layer = "top";
|
||||||
|
height = 40;
|
||||||
|
modules-left = ["sway/workspaces" "sway/mode"];
|
||||||
|
modules-center = ["sway/window"];
|
||||||
|
modules-right = ["custom/mediaplayer" "clock" "battery" "cpu" "network"];
|
||||||
|
"sway/window" = {
|
||||||
|
max-length = 50;
|
||||||
|
};
|
||||||
|
# include song artist/title. source: https://www.reddit.com/r/swaywm/comments/ni0vso/waybar_spotify_tracktitle/
|
||||||
|
"custom/mediaplayer" = {
|
||||||
|
exec = pkgs.writeShellScript "waybar-mediaplayer" ''
|
||||||
|
player_status=$(${pkgs.playerctl}/bin/playerctl status 2> /dev/null)
|
||||||
|
if [ "$player_status" = "Playing" ]; then
|
||||||
|
echo "$(${pkgs.playerctl}/bin/playerctl metadata artist) - $(${pkgs.playerctl}/bin/playerctl metadata title)"
|
||||||
|
elif [ "$player_status" = "Paused" ]; then
|
||||||
|
echo " $(${pkgs.playerctl}/bin/playerctl metadata artist) - $(${pkgs.playerctl}/bin/playerctl metadata title)"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
interval = 2;
|
||||||
|
format = "{} ";
|
||||||
|
# return-type = "json";
|
||||||
|
on-click = "${pkgs.playerctl}/bin/playerctl play-pause";
|
||||||
|
on-scroll-up = "${pkgs.playerctl}/bin/playerctl next";
|
||||||
|
on-scroll-down = "${pkgs.playerctl}/bin/playerctl previous";
|
||||||
|
};
|
||||||
|
network = {
|
||||||
|
# docs: https://github.com/Alexays/Waybar/blob/master/man/waybar-network.5.scd
|
||||||
|
interval = 2;
|
||||||
|
max-length = 40;
|
||||||
|
# custom :> format specifier explained here: https://github.com/Alexays/Waybar/pull/472
|
||||||
|
format-ethernet = " {bandwidthUpBits:>}▲ {bandwidthDownBits:>}▼";
|
||||||
|
tooltip-format-ethernet = "{ifname} {bandwidthUpBits:>}▲ {bandwidthDownBits:>}▼";
|
||||||
|
|
||||||
|
format-wifi = "{ifname} ({signalStrength}%) {bandwidthUpBits:>}▲ {bandwidthDownBits:>}▼";
|
||||||
|
tooltip-format-wifi = "{essid} ({signalStrength}%) {bandwidthUpBits:>}▲ {bandwidthDownBits:>}▼";
|
||||||
|
|
||||||
|
format-disconnected = "";
|
||||||
|
};
|
||||||
|
cpu = {
|
||||||
|
format = " {usage:2}%";
|
||||||
|
tooltip = false;
|
||||||
|
};
|
||||||
|
battery = {
|
||||||
|
states = {
|
||||||
|
good = 95;
|
||||||
|
warning = 30;
|
||||||
|
critical = 10;
|
||||||
|
};
|
||||||
|
format = "{icon} {capacity}%";
|
||||||
|
format-icons = [
|
||||||
|
""
|
||||||
|
""
|
||||||
|
""
|
||||||
|
""
|
||||||
|
""
|
||||||
|
];
|
||||||
|
};
|
||||||
|
clock = {
|
||||||
|
format-alt = "{:%a, %d. %b %H:%M}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# style docs: https://github.com/Alexays/Waybar/wiki/Styling
|
||||||
|
style = ''
|
||||||
|
* {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* defaults below: https://github.com/Alexays/Waybar/blob/master/resources/style.css */
|
||||||
|
window#waybar {
|
||||||
|
background-color: rgba(43, 48, 59, 0.5);
|
||||||
|
border-bottom: 3px solid rgba(100, 114, 125, 0.5);
|
||||||
|
color: #ffffff;
|
||||||
|
transition-property: background-color;
|
||||||
|
transition-duration: .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar.hidden {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
window#waybar.empty {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
window#waybar.solo {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
window#waybar.termite {
|
||||||
|
background-color: #3F3F3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar.chromium {
|
||||||
|
background-color: #000000;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button {
|
||||||
|
padding: 0 5px;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #ffffff;
|
||||||
|
/* Use box-shadow instead of border so the text isn't offset */
|
||||||
|
box-shadow: inset 0 -3px transparent;
|
||||||
|
/* Avoid rounded borders under each workspace name */
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
||||||
|
#workspaces button:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
box-shadow: inset 0 -3px #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.focused {
|
||||||
|
background-color: #64727D;
|
||||||
|
box-shadow: inset 0 -3px #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.urgent {
|
||||||
|
background-color: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mode {
|
||||||
|
background-color: #64727D;
|
||||||
|
border-bottom: 3px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clock,
|
||||||
|
#battery,
|
||||||
|
#cpu,
|
||||||
|
#memory,
|
||||||
|
#disk,
|
||||||
|
#temperature,
|
||||||
|
#backlight,
|
||||||
|
#network,
|
||||||
|
#pulseaudio,
|
||||||
|
#custom-media,
|
||||||
|
#tray,
|
||||||
|
#mode,
|
||||||
|
#idle_inhibitor,
|
||||||
|
#mpd {
|
||||||
|
padding: 0 10px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#window,
|
||||||
|
#workspaces {
|
||||||
|
margin: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If workspaces is the leftmost module, omit left margin */
|
||||||
|
.modules-left > widget:first-child > #workspaces {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If workspaces is the rightmost module, omit right margin */
|
||||||
|
.modules-right > widget:last-child > #workspaces {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clock {
|
||||||
|
background-color: #64727D;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery.charging, #battery.plugged {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #26A65B;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
to {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery.critical:not(.charging) {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
color: #ffffff;
|
||||||
|
animation-name: blink;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
label:focus {
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cpu {
|
||||||
|
background-color: #2ecc71;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#memory {
|
||||||
|
background-color: #9b59b6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#disk {
|
||||||
|
background-color: #964B00;
|
||||||
|
}
|
||||||
|
|
||||||
|
#backlight {
|
||||||
|
background-color: #90b1b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network {
|
||||||
|
background-color: #2980b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network.disconnected {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pulseaudio {
|
||||||
|
background-color: #f1c40f;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pulseaudio.muted {
|
||||||
|
background-color: #90b1b1;
|
||||||
|
color: #2a5c45;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media {
|
||||||
|
background-color: #66cc99;
|
||||||
|
color: #2a5c45;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media.custom-spotify {
|
||||||
|
background-color: #66cc99;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media.custom-vlc {
|
||||||
|
background-color: #ffa000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#temperature {
|
||||||
|
background-color: #f0932b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#temperature.critical {
|
||||||
|
background-color: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray {
|
||||||
|
background-color: #2980b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray > .passive {
|
||||||
|
-gtk-icon-effect: dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray > .needs-attention {
|
||||||
|
-gtk-icon-effect: highlight;
|
||||||
|
background-color: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor {
|
||||||
|
background-color: #2d3436;
|
||||||
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor.activated {
|
||||||
|
background-color: #ecf0f1;
|
||||||
|
color: #2d3436;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd {
|
||||||
|
background-color: #66cc99;
|
||||||
|
color: #2a5c45;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.disconnected {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.stopped {
|
||||||
|
background-color: #90b1b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.paused {
|
||||||
|
background-color: #51a37a;
|
||||||
|
}
|
||||||
|
|
||||||
|
#language {
|
||||||
|
background: #00b093;
|
||||||
|
color: #740864;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin: 0 5px;
|
||||||
|
min-width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state {
|
||||||
|
background: #97e1ad;
|
||||||
|
color: #000000;
|
||||||
|
padding: 0 0px;
|
||||||
|
margin: 0 5px;
|
||||||
|
min-width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state > label {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state > label.locked {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
# style = ''
|
||||||
|
# * {
|
||||||
|
# border: none;
|
||||||
|
# border-radius: 0;
|
||||||
|
# font-family: Source Code Pro;
|
||||||
|
# }
|
||||||
|
# window#waybar {
|
||||||
|
# background: #16191C;
|
||||||
|
# color: #AAB2BF;
|
||||||
|
# }
|
||||||
|
# #workspaces button {
|
||||||
|
# padding: 0 5px;
|
||||||
|
# }
|
||||||
|
# .custom-spotify {
|
||||||
|
# padding: 0 10px;
|
||||||
|
# margin: 0 4px;
|
||||||
|
# background-color: #1DB954;
|
||||||
|
# color: black;
|
||||||
|
# }
|
||||||
|
# '';
|
||||||
|
};
|
||||||
|
sane.home-manager.extraPackages = with pkgs; [
|
||||||
|
swaylock
|
||||||
|
swayidle # (unused)
|
||||||
|
wl-clipboard
|
||||||
|
mako # notification daemon
|
||||||
|
xdg-utils # for xdg-open
|
||||||
|
# user stuff
|
||||||
|
# pavucontrol
|
||||||
|
sway-contrib.grimshot
|
||||||
|
gnome.gnome-bluetooth
|
||||||
|
gnome.gnome-control-center
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
40
modules/hardware/all.nix
Normal file
40
modules/hardware/all.nix
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
boot.initrd.supportedFilesystems = [ "ext4" "btrfs" "ext2" "ext3" "vfat" ];
|
||||||
|
# useful emergency utils
|
||||||
|
boot.initrd.extraUtilsCommands = ''
|
||||||
|
copy_bin_and_libs ${pkgs.btrfs-progs}/bin/btrfstune
|
||||||
|
'';
|
||||||
|
boot.kernelParams = [ "boot.shell_on_fail" ];
|
||||||
|
# other kernelParams:
|
||||||
|
# "boot.trace"
|
||||||
|
# "systemd.log_level=debug"
|
||||||
|
# "systemd.log_target=console"
|
||||||
|
|
||||||
|
# hack in the `boot.shell_on_fail` arg since that doesn't always seem to work.
|
||||||
|
boot.initrd.preFailCommands = "allowShell=1";
|
||||||
|
|
||||||
|
# default: 4 (warn). 7 is debug
|
||||||
|
boot.consoleLogLevel = 7;
|
||||||
|
|
||||||
|
boot.loader.grub.enable = lib.mkDefault false;
|
||||||
|
boot.loader.generic-extlinux-compatible.enable = lib.mkDefault true;
|
||||||
|
|
||||||
|
# non-free firmware
|
||||||
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
services.fwupd.enable = true;
|
||||||
|
|
||||||
|
# powertop will default to putting USB devices -- including HID -- to sleep after TWO SECONDS
|
||||||
|
powerManagement.powertop.enable = false;
|
||||||
|
|
||||||
|
# services.snapper.configs = {
|
||||||
|
# root = {
|
||||||
|
# subvolume = "/";
|
||||||
|
# extraConfig = {
|
||||||
|
# ALLOW_USERS = "colin";
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# services.snapper.snapshotInterval = "daily";
|
||||||
|
}
|
8
modules/hardware/default.nix
Normal file
8
modules/hardware/default.nix
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./all.nix
|
||||||
|
./x86_64.nix
|
||||||
|
];
|
||||||
|
}
|
26
modules/hardware/x86_64.nix
Normal file
26
modules/hardware/x86_64.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
config = mkIf (pkgs.system == "x86_64-linux") {
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"xhci_pci" "ahci" "sd_mod" "sdhci_pci" # nixos-generate-config defaults
|
||||||
|
"usb_storage" # rpi needed this to boot from usb storage, i think.
|
||||||
|
"nvme" # to boot from nvme devices
|
||||||
|
# efi_pstore evivars
|
||||||
|
];
|
||||||
|
|
||||||
|
# enable cross compilation
|
||||||
|
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
|
||||||
|
# nixpkgs.config.allowUnsupportedSystem = true;
|
||||||
|
# nixpkgs.crossSystem.system = "aarch64-linux";
|
||||||
|
|
||||||
|
powerManagement.cpuFreqGovernor = "powersave";
|
||||||
|
hardware.cpu.amd.updateMicrocode = true; # desktop
|
||||||
|
hardware.cpu.intel.updateMicrocode = true; # laptop
|
||||||
|
|
||||||
|
hardware.opengl.driSupport = true;
|
||||||
|
# For 32 bit applications
|
||||||
|
hardware.opengl.driSupport32Bit = true;
|
||||||
|
};
|
||||||
|
}
|
132
modules/image.nix
Normal file
132
modules/image.nix
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
{ config, lib, pkgs, mobile-nixos, utils, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.image;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
# packages whose contents should be copied directly into the /boot partition.
|
||||||
|
# e.g. EFI loaders, u-boot bootloader, etc.
|
||||||
|
sane.image.extraBootFiles = mkOption {
|
||||||
|
default = [];
|
||||||
|
type = types.listOf types.package;
|
||||||
|
};
|
||||||
|
# extra (empty) directories to create in the rootfs.
|
||||||
|
# for example, /var/log might be required by the boot process, so ensure it exists.
|
||||||
|
sane.image.extraDirectories = mkOption {
|
||||||
|
default = [];
|
||||||
|
type = types.listOf types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
# the GPT header is fixed to Logical Block Address 1,
|
||||||
|
# but we can actually put the partition entries anywhere.
|
||||||
|
# this option reserves so many bytes after LBA 1 but *before* the partition entries.
|
||||||
|
# this is not universally supported, but is an easy hack to claim space near the start
|
||||||
|
# of the disk for other purposes (e.g. firmware blobs)
|
||||||
|
sane.image.extraGPTPadding = mkOption {
|
||||||
|
default = 0;
|
||||||
|
# NB: rpi doesn't like non-zero values for this.
|
||||||
|
# at the same time, spinning disks REALLY need partitions to be aligned to 4KiB boundaries.
|
||||||
|
# maybe there's some imageBuilder.fileSystem type which represents empty space?
|
||||||
|
# default = 2014 * 512; # standard is to start part0 at sector 2048 (versus 34 if no padding)
|
||||||
|
type = types.int;
|
||||||
|
};
|
||||||
|
# optional space (in bytes) to leave unallocated after the GPT structure and before the first partition.
|
||||||
|
sane.image.firstPartGap = mkOption {
|
||||||
|
# align the first part to 16 MiB.
|
||||||
|
# do this by inserting a gap of 16 MiB - gptHeaderSize
|
||||||
|
# and then multiply by 1MiB and subtract 1 because mobile-nixos
|
||||||
|
# has a bug which will divide this by 1 MiB (and round up)
|
||||||
|
default = (16 * 1024 * 1024 - 34 * 512) * 1024 * 1024 - 1;
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
};
|
||||||
|
sane.image.bootPartSize = mkOption {
|
||||||
|
default = 512 * 1024 * 1024;
|
||||||
|
type = types.int;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = let
|
||||||
|
# return true if super starts with sub
|
||||||
|
startsWith = super: sub: (
|
||||||
|
(builtins.substring 0 (builtins.stringLength sub) super) == sub
|
||||||
|
);
|
||||||
|
# return the (string) path to get from `stem` to `path`
|
||||||
|
# or errors if not a sub-path
|
||||||
|
relPath = stem: path: (
|
||||||
|
builtins.head (builtins.match "^${stem}(.+)" path)
|
||||||
|
);
|
||||||
|
|
||||||
|
fileSystems = config.fileSystems;
|
||||||
|
bootFs = fileSystems."/boot";
|
||||||
|
nixFs = fileSystems."/nix/store" or fileSystems."/nix" or fileSystems."/";
|
||||||
|
# resolves to e.g. "nix/store", "/store" or ""
|
||||||
|
storeRelPath = relPath nixFs.mountPoint "/nix/store";
|
||||||
|
|
||||||
|
uuidFromFs = fs: builtins.head (builtins.match "/dev/disk/by-uuid/(.+)" fs.device);
|
||||||
|
vfatUuidFromFs = fs: builtins.replaceStrings ["-"] [""] (uuidFromFs fs);
|
||||||
|
|
||||||
|
fsBuilderMapBoot = {
|
||||||
|
"vfat" = pkgs.imageBuilder.fileSystem.makeESP;
|
||||||
|
};
|
||||||
|
fsBuilderMapNix = {
|
||||||
|
"ext4" = pkgs.imageBuilder.fileSystem.makeExt4;
|
||||||
|
"btrfs" = pkgs.imageBuilder.fileSystem.makeBtrfs;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
system.build.img-without-firmware = with pkgs; imageBuilder.diskImage.makeGPT {
|
||||||
|
name = "nixos";
|
||||||
|
diskID = vfatUuidFromFs bootFs;
|
||||||
|
# leave some space for firmware
|
||||||
|
# TODO: we'd prefer to turn this into a protected firmware partition, rather than reserving space in the GPT header itself
|
||||||
|
# Tow-Boot manages to do that; not sure how.
|
||||||
|
headerHole = cfg.extraGPTPadding;
|
||||||
|
partitions = [
|
||||||
|
(pkgs.imageBuilder.gap cfg.firstPartGap)
|
||||||
|
(fsBuilderMapBoot."${bootFs.fsType}" {
|
||||||
|
# fs properties
|
||||||
|
name = "ESP";
|
||||||
|
partitionID = vfatUuidFromFs bootFs;
|
||||||
|
# partition properties
|
||||||
|
partitionLabel = "EFI System";
|
||||||
|
partitionUUID = "44444444-4444-4444-4444-4444${vfatUuidFromFs bootFs}";
|
||||||
|
size = cfg.bootPartSize;
|
||||||
|
|
||||||
|
populateCommands = let
|
||||||
|
extras = builtins.toString (builtins.map (d: "cp -R ${d}/* ./") cfg.extraBootFiles);
|
||||||
|
in ''
|
||||||
|
echo "running installBootLoader"
|
||||||
|
${config.system.build.installBootLoader} ${config.system.build.toplevel} -d .
|
||||||
|
echo "ran installBootLoader"
|
||||||
|
${extras}
|
||||||
|
echo "copied extraBootFiles"
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
(fsBuilderMapNix."${nixFs.fsType}" {
|
||||||
|
# fs properties
|
||||||
|
name = "NIXOS_SYSTEM";
|
||||||
|
partitionID = uuidFromFs nixFs;
|
||||||
|
# partition properties
|
||||||
|
partitionLabel = "Linux filesystem";
|
||||||
|
partitionUUID = uuidFromFs nixFs;
|
||||||
|
populateCommands =
|
||||||
|
let
|
||||||
|
closureInfo = buildPackages.closureInfo { rootPaths = config.system.build.toplevel; };
|
||||||
|
extraRelPaths = builtins.toString (builtins.map (p: "./" + builtins.toString(relPath nixFs.mountPoint p)) cfg.extraDirectories);
|
||||||
|
in
|
||||||
|
''
|
||||||
|
mkdir -p ./${storeRelPath} ${extraRelPaths}
|
||||||
|
echo "Copying system closure..."
|
||||||
|
while IFS= read -r path; do
|
||||||
|
echo " Copying $path"
|
||||||
|
cp -prf "$path" ./${storeRelPath}
|
||||||
|
done < "${closureInfo}/store-paths"
|
||||||
|
echo "Done copying system closure..."
|
||||||
|
cp -v ${closureInfo}/registration ./nix-path-registration
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
system.build.img = lib.mkDefault config.system.build.img-without-firmware;
|
||||||
|
};
|
||||||
|
}
|
129
modules/impermanence.nix
Normal file
129
modules/impermanence.nix
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
# borrows from:
|
||||||
|
# https://xeiaso.net/blog/paranoid-nixos-2021-07-18
|
||||||
|
# https://elis.nu/blog/2020/05/nixos-tmpfs-as-root/
|
||||||
|
# https://github.com/nix-community/impermanence
|
||||||
|
{ lib, config, impermanence, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.impermanence;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.impermanence.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
sane.impermanence.home-files = mkOption {
|
||||||
|
default = [];
|
||||||
|
type = types.listOf types.str;
|
||||||
|
};
|
||||||
|
sane.impermanence.home-dirs = mkOption {
|
||||||
|
default = [];
|
||||||
|
type = types.listOf (types.either types.str (types.attrsOf types.str));
|
||||||
|
};
|
||||||
|
sane.impermanence.service-dirs = mkOption {
|
||||||
|
default = [];
|
||||||
|
type = types.listOf (types.either types.str (types.attrsOf types.str));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
map-dir = defaults: dir: if isString dir then
|
||||||
|
map-dir defaults { directory = "${defaults.directory}${dir}"; }
|
||||||
|
else
|
||||||
|
defaults // dir
|
||||||
|
;
|
||||||
|
map-dirs = defaults: dirs: builtins.map (map-dir defaults) dirs;
|
||||||
|
|
||||||
|
map-home-dirs = map-dirs { user = "colin"; group = "users"; mode = "0755"; directory = "/home/colin/"; };
|
||||||
|
map-sys-dirs = map-dirs { user = "root"; group = "root"; mode = "0755"; directory = ""; };
|
||||||
|
map-service-dirs = map-dirs { user = "root"; group = "root"; mode = "0755"; directory = ""; };
|
||||||
|
|
||||||
|
map-home-files = files: builtins.map (f: {
|
||||||
|
parentDirectory = {
|
||||||
|
user = "colin";
|
||||||
|
group = "users";
|
||||||
|
mode = "0755";
|
||||||
|
};
|
||||||
|
file = "/home/colin/${f}";
|
||||||
|
}) files;
|
||||||
|
in mkIf cfg.enable {
|
||||||
|
sane.image.extraDirectories = [ "/nix/persist/var/log" ];
|
||||||
|
environment.persistence."/nix/persist" = {
|
||||||
|
directories = (map-home-dirs ([
|
||||||
|
# cache is probably too big to fit on the tmpfs
|
||||||
|
# TODO: we could bind-mount it to something which gets cleared per boot, though.
|
||||||
|
".cache"
|
||||||
|
".cargo"
|
||||||
|
".rustup"
|
||||||
|
".ssh"
|
||||||
|
".local/share/keyrings"
|
||||||
|
# intentionally omitted:
|
||||||
|
# ".config" # managed by home-manager
|
||||||
|
# ".local" # nothing useful in here
|
||||||
|
] ++ cfg.home-dirs)) ++ (map-sys-dirs [
|
||||||
|
# TODO: this `0700` here clobbers the perms for /persist/etc, breaking boot on freshly-deployed devices
|
||||||
|
# { mode = "0700"; directory = "/etc/NetworkManager/system-connections"; }
|
||||||
|
# "/etc/nixos"
|
||||||
|
# "/etc/ssh" # persist only the specific files we want, instead
|
||||||
|
"/var/log"
|
||||||
|
"/var/backup" # for e.g. postgres dumps
|
||||||
|
]) ++ (map-service-dirs ([
|
||||||
|
# "/var/lib/AccountsService" # not sure what this is, but it's empty
|
||||||
|
"/var/lib/alsa" # preserve output levels, default devices
|
||||||
|
# "/var/lib/blueman" # files aren't human readable
|
||||||
|
"/var/lib/bluetooth" # preserve bluetooth handshakes
|
||||||
|
"/var/lib/colord" # preserve color calibrations (?)
|
||||||
|
# "/var/lib/dhclient" # empty on lappy; dunno about desko
|
||||||
|
# "/var/lib/fwupd" # not sure why this would need persistent state
|
||||||
|
# "/var/lib/geoclue" # empty on lappy
|
||||||
|
# "/var/lib/lockdown" # empty on desko; might store secrets after iOS handshake?
|
||||||
|
# "/var/lib/logrotate.status" # seems redundant with what's in /var/log?
|
||||||
|
"/var/lib/machines" # maybe not needed, but would be painful to add a VM and forget.
|
||||||
|
# "/var/lib/misc" # empty on lappy
|
||||||
|
# "/var/lib/NetworkManager" # looks to be mostly impermanent state?
|
||||||
|
# "/var/lib/NetworkManager-fortisslvpn" # empty on lappy
|
||||||
|
# "/var/lib/nixos" # has some uid/gid maps, but we enforce these to be deterministic.
|
||||||
|
# "/var/lib/PackageKit" # wtf is this?
|
||||||
|
# "/var/lib/power-profiles-daemon" # redundant with nixos declarations
|
||||||
|
# "/var/lib/private" # empty on lappy
|
||||||
|
# "/var/lib/systemd" # nothing obviously necessary
|
||||||
|
# "/var/lib/udisks2" # empty on lappy
|
||||||
|
# "/var/lib/upower" # historic charge data. unnecessary, but maybe used somewhere?
|
||||||
|
#
|
||||||
|
# servo additions:
|
||||||
|
# "/var/lib/dhparams" # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/dhparams.nix
|
||||||
|
# "/var/lib/dovecot"
|
||||||
|
# "/var/lib/duplicity"
|
||||||
|
] ++ cfg.service-dirs));
|
||||||
|
files = [
|
||||||
|
"/etc/machine-id"
|
||||||
|
"/etc/ssh/ssh_host_ed25519_key"
|
||||||
|
"/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
|
"/etc/ssh/ssh_host_rsa_key"
|
||||||
|
"/etc/ssh/ssh_host_rsa_key.pub"
|
||||||
|
"/home/colin/.zsh_history"
|
||||||
|
# # XXX these only need persistence because i have mutableUsers = true, i think
|
||||||
|
# "/etc/group"
|
||||||
|
# "/etc/passwd"
|
||||||
|
# "/etc/shadow"
|
||||||
|
] ++ map-home-files cfg.home-files;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.sane-sops = {
|
||||||
|
# TODO: it would be better if we could inject the right dependency into setupSecrets instead of patching like this.
|
||||||
|
# /run/current-system/activate contains the precise ordering logic.
|
||||||
|
# it's largely unaware of systemd.
|
||||||
|
# maybe we could insert some activation script which simply waits for /etc/ssh to appear?
|
||||||
|
description = "sops relies on /etc/ssh being available, so re-run its activation AFTER fs-local";
|
||||||
|
script = ''
|
||||||
|
${config.system.activationScripts.setupSecrets.text}
|
||||||
|
${config.system.activationScripts.linkIwdKeys.text}
|
||||||
|
'';
|
||||||
|
after = [ "fs-local.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
31
modules/nixcache.nix
Normal file
31
modules/nixcache.nix
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{ lib, config, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.nixcache;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.nixcache.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# use our own binary cache
|
||||||
|
nix.settings = {
|
||||||
|
substituters = [
|
||||||
|
"https://nixcache.uninsane.org"
|
||||||
|
"http://desko:5000"
|
||||||
|
"https://nix-community.cachix.org"
|
||||||
|
"https://cache.nixos.org/"
|
||||||
|
];
|
||||||
|
trusted-public-keys = [
|
||||||
|
"nixcache.uninsane.org:r3WILM6+QrkmsLgqVQcEdibFD7Q/4gyzD9dGT33GP70="
|
||||||
|
"desko:Q7mjjqoBMgNQ5P0e63sLur65A+D4f3Sv4QiycDIKxiI="
|
||||||
|
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
74
modules/services/duplicity.nix
Normal file
74
modules/services/duplicity.nix
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# docs: https://search.nixos.org/options?channel=21.11&query=duplicity
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.services.duplicity;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.services.duplicity.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# we need this mostly because of the size of duplicity's cache
|
||||||
|
sane.impermanence.service-dirs = [ "/var/lib/duplicity" ];
|
||||||
|
|
||||||
|
services.duplicity.enable = true;
|
||||||
|
services.duplicity.targetUrl = ''"$DUPLICITY_URL"'';
|
||||||
|
services.duplicity.escapeUrl = false;
|
||||||
|
# format: PASSPHRASE=<cleartext> \n DUPLICITY_URL=b2://...
|
||||||
|
# two sisters
|
||||||
|
# PASSPHRASE: remote backups will be encrypted using this passphrase (using gpg)
|
||||||
|
# DUPLICITY_URL: b2://$key_id:$app_key@$bucket
|
||||||
|
# create key with: backblaze-b2 create-key --bucket uninsane-host-duplicity uninsane-host-duplicity-safe listBuckets,listFiles,readBuckets,readFiles,writeFiles
|
||||||
|
# ^ run this until you get a key with no forward slashes :upside_down:
|
||||||
|
# web-created keys are allowed to delete files, which you probably don't want for an incremental backup program
|
||||||
|
# you need to create a new application key from the web in order to first get a key which can create new keys (use env vars in the above command)
|
||||||
|
# TODO: s/duplicity_passphrase/duplicity_env/
|
||||||
|
services.duplicity.secretFile = config.sops.secrets.duplicity_passphrase.path;
|
||||||
|
# NB: manually trigger with `systemctl start duplicity`
|
||||||
|
services.duplicity.frequency = "daily";
|
||||||
|
# TODO: this needs updating to handle impermanence changes
|
||||||
|
services.duplicity.exclude = [
|
||||||
|
# impermanent/inconsequential data:
|
||||||
|
"/dev"
|
||||||
|
"/proc"
|
||||||
|
"/run"
|
||||||
|
"/sys"
|
||||||
|
"/tmp"
|
||||||
|
# bind mounted (dupes):
|
||||||
|
"/var/lib"
|
||||||
|
# other mounts
|
||||||
|
"/mnt"
|
||||||
|
# data that's not worth the cost to backup:
|
||||||
|
"/nix/persist/var/lib/uninsane/media"
|
||||||
|
"/nix/persist/home/colin/tmp"
|
||||||
|
"/nix/persist/home/colin/Videos"
|
||||||
|
"/home/colin/tmp"
|
||||||
|
"/home/colin/Videos"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.duplicity.extraFlags = [
|
||||||
|
# without --allow-source-mismatch, duplicity will abort if you change the hostname between backups
|
||||||
|
"--allow-source-mismatch"
|
||||||
|
];
|
||||||
|
|
||||||
|
# set this for the FIRST backup, then remove it to enable incremental backups
|
||||||
|
# (that the first backup *isn't* full i think is a defect)
|
||||||
|
# services.duplicity.fullIfOlderThan = "always";
|
||||||
|
|
||||||
|
systemd.services.duplicity.serviceConfig = {
|
||||||
|
# rate-limit the read bandwidth in an effort to thereby prevent net upload saturation
|
||||||
|
# this could perhaps be done better by adding a duplicity config option to replace the binary with `trickle`
|
||||||
|
IOReadBandwidthMax = [
|
||||||
|
"/dev/sda1 5M"
|
||||||
|
"/dev/nvme0n1 5M"
|
||||||
|
"/dev/mmc0 5M"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
33
modules/services/nixserve.nix
Normal file
33
modules/services/nixserve.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# docs: https://nixos.wiki/wiki/Binary_Cache
|
||||||
|
# to copy something to this machine's nix cache, do:
|
||||||
|
# nix copy --to ssh://nixcache.uninsane.org PACKAGE
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.services.nixserve;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.services.nixserve.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
sane.services.nixserve.sopsFile = mkOption {
|
||||||
|
default = ../../secrets/servo.yaml;
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.nix-serve = {
|
||||||
|
enable = true;
|
||||||
|
secretKeyFile = config.sops.secrets.nix_serve_privkey.path;
|
||||||
|
openFirewall = true; # not needed for servo; only desko
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets.nix_serve_privkey = {
|
||||||
|
sopsFile = cfg.sopsFile;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
61
modules/universal/allocations.nix
Normal file
61
modules/universal/allocations.nix
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
mkId = id: mkOption {
|
||||||
|
default = id;
|
||||||
|
type = types.int;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
# legacy servo users, some are inconvenient to migrate
|
||||||
|
sane.allocations.dhcpcd-gid = mkId 991;
|
||||||
|
sane.allocations.dhcpcd-uid = mkId 992;
|
||||||
|
sane.allocations.gitea-gid = mkId 993;
|
||||||
|
sane.allocations.git-uid = mkId 994;
|
||||||
|
sane.allocations.jellyfin-gid = mkId 994;
|
||||||
|
sane.allocations.pleroma-gid = mkId 995;
|
||||||
|
sane.allocations.jellyfin-uid = mkId 996;
|
||||||
|
sane.allocations.acme-gid = mkId 996;
|
||||||
|
sane.allocations.pleroma-uid = mkId 997;
|
||||||
|
sane.allocations.acme-uid = mkId 998;
|
||||||
|
sane.allocations.greeter-uid = mkId 999;
|
||||||
|
sane.allocations.greeter-gid = mkId 999;
|
||||||
|
|
||||||
|
sane.allocations.freshrss-uid = mkId 2401;
|
||||||
|
sane.allocations.freshrss-gid = mkId 2401;
|
||||||
|
|
||||||
|
sane.allocations.colin-uid = mkId 1000;
|
||||||
|
sane.allocations.guest-uid = mkId 1100;
|
||||||
|
|
||||||
|
# found on all machines
|
||||||
|
sane.allocations.sshd-uid = mkId 2001; # 997
|
||||||
|
sane.allocations.sshd-gid = mkId 2001; # 997
|
||||||
|
sane.allocations.polkituser-gid = mkId 2002; # 998
|
||||||
|
sane.allocations.systemd-coredump-gid = mkId 2003; # 996
|
||||||
|
sane.allocations.nscd-uid = mkId 2004;
|
||||||
|
sane.allocations.nscd-gid = mkId 2004;
|
||||||
|
sane.allocations.systemd-oom-uid = mkId 2005;
|
||||||
|
sane.allocations.systemd-oom-gid = mkId 2005;
|
||||||
|
|
||||||
|
# found on graphical machines
|
||||||
|
sane.allocations.nm-iodine-uid = mkId 2101; # desko/moby/lappy
|
||||||
|
|
||||||
|
# found on desko machine
|
||||||
|
sane.allocations.usbmux-uid = mkId 2204;
|
||||||
|
sane.allocations.usbmux-gid = mkId 2204;
|
||||||
|
|
||||||
|
|
||||||
|
# originally found on moby machine
|
||||||
|
sane.allocations.avahi-uid = mkId 2304;
|
||||||
|
sane.allocations.avahi-gid = mkId 2304;
|
||||||
|
sane.allocations.colord-uid = mkId 2305;
|
||||||
|
sane.allocations.colord-gid = mkId 2305;
|
||||||
|
sane.allocations.geoclue-uid = mkId 2306;
|
||||||
|
sane.allocations.geoclue-gid = mkId 2306;
|
||||||
|
sane.allocations.rtkit-uid = mkId 2307;
|
||||||
|
sane.allocations.rtkit-gid = mkId 2307;
|
||||||
|
sane.allocations.feedbackd-gid = mkId 2308;
|
||||||
|
};
|
||||||
|
}
|
33
modules/universal/default.nix
Normal file
33
modules/universal/default.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./allocations.nix
|
||||||
|
./env
|
||||||
|
./fs.nix
|
||||||
|
./net.nix
|
||||||
|
./secrets.nix
|
||||||
|
./users.nix
|
||||||
|
./vpn.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
time.timeZone = "America/Los_Angeles";
|
||||||
|
|
||||||
|
fonts = {
|
||||||
|
enableDefaultFonts = true;
|
||||||
|
fonts = with pkgs; [ font-awesome twitter-color-emoji hack-font ];
|
||||||
|
fontconfig.enable = true;
|
||||||
|
fontconfig.defaultFonts = {
|
||||||
|
emoji = [ "Font Awesome 6 Free" "Twitter Color Emoji" ];
|
||||||
|
monospace = [ "Hack" ];
|
||||||
|
serif = [ "DejaVu Serif" ];
|
||||||
|
sansSerif = [ "DejaVu Sans" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# allow `nix flake ...` command
|
||||||
|
nix.extraOptions = ''
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
36
modules/universal/env/default.nix
vendored
Normal file
36
modules/universal/env/default.nix
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./home-manager.nix
|
||||||
|
./home-packages.nix
|
||||||
|
./system-packages.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# programs.vim.defaultEditor = true;
|
||||||
|
environment.variables = {
|
||||||
|
EDITOR = "vim";
|
||||||
|
# git claims it should use EDITOR, but it doesn't!
|
||||||
|
GIT_EDITOR = "vim";
|
||||||
|
# TODO: these should be moved to `home.sessionVariables` (home-manager)
|
||||||
|
# Electron apps should use native wayland backend:
|
||||||
|
# https://nixos.wiki/wiki/Slack#Wayland
|
||||||
|
# Discord under sway crashes with this.
|
||||||
|
# NIXOS_OZONE_WL = "1";
|
||||||
|
# LIBGL_ALWAYS_SOFTWARE = "1";
|
||||||
|
};
|
||||||
|
# enable zsh completions
|
||||||
|
environment.pathsToLink = [ "/share/zsh" ];
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
# required for pam_mount
|
||||||
|
gocryptfs
|
||||||
|
];
|
||||||
|
|
||||||
|
security.pam.mount.enable = true;
|
||||||
|
# security.pam.mount.debugLevel = 1;
|
||||||
|
# security.pam.enableSSHAgentAuth = true; # ??
|
||||||
|
# needed for `allow_other` in e.g. gocryptfs mounts
|
||||||
|
# or i guess going through mount.fuse sets suid so that's not necessary?
|
||||||
|
# programs.fuse.userAllowOther = true;
|
||||||
|
}
|
||||||
|
|
175
modules/universal/env/feeds.nix
vendored
Normal file
175
modules/universal/env/feeds.nix
vendored
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
{ lib }:
|
||||||
|
|
||||||
|
let
|
||||||
|
hourly = { freq = "hourly"; };
|
||||||
|
daily = { freq = "daily"; };
|
||||||
|
weekly = { freq = "weekly"; };
|
||||||
|
infrequent = { freq = "infrequent"; };
|
||||||
|
|
||||||
|
art = { cat = "art"; };
|
||||||
|
humor = { cat = "humor"; };
|
||||||
|
pol = { cat = "pol"; }; # or maybe just "social"
|
||||||
|
rat = { cat = "rat"; };
|
||||||
|
tech = { cat = "tech"; };
|
||||||
|
uncat = { cat = "uncat"; };
|
||||||
|
|
||||||
|
text = { format = "text"; };
|
||||||
|
image = { format = "image"; };
|
||||||
|
podcast = { format = "podcast"; };
|
||||||
|
|
||||||
|
mkRss = format: url: { inherit url format; } // uncat // infrequent;
|
||||||
|
mkText = mkRss text;
|
||||||
|
mkImg = mkRss image;
|
||||||
|
mkPod = mkRss podcast;
|
||||||
|
|
||||||
|
# merge the attrs `new` into each value of the attrs `addTo`
|
||||||
|
addAttrs = new: addTo: builtins.mapAttrs (k: v: v // new) addTo;
|
||||||
|
# for each value in `attrs`, add a value to the child attrs which holds its key within the parent attrs.
|
||||||
|
withInverseMapping = key: attrs: builtins.mapAttrs (k: v: v // { "${key}" = k; }) attrs;
|
||||||
|
in rec {
|
||||||
|
podcasts = [
|
||||||
|
(mkPod "https://lexfridman.com/feed/podcast/" // rat // weekly)
|
||||||
|
## Astral Codex Ten
|
||||||
|
(mkPod "http://feeds.libsyn.com/108018/rss" // rat // daily)
|
||||||
|
## Econ Talk
|
||||||
|
(mkPod "https://feeds.simplecast.com/wgl4xEgL" // rat // daily)
|
||||||
|
## Cory Doctorow
|
||||||
|
(mkPod "https://feeds.feedburner.com/doctorow_podcast" // pol // infrequent)
|
||||||
|
(mkPod "https://congressionaldish.libsyn.com/rss" // pol // infrequent)
|
||||||
|
## Civboot
|
||||||
|
(mkPod "https://anchor.fm/s/34c7232c/podcast/rss" // tech // infrequent)
|
||||||
|
(mkPod "https://feeds.feedburner.com/80000HoursPodcast" // rat // weekly)
|
||||||
|
(mkPod "https://allinchamathjason.libsyn.com/rss" // pol // weekly)
|
||||||
|
(mkPod "https://acquired.libsyn.com/rss" // tech // infrequent)
|
||||||
|
(mkPod "https://rss.acast.com/deconstructed" // pol // infrequent)
|
||||||
|
## The Daily
|
||||||
|
(mkPod "https://feeds.simplecast.com/54nAGcIl" // pol // daily)
|
||||||
|
(mkPod "https://rss.acast.com/intercepted-with-jeremy-scahill" // pol // weekly)
|
||||||
|
(mkPod "https://podcast.posttv.com/itunes/post-reports.xml" // pol // weekly)
|
||||||
|
## Eric Weinstein
|
||||||
|
(mkPod "https://rss.art19.com/the-portal" // rat // infrequent)
|
||||||
|
(mkPod "https://feeds.megaphone.fm/darknetdiaries" // tech // infrequent)
|
||||||
|
(mkPod "http://feeds.wnyc.org/radiolab" // pol // infrequent)
|
||||||
|
(mkPod "https://wakingup.libsyn.com/rss" // pol // infrequent)
|
||||||
|
## 99% Invisible
|
||||||
|
(mkPod "https://feeds.simplecast.com/BqbsxVfO" // pol // infrequent)
|
||||||
|
(mkPod "https://rss.acast.com/ft-tech-tonic" // tech // infrequent)
|
||||||
|
(mkPod "https://feeds.feedburner.com/dancarlin/history?format=xml" // rat // infrequent)
|
||||||
|
## 60 minutes (NB: this features more than *just* audio?)
|
||||||
|
(mkPod "https://www.cbsnews.com/latest/rss/60-minutes" // pol // infrequent)
|
||||||
|
];
|
||||||
|
|
||||||
|
texts = [
|
||||||
|
# AGGREGATORS (> 1 post/day)
|
||||||
|
(mkText "https://www.lesswrong.com/feed.xml" // rat // hourly)
|
||||||
|
(mkText "http://www.econlib.org/index.xml" // pol // hourly)
|
||||||
|
|
||||||
|
# AGGREGATORS (< 1 post/day)
|
||||||
|
(mkText "https://palladiummag.com/feed" // uncat // weekly)
|
||||||
|
(mkText "https://profectusmag.com/feed" // uncat // weekly)
|
||||||
|
(mkText "https://semiaccurate.com/feed" // tech // weekly)
|
||||||
|
(mkText "https://linuxphoneapps.org/blog/atom.xml" // tech // infrequent)
|
||||||
|
(mkText "https://spectrum.ieee.org/rss" // tech // weekly)
|
||||||
|
|
||||||
|
## No Moods, Ads or Cutesy Fucking Icons
|
||||||
|
(mkText "https://www.rifters.com/crawl/?feed=rss2" // uncat // weekly)
|
||||||
|
|
||||||
|
# DEVELOPERS
|
||||||
|
(mkText "https://mg.lol/blog/rss/" // infrequent // tech)
|
||||||
|
## Ken Shirriff
|
||||||
|
(mkText "https://www.righto.com/feeds/posts/default" // tech // infrequent)
|
||||||
|
## Vitalik Buterin
|
||||||
|
(mkText "https://vitalik.ca/feed.xml" // tech // infrequent)
|
||||||
|
## ian (Sanctuary)
|
||||||
|
(mkText "https://sagacioussuricata.com/feed.xml" // tech // infrequent)
|
||||||
|
## Bunnie Juang
|
||||||
|
(mkText "https://www.bunniestudios.com/blog/?feed=rss2" // tech // infrequent)
|
||||||
|
(mkText "https://blog.danieljanus.pl/atom.xml" // tech // infrequent)
|
||||||
|
(mkText "https://ianthehenry.com/feed.xml" // tech // infrequent)
|
||||||
|
(mkText "https://bitbashing.io/feed.xml" // tech // infrequent)
|
||||||
|
(mkText "https://idiomdrottning.org/feed.xml" // uncat // daily)
|
||||||
|
|
||||||
|
# (TECH; POL) COMMENTATORS
|
||||||
|
(mkText "http://benjaminrosshoffman.com/feed" // pol // weekly)
|
||||||
|
## Ben Thompson
|
||||||
|
(mkText "https://www.stratechery.com/rss" // pol // weekly)
|
||||||
|
## Balaji
|
||||||
|
(mkText "https://balajis.com/rss" // pol // weekly)
|
||||||
|
(mkText "https://www.ben-evans.com/benedictevans/rss.xml" // pol // weekly)
|
||||||
|
(mkText "https://www.lynalden.com/feed" // pol // infrequent)
|
||||||
|
(mkText "https://austinvernon.site/rss.xml" // tech // infrequent)
|
||||||
|
(mkText "https://oversharing.substack.com/feed" // pol // daily)
|
||||||
|
(mkText "https://doomberg.substack.com/feed" // tech // weekly)
|
||||||
|
## David Rosenthal
|
||||||
|
(mkText "https://blog.dshr.org/rss.xml" // pol // weekly)
|
||||||
|
## Matt Levine
|
||||||
|
(mkText "https://www.bloomberg.com/opinion/authors/ARbTQlRLRjE/matthew-s-levine.rss" // pol // weekly)
|
||||||
|
|
||||||
|
# RATIONALITY/PHILOSOPHY/ETC
|
||||||
|
(mkText "https://samkriss.substack.com/feed" // humor // infrequent)
|
||||||
|
(mkText "https://unintendedconsequenc.es/feed" // rat // infrequent)
|
||||||
|
(mkText "https://applieddivinitystudies.com/atom.xml" // rat // weekly)
|
||||||
|
(mkText "https://slimemoldtimemold.com/feed.xml" // rat // weekly)
|
||||||
|
(mkText "https://www.richardcarrier.info/feed" // rat // weekly)
|
||||||
|
(mkText "https://www.gwern.net/feed.xml" // uncat // infrequent)
|
||||||
|
## Jason Crawford
|
||||||
|
(mkText "https://rootsofprogress.org/feed.xml" // rat // weekly)
|
||||||
|
## Robin Hanson
|
||||||
|
(mkText "https://www.overcomingbias.com/feed" // rat // daily)
|
||||||
|
## Scott Alexander
|
||||||
|
(mkText "https://astralcodexten.substack.com/feed.xml" // rat // daily)
|
||||||
|
## Paul Christiano
|
||||||
|
(mkText "https://sideways-view.com/feed" // rat // infrequent)
|
||||||
|
## Sean Carroll
|
||||||
|
(mkText "https://www.preposterousuniverse.com/rss" // rat // infrequent)
|
||||||
|
|
||||||
|
# CODE
|
||||||
|
(mkText "https://github.com/Kaiteki-Fedi/Kaiteki/commits/master.atom" // tech // infrequent)
|
||||||
|
];
|
||||||
|
|
||||||
|
images = [
|
||||||
|
(mkImg "https://www.smbc-comics.com/comic/rss" // humor // daily)
|
||||||
|
(mkImg "https://xkcd.com/atom.xml" // humor // daily)
|
||||||
|
(mkImg "http://dilbert.com/feed" // humor // daily)
|
||||||
|
|
||||||
|
# ART
|
||||||
|
(mkImg "https://miniature-calendar.com/feed" // art // daily)
|
||||||
|
];
|
||||||
|
|
||||||
|
all = texts ++ images ++ podcasts;
|
||||||
|
|
||||||
|
# return only the feed items which match this category (e.g. "tech")
|
||||||
|
filterCat = cat: feeds: builtins.filter (item: item.cat == cat) feeds;
|
||||||
|
# return only the feed items which match this format (e.g. "podcast")
|
||||||
|
filterFormat = format: feeds: builtins.filter (item: item.format == format) feeds;
|
||||||
|
|
||||||
|
# transform a list of feeds into an attrs mapping cat => [ feed0 feed1 ... ]
|
||||||
|
partitionByCat = feeds: builtins.groupBy (f: f.cat) feeds;
|
||||||
|
|
||||||
|
# represents a single RSS feed.
|
||||||
|
opmlTerminal = feed: ''<outline xmlUrl="${feed.url}" type="rss"/>'';
|
||||||
|
# a list of RSS feeds.
|
||||||
|
opmlTerminals = feeds: lib.strings.concatStringsSep "\n" (builtins.map opmlTerminal feeds);
|
||||||
|
# one node which packages some flat grouping of terminals.
|
||||||
|
opmlGroup = title: feeds: ''
|
||||||
|
<outline text="${title}" title="${title}">
|
||||||
|
${opmlTerminals feeds}
|
||||||
|
</outline>
|
||||||
|
'';
|
||||||
|
# a list of groups (`groupMap` is an attrs mapping groupName => [ feed0 feed1 ... ]).
|
||||||
|
opmlGroups = groupMap: lib.strings.concatStringsSep "\n" (
|
||||||
|
builtins.attrValues (builtins.mapAttrs opmlGroup groupMap)
|
||||||
|
);
|
||||||
|
# top-level OPML file which could be consumed by something else.
|
||||||
|
opmlTopLevel = body: ''
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<opml version="2.0">
|
||||||
|
<body>
|
||||||
|
${body}
|
||||||
|
</body>
|
||||||
|
</opml>
|
||||||
|
'';
|
||||||
|
|
||||||
|
# **primary API**: generate a OPML file from the provided feeds
|
||||||
|
feedsToOpml = feeds: opmlTopLevel (opmlGroups (partitionByCat feeds));
|
||||||
|
}
|
527
modules/universal/env/home-manager.nix
vendored
Normal file
527
modules/universal/env/home-manager.nix
vendored
Normal file
@@ -0,0 +1,527 @@
|
|||||||
|
# docs:
|
||||||
|
# https://rycee.gitlab.io/home-manager/
|
||||||
|
# https://rycee.gitlab.io/home-manager/options.html
|
||||||
|
# man home-configuration.nix
|
||||||
|
#
|
||||||
|
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.home-manager;
|
||||||
|
vim-swap-dir = ".cache/vim-swap";
|
||||||
|
# extract package from `extraPackages`
|
||||||
|
pkglist = pkgspec: builtins.map (e: e.pkg or e) pkgspec;
|
||||||
|
# extract `dir` from `extraPackages`
|
||||||
|
dirlist = pkgspec: builtins.concatLists (builtins.map (e: if e ? "dir" then [ e.dir ] else []) pkgspec);
|
||||||
|
# extract `persist-files` from `extraPackages`
|
||||||
|
persistfileslist = pkgspec: builtins.concatLists (builtins.map (e: if e ? "persist-files" then e.persist-files else []) pkgspec);
|
||||||
|
# TODO: dirlist and persistfileslist should be folded
|
||||||
|
feeds = import ./feeds.nix { inherit lib; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.home-manager.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
|
||||||
|
# packages to deploy to the user's home
|
||||||
|
sane.home-manager.extraPackages = mkOption {
|
||||||
|
default = [ ];
|
||||||
|
# each entry can be either a package, or attrs:
|
||||||
|
# { pkg = package; dir = optional string;
|
||||||
|
type = types.listOf (types.either types.package types.attrs);
|
||||||
|
};
|
||||||
|
|
||||||
|
# attributes to copy directly to home-manager's `wayland.windowManager` option
|
||||||
|
sane.home-manager.windowManager = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
# extra attributes to include in home-manager's `programs` option
|
||||||
|
sane.home-manager.programs = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
sops.secrets."aerc_accounts" = {
|
||||||
|
owner = config.users.users.colin.name;
|
||||||
|
sopsFile = ../../../secrets/universal/aerc_accounts.conf;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
sops.secrets."sublime_music_config" = {
|
||||||
|
owner = config.users.users.colin.name;
|
||||||
|
sopsFile = ../../../secrets/universal/sublime_music_config.json.bin;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
|
||||||
|
sane.impermanence.home-dirs = [
|
||||||
|
"archive"
|
||||||
|
"dev"
|
||||||
|
"records"
|
||||||
|
"ref"
|
||||||
|
"tmp"
|
||||||
|
"use"
|
||||||
|
"Music"
|
||||||
|
"Pictures"
|
||||||
|
"Videos"
|
||||||
|
vim-swap-dir
|
||||||
|
] ++ (dirlist cfg.extraPackages);
|
||||||
|
sane.impermanence.home-files = persistfileslist cfg.extraPackages;
|
||||||
|
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
|
||||||
|
# XXX this weird rename + closure is to get home-manager's `config.lib.file` to exist.
|
||||||
|
# see: https://github.com/nix-community/home-manager/issues/589#issuecomment-950474105
|
||||||
|
home-manager.users.colin = let sysconfig = config; in { config, ... }: {
|
||||||
|
|
||||||
|
# run `home-manager-help` to access manpages
|
||||||
|
# or `man home-configuration.nix`
|
||||||
|
manual.html.enable = true;
|
||||||
|
|
||||||
|
home.packages = pkglist cfg.extraPackages;
|
||||||
|
wayland.windowManager = cfg.windowManager;
|
||||||
|
|
||||||
|
home.stateVersion = "21.11";
|
||||||
|
home.username = "colin";
|
||||||
|
home.homeDirectory = "/home/colin";
|
||||||
|
|
||||||
|
home.activation = {
|
||||||
|
initKeyring = {
|
||||||
|
after = ["writeBoundary"];
|
||||||
|
before = [];
|
||||||
|
data = "${../../../scripts/init-keyring}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# XDG defines things like ~/Desktop, ~/Downloads, etc.
|
||||||
|
# these clutter the home, so i mostly don't use them.
|
||||||
|
xdg.userDirs = {
|
||||||
|
enable = true;
|
||||||
|
createDirectories = false; # on headless systems, most xdg dirs are noise
|
||||||
|
desktop = "$HOME/.xdg/Desktop";
|
||||||
|
documents = "$HOME/dev";
|
||||||
|
download = "$HOME/tmp";
|
||||||
|
music = "$HOME/Music";
|
||||||
|
pictures = "$HOME/Pictures";
|
||||||
|
publicShare = "$HOME/.xdg/Public";
|
||||||
|
templates = "$HOME/.xdg/Templates";
|
||||||
|
videos = "$HOME/Videos";
|
||||||
|
};
|
||||||
|
|
||||||
|
# the xdg mime type for a file can be found with:
|
||||||
|
# - `xdg-mime query filetype path/to/thing.ext`
|
||||||
|
xdg.mimeApps.enable = true;
|
||||||
|
xdg.mimeApps.defaultApplications = let
|
||||||
|
www = "librewolf.desktop";
|
||||||
|
pdf = "org.gnome.Evince.desktop";
|
||||||
|
md = "obsidian.desktop";
|
||||||
|
thumb = "org.gnome.gThumb.desktop";
|
||||||
|
video = "vlc.desktop";
|
||||||
|
# audio = "mpv.desktop";
|
||||||
|
audio = "vlc.desktop";
|
||||||
|
in {
|
||||||
|
# HTML
|
||||||
|
"text/html" = [ www ];
|
||||||
|
"x-scheme-handler/http" = [ www ];
|
||||||
|
"x-scheme-handler/https" = [ www ];
|
||||||
|
"x-scheme-handler/about" = [ www ];
|
||||||
|
"x-scheme-handler/unknown" = [ www ];
|
||||||
|
# RICH-TEXT DOCUMENTS
|
||||||
|
"application/pdf" = [ pdf ];
|
||||||
|
"text/markdown" = [ md ];
|
||||||
|
# IMAGES
|
||||||
|
"image/heif" = [ thumb ]; # apple codec
|
||||||
|
"image/png" = [ thumb ];
|
||||||
|
"image/jpeg" = [ thumb ];
|
||||||
|
# VIDEO
|
||||||
|
"video/mp4" = [ video ];
|
||||||
|
"video/quicktime" = [ video ];
|
||||||
|
"video/x-matroska" = [ video ];
|
||||||
|
# AUDIO
|
||||||
|
"audio/flac" = [ audio ];
|
||||||
|
"audio/mpeg" = [ audio ];
|
||||||
|
"audio/x-vorbis+ogg" = [ audio ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# convenience
|
||||||
|
home.file."knowledge".source = config.lib.file.mkOutOfStoreSymlink "/home/colin/dev/knowledge";
|
||||||
|
home.file."nixos".source = config.lib.file.mkOutOfStoreSymlink "/home/colin/dev/nixos";
|
||||||
|
home.file."Videos/servo".source = config.lib.file.mkOutOfStoreSymlink "/mnt/servo-media/Videos";
|
||||||
|
home.file."Videos/servo-incomplete".source = config.lib.file.mkOutOfStoreSymlink "/mnt/servo-media/incomplete";
|
||||||
|
home.file."Music/servo".source = config.lib.file.mkOutOfStoreSymlink "/mnt/servo-media/Music";
|
||||||
|
|
||||||
|
# nb markdown/personal knowledge manager
|
||||||
|
home.file.".nb/knowledge".source = config.lib.file.mkOutOfStoreSymlink "/home/colin/dev/knowledge";
|
||||||
|
home.file.".nb/.current".text = "knowledge";
|
||||||
|
home.file.".nbrc".text = ''
|
||||||
|
# manage with `nb settings`
|
||||||
|
export NB_AUTO_SYNC=0
|
||||||
|
'';
|
||||||
|
|
||||||
|
# uBlock filter list configuration.
|
||||||
|
# specifically, enable the GDPR cookie prompt blocker.
|
||||||
|
# data.toOverwrite.filterLists is additive (i.e. it supplements the default filters)
|
||||||
|
# this configuration method is documented here:
|
||||||
|
# - <https://github.com/gorhill/uBlock/issues/2986#issuecomment-364035002>
|
||||||
|
# the specific attribute path is found via scraping ublock code here:
|
||||||
|
# - <https://github.com/gorhill/uBlock/blob/master/src/js/storage.js>
|
||||||
|
# - <https://github.com/gorhill/uBlock/blob/master/assets/assets.json>
|
||||||
|
home.file.".librewolf/managed-storage/uBlock0@raymondhill.net.json".text = ''
|
||||||
|
{
|
||||||
|
"name": "uBlock0@raymondhill.net",
|
||||||
|
"description": "ignored",
|
||||||
|
"type": "storage",
|
||||||
|
"data": {
|
||||||
|
"toOverwrite": "{\"filterLists\": [\"fanboy-cookiemonster\"]}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
home.file.".librewolf/librewolf.overrides.cfg".text = ''
|
||||||
|
// if we can't query the revocation status of a SSL cert because the issuer is offline,
|
||||||
|
// treat it as unrevoked.
|
||||||
|
// see: <https://librewolf.net/docs/faq/#im-getting-sec_error_ocsp_server_error-what-can-i-do>
|
||||||
|
defaultPref("security.OCSP.require", false);
|
||||||
|
'';
|
||||||
|
|
||||||
|
# aerc TUI mail client
|
||||||
|
xdg.configFile."aerc/accounts.conf".source =
|
||||||
|
config.lib.file.mkOutOfStoreSymlink sysconfig.sops.secrets.aerc_accounts.path;
|
||||||
|
|
||||||
|
# make Discord usable even when client is "outdated"
|
||||||
|
xdg.configFile."discord/settings.json".text = ''
|
||||||
|
{
|
||||||
|
"SKIP_HOST_UPDATE": true
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# sublime music player
|
||||||
|
xdg.configFile."sublime-music/config.json".source =
|
||||||
|
config.lib.file.mkOutOfStoreSymlink sysconfig.sops.secrets.sublime_music_config.path;
|
||||||
|
|
||||||
|
xdg.configFile."vlc/vlcrc".text =
|
||||||
|
let
|
||||||
|
podcastUrls = lib.strings.concatStringsSep "|" (
|
||||||
|
builtins.map (feed: feed.url) feeds.podcasts
|
||||||
|
);
|
||||||
|
in ''
|
||||||
|
[podcast]
|
||||||
|
podcast-urls=${podcastUrls}
|
||||||
|
[core]
|
||||||
|
metadata-network-access=0
|
||||||
|
[qt]
|
||||||
|
qt-privacy-ask=0
|
||||||
|
'';
|
||||||
|
|
||||||
|
xdg.configFile."gpodderFeeds.opml".text = with feeds;
|
||||||
|
feedsToOpml feeds.podcasts;
|
||||||
|
|
||||||
|
# news-flash RSS viewer
|
||||||
|
xdg.configFile."newsflashFeeds.opml".text = with feeds;
|
||||||
|
feedsToOpml (feeds.texts ++ feeds.images);
|
||||||
|
|
||||||
|
# gnome feeds RSS viewer
|
||||||
|
xdg.configFile."org.gabmus.gfeeds.json".text =
|
||||||
|
let
|
||||||
|
myFeeds = feeds.texts ++ feeds.images;
|
||||||
|
in builtins.toJSON {
|
||||||
|
# feed format is a map from URL to a dict,
|
||||||
|
# with dict["tags"] a list of string tags.
|
||||||
|
feeds = builtins.foldl' (acc: feed: acc // {
|
||||||
|
"${feed.url}".tags = [ feed.cat feed.freq ];
|
||||||
|
}) {} myFeeds;
|
||||||
|
dark_reader = false;
|
||||||
|
new_first = true;
|
||||||
|
# windowsize = {
|
||||||
|
# width = 350;
|
||||||
|
# height = 650;
|
||||||
|
# };
|
||||||
|
max_article_age_days = 90;
|
||||||
|
enable_js = false;
|
||||||
|
max_refresh_threads = 3;
|
||||||
|
# saved_items = {};
|
||||||
|
# read_items = [];
|
||||||
|
show_read_items = true;
|
||||||
|
full_article_title = true;
|
||||||
|
# views: "webview", "reader", "rsscont"
|
||||||
|
default_view = "rsscont";
|
||||||
|
open_links_externally = true;
|
||||||
|
full_feed_name = false;
|
||||||
|
refresh_on_startup = true;
|
||||||
|
tags = lib.lists.unique (
|
||||||
|
(builtins.catAttrs "cat" myFeeds) ++ (builtins.catAttrs "freq" myFeeds)
|
||||||
|
);
|
||||||
|
open_youtube_externally = false;
|
||||||
|
media_player = "vlc"; # default: mpv
|
||||||
|
};
|
||||||
|
|
||||||
|
programs = {
|
||||||
|
home-manager.enable = true; # this lets home-manager manage dot-files in user dirs, i think
|
||||||
|
|
||||||
|
zsh = {
|
||||||
|
enable = true;
|
||||||
|
enableSyntaxHighlighting = true;
|
||||||
|
enableVteIntegration = true;
|
||||||
|
history.ignorePatterns = [ "rm *" ];
|
||||||
|
# history.path = TODO
|
||||||
|
dotDir = ".config/zsh";
|
||||||
|
|
||||||
|
initExtraBeforeCompInit = ''
|
||||||
|
# p10k instant prompt
|
||||||
|
# run p10k configure to configure, but it can't write out its file :-(
|
||||||
|
POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true
|
||||||
|
'';
|
||||||
|
initExtra = ''
|
||||||
|
# zmv is a way to do rich moves/renames, with pattern matching/substitution.
|
||||||
|
# see for an example: <https://filipe.kiss.ink/zmv-zsh-rename/>
|
||||||
|
autoload -Uz zmv
|
||||||
|
'';
|
||||||
|
|
||||||
|
# prezto = oh-my-zsh fork; controls prompt, auto-completion, etc.
|
||||||
|
# see: https://github.com/sorin-ionescu/prezto
|
||||||
|
prezto = {
|
||||||
|
enable = true;
|
||||||
|
pmodules = [
|
||||||
|
"environment"
|
||||||
|
"terminal"
|
||||||
|
"editor"
|
||||||
|
"history"
|
||||||
|
"directory"
|
||||||
|
"spectrum"
|
||||||
|
"utility"
|
||||||
|
"completion"
|
||||||
|
"prompt"
|
||||||
|
"git"
|
||||||
|
];
|
||||||
|
prompt = {
|
||||||
|
theme = "powerlevel10k";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
kitty = {
|
||||||
|
enable = true;
|
||||||
|
# docs: https://sw.kovidgoyal.net/kitty/conf/
|
||||||
|
settings = {
|
||||||
|
# disable terminal bell (when e.g. you backspace too many times)
|
||||||
|
enable_audio_bell = false;
|
||||||
|
};
|
||||||
|
keybindings = {
|
||||||
|
"ctrl+n" = "new_os_window_with_cwd";
|
||||||
|
};
|
||||||
|
# docs: https://github.com/kovidgoyal/kitty-themes
|
||||||
|
# theme = "1984 Light"; # dislike: awful, harsh blues/teals
|
||||||
|
# theme = "Adventure Time"; # dislike: harsh (dark)
|
||||||
|
# theme = "Atom One Light"; # GOOD: light theme. all color combos readable. not a huge fan of the blue.
|
||||||
|
# theme = "Belafonte Day"; # dislike: too low contrast for text colors
|
||||||
|
# theme = "Belafonte Night"; # better: dark theme that's easy on the eyes. all combos readable. low contrast.
|
||||||
|
# theme = "Catppuccin"; # dislike: a bit pale/low-contrast (dark)
|
||||||
|
# theme = "Desert"; # mediocre: colors are harsh
|
||||||
|
# theme = "Earthsong"; # BEST: dark theme. readable, good contrast. unique, but decent colors.
|
||||||
|
# theme = "Espresso Libre"; # better: dark theme. readable, but meh colors
|
||||||
|
# theme = "Forest Night"; # decent: very pastel. it's workable, but unconventional and muted/flat.
|
||||||
|
# theme = "Gruvbox Material Light Hard"; # mediocre light theme.
|
||||||
|
# theme = "kanagawabones"; # better: dark theme. colors are too background-y
|
||||||
|
# theme = "Kaolin Dark"; # dislike: too dark
|
||||||
|
# theme = "Kaolin Breeze"; # mediocre: not-too-harsh light theme, but some parts are poor contrast
|
||||||
|
# theme = "Later This Evening"; # mediocre: not-too-harsh dark theme, but cursor is poor contrast
|
||||||
|
# theme = "Material"; # decent: light theme, few colors.
|
||||||
|
# theme = "Mayukai"; # decent: not-too-harsh dark theme. the teal is a bit straining
|
||||||
|
# theme = "Nord"; # mediocre: pale background, low contrast
|
||||||
|
# theme = "One Half Light"; # better: not-too-harsh light theme. contrast could be better
|
||||||
|
theme = "PaperColor Dark"; # BEST: dark theme, very readable still the colors are background-y
|
||||||
|
# theme = "Parasio Dark"; # dislike: too low contrast
|
||||||
|
# theme = "Pencil Light"; # better: not-too-harsh light theme. decent contrast.
|
||||||
|
# theme = "Pnevma"; # dislike: too low contrast
|
||||||
|
# theme = "Piatto Light"; # better: readable light theme. pleasing colors. powerline prompt is hard to read.
|
||||||
|
# theme = "Rosé Pine Dawn"; # GOOD: light theme. all color combinations are readable. it is very mild -- may need to manually tweak contrast. tasteful colors
|
||||||
|
# theme = "Rosé Pine Moon"; # GOOD: dark theme. tasteful colors. but background is a bit intense
|
||||||
|
# theme = "Sea Shells"; # mediocre. not all color combos are readable
|
||||||
|
# theme = "Solarized Light"; # mediocre: not-too-harsh light theme; GREAT background; but some colors are low contrast
|
||||||
|
# theme = "Solarized Dark Higher Contrast"; # better: dark theme, decent colors
|
||||||
|
# theme = "Sourcerer"; # mediocre: ugly colors
|
||||||
|
# theme = "Space Gray"; # mediocre: too muted
|
||||||
|
# theme = "Space Gray Eighties"; # better: all readable, decent colors
|
||||||
|
# theme = "Spacemacs"; # mediocre: too muted
|
||||||
|
# theme = "Spring"; # mediocre: readable light theme, but the teal is ugly.
|
||||||
|
# theme = "Srcery"; # better: highly readable. colors are ehhh
|
||||||
|
# theme = "Substrata"; # decent: nice colors, but a bit flat.
|
||||||
|
# theme = "Sundried"; # mediocre: the solar text makes me squint
|
||||||
|
# theme = "Symfonic"; # mediocre: the dark purple has low contrast to the black bg.
|
||||||
|
# theme = "Tango Light"; # dislike: teal is too grating
|
||||||
|
# theme = "Tokyo Night Day"; # medicore: too muted
|
||||||
|
# theme = "Tokyo Night"; # better: tasteful. a bit flat
|
||||||
|
# theme = "Tomorrow"; # GOOD: all color combinations are readable. contrast is slightly better than Rose. on the blander side
|
||||||
|
# theme = "Treehouse"; # dislike: the orange is harsh on my eyes.
|
||||||
|
# theme = "Urple"; # dislike: weird palette
|
||||||
|
# theme = "Warm Neon"; # decent: not-too-harsh dark theme. the green is a bit unattractive
|
||||||
|
# theme = "Wild Cherry"; # GOOD: dark theme: nice colors. a bit flat
|
||||||
|
# theme = "Xcodedark"; # dislike: bad palette
|
||||||
|
# theme = "citylights"; # decent: dark theme. some parts have just a bit low contrast
|
||||||
|
# theme = "neobones_light"; # better light theme. the background is maybe too muted
|
||||||
|
# theme = "vimbones";
|
||||||
|
# theme = "zenbones_dark"; # mediocre: readable, but meh colors
|
||||||
|
# theme = "zenbones_light"; # decent: light theme. all colors are readable. contrast is passable but not excellent. highlight color is BAD
|
||||||
|
# theme = "zenwritten_dark"; # mediocre: looks same as zenbones_dark
|
||||||
|
# extraConfig = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
git = {
|
||||||
|
enable = true;
|
||||||
|
userName = "colin";
|
||||||
|
userEmail = "colin@uninsane.org";
|
||||||
|
|
||||||
|
aliases = { co = "checkout"; };
|
||||||
|
extraConfig = {
|
||||||
|
# difftastic docs:
|
||||||
|
# - <https://difftastic.wilfred.me.uk/git.html>
|
||||||
|
diff.tool = "difftastic";
|
||||||
|
difftool.prompt = false;
|
||||||
|
"difftool \"difftastic\"".cmd = ''${pkgs.difftastic}/bin/difft "$LOCAL" "$REMOTE"'';
|
||||||
|
# now run `git difftool` to use difftastic git
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
neovim = {
|
||||||
|
# neovim: https://github.com/neovim/neovim
|
||||||
|
enable = true;
|
||||||
|
viAlias = true;
|
||||||
|
vimAlias = true;
|
||||||
|
plugins = with pkgs.vimPlugins; [
|
||||||
|
# docs: surround-nvim: https://github.com/ur4ltz/surround.nvim/
|
||||||
|
# docs: vim-surround: https://github.com/tpope/vim-surround
|
||||||
|
vim-surround
|
||||||
|
# docs: fzf-vim (fuzzy finder): https://github.com/junegunn/fzf.vim
|
||||||
|
fzf-vim
|
||||||
|
# docs: https://github.com/KeitaNakamura/tex-conceal.vim/
|
||||||
|
({
|
||||||
|
plugin = tex-conceal-vim;
|
||||||
|
type = "viml";
|
||||||
|
config = ''
|
||||||
|
" present prettier fractions
|
||||||
|
let g:tex_conceal_frac=1
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
({
|
||||||
|
plugin = vim-SyntaxRange;
|
||||||
|
type = "viml";
|
||||||
|
config = ''
|
||||||
|
" enable markdown-style codeblock highlighting for tex code
|
||||||
|
autocmd BufEnter * call SyntaxRange#Include('```tex', '```', 'tex', 'NonText')
|
||||||
|
" autocmd Syntax tex set conceallevel=2
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
# nabla renders inline math in any document, but it's buggy.
|
||||||
|
# https://github.com/jbyuki/nabla.nvim
|
||||||
|
# ({
|
||||||
|
# plugin = pkgs.nabla;
|
||||||
|
# type = "lua";
|
||||||
|
# config = ''
|
||||||
|
# require'nabla'.enable_virt()
|
||||||
|
# '';
|
||||||
|
# })
|
||||||
|
# treesitter syntax highlighting: https://nixos.wiki/wiki/Tree_sitters
|
||||||
|
# docs: https://github.com/nvim-treesitter/nvim-treesitter
|
||||||
|
# config taken from: https://github.com/i077/system/blob/master/modules/home/neovim/default.nix
|
||||||
|
# this is required for tree-sitter to even highlight
|
||||||
|
({
|
||||||
|
plugin = (nvim-treesitter.withPlugins (_: pkgs.tree-sitter.allGrammars));
|
||||||
|
type = "lua";
|
||||||
|
config = ''
|
||||||
|
require'nvim-treesitter.configs'.setup {
|
||||||
|
highlight = {
|
||||||
|
enable = true,
|
||||||
|
-- disable treesitter on Rust so that we can use SyntaxRange
|
||||||
|
-- and leverage TeX rendering in rust projects
|
||||||
|
disable = { "rust", "tex", "latex" },
|
||||||
|
-- disable = { "tex", "latex" },
|
||||||
|
-- true to also use builtin vim syntax highlighting when treesitter fails
|
||||||
|
additional_vim_regex_highlighting = false
|
||||||
|
},
|
||||||
|
incremental_selection = {
|
||||||
|
enable = true,
|
||||||
|
keymaps = {
|
||||||
|
init_selection = "gnn",
|
||||||
|
node_incremental = "grn",
|
||||||
|
mcope_incremental = "grc",
|
||||||
|
node_decremental = "grm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
indent = {
|
||||||
|
enable = true,
|
||||||
|
disable = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vim.o.foldmethod = 'expr'
|
||||||
|
vim.o.foldexpr = 'nvim_treesitter#foldexpr()'
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
extraConfig = ''
|
||||||
|
" let the terminal handle mouse events, that way i get OS-level ctrl+shift+c/etc
|
||||||
|
" this used to be default, until <https://github.com/neovim/neovim/pull/19290>
|
||||||
|
set mouse=
|
||||||
|
|
||||||
|
" copy/paste to system clipboard
|
||||||
|
set clipboard=unnamedplus
|
||||||
|
|
||||||
|
" screw tabs; always expand them into spaces
|
||||||
|
set expandtab
|
||||||
|
|
||||||
|
" at least don't open files with sections folded by default
|
||||||
|
set nofoldenable
|
||||||
|
|
||||||
|
" allow text substitutions for certain glyphs.
|
||||||
|
" higher number = more aggressive substitution (0, 1, 2, 3)
|
||||||
|
" i only make use of this for tex, but it's unclear how to
|
||||||
|
" apply that *just* to tex and retain the SyntaxRange stuff.
|
||||||
|
set conceallevel=2
|
||||||
|
|
||||||
|
" horizontal rule under the active line
|
||||||
|
" set cursorline
|
||||||
|
|
||||||
|
" highlight trailing space & related syntax errors (doesn't seem to work??)
|
||||||
|
" let c_space_errors=1
|
||||||
|
" let python_space_errors=1
|
||||||
|
|
||||||
|
" enable highlighting of leading/trailing spaces,
|
||||||
|
" and especially tabs
|
||||||
|
" source: https://www.reddit.com/r/neovim/comments/chlmfk/highlight_trailing_whitespaces_in_neovim/
|
||||||
|
set list
|
||||||
|
set listchars=tab:▷\·,trail:·,extends:◣,precedes:◢,nbsp:○
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# XXX: although home-manager calls this option `firefox`, we can use other browsers and it still mostly works.
|
||||||
|
firefox = lib.mkIf (sysconfig.sane.gui.enable) {
|
||||||
|
enable = true;
|
||||||
|
package = import ./web-browser.nix pkgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
mpv = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
save-position-on-quit = true;
|
||||||
|
keep-open = "yes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# "command not found" will cause the command to be searched in nixpkgs
|
||||||
|
nix-index.enable = true;
|
||||||
|
} // cfg.programs;
|
||||||
|
|
||||||
|
home.shellAliases = {
|
||||||
|
":q" = "exit";
|
||||||
|
# common typos
|
||||||
|
"cd.." = "cd ..";
|
||||||
|
"cd../" = "cd ../";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
193
modules/universal/env/home-packages.nix
vendored
Normal file
193
modules/universal/env/home-packages.nix
vendored
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
with pkgs;
|
||||||
|
let
|
||||||
|
cfg = config.sane.home-packages;
|
||||||
|
universalPkgs = [
|
||||||
|
backblaze-b2
|
||||||
|
cdrtools
|
||||||
|
duplicity
|
||||||
|
gnupg
|
||||||
|
gocryptfs
|
||||||
|
ifuse
|
||||||
|
ipfs
|
||||||
|
libimobiledevice
|
||||||
|
libsecret # for managing user keyrings
|
||||||
|
lm_sensors # for sensors-detect
|
||||||
|
lshw
|
||||||
|
ffmpeg
|
||||||
|
nb
|
||||||
|
networkmanager
|
||||||
|
nixpkgs-review
|
||||||
|
# nixos-generators
|
||||||
|
# nettools
|
||||||
|
nmon
|
||||||
|
oathToolkit # for oathtool
|
||||||
|
# ponymix
|
||||||
|
pulsemixer
|
||||||
|
python3
|
||||||
|
# python3Packages.eyeD3 # music tagging
|
||||||
|
sane-scripts
|
||||||
|
sequoia
|
||||||
|
snapper
|
||||||
|
sops
|
||||||
|
speedtest-cli
|
||||||
|
sqlite # to debug sqlite3 databases
|
||||||
|
ssh-to-age
|
||||||
|
sudo
|
||||||
|
# tageditor # music tagging
|
||||||
|
unar
|
||||||
|
visidata
|
||||||
|
w3m
|
||||||
|
wireguard-tools
|
||||||
|
# youtube-dl
|
||||||
|
yt-dlp
|
||||||
|
];
|
||||||
|
|
||||||
|
guiPkgs = [
|
||||||
|
# GUI only
|
||||||
|
aerc # email client
|
||||||
|
audacity
|
||||||
|
chromium
|
||||||
|
clinfo
|
||||||
|
electrum
|
||||||
|
|
||||||
|
# creds/session keys, etc
|
||||||
|
{ pkg = element-desktop; dir = ".config/Element"; }
|
||||||
|
|
||||||
|
emote # TODO: package [smile](https://github.com/mijorus/smile) for probably a better mobile experience.
|
||||||
|
evince # works on phosh
|
||||||
|
|
||||||
|
# { pkg = fluffychat-moby; dir = ".local/share/chat.fluffy.fluffychat"; } # TODO: ship normal fluffychat on non-moby?
|
||||||
|
|
||||||
|
foliate
|
||||||
|
font-manager
|
||||||
|
|
||||||
|
# XXX by default fractal stores its state in ~/.local/share/<UUID>.
|
||||||
|
# after logging in, manually change ~/.local/share/keyrings/... to point it to some predictable subdir.
|
||||||
|
# then reboot (so that libsecret daemon re-loads the keyring...?)
|
||||||
|
{ pkg = fractal-next; dir = ".local/share/fractal"; }
|
||||||
|
|
||||||
|
gimp # broken on phosh
|
||||||
|
gnome.cheese
|
||||||
|
gnome.dconf-editor
|
||||||
|
gnome-feeds # RSS reader (with claimed mobile support)
|
||||||
|
gnome.file-roller
|
||||||
|
gnome.gnome-disk-utility
|
||||||
|
gnome.gnome-maps # works on phosh
|
||||||
|
gnome.nautilus
|
||||||
|
# gnome-podcasts
|
||||||
|
gnome.gnome-system-monitor
|
||||||
|
gnome.gnome-terminal # works on phosh
|
||||||
|
gnome.gnome-weather
|
||||||
|
|
||||||
|
{ pkg = gpodder-configured; dir = "gPodder/Downloads"; }
|
||||||
|
|
||||||
|
gthumb
|
||||||
|
inkscape
|
||||||
|
|
||||||
|
kid3 # audio tagging
|
||||||
|
krita
|
||||||
|
libreoffice-fresh # XXX colin: maybe don't want this on mobile
|
||||||
|
lollypop
|
||||||
|
mesa-demos
|
||||||
|
|
||||||
|
{ pkg = mpv; dir = ".config/mpv/watch_later"; }
|
||||||
|
|
||||||
|
networkmanagerapplet
|
||||||
|
|
||||||
|
# not strictly necessary, but allows caching articles; offline use, etc.
|
||||||
|
{ pkg = newsflash; dir = ".local/share/news-flash"; }
|
||||||
|
|
||||||
|
# settings (electron app). TODO: can i manage these settings with home-manager?
|
||||||
|
{ pkg = obsidian; dir = ".config/obsidian"; }
|
||||||
|
|
||||||
|
pavucontrol
|
||||||
|
picard # music tagging
|
||||||
|
playerctl
|
||||||
|
soundconverter
|
||||||
|
# sublime music persists any downloaded albums here.
|
||||||
|
# it doesn't obey a conventional ~/Music/{Artist}/{Album}/{Track} notation, so no symlinking
|
||||||
|
# config (e.g. server connection details) is persisted in ~/.config/sublime-music/config.json
|
||||||
|
# possible to pass config as a CLI arg (sublime-music -c config.json)
|
||||||
|
{ pkg = sublime-music; dir = ".local/share/sublime-music"; }
|
||||||
|
tdesktop # broken on phosh
|
||||||
|
|
||||||
|
# vlc remembers play position in ~/.config/vlc/vlc-qt-interface.conf
|
||||||
|
{ pkg = vlc; persist-files = [ ".config/vlc/vlc-qt-interface.conf" ]; }
|
||||||
|
|
||||||
|
whalebird # pleroma client. input is broken on phosh
|
||||||
|
xdg-utils # for xdg-open
|
||||||
|
xterm # broken on phosh
|
||||||
|
]
|
||||||
|
++ (if pkgs.system == "x86_64-linux" then
|
||||||
|
[
|
||||||
|
# x86_64 only
|
||||||
|
|
||||||
|
# creds, but also 200 MB of node modules, etc
|
||||||
|
(let discord = (pkgs.discord.override {
|
||||||
|
# XXX 2022-07-31: fix to allow links to open in default web-browser:
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/78961
|
||||||
|
nss = pkgs.nss_latest;
|
||||||
|
}); in { pkg = discord; dir = ".config/discord"; })
|
||||||
|
|
||||||
|
kaiteki # Pleroma client
|
||||||
|
gnome.zenity # for kaiteki (it will use qarma, kdialog, or zenity)
|
||||||
|
|
||||||
|
logseq
|
||||||
|
losslesscut-bin
|
||||||
|
makemkv
|
||||||
|
|
||||||
|
# actual monero blockchain (not wallet/etc; safe to delete, just slow to regenerate)
|
||||||
|
{ pkg = monero-gui; dir = ".bitmonero"; }
|
||||||
|
|
||||||
|
# creds, media
|
||||||
|
{ pkg = signal-desktop; dir = ".config/Signal"; }
|
||||||
|
|
||||||
|
# creds. TODO: can i manage this with home-manager?
|
||||||
|
{ pkg = spotify; dir = ".config/spotify"; }
|
||||||
|
|
||||||
|
# hardenedMalloc solves a crash at startup
|
||||||
|
(tor-browser-bundle-bin.override { useHardenedMalloc = false; })
|
||||||
|
|
||||||
|
# zcash coins. safe to delete, just slow to regenerate (10-60 minutes)
|
||||||
|
{ pkg = zecwallet-lite; dir = ".zcash"; }
|
||||||
|
] else []);
|
||||||
|
|
||||||
|
# useful devtools:
|
||||||
|
devPkgs = [
|
||||||
|
bison
|
||||||
|
dtc
|
||||||
|
flex
|
||||||
|
gcc
|
||||||
|
gdb
|
||||||
|
# gcc-arm-embedded
|
||||||
|
# gcc_multi
|
||||||
|
gnumake
|
||||||
|
mix2nix
|
||||||
|
rustup
|
||||||
|
swig
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.home-packages.enableGuiPkgs = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
sane.home-packages.enableDevPkgs = mkOption {
|
||||||
|
description = ''
|
||||||
|
enable packages that are useful for building other software by hand.
|
||||||
|
you should prefer to keep this disabled except when prototyping, e.g. packaging new software.
|
||||||
|
'';
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
sane.home-manager.extraPackages = universalPkgs
|
||||||
|
++ (if cfg.enableGuiPkgs then guiPkgs else [])
|
||||||
|
++ (if cfg.enableDevPkgs then devPkgs else []);
|
||||||
|
};
|
||||||
|
}
|
38
modules/universal/env/system-packages.nix
vendored
Normal file
38
modules/universal/env/system-packages.nix
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
# general-purpose utilities that we want any user to be able to access
|
||||||
|
# (specifically: root, in case of rescue)
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
btrfs-progs
|
||||||
|
cryptsetup
|
||||||
|
dig
|
||||||
|
efibootmgr
|
||||||
|
fatresize
|
||||||
|
fd
|
||||||
|
file
|
||||||
|
gptfdisk
|
||||||
|
hdparm
|
||||||
|
htop
|
||||||
|
iftop
|
||||||
|
inetutils # for telnet
|
||||||
|
iotop
|
||||||
|
iptables
|
||||||
|
jq
|
||||||
|
killall
|
||||||
|
lsof
|
||||||
|
netcat
|
||||||
|
nethogs
|
||||||
|
nmap
|
||||||
|
openssl
|
||||||
|
parted
|
||||||
|
pciutils
|
||||||
|
powertop
|
||||||
|
ripgrep
|
||||||
|
screen
|
||||||
|
smartmontools
|
||||||
|
socat
|
||||||
|
usbutils
|
||||||
|
wget
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
55
modules/universal/env/web-browser.nix
vendored
Normal file
55
modules/universal/env/web-browser.nix
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
pkgs:
|
||||||
|
|
||||||
|
# common settings to toggle (at runtime, in about:config):
|
||||||
|
# > security.ssl.require_safe_negotiation
|
||||||
|
|
||||||
|
# librewolf is a forked firefox which patches firefox to allow more things
|
||||||
|
# (like default search engines) to be configurable at runtime.
|
||||||
|
# many of the settings below won't have effect without those patches.
|
||||||
|
# see: https://gitlab.com/librewolf-community/settings/-/blob/master/distribution/policies.json
|
||||||
|
pkgs.wrapFirefox pkgs.librewolf-unwrapped {
|
||||||
|
# inherit the default librewolf.cfg
|
||||||
|
# it can be further customized via ~/.librewolf/librewolf.overrides.cfg
|
||||||
|
inherit (pkgs.librewolf-unwrapped) extraPrefsFiles;
|
||||||
|
libName = "librewolf";
|
||||||
|
extraPolicies = {
|
||||||
|
NoDefaultBookmarks = true;
|
||||||
|
SearchEngines = {
|
||||||
|
Default = "DuckDuckGo";
|
||||||
|
};
|
||||||
|
AppUpdateURL = "https://localhost";
|
||||||
|
DisableAppUpdate = true;
|
||||||
|
OverrideFirstRunPage = "";
|
||||||
|
OverridePostUpdatePage = "";
|
||||||
|
DisableSystemAddonUpdate = true;
|
||||||
|
DisableFirefoxStudies = true;
|
||||||
|
DisableTelemetry = true;
|
||||||
|
DisableFeedbackCommands = true;
|
||||||
|
DisablePocket = true;
|
||||||
|
DisableSetDesktopBackground = false;
|
||||||
|
Extensions = {
|
||||||
|
Install = [
|
||||||
|
"https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"
|
||||||
|
"https://addons.mozilla.org/firefox/downloads/latest/sponsorblock/latest.xpi"
|
||||||
|
"https://addons.mozilla.org/firefox/downloads/latest/bypass-paywalls-clean/latest.xpi"
|
||||||
|
"https://addons.mozilla.org/firefox/downloads/latest/sidebery/latest.xpi"
|
||||||
|
"https://addons.mozilla.org/firefox/downloads/latest/ether-metamask/latest.xpi"
|
||||||
|
];
|
||||||
|
# remove many default search providers
|
||||||
|
Uninstall = [
|
||||||
|
"google@search.mozilla.org"
|
||||||
|
"bing@search.mozilla.org"
|
||||||
|
"amazondotcom@search.mozilla.org"
|
||||||
|
"ebay@search.mozilla.org"
|
||||||
|
"twitter@search.mozilla.org"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# XXX doesn't seem to have any effect...
|
||||||
|
# docs: https://github.com/mozilla/policy-templates#homepage
|
||||||
|
# Homepage = {
|
||||||
|
# HomepageURL = "https://uninsane.org/";
|
||||||
|
# StartPage = "homepage";
|
||||||
|
# };
|
||||||
|
# NewTabPage = true;
|
||||||
|
};
|
||||||
|
}
|
68
modules/universal/fs.nix
Normal file
68
modules/universal/fs.nix
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
let sshOpts = rec {
|
||||||
|
fsType = "fuse.sshfs";
|
||||||
|
optionsBase = [
|
||||||
|
"x-systemd.automount"
|
||||||
|
"_netdev"
|
||||||
|
"user"
|
||||||
|
"identityfile=/home/colin/.ssh/id_ed25519"
|
||||||
|
"allow_other"
|
||||||
|
"default_permissions"
|
||||||
|
];
|
||||||
|
optionsColin = optionsBase ++ [
|
||||||
|
"transform_symlinks"
|
||||||
|
"idmap=user"
|
||||||
|
"uid=1000"
|
||||||
|
"gid=100"
|
||||||
|
];
|
||||||
|
|
||||||
|
optionsRoot = optionsBase ++ [
|
||||||
|
# we don't transform_symlinks because that breaks the validity of remote /nix stores
|
||||||
|
"sftp_server=/run/wrappers/bin/sudo\\040${pkgs.openssh}/libexec/sftp-server"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
fileSystems."/mnt/servo-media-wan" = {
|
||||||
|
device = "colin@uninsane.org:/var/lib/uninsane/media";
|
||||||
|
inherit (sshOpts) fsType;
|
||||||
|
options = sshOpts.optionsColin;
|
||||||
|
noCheck = true;
|
||||||
|
};
|
||||||
|
fileSystems."/mnt/servo-media-lan" = {
|
||||||
|
device = "colin@servo:/var/lib/uninsane/media";
|
||||||
|
inherit (sshOpts) fsType;
|
||||||
|
options = sshOpts.optionsColin;
|
||||||
|
noCheck = true;
|
||||||
|
};
|
||||||
|
fileSystems."/mnt/servo-root-wan" = {
|
||||||
|
device = "colin@uninsane.org:/";
|
||||||
|
inherit (sshOpts) fsType;
|
||||||
|
options = sshOpts.optionsRoot;
|
||||||
|
noCheck = true;
|
||||||
|
};
|
||||||
|
fileSystems."/mnt/servo-root-lan" = {
|
||||||
|
device = "colin@servo:/";
|
||||||
|
inherit (sshOpts) fsType;
|
||||||
|
options = sshOpts.optionsRoot;
|
||||||
|
noCheck = true;
|
||||||
|
};
|
||||||
|
fileSystems."/mnt/desko-home" = {
|
||||||
|
device = "colin@desko:/home/colin";
|
||||||
|
inherit (sshOpts) fsType;
|
||||||
|
options = sshOpts.optionsColin;
|
||||||
|
noCheck = true;
|
||||||
|
};
|
||||||
|
fileSystems."/mnt/desko-root" = {
|
||||||
|
device = "colin@desko:/";
|
||||||
|
inherit (sshOpts) fsType;
|
||||||
|
options = sshOpts.optionsRoot;
|
||||||
|
noCheck = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.sshfs-fuse
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
69
modules/universal/net.nix
Normal file
69
modules/universal/net.nix
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# if using router's DNS, these mappings will already exist.
|
||||||
|
# if using a different DNS provider (which servo does), then we need to explicity provide them.
|
||||||
|
# ugly hack. would be better to get servo to somehow use the router's DNS
|
||||||
|
networking.hosts = {
|
||||||
|
"192.168.0.5" = [ "servo" ];
|
||||||
|
"192.168.0.20" = [ "lappy" ];
|
||||||
|
"192.168.0.22" = [ "desko" ];
|
||||||
|
"192.168.0.48" = [ "moby" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# the default backend is "wpa_supplicant".
|
||||||
|
# wpa_supplicant reliably picks weak APs to connect to.
|
||||||
|
# see: <https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/474>
|
||||||
|
# iwd is an alternative that shouldn't have this problem
|
||||||
|
# docs:
|
||||||
|
# - <https://nixos.wiki/wiki/Iwd>
|
||||||
|
# - <https://iwd.wiki.kernel.org/networkmanager>
|
||||||
|
# use `iwctl` to control
|
||||||
|
networking.wireless.iwd.enable = true;
|
||||||
|
networking.networkmanager.wifi.backend = "iwd";
|
||||||
|
|
||||||
|
system.activationScripts.linkIwdKeys = let
|
||||||
|
unwrapped = ../../scripts/install-iwd;
|
||||||
|
install-iwd = pkgs.writeShellApplication {
|
||||||
|
name = "install-iwd";
|
||||||
|
runtimeInputs = with pkgs; [ coreutils gnused ];
|
||||||
|
text = ''${unwrapped} "$@"'';
|
||||||
|
};
|
||||||
|
in (lib.stringAfter
|
||||||
|
[ "setupSecrets" ]
|
||||||
|
''
|
||||||
|
mkdir -p /var/lib/iwd
|
||||||
|
${install-iwd}/bin/install-iwd /run/secrets/iwd /var/lib/iwd
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
# TODO: use a glob, or a list, or something?
|
||||||
|
sops.secrets."iwd/community-university.psk" = {
|
||||||
|
sopsFile = ../../secrets/universal/net/community-university.psk.bin;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
sops.secrets."iwd/friend-libertarian-dod.psk" = {
|
||||||
|
sopsFile = ../../secrets/universal/net/friend-libertarian-dod.psk.bin;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
sops.secrets."iwd/friend-rationalist-empathist.psk" = {
|
||||||
|
sopsFile = ../../secrets/universal/net/friend-rationalist-empathist.psk.bin;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
sops.secrets."iwd/home-bedroom.psk" = {
|
||||||
|
sopsFile = ../../secrets/universal/net/home-bedroom.psk.bin;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
sops.secrets."iwd/home-shared-24G.psk" = {
|
||||||
|
sopsFile = ../../secrets/universal/net/home-shared-24G.psk.bin;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
sops.secrets."iwd/home-shared.psk" = {
|
||||||
|
sopsFile = ../../secrets/universal/net/home-shared.psk.bin;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
sops.secrets."iwd/iphone" = {
|
||||||
|
sopsFile = ../../secrets/universal/net/iphone.psk.bin;
|
||||||
|
format = "binary";
|
||||||
|
};
|
||||||
|
}
|
53
modules/universal/secrets.nix
Normal file
53
modules/universal/secrets.nix
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# SOPS configuration:
|
||||||
|
# docs: https://github.com/Mic92/sops-nix
|
||||||
|
#
|
||||||
|
# for each new user you want to edit sops files:
|
||||||
|
# create a private age key from ssh key:
|
||||||
|
# $ mkdir -p ~/.config/sops/age; ssh-to-age -private-key -i ~/.ssh/id_ed25519 > ~/.config/sops/age/keys.txt; chmod 600 ~/.config/sops/age/keys.txt
|
||||||
|
# if the private key was password protected, then first decrypt it:
|
||||||
|
# $ cp ~/.ssh/id_ed25519 /tmp/id_ed25519
|
||||||
|
# $ ssh-keygen -p -N "" -f /tmp/id_ed25519
|
||||||
|
#
|
||||||
|
# for each user you want to decrypt secrets:
|
||||||
|
# $ cat ~/.ssh/id_ed25519.pub | ssh-to-age
|
||||||
|
# add the result to .sops.yaml
|
||||||
|
# since we specify ssh pubkeys in the nix config, you can just grep for `ssh-ed25519` here and use those instead
|
||||||
|
#
|
||||||
|
# for each machine you want to decrypt secrets:
|
||||||
|
# $ cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age
|
||||||
|
# add the result to .sops.yaml
|
||||||
|
# $ sops updatekeys secrets/example.yaml
|
||||||
|
#
|
||||||
|
# to create a new secret:
|
||||||
|
# $ sops secrets/example.yaml
|
||||||
|
# control access below (sops.secret.<x>.owner = ...)
|
||||||
|
#
|
||||||
|
# to read a secret:
|
||||||
|
# $ cat /run/secrets/example_key
|
||||||
|
|
||||||
|
# sops.age.sshKeyPaths = [ "/home/colin/.ssh/id_ed25519_dec" ];
|
||||||
|
# This will add secrets.yaml to the nix store
|
||||||
|
# You can avoid this by adding a string to the full path instead, i.e.
|
||||||
|
# sops.defaultSopsFile = "/root/.sops/secrets/example.yaml";
|
||||||
|
sops.defaultSopsFile = ./../../secrets/universal.yaml;
|
||||||
|
# This will automatically import SSH keys as age keys
|
||||||
|
sops.age.sshKeyPaths = [
|
||||||
|
"/etc/ssh/ssh_host_ed25519_key"
|
||||||
|
# "/home/colin/.ssh/id_ed25519_dec"
|
||||||
|
];
|
||||||
|
# This is using an age key that is expected to already be in the filesystem
|
||||||
|
# sops.age.keyFile = "/home/colin/.ssh/age.pub";
|
||||||
|
# sops.age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||||
|
# This will generate a new key if the key specified above does not exist
|
||||||
|
# sops.age.generateKey = true;
|
||||||
|
# This is the actual specification of the secrets.
|
||||||
|
# sops.secrets.example_key = {
|
||||||
|
# owner = config.users.users.colin.name;
|
||||||
|
# };
|
||||||
|
# sops.secrets."myservice/my_subdir/my_secret" = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
132
modules/universal/users.nix
Normal file
132
modules/universal/users.nix
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
# installer docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.sane.users;
|
||||||
|
# see nixpkgs/nixos/modules/services/networking/dhcpcd.nix
|
||||||
|
hasDHCP = config.networking.dhcpcd.enable &&
|
||||||
|
(config.networking.useDHCP || any (i: i.useDHCP == true) (attrValues config.networking.interfaces));
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
sane.users.guest.enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# Users are exactly these specified here;
|
||||||
|
# old ones will be deleted (from /etc/passwd, etc) upon upgrade.
|
||||||
|
users.mutableUsers = false;
|
||||||
|
|
||||||
|
# docs: https://nixpkgs-manual-sphinx-markedown-example.netlify.app/generated/options-db.xml.html#users-users
|
||||||
|
users.users.colin = {
|
||||||
|
# sets group to "users" (?)
|
||||||
|
isNormalUser = true;
|
||||||
|
home = "/home/colin";
|
||||||
|
uid = config.sane.allocations.colin-uid;
|
||||||
|
# i don't get exactly what this is, but nixos defaults to this non-deterministically
|
||||||
|
# in /var/lib/nixos/auto-subuid-map and i don't want that.
|
||||||
|
subUidRanges = [
|
||||||
|
{ startUid=100000; count=1; }
|
||||||
|
];
|
||||||
|
group = "users";
|
||||||
|
extraGroups = [
|
||||||
|
"wheel"
|
||||||
|
"nixbuild"
|
||||||
|
"networkmanager"
|
||||||
|
# phosh/mobile. XXX colin: unsure if necessary
|
||||||
|
"video"
|
||||||
|
"feedbackd"
|
||||||
|
"dialout" # required for modem access
|
||||||
|
];
|
||||||
|
initialPassword = lib.mkDefault "";
|
||||||
|
shell = pkgs.zsh;
|
||||||
|
# shell = pkgs.bashInteractive;
|
||||||
|
# XXX colin: create ssh key for THIS user by logging in and running:
|
||||||
|
# ssh-keygen -t ed25519
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu colin@lappy"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX colin@desko"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX colin@servo"
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU colin@moby"
|
||||||
|
];
|
||||||
|
|
||||||
|
pamMount = {
|
||||||
|
# mount encrypted stuff at login
|
||||||
|
# requires that login password == fs encryption password
|
||||||
|
# fstype = "fuse";
|
||||||
|
# path = "${pkgs.gocryptfs}/bin/gocryptfs#/nix/persist/home/colin/private";
|
||||||
|
fstype = "fuse.gocryptfs";
|
||||||
|
path = "/nix/persist/home/colin/private";
|
||||||
|
mountpoint = "/home/colin/private";
|
||||||
|
options="nodev,nosuid,quiet,allow_other";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
sane.impermanence.service-dirs = mkIf cfg.guest.enable [
|
||||||
|
{ user = "guest"; group = "users"; directory = "/home/guest"; }
|
||||||
|
];
|
||||||
|
users.users.guest = mkIf cfg.guest.enable {
|
||||||
|
isNormalUser = true;
|
||||||
|
home = "/home/guest";
|
||||||
|
uid = config.sane.allocations.guest-uid;
|
||||||
|
subUidRanges = [
|
||||||
|
{ startUid=200000; count=1; }
|
||||||
|
];
|
||||||
|
group = "users";
|
||||||
|
initialPassword = lib.mkDefault "";
|
||||||
|
shell = pkgs.zsh;
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
# TODO: insert pubkeys that should be allowed in
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.dhcpcd = mkIf hasDHCP {
|
||||||
|
uid = config.sane.allocations.dhcpcd-uid;
|
||||||
|
};
|
||||||
|
users.groups.dhcpcd = mkIf hasDHCP {
|
||||||
|
gid = config.sane.allocations.dhcpcd-gid;
|
||||||
|
};
|
||||||
|
|
||||||
|
security.sudo = {
|
||||||
|
enable = true;
|
||||||
|
wheelNeedsPassword = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
permitRootLogin = "no";
|
||||||
|
passwordAuthentication = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# affix some UIDs which were historically auto-generated
|
||||||
|
users.users.sshd.uid = config.sane.allocations.sshd-uid;
|
||||||
|
users.groups.polkituser.gid = config.sane.allocations.polkituser-gid;
|
||||||
|
users.groups.sshd.gid = config.sane.allocations.sshd-gid;
|
||||||
|
users.groups.systemd-coredump.gid = config.sane.allocations.systemd-coredump-gid;
|
||||||
|
users.users.nscd.uid = config.sane.allocations.nscd-uid;
|
||||||
|
users.groups.nscd.gid = config.sane.allocations.nscd-gid;
|
||||||
|
users.users.systemd-oom.uid = config.sane.allocations.systemd-oom-uid;
|
||||||
|
users.groups.systemd-oom.gid = config.sane.allocations.systemd-oom-gid;
|
||||||
|
|
||||||
|
# guarantee determinism in uid/gid generation for users:
|
||||||
|
assertions = let
|
||||||
|
uidAssertions = builtins.attrValues (builtins.mapAttrs (name: user: {
|
||||||
|
assertion = user.uid != null;
|
||||||
|
message = "non-deterministic uid detected for: ${name}";
|
||||||
|
}) config.users.users);
|
||||||
|
gidAssertions = builtins.attrValues (builtins.mapAttrs (name: group: {
|
||||||
|
assertion = group.gid != null;
|
||||||
|
message = "non-deterministic gid detected for: ${name}";
|
||||||
|
}) config.users.groups);
|
||||||
|
autoSubAssertions = builtins.attrValues (builtins.mapAttrs (name: user: {
|
||||||
|
assertion = !user.autoSubUidGidRange;
|
||||||
|
message = "non-deterministic subUids/Guids detected for: ${name}";
|
||||||
|
}) config.users.users);
|
||||||
|
in uidAssertions ++ gidAssertions ++ autoSubAssertions;
|
||||||
|
};
|
||||||
|
}
|
58
modules/universal/vpn.nix
Normal file
58
modules/universal/vpn.nix
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
networking.wg-quick.interfaces.ovpnd-us = {
|
||||||
|
address = [
|
||||||
|
"172.27.237.218/32"
|
||||||
|
"fd00:0000:1337:cafe:1111:1111:ab00:4c8f/128"
|
||||||
|
];
|
||||||
|
dns = [
|
||||||
|
"46.227.67.134"
|
||||||
|
"192.165.9.158"
|
||||||
|
];
|
||||||
|
peers = [
|
||||||
|
{
|
||||||
|
allowedIPs = [
|
||||||
|
"0.0.0.0/0"
|
||||||
|
"::/0"
|
||||||
|
];
|
||||||
|
endpoint = "vpn31.prd.losangeles.ovpn.com:9929";
|
||||||
|
publicKey = "VW6bEWMOlOneta1bf6YFE25N/oMGh1E1UFBCfyggd0k=";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
privateKeyFile = config.sops.secrets.wg_ovpnd_us_privkey.path;
|
||||||
|
# to start: `systemctl start wg-quick-ovpnd-us`
|
||||||
|
autostart = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.wg-quick.interfaces.ovpnd-ukr = {
|
||||||
|
address = [
|
||||||
|
"172.18.180.159/32"
|
||||||
|
"fd00:0000:1337:cafe:1111:1111:ec5c:add3/128"
|
||||||
|
];
|
||||||
|
dns = [
|
||||||
|
"46.227.67.134"
|
||||||
|
"192.165.9.158"
|
||||||
|
];
|
||||||
|
peers = [
|
||||||
|
{
|
||||||
|
allowedIPs = [
|
||||||
|
"0.0.0.0/0"
|
||||||
|
"::/0"
|
||||||
|
];
|
||||||
|
endpoint = "vpn96.prd.kyiv.ovpn.com:9929";
|
||||||
|
publicKey = "CjZcXDxaaKpW8b5As1EcNbI6+42A6BjWahwXDCwfVFg=";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
privateKeyFile = config.sops.secrets.wg_ovpnd_ukr_privkey.path;
|
||||||
|
# to start: `systemctl start wg-quick-ovpnd-ukr`
|
||||||
|
autostart = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets."wg_ovpnd_us_privkey" = {
|
||||||
|
sopsFile = ../../secrets/universal.yaml;
|
||||||
|
};
|
||||||
|
sops.secrets."wg_ovpnd_ukr_privkey" = {
|
||||||
|
sopsFile = ../../secrets/universal.yaml;
|
||||||
|
};
|
||||||
|
}
|
@@ -1,19 +0,0 @@
|
|||||||
diff --git a/nixos/modules/services/x11/desktop-managers/phosh.nix b/nixos/modules/services/x11/desktop-managers/phosh.nix
|
|
||||||
index 4bf78fa16e7..13f7b3fbef2 100644
|
|
||||||
--- a/nixos/modules/services/x11/desktop-managers/phosh.nix
|
|
||||||
+++ b/nixos/modules/services/x11/desktop-managers/phosh.nix
|
|
||||||
@@ -78,7 +78,13 @@ let
|
|
||||||
description = ''
|
|
||||||
Display scaling factor.
|
|
||||||
'';
|
|
||||||
- type = types.nullOr types.ints.unsigned;
|
|
||||||
+ type = types.nullOr (
|
|
||||||
+ types.addCheck
|
|
||||||
+ (types.either types.int types.float)
|
|
||||||
+ (x : x > 0)
|
|
||||||
+ ) // {
|
|
||||||
+ description = "null or positive integer or float";
|
|
||||||
+ };
|
|
||||||
default = null;
|
|
||||||
example = 2;
|
|
||||||
};
|
|
@@ -1,18 +0,0 @@
|
|||||||
diff --git a/pkgs/applications/misc/whalebird/default.nix b/pkgs/applications/misc/whalebird/default.nix
|
|
||||||
index 9b8a7f0a348..0f60f74c91b 100644
|
|
||||||
--- a/pkgs/applications/misc/whalebird/default.nix
|
|
||||||
+++ b/pkgs/applications/misc/whalebird/default.nix
|
|
||||||
@@ -3,11 +3,11 @@
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
pname = "whalebird";
|
|
||||||
- version = "4.5.4";
|
|
||||||
+ version = "4.6.0";
|
|
||||||
|
|
||||||
src = fetchurl {
|
|
||||||
url = "https://github.com/h3poteto/whalebird-desktop/releases/download/${version}/Whalebird-${version}-linux-x64.deb";
|
|
||||||
- sha256 = "048c2hpnlzjli8r1lcm7hd32qfsq4p9vkimrgc049yw9f15ndjpr";
|
|
||||||
+ sha256 = "d8042eb21e4320771782a1835a591252894ad657eec46248c807d5a772e1938e";
|
|
||||||
};
|
|
||||||
|
|
||||||
nativeBuildInputs = [
|
|
43
nixpatches/07-duplicity-rich-url.patch
Normal file
43
nixpatches/07-duplicity-rich-url.patch
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
diff --git a/nixos/modules/services/backup/duplicity.nix b/nixos/modules/services/backup/duplicity.nix
|
||||||
|
index 6949fa8b995..33d772ffa37 100644
|
||||||
|
--- a/nixos/modules/services/backup/duplicity.nix
|
||||||
|
+++ b/nixos/modules/services/backup/duplicity.nix
|
||||||
|
@@ -54,6 +54,17 @@ in
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
+ escapeUrl = mkOption {
|
||||||
|
+ type = types.bool;
|
||||||
|
+ example = false;
|
||||||
|
+ default = true;
|
||||||
|
+ description = ''
|
||||||
|
+ Whether to escape the targetUrl when passing it to Duplicity as a CLI
|
||||||
|
+ argument. One might disable this in order to make use of shell
|
||||||
|
+ expressions such as environment variables.
|
||||||
|
+ '';
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
secretFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
@@ -148,7 +159,7 @@ in
|
||||||
|
|
||||||
|
script =
|
||||||
|
let
|
||||||
|
- target = escapeShellArg cfg.targetUrl;
|
||||||
|
+ target = if cfg.escapeUrl then (escapeShellArg cfg.targetUrl) else cfg.targetUrl;
|
||||||
|
extra = escapeShellArgs ([ "--archive-dir" stateDirectory ] ++ cfg.extraFlags);
|
||||||
|
dup = "${pkgs.duplicity}/bin/duplicity";
|
||||||
|
in
|
||||||
|
@@ -158,9 +169,8 @@ in
|
||||||
|
${lib.optionalString (cfg.cleanup.maxAge != null) "${dup} remove-older-than ${lib.escapeShellArg cfg.cleanup.maxAge} ${target} --force ${extra}"}
|
||||||
|
${lib.optionalString (cfg.cleanup.maxFull != null) "${dup} remove-all-but-n-full ${toString cfg.cleanup.maxFull} ${target} --force ${extra}"}
|
||||||
|
${lib.optionalString (cfg.cleanup.maxIncr != null) "${dup} remove-all-inc-of-but-n-full ${toString cfg.cleanup.maxIncr} ${target} --force ${extra}"}
|
||||||
|
- exec ${dup} ${if cfg.fullIfOlderThan == "always" then "full" else "incr"} ${lib.escapeShellArgs (
|
||||||
|
- [ cfg.root cfg.targetUrl ]
|
||||||
|
- ++ concatMap (p: [ "--include" p ]) cfg.include
|
||||||
|
+ exec ${dup} ${if cfg.fullIfOlderThan == "always" then "full" else "incr"} ${lib.escapeShellArg cfg.root} ${target} ${lib.escapeShellArgs (
|
||||||
|
+ concatMap (p: [ "--include" p ]) cfg.include
|
||||||
|
++ concatMap (p: [ "--exclude" p ]) cfg.exclude
|
||||||
|
++ (lib.optionals (cfg.fullIfOlderThan != "never" && cfg.fullIfOlderThan != "always") [ "--full-if-older-than" cfg.fullIfOlderThan ])
|
||||||
|
)} ${extra}
|
40
nixpatches/10-flutter-arm64.patch
Normal file
40
nixpatches/10-flutter-arm64.patch
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
diff --git a/pkgs/applications/networking/instant-messengers/fluffychat/default.nix b/pkgs/applications/networking/instant-messengers/fluffychat/default.nix
|
||||||
|
index 565c44f72e9..f20a3d4e9be 100644
|
||||||
|
--- a/pkgs/applications/networking/instant-messengers/fluffychat/default.nix
|
||||||
|
+++ b/pkgs/applications/networking/instant-messengers/fluffychat/default.nix
|
||||||
|
@@ -4,13 +4,19 @@
|
||||||
|
, olm
|
||||||
|
, imagemagick
|
||||||
|
, makeDesktopItem
|
||||||
|
+, stdenv
|
||||||
|
}:
|
||||||
|
|
||||||
|
+let vendorHashes = {
|
||||||
|
+ x86_64-linux = "sha256-p5EJP2zSvWyRV1uyTHw0EpFsEwAGtX5B9WVjpLmnVew=";
|
||||||
|
+ aarch64-linux = "sha256-Ps0HmDI6BFxHrLRq3KWNk4hw0qneq5hqB/Mp99f+hO4=";
|
||||||
|
+};
|
||||||
|
+in
|
||||||
|
flutter.mkFlutterApp rec {
|
||||||
|
pname = "fluffychat";
|
||||||
|
version = "1.6.1";
|
||||||
|
|
||||||
|
- vendorHash = "sha256-SelMRETFYZgTStV90gRoKhazu1NPbcSMO9mYebSQskQ=";
|
||||||
|
+ vendorHash = vendorHashes."${stdenv.hostPlatform.system}" or (throw "unsupported system: ${stdenv.hostPlatform.system}");
|
||||||
|
|
||||||
|
src = fetchFromGitLab {
|
||||||
|
owner = "famedly";
|
||||||
|
diff --git a/pkgs/development/compilers/flutter/default.nix b/pkgs/development/compilers/flutter/default.nix
|
||||||
|
index 9eba6773448..e9d352169b2 100644
|
||||||
|
--- a/pkgs/development/compilers/flutter/default.nix
|
||||||
|
+++ b/pkgs/development/compilers/flutter/default.nix
|
||||||
|
@@ -19,6 +19,10 @@ let
|
||||||
|
url = "${dartSourceBase}/stable/release/${dartVersion}/sdk/dartsdk-linux-x64-release.zip";
|
||||||
|
sha256 = "sha256-PMY6DCFQC8XrlnFzOEPcwgBAs5/cAvNd78969Z+I1Fk=";
|
||||||
|
};
|
||||||
|
+ "${dartVersion}-aarch64-linux" = fetchurl {
|
||||||
|
+ url = "${dartSourceBase}/stable/release/${dartVersion}/sdk/dartsdk-linux-arm64-release.zip";
|
||||||
|
+ sha256 = "sha256-BIK6kUx+m+/GfR/wBXv8rjVNbP6w1HFvH/RGIwiaJog=";
|
||||||
|
+ };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
54
nixpatches/list.nix
Normal file
54
nixpatches/list.nix
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
fetchpatch: [
|
||||||
|
# phosh-mobile-settings: init at 0.21.1
|
||||||
|
(fetchpatch {
|
||||||
|
url = "http://git.uninsane.org/colin/nixpkgs/commit/0c1a7e8504291eb0076bbee3f8ebf693f4641112.diff";
|
||||||
|
# url = "https://github.com/NixOS/nixpkgs/pull/193845.diff";
|
||||||
|
sha256 = "sha256-OczjlQcG7sTM/V9Y9VL/qdwaWPKfjAJsh3czqqhRQig=";
|
||||||
|
})
|
||||||
|
|
||||||
|
# # kaiteki: init at 2022-09-03
|
||||||
|
# vendorHash changes too frequently (might not be reproducible).
|
||||||
|
# using local package defn until stabilized
|
||||||
|
# (fetchpatch {
|
||||||
|
# url = "https://git.uninsane.org/colin/nixpkgs/commit/e2c7f5f4870fcb0e5405e9001b39a64c516852d4.diff";
|
||||||
|
# # url = "https://github.com/NixOS/nixpkgs/pull/193169.diff";
|
||||||
|
# sha256 = "sha256-UWnfS+stVpUZ3Sfaym9XtVBlwvHWJVMaW7cYIcf3M5Q=";
|
||||||
|
# })
|
||||||
|
|
||||||
|
# freshrss: patchShebangs instead of specifying interpreter in the service
|
||||||
|
(fetchpatch {
|
||||||
|
# url = "https://git.uninsane.org/colin/nixpkgs/commit/9443d83e6fee728c1926a783647b45011bd3b514.diff";
|
||||||
|
url = "https://github.com/NixOS/nixpkgs/pull/196140.diff";
|
||||||
|
sha256 = "sha256-Lngle5YTE7ymQyUarKbebMjiaTlY5cJBoaeZk7AgbXE=";
|
||||||
|
})
|
||||||
|
|
||||||
|
# nautilus: look for the gtk4 FileChooser settings instead of the gtk4 one
|
||||||
|
(fetchpatch {
|
||||||
|
# original version (include the patch in nixpkgs)
|
||||||
|
# url = "https://git.uninsane.org/colin/nixpkgs/commit/4636a04c1c4982a0e71ae77d3aa6f52d1a3170f1.diff";
|
||||||
|
# sha256 = "sha256-XKfXStdcveYuk58rlORVJOv0a9Q5aRj1bYT5k79rL0g=";
|
||||||
|
|
||||||
|
# v2 (fetchpatch from upstream PR)
|
||||||
|
# url = "https://git.uninsane.org/colin/nixpkgs/commit/730a802808c549220144e4e62aa419bb07c5ae29.diff";
|
||||||
|
url = "https://github.com/NixOS/nixpkgs/pull/195985.diff";
|
||||||
|
sha256 = "sha256-zd7WGOTm3ygh0Wk3uiA+1S+RqD9yWDSXvo7veHs0K00=";
|
||||||
|
})
|
||||||
|
|
||||||
|
# Fix mk flutter app
|
||||||
|
# closed (not merged). updates fluffychat 1.2.0 -> 1.6.1, but unstable hashing
|
||||||
|
# (fetchpatch {
|
||||||
|
# url = "https://github.com/NixOS/nixpkgs/pull/186839.diff";
|
||||||
|
# sha256 = "sha256-NdIfie+eTy4V1vgqiiRPtWdnxZ5ZHsvCMfkEDUv9SC8=";
|
||||||
|
# })
|
||||||
|
|
||||||
|
# for raspberry pi: allow building u-boot for rpi 4{,00}
|
||||||
|
# TODO: remove after upstreamed: https://github.com/NixOS/nixpkgs/pull/176018
|
||||||
|
# (it's a dupe of https://github.com/NixOS/nixpkgs/pull/112677 )
|
||||||
|
./02-rpi4-uboot.patch
|
||||||
|
|
||||||
|
# TODO: upstream
|
||||||
|
./07-duplicity-rich-url.patch
|
||||||
|
|
||||||
|
# enable aarch64 support for flutter's dart package
|
||||||
|
# ./10-flutter-arm64.patch
|
||||||
|
]
|
13
pkgs/bootpart-tow-boot-rpi-aarch64/config.txt
Normal file
13
pkgs/bootpart-tow-boot-rpi-aarch64/config.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[pi3]
|
||||||
|
kernel=Tow-Boot.noenv.rpi3.bin
|
||||||
|
|
||||||
|
[pi4]
|
||||||
|
kernel=Tow-Boot.noenv.rpi4.bin
|
||||||
|
enable_gic=1
|
||||||
|
armstub=armstub8-gic.bin
|
||||||
|
disable_overscan=1
|
||||||
|
|
||||||
|
[all]
|
||||||
|
arm_64bit=1
|
||||||
|
enable_uart=1
|
||||||
|
avoid_warnings=1
|
37
pkgs/bootpart-tow-boot-rpi-aarch64/default.nix
Normal file
37
pkgs/bootpart-tow-boot-rpi-aarch64/default.nix
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{ stdenv, pkgs }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "bootpart-tow-boot-rpi-aarch64";
|
||||||
|
version = "1";
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
tow-boot-rpi4 # for Tow-Boot.*.bin
|
||||||
|
raspberrypifw # for bootcode.bin, *.dat, *.elf, *.dtb
|
||||||
|
raspberrypi-armstubs # for armstub*
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
src = ./config.txt;
|
||||||
|
|
||||||
|
dontUnpack = true;
|
||||||
|
|
||||||
|
installPhase = with pkgs; ''
|
||||||
|
mkdir "$out"
|
||||||
|
cp ${tow-boot-rpi4}/Tow-Boot.noenv.*.bin "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.dtb "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.bin "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.dat "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.img "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.elf "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/overlays "$out"/
|
||||||
|
cp ${raspberrypi-armstubs}/* "$out"/
|
||||||
|
cp ${src} "$out"/config.txt
|
||||||
|
'';
|
||||||
|
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "unmanaged files to place in /boot on a raspberry pi system";
|
||||||
|
platforms = [ "aarch64-linux" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
10
pkgs/bootpart-u-boot-rpi-aarch64/config.txt
Normal file
10
pkgs/bootpart-u-boot-rpi-aarch64/config.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[pi4]
|
||||||
|
kernel=u-boot.bin
|
||||||
|
enable_gic=1
|
||||||
|
armstub=armstub8-gic.bin
|
||||||
|
disable_overscan=1
|
||||||
|
|
||||||
|
[all]
|
||||||
|
arm_64bit=1
|
||||||
|
enable_uart=1
|
||||||
|
avoid_warnings=1
|
39
pkgs/bootpart-u-boot-rpi-aarch64/default.nix
Normal file
39
pkgs/bootpart-u-boot-rpi-aarch64/default.nix
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{ stdenv, pkgs }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "bootpart-u-boot-rpi-aarch64";
|
||||||
|
version = "1";
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
ubootRaspberryPi4_64bit
|
||||||
|
raspberrypifw # for bootcode.bin, *.dat, *.elf, *.dtb
|
||||||
|
raspberrypi-armstubs # for armstub*
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
src = ./config.txt;
|
||||||
|
|
||||||
|
dontUnpack = true;
|
||||||
|
|
||||||
|
installPhase = with pkgs; ''
|
||||||
|
mkdir "$out"
|
||||||
|
cp ${ubootRaspberryPi4_64bit}/u-boot.bin "$out"/
|
||||||
|
cp ${ubootRaspberryPi4_64bit}/*.dtb "$out"/
|
||||||
|
# NB: raspberrypifw dtb's are meant for the kernel, not for u-boot
|
||||||
|
# cp -R ${raspberrypifw}/share/raspberrypi/boot/*.dtb "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.bin "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.dat "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.img "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/*.elf "$out"/
|
||||||
|
cp -R ${raspberrypifw}/share/raspberrypi/boot/overlays "$out"/
|
||||||
|
cp ${raspberrypi-armstubs}/* "$out"/
|
||||||
|
cp ${src} "$out"/config.txt
|
||||||
|
'';
|
||||||
|
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "unmanaged files to place in /boot on a raspberry pi system";
|
||||||
|
platforms = [ "aarch64-linux" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
37
pkgs/bootpart-uefi-x86_64/default.nix
Normal file
37
pkgs/bootpart-uefi-x86_64/default.nix
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{ stdenv, pkgs }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "bootpart-uefi-x86_64";
|
||||||
|
version = "1";
|
||||||
|
|
||||||
|
buildInputs = [ pkgs.syslinux ];
|
||||||
|
|
||||||
|
dontUnpack = true;
|
||||||
|
|
||||||
|
installPhase = with pkgs; ''
|
||||||
|
# populate the EFI directory with syslinux, and configure it to read that extlinux.conf file managed by nixos
|
||||||
|
mkdir -p "$out/EFI/syslinux" "$out/EFI/BOOT" "$out/syslinux"
|
||||||
|
cp -R "${syslinux}/share/syslinux/efi64"/* "$out/EFI/syslinux"
|
||||||
|
echo "DEFAULT trampoline" > "$out/EFI/syslinux/syslinux.cfg"
|
||||||
|
echo "LABEL trampoline" >> "$out/EFI/syslinux/syslinux.cfg"
|
||||||
|
echo " SAY trampoline into generic extlinux.conf" >> "$out/EFI/syslinux/syslinux.cfg"
|
||||||
|
echo " CONFIG ../../syslinux/syslinux.cfg ../../syslinux" >> "$out/EFI/syslinux/syslinux.cfg"
|
||||||
|
|
||||||
|
# we create this "trampoline" layer so that we can setup the UI directive
|
||||||
|
# and enable a menu before loading the real, nixos-managed extlinux.conf
|
||||||
|
cp "${syslinux}/share/syslinux/efi64/menu.c32" "$out/syslinux/menu.c32"
|
||||||
|
echo "UI menu.c32" > "$out/syslinux/syslinux.cfg"
|
||||||
|
echo "INCLUDE ../extlinux/extlinux.conf" >> "$out/syslinux/syslinux.cfg"
|
||||||
|
|
||||||
|
# create the EFI/BOOT/BOOTX64.EFI default entry
|
||||||
|
cp "$out/EFI/syslinux"/* "$out/EFI/BOOT"
|
||||||
|
mv "$out/EFI/BOOT/syslinux.efi" "$out/EFI/BOOT/BOOTX64.EFI"
|
||||||
|
'';
|
||||||
|
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "unmanaged files to place in /boot on a x86-64 extlinux system";
|
||||||
|
platforms = [ "x86_64-linux" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
13
pkgs/firefox-unwrapped/allow-searchengines-non-esr.patch
Normal file
13
pkgs/firefox-unwrapped/allow-searchengines-non-esr.patch
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/browser/components/enterprisepolicies/schemas/policies-schema.json b/browser/components/enterprisepolicies/schemas/policies-schema.json
|
||||||
|
index d436cf1ca1..ecd6e53b9e 100644
|
||||||
|
--- a/browser/components/enterprisepolicies/schemas/policies-schema.json
|
||||||
|
+++ b/browser/components/enterprisepolicies/schemas/policies-schema.json
|
||||||
|
@@ -1074,7 +1074,7 @@
|
||||||
|
},
|
||||||
|
|
||||||
|
"SearchEngines": {
|
||||||
|
- "enterprise_only": true,
|
||||||
|
+ "enterprise_only": false,
|
||||||
|
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user