Compare commits
1081 Commits
devplayer0
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
f4a5f018f7 | ||
|
a056552137 | ||
|
7fd4e5f7c3 | ||
|
60a1ffe606 | ||
|
30e8e79ac9 | ||
|
b99389f02d | ||
|
cbac36aa93 | ||
|
5a7a68136d | ||
|
08061fddcc | ||
|
1819817298 | ||
|
d772438feb | ||
|
711fb0167d | ||
|
3c352ba051 | ||
|
23a60b0966 | ||
|
1a827e70dc | ||
|
f826c0aafa | ||
|
682cf788e1 | ||
|
52614866fd | ||
|
bbd2561c7f | ||
|
f9b5b1f98c | ||
|
b88f9fe294 | ||
|
c56b374946 | ||
|
b20782310e | ||
|
0ff027e0ae | ||
|
9f06965445 | ||
|
b5dea63a56 | ||
|
01ccbb3e07 | ||
|
b22490d198 | ||
|
0ee5d53bc1 | ||
|
226e750730 | ||
|
71622a3d82 | ||
|
1502af5a9f | ||
|
43a6c7cbdc | ||
|
16351967ed | ||
|
adf9e07578 | ||
|
debeda222a | ||
|
7064bc9d99 | ||
|
c14b9064de | ||
|
880ca7e7cc | ||
|
a874ed2e83 | ||
|
2a59d4daed | ||
|
c583c7cdc5 | ||
|
8d07d2cae3 | ||
|
488a5de3ba | ||
|
82919b8e74 | ||
|
b4a5d25d3f | ||
|
fa3abc3441 | ||
|
8e07d8423e | ||
|
84abec6a3d | ||
|
516c5a1921 | ||
|
431621bba7 | ||
|
f873018b61 | ||
|
955a3e01f2 | ||
|
d266649035 | ||
|
a1d35315ca | ||
|
511b0843c7 | ||
|
0c78ebd800 | ||
|
4e0999e058 | ||
|
f40efe1ce9 | ||
|
8fe12bdf8c | ||
|
977c297cc6 | ||
|
99c3d04cf2 | ||
|
cd45cfe9c4 | ||
|
7a6eb7e69d | ||
|
0633f26e7b | ||
|
4e480bb11d | ||
|
183d460315 | ||
|
56597456e1 | ||
|
a68512db54 | ||
|
a3f0dacb12 | ||
|
33f830be76 | ||
|
2fe4a84888 | ||
|
dfd6a4a50f | ||
|
73710fe751 | ||
|
a81305c367 | ||
|
ffdc074242 | ||
|
c18529fe16 | ||
|
a5ea1f37d2 | ||
|
94ff31ecb8 | ||
|
77a34c1488 | ||
|
f3bb835a46 | ||
|
3c818433d5 | ||
|
1f506d83a5 | ||
|
0dd1c943d7 | ||
|
9e34adf224 | ||
|
617a7655c2 | ||
|
8a667a5213 | ||
|
425683af2d | ||
|
08ae948608 | ||
|
397b693e76 | ||
|
9b8a474730 | ||
|
97520c9ed0 | ||
|
fb35df9f91 | ||
|
14df465130 | ||
|
395d59f54b | ||
|
9fc2250e80 | ||
|
c989da7576 | ||
|
87e00e577b | ||
|
b0a667f16d | ||
|
64d8372298 | ||
|
c363307fac | ||
|
c60179cdca | ||
|
972f716b4f | ||
|
32c14266ff | ||
|
2ba711361f | ||
|
923e2e59cc | ||
|
e012442a7e | ||
|
46fba61472 | ||
|
be214b4f0e | ||
|
86911616f7 | ||
|
866939c5b2 | ||
|
57feb2a16f | ||
|
2885c26828 | ||
|
93dd0f49d8 | ||
|
357fff0f44 | ||
|
0ea5454f75 | ||
|
18cf9ad14b | ||
|
8819a28de8 | ||
|
e383460f09 | ||
|
e5a4cc81ab | ||
|
9a75f507da | ||
|
8de0d4c501 | ||
|
f87e975048 | ||
|
b422806efb | ||
|
3546de54ee | ||
|
8ad72fe696 | ||
|
a162fd2c83 | ||
|
bb3c18e58d | ||
|
5a32f1dbaf | ||
|
cf833bdebf | ||
|
8f9968055f | ||
|
9ae3dd3069 | ||
|
fe1d869538 | ||
|
4703b8d2c7 | ||
|
ed30be523a | ||
|
a76379e89c | ||
|
cf84acca6b | ||
|
9a6d55f825 | ||
|
fd5d1e6df1 | ||
|
ad356675a8 | ||
|
df47280e16 | ||
|
8989584d83 | ||
|
88bd81e177 | ||
|
23a7a5d3cc | ||
|
715ce088a4 | ||
|
bcb2e3071f | ||
|
e090142219 | ||
|
c318085efa | ||
|
3be17711c3 | ||
|
4d39a7b8e6 | ||
|
ea65e3038a | ||
|
69f2173cf6 | ||
|
f962636439 | ||
|
6394be51d2 | ||
|
b3e8e251f3 | ||
|
962a6862f0 | ||
|
a4242293ee | ||
|
4278c679ea | ||
|
8c4cc0b2c1 | ||
|
bcc5c141bf | ||
|
ef688ab1ca | ||
|
836aba1612 | ||
|
9396352fba | ||
|
3b56519f50 | ||
|
50d277f9e7 | ||
|
e16d20f2ba | ||
|
33cca9243a | ||
|
96a833668a | ||
|
02e1f93cb4 | ||
|
61d0cc13ef | ||
|
b4d7b9ade2 | ||
|
bf5d64a130 | ||
|
9ba5483ef3 | ||
|
c32996b673 | ||
|
79a75faeb9 | ||
|
cb016f116b | ||
|
82434f382c | ||
|
ba5a5fac7b | ||
|
c9c0906085 | ||
|
bc604cb912 | ||
|
da01f1f995 | ||
|
64de6c47ca | ||
|
9ae0f77577 | ||
|
266283bec3 | ||
|
ada2b1255e | ||
|
c1d4a2c2c1 | ||
|
223586a617 | ||
|
61f3a9680a | ||
|
e3199efe35 | ||
|
88bdfb1565 | ||
|
4a98c23fd0 | ||
|
2aabd11961 | ||
|
cf28257e4f | ||
|
2fd0802cbf | ||
|
207dd001b4 | ||
|
5978e7fa2f | ||
|
dd884440df | ||
|
c055f6bc0a | ||
|
37715c3137 | ||
|
2c7123c522 | ||
|
47da8867f3 | ||
|
b9816a9ba6 | ||
|
f5e33aca67 | ||
|
bb2555a094 | ||
|
b6354e9225 | ||
|
4c5015ad7d | ||
|
d3e0827671 | ||
|
2f9c22f53b | ||
|
55d1ba40f2 | ||
|
1b02b613fa | ||
|
689cdd9c4b | ||
|
f89a5a2a26 | ||
|
2eaa53ac8c | ||
|
a344bfd09a | ||
|
e3ac562312 | ||
|
bf50468b8f | ||
|
3c18c8fcc2 | ||
|
a403221cb8 | ||
|
ae944e6d41 | ||
|
a551c5a12e | ||
|
26981a812c | ||
|
5de6a11a50 | ||
|
b99353c158 | ||
|
b61dffc48e | ||
|
167244df67 | ||
|
03f953d285 | ||
|
cdc2e32ea4 | ||
|
01c33fb6d7 | ||
|
326602a983 | ||
|
b9da4f27d9 | ||
|
cd2aa80f1c | ||
|
78bccf7125 | ||
|
7f33274e2b | ||
|
2a8bd1bc8c | ||
|
0589c0d364 | ||
|
ab4517e2fc | ||
|
eebd4c3b01 | ||
|
8ee82bb6f6 | ||
|
9b0e7e5e50 | ||
|
0eac31b715 | ||
|
785d9b39fe | ||
|
3846c54866 | ||
|
8a6e2fb470 | ||
|
3dbf6e8399 | ||
|
15ae63f203 | ||
|
410b2d7f07 | ||
|
d063ad64cb | ||
|
d3f13a2d1c | ||
|
eab3a12f09 | ||
|
dee0bf3ba9 | ||
|
3896ef1df7 | ||
|
b32bafe364 | ||
|
f8eae6bfde | ||
|
47dc99eace | ||
|
4992f3d997 | ||
|
c78003c4e0 | ||
|
0aa1319ab1 | ||
|
91d74082c4 | ||
|
06ad3811a8 | ||
|
f3563c996e | ||
|
77fce1dc58 | ||
|
41db5209c7 | ||
|
a230d5228d | ||
|
6d50a8c57f | ||
|
d8410d8366 | ||
|
a0ce661c99 | ||
|
342a5021df | ||
|
6cc7449e30 | ||
|
b0b3a75676 | ||
|
47c83cb438 | ||
|
40142caad0 | ||
|
e6b629da27 | ||
|
55303d50c4 | ||
|
77e646f171 | ||
|
95428bab8c | ||
|
ed307b9aac | ||
|
e641109687 | ||
|
b6df5d10fa | ||
|
6de1312a38 | ||
|
84ace4a412 | ||
|
f50a1bd99d | ||
|
3ac012e7e2 | ||
|
5b0ffc8037 | ||
|
dd363fd877 | ||
|
b989e7e8ad | ||
|
7f6123b2ac | ||
|
5436a94e65 | ||
|
ea0adc05b5 | ||
|
1170690e24 | ||
|
db00b7e57f | ||
|
c0f61fe3d4 | ||
|
cc9e038ab7 | ||
|
be9539b794 | ||
|
a23730505e | ||
|
04ad1f46f9 | ||
|
62510f7f04 | ||
|
31f44e2164 | ||
|
99b2f3707d | ||
|
a0559c7b2b | ||
|
056ebe065a | ||
|
854baca4aa | ||
|
95cc099222 | ||
|
eca5c988af | ||
|
a4ad23a111 | ||
|
fc89c62ec7 | ||
|
96e1dd3cc9 | ||
|
c7d5bac624 | ||
|
c3329f7b0c | ||
|
45d974dfd7 | ||
|
a5141d0d56 | ||
|
2194be4193 | ||
|
0255169931 | ||
|
2ed1d21df1 | ||
|
ff51c1beb8 | ||
|
e4647f0245 | ||
|
16b1fd4129 | ||
|
7483154982 | ||
|
9af3e7da9b | ||
|
b67f6c616a | ||
|
8e9268dfbb | ||
|
836d207c6c | ||
|
c8089754ee | ||
|
8a3d41aa0f | ||
|
db7c27acdf | ||
|
7a6698e0aa | ||
|
7bff6409e3 | ||
|
c941d80adf | ||
|
76d6ef5dde | ||
|
268eadc6ba | ||
|
3756c546a2 | ||
|
09da4761e1 | ||
|
ad52fb854b | ||
|
1cba7befa3 | ||
|
2ad0246b94 | ||
|
923fccbf92 | ||
|
a5865295af | ||
|
4a3071c613 | ||
|
2d2b2dd2e2 | ||
|
311ccd7dd8 | ||
|
b62f26270d | ||
|
56e97be9b0 | ||
|
0196082f6c | ||
|
b8d9c3b2ad | ||
|
f3d53e22f7 | ||
|
b4fd89b737 | ||
|
300d4f73bd | ||
|
8f6163d138 | ||
|
7bcf4b31fe | ||
|
14f8fd6e81 | ||
|
cb460d69fb | ||
|
828496d1a4 | ||
|
1c30becbdd | ||
|
d1fc66799f | ||
|
c0f23c4e5d | ||
|
994a770924 | ||
|
49d26b7cd6 | ||
|
5b7acac7d2 | ||
|
9483e2e635 | ||
|
179f72ed4d | ||
|
1e925a2dfd | ||
|
14877193e2 | ||
|
260fe04e85 | ||
|
98bbdd1246 | ||
|
2d7406c682 | ||
|
2deaa48726 | ||
|
6ede23a857 | ||
|
c55f24450d | ||
|
32d6f52008 | ||
|
1f33e2a756 | ||
|
a1ed423d07 | ||
|
8e750424b4 | ||
|
a5fb96baf0 | ||
|
be84d0bc44 | ||
|
bdf1baf684 | ||
|
0d739c9456 | ||
|
65517c04a4 | ||
|
43d34c4e96 | ||
|
14147f11da | ||
|
e1c06e7f84 | ||
|
63863a8847 | ||
|
ba80e23a74 | ||
|
0ea2d3a446 | ||
|
dff42fc1b8 | ||
|
b860c30ef8 | ||
|
84dafe5c5d | ||
|
7389d32232 | ||
|
22a3deafee | ||
|
cd6c2bc48f | ||
|
53f77a5620 | ||
|
1f197e6da2 | ||
|
44a426a44f | ||
|
6fb81c30b5 | ||
|
e43ca6ae77 | ||
|
130f661d36 | ||
|
a9464b38c3 | ||
|
299f7c8d48 | ||
|
fb9e5b1059 | ||
|
a68d0d6c2b | ||
|
a7c0f23bd6 | ||
|
7d5c030bdf | ||
|
b04ca6b759 | ||
|
b0bb6ea985 | ||
|
cf88138cad | ||
|
38260c284c | ||
|
564e219aa5 | ||
|
cafc21fb16 | ||
|
6f48feb653 | ||
|
614d709921 | ||
|
20b02e33c9 | ||
|
d566f2494f | ||
|
5d55f09c22 | ||
|
1b5237a9bd | ||
|
bb9af90bf2 | ||
|
2099a8d7cc | ||
|
01c1cbeea2 | ||
|
c688c75483 | ||
|
fb08995413 | ||
|
b402ee4285 | ||
|
769f42e45a | ||
|
4feee53847 | ||
|
e892b41187 | ||
|
6832176666 | ||
|
bd06cd59e9 | ||
|
65d311a745 | ||
|
abf234f409 | ||
|
33e47243a2 | ||
|
7e027363e2 | ||
|
d1d6226258 | ||
|
7946623149 | ||
|
aabf3a0c61 | ||
|
f3f3a3eee0 | ||
|
3afd26366a | ||
|
4b39e819bf | ||
|
fec9222abf | ||
|
2adb5faba2 | ||
|
b0fb9d547c | ||
|
39a078a3ef | ||
|
5aa819d0e0 | ||
|
0b87b1feb6 | ||
|
acf1b4900e | ||
|
2538d58436 | ||
|
4f2b642f6c | ||
|
5b9f28cf6e | ||
|
d60e537249 | ||
|
913dffe34c | ||
|
e7387f290c | ||
|
95dbdbbd9a | ||
|
1d62a85ff5 | ||
|
970e93b9f8 | ||
|
f8b32a4921 | ||
|
199ab2b321 | ||
|
97d45f98f2 | ||
|
319cef6187 | ||
|
6399331a25 | ||
|
522d5d85db | ||
|
42e77274c8 | ||
|
d61106e509 | ||
|
421aafb453 | ||
|
64f6de59cc | ||
|
bfff65c1e5 | ||
|
2b1e9f0252 | ||
|
665fcc80ea | ||
|
0b75c4e176 | ||
|
02fe29395d | ||
|
3c268106ae | ||
|
51c0f230d5 | ||
|
171142d09c | ||
|
504fcfb198 | ||
|
d584552796 | ||
|
5706049cf6 | ||
|
bc05d768e3 | ||
|
b3e8cfc28b | ||
|
3e3d4ca65a | ||
|
8d41c90145 | ||
|
95a92c0429 | ||
|
69eb494e68 | ||
|
c2c53cb7b1 | ||
|
3b6448baa5 | ||
|
bfe7bb410f | ||
|
dfb9a94013 | ||
|
81684eba3f | ||
|
eeab2e4e5e | ||
|
70b1a96bf5 | ||
|
49c8101b6f | ||
|
2f682051a9 | ||
|
3ebbc67763 | ||
|
572df3a233 | ||
|
2330454c04 | ||
|
8d4851c6f2 | ||
|
af1aa40e73 | ||
|
d2a0baa169 | ||
|
e62e20249f | ||
|
73b6cbce5c | ||
|
3c02da2176 | ||
|
543abba9d0 | ||
|
115b31f2a3 | ||
|
ff3faba639 | ||
|
43b7d77530 | ||
|
edd47f7c85 | ||
|
47048ebe1e | ||
|
e72faf8015 | ||
|
c8bacdae50 | ||
|
6a134c9a35 | ||
|
ae933cb7df | ||
|
c8aeacd0ae | ||
|
30ccc85dd9 | ||
|
12cadcb077 | ||
|
02d838abb9 | ||
|
acd9b02b6d | ||
|
99d776a64c | ||
|
dabd3bd5fa | ||
|
875cba81ba | ||
|
3380c823c9 | ||
|
51fcc9d335 | ||
|
6dfdf6749f | ||
|
efd30bb7bc | ||
|
c39f3576f4 | ||
|
8cad8436de | ||
|
4b8921fde4 | ||
|
b71f4a89a4 | ||
|
265b3aa46a | ||
|
017d88ec83 | ||
|
7904efb866 | ||
|
892247b9b8 | ||
|
251e822f97 | ||
|
6bf4c9b790 | ||
|
ac0c0e1c33 | ||
|
1fdd6dfe48 | ||
|
58cca6e009 | ||
|
f946c505ed | ||
|
521bba39df | ||
|
b99959d762 | ||
|
07894f4f30 | ||
|
93d6b8180e | ||
|
2d4a4c110a | ||
|
2bf4393a9b | ||
|
83cc2cd01f | ||
|
e14d1dc198 | ||
|
e4ffb753b1 | ||
|
4dbf3a75ae | ||
|
44985668d8 | ||
|
a9748cc118 | ||
|
5f44beaebb | ||
|
e8e5c6c79b | ||
|
cc88c367bb | ||
|
6974870a0a | ||
|
307f280e81 | ||
|
851d23320b | ||
|
8eb355e978 | ||
|
8b8b523eb9 | ||
|
084011a1b4 | ||
|
b3796eddc4 | ||
|
a7f917375f | ||
|
36b176c8e3 | ||
|
9f025e3df5 | ||
|
4f47314003 | ||
|
f9825ae100 | ||
|
3b6ddc5927 | ||
|
ea4bd53274 | ||
|
951787fba3 | ||
|
c617a4cb83 | ||
|
500c84cedd | ||
|
f88528a137 | ||
|
c93d8f88a7 | ||
|
34970fdcf3 | ||
|
faf7fde49e | ||
|
5419e3778f | ||
|
56bd2c2da6 | ||
|
9353cb1b74 | ||
|
1e44f5e3df | ||
|
588c1c985b | ||
|
5b48323837 | ||
|
baece5fb08 | ||
|
95e5f256d6 | ||
|
8f9336460b | ||
|
f1019c7adb | ||
|
e86917ad30 | ||
|
69dd091d51 | ||
|
699ee515a1 | ||
|
4bfa9c3f97 | ||
|
357422f21b | ||
|
c39797b55e | ||
|
5ced735a89 | ||
|
278fc7501c | ||
|
66ea353e1c | ||
|
7123ef8458 | ||
|
3fa1cc4f5f | ||
|
03ba605ab0 | ||
|
44990e93c3 | ||
|
59a4e8349e | ||
|
f8b0d3a756 | ||
|
fe175fe575 | ||
|
43e70943da | ||
|
b04e01279b | ||
|
f89578e797 | ||
|
11904bba73 | ||
|
d279b64dc1 | ||
|
2ecc659ae8 | ||
|
cc25de02a5 | ||
|
334d6eb492 | ||
|
165ad257f7 | ||
|
07819ffd98 | ||
|
5adb3502aa | ||
|
269e2407e9 | ||
|
4a435c16d2 | ||
|
e4c0bdd97f | ||
|
7abfa8873a | ||
|
b84a9d0112 | ||
|
288a627154 | ||
|
2a8d189e9b | ||
|
e593a4c094 | ||
|
1b4c241f80 | ||
|
1bf69e64ec | ||
|
1d3ea1dbe5 | ||
|
e3f2e1c9fb | ||
|
724f15d7d8 | ||
|
0280cad999 | ||
|
aa912dbb95 | ||
|
0ed2ac3ee5 | ||
|
c7c136a610 | ||
|
60e11b72fa | ||
|
8c5c3e5bc2 | ||
|
7edacad9b7 | ||
|
d8791f8ac3 | ||
|
8a2c001038 | ||
|
f34a785514 | ||
|
581d7e4d23 | ||
|
bed88b7c2c | ||
|
7b404c8aee | ||
|
c52537868c | ||
|
0ecd14bacb | ||
|
602c7e4553 | ||
|
9941229fd9 | ||
|
542b211fa7 | ||
|
e7535d9bc9 | ||
|
3f7d6de841 | ||
|
1bca510023 | ||
|
9dea01228a | ||
|
a04f8743c7 | ||
|
1a33aa67b2 | ||
|
9bdf42fec3 | ||
|
64b2f13b2e | ||
|
e439619ef8 | ||
|
9884d8921a | ||
|
e79c1007de | ||
|
4b27a14352 | ||
|
72dc28520e | ||
|
54a93b6c5a | ||
|
6a98838fbf | ||
|
ee79e0dae5 | ||
|
9a68795314 | ||
|
a0d6d9ed67 | ||
|
d28ba31b06 | ||
|
35c69434e6 | ||
|
13324edce0 | ||
|
55a8bee3cd | ||
|
0447b7a53d | ||
|
4054dc1b47 | ||
|
f32d3b5fad | ||
|
4c277aea43 | ||
|
ac0ef9675a | ||
|
9ec849f281 | ||
|
e785acdef5 | ||
|
60e64ed72c | ||
|
97b2472542 | ||
|
5f633006f0 | ||
|
e5dcb6d8cc | ||
|
ff29f0ac75 | ||
|
c4b0987e5a | ||
|
adc0e5c9b1 | ||
|
44028b5989 | ||
|
d25ed0a789 | ||
|
e2cab77f21 | ||
|
f3125d2f71 | ||
|
7fa0fa45a8 | ||
|
6822ad5dba | ||
|
abdb2b1f86 | ||
|
8e9dfecc09 | ||
|
dfee0f4940 | ||
|
6d53ec21a0 | ||
|
595e00cbca | ||
|
5a6ea278da | ||
|
cee3b71531 | ||
|
5ca1ce25e1 | ||
|
1cd22bbd50 | ||
|
009616cc4d | ||
|
5e281ad29a | ||
|
954f9b947a | ||
|
2fbd23ab9e | ||
|
5a7a6c2f25 | ||
|
6f7f48833e | ||
|
a4308aba72 | ||
|
07c91eefe4 | ||
|
992dd01f11 | ||
|
b22393b73f | ||
|
201bef8a3e | ||
|
335b323f4d | ||
|
8e01867781 | ||
|
20fb3d9b9e | ||
|
aef7105b3d | ||
|
ea60c79b79 | ||
|
922853783a | ||
|
a930012b75 | ||
|
c3677f8ca7 | ||
|
46e484a4ff | ||
|
0b671fc6e1 | ||
|
d3021e5509 | ||
|
17399d3824 | ||
|
50bfbbd7d4 | ||
|
583cf87533 | ||
|
c6ce9eaf37 | ||
|
9b7c788f89 | ||
|
c417f4153b | ||
|
149f9897d5 | ||
|
277ad755e7 | ||
|
0419cb537e | ||
|
9230f0ec9d | ||
|
d05336fe3f | ||
|
03454a0cac | ||
|
a4dd838b66 | ||
|
aa8b440108 | ||
|
ae281b2cba | ||
|
60da38b473 | ||
|
d4265a8997 | ||
|
9a4eeca7a6 | ||
|
14d8890fb9 | ||
|
cebaaf501b | ||
|
a944e46c81 | ||
|
bc563dea32 | ||
|
e1e6f5acd3 | ||
|
cf4e92a010 | ||
|
2310dcb750 | ||
|
1a98618560 | ||
|
c9fba96dba | ||
|
a19d9041fd | ||
|
e820bbfd87 | ||
|
ae379c99c9 | ||
|
79d5824997 | ||
|
8e64298570 | ||
|
8142620c37 | ||
|
89ff8b6b8d | ||
|
62f028f409 | ||
|
226216574a | ||
|
013b002ff9 | ||
|
5945901935 | ||
|
7bc536f6f1 | ||
|
c85e05343f | ||
|
fd4a692661 | ||
|
695e6a025f | ||
|
a5db1dd477 | ||
|
5020a1c82a | ||
|
145b28d899 | ||
|
8a30b22d0a | ||
|
712f670bb3 | ||
|
b9d1c3ee13 | ||
|
c929692827 | ||
|
991195ade7 | ||
|
668d72c474 | ||
|
b26135cd5c | ||
|
f1745cb78f | ||
|
e22a765605 | ||
|
bdf12d1a06 | ||
|
cf99465f46 | ||
|
e405f30513 | ||
|
d00aba92df | ||
|
2202fa533b | ||
|
134d72cd4c | ||
|
c78d3b8465 | ||
|
bbe77e1e87 | ||
|
2685312ba9 | ||
|
b386cae5ba | ||
|
258e563d2c | ||
|
ea757832c1 | ||
|
c49e024745 | ||
|
444f948e3c | ||
|
c945a25c0b | ||
|
7fbad767df | ||
|
053ae2cfff | ||
|
a253c2d94c | ||
|
7069636733 | ||
|
eba5e18f5e | ||
|
47866d72ca | ||
|
47e05fadce | ||
|
faf198371a | ||
|
2d9cb77fbc | ||
|
b3756fbfe1 | ||
|
470dff29fa | ||
|
95357bc936 | ||
|
142f3a52bc | ||
|
ab94a42728 | ||
|
2861fbe572 | ||
|
241087650a | ||
|
4e80396028 | ||
|
a414020582 | ||
|
ba6e7e10bb | ||
|
39d9937d05 | ||
|
f5c2c7bbf2 | ||
|
247134aefb | ||
|
6a73a0aca9 | ||
|
257f608dfc | ||
|
66fecabb5f | ||
|
8553d979a1 | ||
|
bb74224921 | ||
|
59061eb9ea | ||
|
9540ed8747 | ||
|
e58e1161de | ||
|
ad50df3384 | ||
|
6bb8101aaf | ||
|
51503b1c36 | ||
|
54313579bb | ||
|
e0c4e89535 | ||
|
9ea0de6394 | ||
|
16e096e34e | ||
|
e7af7017b1 | ||
|
31cb06a26a | ||
|
cc11443256 | ||
|
25bc2d8c45 | ||
|
10eb3ebd78 | ||
|
d4b4471786 | ||
|
61d15c60fc | ||
|
bd1f484c05 | ||
|
07fb8bb1a6 | ||
|
e2d3e2e33c | ||
|
01218209dc | ||
|
699a0f8601 | ||
|
ef50268985 | ||
|
f600d6a3b1 | ||
|
9d80afc3c4 | ||
|
f6a10dfc09 | ||
|
ecb168c8d7 | ||
|
794d3952b0 | ||
|
bde5fcc9b8 | ||
|
b477479cb7 | ||
|
de5c62db29 | ||
|
f645147c7e | ||
|
291d92e529 | ||
|
e8fa5a92e9 | ||
|
1d19c390cf | ||
|
dfd031a486 | ||
|
496d11787d | ||
|
cab8ab375c | ||
|
c62a55f1b6 | ||
|
82146f6a71 | ||
|
5a670b332a | ||
|
503fd3014a | ||
|
3c80b14a81 | ||
|
a62e66394b | ||
|
236ed7869d | ||
|
b1a2522f05 | ||
|
9a8512f460 | ||
|
0334b1bf8e | ||
|
4feff6c9b5 | ||
|
650b7695e0 | ||
|
387be4f6c3 | ||
|
d5a377e94e | ||
|
3eb92bcce7 | ||
|
17c011592a | ||
|
d99f51ac60 | ||
|
187ef4d65b | ||
|
a8ae141ee9 | ||
|
ac08a31d7f | ||
|
238f0190ba | ||
|
656e285fa3 | ||
|
edbb4903fa | ||
|
8d33e4ff7d | ||
|
e28b3f0713 | ||
|
998c477262 | ||
|
e893090d19 | ||
|
445e5f83d4 | ||
|
c33e7bf9b4 | ||
|
e687982294 | ||
|
7a71540369 | ||
|
db38085367 | ||
|
ebbbe4c8aa | ||
|
07d95b3be7 | ||
|
cdc7b2d51d | ||
|
6cb5eb6735 | ||
|
2432cb68e4 | ||
|
7542b942a4 | ||
|
49ab9e2f2b | ||
|
df146dcf5c | ||
|
7263220870 | ||
|
7413190665 | ||
|
99799235a7 | ||
|
fe48be2ab5 | ||
|
f719a8a49b | ||
|
535e0c8a58 | ||
|
5cbc6f5623 | ||
|
4d40d318f8 | ||
|
665019c80e | ||
|
860855c3b5 | ||
|
f9b4435b5a | ||
|
bf239275a2 | ||
|
92a4d1d60d | ||
|
796d9387ed | ||
|
1588793de6 | ||
|
287518360a | ||
|
2a334fbfa3 | ||
|
261ec4e6d9 | ||
|
da5d2f176d | ||
|
ab34686a5b | ||
|
5463082f3f | ||
|
49dcd55e30 | ||
|
51383099e7 | ||
|
aebb41980c | ||
|
9896808a25 | ||
|
6b0a1f8123 | ||
|
668709c820 | ||
|
7eca847314 | ||
|
27759f6798 | ||
|
157c607825 | ||
|
8d123ca4b2 | ||
|
b2a83dc1e6 | ||
|
12da01a2e2 | ||
|
b079cadebc | ||
|
a2430c57d7 | ||
|
b4d11602b8 | ||
|
a848fde40e | ||
|
b247f03fcd | ||
|
3ef018f5e3 | ||
|
a35d172934 | ||
|
7025e30f43 | ||
|
849225f9a1 | ||
|
488fde7d06 | ||
|
a7f17f6ee4 | ||
|
3a080abf13 | ||
|
47f6cf666d | ||
|
a4633945f0 | ||
|
bc67ed671b | ||
|
8af60309ba | ||
|
088785adf8 | ||
|
c50074fffd | ||
|
0479ef4106 | ||
|
01cb82366f | ||
|
199697f54e | ||
|
56f8cbd775 | ||
|
7ac450eaa0 | ||
|
2e4d755351 | ||
|
10f2b080c3 | ||
|
4adad7f664 | ||
|
e37e7e348d | ||
|
f443299c58 | ||
|
866e1786e3 | ||
|
37d6a2688f | ||
|
56203bca4e | ||
|
8bd70ef699 | ||
|
a2cbe67701 | ||
|
fd1cd69315 | ||
|
3d7fbe88ab | ||
|
a6b9aaba1b | ||
|
31e9e8c0aa | ||
|
e47b17e239 | ||
|
6c6d08dc4f | ||
|
3b41ec0691 | ||
|
6b75aa3623 | ||
|
9f9553ee5a | ||
|
3f36a03842 | ||
|
c7b0f4de4a | ||
|
84151e088b | ||
|
a608ec048b | ||
|
1e191cba1e | ||
|
354c08e558 | ||
|
36e403d7e4 | ||
|
5f93d3f0e2 | ||
|
94fe01900a | ||
|
d5ba75979a | ||
|
c466c22945 | ||
|
b9e2cc9f69 | ||
|
67e16b74c7 | ||
|
b683d90355 | ||
|
15fa96fd94 | ||
|
6a915e6312 | ||
|
8cf68bd054 | ||
|
e904075ee6 | ||
|
1ffc6e0c7a | ||
|
e5df03ca91 | ||
|
099b6c54fb | ||
|
aee73ac488 | ||
|
7dd27c3376 | ||
|
0bed3f1cef | ||
|
06a2b04963 | ||
|
6347c8ba51 | ||
|
6d0eadc439 | ||
|
e80357c95b | ||
|
e250f56a19 | ||
|
abd0237851 | ||
|
2496c495ef | ||
|
45556cbdb8 | ||
|
696ff47378 | ||
|
65e7ddabb4 | ||
|
d649398796 | ||
|
c5a0fff879 | ||
|
f02f515725 | ||
|
ec11f1cc97 | ||
|
c90e5ad038 | ||
|
7c1b6a3abc | ||
|
551bea6443 | ||
|
2a6bf99e78 | ||
|
91cbd96ffe | ||
|
73307b55a1 | ||
|
a53505b452 | ||
|
e36b87dce3 | ||
|
c73e275bfa | ||
|
d1761537ac | ||
|
ec7e617440 | ||
|
13b508e968 | ||
|
8ae2932d56 | ||
|
3e8d408a5e | ||
|
198e6f212e | ||
|
ee25f37003 | ||
|
0b8b1b5273 | ||
|
92222bebc3 | ||
|
9f4511da1a | ||
|
efad626197 | ||
|
494d5c1958 | ||
|
652d9def63 | ||
|
f5afe5b452 | ||
|
b8c9d52b84 | ||
|
f3ea13c879 | ||
|
f6d43fcff8 | ||
|
fbc630fc15 | ||
|
4ffa98835d | ||
|
3f8bf41b93 | ||
|
936c762b8e | ||
|
ff51f58e1d | ||
|
ea103a02af | ||
|
697286bf4d | ||
|
250ac961c1 | ||
|
abc5566af9 | ||
|
d87419737d | ||
|
4814bb478f | ||
|
5f4f671862 | ||
|
58600bbcf9 | ||
|
bbaf0abf9c | ||
|
21eb9f187e | ||
|
5a4df0c14f | ||
|
8ad7b50bf8 | ||
|
009bee2d92 | ||
|
ad430b1b09 | ||
|
6e397f45c2 | ||
|
05baf00899 | ||
|
4f681fdcdd | ||
|
21dea5914a | ||
|
34941a6aa4 | ||
|
b5c19b4cb0 | ||
|
05a28af51b | ||
|
97954a8515 | ||
|
b5938e6b8c | ||
|
16ec17e630 | ||
|
3d728b1d9a | ||
|
b143a809ea | ||
|
500c708ba6 | ||
|
30610d3d1f | ||
|
4de62b4c0f | ||
|
9a9707a8b7 | ||
|
74458684bd | ||
|
8bc4908f5c | ||
|
780c0bbdea | ||
|
cb14281e11 | ||
|
f621753b76 | ||
|
6cecfd8ad7 | ||
|
9af38b4ee1 | ||
|
5b4a8db4d9 | ||
|
10959a8288 | ||
|
6bd3ff7838 | ||
|
3c21a5c9d6 | ||
|
42ac7b2428 | ||
|
0d2187f1b2 | ||
|
4d0407614d | ||
|
f6c2abe751 | ||
|
1c79bffa29 | ||
|
e383d67656 | ||
|
005fca6532 | ||
|
722137f9ea | ||
|
55e7c6155a | ||
|
c4f70c3c27 | ||
|
ee051d65f3 | ||
|
38d02e4ecd | ||
|
402699d00e | ||
|
063943c214 | ||
|
cd75ec216a |
@ -204,5 +204,11 @@ ce21e97a1f20dee15da85c084f9d1148d84f853b
|
||||
# sqlc: format with nixfmt
|
||||
2bdec131b2bb2c8563f4556d741d34ccb77409e2
|
||||
|
||||
# ant: format with nixfmt-rfc-style
|
||||
2538d58436b8d0b56d29780aeebf4bf720ddb9ea
|
||||
|
||||
# treewide: migrate packages to pkgs/by-name, take 1
|
||||
571c71e6f73af34a229414f51585738894211408
|
||||
|
||||
# format files with nixfmt (#347275)
|
||||
adb9714bd909df283c66bbd641bd631ff50a4260
|
||||
|
3
.github/labeler.yml
vendored
3
.github/labeler.yml
vendored
@ -194,7 +194,7 @@
|
||||
- pkgs/by-name/ma/maven/**/*
|
||||
- doc/languages-frameworks/maven.section.md
|
||||
# Ant
|
||||
- pkgs/by-name/ap/apacheAnt/**/*
|
||||
- pkgs/by-name/an/ant/**/*
|
||||
# javaPackages attrset
|
||||
- pkgs/development/java-modules/**/*
|
||||
- pkgs/top-level/java-packages.nix
|
||||
@ -445,6 +445,7 @@
|
||||
- doc/languages-frameworks/ruby.section.md
|
||||
- pkgs/development/interpreters/ruby/**/*
|
||||
- pkgs/development/ruby-modules/**/*
|
||||
- pkgs/top-level/ruby-packages.nix
|
||||
|
||||
"6.topic: rust":
|
||||
- any:
|
||||
|
3
.github/workflows/check-shell.yml
vendored
3
.github/workflows/check-shell.yml
vendored
@ -2,6 +2,9 @@ name: "Check shell"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
paths:
|
||||
- 'shell.nix'
|
||||
- 'ci/**'
|
||||
|
||||
permissions: {}
|
||||
|
||||
|
160
.github/workflows/eval.yml
vendored
160
.github/workflows/eval.yml
vendored
@ -1,6 +1,16 @@
|
||||
name: Eval
|
||||
|
||||
on: pull_request_target
|
||||
on:
|
||||
pull_request_target:
|
||||
push:
|
||||
# Keep this synced with ci/request-reviews/dev-branches.txt
|
||||
branches:
|
||||
- master
|
||||
- staging
|
||||
- release-*
|
||||
- staging-*
|
||||
- haskell-updates
|
||||
- python-updates
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@ -11,6 +21,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
mergedSha: ${{ steps.merged.outputs.mergedSha }}
|
||||
baseSha: ${{ steps.baseSha.outputs.baseSha }}
|
||||
systems: ${{ steps.systems.outputs.systems }}
|
||||
steps:
|
||||
# Important: Because of `pull_request_target`, this doesn't check out the PR,
|
||||
@ -24,14 +35,22 @@ jobs:
|
||||
id: merged
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_EVENT: ${{ github.event_name }}
|
||||
run: |
|
||||
if mergedSha=$(base/ci/get-merge-commit.sh ${{ github.repository }} ${{ github.event.number }}); then
|
||||
echo "Checking the merge commit $mergedSha"
|
||||
echo "mergedSha=$mergedSha" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
# Skipping so that no notifications are sent
|
||||
echo "Skipping the rest..."
|
||||
fi
|
||||
case "$GH_EVENT" in
|
||||
push)
|
||||
echo "mergedSha=${{ github.sha }}" >> "$GITHUB_OUTPUT"
|
||||
;;
|
||||
pull_request_target)
|
||||
if mergedSha=$(base/ci/get-merge-commit.sh ${{ github.repository }} ${{ github.event.number }}); then
|
||||
echo "Checking the merge commit $mergedSha"
|
||||
echo "mergedSha=$mergedSha" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
# Skipping so that no notifications are sent
|
||||
echo "Skipping the rest..."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
rm -rf base
|
||||
- name: Check out the PR at the test merge commit
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
@ -39,8 +58,16 @@ jobs:
|
||||
if: steps.merged.outputs.mergedSha
|
||||
with:
|
||||
ref: ${{ steps.merged.outputs.mergedSha }}
|
||||
fetch-depth: 2
|
||||
path: nixpkgs
|
||||
|
||||
- name: Determine base commit
|
||||
if: github.event_name == 'pull_request_target' && steps.merged.outputs.mergedSha
|
||||
id: baseSha
|
||||
run: |
|
||||
baseSha=$(git -C nixpkgs rev-parse HEAD^1)
|
||||
echo "baseSha=$baseSha" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
|
||||
if: steps.merged.outputs.mergedSha
|
||||
@ -105,6 +132,8 @@ jobs:
|
||||
name: Process
|
||||
runs-on: ubuntu-latest
|
||||
needs: [ outpaths, attrs ]
|
||||
outputs:
|
||||
baseRunId: ${{ steps.baseRunId.outputs.baseRunId }}
|
||||
steps:
|
||||
- name: Download output paths and eval stats for all systems
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
@ -124,18 +153,117 @@ jobs:
|
||||
- name: Combine all output paths and eval stats
|
||||
run: |
|
||||
nix-build nixpkgs/ci -A eval.combine \
|
||||
--arg resultsDir ./intermediate
|
||||
--arg resultsDir ./intermediate \
|
||||
-o prResult
|
||||
|
||||
- name: Upload the combined results
|
||||
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||
with:
|
||||
name: result
|
||||
path: result/*
|
||||
path: prResult/*
|
||||
|
||||
- name: Get base run id
|
||||
if: needs.attrs.outputs.baseSha
|
||||
id: baseRunId
|
||||
run: |
|
||||
# Get the latest eval.yml workflow run for the PR's base commit
|
||||
if ! run=$(gh api --method GET /repos/"$REPOSITORY"/actions/workflows/eval.yml/runs \
|
||||
-f head_sha="$BASE_SHA" -f event=push \
|
||||
--jq '.workflow_runs | sort_by(.run_started_at) | .[-1]') \
|
||||
|| [[ -z "$run" ]]; then
|
||||
echo "Could not find an eval.yml workflow run for $BASE_SHA, cannot make comparison"
|
||||
exit 0
|
||||
fi
|
||||
echo "Comparing against $(jq .html_url <<< "$run")"
|
||||
runId=$(jq .id <<< "$run")
|
||||
conclusion=$(jq -r .conclusion <<< "$run")
|
||||
|
||||
# TODO: Run this workflow also on `push` (on at least the main development branches)
|
||||
# Then add an extra step here that waits for the base branch (not the merge base, because that could be very different)
|
||||
# to have completed the eval, then use
|
||||
# gh api --method GET /repos/NixOS/nixpkgs/actions/workflows/eval.yml/runs -f head_sha=<BASE>
|
||||
# and follow it to the artifact results, where you can then download the outpaths.json from the base branch
|
||||
# That can then be used to compare the number of changed paths, get evaluation stats and ping appropriate reviewers
|
||||
while [[ "$conclusion" == null ]]; do
|
||||
echo "Workflow not done, waiting 10 seconds before checking again"
|
||||
sleep 10
|
||||
conclusion=$(gh api /repos/"$REPOSITORY"/actions/runs/"$runId" --jq '.conclusion')
|
||||
done
|
||||
|
||||
if [[ "$conclusion" != "success" ]]; then
|
||||
echo "Workflow was not successful, cannot make comparison"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "baseRunId=$runId" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
BASE_SHA: ${{ needs.attrs.outputs.baseSha }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
if: steps.baseRunId.outputs.baseRunId
|
||||
with:
|
||||
name: result
|
||||
path: baseResult
|
||||
github-token: ${{ github.token }}
|
||||
run-id: ${{ steps.baseRunId.outputs.baseRunId }}
|
||||
|
||||
- name: Compare against the base branch
|
||||
if: steps.baseRunId.outputs.baseRunId
|
||||
run: |
|
||||
nix-build nixpkgs/ci -A eval.compare \
|
||||
--arg beforeResultDir ./baseResult \
|
||||
--arg afterResultDir ./prResult \
|
||||
-o comparison
|
||||
|
||||
# TODO: Request reviews from maintainers for packages whose files are modified in the PR
|
||||
|
||||
- name: Upload the combined results
|
||||
if: steps.baseRunId.outputs.baseRunId
|
||||
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||
with:
|
||||
name: comparison
|
||||
path: comparison/*
|
||||
|
||||
# Separate job to have a very tightly scoped PR write token
|
||||
tag:
|
||||
name: Tag
|
||||
runs-on: ubuntu-latest
|
||||
needs: process
|
||||
if: needs.process.outputs.baseRunId
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Download process result
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
with:
|
||||
name: comparison
|
||||
path: comparison
|
||||
|
||||
- name: Tagging pull request
|
||||
run: |
|
||||
# Get all currently set rebuild labels
|
||||
gh api \
|
||||
/repos/"$REPOSITORY"/issues/"$NUMBER"/labels \
|
||||
--jq '.[].name | select(startswith("10.rebuild"))' \
|
||||
| sort > before
|
||||
|
||||
# And the labels that should be there
|
||||
jq -r '.labels[]' comparison/changed-paths.json \
|
||||
| sort > after
|
||||
|
||||
# Remove the ones not needed anymore
|
||||
while read -r toRemove; do
|
||||
echo "Removing label $toRemove"
|
||||
gh api \
|
||||
--method DELETE \
|
||||
/repos/"$REPOSITORY"/issues/"$NUMBER"/labels/"$toRemove"
|
||||
done < <(comm -23 before after)
|
||||
|
||||
# And add the ones that aren't set already
|
||||
while read -r toAdd; do
|
||||
echo "Adding label $toAdd"
|
||||
gh api \
|
||||
--method POST \
|
||||
/repos/"$REPOSITORY"/issues/"$NUMBER"/labels \
|
||||
-f "labels[]=$toAdd"
|
||||
done < <(comm -13 before after)
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
NUMBER: ${{ github.event.number }}
|
||||
|
1
.mailmap
1
.mailmap
@ -14,6 +14,7 @@ Jörg Thalheim <joerg@thalheim.io> <Mic92@users.noreply.github.com>
|
||||
Lin Jian <me@linj.tech> <linj.dev@outlook.com>
|
||||
Lin Jian <me@linj.tech> <75130626+jian-lin@users.noreply.github.com>
|
||||
Martin Weinelt <hexa@darmstadt.ccc.de> <mweinelt@users.noreply.github.com>
|
||||
moni <lythe1107@gmail.com> <lythe1107@icloud.com>
|
||||
R. RyanTM <ryantm-bot@ryantm.com>
|
||||
Robert Hensing <robert@roberthensing.nl> <roberth@users.noreply.github.com>
|
||||
Sandro Jäckel <sandro.jaeckel@gmail.com>
|
||||
|
@ -345,7 +345,7 @@ See [Nix Channel Status](https://status.nixos.org/) for the current channels and
|
||||
Here's a brief overview of the main Git branches and what channels they're used for:
|
||||
|
||||
- `master`: The main branch, used for the unstable channels such as `nixpkgs-unstable`, `nixos-unstable` and `nixos-unstable-small`.
|
||||
- `release-YY.MM` (e.g. `release-24.11`): The NixOS release branches, used for the stable channels such as `nixos-24.11`, `nixos-24.11-small` and `nixpkgs-24.11-darwin`.
|
||||
- `release-YY.MM` (e.g. `release-25.05`): The NixOS release branches, used for the stable channels such as `nixos-25.05`, `nixos-25.05-small` and `nixpkgs-25.05-darwin`.
|
||||
|
||||
When a channel is updated, a corresponding Git branch is also updated to point to the corresponding commit.
|
||||
So e.g. the [`nixpkgs-unstable` branch](https://github.com/nixos/nixpkgs/tree/nixpkgs-unstable) corresponds to the Git commit from the [`nixpkgs-unstable` channel](https://channels.nixos.org/nixpkgs-unstable).
|
||||
|
@ -52,9 +52,9 @@ Nixpkgs and NixOS are built and tested by our continuous integration
|
||||
system, [Hydra](https://hydra.nixos.org/).
|
||||
|
||||
* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
|
||||
* [Continuous package builds for the NixOS 24.05 release](https://hydra.nixos.org/jobset/nixos/release-24.05)
|
||||
* [Continuous package builds for the NixOS 24.11 release](https://hydra.nixos.org/jobset/nixos/release-24.11)
|
||||
* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
|
||||
* [Tests for the NixOS 24.05 release](https://hydra.nixos.org/job/nixos/release-24.05/tested#tabs-constituents)
|
||||
* [Tests for the NixOS 24.11 release](https://hydra.nixos.org/job/nixos/release-24.11/tested#tabs-constituents)
|
||||
|
||||
Artifacts successfully built with Hydra are published to cache at
|
||||
https://cache.nixos.org/. When successful build and test criteria are
|
||||
|
152
ci/eval/compare.jq
Normal file
152
ci/eval/compare.jq
Normal file
@ -0,0 +1,152 @@
|
||||
# Turns
|
||||
#
|
||||
# {
|
||||
# "hello.aarch64-linux": "a",
|
||||
# "hello.x86_64-linux": "b",
|
||||
# "hello.aarch64-darwin": "c",
|
||||
# "hello.x86_64-darwin": "d"
|
||||
# }
|
||||
#
|
||||
# into
|
||||
#
|
||||
# {
|
||||
# "hello": {
|
||||
# "linux": {
|
||||
# "aarch64": "a",
|
||||
# "x86_64": "b"
|
||||
# },
|
||||
# "darwin": {
|
||||
# "aarch64": "c",
|
||||
# "x86_64": "d"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# while filtering out any attribute paths that don't match this pattern
|
||||
def expand_system:
|
||||
to_entries
|
||||
| map(
|
||||
.key |= split(".")
|
||||
| select(.key | length > 1)
|
||||
| .double = (.key[-1] | split("-"))
|
||||
| select(.double | length == 2)
|
||||
)
|
||||
| group_by(.key[0:-1])
|
||||
| map(
|
||||
{
|
||||
key: .[0].key[0:-1] | join("."),
|
||||
value:
|
||||
group_by(.double[1])
|
||||
| map(
|
||||
{
|
||||
key: .[0].double[1],
|
||||
value: map(.key = .double[0]) | from_entries
|
||||
}
|
||||
)
|
||||
| from_entries
|
||||
})
|
||||
| from_entries
|
||||
;
|
||||
|
||||
# Transposes
|
||||
#
|
||||
# {
|
||||
# "a": [ "x", "y" ],
|
||||
# "b": [ "x" ],
|
||||
# }
|
||||
#
|
||||
# into
|
||||
#
|
||||
# {
|
||||
# "x": [ "a", "b" ],
|
||||
# "y": [ "a" ]
|
||||
# }
|
||||
def transpose:
|
||||
[
|
||||
to_entries[]
|
||||
| {
|
||||
key: .key,
|
||||
value: .value[]
|
||||
}
|
||||
]
|
||||
| group_by(.value)
|
||||
| map({
|
||||
key: .[0].value,
|
||||
value: map(.key)
|
||||
})
|
||||
| from_entries
|
||||
;
|
||||
|
||||
# Computes the key difference for two objects:
|
||||
# {
|
||||
# added: [ <keys only in the second object> ],
|
||||
# removed: [ <keys only in the first object> ],
|
||||
# changed: [ <keys with different values between the two objects> ],
|
||||
# }
|
||||
#
|
||||
def diff($before; $after):
|
||||
{
|
||||
added: $after | delpaths($before | keys | map([.])) | keys,
|
||||
removed: $before | delpaths($after | keys | map([.])) | keys,
|
||||
changed:
|
||||
$before
|
||||
| to_entries
|
||||
| map(
|
||||
$after."\(.key)" as $after2
|
||||
| select(
|
||||
# Filter out attributes that don't exist anymore
|
||||
($after2 != null)
|
||||
and
|
||||
# Filter out attributes that are the same as the new value
|
||||
(.value != $after2)
|
||||
)
|
||||
| .key
|
||||
)
|
||||
}
|
||||
;
|
||||
|
||||
($before[0] | expand_system) as $before
|
||||
| ($after[0] | expand_system) as $after
|
||||
| .attrdiff = diff($before; $after)
|
||||
| .rebuildsByKernel = (
|
||||
.attrdiff.changed
|
||||
| map({
|
||||
key: .,
|
||||
value: diff($before."\(.)"; $after."\(.)").changed
|
||||
})
|
||||
| from_entries
|
||||
| transpose
|
||||
)
|
||||
| .rebuildCountByKernel = (
|
||||
.rebuildsByKernel
|
||||
| with_entries(.value |= length)
|
||||
| pick(.linux, .darwin)
|
||||
| {
|
||||
linux: (.linux // 0),
|
||||
darwin: (.darwin // 0),
|
||||
}
|
||||
)
|
||||
| .labels = (
|
||||
.rebuildCountByKernel
|
||||
| to_entries
|
||||
| map(
|
||||
"10.rebuild-\(.key): " +
|
||||
if .value == 0 then
|
||||
"0"
|
||||
elif .value <= 10 then
|
||||
"1-10"
|
||||
elif .value <= 100 then
|
||||
"11-100"
|
||||
elif .value <= 500 then
|
||||
"101-500"
|
||||
elif .value <= 1000 then
|
||||
"501-1000"
|
||||
elif .value <= 2500 then
|
||||
"1001-2500"
|
||||
elif .value <= 5000 then
|
||||
"2501-5000"
|
||||
else
|
||||
"5000+"
|
||||
end
|
||||
)
|
||||
)
|
@ -50,8 +50,12 @@ let
|
||||
export GC_INITIAL_HEAP_SIZE=4g
|
||||
command time -v \
|
||||
nix-instantiate --eval --strict --json --show-trace \
|
||||
$src/pkgs/top-level/release-attrpaths-superset.nix -A paths \
|
||||
--arg enableWarnings false > $out/paths.json
|
||||
"$src/pkgs/top-level/release-attrpaths-superset.nix" \
|
||||
-A paths \
|
||||
-I "$src" \
|
||||
--option restrict-eval true \
|
||||
--option allow-import-from-derivation false \
|
||||
--arg enableWarnings false > $out/paths.json
|
||||
mv "$supportedSystemsPath" $out/systems.json
|
||||
'';
|
||||
|
||||
@ -84,6 +88,8 @@ let
|
||||
set +e
|
||||
command time -f "Chunk $myChunk on $system done [%MKB max resident, %Es elapsed] %C" \
|
||||
nix-env -f "${nixpkgs}/pkgs/top-level/release-attrpaths-parallel.nix" \
|
||||
--option restrict-eval true \
|
||||
--option allow-import-from-derivation false \
|
||||
--query --available \
|
||||
--no-name --attr-path --out-path \
|
||||
--show-trace \
|
||||
@ -93,6 +99,8 @@ let
|
||||
--arg systems "[ \"$system\" ]" \
|
||||
--arg checkMeta ${lib.boolToString checkMeta} \
|
||||
--arg includeBroken ${lib.boolToString includeBroken} \
|
||||
-I ${nixpkgs} \
|
||||
-I ${attrpathFile} \
|
||||
> "$outputDir/result/$myChunk"
|
||||
exitCode=$?
|
||||
set -e
|
||||
@ -238,6 +246,24 @@ let
|
||||
jq -s from_entries > $out/stats.json
|
||||
'';
|
||||
|
||||
compare =
|
||||
{ beforeResultDir, afterResultDir }:
|
||||
runCommand "compare"
|
||||
{
|
||||
nativeBuildInputs = [
|
||||
jq
|
||||
];
|
||||
}
|
||||
''
|
||||
mkdir $out
|
||||
jq -n -f ${./compare.jq} \
|
||||
--slurpfile before ${beforeResultDir}/outpaths.json \
|
||||
--slurpfile after ${afterResultDir}/outpaths.json \
|
||||
> $out/changed-paths.json
|
||||
|
||||
# TODO: Compare eval stats
|
||||
'';
|
||||
|
||||
full =
|
||||
{
|
||||
# Whether to evaluate just a single system, by default all are evaluated
|
||||
@ -268,6 +294,7 @@ in
|
||||
attrpathsSuperset
|
||||
singleSystem
|
||||
combine
|
||||
compare
|
||||
# The above three are used by separate VMs in a GitHub workflow,
|
||||
# while the below is intended for testing on a single local machine
|
||||
full
|
||||
|
@ -1,7 +1,9 @@
|
||||
# Trusted development branches:
|
||||
# These generally require PRs to update and are built by Hydra.
|
||||
# Keep this synced with the branches in .github/workflows/eval.yml
|
||||
master
|
||||
staging
|
||||
release-*
|
||||
staging-*
|
||||
haskell-updates
|
||||
python-updates
|
||||
|
@ -9,6 +9,8 @@
|
||||
mkShellNoCC,
|
||||
documentation-highlighter,
|
||||
nixos-render-docs,
|
||||
nixos-render-docs-redirects,
|
||||
writeShellScriptBin,
|
||||
nixpkgs ? { },
|
||||
}:
|
||||
|
||||
@ -105,8 +107,14 @@ stdenvNoCC.mkDerivation (
|
||||
buildArgs = "./.";
|
||||
open = "/share/doc/nixpkgs/manual.html";
|
||||
};
|
||||
nixos-render-docs-redirects' = writeShellScriptBin "redirects" "${lib.getExe nixos-render-docs-redirects} --file ${toString ../redirects.json} $@";
|
||||
in
|
||||
mkShellNoCC { packages = [ devmode' ]; };
|
||||
mkShellNoCC {
|
||||
packages = [
|
||||
devmode'
|
||||
nixos-render-docs-redirects'
|
||||
];
|
||||
};
|
||||
|
||||
tests.manpage-urls = callPackage ../tests/manpage-urls.nix { };
|
||||
};
|
||||
|
@ -6,9 +6,9 @@ let
|
||||
filterAttrs
|
||||
foldl
|
||||
hasInfix
|
||||
isAttrs
|
||||
isFunction
|
||||
isList
|
||||
isString
|
||||
mapAttrs
|
||||
optional
|
||||
optionalAttrs
|
||||
@ -55,24 +55,34 @@ let
|
||||
*/
|
||||
flakeExposed = import ./flake-systems.nix { };
|
||||
|
||||
# Turn localSystem or crossSystem, which could be system-string or attrset, into
|
||||
# attrset.
|
||||
systemToAttrs = systemOrArgs:
|
||||
if isAttrs systemOrArgs then systemOrArgs else { system = systemOrArgs; };
|
||||
|
||||
# Elaborate a `localSystem` or `crossSystem` so that it contains everything
|
||||
# necessary.
|
||||
#
|
||||
# `parsed` is inferred from args, both because there are two options with one
|
||||
# clearly preferred, and to prevent cycles. A simpler fixed point where the RHS
|
||||
# always just used `final.*` would fail on both counts.
|
||||
elaborate = args': let
|
||||
args = if isString args' then { system = args'; }
|
||||
else args';
|
||||
elaborate = systemOrArgs: let
|
||||
allArgs = systemToAttrs systemOrArgs;
|
||||
|
||||
# Those two will always be derived from "config", if given, so they should NOT
|
||||
# be overridden further down with "// args".
|
||||
args = builtins.removeAttrs allArgs [ "parsed" "system" ];
|
||||
|
||||
# TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL.
|
||||
rust = args.rust or args.rustc or {};
|
||||
|
||||
final = {
|
||||
# Prefer to parse `config` as it is strictly more informative.
|
||||
parsed = parse.mkSystemFromString (if args ? config then args.config else args.system);
|
||||
# Either of these can be losslessly-extracted from `parsed` iff parsing succeeds.
|
||||
parsed = parse.mkSystemFromString (args.config or allArgs.system);
|
||||
# This can be losslessly-extracted from `parsed` iff parsing succeeds.
|
||||
system = parse.doubleFromSystem final.parsed;
|
||||
# TODO: This currently can't be losslessly-extracted from `parsed`, for example
|
||||
# because of -mingw32.
|
||||
config = parse.tripleFromSystem final.parsed;
|
||||
# Determine whether we can execute binaries built for the provided platform.
|
||||
canExecute = platform:
|
||||
@ -435,5 +445,6 @@ in
|
||||
inspect
|
||||
parse
|
||||
platforms
|
||||
systemToAttrs
|
||||
;
|
||||
}
|
||||
|
@ -78,6 +78,18 @@ lib.runTests (
|
||||
expr = toLosslessStringMaybe (lib.systems.elaborate "x86_64-linux" // { something = "extra"; });
|
||||
expected = null;
|
||||
};
|
||||
test_elaborate_config_over_system = {
|
||||
expr = (lib.systems.elaborate { config = "i686-unknown-linux-gnu"; system = "x86_64-linux"; }).system;
|
||||
expected = "i686-linux";
|
||||
};
|
||||
test_elaborate_config_over_parsed = {
|
||||
expr = (lib.systems.elaborate { config = "i686-unknown-linux-gnu"; parsed = (lib.systems.elaborate "x86_64-linux").parsed; }).parsed.cpu.arch;
|
||||
expected = "i686";
|
||||
};
|
||||
test_elaborate_system_over_parsed = {
|
||||
expr = (lib.systems.elaborate { system = "i686-linux"; parsed = (lib.systems.elaborate "x86_64-linux").parsed; }).parsed.cpu.arch;
|
||||
expected = "i686";
|
||||
};
|
||||
}
|
||||
|
||||
# Generate test cases to assert that a change in any non-function attribute makes a platform unequal
|
||||
|
@ -1313,7 +1313,6 @@
|
||||
name = "Wroclaw";
|
||||
};
|
||||
amuckstot30 = {
|
||||
email = "amuckstot30@tutanota.com";
|
||||
github = "amuckstot30";
|
||||
githubId = 157274630;
|
||||
name = "amuckstot30";
|
||||
@ -1625,6 +1624,12 @@
|
||||
githubId = 4194320;
|
||||
name = "Anton Schirg";
|
||||
};
|
||||
anugrahn1 = {
|
||||
email = "pnanugrah@gmail.com";
|
||||
github = "anugrahn1";
|
||||
githubId = 117428605;
|
||||
name = "Anugrah Naranatt";
|
||||
};
|
||||
anytimetraveler = {
|
||||
email = "simon@simonscode.org";
|
||||
github = "AnyTimeTraveler";
|
||||
@ -4800,6 +4805,12 @@
|
||||
name = "Dov Alperin";
|
||||
keys = [ { fingerprint = "4EED 5096 B925 86FA 1101 6673 7F2C 07B9 1B52 BB61"; } ];
|
||||
};
|
||||
damhiya = {
|
||||
name = "SoonWon Moon";
|
||||
email = "damhiya@gmail.com";
|
||||
github = "damhiya";
|
||||
githubId = 13533446;
|
||||
};
|
||||
DamienCassou = {
|
||||
email = "damien@cassou.me";
|
||||
github = "DamienCassou";
|
||||
@ -13732,7 +13743,6 @@
|
||||
github = "matthewpi";
|
||||
githubId = 26559841;
|
||||
name = "Matthew Penner";
|
||||
keys = [ { fingerprint = "5118 F1CC B7B0 6C17 4DD1 5267 3131 1906 AD4C F6D6"; } ];
|
||||
};
|
||||
matthiasbenaets = {
|
||||
email = "matthias.benaets@gmail.com";
|
||||
@ -16795,6 +16805,11 @@
|
||||
githubId = 33826198;
|
||||
name = "Philipp Arras";
|
||||
};
|
||||
parth = {
|
||||
github = "parth";
|
||||
githubId = 821972;
|
||||
name = "Parth Mehrotra";
|
||||
};
|
||||
pashashocky = {
|
||||
email = "pashashocky@gmail.com";
|
||||
github = "pashashocky";
|
||||
@ -21192,12 +21207,6 @@
|
||||
githubId = 1694705;
|
||||
name = "Sam Stites";
|
||||
};
|
||||
stnley = {
|
||||
email = "michael@stnley.io";
|
||||
github = "stnley";
|
||||
githubId = 64174376;
|
||||
name = "Michael Stanley";
|
||||
};
|
||||
strager = {
|
||||
email = "strager.nds@gmail.com";
|
||||
github = "strager";
|
||||
@ -23347,6 +23356,13 @@
|
||||
name = "Vinicius Bernardino";
|
||||
keys = [ { fingerprint = "F0D3 920C 722A 541F 0CCD 66E3 A7BA BA05 3D78 E7CA"; } ];
|
||||
};
|
||||
vog = {
|
||||
email = "v@njh.eu";
|
||||
github = "vog";
|
||||
githubId = 412749;
|
||||
name = "Volker Diels-Grabsch";
|
||||
keys = [ { fingerprint = "A7E6 9C4F 69DC 5D6C FC84 EE34 A29F BD51 5F89 90AF"; } ];
|
||||
};
|
||||
voidless = {
|
||||
email = "julius.schmitt@yahoo.de";
|
||||
github = "voidIess";
|
||||
|
@ -6,7 +6,7 @@ expressions and associated binaries. The NixOS channels are updated
|
||||
automatically from NixOS's Git repository after certain tests have
|
||||
passed and all packages have been built. These channels are:
|
||||
|
||||
- *Stable channels*, such as [`nixos-24.05`](https://channels.nixos.org/nixos-24.05).
|
||||
- *Stable channels*, such as [`nixos-24.11`](https://channels.nixos.org/nixos-24.11).
|
||||
These only get conservative bug fixes and package upgrades. For
|
||||
instance, a channel update may cause the Linux kernel on your system
|
||||
to be upgraded from 4.19.34 to 4.19.38 (a minor bug fix), but not
|
||||
@ -19,7 +19,7 @@ passed and all packages have been built. These channels are:
|
||||
radical changes between channel updates. It's not recommended for
|
||||
production systems.
|
||||
|
||||
- *Small channels*, such as [`nixos-24.05-small`](https://channels.nixos.org/nixos-24.05-small)
|
||||
- *Small channels*, such as [`nixos-24.11-small`](https://channels.nixos.org/nixos-24.11-small)
|
||||
or [`nixos-unstable-small`](https://channels.nixos.org/nixos-unstable-small).
|
||||
These are identical to the stable and unstable channels described above,
|
||||
except that they contain fewer binary packages. This means they get updated
|
||||
@ -38,8 +38,8 @@ supported stable release.
|
||||
|
||||
When you first install NixOS, you're automatically subscribed to the
|
||||
NixOS channel that corresponds to your installation source. For
|
||||
instance, if you installed from a 24.05 ISO, you will be subscribed to
|
||||
the `nixos-24.05` channel. To see which NixOS channel you're subscribed
|
||||
instance, if you installed from a 24.11 ISO, you will be subscribed to
|
||||
the `nixos-24.11` channel. To see which NixOS channel you're subscribed
|
||||
to, run the following as root:
|
||||
|
||||
```ShellSession
|
||||
@ -54,16 +54,16 @@ To switch to a different NixOS channel, do
|
||||
```
|
||||
|
||||
(Be sure to include the `nixos` parameter at the end.) For instance, to
|
||||
use the NixOS 24.05 stable channel:
|
||||
use the NixOS 24.11 stable channel:
|
||||
|
||||
```ShellSession
|
||||
# nix-channel --add https://channels.nixos.org/nixos-24.05 nixos
|
||||
# nix-channel --add https://channels.nixos.org/nixos-24.11 nixos
|
||||
```
|
||||
|
||||
If you have a server, you may want to use the "small" channel instead:
|
||||
|
||||
```ShellSession
|
||||
# nix-channel --add https://channels.nixos.org/nixos-24.05-small nixos
|
||||
# nix-channel --add https://channels.nixos.org/nixos-24.11-small nixos
|
||||
```
|
||||
|
||||
And if you want to live on the bleeding edge:
|
||||
@ -117,6 +117,6 @@ modules. You can also specify a channel explicitly, e.g.
|
||||
|
||||
```nix
|
||||
{
|
||||
system.autoUpgrade.channel = "https://channels.nixos.org/nixos-24.05";
|
||||
system.autoUpgrade.channel = "https://channels.nixos.org/nixos-24.11";
|
||||
}
|
||||
```
|
||||
|
@ -1868,6 +1868,21 @@
|
||||
"sec-release-24.11-migration-dto-compatible": [
|
||||
"release-notes.html#sec-release-24.11-migration-dto-compatible"
|
||||
],
|
||||
"sec-release-24.11-wiki": [
|
||||
"release-notes.html#sec-release-24.11-wiki"
|
||||
],
|
||||
"sec-release-24.11-lib": [
|
||||
"release-notes.html#sec-release-24.11-lib"
|
||||
],
|
||||
"sec-release-24.11-lib-breaking": [
|
||||
"release-notes.html#sec-release-24.11-lib-breaking"
|
||||
],
|
||||
"sec-release-24.11-lib-additions-improvements": [
|
||||
"release-notes.html#sec-release-24.11-lib-additions-improvements"
|
||||
],
|
||||
"sec-release-24.11-lib-deprecations": [
|
||||
"release-notes.html#sec-release-24.11-lib-deprecations"
|
||||
],
|
||||
"sec-release-24.05": [
|
||||
"release-notes.html#sec-release-24.05"
|
||||
],
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Release 24.11 (“Vicuña”, 2024.11/??) {#sec-release-24.11}
|
||||
# Release 24.11 (“Vicuña”, 2024.11/28) {#sec-release-24.11}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
@ -135,6 +135,8 @@
|
||||
|
||||
- [Radicle](https://radicle.xyz), an open source, peer-to-peer code collaboration stack built on Git. Available as [services.radicle](#opt-services.radicle.enable).
|
||||
|
||||
- [Ordinal](https://github.com/snu-sf/Ordinal), A library for ordinal numbers in the Coq proof assistant.
|
||||
|
||||
- [ddns-updater](https://github.com/qdm12/ddns-updater), a service with a WebUI to update DNS records periodically for many providers. Available as [services.ddns-updater](#opt-services.ddns-updater.enable).
|
||||
|
||||
- [Immersed](https://immersed.com/), a closed-source coworking platform. Available as [programs.immersed](#opt-programs.immersed.enable).
|
||||
@ -151,8 +153,6 @@
|
||||
|
||||
- [zeronsd](https://github.com/zerotier/zeronsd), a DNS server for ZeroTier users. Available with [services.zeronsd.servedNetworks](#opt-services.zeronsd.servedNetworks).
|
||||
|
||||
- [agorakit](https://github.com/agorakit/agorakit), an organization tool for citizens' collectives. Available with [services.agorakit](#opt-services.agorakit.enable).
|
||||
|
||||
- [Collabora Online](https://www.collaboraonline.com/), a collaborative online office suite based on LibreOffice technology. Available as [services.collabora-online](options.html#opt-services.collabora-online.enable).
|
||||
|
||||
- [wg-access-server](https://github.com/freifunkMUC/wg-access-server/), an all-in-one WireGuard VPN solution with a WebUI for connecting devices. Available as [services.wg-access-server](#opt-services.wg-access-server.enable).
|
||||
@ -797,10 +797,6 @@
|
||||
not the `hare` package, should be added to `nativeBuildInputs` when building
|
||||
Hare programs.
|
||||
|
||||
- [`lib.options.mkPackageOptionMD`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.options.mkPackageOptionMD) is now obsolete; use the identical [`lib.options.mkPackageOption`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.options.mkPackageOption) instead.
|
||||
|
||||
- `lib.misc.mapAttrsFlatten` is now formally deprecated and will be removed in future releases; use the identical [`lib.attrsets.mapAttrsToList`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.attrsets.mapAttrsToList) instead.
|
||||
|
||||
- `virtualisation.docker.liveRestore` has been renamed to `virtualisation.docker.daemon.settings."live-restore"` and turned off by default for state versions of at least 24.11.
|
||||
|
||||
- Tailscale's `authKeyFile` can now have its corresponding parameters set through `config.services.tailscale.authKeyParameters`, allowing for non-ephemeral unsupervised deployment and more.
|
||||
@ -915,9 +911,7 @@
|
||||
|
||||
- `freecad` now supports addons and custom configuration in nix-way, which can be used by calling `freecad.customize`.
|
||||
|
||||
- `bind.cacheNetworks` now only controls access for recursive queries, where it previously controlled access for all queries.
|
||||
|
||||
## Detailed migration information {#sec-release-24.11-migration}
|
||||
## Detailed Migration Information {#sec-release-24.11-migration}
|
||||
|
||||
### `sound` options removal {#sec-release-24.11-migration-sound}
|
||||
|
||||
@ -978,3 +972,62 @@ To provide some examples:
|
||||
| `"foo", "bar"` | `"baz", "bar"` | no match | match | One compatible string matching is enough |
|
||||
|
||||
Note that this also allows writing overlays that explicitly apply to multiple boards.
|
||||
|
||||
## Nixpkgs Library {#sec-release-24.11-lib}
|
||||
|
||||
### Breaking changes {#sec-release-24.11-lib-breaking}
|
||||
|
||||
- [`lib.escapeShellArg`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.strings.escapeShellArg) and [`lib.escapeShellArgs`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.strings.escapeShellArgs): Arguments that don't need to be escaped won't be anymore, which is not breaking according to the functions documentation, but it can cause breakages if used for the non-intended use cases.
|
||||
- [`lib.warn msg val`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.trivial.warn) (and its relatives [`lib.warnIf`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.trivial.warnIf) and [`lib.warnIfNot`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.trivial.warnIfNot)) now require `msg` to be a string to match the behavior of the new [`builtins.warn`](https://nix.dev/manual/nix/2.25/language/builtins.html?highlight=warn#builtins-warn).
|
||||
- `lib.mdDoc`: Removed after deprecation in the previous release.
|
||||
|
||||
### Additions and Improvements {#sec-release-24.11-lib-additions-improvements}
|
||||
|
||||
New and extended interfaces:
|
||||
- [`lib.fromHexString`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.trivial.fromHexString): Convert a hexadecimal string to it's integer representation.
|
||||
- `lib.network.ipv6.fromString`: Parse an IPv6 address.
|
||||
- [`lib.getLicenseFromSpdxIdOr`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.meta.getLicenseFromSpdxIdOr): Get the corresponding attribute in `lib.licenses` from an SPDX ID or fall back to the given default value.
|
||||
- [`lib.licensesSpdx`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.meta.licensesSpdx): Mapping of SPDX ID to the attributes in `lib.licenses`.
|
||||
- [`lib.getFirstOutput`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.attrsets.getFirstOutput): Like `getOutput` but with a list of fallback output names.
|
||||
- [`lib.getInclude`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.attrsets.getInclude) and [`lib.getStatic`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.attrsets.getStatic): Get a package’s `include`/`static` output.
|
||||
- [`lib.trim`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.strings.trim) and [`lib.trimWith`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.strings.trimWith): Remove leading and trailing whitespace from a string.
|
||||
- [`lib.meta.defaultPriority`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.meta.defaultPriority): The default priority of packages in Nix.
|
||||
- [`lib.toExtension`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.fixedPoints.toExtension): Convert to an extending function (overlay).
|
||||
- `lib.fetchers.normalizeHash`: Convert an attrset containing one of `hash`, `sha256` or `sha512` into one containing `outputHash{,Algo}` as accepted by `mkDerivation`.
|
||||
- `lib.fetchers.withNormalizedHash`: Wraps a function which accepts `outputHash{,Algo}` into one which accepts `hash`, `sha256` or `sha512`.
|
||||
- Various builtins are now reexported in a more standard way:
|
||||
- `lib.map` -> `lib.lists.map` -> `builtins.map`
|
||||
- `lib.intersectAttrs` -> `lib.attrsets.intersectAttrs` -> `builtins.intersectAttrs`
|
||||
- `lib.removeAttrs` -> `lib.attrsets.removeAttrs` -> `builtins.removeAttrs`
|
||||
- `lib.match` -> `lib.strings.match` -> `builtins.match`
|
||||
- `lib.split` -> `lib.strings.split` -> `builtins.split`
|
||||
- `lib.typeOf` -> `builtins.typeOf`
|
||||
- `lib.unsafeGetAttrPos` -> `builtins.unsafeGetAttrPos`
|
||||
- [`lib.cli.toGNUCommandLine`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.cli.toGNUCommandLine) now supports the `optionValueSeparator` argument attribute to control the key-value separator for arguments.
|
||||
|
||||
Documentation improvements:
|
||||
- Much of the documentation has been migrated to the [standard doc-comment format](https://github.com/NixOS/rfcs/pull/145), including [`lib.derivations`](https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-derivations), [`lib.fixedPoints`](https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-fixedPoints), [`lib.gvariant`](https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-gvariant), [`lib.filesystem`](https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-filesystem), [`lib.strings`](https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-strings), [`lib.meta`](https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-meta).
|
||||
- [`lib.generators` documentation](https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-generators) is now improved and rendered in the manual.
|
||||
- [`lib.cli` documentation](https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-cli) is now improved and rendered in the manual.
|
||||
- [`lib.composeExtensions`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.fixedPoints.composeExtensions) and [`lib.composeManyExtensions`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.fixedPoints.composeManyExtensions) documentation is now improved.
|
||||
- [`lib.importTOML`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.trivial.importTOML) and [`lib.importJSON`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.trivial.importJSON)'s documentation now have an example.
|
||||
|
||||
Module System:
|
||||
- `lib.importApply`: New function, imports a Nix expression file much like the module system would, after passing an extra positional argument to the function in the file.
|
||||
- Improve error message when accessing an option that isn't defined.
|
||||
- `lib.types.anything`: Don't fail to merge when specifying the same list multiple times.
|
||||
- Improve error when loading a flake as a module.
|
||||
|
||||
### Deprecations {#sec-release-24.11-lib-deprecations}
|
||||
|
||||
- [`lib.options.mkPackageOptionMD`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.options.mkPackageOptionMD) is now obsolete; use the identical [`lib.options.mkPackageOption`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.options.mkPackageOption) instead.
|
||||
- `lib.misc.mapAttrsFlatten` is now formally deprecated and will be removed in future releases; use the identical [`lib.attrsets.mapAttrsToList`](https://nixos.org/manual/nixpkgs/unstable#function-library-lib.attrsets.mapAttrsToList) instead.
|
||||
- `lib.isInOldestRelease`: Renamed to [`oldestSupportedReleaseIsAtLeast`](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.trivial.oldestSupportedReleaseIsAtLeast) and deprecated.
|
||||
|
||||
## NixOS Wiki {#sec-release-24.11-wiki}
|
||||
|
||||
The official NixOS Wiki at [wiki.nixos.org](https://wiki.nixos.org/) was launched in April 2024, featuring
|
||||
content initially copied from the community wiki. The wiki enhances the official documentation, linking to
|
||||
existing resources and providing a categorization system for easy navigation, and is guided by a new "Manual
|
||||
of Style" — a contribution guide and enhanced templates. It offers a wealth of new information, including
|
||||
articles on applications, desktop environments, and a growing number of translations in multiple languages.
|
||||
|
@ -14,8 +14,12 @@
|
||||
|
||||
- [Kimai](https://www.kimai.org/), a web-based multi-user time-tracking application. Available as [services.kimai](option.html#opt-services.kimai).
|
||||
|
||||
- [Omnom](https://github.com/asciimoo/omnom), a webpage bookmarking and snapshotting service. Available as [services.omnom](options.html#opt-services.omnom.enable).
|
||||
|
||||
- [Amazon CloudWatch Agent](https://github.com/aws/amazon-cloudwatch-agent), the official telemetry collector for AWS CloudWatch and AWS X-Ray. Available as [services.amazon-cloudwatch-agent](#opt-services.amazon-cloudwatch-agent.enable).
|
||||
|
||||
- [agorakit](https://github.com/agorakit/agorakit), an organization tool for citizens' collectives. Available with [services.agorakit](#opt-services.agorakit.enable).
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
## Backward Incompatibilities {#sec-release-25.05-incompatibilities}
|
||||
@ -47,6 +51,8 @@
|
||||
[official website](https://www.nerdfonts.com/font-downloads) as the titles in preview images, with the "Nerd Font"
|
||||
suffix and any whitespaces trimmed.
|
||||
|
||||
- `gkraken` software and `hardware.gkraken.enable` option have been removed, use `coolercontrol` via `programs.coolercontrol.enable` option instead.
|
||||
|
||||
- the notmuch vim plugin now lives in a separate output of the `notmuch`
|
||||
package. Installing `notmuch` will not bring the notmuch vim package anymore,
|
||||
add `vimPlugins.notmuch-vim` to your (Neo)vim configuration if you want the
|
||||
@ -58,6 +64,6 @@
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
- Create the first release note entry in this section!
|
||||
- `bind.cacheNetworks` now only controls access for recursive queries, where it previously controlled access for all queries.
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
@ -10,7 +10,11 @@ let
|
||||
buildArgs = "../../release.nix -A manualHTML.${builtins.currentSystem}";
|
||||
open = "/${outputPath}/${indexPath}";
|
||||
};
|
||||
nixos-render-docs-redirects = pkgs.writeShellScriptBin "redirects" "${pkgs.lib.getExe pkgs.nixos-render-docs-redirects} --file ${toString ./redirects.json} $@";
|
||||
in
|
||||
pkgs.mkShellNoCC {
|
||||
packages = [ devmode ];
|
||||
packages = [
|
||||
devmode
|
||||
nixos-render-docs-redirects
|
||||
];
|
||||
}
|
||||
|
@ -27,9 +27,6 @@
|
||||
# This should not contain packages that are broken or can't build, since it
|
||||
# will break this expression
|
||||
#
|
||||
# Currently broken packages:
|
||||
# - contour
|
||||
#
|
||||
# can be generated with:
|
||||
# lib.attrNames (lib.filterAttrs
|
||||
# (_: drv: (builtins.tryEval (lib.isDerivation drv && drv ? terminfo)).value)
|
||||
@ -39,6 +36,7 @@
|
||||
with pkgs.pkgsBuildBuild;
|
||||
[
|
||||
alacritty
|
||||
contour
|
||||
foot
|
||||
kitty
|
||||
mtm
|
||||
|
@ -1,15 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.hardware.gkraken;
|
||||
in
|
||||
{
|
||||
options.hardware.gkraken = {
|
||||
enable = lib.mkEnableOption "gkraken's udev rules for NZXT AIO liquid coolers";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.udev.packages = with pkgs; [
|
||||
gkraken
|
||||
];
|
||||
};
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
imcfg = config.i18n.inputMethod;
|
||||
in
|
||||
{
|
||||
config = mkIf (imcfg.enable && imcfg.type == "hime") {
|
||||
config = lib.mkIf (imcfg.enable && imcfg.type == "hime") {
|
||||
i18n.inputMethod.package = pkgs.hime;
|
||||
environment.variables = {
|
||||
GTK_IM_MODULE = "hime";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
imcfg = config.i18n.inputMethod;
|
||||
cfg = imcfg.ibus;
|
||||
@ -9,10 +6,10 @@ let
|
||||
ibusEngine = lib.types.mkOptionType {
|
||||
name = "ibus-engine";
|
||||
inherit (lib.types.package) descriptionClass merge;
|
||||
check = x: (lib.types.package.check x) && (attrByPath ["meta" "isIbusEngine"] false x);
|
||||
check = x: (lib.types.package.check x) && (lib.attrByPath ["meta" "isIbusEngine"] false x);
|
||||
};
|
||||
|
||||
impanel = optionalString (cfg.panel != null) "--panel=${cfg.panel}";
|
||||
impanel = lib.optionalString (cfg.panel != null) "--panel=${cfg.panel}";
|
||||
|
||||
ibusAutostart = pkgs.writeTextFile {
|
||||
name = "autostart-ibus-daemon";
|
||||
@ -29,32 +26,32 @@ let
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "programs" "ibus" "plugins" ] [ "i18n" "inputMethod" "ibus" "engines" ])
|
||||
(lib.mkRenamedOptionModule [ "programs" "ibus" "plugins" ] [ "i18n" "inputMethod" "ibus" "engines" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
i18n.inputMethod.ibus = {
|
||||
engines = mkOption {
|
||||
type = with types; listOf ibusEngine;
|
||||
engines = lib.mkOption {
|
||||
type = with lib.types; listOf ibusEngine;
|
||||
default = [];
|
||||
example = literalExpression "with pkgs.ibus-engines; [ mozc hangul ]";
|
||||
example = lib.literalExpression "with pkgs.ibus-engines; [ mozc hangul ]";
|
||||
description =
|
||||
let
|
||||
enginesDrv = filterAttrs (const isDerivation) pkgs.ibus-engines;
|
||||
engines = concatStringsSep ", "
|
||||
(map (name: "`${name}`") (attrNames enginesDrv));
|
||||
enginesDrv = lib.filterAttrs (lib.const lib.isDerivation) pkgs.ibus-engines;
|
||||
engines = lib.concatStringsSep ", "
|
||||
(map (name: "`${name}`") (lib.attrNames enginesDrv));
|
||||
in "Enabled IBus engines. Available engines are: ${engines}.";
|
||||
};
|
||||
panel = mkOption {
|
||||
type = with types; nullOr path;
|
||||
panel = lib.mkOption {
|
||||
type = with lib.types; nullOr path;
|
||||
default = null;
|
||||
example = literalExpression ''"''${pkgs.plasma5Packages.plasma-desktop}/libexec/kimpanel-ibus-panel"'';
|
||||
example = lib.literalExpression ''"''${pkgs.plasma5Packages.plasma-desktop}/libexec/kimpanel-ibus-panel"'';
|
||||
description = "Replace the IBus panel with another panel.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (imcfg.enable && imcfg.type == "ibus") {
|
||||
config = lib.mkIf (imcfg.enable && imcfg.type == "ibus") {
|
||||
i18n.inputMethod.package = ibusPackage;
|
||||
|
||||
environment.systemPackages = [
|
||||
@ -76,7 +73,7 @@ in
|
||||
XMODIFIERS = "@im=ibus";
|
||||
};
|
||||
|
||||
xdg.portal.extraPortals = mkIf config.xdg.portal.enable [
|
||||
xdg.portal.extraPortals = lib.mkIf config.xdg.portal.enable [
|
||||
ibusPackage
|
||||
];
|
||||
};
|
||||
|
@ -1,11 +1,9 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
imcfg = config.i18n.inputMethod;
|
||||
in
|
||||
{
|
||||
config = mkIf (imcfg.enable && imcfg.type == "nabi") {
|
||||
config = lib.mkIf (imcfg.enable && imcfg.type == "nabi") {
|
||||
i18n.inputMethod.package = pkgs.nabi;
|
||||
|
||||
environment.variables = {
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
imcfg = config.i18n.inputMethod;
|
||||
cfg = imcfg.uim;
|
||||
@ -10,8 +7,8 @@ in
|
||||
options = {
|
||||
|
||||
i18n.inputMethod.uim = {
|
||||
toolbar = mkOption {
|
||||
type = types.enum [ "gtk" "gtk3" "gtk-systray" "gtk3-systray" "qt5" ];
|
||||
toolbar = lib.mkOption {
|
||||
type = lib.types.enum [ "gtk" "gtk3" "gtk-systray" "gtk3-systray" "qt5" ];
|
||||
default = "gtk";
|
||||
example = "gtk-systray";
|
||||
description = ''
|
||||
@ -22,7 +19,7 @@ in
|
||||
|
||||
};
|
||||
|
||||
config = mkIf (imcfg.enable && imcfg.type == "uim") {
|
||||
config = lib.mkIf (imcfg.enable && imcfg.type == "uim") {
|
||||
i18n.inputMethod.package = pkgs.uim;
|
||||
|
||||
environment.variables = {
|
||||
|
@ -8,7 +8,21 @@
|
||||
let
|
||||
inherit (lib) types;
|
||||
|
||||
imageModules = { };
|
||||
imageModules = {
|
||||
azure = [ ../virtualisation/azure-image.nix ];
|
||||
digital-ocean = [ ../virtualisation/digital-ocean-image.nix ];
|
||||
google-compute = [ ../virtualisation/google-compute-image.nix ];
|
||||
hyperv = [ ../virtualisation/hyperv-image.nix ];
|
||||
linode = [ ../virtualisation/linode-image.nix ];
|
||||
lxc = [ ../virtualisation/lxc-container.nix ];
|
||||
lxc-metadata = [ ../virtualisation/lxc-image-metadata.nix ];
|
||||
oci = [ ../virtualisation/oci-image.nix ];
|
||||
proxmox = [ ../virtualisation/proxmox-image.nix ];
|
||||
kubevirt = [ ../virtualisation/kubevirt.nix ];
|
||||
vagrant-virtualbox = [ ../virtualisation/vagrant-virtualbox-image.nix ];
|
||||
virtualbox = [ ../virtualisation/virtualbox-image.nix ];
|
||||
vmware = [ ../virtualisation/vmware-image.nix ];
|
||||
};
|
||||
imageConfigs = lib.mapAttrs (
|
||||
name: modules:
|
||||
extendModules {
|
||||
|
@ -1,13 +1,10 @@
|
||||
{ lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
{
|
||||
|
||||
options = {
|
||||
|
||||
assertions = mkOption {
|
||||
type = types.listOf types.unspecified;
|
||||
assertions = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.unspecified;
|
||||
internal = true;
|
||||
default = [];
|
||||
example = [ { assertion = false; message = "you can't enable this for that reason"; } ];
|
||||
@ -18,10 +15,10 @@ with lib;
|
||||
'';
|
||||
};
|
||||
|
||||
warnings = mkOption {
|
||||
warnings = lib.mkOption {
|
||||
internal = true;
|
||||
default = [];
|
||||
type = types.listOf types.str;
|
||||
type = lib.types.listOf lib.types.str;
|
||||
example = [ "The `foo' service is deprecated and will go away soon!" ];
|
||||
description = ''
|
||||
This option allows modules to show warnings to users during
|
||||
|
@ -1,11 +1,8 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
crashdump = config.boot.crashDump;
|
||||
|
||||
kernelParams = concatStringsSep " " crashdump.kernelParams;
|
||||
kernelParams = lib.concatStringsSep " " crashdump.kernelParams;
|
||||
|
||||
in
|
||||
###### interface
|
||||
@ -13,8 +10,8 @@ in
|
||||
options = {
|
||||
boot = {
|
||||
crashDump = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If enabled, NixOS will set up a kernel that will
|
||||
@ -24,17 +21,17 @@ in
|
||||
It also activates the NMI watchdog.
|
||||
'';
|
||||
};
|
||||
reservedMemory = mkOption {
|
||||
reservedMemory = lib.mkOption {
|
||||
default = "128M";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The amount of memory reserved for the crashdump kernel.
|
||||
If you choose a too high value, dmesg will mention
|
||||
"crashkernel reservation failed".
|
||||
'';
|
||||
};
|
||||
kernelParams = mkOption {
|
||||
type = types.listOf types.str;
|
||||
kernelParams = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "1" "boot.shell_on_fail" ];
|
||||
description = ''
|
||||
Parameters that will be passed to the kernel kexec-ed on crash.
|
||||
@ -46,7 +43,7 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf crashdump.enable {
|
||||
config = lib.mkIf crashdump.enable {
|
||||
boot = {
|
||||
postBootCommands = ''
|
||||
echo "loading crashdump kernel...";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.system.nixos;
|
||||
in
|
||||
@ -10,8 +7,8 @@ in
|
||||
|
||||
options.system = {
|
||||
|
||||
nixos.label = mkOption {
|
||||
type = types.strMatching "[a-zA-Z0-9:_\\.-]*";
|
||||
nixos.label = lib.mkOption {
|
||||
type = lib.types.strMatching "[a-zA-Z0-9:_\\.-]*";
|
||||
description = ''
|
||||
NixOS version name to be used in the names of generated
|
||||
outputs and boot labels.
|
||||
@ -43,8 +40,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
nixos.tags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
nixos.tags = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
example = [ "with-xen" ];
|
||||
description = ''
|
||||
@ -68,9 +65,9 @@ in
|
||||
config = {
|
||||
# This is set here rather than up there so that changing it would
|
||||
# not rebuild the manual
|
||||
system.nixos.label = mkDefault (maybeEnv "NIXOS_LABEL"
|
||||
(concatStringsSep "-" ((sort (x: y: x < y) cfg.tags)
|
||||
++ [ (maybeEnv "NIXOS_LABEL_VERSION" cfg.version) ])));
|
||||
system.nixos.label = lib.mkDefault (lib.maybeEnv "NIXOS_LABEL"
|
||||
(lib.concatStringsSep "-" ((lib.sort (x: y: x < y) cfg.tags)
|
||||
++ [ (lib.maybeEnv "NIXOS_LABEL_VERSION" cfg.version) ])));
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,28 +1,25 @@
|
||||
{ lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
maintainer = mkOptionType {
|
||||
maintainer = lib.mkOptionType {
|
||||
name = "maintainer";
|
||||
check = email: elem email (attrValues lib.maintainers);
|
||||
merge = loc: defs: listToAttrs (singleton (nameValuePair (last defs).file (last defs).value));
|
||||
check = email: lib.elem email (lib.attrValues lib.maintainers);
|
||||
merge = loc: defs: lib.listToAttrs (lib.singleton (lib.nameValuePair (lib.last defs).file (lib.last defs).value));
|
||||
};
|
||||
|
||||
listOfMaintainers = types.listOf maintainer // {
|
||||
listOfMaintainers = lib.types.listOf maintainer // {
|
||||
# Returns list of
|
||||
# { "module-file" = [
|
||||
# "maintainer1 <first@nixos.org>"
|
||||
# "maintainer2 <second@nixos.org>" ];
|
||||
# }
|
||||
merge = loc: defs:
|
||||
zipAttrs
|
||||
(flatten (imap1 (n: def: imap1 (m: def':
|
||||
lib.zipAttrs
|
||||
(lib.flatten (lib.imap1 (n: def: lib.imap1 (m: def':
|
||||
maintainer.merge (loc ++ ["[${toString n}-${toString m}]"])
|
||||
[{ inherit (def) file; value = def'; }]) def.value) defs));
|
||||
};
|
||||
|
||||
docFile = types.path // {
|
||||
docFile = lib.types.path // {
|
||||
# Returns tuples of
|
||||
# { file = "module location"; value = <path/to/doc.xml>; }
|
||||
merge = loc: defs: defs;
|
||||
@ -33,18 +30,18 @@ in
|
||||
options = {
|
||||
meta = {
|
||||
|
||||
maintainers = mkOption {
|
||||
maintainers = lib.mkOption {
|
||||
type = listOfMaintainers;
|
||||
internal = true;
|
||||
default = [];
|
||||
example = literalExpression ''[ lib.maintainers.all ]'';
|
||||
example = lib.literalExpression ''[ lib.maintainers.all ]'';
|
||||
description = ''
|
||||
List of maintainers of each module. This option should be defined at
|
||||
most once per module.
|
||||
'';
|
||||
};
|
||||
|
||||
doc = mkOption {
|
||||
doc = lib.mkOption {
|
||||
type = docFile;
|
||||
internal = true;
|
||||
example = "./meta.chapter.md";
|
||||
@ -54,8 +51,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
buildDocsInSandbox = mkOption {
|
||||
type = types.bool // {
|
||||
buildDocsInSandbox = lib.mkOption {
|
||||
type = lib.types.bool // {
|
||||
merge = loc: defs: defs;
|
||||
};
|
||||
internal = true;
|
||||
@ -72,5 +69,5 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = singleton lib.maintainers.pierron;
|
||||
meta.maintainers = lib.singleton lib.maintainers.pierron;
|
||||
}
|
||||
|
@ -36,14 +36,13 @@ let
|
||||
DOCUMENTATION_URL = optionalString isNixos "https://nixos.org/learn.html";
|
||||
SUPPORT_URL = optionalString isNixos "https://nixos.org/community.html";
|
||||
BUG_REPORT_URL = optionalString isNixos "https://github.com/NixOS/nixpkgs/issues";
|
||||
ANSI_COLOR = optionalString isNixos "1;34";
|
||||
ANSI_COLOR = optionalString isNixos "0;38;2;126;186;228";
|
||||
IMAGE_ID = optionalString (config.system.image.id != null) config.system.image.id;
|
||||
IMAGE_VERSION = optionalString (config.system.image.version != null) config.system.image.version;
|
||||
VARIANT = optionalString (cfg.variantName != null) cfg.variantName;
|
||||
VARIANT_ID = optionalString (cfg.variant_id != null) cfg.variant_id;
|
||||
DEFAULT_HOSTNAME = config.networking.fqdnOrHostName;
|
||||
SUPPORT_END = "2025-06-30";
|
||||
};
|
||||
DEFAULT_HOSTNAME = config.system.nixos.distroId;
|
||||
} // cfg.extraOSReleaseArgs;
|
||||
|
||||
initrdReleaseContents = (removeAttrs osReleaseContents [ "BUILD_ID" ]) // {
|
||||
PRETTY_NAME = "${osReleaseContents.PRETTY_NAME} (Initrd)";
|
||||
@ -143,6 +142,26 @@ in
|
||||
default = "NixOS";
|
||||
description = "The name of the operating system vendor";
|
||||
};
|
||||
|
||||
extraOSReleaseArgs = mkOption {
|
||||
internal = true;
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Additional attributes to be merged with the /etc/os-release generator.";
|
||||
example = {
|
||||
ANSI_COLOR = "1;31";
|
||||
};
|
||||
};
|
||||
|
||||
extraLSBReleaseArgs = mkOption {
|
||||
internal = true;
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
description = "Additional attributes to be merged with the /etc/lsb-release generator.";
|
||||
example = {
|
||||
LSB_VERSION = "1.0";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
image = {
|
||||
@ -237,13 +256,13 @@ in
|
||||
# https://www.freedesktop.org/software/systemd/man/os-release.html for the
|
||||
# format.
|
||||
environment.etc = {
|
||||
"lsb-release".text = attrsToText {
|
||||
"lsb-release".text = attrsToText ({
|
||||
LSB_VERSION = "${cfg.release} (${cfg.codeName})";
|
||||
DISTRIB_ID = "${cfg.distroId}";
|
||||
DISTRIB_RELEASE = cfg.release;
|
||||
DISTRIB_CODENAME = toLower cfg.codeName;
|
||||
DISTRIB_DESCRIPTION = "${cfg.distroName} ${cfg.release} (${cfg.codeName})";
|
||||
};
|
||||
} // cfg.extraLSBReleaseArgs);
|
||||
|
||||
"os-release".text = attrsToText osReleaseContents;
|
||||
};
|
||||
|
@ -65,7 +65,6 @@
|
||||
./hardware/digitalbitbox.nix
|
||||
./hardware/flipperzero.nix
|
||||
./hardware/flirc.nix
|
||||
./hardware/gkraken.nix
|
||||
./hardware/glasgow.nix
|
||||
./hardware/gpgsmartcards.nix
|
||||
./hardware/graphics.nix
|
||||
@ -813,6 +812,7 @@
|
||||
./services/misc/octoprint.nix
|
||||
./services/misc/ollama.nix
|
||||
./services/misc/ombi.nix
|
||||
./services/misc/omnom.nix
|
||||
./services/misc/open-webui.nix
|
||||
./services/misc/osrm.nix
|
||||
./services/misc/owncast.nix
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.fcast-receiver;
|
||||
in
|
||||
@ -11,20 +8,20 @@ in
|
||||
};
|
||||
|
||||
options.programs.fcast-receiver = {
|
||||
enable = mkEnableOption "FCast Receiver";
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkEnableOption "FCast Receiver";
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports needed for the functionality of the program.
|
||||
'';
|
||||
};
|
||||
package = mkPackageOption pkgs "fcast-receiver" { };
|
||||
package = lib.mkPackageOption pkgs "fcast-receiver" { };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 46899 ];
|
||||
};
|
||||
};
|
||||
|
@ -33,6 +33,10 @@ in
|
||||
systemd-logind API). Instead of using the module you can now
|
||||
simply add the brightnessctl package to environment.systemPackages.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "hardware" "gkraken" "enable" ] ''
|
||||
gkraken was deprecated by coolercontrol and thus removed from nixpkgs.
|
||||
Consider using programs.coolercontrol instead.
|
||||
'')
|
||||
(mkRemovedOptionModule [ "hardware" "u2f" ] ''
|
||||
The U2F modules module was removed, as all it did was adding the
|
||||
udev rules from libu2f-host to the system. Udev gained native support
|
||||
|
@ -1,30 +1,27 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
inherit (builtins) attrNames head map match readFile;
|
||||
inherit (lib) types;
|
||||
inherit (config.environment) etc;
|
||||
cfg = config.security.apparmor;
|
||||
mkDisableOption = name: mkEnableOption name // {
|
||||
mkDisableOption = name: lib.mkEnableOption name // {
|
||||
default = true;
|
||||
example = false;
|
||||
};
|
||||
enabledPolicies = filterAttrs (n: p: p.enable) cfg.policies;
|
||||
enabledPolicies = lib.filterAttrs (n: p: p.enable) cfg.policies;
|
||||
in
|
||||
|
||||
{
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "security" "apparmor" "confineSUIDApplications" ] "Please use the new options: `security.apparmor.policies.<policy>.enable'.")
|
||||
(mkRemovedOptionModule [ "security" "apparmor" "profiles" ] "Please use the new option: `security.apparmor.policies'.")
|
||||
(lib.mkRemovedOptionModule [ "security" "apparmor" "confineSUIDApplications" ] "Please use the new options: `security.apparmor.policies.<policy>.enable'.")
|
||||
(lib.mkRemovedOptionModule [ "security" "apparmor" "profiles" ] "Please use the new option: `security.apparmor.policies'.")
|
||||
apparmor/includes.nix
|
||||
apparmor/profiles.nix
|
||||
];
|
||||
|
||||
options = {
|
||||
security.apparmor = {
|
||||
enable = mkEnableOption ''
|
||||
enable = lib.mkEnableOption ''
|
||||
the AppArmor Mandatory Access Control system.
|
||||
|
||||
If you're enabling this module on a running system,
|
||||
@ -41,7 +38,7 @@ in
|
||||
Enable [](#opt-security.apparmor.killUnconfinedConfinables)
|
||||
if you want this service to do such killing
|
||||
by sending a `SIGTERM` to those running processes'';
|
||||
policies = mkOption {
|
||||
policies = lib.mkOption {
|
||||
description = ''
|
||||
AppArmor policies.
|
||||
'';
|
||||
@ -49,7 +46,7 @@ in
|
||||
options = {
|
||||
enable = mkDisableOption "loading of the profile into the kernel";
|
||||
enforce = mkDisableOption "enforcing of the policy or only complain in the logs";
|
||||
profile = mkOption {
|
||||
profile = lib.mkOption {
|
||||
description = "The policy of the profile.";
|
||||
type = types.lines;
|
||||
apply = pkgs.writeText name;
|
||||
@ -58,28 +55,28 @@ in
|
||||
}));
|
||||
default = {};
|
||||
};
|
||||
includes = mkOption {
|
||||
includes = lib.mkOption {
|
||||
type = types.attrsOf types.lines;
|
||||
default = {};
|
||||
description = ''
|
||||
List of paths to be added to AppArmor's searched paths
|
||||
when resolving `include` directives.
|
||||
'';
|
||||
apply = mapAttrs pkgs.writeText;
|
||||
apply = lib.mapAttrs pkgs.writeText;
|
||||
};
|
||||
packages = mkOption {
|
||||
packages = lib.mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = "List of packages to be added to AppArmor's include path";
|
||||
};
|
||||
enableCache = mkEnableOption ''
|
||||
enableCache = lib.mkEnableOption ''
|
||||
caching of AppArmor policies
|
||||
in `/var/cache/apparmor/`.
|
||||
|
||||
Beware that AppArmor policies almost always contain Nix store paths,
|
||||
and thus produce at each change of these paths
|
||||
a new cached version accumulating in the cache'';
|
||||
killUnconfinedConfinables = mkEnableOption ''
|
||||
killUnconfinedConfinables = lib.mkEnableOption ''
|
||||
killing of processes which have an AppArmor profile enabled
|
||||
(in [](#opt-security.apparmor.policies))
|
||||
but are not confined (because AppArmor can only confine new processes).
|
||||
@ -92,7 +89,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = map (policy:
|
||||
{ assertion = match ".*/.*" policy == null;
|
||||
message = "`security.apparmor.policies.\"${policy}\"' must not contain a slash.";
|
||||
@ -108,15 +105,15 @@ in
|
||||
environment.etc."apparmor.d".source = pkgs.linkFarm "apparmor.d" (
|
||||
# It's important to put only enabledPolicies here and not all cfg.policies
|
||||
# because aa-remove-unknown reads profiles from all /etc/apparmor.d/*
|
||||
mapAttrsToList (name: p: { inherit name; path = p.profile; }) enabledPolicies ++
|
||||
mapAttrsToList (name: path: { inherit name path; }) cfg.includes
|
||||
lib.mapAttrsToList (name: p: { inherit name; path = p.profile; }) enabledPolicies ++
|
||||
lib.mapAttrsToList (name: path: { inherit name path; }) cfg.includes
|
||||
);
|
||||
environment.etc."apparmor/parser.conf".text = ''
|
||||
${if cfg.enableCache then "write-cache" else "skip-cache"}
|
||||
cache-loc /var/cache/apparmor
|
||||
Include /etc/apparmor.d
|
||||
'' +
|
||||
concatMapStrings (p: "Include ${p}/etc/apparmor.d\n") cfg.packages;
|
||||
lib.concatMapStrings (p: "Include ${p}/etc/apparmor.d\n") cfg.packages;
|
||||
# For aa-logprof
|
||||
environment.etc."apparmor/apparmor.conf".text = ''
|
||||
'';
|
||||
@ -142,7 +139,7 @@ in
|
||||
# 3 - force all perms on the rule to be user
|
||||
default_owner_prompt = 1
|
||||
|
||||
custom_includes = /etc/apparmor.d ${concatMapStringsSep " " (p: "${p}/etc/apparmor.d") cfg.packages}
|
||||
custom_includes = /etc/apparmor.d ${lib.concatMapStringsSep " " (p: "${p}/etc/apparmor.d") cfg.packages}
|
||||
|
||||
[qualifiers]
|
||||
${pkgs.runtimeShell} = icnu
|
||||
@ -187,17 +184,17 @@ in
|
||||
xargs --verbose --no-run-if-empty --delimiter='\n' \
|
||||
kill
|
||||
'';
|
||||
commonOpts = p: "--verbose --show-cache ${optionalString (!p.enforce) "--complain "}${p.profile}";
|
||||
commonOpts = p: "--verbose --show-cache ${lib.optionalString (!p.enforce) "--complain "}${p.profile}";
|
||||
in {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
ExecStartPre = "${pkgs.apparmor-utils}/bin/aa-teardown";
|
||||
ExecStart = mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}") enabledPolicies;
|
||||
ExecStartPost = optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
|
||||
ExecStart = lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}") enabledPolicies;
|
||||
ExecStartPost = lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
|
||||
ExecReload =
|
||||
# Add or replace into the kernel profiles in enabledPolicies
|
||||
# (because AppArmor can do that without stopping the processes already confined).
|
||||
mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}") enabledPolicies ++
|
||||
lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}") enabledPolicies ++
|
||||
# Remove from the kernel any profile whose name is not
|
||||
# one of the names within the content of the profiles in enabledPolicies
|
||||
# (indirectly read from /etc/apparmor.d/*, without recursing into sub-directory).
|
||||
@ -205,7 +202,7 @@ in
|
||||
[ "${pkgs.apparmor-utils}/bin/aa-remove-unknown" ] ++
|
||||
# Optionally kill the processes which are unconfined but now have a profile loaded
|
||||
# (because AppArmor can only start to confine new processes).
|
||||
optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
|
||||
lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
|
||||
ExecStop = "${pkgs.apparmor-utils}/bin/aa-teardown";
|
||||
CacheDirectory = [ "apparmor" "apparmor/logprof" ];
|
||||
CacheDirectoryMode = "0700";
|
||||
@ -213,5 +210,5 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ julm ];
|
||||
meta.maintainers = with lib.maintainers; [ julm ];
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.security.audit;
|
||||
enabled = cfg.enable == "lock" || cfg.enable;
|
||||
@ -29,7 +26,7 @@ let
|
||||
|
||||
# Put the rules in a temporary file owned and only readable by root
|
||||
rulesfile="$(mktemp)"
|
||||
${concatMapStrings (x: "echo '${x}' >> $rulesfile\n") cfg.rules}
|
||||
${lib.concatMapStrings (x: "echo '${x}' >> $rulesfile\n") cfg.rules}
|
||||
|
||||
# Apply the requested rules
|
||||
auditctl -R "$rulesfile"
|
||||
@ -53,8 +50,8 @@ let
|
||||
in {
|
||||
options = {
|
||||
security.audit = {
|
||||
enable = mkOption {
|
||||
type = types.enum [ false true "lock" ];
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.enum [ false true "lock" ];
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable the Linux audit system. The special `lock` value can be used to
|
||||
@ -64,14 +61,14 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
failureMode = mkOption {
|
||||
type = types.enum [ "silent" "printk" "panic" ];
|
||||
failureMode = lib.mkOption {
|
||||
type = lib.types.enum [ "silent" "printk" "panic" ];
|
||||
default = "printk";
|
||||
description = "How to handle critical errors in the auditing system";
|
||||
};
|
||||
|
||||
backlogLimit = mkOption {
|
||||
type = types.int;
|
||||
backlogLimit = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 64; # Apparently the kernel default
|
||||
description = ''
|
||||
The maximum number of outstanding audit buffers allowed; exceeding this is
|
||||
@ -79,8 +76,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
rateLimit = mkOption {
|
||||
type = types.int;
|
||||
rateLimit = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 0;
|
||||
description = ''
|
||||
The maximum messages per second permitted before triggering a failure as
|
||||
@ -88,8 +85,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
rules = mkOption {
|
||||
type = types.listOf types.str; # (types.either types.str (types.submodule rule));
|
||||
rules = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str; # (types.either types.str (types.submodule rule));
|
||||
default = [];
|
||||
example = [ "-a exit,always -F arch=b64 -S execve" ];
|
||||
description = ''
|
||||
|
@ -1,22 +1,19 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.security.please;
|
||||
ini = pkgs.formats.ini { };
|
||||
in
|
||||
{
|
||||
options.security.please = {
|
||||
enable = mkEnableOption ''
|
||||
enable = lib.mkEnableOption ''
|
||||
please, a Sudo clone which allows a users to execute a command or edit a
|
||||
file as another user
|
||||
'';
|
||||
|
||||
package = mkPackageOption pkgs "please" { };
|
||||
package = lib.mkPackageOption pkgs "please" { };
|
||||
|
||||
wheelNeedsPassword = mkOption {
|
||||
type = types.bool;
|
||||
wheelNeedsPassword = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether users of the `wheel` group must provide a password to run
|
||||
@ -25,7 +22,7 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
type = ini.type;
|
||||
default = { };
|
||||
example = {
|
||||
@ -53,7 +50,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
security.wrappers =
|
||||
let
|
||||
owner = "root";
|
||||
@ -110,6 +107,6 @@ in
|
||||
usshAuth = true;
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ azahi ];
|
||||
meta.maintainers = with lib.maintainers; [ azahi ];
|
||||
};
|
||||
}
|
||||
|
@ -1,39 +1,36 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.oxidized;
|
||||
in
|
||||
{
|
||||
options.services.oxidized = {
|
||||
enable = mkEnableOption "the oxidized configuration backup service";
|
||||
enable = lib.mkEnableOption "the oxidized configuration backup service";
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "oxidized";
|
||||
description = ''
|
||||
User under which the oxidized service runs.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "oxidized";
|
||||
description = ''
|
||||
Group under which the oxidized service runs.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/oxidized";
|
||||
description = "State directory for the oxidized service.";
|
||||
};
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
example = literalExpression ''
|
||||
configFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
example = lib.literalExpression ''
|
||||
pkgs.writeText "oxidized-config.yml" '''
|
||||
---
|
||||
debug: true
|
||||
@ -67,9 +64,9 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
routerDB = mkOption {
|
||||
type = types.path;
|
||||
example = literalExpression ''
|
||||
routerDB = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
example = lib.literalExpression ''
|
||||
pkgs.writeText "oxidized-router.db" '''
|
||||
hostname-sw1:powerconnect:username1:password2
|
||||
hostname-sw2:procurve:username2:password2
|
||||
@ -82,7 +79,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.groups.${cfg.group} = { };
|
||||
users.users.${cfg.user} = {
|
||||
description = "Oxidized service user";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.salt.minion;
|
||||
@ -21,9 +18,9 @@ in
|
||||
{
|
||||
options = {
|
||||
services.salt.minion = {
|
||||
enable = mkEnableOption "Salt configuration management system minion service";
|
||||
configuration = mkOption {
|
||||
type = types.attrs;
|
||||
enable = lib.mkEnableOption "Salt configuration management system minion service";
|
||||
configuration = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = {};
|
||||
description = ''
|
||||
Salt minion configuration as Nix attribute set.
|
||||
@ -34,7 +31,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment = {
|
||||
# Set this up in /etc/salt/minion so `salt-call`, etc. work.
|
||||
# The alternatives are
|
||||
|
@ -1,18 +1,14 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with pkgs;
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.activemq;
|
||||
|
||||
activemqBroker = runCommand "activemq-broker"
|
||||
activemqBroker = pkgs.runCommand "activemq-broker"
|
||||
{
|
||||
nativeBuildInputs = [ jdk ];
|
||||
nativeBuildInputs = [ pkgs.jdk ];
|
||||
} ''
|
||||
mkdir -p $out/lib
|
||||
source ${activemq}/lib/classpath.env
|
||||
source ${pkgs.activemq}/lib/classpath.env
|
||||
export CLASSPATH
|
||||
ln -s "${./ActiveMQBroker.java}" ActiveMQBroker.java
|
||||
javac -d $out/lib ActiveMQBroker.java
|
||||
@ -23,25 +19,25 @@ in
|
||||
|
||||
options = {
|
||||
services.activemq = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable the Apache ActiveMQ message broker service.
|
||||
'';
|
||||
};
|
||||
configurationDir = mkOption {
|
||||
default = "${activemq}/conf";
|
||||
defaultText = literalExpression ''"''${pkgs.activemq}/conf"'';
|
||||
type = types.str;
|
||||
configurationDir = lib.mkOption {
|
||||
default = "${pkgs.activemq}/conf";
|
||||
defaultText = lib.literalExpression ''"''${pkgs.activemq}/conf"'';
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The base directory for ActiveMQ's configuration.
|
||||
By default, this directory is searched for a file named activemq.xml,
|
||||
which should contain the configuration for the broker service.
|
||||
'';
|
||||
};
|
||||
configurationURI = mkOption {
|
||||
type = types.str;
|
||||
configurationURI = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "xbean:activemq.xml";
|
||||
description = ''
|
||||
The URI that is passed along to the BrokerFactory to
|
||||
@ -51,8 +47,8 @@ in
|
||||
an activemq.xml configuration file in it.
|
||||
'';
|
||||
};
|
||||
baseDir = mkOption {
|
||||
type = types.str;
|
||||
baseDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/activemq";
|
||||
description = ''
|
||||
The base directory where ActiveMQ stores its persistent data and logs.
|
||||
@ -61,10 +57,10 @@ in
|
||||
this in activemq.xml.
|
||||
'';
|
||||
};
|
||||
javaProperties = mkOption {
|
||||
type = types.attrs;
|
||||
javaProperties = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
"java.net.preferIPv4Stack" = "true";
|
||||
}
|
||||
@ -73,7 +69,7 @@ in
|
||||
"activemq.base" = "${cfg.baseDir}";
|
||||
"activemq.data" = "${cfg.baseDir}/data";
|
||||
"activemq.conf" = "${cfg.configurationDir}";
|
||||
"activemq.home" = "${activemq}";
|
||||
"activemq.home" = "${pkgs.activemq}";
|
||||
} // attrs;
|
||||
description = ''
|
||||
Specifies Java properties that are sent to the ActiveMQ
|
||||
@ -83,8 +79,8 @@ in
|
||||
given reasonable defaults.
|
||||
'';
|
||||
};
|
||||
extraJavaOptions = mkOption {
|
||||
type = types.separatedString " ";
|
||||
extraJavaOptions = lib.mkOption {
|
||||
type = lib.types.separatedString " ";
|
||||
default = "";
|
||||
example = "-Xmx2G -Xms2G -XX:MaxPermSize=512M";
|
||||
description = ''
|
||||
@ -95,7 +91,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.users.activemq = {
|
||||
description = "ActiveMQ server user";
|
||||
group = "activemq";
|
||||
@ -118,13 +114,13 @@ in
|
||||
systemd.services.activemq = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
path = [ jre ];
|
||||
path = [ pkgs.jre ];
|
||||
serviceConfig.User = "activemq";
|
||||
script = ''
|
||||
source ${activemq}/lib/classpath.env
|
||||
source ${pkgs.activemq}/lib/classpath.env
|
||||
export CLASSPATH=${activemqBroker}/lib:${cfg.configurationDir}:$CLASSPATH
|
||||
exec java \
|
||||
${concatStringsSep " \\\n" (mapAttrsToList (name: value: "-D${name}=${value}") cfg.javaProperties)} \
|
||||
${lib.concatStringsSep " \\\n" (lib.mapAttrsToList (name: value: "-D${name}=${value}") cfg.javaProperties)} \
|
||||
${cfg.extraJavaOptions} ActiveMQBroker "${cfg.configurationURI}"
|
||||
'';
|
||||
};
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.botamusique;
|
||||
|
||||
@ -12,34 +9,34 @@ in
|
||||
meta.maintainers = with lib.maintainers; [ hexa ];
|
||||
|
||||
options.services.botamusique = {
|
||||
enable = mkEnableOption "botamusique, a bot to play audio streams on mumble";
|
||||
enable = lib.mkEnableOption "botamusique, a bot to play audio streams on mumble";
|
||||
|
||||
package = mkPackageOption pkgs "botamusique" { };
|
||||
package = lib.mkPackageOption pkgs "botamusique" { };
|
||||
|
||||
settings = mkOption {
|
||||
type = with types; submodule {
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types; submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
server.host = mkOption {
|
||||
server.host = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
example = "mumble.example.com";
|
||||
description = "Hostname of the mumble server to connect to.";
|
||||
};
|
||||
|
||||
server.port = mkOption {
|
||||
server.port = lib.mkOption {
|
||||
type = types.port;
|
||||
default = 64738;
|
||||
description = "Port of the mumble server to connect to.";
|
||||
};
|
||||
|
||||
bot.username = mkOption {
|
||||
bot.username = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "botamusique";
|
||||
description = "Name the bot should appear with.";
|
||||
};
|
||||
|
||||
bot.comment = mkOption {
|
||||
bot.comment = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "Hi, I'm here to play radio, local music or youtube/soundcloud music. Have fun!";
|
||||
description = "Comment displayed for the bot.";
|
||||
@ -54,7 +51,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.botamusique = {
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
@ -1,58 +1,55 @@
|
||||
{ pkgs, lib, config, utils, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.gmediarender;
|
||||
in
|
||||
{
|
||||
options.services.gmediarender = {
|
||||
enable = mkEnableOption "the gmediarender DLNA renderer";
|
||||
enable = lib.mkEnableOption "the gmediarender DLNA renderer";
|
||||
|
||||
audioDevice = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
audioDevice = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The audio device to use.
|
||||
'';
|
||||
};
|
||||
|
||||
audioSink = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
audioSink = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The audio sink to use.
|
||||
'';
|
||||
};
|
||||
|
||||
friendlyName = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
friendlyName = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
A "friendly name" for identifying the endpoint.
|
||||
'';
|
||||
};
|
||||
|
||||
initialVolume = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
initialVolume = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = 0;
|
||||
description = ''
|
||||
A default volume attenuation (in dB) for the endpoint.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "gmediarender" {
|
||||
package = lib.mkPackageOption pkgs "gmediarender" {
|
||||
default = "gmrender-resurrect";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.nullOr types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.port;
|
||||
default = null;
|
||||
description = "Port that will be used to accept client connections.";
|
||||
};
|
||||
|
||||
uuid = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
uuid = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
A UUID for uniquely identifying the endpoint. If you have
|
||||
@ -61,7 +58,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd = {
|
||||
services.gmediarender = {
|
||||
wants = [ "network-online.target" ];
|
||||
@ -78,12 +75,12 @@ in
|
||||
SupplementaryGroups = [ "audio" ];
|
||||
ExecStart =
|
||||
"${cfg.package}/bin/gmediarender " +
|
||||
optionalString (cfg.audioDevice != null) ("--gstout-audiodevice=${utils.escapeSystemdExecArg cfg.audioDevice} ") +
|
||||
optionalString (cfg.audioSink != null) ("--gstout-audiosink=${utils.escapeSystemdExecArg cfg.audioSink} ") +
|
||||
optionalString (cfg.friendlyName != null) ("--friendly-name=${utils.escapeSystemdExecArg cfg.friendlyName} ") +
|
||||
optionalString (cfg.initialVolume != 0) ("--initial-volume=${toString cfg.initialVolume} ") +
|
||||
optionalString (cfg.port != null) ("--port=${toString cfg.port} ") +
|
||||
optionalString (cfg.uuid != null) ("--uuid=${utils.escapeSystemdExecArg cfg.uuid} ");
|
||||
lib.optionalString (cfg.audioDevice != null) ("--gstout-audiodevice=${utils.escapeSystemdExecArg cfg.audioDevice} ") +
|
||||
lib.optionalString (cfg.audioSink != null) ("--gstout-audiosink=${utils.escapeSystemdExecArg cfg.audioSink} ") +
|
||||
lib.optionalString (cfg.friendlyName != null) ("--friendly-name=${utils.escapeSystemdExecArg cfg.friendlyName} ") +
|
||||
lib.optionalString (cfg.initialVolume != 0) ("--initial-volume=${toString cfg.initialVolume} ") +
|
||||
lib.optionalString (cfg.port != null) ("--port=${toString cfg.port} ") +
|
||||
lib.optionalString (cfg.uuid != null) ("--uuid=${utils.escapeSystemdExecArg cfg.uuid} ");
|
||||
Restart = "always";
|
||||
RuntimeDirectory = "gmediarender";
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.gonic;
|
||||
settingsFormat = pkgs.formats.keyValue {
|
||||
@ -13,11 +10,11 @@ in
|
||||
options = {
|
||||
services.gonic = {
|
||||
|
||||
enable = mkEnableOption "Gonic music server";
|
||||
enable = lib.mkEnableOption "Gonic music server";
|
||||
|
||||
settings = mkOption rec {
|
||||
settings = lib.mkOption rec {
|
||||
type = settingsFormat.type;
|
||||
apply = recursiveUpdate default;
|
||||
apply = lib.recursiveUpdate default;
|
||||
default = {
|
||||
listen-addr = "127.0.0.1:4747";
|
||||
cache-path = "/var/cache/gonic";
|
||||
@ -36,7 +33,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.gonic = {
|
||||
description = "Gonic Media Server";
|
||||
after = [ "network.target" ];
|
||||
@ -45,7 +42,7 @@ in
|
||||
ExecStart =
|
||||
let
|
||||
# these values are null by default but should not appear in the final config
|
||||
filteredSettings = filterAttrs (n: v: !((n == "tls-cert" || n == "tls-key") && v == null)) cfg.settings;
|
||||
filteredSettings = lib.filterAttrs (n: v: !((n == "tls-cert" || n == "tls-key") && v == null)) cfg.settings;
|
||||
in
|
||||
"${pkgs.gonic}/bin/gonic -config-path ${settingsFormat.generate "gonic" filteredSettings}";
|
||||
DynamicUser = true;
|
||||
@ -89,5 +86,5 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = [ maintainers.autrimpo ];
|
||||
meta.maintainers = [ lib.maintainers.autrimpo ];
|
||||
}
|
||||
|
@ -1,25 +1,22 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.goxlr-utility;
|
||||
in
|
||||
|
||||
with lib;
|
||||
{
|
||||
|
||||
options = {
|
||||
services.goxlr-utility = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Whether to enable goxlr-utility for controlling your TC-Helicon GoXLR or GoXLR Mini
|
||||
'';
|
||||
};
|
||||
package = mkPackageOption pkgs "goxlr-utility" { };
|
||||
autoStart.xdg = mkOption {
|
||||
package = lib.mkPackageOption pkgs "goxlr-utility" { };
|
||||
autoStart.xdg = lib.mkOption {
|
||||
default = true;
|
||||
type = with types; bool;
|
||||
type = with lib.types; bool;
|
||||
description = ''
|
||||
Start the daemon automatically using XDG autostart.
|
||||
Sets `xdg.autostart.enable = true` if not already enabled.
|
||||
@ -44,16 +41,16 @@ with lib;
|
||||
'';
|
||||
};
|
||||
in
|
||||
mkIf config.services.goxlr-utility.enable {
|
||||
lib.mkIf config.services.goxlr-utility.enable {
|
||||
services.udev.packages = [ cfg.package ];
|
||||
|
||||
xdg.autostart.enable = mkIf cfg.autoStart.xdg true;
|
||||
environment.systemPackages = mkIf cfg.autoStart.xdg
|
||||
xdg.autostart.enable = lib.mkIf cfg.autoStart.xdg true;
|
||||
environment.systemPackages = lib.mkIf cfg.autoStart.xdg
|
||||
[
|
||||
cfg.package
|
||||
goxlr-autostart
|
||||
];
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ errnoh ];
|
||||
meta.maintainers = with lib.maintainers; [ errnoh ];
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.hqplayerd;
|
||||
pkg = pkgs.hqplayerd;
|
||||
@ -12,11 +9,11 @@ in
|
||||
{
|
||||
options = {
|
||||
services.hqplayerd = {
|
||||
enable = mkEnableOption "HQPlayer Embedded";
|
||||
enable = lib.mkEnableOption "HQPlayer Embedded";
|
||||
|
||||
auth = {
|
||||
username = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
username = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Username used for HQPlayer's WebUI.
|
||||
@ -26,8 +23,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
password = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Password used for HQPlayer's WebUI.
|
||||
@ -38,8 +35,8 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
licenseFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
licenseFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path to the HQPlayer license key file.
|
||||
@ -49,16 +46,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Opens ports needed for the WebUI and controller API.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
config = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.lines;
|
||||
default = null;
|
||||
description = ''
|
||||
HQplayer daemon configuration, written to /etc/hqplayer/hqplayerd.xml.
|
||||
@ -69,7 +66,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = (cfg.auth.username != null -> cfg.auth.password != null)
|
||||
@ -80,13 +77,13 @@ in
|
||||
|
||||
environment = {
|
||||
etc = {
|
||||
"hqplayer/hqplayerd.xml" = mkIf (cfg.config != null) { source = pkgs.writeText "hqplayerd.xml" cfg.config; };
|
||||
"hqplayer/hqplayerd4-key.xml" = mkIf (cfg.licenseFile != null) { source = cfg.licenseFile; };
|
||||
"hqplayer/hqplayerd.xml" = lib.mkIf (cfg.config != null) { source = pkgs.writeText "hqplayerd.xml" cfg.config; };
|
||||
"hqplayer/hqplayerd4-key.xml" = lib.mkIf (cfg.licenseFile != null) { source = cfg.licenseFile; };
|
||||
};
|
||||
systemPackages = [ pkg ];
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 8088 4321 ];
|
||||
};
|
||||
|
||||
@ -107,7 +104,7 @@ in
|
||||
|
||||
unitConfig.ConditionPathExists = [ configDir stateDir ];
|
||||
|
||||
restartTriggers = optionals (cfg.config != null) [ config.environment.etc."hqplayer/hqplayerd.xml".source ];
|
||||
restartTriggers = lib.optionals (cfg.config != null) [ config.environment.etc."hqplayer/hqplayerd.xml".source ];
|
||||
|
||||
preStart = ''
|
||||
cp -r "${pkg}/var/lib/hqplayer/web" "${stateDir}"
|
||||
@ -117,7 +114,7 @@ in
|
||||
echo "creating initial config file"
|
||||
install -m 0644 "${pkg}/etc/hqplayer/hqplayerd.xml" "${configDir}/hqplayerd.xml"
|
||||
fi
|
||||
'' + optionalString (cfg.auth.username != null && cfg.auth.password != null) ''
|
||||
'' + lib.optionalString (cfg.auth.username != null && cfg.auth.password != null) ''
|
||||
${pkg}/bin/hqplayerd -s ${cfg.auth.username} ${cfg.auth.password}
|
||||
'';
|
||||
};
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.icecast;
|
||||
configFile = pkgs.writeText "icecast.xml" ''
|
||||
@ -44,62 +41,62 @@ in {
|
||||
|
||||
services.icecast = {
|
||||
|
||||
enable = mkEnableOption "Icecast server";
|
||||
enable = lib.mkEnableOption "Icecast server";
|
||||
|
||||
hostname = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
hostname = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = "DNS name or IP address that will be used for the stream directory lookups or possibly the playlist generation if a Host header is not provided.";
|
||||
default = config.networking.domain;
|
||||
defaultText = literalExpression "config.networking.domain";
|
||||
defaultText = lib.literalExpression "config.networking.domain";
|
||||
};
|
||||
|
||||
admin = {
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Username used for all administration functions.";
|
||||
default = "admin";
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
password = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Password used for all administration functions.";
|
||||
};
|
||||
};
|
||||
|
||||
logDir = mkOption {
|
||||
type = types.path;
|
||||
logDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = "Base directory used for logging.";
|
||||
default = "/var/log/icecast";
|
||||
};
|
||||
|
||||
listen = {
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = "TCP port that will be used to accept client connections.";
|
||||
default = 8000;
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Address Icecast will listen on.";
|
||||
default = "::";
|
||||
};
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "User privileges for the server.";
|
||||
default = "nobody";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Group privileges for the server.";
|
||||
default = "nogroup";
|
||||
};
|
||||
|
||||
extraConf = mkOption {
|
||||
type = types.lines;
|
||||
extraConf = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
description = "icecast.xml content.";
|
||||
default = "";
|
||||
};
|
||||
@ -111,7 +108,7 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
systemd.services.icecast = {
|
||||
after = [ "network.target" ];
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.jack;
|
||||
|
||||
@ -10,29 +7,29 @@ let
|
||||
|
||||
enable32BitAlsaPlugins = cfg.alsa.support32Bit && pkgs.stdenv.hostPlatform.isx86_64 && pkgs.pkgsi686Linux.alsa-lib != null;
|
||||
|
||||
umaskNeeded = versionOlder cfg.jackd.package.version "1.9.12";
|
||||
bridgeNeeded = versionAtLeast cfg.jackd.package.version "1.9.12";
|
||||
umaskNeeded = lib.versionOlder cfg.jackd.package.version "1.9.12";
|
||||
bridgeNeeded = lib.versionAtLeast cfg.jackd.package.version "1.9.12";
|
||||
in {
|
||||
options = {
|
||||
services.jack = {
|
||||
jackd = {
|
||||
enable = mkEnableOption ''
|
||||
enable = lib.mkEnableOption ''
|
||||
JACK Audio Connection Kit. You need to add yourself to the "jackaudio" group
|
||||
'';
|
||||
|
||||
package = mkPackageOption pkgs "jack2" {
|
||||
package = lib.mkPackageOption pkgs "jack2" {
|
||||
example = "jack1";
|
||||
} // {
|
||||
# until jack1 promiscuous mode is fixed
|
||||
internal = true;
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
extraOptions = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [
|
||||
"-dalsa"
|
||||
];
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
[ "-dalsa" "--device" "hw:1" ];
|
||||
'';
|
||||
description = ''
|
||||
@ -40,8 +37,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
session = mkOption {
|
||||
type = types.lines;
|
||||
session = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
description = ''
|
||||
Commands to run after JACK is started.
|
||||
'';
|
||||
@ -50,16 +47,16 @@ in {
|
||||
};
|
||||
|
||||
alsa = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Route audio to/from generic ALSA-using applications using ALSA JACK PCM plugin.
|
||||
'';
|
||||
};
|
||||
|
||||
support32Bit = mkOption {
|
||||
type = types.bool;
|
||||
support32Bit = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to support sound for 32-bit ALSA applications on 64-bit system.
|
||||
@ -68,8 +65,8 @@ in {
|
||||
};
|
||||
|
||||
loopback = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Create ALSA loopback device, instead of using PCM plugin. Has broader
|
||||
@ -78,23 +75,23 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
index = mkOption {
|
||||
type = types.int;
|
||||
index = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10;
|
||||
description = ''
|
||||
Index of an ALSA loopback device.
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.lines;
|
||||
config = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
description = ''
|
||||
ALSA config for loopback device.
|
||||
'';
|
||||
};
|
||||
|
||||
dmixConfig = mkOption {
|
||||
type = types.lines;
|
||||
dmixConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
example = ''
|
||||
period_size 2048
|
||||
@ -107,8 +104,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
session = mkOption {
|
||||
type = types.lines;
|
||||
session = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
description = ''
|
||||
Additional commands to run to setup loopback device.
|
||||
'';
|
||||
@ -119,9 +116,9 @@ in {
|
||||
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
config = lib.mkMerge [
|
||||
|
||||
(mkIf pcmPlugin {
|
||||
(lib.mkIf pcmPlugin {
|
||||
environment.etc."alsa/conf.d/98-jack.conf".text = ''
|
||||
pcm_type.jack {
|
||||
libs.native = ${pkgs.alsa-plugins}/lib/alsa-lib/libasound_module_pcm_jack.so ;
|
||||
@ -136,13 +133,13 @@ in {
|
||||
'';
|
||||
})
|
||||
|
||||
(mkIf loopback {
|
||||
(lib.mkIf loopback {
|
||||
boot.kernelModules = [ "snd-aloop" ];
|
||||
boot.kernelParams = [ "snd-aloop.index=${toString cfg.loopback.index}" ];
|
||||
environment.etc."alsa/conf.d/99-jack-loopback.conf".text = cfg.loopback.config;
|
||||
})
|
||||
|
||||
(mkIf cfg.jackd.enable {
|
||||
(lib.mkIf cfg.jackd.enable {
|
||||
services.jack.jackd.session = ''
|
||||
${lib.optionalString bridgeNeeded "${pkgs.a2jmidid}/bin/a2jmidid -e &"}
|
||||
'';
|
||||
@ -247,7 +244,7 @@ in {
|
||||
ExecStart = "${cfg.jackd.package}/bin/jackd ${lib.escapeShellArgs cfg.jackd.extraOptions}";
|
||||
LimitRTPRIO = 99;
|
||||
LimitMEMLOCK = "infinity";
|
||||
} // optionalAttrs umaskNeeded {
|
||||
} // lib.optionalAttrs umaskNeeded {
|
||||
UMask = "007";
|
||||
};
|
||||
path = [ cfg.jackd.package ];
|
||||
|
@ -1,18 +1,16 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.jmusicbot;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.jmusicbot = {
|
||||
enable = mkEnableOption "jmusicbot, a Discord music bot that's easy to set up and run yourself";
|
||||
enable = lib.mkEnableOption "jmusicbot, a Discord music bot that's easy to set up and run yourself";
|
||||
|
||||
package = mkPackageOption pkgs "jmusicbot" { };
|
||||
package = lib.mkPackageOption pkgs "jmusicbot" { };
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.path;
|
||||
stateDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
The directory where config.txt and serversettings.json is saved.
|
||||
If left as the default value this directory will automatically be created before JMusicBot starts, otherwise the sysadmin is responsible for ensuring the directory exists with appropriate ownership and permissions.
|
||||
@ -23,20 +21,20 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.jmusicbot = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
description = "Discord music bot that's easy to set up and run yourself!";
|
||||
serviceConfig = mkMerge [{
|
||||
serviceConfig = lib.mkMerge [{
|
||||
ExecStart = "${cfg.package}/bin/JMusicBot";
|
||||
WorkingDirectory = cfg.stateDir;
|
||||
Restart = "always";
|
||||
RestartSec = 20;
|
||||
DynamicUser = true;
|
||||
}
|
||||
(mkIf (cfg.stateDir == "/var/lib/jmusicbot") { StateDirectory = "jmusicbot"; })];
|
||||
(lib.mkIf (cfg.stateDir == "/var/lib/jmusicbot") { StateDirectory = "jmusicbot"; })];
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
streams = builtins.attrNames config.services.liquidsoap.streams;
|
||||
|
||||
@ -29,7 +26,7 @@ in
|
||||
|
||||
options = {
|
||||
|
||||
services.liquidsoap.streams = mkOption {
|
||||
services.liquidsoap.streams = lib.mkOption {
|
||||
|
||||
description = ''
|
||||
Set of Liquidsoap streams to start,
|
||||
@ -38,7 +35,7 @@ in
|
||||
|
||||
default = {};
|
||||
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
myStream1 = "/etc/liquidsoap/myStream1.liq";
|
||||
myStream2 = ./myStream2.liq;
|
||||
@ -46,13 +43,13 @@ in
|
||||
}
|
||||
'';
|
||||
|
||||
type = types.attrsOf (types.either types.path types.str);
|
||||
type = lib.types.attrsOf (lib.types.either lib.types.path lib.types.str);
|
||||
};
|
||||
|
||||
};
|
||||
##### implementation
|
||||
|
||||
config = mkIf (builtins.length streams != 0) {
|
||||
config = lib.mkIf (builtins.length streams != 0) {
|
||||
|
||||
users.users.liquidsoap = {
|
||||
uid = config.ids.uids.liquidsoap;
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.mpdscribble;
|
||||
mpdCfg = config.services.mpd;
|
||||
@ -22,7 +19,7 @@ let
|
||||
journal = /var/lib/mpdscribble/${secname}.journal
|
||||
'';
|
||||
|
||||
endpoints = concatStringsSep "\n" (mapAttrsToList mkSection cfg.endpoints);
|
||||
endpoints = lib.concatStringsSep "\n" (lib.mapAttrsToList mkSection cfg.endpoints);
|
||||
cfgTemplate = pkgs.writeText "mpdscribble.conf" ''
|
||||
## This file was automatically genenrated by NixOS and will be overwritten.
|
||||
## Do not edit. Edit your NixOS configuration instead.
|
||||
@ -31,7 +28,7 @@ let
|
||||
## http://mpd.wikia.com/wiki/Client:mpdscribble
|
||||
|
||||
# HTTP proxy URL.
|
||||
${optionalString (cfg.proxy != null) "proxy = ${cfg.proxy}"}
|
||||
${lib.optionalString (cfg.proxy != null) "proxy = ${cfg.proxy}"}
|
||||
|
||||
# The location of the mpdscribble log file. The special value
|
||||
# "syslog" makes mpdscribble use the local syslog daemon. On most
|
||||
@ -47,7 +44,7 @@ let
|
||||
|
||||
# The host running MPD, possibly protected by a password
|
||||
# ([PASSWORD@]HOSTNAME).
|
||||
host = ${(optionalString (cfg.passwordFile != null) "{{MPD_PASSWORD}}@") + cfg.host}
|
||||
host = ${(lib.optionalString (cfg.passwordFile != null) "{{MPD_PASSWORD}}@") + cfg.host}
|
||||
|
||||
# The port that the MPD listens on and mpdscribble should try to
|
||||
# connect to.
|
||||
@ -59,13 +56,13 @@ let
|
||||
cfgFile = "/run/mpdscribble/mpdscribble.conf";
|
||||
|
||||
replaceSecret = secretFile: placeholder: targetFile:
|
||||
optionalString (secretFile != null) ''
|
||||
lib.optionalString (secretFile != null) ''
|
||||
${pkgs.replace-secret}/bin/replace-secret '${placeholder}' '${secretFile}' '${targetFile}' '';
|
||||
|
||||
preStart = pkgs.writeShellScript "mpdscribble-pre-start" ''
|
||||
cp -f "${cfgTemplate}" "${cfgFile}"
|
||||
${replaceSecret cfg.passwordFile "{{MPD_PASSWORD}}" cfgFile}
|
||||
${concatStringsSep "\n" (mapAttrsToList (secname: cfg:
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList (secname: cfg:
|
||||
replaceSecret cfg.passwordFile "{{${secname}_PASSWORD}}" cfgFile)
|
||||
cfg.endpoints)}
|
||||
'';
|
||||
@ -77,62 +74,62 @@ in {
|
||||
|
||||
options.services.mpdscribble = {
|
||||
|
||||
enable = mkEnableOption "mpdscribble, an MPD client which submits info about tracks being played to Last.fm (formerly AudioScrobbler)";
|
||||
enable = lib.mkEnableOption "mpdscribble, an MPD client which submits info about tracks being played to Last.fm (formerly AudioScrobbler)";
|
||||
|
||||
proxy = mkOption {
|
||||
proxy = lib.mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.str;
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
HTTP proxy URL.
|
||||
'';
|
||||
};
|
||||
|
||||
verbose = mkOption {
|
||||
verbose = lib.mkOption {
|
||||
default = 1;
|
||||
type = types.int;
|
||||
type = lib.types.int;
|
||||
description = ''
|
||||
Log level for the mpdscribble daemon.
|
||||
'';
|
||||
};
|
||||
|
||||
journalInterval = mkOption {
|
||||
journalInterval = lib.mkOption {
|
||||
default = 600;
|
||||
example = 60;
|
||||
type = types.int;
|
||||
type = lib.types.int;
|
||||
description = ''
|
||||
How often should mpdscribble save the journal file? [seconds]
|
||||
'';
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
host = lib.mkOption {
|
||||
default = (if mpdCfg.network.listenAddress != "any" then
|
||||
mpdCfg.network.listenAddress
|
||||
else
|
||||
"localhost");
|
||||
defaultText = literalExpression ''
|
||||
defaultText = lib.literalExpression ''
|
||||
if config.${mpdOpt.network.listenAddress} != "any"
|
||||
then config.${mpdOpt.network.listenAddress}
|
||||
else "localhost"
|
||||
'';
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Host for the mpdscribble daemon to search for a mpd daemon on.
|
||||
'';
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
passwordFile = lib.mkOption {
|
||||
default = if localMpd then
|
||||
(findFirst
|
||||
(c: any (x: x == "read") c.permissions)
|
||||
(lib.findFirst
|
||||
(c: lib.any (x: x == "read") c.permissions)
|
||||
{ passwordFile = null; }
|
||||
mpdCfg.credentials).passwordFile
|
||||
else
|
||||
null;
|
||||
defaultText = literalMD ''
|
||||
defaultText = lib.literalMD ''
|
||||
The first password file with read access configured for MPD when using a local instance,
|
||||
otherwise `null`.
|
||||
'';
|
||||
type = types.nullOr types.str;
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
File containing the password for the mpd daemon.
|
||||
If there is a local mpd configured using {option}`services.mpd.credentials`
|
||||
@ -140,37 +137,37 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
port = lib.mkOption {
|
||||
default = mpdCfg.network.port;
|
||||
defaultText = literalExpression "config.${mpdOpt.network.port}";
|
||||
type = types.port;
|
||||
defaultText = lib.literalExpression "config.${mpdOpt.network.port}";
|
||||
type = lib.types.port;
|
||||
description = ''
|
||||
Port for the mpdscribble daemon to search for a mpd daemon on.
|
||||
'';
|
||||
};
|
||||
|
||||
endpoints = mkOption {
|
||||
endpoints = lib.mkOption {
|
||||
type = (let
|
||||
endpoint = { name, ... }: {
|
||||
options = {
|
||||
url = mkOption {
|
||||
type = types.str;
|
||||
url = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = endpointUrls.${name} or "";
|
||||
description = "The url endpoint where the scrobble API is listening.";
|
||||
};
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
username = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Username for the scrobble service.
|
||||
'';
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = "File containing the password, either as MD5SUM or cleartext.";
|
||||
};
|
||||
};
|
||||
};
|
||||
in types.attrsOf (types.submodule endpoint));
|
||||
in lib.types.attrsOf (lib.types.submodule endpoint));
|
||||
default = { };
|
||||
example = {
|
||||
"last.fm" = {
|
||||
@ -181,7 +178,7 @@ in {
|
||||
description = ''
|
||||
Endpoints to scrobble to.
|
||||
If the endpoint is one of "${
|
||||
concatStringsSep "\", \"" (attrNames endpointUrls)
|
||||
lib.concatStringsSep "\", \"" (lib.attrNames endpointUrls)
|
||||
}" the url is set automatically.
|
||||
'';
|
||||
};
|
||||
@ -190,9 +187,9 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.mpdscribble = {
|
||||
after = [ "network.target" ] ++ (optional localMpd "mpd.service");
|
||||
after = [ "network.target" ] ++ (lib.optional localMpd "mpd.service");
|
||||
description = "mpdscribble mpd scrobble client";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
|
@ -1,18 +1,15 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
name = "networkaudiod";
|
||||
cfg = config.services.networkaudiod;
|
||||
in {
|
||||
options = {
|
||||
services.networkaudiod = {
|
||||
enable = mkEnableOption "Networkaudiod (NAA)";
|
||||
enable = lib.mkEnableOption "Networkaudiod (NAA)";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.packages = [ pkgs.networkaudiod ];
|
||||
systemd.services.networkaudiod.wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
@ -1,30 +1,27 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
name = "roon-bridge";
|
||||
cfg = config.services.roon-bridge;
|
||||
in {
|
||||
options = {
|
||||
services.roon-bridge = {
|
||||
enable = mkEnableOption "Roon Bridge";
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkEnableOption "Roon Bridge";
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for the bridge.
|
||||
'';
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "roon-bridge";
|
||||
description = ''
|
||||
User to run the Roon bridge as.
|
||||
'';
|
||||
};
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "roon-bridge";
|
||||
description = ''
|
||||
Group to run the Roon Bridge as.
|
||||
@ -33,7 +30,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.roon-bridge = {
|
||||
after = [ "network.target" ];
|
||||
description = "Roon Bridge";
|
||||
@ -50,17 +47,17 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPortRanges = [{ from = 9100; to = 9200; }];
|
||||
allowedUDPPorts = [ 9003 ];
|
||||
extraCommands = optionalString (!config.networking.nftables.enable) ''
|
||||
extraCommands = lib.optionalString (!config.networking.nftables.enable) ''
|
||||
iptables -A INPUT -s 224.0.0.0/4 -j ACCEPT
|
||||
iptables -A INPUT -d 224.0.0.0/4 -j ACCEPT
|
||||
iptables -A INPUT -s 240.0.0.0/5 -j ACCEPT
|
||||
iptables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT
|
||||
iptables -A INPUT -m pkttype --pkt-type broadcast -j ACCEPT
|
||||
'';
|
||||
extraInputRules = optionalString config.networking.nftables.enable ''
|
||||
extraInputRules = lib.optionalString config.networking.nftables.enable ''
|
||||
ip saddr { 224.0.0.0/4, 240.0.0.0/5 } accept
|
||||
ip daddr 224.0.0.0/4 accept
|
||||
pkttype { multicast, broadcast } accept
|
||||
@ -70,7 +67,7 @@ in {
|
||||
|
||||
users.groups.${cfg.group} = {};
|
||||
users.users.${cfg.user} =
|
||||
optionalAttrs (cfg.user == "roon-bridge") {
|
||||
lib.optionalAttrs (cfg.user == "roon-bridge") {
|
||||
isSystemUser = true;
|
||||
description = "Roon Bridge user";
|
||||
group = cfg.group;
|
||||
|
@ -1,31 +1,28 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
name = "roon-server";
|
||||
cfg = config.services.roon-server;
|
||||
in {
|
||||
options = {
|
||||
services.roon-server = {
|
||||
enable = mkEnableOption "Roon Server";
|
||||
enable = lib.mkEnableOption "Roon Server";
|
||||
package = lib.mkPackageOption pkgs "roon-server" { };
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for the server.
|
||||
'';
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "roon-server";
|
||||
description = ''
|
||||
User to run the Roon Server as.
|
||||
'';
|
||||
};
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "roon-server";
|
||||
description = ''
|
||||
Group to run the Roon Server as.
|
||||
@ -34,7 +31,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.roon-server = {
|
||||
after = [ "network.target" ];
|
||||
description = "Roon Server";
|
||||
@ -52,14 +49,14 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPortRanges = [
|
||||
{ from = 9100; to = 9200; }
|
||||
{ from = 9330; to = 9339; }
|
||||
{ from = 30000; to = 30010; }
|
||||
];
|
||||
allowedUDPPorts = [ 9003 ];
|
||||
extraCommands = optionalString (!config.networking.nftables.enable) ''
|
||||
extraCommands = lib.optionalString (!config.networking.nftables.enable) ''
|
||||
## IGMP / Broadcast ##
|
||||
iptables -A INPUT -s 224.0.0.0/4 -j ACCEPT
|
||||
iptables -A INPUT -d 224.0.0.0/4 -j ACCEPT
|
||||
@ -67,7 +64,7 @@ in {
|
||||
iptables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT
|
||||
iptables -A INPUT -m pkttype --pkt-type broadcast -j ACCEPT
|
||||
'';
|
||||
extraInputRules = optionalString config.networking.nftables.enable ''
|
||||
extraInputRules = lib.optionalString config.networking.nftables.enable ''
|
||||
ip saddr { 224.0.0.0/4, 240.0.0.0/5 } accept
|
||||
ip daddr 224.0.0.0/4 accept
|
||||
pkttype { multicast, broadcast } accept
|
||||
@ -77,7 +74,7 @@ in {
|
||||
|
||||
users.groups.${cfg.group} = {};
|
||||
users.users.${cfg.user} =
|
||||
optionalAttrs (cfg.user == "roon-server") {
|
||||
lib.optionalAttrs (cfg.user == "roon-server") {
|
||||
isSystemUser = true;
|
||||
description = "Roon Server user";
|
||||
group = cfg.group;
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.slimserver;
|
||||
@ -11,18 +8,18 @@ in {
|
||||
|
||||
services.slimserver = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable slimserver.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "slimserver" { };
|
||||
package = lib.mkPackageOption pkgs "slimserver" { };
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/slimserver";
|
||||
description = ''
|
||||
The directory where slimserver stores its state, tag cache,
|
||||
@ -35,7 +32,7 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '${cfg.dataDir}' - slimserver slimserver - -"
|
||||
|
@ -1,14 +1,11 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.spotifyd;
|
||||
toml = pkgs.formats.toml {};
|
||||
warnConfig =
|
||||
if cfg.config != ""
|
||||
then lib.trace "Using the stringly typed .config attribute is discouraged. Use the TOML typed .settings attribute instead."
|
||||
else id;
|
||||
else lib.id;
|
||||
spotifydConf =
|
||||
if cfg.settings != {}
|
||||
then toml.generate "spotify.conf" cfg.settings
|
||||
@ -17,18 +14,18 @@ in
|
||||
{
|
||||
options = {
|
||||
services.spotifyd = {
|
||||
enable = mkEnableOption "spotifyd, a Spotify playing daemon";
|
||||
enable = lib.mkEnableOption "spotifyd, a Spotify playing daemon";
|
||||
|
||||
config = mkOption {
|
||||
config = lib.mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
type = lib.types.lines;
|
||||
description = ''
|
||||
(Deprecated) Configuration for Spotifyd. For syntax and directives, see
|
||||
<https://docs.spotifyd.rs/config/File.html>.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
default = {};
|
||||
type = toml.type;
|
||||
example = { global.bitrate = 320; };
|
||||
@ -40,7 +37,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.config == "" || cfg.settings == {};
|
||||
@ -65,5 +62,5 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = [ maintainers.anderslundstedt ];
|
||||
meta.maintainers = [ lib.maintainers.anderslundstedt ];
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.ympd;
|
||||
in {
|
||||
@ -12,26 +9,26 @@ in {
|
||||
|
||||
services.ympd = {
|
||||
|
||||
enable = mkEnableOption "ympd, the MPD Web GUI";
|
||||
enable = lib.mkEnableOption "ympd, the MPD Web GUI";
|
||||
|
||||
webPort = mkOption {
|
||||
type = types.either types.str types.port; # string for backwards compat
|
||||
webPort = lib.mkOption {
|
||||
type = lib.types.either lib.types.str lib.types.port; # string for backwards compat
|
||||
default = "8080";
|
||||
description = "The port where ympd's web interface will be available.";
|
||||
example = "ssl://8080:/path/to/ssl-private-key.pem";
|
||||
};
|
||||
|
||||
mpd = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = "The host where MPD is listening.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = config.services.mpd.network.port;
|
||||
defaultText = literalExpression "config.services.mpd.network.port";
|
||||
defaultText = lib.literalExpression "config.services.mpd.network.port";
|
||||
description = "The port where MPD is listening.";
|
||||
example = 6600;
|
||||
};
|
||||
@ -44,7 +41,7 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
systemd.services.ympd = {
|
||||
description = "Standalone MPD Web GUI written in C";
|
||||
|
@ -1,20 +1,17 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.borgmatic;
|
||||
settingsFormat = pkgs.formats.yaml { };
|
||||
|
||||
repository = with types; submodule {
|
||||
repository = with lib.types; submodule {
|
||||
options = {
|
||||
path = mkOption {
|
||||
path = lib.mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
Path to the repository
|
||||
'';
|
||||
};
|
||||
label = mkOption {
|
||||
label = lib.mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
Label to the repository
|
||||
@ -22,10 +19,10 @@ let
|
||||
};
|
||||
};
|
||||
};
|
||||
cfgType = with types; submodule {
|
||||
cfgType = with lib.types; submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
source_directories = mkOption {
|
||||
source_directories = lib.mkOption {
|
||||
type = listOf str;
|
||||
default = [];
|
||||
description = ''
|
||||
@ -34,7 +31,7 @@ let
|
||||
'';
|
||||
example = [ "/home" "/etc" "/var/log/syslog*" "/home/user/path with spaces" ];
|
||||
};
|
||||
repositories = mkOption {
|
||||
repositories = lib.mkOption {
|
||||
type = listOf repository;
|
||||
default = [];
|
||||
description = ''
|
||||
@ -59,33 +56,33 @@ let
|
||||
in
|
||||
{
|
||||
options.services.borgmatic = {
|
||||
enable = mkEnableOption "borgmatic";
|
||||
enable = lib.mkEnableOption "borgmatic";
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
See https://torsion.org/borgmatic/docs/reference/configuration/
|
||||
'';
|
||||
default = null;
|
||||
type = types.nullOr cfgType;
|
||||
type = lib.types.nullOr cfgType;
|
||||
};
|
||||
|
||||
configurations = mkOption {
|
||||
configurations = lib.mkOption {
|
||||
description = ''
|
||||
Set of borgmatic configurations, see https://torsion.org/borgmatic/docs/reference/configuration/
|
||||
'';
|
||||
default = { };
|
||||
type = types.attrsOf cfgType;
|
||||
type = lib.types.attrsOf cfgType;
|
||||
};
|
||||
|
||||
enableConfigCheck = mkEnableOption "checking all configurations during build time" // { default = true; };
|
||||
enableConfigCheck = lib.mkEnableOption "checking all configurations during build time" // { default = true; };
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
configFiles =
|
||||
(optionalAttrs (cfg.settings != null) { "borgmatic/config.yaml".source = cfgfile; }) //
|
||||
mapAttrs'
|
||||
(name: value: nameValuePair
|
||||
(lib.optionalAttrs (cfg.settings != null) { "borgmatic/config.yaml".source = cfgfile; }) //
|
||||
lib.mapAttrs'
|
||||
(name: value: lib.nameValuePair
|
||||
"borgmatic.d/${name}.yaml"
|
||||
{ source = settingsFormat.generate "${name}.yaml" value; })
|
||||
cfg.configurations;
|
||||
@ -94,12 +91,12 @@ in
|
||||
touch $out
|
||||
'';
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
lib.mkIf cfg.enable {
|
||||
|
||||
warnings = []
|
||||
++ optional (cfg.settings != null && cfg.settings ? location)
|
||||
++ lib.optional (cfg.settings != null && cfg.settings ? location)
|
||||
"`services.borgmatic.settings.location` is deprecated, please move your options out of sections to the global scope"
|
||||
++ optional (catAttrs "location" (attrValues cfg.configurations) != [])
|
||||
++ lib.optional (lib.catAttrs "location" (lib.attrValues cfg.configurations) != [])
|
||||
"`services.borgmatic.configurations.<name>.location` is deprecated, please move your options out of sections to the global scope"
|
||||
;
|
||||
|
||||
@ -112,6 +109,6 @@ in
|
||||
# Workaround: https://github.com/NixOS/nixpkgs/issues/81138
|
||||
systemd.timers.borgmatic.wantedBy = [ "timers.target" ];
|
||||
|
||||
system.checks = mkIf cfg.enableConfigCheck (mapAttrsToList borgmaticCheck configFiles);
|
||||
system.checks = lib.mkIf cfg.enableConfigCheck (lib.mapAttrsToList borgmaticCheck configFiles);
|
||||
};
|
||||
}
|
||||
|
@ -1,27 +1,24 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.duplicati;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.duplicati = {
|
||||
enable = mkEnableOption "Duplicati";
|
||||
enable = lib.mkEnableOption "Duplicati";
|
||||
|
||||
package = mkPackageOption pkgs "duplicati" { };
|
||||
package = lib.mkPackageOption pkgs "duplicati" { };
|
||||
|
||||
port = mkOption {
|
||||
port = lib.mkOption {
|
||||
default = 8200;
|
||||
type = types.port;
|
||||
type = lib.types.port;
|
||||
description = ''
|
||||
Port serving the web interface
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/duplicati";
|
||||
description = ''
|
||||
The directory where Duplicati stores its data files.
|
||||
@ -34,18 +31,18 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
interface = mkOption {
|
||||
interface = lib.mkOption {
|
||||
default = "127.0.0.1";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Listening interface for the web UI
|
||||
Set it to "any" to listen on all available interfaces
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
user = lib.mkOption {
|
||||
default = "duplicati";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Duplicati runs as it's own user. It will only be able to backup world-readable files.
|
||||
Run as root with special care.
|
||||
@ -54,21 +51,21 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
systemd.services.duplicati = {
|
||||
description = "Duplicati backup";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = mkMerge [
|
||||
serviceConfig = lib.mkMerge [
|
||||
{
|
||||
User = cfg.user;
|
||||
Group = "duplicati";
|
||||
ExecStart = "${cfg.package}/bin/duplicati-server --webservice-interface=${cfg.interface} --webservice-port=${toString cfg.port} --server-datafolder=${cfg.dataDir}";
|
||||
Restart = "on-failure";
|
||||
}
|
||||
(mkIf (cfg.dataDir == "/var/lib/duplicati") {
|
||||
(lib.mkIf (cfg.dataDir == "/var/lib/duplicati") {
|
||||
StateDirectory = "duplicati";
|
||||
})
|
||||
];
|
||||
|
@ -1,30 +1,28 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.duplicity;
|
||||
|
||||
stateDirectory = "/var/lib/duplicity";
|
||||
|
||||
localTarget =
|
||||
if hasPrefix "file://" cfg.targetUrl
|
||||
then removePrefix "file://" cfg.targetUrl else null;
|
||||
if lib.hasPrefix "file://" cfg.targetUrl
|
||||
then lib.removePrefix "file://" cfg.targetUrl else null;
|
||||
|
||||
in
|
||||
{
|
||||
options.services.duplicity = {
|
||||
enable = mkEnableOption "backups with duplicity";
|
||||
enable = lib.mkEnableOption "backups with duplicity";
|
||||
|
||||
root = mkOption {
|
||||
type = types.path;
|
||||
root = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/";
|
||||
description = ''
|
||||
Root directory to backup.
|
||||
'';
|
||||
};
|
||||
|
||||
include = mkOption {
|
||||
type = types.listOf types.str;
|
||||
include = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "/home" ];
|
||||
description = ''
|
||||
@ -33,8 +31,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
exclude = mkOption {
|
||||
type = types.listOf types.str;
|
||||
exclude = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of paths to exclude from backups. See the FILE SELECTION section in
|
||||
@ -42,8 +40,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
includeFileList = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
includeFileList = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
example = /path/to/fileList.txt;
|
||||
description = ''
|
||||
@ -53,8 +51,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
excludeFileList = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
excludeFileList = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
example = /path/to/fileList.txt;
|
||||
description = ''
|
||||
@ -64,8 +62,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
targetUrl = mkOption {
|
||||
type = types.str;
|
||||
targetUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "s3://host:port/prefix";
|
||||
description = ''
|
||||
Target url to backup to. See the URL FORMAT section in
|
||||
@ -73,8 +71,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
secretFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
secretFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Path of a file containing secrets (gpg passphrase, access key...) in
|
||||
@ -88,8 +86,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
frequency = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
frequency = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "daily";
|
||||
description = ''
|
||||
Run duplicity with the given frequency (see
|
||||
@ -98,8 +96,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
extraFlags = mkOption {
|
||||
type = types.listOf types.str;
|
||||
extraFlags = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "--backend-retry-delay" "100" ];
|
||||
description = ''
|
||||
@ -108,8 +106,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
fullIfOlderThan = mkOption {
|
||||
type = types.str;
|
||||
fullIfOlderThan = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "never";
|
||||
example = "1M";
|
||||
description = ''
|
||||
@ -123,8 +121,8 @@ in
|
||||
};
|
||||
|
||||
cleanup = {
|
||||
maxAge = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
maxAge = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "6M";
|
||||
description = ''
|
||||
@ -132,8 +130,8 @@ in
|
||||
will not be deleted if backup sets newer than time depend on them.
|
||||
'';
|
||||
};
|
||||
maxFull = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
maxFull = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
example = 2;
|
||||
description = ''
|
||||
@ -142,8 +140,8 @@ in
|
||||
associated incremental sets).
|
||||
'';
|
||||
};
|
||||
maxIncr = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
maxIncr = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
example = 1;
|
||||
description = ''
|
||||
@ -155,7 +153,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd = {
|
||||
services.duplicity = {
|
||||
description = "backup files with duplicity";
|
||||
@ -164,8 +162,8 @@ in
|
||||
|
||||
script =
|
||||
let
|
||||
target = escapeShellArg cfg.targetUrl;
|
||||
extra = escapeShellArgs ([ "--archive-dir" stateDirectory ] ++ cfg.extraFlags);
|
||||
target = lib.escapeShellArg cfg.targetUrl;
|
||||
extra = lib.escapeShellArgs ([ "--archive-dir" stateDirectory ] ++ cfg.extraFlags);
|
||||
dup = "${pkgs.duplicity}/bin/duplicity";
|
||||
in
|
||||
''
|
||||
@ -178,8 +176,8 @@ in
|
||||
[ cfg.root cfg.targetUrl ]
|
||||
++ lib.optionals (cfg.includeFileList != null) [ "--include-filelist" cfg.includeFileList ]
|
||||
++ lib.optionals (cfg.excludeFileList != null) [ "--exclude-filelist" cfg.excludeFileList ]
|
||||
++ concatMap (p: [ "--include" p ]) cfg.include
|
||||
++ concatMap (p: [ "--exclude" p ]) cfg.exclude
|
||||
++ lib.concatMap (p: [ "--include" p ]) cfg.include
|
||||
++ lib.concatMap (p: [ "--exclude" p ]) cfg.exclude
|
||||
++ (lib.optionals (cfg.fullIfOlderThan != "never" && cfg.fullIfOlderThan != "always") [ "--full-if-older-than" cfg.fullIfOlderThan ])
|
||||
)} ${extra}
|
||||
'';
|
||||
@ -188,19 +186,19 @@ in
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = "read-only";
|
||||
StateDirectory = baseNameOf stateDirectory;
|
||||
} // optionalAttrs (localTarget != null) {
|
||||
} // lib.optionalAttrs (localTarget != null) {
|
||||
ReadWritePaths = localTarget;
|
||||
} // optionalAttrs (cfg.secretFile != null) {
|
||||
} // lib.optionalAttrs (cfg.secretFile != null) {
|
||||
EnvironmentFile = cfg.secretFile;
|
||||
};
|
||||
} // optionalAttrs (cfg.frequency != null) {
|
||||
} // lib.optionalAttrs (cfg.frequency != null) {
|
||||
startAt = cfg.frequency;
|
||||
};
|
||||
|
||||
tmpfiles.rules = optional (localTarget != null) "d ${localTarget} 0700 root root -";
|
||||
tmpfiles.rules = lib.optional (localTarget != null) "d ${localTarget} 0700 root root -";
|
||||
};
|
||||
|
||||
assertions = singleton {
|
||||
assertions = lib.singleton {
|
||||
# Duplicity will fail if the last file selection option is an include. It
|
||||
# is not always possible to detect but this simple case can be caught.
|
||||
assertion = cfg.include != [ ] -> cfg.exclude != [ ] || cfg.extraFlags != [ ];
|
||||
|
@ -314,7 +314,7 @@ in
|
||||
binlog-ignore-db = [ "information_schema" "performance_schema" "mysql" ];
|
||||
})
|
||||
(lib.mkIf (!isMariaDB) {
|
||||
plugin-load-add = "auth_socket.so";
|
||||
plugin-load-add = [ "auth_socket.so" ];
|
||||
})
|
||||
];
|
||||
|
||||
|
@ -263,6 +263,15 @@ in {
|
||||
serve = {
|
||||
enable = lib.mkEnableOption "automatic nginx and uwsgi setup for mailman-web";
|
||||
|
||||
uwsgiSettings = lib.mkOption {
|
||||
default = { };
|
||||
example = { uwsgi.buffer-size = 8192; };
|
||||
inherit (pkgs.formats.json {}) type;
|
||||
description = ''
|
||||
Extra configuration to merge into uwsgi config.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualRoot = lib.mkOption {
|
||||
default = "/";
|
||||
example = lib.literalExpression "/lists";
|
||||
@ -580,18 +589,20 @@ in {
|
||||
};
|
||||
|
||||
mailman-uwsgi = lib.mkIf cfg.serve.enable (let
|
||||
uwsgiConfig.uwsgi = {
|
||||
type = "normal";
|
||||
plugins = ["python3"];
|
||||
home = webEnv;
|
||||
http = "127.0.0.1:18507";
|
||||
}
|
||||
// (if cfg.serve.virtualRoot == "/"
|
||||
then { module = "mailman_web.wsgi:application"; }
|
||||
else {
|
||||
mount = "${cfg.serve.virtualRoot}=mailman_web.wsgi:application";
|
||||
manage-script-name = true;
|
||||
uwsgiConfig = lib.recursiveUpdate {
|
||||
uwsgi = {
|
||||
type = "normal";
|
||||
plugins = ["python3"];
|
||||
home = webEnv;
|
||||
http = "127.0.0.1:18507";
|
||||
}
|
||||
// (if cfg.serve.virtualRoot == "/"
|
||||
then { module = "mailman_web.wsgi:application"; }
|
||||
else {
|
||||
mount = "${cfg.serve.virtualRoot}=mailman_web.wsgi:application";
|
||||
manage-script-name = true;
|
||||
});
|
||||
} cfg.serve.uwsgiSettings;
|
||||
uwsgiConfigFile = pkgs.writeText "uwsgi-mailman.json" (builtins.toJSON uwsgiConfig);
|
||||
in {
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
@ -1348,7 +1348,7 @@ in {
|
||||
ln -sf ${cableYml} ${cfg.statePath}/config/cable.yml
|
||||
ln -sf ${resqueYml} ${cfg.statePath}/config/resque.yml
|
||||
|
||||
${cfg.packages.gitlab-shell}/bin/gitlab-shell-install
|
||||
${cfg.packages.gitlab-shell}/support/make_necessary_dirs
|
||||
|
||||
${optionalString cfg.smtp.enable ''
|
||||
install -m u=rw ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb
|
||||
|
251
nixos/modules/services/misc/omnom.nix
Normal file
251
nixos/modules/services/misc/omnom.nix
Normal file
@ -0,0 +1,251 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.omnom;
|
||||
settingsFormat = pkgs.formats.yaml { };
|
||||
|
||||
configFile = settingsFormat.generate "omnom-config.yml" cfg.settings;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.omnom = {
|
||||
enable = lib.mkEnableOption "Omnom, a webpage bookmarking and snapshotting service";
|
||||
package = lib.mkPackageOption pkgs "omnom" { };
|
||||
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/omnom";
|
||||
description = "The directory where Omnom stores its data files.";
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 7331;
|
||||
description = "The Omnom service port.";
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to open ports in the firewall.";
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.nonEmptyStr;
|
||||
default = "omnom";
|
||||
description = "The Omnom service user.";
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
type = lib.types.nonEmptyStr;
|
||||
default = "omnom";
|
||||
description = "The Omnom service group.";
|
||||
};
|
||||
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = "File containing the password for the SMTP user.";
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
Configuration options for the /etc/omnom/config.yml file.
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
app = {
|
||||
debug = lib.mkEnableOption "debug mode";
|
||||
disable_signup = lib.mkEnableOption "restricting user creation";
|
||||
results_per_page = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 20;
|
||||
description = "Number of results per page.";
|
||||
};
|
||||
};
|
||||
db = {
|
||||
connection = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${cfg.dataDir}/db.sqlite3";
|
||||
description = "Database connection URI.";
|
||||
defaultText = lib.literalExpression ''
|
||||
"''${config.services.omnom.dataDir}/db.sqlite3"
|
||||
'';
|
||||
};
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "sqlite" ];
|
||||
default = "sqlite";
|
||||
description = "Database type.";
|
||||
};
|
||||
};
|
||||
server = {
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1:${toString cfg.port}";
|
||||
description = "Server address.";
|
||||
defaultText = lib.literalExpression ''
|
||||
"127.0.0.1:''${config.services.omnom.port}"
|
||||
'';
|
||||
};
|
||||
secure_cookie = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to limit cookies to a secure channel.";
|
||||
};
|
||||
};
|
||||
storage = {
|
||||
type = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "fs";
|
||||
description = "Storage type.";
|
||||
};
|
||||
root = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "${cfg.dataDir}/static/data";
|
||||
defaultText = lib.literalExpression ''
|
||||
"''${config.services.omnom.dataDir}/static/data"
|
||||
'';
|
||||
description = "Where the snapshots are saved.";
|
||||
};
|
||||
};
|
||||
smtp = {
|
||||
tls = lib.mkEnableOption "Whether TLS encryption should be used.";
|
||||
tls_allow_insecure = lib.mkEnableOption "Whether to allow insecure TLS.";
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "SMTP server hostname.";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 25;
|
||||
description = "SMTP server port address.";
|
||||
};
|
||||
sender = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "Omnom <omnom@127.0.0.1>";
|
||||
description = "Omnom sender e-mail.";
|
||||
};
|
||||
send_timeout = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 10;
|
||||
description = "Send timeout duration in seconds.";
|
||||
};
|
||||
connection_timeout = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 5;
|
||||
description = "Connection timeout duration in seconds.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !lib.hasAttr "password" cfg.settings.smtp;
|
||||
message = ''
|
||||
`services.omnom.settings.smtp.password` must be defined in `services.omnom.passwordFile`.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = !(cfg.settings.storage.root != "${cfg.dataDir}/static/data");
|
||||
message = ''
|
||||
For Omnom to access the snapshots, it needs the storage root
|
||||
directory to be inside the service's working directory.
|
||||
|
||||
As such, `services.omnom.settings.storage.root` must be the same as
|
||||
`''${services.omnom.dataDir}/static/data`.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services.omnom = {
|
||||
path = with pkgs; [
|
||||
yq-go # needed by startup script
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
StateDirectory = "omnom";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
LoadCredential = lib.optional (cfg.passwordFile != null) "PASSWORD_FILE:${cfg.passwordFile}";
|
||||
};
|
||||
script = ''
|
||||
install -m 600 ${configFile} $STATE_DIRECTORY/config.yml
|
||||
|
||||
${lib.optionalString (cfg.passwordFile != null) ''
|
||||
# merge password into main config
|
||||
yq -i '.smtp.password = load(env(CREDENTIALS_DIRECTORY) + "/PASSWORD_FILE")' \
|
||||
"$STATE_DIRECTORY/config.yml"
|
||||
''}
|
||||
|
||||
${lib.getExe cfg.package} listen --config "$STATE_DIRECTORY/config.yml"
|
||||
'';
|
||||
after = [
|
||||
"network.target"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
# TODO: The program needs to run from the dataDir for it the work, which
|
||||
# is difficult to do with a DynamicUser.
|
||||
# After this has been fixed upstream, remove this and use DynamicUser, instead.
|
||||
# See: https://github.com/asciimoo/omnom/issues/21
|
||||
users = {
|
||||
users = lib.mkIf (cfg.user == "omnom") {
|
||||
omnom = {
|
||||
group = cfg.group;
|
||||
home = cfg.dataDir;
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
groups = lib.mkIf (cfg.group == "omnom") { omnom = { }; };
|
||||
};
|
||||
|
||||
systemd.tmpfiles.settings."10-omnom" =
|
||||
let
|
||||
settings = {
|
||||
inherit (cfg) user group;
|
||||
};
|
||||
in
|
||||
{
|
||||
"${cfg.dataDir}"."d" = settings;
|
||||
"${cfg.dataDir}/templates"."L+" = settings // {
|
||||
argument = "${cfg.package}/share/templates";
|
||||
};
|
||||
"${cfg.settings.storage.root}"."d" = settings;
|
||||
};
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
|
||||
environment.systemPackages =
|
||||
let
|
||||
omnom-wrapped = pkgs.writeScriptBin "omnom" ''
|
||||
#! ${pkgs.runtimeShell}
|
||||
cd ${cfg.dataDir}
|
||||
sudo=exec
|
||||
if [[ "$USER" != ${cfg.user} ]]; then
|
||||
sudo='exec /run/wrappers/bin/sudo -u ${cfg.user}'
|
||||
fi
|
||||
$sudo ${lib.getExe cfg.package} "$@"
|
||||
'';
|
||||
in
|
||||
[ omnom-wrapped ];
|
||||
};
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.paperless;
|
||||
|
||||
@ -17,16 +15,16 @@ let
|
||||
PAPERLESS_CONSUMPTION_DIR = cfg.consumptionDir;
|
||||
PAPERLESS_THUMBNAIL_FONT_NAME = defaultFont;
|
||||
GUNICORN_CMD_ARGS = "--bind=${cfg.address}:${toString cfg.port}";
|
||||
} // optionalAttrs (config.time.timeZone != null) {
|
||||
} // lib.optionalAttrs (config.time.timeZone != null) {
|
||||
PAPERLESS_TIME_ZONE = config.time.timeZone;
|
||||
} // optionalAttrs enableRedis {
|
||||
} // lib.optionalAttrs enableRedis {
|
||||
PAPERLESS_REDIS = "unix://${redisServer.unixSocket}";
|
||||
} // optionalAttrs (cfg.settings.PAPERLESS_ENABLE_NLTK or true) {
|
||||
} // lib.optionalAttrs (cfg.settings.PAPERLESS_ENABLE_NLTK or true) {
|
||||
PAPERLESS_NLTK_DIR = pkgs.symlinkJoin {
|
||||
name = "paperless_ngx_nltk_data";
|
||||
paths = cfg.package.nltkData;
|
||||
};
|
||||
} // optionalAttrs (cfg.openMPThreadingWorkaround) {
|
||||
} // lib.optionalAttrs (cfg.openMPThreadingWorkaround) {
|
||||
OMP_NUM_THREADS = "1";
|
||||
} // (lib.mapAttrs (_: s:
|
||||
if (lib.isAttrs s || lib.isList s) then builtins.toJSON s
|
||||
@ -53,7 +51,7 @@ let
|
||||
CapabilityBoundingSet = "";
|
||||
# ProtectClock adds DeviceAllow=char-rtc r
|
||||
DeviceAllow = "";
|
||||
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
@ -80,22 +78,22 @@ let
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SupplementaryGroups = optional enableRedis redisServer.user;
|
||||
SupplementaryGroups = lib.optional enableRedis redisServer.user;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [ "@system-service" "~@privileged @setuid @keyring" ];
|
||||
UMask = "0066";
|
||||
};
|
||||
in
|
||||
{
|
||||
meta.maintainers = with maintainers; [ leona SuperSandro2000 erikarvstedt ];
|
||||
meta.maintainers = with lib.maintainers; [ leona SuperSandro2000 erikarvstedt ];
|
||||
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "paperless-ng" ] [ "services" "paperless" ])
|
||||
(mkRenamedOptionModule [ "services" "paperless" "extraConfig" ] [ "services" "paperless" "settings" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "paperless-ng" ] [ "services" "paperless" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "paperless" "extraConfig" ] [ "services" "paperless" "settings" ])
|
||||
];
|
||||
|
||||
options.services.paperless = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
@ -110,34 +108,34 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/paperless";
|
||||
description = "Directory to store the Paperless data.";
|
||||
};
|
||||
|
||||
mediaDir = mkOption {
|
||||
type = types.str;
|
||||
mediaDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${cfg.dataDir}/media";
|
||||
defaultText = literalExpression ''"''${dataDir}/media"'';
|
||||
defaultText = lib.literalExpression ''"''${dataDir}/media"'';
|
||||
description = "Directory to store the Paperless documents.";
|
||||
};
|
||||
|
||||
consumptionDir = mkOption {
|
||||
type = types.str;
|
||||
consumptionDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${cfg.dataDir}/consume";
|
||||
defaultText = literalExpression ''"''${dataDir}/consume"'';
|
||||
defaultText = lib.literalExpression ''"''${dataDir}/consume"'';
|
||||
description = "Directory from which new documents are imported.";
|
||||
};
|
||||
|
||||
consumptionDirIsPublic = mkOption {
|
||||
type = types.bool;
|
||||
consumptionDirIsPublic = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether all users can write to the consumption dir.";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
example = "/run/keys/paperless-password";
|
||||
description = ''
|
||||
@ -158,19 +156,19 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = "Web interface address.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 28981;
|
||||
description = "Web interface port.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = with lib.types; attrsOf (let
|
||||
typeList = [ bool float int str path package ];
|
||||
@ -196,19 +194,19 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultUser;
|
||||
description = "User under which Paperless runs.";
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "paperless-ngx" { } // {
|
||||
package = lib.mkPackageOption pkgs "paperless-ngx" { } // {
|
||||
apply = pkg: pkg.override {
|
||||
tesseract5 = pkg.tesseract5.override {
|
||||
# always enable detection modules
|
||||
# tesseract fails to build when eng is not present
|
||||
enableLanguages = if cfg.settings ? PAPERLESS_OCR_LANGUAGE then
|
||||
lists.unique (
|
||||
lib.lists.unique (
|
||||
[ "equ" "osd" "eng" ]
|
||||
++ lib.splitString "+" cfg.settings.PAPERLESS_OCR_LANGUAGE
|
||||
)
|
||||
@ -217,7 +215,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
openMPThreadingWorkaround = mkEnableOption ''
|
||||
openMPThreadingWorkaround = lib.mkEnableOption ''
|
||||
a workaround for document classifier timeouts.
|
||||
|
||||
Paperless uses OpenBLAS via scikit-learn for document classification.
|
||||
@ -229,10 +227,10 @@ in
|
||||
|
||||
This sets `OMP_NUM_THREADS` to `1` in order to mitigate the issue. See
|
||||
https://github.com/NixOS/nixpkgs/issues/240591 for more information
|
||||
'' // mkOption { default = true; };
|
||||
'' // lib.mkOption { default = true; };
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr lib.types.path;
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
example = "/run/secrets/paperless";
|
||||
description = ''
|
||||
@ -250,8 +248,8 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.redis.servers.paperless.enable = mkIf enableRedis true;
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.redis.servers.paperless.enable = lib.mkIf enableRedis true;
|
||||
|
||||
systemd.slices.system-paperless = {
|
||||
description = "Paperless Document Management System Slice";
|
||||
@ -308,7 +306,7 @@ in
|
||||
echo ${cfg.package.version} > "$versionFile"
|
||||
fi
|
||||
''
|
||||
+ optionalString (cfg.passwordFile != null) ''
|
||||
+ lib.optionalString (cfg.passwordFile != null) ''
|
||||
export PAPERLESS_ADMIN_USER="''${PAPERLESS_ADMIN_USER:-admin}"
|
||||
PAPERLESS_ADMIN_PASSWORD=$(cat "$CREDENTIALS_DIRECTORY/PAPERLESS_ADMIN_PASSWORD")
|
||||
export PAPERLESS_ADMIN_PASSWORD
|
||||
@ -320,7 +318,7 @@ in
|
||||
echo "$superuserState" > "$superuserStateFile"
|
||||
fi
|
||||
'';
|
||||
} // optionalAttrs enableRedis {
|
||||
} // lib.optionalAttrs enableRedis {
|
||||
after = [ "redis-paperless.service" ];
|
||||
};
|
||||
|
||||
@ -401,7 +399,7 @@ in
|
||||
unitConfig.JoinsNamespaceOf = "paperless-task-queue.service";
|
||||
};
|
||||
|
||||
users = optionalAttrs (cfg.user == defaultUser) {
|
||||
users = lib.optionalAttrs (cfg.user == defaultUser) {
|
||||
users.${defaultUser} = {
|
||||
group = defaultUser;
|
||||
uid = config.ids.uids.paperless;
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.parsoid;
|
||||
@ -15,19 +12,19 @@ let
|
||||
module = "lib/index.js";
|
||||
entrypoint = "apiServiceWorker";
|
||||
conf = {
|
||||
mwApis = map (x: if isAttrs x then x else { uri = x; }) cfg.wikis;
|
||||
mwApis = map (x: if lib.isAttrs x then x else { uri = x; }) cfg.wikis;
|
||||
serverInterface = cfg.interface;
|
||||
serverPort = cfg.port;
|
||||
};
|
||||
}];
|
||||
};
|
||||
|
||||
confFile = pkgs.writeText "config.yml" (builtins.toJSON (recursiveUpdate confTree cfg.extraConfig));
|
||||
confFile = pkgs.writeText "config.yml" (builtins.toJSON (lib.recursiveUpdate confTree cfg.extraConfig));
|
||||
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "parsoid" "interwikis" ] "Use services.parsoid.wikis instead")
|
||||
(lib.mkRemovedOptionModule [ "services" "parsoid" "interwikis" ] "Use services.parsoid.wikis instead")
|
||||
];
|
||||
|
||||
##### interface
|
||||
@ -36,8 +33,8 @@ in
|
||||
|
||||
services.parsoid = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable Parsoid -- bidirectional
|
||||
@ -45,40 +42,40 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
wikis = mkOption {
|
||||
type = types.listOf (types.either types.str types.attrs);
|
||||
wikis = lib.mkOption {
|
||||
type = lib.types.listOf (lib.types.either lib.types.str lib.types.attrs);
|
||||
example = [ "http://localhost/api.php" ];
|
||||
description = ''
|
||||
Used MediaWiki API endpoints.
|
||||
'';
|
||||
};
|
||||
|
||||
workers = mkOption {
|
||||
type = types.int;
|
||||
workers = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 2;
|
||||
description = ''
|
||||
Number of Parsoid workers.
|
||||
'';
|
||||
};
|
||||
|
||||
interface = mkOption {
|
||||
type = types.str;
|
||||
interface = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
description = ''
|
||||
Interface to listen on.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8000;
|
||||
description = ''
|
||||
Port to listen on.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = {};
|
||||
description = ''
|
||||
Extra configuration to add to parsoid configuration.
|
||||
@ -91,7 +88,7 @@ in
|
||||
|
||||
##### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
systemd.services.parsoid = {
|
||||
description = "Bidirectional wikitext parser";
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.pinnwand;
|
||||
|
||||
@ -10,25 +7,25 @@ let
|
||||
in
|
||||
{
|
||||
options.services.pinnwand = {
|
||||
enable = mkEnableOption "Pinnwand, a pastebin";
|
||||
enable = lib.mkEnableOption "Pinnwand, a pastebin";
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
description = "The port to listen on.";
|
||||
default = 8000;
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
default = {};
|
||||
description = ''
|
||||
Your {file}`pinnwand.toml` as a Nix attribute set. Look up
|
||||
possible options in the [documentation](https://pinnwand.readthedocs.io/en/v${pkgs.pinnwand.version}/configuration.html).
|
||||
'';
|
||||
type = types.submodule {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
database_uri = mkOption {
|
||||
type = types.str;
|
||||
database_uri = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "sqlite:////var/lib/pinnwand/pinnwand.db";
|
||||
example = "sqlite:///:memory";
|
||||
description = ''
|
||||
@ -38,16 +35,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
paste_size = mkOption {
|
||||
type = types.ints.positive;
|
||||
paste_size = lib.mkOption {
|
||||
type = lib.types.ints.positive;
|
||||
default = 262144;
|
||||
example = 524288;
|
||||
description = ''
|
||||
Maximum size of a paste in bytes.
|
||||
'';
|
||||
};
|
||||
paste_help = mkOption {
|
||||
type = types.str;
|
||||
paste_help = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = ''
|
||||
<p>Welcome to pinnwand, this site is a pastebin. It allows you to share code with others. If you write code in the text area below and press the paste button you will be given a link you can share with others so they can view your code as well.</p><p>People with the link can view your pasted code, only you can remove your paste and it expires automatically. Note that anyone could guess the URI to your paste so don't rely on it being private.</p>
|
||||
'';
|
||||
@ -55,8 +52,8 @@ in
|
||||
Raw HTML help text shown in the header area.
|
||||
'';
|
||||
};
|
||||
footer = mkOption {
|
||||
type = types.str;
|
||||
footer = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = ''
|
||||
View <a href="//github.com/supakeen/pinnwand" target="_BLANK">source code</a>, the <a href="/removal">removal</a> or <a href="/expiry">expiry</a> stories, or read the <a href="/about">about</a> page.
|
||||
'';
|
||||
@ -69,7 +66,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.pinnwand = {
|
||||
description = "Pinnwannd HTTP Server";
|
||||
after = [ "network.target" ];
|
||||
|
@ -1,53 +1,50 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.plex;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "plex" "managePlugins" ] "Please omit or define the option: `services.plex.extraPlugins' instead.")
|
||||
(lib.mkRemovedOptionModule [ "services" "plex" "managePlugins" ] "Please omit or define the option: `services.plex.extraPlugins' instead.")
|
||||
];
|
||||
|
||||
options = {
|
||||
services.plex = {
|
||||
enable = mkEnableOption "Plex Media Server";
|
||||
enable = lib.mkEnableOption "Plex Media Server";
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/plex";
|
||||
description = ''
|
||||
The directory where Plex stores its data files.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for the media server.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "plex";
|
||||
description = ''
|
||||
User account under which Plex runs.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "plex";
|
||||
description = ''
|
||||
Group under which Plex runs.
|
||||
'';
|
||||
};
|
||||
|
||||
extraPlugins = mkOption {
|
||||
type = types.listOf types.path;
|
||||
extraPlugins = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [];
|
||||
description = ''
|
||||
A list of paths to extra plugin bundles to install in Plex's plugin
|
||||
@ -55,7 +52,7 @@ in
|
||||
symlinks in Plex's plugin directory will be cleared and this module
|
||||
will symlink all of the paths specified here to that directory.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
[
|
||||
(builtins.path {
|
||||
name = "Audnexus.bundle";
|
||||
@ -70,8 +67,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
extraScanners = mkOption {
|
||||
type = types.listOf types.path;
|
||||
extraScanners = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [];
|
||||
description = ''
|
||||
A list of paths to extra scanners to install in Plex's scanners
|
||||
@ -81,7 +78,7 @@ in
|
||||
in Plex's scanners directory will be cleared and this module will
|
||||
symlink all of the paths specified here to that directory.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
[
|
||||
(fetchFromGitHub {
|
||||
owner = "ZeroQI";
|
||||
@ -93,8 +90,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
accelerationDevices = mkOption {
|
||||
type = types.listOf types.str;
|
||||
accelerationDevices = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = ["*"];
|
||||
example = [ "/dev/dri/renderD128" ];
|
||||
description = ''
|
||||
@ -104,7 +101,7 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "plex" {
|
||||
package = lib.mkPackageOption pkgs "plex" {
|
||||
extraDescription = ''
|
||||
Plex subscribers may wish to use their own package here,
|
||||
pointing to subscriber-only server versions.
|
||||
@ -113,7 +110,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
# Most of this is just copied from the RPM package's systemd service file.
|
||||
systemd.services.plex = {
|
||||
description = "Plex Media Server";
|
||||
@ -149,7 +146,7 @@ in
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = cfg.accelerationDevices == [];
|
||||
DeviceAllow = mkIf (cfg.accelerationDevices != [] && !lib.elem "*" cfg.accelerationDevices) cfg.accelerationDevices;
|
||||
DeviceAllow = lib.mkIf (cfg.accelerationDevices != [] && !lib.elem "*" cfg.accelerationDevices) cfg.accelerationDevices;
|
||||
ProtectSystem = true;
|
||||
ProtectHome = true;
|
||||
ProtectControlGroups = true;
|
||||
@ -167,8 +164,8 @@ in
|
||||
environment = {
|
||||
# Configuration for our FHS userenv script
|
||||
PLEX_DATADIR=cfg.dataDir;
|
||||
PLEX_PLUGINS=concatMapStringsSep ":" builtins.toString cfg.extraPlugins;
|
||||
PLEX_SCANNERS=concatMapStringsSep ":" builtins.toString cfg.extraScanners;
|
||||
PLEX_PLUGINS=lib.concatMapStringsSep ":" builtins.toString cfg.extraPlugins;
|
||||
PLEX_SCANNERS=lib.concatMapStringsSep ":" builtins.toString cfg.extraScanners;
|
||||
|
||||
# The following variables should be set by the FHS userenv script:
|
||||
# PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR
|
||||
@ -186,19 +183,19 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 32400 3005 8324 32469 ];
|
||||
allowedUDPPorts = [ 1900 5353 32410 32412 32413 32414 ];
|
||||
};
|
||||
|
||||
users.users = mkIf (cfg.user == "plex") {
|
||||
users.users = lib.mkIf (cfg.user == "plex") {
|
||||
plex = {
|
||||
group = cfg.group;
|
||||
uid = config.ids.uids.plex;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = mkIf (cfg.group == "plex") {
|
||||
users.groups = lib.mkIf (cfg.group == "plex") {
|
||||
plex = {
|
||||
gid = config.ids.gids.plex;
|
||||
};
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.plikd;
|
||||
|
||||
@ -11,15 +8,15 @@ in
|
||||
{
|
||||
options = {
|
||||
services.plikd = {
|
||||
enable = mkEnableOption "plikd, a temporary file upload system";
|
||||
enable = lib.mkEnableOption "plikd, a temporary file upload system";
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Open ports in the firewall for the plikd.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
type = format.type;
|
||||
default = {};
|
||||
description = ''
|
||||
@ -30,8 +27,8 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.plikd.settings = mapAttrs (name: mkDefault) {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.plikd.settings = lib.mapAttrs (name: lib.mkDefault) {
|
||||
ListenPort = 8080;
|
||||
ListenAddress = "localhost";
|
||||
DataBackend = "file";
|
||||
@ -75,7 +72,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.settings.ListenPort ];
|
||||
};
|
||||
};
|
||||
|
@ -2,8 +2,6 @@
|
||||
, pkgs
|
||||
, lib
|
||||
, ...}:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.polaris;
|
||||
settingsFormat = pkgs.formats.toml {};
|
||||
@ -11,31 +9,31 @@ in
|
||||
{
|
||||
options = {
|
||||
services.polaris = {
|
||||
enable = mkEnableOption "Polaris Music Server";
|
||||
enable = lib.mkEnableOption "Polaris Music Server";
|
||||
|
||||
package = mkPackageOption pkgs "polaris" { };
|
||||
package = lib.mkPackageOption pkgs "polaris" { };
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "polaris";
|
||||
description = "User account under which Polaris runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "polaris";
|
||||
description = "Group under which Polaris is run.";
|
||||
};
|
||||
|
||||
extraGroups = mkOption {
|
||||
type = types.listOf types.str;
|
||||
extraGroups = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Polaris' auxiliary groups.";
|
||||
example = literalExpression ''["media" "music"]'';
|
||||
example = lib.literalExpression ''["media" "music"]'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 5050;
|
||||
description = ''
|
||||
The port which the Polaris REST api and web UI should listen to.
|
||||
@ -43,7 +41,7 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = {};
|
||||
description = ''
|
||||
@ -51,7 +49,7 @@ in
|
||||
Although poorly documented, an example may be found here:
|
||||
[test-config.toml](https://github.com/agersant/polaris/blob/374d0ca56fc0a466d797a4b252e2078607476797/test-data/config.toml)
|
||||
'';
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
settings.reindex_every_n_seconds = 7*24*60*60; # weekly, default is 1800
|
||||
settings.album_art_pattern =
|
||||
@ -70,8 +68,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open the configured port in the firewall.
|
||||
@ -80,7 +78,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.polaris = {
|
||||
description = "Polaris Music Server";
|
||||
after = [ "network.target" ];
|
||||
@ -93,13 +91,13 @@ in
|
||||
SupplementaryGroups = cfg.extraGroups;
|
||||
StateDirectory = "polaris";
|
||||
CacheDirectory = "polaris";
|
||||
ExecStart = escapeShellArgs ([
|
||||
ExecStart = lib.escapeShellArgs ([
|
||||
"${cfg.package}/bin/polaris"
|
||||
"--foreground"
|
||||
"--port" cfg.port
|
||||
"--database" "/var/lib/${StateDirectory}/db.sqlite"
|
||||
"--cache" "/var/cache/${CacheDirectory}"
|
||||
] ++ optionals (cfg.settings != {}) [
|
||||
] ++ lib.optionals (cfg.settings != {}) [
|
||||
"--config" (settingsFormat.generate "polaris-config.toml" cfg.settings)
|
||||
]);
|
||||
Restart = "on-failure";
|
||||
@ -141,11 +139,11 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ pbsds ];
|
||||
meta.maintainers = with lib.maintainers; [ pbsds ];
|
||||
}
|
||||
|
@ -1,25 +1,22 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.preload;
|
||||
in {
|
||||
meta = { maintainers = pkgs.preload.meta.maintainers; };
|
||||
|
||||
options.services.preload = {
|
||||
enable = mkEnableOption "preload";
|
||||
package = mkPackageOption pkgs "preload" { };
|
||||
enable = lib.mkEnableOption "preload";
|
||||
package = lib.mkPackageOption pkgs "preload" { };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.preload = {
|
||||
description = "Loads data into ram during idle time of CPU.";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
EnvironmentFile = "${cfg.package}/etc/conf.d/preload";
|
||||
ExecStart = "${getExe cfg.package} -l '' --foreground $PRELOAD_OPTS";
|
||||
ExecStart = "${lib.getExe cfg.package} -l '' --foreground $PRELOAD_OPTS";
|
||||
Type = "simple";
|
||||
# Only preload data during CPU idle time
|
||||
IOSchedulingClass = 3;
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.prowlarr;
|
||||
|
||||
@ -9,19 +6,19 @@ in
|
||||
{
|
||||
options = {
|
||||
services.prowlarr = {
|
||||
enable = mkEnableOption "Prowlarr, an indexer manager/proxy for Torrent trackers and Usenet indexers";
|
||||
enable = lib.mkEnableOption "Prowlarr, an indexer manager/proxy for Torrent trackers and Usenet indexers";
|
||||
|
||||
package = mkPackageOption pkgs "prowlarr" { };
|
||||
package = lib.mkPackageOption pkgs "prowlarr" { };
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Open ports in the firewall for the Prowlarr web interface.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.prowlarr = {
|
||||
description = "Prowlarr";
|
||||
after = [ "network.target" ];
|
||||
@ -37,7 +34,7 @@ in
|
||||
environment.HOME = "/var/empty";
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 9696 ];
|
||||
};
|
||||
};
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.pykms;
|
||||
libDir = "/var/lib/pykms";
|
||||
@ -10,56 +8,56 @@ in
|
||||
meta.maintainers = with lib.maintainers; [ peterhoeg ];
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "pykms" "verbose" ] "Use services.pykms.logLevel instead")
|
||||
(lib.mkRemovedOptionModule [ "services" "pykms" "verbose" ] "Use services.pykms.logLevel instead")
|
||||
];
|
||||
|
||||
options = {
|
||||
services.pykms = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the PyKMS service.";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
listenAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0.0.0.0";
|
||||
description = "The IP address on which to listen.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 1688;
|
||||
description = "The port on which to listen.";
|
||||
};
|
||||
|
||||
openFirewallPort = mkOption {
|
||||
type = types.bool;
|
||||
openFirewallPort = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether the listening port should be opened automatically.";
|
||||
};
|
||||
|
||||
memoryLimit = mkOption {
|
||||
type = types.str;
|
||||
memoryLimit = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "64M";
|
||||
description = "How much memory to use at most.";
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum [ "CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG" "MININFO" ];
|
||||
logLevel = lib.mkOption {
|
||||
type = lib.types.enum [ "CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG" "MININFO" ];
|
||||
default = "INFO";
|
||||
description = "How much to log";
|
||||
};
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Additional arguments";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewallPort [ cfg.port ];
|
||||
|
||||
systemd.services.pykms = {
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.radarr;
|
||||
|
||||
@ -9,37 +6,37 @@ in
|
||||
{
|
||||
options = {
|
||||
services.radarr = {
|
||||
enable = mkEnableOption "Radarr, a UsetNet/BitTorrent movie downloader";
|
||||
enable = lib.mkEnableOption "Radarr, a UsetNet/BitTorrent movie downloader";
|
||||
|
||||
package = mkPackageOption pkgs "radarr" { };
|
||||
package = lib.mkPackageOption pkgs "radarr" { };
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/radarr/.config/Radarr";
|
||||
description = "The directory where Radarr stores its data files.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Open ports in the firewall for the Radarr web interface.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "radarr";
|
||||
description = "User account under which Radarr runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "radarr";
|
||||
description = "Group under which Radarr runs.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.tmpfiles.settings."10-radarr".${cfg.dataDir}.d = {
|
||||
inherit (cfg) user group;
|
||||
mode = "0700";
|
||||
@ -59,11 +56,11 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 7878 ];
|
||||
};
|
||||
|
||||
users.users = mkIf (cfg.user == "radarr") {
|
||||
users.users = lib.mkIf (cfg.user == "radarr") {
|
||||
radarr = {
|
||||
group = cfg.group;
|
||||
home = cfg.dataDir;
|
||||
@ -71,7 +68,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = mkIf (cfg.group == "radarr") {
|
||||
users.groups = lib.mkIf (cfg.group == "radarr") {
|
||||
radarr.gid = config.ids.gids.radarr;
|
||||
};
|
||||
};
|
||||
|
@ -1,41 +1,38 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.readarr;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.readarr = {
|
||||
enable = mkEnableOption "Readarr, a Usenet/BitTorrent ebook downloader";
|
||||
enable = lib.mkEnableOption "Readarr, a Usenet/BitTorrent ebook downloader";
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/readarr/";
|
||||
description = "The directory where Readarr stores its data files.";
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "readarr" { };
|
||||
package = lib.mkPackageOption pkgs "readarr" { };
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for Readarr
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "readarr";
|
||||
description = ''
|
||||
User account under which Readarr runs.
|
||||
'';
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "readarr";
|
||||
description = ''
|
||||
Group under which Readarr runs.
|
||||
@ -44,7 +41,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.tmpfiles.settings."10-readarr".${cfg.dataDir}.d = {
|
||||
inherit (cfg) user group;
|
||||
mode = "0700";
|
||||
@ -64,11 +61,11 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 8787 ];
|
||||
};
|
||||
|
||||
users.users = mkIf (cfg.user == "readarr") {
|
||||
users.users = lib.mkIf (cfg.user == "readarr") {
|
||||
readarr = {
|
||||
description = "Readarr service";
|
||||
home = cfg.dataDir;
|
||||
@ -77,7 +74,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = mkIf (cfg.group == "readarr") {
|
||||
users.groups = lib.mkIf (cfg.group == "readarr") {
|
||||
readarr = { };
|
||||
};
|
||||
};
|
||||
|
@ -104,7 +104,6 @@ in
|
||||
Group = "renovate";
|
||||
DynamicUser = true;
|
||||
LoadCredential = lib.mapAttrsToList (name: value: "SECRET-${name}:${value}") cfg.credentials;
|
||||
Restart = "on-failure";
|
||||
CacheDirectory = "renovate";
|
||||
StateDirectory = "renovate";
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.rippleDataApi;
|
||||
|
||||
@ -23,8 +20,8 @@ let
|
||||
|
||||
db_config = builtins.toJSON {
|
||||
production = {
|
||||
username = optional (cfg.couchdb.pass != "") cfg.couchdb.user;
|
||||
password = optional (cfg.couchdb.pass != "") cfg.couchdb.pass;
|
||||
username = lib.optional (cfg.couchdb.pass != "") cfg.couchdb.user;
|
||||
password = lib.optional (cfg.couchdb.pass != "") cfg.couchdb.pass;
|
||||
host = cfg.couchdb.host;
|
||||
port = cfg.couchdb.port;
|
||||
database = cfg.couchdb.db;
|
||||
@ -35,105 +32,105 @@ let
|
||||
in {
|
||||
options = {
|
||||
services.rippleDataApi = {
|
||||
enable = mkEnableOption "ripple data api";
|
||||
enable = lib.mkEnableOption "ripple data api";
|
||||
|
||||
port = mkOption {
|
||||
port = lib.mkOption {
|
||||
description = "Ripple data api port";
|
||||
default = 5993;
|
||||
type = types.port;
|
||||
type = lib.types.port;
|
||||
};
|
||||
|
||||
importMode = mkOption {
|
||||
importMode = lib.mkOption {
|
||||
description = "Ripple data api import mode.";
|
||||
default = "liveOnly";
|
||||
type = types.enum ["live" "liveOnly"];
|
||||
type = lib.types.enum ["live" "liveOnly"];
|
||||
};
|
||||
|
||||
minLedger = mkOption {
|
||||
minLedger = lib.mkOption {
|
||||
description = "Ripple data api minimal ledger to fetch.";
|
||||
default = null;
|
||||
type = types.nullOr types.int;
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
};
|
||||
|
||||
maxLedger = mkOption {
|
||||
maxLedger = lib.mkOption {
|
||||
description = "Ripple data api maximal ledger to fetch.";
|
||||
default = null;
|
||||
type = types.nullOr types.int;
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
};
|
||||
|
||||
redis = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
description = "Whether to enable caching of ripple data to redis.";
|
||||
default = true;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
host = lib.mkOption {
|
||||
description = "Ripple data api redis host.";
|
||||
default = "localhost";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
port = lib.mkOption {
|
||||
description = "Ripple data api redis port.";
|
||||
default = 5984;
|
||||
type = types.port;
|
||||
type = lib.types.port;
|
||||
};
|
||||
};
|
||||
|
||||
couchdb = {
|
||||
host = mkOption {
|
||||
host = lib.mkOption {
|
||||
description = "Ripple data api couchdb host.";
|
||||
default = "localhost";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
port = lib.mkOption {
|
||||
description = "Ripple data api couchdb port.";
|
||||
default = 5984;
|
||||
type = types.port;
|
||||
type = lib.types.port;
|
||||
};
|
||||
|
||||
db = mkOption {
|
||||
db = lib.mkOption {
|
||||
description = "Ripple data api couchdb database.";
|
||||
default = "rippled";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
user = lib.mkOption {
|
||||
description = "Ripple data api couchdb username.";
|
||||
default = "rippled";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
};
|
||||
|
||||
pass = mkOption {
|
||||
pass = lib.mkOption {
|
||||
description = "Ripple data api couchdb password.";
|
||||
default = "";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
};
|
||||
|
||||
create = mkOption {
|
||||
create = lib.mkOption {
|
||||
description = "Whether to create couchdb database needed by ripple data api.";
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
rippleds = mkOption {
|
||||
rippleds = lib.mkOption {
|
||||
description = "List of rippleds to be used by ripple data api.";
|
||||
default = [
|
||||
"http://s_east.ripple.com:51234"
|
||||
"http://s_west.ripple.com:51234"
|
||||
];
|
||||
type = types.listOf types.str;
|
||||
type = lib.types.listOf lib.types.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf (cfg.enable) {
|
||||
services.couchdb.enable = mkDefault true;
|
||||
services.couchdb.bindAddress = mkDefault "0.0.0.0";
|
||||
services.redis.enable = mkDefault true;
|
||||
config = lib.mkIf (cfg.enable) {
|
||||
services.couchdb.enable = lib.mkDefault true;
|
||||
services.couchdb.bindAddress = lib.mkDefault "0.0.0.0";
|
||||
services.redis.enable = lib.mkDefault true;
|
||||
|
||||
systemd.services.ripple-data-api = {
|
||||
after = [ "couchdb.service" "redis.service" "ripple-data-api-importer.service" ];
|
||||
@ -176,9 +173,9 @@ in {
|
||||
User = "ripple-data-api";
|
||||
};
|
||||
|
||||
preStart = mkMerge [
|
||||
(mkIf (cfg.couchdb.create) ''
|
||||
HOST="http://${optionalString (cfg.couchdb.pass != "") "${cfg.couchdb.user}:${cfg.couchdb.pass}@"}${cfg.couchdb.host}:${toString cfg.couchdb.port}"
|
||||
preStart = lib.mkMerge [
|
||||
(lib.mkIf (cfg.couchdb.create) ''
|
||||
HOST="http://${lib.optionalString (cfg.couchdb.pass != "") "${cfg.couchdb.user}:${cfg.couchdb.pass}@"}${cfg.couchdb.host}:${toString cfg.couchdb.port}"
|
||||
curl -X PUT $HOST/${cfg.couchdb.db} || true
|
||||
'')
|
||||
"${pkgs.ripple-data-api}/bin/update-views"
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ options, config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
opt = options.services.rkvm;
|
||||
cfg = config.services.rkvm;
|
||||
@ -10,35 +8,35 @@ in
|
||||
meta.maintainers = [ ];
|
||||
|
||||
options.services.rkvm = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
default = cfg.server.enable || cfg.client.enable;
|
||||
defaultText = literalExpression "config.${opt.server.enable} || config.${opt.client.enable}";
|
||||
type = types.bool;
|
||||
defaultText = lib.literalExpression "config.${opt.server.enable} || config.${opt.client.enable}";
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Whether to enable rkvm, a Virtual KVM switch for Linux machines.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "rkvm" { };
|
||||
package = lib.mkPackageOption pkgs "rkvm" { };
|
||||
|
||||
server = {
|
||||
enable = mkEnableOption "the rkvm server daemon (input transmitter)";
|
||||
enable = lib.mkEnableOption "the rkvm server daemon (input transmitter)";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.submodule
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule
|
||||
{
|
||||
freeformType = toml.type;
|
||||
options = {
|
||||
listen = mkOption {
|
||||
type = types.str;
|
||||
listen = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0.0.0.0:5258";
|
||||
description = ''
|
||||
An internet socket address to listen on, either IPv4 or IPv6.
|
||||
'';
|
||||
};
|
||||
|
||||
switch-keys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
switch-keys = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "left-alt" "left-ctrl" ];
|
||||
description = ''
|
||||
A key list specifying a host switch combination.
|
||||
@ -47,8 +45,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
certificate = mkOption {
|
||||
type = types.path;
|
||||
certificate = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/etc/rkvm/certificate.pem";
|
||||
description = ''
|
||||
TLS certificate path.
|
||||
@ -59,8 +57,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
key = mkOption {
|
||||
type = types.path;
|
||||
key = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/etc/rkvm/key.pem";
|
||||
description = ''
|
||||
TLS key path.
|
||||
@ -71,8 +69,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
password = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Shared secret token to authenticate the client.
|
||||
Make sure this matches your client's config.
|
||||
@ -87,23 +85,23 @@ in
|
||||
};
|
||||
|
||||
client = {
|
||||
enable = mkEnableOption "the rkvm client daemon (input receiver)";
|
||||
enable = lib.mkEnableOption "the rkvm client daemon (input receiver)";
|
||||
|
||||
settings = mkOption {
|
||||
type = types.submodule
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule
|
||||
{
|
||||
freeformType = toml.type;
|
||||
options = {
|
||||
server = mkOption {
|
||||
type = types.str;
|
||||
server = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "192.168.0.123:5258";
|
||||
description = ''
|
||||
An RKVM server's internet socket address, either IPv4 or IPv6.
|
||||
'';
|
||||
};
|
||||
|
||||
certificate = mkOption {
|
||||
type = types.path;
|
||||
certificate = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/etc/rkvm/certificate.pem";
|
||||
description = ''
|
||||
TLS ceritficate path.
|
||||
@ -114,8 +112,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
password = mkOption {
|
||||
type = types.str;
|
||||
password = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Shared secret token to authenticate the client.
|
||||
Make sure this matches your server's config.
|
||||
@ -131,7 +129,7 @@ in
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
systemd.services =
|
||||
@ -156,8 +154,8 @@ in
|
||||
};
|
||||
in
|
||||
{
|
||||
rkvm-server = mkIf cfg.server.enable (mkBase "server");
|
||||
rkvm-client = mkIf cfg.client.enable (mkBase "client");
|
||||
rkvm-server = lib.mkIf cfg.server.enable (mkBase "server");
|
||||
rkvm-client = lib.mkIf cfg.client.enable (mkBase "client");
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -4,9 +4,6 @@
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.rmfakecloud;
|
||||
serviceDataDir = "/var/lib/rmfakecloud";
|
||||
@ -15,28 +12,28 @@ in
|
||||
{
|
||||
options = {
|
||||
services.rmfakecloud = {
|
||||
enable = mkEnableOption "rmfakecloud remarkable self-hosted cloud";
|
||||
enable = lib.mkEnableOption "rmfakecloud remarkable self-hosted cloud";
|
||||
|
||||
package = mkPackageOption pkgs "rmfakecloud" { };
|
||||
package = lib.mkPackageOption pkgs "rmfakecloud" { };
|
||||
|
||||
storageUrl = mkOption {
|
||||
type = types.str;
|
||||
storageUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "https://local.appspot.com";
|
||||
description = ''
|
||||
URL used by the tablet to access the rmfakecloud service.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 3000;
|
||||
description = ''
|
||||
Listening port number.
|
||||
'';
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
type = types.enum [
|
||||
logLevel = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"info"
|
||||
"debug"
|
||||
"warn"
|
||||
@ -48,8 +45,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
extraSettings = mkOption {
|
||||
type = with types; attrsOf str;
|
||||
extraSettings = lib.mkOption {
|
||||
type = with lib.types; attrsOf str;
|
||||
default = { };
|
||||
example = {
|
||||
DATADIR = "/custom/path/for/rmfakecloud/data";
|
||||
@ -63,8 +60,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = with types; nullOr path;
|
||||
environmentFile = lib.mkOption {
|
||||
type = with lib.types; nullOr path;
|
||||
default = null;
|
||||
example = "/etc/secrets/rmfakecloud.env";
|
||||
description = ''
|
||||
@ -78,7 +75,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.rmfakecloud = {
|
||||
description = "rmfakecloud remarkable self-hosted cloud";
|
||||
|
||||
@ -113,9 +110,9 @@ in
|
||||
Type = "simple";
|
||||
Restart = "always";
|
||||
|
||||
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||
|
||||
AmbientCapabilities = mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
|
||||
AmbientCapabilities = lib.mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
|
||||
|
||||
DynamicUser = true;
|
||||
PrivateDevices = true;
|
||||
@ -148,5 +145,5 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ pacien ];
|
||||
meta.maintainers = with lib.maintainers; [ pacien ];
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.safeeyes;
|
||||
@ -16,7 +13,7 @@ in
|
||||
|
||||
services.safeeyes = {
|
||||
|
||||
enable = mkEnableOption "the safeeyes OSGi service";
|
||||
enable = lib.mkEnableOption "the safeeyes OSGi service";
|
||||
|
||||
};
|
||||
|
||||
@ -24,7 +21,7 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.safeeyes ];
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
{
|
||||
options.services.sdrplayApi = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
@ -17,7 +16,7 @@ with lib;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf config.services.sdrplayApi.enable {
|
||||
config = lib.mkIf config.services.sdrplayApi.enable {
|
||||
systemd.services.sdrplayApi = {
|
||||
description = "SDRplay API Service";
|
||||
after = [ "network.target" ];
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.serviio;
|
||||
@ -28,16 +25,16 @@ in {
|
||||
options = {
|
||||
services.serviio = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable the Serviio Media Server.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/serviio";
|
||||
description = ''
|
||||
The directory where serviio stores its state, data, etc.
|
||||
@ -49,7 +46,7 @@ in {
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.serviio = {
|
||||
description = "Serviio Media Server";
|
||||
after = [ "network.target" ];
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
name = "sickbeard";
|
||||
@ -17,41 +14,41 @@ in
|
||||
|
||||
options = {
|
||||
services.sickbeard = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable the sickbeard server.";
|
||||
};
|
||||
package = mkPackageOption pkgs "sickbeard" {
|
||||
package = lib.mkPackageOption pkgs "sickbeard" {
|
||||
example = "sickrage";
|
||||
extraDescription = ''
|
||||
Enable `pkgs.sickrage` or `pkgs.sickgear`
|
||||
as an alternative to SickBeard
|
||||
'';
|
||||
};
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/${name}";
|
||||
description = "Path where to store data files.";
|
||||
};
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
configFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "${cfg.dataDir}/config.ini";
|
||||
defaultText = literalExpression ''"''${config.${opt.dataDir}}/config.ini"'';
|
||||
defaultText = lib.literalExpression ''"''${config.${opt.dataDir}}/config.ini"'';
|
||||
description = "Path to config file.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.ints.u16;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.ints.u16;
|
||||
default = 8081;
|
||||
description = "Port to bind to.";
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "User to run the service as";
|
||||
};
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Group to run the service as";
|
||||
};
|
||||
@ -61,9 +58,9 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
users.users = optionalAttrs (cfg.user == name) {
|
||||
users.users = lib.optionalAttrs (cfg.user == name) {
|
||||
${name} = {
|
||||
uid = config.ids.uids.sickbeard;
|
||||
group = cfg.group;
|
||||
@ -73,7 +70,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == name) {
|
||||
users.groups = lib.optionalAttrs (cfg.group == name) {
|
||||
${name}.gid = config.ids.gids.sickbeard;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.signald;
|
||||
dataDir = "/var/lib/signald";
|
||||
@ -8,36 +6,36 @@ let
|
||||
in
|
||||
{
|
||||
options.services.signald = {
|
||||
enable = mkEnableOption "signald, the unofficial daemon for interacting with Signal";
|
||||
enable = lib.mkEnableOption "signald, the unofficial daemon for interacting with Signal";
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultUser;
|
||||
description = "User under which signald runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultUser;
|
||||
description = "Group under which signald runs.";
|
||||
};
|
||||
|
||||
socketPath = mkOption {
|
||||
type = types.str;
|
||||
socketPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/run/signald/signald.sock";
|
||||
description = "Path to the signald socket";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users = optionalAttrs (cfg.user == defaultUser) {
|
||||
config = lib.mkIf cfg.enable {
|
||||
users.users = lib.optionalAttrs (cfg.user == defaultUser) {
|
||||
${defaultUser} = {
|
||||
group = cfg.group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = optionalAttrs (cfg.group == defaultUser) {
|
||||
users.groups = lib.optionalAttrs (cfg.group == defaultUser) {
|
||||
${defaultUser} = { };
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.siproxd;
|
||||
@ -17,10 +14,10 @@ let
|
||||
rtp_port_high = ${toString cfg.rtpPortHigh}
|
||||
rtp_dscp = ${toString cfg.rtpDscp}
|
||||
sip_dscp = ${toString cfg.sipDscp}
|
||||
${optionalString (cfg.hostsAllowReg != []) "hosts_allow_reg = ${concatStringsSep "," cfg.hostsAllowReg}"}
|
||||
${optionalString (cfg.hostsAllowSip != []) "hosts_allow_sip = ${concatStringsSep "," cfg.hostsAllowSip}"}
|
||||
${optionalString (cfg.hostsDenySip != []) "hosts_deny_sip = ${concatStringsSep "," cfg.hostsDenySip}"}
|
||||
${optionalString (cfg.passwordFile != "") "proxy_auth_pwfile = ${cfg.passwordFile}"}
|
||||
${lib.optionalString (cfg.hostsAllowReg != []) "hosts_allow_reg = ${lib.concatStringsSep "," cfg.hostsAllowReg}"}
|
||||
${lib.optionalString (cfg.hostsAllowSip != []) "hosts_allow_sip = ${lib.concatStringsSep "," cfg.hostsAllowSip}"}
|
||||
${lib.optionalString (cfg.hostsDenySip != []) "hosts_deny_sip = ${lib.concatStringsSep "," cfg.hostsDenySip}"}
|
||||
${lib.optionalString (cfg.passwordFile != "") "proxy_auth_pwfile = ${cfg.passwordFile}"}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
@ -34,8 +31,8 @@ in
|
||||
|
||||
services.siproxd = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable the Siproxd SIP
|
||||
@ -43,20 +40,20 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
ifInbound = mkOption {
|
||||
type = types.str;
|
||||
ifInbound = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "eth0";
|
||||
description = "Local network interface";
|
||||
};
|
||||
|
||||
ifOutbound = mkOption {
|
||||
type = types.str;
|
||||
ifOutbound = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "ppp0";
|
||||
description = "Public network interface";
|
||||
};
|
||||
|
||||
hostsAllowReg = mkOption {
|
||||
type = types.listOf types.str;
|
||||
hostsAllowReg = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "192.168.1.0/24" "192.168.2.0/24" ];
|
||||
description = ''
|
||||
@ -64,8 +61,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hostsAllowSip = mkOption {
|
||||
type = types.listOf types.str;
|
||||
hostsAllowSip = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "123.45.0.0/16" "123.46.0.0/16" ];
|
||||
description = ''
|
||||
@ -73,8 +70,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hostsDenySip = mkOption {
|
||||
type = types.listOf types.str;
|
||||
hostsDenySip = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
example = [ "10.0.0.0/8" "11.0.0.0/8" ];
|
||||
description = ''
|
||||
@ -83,32 +80,32 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
sipListenPort = mkOption {
|
||||
type = types.int;
|
||||
sipListenPort = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 5060;
|
||||
description = ''
|
||||
Port to listen for incoming SIP messages.
|
||||
'';
|
||||
};
|
||||
|
||||
rtpPortLow = mkOption {
|
||||
type = types.int;
|
||||
rtpPortLow = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 7070;
|
||||
description = ''
|
||||
Bottom of UDP port range for incoming and outgoing RTP traffic
|
||||
'';
|
||||
};
|
||||
|
||||
rtpPortHigh = mkOption {
|
||||
type = types.int;
|
||||
rtpPortHigh = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 7089;
|
||||
description = ''
|
||||
Top of UDP port range for incoming and outgoing RTP traffic
|
||||
'';
|
||||
};
|
||||
|
||||
rtpTimeout = mkOption {
|
||||
type = types.int;
|
||||
rtpTimeout = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 300;
|
||||
description = ''
|
||||
Timeout for an RTP stream. If for the specified
|
||||
@ -117,8 +114,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
rtpDscp = mkOption {
|
||||
type = types.int;
|
||||
rtpDscp = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 46;
|
||||
description = ''
|
||||
DSCP (differentiated services) value to be assigned
|
||||
@ -127,8 +124,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
sipDscp = mkOption {
|
||||
type = types.int;
|
||||
sipDscp = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 0;
|
||||
description = ''
|
||||
DSCP (differentiated services) value to be assigned
|
||||
@ -137,16 +134,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.str;
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Path to per-user password file.
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
description = ''
|
||||
Extra configuration to add to siproxd configuration.
|
||||
@ -159,7 +156,7 @@ in
|
||||
|
||||
##### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
users.users.siproxyd = {
|
||||
uid = config.ids.uids.siproxd;
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.soft-serve;
|
||||
configFile = format.generate "config.yaml" cfg.settings;
|
||||
@ -12,11 +9,11 @@ in
|
||||
{
|
||||
options = {
|
||||
services.soft-serve = {
|
||||
enable = mkEnableOption "soft-serve";
|
||||
enable = lib.mkEnableOption "soft-serve";
|
||||
|
||||
package = mkPackageOption pkgs "soft-serve" { };
|
||||
package = lib.mkPackageOption pkgs "soft-serve" { };
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
type = format.type;
|
||||
default = { };
|
||||
description = ''
|
||||
@ -24,7 +21,7 @@ in
|
||||
|
||||
See <${docUrl}>.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
name = "dadada's repos";
|
||||
log_format = "text";
|
||||
@ -41,7 +38,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
# The config file has to be inside the state dir
|
||||
@ -61,7 +58,7 @@ in
|
||||
Type = "simple";
|
||||
DynamicUser = true;
|
||||
Restart = "always";
|
||||
ExecStart = "${getExe cfg.package} serve";
|
||||
ExecStart = "${lib.getExe cfg.package} serve";
|
||||
StateDirectory = "soft-serve";
|
||||
WorkingDirectory = stateDir;
|
||||
RuntimeDirectory = "soft-serve";
|
||||
@ -95,5 +92,5 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = [ maintainers.dadada ];
|
||||
meta.maintainers = [ lib.maintainers.dadada ];
|
||||
}
|
||||
|
@ -1,46 +1,43 @@
|
||||
{ config, pkgs, lib, utils, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.sonarr;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.sonarr = {
|
||||
enable = mkEnableOption "Sonarr";
|
||||
enable = lib.mkEnableOption "Sonarr";
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/sonarr/.config/NzbDrone";
|
||||
description = "The directory where Sonarr stores its data files.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open ports in the firewall for the Sonarr web interface
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "sonarr";
|
||||
description = "User account under which Sonaar runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "sonarr";
|
||||
description = "Group under which Sonaar runs.";
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "sonarr" { };
|
||||
package = lib.mkPackageOption pkgs "sonarr" { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '${cfg.dataDir}' 0700 ${cfg.user} ${cfg.group} - -"
|
||||
];
|
||||
@ -63,11 +60,11 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall {
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ 8989 ];
|
||||
};
|
||||
|
||||
users.users = mkIf (cfg.user == "sonarr") {
|
||||
users.users = lib.mkIf (cfg.user == "sonarr") {
|
||||
sonarr = {
|
||||
group = cfg.group;
|
||||
home = cfg.dataDir;
|
||||
@ -75,7 +72,7 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = mkIf (cfg.group == "sonarr") {
|
||||
users.groups = lib.mkIf (cfg.group == "sonarr") {
|
||||
sonarr.gid = config.ids.gids.sonarr;
|
||||
};
|
||||
};
|
||||
|
@ -1,17 +1,15 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.spice-vdagentd;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.spice-vdagentd = {
|
||||
enable = mkEnableOption "Spice guest vdagent daemon";
|
||||
enable = lib.mkEnableOption "Spice guest vdagent daemon";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.spice-vdagent ];
|
||||
|
||||
|
@ -1,19 +1,17 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.spice-webdavd;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.spice-webdavd = {
|
||||
enable = mkEnableOption "the spice guest webdav proxy daemon";
|
||||
enable = lib.mkEnableOption "the spice guest webdav proxy daemon";
|
||||
|
||||
package = mkPackageOption pkgs "phodav" { };
|
||||
package = lib.mkPackageOption pkgs "phodav" { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
# ensure the webdav fs this exposes can actually be mounted
|
||||
services.davfs2.enable = true;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.sssd;
|
||||
nscd = config.services.nscd;
|
||||
@ -10,10 +9,10 @@ let
|
||||
in {
|
||||
options = {
|
||||
services.sssd = {
|
||||
enable = mkEnableOption "the System Security Services Daemon";
|
||||
enable = lib.mkEnableOption "the System Security Services Daemon";
|
||||
|
||||
config = mkOption {
|
||||
type = types.lines;
|
||||
config = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
description = "Contents of {file}`sssd.conf`.";
|
||||
default = ''
|
||||
[sssd]
|
||||
@ -34,8 +33,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
sshAuthorizedKeysIntegration = mkOption {
|
||||
type = types.bool;
|
||||
sshAuthorizedKeysIntegration = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to make sshd look up authorized keys from SSS.
|
||||
@ -43,16 +42,16 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
kcm = mkOption {
|
||||
type = types.bool;
|
||||
kcm = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to use SSS as a Kerberos Cache Manager (KCM).
|
||||
Kerberos will be configured to cache credentials in SSS.
|
||||
'';
|
||||
};
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Environment file as defined in {manpage}`systemd.exec(5)`.
|
||||
@ -75,8 +74,8 @@ in {
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkMerge [
|
||||
(mkIf cfg.enable {
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf cfg.enable {
|
||||
# For `sssctl` to work.
|
||||
environment.etc."sssd/sssd.conf".source = settingsFile;
|
||||
environment.etc."sssd/conf.d".source = "${dataDir}/conf.d";
|
||||
@ -126,7 +125,7 @@ in {
|
||||
services.dbus.packages = [ pkgs.sssd ];
|
||||
})
|
||||
|
||||
(mkIf cfg.kcm {
|
||||
(lib.mkIf cfg.kcm {
|
||||
systemd.services.sssd-kcm = {
|
||||
description = "SSSD Kerberos Cache Manager";
|
||||
requires = [ "sssd-kcm.socket" ];
|
||||
@ -148,7 +147,7 @@ in {
|
||||
security.krb5.settings.libdefaults.default_ccache_name = "KCM:";
|
||||
})
|
||||
|
||||
(mkIf cfg.sshAuthorizedKeysIntegration {
|
||||
(lib.mkIf cfg.sshAuthorizedKeysIntegration {
|
||||
# Ugly: sshd refuses to start if a store path is given because /nix/store is group-writable.
|
||||
# So indirect by a symlink.
|
||||
environment.etc."ssh/authorized_keys_command" = {
|
||||
@ -162,5 +161,5 @@ in {
|
||||
services.openssh.authorizedKeysCommandUser = "nobody";
|
||||
})];
|
||||
|
||||
meta.maintainers = with maintainers; [ bbigras ];
|
||||
meta.maintainers = with lib.maintainers; [ bbigras ];
|
||||
}
|
||||
|
@ -1,17 +1,14 @@
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.subsonic;
|
||||
opt = options.services.subsonic;
|
||||
in {
|
||||
options = {
|
||||
services.subsonic = {
|
||||
enable = mkEnableOption "Subsonic daemon";
|
||||
enable = lib.mkEnableOption "Subsonic daemon";
|
||||
|
||||
home = mkOption {
|
||||
type = types.path;
|
||||
home = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/subsonic";
|
||||
description = ''
|
||||
The directory where Subsonic will create files.
|
||||
@ -19,8 +16,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
type = types.str;
|
||||
listenAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0.0.0.0";
|
||||
description = ''
|
||||
The host name or IP address on which to bind Subsonic.
|
||||
@ -30,8 +27,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 4040;
|
||||
description = ''
|
||||
The port on which Subsonic will listen for
|
||||
@ -39,8 +36,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
httpsPort = mkOption {
|
||||
type = types.port;
|
||||
httpsPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 0;
|
||||
description = ''
|
||||
The port on which Subsonic will listen for
|
||||
@ -48,8 +45,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
contextPath = mkOption {
|
||||
type = types.path;
|
||||
contextPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/";
|
||||
description = ''
|
||||
The context path, i.e., the last part of the Subsonic
|
||||
@ -57,8 +54,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
maxMemory = mkOption {
|
||||
type = types.int;
|
||||
maxMemory = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 100;
|
||||
description = ''
|
||||
The memory limit (max Java heap size) in megabytes.
|
||||
@ -66,8 +63,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
defaultMusicFolder = mkOption {
|
||||
type = types.path;
|
||||
defaultMusicFolder = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/music";
|
||||
description = ''
|
||||
Configure Subsonic to use this folder for music. This option
|
||||
@ -75,8 +72,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
defaultPodcastFolder = mkOption {
|
||||
type = types.path;
|
||||
defaultPodcastFolder = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/music/Podcast";
|
||||
description = ''
|
||||
Configure Subsonic to use this folder for Podcasts. This option
|
||||
@ -84,8 +81,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
defaultPlaylistFolder = mkOption {
|
||||
type = types.path;
|
||||
defaultPlaylistFolder = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/playlists";
|
||||
description = ''
|
||||
Configure Subsonic to use this folder for playlists. This option
|
||||
@ -93,10 +90,10 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
transcoders = mkOption {
|
||||
type = types.listOf types.path;
|
||||
transcoders = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [ "${pkgs.ffmpeg.bin}/bin/ffmpeg" ];
|
||||
defaultText = literalExpression ''[ "''${pkgs.ffmpeg.bin}/bin/ffmpeg" ]'';
|
||||
defaultText = lib.literalExpression ''[ "''${pkgs.ffmpeg.bin}/bin/ffmpeg" ]'';
|
||||
description = ''
|
||||
List of paths to transcoder executables that should be accessible
|
||||
from Subsonic. Symlinks will be created to each executable inside
|
||||
@ -106,7 +103,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.subsonic = {
|
||||
description = "Personal media streamer";
|
||||
after = [ "network.target" ];
|
||||
|
@ -1,17 +1,14 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.sundtek;
|
||||
|
||||
in
|
||||
{
|
||||
options.services.sundtek = {
|
||||
enable = mkEnableOption "Sundtek driver";
|
||||
enable = lib.mkEnableOption "Sundtek driver";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = [ pkgs.sundtek ];
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
# SVN server
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.svnserve;
|
||||
@ -17,14 +14,14 @@ in
|
||||
|
||||
services.svnserve = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable svnserve to serve Subversion repositories through the SVN protocol.";
|
||||
};
|
||||
|
||||
svnBaseDir = mkOption {
|
||||
type = types.str;
|
||||
svnBaseDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/repos";
|
||||
description = "Base directory from which Subversion repositories are accessed.";
|
||||
};
|
||||
@ -35,7 +32,7 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.svnserve = {
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfgC = config.services.synergy.client;
|
||||
@ -19,60 +16,60 @@ in
|
||||
# !!! All these option descriptions needs to be cleaned up.
|
||||
|
||||
client = {
|
||||
enable = mkEnableOption "the Synergy client (receive keyboard and mouse events from a Synergy server)";
|
||||
enable = lib.mkEnableOption "the Synergy client (receive keyboard and mouse events from a Synergy server)";
|
||||
|
||||
screenName = mkOption {
|
||||
screenName = lib.mkOption {
|
||||
default = "";
|
||||
type = types.str;
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Use the given name instead of the hostname to identify
|
||||
ourselves to the server.
|
||||
'';
|
||||
};
|
||||
serverAddress = mkOption {
|
||||
type = types.str;
|
||||
serverAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The server address is of the form: [hostname][:port]. The
|
||||
hostname must be the address or hostname of the server. The
|
||||
port overrides the default port, 24800.
|
||||
'';
|
||||
};
|
||||
autoStart = mkOption {
|
||||
autoStart = lib.mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = "Whether the Synergy client should be started automatically.";
|
||||
};
|
||||
};
|
||||
|
||||
server = {
|
||||
enable = mkEnableOption "the Synergy server (send keyboard and mouse events)";
|
||||
enable = lib.mkEnableOption "the Synergy server (send keyboard and mouse events)";
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.path;
|
||||
configFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/etc/synergy-server.conf";
|
||||
description = "The Synergy server configuration file.";
|
||||
};
|
||||
screenName = mkOption {
|
||||
type = types.str;
|
||||
screenName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Use the given name instead of the hostname to identify
|
||||
this screen in the configuration.
|
||||
'';
|
||||
};
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "Address on which to listen for clients.";
|
||||
};
|
||||
autoStart = mkOption {
|
||||
autoStart = lib.mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
type = lib.types.bool;
|
||||
description = "Whether the Synergy server should be started automatically.";
|
||||
};
|
||||
tls = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether TLS encryption should be used.
|
||||
@ -83,8 +80,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
cert = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
cert = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "~/.synergy/SSL/Synergy.pem";
|
||||
description = "The TLS certificate to use for encryption.";
|
||||
@ -98,24 +95,24 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf cfgC.enable {
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf cfgC.enable {
|
||||
systemd.user.services.synergy-client = {
|
||||
after = [ "network.target" "graphical-session.target" ];
|
||||
description = "Synergy client";
|
||||
wantedBy = optional cfgC.autoStart "graphical-session.target";
|
||||
wantedBy = lib.optional cfgC.autoStart "graphical-session.target";
|
||||
path = [ pkgs.synergy ];
|
||||
serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}'';
|
||||
serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${lib.optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}'';
|
||||
serviceConfig.Restart = "on-failure";
|
||||
};
|
||||
})
|
||||
(mkIf cfgS.enable {
|
||||
(lib.mkIf cfgS.enable {
|
||||
systemd.user.services.synergy-server = {
|
||||
after = [ "network.target" "graphical-session.target" ];
|
||||
description = "Synergy server";
|
||||
wantedBy = optional cfgS.autoStart "graphical-session.target";
|
||||
wantedBy = lib.optional cfgS.autoStart "graphical-session.target";
|
||||
path = [ pkgs.synergy ];
|
||||
serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f${optionalString (cfgS.address != "") " -a ${cfgS.address}"}${optionalString (cfgS.screenName != "") " -n ${cfgS.screenName}"}${optionalString cfgS.tls.enable " --enable-crypto"}${optionalString (cfgS.tls.cert != null) (" --tls-cert ${cfgS.tls.cert}")}'';
|
||||
serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f${lib.optionalString (cfgS.address != "") " -a ${cfgS.address}"}${lib.optionalString (cfgS.screenName != "") " -n ${cfgS.screenName}"}${lib.optionalString cfgS.tls.enable " --enable-crypto"}${lib.optionalString (cfgS.tls.cert != null) (" --tls-cert ${cfgS.tls.cert}")}'';
|
||||
serviceConfig.Restart = "on-failure";
|
||||
};
|
||||
})
|
||||
|
@ -1,6 +1,4 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.tandoor-recipes;
|
||||
pkg = cfg.package;
|
||||
@ -11,7 +9,7 @@ let
|
||||
DEBUG = "0";
|
||||
DEBUG_TOOLBAR = "0";
|
||||
MEDIA_ROOT = "/var/lib/tandoor-recipes";
|
||||
} // optionalAttrs (config.time.timeZone != null) {
|
||||
} // lib.optionalAttrs (config.time.timeZone != null) {
|
||||
TZ = config.time.timeZone;
|
||||
} // (
|
||||
lib.mapAttrs (_: toString) cfg.extraConfig
|
||||
@ -27,10 +25,10 @@ let
|
||||
'';
|
||||
in
|
||||
{
|
||||
meta.maintainers = with maintainers; [ ambroisie ];
|
||||
meta.maintainers = with lib.maintainers; [ ambroisie ];
|
||||
|
||||
options.services.tandoor-recipes = {
|
||||
enable = mkOption {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
@ -45,20 +43,20 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
address = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "localhost";
|
||||
description = "Web interface address.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8080;
|
||||
description = "Web interface port.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = { };
|
||||
description = ''
|
||||
Extra tandoor recipes config options.
|
||||
@ -71,10 +69,10 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "tandoor-recipes" { };
|
||||
package = lib.mkPackageOption pkgs "tandoor-recipes" { };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.tandoor-recipes = {
|
||||
description = "Tandoor Recipes server";
|
||||
|
||||
|
@ -1,60 +1,57 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.tautulli;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule [ "services" "plexpy" ] [ "services" "tautulli" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "plexpy" ] [ "services" "tautulli" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
services.tautulli = {
|
||||
enable = mkEnableOption "Tautulli Plex Monitor";
|
||||
enable = lib.mkEnableOption "Tautulli Plex Monitor";
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/plexpy";
|
||||
description = "The directory where Tautulli stores its data files.";
|
||||
};
|
||||
|
||||
configFile = mkOption {
|
||||
type = types.str;
|
||||
configFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/plexpy/config.ini";
|
||||
description = "The location of Tautulli's config file.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8181;
|
||||
description = "TCP port where Tautulli listens.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Open ports in the firewall for Tautulli.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "plexpy";
|
||||
description = "User account under which Tautulli runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nogroup";
|
||||
description = "Group under which Tautulli runs.";
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "tautulli" { };
|
||||
package = lib.mkPackageOption pkgs "tautulli" { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '${cfg.dataDir}' - ${cfg.user} ${cfg.group} - -"
|
||||
];
|
||||
@ -73,9 +70,9 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
|
||||
|
||||
users.users = mkIf (cfg.user == "plexpy") {
|
||||
users.users = lib.mkIf (cfg.user == "plexpy") {
|
||||
plexpy = { group = cfg.group; uid = config.ids.uids.plexpy; };
|
||||
};
|
||||
};
|
||||
|
@ -1,11 +1,8 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.tiddlywiki;
|
||||
listenParams = concatStrings (mapAttrsToList (n: v: " '${n}=${toString v}' ") cfg.listenOptions);
|
||||
listenParams = lib.concatStrings (lib.mapAttrsToList (n: v: " '${n}=${toString v}' ") cfg.listenOptions);
|
||||
exe = "${pkgs.nodePackages.tiddlywiki}/lib/node_modules/.bin/tiddlywiki";
|
||||
name = "tiddlywiki";
|
||||
dataDir = "/var/lib/" + name;
|
||||
@ -14,10 +11,10 @@ in {
|
||||
|
||||
options.services.tiddlywiki = {
|
||||
|
||||
enable = mkEnableOption "TiddlyWiki nodejs server";
|
||||
enable = lib.mkEnableOption "TiddlyWiki nodejs server";
|
||||
|
||||
listenOptions = mkOption {
|
||||
type = types.attrs;
|
||||
listenOptions = lib.mkOption {
|
||||
type = lib.types.attrs;
|
||||
default = {};
|
||||
example = {
|
||||
credentials = "../credentials.csv";
|
||||
@ -32,7 +29,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd = {
|
||||
services.tiddlywiki = {
|
||||
description = "TiddlyWiki nodejs server";
|
||||
|
@ -1,28 +1,25 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let cfg = config.services.tp-auto-kbbl;
|
||||
|
||||
in {
|
||||
meta.maintainers = with maintainers; [ sebtm ];
|
||||
meta.maintainers = with lib.maintainers; [ sebtm ];
|
||||
|
||||
options = {
|
||||
services.tp-auto-kbbl = {
|
||||
enable = mkEnableOption "auto toggle keyboard back-lighting on Thinkpads (and maybe other laptops) for Linux";
|
||||
enable = lib.mkEnableOption "auto toggle keyboard back-lighting on Thinkpads (and maybe other laptops) for Linux";
|
||||
|
||||
package = mkPackageOption pkgs "tp-auto-kbbl" { };
|
||||
package = lib.mkPackageOption pkgs "tp-auto-kbbl" { };
|
||||
|
||||
arguments = mkOption {
|
||||
type = types.listOf types.str;
|
||||
arguments = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of arguments appended to `./tp-auto-kbbl --device [device] [arguments]`
|
||||
'';
|
||||
};
|
||||
|
||||
device = mkOption {
|
||||
type = types.str;
|
||||
device = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/dev/input/event0";
|
||||
description = "Device watched for activities.";
|
||||
};
|
||||
@ -30,12 +27,12 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
systemd.services.tp-auto-kbbl = {
|
||||
serviceConfig = {
|
||||
ExecStart = concatStringsSep " "
|
||||
ExecStart = lib.concatStringsSep " "
|
||||
([ "${cfg.package}/bin/tp-auto-kbbl" "--device ${cfg.device}" ] ++ cfg.arguments);
|
||||
Restart = "always";
|
||||
Type = "simple";
|
||||
|
@ -1,23 +1,20 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.programs.tuxclocker;
|
||||
in
|
||||
{
|
||||
options.programs.tuxclocker = {
|
||||
enable = mkEnableOption ''
|
||||
enable = lib.mkEnableOption ''
|
||||
TuxClocker, a hardware control and monitoring program
|
||||
'';
|
||||
|
||||
enableAMD = mkEnableOption ''
|
||||
enableAMD = lib.mkEnableOption ''
|
||||
AMD GPU controls.
|
||||
Sets the `amdgpu.ppfeaturemask` kernel parameter to 0xfffd7fff to enable all TuxClocker controls
|
||||
'';
|
||||
|
||||
enabledNVIDIADevices = mkOption {
|
||||
type = types.listOf types.int;
|
||||
enabledNVIDIADevices = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.int;
|
||||
default = [ ];
|
||||
example = [ 0 1 ];
|
||||
description = ''
|
||||
@ -26,8 +23,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
useUnfree = mkOption {
|
||||
type = types.bool;
|
||||
useUnfree = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
@ -40,7 +37,7 @@ in
|
||||
config = let
|
||||
package = if cfg.useUnfree then pkgs.tuxclocker else pkgs.tuxclocker-without-unfree;
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [
|
||||
package
|
||||
];
|
||||
@ -62,10 +59,10 @@ in
|
||||
EndSection
|
||||
'');
|
||||
in
|
||||
concatStrings (map configSection cfg.enabledNVIDIADevices);
|
||||
lib.concatStrings (map configSection cfg.enabledNVIDIADevices);
|
||||
|
||||
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/amd/include/amd_shared.h#n207
|
||||
# Enable everything modifiable in TuxClocker
|
||||
boot.kernelParams = mkIf cfg.enableAMD [ "amdgpu.ppfeaturemask=0xfffd7fff" ];
|
||||
boot.kernelParams = lib.mkIf cfg.enableAMD [ "amdgpu.ppfeaturemask=0xfffd7fff" ];
|
||||
};
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.tzupdate;
|
||||
in {
|
||||
options.services.tzupdate = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable the tzupdate timezone updating service. This provides
|
||||
@ -17,7 +14,7 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
# We need to have imperative time zone management for this to work.
|
||||
# This will give users an error if they have set an explicit time
|
||||
# zone, which is better than silently overriding it.
|
||||
|
@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
settingsFormat = {
|
||||
type = with lib.types; attrsOf (oneOf [ bool int str ]);
|
||||
@ -13,21 +10,21 @@ let
|
||||
in {
|
||||
options = {
|
||||
|
||||
services.uhub = mkOption {
|
||||
services.uhub = lib.mkOption {
|
||||
default = { };
|
||||
description = "Uhub ADC hub instances";
|
||||
type = types.attrsOf (types.submodule {
|
||||
type = lib.types.attrsOf (lib.types.submodule {
|
||||
options = {
|
||||
|
||||
enable = mkEnableOption "hub instance" // { default = true; };
|
||||
enable = lib.mkEnableOption "hub instance" // { default = true; };
|
||||
|
||||
enableTLS = mkOption {
|
||||
type = types.bool;
|
||||
enableTLS = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable TLS support.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
inherit (settingsFormat) type;
|
||||
description = ''
|
||||
Configuration of uhub.
|
||||
@ -43,18 +40,18 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
plugins = mkOption {
|
||||
plugins = lib.mkOption {
|
||||
description = "Uhub plugin configuration.";
|
||||
type = with types;
|
||||
type = with lib.types;
|
||||
listOf (submodule {
|
||||
options = {
|
||||
plugin = mkOption {
|
||||
plugin = lib.mkOption {
|
||||
type = path;
|
||||
example = literalExpression
|
||||
example = lib.literalExpression
|
||||
"$${pkgs.uhub}/plugins/mod_auth_sqlite.so";
|
||||
description = "Path to plugin file.";
|
||||
};
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
description = "Settings specific to this plugin.";
|
||||
type = with types; attrsOf str;
|
||||
example = { file = "/etc/uhub/users.db"; };
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user