mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-10 15:23:43 +00:00
Compare commits
788 Commits
devShellTo
...
18.03
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
120b013e0c | ||
|
|
e4cc8c1397 | ||
|
|
ca6b64ae7b | ||
|
|
cbccde97dd | ||
|
|
d5c26dd063 | ||
|
|
251bc50e95 | ||
|
|
43f1db5b0d | ||
|
|
c1c01c7848 | ||
|
|
d93b08e6d2 | ||
|
|
c51459026a | ||
|
|
ac447b0524 | ||
|
|
47caeb1272 | ||
|
|
5bcdc86715 | ||
|
|
ecb39c43c2 | ||
|
|
d7aa359bcd | ||
|
|
bc632a2f55 | ||
|
|
b3c938bfeb | ||
|
|
6684b3e160 | ||
|
|
b2bc3db8f5 | ||
|
|
b39bb9bead | ||
|
|
a6d00d0d8f | ||
|
|
f0c713c813 | ||
|
|
9af18ff545 | ||
|
|
9331411a27 | ||
|
|
652a754cad | ||
|
|
09bca91e3b | ||
|
|
ba239f468f | ||
|
|
1dd960f66e | ||
|
|
f67968cdfa | ||
|
|
79910a4452 | ||
|
|
27974ed369 | ||
|
|
da36dfff14 | ||
|
|
154e0a254a | ||
|
|
829d2cdb5c | ||
|
|
021ee7d93b | ||
|
|
b8edfed0e2 | ||
|
|
311dcc7462 | ||
|
|
e54a063017 | ||
|
|
585aa0e9ee | ||
|
|
8039a49f1e | ||
|
|
96ccbe16ee | ||
|
|
a2c57c5336 | ||
|
|
a7c0fdbc9e | ||
|
|
97afec420e | ||
|
|
29a6d29e66 | ||
|
|
d798fa02f9 | ||
|
|
cde1f31f28 | ||
|
|
0a224fe280 | ||
|
|
834d892989 | ||
|
|
7d9e35afc2 | ||
|
|
0c79da12a3 | ||
|
|
efb1868bba | ||
|
|
1de51da824 | ||
|
|
2013114be0 | ||
|
|
2bbd0df63a | ||
|
|
43106ec955 | ||
|
|
11238ffbe1 | ||
|
|
0d91583166 | ||
|
|
a4f5011b73 | ||
|
|
0f51a9b9d9 | ||
|
|
c8163071bf | ||
|
|
7292975ca0 | ||
|
|
69a03de038 | ||
|
|
e79abe3062 | ||
|
|
2ddacd2959 | ||
|
|
c30303e038 | ||
|
|
e6114781b0 | ||
|
|
fbc2cb78b7 | ||
|
|
d40fc89bc2 | ||
|
|
343a3e28cc | ||
|
|
a07b79c3fd | ||
|
|
1dbe306ede | ||
|
|
21dd95bacf | ||
|
|
1784c7727a | ||
|
|
8f354913e6 | ||
|
|
75e1a7ed59 | ||
|
|
78e13f5da2 | ||
|
|
ba717c5471 | ||
|
|
7daf4299f5 | ||
|
|
9f24495851 | ||
|
|
4b148bce24 | ||
|
|
da3ef811d1 | ||
|
|
6d04965db9 | ||
|
|
255f999541 | ||
|
|
b0f5bc0f4a | ||
|
|
b65794b46e | ||
|
|
be798556eb | ||
|
|
b6474a3a3b | ||
|
|
718952b03b | ||
|
|
caba43d6fa | ||
|
|
d9e3401dbe | ||
|
|
2f5dae1b33 | ||
|
|
4d9d3cbfeb | ||
|
|
39e76f5a34 | ||
|
|
d206dca875 | ||
|
|
4bf9dd12af | ||
|
|
54c76d597f | ||
|
|
51c49db0f0 | ||
|
|
f74188b551 | ||
|
|
27ae4cea4e | ||
|
|
a7d6297032 | ||
|
|
d5f40d0ebd | ||
|
|
2251b7bfa7 | ||
|
|
7c4115b0c4 | ||
|
|
0101637e2e | ||
|
|
b052ce05d0 | ||
|
|
6c056757fb | ||
|
|
f21299103f | ||
|
|
7b43a4ffec | ||
|
|
877cde2272 | ||
|
|
f9b510b476 | ||
|
|
45715be8a9 | ||
|
|
bfd827cba1 | ||
|
|
8410194b6b | ||
|
|
df8996671e | ||
|
|
65d266574e | ||
|
|
2d11ec0612 | ||
|
|
45a8928acd | ||
|
|
0a73cde76f | ||
|
|
2ee303490f | ||
|
|
0bf74b94ba | ||
|
|
92b1816591 | ||
|
|
77c457b2b2 | ||
|
|
9e8f45e671 | ||
|
|
43a979c918 | ||
|
|
05c9191a20 | ||
|
|
7c34ee2b80 | ||
|
|
824d63448b | ||
|
|
34a2cd7d08 | ||
|
|
d2b6e655ca | ||
|
|
b65061a3fd | ||
|
|
0d02468af7 | ||
|
|
5afb48364d | ||
|
|
6a582b7a78 | ||
|
|
8e34b6def1 | ||
|
|
40212de191 | ||
|
|
38302326ce | ||
|
|
22782ef953 | ||
|
|
37b5385f88 | ||
|
|
2e569319fa | ||
|
|
883b7c54d8 | ||
|
|
a50e55382b | ||
|
|
c0c6e98690 | ||
|
|
bccc513396 | ||
|
|
5d817cfa4b | ||
|
|
d610810de0 | ||
|
|
732e3d05de | ||
|
|
ae174ee217 | ||
|
|
a585401f3f | ||
|
|
3d007c880e | ||
|
|
0f188554ac | ||
|
|
a758dcd467 | ||
|
|
dad020675d | ||
|
|
0e8f36fb1f | ||
|
|
a4c1951910 | ||
|
|
663c605492 | ||
|
|
b38f07ccac | ||
|
|
8ebd176017 | ||
|
|
a1b27036c5 | ||
|
|
0b9fea1e1a | ||
|
|
58d56020b7 | ||
|
|
35e62a279d | ||
|
|
7662b6c9f4 | ||
|
|
972c80d30e | ||
|
|
1d3e888bda | ||
|
|
79086fbc1e | ||
|
|
05e0dc4c6d | ||
|
|
af9b83af22 | ||
|
|
c4e37974c3 | ||
|
|
4166986dfa | ||
|
|
f9245e3e80 | ||
|
|
79bf41dfb0 | ||
|
|
2208739d1c | ||
|
|
933ba214e9 | ||
|
|
4e0b497cab | ||
|
|
06022fff51 | ||
|
|
741ae94dc0 | ||
|
|
0192dc6321 | ||
|
|
c9ab869bd2 | ||
|
|
ad027421c3 | ||
|
|
b6ddb9913f | ||
|
|
4403f33860 | ||
|
|
7a752aa8f8 | ||
|
|
12deb60a67 | ||
|
|
642a86ba84 | ||
|
|
22ad26e23d | ||
|
|
2224dd1599 | ||
|
|
91b09422cf | ||
|
|
c4597d2568 | ||
|
|
f2c9a2557b | ||
|
|
298ea40d39 | ||
|
|
a68e60f450 | ||
|
|
1896fcff60 | ||
|
|
176d151f4d | ||
|
|
cf87889431 | ||
|
|
eff6d9628c | ||
|
|
4c669db598 | ||
|
|
48ade50d8e | ||
|
|
b0abe78b5c | ||
|
|
828fdd61b9 | ||
|
|
94c403fb92 | ||
|
|
e794f9abbf | ||
|
|
dc01b66eef | ||
|
|
7c46833b04 | ||
|
|
1da25dd104 | ||
|
|
d843d7f21a | ||
|
|
ccabf39f5c | ||
|
|
35a6799b17 | ||
|
|
e2b8732980 | ||
|
|
bdac630c1d | ||
|
|
85d5fdce26 | ||
|
|
a903faf1d5 | ||
|
|
a978eee06f | ||
|
|
e32dee886f | ||
|
|
6f384b77d2 | ||
|
|
898cddd756 | ||
|
|
e789f6f6e5 | ||
|
|
be44525d04 | ||
|
|
9d8c6c71c0 | ||
|
|
15e3aad1a2 | ||
|
|
4e67f8974a | ||
|
|
86508d4ea4 | ||
|
|
f45bc2b3e4 | ||
|
|
ad57d1ec63 | ||
|
|
75276115bf | ||
|
|
7a79af0b8d | ||
|
|
0d20e7db5b | ||
|
|
a3be411dbd | ||
|
|
2a57fc65b0 | ||
|
|
d4f3c16982 | ||
|
|
f61244da2e | ||
|
|
f4770f2030 | ||
|
|
1febd196e7 | ||
|
|
9c85d196a9 | ||
|
|
0058e51c8c | ||
|
|
4a34e749f7 | ||
|
|
3976ff79e8 | ||
|
|
f6c0edb3ec | ||
|
|
08101d052d | ||
|
|
fb4847ebdd | ||
|
|
ba2a04f656 | ||
|
|
af6cc8e704 | ||
|
|
296c09a355 | ||
|
|
48856a91c0 | ||
|
|
cdb97353df | ||
|
|
9e804ba5bf | ||
|
|
3cf448faf2 | ||
|
|
01204cf872 | ||
|
|
eef14cb305 | ||
|
|
31ba589e50 | ||
|
|
2d2ab94cd2 | ||
|
|
01cce78ec4 | ||
|
|
361bd591ea | ||
|
|
a614f9f4c1 | ||
|
|
b828d00ffd | ||
|
|
135e13f8fc | ||
|
|
55e97a2ebb | ||
|
|
510fd552eb | ||
|
|
d200e2cfde | ||
|
|
ba11500aa8 | ||
|
|
766a80ec84 | ||
|
|
b9084d0160 | ||
|
|
05f206c3c1 | ||
|
|
7ef13f58b6 | ||
|
|
64301d0a32 | ||
|
|
d01e4430b3 | ||
|
|
bbde130fd7 | ||
|
|
d011c7bd02 | ||
|
|
ef716bb5cf | ||
|
|
13958f4a36 | ||
|
|
72314d37e8 | ||
|
|
0e735393c7 | ||
|
|
103e2c4efb | ||
|
|
eb80bdc402 | ||
|
|
07d1b17941 | ||
|
|
d6595b4d5b | ||
|
|
ca3bf23f5f | ||
|
|
9680902949 | ||
|
|
5445bb1583 | ||
|
|
75842fe98c | ||
|
|
8c3cb029e0 | ||
|
|
b8673bc3e0 | ||
|
|
2b397bfa75 | ||
|
|
0782536e49 | ||
|
|
8b578b862b | ||
|
|
5150a7ef50 | ||
|
|
a6146ec8bb | ||
|
|
96c97c51cb | ||
|
|
ad06aec8b5 | ||
|
|
80c6cd1a9e | ||
|
|
9914060dfb | ||
|
|
d49e4f607f | ||
|
|
beea3c9d36 | ||
|
|
5995e9c217 | ||
|
|
c0b813ed17 | ||
|
|
da20f8dd22 | ||
|
|
d775a130a3 | ||
|
|
9a81f1ba5b | ||
|
|
79378daa0e | ||
|
|
c6603050ba | ||
|
|
11f1cb7819 | ||
|
|
555ac8418c | ||
|
|
dc70be405f | ||
|
|
0f74315456 | ||
|
|
6297c190d0 | ||
|
|
7fa2f865b8 | ||
|
|
ea9f3fca65 | ||
|
|
c0cd5eeab8 | ||
|
|
cc25915367 | ||
|
|
5df02d9783 | ||
|
|
e28a58fb09 | ||
|
|
032a3286fd | ||
|
|
9cd1122df5 | ||
|
|
97a2621dae | ||
|
|
69e8d7ddd8 | ||
|
|
77c052d908 | ||
|
|
fa78cd4d68 | ||
|
|
9fd4a62b64 | ||
|
|
043ee6c65d | ||
|
|
67cdc01ba8 | ||
|
|
828d15e9d3 | ||
|
|
7b9ca7b7c5 | ||
|
|
f638751bb2 | ||
|
|
7098c05b59 | ||
|
|
c6eac40de4 | ||
|
|
c8ac1a2176 | ||
|
|
c7b7779ee2 | ||
|
|
19e7212940 | ||
|
|
7185278447 | ||
|
|
6d2fd84beb | ||
|
|
9fd7e2eee2 | ||
|
|
15d741b62b | ||
|
|
b87bafdffd | ||
|
|
0aafdaecee | ||
|
|
99ac0883cc | ||
|
|
f6c66f6cb1 | ||
|
|
5a777d237c | ||
|
|
0938277468 | ||
|
|
d2bb154421 | ||
|
|
f086e3ebde | ||
|
|
225eac1f37 | ||
|
|
8337d1ddca | ||
|
|
8d24d4fac9 | ||
|
|
14cbca54da | ||
|
|
e530ee1af5 | ||
|
|
9553628c22 | ||
|
|
c2a0eeeb1a | ||
|
|
5abaf2a959 | ||
|
|
607fc823d0 | ||
|
|
63e3251637 | ||
|
|
42e2ed6520 | ||
|
|
a3983d6d05 | ||
|
|
a2b75703d5 | ||
|
|
9ba0bf3e52 | ||
|
|
517d8261d1 | ||
|
|
ed8c29fa65 | ||
|
|
7e39d25600 | ||
|
|
084993f345 | ||
|
|
7a5c7c1818 | ||
|
|
280d762338 | ||
|
|
f6779e0f45 | ||
|
|
b8b740808c | ||
|
|
f87594f3ca | ||
|
|
a8cdcc52d8 | ||
|
|
89ed0cfde6 | ||
|
|
ddbff03f0f | ||
|
|
5bbfe48355 | ||
|
|
19daa8ca0d | ||
|
|
6c3638cff5 | ||
|
|
10c404acd2 | ||
|
|
e8f7e1e76c | ||
|
|
27994f8cdf | ||
|
|
b964be2410 | ||
|
|
3b1e354a2c | ||
|
|
6759a03179 | ||
|
|
0b0bd0c8cc | ||
|
|
ac2378d812 | ||
|
|
548044350a | ||
|
|
6924132355 | ||
|
|
b506cdbf90 | ||
|
|
dda33d697d | ||
|
|
715338b4bb | ||
|
|
0184e3f8cc | ||
|
|
6baf97fe61 | ||
|
|
747a426ce6 | ||
|
|
1287bc21b2 | ||
|
|
c310c64d71 | ||
|
|
b34d370eb7 | ||
|
|
18221dde69 | ||
|
|
eecc751716 | ||
|
|
ce032734c7 | ||
|
|
f999bc180b | ||
|
|
f1f0134dbd | ||
|
|
7a85df0ecd | ||
|
|
e68997c03a | ||
|
|
5141fe1cf3 | ||
|
|
ee97df8432 | ||
|
|
e496420972 | ||
|
|
a5d75da87f | ||
|
|
bf4578f62e | ||
|
|
d3c1ae3576 | ||
|
|
7249ff9d5b | ||
|
|
244e3da862 | ||
|
|
02a6deb7af | ||
|
|
35ca4c5115 | ||
|
|
f9def2f4e3 | ||
|
|
090ca7e47c | ||
|
|
9dfac9497d | ||
|
|
6e30c6b265 | ||
|
|
6daee8c3f8 | ||
|
|
5e4411f45b | ||
|
|
f2390ae057 | ||
|
|
199da0db1e | ||
|
|
0b3170b874 | ||
|
|
3ae19a3610 | ||
|
|
c68ed70878 | ||
|
|
0869801a69 | ||
|
|
fce096accc | ||
|
|
3f6c94e3df | ||
|
|
2380e3071c | ||
|
|
617d73f229 | ||
|
|
557aa6e7d7 | ||
|
|
5aeb26da06 | ||
|
|
280ac9b471 | ||
|
|
ebcf130a84 | ||
|
|
ed6e9c5e19 | ||
|
|
f949149dc4 | ||
|
|
d64af3e40f | ||
|
|
83e6969c44 | ||
|
|
592fb2c5a1 | ||
|
|
4937ce0100 | ||
|
|
d0d3a639a3 | ||
|
|
5b2d17228c | ||
|
|
d467692907 | ||
|
|
8a7a75372b | ||
|
|
725c6f452b | ||
|
|
039365d20f | ||
|
|
88075cf435 | ||
|
|
de8842891f | ||
|
|
c8b6fd95d4 | ||
|
|
0e7c9b3281 | ||
|
|
6e6417c013 | ||
|
|
b1053e6191 | ||
|
|
c1c6b00627 | ||
|
|
deebf75a72 | ||
|
|
c4e19a11bc | ||
|
|
d862661b7c | ||
|
|
4062990844 | ||
|
|
3c3e44a506 | ||
|
|
473fd8a01e | ||
|
|
0c52ab986b | ||
|
|
0e00bd52bd | ||
|
|
2a32f6bc0c | ||
|
|
f23e611426 | ||
|
|
5cef3289e7 | ||
|
|
9e3aa30b79 | ||
|
|
7f16996a35 | ||
|
|
e557b37549 | ||
|
|
12a88b2c51 | ||
|
|
685cf3ee5e | ||
|
|
39099eafe8 | ||
|
|
af126c64fb | ||
|
|
90d01305fb | ||
|
|
6fc7f86338 | ||
|
|
6dc10f3d04 | ||
|
|
812b2196fc | ||
|
|
e95d2412ac | ||
|
|
10e896f4e2 | ||
|
|
408c8c0678 | ||
|
|
27a8abf0e8 | ||
|
|
b1ef373069 | ||
|
|
fb3308d17a | ||
|
|
177e20c14e | ||
|
|
94ed4376e8 | ||
|
|
52e6f6f60c | ||
|
|
6381f5a4ee | ||
|
|
a2684671a1 | ||
|
|
be85709dfb | ||
|
|
4aa47178c9 | ||
|
|
92548bc6f0 | ||
|
|
95f07cc550 | ||
|
|
2401186d2c | ||
|
|
655704bf00 | ||
|
|
37b31ea04f | ||
|
|
af97515d70 | ||
|
|
1d5485c8c8 | ||
|
|
622c5bebbe | ||
|
|
0bdb853ef8 | ||
|
|
32c2d99f01 | ||
|
|
07f1fe42bb | ||
|
|
b26595f873 | ||
|
|
736189fe74 | ||
|
|
490e46dea6 | ||
|
|
6692ae9684 | ||
|
|
7cb4bebacd | ||
|
|
f024b57f39 | ||
|
|
ec191e7d96 | ||
|
|
4ab4af1bb5 | ||
|
|
f2d24b8ec6 | ||
|
|
683c5794b0 | ||
|
|
b4645c3783 | ||
|
|
22f0d6474c | ||
|
|
0f1c8dded7 | ||
|
|
e666b54155 | ||
|
|
4116dd129d | ||
|
|
f50a31681e | ||
|
|
6121f5b376 | ||
|
|
d2326197be | ||
|
|
6564e4f227 | ||
|
|
39609cc945 | ||
|
|
2bebfbd3cc | ||
|
|
88d768c59e | ||
|
|
736661ec4b | ||
|
|
82378f031a | ||
|
|
6480eb59f7 | ||
|
|
300ceef5c3 | ||
|
|
480fb8c05e | ||
|
|
362b9457a0 | ||
|
|
a34123b711 | ||
|
|
ddc2ad4e2e | ||
|
|
857d5a086a | ||
|
|
5e38637412 | ||
|
|
1a4173a683 | ||
|
|
81afea1f98 | ||
|
|
8860315c20 | ||
|
|
ab326cb02a | ||
|
|
4d7ed482dc | ||
|
|
5ab9937099 | ||
|
|
5f9ae3929b | ||
|
|
4298a313ad | ||
|
|
cd7765df84 | ||
|
|
7c37a863e0 | ||
|
|
fda0d2fbbe | ||
|
|
fed17ce233 | ||
|
|
11d8ea3f8f | ||
|
|
beccfcd7a1 | ||
|
|
fa8e61d118 | ||
|
|
5687a38cb0 | ||
|
|
dcb1b693ef | ||
|
|
016274cc6c | ||
|
|
136a39ee4d | ||
|
|
fd6d464cfc | ||
|
|
85cbd5391a | ||
|
|
f9cb527902 | ||
|
|
3fcbb254fb | ||
|
|
b05df747cb | ||
|
|
72fa68058e | ||
|
|
4a573f8ae1 | ||
|
|
2d3e899b06 | ||
|
|
2a5231c403 | ||
|
|
038560d68b | ||
|
|
5c5b188afd | ||
|
|
a64dea5c2f | ||
|
|
9697a84a79 | ||
|
|
a35928047c | ||
|
|
6afb73a984 | ||
|
|
b7a4c0e3c0 | ||
|
|
66ed24239d | ||
|
|
075908d34b | ||
|
|
3264fe594d | ||
|
|
2c8a6a879c | ||
|
|
570cf67110 | ||
|
|
9a02553f8a | ||
|
|
763ec32dd7 | ||
|
|
7ad7c976d8 | ||
|
|
1f9ffb4004 | ||
|
|
06e99e0a7f | ||
|
|
75f8209e3b | ||
|
|
2271731c30 | ||
|
|
a14d18e39b | ||
|
|
1769af7a28 | ||
|
|
98bc0c37bf | ||
|
|
41f93c6273 | ||
|
|
f04f613270 | ||
|
|
74f70f91a2 | ||
|
|
3d5ae7dd9c | ||
|
|
ad6601bc06 | ||
|
|
d75137ece7 | ||
|
|
14d6a5dd23 | ||
|
|
bfb9424e13 | ||
|
|
ef49c300a6 | ||
|
|
f275ec88ad | ||
|
|
380dac18a0 | ||
|
|
c8adc90361 | ||
|
|
5ceb25c217 | ||
|
|
36eee0b9a3 | ||
|
|
a332101652 | ||
|
|
2062aef4f0 | ||
|
|
050ad5dd36 | ||
|
|
442da8b898 | ||
|
|
378041f1b6 | ||
|
|
89242aadcc | ||
|
|
f0da9baaa4 | ||
|
|
52d6b940ff | ||
|
|
0f558b07e3 | ||
|
|
99901537c7 | ||
|
|
8f7a7dfbdd | ||
|
|
8be8c91d0a | ||
|
|
0cc0001756 | ||
|
|
b9cfe0cefb | ||
|
|
d6986819fb | ||
|
|
55f626e58f | ||
|
|
0c077427e1 | ||
|
|
a3d87f1ed8 | ||
|
|
2783e4e755 | ||
|
|
60d6d53eee | ||
|
|
9dbc763949 | ||
|
|
665c75eccb | ||
|
|
449ad50644 | ||
|
|
30c9664568 | ||
|
|
7fbb31a12b | ||
|
|
9bf324b5d0 | ||
|
|
ec46986f86 | ||
|
|
545665b51a | ||
|
|
580d00d507 | ||
|
|
bb88585479 | ||
|
|
0092cf65e9 | ||
|
|
b999b5e80c | ||
|
|
6b44b2ee32 | ||
|
|
a333b11963 | ||
|
|
c568f4d21a | ||
|
|
556857bc22 | ||
|
|
a215099636 | ||
|
|
d4fc1a0c0b | ||
|
|
11caaec824 | ||
|
|
5065d28a1c | ||
|
|
6afcd42e3b | ||
|
|
ce68ae5d9a | ||
|
|
313dab0c3f | ||
|
|
1f34ba8343 | ||
|
|
9ac481091f | ||
|
|
62bdacf6bd | ||
|
|
80a280f609 | ||
|
|
cb47e35408 | ||
|
|
656e1561f8 | ||
|
|
7ec3ba485d | ||
|
|
131f9a4fe1 | ||
|
|
f57a786cfb | ||
|
|
8fb34d8fc2 | ||
|
|
b8ebbc0e3d | ||
|
|
b6bd99869d | ||
|
|
2f93afbd51 | ||
|
|
81f8347c01 | ||
|
|
f9387d8e33 | ||
|
|
328a1c6ea2 | ||
|
|
bdb9c3b4e9 | ||
|
|
fc3b588207 | ||
|
|
013d0ba929 | ||
|
|
af64b8d165 | ||
|
|
af554ad3cc | ||
|
|
3b75b1004d | ||
|
|
5b772cd2a5 | ||
|
|
252397d7c1 | ||
|
|
6233a34505 | ||
|
|
035c9265d3 | ||
|
|
3708494230 | ||
|
|
b43fbc45f4 | ||
|
|
d19d0544bd | ||
|
|
0bd5b4aa99 | ||
|
|
330204b212 | ||
|
|
0585d51567 | ||
|
|
a32fcfd0da | ||
|
|
c536d4030b | ||
|
|
c5ba8b96e9 | ||
|
|
6ac7a6f909 | ||
|
|
fa8607a4c7 | ||
|
|
57b6a82d95 | ||
|
|
061f2bd51b | ||
|
|
12a39b0f92 | ||
|
|
f9f9c47419 | ||
|
|
2b9270f54c | ||
|
|
a8aacac1bd | ||
|
|
da702c3ecb | ||
|
|
237391c8a8 | ||
|
|
58cc2513d8 | ||
|
|
ece5594fd0 | ||
|
|
379c3fd1cf | ||
|
|
124228bcfa | ||
|
|
22b9e5d37f | ||
|
|
0cf830ecb6 | ||
|
|
9a6e742e94 | ||
|
|
2f3ea8863d | ||
|
|
ff94b5ced4 | ||
|
|
8088cd2fbe | ||
|
|
db7068e685 | ||
|
|
08d2a6a981 | ||
|
|
7086687469 | ||
|
|
280b912570 | ||
|
|
99dcf80e4b | ||
|
|
d9f179252d | ||
|
|
e06c2d9cfe | ||
|
|
33a4313eba | ||
|
|
5d1b222116 | ||
|
|
1189fd2504 | ||
|
|
602e64b42d | ||
|
|
cc1cda8bae | ||
|
|
7b72d7f713 | ||
|
|
d2bf584a75 | ||
|
|
8234bcad01 | ||
|
|
9bfeba6fc6 | ||
|
|
bef3bb584b | ||
|
|
ceb427eb50 | ||
|
|
c26c22b7ab | ||
|
|
0a0b31db3d | ||
|
|
686ce4dade | ||
|
|
180d071c3a | ||
|
|
67a504ed46 | ||
|
|
861f8bf015 | ||
|
|
01360a2845 | ||
|
|
f1333eeaa1 | ||
|
|
a9ee2cf9cc | ||
|
|
02a0fb8e74 | ||
|
|
d308c7fc7a | ||
|
|
77e99aa707 | ||
|
|
b8ec973e7d | ||
|
|
e6d0584d78 | ||
|
|
3c4c5913bb | ||
|
|
058417c31e | ||
|
|
8e58deb53f | ||
|
|
eadbc34c6d | ||
|
|
0bbaa51b4c | ||
|
|
1ce672458c | ||
|
|
6d88a00f01 | ||
|
|
ee88a41926 | ||
|
|
b312bdcd53 | ||
|
|
9cde87b0ee | ||
|
|
b31fd67d79 | ||
|
|
bd6d6078c6 | ||
|
|
f394f5230a | ||
|
|
a4340341a6 | ||
|
|
9defa1d4c0 | ||
|
|
e78837f435 | ||
|
|
ad6a090cfe | ||
|
|
43dd25e579 | ||
|
|
a053461720 | ||
|
|
724dcdd066 | ||
|
|
46fc5c8419 | ||
|
|
fac8c4d2d9 | ||
|
|
0feab3dabe | ||
|
|
df63bd6b9a | ||
|
|
bf5e7c48c4 | ||
|
|
17ff10ab83 | ||
|
|
82bb0a18f0 | ||
|
|
aa84b58f00 | ||
|
|
01f9a70647 | ||
|
|
5f98ff26d9 | ||
|
|
c43e04dd94 | ||
|
|
03dc796bbc | ||
|
|
eec99996ec | ||
|
|
52859c481a | ||
|
|
c6de8f318e | ||
|
|
70e1ebe0c7 | ||
|
|
69a3a1dce1 | ||
|
|
48a724cebd | ||
|
|
4dd70f96cc | ||
|
|
e4fe0e4555 | ||
|
|
8056287c13 | ||
|
|
8022ebc47c | ||
|
|
fee03226a6 | ||
|
|
b759739d05 | ||
|
|
f93e902ab2 | ||
|
|
6b3d6a9f7a | ||
|
|
9b53db5d7e | ||
|
|
b0eb9ec92d | ||
|
|
e4f2f026bd | ||
|
|
fa64b9e64f | ||
|
|
4069dab3ca | ||
|
|
2c1addb451 | ||
|
|
d0aa15abca | ||
|
|
7b987e2e86 | ||
|
|
6569c4f184 | ||
|
|
1bebf7af74 | ||
|
|
f43ea6e7ff | ||
|
|
05ddccd657 | ||
|
|
4d6473908f | ||
|
|
4fb6f7b83d | ||
|
|
77d3830fda | ||
|
|
487731bcd3 | ||
|
|
7539b80e17 | ||
|
|
b5088858f6 | ||
|
|
a2ab45f547 | ||
|
|
8e75367ced | ||
|
|
141aec6186 | ||
|
|
0e44dd1677 | ||
|
|
5868f9ae1e | ||
|
|
5b18373a45 | ||
|
|
66a621d314 | ||
|
|
a2037bb238 |
6
doc/.gitignore
vendored
Normal file
6
doc/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
*.chapter.xml
|
||||||
|
*.section.xml
|
||||||
|
.version
|
||||||
|
out
|
||||||
|
manual-full.xml
|
||||||
|
highlightjs
|
||||||
96
doc/Makefile
Normal file
96
doc/Makefile
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
MD_TARGETS=$(addsuffix .xml, $(basename $(wildcard ./*.md ./**/*.md)))
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: validate out/html/index.html out/epub/manual.epub
|
||||||
|
|
||||||
|
.PHONY: debug
|
||||||
|
debug:
|
||||||
|
nix-shell --run "xmloscopy --docbook5 ./manual.xml ./manual-full.xml"
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f ${MD_TARGETS} .version manual-full.xml
|
||||||
|
rm -rf ./out/ ./highlightjs
|
||||||
|
|
||||||
|
.PHONY: validate
|
||||||
|
validate: manual-full.xml
|
||||||
|
jing "$$RNG" manual-full.xml
|
||||||
|
|
||||||
|
out/html/index.html: manual-full.xml style.css highlightjs
|
||||||
|
mkdir -p out/html
|
||||||
|
xsltproc ${xsltFlags} \
|
||||||
|
--nonet --xinclude \
|
||||||
|
--output $@ \
|
||||||
|
"$$XSL/docbook/xhtml/docbook.xsl" \
|
||||||
|
./manual-full.xml
|
||||||
|
|
||||||
|
mkdir -p out/html/highlightjs/
|
||||||
|
echo "document.onreadystatechange = function () { \
|
||||||
|
var listings = document.querySelectorAll('.programlisting, .screen'); \
|
||||||
|
for (i = 0; i < listings.length; ++i) { \
|
||||||
|
hljs.highlightBlock(listings[i]); \
|
||||||
|
} \
|
||||||
|
} " > out/html/highlightjs/loader.js
|
||||||
|
|
||||||
|
cp -r highlightjs out/html/
|
||||||
|
|
||||||
|
cp ./overrides.css out/html/
|
||||||
|
cp ./style.css out/html/style.css
|
||||||
|
|
||||||
|
mkdir -p out/html/images/callouts
|
||||||
|
cp "$$XSL/docbook/images/callouts/"*.svg out/html/images/callouts/
|
||||||
|
chmod u+w -R out/html/
|
||||||
|
|
||||||
|
out/epub/manual.epub: manual-full.xml
|
||||||
|
mkdir -p out/epub/scratch
|
||||||
|
xsltproc ${xsltFlags} --nonet \
|
||||||
|
--output out/epub/scratch/ \
|
||||||
|
"$$XSL/docbook/epub/docbook.xsl" \
|
||||||
|
./manual-full.xml
|
||||||
|
|
||||||
|
cp ./overrides.css out/epub/scratch/OEBPS
|
||||||
|
cp ./style.css out/epub/scratch/OEBPS
|
||||||
|
mkdir -p out/epub/scratch/OEBPS/images/callouts/
|
||||||
|
cp "$$XSL/docbook/images/callouts/"*.svg out/epub/scratch/OEBPS/images/callouts/
|
||||||
|
echo "application/epub+zip" > mimetype
|
||||||
|
zip -0Xq "out/epub/manual.epub" mimetype
|
||||||
|
rm mimetype
|
||||||
|
cd "out/epub/scratch/" && zip -Xr9D "../manual.epub" *
|
||||||
|
rm -rf "out/epub/scratch/"
|
||||||
|
|
||||||
|
highlightjs:
|
||||||
|
mkdir -p highlightjs
|
||||||
|
cp -r "$$HIGHLIGHTJS/highlight.pack.js" highlightjs/
|
||||||
|
cp -r "$$HIGHLIGHTJS/LICENSE" highlightjs/
|
||||||
|
cp -r "$$HIGHLIGHTJS/mono-blue.css" highlightjs/
|
||||||
|
|
||||||
|
|
||||||
|
manual-full.xml: ${MD_TARGETS} .version *.xml
|
||||||
|
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
|
||||||
|
|
||||||
|
.version:
|
||||||
|
nix-instantiate --eval \
|
||||||
|
-E '(import ../lib).nixpkgsVersion' > .version
|
||||||
|
|
||||||
|
%.section.xml: %.section.md
|
||||||
|
pandoc $^ -w docbook+smart \
|
||||||
|
-f markdown+smart \
|
||||||
|
| sed -e 's|<ulink url=|<link xlink:href=|' \
|
||||||
|
-e 's|</ulink>|</link>|' \
|
||||||
|
-e 's|<sect. id=|<section xml:id=|' \
|
||||||
|
-e 's|</sect[0-9]>|</section>|' \
|
||||||
|
-e '1s| id=| xml:id=|' \
|
||||||
|
-e '1s|\(<[^ ]* \)|\1xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" |' \
|
||||||
|
| cat > $@
|
||||||
|
|
||||||
|
%.chapter.xml: %.chapter.md
|
||||||
|
pandoc $^ -w docbook+smart \
|
||||||
|
--top-level-division=chapter \
|
||||||
|
-f markdown+smart \
|
||||||
|
| sed -e 's|<ulink url=|<link xlink:href=|' \
|
||||||
|
-e 's|</ulink>|</link>|' \
|
||||||
|
-e 's|<sect. id=|<section xml:id=|' \
|
||||||
|
-e 's|</sect[0-9]>|</section>|' \
|
||||||
|
-e '1s| id=| xml:id=|' \
|
||||||
|
-e '1s|\(<[^ ]* \)|\1|' \
|
||||||
|
| cat > $@
|
||||||
@@ -6,12 +6,27 @@
|
|||||||
|
|
||||||
<para>The DocBook sources of the Nixpkgs manual are in the <filename
|
<para>The DocBook sources of the Nixpkgs manual are in the <filename
|
||||||
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/doc">doc</filename>
|
xlink:href="https://github.com/NixOS/nixpkgs/tree/master/doc">doc</filename>
|
||||||
subdirectory of the Nixpkgs repository. If you make modifications to
|
subdirectory of the Nixpkgs repository.</para>
|
||||||
the manual, it's important to build it before committing. You can do that as follows:
|
|
||||||
|
<para>You can quickly check your edits with <command>make</command>:</para>
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
$ cd /path/to/nixpkgs
|
$ cd /path/to/nixpkgs/doc
|
||||||
$ nix-build doc
|
$ nix-shell
|
||||||
|
[nix-shell]$ make
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
<para>If you experience problems, run <command>make debug</command>
|
||||||
|
to help understand the docbook errors.</para>
|
||||||
|
|
||||||
|
<para>After making modifications to the manual, it's important to
|
||||||
|
build it before committing. You can do that as follows:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ cd /path/to/nixpkgs/doc
|
||||||
|
$ nix-shell
|
||||||
|
[nix-shell]$ make clean
|
||||||
|
[nix-shell]$ nix-build .
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
If the build succeeds, the manual will be in
|
If the build succeeds, the manual will be in
|
||||||
|
|||||||
131
doc/default.nix
131
doc/default.nix
@@ -7,112 +7,41 @@ in
|
|||||||
pkgs.stdenv.mkDerivation {
|
pkgs.stdenv.mkDerivation {
|
||||||
name = "nixpkgs-manual";
|
name = "nixpkgs-manual";
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [ pandoc libxml2 libxslt zip jing ];
|
||||||
|
|
||||||
buildInputs = with pkgs; [ pandoc libxml2 libxslt zip ];
|
src = ./.;
|
||||||
|
|
||||||
xsltFlags = ''
|
# Hacking on these variables? Make sure to close and open
|
||||||
--param section.autolabel 1
|
# nix-shell between each test, maybe even:
|
||||||
--param section.label.includes.component.label 1
|
# $ nix-shell --run "make clean all"
|
||||||
--param html.stylesheet 'style.css'
|
# otherwise they won't reapply :)
|
||||||
--param xref.with.number.and.title 1
|
HIGHLIGHTJS = pkgs.documentation-highlighter;
|
||||||
--param toc.section.depth 3
|
XSL = "${pkgs.docbook5_xsl}/xml/xsl";
|
||||||
--param admon.style '''
|
RNG = "${pkgs.docbook5}/xml/rng/docbook/docbook.rng";
|
||||||
--param callout.graphics.extension '.gif'
|
xsltFlags = lib.concatStringsSep " " [
|
||||||
|
"--param section.autolabel 1"
|
||||||
|
"--param section.label.includes.component.label 1"
|
||||||
|
"--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'"
|
||||||
|
"--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'"
|
||||||
|
"--param xref.with.number.and.title 1"
|
||||||
|
"--param toc.section.depth 3"
|
||||||
|
"--stringparam admon.style ''"
|
||||||
|
"--stringparam callout.graphics.extension .svg"
|
||||||
|
];
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
echo ${lib.nixpkgsVersion} > .version
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
dest="$out/share/doc/nixpkgs"
|
||||||
|
mkdir -p "$(dirname "$dest")"
|
||||||
|
mv out/html "$dest"
|
||||||
|
mv "$dest/index.html" "$dest/manual.html"
|
||||||
|
|
||||||
buildCommand = let toDocbook = { useChapters ? false, inputFile, outputFile }:
|
mv out/epub/manual.epub "$dest/nixpkgs-manual.epub"
|
||||||
let
|
|
||||||
extraHeader = lib.optionalString (!useChapters)
|
|
||||||
''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
|
|
||||||
in ''
|
|
||||||
{
|
|
||||||
pandoc '${inputFile}' -w docbook+smart ${lib.optionalString useChapters "--top-level-division=chapter"} \
|
|
||||||
-f markdown+smart \
|
|
||||||
| sed -e 's|<ulink url=|<link xlink:href=|' \
|
|
||||||
-e 's|</ulink>|</link>|' \
|
|
||||||
-e 's|<sect. id=|<section xml:id=|' \
|
|
||||||
-e 's|</sect[0-9]>|</section>|' \
|
|
||||||
-e '1s| id=| xml:id=|' \
|
|
||||||
-e '1s|\(<[^ ]* \)|\1${extraHeader}|'
|
|
||||||
} > '${outputFile}'
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
|
|
||||||
''
|
mkdir -p $out/nix-support/
|
||||||
ln -s '${sources}/'*.xml .
|
echo "doc manual $dest manual.html" >> $out/nix-support/hydra-build-products
|
||||||
mkdir ./languages-frameworks
|
|
||||||
cp -s '${sources-langs}'/* ./languages-frameworks
|
|
||||||
''
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ./introduction.md;
|
|
||||||
outputFile = "introduction.xml";
|
|
||||||
useChapters = true;
|
|
||||||
}
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ./shell.md;
|
|
||||||
outputFile = "shell.xml";
|
|
||||||
}
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ./languages-frameworks/python.md;
|
|
||||||
outputFile = "./languages-frameworks/python.xml";
|
|
||||||
}
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ./languages-frameworks/haskell.md;
|
|
||||||
outputFile = "./languages-frameworks/haskell.xml";
|
|
||||||
}
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ../pkgs/development/idris-modules/README.md;
|
|
||||||
outputFile = "languages-frameworks/idris.xml";
|
|
||||||
}
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ../pkgs/development/node-packages/README.md;
|
|
||||||
outputFile = "languages-frameworks/node.xml";
|
|
||||||
}
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ../pkgs/development/r-modules/README.md;
|
|
||||||
outputFile = "languages-frameworks/r.xml";
|
|
||||||
}
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ./languages-frameworks/rust.md;
|
|
||||||
outputFile = "./languages-frameworks/rust.xml";
|
|
||||||
}
|
|
||||||
+ toDocbook {
|
|
||||||
inputFile = ./languages-frameworks/vim.md;
|
|
||||||
outputFile = "./languages-frameworks/vim.xml";
|
|
||||||
}
|
|
||||||
+ ''
|
|
||||||
echo ${lib.nixpkgsVersion} > .version
|
|
||||||
|
|
||||||
# validate against relaxng schema
|
|
||||||
xmllint --nonet --xinclude --noxincludenode manual.xml --output manual-full.xml
|
|
||||||
${pkgs.jing}/bin/jing ${pkgs.docbook5}/xml/rng/docbook/docbook.rng manual-full.xml
|
|
||||||
|
|
||||||
dst=$out/share/doc/nixpkgs
|
|
||||||
mkdir -p $dst
|
|
||||||
xsltproc $xsltFlags --nonet --xinclude \
|
|
||||||
--output $dst/manual.html \
|
|
||||||
${pkgs.docbook5_xsl}/xml/xsl/docbook/xhtml/docbook.xsl \
|
|
||||||
./manual.xml
|
|
||||||
|
|
||||||
cp ${./style.css} $dst/style.css
|
|
||||||
|
|
||||||
mkdir -p $dst/images/callouts
|
|
||||||
cp "${pkgs.docbook5_xsl}/xml/xsl/docbook/images/callouts/"*.gif $dst/images/callouts/
|
|
||||||
|
|
||||||
mkdir -p $out/nix-support
|
|
||||||
echo "doc manual $dst manual.html" >> $out/nix-support/hydra-build-products
|
|
||||||
|
|
||||||
xsltproc $xsltFlags --nonet --xinclude \
|
|
||||||
--output $dst/epub/ \
|
|
||||||
${pkgs.docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl \
|
|
||||||
./manual.xml
|
|
||||||
|
|
||||||
cp -r $dst/images $dst/epub/OEBPS
|
|
||||||
echo "application/epub+zip" > mimetype
|
|
||||||
manual="$dst/nixpkgs-manual.epub"
|
|
||||||
zip -0Xq "$manual" mimetype
|
|
||||||
cd $dst/epub && zip -Xr9D "$manual" *
|
|
||||||
rm -rf $dst/epub
|
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
39
doc/languages-frameworks/idris.section.md
Normal file
39
doc/languages-frameworks/idris.section.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
Idris packages
|
||||||
|
==============
|
||||||
|
|
||||||
|
This directory contains build rules for idris packages. In addition,
|
||||||
|
it contains several functions to build and compose those packages.
|
||||||
|
Everything is exposed to the user via the `idrisPackages` attribute.
|
||||||
|
|
||||||
|
callPackage
|
||||||
|
------------
|
||||||
|
|
||||||
|
This is like the normal nixpkgs callPackage function, specialized to
|
||||||
|
idris packages.
|
||||||
|
|
||||||
|
builtins
|
||||||
|
---------
|
||||||
|
|
||||||
|
This is a list of all of the libraries that come packaged with Idris
|
||||||
|
itself.
|
||||||
|
|
||||||
|
build-idris-package
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
A function to build an idris package. Its sole argument is a set like
|
||||||
|
you might pass to `stdenv.mkDerivation`, except `build-idris-package`
|
||||||
|
sets several attributes for you. See `build-idris-package.nix` for
|
||||||
|
details.
|
||||||
|
|
||||||
|
build-builtin-package
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
A version of `build-idris-package` specialized to builtin libraries.
|
||||||
|
Mostly for internal use.
|
||||||
|
|
||||||
|
with-packages
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Bundle idris together with a list of packages. Because idris currently
|
||||||
|
only supports a single directory in its library path, you must include
|
||||||
|
all desired libraries here, including `prelude` and `base`.
|
||||||
@@ -17,19 +17,18 @@ such as Perl or Haskell. These are described in this chapter.</para>
|
|||||||
<xi:include href="bower.xml" />
|
<xi:include href="bower.xml" />
|
||||||
<xi:include href="coq.xml" />
|
<xi:include href="coq.xml" />
|
||||||
<xi:include href="go.xml" />
|
<xi:include href="go.xml" />
|
||||||
<xi:include href="haskell.xml" />
|
<xi:include href="haskell.section.xml" />
|
||||||
<xi:include href="idris.xml" /> <!-- generated from ../../pkgs/development/idris-modules/README.md -->
|
<xi:include href="idris.section.xml" />
|
||||||
<xi:include href="java.xml" />
|
<xi:include href="java.xml" />
|
||||||
<xi:include href="lua.xml" />
|
<xi:include href="lua.xml" />
|
||||||
<xi:include href="node.xml" /> <!-- generated from ../../pkgs/development/node-packages/README.md -->
|
<xi:include href="node.section.xml" />
|
||||||
<xi:include href="perl.xml" />
|
<xi:include href="perl.xml" />
|
||||||
<xi:include href="python.xml" />
|
<xi:include href="python.section.xml" />
|
||||||
<xi:include href="qt.xml" />
|
<xi:include href="qt.xml" />
|
||||||
<xi:include href="r.xml" /> <!-- generated from ../../pkgs/development/r-modules/README.md -->
|
<xi:include href="r.section.xml" />
|
||||||
<xi:include href="ruby.xml" />
|
<xi:include href="ruby.xml" />
|
||||||
<xi:include href="rust.xml" />
|
<xi:include href="rust.section.xml" />
|
||||||
<xi:include href="texlive.xml" />
|
<xi:include href="texlive.xml" />
|
||||||
<xi:include href="vim.xml" />
|
<xi:include href="vim.section.xml" />
|
||||||
|
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|||||||
51
doc/languages-frameworks/node.section.md
Normal file
51
doc/languages-frameworks/node.section.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
Node.js packages
|
||||||
|
================
|
||||||
|
The `pkgs/development/node-packages` folder contains a generated collection of
|
||||||
|
[NPM packages](https://npmjs.com/) that can be installed with the Nix package
|
||||||
|
manager.
|
||||||
|
|
||||||
|
As a rule of thumb, the package set should only provide *end user* software
|
||||||
|
packages, such as command-line utilities. Libraries should only be added to the
|
||||||
|
package set if there is a non-NPM package that requires it.
|
||||||
|
|
||||||
|
When it is desired to use NPM libraries in a development project, use the
|
||||||
|
`node2nix` generator directly on the `package.json` configuration file of the
|
||||||
|
project.
|
||||||
|
|
||||||
|
The package set also provides support for multiple Node.js versions. The policy
|
||||||
|
is that a new package should be added to the collection for the latest stable LTS
|
||||||
|
release (which is currently 6.x), unless there is an explicit reason to support
|
||||||
|
a different release.
|
||||||
|
|
||||||
|
If your package uses native addons, you need to examine what kind of native
|
||||||
|
build system it uses. Here are some examples:
|
||||||
|
|
||||||
|
* `node-gyp`
|
||||||
|
* `node-gyp-builder`
|
||||||
|
* `node-pre-gyp`
|
||||||
|
|
||||||
|
After you have identified the correct system, you need to override your package
|
||||||
|
expression while adding in build system as a build input. For example, `dat`
|
||||||
|
requires `node-gyp-build`, so we override its expression in `default-v6.nix`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
dat = nodePackages.dat.override (oldAttrs: {
|
||||||
|
buildInputs = oldAttrs.buildInputs ++ [ nodePackages.node-gyp-build ];
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
To add a package from NPM to nixpkgs:
|
||||||
|
|
||||||
|
1. Modify `pkgs/development/node-packages/node-packages-v6.json` to add, update
|
||||||
|
or remove package entries. (Or `pkgs/development/node-packages/node-packages-v4.json`
|
||||||
|
for packages depending on Node.js 4.x)
|
||||||
|
2. Run the script: `(cd pkgs/development/node-packages && ./generate.sh)`.
|
||||||
|
3. Build your new package to test your changes:
|
||||||
|
`cd /path/to/nixpkgs && nix-build -A nodePackages.<new-or-updated-package>`.
|
||||||
|
To build against a specific Node.js version (e.g. 4.x):
|
||||||
|
`nix-build -A nodePackages_4_x.<new-or-updated-package>`
|
||||||
|
4. Add and commit all modified and generated files.
|
||||||
|
|
||||||
|
For more information about the generation process, consult the
|
||||||
|
[README.md](https://github.com/svanderburg/node2nix) file of the `node2nix`
|
||||||
|
tool.
|
||||||
@@ -871,8 +871,10 @@ Executing `python setup.py bdist_wheel` in a `nix-shell `fails with
|
|||||||
```
|
```
|
||||||
ValueError: ZIP does not support timestamps before 1980
|
ValueError: ZIP does not support timestamps before 1980
|
||||||
```
|
```
|
||||||
This is because files are included that depend on items in the Nix store which have a timestamp of, that is, it corresponds to January the 1st, 1970 at 00:00:00. And as the error informs you, ZIP does not support that.
|
|
||||||
The command `bdist_wheel` takes into account `SOURCE_DATE_EPOCH`, and `nix-shell` sets this to 1. By setting it to a value corresponding to 1980 or later, or by unsetting it, it is possible to build wheels.
|
This is because files from the Nix store (which have a timestamp of the UNIX epoch of January 1, 1970) are included in the .ZIP, but .ZIP archives follow the DOS convention of counting timestamps from 1980.
|
||||||
|
|
||||||
|
The command `bdist_wheel` reads the `SOURCE_DATE_EPOCH` environment variable, which `nix-shell` sets to 1. Unsetting this variable or giving it a value corresponding to 1980 or later enables building wheels.
|
||||||
|
|
||||||
Use 1980 as timestamp:
|
Use 1980 as timestamp:
|
||||||
```shell
|
```shell
|
||||||
@@ -882,7 +884,7 @@ or the current time:
|
|||||||
```shell
|
```shell
|
||||||
nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
|
nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
|
||||||
```
|
```
|
||||||
or unset:
|
or unset `SOURCE_DATE_EPOCH`:
|
||||||
```shell
|
```shell
|
||||||
nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
|
nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
|
||||||
```
|
```
|
||||||
120
doc/languages-frameworks/r.section.md
Normal file
120
doc/languages-frameworks/r.section.md
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
R packages
|
||||||
|
==========
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Define an environment for R that contains all the libraries that you'd like to
|
||||||
|
use by adding the following snippet to your $HOME/.config/nixpkgs/config.nix file:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
packageOverrides = super: let self = super.pkgs; in
|
||||||
|
{
|
||||||
|
|
||||||
|
rEnv = super.rWrapper.override {
|
||||||
|
packages = with self.rPackages; [
|
||||||
|
devtools
|
||||||
|
ggplot2
|
||||||
|
reshape2
|
||||||
|
yaml
|
||||||
|
optparse
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can use `nix-env -f "<nixpkgs>" -iA rEnv` to install it into your user
|
||||||
|
profile. The set of available libraries can be discovered by running the
|
||||||
|
command `nix-env -f "<nixpkgs>" -qaP -A rPackages`. The first column from that
|
||||||
|
output is the name that has to be passed to rWrapper in the code snipped above.
|
||||||
|
|
||||||
|
However, if you'd like to add a file to your project source to make the
|
||||||
|
environment available for other contributors, you can create a `default.nix`
|
||||||
|
file like so:
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> {};
|
||||||
|
stdenv = pkgs.stdenv;
|
||||||
|
in with pkgs; {
|
||||||
|
myProject = stdenv.mkDerivation {
|
||||||
|
name = "myProject";
|
||||||
|
version = "1";
|
||||||
|
src = if pkgs.lib.inNixShell then null else nix;
|
||||||
|
|
||||||
|
buildInputs = with rPackages; [
|
||||||
|
R
|
||||||
|
ggplot2
|
||||||
|
knitr
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
and then run `nix-shell .` to be dropped into a shell with those packages
|
||||||
|
available.
|
||||||
|
|
||||||
|
## RStudio
|
||||||
|
|
||||||
|
RStudio uses a standard set of packages and ignores any custom R
|
||||||
|
environments or installed packages you may have. To create a custom
|
||||||
|
environment, see `rstudioWrapper`, which functions similarly to
|
||||||
|
`rWrapper`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
packageOverrides = super: let self = super.pkgs; in
|
||||||
|
{
|
||||||
|
|
||||||
|
rstudioEnv = super.rstudioWrapper.override {
|
||||||
|
packages = with self.rPackages; [
|
||||||
|
dplyr
|
||||||
|
ggplot2
|
||||||
|
reshape2
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then like above, `nix-env -f "<nixpkgs>" -iA rstudioEnv` will install
|
||||||
|
this into your user profile.
|
||||||
|
|
||||||
|
Alternatively, you can create a self-contained `shell.nix` without the need to
|
||||||
|
modify any configuration files:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ pkgs ? import <nixpkgs> {}
|
||||||
|
}:
|
||||||
|
|
||||||
|
pkgs.rstudioWrapper.override {
|
||||||
|
packages = with pkgs.rPackages; [ dplyr ggplot2 reshape2 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Executing `nix-shell` will then drop you into an environment equivalent to the
|
||||||
|
one above. If you need additional packages just add them to the list and
|
||||||
|
re-enter the shell.
|
||||||
|
|
||||||
|
## Updating the package set
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-shell generate-shell.nix
|
||||||
|
|
||||||
|
Rscript generate-r-packages.R cran > cran-packages.nix.new
|
||||||
|
mv cran-packages.nix.new cran-packages.nix
|
||||||
|
|
||||||
|
Rscript generate-r-packages.R bioc > bioc-packages.nix.new
|
||||||
|
mv bioc-packages.nix.new bioc-packages.nix
|
||||||
|
```
|
||||||
|
|
||||||
|
`generate-r-packages.R <repo>` reads `<repo>-packages.nix`, therefor the renaming.
|
||||||
|
|
||||||
|
|
||||||
|
## Testing if the Nix-expression could be evaluated
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix-build test-evaluation.nix --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
If this exits fine, the expression is ok. If not, you have to edit `default.nix`
|
||||||
@@ -16,6 +16,12 @@ cargo
|
|||||||
into the `environment.systemPackages` or bring them into
|
into the `environment.systemPackages` or bring them into
|
||||||
scope with `nix-shell -p rustc cargo`.
|
scope with `nix-shell -p rustc cargo`.
|
||||||
|
|
||||||
|
> If you are using NixOS and you want to use rust without a nix expression you
|
||||||
|
> probably want to add the following in your `configuration.nix` to build
|
||||||
|
> crates with C dependencies.
|
||||||
|
>
|
||||||
|
> environment.systemPackages = [binutils gcc gnumake openssl pkgconfig]
|
||||||
|
|
||||||
For daily builds (beta and nightly) use either rustup from
|
For daily builds (beta and nightly) use either rustup from
|
||||||
nixpkgs or use the [Rust nightlies
|
nixpkgs or use the [Rust nightlies
|
||||||
overlay](#using-the-rust-nightlies-overlay).
|
overlay](#using-the-rust-nightlies-overlay).
|
||||||
@@ -76,7 +82,7 @@ an example for a minimal `hello` crate:
|
|||||||
Compiling hello v0.1.0 (file:///tmp/hello)
|
Compiling hello v0.1.0 (file:///tmp/hello)
|
||||||
Finished dev [unoptimized + debuginfo] target(s) in 0.20 secs
|
Finished dev [unoptimized + debuginfo] target(s) in 0.20 secs
|
||||||
$ carnix -o hello.nix --src ./. Cargo.lock --standalone
|
$ carnix -o hello.nix --src ./. Cargo.lock --standalone
|
||||||
$ nix-build hello.nix
|
$ nix-build hello.nix -A hello_0_1_0
|
||||||
|
|
||||||
Now, the file produced by the call to `carnix`, called `hello.nix`, looks like:
|
Now, the file produced by the call to `carnix`, called `hello.nix`, looks like:
|
||||||
|
|
||||||
@@ -276,6 +282,84 @@ features, we would write:
|
|||||||
|
|
||||||
Where `diesel.nix` is the file generated by Carnix, as explained above.
|
Where `diesel.nix` is the file generated by Carnix, as explained above.
|
||||||
|
|
||||||
|
|
||||||
|
## Setting Up `nix-shell`
|
||||||
|
Oftentimes you want to develop code from within `nix-shell`. Unfortunately
|
||||||
|
`buildRustCrate` does not support common `nix-shell` operations directly
|
||||||
|
(see [this issue](https://github.com/NixOS/nixpkgs/issues/37945))
|
||||||
|
so we will use `stdenv.mkDerivation` instead.
|
||||||
|
|
||||||
|
Using the example `hello` project above, we want to do the following:
|
||||||
|
- Have access to `cargo` and `rustc`
|
||||||
|
- Have the `openssl` library available to a crate through it's _normal_
|
||||||
|
compilation mechanism (`pkg-config`).
|
||||||
|
|
||||||
|
A typical `shell.nix` might look like:
|
||||||
|
|
||||||
|
```
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "rust-env";
|
||||||
|
buildInputs = [
|
||||||
|
rustc cargo
|
||||||
|
|
||||||
|
# Example Additional Dependencies
|
||||||
|
pkgconfig openssl
|
||||||
|
];
|
||||||
|
|
||||||
|
# Set Environment Variables
|
||||||
|
RUST_BACKTRACE = 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You should now be able to run the following:
|
||||||
|
```
|
||||||
|
$ nix-shell --pure
|
||||||
|
$ cargo build
|
||||||
|
$ cargo test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Controlling Rust Version Inside `nix-shell`
|
||||||
|
To control your rust version (i.e. use nightly) from within `shell.nix` (or
|
||||||
|
other nix expressions) you can use the following `shell.nix`
|
||||||
|
|
||||||
|
```
|
||||||
|
# Latest Nightly
|
||||||
|
with import <nixpkgs> {};
|
||||||
|
let src = fetchFromGitHub {
|
||||||
|
owner = "mozilla";
|
||||||
|
repo = "nixpkgs-mozilla";
|
||||||
|
# commit from: 2018-03-27
|
||||||
|
rev = "2945b0b6b2fd19e7d23bac695afd65e320efcebe";
|
||||||
|
sha256 = "034m1dryrzh2lmjvk3c0krgip652dql46w5yfwpvh7gavd3iypyw";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
with import "${src.out}/rust-overlay.nix" pkgs pkgs;
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "rust-env";
|
||||||
|
buildInputs = [
|
||||||
|
# Note: to use use stable, just replace `nightly` with `stable`
|
||||||
|
latest.rustChannels.nightly.rust
|
||||||
|
|
||||||
|
# Add some extra dependencies from `pkgs`
|
||||||
|
pkgconfig openssl
|
||||||
|
];
|
||||||
|
|
||||||
|
# Set Environment Variables
|
||||||
|
RUST_BACKTRACE = 1;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now run:
|
||||||
|
```
|
||||||
|
$ rustc --version
|
||||||
|
rustc 1.26.0-nightly (188e693b3 2018-03-26)
|
||||||
|
```
|
||||||
|
|
||||||
|
To see that you are using nightly.
|
||||||
|
|
||||||
|
|
||||||
## Using the Rust nightlies overlay
|
## Using the Rust nightlies overlay
|
||||||
|
|
||||||
Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.
|
Mozilla provides an overlay for nixpkgs to bring a nightly version of Rust into scope.
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
</info>
|
</info>
|
||||||
|
|
||||||
<xi:include href="introduction.xml" />
|
<xi:include href="introduction.chapter.xml" />
|
||||||
<xi:include href="quick-start.xml" />
|
<xi:include href="quick-start.xml" />
|
||||||
<xi:include href="stdenv.xml" />
|
<xi:include href="stdenv.xml" />
|
||||||
<xi:include href="multiple-output.xml" />
|
<xi:include href="multiple-output.xml" />
|
||||||
|
|||||||
8
doc/overrides.css
Normal file
8
doc/overrides.css
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
.programlisting img {
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calloutlist img {
|
||||||
|
width: 1.5em;
|
||||||
|
}
|
||||||
4
doc/shell.nix
Normal file
4
doc/shell.nix
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs ? import ../. {} }:
|
||||||
|
(import ./default.nix).overrideAttrs (x: {
|
||||||
|
buildInputs = x.buildInputs ++ [ pkgs.xmloscopy ];
|
||||||
|
})
|
||||||
@@ -4,6 +4,8 @@ author: zimbatm
|
|||||||
date: 2017-10-30
|
date: 2017-10-30
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# mkShell
|
||||||
|
|
||||||
pkgs.mkShell is a special kind of derivation that is only useful when using
|
pkgs.mkShell is a special kind of derivation that is only useful when using
|
||||||
it combined with nix-shell. It will in fact fail to instantiate when invoked
|
it combined with nix-shell. It will in fact fail to instantiate when invoked
|
||||||
with nix-build.
|
with nix-build.
|
||||||
@@ -29,8 +29,8 @@ h2 /* chapters, appendices, subtitle */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Extra space between chapters, appendices. */
|
/* Extra space between chapters, appendices. */
|
||||||
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
|
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
|
||||||
{
|
{
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ pre.screen, pre.programlisting
|
|||||||
padding: 3px 3px;
|
padding: 3px 3px;
|
||||||
margin-left: 1.5em;
|
margin-left: 1.5em;
|
||||||
margin-right: 1.5em;
|
margin-right: 1.5em;
|
||||||
color: #600000;
|
|
||||||
background: #f4f4f8;
|
background: #f4f4f8;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
border-radius: 0.4em;
|
border-radius: 0.4em;
|
||||||
@@ -118,7 +118,6 @@ div.example pre.programlisting
|
|||||||
margin: 0 0 0 0;
|
margin: 0 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Notes, warnings etc:
|
Notes, warnings etc:
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@@ -172,7 +171,7 @@ div.navfooter *
|
|||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Links colors and highlighting:
|
Links colors and highlighting:
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
a { text-decoration: none; }
|
a { text-decoration: none; }
|
||||||
@@ -209,7 +208,7 @@ tt, code
|
|||||||
.term
|
.term
|
||||||
{
|
{
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.variablelist dd p, div.glosslist dd p
|
div.variablelist dd p, div.glosslist dd p
|
||||||
@@ -252,4 +251,4 @@ table
|
|||||||
div.affiliation
|
div.affiliation
|
||||||
{
|
{
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ let
|
|||||||
|
|
||||||
# packaging
|
# packaging
|
||||||
customisation = callLibs ./customisation.nix;
|
customisation = callLibs ./customisation.nix;
|
||||||
maintainers = import ./maintainers-list.nix;
|
maintainers = import ../maintainers/maintainer-list.nix;
|
||||||
meta = callLibs ./meta.nix;
|
meta = callLibs ./meta.nix;
|
||||||
sources = callLibs ./sources.nix;
|
sources = callLibs ./sources.nix;
|
||||||
versions = callLibs ./versions.nix;
|
versions = callLibs ./versions.nix;
|
||||||
|
|||||||
@@ -660,7 +660,7 @@ rec {
|
|||||||
doRename = { from, to, visible, warn, use }:
|
doRename = { from, to, visible, warn, use }:
|
||||||
let
|
let
|
||||||
toOf = attrByPath to
|
toOf = attrByPath to
|
||||||
(abort "Renaming error: option `${showOption to}' does not exists.");
|
(abort "Renaming error: option `${showOption to}' does not exist.");
|
||||||
in
|
in
|
||||||
{ config, options, ... }:
|
{ config, options, ... }:
|
||||||
{ options = setAttrByPath from (mkOption {
|
{ options = setAttrByPath from (mkOption {
|
||||||
|
|||||||
@@ -176,6 +176,11 @@
|
|||||||
github = "abigailbuccaneer";
|
github = "abigailbuccaneer";
|
||||||
name = "Abigail Bunyan";
|
name = "Abigail Bunyan";
|
||||||
};
|
};
|
||||||
|
aborsu = {
|
||||||
|
email = "a.borsu@gmail.com";
|
||||||
|
github = "aborsu";
|
||||||
|
name = "Augustin Borsu";
|
||||||
|
};
|
||||||
aboseley = {
|
aboseley = {
|
||||||
email = "adam.boseley@gmail.com";
|
email = "adam.boseley@gmail.com";
|
||||||
github = "aboseley";
|
github = "aboseley";
|
||||||
@@ -314,6 +319,11 @@
|
|||||||
github = "amiloradovsky";
|
github = "amiloradovsky";
|
||||||
name = "Andrew Miloradovsky";
|
name = "Andrew Miloradovsky";
|
||||||
};
|
};
|
||||||
|
aminechikhaoui = {
|
||||||
|
email = "amine.chikhaoui91@gmail.com";
|
||||||
|
github = "AmineChikhaoui";
|
||||||
|
name = "Amine Chikhaoui";
|
||||||
|
};
|
||||||
amorsillo = {
|
amorsillo = {
|
||||||
email = "andrew.morsillo@gmail.com";
|
email = "andrew.morsillo@gmail.com";
|
||||||
github = "AndrewMorsillo";
|
github = "AndrewMorsillo";
|
||||||
@@ -555,7 +565,6 @@
|
|||||||
};
|
};
|
||||||
bjg = {
|
bjg = {
|
||||||
email = "bjg@gnu.org";
|
email = "bjg@gnu.org";
|
||||||
github = "civodul";
|
|
||||||
name = "Brian Gough";
|
name = "Brian Gough";
|
||||||
};
|
};
|
||||||
bjornfor = {
|
bjornfor = {
|
||||||
@@ -632,11 +641,6 @@
|
|||||||
github = "calbrecht";
|
github = "calbrecht";
|
||||||
name = "Christian Albrecht";
|
name = "Christian Albrecht";
|
||||||
};
|
};
|
||||||
calrama = {
|
|
||||||
email = "moritz@ucworks.org";
|
|
||||||
github = "MoritzMaxeiner";
|
|
||||||
name = "Moritz Maxeiner";
|
|
||||||
};
|
|
||||||
calvertvl = {
|
calvertvl = {
|
||||||
email = "calvertvl@gmail.com";
|
email = "calvertvl@gmail.com";
|
||||||
github = "calvertvl";
|
github = "calvertvl";
|
||||||
@@ -1524,6 +1528,11 @@
|
|||||||
github = "hrdinka";
|
github = "hrdinka";
|
||||||
name = "Christoph Hrdinka";
|
name = "Christoph Hrdinka";
|
||||||
};
|
};
|
||||||
|
hschaeidt = {
|
||||||
|
email = "he.schaeidt@gmail.com";
|
||||||
|
github = "hschaeidt";
|
||||||
|
name = "Hendrik Schaeidt";
|
||||||
|
};
|
||||||
htr = {
|
htr = {
|
||||||
email = "hugo@linux.com";
|
email = "hugo@linux.com";
|
||||||
github = "htr";
|
github = "htr";
|
||||||
@@ -1663,7 +1672,7 @@
|
|||||||
name = "Johannes Frankenau";
|
name = "Johannes Frankenau";
|
||||||
};
|
};
|
||||||
jgeerds = {
|
jgeerds = {
|
||||||
email = "jascha@jgeerds.name";
|
email = "jascha@geerds.org";
|
||||||
github = "jgeerds";
|
github = "jgeerds";
|
||||||
name = "Jascha Geerds";
|
name = "Jascha Geerds";
|
||||||
};
|
};
|
||||||
@@ -2013,6 +2022,11 @@
|
|||||||
github = "lo1tuma";
|
github = "lo1tuma";
|
||||||
name = "Mathias Schreck";
|
name = "Mathias Schreck";
|
||||||
};
|
};
|
||||||
|
lopsided98 = {
|
||||||
|
email = "benwolsieffer@gmail.com";
|
||||||
|
github = "lopsided98";
|
||||||
|
name = "Ben Wolsieffer";
|
||||||
|
};
|
||||||
loskutov = {
|
loskutov = {
|
||||||
email = "ignat.loskutov@gmail.com";
|
email = "ignat.loskutov@gmail.com";
|
||||||
github = "loskutov";
|
github = "loskutov";
|
||||||
@@ -3155,6 +3169,11 @@
|
|||||||
github = "sellout";
|
github = "sellout";
|
||||||
name = "Greg Pfeil";
|
name = "Greg Pfeil";
|
||||||
};
|
};
|
||||||
|
sengaya = {
|
||||||
|
email = "tlo@sengaya.de";
|
||||||
|
github = "sengaya";
|
||||||
|
name = "Thilo Uttendorfer";
|
||||||
|
};
|
||||||
sepi = {
|
sepi = {
|
||||||
email = "raffael@mancini.lu";
|
email = "raffael@mancini.lu";
|
||||||
github = "sepi";
|
github = "sepi";
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#! /usr/bin/env nix-shell
|
#! /usr/bin/env nix-shell
|
||||||
#! nix-shell -i python3 -p 'python3.withPackages(ps: with ps; [ packaging requests toolz ])' -p git
|
#! nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ packaging requests toolz ])" -p git
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Update a Python package expression by passing in the `.nix` file, or the directory containing it.
|
Update a Python package expression by passing in the `.nix` file, or the directory containing it.
|
||||||
@@ -358,4 +358,4 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -282,8 +282,8 @@ options.mod = mkOption {
|
|||||||
option set (<xref linkend='ex-submodule-listof-definition' />).</para>
|
option set (<xref linkend='ex-submodule-listof-definition' />).</para>
|
||||||
|
|
||||||
|
|
||||||
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
|
<example xml:id='ex-submodule-listof-declaration'><title>Declaration of a list
|
||||||
nof submodules</title>
|
of submodules</title>
|
||||||
<screen>
|
<screen>
|
||||||
options.mod = mkOption {
|
options.mod = mkOption {
|
||||||
description = "submodule example";
|
description = "submodule example";
|
||||||
|
|||||||
@@ -227,6 +227,18 @@ $ sudo groupdel nixbld</screen>
|
|||||||
line)</para></listitem>
|
line)</para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
<note><para>Support for <literal>NIXOS_LUSTRATE</literal> was added
|
||||||
|
in NixOS 16.09. The act of "lustrating" refers to the
|
||||||
|
wiping of the existing distribution. Creating
|
||||||
|
<literal>/etc/NIXOS_LUSTRATE</literal> can also be used on
|
||||||
|
NixOS to remove all mutable files from your root partition
|
||||||
|
(anything that's not in <literal>/nix</literal> or
|
||||||
|
<literal>/boot</literal> gets "lustrated" on the next
|
||||||
|
boot.</para>
|
||||||
|
<para>lustrate /ˈlʌstreɪt/ verb.</para>
|
||||||
|
<para>purify by expiatory sacrifice, ceremonial washing, or
|
||||||
|
some other ritual action.</para></note>
|
||||||
|
|
||||||
<para>Let's create the files:</para>
|
<para>Let's create the files:</para>
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
version="5.0"
|
version="5.0"
|
||||||
xml:id="sec-release-18.03">
|
xml:id="sec-release-18.03">
|
||||||
|
|
||||||
<title>Release 18.03 (“Impala”, 2018/03/??)</title>
|
<title>Release 18.03 (“Impala”, 2018/04/04)</title>
|
||||||
|
|
||||||
<section xmlns="http://docbook.org/ns/docbook"
|
<section xmlns="http://docbook.org/ns/docbook"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
@@ -18,6 +18,20 @@
|
|||||||
has the following highlights: </para>
|
has the following highlights: </para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
End of support is planned for end of October 2018, handing over to 18.09.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Platform support: x86_64-linux and x86_64-darwin since release time (the latter isn't NixOS, really).
|
||||||
|
Binaries for aarch64-linux are available, but no channel exists yet, as it's waiting for some test fixes, etc.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Nix now defaults to 2.0; see its
|
Nix now defaults to 2.0; see its
|
||||||
@@ -27,13 +41,13 @@ has the following highlights: </para>
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Linux kernel defaults to the 4.14 branch (it was 4.9).
|
Core version changes: linux: 4.9 -> 4.14, glibc: 2.25 -> 2.26, gcc: 6 -> 7, systemd: 234 -> 237.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
GCC defaults to 7.x (it was 6.x).
|
Desktop version changes: gnome: 3.24 -> 3.26, (KDE) plasma-desktop: 5.10 -> 5.12.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
@@ -59,13 +73,7 @@ has the following highlights: </para>
|
|||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>PHP now defaults to PHP 7.2, updated from 7.1.</para>
|
||||||
The GNOME version is now 3.26.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>PHP now defaults to PHP 7.2</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
@@ -81,9 +89,66 @@ has the following highlights: </para>
|
|||||||
<para>The following new services were added since the last release:</para>
|
<para>The following new services were added since the last release:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem><para><literal>./config/krb5/default.nix</literal></para></listitem>
|
||||||
<para></para>
|
<listitem><para><literal>./hardware/digitalbitbox.nix</literal></para></listitem>
|
||||||
</listitem>
|
<listitem><para><literal>./misc/label.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/ccache.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/criu.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/digitalbitbox/default.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/less.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/npm.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/plotinus.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/rootston.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/systemtap.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/sway.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/udevil.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/way-cooler.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/yabar.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./programs/zsh/zsh-autoenv.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/backup/borgbackup.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/backup/crashplan-small-business.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/desktops/dleyna-renderer.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/desktops/dleyna-server.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/desktops/pipewire.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/desktops/gnome3/chrome-gnome-shell.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/desktops/gnome3/tracker-miners.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/hardware/fwupd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/hardware/interception-tools.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/hardware/u2f.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/hardware/usbmuxd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/mail/clamsmtp.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/mail/dkimproxy-out.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/mail/pfix-srsd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/gitea.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/home-assistant.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/ihaskell.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/logkeys.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/novacomd.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/osrm.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/plexpy.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/pykms.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/misc/tzupdate.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/monitoring/fusion-inventory.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/monitoring/prometheus/exporters.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/network-filesystems/beegfs.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/network-filesystems/davfs2.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/network-filesystems/openafs/client.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/network-filesystems/openafs/server.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/network-filesystems/ceph.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/networking/aria2.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/networking/monero.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/networking/nghttpx/default.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/networking/nixops-dns.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/networking/rxe.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/networking/stunnel.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/web-apps/matomo.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/web-apps/restya-board.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/web-servers/mighttpd2.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./services/x11/fractalart.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./system/boot/binfmt.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./system/boot/grow-partition.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./tasks/filesystems/ecryptfs.nix</literal></para></listitem>
|
||||||
|
<listitem><para><literal>./virtualisation/hyperv-guest.nix</literal></para></listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@@ -322,6 +387,43 @@ following incompatible changes:</para>
|
|||||||
<link xlink:href="https://github.com/rvl/pump.io-nixos">external module</link>.
|
<link xlink:href="https://github.com/rvl/pump.io-nixos">external module</link>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The Prosody XMPP server has received a major update. The following modules were renamed:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>services.prosody.modules.httpserver</option> is now <option>services.prosody.modules.http_files</option>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<option>services.prosody.modules.console</option> is now <option>services.prosody.modules.admin_telnet</option>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Many new modules are now core modules, most notably <option>services.prosody.modules.carbons</option>
|
||||||
|
and <option>services.prosody.modules.mam</option>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The better-performing <literal>libevent</literal> backend is now enabled by default.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<literal>withCommunityModules</literal> now passes through the modules to <option>services.prosody.extraModules</option>.
|
||||||
|
Use <literal>withOnlyInstalledCommunityModules</literal> for modules that should not be enabled directly, e.g <literal>lib_ldap</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
All prometheus exporter modules are now defined as submodules.
|
||||||
|
The exporters are configured using <literal>services.prometheus.exporters</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@@ -381,15 +483,6 @@ following incompatible changes:</para>
|
|||||||
have been added to set up static routing.
|
have been added to set up static routing.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The option <option>services.xserver.desktopManager.default</option> is now
|
|
||||||
<literal>none</literal> by default. An assertion failure is thrown if WM's
|
|
||||||
and DM's default are <literal>none</literal>.
|
|
||||||
To explicitly run a plain X session without and DM or WM, the newly
|
|
||||||
introduced option <option>services.xserver.plainX</option> must be set to true.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The option <option>services.logstash.listenAddress</option> is now <literal>127.0.0.1</literal> by default.
|
The option <option>services.logstash.listenAddress</option> is now <literal>127.0.0.1</literal> by default.
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ with lib;
|
|||||||
networkmanager-l2tp = pkgs.networkmanager-l2tp.override { withGnome = false; };
|
networkmanager-l2tp = pkgs.networkmanager-l2tp.override { withGnome = false; };
|
||||||
networkmanager-openconnect = pkgs.networkmanager-openconnect.override { withGnome = false; };
|
networkmanager-openconnect = pkgs.networkmanager-openconnect.override { withGnome = false; };
|
||||||
networkmanager-openvpn = pkgs.networkmanager-openvpn.override { withGnome = false; };
|
networkmanager-openvpn = pkgs.networkmanager-openvpn.override { withGnome = false; };
|
||||||
networkmanager-pptp = pkgs.networkmanager-pptp.override { withGnome = false; };
|
|
||||||
networkmanager-vpnc = pkgs.networkmanager-vpnc.override { withGnome = false; };
|
networkmanager-vpnc = pkgs.networkmanager-vpnc.override { withGnome = false; };
|
||||||
networkmanager-iodine = pkgs.networkmanager-iodine.override { withGnome = false; };
|
networkmanager-iodine = pkgs.networkmanager-iodine.override { withGnome = false; };
|
||||||
pinentry = pkgs.pinentry_ncurses;
|
pinentry = pkgs.pinentry_ncurses;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ let
|
|||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
apply = x: assert (builtins.stringLength x < 32 || abort "Username '${x}' is longer than 31 characters which is not allowed!"); x;
|
||||||
description = ''
|
description = ''
|
||||||
The name of the user account. If undefined, the name of the
|
The name of the user account. If undefined, the name of the
|
||||||
attribute set will be used.
|
attribute set will be used.
|
||||||
@@ -91,6 +92,7 @@ let
|
|||||||
|
|
||||||
group = mkOption {
|
group = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
apply = x: assert (builtins.stringLength x < 17 || abort "Group name '${x}' is longer than 16 characters which is not allowed!"); x;
|
||||||
default = "nogroup";
|
default = "nogroup";
|
||||||
description = "The user's primary group.";
|
description = "The user's primary group.";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,13 +15,19 @@ let
|
|||||||
|
|
||||||
opengl = config.hardware.opengl;
|
opengl = config.hardware.opengl;
|
||||||
|
|
||||||
|
kernel = pkgs.linux_4_9.override {
|
||||||
|
extraConfig = ''
|
||||||
|
KALLSYMS_ALL y
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
config = mkIf enabled {
|
config = mkIf enabled {
|
||||||
|
|
||||||
nixpkgs.config.xorg.abiCompat = "1.18";
|
nixpkgs.config.xorg.abiCompat = "1.19";
|
||||||
|
|
||||||
services.xserver.drivers = singleton
|
services.xserver.drivers = singleton
|
||||||
{ name = "amdgpu"; modules = [ package ]; libPath = [ package ]; };
|
{ name = "amdgpu"; modules = [ package ]; libPath = [ package ]; };
|
||||||
@@ -31,6 +37,9 @@ in
|
|||||||
|
|
||||||
boot.extraModulePackages = [ package ];
|
boot.extraModulePackages = [ package ];
|
||||||
|
|
||||||
|
boot.kernelPackages =
|
||||||
|
pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor kernel);
|
||||||
|
|
||||||
boot.blacklistedKernelModules = [ "radeon" ];
|
boot.blacklistedKernelModules = [ "radeon" ];
|
||||||
|
|
||||||
hardware.firmware = [ package ];
|
hardware.firmware = [ package ];
|
||||||
@@ -38,10 +47,15 @@ in
|
|||||||
system.activationScripts.setup-amdgpu-pro = ''
|
system.activationScripts.setup-amdgpu-pro = ''
|
||||||
mkdir -p /run/lib
|
mkdir -p /run/lib
|
||||||
ln -sfn ${package}/lib ${package.libCompatDir}
|
ln -sfn ${package}/lib ${package.libCompatDir}
|
||||||
|
ln -sfn ${package} /run/amdgpu-pro
|
||||||
'' + optionalString opengl.driSupport32Bit ''
|
'' + optionalString opengl.driSupport32Bit ''
|
||||||
ln -sfn ${package32}/lib ${package32.libCompatDir}
|
ln -sfn ${package32}/lib ${package32.libCompatDir}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
system.requiredKernelConfig = with config.lib.kernelConfig; [
|
||||||
|
(isYes "KALLSYMS_ALL")
|
||||||
|
];
|
||||||
|
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"amd/amdrc".source = package + "/etc/amd/amdrc";
|
"amd/amdrc".source = package + "/etc/amd/amdrc";
|
||||||
"amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";
|
"amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ let
|
|||||||
kernelPackages.nvidia_x11
|
kernelPackages.nvidia_x11
|
||||||
else if elem "nvidiaBeta" drivers then
|
else if elem "nvidiaBeta" drivers then
|
||||||
kernelPackages.nvidia_x11_beta
|
kernelPackages.nvidia_x11_beta
|
||||||
else if elem "nvidiaLegacy173" drivers then
|
|
||||||
kernelPackages.nvidia_x11_legacy173
|
|
||||||
else if elem "nvidiaLegacy304" drivers then
|
else if elem "nvidiaLegacy304" drivers then
|
||||||
kernelPackages.nvidia_x11_legacy304
|
kernelPackages.nvidia_x11_legacy304
|
||||||
else if elem "nvidiaLegacy340" drivers then
|
else if elem "nvidiaLegacy340" drivers then
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ in
|
|||||||
"it cannot be cross compiled";
|
"it cannot be cross compiled";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Needed by RPi firmware
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
|
|
||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
boot.loader.generic-extlinux-compatible.enable = true;
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ in
|
|||||||
"it cannot be cross compiled";
|
"it cannot be cross compiled";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Needed by RPi firmware
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
|
|
||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
boot.loader.generic-extlinux-compatible.enable = true;
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ in
|
|||||||
"it cannot be cross compiled";
|
"it cannot be cross compiled";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Needed by RPi firmware
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
|
||||||
|
|
||||||
boot.loader.grub.enable = false;
|
boot.loader.grub.enable = false;
|
||||||
boot.loader.generic-extlinux-compatible.enable = true;
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,20 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.sdImage = {
|
options.sdImage = {
|
||||||
|
imageName = mkOption {
|
||||||
|
default = "${config.sdImage.imageBaseName}-${config.system.nixos.label}-${pkgs.stdenv.system}.img";
|
||||||
|
description = ''
|
||||||
|
Name of the generated image file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
imageBaseName = mkOption {
|
||||||
|
default = "nixos-sd-image";
|
||||||
|
description = ''
|
||||||
|
Prefix of the name of the generated image file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
storePaths = mkOption {
|
storePaths = mkOption {
|
||||||
type = with types; listOf package;
|
type = with types; listOf package;
|
||||||
example = literalExample "[ pkgs.stdenv ]";
|
example = literalExample "[ pkgs.stdenv ]";
|
||||||
@@ -61,19 +75,25 @@ in
|
|||||||
sdImage.storePaths = [ config.system.build.toplevel ];
|
sdImage.storePaths = [ config.system.build.toplevel ];
|
||||||
|
|
||||||
system.build.sdImage = pkgs.stdenv.mkDerivation {
|
system.build.sdImage = pkgs.stdenv.mkDerivation {
|
||||||
name = "sd-image-${pkgs.stdenv.system}.img";
|
name = config.sdImage.imageName;
|
||||||
|
|
||||||
buildInputs = with pkgs; [ dosfstools e2fsprogs mtools libfaketime utillinux ];
|
buildInputs = with pkgs; [ dosfstools e2fsprogs mtools libfaketime utillinux ];
|
||||||
|
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
|
mkdir -p $out/nix-support $out/sd-image
|
||||||
|
export img=$out/sd-image/${config.sdImage.imageName}
|
||||||
|
|
||||||
|
echo "${pkgs.stdenv.system}" > $out/nix-support/system
|
||||||
|
echo "file sd-image $img" >> $out/nix-support/hydra-build-products
|
||||||
|
|
||||||
# Create the image file sized to fit /boot and /, plus 20M of slack
|
# Create the image file sized to fit /boot and /, plus 20M of slack
|
||||||
rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
|
rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
|
||||||
bootSizeBlocks=$((${toString config.sdImage.bootSize} * 1024 * 1024 / 512))
|
bootSizeBlocks=$((${toString config.sdImage.bootSize} * 1024 * 1024 / 512))
|
||||||
imageSize=$((rootSizeBlocks * 512 + bootSizeBlocks * 512 + 20 * 1024 * 1024))
|
imageSize=$((rootSizeBlocks * 512 + bootSizeBlocks * 512 + 20 * 1024 * 1024))
|
||||||
truncate -s $imageSize $out
|
truncate -s $imageSize $img
|
||||||
|
|
||||||
# type=b is 'W95 FAT32', type=83 is 'Linux'.
|
# type=b is 'W95 FAT32', type=83 is 'Linux'.
|
||||||
sfdisk $out <<EOF
|
sfdisk $img <<EOF
|
||||||
label: dos
|
label: dos
|
||||||
label-id: 0x2178694e
|
label-id: 0x2178694e
|
||||||
|
|
||||||
@@ -82,11 +102,11 @@ in
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Copy the rootfs into the SD image
|
# Copy the rootfs into the SD image
|
||||||
eval $(partx $out -o START,SECTORS --nr 2 --pairs)
|
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
|
||||||
dd conv=notrunc if=${rootfsImage} of=$out seek=$START count=$SECTORS
|
dd conv=notrunc if=${rootfsImage} of=$img seek=$START count=$SECTORS
|
||||||
|
|
||||||
# Create a FAT32 /boot partition of suitable size into bootpart.img
|
# Create a FAT32 /boot partition of suitable size into bootpart.img
|
||||||
eval $(partx $out -o START,SECTORS --nr 1 --pairs)
|
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
|
||||||
truncate -s $((SECTORS * 512)) bootpart.img
|
truncate -s $((SECTORS * 512)) bootpart.img
|
||||||
faketime "1970-01-01 00:00:00" mkfs.vfat -i 0x2178694e -n NIXOS_BOOT bootpart.img
|
faketime "1970-01-01 00:00:00" mkfs.vfat -i 0x2178694e -n NIXOS_BOOT bootpart.img
|
||||||
|
|
||||||
@@ -96,7 +116,7 @@ in
|
|||||||
|
|
||||||
# Copy the populated /boot into the SD image
|
# Copy the populated /boot into the SD image
|
||||||
(cd boot; mcopy -bpsvm -i ../bootpart.img ./* ::)
|
(cd boot; mcopy -bpsvm -i ../bootpart.img ./* ::)
|
||||||
dd conv=notrunc if=bootpart.img of=$out seek=$START count=$SECTORS
|
dd conv=notrunc if=bootpart.img of=$img seek=$START count=$SECTORS
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -382,6 +382,6 @@ fi
|
|||||||
if [ "$action" = build-vm ]; then
|
if [ "$action" = build-vm ]; then
|
||||||
cat >&2 <<EOF
|
cat >&2 <<EOF
|
||||||
|
|
||||||
Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm).
|
Done. The virtual machine can be started by running $(echo $pathToConfig/bin/run-*-vm)
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -19,4 +19,6 @@ with lib;
|
|||||||
# Add some more video drivers to give X11 a shot at working in
|
# Add some more video drivers to give X11 a shot at working in
|
||||||
# VMware and QEMU.
|
# VMware and QEMU.
|
||||||
services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ];
|
services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ];
|
||||||
|
|
||||||
|
powerManagement.enable = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,21 @@ in
|
|||||||
|
|
||||||
options.system = {
|
options.system = {
|
||||||
|
|
||||||
|
# XXX: Reintroduce old options to make nixops before 1.6 able to evaluate configurations
|
||||||
|
# XXX: Remove after nixops has been bumped to a compatible version
|
||||||
|
nixosVersion = mkOption {
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
type = types.str;
|
||||||
|
default = config.system.nixos.version;
|
||||||
|
};
|
||||||
|
nixosVersionSuffix = mkOption {
|
||||||
|
readOnly = true;
|
||||||
|
internal = true;
|
||||||
|
type = types.str;
|
||||||
|
default = config.system.nixos.versionSuffix;
|
||||||
|
};
|
||||||
|
|
||||||
nixos.version = mkOption {
|
nixos.version = mkOption {
|
||||||
internal = true;
|
internal = true;
|
||||||
type = types.str;
|
type = types.str;
|
||||||
@@ -70,7 +85,7 @@ in
|
|||||||
defaultChannel = mkOption {
|
defaultChannel = mkOption {
|
||||||
internal = true;
|
internal = true;
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = https://nixos.org/channels/nixos-unstable;
|
default = https://nixos.org/channels/nixos-18.03;
|
||||||
description = "Default NixOS channel to which the root user is subscribed.";
|
description = "Default NixOS channel to which the root user is subscribed.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,7 @@
|
|||||||
./services/audio/ympd.nix
|
./services/audio/ympd.nix
|
||||||
./services/backup/almir.nix
|
./services/backup/almir.nix
|
||||||
./services/backup/bacula.nix
|
./services/backup/bacula.nix
|
||||||
|
./services/backup/borgbackup.nix
|
||||||
./services/backup/crashplan.nix
|
./services/backup/crashplan.nix
|
||||||
./services/backup/crashplan-small-business.nix
|
./services/backup/crashplan-small-business.nix
|
||||||
./services/backup/mysql-backup.nix
|
./services/backup/mysql-backup.nix
|
||||||
@@ -322,7 +323,7 @@
|
|||||||
./services/misc/geoip-updater.nix
|
./services/misc/geoip-updater.nix
|
||||||
./services/misc/gitea.nix
|
./services/misc/gitea.nix
|
||||||
#./services/misc/gitit.nix
|
#./services/misc/gitit.nix
|
||||||
./services/misc/gitlab.nix
|
#./services/misc/gitlab.nix
|
||||||
./services/misc/gitolite.nix
|
./services/misc/gitolite.nix
|
||||||
./services/misc/gogs.nix
|
./services/misc/gogs.nix
|
||||||
./services/misc/gollum.nix
|
./services/misc/gollum.nix
|
||||||
@@ -396,16 +397,7 @@
|
|||||||
./services/monitoring/osquery.nix
|
./services/monitoring/osquery.nix
|
||||||
./services/monitoring/prometheus/default.nix
|
./services/monitoring/prometheus/default.nix
|
||||||
./services/monitoring/prometheus/alertmanager.nix
|
./services/monitoring/prometheus/alertmanager.nix
|
||||||
./services/monitoring/prometheus/blackbox-exporter.nix
|
./services/monitoring/prometheus/exporters.nix
|
||||||
./services/monitoring/prometheus/collectd-exporter.nix
|
|
||||||
./services/monitoring/prometheus/fritzbox-exporter.nix
|
|
||||||
./services/monitoring/prometheus/json-exporter.nix
|
|
||||||
./services/monitoring/prometheus/minio-exporter.nix
|
|
||||||
./services/monitoring/prometheus/nginx-exporter.nix
|
|
||||||
./services/monitoring/prometheus/node-exporter.nix
|
|
||||||
./services/monitoring/prometheus/snmp-exporter.nix
|
|
||||||
./services/monitoring/prometheus/unifi-exporter.nix
|
|
||||||
./services/monitoring/prometheus/varnish-exporter.nix
|
|
||||||
./services/monitoring/riemann.nix
|
./services/monitoring/riemann.nix
|
||||||
./services/monitoring/riemann-dash.nix
|
./services/monitoring/riemann-dash.nix
|
||||||
./services/monitoring/riemann-tools.nix
|
./services/monitoring/riemann-tools.nix
|
||||||
|
|||||||
@@ -10,4 +10,10 @@
|
|||||||
password = "demo";
|
password = "demo";
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.xserver.displayManager.sddm.autoLogin = {
|
||||||
|
enable = true;
|
||||||
|
relogin = true;
|
||||||
|
user = "demo";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ in
|
|||||||
programs.bash = {
|
programs.bash = {
|
||||||
|
|
||||||
shellInit = ''
|
shellInit = ''
|
||||||
. ${config.system.build.setEnvironment}
|
${config.system.build.setEnvironment.text}
|
||||||
|
|
||||||
${cfge.shellInit}
|
${cfge.shellInit}
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ in
|
|||||||
if [ -n "$__ETC_ZSHENV_SOURCED" ]; then return; fi
|
if [ -n "$__ETC_ZSHENV_SOURCED" ]; then return; fi
|
||||||
export __ETC_ZSHENV_SOURCED=1
|
export __ETC_ZSHENV_SOURCED=1
|
||||||
|
|
||||||
. ${config.system.build.setEnvironment}
|
${config.system.build.setEnvironment.text}
|
||||||
|
|
||||||
${cfge.shellInit}
|
${cfge.shellInit}
|
||||||
|
|
||||||
|
|||||||
@@ -196,9 +196,9 @@ with lib;
|
|||||||
(mkRenamedOptionModule [ "virtualization" "growPartition" ] [ "boot" "growPartition" ])
|
(mkRenamedOptionModule [ "virtualization" "growPartition" ] [ "boot" "growPartition" ])
|
||||||
|
|
||||||
# misc/version.nix
|
# misc/version.nix
|
||||||
(mkRenamedOptionModule [ "config" "system" "nixosVersion" ] [ "config" "system" "nixos" "version" ])
|
#(mkRenamedOptionModule [ "config" "system" "nixosVersion" ] [ "config" "system" "nixos" "version" ])
|
||||||
(mkRenamedOptionModule [ "config" "system" "nixosRelease" ] [ "config" "system" "nixos" "release" ])
|
(mkRenamedOptionModule [ "config" "system" "nixosRelease" ] [ "config" "system" "nixos" "release" ])
|
||||||
(mkRenamedOptionModule [ "config" "system" "nixosVersionSuffix" ] [ "config" "system" "nixos" "versionSuffix" ])
|
#(mkRenamedOptionModule [ "config" "system" "nixosVersionSuffix" ] [ "config" "system" "nixos" "versionSuffix" ])
|
||||||
(mkRenamedOptionModule [ "config" "system" "nixosRevision" ] [ "config" "system" "nixos" "revision" ])
|
(mkRenamedOptionModule [ "config" "system" "nixosRevision" ] [ "config" "system" "nixos" "revision" ])
|
||||||
(mkRenamedOptionModule [ "config" "system" "nixosCodeName" ] [ "config" "system" "nixos" "codeName" ])
|
(mkRenamedOptionModule [ "config" "system" "nixosCodeName" ] [ "config" "system" "nixos" "codeName" ])
|
||||||
(mkRenamedOptionModule [ "config" "system" "nixosLabel" ] [ "config" "system" "nixos" "label" ])
|
(mkRenamedOptionModule [ "config" "system" "nixosLabel" ] [ "config" "system" "nixos" "label" ])
|
||||||
@@ -240,5 +240,11 @@ with lib;
|
|||||||
|
|
||||||
# Xen
|
# Xen
|
||||||
(mkRenamedOptionModule [ "virtualisation" "xen" "qemu-package" ] [ "virtualisation" "xen" "package-qemu" ])
|
(mkRenamedOptionModule [ "virtualisation" "xen" "qemu-package" ] [ "virtualisation" "xen" "package-qemu" ])
|
||||||
];
|
] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter"
|
||||||
|
"jsonExporter" "minioExporter" "nginxExporter" "nodeExporter"
|
||||||
|
"snmpExporter" "unifiExporter" "varnishExporter" ]
|
||||||
|
(opt: mkRemovedOptionModule [ "services" "prometheus" "${opt}" ] ''
|
||||||
|
The prometheus exporters are now configured using `services.prometheus.exporters'.
|
||||||
|
See the 18.03 release notes for more information.
|
||||||
|
'' ));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ in
|
|||||||
default = true;
|
default = true;
|
||||||
description =
|
description =
|
||||||
''
|
''
|
||||||
Whether users of the <code>wheel</code> group can execute
|
Whether users of the <code>wheel</code> group must
|
||||||
commands as super user without entering a password.
|
provide a password to run commands as super user via <command>sudo</command>.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
580
nixos/modules/services/backup/borgbackup.nix
Normal file
580
nixos/modules/services/backup/borgbackup.nix
Normal file
@@ -0,0 +1,580 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
isLocalPath = x:
|
||||||
|
builtins.substring 0 1 x == "/" # absolute path
|
||||||
|
|| builtins.substring 0 1 x == "." # relative path
|
||||||
|
|| builtins.match "[.*:.*]" == null; # not machine:path
|
||||||
|
|
||||||
|
mkExcludeFile = cfg:
|
||||||
|
# Write each exclude pattern to a new line
|
||||||
|
pkgs.writeText "excludefile" (concatStringsSep "\n" cfg.exclude);
|
||||||
|
|
||||||
|
mkKeepArgs = cfg:
|
||||||
|
# If cfg.prune.keep e.g. has a yearly attribute,
|
||||||
|
# its content is passed on as --keep-yearly
|
||||||
|
concatStringsSep " "
|
||||||
|
(mapAttrsToList (x: y: "--keep-${x}=${toString y}") cfg.prune.keep);
|
||||||
|
|
||||||
|
mkBackupScript = cfg: ''
|
||||||
|
on_exit()
|
||||||
|
{
|
||||||
|
exitStatus=$?
|
||||||
|
# Reset the EXIT handler, or else we're called again on 'exit' below
|
||||||
|
trap - EXIT
|
||||||
|
${cfg.postHook}
|
||||||
|
exit $exitStatus
|
||||||
|
}
|
||||||
|
trap 'on_exit' INT TERM QUIT EXIT
|
||||||
|
|
||||||
|
archiveName="${cfg.archiveBaseName}-$(date ${cfg.dateFormat})"
|
||||||
|
archiveSuffix="${optionalString cfg.appendFailedSuffix ".failed"}"
|
||||||
|
${cfg.preHook}
|
||||||
|
'' + optionalString cfg.doInit ''
|
||||||
|
# Run borg init if the repo doesn't exist yet
|
||||||
|
if ! borg list > /dev/null; then
|
||||||
|
borg init \
|
||||||
|
--encryption ${cfg.encryption.mode} \
|
||||||
|
$extraInitArgs
|
||||||
|
${cfg.postInit}
|
||||||
|
fi
|
||||||
|
'' + ''
|
||||||
|
borg create \
|
||||||
|
--compression ${cfg.compression} \
|
||||||
|
--exclude-from ${mkExcludeFile cfg} \
|
||||||
|
$extraCreateArgs \
|
||||||
|
"::$archiveName$archiveSuffix" \
|
||||||
|
${escapeShellArgs cfg.paths}
|
||||||
|
'' + optionalString cfg.appendFailedSuffix ''
|
||||||
|
borg rename "::$archiveName$archiveSuffix" "$archiveName"
|
||||||
|
'' + ''
|
||||||
|
${cfg.postCreate}
|
||||||
|
'' + optionalString (cfg.prune.keep != { }) ''
|
||||||
|
borg prune \
|
||||||
|
${mkKeepArgs cfg} \
|
||||||
|
--prefix ${escapeShellArg cfg.prune.prefix} \
|
||||||
|
$extraPruneArgs
|
||||||
|
${cfg.postPrune}
|
||||||
|
'';
|
||||||
|
|
||||||
|
mkPassEnv = cfg: with cfg.encryption;
|
||||||
|
if passCommand != null then
|
||||||
|
{ BORG_PASSCOMMAND = passCommand; }
|
||||||
|
else if passphrase != null then
|
||||||
|
{ BORG_PASSPHRASE = passphrase; }
|
||||||
|
else { };
|
||||||
|
|
||||||
|
mkBackupService = name: cfg:
|
||||||
|
let
|
||||||
|
userHome = config.users.users.${cfg.user}.home;
|
||||||
|
in nameValuePair "borgbackup-job-${name}" {
|
||||||
|
description = "BorgBackup job ${name}";
|
||||||
|
path = with pkgs; [
|
||||||
|
borgbackup openssh
|
||||||
|
];
|
||||||
|
script = mkBackupScript cfg;
|
||||||
|
serviceConfig = {
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
# Only run when no other process is using CPU or disk
|
||||||
|
CPUSchedulingPolicy = "idle";
|
||||||
|
IOSchedulingClass = "idle";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ReadWritePaths =
|
||||||
|
[ "${userHome}/.config/borg" "${userHome}/.cache/borg" ]
|
||||||
|
# Borg needs write access to repo if it is not remote
|
||||||
|
++ optional (isLocalPath cfg.repo) cfg.repo;
|
||||||
|
PrivateTmp = true;
|
||||||
|
};
|
||||||
|
environment = {
|
||||||
|
BORG_REPO = cfg.repo;
|
||||||
|
inherit (cfg) extraInitArgs extraCreateArgs extraPruneArgs;
|
||||||
|
} // (mkPassEnv cfg) // cfg.environment;
|
||||||
|
inherit (cfg) startAt;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Paths listed in ReadWritePaths must exist before service is started
|
||||||
|
mkActivationScript = name: cfg:
|
||||||
|
let
|
||||||
|
install = "install -o ${cfg.user} -g ${cfg.group}";
|
||||||
|
in
|
||||||
|
nameValuePair "borgbackup-job-${name}" (stringAfter [ "users" ] (''
|
||||||
|
# Eensure that the home directory already exists
|
||||||
|
# We can't assert createHome == true because that's not the case for root
|
||||||
|
cd "${config.users.users.${cfg.user}.home}"
|
||||||
|
${install} -d .config/borg
|
||||||
|
${install} -d .cache/borg
|
||||||
|
'' + optionalString (isLocalPath cfg.repo) ''
|
||||||
|
${install} -d ${escapeShellArg cfg.repo}
|
||||||
|
''));
|
||||||
|
|
||||||
|
mkPassAssertion = name: cfg: {
|
||||||
|
assertion = with cfg.encryption;
|
||||||
|
mode != "none" -> passCommand != null || passphrase != null;
|
||||||
|
message =
|
||||||
|
"passCommand or passphrase has to be specified because"
|
||||||
|
+ '' borgbackup.jobs.${name}.encryption != "none"'';
|
||||||
|
};
|
||||||
|
|
||||||
|
mkRepoService = name: cfg:
|
||||||
|
nameValuePair "borgbackup-repo-${name}" {
|
||||||
|
description = "Create BorgBackup repository ${name} directory";
|
||||||
|
script = ''
|
||||||
|
mkdir -p ${escapeShellArg cfg.path}
|
||||||
|
chown ${cfg.user}:${cfg.group} ${escapeShellArg cfg.path}
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
# The service's only task is to ensure that the specified path exists
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
mkAuthorizedKey = cfg: appendOnly: key:
|
||||||
|
let
|
||||||
|
# Because of the following line, clients do not need to specify an absolute repo path
|
||||||
|
cdCommand = "cd ${escapeShellArg cfg.path}";
|
||||||
|
restrictedArg = "--restrict-to-${if cfg.allowSubRepos then "path" else "repository"} .";
|
||||||
|
appendOnlyArg = optionalString appendOnly "--append-only";
|
||||||
|
quotaArg = optionalString (cfg.quota != null) "--storage-quota ${cfg.quota}";
|
||||||
|
serveCommand = "borg serve ${restrictedArg} ${appendOnlyArg} ${quotaArg}";
|
||||||
|
in
|
||||||
|
''command="${cdCommand} && ${serveCommand}",restrict ${key}'';
|
||||||
|
|
||||||
|
mkUsersConfig = name: cfg: {
|
||||||
|
users.${cfg.user} = {
|
||||||
|
openssh.authorizedKeys.keys =
|
||||||
|
(map (mkAuthorizedKey cfg false) cfg.authorizedKeys
|
||||||
|
++ map (mkAuthorizedKey cfg true) cfg.authorizedKeysAppendOnly);
|
||||||
|
useDefaultShell = true;
|
||||||
|
};
|
||||||
|
groups.${cfg.group} = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
mkKeysAssertion = name: cfg: {
|
||||||
|
assertion = cfg.authorizedKeys != [ ] || cfg.authorizedKeysAppendOnly != [ ];
|
||||||
|
message =
|
||||||
|
"borgbackup.repos.${name} does not make sense"
|
||||||
|
+ " without at least one public key";
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
meta.maintainers = with maintainers; [ dotlambda ];
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options.services.borgbackup.jobs = mkOption {
|
||||||
|
description = "Deduplicating backups using BorgBackup.";
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
rootBackup = {
|
||||||
|
paths = "/";
|
||||||
|
exclude = [ "/nix" ];
|
||||||
|
repo = "/path/to/local/repo";
|
||||||
|
encryption = {
|
||||||
|
mode = "repokey";
|
||||||
|
passphrase = "secret";
|
||||||
|
};
|
||||||
|
compression = "auto,lzma";
|
||||||
|
startAt = "weekly";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
type = types.attrsOf (types.submodule (let globalConfig = config; in
|
||||||
|
{ name, config, ... }: {
|
||||||
|
options = {
|
||||||
|
|
||||||
|
paths = mkOption {
|
||||||
|
type = with types; either path (nonEmptyListOf path);
|
||||||
|
description = "Path(s) to back up.";
|
||||||
|
example = "/home/user";
|
||||||
|
apply = x: if isList x then x else [ x ];
|
||||||
|
};
|
||||||
|
|
||||||
|
repo = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Remote or local repository to back up to.";
|
||||||
|
example = "user@machine:/path/to/repo";
|
||||||
|
};
|
||||||
|
|
||||||
|
archiveBaseName = mkOption {
|
||||||
|
type = types.strMatching "[^/{}]+";
|
||||||
|
default = "${globalConfig.networking.hostName}-${name}";
|
||||||
|
defaultText = "\${config.networking.hostName}-<name>";
|
||||||
|
description = ''
|
||||||
|
How to name the created archives. A timestamp, whose format is
|
||||||
|
determined by <option>dateFormat</option>, will be appended. The full
|
||||||
|
name can be modified at runtime (<literal>$archiveName</literal>).
|
||||||
|
Placeholders like <literal>{hostname}</literal> must not be used.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
dateFormat = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Arguments passed to <command>date</command>
|
||||||
|
to create a timestamp suffix for the archive name.
|
||||||
|
'';
|
||||||
|
default = "+%Y-%m-%dT%H:%M:%S";
|
||||||
|
example = "-u +%s";
|
||||||
|
};
|
||||||
|
|
||||||
|
startAt = mkOption {
|
||||||
|
type = with types; either str (listOf str);
|
||||||
|
default = "daily";
|
||||||
|
description = ''
|
||||||
|
When or how often the backup should run.
|
||||||
|
Must be in the format described in
|
||||||
|
<citerefentry><refentrytitle>systemd.time</refentrytitle>
|
||||||
|
<manvolnum>7</manvolnum></citerefentry>.
|
||||||
|
If you do not want the backup to start
|
||||||
|
automatically, use <literal>[ ]</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The user <command>borg</command> is run as.
|
||||||
|
User or group need read permission
|
||||||
|
for the specified <option>paths</option>.
|
||||||
|
'';
|
||||||
|
default = "root";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The group borg is run as. User or group needs read permission
|
||||||
|
for the specified <option>paths</option>.
|
||||||
|
'';
|
||||||
|
default = "root";
|
||||||
|
};
|
||||||
|
|
||||||
|
encryption.mode = mkOption {
|
||||||
|
type = types.enum [
|
||||||
|
"repokey" "keyfile"
|
||||||
|
"repokey-blake2" "keyfile-blake2"
|
||||||
|
"authenticated" "authenticated-blake2"
|
||||||
|
"none"
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
Encryption mode to use. Setting a mode
|
||||||
|
other than <literal>"none"</literal> requires
|
||||||
|
you to specify a <option>passCommand</option>
|
||||||
|
or a <option>passphrase</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
encryption.passCommand = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
description = ''
|
||||||
|
A command which prints the passphrase to stdout.
|
||||||
|
Mutually exclusive with <option>passphrase</option>.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
example = "cat /path/to/passphrase_file";
|
||||||
|
};
|
||||||
|
|
||||||
|
encryption.passphrase = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
description = ''
|
||||||
|
The passphrase the backups are encrypted with.
|
||||||
|
Mutually exclusive with <option>passCommand</option>.
|
||||||
|
If you do not want the passphrase to be stored in the
|
||||||
|
world-readable Nix store, use <option>passCommand</option>.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
compression = mkOption {
|
||||||
|
# "auto" is optional,
|
||||||
|
# compression mode must be given,
|
||||||
|
# compression level is optional
|
||||||
|
type = types.strMatching "none|(auto,)?(lz4|zstd|zlib|lzma)(,[[:digit:]]{1,2})?";
|
||||||
|
description = ''
|
||||||
|
Compression method to use. Refer to
|
||||||
|
<command>borg help compression</command>
|
||||||
|
for all available options.
|
||||||
|
'';
|
||||||
|
default = "lz4";
|
||||||
|
example = "auto,lzma";
|
||||||
|
};
|
||||||
|
|
||||||
|
exclude = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = ''
|
||||||
|
Exclude paths matching any of the given patterns. See
|
||||||
|
<command>borg help patterns</command> for pattern syntax.
|
||||||
|
'';
|
||||||
|
default = [ ];
|
||||||
|
example = [
|
||||||
|
"/home/*/.cache"
|
||||||
|
"/nix"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
doInit = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Run <command>borg init</command> if the
|
||||||
|
specified <option>repo</option> does not exist.
|
||||||
|
You should set this to <literal>false</literal>
|
||||||
|
if the repository is located on an external drive
|
||||||
|
that might not always be mounted.
|
||||||
|
'';
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
appendFailedSuffix = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Append a <literal>.failed</literal> suffix
|
||||||
|
to the archive name, which is only removed if
|
||||||
|
<command>borg create</command> has a zero exit status.
|
||||||
|
'';
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
prune.keep = mkOption {
|
||||||
|
# Specifying e.g. `prune.keep.yearly = -1`
|
||||||
|
# means there is no limit of yearly archives to keep
|
||||||
|
# The regex is for use with e.g. --keep-within 1y
|
||||||
|
type = with types; attrsOf (either int (strMatching "[[:digit:]]+[Hdwmy]"));
|
||||||
|
description = ''
|
||||||
|
Prune a repository by deleting all archives not matching any of the
|
||||||
|
specified retention options. See <command>borg help prune</command>
|
||||||
|
for the available options.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
within = "1d"; # Keep all archives from the last day
|
||||||
|
daily = 7;
|
||||||
|
weekly = 4;
|
||||||
|
monthly = -1; # Keep at least one archive for each month
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
prune.prefix = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Only consider archive names starting with this prefix for pruning.
|
||||||
|
By default, only archives created by this job are considered.
|
||||||
|
Use <literal>""</literal> to consider all archives.
|
||||||
|
'';
|
||||||
|
default = config.archiveBaseName;
|
||||||
|
defaultText = "\${archiveBaseName}";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
description = ''
|
||||||
|
Environment variables passed to the backup script.
|
||||||
|
You can for example specify which SSH key to use.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
example = { BORG_RSH = "ssh -i /path/to/key"; };
|
||||||
|
};
|
||||||
|
|
||||||
|
preHook = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
Shell commands to run before the backup.
|
||||||
|
This can for example be used to mount file systems.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
example = ''
|
||||||
|
# To add excluded paths at runtime
|
||||||
|
extraCreateArgs="$extraCreateArgs --exclude /some/path"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
postInit = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
Shell commands to run after <command>borg init</command>.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
postCreate = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
Shell commands to run after <command>borg create</command>. The name
|
||||||
|
of the created archive is stored in <literal>$archiveName</literal>.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
postPrune = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
Shell commands to run after <command>borg prune</command>.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
postHook = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
description = ''
|
||||||
|
Shell commands to run just before exit. They are executed
|
||||||
|
even if a previous command exits with a non-zero exit code.
|
||||||
|
The latter is available as <literal>$exitStatus</literal>.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraInitArgs = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Additional arguments for <command>borg init</command>.
|
||||||
|
Can also be set at runtime using <literal>$extraInitArgs</literal>.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
example = "--append-only";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraCreateArgs = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Additional arguments for <command>borg create</command>.
|
||||||
|
Can also be set at runtime using <literal>$extraCreateArgs</literal>.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
example = "--stats --checkpoint-interval 600";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraPruneArgs = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Additional arguments for <command>borg prune</command>.
|
||||||
|
Can also be set at runtime using <literal>$extraPruneArgs</literal>.
|
||||||
|
'';
|
||||||
|
default = "";
|
||||||
|
example = "--save-space";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
options.services.borgbackup.repos = mkOption {
|
||||||
|
description = ''
|
||||||
|
Serve BorgBackup repositories to given public SSH keys,
|
||||||
|
restricting their access to the repository only.
|
||||||
|
Also, clients do not need to specify the absolute path when accessing the repository,
|
||||||
|
i.e. <literal>user@machine:.</literal> is enough. (Note colon and dot.)
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
type = types.attrsOf (types.submodule (
|
||||||
|
{ name, config, ... }: {
|
||||||
|
options = {
|
||||||
|
|
||||||
|
path = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = ''
|
||||||
|
Where to store the backups. Note that the directory
|
||||||
|
is created automatically, with correct permissions.
|
||||||
|
'';
|
||||||
|
default = "/var/lib/borgbackup";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The user <command>borg serve</command> is run as.
|
||||||
|
User or group needs write permission
|
||||||
|
for the specified <option>path</option>.
|
||||||
|
'';
|
||||||
|
default = "borg";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The group <command>borg serve</command> is run as.
|
||||||
|
User or group needs write permission
|
||||||
|
for the specified <option>path</option>.
|
||||||
|
'';
|
||||||
|
default = "borg";
|
||||||
|
};
|
||||||
|
|
||||||
|
authorizedKeys = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = ''
|
||||||
|
Public SSH keys that are given full write access to this repository.
|
||||||
|
You should use a different SSH key for each repository you write to, because
|
||||||
|
the specified keys are restricted to running <command>borg serve</command>
|
||||||
|
and can only access this single repository.
|
||||||
|
'';
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
authorizedKeysAppendOnly = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
description = ''
|
||||||
|
Public SSH keys that can only be used to append new data (archives) to the repository.
|
||||||
|
Note that archives can still be marked as deleted and are subsequently removed from disk
|
||||||
|
upon accessing the repo with full write access, e.g. when pruning.
|
||||||
|
'';
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
|
||||||
|
allowSubRepos = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Allow clients to create repositories in subdirectories of the
|
||||||
|
specified <option>path</option>. These can be accessed using
|
||||||
|
<literal>user@machine:path/to/subrepo</literal>. Note that a
|
||||||
|
<option>quota</option> applies to repositories independently.
|
||||||
|
Therefore, if this is enabled, clients can create multiple
|
||||||
|
repositories and upload an arbitrary amount of data.
|
||||||
|
'';
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
quota = mkOption {
|
||||||
|
# See the definition of parse_file_size() in src/borg/helpers/parseformat.py
|
||||||
|
type = with types; nullOr (strMatching "[[:digit:].]+[KMGTP]?");
|
||||||
|
description = ''
|
||||||
|
Storage quota for the repository. This quota is ensured for all
|
||||||
|
sub-repositories if <option>allowSubRepos</option> is enabled
|
||||||
|
but not for the overall storage space used.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
example = "100G";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = mkIf (with config.services.borgbackup; jobs != { } || repos != { })
|
||||||
|
(with config.services.borgbackup; {
|
||||||
|
assertions =
|
||||||
|
mapAttrsToList mkPassAssertion jobs
|
||||||
|
++ mapAttrsToList mkKeysAssertion repos;
|
||||||
|
|
||||||
|
system.activationScripts = mapAttrs' mkActivationScript jobs;
|
||||||
|
|
||||||
|
systemd.services =
|
||||||
|
# A job named "foo" is mapped to systemd.services.borgbackup-job-foo
|
||||||
|
mapAttrs' mkBackupService jobs
|
||||||
|
# A repo named "foo" is mapped to systemd.services.borgbackup-repo-foo
|
||||||
|
// mapAttrs' mkRepoService repos;
|
||||||
|
|
||||||
|
users = mkMerge (mapAttrsToList mkUsersConfig repos);
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [ borgbackup ];
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -386,7 +386,7 @@ in
|
|||||||
echo Resetting znapzend zetups
|
echo Resetting znapzend zetups
|
||||||
${pkgs.znapzend}/bin/znapzendzetup list \
|
${pkgs.znapzend}/bin/znapzendzetup list \
|
||||||
| grep -oP '(?<=\*\*\* backup plan: ).*(?= \*\*\*)' \
|
| grep -oP '(?<=\*\*\* backup plan: ).*(?= \*\*\*)' \
|
||||||
| xargs ${pkgs.znapzend}/bin/znapzendzetup delete
|
| xargs -I{} ${pkgs.znapzend}/bin/znapzendzetup delete "{}"
|
||||||
'' + concatStringsSep "\n" (mapAttrsToList (dataset: config: ''
|
'' + concatStringsSep "\n" (mapAttrsToList (dataset: config: ''
|
||||||
echo Importing znapzend zetup ${config} for dataset ${dataset}
|
echo Importing znapzend zetup ${config} for dataset ${dataset}
|
||||||
${pkgs.znapzend}/bin/znapzendzetup import --write ${dataset} ${config}
|
${pkgs.znapzend}/bin/znapzendzetup import --write ${dataset} ${config}
|
||||||
|
|||||||
@@ -145,6 +145,11 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
# server references the dejavu fonts
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.dejavu_fonts
|
||||||
|
];
|
||||||
|
|
||||||
users.extraGroups = optional (cfg.group == "jenkins") {
|
users.extraGroups = optional (cfg.group == "jenkins") {
|
||||||
name = "jenkins";
|
name = "jenkins";
|
||||||
gid = config.ids.gids.jenkins;
|
gid = config.ids.gids.jenkins;
|
||||||
@@ -200,10 +205,12 @@ in {
|
|||||||
${replacePlugins}
|
${replacePlugins}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# For reference: https://wiki.jenkins.io/display/JENKINS/JenkinsLinuxStartupScript
|
||||||
script = ''
|
script = ''
|
||||||
${pkgs.jdk}/bin/java ${concatStringsSep " " cfg.extraJavaOptions} -jar ${cfg.package}/webapps/jenkins.war --httpListenAddress=${cfg.listenAddress} \
|
${pkgs.jdk}/bin/java ${concatStringsSep " " cfg.extraJavaOptions} -jar ${cfg.package}/webapps/jenkins.war --httpListenAddress=${cfg.listenAddress} \
|
||||||
--httpPort=${toString cfg.port} \
|
--httpPort=${toString cfg.port} \
|
||||||
--prefix=${cfg.prefix} \
|
--prefix=${cfg.prefix} \
|
||||||
|
-Djava.awt.headless=true \
|
||||||
${concatStringsSep " " cfg.extraOptions}
|
${concatStringsSep " " cfg.extraOptions}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ in
|
|||||||
JAVA_HOME = jre;
|
JAVA_HOME = jre;
|
||||||
GRAYLOG_CONF = "${confFile}";
|
GRAYLOG_CONF = "${confFile}";
|
||||||
};
|
};
|
||||||
path = [ pkgs.openjdk8 pkgs.which pkgs.procps ];
|
path = [ pkgs.jre_headless pkgs.which pkgs.procps ];
|
||||||
preStart = ''
|
preStart = ''
|
||||||
mkdir -p /var/lib/graylog -m 755
|
mkdir -p /var/lib/graylog -m 755
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ let
|
|||||||
|
|
||||||
''
|
''
|
||||||
default_internal_user = ${cfg.user}
|
default_internal_user = ${cfg.user}
|
||||||
|
default_internal_group = ${cfg.group}
|
||||||
${optionalString (cfg.mailUser != null) "mail_uid = ${cfg.mailUser}"}
|
${optionalString (cfg.mailUser != null) "mail_uid = ${cfg.mailUser}"}
|
||||||
${optionalString (cfg.mailGroup != null) "mail_gid = ${cfg.mailGroup}"}
|
${optionalString (cfg.mailGroup != null) "mail_gid = ${cfg.mailGroup}"}
|
||||||
|
|
||||||
|
|||||||
@@ -1,205 +1,69 @@
|
|||||||
# The following was taken from github.com/crohr/syslogger and is BSD
|
worker_processes 3
|
||||||
# licensed.
|
|
||||||
require 'syslog'
|
|
||||||
require 'logger'
|
|
||||||
require 'thread'
|
|
||||||
|
|
||||||
class Syslogger
|
|
||||||
|
|
||||||
VERSION = "1.6.0"
|
|
||||||
|
|
||||||
attr_reader :level, :ident, :options, :facility, :max_octets
|
|
||||||
attr_accessor :formatter
|
|
||||||
|
|
||||||
MAPPING = {
|
|
||||||
Logger::DEBUG => Syslog::LOG_DEBUG,
|
|
||||||
Logger::INFO => Syslog::LOG_INFO,
|
|
||||||
Logger::WARN => Syslog::LOG_WARNING,
|
|
||||||
Logger::ERROR => Syslog::LOG_ERR,
|
|
||||||
Logger::FATAL => Syslog::LOG_CRIT,
|
|
||||||
Logger::UNKNOWN => Syslog::LOG_ALERT
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
# Initializes default options for the logger
|
|
||||||
# <tt>ident</tt>:: the name of your program [default=$0].
|
|
||||||
# <tt>options</tt>:: syslog options [default=<tt>Syslog::LOG_PID | Syslog::LOG_CONS</tt>].
|
|
||||||
# Correct values are:
|
|
||||||
# LOG_CONS : writes the message on the console if an error occurs when sending the message;
|
|
||||||
# LOG_NDELAY : no delay before sending the message;
|
|
||||||
# LOG_PERROR : messages will also be written on STDERR;
|
|
||||||
# LOG_PID : adds the process number to the message (just after the program name)
|
|
||||||
# <tt>facility</tt>:: the syslog facility [default=nil] Correct values include:
|
|
||||||
# Syslog::LOG_DAEMON
|
|
||||||
# Syslog::LOG_USER
|
|
||||||
# Syslog::LOG_SYSLOG
|
|
||||||
# Syslog::LOG_LOCAL2
|
|
||||||
# Syslog::LOG_NEWS
|
|
||||||
# etc.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# logger = Syslogger.new("my_app", Syslog::LOG_PID | Syslog::LOG_CONS, Syslog::LOG_LOCAL0)
|
|
||||||
# logger.level = Logger::INFO # use Logger levels
|
|
||||||
# logger.warn "warning message"
|
|
||||||
# logger.debug "debug message"
|
|
||||||
#
|
|
||||||
def initialize(ident = $0, options = Syslog::LOG_PID | Syslog::LOG_CONS, facility = nil)
|
|
||||||
@ident = ident
|
|
||||||
@options = options || (Syslog::LOG_PID | Syslog::LOG_CONS)
|
|
||||||
@facility = facility
|
|
||||||
@level = Logger::INFO
|
|
||||||
@mutex = Mutex.new
|
|
||||||
@formatter = Logger::Formatter.new
|
|
||||||
end
|
|
||||||
|
|
||||||
%w{debug info warn error fatal unknown}.each do |logger_method|
|
|
||||||
# Accepting *args as message could be nil.
|
|
||||||
# Default params not supported in ruby 1.8.7
|
|
||||||
define_method logger_method.to_sym do |*args, &block|
|
|
||||||
return true if @level > Logger.const_get(logger_method.upcase)
|
|
||||||
message = args.first || block && block.call
|
|
||||||
add(Logger.const_get(logger_method.upcase), message)
|
|
||||||
end
|
|
||||||
|
|
||||||
unless logger_method == 'unknown'
|
|
||||||
define_method "#{logger_method}?".to_sym do
|
|
||||||
@level <= Logger.const_get(logger_method.upcase)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Log a message at the Logger::INFO level. Useful for use with Rack::CommonLogger
|
|
||||||
def write(msg)
|
|
||||||
add(Logger::INFO, msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Logs a message at the Logger::INFO level.
|
|
||||||
def <<(msg)
|
|
||||||
add(Logger::INFO, msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Low level method to add a message.
|
|
||||||
# +severity+:: the level of the message. One of Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR, Logger::FATAL, Logger::UNKNOWN
|
|
||||||
# +message+:: the message string.
|
|
||||||
# If nil, the method will call the block and use the result as the message string.
|
|
||||||
# If both are nil or no block is given, it will use the progname as per the behaviour of both the standard Ruby logger, and the Rails BufferedLogger.
|
|
||||||
# +progname+:: optionally, overwrite the program name that appears in the log message.
|
|
||||||
def add(severity, message = nil, progname = nil, &block)
|
|
||||||
if message.nil? && block.nil? && !progname.nil?
|
|
||||||
message, progname = progname, nil
|
|
||||||
end
|
|
||||||
progname ||= @ident
|
|
||||||
|
|
||||||
@mutex.synchronize do
|
|
||||||
Syslog.open(progname, @options, @facility) do |s|
|
|
||||||
s.mask = Syslog::LOG_UPTO(MAPPING[@level])
|
|
||||||
communication = clean(message || block && block.call)
|
|
||||||
if self.max_octets
|
|
||||||
buffer = "#{tags_text}"
|
|
||||||
communication.bytes do |byte|
|
|
||||||
buffer.concat(byte)
|
|
||||||
# if the last byte we added is potentially part of an escape, we'll go ahead and add another byte
|
|
||||||
if buffer.bytesize >= self.max_octets && !['%'.ord,'\\'.ord].include?(byte)
|
|
||||||
s.log(MAPPING[severity],buffer)
|
|
||||||
buffer = ""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
s.log(MAPPING[severity],buffer) unless buffer.empty?
|
|
||||||
else
|
|
||||||
s.log(MAPPING[severity],"#{tags_text}#{communication}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Set the max octets of the messages written to the log
|
|
||||||
def max_octets=(max_octets)
|
|
||||||
@max_octets = max_octets
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sets the minimum level for messages to be written in the log.
|
|
||||||
# +level+:: one of <tt>Logger::DEBUG</tt>, <tt>Logger::INFO</tt>, <tt>Logger::WARN</tt>, <tt>Logger::ERROR</tt>, <tt>Logger::FATAL</tt>, <tt>Logger::UNKNOWN</tt>
|
|
||||||
def level=(level)
|
|
||||||
level = Logger.const_get(level.to_s.upcase) if level.is_a?(Symbol)
|
|
||||||
|
|
||||||
unless level.is_a?(Fixnum)
|
|
||||||
raise ArgumentError.new("Invalid logger level `#{level.inspect}`")
|
|
||||||
end
|
|
||||||
|
|
||||||
@level = level
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sets the ident string passed along to Syslog
|
|
||||||
def ident=(ident)
|
|
||||||
@ident = ident
|
|
||||||
end
|
|
||||||
|
|
||||||
# Tagging code borrowed from ActiveSupport gem
|
|
||||||
def tagged(*tags)
|
|
||||||
new_tags = push_tags(*tags)
|
|
||||||
yield self
|
|
||||||
ensure
|
|
||||||
pop_tags(new_tags.size)
|
|
||||||
end
|
|
||||||
|
|
||||||
def push_tags(*tags)
|
|
||||||
tags.flatten.reject{ |i| i.respond_to?(:empty?) ? i.empty? : !i }.tap do |new_tags|
|
|
||||||
current_tags.concat new_tags
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def pop_tags(size = 1)
|
|
||||||
current_tags.pop size
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear_tags!
|
|
||||||
current_tags.clear
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
# Borrowed from SyslogLogger.
|
|
||||||
def clean(message)
|
|
||||||
message = message.to_s.dup
|
|
||||||
message.strip! # remove whitespace
|
|
||||||
message.gsub!(/\n/, '\\n') # escape newlines
|
|
||||||
message.gsub!(/%/, '%%') # syslog(3) freaks on % (printf)
|
|
||||||
message.gsub!(/\e\[[^m]*m/, '') # remove useless ansi color codes
|
|
||||||
message
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def tags_text
|
|
||||||
tags = current_tags
|
|
||||||
if tags.any?
|
|
||||||
tags.collect { |tag| "[#{tag}] " }.join
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def current_tags
|
|
||||||
Thread.current[:syslogger_tagged_logging_tags] ||= []
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
worker_processes 2
|
|
||||||
working_directory ENV["GITLAB_PATH"]
|
|
||||||
pid ENV["UNICORN_PATH"] + "/tmp/pids/unicorn.pid"
|
|
||||||
|
|
||||||
listen ENV["UNICORN_PATH"] + "/tmp/sockets/gitlab.socket", :backlog => 1024
|
listen ENV["UNICORN_PATH"] + "/tmp/sockets/gitlab.socket", :backlog => 1024
|
||||||
|
listen "/run/gitlab/gitlab.socket", :backlog => 1024
|
||||||
|
|
||||||
|
working_directory ENV["GITLAB_PATH"]
|
||||||
|
|
||||||
|
pid ENV["UNICORN_PATH"] + "/tmp/pids/unicorn.pid"
|
||||||
|
|
||||||
timeout 60
|
timeout 60
|
||||||
|
|
||||||
logger Syslogger.new
|
# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings
|
||||||
|
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
|
||||||
preload_app true
|
preload_app true
|
||||||
|
|
||||||
GC.respond_to?(:copy_on_write_friendly=) and
|
GC.respond_to?(:copy_on_write_friendly=) and
|
||||||
GC.copy_on_write_friendly = true
|
GC.copy_on_write_friendly = true
|
||||||
|
|
||||||
check_client_connection false
|
check_client_connection false
|
||||||
|
|
||||||
|
before_fork do |server, worker|
|
||||||
|
# the following is highly recommended for Rails + "preload_app true"
|
||||||
|
# as there's no need for the master process to hold a connection
|
||||||
|
defined?(ActiveRecord::Base) and
|
||||||
|
ActiveRecord::Base.connection.disconnect!
|
||||||
|
|
||||||
|
# The following is only recommended for memory/DB-constrained
|
||||||
|
# installations. It is not needed if your system can house
|
||||||
|
# twice as many worker_processes as you have configured.
|
||||||
|
#
|
||||||
|
# This allows a new master process to incrementally
|
||||||
|
# phase out the old master process with SIGTTOU to avoid a
|
||||||
|
# thundering herd (especially in the "preload_app false" case)
|
||||||
|
# when doing a transparent upgrade. The last worker spawned
|
||||||
|
# will then kill off the old master process with a SIGQUIT.
|
||||||
|
old_pid = "#{server.config[:pid]}.oldbin"
|
||||||
|
if old_pid != server.pid
|
||||||
|
begin
|
||||||
|
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
|
||||||
|
Process.kill(sig, File.read(old_pid).to_i)
|
||||||
|
rescue Errno::ENOENT, Errno::ESRCH
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Throttle the master from forking too quickly by sleeping. Due
|
||||||
|
# to the implementation of standard Unix signal handlers, this
|
||||||
|
# helps (but does not completely) prevent identical, repeated signals
|
||||||
|
# from being lost when the receiving process is busy.
|
||||||
|
# sleep 1
|
||||||
|
end
|
||||||
|
|
||||||
after_fork do |server, worker|
|
after_fork do |server, worker|
|
||||||
|
# per-process listener ports for debugging/admin/migrations
|
||||||
|
# addr = "127.0.0.1:#{9293 + worker.nr}"
|
||||||
|
# server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)
|
||||||
|
|
||||||
|
# the following is *required* for Rails + "preload_app true",
|
||||||
defined?(ActiveRecord::Base) and
|
defined?(ActiveRecord::Base) and
|
||||||
ActiveRecord::Base.establish_connection
|
ActiveRecord::Base.establish_connection
|
||||||
|
|
||||||
|
# reset prometheus client, this will cause any opened metrics files to be closed
|
||||||
|
defined?(::Prometheus::Client.reinitialize_on_pid_change) &&
|
||||||
|
Prometheus::Client.reinitialize_on_pid_change
|
||||||
|
|
||||||
|
# if preload_app is true, then you may also want to check and
|
||||||
|
# restart any other shared sockets/descriptors such as Memcached,
|
||||||
|
# and Redis. TokyoCabinet file handles are safe to reuse
|
||||||
|
# between any number of forked children (assuming your kernel
|
||||||
|
# correctly implements pread()/pwrite() system calls)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ with lib;
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.gitea;
|
cfg = config.services.gitea;
|
||||||
|
pg = config.services.postgresql;
|
||||||
|
usePostgresql = cfg.database.type == "postgres";
|
||||||
configFile = pkgs.writeText "app.ini" ''
|
configFile = pkgs.writeText "app.ini" ''
|
||||||
APP_NAME = ${cfg.appName}
|
APP_NAME = ${cfg.appName}
|
||||||
RUN_USER = ${cfg.user}
|
RUN_USER = ${cfg.user}
|
||||||
@@ -16,6 +18,9 @@ let
|
|||||||
USER = ${cfg.database.user}
|
USER = ${cfg.database.user}
|
||||||
PASSWD = #dbpass#
|
PASSWD = #dbpass#
|
||||||
PATH = ${cfg.database.path}
|
PATH = ${cfg.database.path}
|
||||||
|
${optionalString usePostgresql ''
|
||||||
|
SSL_MODE = disable
|
||||||
|
''}
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
ROOT = ${cfg.repositoryRoot}
|
ROOT = ${cfg.repositoryRoot}
|
||||||
@@ -35,6 +40,10 @@ let
|
|||||||
SECRET_KEY = #secretkey#
|
SECRET_KEY = #secretkey#
|
||||||
INSTALL_LOCK = true
|
INSTALL_LOCK = true
|
||||||
|
|
||||||
|
[log]
|
||||||
|
ROOT_PATH = ${cfg.log.rootPath}
|
||||||
|
LEVEL = ${cfg.log.level}
|
||||||
|
|
||||||
${cfg.extraConfig}
|
${cfg.extraConfig}
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
@@ -60,6 +69,19 @@ in
|
|||||||
description = "gitea data directory.";
|
description = "gitea data directory.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
log = {
|
||||||
|
rootPath = mkOption {
|
||||||
|
default = "${cfg.stateDir}/log";
|
||||||
|
type = types.str;
|
||||||
|
description = "Root path for log files.";
|
||||||
|
};
|
||||||
|
level = mkOption {
|
||||||
|
default = "Trace";
|
||||||
|
type = types.enum [ "Trace" "Debug" "Info" "Warn" "Error" "Critical" ];
|
||||||
|
description = "General log level.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "gitea";
|
default = "gitea";
|
||||||
@@ -82,7 +104,7 @@ in
|
|||||||
|
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
default = 3306;
|
default = (if !usePostgresql then 3306 else pg.port);
|
||||||
description = "Database host port.";
|
description = "Database host port.";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,6 +145,15 @@ in
|
|||||||
default = "${cfg.stateDir}/data/gitea.db";
|
default = "${cfg.stateDir}/data/gitea.db";
|
||||||
description = "Path to the sqlite3 database file.";
|
description = "Path to the sqlite3 database file.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
createDatabase = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether to create a local postgresql database automatically.
|
||||||
|
This only applies if database type "postgres" is selected.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
appName = mkOption {
|
appName = mkOption {
|
||||||
@@ -186,10 +217,11 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
services.postgresql.enable = mkIf usePostgresql (mkDefault true);
|
||||||
|
|
||||||
systemd.services.gitea = {
|
systemd.services.gitea = {
|
||||||
description = "gitea";
|
description = "gitea";
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" "postgresql.service" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
path = [ pkgs.gitea.bin ];
|
path = [ pkgs.gitea.bin ];
|
||||||
|
|
||||||
@@ -231,12 +263,31 @@ in
|
|||||||
mkdir -p ${cfg.stateDir}/conf
|
mkdir -p ${cfg.stateDir}/conf
|
||||||
cp -r ${pkgs.gitea.out}/locale ${cfg.stateDir}/conf/locale
|
cp -r ${pkgs.gitea.out}/locale ${cfg.stateDir}/conf/locale
|
||||||
fi
|
fi
|
||||||
|
'' + optionalString (usePostgresql && cfg.database.createDatabase) ''
|
||||||
|
if ! test -e "${cfg.stateDir}/db-created"; then
|
||||||
|
echo "CREATE ROLE ${cfg.database.user}
|
||||||
|
WITH ENCRYPTED PASSWORD '$(head -n1 ${cfg.database.passwordFile})'
|
||||||
|
NOCREATEDB NOCREATEROLE LOGIN" |
|
||||||
|
${pkgs.sudo}/bin/sudo -u ${pg.superUser} ${pg.package}/bin/psql
|
||||||
|
${pkgs.sudo}/bin/sudo -u ${pg.superUser} \
|
||||||
|
${pg.package}/bin/createdb \
|
||||||
|
--owner=${cfg.database.user} \
|
||||||
|
--encoding=UTF8 \
|
||||||
|
--lc-collate=C \
|
||||||
|
--lc-ctype=C \
|
||||||
|
--template=template0 \
|
||||||
|
${cfg.database.name}
|
||||||
|
touch "${cfg.stateDir}/db-created"
|
||||||
|
fi
|
||||||
|
'' + ''
|
||||||
|
chown ${cfg.user} -R ${cfg.stateDir}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "simple";
|
Type = "simple";
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
WorkingDirectory = cfg.stateDir;
|
WorkingDirectory = cfg.stateDir;
|
||||||
|
PermissionsStartOnly = true;
|
||||||
ExecStart = "${pkgs.gitea.bin}/bin/gitea web";
|
ExecStart = "${pkgs.gitea.bin}/bin/gitea web";
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
};
|
};
|
||||||
@@ -253,6 +304,7 @@ in
|
|||||||
description = "Gitea Service";
|
description = "Gitea Service";
|
||||||
home = cfg.stateDir;
|
home = cfg.stateDir;
|
||||||
createHome = true;
|
createHome = true;
|
||||||
|
useDefaultShell = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ let
|
|||||||
GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/";
|
GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/";
|
||||||
GITLAB_STATE_PATH = "${cfg.statePath}";
|
GITLAB_STATE_PATH = "${cfg.statePath}";
|
||||||
GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads";
|
GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads";
|
||||||
|
SCHEMA = "${cfg.statePath}/db/schema.rb";
|
||||||
GITLAB_LOG_PATH = "${cfg.statePath}/log";
|
GITLAB_LOG_PATH = "${cfg.statePath}/log";
|
||||||
GITLAB_SHELL_PATH = "${cfg.packages.gitlab-shell}";
|
GITLAB_SHELL_PATH = "${cfg.packages.gitlab-shell}";
|
||||||
GITLAB_SHELL_CONFIG_PATH = "${cfg.statePath}/shell/config.yml";
|
GITLAB_SHELL_CONFIG_PATH = "${cfg.statePath}/shell/config.yml";
|
||||||
@@ -500,7 +501,7 @@ in {
|
|||||||
Type = "simple";
|
Type = "simple";
|
||||||
User = cfg.user;
|
User = cfg.user;
|
||||||
Group = cfg.group;
|
Group = cfg.group;
|
||||||
TimeoutSec = "300";
|
TimeoutSec = "infinity";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
WorkingDirectory = gitlabEnv.HOME;
|
WorkingDirectory = gitlabEnv.HOME;
|
||||||
ExecStart = "${cfg.packages.gitaly}/bin/gitaly ${gitalyToml}";
|
ExecStart = "${cfg.packages.gitaly}/bin/gitaly ${gitalyToml}";
|
||||||
@@ -566,6 +567,7 @@ in {
|
|||||||
mkdir -p ${cfg.statePath}/tmp/pids
|
mkdir -p ${cfg.statePath}/tmp/pids
|
||||||
mkdir -p ${cfg.statePath}/tmp/sockets
|
mkdir -p ${cfg.statePath}/tmp/sockets
|
||||||
mkdir -p ${cfg.statePath}/shell
|
mkdir -p ${cfg.statePath}/shell
|
||||||
|
mkdir -p ${cfg.statePath}/db
|
||||||
|
|
||||||
rm -rf ${cfg.statePath}/config ${cfg.statePath}/shell/hooks
|
rm -rf ${cfg.statePath}/config ${cfg.statePath}/shell/hooks
|
||||||
mkdir -p ${cfg.statePath}/config
|
mkdir -p ${cfg.statePath}/config
|
||||||
@@ -580,6 +582,7 @@ in {
|
|||||||
ln -sf ${cfg.statePath}/log /run/gitlab/log
|
ln -sf ${cfg.statePath}/log /run/gitlab/log
|
||||||
ln -sf ${cfg.statePath}/uploads /run/gitlab/uploads
|
ln -sf ${cfg.statePath}/uploads /run/gitlab/uploads
|
||||||
ln -sf ${cfg.statePath}/tmp /run/gitlab/tmp
|
ln -sf ${cfg.statePath}/tmp /run/gitlab/tmp
|
||||||
|
ln -sf $GITLAB_SHELL_CONFIG_PATH /run/gitlab/shell-config.yml
|
||||||
chown -R ${cfg.user}:${cfg.group} /run/gitlab
|
chown -R ${cfg.user}:${cfg.group} /run/gitlab
|
||||||
|
|
||||||
# Prepare home directory
|
# Prepare home directory
|
||||||
@@ -587,6 +590,7 @@ in {
|
|||||||
touch ${gitlabEnv.HOME}/.ssh/authorized_keys
|
touch ${gitlabEnv.HOME}/.ssh/authorized_keys
|
||||||
chown -R ${cfg.user}:${cfg.group} ${gitlabEnv.HOME}/
|
chown -R ${cfg.user}:${cfg.group} ${gitlabEnv.HOME}/
|
||||||
|
|
||||||
|
cp -rf ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db
|
||||||
cp -rf ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config
|
cp -rf ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config
|
||||||
${optionalString cfg.smtp.enable ''
|
${optionalString cfg.smtp.enable ''
|
||||||
ln -sf ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb
|
ln -sf ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ in {
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
systemd.services.home-assistant = {
|
systemd.services.home-assistant = {
|
||||||
description = "Home Assistant";
|
description = "Home Assistant";
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
preStart = lib.optionalString (cfg.config != null) ''
|
preStart = lib.optionalString (cfg.config != null) ''
|
||||||
rm -f ${cfg.configDir}/configuration.yaml
|
rm -f ${cfg.configDir}/configuration.yaml
|
||||||
@@ -121,6 +120,16 @@ in {
|
|||||||
ReadWritePaths = "${cfg.configDir}";
|
ReadWritePaths = "${cfg.configDir}";
|
||||||
PrivateTmp = true;
|
PrivateTmp = true;
|
||||||
};
|
};
|
||||||
|
path = [
|
||||||
|
"/run/wrappers" # needed for ping
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.targets.home-assistant = rec {
|
||||||
|
description = "Home Assistant";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "home-assistant.service" ];
|
||||||
|
after = wants;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.extraUsers.hass = {
|
users.extraUsers.hass = {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ let
|
|||||||
|
|
||||||
cfg = config.services.parsoid;
|
cfg = config.services.parsoid;
|
||||||
|
|
||||||
|
parsoid = pkgs.nodePackages."parsoid-git://github.com/abbradar/parsoid#stable";
|
||||||
|
|
||||||
confTree = {
|
confTree = {
|
||||||
worker_heartbeat_timeout = 300000;
|
worker_heartbeat_timeout = 300000;
|
||||||
logging = { level = "info"; };
|
logging = { level = "info"; };
|
||||||
@@ -93,7 +95,7 @@ in
|
|||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
User = "nobody";
|
User = "nobody";
|
||||||
ExecStart = "${pkgs.nodePackages.parsoid}/lib/node_modules/parsoid/bin/server.js -c ${confFile} -n ${toString cfg.workers}";
|
ExecStart = "${parsoid}/lib/node_modules/parsoid/bin/server.js -c ${confFile} -n ${toString cfg.workers}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ let
|
|||||||
DATABASE_USER = cfg.database.user;
|
DATABASE_USER = cfg.database.user;
|
||||||
DATABASE_PASSWORD = cfg.database.password;
|
DATABASE_PASSWORD = cfg.database.password;
|
||||||
DATABASE_PATH = cfg.database.path;
|
DATABASE_PATH = cfg.database.path;
|
||||||
|
DATABASE_CONN_MAX_LIFETIME = cfg.database.connMaxLifetime;
|
||||||
|
|
||||||
SECURITY_ADMIN_USER = cfg.security.adminUser;
|
SECURITY_ADMIN_USER = cfg.security.adminUser;
|
||||||
SECURITY_ADMIN_PASSWORD = cfg.security.adminPassword;
|
SECURITY_ADMIN_PASSWORD = cfg.security.adminPassword;
|
||||||
@@ -143,6 +144,15 @@ in {
|
|||||||
default = "${cfg.dataDir}/data/grafana.db";
|
default = "${cfg.dataDir}/data/grafana.db";
|
||||||
type = types.path;
|
type = types.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
connMaxLifetime = mkOption {
|
||||||
|
description = ''
|
||||||
|
Sets the maximum amount of time (in seconds) a connection may be reused.
|
||||||
|
For MySQL this setting should be shorter than the `wait_timeout' variable.
|
||||||
|
'';
|
||||||
|
default = 14400;
|
||||||
|
type = types.int;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
security = {
|
security = {
|
||||||
@@ -241,7 +251,9 @@ in {
|
|||||||
description = "Grafana Service Daemon";
|
description = "Grafana Service Daemon";
|
||||||
wantedBy = ["multi-user.target"];
|
wantedBy = ["multi-user.target"];
|
||||||
after = ["networking.target"];
|
after = ["networking.target"];
|
||||||
environment = mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions;
|
environment = {
|
||||||
|
QT_QPA_PLATFORM = "offscreen";
|
||||||
|
} // mapAttrs' (n: v: nameValuePair "GF_${n}" (toString v)) envOptions;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${cfg.package.bin}/bin/grafana-server -homepath ${cfg.dataDir}";
|
ExecStart = "${cfg.package.bin}/bin/grafana-server -homepath ${cfg.dataDir}";
|
||||||
WorkingDirectory = cfg.dataDir;
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.blackboxExporter;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.blackboxExporter = {
|
|
||||||
enable = mkEnableOption "prometheus blackbox exporter";
|
|
||||||
|
|
||||||
configFile = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = ''
|
|
||||||
Path to configuration file.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9115;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the blackbox exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
systemd.services.prometheus-blackbox-exporter = {
|
|
||||||
description = "Prometheus exporter for blackbox probes";
|
|
||||||
unitConfig.Documentation = "https://github.com/prometheus/blackbox_exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
AmbientCapabilities = [ "CAP_NET_RAW" ]; # for ping probes
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.prometheus-blackbox-exporter}/bin/blackbox_exporter \
|
|
||||||
--web.listen-address :${toString cfg.port} \
|
|
||||||
--config.file ${cfg.configFile} \
|
|
||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.collectdExporter;
|
|
||||||
|
|
||||||
collectSettingsArgs = if (cfg.collectdBinary.enable) then ''
|
|
||||||
-collectd.listen-address ${optionalString (cfg.collectdBinary.listenAddress != null) cfg.collectdBinary.listenAddress}:${toString cfg.collectdBinary.port} \
|
|
||||||
-collectd.security-level ${cfg.collectdBinary.securityLevel} \
|
|
||||||
'' else "";
|
|
||||||
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.collectdExporter = {
|
|
||||||
enable = mkEnableOption "prometheus collectd exporter";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9103;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
This is used for scraping as well as the to receive collectd data via the write_http plugin.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
example = "0.0.0.0";
|
|
||||||
description = ''
|
|
||||||
Address to listen on for web interface, telemetry and collectd JSON data.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
collectdBinary = {
|
|
||||||
enable = mkEnableOption "collectd binary protocol receiver";
|
|
||||||
|
|
||||||
authFile = mkOption {
|
|
||||||
default = null;
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
description = "File mapping user names to pre-shared keys (passwords).";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 25826;
|
|
||||||
description = ''Network address on which to accept collectd binary network packets.'';
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
example = "0.0.0.0";
|
|
||||||
description = ''
|
|
||||||
Address to listen on for binary network packets.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
securityLevel = mkOption {
|
|
||||||
type = types.enum ["None" "Sign" "Encrypt"];
|
|
||||||
default = "None";
|
|
||||||
description = ''
|
|
||||||
Minimum required security level for accepted packets.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the collectd exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
logFormat = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "logger:stderr";
|
|
||||||
example = "logger:syslog?appname=bob&local=7 or logger:stdout?json=true";
|
|
||||||
description = ''
|
|
||||||
Set the log target and format.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
logLevel = mkOption {
|
|
||||||
type = types.enum ["debug" "info" "warn" "error" "fatal"];
|
|
||||||
default = "info";
|
|
||||||
description = ''
|
|
||||||
Only log messages with the given severity or above.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = (optional cfg.openFirewall cfg.port) ++
|
|
||||||
(optional (cfg.openFirewall && cfg.collectdBinary.enable) cfg.collectdBinary.port);
|
|
||||||
|
|
||||||
systemd.services.prometheus-collectd-exporter = {
|
|
||||||
description = "Prometheus exporter for Collectd metrics";
|
|
||||||
unitConfig.Documentation = "https://github.com/prometheus/collectd_exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
DynamicUser = true;
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.prometheus-collectd-exporter}/bin/collectd_exporter \
|
|
||||||
-log.format ${cfg.logFormat} \
|
|
||||||
-log.level ${cfg.logLevel} \
|
|
||||||
-web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port} \
|
|
||||||
${collectSettingsArgs} \
|
|
||||||
${concatStringsSep " " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
172
nixos/modules/services/monitoring/prometheus/exporters.nix
Normal file
172
nixos/modules/services/monitoring/prometheus/exporters.nix
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters;
|
||||||
|
|
||||||
|
# each attribute in `exporterOpts` is expected to have specified:
|
||||||
|
# - port (types.int): port on which the exporter listens
|
||||||
|
# - serviceOpts (types.attrs): config that is merged with the
|
||||||
|
# default definition of the exporter's
|
||||||
|
# systemd service
|
||||||
|
# - extraOpts (types.attrs): extra configuration options to
|
||||||
|
# configure the exporter with, which
|
||||||
|
# are appended to the default options
|
||||||
|
#
|
||||||
|
# Note that `extraOpts` is optional, but a script for the exporter's
|
||||||
|
# systemd service must be provided by specifying either
|
||||||
|
# `serviceOpts.script` or `serviceOpts.serviceConfig.ExecStart`
|
||||||
|
exporterOpts = {
|
||||||
|
blackbox = import ./exporters/blackbox.nix { inherit config lib pkgs; };
|
||||||
|
collectd = import ./exporters/collectd.nix { inherit config lib pkgs; };
|
||||||
|
fritzbox = import ./exporters/fritzbox.nix { inherit config lib pkgs; };
|
||||||
|
json = import ./exporters/json.nix { inherit config lib pkgs; };
|
||||||
|
minio = import ./exporters/minio.nix { inherit config lib pkgs; };
|
||||||
|
nginx = import ./exporters/nginx.nix { inherit config lib pkgs; };
|
||||||
|
node = import ./exporters/node.nix { inherit config lib pkgs; };
|
||||||
|
postfix = import ./exporters/postfix.nix { inherit config lib pkgs; };
|
||||||
|
snmp = import ./exporters/snmp.nix { inherit config lib pkgs; };
|
||||||
|
unifi = import ./exporters/unifi.nix { inherit config lib pkgs; };
|
||||||
|
varnish = import ./exporters/varnish.nix { inherit config lib pkgs; };
|
||||||
|
};
|
||||||
|
|
||||||
|
mkExporterOpts = ({ name, port }: {
|
||||||
|
enable = mkEnableOption "the prometheus ${name} exporter";
|
||||||
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = port;
|
||||||
|
description = ''
|
||||||
|
Port to listen on.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
listenAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
description = ''
|
||||||
|
Address to listen on.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
extraFlags = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
Extra commandline options to pass to the ${name} exporter.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
openFirewall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Open port in firewall for incoming connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
firewallFilter = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "-p tcp -m tcp --dport ${toString port}";
|
||||||
|
example = literalExample ''
|
||||||
|
"-i eth0 -p tcp -m tcp --dport ${toString port}"
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Specify a filter for iptables to use when
|
||||||
|
<option>services.prometheus.exporters.${name}.openFirewall</option>
|
||||||
|
is true. It is used as `ip46tables -I INPUT <option>firewallFilter</option> -j ACCEPT`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "nobody";
|
||||||
|
description = ''
|
||||||
|
User name under which the ${name} exporter shall be run.
|
||||||
|
Has no effect when <option>systemd.services.prometheus-${name}-exporter.serviceConfig.DynamicUser</option> is true.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "nobody";
|
||||||
|
description = ''
|
||||||
|
Group under which the ${name} exporter shall be run.
|
||||||
|
Has no effect when <option>systemd.services.prometheus-${name}-exporter.serviceConfig.DynamicUser</option> is true.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
mkSubModule = { name, port, extraOpts, serviceOpts }: {
|
||||||
|
${name} = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
options = (mkExporterOpts {
|
||||||
|
inherit name port;
|
||||||
|
} // extraOpts);
|
||||||
|
};
|
||||||
|
internal = true;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkSubModules = (foldl' (a: b: a//b) {}
|
||||||
|
(mapAttrsToList (name: opts: mkSubModule {
|
||||||
|
inherit name;
|
||||||
|
inherit (opts) port serviceOpts;
|
||||||
|
extraOpts = opts.extraOpts or {};
|
||||||
|
}) exporterOpts)
|
||||||
|
);
|
||||||
|
|
||||||
|
mkExporterConf = { name, conf, serviceOpts }:
|
||||||
|
mkIf conf.enable {
|
||||||
|
networking.firewall.extraCommands = mkIf conf.openFirewall ''
|
||||||
|
ip46tables -I INPUT ${conf.firewallFilter} -j ACCEPT
|
||||||
|
'';
|
||||||
|
systemd.services."prometheus-${name}-exporter" = mkMerge ([{
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = mkDefault "always";
|
||||||
|
PrivateTmp = mkDefault true;
|
||||||
|
WorkingDirectory = mkDefault /tmp;
|
||||||
|
} // mkIf (!(serviceOpts.serviceConfig.DynamicUser or false)) {
|
||||||
|
User = conf.user;
|
||||||
|
Group = conf.group;
|
||||||
|
};
|
||||||
|
} serviceOpts ]);
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.prometheus.exporters = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
options = (mkSubModules);
|
||||||
|
};
|
||||||
|
description = "Prometheus exporter configuration";
|
||||||
|
default = {};
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
node = {
|
||||||
|
enable = true;
|
||||||
|
enabledCollectors = [ "systemd" ];
|
||||||
|
};
|
||||||
|
varnish.enable = true;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge ([{
|
||||||
|
assertions = [{
|
||||||
|
assertion = (cfg.snmp.configurationPath == null) != (cfg.snmp.configuration == null);
|
||||||
|
message = ''
|
||||||
|
Please ensure you have either `services.prometheus.exporters.snmp.configuration'
|
||||||
|
or `services.prometheus.exporters.snmp.configurationPath' set!
|
||||||
|
'';
|
||||||
|
}];
|
||||||
|
}] ++ [(mkIf config.services.minio.enable {
|
||||||
|
services.prometheus.exporters.minio.minioAddress = mkDefault "http://localhost:9000";
|
||||||
|
services.prometheus.exporters.minio.minioAccessKey = mkDefault config.services.minio.accessKey;
|
||||||
|
services.prometheus.exporters.minio.minioAccessSecret = mkDefault config.services.minio.secretKey;
|
||||||
|
})] ++ (mapAttrsToList (name: conf:
|
||||||
|
mkExporterConf {
|
||||||
|
inherit name;
|
||||||
|
inherit (conf) serviceOpts;
|
||||||
|
conf = cfg.${name};
|
||||||
|
}) exporterOpts)
|
||||||
|
);
|
||||||
|
|
||||||
|
meta.doc = ./exporters.xml;
|
||||||
|
}
|
||||||
135
nixos/modules/services/monitoring/prometheus/exporters.xml
Normal file
135
nixos/modules/services/monitoring/prometheus/exporters.xml
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="module-services-prometheus-exporters">
|
||||||
|
|
||||||
|
<title>Prometheus exporters</title>
|
||||||
|
|
||||||
|
<para>Prometheus exporters provide metrics for the <link xlink:href="https://prometheus.io">prometheus monitoring system</link>.</para>
|
||||||
|
|
||||||
|
<section><title>Configuration</title>
|
||||||
|
<para>One of the most common exporters is the <link xlink:href="https://github.com/prometheus/node_exporter">node exporter</link>, it provides hardware and OS metrics from the host it's running on. The exporter could be configured as follows:
|
||||||
|
<programlisting>
|
||||||
|
services.promtheus.exporters.node = {
|
||||||
|
enable = true;
|
||||||
|
enabledCollectors = [
|
||||||
|
"logind"
|
||||||
|
"systemd"
|
||||||
|
];
|
||||||
|
disabledCollectors = [
|
||||||
|
"textfile"
|
||||||
|
];
|
||||||
|
openFirewall = true;
|
||||||
|
firewallFilter = "-i br0 -p tcp -m tcp --dport 9100";
|
||||||
|
};
|
||||||
|
</programlisting>
|
||||||
|
It should now serve all metrics from the collectors
|
||||||
|
that are explicitly enabled and the ones that are
|
||||||
|
<link xlink:href="https://github.com/prometheus/node_exporter#enabled-by-default">enabled by default</link>, via http under <literal>/metrics</literal>. In this example the firewall should just
|
||||||
|
allow incoming connections to the exporter's port on the bridge interface <literal>br0</literal>
|
||||||
|
(this would have to be configured seperately of course).
|
||||||
|
For more information about configuration see <literal>man configuration.nix</literal> or
|
||||||
|
search through the <link xlink:href="https://nixos.org/nixos/options.html#prometheus.exporters">available options</link>.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
<section><title>Adding a new exporter</title>
|
||||||
|
<para>To add a new exporter, it has to be packaged first (see <literal>nixpkgs/pkgs/servers/monitoring/prometheus/</literal> for examples), then a module can be added. The postfix exporter is used in this example:</para>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Some default options for all exporters are provided by
|
||||||
|
<literal>nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix</literal>:
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem override='none'>
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem><para><literal>enable</literal></para></listitem>
|
||||||
|
<listitem><para><literal>port</literal></para></listitem>
|
||||||
|
<listitem><para><literal>listenAddress</literal></para></listitem>
|
||||||
|
<listitem><para><literal>extraFlags</literal></para></listitem>
|
||||||
|
<listitem><para><literal>openFirewall</literal></para></listitem>
|
||||||
|
<listitem><para><literal>firewallFilter</literal></para></listitem>
|
||||||
|
<listitem><para><literal>user</literal></para></listitem>
|
||||||
|
<listitem><para><literal>group</literal></para></listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>As there is already a package available, the module can now be added.
|
||||||
|
This is accomplished by adding a new file to the
|
||||||
|
<literal>nixos/modules/services/monitoring/prometheus/exporters/</literal> directory,
|
||||||
|
which will be called postfix.nix and contains all exporter specific options
|
||||||
|
and configuration:
|
||||||
|
<programlisting>
|
||||||
|
# nixpgs/nixos/modules/services/prometheus/exporters/postfix.nix
|
||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
# for convenience we define cfg here
|
||||||
|
cfg = config.services.prometheus.exporters.postfix;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9154; # The postfix exporter listens on this port by default
|
||||||
|
|
||||||
|
# `extraOpts` is an attribute set which contains additional options
|
||||||
|
# (and optional overrides for default options).
|
||||||
|
# Note that this attribute is optional.
|
||||||
|
extraOpts = {
|
||||||
|
telemetryPath = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/metrics";
|
||||||
|
description = ''
|
||||||
|
Path under which to expose metrics.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
logfilePath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = /var/log/postfix_exporter_input.log;
|
||||||
|
example = /var/log/mail.log;
|
||||||
|
description = ''
|
||||||
|
Path where Postfix writes log entries.
|
||||||
|
This file will be truncated by this exporter!
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
showqPath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = /var/spool/postfix/public/showq;
|
||||||
|
example = /var/lib/postfix/queue/public/showq;
|
||||||
|
description = ''
|
||||||
|
Path at which Postfix places its showq socket.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# `serviceOpts` is an attribute set which contains configuration
|
||||||
|
# for the exporter's systemd service. One of
|
||||||
|
# `serviceOpts.script` and `serviceOpts.serviceConfig.ExecStart`
|
||||||
|
# has to be specified here. This will be merged with the default
|
||||||
|
# service confiuration.
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
|
||||||
|
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
--web.telemetry-path ${cfg.telemetryPath} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This should already be enough for the postfix exporter. Additionally one could
|
||||||
|
now add assertions and conditional default values. This can be done in the
|
||||||
|
'meta-module' that combines all exporter definitions and generates the submodules:
|
||||||
|
<literal>nixpkgs/nixos/modules/services/prometheus/exporters.nix</literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</section>
|
||||||
|
</chapter>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.blackbox;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9115;
|
||||||
|
extraOpts = {
|
||||||
|
configFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = ''
|
||||||
|
Path to configuration file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
AmbientCapabilities = [ "CAP_NET_RAW" ]; # for ping probes
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-blackbox-exporter}/bin/blackbox_exporter \
|
||||||
|
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
--config.file ${cfg.configFile} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.collectd;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9103;
|
||||||
|
extraOpts = {
|
||||||
|
collectdBinary = {
|
||||||
|
enable = mkEnableOption "collectd binary protocol receiver";
|
||||||
|
|
||||||
|
authFile = mkOption {
|
||||||
|
default = null;
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
description = "File mapping user names to pre-shared keys (passwords).";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 25826;
|
||||||
|
description = ''Network address on which to accept collectd binary network packets.'';
|
||||||
|
};
|
||||||
|
|
||||||
|
listenAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
description = ''
|
||||||
|
Address to listen on for binary network packets.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
securityLevel = mkOption {
|
||||||
|
type = types.enum ["None" "Sign" "Encrypt"];
|
||||||
|
default = "None";
|
||||||
|
description = ''
|
||||||
|
Minimum required security level for accepted packets.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
logFormat = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "logger:stderr";
|
||||||
|
example = "logger:syslog?appname=bob&local=7 or logger:stdout?json=true";
|
||||||
|
description = ''
|
||||||
|
Set the log target and format.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
logLevel = mkOption {
|
||||||
|
type = types.enum ["debug" "info" "warn" "error" "fatal"];
|
||||||
|
default = "info";
|
||||||
|
description = ''
|
||||||
|
Only log messages with the given severity or above.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = let
|
||||||
|
collectSettingsArgs = if (cfg.collectdBinary.enable) then ''
|
||||||
|
-collectd.listen-address ${cfg.collectdBinary.listenAddress}:${toString cfg.collectdBinary.port} \
|
||||||
|
-collectd.security-level ${cfg.collectdBinary.securityLevel} \
|
||||||
|
'' else "";
|
||||||
|
in {
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-collectd-exporter}/bin/collectd_exporter \
|
||||||
|
-log.format ${cfg.logFormat} \
|
||||||
|
-log.level ${cfg.logLevel} \
|
||||||
|
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
${collectSettingsArgs} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.fritzbox;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9133;
|
||||||
|
extraOpts = {
|
||||||
|
gatewayAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "fritz.box";
|
||||||
|
description = ''
|
||||||
|
The hostname or IP of the FRITZ!Box.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
gatewayPort = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 49000;
|
||||||
|
description = ''
|
||||||
|
The port of the FRITZ!Box UPnP service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-fritzbox-exporter}/bin/fritzbox_exporter \
|
||||||
|
-listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
-gateway-address ${cfg.gatewayAddress} \
|
||||||
|
-gateway-port ${toString cfg.gatewayPort} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.json;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 7979;
|
||||||
|
extraOpts = {
|
||||||
|
url = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
URL to scrape JSON from.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
configFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = ''
|
||||||
|
Path to configuration file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
listenAddress = {}; # not used
|
||||||
|
};
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-json-exporter}/bin/prometheus-json-exporter \
|
||||||
|
--port ${toString cfg.port} \
|
||||||
|
${cfg.url} ${cfg.configFile} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.minio;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9290;
|
||||||
|
extraOpts = {
|
||||||
|
minioAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "https://10.0.0.1:9000";
|
||||||
|
description = ''
|
||||||
|
The URL of the minio server.
|
||||||
|
Use HTTPS if Minio accepts secure connections only.
|
||||||
|
By default this connects to the local minio server if enabled.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
minioAccessKey = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "yourMinioAccessKey";
|
||||||
|
description = ''
|
||||||
|
The value of the Minio access key.
|
||||||
|
It is required in order to connect to the server.
|
||||||
|
By default this uses the one from the local minio server if enabled
|
||||||
|
and <literal>config.services.minio.accessKey</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
minioAccessSecret = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
The value of the Minio access secret.
|
||||||
|
It is required in order to connect to the server.
|
||||||
|
By default this uses the one from the local minio server if enabled
|
||||||
|
and <literal>config.services.minio.secretKey</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
minioBucketStats = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Collect statistics about the buckets and files in buckets.
|
||||||
|
It requires more computation, use it carefully in case of large buckets..
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-minio-exporter}/bin/minio-exporter \
|
||||||
|
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
-minio.server ${cfg.minioAddress} \
|
||||||
|
-minio.access-key ${cfg.minioAccessKey} \
|
||||||
|
-minio.access-secret ${cfg.minioAccessSecret} \
|
||||||
|
${optionalString cfg.minioBucketStats "-minio.bucket-stats"} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.nginx;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9113;
|
||||||
|
extraOpts = {
|
||||||
|
scrapeUri = mkOption {
|
||||||
|
type = types.string;
|
||||||
|
default = "http://localhost/nginx_status";
|
||||||
|
description = ''
|
||||||
|
Address to access the nginx status page.
|
||||||
|
Can be enabled with services.nginx.statusPage = true.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-nginx-exporter}/bin/nginx_exporter \
|
||||||
|
-nginx.scrape_uri '${cfg.scrapeUri}' \
|
||||||
|
-telemetry.address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.node;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9100;
|
||||||
|
extraOpts = {
|
||||||
|
enabledCollectors = mkOption {
|
||||||
|
type = types.listOf types.string;
|
||||||
|
default = [];
|
||||||
|
example = ''[ "systemd" ]'';
|
||||||
|
description = ''
|
||||||
|
Collectors to enable. The collectors listed here are enabled in addition to the default ones.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
disabledCollectors = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = ''[ "timex" ]'';
|
||||||
|
description = ''
|
||||||
|
Collectors to disable which are enabled by default.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-node-exporter}/bin/node_exporter \
|
||||||
|
${concatMapStringsSep " " (x: "--collector." + x) cfg.enabledCollectors} \
|
||||||
|
${concatMapStringsSep " " (x: "--no-collector." + x) cfg.disabledCollectors} \
|
||||||
|
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.postfix;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9154;
|
||||||
|
extraOpts = {
|
||||||
|
telemetryPath = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/metrics";
|
||||||
|
description = ''
|
||||||
|
Path under which to expose metrics.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
logfilePath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/log/postfix_exporter_input.log";
|
||||||
|
example = "/var/log/mail.log";
|
||||||
|
description = ''
|
||||||
|
Path where Postfix writes log entries.
|
||||||
|
This file will be truncated by this exporter!
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
showqPath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/spool/postfix/public/showq";
|
||||||
|
example = "/var/lib/postfix/queue/public/showq";
|
||||||
|
description = ''
|
||||||
|
Path where Postfix places it's showq socket.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
|
||||||
|
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
--web.telemetry-path ${cfg.telemetryPath} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.snmp;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9116;
|
||||||
|
extraOpts = {
|
||||||
|
configurationPath = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Path to a snmp exporter configuration file. Mutually exclusive with 'configuration' option.
|
||||||
|
'';
|
||||||
|
example = "./snmp.yml";
|
||||||
|
};
|
||||||
|
|
||||||
|
configuration = mkOption {
|
||||||
|
type = types.nullOr types.attrs;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Snmp exporter configuration as nix attribute set. Mutually exclusive with 'configurationPath' option.
|
||||||
|
'';
|
||||||
|
example = ''
|
||||||
|
{
|
||||||
|
"default" = {
|
||||||
|
"version" = 2;
|
||||||
|
"auth" = {
|
||||||
|
"community" = "public";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
logFormat = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "logger:stderr";
|
||||||
|
description = ''
|
||||||
|
Set the log target and format.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
logLevel = mkOption {
|
||||||
|
type = types.enum ["debug" "info" "warn" "error" "fatal"];
|
||||||
|
default = "info";
|
||||||
|
description = ''
|
||||||
|
Only log messages with the given severity or above.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = let
|
||||||
|
configFile = if cfg.configurationPath != null
|
||||||
|
then cfg.configurationPath
|
||||||
|
else "${pkgs.writeText "snmp-eporter-conf.yml" (builtins.toJSON cfg.configuration)}";
|
||||||
|
in {
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-snmp-exporter.bin}/bin/snmp_exporter \
|
||||||
|
-config.file ${configFile} \
|
||||||
|
-log.format ${cfg.logFormat} \
|
||||||
|
-log.level ${cfg.logLevel} \
|
||||||
|
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.unifi;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9130;
|
||||||
|
extraOpts = {
|
||||||
|
unifiAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "https://10.0.0.1:8443";
|
||||||
|
description = ''
|
||||||
|
URL of the UniFi Controller API.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
unifiInsecure = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
If enabled skip the verification of the TLS certificate of the UniFi Controller API.
|
||||||
|
Use with caution.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
unifiUsername = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "ReadOnlyUser";
|
||||||
|
description = ''
|
||||||
|
username for authentication against UniFi Controller API.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
unifiPassword = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Password for authentication against UniFi Controller API.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
unifiTimeout = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "5s";
|
||||||
|
example = "2m";
|
||||||
|
description = ''
|
||||||
|
Timeout including unit for UniFi Controller API requests.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
serviceOpts = {
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-unifi-exporter}/bin/unifi_exporter \
|
||||||
|
-telemetry.addr ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
-unifi.addr ${cfg.unifiAddress} \
|
||||||
|
-unifi.username ${cfg.unifiUsername} \
|
||||||
|
-unifi.password ${cfg.unifiPassword} \
|
||||||
|
-unifi.timeout ${cfg.unifiTimeout} \
|
||||||
|
${optionalString cfg.unifiInsecure "-unifi.insecure" } \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{ config, lib, pkgs }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.prometheus.exporters.varnish;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
port = 9131;
|
||||||
|
serviceOpts = {
|
||||||
|
path = [ pkgs.varnish ];
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = true;
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.prometheus-varnish-exporter}/bin/prometheus_varnish_exporter \
|
||||||
|
-web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||||
|
${concatStringsSep " \\\n " cfg.extraFlags}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.fritzboxExporter;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.fritzboxExporter = {
|
|
||||||
enable = mkEnableOption "prometheus fritzbox exporter";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9133;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
gatewayAddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "fritz.box";
|
|
||||||
description = ''
|
|
||||||
The hostname or IP of the FRITZ!Box.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
gatewayPort = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 49000;
|
|
||||||
description = ''
|
|
||||||
The port of the FRITZ!Box UPnP service.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the fritzbox exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
systemd.services.prometheus-fritzbox-exporter = {
|
|
||||||
description = "Prometheus exporter for FRITZ!Box via UPnP";
|
|
||||||
unitConfig.Documentation = "https://github.com/ndecker/fritzbox_exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.prometheus-fritzbox-exporter}/bin/fritzbox_exporter \
|
|
||||||
-listen-address :${toString cfg.port} \
|
|
||||||
-gateway-address ${cfg.gatewayAddress} \
|
|
||||||
-gateway-port ${toString cfg.gatewayPort} \
|
|
||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.jsonExporter;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.jsonExporter = {
|
|
||||||
enable = mkEnableOption "prometheus JSON exporter";
|
|
||||||
|
|
||||||
url = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
URL to scrape JSON from.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
configFile = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
description = ''
|
|
||||||
Path to configuration file.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 7979;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the JSON exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
systemd.services.prometheus-json-exporter = {
|
|
||||||
description = "Prometheus exporter for JSON over HTTP";
|
|
||||||
unitConfig.Documentation = "https://github.com/kawamuray/prometheus-json-exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.prometheus-json-exporter}/bin/prometheus-json-exporter \
|
|
||||||
--port ${toString cfg.port} \
|
|
||||||
${cfg.url} ${cfg.configFile} \
|
|
||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.minioExporter;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.minioExporter = {
|
|
||||||
enable = mkEnableOption "prometheus minio exporter";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9290;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
example = "0.0.0.0";
|
|
||||||
description = ''
|
|
||||||
Address to listen on for web interface and telemetry.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
minioAddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "https://10.0.0.1:9000";
|
|
||||||
default = if config.services.minio.enable then "http://localhost:9000" else null;
|
|
||||||
description = ''
|
|
||||||
The URL of the minio server.
|
|
||||||
Use HTTPS if Minio accepts secure connections only.
|
|
||||||
By default this connects to the local minio server if enabled.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
minioAccessKey = mkOption ({
|
|
||||||
type = types.str;
|
|
||||||
example = "BKIKJAA5BMMU2RHO6IBB";
|
|
||||||
description = ''
|
|
||||||
The value of the Minio access key.
|
|
||||||
It is required in order to connect to the server.
|
|
||||||
By default this uses the one from the local minio server if enabled
|
|
||||||
and <literal>config.services.minio.accessKey</literal>.
|
|
||||||
'';
|
|
||||||
} // optionalAttrs (config.services.minio.enable && config.services.minio.accessKey != "") {
|
|
||||||
default = config.services.minio.accessKey;
|
|
||||||
});
|
|
||||||
|
|
||||||
minioAccessSecret = mkOption ({
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
The calue of the Minio access secret.
|
|
||||||
It is required in order to connect to the server.
|
|
||||||
By default this uses the one from the local minio server if enabled
|
|
||||||
and <literal>config.services.minio.secretKey</literal>.
|
|
||||||
'';
|
|
||||||
} // optionalAttrs (config.services.minio.enable && config.services.minio.secretKey != "") {
|
|
||||||
default = config.services.minio.secretKey;
|
|
||||||
});
|
|
||||||
|
|
||||||
minioBucketStats = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Collect statistics about the buckets and files in buckets.
|
|
||||||
It requires more computation, use it carefully in case of large buckets..
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the minio exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
systemd.services.prometheus-minio-exporter = {
|
|
||||||
description = "Prometheus exporter for Minio server metrics";
|
|
||||||
unitConfig.Documentation = "https://github.com/joe-pll/minio-exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = optional config.services.minio.enable "minio.service";
|
|
||||||
serviceConfig = {
|
|
||||||
DynamicUser = true;
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.prometheus-minio-exporter}/bin/minio-exporter \
|
|
||||||
-web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port} \
|
|
||||||
-minio.server ${cfg.minioAddress} \
|
|
||||||
-minio.access-key ${cfg.minioAccessKey} \
|
|
||||||
-minio.access-secret ${cfg.minioAccessSecret} \
|
|
||||||
${optionalString cfg.minioBucketStats "-minio.bucket-stats"} \
|
|
||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.nginxExporter;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.nginxExporter = {
|
|
||||||
enable = mkEnableOption "prometheus nginx exporter";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9113;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.string;
|
|
||||||
default = "0.0.0.0";
|
|
||||||
description = ''
|
|
||||||
Address to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
scrapeUri = mkOption {
|
|
||||||
type = types.string;
|
|
||||||
default = "http://localhost/nginx_status";
|
|
||||||
description = ''
|
|
||||||
Address to access the nginx status page.
|
|
||||||
Can be enabled with services.nginx.statusPage = true.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the nginx exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
systemd.services.prometheus-nginx-exporter = {
|
|
||||||
after = [ "network.target" "nginx.service" ];
|
|
||||||
description = "Prometheus exporter for nginx metrics";
|
|
||||||
unitConfig.Documentation = "https://github.com/discordianfish/nginx_exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.prometheus-nginx-exporter}/bin/nginx_exporter \
|
|
||||||
-nginx.scrape_uri '${cfg.scrapeUri}' \
|
|
||||||
-telemetry.address ${cfg.listenAddress}:${toString cfg.port} \
|
|
||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.nodeExporter;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.nodeExporter = {
|
|
||||||
enable = mkEnableOption "prometheus node exporter";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9100;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.string;
|
|
||||||
default = "0.0.0.0";
|
|
||||||
description = ''
|
|
||||||
Address to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
enabledCollectors = mkOption {
|
|
||||||
type = types.listOf types.string;
|
|
||||||
default = [];
|
|
||||||
example = ''[ "systemd" ]'';
|
|
||||||
description = ''
|
|
||||||
Collectors to enable. The collectors listed here are enabled in addition to the default ones.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
disabledCollectors = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
example = ''[ "timex" ]'';
|
|
||||||
description = ''
|
|
||||||
Collectors to disable which are enabled by default.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the node exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
systemd.services.prometheus-node-exporter = {
|
|
||||||
description = "Prometheus exporter for machine metrics";
|
|
||||||
unitConfig.Documentation = "https://github.com/prometheus/node_exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
script = ''
|
|
||||||
exec ${pkgs.prometheus-node-exporter}/bin/node_exporter \
|
|
||||||
${concatMapStringsSep " " (x: "--collector." + x) cfg.enabledCollectors} \
|
|
||||||
${concatMapStringsSep " " (x: "--no-collector." + x) cfg.disabledCollectors} \
|
|
||||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
|
||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.snmpExporter;
|
|
||||||
mkConfigFile = pkgs.writeText "snmp.yml" (if cfg.configurationPath == null then builtins.toJSON cfg.configuration else builtins.readFile cfg.configurationPath);
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.snmpExporter = {
|
|
||||||
enable = mkEnableOption "Prometheus snmp exporter";
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "nobody";
|
|
||||||
description = ''
|
|
||||||
User name under which snmp exporter shall be run.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "nogroup";
|
|
||||||
description = ''
|
|
||||||
Group under which snmp exporter shall be run.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9116;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Address to listen on for web interface and telemetry.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
configurationPath = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Path to a snmp exporter configuration file. Mutually exclusive with 'configuration' option.
|
|
||||||
'';
|
|
||||||
example = "./snmp.yml";
|
|
||||||
};
|
|
||||||
|
|
||||||
configuration = mkOption {
|
|
||||||
type = types.nullOr types.attrs;
|
|
||||||
default = {};
|
|
||||||
description = ''
|
|
||||||
Snmp exporter configuration as nix attribute set. Mutually exclusive with 'configurationPath' option.
|
|
||||||
'';
|
|
||||||
example = ''
|
|
||||||
{
|
|
||||||
"default" = {
|
|
||||||
"version" = 2;
|
|
||||||
"auth" = {
|
|
||||||
"community" = "public";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
logFormat = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "logger:stderr";
|
|
||||||
description = ''
|
|
||||||
Set the log target and format.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
logLevel = mkOption {
|
|
||||||
type = types.enum ["debug" "info" "warn" "error" "fatal"];
|
|
||||||
default = "info";
|
|
||||||
description = ''
|
|
||||||
Only log messages with the given severity or above.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
assertions = singleton
|
|
||||||
{
|
|
||||||
assertion = (cfg.configurationPath == null) != (cfg.configuration == null);
|
|
||||||
message = "Please ensure you have either 'configuration' or 'configurationPath' set!";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.prometheus-snmp-exporter = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "network.target" ];
|
|
||||||
script = ''
|
|
||||||
${pkgs.prometheus-snmp-exporter.bin}/bin/snmp_exporter \
|
|
||||||
-config.file ${mkConfigFile} \
|
|
||||||
-log.format ${cfg.logFormat} \
|
|
||||||
-log.level ${cfg.logLevel} \
|
|
||||||
-web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port}
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = "/tmp";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.unifiExporter;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.unifiExporter = {
|
|
||||||
enable = mkEnableOption "prometheus unifi exporter";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9130;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
unifiAddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "https://10.0.0.1:8443";
|
|
||||||
description = ''
|
|
||||||
URL of the UniFi Controller API.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
unifiInsecure = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
If enabled skip the verification of the TLS certificate of the UniFi Controller API.
|
|
||||||
Use with caution.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
unifiUsername = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
example = "ReadOnlyUser";
|
|
||||||
description = ''
|
|
||||||
username for authentication against UniFi Controller API.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
unifiPassword = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Password for authentication against UniFi Controller API.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
unifiTimeout = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "5s";
|
|
||||||
example = "2m";
|
|
||||||
description = ''
|
|
||||||
Timeout including unit for UniFi Controller API requests.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the unifi exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
systemd.services.prometheus-unifi-exporter = {
|
|
||||||
description = "Prometheus exporter for UniFi Controller metrics";
|
|
||||||
unitConfig.Documentation = "https://github.com/mdlayher/unifi_exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = optional config.services.unifi.enable "unifi.service";
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
ExecStart = ''
|
|
||||||
${pkgs.prometheus-unifi-exporter}/bin/unifi_exporter \
|
|
||||||
-telemetry.addr :${toString cfg.port} \
|
|
||||||
-unifi.addr ${cfg.unifiAddress} \
|
|
||||||
-unifi.username ${cfg.unifiUsername} \
|
|
||||||
-unifi.password ${cfg.unifiPassword} \
|
|
||||||
-unifi.timeout ${cfg.unifiTimeout} \
|
|
||||||
${optionalString cfg.unifiInsecure "-unifi.insecure" } \
|
|
||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
# Shamelessly cribbed from nginx-exporter.nix. ~ C.
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.prometheus.varnishExporter;
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.prometheus.varnishExporter = {
|
|
||||||
enable = mkEnableOption "prometheus Varnish exporter";
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 9131;
|
|
||||||
description = ''
|
|
||||||
Port to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraFlags = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
description = ''
|
|
||||||
Extra commandline options when launching the Varnish exporter.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Open port in firewall for incoming connections.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port;
|
|
||||||
|
|
||||||
systemd.services.prometheus-varnish-exporter = {
|
|
||||||
description = "Prometheus exporter for Varnish metrics";
|
|
||||||
unitConfig.Documentation = "https://github.com/jonnenauha/prometheus_varnish_exporter";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
path = [ pkgs.varnish ];
|
|
||||||
script = ''
|
|
||||||
exec ${pkgs.prometheus-varnish-exporter}/bin/prometheus_varnish_exporter \
|
|
||||||
-web.listen-address :${toString cfg.port} \
|
|
||||||
${concatStringsSep " \\\n " cfg.extraFlags}
|
|
||||||
'';
|
|
||||||
serviceConfig = {
|
|
||||||
User = "nobody";
|
|
||||||
Restart = "always";
|
|
||||||
PrivateTmp = true;
|
|
||||||
WorkingDirectory = /tmp;
|
|
||||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -135,8 +135,7 @@ in {
|
|||||||
default = { inherit networkmanager modemmanager wpa_supplicant
|
default = { inherit networkmanager modemmanager wpa_supplicant
|
||||||
networkmanager-openvpn networkmanager-vpnc
|
networkmanager-openvpn networkmanager-vpnc
|
||||||
networkmanager-openconnect networkmanager-fortisslvpn
|
networkmanager-openconnect networkmanager-fortisslvpn
|
||||||
networkmanager-pptp networkmanager-l2tp
|
networkmanager-l2tp networkmanager-iodine; };
|
||||||
networkmanager-iodine; };
|
|
||||||
internal = true;
|
internal = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -267,8 +266,6 @@ in {
|
|||||||
message = "You can not use networking.networkmanager with networking.wireless";
|
message = "You can not use networking.networkmanager with networking.wireless";
|
||||||
}];
|
}];
|
||||||
|
|
||||||
boot.kernelModules = [ "ppp_mppe" ]; # Needed for most (all?) PPTP VPN connections.
|
|
||||||
|
|
||||||
environment.etc = with cfg.basePackages; [
|
environment.etc = with cfg.basePackages; [
|
||||||
{ source = configFile;
|
{ source = configFile;
|
||||||
target = "NetworkManager/NetworkManager.conf";
|
target = "NetworkManager/NetworkManager.conf";
|
||||||
@@ -285,9 +282,6 @@ in {
|
|||||||
{ source = "${networkmanager-fortisslvpn}/etc/NetworkManager/VPN/nm-fortisslvpn-service.name";
|
{ source = "${networkmanager-fortisslvpn}/etc/NetworkManager/VPN/nm-fortisslvpn-service.name";
|
||||||
target = "NetworkManager/VPN/nm-fortisslvpn-service.name";
|
target = "NetworkManager/VPN/nm-fortisslvpn-service.name";
|
||||||
}
|
}
|
||||||
{ source = "${networkmanager-pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
|
|
||||||
target = "NetworkManager/VPN/nm-pptp-service.name";
|
|
||||||
}
|
|
||||||
{ source = "${networkmanager-l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name";
|
{ source = "${networkmanager-l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name";
|
||||||
target = "NetworkManager/VPN/nm-l2tp-service.name";
|
target = "NetworkManager/VPN/nm-l2tp-service.name";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ in
|
|||||||
environment.NIX_SECRET_KEY_FILE = cfg.secretKeyFile;
|
environment.NIX_SECRET_KEY_FILE = cfg.secretKeyFile;
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "5s";
|
||||||
ExecStart = "${pkgs.nix-serve}/bin/nix-serve " +
|
ExecStart = "${pkgs.nix-serve}/bin/nix-serve " +
|
||||||
"--listen ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}";
|
"--listen ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}";
|
||||||
User = "nix-serve";
|
User = "nix-serve";
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ let
|
|||||||
description = "Path to the key file.";
|
description = "Path to the key file.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# TODO: rename to certificate to match the prosody config
|
||||||
cert = mkOption {
|
cert = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
description = "Path to the certificate file.";
|
description = "Path to the certificate file.";
|
||||||
@@ -30,7 +31,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
moduleOpts = {
|
moduleOpts = {
|
||||||
|
# Generally required
|
||||||
roster = mkOption {
|
roster = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@@ -61,12 +62,38 @@ let
|
|||||||
description = "Service discovery";
|
description = "Service discovery";
|
||||||
};
|
};
|
||||||
|
|
||||||
legacyauth = mkOption {
|
# Not essential, but recommended
|
||||||
|
carbons = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = "Legacy authentication. Only used by some old clients and bots";
|
description = "Keep multiple clients in sync";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pep = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Enables users to publish their mood, activity, playing music and more";
|
||||||
|
};
|
||||||
|
|
||||||
|
private = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Private XML storage (for room bookmarks, etc.)";
|
||||||
|
};
|
||||||
|
|
||||||
|
blocklist = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Allow users to block communications with other users";
|
||||||
|
};
|
||||||
|
|
||||||
|
vcard = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Allow users to set vCards";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Nice to have
|
||||||
version = mkOption {
|
version = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@@ -91,36 +118,112 @@ let
|
|||||||
description = "Replies to XMPP pings with pongs";
|
description = "Replies to XMPP pings with pongs";
|
||||||
};
|
};
|
||||||
|
|
||||||
console = mkOption {
|
register = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = true;
|
||||||
description = "telnet to port 5582";
|
description = "Allow users to register on this server using a client and change passwords";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mam = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Store messages in an archive and allow users to access it";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Admin interfaces
|
||||||
|
admin_adhoc = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Allows administration via an XMPP client that supports ad-hoc commands";
|
||||||
|
};
|
||||||
|
|
||||||
|
admin_telnet = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Opens telnet console interface on localhost port 5582";
|
||||||
|
};
|
||||||
|
|
||||||
|
# HTTP modules
|
||||||
bosh = mkOption {
|
bosh = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "Enable BOSH clients, aka 'Jabber over HTTP'";
|
description = "Enable BOSH clients, aka 'Jabber over HTTP'";
|
||||||
};
|
};
|
||||||
|
|
||||||
httpserver = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Serve static files from a directory over HTTP";
|
|
||||||
};
|
|
||||||
|
|
||||||
websocket = mkOption {
|
websocket = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = "Enable WebSocket support";
|
description = "Enable WebSocket support";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
http_files = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Serve static files from a directory over HTTP";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Other specific functionality
|
||||||
|
limits = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable bandwidth limiting for XMPP connections";
|
||||||
|
};
|
||||||
|
|
||||||
|
groups = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Shared roster support";
|
||||||
|
};
|
||||||
|
|
||||||
|
server_contact_info = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Publish contact information for this service";
|
||||||
|
};
|
||||||
|
|
||||||
|
announce = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Send announcement to all online users";
|
||||||
|
};
|
||||||
|
|
||||||
|
welcome = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Welcome users who register accounts";
|
||||||
|
};
|
||||||
|
|
||||||
|
watchregistrations = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Alert admins of registrations";
|
||||||
|
};
|
||||||
|
|
||||||
|
motd = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Send a message to users when they log in";
|
||||||
|
};
|
||||||
|
|
||||||
|
legacyauth = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Legacy authentication. Only used by some old clients and bots";
|
||||||
|
};
|
||||||
|
|
||||||
|
proxy65 = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enables a file transfer proxy service which clients behind NAT can use";
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
toLua = x:
|
toLua = x:
|
||||||
if builtins.isString x then ''"${x}"''
|
if builtins.isString x then ''"${x}"''
|
||||||
else if builtins.isBool x then toString x
|
else if builtins.isBool x then (if x == true then "true" else "false")
|
||||||
else if builtins.isInt x then toString x
|
else if builtins.isInt x then toString x
|
||||||
|
else if builtins.isList x then ''{ ${lib.concatStringsSep ", " (map (n: toLua n) x) } }''
|
||||||
else throw "Invalid Lua value";
|
else throw "Invalid Lua value";
|
||||||
|
|
||||||
createSSLOptsStr = o: ''
|
createSSLOptsStr = o: ''
|
||||||
@@ -198,6 +301,59 @@ in
|
|||||||
description = "Allow account creation";
|
description = "Allow account creation";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
c2sRequireEncryption = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Force clients to use encrypted connections? This option will
|
||||||
|
prevent clients from authenticating unless they are using encryption.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
s2sRequireEncryption = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Force servers to use encrypted connections? This option will
|
||||||
|
prevent servers from authenticating unless they are using encryption.
|
||||||
|
Note that this is different from authentication.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
s2sSecureAuth = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Force certificate authentication for server-to-server connections?
|
||||||
|
This provides ideal security, but requires servers you communicate
|
||||||
|
with to support encryption AND present valid, trusted certificates.
|
||||||
|
For more information see https://prosody.im/doc/s2s#security
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
s2sInsecureDomains = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [ "insecure.example.com" ];
|
||||||
|
description = ''
|
||||||
|
Some servers have invalid or self-signed certificates. You can list
|
||||||
|
remote domains here that will not be required to authenticate using
|
||||||
|
certificates. They will be authenticated using DNS instead, even
|
||||||
|
when s2s_secure_auth is enabled.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
s2sSecureDomains = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
example = [ "jabber.org" ];
|
||||||
|
description = ''
|
||||||
|
Even if you leave s2s_secure_auth disabled, you can still require valid
|
||||||
|
certificates for some domains by specifying a list here.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
modules = moduleOpts;
|
modules = moduleOpts;
|
||||||
|
|
||||||
extraModules = mkOption {
|
extraModules = mkOption {
|
||||||
@@ -206,6 +362,12 @@ in
|
|||||||
description = "Enable custom modules";
|
description = "Enable custom modules";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraPluginPaths = mkOption {
|
||||||
|
type = types.listOf types.path;
|
||||||
|
default = [];
|
||||||
|
description = "Addtional path in which to look find plugins/modules";
|
||||||
|
};
|
||||||
|
|
||||||
virtualHosts = mkOption {
|
virtualHosts = mkOption {
|
||||||
|
|
||||||
description = "Define the virtual hosts";
|
description = "Define the virtual hosts";
|
||||||
@@ -255,38 +417,48 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.prosody ];
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
environment.etc."prosody/prosody.cfg.lua".text = ''
|
environment.etc."prosody/prosody.cfg.lua".text = ''
|
||||||
|
|
||||||
pidfile = "/var/lib/prosody/prosody.pid"
|
pidfile = "/var/lib/prosody/prosody.pid"
|
||||||
|
|
||||||
|
|
||||||
log = "*syslog"
|
log = "*syslog"
|
||||||
|
|
||||||
data_path = "/var/lib/prosody"
|
data_path = "/var/lib/prosody"
|
||||||
|
plugin_paths = {
|
||||||
allow_registration = ${boolToString cfg.allowRegistration};
|
${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.extraPluginPaths) }
|
||||||
|
}
|
||||||
${ optionalString cfg.modules.console "console_enabled = true;" }
|
|
||||||
|
|
||||||
${ optionalString (cfg.ssl != null) (createSSLOptsStr cfg.ssl) }
|
${ optionalString (cfg.ssl != null) (createSSLOptsStr cfg.ssl) }
|
||||||
|
|
||||||
admins = { ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.admins) } };
|
admins = ${toLua cfg.admins}
|
||||||
|
|
||||||
|
-- we already build with libevent, so we can just enable it for a more performant server
|
||||||
|
use_libevent = true
|
||||||
|
|
||||||
modules_enabled = {
|
modules_enabled = {
|
||||||
|
|
||||||
${ lib.concatStringsSep "\n\ \ " (lib.mapAttrsToList
|
${ lib.concatStringsSep "\n\ \ " (lib.mapAttrsToList
|
||||||
(name: val: optionalString val ''"${name}";'')
|
(name: val: optionalString val "${toLua name};")
|
||||||
cfg.modules) }
|
cfg.modules) }
|
||||||
|
${ lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.package.communityModules)}
|
||||||
${ optionalString cfg.allowRegistration "\"register\"\;" }
|
${ lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.extraModules)}
|
||||||
|
|
||||||
${ lib.concatStringsSep "\n" (map (x: "\"${x}\";") cfg.extraModules)}
|
|
||||||
|
|
||||||
"posix";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
allow_registration = ${toLua cfg.allowRegistration}
|
||||||
|
|
||||||
|
c2s_require_encryption = ${toLua cfg.c2sRequireEncryption}
|
||||||
|
|
||||||
|
s2s_require_encryption = ${toLua cfg.s2sRequireEncryption}
|
||||||
|
|
||||||
|
s2s_secure_auth = ${toLua cfg.s2sSecureAuth}
|
||||||
|
|
||||||
|
s2s_insecure_domains = ${toLua cfg.s2sInsecureDomains}
|
||||||
|
|
||||||
|
s2s_secure_domains = ${toLua cfg.s2sSecureDomains}
|
||||||
|
|
||||||
|
|
||||||
${ cfg.extraConfig }
|
${ cfg.extraConfig }
|
||||||
|
|
||||||
${ lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: ''
|
${ lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: ''
|
||||||
|
|||||||
@@ -50,12 +50,7 @@ in
|
|||||||
description = ''
|
description = ''
|
||||||
If enabled, start the Resilio Sync daemon. Once enabled, you can
|
If enabled, start the Resilio Sync daemon. Once enabled, you can
|
||||||
interact with the service through the Web UI, or configure it in your
|
interact with the service through the Web UI, or configure it in your
|
||||||
NixOS configuration. Enabling the <literal>resilio</literal> service
|
NixOS configuration.
|
||||||
also installs a systemd user unit which can be used to start
|
|
||||||
user-specific copies of the daemon. Once installed, you can use
|
|
||||||
<literal>systemctl --user start resilio</literal> as your user to start
|
|
||||||
the daemon using the configuration file located at
|
|
||||||
<literal>$HOME/.config/resilio-sync/config.json</literal>.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ in
|
|||||||
mkdir -m 0755 -p ${stateDir}/dev/
|
mkdir -m 0755 -p ${stateDir}/dev/
|
||||||
cp ${confFile} ${stateDir}/unbound.conf
|
cp ${confFile} ${stateDir}/unbound.conf
|
||||||
${optionalString cfg.enableRootTrustAnchor ''
|
${optionalString cfg.enableRootTrustAnchor ''
|
||||||
${pkgs.unbound}/bin/unbound-anchor -a ${rootTrustAnchorFile}
|
${pkgs.unbound}/bin/unbound-anchor -a ${rootTrustAnchorFile} || echo "Root anchor updated!"
|
||||||
chown unbound ${stateDir} ${rootTrustAnchorFile}
|
chown unbound ${stateDir} ${rootTrustAnchorFile}
|
||||||
''}
|
''}
|
||||||
touch ${stateDir}/dev/random
|
touch ${stateDir}/dev/random
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ in
|
|||||||
|
|
||||||
listenAddresses = mkOption {
|
listenAddresses = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [ "127.0.0.1:631" ];
|
default = [ "localhost:631" ];
|
||||||
example = [ "*:631" ];
|
example = [ "*:631" ];
|
||||||
description = ''
|
description = ''
|
||||||
A list of addresses and ports on which to listen.
|
A list of addresses and ports on which to listen.
|
||||||
@@ -321,7 +321,10 @@ in
|
|||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
serviceConfig.PrivateTmp = true;
|
serviceConfig = {
|
||||||
|
PrivateTmp = true;
|
||||||
|
RuntimeDirectory = [ "cups" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.cups-browsed = mkIf avahiEnabled
|
systemd.services.cups-browsed = mkIf avahiEnabled
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ with lib;
|
|||||||
default = [];
|
default = [];
|
||||||
example = [
|
example = [
|
||||||
{ urlPath = "/foo/bar.png";
|
{ urlPath = "/foo/bar.png";
|
||||||
files = "/home/eelco/some-file.png";
|
file = "/home/eelco/some-file.png";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
description = ''
|
description = ''
|
||||||
|
|||||||
@@ -87,11 +87,11 @@ in
|
|||||||
|
|
||||||
default = mkOption {
|
default = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "none";
|
default = "";
|
||||||
example = "plasma5";
|
example = "none";
|
||||||
description = "Default desktop manager loaded if none have been chosen.";
|
description = "Default desktop manager loaded if none have been chosen.";
|
||||||
apply = defaultDM:
|
apply = defaultDM:
|
||||||
if defaultDM == "none" && cfg.session.list != [] then
|
if defaultDM == "" && cfg.session.list != [] then
|
||||||
(head cfg.session.list).name
|
(head cfg.session.list).name
|
||||||
else if any (w: w.name == defaultDM) cfg.session.list then
|
else if any (w: w.name == defaultDM) cfg.session.list then
|
||||||
defaultDM
|
defaultDM
|
||||||
|
|||||||
@@ -182,8 +182,7 @@ in {
|
|||||||
{ inherit (pkgs) networkmanager modemmanager wpa_supplicant;
|
{ inherit (pkgs) networkmanager modemmanager wpa_supplicant;
|
||||||
inherit (pkgs.gnome3) networkmanager-openvpn networkmanager-vpnc
|
inherit (pkgs.gnome3) networkmanager-openvpn networkmanager-vpnc
|
||||||
networkmanager-openconnect networkmanager-fortisslvpn
|
networkmanager-openconnect networkmanager-fortisslvpn
|
||||||
networkmanager-pptp networkmanager-iodine
|
networkmanager-iodine networkmanager-l2tp; };
|
||||||
networkmanager-l2tp; };
|
|
||||||
|
|
||||||
# Needed for themes and backgrounds
|
# Needed for themes and backgrounds
|
||||||
environment.pathsToLink = [ "/share" ];
|
environment.pathsToLink = [ "/share" ];
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ in
|
|||||||
./afterstep.nix
|
./afterstep.nix
|
||||||
./bspwm.nix
|
./bspwm.nix
|
||||||
./dwm.nix
|
./dwm.nix
|
||||||
|
./evilwm.nix
|
||||||
./exwm.nix
|
./exwm.nix
|
||||||
./fluxbox.nix
|
./fluxbox.nix
|
||||||
./fvwm.nix
|
./fvwm.nix
|
||||||
@@ -61,9 +62,7 @@ in
|
|||||||
example = "wmii";
|
example = "wmii";
|
||||||
description = "Default window manager loaded if none have been chosen.";
|
description = "Default window manager loaded if none have been chosen.";
|
||||||
apply = defaultWM:
|
apply = defaultWM:
|
||||||
if defaultWM == "none" && cfg.session != [] then
|
if any (w: w.name == defaultWM) cfg.session then
|
||||||
(head cfg.session).name
|
|
||||||
else if any (w: w.name == defaultWM) cfg.session then
|
|
||||||
defaultWM
|
defaultWM
|
||||||
else
|
else
|
||||||
throw "Default window manager (${defaultWM}) not found.";
|
throw "Default window manager (${defaultWM}) not found.";
|
||||||
|
|||||||
@@ -161,15 +161,6 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
plainX = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Whether the X11 session can be plain (without DM/WM) and
|
|
||||||
the Xsession script will be used as fallback or not.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
autorun = mkOption {
|
autorun = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
@@ -561,11 +552,6 @@ in
|
|||||||
+ "${toString (length primaryHeads)} heads set to primary: "
|
+ "${toString (length primaryHeads)} heads set to primary: "
|
||||||
+ concatMapStringsSep ", " (x: x.output) primaryHeads;
|
+ concatMapStringsSep ", " (x: x.output) primaryHeads;
|
||||||
})
|
})
|
||||||
{ assertion = cfg.desktopManager.default == "none" && cfg.windowManager.default == "none" -> cfg.plainX;
|
|
||||||
message = "Either the desktop manager or the window manager shouldn't be `none`! "
|
|
||||||
+ "To explicitly allow this, you can also set `services.xserver.plainX` to `true`. "
|
|
||||||
+ "The `default` value looks for enabled WMs/DMs and select the first one.";
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.etc =
|
environment.etc =
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ sub GrubFs {
|
|||||||
# Based on the type pull in the identifier from the system
|
# Based on the type pull in the identifier from the system
|
||||||
my ($status, @devInfo) = runCommand("@utillinux@/bin/blkid -o export @{[$fs->device]}");
|
my ($status, @devInfo) = runCommand("@utillinux@/bin/blkid -o export @{[$fs->device]}");
|
||||||
if ($status != 0) {
|
if ($status != 0) {
|
||||||
die "Failed to get blkid info for @{[$fs->mount]} on @{[$fs->device]}";
|
die "Failed to get blkid info (returned $status) for @{[$fs->mount]} on @{[$fs->device]}";
|
||||||
}
|
}
|
||||||
my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/;
|
my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/;
|
||||||
if ($#matches != 0) {
|
if ($#matches != 0) {
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ let
|
|||||||
default = { };
|
default = { };
|
||||||
example = { mtu = "1492"; window = "524288"; };
|
example = { mtu = "1492"; window = "524288"; };
|
||||||
description = ''
|
description = ''
|
||||||
Other route options. See the symbol <literal>OPTION</literal>
|
Other route options. See the symbol <literal>OPTIONS</literal>
|
||||||
in the <literal>ip-route(8)</literal> manual page for the details.
|
in the <literal>ip-route(8)</literal> manual page for the details.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
@@ -191,7 +191,7 @@ let
|
|||||||
preferTempAddress = mkOption {
|
preferTempAddress = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = cfg.enableIPv6;
|
default = cfg.enableIPv6;
|
||||||
defaultText = literalExample "config.networking.enableIpv6";
|
defaultText = literalExample "config.networking.enableIPv6";
|
||||||
description = ''
|
description = ''
|
||||||
When using SLAAC prefer a temporary (IPv6) address over the EUI-64
|
When using SLAAC prefer a temporary (IPv6) address over the EUI-64
|
||||||
address for originating connections. This is used to reduce tracking.
|
address for originating connections. This is used to reduce tracking.
|
||||||
|
|||||||
@@ -319,8 +319,8 @@ in
|
|||||||
networkingOptions =
|
networkingOptions =
|
||||||
mkOption {
|
mkOption {
|
||||||
default = [
|
default = [
|
||||||
"-net nic,vlan=0,model=virtio"
|
"-net nic,netdev=user.0,model=virtio"
|
||||||
"-net user,vlan=0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}"
|
"-netdev user,id=user.0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}"
|
||||||
];
|
];
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = ''
|
description = ''
|
||||||
@@ -434,9 +434,11 @@ in
|
|||||||
|
|
||||||
virtualisation.pathsInNixDB = [ config.system.build.toplevel ];
|
virtualisation.pathsInNixDB = [ config.system.build.toplevel ];
|
||||||
|
|
||||||
# FIXME: Figure out how to make this work on non-x86
|
# FIXME: Consolidate this one day.
|
||||||
virtualisation.qemu.options =
|
virtualisation.qemu.options = mkMerge [
|
||||||
mkIf (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [ "-vga std" "-usbdevice tablet" ];
|
(mkIf (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [ "-vga std" "-usb" "-device usb-tablet,bus=usb-bus.0" ])
|
||||||
|
(mkIf (pkgs.stdenv.isArm || pkgs.stdenv.isAarch64) [ "-device virtio-gpu-pci" "-device usb-ehci,id=usb0" "-device usb-kbd" "-device usb-tablet" ])
|
||||||
|
];
|
||||||
|
|
||||||
# Mount the host filesystem via 9P, and bind-mount the Nix store
|
# Mount the host filesystem via 9P, and bind-mount the Nix store
|
||||||
# of the host into our own filesystem. We use mkVMOverride to
|
# of the host into our own filesystem. We use mkVMOverride to
|
||||||
|
|||||||
@@ -52,17 +52,17 @@ in rec {
|
|||||||
(all nixos.dummy)
|
(all nixos.dummy)
|
||||||
(all nixos.manual)
|
(all nixos.manual)
|
||||||
|
|
||||||
nixos.iso_minimal.x86_64-linux
|
nixos.iso_minimal.x86_64-linux or []
|
||||||
nixos.iso_minimal.i686-linux
|
nixos.iso_minimal.i686-linux or []
|
||||||
nixos.iso_graphical.x86_64-linux
|
nixos.iso_graphical.x86_64-linux or []
|
||||||
nixos.ova.x86_64-linux
|
nixos.ova.x86_64-linux or []
|
||||||
|
|
||||||
#(all nixos.tests.containers)
|
#(all nixos.tests.containers)
|
||||||
nixos.tests.chromium.x86_64-linux
|
nixos.tests.chromium.x86_64-linux or []
|
||||||
(all nixos.tests.firefox)
|
(all nixos.tests.firefox)
|
||||||
(all nixos.tests.firewall)
|
(all nixos.tests.firewall)
|
||||||
(all nixos.tests.gnome3)
|
(all nixos.tests.gnome3)
|
||||||
nixos.tests.installer.zfsroot.x86_64-linux # ZFS is 64bit only
|
nixos.tests.installer.zfsroot.x86_64-linux or [] # ZFS is 64bit only
|
||||||
(all nixos.tests.installer.lvm)
|
(all nixos.tests.installer.lvm)
|
||||||
(all nixos.tests.installer.luksroot)
|
(all nixos.tests.installer.luksroot)
|
||||||
(all nixos.tests.installer.separateBoot)
|
(all nixos.tests.installer.separateBoot)
|
||||||
@@ -81,7 +81,7 @@ in rec {
|
|||||||
(all nixos.tests.boot.uefiUsb)
|
(all nixos.tests.boot.uefiUsb)
|
||||||
(all nixos.tests.boot-stage1)
|
(all nixos.tests.boot-stage1)
|
||||||
(all nixos.tests.hibernate)
|
(all nixos.tests.hibernate)
|
||||||
nixos.tests.docker.x86_64-linux
|
nixos.tests.docker.x86_64-linux or []
|
||||||
(all nixos.tests.ecryptfs)
|
(all nixos.tests.ecryptfs)
|
||||||
(all nixos.tests.env)
|
(all nixos.tests.env)
|
||||||
(all nixos.tests.ipv6)
|
(all nixos.tests.ipv6)
|
||||||
|
|||||||
@@ -16,7 +16,11 @@ let
|
|||||||
inherit system;
|
inherit system;
|
||||||
} // args);
|
} // args);
|
||||||
|
|
||||||
callTestOnTheseSystems = systems: fn: args: forTheseSystems systems (system: hydraJob (importTest fn args system));
|
# Note: only supportedSystems are considered.
|
||||||
|
callTestOnTheseSystems = systems: fn: args:
|
||||||
|
forTheseSystems
|
||||||
|
(intersectLists supportedSystems systems)
|
||||||
|
(system: hydraJob (importTest fn args system));
|
||||||
callTest = callTestOnTheseSystems supportedSystems;
|
callTest = callTestOnTheseSystems supportedSystems;
|
||||||
|
|
||||||
callSubTests = callSubTestsOnTheseSystems supportedSystems;
|
callSubTests = callSubTestsOnTheseSystems supportedSystems;
|
||||||
@@ -51,6 +55,17 @@ let
|
|||||||
}).config.system.build.isoImage);
|
}).config.system.build.isoImage);
|
||||||
|
|
||||||
|
|
||||||
|
makeSdImage =
|
||||||
|
{ module, maintainers ? ["dezgeg"], system }:
|
||||||
|
|
||||||
|
with import nixpkgs { inherit system; };
|
||||||
|
|
||||||
|
hydraJob ((import lib/eval-config.nix {
|
||||||
|
inherit system;
|
||||||
|
modules = [ module versionModule ];
|
||||||
|
}).config.system.build.sdImage);
|
||||||
|
|
||||||
|
|
||||||
makeSystemTarball =
|
makeSystemTarball =
|
||||||
{ module, maintainers ? ["viric"], system }:
|
{ module, maintainers ? ["viric"], system }:
|
||||||
|
|
||||||
@@ -151,6 +166,10 @@ in rec {
|
|||||||
inherit system;
|
inherit system;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sd_image = forTheseSystems [ "aarch64-linux" ] (system: makeSdImage {
|
||||||
|
module = ./modules/installer/cd-dvd/sd-image-aarch64.nix;
|
||||||
|
inherit system;
|
||||||
|
});
|
||||||
|
|
||||||
# A bootable VirtualBox virtual appliance as an OVA file (i.e. packaged OVF).
|
# A bootable VirtualBox virtual appliance as an OVA file (i.e. packaged OVF).
|
||||||
ova = forTheseSystems [ "x86_64-linux" ] (system:
|
ova = forTheseSystems [ "x86_64-linux" ] (system:
|
||||||
@@ -231,7 +250,7 @@ in rec {
|
|||||||
tests.buildbot = callTest tests/buildbot.nix {};
|
tests.buildbot = callTest tests/buildbot.nix {};
|
||||||
tests.cadvisor = callTestOnTheseSystems ["x86_64-linux"] tests/cadvisor.nix {};
|
tests.cadvisor = callTestOnTheseSystems ["x86_64-linux"] tests/cadvisor.nix {};
|
||||||
tests.ceph = callTestOnTheseSystems ["x86_64-linux"] tests/ceph.nix {};
|
tests.ceph = callTestOnTheseSystems ["x86_64-linux"] tests/ceph.nix {};
|
||||||
tests.chromium = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/chromium.nix {}).stable;
|
tests.chromium = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/chromium.nix {}).stable or {};
|
||||||
tests.cjdns = callTest tests/cjdns.nix {};
|
tests.cjdns = callTest tests/cjdns.nix {};
|
||||||
tests.cloud-init = callTest tests/cloud-init.nix {};
|
tests.cloud-init = callTest tests/cloud-init.nix {};
|
||||||
tests.containers-ipv4 = callTest tests/containers-ipv4.nix {};
|
tests.containers-ipv4 = callTest tests/containers-ipv4.nix {};
|
||||||
@@ -252,8 +271,8 @@ in rec {
|
|||||||
tests.dnscrypt-proxy = callTestOnTheseSystems ["x86_64-linux"] tests/dnscrypt-proxy.nix {};
|
tests.dnscrypt-proxy = callTestOnTheseSystems ["x86_64-linux"] tests/dnscrypt-proxy.nix {};
|
||||||
tests.ecryptfs = callTest tests/ecryptfs.nix {};
|
tests.ecryptfs = callTest tests/ecryptfs.nix {};
|
||||||
tests.etcd = callTestOnTheseSystems ["x86_64-linux"] tests/etcd.nix {};
|
tests.etcd = callTestOnTheseSystems ["x86_64-linux"] tests/etcd.nix {};
|
||||||
tests.ec2-nixops = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/ec2.nix {}).boot-ec2-nixops;
|
tests.ec2-nixops = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/ec2.nix {}).boot-ec2-nixops or {};
|
||||||
tests.ec2-config = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/ec2.nix {}).boot-ec2-config;
|
tests.ec2-config = (callSubTestsOnTheseSystems ["x86_64-linux"] tests/ec2.nix {}).boot-ec2-config or {};
|
||||||
tests.elk = callSubTestsOnTheseSystems ["x86_64-linux"] tests/elk.nix {};
|
tests.elk = callSubTestsOnTheseSystems ["x86_64-linux"] tests/elk.nix {};
|
||||||
tests.env = callTest tests/env.nix {};
|
tests.env = callTest tests/env.nix {};
|
||||||
tests.ferm = callTest tests/ferm.nix {};
|
tests.ferm = callTest tests/ferm.nix {};
|
||||||
@@ -292,7 +311,7 @@ in rec {
|
|||||||
tests.kernel-copperhead = callTest tests/kernel-copperhead.nix {};
|
tests.kernel-copperhead = callTest tests/kernel-copperhead.nix {};
|
||||||
tests.kernel-latest = callTest tests/kernel-latest.nix {};
|
tests.kernel-latest = callTest tests/kernel-latest.nix {};
|
||||||
tests.kernel-lts = callTest tests/kernel-lts.nix {};
|
tests.kernel-lts = callTest tests/kernel-lts.nix {};
|
||||||
tests.kubernetes = hydraJob (import tests/kubernetes/default.nix { system = "x86_64-linux"; });
|
tests.kubernetes = callSubTestsOnTheseSystems ["x86_64-linux"] tests/kubernetes/default.nix {};
|
||||||
tests.latestKernel.login = callTest tests/login.nix { latestKernel = true; };
|
tests.latestKernel.login = callTest tests/login.nix { latestKernel = true; };
|
||||||
tests.ldap = callTest tests/ldap.nix {};
|
tests.ldap = callTest tests/ldap.nix {};
|
||||||
#tests.lightdm = callTest tests/lightdm.nix {};
|
#tests.lightdm = callTest tests/lightdm.nix {};
|
||||||
@@ -340,6 +359,7 @@ in rec {
|
|||||||
tests.predictable-interface-names = callSubTests tests/predictable-interface-names.nix {};
|
tests.predictable-interface-names = callSubTests tests/predictable-interface-names.nix {};
|
||||||
tests.printing = callTest tests/printing.nix {};
|
tests.printing = callTest tests/printing.nix {};
|
||||||
tests.prometheus = callTest tests/prometheus.nix {};
|
tests.prometheus = callTest tests/prometheus.nix {};
|
||||||
|
tests.prosody = callTest tests/prosody.nix {};
|
||||||
tests.proxy = callTest tests/proxy.nix {};
|
tests.proxy = callTest tests/proxy.nix {};
|
||||||
# tests.quagga = callTest tests/quagga.nix {};
|
# tests.quagga = callTest tests/quagga.nix {};
|
||||||
tests.quake3 = callTest tests/quake3.nix {};
|
tests.quake3 = callTest tests/quake3.nix {};
|
||||||
|
|||||||
@@ -17,20 +17,14 @@ import ./make-test.nix ({ pkgs, lib, ... }:
|
|||||||
startAll;
|
startAll;
|
||||||
|
|
||||||
$machine->fail("test -f ~root/at-1");
|
$machine->fail("test -f ~root/at-1");
|
||||||
$machine->fail("test -f ~root/batch-1");
|
|
||||||
$machine->fail("test -f ~alice/at-1");
|
$machine->fail("test -f ~alice/at-1");
|
||||||
$machine->fail("test -f ~alice/batch-1");
|
|
||||||
|
|
||||||
$machine->succeed("echo 'touch ~root/at-1' | at now+1min");
|
$machine->succeed("echo 'touch ~root/at-1' | at now+1min");
|
||||||
$machine->succeed("echo 'touch ~root/batch-1' | batch");
|
|
||||||
$machine->succeed("su - alice -c \"echo 'touch at-1' | at now+1min\"");
|
$machine->succeed("su - alice -c \"echo 'touch at-1' | at now+1min\"");
|
||||||
$machine->succeed("su - alice -c \"echo 'touch batch-1' | batch\"");
|
|
||||||
|
|
||||||
$machine->succeed("sleep 1.5m");
|
$machine->succeed("sleep 1.5m");
|
||||||
|
|
||||||
$machine->succeed("test -f ~root/at-1");
|
$machine->succeed("test -f ~root/at-1");
|
||||||
$machine->succeed("test -f ~root/batch-1");
|
|
||||||
$machine->succeed("test -f ~alice/at-1");
|
$machine->succeed("test -f ~alice/at-1");
|
||||||
$machine->succeed("test -f ~alice/batch-1");
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,21 +1,162 @@
|
|||||||
import ./make-test.nix ({ pkgs, ...}: {
|
import ./make-test.nix ({ pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
passphrase = "supersecret";
|
||||||
|
dataDir = "/ran:dom/data";
|
||||||
|
excludeFile = "not_this_file";
|
||||||
|
keepFile = "important_file";
|
||||||
|
keepFileData = "important_data";
|
||||||
|
localRepo = "/root/back:up";
|
||||||
|
archiveName = "my_archive";
|
||||||
|
remoteRepo = "borg@server:."; # No need to specify path
|
||||||
|
privateKey = pkgs.writeText "id_ed25519" ''
|
||||||
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||||
|
QyNTUxOQAAACBx8UB04Q6Q/fwDFjakHq904PYFzG9pU2TJ9KXpaPMcrwAAAJB+cF5HfnBe
|
||||||
|
RwAAAAtzc2gtZWQyNTUxOQAAACBx8UB04Q6Q/fwDFjakHq904PYFzG9pU2TJ9KXpaPMcrw
|
||||||
|
AAAEBN75NsJZSpt63faCuaD75Unko0JjlSDxMhYHAPJk2/xXHxQHThDpD9/AMWNqQer3Tg
|
||||||
|
9gXMb2lTZMn0pelo8xyvAAAADXJzY2h1ZXR6QGt1cnQ=
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
'';
|
||||||
|
publicKey = ''
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHHxQHThDpD9/AMWNqQer3Tg9gXMb2lTZMn0pelo8xyv root@client
|
||||||
|
'';
|
||||||
|
privateKeyAppendOnly = pkgs.writeText "id_ed25519" ''
|
||||||
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||||
|
QyNTUxOQAAACBacZuz1ELGQdhI7PF6dGFafCDlvh8pSEc4cHjkW0QjLwAAAJC9YTxxvWE8
|
||||||
|
cQAAAAtzc2gtZWQyNTUxOQAAACBacZuz1ELGQdhI7PF6dGFafCDlvh8pSEc4cHjkW0QjLw
|
||||||
|
AAAEAAhV7wTl5dL/lz+PF/d4PnZXuG1Id6L/mFEiGT1tZsuFpxm7PUQsZB2Ejs8Xp0YVp8
|
||||||
|
IOW+HylIRzhweORbRCMvAAAADXJzY2h1ZXR6QGt1cnQ=
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
'';
|
||||||
|
publicKeyAppendOnly = ''
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFpxm7PUQsZB2Ejs8Xp0YVp8IOW+HylIRzhweORbRCMv root@client
|
||||||
|
'';
|
||||||
|
|
||||||
|
in {
|
||||||
name = "borgbackup";
|
name = "borgbackup";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib; {
|
||||||
maintainers = [ mic92 ];
|
maintainers = with maintainers; [ dotlambda ];
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
machine = { config, pkgs, ... }: {
|
client = { config, pkgs, ... }: {
|
||||||
environment.systemPackages = [ pkgs.borgbackup ];
|
services.borgbackup.jobs = {
|
||||||
|
|
||||||
|
local = rec {
|
||||||
|
paths = dataDir;
|
||||||
|
repo = localRepo;
|
||||||
|
preHook = ''
|
||||||
|
# Don't append a timestamp
|
||||||
|
archiveName="${archiveName}"
|
||||||
|
'';
|
||||||
|
encryption = {
|
||||||
|
mode = "repokey";
|
||||||
|
inherit passphrase;
|
||||||
|
};
|
||||||
|
compression = "auto,zlib,9";
|
||||||
|
prune.keep = {
|
||||||
|
within = "1y";
|
||||||
|
yearly = 5;
|
||||||
|
};
|
||||||
|
exclude = [ "*/${excludeFile}" ];
|
||||||
|
postHook = "echo post";
|
||||||
|
startAt = [ ]; # Do not run automatically
|
||||||
|
};
|
||||||
|
|
||||||
|
remote = {
|
||||||
|
paths = dataDir;
|
||||||
|
repo = remoteRepo;
|
||||||
|
encryption.mode = "none";
|
||||||
|
startAt = [ ];
|
||||||
|
environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519";
|
||||||
|
};
|
||||||
|
|
||||||
|
remoteAppendOnly = {
|
||||||
|
paths = dataDir;
|
||||||
|
repo = remoteRepo;
|
||||||
|
encryption.mode = "none";
|
||||||
|
startAt = [ ];
|
||||||
|
environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519.appendOnly";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
server = { config, pkgs, ... }: {
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
passwordAuthentication = false;
|
||||||
|
challengeResponseAuthentication = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.borgbackup.repos.repo1 = {
|
||||||
|
authorizedKeys = [ publicKey ];
|
||||||
|
path = "/data/borgbackup";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Second repo to make sure the authorizedKeys options are merged correctly
|
||||||
|
services.borgbackup.repos.repo2 = {
|
||||||
|
authorizedKeysAppendOnly = [ publicKeyAppendOnly ];
|
||||||
|
path = "/data/borgbackup";
|
||||||
|
quota = ".5G";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
my $borg = "BORG_PASSPHRASE=supersecret borg";
|
startAll;
|
||||||
$machine->succeed("$borg init --encryption=repokey /tmp/backup");
|
|
||||||
$machine->succeed("mkdir /tmp/data/ && echo 'data' >/tmp/data/file");
|
$client->fail('test -d "${remoteRepo}"');
|
||||||
$machine->succeed("$borg create --stats /tmp/backup::test /tmp/data");
|
|
||||||
$machine->succeed("$borg extract /tmp/backup::test");
|
$client->succeed("cp ${privateKey} /root/id_ed25519");
|
||||||
$machine->succeed('c=$(cat data/file) && echo "c = $c" >&2 && [[ "$c" == "data" ]]');
|
$client->succeed("chmod 0600 /root/id_ed25519");
|
||||||
|
$client->succeed("cp ${privateKeyAppendOnly} /root/id_ed25519.appendOnly");
|
||||||
|
$client->succeed("chmod 0600 /root/id_ed25519.appendOnly");
|
||||||
|
|
||||||
|
$client->succeed("mkdir -p ${dataDir}");
|
||||||
|
$client->succeed("touch ${dataDir}/${excludeFile}");
|
||||||
|
$client->succeed("echo '${keepFileData}' > ${dataDir}/${keepFile}");
|
||||||
|
|
||||||
|
subtest "local", sub {
|
||||||
|
my $borg = "BORG_PASSPHRASE='${passphrase}' borg";
|
||||||
|
$client->systemctl("start --wait borgbackup-job-local");
|
||||||
|
$client->fail("systemctl is-failed borgbackup-job-local");
|
||||||
|
# Make sure exactly one archive has been created
|
||||||
|
$client->succeed("c=\$($borg list '${localRepo}' | wc -l) && [[ \$c == '1' ]]");
|
||||||
|
# Make sure excludeFile has been excluded
|
||||||
|
$client->fail("$borg list '${localRepo}::${archiveName}' | grep -qF '${excludeFile}'");
|
||||||
|
# Make sure keepFile has the correct content
|
||||||
|
$client->succeed("$borg extract '${localRepo}::${archiveName}'");
|
||||||
|
$client->succeed('c=$(cat ${dataDir}/${keepFile}) && [[ "$c" == "${keepFileData}" ]]');
|
||||||
|
};
|
||||||
|
|
||||||
|
subtest "remote", sub {
|
||||||
|
my $borg = "BORG_RSH='ssh -oStrictHostKeyChecking=no -i /root/id_ed25519' borg";
|
||||||
|
$server->waitForUnit("sshd.service");
|
||||||
|
$client->waitForUnit("network.target");
|
||||||
|
$client->systemctl("start --wait borgbackup-job-remote");
|
||||||
|
$client->fail("systemctl is-failed borgbackup-job-remote");
|
||||||
|
|
||||||
|
# Make sure we can't access repos other than the specified one
|
||||||
|
$client->fail("$borg list borg\@server:wrong");
|
||||||
|
|
||||||
|
#TODO: Make sure that data is actually deleted
|
||||||
|
};
|
||||||
|
|
||||||
|
subtest "remoteAppendOnly", sub {
|
||||||
|
my $borg = "BORG_RSH='ssh -oStrictHostKeyChecking=no -i /root/id_ed25519.appendOnly' borg";
|
||||||
|
$server->waitForUnit("sshd.service");
|
||||||
|
$client->waitForUnit("network.target");
|
||||||
|
$client->systemctl("start --wait borgbackup-job-remoteAppendOnly");
|
||||||
|
$client->fail("systemctl is-failed borgbackup-job-remoteAppendOnly");
|
||||||
|
|
||||||
|
# Make sure we can't access repos other than the specified one
|
||||||
|
$client->fail("$borg list borg\@server:wrong");
|
||||||
|
|
||||||
|
#TODO: Make sure that data is not actually deleted
|
||||||
|
};
|
||||||
|
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -138,8 +138,8 @@ let
|
|||||||
boulder = let
|
boulder = let
|
||||||
owner = "letsencrypt";
|
owner = "letsencrypt";
|
||||||
repo = "boulder";
|
repo = "boulder";
|
||||||
rev = "9866abab8962a591f06db457a4b84c518cc88243";
|
rev = "9c6a1f2adc4c26d925588f5ae366cfd4efb7813a";
|
||||||
version = "20170510";
|
version = "20180129";
|
||||||
|
|
||||||
in pkgs.buildGoPackage rec {
|
in pkgs.buildGoPackage rec {
|
||||||
name = "${repo}-${version}";
|
name = "${repo}-${version}";
|
||||||
@@ -147,7 +147,7 @@ let
|
|||||||
src = pkgs.fetchFromGitHub {
|
src = pkgs.fetchFromGitHub {
|
||||||
name = "${name}-src";
|
name = "${name}-src";
|
||||||
inherit rev owner repo;
|
inherit rev owner repo;
|
||||||
sha256 = "170m5cjngbrm36wi7wschqw8jzs7kxpcyzmshq3pcrmcpigrhna1";
|
sha256 = "09kszswrifm9rc6idfaq0p1mz5w21as2qbc8gd5pphrq9cf9pn55";
|
||||||
};
|
};
|
||||||
|
|
||||||
postPatch = ''
|
postPatch = ''
|
||||||
@@ -168,6 +168,18 @@ let
|
|||||||
cat "${snakeOilCa}/ca.pem" > test/test-ca.pem
|
cat "${snakeOilCa}/ca.pem" > test/test-ca.pem
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Until vendored pkcs11 is go 1.9 compatible
|
||||||
|
preBuild = ''
|
||||||
|
rm -r go/src/github.com/letsencrypt/boulder/vendor/github.com/miekg/pkcs11
|
||||||
|
'';
|
||||||
|
|
||||||
|
extraSrcs = map mkGoDep [
|
||||||
|
{ goPackagePath = "github.com/miekg/pkcs11";
|
||||||
|
rev = "6dbd569b952ec150d1425722dbbe80f2c6193f83";
|
||||||
|
sha256 = "1m8g6fx7df6hf6q6zsbyw1icjmm52dmsx28rgb0h930wagvngfwb";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
goPackagePath = "github.com/${owner}/${repo}";
|
goPackagePath = "github.com/${owner}/${repo}";
|
||||||
buildInputs = [ pkgs.libtool ];
|
buildInputs = [ pkgs.libtool ];
|
||||||
};
|
};
|
||||||
@@ -284,7 +296,11 @@ let
|
|||||||
ocsp-updater.after = [ "boulder-publisher" ];
|
ocsp-updater.after = [ "boulder-publisher" ];
|
||||||
ocsp-responder.args = "--config ${cfgDir}/ocsp-responder.json";
|
ocsp-responder.args = "--config ${cfgDir}/ocsp-responder.json";
|
||||||
ct-test-srv = {};
|
ct-test-srv = {};
|
||||||
mail-test-srv.args = "--closeFirst 5";
|
mail-test-srv.args = let
|
||||||
|
key = "${boulderSource}/test/mail-test-srv/minica-key.pem";
|
||||||
|
crt = "${boulderSource}/test/mail-test-srv/minica.pem";
|
||||||
|
in
|
||||||
|
"--closeFirst 5 --cert ${crt} --key ${key}";
|
||||||
};
|
};
|
||||||
|
|
||||||
commonPath = [ softhsm pkgs.mariadb goose boulder ];
|
commonPath = [ softhsm pkgs.mariadb goose boulder ];
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import ./make-test.nix ({ pkgs, ...} : {
|
|||||||
containers.foo.config = {};
|
containers.foo.config = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in [ pkgs.stdenv emptyContainer.config.containers.foo.path ];
|
in [ pkgs.stdenv emptyContainer.config.containers.foo.path pkgs.libxslt ];
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript =
|
testScript =
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Test for NixOS' container support.
|
# Test for NixOS' container support.
|
||||||
|
|
||||||
import ./make-test.nix ({ pkgs, ...} : {
|
import ./make-test.nix ({ pkgs, ...} : {
|
||||||
name = "containers-bridge";
|
name = "containers-tmpfs";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ ckampka ];
|
maintainers = [ ckampka ];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import ./make-test.nix ({ pkgs, ... }: {
|
|||||||
docker =
|
docker =
|
||||||
{ config, pkgs, ... }: {
|
{ config, pkgs, ... }: {
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
diskSize = 1024;
|
diskSize = 2048;
|
||||||
docker.enable = true;
|
docker.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -21,19 +21,29 @@ import ./make-test.nix ({ pkgs, ... }: {
|
|||||||
$docker->waitForUnit("sockets.target");
|
$docker->waitForUnit("sockets.target");
|
||||||
|
|
||||||
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.bash}'");
|
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.bash}'");
|
||||||
$docker->succeed("docker run ${pkgs.dockerTools.examples.bash.imageName} /bin/bash --version");
|
$docker->succeed("docker run --rm ${pkgs.dockerTools.examples.bash.imageName} /bin/bash --version");
|
||||||
|
$docker->succeed("docker rmi ${pkgs.dockerTools.examples.bash.imageName}");
|
||||||
|
|
||||||
|
# Check if the nix store is correctly initialized by listing dependencies of the installed Nix binary
|
||||||
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.nix}'");
|
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.nix}'");
|
||||||
$docker->succeed("docker run ${pkgs.dockerTools.examples.nix.imageName} /bin/nix-store -qR ${pkgs.nix}");
|
$docker->succeed("docker run --rm ${pkgs.dockerTools.examples.nix.imageName} /bin/nix-store -qR ${pkgs.nix}");
|
||||||
|
$docker->succeed("docker rmi ${pkgs.dockerTools.examples.nix.imageName}");
|
||||||
|
|
||||||
# To test the pullImage tool
|
# To test the pullImage tool
|
||||||
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.nixFromDockerHub}'");
|
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.nixFromDockerHub}'");
|
||||||
$docker->succeed("docker run nixos/nix:1.11 nix-store --version");
|
$docker->succeed("docker run --rm nixos/nix:1.11 nix-store --version");
|
||||||
|
$docker->succeed("docker rmi nixos/nix:1.11");
|
||||||
|
|
||||||
# To test runAsRoot and entry point
|
# To test runAsRoot and entry point
|
||||||
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.nginx}'");
|
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.nginx}'");
|
||||||
$docker->succeed("docker run --name nginx -d -p 8000:80 ${pkgs.dockerTools.examples.nginx.imageName}");
|
$docker->succeed("docker run --name nginx -d -p 8000:80 ${pkgs.dockerTools.examples.nginx.imageName}");
|
||||||
$docker->waitUntilSucceeds('curl http://localhost:8000/');
|
$docker->waitUntilSucceeds('curl http://localhost:8000/');
|
||||||
$docker->succeed("docker rm --force nginx");
|
$docker->succeed("docker rm --force nginx");
|
||||||
|
$docker->succeed("docker rmi '${pkgs.dockerTools.examples.nginx.imageName}'");
|
||||||
|
|
||||||
|
# An pulled image can be used as base image
|
||||||
|
$docker->succeed("docker load --input='${pkgs.dockerTools.examples.onTopOfPulledImage}'");
|
||||||
|
$docker->succeed("docker run --rm ontopofpulledimage hello");
|
||||||
|
$docker->succeed("docker rmi ontopofpulledimage");
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ import ./make-test.nix ({ lib, ... }:
|
|||||||
$machine->start;
|
$machine->start;
|
||||||
$machine->waitForUnit("grafana.service");
|
$machine->waitForUnit("grafana.service");
|
||||||
$machine->waitForOpenPort(3000);
|
$machine->waitForOpenPort(3000);
|
||||||
$machine->succeed("curl -sS http://127.0.0.1:3000/");
|
$machine->succeed("curl -sSfL http://127.0.0.1:3000/");
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -69,13 +69,20 @@ let
|
|||||||
let
|
let
|
||||||
iface = if grubVersion == 1 then "ide" else "virtio";
|
iface = if grubVersion == 1 then "ide" else "virtio";
|
||||||
isEfi = bootLoader == "systemd-boot" || (bootLoader == "grub" && grubUseEfi);
|
isEfi = bootLoader == "systemd-boot" || (bootLoader == "grub" && grubUseEfi);
|
||||||
|
|
||||||
|
# FIXME don't duplicate the -enable-kvm etc. flags here yet again!
|
||||||
qemuFlags =
|
qemuFlags =
|
||||||
(if system == "x86_64-linux" then "-m 768 " else "-m 512 ") +
|
(if system == "x86_64-linux" then "-m 768 " else "-m 512 ") +
|
||||||
(optionalString (system == "x86_64-linux") "-cpu kvm64 ");
|
(optionalString (system == "x86_64-linux") "-cpu kvm64 ") +
|
||||||
|
(optionalString (system == "aarch64-linux") "-enable-kvm -machine virt,gic-version=host -cpu host ");
|
||||||
|
|
||||||
hdFlags = ''hda => "vm-state-machine/machine.qcow2", hdaInterface => "${iface}", ''
|
hdFlags = ''hda => "vm-state-machine/machine.qcow2", hdaInterface => "${iface}", ''
|
||||||
+ optionalString isEfi ''bios => "${pkgs.OVMF.fd}/FV/OVMF.fd", '';
|
+ optionalString isEfi (if pkgs.stdenv.isAarch64
|
||||||
in
|
then ''bios => "${pkgs.OVMF.fd}/FV/QEMU_EFI.fd", ''
|
||||||
''
|
else ''bios => "${pkgs.OVMF.fd}/FV/OVMF.fd", '');
|
||||||
|
in if !isEfi && !(pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then
|
||||||
|
throw "Non-EFI boot methods are only supported on i686 / x86_64"
|
||||||
|
else ''
|
||||||
$machine->start;
|
$machine->start;
|
||||||
|
|
||||||
# Make sure that we get a login prompt etc.
|
# Make sure that we get a login prompt etc.
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user