Compare commits
1463 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0395b9b94a | ||
|
|
435ccc7980 | ||
|
|
da85bea7a8 | ||
|
|
874ad7d9f8 | ||
|
|
b0328c244d | ||
|
|
3cd0704387 | ||
|
|
428680b307 | ||
|
|
84d9e213d2 | ||
|
|
7b9583680e | ||
|
|
6e0989685a | ||
|
|
1882e802e7 | ||
|
|
44272d8719 | ||
|
|
1b851ae8f6 | ||
|
|
27788f4060 | ||
|
|
4cb5c51375 | ||
|
|
e297aa7b1c | ||
|
|
689b2783fc | ||
|
|
f68c2b5a78 | ||
|
|
9b67f234c9 | ||
|
|
099ba37820 | ||
|
|
5afee18726 | ||
|
|
9dd2b8ac7b | ||
|
|
ab8ba71205 | ||
|
|
6a0dd63508 | ||
|
|
25196d0d26 | ||
|
|
bd17ccf1d8 | ||
|
|
4801420893 | ||
|
|
2e6f06c37e | ||
|
|
aa43cbb764 | ||
|
|
6d80870832 | ||
|
|
62e214fa6f | ||
|
|
576abaa650 | ||
|
|
af1e2ffca1 | ||
|
|
71987b18d4 | ||
|
|
ca40fbdc50 | ||
|
|
8efe937a35 | ||
|
|
1dffbff57d | ||
|
|
626a94d70e | ||
|
|
f9bcbddef2 | ||
|
|
5d5b931fb1 | ||
|
|
1ca8e95178 | ||
|
|
de38fa9987 | ||
|
|
e3c19ff9bc | ||
|
|
2a8f09a8c1 | ||
|
|
00e0c416ff | ||
|
|
e4d43f1f94 | ||
|
|
c800f47395 | ||
|
|
06d4566c2d | ||
|
|
5ba5ca7888 | ||
|
|
d76c4fe770 | ||
|
|
35a49f1d7f | ||
|
|
0b59882fe3 | ||
|
|
d73e16df05 | ||
|
|
82e6275a7b | ||
|
|
1db034364a | ||
|
|
be79d1f189 | ||
|
|
0af668426d | ||
|
|
fbab9ed01e | ||
|
|
e3013543d3 | ||
|
|
2df9cbeb47 | ||
|
|
338f29dbd4 | ||
|
|
ba334bd6f7 | ||
|
|
2cb8aaa610 | ||
|
|
11a7f8ce14 | ||
|
|
7f2c324ed1 | ||
|
|
f1efb97075 | ||
|
|
cd74a55afc | ||
|
|
f986a44980 | ||
|
|
b52846ab5b | ||
|
|
e50d7335bf | ||
|
|
964349e44d | ||
|
|
21f515724c | ||
|
|
3c470c97a1 | ||
|
|
6567ab95a0 | ||
|
|
549c3706a5 | ||
|
|
90948a4e3a | ||
|
|
eedbc4e06c | ||
|
|
0fc3e581e0 | ||
|
|
d7da6c9ea9 | ||
|
|
6cdaa858d0 | ||
|
|
7536fe31dd | ||
|
|
4fcf44825f | ||
|
|
0c9718aabc | ||
|
|
8df60b4ea8 | ||
|
|
4cde04f476 | ||
|
|
f5f29dc2b7 | ||
|
|
1ff01187e2 | ||
|
|
4eb9e20028 | ||
|
|
a3aa850f0f | ||
|
|
193330d321 | ||
|
|
91a1987607 | ||
|
|
d0b88db441 | ||
|
|
7a2b64e55c | ||
|
|
ea94a87493 | ||
|
|
72804dc0bd | ||
|
|
7474ac871b | ||
|
|
8956ae1987 | ||
|
|
897ca33a1c | ||
|
|
27131866c9 | ||
|
|
9d7ce0bf45 | ||
|
|
2f5789c5d6 | ||
|
|
4b45d8c95a | ||
|
|
ec5b04862b | ||
|
|
d6dbda7004 | ||
|
|
2c39e4eca0 | ||
|
|
5773d667ee | ||
|
|
b8d446829e | ||
|
|
4db0a9555e | ||
|
|
c8155e9f5f | ||
|
|
bac8055652 | ||
|
|
c0d93a01ee | ||
|
|
5ef5d70b5e | ||
|
|
c9c3fc710b | ||
|
|
9d87d03331 | ||
|
|
513b143cd8 | ||
|
|
fd10f6f241 | ||
|
|
dc30856141 | ||
|
|
7a4d9574d9 | ||
|
|
6cf7c6a6b0 | ||
|
|
ee6ac38848 | ||
|
|
4dee01da7c | ||
|
|
0e77aa3982 | ||
|
|
9ccea31dc2 | ||
|
|
453f675810 | ||
|
|
e104842f8b | ||
|
|
4070264613 | ||
|
|
3105679226 | ||
|
|
5ab37f0e44 | ||
|
|
ac4a1ef0c1 | ||
|
|
ae506c1ea4 | ||
|
|
3050395810 | ||
|
|
212e72c609 | ||
|
|
e026bc3b05 | ||
|
|
1969f357b7 | ||
|
|
cd532a9251 | ||
|
|
bc6b3f7e8f | ||
|
|
72cd52c3cd | ||
|
|
197922ea4e | ||
|
|
4a4a009f78 | ||
|
|
f90f660b24 | ||
|
|
07d2c6d213 | ||
|
|
12991152be | ||
|
|
63c80ae26f | ||
|
|
a5c392a80e | ||
|
|
812e027e1d | ||
|
|
f1c555cef8 | ||
|
|
5cb78053f0 | ||
|
|
e38382895d | ||
|
|
f9686885be | ||
|
|
049322702b | ||
|
|
23ce4b3393 | ||
|
|
66ddbef754 | ||
|
|
f25791c196 | ||
|
|
65b5f177b5 | ||
|
|
c1ae18941a | ||
|
|
842ce8bafd | ||
|
|
15457c5673 | ||
|
|
e5c499b833 | ||
|
|
0f9a7225ab | ||
|
|
54a2cd9ce4 | ||
|
|
9971d875a4 | ||
|
|
9f01a3f0a8 | ||
|
|
82327e3cc4 | ||
|
|
8191992c83 | ||
|
|
3395e3bbc4 | ||
|
|
2d5b1b24bf | ||
|
|
ac12517f3e | ||
|
|
86aab6e9a0 | ||
|
|
d16fd24973 | ||
|
|
3460e4cf00 | ||
|
|
96051dd057 | ||
|
|
be220702a7 | ||
|
|
f8624762ac | ||
|
|
fe9d2f974d | ||
|
|
0d59f1ca49 | ||
|
|
25f32625e2 | ||
|
|
af241ae7d3 | ||
|
|
d4609bb3af | ||
|
|
37fbfffd8e | ||
|
|
f32cdc4fab | ||
|
|
38dcd0c4b8 | ||
|
|
863a45f1f3 | ||
|
|
f31c66d392 | ||
|
|
311b59001a | ||
|
|
32940702fc | ||
|
|
c7af84ce84 | ||
|
|
ef1d0142a0 | ||
|
|
908590dc6c | ||
|
|
75cd75b1ae | ||
|
|
d8306148e0 | ||
|
|
6e5165b773 | ||
|
|
b24b8ef77c | ||
|
|
ca580bec35 | ||
|
|
11ba4302e3 | ||
|
|
cbc216911d | ||
|
|
8522db1641 | ||
|
|
be59f07799 | ||
|
|
6a037a738a | ||
|
|
4e58294ae6 | ||
|
|
1dd29d7aeb | ||
|
|
97307811ee | ||
|
|
73252aef18 | ||
|
|
29205e0218 | ||
|
|
177aee07c6 | ||
|
|
3d3c7fadf7 | ||
|
|
fda7b95cb0 | ||
|
|
838509d1a0 | ||
|
|
1893f78f8e | ||
|
|
37164ae389 | ||
|
|
2f1a1c5a49 | ||
|
|
b2e00fd5b7 | ||
|
|
e94fc238cf | ||
|
|
fb98e29067 | ||
|
|
c6676ea253 | ||
|
|
fce24b7d6c | ||
|
|
60ecbd7934 | ||
|
|
3139cad9cd | ||
|
|
476493dbf5 | ||
|
|
92f9d18aa0 | ||
|
|
f3e0d46821 | ||
|
|
5421ad243e | ||
|
|
b8875213dc | ||
|
|
bfef3ec855 | ||
|
|
d1c6e0fe8c | ||
|
|
e8d6ee7c1b | ||
|
|
e350671737 | ||
|
|
6920c23701 | ||
|
|
84f112b1c8 | ||
|
|
aca4f7dff0 | ||
|
|
5324bb9399 | ||
|
|
346aeee1cb | ||
|
|
89dc62c174 | ||
|
|
308ecf6361 | ||
|
|
da1e4fdfb5 | ||
|
|
970366266b | ||
|
|
1c58ad2ffa | ||
|
|
359ede1d72 | ||
|
|
fc0ded3408 | ||
|
|
1511f01351 | ||
|
|
d41c5eb13f | ||
|
|
8af704eef1 | ||
|
|
ad228d84e5 | ||
|
|
3ed8290e53 | ||
|
|
e02edb1483 | ||
|
|
b7376edf06 | ||
|
|
6a888ec29a | ||
|
|
3cf1705583 | ||
|
|
8f6b347abd | ||
|
|
a2740c9ca2 | ||
|
|
88e6bb76de | ||
|
|
24e23a1a73 | ||
|
|
4967f0509a | ||
|
|
2ebeffcfd4 | ||
|
|
17afc42895 | ||
|
|
2e9b7c4cb2 | ||
|
|
dff440aab3 | ||
|
|
df4342bc17 | ||
|
|
1277aab219 | ||
|
|
0b606aad46 | ||
|
|
b932ea58ec | ||
|
|
8215b75d36 | ||
|
|
7a108d904e | ||
|
|
fe38fce2d8 | ||
|
|
c9857ef262 | ||
|
|
bbdf08bc0f | ||
|
|
fd73c1e20a | ||
|
|
c2154d4c84 | ||
|
|
7d4a7136db | ||
|
|
fabde432dc | ||
|
|
9f47eac92b | ||
|
|
e9c07a3b26 | ||
|
|
9b82ecbae0 | ||
|
|
c8235c5313 | ||
|
|
05d68a6e23 | ||
|
|
5cc8609e30 | ||
|
|
93a5ef0516 | ||
|
|
1c58e13bee | ||
|
|
05c45f301d | ||
|
|
2cc345b95f | ||
|
|
cfc8132391 | ||
|
|
fe34b91289 | ||
|
|
e681b1f064 | ||
|
|
8fff3e7bb5 | ||
|
|
94a0548dc4 | ||
|
|
9b845e6936 | ||
|
|
0ac35b67b8 | ||
|
|
c137c0a5eb | ||
|
|
f194629f96 | ||
|
|
db1d45037c | ||
|
|
ec9e0c03c3 | ||
|
|
a3015db6c3 | ||
|
|
0e9ddcc306 | ||
|
|
1f56235438 | ||
|
|
4af2611bd1 | ||
|
|
4c6a26539c | ||
|
|
9400cb36b7 | ||
|
|
37db080644 | ||
|
|
2c75945de5 | ||
|
|
898a3f729c | ||
|
|
09a38f9125 | ||
|
|
e56e790642 | ||
|
|
6bb4e3e8fe | ||
|
|
e2f9a61dc9 | ||
|
|
2ee1b9359b | ||
|
|
c2cab20732 | ||
|
|
b4ed97e3a3 | ||
|
|
23b8b7e096 | ||
|
|
40bffe0a43 | ||
|
|
dff12b38f9 | ||
|
|
bf1f123b09 | ||
|
|
0e0dcf2c7e | ||
|
|
c36467ad2e | ||
|
|
b29b6feaba | ||
|
|
c5e4404580 | ||
|
|
dffc3fe43b | ||
|
|
e4bd42f98f | ||
|
|
b8867a0239 | ||
|
|
82c4b37c6f | ||
|
|
27417c6160 | ||
|
|
f76e85d8f5 | ||
|
|
b6ee5e5bf0 | ||
|
|
af765a8eab | ||
|
|
c6184dec6c | ||
|
|
eb1d1ca780 | ||
|
|
b39cc4fc81 | ||
|
|
a2778988f2 | ||
|
|
561e977f51 | ||
|
|
2fd8f8bb99 | ||
|
|
fcb8d6a7a0 | ||
|
|
92bcb61127 | ||
|
|
c7654bc491 | ||
|
|
af4689f9e9 | ||
|
|
7480f4f9a4 | ||
|
|
9f64cb89cb | ||
|
|
69deca194e | ||
|
|
6d7de7f3de | ||
|
|
57b9505731 | ||
|
|
4c9ff89c26 | ||
|
|
c94f3d5575 | ||
|
|
57a30e101b | ||
|
|
fc3568e263 | ||
|
|
b144c4d617 | ||
|
|
90825dea51 | ||
|
|
3162ad5ff4 | ||
|
|
d5e1bffd2a | ||
|
|
72462b4b6e | ||
|
|
364f75e03a | ||
|
|
da2ad30054 | ||
|
|
bf6792c0df | ||
|
|
49304bae81 | ||
|
|
4ec6eb1fdf | ||
|
|
f3e432305a | ||
|
|
1e0f59ae14 | ||
|
|
766ad5db3b | ||
|
|
fdc9da034f | ||
|
|
3908d3929c | ||
|
|
6438ba22af | ||
|
|
15e8bd3bcb | ||
|
|
e0d39c8dc4 | ||
|
|
12f6bb33d2 | ||
|
|
ce2281e6d8 | ||
|
|
1c7ce2a018 | ||
|
|
73a57a2f22 | ||
|
|
3839dda2ec | ||
|
|
92ca93528f | ||
|
|
61ea9e9867 | ||
|
|
bc647fd299 | ||
|
|
a0369b14f4 | ||
|
|
657b47e1b3 | ||
|
|
6a4037ca05 | ||
|
|
092f447c6d | ||
|
|
6f639943c2 | ||
|
|
2b5ab03524 | ||
|
|
fb40d73e23 | ||
|
|
a0ad8ba12e | ||
|
|
112ff7833d | ||
|
|
38374a9d35 | ||
|
|
0681f8c907 | ||
|
|
2965d40612 | ||
|
|
8e8caf7f3e | ||
|
|
9c00fa4179 | ||
|
|
62a8fe6388 | ||
|
|
30117fb35b | ||
|
|
1762b9616c | ||
|
|
17bb00d378 | ||
|
|
c85e662004 | ||
|
|
89771a8821 | ||
|
|
772ef22c25 | ||
|
|
8ad898b2cd | ||
|
|
b1f5995a20 | ||
|
|
56a1f8f499 | ||
|
|
d1643bdaa2 | ||
|
|
68c626c6b0 | ||
|
|
ce3095e141 | ||
|
|
d3713716b6 | ||
|
|
eef09c220d | ||
|
|
72e80c59b5 | ||
|
|
01722b3d2c | ||
|
|
60da5d2b8f | ||
|
|
a3dc1e65ab | ||
|
|
42c5774e78 | ||
|
|
b7203e853e | ||
|
|
6cf23c3e8f | ||
|
|
ad8b96f1f2 | ||
|
|
c0015e87af | ||
|
|
fe97c69898 | ||
|
|
0a5a867758 | ||
|
|
fcca702a96 | ||
|
|
90da34e421 | ||
|
|
63d6e0ad3f | ||
|
|
b591536e93 | ||
|
|
596b0e0a04 | ||
|
|
c7346a275c | ||
|
|
04ed11a978 | ||
|
|
a1355917ec | ||
|
|
82a0d614cf | ||
|
|
b33621d425 | ||
|
|
1c969611ba | ||
|
|
00aa7c6705 | ||
|
|
1888f7889b | ||
|
|
b5bdfdef73 | ||
|
|
a10951de08 | ||
|
|
1dcadadf74 | ||
|
|
38b7d55af1 | ||
|
|
88b291ffc4 | ||
|
|
177f3996e2 | ||
|
|
25230a17a9 | ||
|
|
847f19a5f7 | ||
|
|
7f5b750b40 | ||
|
|
186571965d | ||
|
|
aa952d5f0b | ||
|
|
b8283773bd | ||
|
|
c8cc50d46e | ||
|
|
85e93d7b87 | ||
|
|
d3f780996c | ||
|
|
88acb64610 | ||
|
|
b4b1f4525f | ||
|
|
ab5834f7a1 | ||
|
|
52fec8dde8 | ||
|
|
c96e8cd097 | ||
|
|
5ea8161b55 | ||
|
|
c368e079ca | ||
|
|
44f3f8048f | ||
|
|
c740c3ce50 | ||
|
|
683a499ebb | ||
|
|
acc889c821 | ||
|
|
53a1644187 | ||
|
|
83eec5a997 | ||
|
|
9bdb88ea6e | ||
|
|
fe08d17934 | ||
|
|
d552d38758 | ||
|
|
2ac99a32da | ||
|
|
d798349ede | ||
|
|
ff6becafa8 | ||
|
|
1d9ab273ba | ||
|
|
cf93397d3f | ||
|
|
6cc6c15a2d | ||
|
|
6e01ecd112 | ||
|
|
588dad4084 | ||
|
|
63145be2a5 | ||
|
|
d6064dd19b | ||
|
|
2740a22d2c | ||
|
|
370428f86d | ||
|
|
86ea7d1566 | ||
|
|
a7e55151a8 | ||
|
|
fbe9fe0e75 | ||
|
|
9e43a4a041 | ||
|
|
9711524188 | ||
|
|
01200d07d2 | ||
|
|
b303ad012c | ||
|
|
edbb105e98 | ||
|
|
f134fc4cbe | ||
|
|
e46090edb1 | ||
|
|
b01d62285c | ||
|
|
a1f428b13b | ||
|
|
5ee06e612a | ||
|
|
e80257f122 | ||
|
|
c05d9ae7a5 | ||
|
|
a2d92bb20e | ||
|
|
b30f5784d0 | ||
|
|
2b761d5f50 | ||
|
|
4412f7c083 | ||
|
|
0124d118ef | ||
|
|
06880d7ed8 | ||
|
|
75a1d9849d | ||
|
|
510bc1735b | ||
|
|
62d476c7ee | ||
|
|
ea65ae0f9c | ||
|
|
1a8e15053a | ||
|
|
2b2de5ef6a | ||
|
|
6f245bf24a | ||
|
|
45d7b1a9e9 | ||
|
|
1fd59447d5 | ||
|
|
c5f23f10a8 | ||
|
|
d48edcc3a5 | ||
|
|
82a9c93c7f | ||
|
|
03ae5e6459 | ||
|
|
7689181e4f | ||
|
|
00b286275c | ||
|
|
ebfceeb333 | ||
|
|
0a97eb6bd7 | ||
|
|
542fe0d8f3 | ||
|
|
bb50c89319 | ||
|
|
465cb68244 | ||
|
|
eba840c8a1 | ||
|
|
2da6a42448 | ||
|
|
44309c5067 | ||
|
|
493d4bd949 | ||
|
|
72fb2a7edc | ||
|
|
08355643ab | ||
|
|
782c0bff45 | ||
|
|
d3dcdfa006 | ||
|
|
d3449b286b | ||
|
|
a786d26dc2 | ||
|
|
16535552ad | ||
|
|
cef8c169b1 | ||
|
|
7dedd3fa24 | ||
|
|
c5bea16611 | ||
|
|
7f6837a0f6 | ||
|
|
cd4d2705ec | ||
|
|
1a68710d4d | ||
|
|
ebc9f36a81 | ||
|
|
174b68a2a2 | ||
|
|
70581b6363 | ||
|
|
feefcb3a98 | ||
|
|
3a5f04f48c | ||
|
|
031d70e500 | ||
|
|
3e4bdfedee | ||
|
|
deac171925 | ||
|
|
3f5b98e65a | ||
|
|
d7653dfc6d | ||
|
|
ca9f589a93 | ||
|
|
b986c7f8b1 | ||
|
|
227a48f86f | ||
|
|
0dddcf867a | ||
|
|
b0b81b7500 | ||
|
|
8b039ba74f | ||
|
|
a143014d73 | ||
|
|
a474425425 | ||
|
|
b3f55fdf62 | ||
|
|
2f21d522c2 | ||
|
|
895f00c372 | ||
|
|
73bba12d8b | ||
|
|
a1a5e63e14 | ||
|
|
41c4558afe | ||
|
|
39b08f4c0c | ||
|
|
4bc00760f9 | ||
|
|
45ce2c7413 | ||
|
|
98a2adb135 | ||
|
|
6734c18c99 | ||
|
|
23aa1619da | ||
|
|
4c95ef3768 | ||
|
|
536f061765 | ||
|
|
5bd8795e1f | ||
|
|
921a2aeb05 | ||
|
|
c31000bc93 | ||
|
|
40daf0d800 | ||
|
|
fee93541a4 | ||
|
|
2dff9556a4 | ||
|
|
c30330df6f | ||
|
|
d48c973ece | ||
|
|
0b6220fbd6 | ||
|
|
7ee81f3887 | ||
|
|
c769841bc4 | ||
|
|
6267d74889 | ||
|
|
bcecc99007 | ||
|
|
1bb87c0487 | ||
|
|
66577a1c64 | ||
|
|
9b63bb88c8 | ||
|
|
1196470e92 | ||
|
|
240399e059 | ||
|
|
8d6af08530 | ||
|
|
169edf9407 | ||
|
|
804ac52489 | ||
|
|
d35231ec60 | ||
|
|
111d347237 | ||
|
|
749696e71c | ||
|
|
efa4bdbfcd | ||
|
|
4410e9d995 | ||
|
|
f05d5f89ff | ||
|
|
562585e901 | ||
|
|
4222402219 | ||
|
|
76cb3c702c | ||
|
|
1559c596f6 | ||
|
|
00b6c6d0c3 | ||
|
|
9cc8047f44 | ||
|
|
b0cb117226 | ||
|
|
62a07992bd | ||
|
|
67fe3e07b2 | ||
|
|
9622d00afa | ||
|
|
f8a2e8a552 | ||
|
|
dd3714f6ef | ||
|
|
da76c72bc9 | ||
|
|
6520b757c5 | ||
|
|
3b36c64b15 | ||
|
|
3872371f25 | ||
|
|
01dcdfcf33 | ||
|
|
1673c373c9 | ||
|
|
872ba75d8b | ||
|
|
ba9ad29fdb | ||
|
|
6bd9576aeb | ||
|
|
0bf34de43b | ||
|
|
1860070548 | ||
|
|
2040240e23 | ||
|
|
568a099c88 | ||
|
|
6d97d81656 | ||
|
|
31cc9366fc | ||
|
|
16c4856027 | ||
|
|
d267db0d75 | ||
|
|
23304f527a | ||
|
|
b134c2d052 | ||
|
|
503cc4431b | ||
|
|
915f62fa19 | ||
|
|
1fe1976e0d | ||
|
|
8945a0ea2c | ||
|
|
d1fdade755 | ||
|
|
e43e8be8e7 | ||
|
|
53edb55588 | ||
|
|
105f8ffc98 | ||
|
|
95295482ea | ||
|
|
f12a048a05 | ||
|
|
a0c56197fc | ||
|
|
30f89e0d65 | ||
|
|
d8ff3aaae7 | ||
|
|
98283915f5 | ||
|
|
ba20730b3f | ||
|
|
963f2bf12b | ||
|
|
6b5e271163 | ||
|
|
256940fc48 | ||
|
|
8decb07c31 | ||
|
|
488792a87d | ||
|
|
dfcd78d851 | ||
|
|
3b8946e09a | ||
|
|
29d35805c6 | ||
|
|
3ecb09a40a | ||
|
|
d299bd710a | ||
|
|
b9b8b8a63b | ||
|
|
e1509adbbb | ||
|
|
d087700347 | ||
|
|
c0745a2531 | ||
|
|
a75475ca61 | ||
|
|
0bb8db257d | ||
|
|
c60715e937 | ||
|
|
023217f07c | ||
|
|
165786dbc0 | ||
|
|
8edf107177 | ||
|
|
0a7ca24c26 | ||
|
|
895a74a814 | ||
|
|
ed5c0f69f2 | ||
|
|
aa23bba27f | ||
|
|
e1e49c58e1 | ||
|
|
ecbc3fedd3 | ||
|
|
4bb38591e5 | ||
|
|
7347daba8c | ||
|
|
f8b84a3b8c | ||
|
|
3229f85585 | ||
|
|
20df50d8e1 | ||
|
|
dc931fe1cd | ||
|
|
558eda0115 | ||
|
|
287084d688 | ||
|
|
c5b83d8913 | ||
|
|
91d67692cf | ||
|
|
ea7fa88131 | ||
|
|
7a716ef2a5 | ||
|
|
0ec7f47b00 | ||
|
|
43f158bb08 | ||
|
|
3f35612c04 | ||
|
|
25dff2b7db | ||
|
|
042975ea8e | ||
|
|
45c70382ac | ||
|
|
8b1d65bebe | ||
|
|
2691498b5c | ||
|
|
fbbc4d8dda | ||
|
|
e8186085e0 | ||
|
|
73d7a51ee6 | ||
|
|
532d73d5d8 | ||
|
|
5b86451f02 | ||
|
|
0afeb7f51e | ||
|
|
96443e94a1 | ||
|
|
f628ca2a1f | ||
|
|
ae568847f5 | ||
|
|
19643a781e | ||
|
|
86227390c5 | ||
|
|
6a308c7da4 | ||
|
|
d853877ce9 | ||
|
|
5f831c1057 | ||
|
|
93f863be96 | ||
|
|
121a407eec | ||
|
|
3cc18d3753 | ||
|
|
4fc30922cf | ||
|
|
1cf4801108 | ||
|
|
689b825627 | ||
|
|
b667abc699 | ||
|
|
5789eaa3f4 | ||
|
|
d1158bb816 | ||
|
|
8490ee37a6 | ||
|
|
d3eb1cf3bb | ||
|
|
d140c75530 | ||
|
|
577ebeaefb | ||
|
|
7f62be1bcd | ||
|
|
5a1fb03b8f | ||
|
|
2f992692e2 | ||
|
|
ffcf9d24a6 | ||
|
|
fbf17f1ad7 | ||
|
|
fa125b9b28 | ||
|
|
f61f67ddee | ||
|
|
374908726b | ||
|
|
07a0b8ca67 | ||
|
|
56e19d970d | ||
|
|
e321551d54 | ||
|
|
c4a40949d9 | ||
|
|
0780805246 | ||
|
|
fd86dd93dd | ||
|
|
34b12bad59 | ||
|
|
80027144ae | ||
|
|
7251d048fa | ||
|
|
3fab1f04a7 | ||
|
|
4f3fb34844 | ||
|
|
3cb0387d3f | ||
|
|
f0bbd153c6 | ||
|
|
f72206b736 | ||
|
|
89ffe1eff9 | ||
|
|
d3e1aad421 | ||
|
|
e76df9bd52 | ||
|
|
1c718f80d3 | ||
|
|
668fef2e4f | ||
|
|
e7cb2847ab | ||
|
|
f023f64f40 | ||
|
|
fe2db1dae5 | ||
|
|
b8ce649a35 | ||
|
|
8b1b5f9a12 | ||
|
|
8d7c6644c5 | ||
|
|
1a57f499b0 | ||
|
|
c0a133876e | ||
|
|
b95ce3194d | ||
|
|
e4dd7dadf4 | ||
|
|
bb6656b8a2 | ||
|
|
99bbddedb1 | ||
|
|
79f4583f8a | ||
|
|
df66d346df | ||
|
|
5789b692d4 | ||
|
|
b8564987a3 | ||
|
|
302386f775 | ||
|
|
cde4b60919 | ||
|
|
bd5388e7b2 | ||
|
|
b63f79175e | ||
|
|
40f0e3b366 | ||
|
|
d1139ff36b | ||
|
|
9ff9c3f2f8 | ||
|
|
62ff5ad424 | ||
|
|
77a78af678 | ||
|
|
649a81bcd6 | ||
|
|
e2257d4eeb | ||
|
|
2cd468874f | ||
|
|
81c53fe8e5 | ||
|
|
2b4c24f46a | ||
|
|
f7b7df8d1f | ||
|
|
418a837897 | ||
|
|
4724903c78 | ||
|
|
6f4682ad36 | ||
|
|
caa5793b4a | ||
|
|
f38224e924 | ||
|
|
fa07558a06 | ||
|
|
ddb5577f2e | ||
|
|
ce4d8e3ef8 | ||
|
|
7a58ad0ef5 | ||
|
|
612aeb2df5 | ||
|
|
c54814b175 | ||
|
|
27dc76c1a5 | ||
|
|
e6e74f987f | ||
|
|
1351b0df87 | ||
|
|
7a65b2470e | ||
|
|
583ff4ec46 | ||
|
|
cb1951e746 | ||
|
|
211bc7f0e6 | ||
|
|
f57a38b109 | ||
|
|
c2b0d8749f | ||
|
|
6de33a9c67 | ||
|
|
54801ed6ad | ||
|
|
b1f001538e | ||
|
|
83ae6503e8 | ||
|
|
951357e5fb | ||
|
|
a55f589720 | ||
|
|
c0f2f4eeef | ||
|
|
a529c740d2 | ||
|
|
e8c43abd9a | ||
|
|
4425a5c547 | ||
|
|
49bcb18035 | ||
|
|
00928c8bc9 | ||
|
|
48d4a23aa0 | ||
|
|
cf1c3d03bd | ||
|
|
4e6a2fbc56 | ||
|
|
fa738e50bc | ||
|
|
4b6d3c5a28 | ||
|
|
19ce732a13 | ||
|
|
e3bf228c92 | ||
|
|
3b4a15bd48 | ||
|
|
e5641dfe1e | ||
|
|
1102c77919 | ||
|
|
bfa41eb671 | ||
|
|
8af062f372 | ||
|
|
21948deed9 | ||
|
|
63e10b4d28 | ||
|
|
2579e32c2b | ||
|
|
90ee1e3fe3 | ||
|
|
cc3b93c991 | ||
|
|
c0d55f9183 | ||
|
|
8079ab87a2 | ||
|
|
2b9d0a99cb | ||
|
|
40dfac968a | ||
|
|
451c223dee | ||
|
|
28db297862 | ||
|
|
d771c28613 | ||
|
|
7adb986e35 | ||
|
|
f61337fdb3 | ||
|
|
3890de049d | ||
|
|
9000150a78 | ||
|
|
5d377ace2d | ||
|
|
c287e797a8 | ||
|
|
ae1e4dfad2 | ||
|
|
b501bea25f | ||
|
|
018f884ffd | ||
|
|
c698ec1f22 | ||
|
|
b6b142b4b1 | ||
|
|
0e49f94120 | ||
|
|
5476e987d5 | ||
|
|
c4f4eef915 | ||
|
|
c8b9e47fb3 | ||
|
|
00d93b65fa | ||
|
|
45ed6e7ef2 | ||
|
|
d0a2db17d9 | ||
|
|
786ee585b8 | ||
|
|
2d801bf0a4 | ||
|
|
9ce3fa2b2d | ||
|
|
3a4bd320c2 | ||
|
|
11f0680f69 | ||
|
|
05862209de | ||
|
|
621a53f64d | ||
|
|
36b3e15953 | ||
|
|
ec7d498b72 | ||
|
|
5278bb7c16 | ||
|
|
1df82b6245 | ||
|
|
9f3f2e21ed | ||
|
|
f867f090ed | ||
|
|
05f907787f | ||
|
|
bb5a6c0085 | ||
|
|
6b30e1462e | ||
|
|
41d6523ef5 | ||
|
|
47f587700d | ||
|
|
b30d1e7ada | ||
|
|
88ef77226e | ||
|
|
e629a17cc1 | ||
|
|
fe1162a805 | ||
|
|
e6a61b8da7 | ||
|
|
8df1a3b579 | ||
|
|
9a313469a4 | ||
|
|
b07060688a | ||
|
|
dadfddfa7c | ||
|
|
cea4e2c618 | ||
|
|
8bdf83f936 | ||
|
|
ceeedb58d2 | ||
|
|
7a3e7d0e61 | ||
|
|
6069b946ad | ||
|
|
603f08506e | ||
|
|
09191caea8 | ||
|
|
d1da6967b8 | ||
|
|
ae71895f55 | ||
|
|
e4b82af387 | ||
|
|
215b70f51e | ||
|
|
f78126bfd6 | ||
|
|
855abd85d8 | ||
|
|
7ee43df862 | ||
|
|
349e988903 | ||
|
|
00b8bce4d0 | ||
|
|
0d2ebb4373 | ||
|
|
3f4d3f8a1a | ||
|
|
8bf378e999 | ||
|
|
4e1a2cd537 | ||
|
|
ed64976cec | ||
|
|
651a18dd24 | ||
|
|
b90a435332 | ||
|
|
1c52e344c4 | ||
|
|
e8838713df | ||
|
|
4be4f6de56 | ||
|
|
10ae8fabf1 | ||
|
|
b77fb8acb5 | ||
|
|
ccb1022022 | ||
|
|
b8d9616af1 | ||
|
|
a5e761dddb | ||
|
|
dd77f7d593 | ||
|
|
bff3ad767e | ||
|
|
167d12b02c | ||
|
|
2af5d35fdc | ||
|
|
e4655b166c | ||
|
|
4b8f1b0ec0 | ||
|
|
21c55ab3b5 | ||
|
|
a83b10f84c | ||
|
|
b3ba762dbf | ||
|
|
818aad3ec4 | ||
|
|
eec5409a69 | ||
|
|
18b7363a69 | ||
|
|
c4969aebaf | ||
|
|
e02a1352c1 | ||
|
|
f0fc3dd88b | ||
|
|
5c0bd51d49 | ||
|
|
d2c58ba605 | ||
|
|
fdbbcc4492 | ||
|
|
542ae5c8f8 | ||
|
|
307cc8c33d | ||
|
|
795d9b8668 | ||
|
|
c935e8eeaf | ||
|
|
19c278de89 | ||
|
|
af3db853fa | ||
|
|
29727ff944 | ||
|
|
e5346c54df | ||
|
|
f702c92262 | ||
|
|
b05b98df75 | ||
|
|
efb938468c | ||
|
|
8d2f156c32 | ||
|
|
ae8884b949 | ||
|
|
2f9d60ed7f | ||
|
|
5e61b422c5 | ||
|
|
fb2dd32100 | ||
|
|
816d3e5724 | ||
|
|
82e2a070e0 | ||
|
|
edf9eb8181 | ||
|
|
0c85ef7090 | ||
|
|
844219f364 | ||
|
|
c663b84573 | ||
|
|
35db4f65a0 | ||
|
|
629ab80022 | ||
|
|
b0f7f9c98f | ||
|
|
ae522f930d | ||
|
|
cd128f4bad | ||
|
|
c6a929986a | ||
|
|
86e8c67efc | ||
|
|
4bd51d74af | ||
|
|
bbe2811a10 | ||
|
|
818ab58cc6 | ||
|
|
4546be1b3e | ||
|
|
c55bf085eb | ||
|
|
4036185cb4 | ||
|
|
3f8e620b19 | ||
|
|
7d7ec2b3a8 | ||
|
|
3fcfd899f8 | ||
|
|
beaefdf706 | ||
|
|
f12d56b27b | ||
|
|
794e4ab475 | ||
|
|
7ef053c632 | ||
|
|
4de0639105 | ||
|
|
9fc4cb2ae9 | ||
|
|
0d38b4c792 | ||
|
|
75989bdca7 | ||
|
|
054be50257 | ||
|
|
2e1493037b | ||
|
|
6656ef7b5b | ||
|
|
90ad02bf62 | ||
|
|
a75d11a7e6 | ||
|
|
e07c0dcf5c | ||
|
|
b99c6e0e29 | ||
|
|
196815f700 | ||
|
|
ab31f9986c | ||
|
|
2c8c103ef8 | ||
|
|
e5949b5ce8 | ||
|
|
5039d3b9de | ||
|
|
46e36f9b73 | ||
|
|
ff0c0b645c | ||
|
|
e4bdd49022 | ||
|
|
0babc4ff31 | ||
|
|
a5f2750ebb | ||
|
|
312bab008d | ||
|
|
584f8a62de | ||
|
|
ecba88de93 | ||
|
|
b4b5e9ce2f | ||
|
|
a705e8ce0a | ||
|
|
0f39633290 | ||
|
|
7d4ccd9b17 | ||
|
|
53b27ddce2 | ||
|
|
a91954f0c6 | ||
|
|
87b189c2b3 | ||
|
|
821380c77b | ||
|
|
dfe0938614 | ||
|
|
572aba284a | ||
|
|
aa1ea0d1e4 | ||
|
|
7c33ed691c | ||
|
|
d74c8a3f4e | ||
|
|
6631a6e1a1 | ||
|
|
97b1af1cbe | ||
|
|
dd85fc1c5a | ||
|
|
67364a5795 | ||
|
|
d1a5c28a46 | ||
|
|
042c060f78 | ||
|
|
92d917b71a | ||
|
|
86169d2114 | ||
|
|
c42d1acfeb | ||
|
|
26d92017d3 | ||
|
|
c0a7b84748 | ||
|
|
9fa21765e7 | ||
|
|
0e3574d7f8 | ||
|
|
a9d4f2b303 | ||
|
|
d74236d1f2 | ||
|
|
50c3b5df32 | ||
|
|
22d6e31fc6 | ||
|
|
ca0bce2851 | ||
|
|
cfb77d6e5b | ||
|
|
90516c5a7b | ||
|
|
ac841a4679 | ||
|
|
f1b8dd43be | ||
|
|
7b006122ae | ||
|
|
adf0216d98 | ||
|
|
d52d391164 | ||
|
|
60f4b25d7d | ||
|
|
f37b6fd07e | ||
|
|
5b01f5cbb2 | ||
|
|
596e4a5693 | ||
|
|
2df9a972fc | ||
|
|
eff80419c7 | ||
|
|
59124228b3 | ||
|
|
1bffd83e1a | ||
|
|
4ea742c3f7 | ||
|
|
0edc84a8f9 | ||
|
|
b0ebad88cd | ||
|
|
91978e3b9a | ||
|
|
ed39532dda | ||
|
|
9a1320af29 | ||
|
|
66adbdfd97 | ||
|
|
9204ea7294 | ||
|
|
f294623d1d | ||
|
|
6cb4bdf152 | ||
|
|
f43823f676 | ||
|
|
d961c29c9c | ||
|
|
36a51ecab3 | ||
|
|
3eb6217508 | ||
|
|
2fad86f361 | ||
|
|
be64fbb501 | ||
|
|
6601e46567 | ||
|
|
6e51af8023 | ||
|
|
a6eed133c5 | ||
|
|
e3128014db | ||
|
|
fe94b72acc | ||
|
|
15c035c13f | ||
|
|
80ebc553ec | ||
|
|
c8608c488c | ||
|
|
eef754813f | ||
|
|
ee22a91ab8 | ||
|
|
06bbfb6004 | ||
|
|
f91748ba73 | ||
|
|
ee3032e4de | ||
|
|
18b0808475 | ||
|
|
3c68a661f2 | ||
|
|
d3cd0f5856 | ||
|
|
e19c90fc6b | ||
|
|
ea8e8df6c7 | ||
|
|
e682a8e138 | ||
|
|
d57981bac4 | ||
|
|
6f70fcd1c5 | ||
|
|
70a2381953 | ||
|
|
0f55dd5b0e | ||
|
|
a728780fbd | ||
|
|
3c46fe62b8 | ||
|
|
db459458c3 | ||
|
|
77c2739c25 | ||
|
|
8b60529231 | ||
|
|
2ec9d2fb02 | ||
|
|
af5ff6c918 | ||
|
|
df32610dfa | ||
|
|
00ee039c27 | ||
|
|
2d5a99baf0 | ||
|
|
3614d55aa1 | ||
|
|
c660eb61f1 | ||
|
|
2a788bf9e7 | ||
|
|
06068b353d | ||
|
|
b33e85229d | ||
|
|
cb5e7254b6 | ||
|
|
8a41792d43 | ||
|
|
72fb2ccfa1 | ||
|
|
91bec54016 | ||
|
|
3a535abbc7 | ||
|
|
0610486d61 | ||
|
|
f32c6ed873 | ||
|
|
85ec6a6a44 | ||
|
|
34ec98176e | ||
|
|
eaabcba1c3 | ||
|
|
74dd603495 | ||
|
|
fffacd7c78 | ||
|
|
f94a804ced | ||
|
|
e95f3c4443 | ||
|
|
6a5f9c86f6 | ||
|
|
df7e9b6d68 | ||
|
|
c68e5913c7 | ||
|
|
202683a4fc | ||
|
|
9bdd949cfd | ||
|
|
5e51ffb1c2 | ||
|
|
2f8b0e557b | ||
|
|
080d607975 | ||
|
|
30c8c3ba2d | ||
|
|
a8dfdc52b8 | ||
|
|
c87a56f4d0 | ||
|
|
75361b6dce | ||
|
|
f8a8b4d8f8 | ||
|
|
d64e0c1b64 | ||
|
|
eda2aaae92 | ||
|
|
a424ab0444 | ||
|
|
a24f2c9b84 | ||
|
|
6f2d51287c | ||
|
|
4494000e04 | ||
|
|
064816ab98 | ||
|
|
812c0dfbe2 | ||
|
|
f2682e6e18 | ||
|
|
dead8189ac | ||
|
|
e24e2caaaf | ||
|
|
cf198952d0 | ||
|
|
7850d3d279 | ||
|
|
1b5b654fe2 | ||
|
|
33664f0e8d | ||
|
|
0a9d627e50 | ||
|
|
88b79cd55c | ||
|
|
a9fa5e050a | ||
|
|
10f3a2e5f2 | ||
|
|
759ac27f28 | ||
|
|
c9ff3747db | ||
|
|
c2d27d30cf | ||
|
|
e4f0ba55ac | ||
|
|
b5ac83f3a3 | ||
|
|
8e74d1badb | ||
|
|
78b00bbd8a | ||
|
|
5339ae4437 | ||
|
|
6766041b84 | ||
|
|
659a3e399b | ||
|
|
f7be7324b4 | ||
|
|
f53b3ef693 | ||
|
|
040c40d3fc | ||
|
|
cd35f0280c | ||
|
|
57d33013ce | ||
|
|
42ae8d95aa | ||
|
|
bac123ddd9 | ||
|
|
3593c8285d | ||
|
|
12ddbad458 | ||
|
|
e222484401 | ||
|
|
b66ab6cdbc | ||
|
|
3be2e71ab3 | ||
|
|
d593625d05 | ||
|
|
3889415bf8 | ||
|
|
75d2492f20 | ||
|
|
16d9c872e4 | ||
|
|
6c75cf69c3 | ||
|
|
0d4a10e910 | ||
|
|
c6a21aed07 | ||
|
|
538a64e8c3 | ||
|
|
b6c768fb6a | ||
|
|
4e17e7a4da | ||
|
|
33de2bc080 | ||
|
|
f435f82475 | ||
|
|
dfebfc835f | ||
|
|
80f739b571 | ||
|
|
a375326a97 | ||
|
|
a647c163ca | ||
|
|
a86fb15a15 | ||
|
|
33dc8c5e87 | ||
|
|
0f4dd4417e | ||
|
|
a828fe5b46 | ||
|
|
d8bf0d4859 | ||
|
|
38539b943a | ||
|
|
83258225e6 | ||
|
|
4dde0b0562 | ||
|
|
6963de2091 | ||
|
|
0dd988d2e3 | ||
|
|
bf386de9f2 | ||
|
|
5acb691402 | ||
|
|
8e065c6b3e | ||
|
|
f6aee2f477 | ||
|
|
95d20dfde9 | ||
|
|
aa3bc3d5dc | ||
|
|
21e9d183cc | ||
|
|
ce5776758d | ||
|
|
96d3534a9e | ||
|
|
cc804d0dc6 | ||
|
|
ca9de88a51 | ||
|
|
5761827d5b | ||
|
|
6e1b099279 | ||
|
|
9eba2c3945 | ||
|
|
697e0b3a6f | ||
|
|
41633f9f73 | ||
|
|
c879a20850 | ||
|
|
91539d305f | ||
|
|
b2ce6fde5a | ||
|
|
58c84cda3b | ||
|
|
456179018a | ||
|
|
95abf9c402 | ||
|
|
0207272b28 | ||
|
|
21ef1670b3 | ||
|
|
7d14f5c331 | ||
|
|
d155d80155 | ||
|
|
1a71495273 | ||
|
|
69e3ffb076 | ||
|
|
1b0088ebb2 | ||
|
|
ddea253ff8 | ||
|
|
c0c4ddcd9c | ||
|
|
451ebf24ce | ||
|
|
e0204f8d46 | ||
|
|
2989783f64 | ||
|
|
608b0265e1 | ||
|
|
0423787086 | ||
|
|
a7d8eaba54 | ||
|
|
d1b0909894 | ||
|
|
99851c6f06 | ||
|
|
327569035c | ||
|
|
45fd703bff | ||
|
|
31a1a8ed3c | ||
|
|
5169a6da98 | ||
|
|
c045630522 | ||
|
|
363f37d084 | ||
|
|
fc6a032989 | ||
|
|
3c1c6b8f00 | ||
|
|
12b257f045 | ||
|
|
96515b0c0d | ||
|
|
a54736355a | ||
|
|
58e423ce32 | ||
|
|
7186539711 | ||
|
|
1b3e704fb9 | ||
|
|
867967265b | ||
|
|
af4fb6ef61 | ||
|
|
ef00999fb7 | ||
|
|
4916d92092 | ||
|
|
8cffec8485 | ||
|
|
f398949b40 | ||
|
|
05fbc606fc | ||
|
|
6b2ae52808 | ||
|
|
e39999ed48 | ||
|
|
dc82160164 | ||
|
|
b654381eb3 | ||
|
|
d0f5719c2a | ||
|
|
80da7a6375 | ||
|
|
37a337bcec | ||
|
|
6e120b76ee | ||
|
|
9cee600c88 | ||
|
|
b86555aa2b | ||
|
|
3d119f0a3b | ||
|
|
d9c5e3bbf0 | ||
|
|
2ae43ced9a | ||
|
|
39a6abc0bc | ||
|
|
88541569a2 | ||
|
|
de88004a9d | ||
|
|
ab3ce1cc13 | ||
|
|
4f34c40398 | ||
|
|
784ee35c80 | ||
|
|
0ebe69dc67 | ||
|
|
0f754280a4 | ||
|
|
c89783b6a7 | ||
|
|
3b81b26457 | ||
|
|
374198ad6d | ||
|
|
11525377e1 | ||
|
|
8b7839b608 | ||
|
|
c7d44bad00 | ||
|
|
056b3ecfa4 | ||
|
|
525c78a2c3 | ||
|
|
bb1034316d | ||
|
|
5839597c66 | ||
|
|
712b616a84 | ||
|
|
cebc150b7c | ||
|
|
1c5f73f529 | ||
|
|
87295b9844 | ||
|
|
828cf7b058 | ||
|
|
141a65de09 | ||
|
|
c588f79e4d | ||
|
|
69f28eb335 | ||
|
|
02654f782f | ||
|
|
00a75b1cd2 | ||
|
|
dc4a71aae5 | ||
|
|
e69c48dc43 | ||
|
|
e7c76f7274 | ||
|
|
c6beaf5708 | ||
|
|
674c5ff64f | ||
|
|
1b18991082 | ||
|
|
e37bca136e | ||
|
|
8bec2c07a1 | ||
|
|
b4e0335d4d | ||
|
|
af7cdb1096 | ||
|
|
42bc395b63 | ||
|
|
ce113c32d2 | ||
|
|
7c9d7a253c | ||
|
|
1b4b16cc6d | ||
|
|
f7f0116dd7 | ||
|
|
76f1ba4f3b | ||
|
|
0a26b56cba | ||
|
|
fe2be8f016 | ||
|
|
62d81aadba | ||
|
|
5a8455c85e | ||
|
|
25eea97873 | ||
|
|
201b48de60 | ||
|
|
0402b6398d | ||
|
|
68a5414982 | ||
|
|
6055d84beb | ||
|
|
0a62d9b3d7 | ||
|
|
89a2fa68ac | ||
|
|
cca4a8dc1a | ||
|
|
e2ff27da07 | ||
|
|
86e93b9f61 | ||
|
|
e9c50064b5 | ||
|
|
6170bb474b | ||
|
|
0b907321cc | ||
|
|
79b02dffcb | ||
|
|
2bfb00c66e | ||
|
|
b1cc845413 | ||
|
|
ff8d0698c7 | ||
|
|
e3e5c8bc91 | ||
|
|
012f8d187c | ||
|
|
d0344dd2c1 | ||
|
|
581e1bc5b4 | ||
|
|
bcc9943cee | ||
|
|
00b2c05749 | ||
|
|
24a8f9e27b | ||
|
|
1042c10fd0 | ||
|
|
c5bc571861 | ||
|
|
7873cfb18d | ||
|
|
f1bdeac986 | ||
|
|
152b1d6bf9 | ||
|
|
28e7e29abd | ||
|
|
5a64e66268 | ||
|
|
9ccbd55c5b | ||
|
|
30e9d01516 | ||
|
|
ba0a81d14f | ||
|
|
45c83e5f9b | ||
|
|
263187a2ec | ||
|
|
b584a0e7de | ||
|
|
bf2adf72c4 | ||
|
|
ccdbf589a4 | ||
|
|
a1ea85e92b | ||
|
|
5f862658c3 | ||
|
|
6498adb002 | ||
|
|
38816759fc | ||
|
|
87e6649fc3 | ||
|
|
103c46abc2 | ||
|
|
d5626bf4c1 | ||
|
|
e292144d46 | ||
|
|
03cbb9ad59 | ||
|
|
c0b7a8a0b5 | ||
|
|
5599665a27 | ||
|
|
8f71bc33d5 | ||
|
|
840056af04 | ||
|
|
d361901bfe | ||
|
|
037ff4e70a | ||
|
|
9dd175294c | ||
|
|
97da6d62f2 | ||
|
|
4f011bccf8 | ||
|
|
7a173a7be1 | ||
|
|
b39ec410ee | ||
|
|
bb36a1a3cf | ||
|
|
a52fd0dbd0 | ||
|
|
02daf2ec0b | ||
|
|
56c7f0e8c5 | ||
|
|
60ba98242f | ||
|
|
64080d26fe | ||
|
|
2d729e4f6f | ||
|
|
287dfee35e | ||
|
|
7251a81bde | ||
|
|
b49d323ce2 | ||
|
|
cfc874ee52 | ||
|
|
c4d22997f3 | ||
|
|
5ac27053e9 | ||
|
|
9b05d5848c | ||
|
|
92063851b1 | ||
|
|
82aca33899 | ||
|
|
30a7bfbebe | ||
|
|
3cfb8d1584 | ||
|
|
eff5021eaa | ||
|
|
bfdacb712c | ||
|
|
03109e9580 | ||
|
|
c8f4d89a34 | ||
|
|
e03d6e0998 | ||
|
|
eb62e23f14 | ||
|
|
d089372565 | ||
|
|
dc8b51754b | ||
|
|
f30fd9c47b | ||
|
|
2111098a3a | ||
|
|
f7980b4712 | ||
|
|
74f954ee62 | ||
|
|
37b8e59f6f | ||
|
|
bd42510e49 | ||
|
|
b3e8d72770 | ||
|
|
ae4a3cfa03 | ||
|
|
fd205fb6f8 | ||
|
|
ad0dc41899 | ||
|
|
206bbb5dc9 | ||
|
|
cd2196b089 | ||
|
|
0db9e6cd1a | ||
|
|
c780c1124e | ||
|
|
fa7cd5369b | ||
|
|
c10c61449f | ||
|
|
4f7824c58e | ||
|
|
d367b8e787 | ||
|
|
9e7c1a4bbd | ||
|
|
4fa08f3edb | ||
|
|
26566cd28e | ||
|
|
9f14d7d33a | ||
|
|
ca6d287b33 | ||
|
|
7899fc959d | ||
|
|
739bab0be7 | ||
|
|
d45ad8fcf5 | ||
|
|
5b8c09c124 | ||
|
|
3baf8be1d1 | ||
|
|
5d8b7eb3e1 | ||
|
|
84e01203a7 | ||
|
|
da4495eb17 | ||
|
|
b669d3d2e8 | ||
|
|
7db05781a6 | ||
|
|
ed23c8568e | ||
|
|
9fff492561 | ||
|
|
ef53735f28 | ||
|
|
8120b6fb8a | ||
|
|
4c8098f30c | ||
|
|
5cdcaf5e8e | ||
|
|
b4bda4765a | ||
|
|
934642155c | ||
|
|
a12a43046b | ||
|
|
f872262e08 | ||
|
|
494fc5acbb | ||
|
|
14ebde5289 | ||
|
|
3afa16e16f | ||
|
|
8a2f5f0607 | ||
|
|
8ce96becf0 | ||
|
|
57aeef0b6a | ||
|
|
45c6405a30 | ||
|
|
f92408136e | ||
|
|
71d61508f2 | ||
|
|
89f9c0d41b | ||
|
|
02b66e97ba | ||
|
|
2cf0e67761 | ||
|
|
66b2d18243 | ||
|
|
1734e8a149 | ||
|
|
22a47ab03c | ||
|
|
6a4a8208be | ||
|
|
3beb6f6e76 | ||
|
|
81d658fe4a | ||
|
|
853d2e0aa4 | ||
|
|
ae50a5e7be | ||
|
|
dc670a173a | ||
|
|
e91160021f | ||
|
|
498f8b0485 | ||
|
|
adde4f0c8d | ||
|
|
ddd22c37c5 | ||
|
|
03ef6b69be | ||
|
|
3567bdb514 | ||
|
|
a5dffb3d3d | ||
|
|
3c67df928f | ||
|
|
4b33c2dd4c | ||
|
|
e133e91410 | ||
|
|
8e765b8876 | ||
|
|
e587aec123 | ||
|
|
7e3625f924 | ||
|
|
c6f2b89c0e | ||
|
|
0abdf4beaa | ||
|
|
cf4c29d90a | ||
|
|
b5944ac4ff | ||
|
|
c6712a007f | ||
|
|
ad0dd359b4 | ||
|
|
0b419c048b | ||
|
|
4fb82d3d80 | ||
|
|
504563ea44 | ||
|
|
0f6279d874 | ||
|
|
3202206d1d | ||
|
|
287c88ca59 | ||
|
|
e90569905e |
16
.dir-locals.el
Normal file
16
.dir-locals.el
Normal file
@@ -0,0 +1,16 @@
|
||||
((c++-mode . (
|
||||
(c-file-style . "k&r")
|
||||
(c-basic-offset . 4)
|
||||
(indent-tabs-mode . nil)
|
||||
(tab-width . 4)
|
||||
(show-trailing-whitespace . t)
|
||||
(indicate-empty-lines . t)
|
||||
(eval . (c-set-offset 'innamespace 0))
|
||||
(eval . (c-set-offset 'defun-open 0))
|
||||
(eval . (c-set-offset 'inline-open 0))
|
||||
(eval . (c-set-offset 'arglist-intro '+))
|
||||
(eval . (c-set-offset 'arglist-cont 0))
|
||||
(eval . (c-set-offset 'arglist-cont-nonempty '+))
|
||||
(eval . (c-set-offset 'substatement-open 0))
|
||||
(eval . (c-set-offset 'access-label '-))
|
||||
)))
|
||||
26
.editorconfig
Normal file
26
.editorconfig
Normal file
@@ -0,0 +1,26 @@
|
||||
# EditorConfig configuration for nix
|
||||
# http://EditorConfig.org
|
||||
|
||||
# Top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file, utf-8 charset
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
|
||||
# Match nix files, set indent to spaces with width of two
|
||||
[*.nix]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# Match c++/shell/perl, set indent to spaces with width of four
|
||||
[*.{hpp,cc,hh,sh,pl}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
# Match diffs, avoid to trim trailing whitespace
|
||||
[*.{diff,patch}]
|
||||
trim_trailing_whitespace = false
|
||||
27
.github/ISSUE_TEMPLATE.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<!--
|
||||
|
||||
# Filing a Nix issue
|
||||
|
||||
*WAIT* Are you sure you're filing your issue in the right repository?
|
||||
|
||||
We appreciate you taking the time to tell us about issues you encounter, but routing the issue to the right place will get you help sooner and save everyone time.
|
||||
|
||||
This is the Nix repository, and issues here should be about Nix the build and package management *_tool_*.
|
||||
|
||||
If you have a problem with a specific package on NixOS or when using Nix, you probably want to file an issue with _nixpkgs_, whose issue tracker is over at https://github.com/NixOS/nixpkgs/issues.
|
||||
|
||||
Examples of _Nix_ issues:
|
||||
|
||||
- Nix segfaults when I run `nix-build -A blahblah`
|
||||
- The Nix language needs a new builtin: `builtins.foobar`
|
||||
- Regression in the behavior of `nix-env` in Nix 1.12
|
||||
|
||||
Examples of _nixpkgs_ issues:
|
||||
|
||||
- glibc is b0rked on aarch64
|
||||
- chromium in NixOS doesn't support U2F but google-chrome does!
|
||||
- The OpenJDK package on macOS is missing a key component
|
||||
|
||||
Chances are if you're a newcomer to the Nix world, you'll probably want the [nixpkgs tracker](https://github.com/NixOS/nixpkgs/issues). It also gets a lot more eyeball traffic so you'll probably get a response a lot more quickly.
|
||||
|
||||
-->
|
||||
56
.gitignore
vendored
56
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
Makefile.config
|
||||
perl/Makefile.config
|
||||
|
||||
# /
|
||||
/aclocal.m4
|
||||
@@ -34,31 +35,10 @@ Makefile.config
|
||||
|
||||
# /scripts/
|
||||
/scripts/nix-profile.sh
|
||||
/scripts/nix-pull
|
||||
/scripts/nix-push
|
||||
/scripts/nix-switch
|
||||
/scripts/nix-collect-garbage
|
||||
/scripts/nix-prefetch-url
|
||||
/scripts/nix-install-package
|
||||
/scripts/nix-channel
|
||||
/scripts/nix-build
|
||||
/scripts/nix-copy-closure
|
||||
/scripts/nix-generate-patches
|
||||
/scripts/NixConfig.pm
|
||||
/scripts/NixManifest.pm
|
||||
/scripts/GeneratePatches.pm
|
||||
/scripts/download-using-manifests.pl
|
||||
/scripts/copy-from-other-stores.pl
|
||||
/scripts/download-from-binary-cache.pl
|
||||
/scripts/find-runtime-roots.pl
|
||||
/scripts/build-remote.pl
|
||||
/scripts/nix-reduce-build
|
||||
/scripts/nix-http-export.cgi
|
||||
|
||||
# /src/bsdiff-4.3/
|
||||
/src/bsdiff-4.3/bsdiff
|
||||
/src/bsdiff-4.3/bspatch
|
||||
|
||||
# /src/libexpr/
|
||||
/src/libexpr/lexer-tab.cc
|
||||
/src/libexpr/lexer-tab.hh
|
||||
@@ -68,28 +48,38 @@ Makefile.config
|
||||
/src/libexpr/nix.tbl
|
||||
|
||||
# /src/libstore/
|
||||
/src/libstore/schema.sql.hh
|
||||
/src/libstore/*.gen.hh
|
||||
|
||||
/src/nix/nix
|
||||
|
||||
# /src/nix-env/
|
||||
/src/nix-env/nix-env
|
||||
|
||||
# /src/nix-hash/
|
||||
/src/nix-hash/nix-hash
|
||||
|
||||
# /src/nix-instantiate/
|
||||
/src/nix-instantiate/nix-instantiate
|
||||
|
||||
# /src/nix-log2xml/
|
||||
/src/nix-log2xml/nix-log2xml
|
||||
|
||||
# /src/nix-store/
|
||||
/src/nix-store/nix-store
|
||||
|
||||
/src/nix-prefetch-url/nix-prefetch-url
|
||||
|
||||
# /src/nix-daemon/
|
||||
/src/nix-daemon/nix-daemon
|
||||
|
||||
# /src/download-via-ssh/
|
||||
/src/download-via-ssh/download-via-ssh
|
||||
/src/nix-collect-garbage/nix-collect-garbage
|
||||
|
||||
# /src/nix-channel/
|
||||
/src/nix-channel/nix-channel
|
||||
|
||||
# /src/buildenv/
|
||||
/src/buildenv/buildenv
|
||||
|
||||
# /src/nix-build/
|
||||
/src/nix-build/nix-build
|
||||
|
||||
/src/nix-copy-closure/nix-copy-closure
|
||||
|
||||
/src/build-remote/build-remote
|
||||
|
||||
# /tests/
|
||||
/tests/test-tmp
|
||||
@@ -109,14 +99,20 @@ Makefile.config
|
||||
/misc/systemd/nix-daemon.socket
|
||||
/misc/upstart/nix-daemon.conf
|
||||
|
||||
/src/resolve-system-dependencies/resolve-system-dependencies
|
||||
|
||||
inst/
|
||||
|
||||
*.a
|
||||
*.o
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
*.exe
|
||||
*.dep
|
||||
*~
|
||||
*.pc
|
||||
*.plist
|
||||
|
||||
# GNU Global
|
||||
GPATH
|
||||
|
||||
2
.travis.yml
Normal file
2
.travis.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
os: osx
|
||||
script: ./tests/install-darwin.sh
|
||||
229
INSTALL
229
INSTALL
@@ -1,229 +0,0 @@
|
||||
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
will cause the specified gcc to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
15
Makefile
15
Makefile
@@ -5,27 +5,28 @@ makefiles = \
|
||||
src/libstore/local.mk \
|
||||
src/libmain/local.mk \
|
||||
src/libexpr/local.mk \
|
||||
src/nix-hash/local.mk \
|
||||
src/nix/local.mk \
|
||||
src/nix-store/local.mk \
|
||||
src/nix-instantiate/local.mk \
|
||||
src/nix-env/local.mk \
|
||||
src/nix-daemon/local.mk \
|
||||
src/nix-collect-garbage/local.mk \
|
||||
src/download-via-ssh/local.mk \
|
||||
src/nix-log2xml/local.mk \
|
||||
src/nix-copy-closure/local.mk \
|
||||
src/nix-prefetch-url/local.mk \
|
||||
src/bsdiff-4.3/local.mk \
|
||||
perl/local.mk \
|
||||
src/buildenv/local.mk \
|
||||
src/resolve-system-dependencies/local.mk \
|
||||
src/nix-channel/local.mk \
|
||||
src/nix-build/local.mk \
|
||||
src/build-remote/local.mk \
|
||||
scripts/local.mk \
|
||||
corepkgs/local.mk \
|
||||
misc/systemd/local.mk \
|
||||
misc/launchd/local.mk \
|
||||
misc/upstart/local.mk \
|
||||
misc/emacs/local.mk \
|
||||
doc/manual/local.mk \
|
||||
tests/local.mk
|
||||
|
||||
GLOBAL_CXXFLAGS += -std=c++0x -g -Wall
|
||||
GLOBAL_CXXFLAGS += -std=c++14 -g -Wall -include config.h
|
||||
|
||||
-include Makefile.config
|
||||
|
||||
|
||||
@@ -3,20 +3,24 @@ CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
ENABLE_S3 = @ENABLE_S3@
|
||||
HAVE_SODIUM = @HAVE_SODIUM@
|
||||
HAVE_READLINE = @HAVE_READLINE@
|
||||
HAVE_BROTLI = @HAVE_BROTLI@
|
||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
SODIUM_LIBS = @SODIUM_LIBS@
|
||||
LIBLZMA_LIBS = @LIBLZMA_LIBS@
|
||||
SQLITE3_LIBS = @SQLITE3_LIBS@
|
||||
LIBBROTLI_LIBS = @LIBBROTLI_LIBS@
|
||||
bash = @bash@
|
||||
bindir = @bindir@
|
||||
bsddiff_compat_include = @bsddiff_compat_include@
|
||||
curl = @curl@
|
||||
brotli = @brotli@
|
||||
lsof = @lsof@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
dblatex = @dblatex@
|
||||
docdir = @docdir@
|
||||
exec_prefix = @exec_prefix@
|
||||
includedir = @includedir@
|
||||
@@ -24,12 +28,11 @@ libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
perl = @perl@
|
||||
perlbindings = @perlbindings@
|
||||
perllibdir = @perllibdir@
|
||||
pkglibdir = $(libdir)/$(PACKAGE_NAME)
|
||||
prefix = @prefix@
|
||||
sandbox_shell = @sandbox_shell@
|
||||
storedir = @storedir@
|
||||
sysconfdir = @sysconfdir@
|
||||
doc_generate = @doc_generate@
|
||||
xmllint = @xmllint@
|
||||
xsltproc = @xsltproc@
|
||||
|
||||
10
README
10
README
@@ -1,10 +0,0 @@
|
||||
Nix is a purely functional package manager. For installation and
|
||||
usage instructions, please read the manual, which can be found in
|
||||
`docs/manual/manual.html', and additionally at the Nix website at
|
||||
<http://nixos.org/>.
|
||||
|
||||
|
||||
Acknowledgments
|
||||
|
||||
This product includes software developed by the OpenSSL Project for
|
||||
use in the OpenSSL Toolkit (http://www.OpenSSL.org/).
|
||||
22
README.md
Normal file
22
README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
Nix, the purely functional package manager
|
||||
------------------------------------------
|
||||
|
||||
Nix is a new take on package management that is fairly unique. Because of its
|
||||
purity aspects, a lot of issues found in traditional package managers don't
|
||||
appear with Nix.
|
||||
|
||||
To find out more about the tool, usage and installation instructions, please
|
||||
read the manual, which is available on the Nix website at
|
||||
<http://nixos.org/nix/manual>.
|
||||
|
||||
## Contributing
|
||||
|
||||
Take a look at the [Hacking Section](http://nixos.org/nix/manual/#chap-hacking)
|
||||
of the manual. It helps you to get started with building Nix from source.
|
||||
|
||||
## License
|
||||
|
||||
Nix is released under the LGPL v2.1
|
||||
|
||||
This product includes software developed by the OpenSSL Project for
|
||||
use in the [OpenSSL Toolkit](http://www.OpenSSL.org/).
|
||||
146
configure.ac
146
configure.ac
@@ -1,5 +1,5 @@
|
||||
AC_INIT(nix, m4_esyscmd([bash -c "echo -n $(cat ./version)$VERSION_SUFFIX"]))
|
||||
AC_CONFIG_SRCDIR(README)
|
||||
AC_CONFIG_SRCDIR(README.md)
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
|
||||
AC_PROG_SED
|
||||
@@ -16,12 +16,14 @@ AC_ARG_WITH(system, AC_HELP_STRING([--with-system=SYSTEM],
|
||||
machine_name="i686";;
|
||||
amd64)
|
||||
machine_name="x86_64";;
|
||||
armv6|armv7)
|
||||
machine_name="${host_cpu}l";;
|
||||
*)
|
||||
machine_name="$host_cpu";;
|
||||
esac
|
||||
|
||||
case "$host_os" in
|
||||
linux-gnu*)
|
||||
linux-gnu*|linux-musl*)
|
||||
# For backward compatibility, strip the `-gnu' part.
|
||||
system="$machine_name-linux";;
|
||||
*)
|
||||
@@ -59,6 +61,7 @@ CFLAGS=
|
||||
CXXFLAGS=
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AX_CXX_COMPILE_STDCXX_11
|
||||
|
||||
|
||||
# Use 64-bit file system calls so that we can support files > 2 GiB.
|
||||
@@ -77,7 +80,7 @@ static char buf[1024];]],
|
||||
AC_LANG_POP(C++)
|
||||
|
||||
|
||||
AC_CHECK_FUNCS([statvfs])
|
||||
AC_CHECK_FUNCS([statvfs pipe2])
|
||||
|
||||
|
||||
# Check for lutimes, optionally used for changing the mtime of
|
||||
@@ -103,11 +106,6 @@ AC_CHECK_HEADERS([locale])
|
||||
AC_LANG_POP(C++)
|
||||
|
||||
|
||||
# Check for <err.h>.
|
||||
AC_CHECK_HEADER([err.h], [], [bsddiff_compat_include="-Icompat-include"])
|
||||
AC_SUBST([bsddiff_compat_include])
|
||||
|
||||
|
||||
AC_DEFUN([NEED_PROG],
|
||||
[
|
||||
AC_PATH_PROG($1, $2)
|
||||
@@ -116,39 +114,21 @@ if test -z "$$1"; then
|
||||
fi
|
||||
])
|
||||
|
||||
NEED_PROG(curl, curl)
|
||||
NEED_PROG(bash, bash)
|
||||
NEED_PROG(patch, patch)
|
||||
AC_PATH_PROG(xmllint, xmllint, false)
|
||||
AC_PATH_PROG(xsltproc, xsltproc, false)
|
||||
AC_PATH_PROG(flex, flex, false)
|
||||
AC_PATH_PROG(bison, bison, false)
|
||||
NEED_PROG(perl, perl)
|
||||
NEED_PROG(sed, sed)
|
||||
NEED_PROG(tar, tar)
|
||||
NEED_PROG(bzip2, bzip2)
|
||||
NEED_PROG(gzip, gzip)
|
||||
NEED_PROG(xz, xz)
|
||||
AC_PATH_PROG(dot, dot)
|
||||
AC_PATH_PROG(dblatex, dblatex)
|
||||
AC_PATH_PROG(pv, pv, pv)
|
||||
|
||||
|
||||
# Test that Perl has the open/fork feature (Perl 5.8.0 and beyond).
|
||||
AC_MSG_CHECKING([whether Perl is recent enough])
|
||||
if ! $perl -e 'open(FOO, "-|", "true"); while (<FOO>) { print; }; close FOO or die;'; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([Your Perl version is too old. Nix requires Perl 5.8.0 or newer.])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
|
||||
# Figure out where to install Perl modules.
|
||||
AC_MSG_CHECKING([for the Perl installation prefix])
|
||||
perlversion=$($perl -e 'use Config; print $Config{version};')
|
||||
perlarchname=$($perl -e 'use Config; print $Config{archname};')
|
||||
AC_SUBST(perllibdir, [${libdir}/perl5/site_perl/$perlversion/$perlarchname])
|
||||
AC_MSG_RESULT($perllibdir)
|
||||
AC_PATH_PROGS(brotli, brotli bro, bro)
|
||||
AC_PATH_PROG(lsof, lsof, lsof)
|
||||
|
||||
|
||||
NEED_PROG(cat, cat)
|
||||
@@ -166,10 +146,6 @@ AC_SUBST(storedir)
|
||||
|
||||
|
||||
# Look for OpenSSL, a required dependency.
|
||||
AC_PATH_PROG(openssl, openssl, openssl) # if not found, call openssl in $PATH
|
||||
AC_SUBST(openssl)
|
||||
AC_DEFINE_UNQUOTED(OPENSSL_PATH, ["$openssl"], [Path of the OpenSSL binary])
|
||||
|
||||
PKG_CHECK_MODULES([OPENSSL], [libcrypto], [CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"])
|
||||
|
||||
|
||||
@@ -200,6 +176,35 @@ AC_SUBST(HAVE_SODIUM, [$have_sodium])
|
||||
PKG_CHECK_MODULES([LIBLZMA], [liblzma], [CXXFLAGS="$LIBLZMA_CFLAGS $CXXFLAGS"])
|
||||
|
||||
|
||||
# Look for libbrotli{enc,dec}, optional dependencies
|
||||
PKG_CHECK_MODULES([LIBBROTLI], [libbrotlienc libbrotlidec],
|
||||
[AC_DEFINE([HAVE_BROTLI], [1], [Whether to use libbrotli.])
|
||||
CXXFLAGS="$LIBBROTLI_CFLAGS $CXXFLAGS"]
|
||||
have_brotli=1], [have_brotli=])
|
||||
AC_SUBST(HAVE_BROTLI, [$have_brotli])
|
||||
|
||||
# Look for libseccomp, required for Linux sandboxing.
|
||||
if test "$sys_name" = linux; then
|
||||
PKG_CHECK_MODULES([LIBSECCOMP], [libseccomp],
|
||||
[CXXFLAGS="$LIBSECCOMP_CFLAGS $CXXFLAGS"])
|
||||
fi
|
||||
|
||||
|
||||
# Look for aws-cpp-sdk-s3.
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_CHECK_HEADERS([aws/s3/S3Client.h],
|
||||
[AC_DEFINE([ENABLE_S3], [1], [Whether to enable S3 support via aws-sdk-cpp.])
|
||||
enable_s3=1], [enable_s3=])
|
||||
AC_SUBST(ENABLE_S3, [$enable_s3])
|
||||
AC_LANG_POP(C++)
|
||||
|
||||
if test -n "$enable_s3"; then
|
||||
declare -a aws_version_tokens=($(printf '#include <aws/core/VersionConfig.h>\nAWS_SDK_VERSION_STRING' | cpp -E | grep -v '^#.*' | sed 's/"//g' | tr '.' ' '))
|
||||
AC_DEFINE_UNQUOTED([AWS_VERSION_MAJOR], ${aws_version_tokens@<:@0@:>@}, [Major version of aws-sdk-cpp.])
|
||||
AC_DEFINE_UNQUOTED([AWS_VERSION_MINOR], ${aws_version_tokens@<:@1@:>@}, [Minor version of aws-sdk-cpp.])
|
||||
fi
|
||||
|
||||
|
||||
# Whether to use the Boehm garbage collector.
|
||||
AC_ARG_ENABLE(gc, AC_HELP_STRING([--enable-gc],
|
||||
[enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=no]]),
|
||||
@@ -211,80 +216,25 @@ if test "$gc" = yes; then
|
||||
fi
|
||||
|
||||
|
||||
# Check for the required Perl dependencies (DBI, DBD::SQLite and WWW::Curl).
|
||||
perlFlags="-I$perllibdir"
|
||||
|
||||
AC_ARG_WITH(dbi, AC_HELP_STRING([--with-dbi=PATH],
|
||||
[prefix of the Perl DBI library]),
|
||||
perlFlags="$perlFlags -I$withval")
|
||||
|
||||
AC_ARG_WITH(dbd-sqlite, AC_HELP_STRING([--with-dbd-sqlite=PATH],
|
||||
[prefix of the Perl DBD::SQLite library]),
|
||||
perlFlags="$perlFlags -I$withval")
|
||||
|
||||
AC_ARG_WITH(www-curl, AC_HELP_STRING([--with-www-curl=PATH],
|
||||
[prefix of the Perl WWW::Curl library]),
|
||||
perlFlags="$perlFlags -I$withval")
|
||||
|
||||
AC_MSG_CHECKING([whether DBD::SQLite works])
|
||||
if ! $perl $perlFlags -e 'use DBI; use DBD::SQLite;' 2>&5; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_FAILURE([The Perl modules DBI and/or DBD::SQLite are missing.])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
AC_MSG_CHECKING([whether WWW::Curl works])
|
||||
if ! $perl $perlFlags -e 'use WWW::Curl;' 2>&5; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_FAILURE([The Perl module WWW::Curl is missing.])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
AC_SUBST(perlFlags)
|
||||
|
||||
|
||||
# Check for otool, an optional dependency on Darwin.
|
||||
AC_PATH_PROG(otool, otool)
|
||||
AC_MSG_CHECKING([that otool works])
|
||||
case $host_os in
|
||||
darwin*)
|
||||
if test -z "$otool" || ! $otool --version 2>/dev/null; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([Can't get version from otool; do you need to install developer tools?])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(not needed)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Whether to build the Perl bindings
|
||||
AC_MSG_CHECKING([whether to build the Perl bindings])
|
||||
AC_ARG_ENABLE(perl-bindings, AC_HELP_STRING([--enable-perl-bindings],
|
||||
[whether to build the Perl bindings (recommended) [default=yes]]),
|
||||
perlbindings=$enableval, perlbindings=yes)
|
||||
if test "$enable_shared" = no; then
|
||||
# Perl bindings require shared libraries.
|
||||
perlbindings=no
|
||||
fi
|
||||
AC_SUBST(perlbindings)
|
||||
AC_MSG_RESULT($perlbindings)
|
||||
|
||||
|
||||
AC_ARG_ENABLE(init-state, AC_HELP_STRING([--disable-init-state],
|
||||
[do not initialise DB etc. in `make install']),
|
||||
init_state=$enableval, init_state=yes)
|
||||
#AM_CONDITIONAL(INIT_STATE, test "$init_state" = "yes")
|
||||
|
||||
|
||||
# documentation generation switch
|
||||
AC_ARG_ENABLE(doc-gen, AC_HELP_STRING([--disable-doc-gen],
|
||||
[disable documentation generation]),
|
||||
doc_generate=$enableval, doc_generate=yes)
|
||||
AC_SUBST(doc_generate)
|
||||
|
||||
|
||||
# Setuid installations.
|
||||
AC_CHECK_FUNCS([setresuid setreuid lchown])
|
||||
|
||||
|
||||
# Nice to have, but not essential.
|
||||
AC_CHECK_FUNCS([strsignal posix_fallocate nanosleep sysconf])
|
||||
AC_CHECK_FUNCS([strsignal posix_fallocate sysconf])
|
||||
|
||||
|
||||
# This is needed if bzip2 is a static library, and the Nix libraries
|
||||
@@ -310,6 +260,12 @@ fi
|
||||
AC_SUBST(tarFlags)
|
||||
|
||||
|
||||
AC_ARG_WITH(sandbox-shell, AC_HELP_STRING([--with-sandbox-shell=PATH],
|
||||
[path of a statically-linked shell to use as /bin/sh in sandboxes]),
|
||||
sandbox_shell=$withval)
|
||||
AC_SUBST(sandbox_shell)
|
||||
|
||||
|
||||
# Expand all variables in config.status.
|
||||
test "$prefix" = NONE && prefix=$ac_default_prefix
|
||||
test "$exec_prefix" = NONE && exec_prefix='${prefix}'
|
||||
|
||||
@@ -5,8 +5,7 @@ with import <nix/config.nix>;
|
||||
derivation {
|
||||
name = "user-environment";
|
||||
system = builtins.currentSystem;
|
||||
builder = perl;
|
||||
args = [ "-w" ./buildenv.pl ];
|
||||
builder = nixLibexecDir + "/nix/buildenv";
|
||||
|
||||
inherit manifest;
|
||||
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
use strict;
|
||||
use Cwd;
|
||||
use IO::Handle;
|
||||
use utf8;
|
||||
|
||||
STDOUT->autoflush(1);
|
||||
|
||||
my $out = $ENV{"out"};
|
||||
mkdir "$out", 0755 || die "error creating $out";
|
||||
|
||||
|
||||
my $symlinks = 0;
|
||||
|
||||
my %priorities;
|
||||
|
||||
|
||||
# For each activated package, create symlinks.
|
||||
|
||||
sub createLinks {
|
||||
my $srcDir = shift;
|
||||
my $dstDir = shift;
|
||||
my $priority = shift;
|
||||
|
||||
my @srcFiles = glob("$srcDir/*");
|
||||
|
||||
foreach my $srcFile (@srcFiles) {
|
||||
my $baseName = $srcFile;
|
||||
$baseName =~ s/^.*\///g; # strip directory
|
||||
my $dstFile = "$dstDir/$baseName";
|
||||
|
||||
# The files below are special-cased so that they don't show up
|
||||
# in user profiles, either because they are useless, or
|
||||
# because they would cause pointless collisions (e.g., each
|
||||
# Python package brings its own
|
||||
# `$out/lib/pythonX.Y/site-packages/easy-install.pth'.)
|
||||
# Urgh, hacky...
|
||||
if ($srcFile =~ /\/propagated-build-inputs$/ ||
|
||||
$srcFile =~ /\/nix-support$/ ||
|
||||
$srcFile =~ /\/perllocal.pod$/ ||
|
||||
$srcFile =~ /\/info\/dir$/ ||
|
||||
$srcFile =~ /\/log$/)
|
||||
{
|
||||
# Do nothing.
|
||||
}
|
||||
|
||||
elsif (-d $srcFile) {
|
||||
|
||||
lstat $dstFile;
|
||||
|
||||
if (-d _) {
|
||||
createLinks($srcFile, $dstFile, $priority);
|
||||
}
|
||||
|
||||
elsif (-l _) {
|
||||
my $target = readlink $dstFile or die;
|
||||
if (!-d $target) {
|
||||
die "collision between directory ‘$srcFile’ and non-directory ‘$target’";
|
||||
}
|
||||
unlink $dstFile or die "error unlinking ‘$dstFile’: $!";
|
||||
mkdir $dstFile, 0755 ||
|
||||
die "error creating directory ‘$dstFile’: $!";
|
||||
createLinks($target, $dstFile, $priorities{$dstFile});
|
||||
createLinks($srcFile, $dstFile, $priority);
|
||||
}
|
||||
|
||||
else {
|
||||
symlink($srcFile, $dstFile) ||
|
||||
die "error creating link ‘$dstFile’: $!";
|
||||
$priorities{$dstFile} = $priority;
|
||||
$symlinks++;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (-l $dstFile) {
|
||||
my $target = readlink $dstFile;
|
||||
my $prevPriority = $priorities{$dstFile};
|
||||
die("collision between ‘$srcFile’ and ‘$target’; " .
|
||||
"use ‘nix-env --set-flag priority NUMBER PKGNAME’ " .
|
||||
"to change the priority of one of the conflicting packages\n")
|
||||
if $prevPriority == $priority;
|
||||
next if $prevPriority < $priority;
|
||||
unlink $dstFile or die;
|
||||
}
|
||||
|
||||
symlink($srcFile, $dstFile) ||
|
||||
die "error creating link ‘$dstFile’: $!";
|
||||
$priorities{$dstFile} = $priority;
|
||||
$symlinks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my %done;
|
||||
my %postponed;
|
||||
|
||||
sub addPkg;
|
||||
sub addPkg {
|
||||
my $pkgDir = shift;
|
||||
my $priority = shift;
|
||||
|
||||
return if (defined $done{$pkgDir});
|
||||
$done{$pkgDir} = 1;
|
||||
|
||||
# print "symlinking $pkgDir\n";
|
||||
createLinks("$pkgDir", "$out", $priority);
|
||||
|
||||
my $propagatedFN = "$pkgDir/nix-support/propagated-user-env-packages";
|
||||
if (-e $propagatedFN) {
|
||||
open PROP, "<$propagatedFN" or die;
|
||||
my $propagated = <PROP>;
|
||||
close PROP;
|
||||
my @propagated = split ' ', $propagated;
|
||||
foreach my $p (@propagated) {
|
||||
$postponed{$p} = 1 unless defined $done{$p};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Convert the stuff we get from the environment back into a coherent
|
||||
# data type.
|
||||
my @pkgs;
|
||||
my @derivations = split ' ', $ENV{"derivations"};
|
||||
while (scalar @derivations) {
|
||||
my $active = shift @derivations;
|
||||
my $priority = shift @derivations;
|
||||
my $outputs = shift @derivations;
|
||||
for (my $n = 0; $n < $outputs; $n++) {
|
||||
my $path = shift @derivations;
|
||||
push @pkgs,
|
||||
{ path => $path
|
||||
, active => $active ne "false"
|
||||
, priority => int($priority) };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Symlink to the packages that have been installed explicitly by the
|
||||
# user. Process in priority order to reduce unnecessary
|
||||
# symlink/unlink steps.
|
||||
@pkgs = sort { $a->{priority} <=> $b->{priority} || $a->{path} cmp $b->{path} } @pkgs;
|
||||
foreach my $pkg (@pkgs) {
|
||||
#print $pkg, " ", $pkgs{$pkg}->{priority}, "\n";
|
||||
addPkg($pkg->{path}, $pkg->{priority}) if $pkg->{active};
|
||||
}
|
||||
|
||||
|
||||
# Symlink to the packages that have been "propagated" by packages
|
||||
# installed by the user (i.e., package X declares that it wants Y
|
||||
# installed as well). We do these later because they have a lower
|
||||
# priority in case of collisions.
|
||||
my $priorityCounter = 1000; # don't care about collisions
|
||||
while (scalar(keys %postponed) > 0) {
|
||||
my @pkgDirs = keys %postponed;
|
||||
%postponed = ();
|
||||
foreach my $pkgDir (sort @pkgDirs) {
|
||||
addPkg($pkgDir, $priorityCounter++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
print STDERR "created $symlinks symlinks in user environment\n";
|
||||
|
||||
|
||||
symlink($ENV{"manifest"}, "$out/manifest.nix") or die "cannot create manifest";
|
||||
@@ -3,7 +3,6 @@ let
|
||||
let val = builtins.getEnv var; in
|
||||
if val != "" then val else def;
|
||||
in rec {
|
||||
perl = "@perl@";
|
||||
shell = "@bash@";
|
||||
coreutils = "@coreutils@";
|
||||
bzip2 = "@bzip2@";
|
||||
@@ -14,6 +13,10 @@ in rec {
|
||||
tr = "@tr@";
|
||||
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
|
||||
nixPrefix = "@prefix@";
|
||||
nixLibexecDir = fromEnv "NIX_LIBEXEC_DIR" "@libexecdir@";
|
||||
nixLocalstateDir = "@localstatedir@";
|
||||
nixSysconfDir = "@sysconfdir@";
|
||||
nixStoreDir = fromEnv "NIX_STORE_DIR" "@storedir@";
|
||||
|
||||
# If Nix is installed in the Nix store, then automatically add it as
|
||||
# a dependency to the core packages. This ensures that they work
|
||||
|
||||
@@ -1,26 +1,20 @@
|
||||
with import <nix/config.nix>;
|
||||
|
||||
{ system ? builtins.currentSystem
|
||||
, url
|
||||
, outputHash ? ""
|
||||
, outputHashAlgo ? ""
|
||||
, md5 ? "", sha1 ? "", sha256 ? ""
|
||||
, md5 ? "", sha1 ? "", sha256 ? "", sha512 ? ""
|
||||
, outputHash ?
|
||||
if sha512 != "" then sha512 else if sha1 != "" then sha1 else if md5 != "" then md5 else sha256
|
||||
, outputHashAlgo ?
|
||||
if sha512 != "" then "sha512" else if sha1 != "" then "sha1" else if md5 != "" then "md5" else "sha256"
|
||||
, executable ? false
|
||||
, unpack ? false
|
||||
, name ? baseNameOf (toString url)
|
||||
}:
|
||||
|
||||
assert (outputHash != "" && outputHashAlgo != "")
|
||||
|| md5 != "" || sha1 != "" || sha256 != "";
|
||||
|
||||
derivation {
|
||||
builder = "builtin:fetchurl";
|
||||
|
||||
# New-style output content requirements.
|
||||
outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else
|
||||
if sha256 != "" then "sha256" else if sha1 != "" then "sha1" else "md5";
|
||||
outputHash = if outputHash != "" then outputHash else
|
||||
if sha256 != "" then sha256 else if sha1 != "" then sha1 else md5;
|
||||
inherit outputHashAlgo outputHash;
|
||||
outputHashMode = if unpack || executable then "recursive" else "flat";
|
||||
|
||||
inherit name system url executable unpack;
|
||||
@@ -35,4 +29,7 @@ derivation {
|
||||
# by definition pure.
|
||||
"http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"
|
||||
];
|
||||
|
||||
# To make "nix-prefetch-url" work.
|
||||
urls = [ url ];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
corepkgs_FILES = nar.nix buildenv.nix buildenv.pl unpack-channel.nix derivation.nix fetchurl.nix imported-drv-to-derivation.nix
|
||||
corepkgs_FILES = buildenv.nix unpack-channel.nix derivation.nix fetchurl.nix imported-drv-to-derivation.nix
|
||||
|
||||
$(foreach file,config.nix $(corepkgs_FILES),$(eval $(call install-data-in,$(d)/$(file),$(datadir)/nix/corepkgs)))
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
with import <nix/config.nix>;
|
||||
|
||||
let
|
||||
|
||||
builder = builtins.toFile "nar.sh"
|
||||
''
|
||||
export PATH=${nixBinDir}:${coreutils}
|
||||
|
||||
if [ $compressionType = xz ]; then
|
||||
ext=.xz
|
||||
compressor="| ${xz} -7"
|
||||
elif [ $compressionType = bzip2 ]; then
|
||||
ext=.bz2
|
||||
compressor="| ${bzip2}"
|
||||
else
|
||||
ext=
|
||||
compressor=
|
||||
fi
|
||||
|
||||
echo "packing ‘$storePath’..."
|
||||
mkdir $out
|
||||
dst=$out/tmp.nar$ext
|
||||
|
||||
set -o pipefail
|
||||
eval "nix-store --dump \"$storePath\" $compressor > $dst"
|
||||
|
||||
hash=$(nix-hash --flat --type $hashAlgo --base32 $dst)
|
||||
echo -n $hash > $out/nar-compressed-hash
|
||||
|
||||
mv $dst $out/$hash.nar$ext
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{ storePath, hashAlgo, compressionType }:
|
||||
|
||||
derivation {
|
||||
name = "nar";
|
||||
system = builtins.currentSystem;
|
||||
builder = shell;
|
||||
args = [ "-e" builder ];
|
||||
inherit storePath hashAlgo compressionType;
|
||||
|
||||
# Remote machines may not have ${nixBinDir} or ${coreutils} in the same prefixes
|
||||
preferLocalBuild = true;
|
||||
|
||||
inherit chrootDeps;
|
||||
}
|
||||
@@ -15,7 +15,9 @@ let
|
||||
else
|
||||
${bzip2} -d < $src | ${tar} xf - ${tarFlags}
|
||||
fi
|
||||
mv * $out/$channelName
|
||||
if [ * != $channelName ]; then
|
||||
mv * $out/$channelName
|
||||
fi
|
||||
if [ -n "$binaryCacheURL" ]; then
|
||||
mkdir $out/binary-caches
|
||||
echo -n "$binaryCacheURL" > $out/binary-caches/$channelName
|
||||
|
||||
18
dev-shell
18
dev-shell
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
if [ -e tests/test-tmp ]; then
|
||||
chmod -R u+w tests/test-tmp
|
||||
rm -rf tests/test-tmp
|
||||
fi
|
||||
|
||||
s=$(type -p nix-shell)
|
||||
exec $s release.nix -A tarball --command "
|
||||
unset http_proxy
|
||||
export NIX_REMOTE=$NIX_REMOTE
|
||||
export NIX_PATH='$NIX_PATH'
|
||||
export NIX_BUILD_SHELL=$(type -p bash)
|
||||
export c=\$configureFlags
|
||||
exec $s release.nix -A build.$(if [ $(uname -s) = Darwin ]; then echo x86_64-darwin; else echo x86_64-linux; fi) --exclude tarball --command '
|
||||
configureFlags+=\" \$c --prefix=$(pwd)/inst --sysconfdir=$(pwd)/inst/etc\"
|
||||
return
|
||||
'" \
|
||||
"$@"
|
||||
@@ -11,9 +11,9 @@ forward Nix builds to other machines over the network. This allows
|
||||
multiple builds to be performed in parallel (thus improving
|
||||
performance) and allows Nix to perform multi-platform builds in a
|
||||
semi-transparent way. For instance, if you perform a build for a
|
||||
<literal>powerpc-darwin</literal> on an <literal>i686-linux</literal>
|
||||
<literal>x86_64-darwin</literal> on an <literal>i686-linux</literal>
|
||||
machine, Nix can automatically forward the build to a
|
||||
<literal>powerpc-darwin</literal> machine, if available.</para>
|
||||
<literal>x86_64-darwin</literal> machine, if available.</para>
|
||||
|
||||
<para>You can enable distributed builds by setting the environment
|
||||
variable <envar>NIX_BUILD_HOOK</envar> to point to a program that Nix
|
||||
@@ -22,15 +22,12 @@ will call whenever it wants to build a derivation. The build hook
|
||||
will perform it in the usual way if possible, or it can accept it, in
|
||||
which case it is responsible for somehow getting the inputs of the
|
||||
build to another machine, doing the build there, and getting the
|
||||
results back. The details of the build hook protocol are described in
|
||||
the documentation of the <link
|
||||
linkend="envar-build-hook"><envar>NIX_BUILD_HOOK</envar>
|
||||
variable</link>.</para>
|
||||
results back.</para>
|
||||
|
||||
<example xml:id='ex-remote-systems'><title>Remote machine configuration:
|
||||
<filename>remote-systems.conf</filename></title>
|
||||
<programlisting>
|
||||
nix@mcflurry.labs.cs.uu.nl powerpc-darwin /home/nix/.ssh/id_quarterpounder_auto 2
|
||||
nix@mcflurry.labs.cs.uu.nl x86_64-darwin /home/nix/.ssh/id_quarterpounder_auto 2
|
||||
nix@scratchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 1 kvm
|
||||
nix@itchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 2
|
||||
nix@poochie.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 2 kvm perf
|
||||
@@ -42,9 +39,10 @@ purposes. It uses <command>ssh</command> and
|
||||
<command>nix-copy-closure</command> to copy the build inputs and
|
||||
outputs and perform the remote build. To use it, you should set
|
||||
<envar>NIX_BUILD_HOOK</envar> to
|
||||
<filename><replaceable>prefix</replaceable>/libexec/nix/build-remote.pl</filename>.
|
||||
<filename><replaceable>prefix</replaceable>/libexec/nix/build-remote</filename>.
|
||||
You should also define a list of available build machines and point
|
||||
the environment variable <envar>NIX_REMOTE_SYSTEMS</envar> to it. An
|
||||
the environment variable <envar>NIX_REMOTE_SYSTEMS</envar> to
|
||||
it. <envar>NIX_REMOTE_SYSTEMS</envar> must be an absolute path. An
|
||||
example configuration is shown in <xref linkend='ex-remote-systems'
|
||||
/>. Each line in the file specifies a machine, with the following
|
||||
bits of information:
|
||||
@@ -58,7 +56,7 @@ bits of information:
|
||||
<filename>~/.ssh/config</filename>.</para></listitem>
|
||||
|
||||
<listitem><para>A comma-separated list of Nix platform type
|
||||
identifiers, such as <literal>powerpc-darwin</literal>. It is
|
||||
identifiers, such as <literal>x86_64-darwin</literal>. It is
|
||||
possible for a machine to support multiple platform types, e.g.,
|
||||
<literal>i686-linux,x86_64-linux</literal>.</para></listitem>
|
||||
|
||||
@@ -67,7 +65,7 @@ bits of information:
|
||||
should not have a passphrase!</para></listitem>
|
||||
|
||||
<listitem><para>The maximum number of builds that
|
||||
<filename>build-remote.pl</filename> will execute in parallel on the
|
||||
<filename>build-remote</filename> will execute in parallel on the
|
||||
machine. Typically this should be equal to the number of CPU cores.
|
||||
For instance, the machine <literal>itchy</literal> in the example
|
||||
will execute up to 8 builds in parallel.</para></listitem>
|
||||
@@ -79,7 +77,7 @@ bits of information:
|
||||
<listitem><para>A comma-separated list of <emphasis>supported
|
||||
features</emphasis>. If a derivation has the
|
||||
<varname>requiredSystemFeatures</varname> attribute, then
|
||||
<filename>build-remote.pl</filename> will only perform the
|
||||
<filename>build-remote</filename> will only perform the
|
||||
derivation on a machine that has the specified features. For
|
||||
instance, the attribute
|
||||
|
||||
@@ -102,14 +100,6 @@ requiredSystemFeatures = [ "kvm" ];
|
||||
|
||||
</orderedlist>
|
||||
|
||||
You should also set up the environment variable
|
||||
<envar>NIX_CURRENT_LOAD</envar> to point at a directory (e.g.,
|
||||
<filename>/var/run/nix/current-load</filename>) that
|
||||
<filename>build-remote.pl</filename> uses to remember how many builds
|
||||
it is currently executing remotely. It doesn't look at the actual
|
||||
load on the remote machine, so if you have multiple instances of Nix
|
||||
running, they should use the same <envar>NIX_CURRENT_LOAD</envar>
|
||||
file. Maybe in the future <filename>build-remote.pl</filename> will
|
||||
look at the actual remote load.</para>
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -17,28 +17,48 @@
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>A number of persistent settings of Nix are stored in the file
|
||||
<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename>.
|
||||
This file is a list of <literal><replaceable>name</replaceable> =
|
||||
<para>Nix reads settings from two configuration files:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>The system-wide configuration file
|
||||
<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename>
|
||||
(i.e. <filename>/etc/nix/nix.conf</filename> on most systems), or
|
||||
<filename>$NIX_CONF_DIR/nix.conf</filename> if
|
||||
<envar>NIX_CONF_DIR</envar> is set.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The user configuration file
|
||||
<filename>$XDG_CONFIG_HOME/nix/nix.conf</filename>, or
|
||||
<filename>~/.config/nix/nix.conf</filename> if
|
||||
<envar>XDG_CONFIG_HOME</envar> is not set.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
<para>The configuration files consist of
|
||||
<literal><replaceable>name</replaceable> =
|
||||
<replaceable>value</replaceable></literal> pairs, one per line.
|
||||
Comments start with a <literal>#</literal> character. Here is an example
|
||||
configuration file:</para>
|
||||
Comments start with a <literal>#</literal> character. Here is an
|
||||
example configuration file:</para>
|
||||
|
||||
<programlisting>
|
||||
gc-keep-outputs = true # Nice for developers
|
||||
gc-keep-derivations = true # Idem
|
||||
env-keep-derivations = false
|
||||
keep-outputs = true # Nice for developers
|
||||
keep-derivations = true # Idem
|
||||
</programlisting>
|
||||
|
||||
<para>You can override settings using the <option>--option</option>
|
||||
flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
<para>You can override settings on the command line using the
|
||||
<option>--option</option> flag, e.g. <literal>--option keep-outputs
|
||||
false</literal>.</para>
|
||||
|
||||
<para>The following settings are currently available:
|
||||
|
||||
<variablelist>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-gc-keep-outputs"><term><literal>gc-keep-outputs</literal></term>
|
||||
<varlistentry xml:id="conf-keep-outputs"><term><literal>keep-outputs</literal></term>
|
||||
|
||||
<listitem><para>If <literal>true</literal>, the garbage collector
|
||||
will keep the outputs of non-garbage derivations. If
|
||||
@@ -55,7 +75,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-gc-keep-derivations"><term><literal>gc-keep-derivations</literal></term>
|
||||
<varlistentry xml:id="conf-keep-derivations"><term><literal>keep-derivations</literal></term>
|
||||
|
||||
<listitem><para>If <literal>true</literal> (default), the garbage
|
||||
collector will keep the derivations from which non-garbage store
|
||||
@@ -67,12 +87,12 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
traceability (e.g., it allows you to ask with what dependencies or
|
||||
options a store path was built), so by default this option is on.
|
||||
Turn it off to save a bit of disk space (or a lot if
|
||||
<literal>gc-keep-outputs</literal> is also turned on).</para></listitem>
|
||||
<literal>keep-outputs</literal> is also turned on).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>env-keep-derivations</literal></term>
|
||||
<varlistentry><term><literal>keep-env-derivations</literal></term>
|
||||
|
||||
<listitem><para>If <literal>false</literal> (default), derivations
|
||||
are not stored in Nix user environments. That is, the derivation
|
||||
@@ -84,32 +104,32 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
garbage-collected until the user environment generation is deleted
|
||||
(<command>nix-env --delete-generations</command>). To prevent
|
||||
build-time-only dependencies from being collected, you should also
|
||||
turn on <literal>gc-keep-outputs</literal>.</para>
|
||||
turn on <literal>keep-outputs</literal>.</para>
|
||||
|
||||
<para>The difference between this option and
|
||||
<literal>gc-keep-derivations</literal> is that this one is
|
||||
<literal>keep-derivations</literal> is that this one is
|
||||
“sticky”: it applies to any user environment created while this
|
||||
option was enabled, while <literal>gc-keep-derivations</literal>
|
||||
option was enabled, while <literal>keep-derivations</literal>
|
||||
only applies at the moment the garbage collector is
|
||||
run.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-build-max-jobs"><term><literal>build-max-jobs</literal></term>
|
||||
<varlistentry xml:id="conf-max-jobs"><term><literal>max-jobs</literal></term>
|
||||
|
||||
<listitem><para>This option defines the maximum number of jobs
|
||||
that Nix will try to build in parallel. The default is
|
||||
<literal>1</literal>. You should generally set it to the number
|
||||
of CPUs in your system (e.g., <literal>2</literal> on an Athlon 64
|
||||
X2). It can be overridden using the <option
|
||||
<literal>1</literal>. The special value <literal>auto</literal>
|
||||
causes Nix to use the number of CPUs in your system. It can be
|
||||
overridden using the <option
|
||||
linkend='opt-max-jobs'>--max-jobs</option> (<option>-j</option>)
|
||||
command line switch.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-build-cores"><term><literal>build-cores</literal></term>
|
||||
<varlistentry xml:id="conf-cores"><term><literal>cores</literal></term>
|
||||
|
||||
<listitem><para>Sets the value of the
|
||||
<envar>NIX_BUILD_CORES</envar> environment variable in the
|
||||
@@ -128,7 +148,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-build-max-silent-time"><term><literal>build-max-silent-time</literal></term>
|
||||
<varlistentry xml:id="conf-max-silent-time"><term><literal>max-silent-time</literal></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
@@ -149,7 +169,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-build-timeout"><term><literal>build-timeout</literal></term>
|
||||
<varlistentry xml:id="conf-timeout"><term><literal>timeout</literal></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
@@ -169,7 +189,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-build-max-log-size"><term><literal>build-max-log-size</literal></term>
|
||||
<varlistentry xml:id="conf-max-build-log-size"><term><literal>max-build-log-size</literal></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
@@ -224,7 +244,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>build-use-sandbox</literal></term>
|
||||
<varlistentry><term><literal>sandbox</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>true</literal>, builds will be
|
||||
performed in a <emphasis>sandboxed environment</emphasis>, i.e.,
|
||||
@@ -233,7 +253,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
directory, private versions of <filename>/proc</filename>,
|
||||
<filename>/dev</filename>, <filename>/dev/shm</filename> and
|
||||
<filename>/dev/pts</filename> (on Linux), and the paths configured with the
|
||||
<link linkend='conf-build-sandbox-paths'><literal>build-sandbox-paths</literal>
|
||||
<link linkend='conf-sandbox-paths'><literal>sandbox-paths</literal>
|
||||
option</link>. This is useful to prevent undeclared dependencies
|
||||
on files in directories such as <filename>/usr/bin</filename>. In
|
||||
addition, on Linux, builds run in private PID, mount, network, IPC
|
||||
@@ -241,7 +261,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
system (except that fixed-output derivations do not run in private
|
||||
network namespace to ensure they can access the network).</para>
|
||||
|
||||
<para>Currently, sandboxing only work on Linux and Mac OS X. The use
|
||||
<para>Currently, sandboxing only work on Linux and macOS. The use
|
||||
of a sandbox requires that Nix is run as root (so you should use
|
||||
the <link linkend='conf-build-users-group'>“build users”
|
||||
feature</link> to perform the actual builds under different users
|
||||
@@ -259,8 +279,8 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-build-sandbox-paths">
|
||||
<term><literal>build-sandbox-paths</literal></term>
|
||||
<varlistentry xml:id="conf-sandbox-paths">
|
||||
<term><literal>sandbox-paths</literal></term>
|
||||
|
||||
<listitem><para>A list of paths bind-mounted into Nix sandbox
|
||||
environments. You can use the syntax
|
||||
@@ -268,7 +288,12 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
to mount a path in a different location in the sandbox; for
|
||||
instance, <literal>/bin=/nix-bin</literal> will mount the path
|
||||
<literal>/nix-bin</literal> as <literal>/bin</literal> inside the
|
||||
sandbox.</para>
|
||||
sandbox. If <replaceable>source</replaceable> is followed by
|
||||
<literal>?</literal>, then it is not an error if
|
||||
<replaceable>source</replaceable> does not exist; for example,
|
||||
<literal>/dev/nvidiactl?</literal> specifies that
|
||||
<filename>/dev/nvidiactl</filename> will only be mounted in the
|
||||
sandbox if it exists in the host filesystem.</para>
|
||||
|
||||
<para>Depending on how Nix was built, the default value for this option
|
||||
may be empty or provide <filename>/bin/sh</filename> as a
|
||||
@@ -277,17 +302,17 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-build-extra-sandbox-paths">
|
||||
<varlistentry xml:id="conf-extra-sandbox-paths">
|
||||
<term><literal>build-extra-sandbox-paths</literal></term>
|
||||
|
||||
<listitem><para>A list of additional paths appended to
|
||||
<option>build-sandbox-paths</option>. Useful if you want to extend
|
||||
<option>sandbox-paths</option>. Useful if you want to extend
|
||||
its default value.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>build-use-substitutes</literal></term>
|
||||
<varlistentry><term><literal>substitute</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>true</literal> (default), Nix
|
||||
will use binary substitutes if available. This option can be
|
||||
@@ -296,7 +321,21 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>build-fallback</literal></term>
|
||||
<varlistentry><term><literal>builders-use-substitutes</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>true</literal>, Nix will instruct
|
||||
remote build machines to use their own binary substitutes if available. In
|
||||
practical terms, this means that remote hosts will fetch as many build
|
||||
dependencies as possible from their own substitutes (e.g, from
|
||||
<literal>cache.nixos.org</literal>), instead of waiting for this host to
|
||||
upload them all. This can drastically reduce build times if the network
|
||||
connection between this computer and the remote build host is slow. Defaults
|
||||
to <literal>false</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>fallback</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>true</literal>, Nix will fall
|
||||
back to building from source if a binary substitute fails. This
|
||||
@@ -306,22 +345,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>build-cache-failure</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>true</literal>, Nix will
|
||||
“cache” build failures, meaning that it will remember (in its
|
||||
database) that a derivation previously failed. If you then try to
|
||||
build the derivation again, Nix will immediately fail rather than
|
||||
perform the build again. Failures in fixed-output derivations
|
||||
(such as <function>fetchurl</function> calls) are never cached.
|
||||
The “failed” status of a derivation can be cleared using
|
||||
<command>nix-store --clear-failed-paths</command>. By default,
|
||||
failure caching is disabled.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>build-keep-log</literal></term>
|
||||
<varlistentry><term><literal>keep-build-log</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>true</literal> (the default),
|
||||
Nix will write the build log of a derivation (i.e. the standard
|
||||
@@ -333,7 +357,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>build-compress-log</literal></term>
|
||||
<varlistentry><term><literal>compress-build-log</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>true</literal> (the default),
|
||||
build logs written to <filename>/nix/var/log/nix/drvs</filename>
|
||||
@@ -343,25 +367,16 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>use-binary-caches</literal></term>
|
||||
<varlistentry><term><literal>substituters</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>true</literal> (the default),
|
||||
Nix will check the binary caches specified by
|
||||
<option>binary-caches</option> and related options to obtain
|
||||
binary substitutes.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>binary-caches</literal></term>
|
||||
|
||||
<listitem><para>A list of URLs of binary caches, separated by
|
||||
<listitem><para>A list of URLs of substituters, separated by
|
||||
whitespace. The default is
|
||||
<literal>https://cache.nixos.org</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<!--
|
||||
<varlistentry><term><literal>binary-caches-files</literal></term>
|
||||
|
||||
<listitem><para>A list of names of files that will be read to
|
||||
@@ -374,80 +389,98 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
option to read files created by untrusted users!</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
-->
|
||||
|
||||
|
||||
<varlistentry><term><literal>trusted-binary-caches</literal></term>
|
||||
<varlistentry><term><literal>trusted-substituters</literal></term>
|
||||
|
||||
<listitem><para>A list of URLs of binary caches, separated by
|
||||
<listitem><para>A list of URLs of substituters, separated by
|
||||
whitespace. These are not used by default, but can be enabled by
|
||||
users of the Nix daemon by specifying <literal>--option
|
||||
binary-caches <replaceable>urls</replaceable></literal> on the
|
||||
substituters <replaceable>urls</replaceable></literal> on the
|
||||
command line. Unprivileged users are only allowed to pass a
|
||||
subset of the URLs listed in <literal>binary-caches</literal> and
|
||||
<literal>trusted-binary-caches</literal>.</para></listitem>
|
||||
subset of the URLs listed in <literal>substituters</literal> and
|
||||
<literal>trusted-substituters</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>extra-binary-caches</literal></term>
|
||||
<varlistentry><term><literal>extra-substituters</literal></term>
|
||||
|
||||
<listitem><para>Additional binary caches appended to those
|
||||
specified in <option>binary-caches</option> and
|
||||
<option>binary-caches-files</option>. When used by unprivileged
|
||||
users, untrusted binary caches (i.e. those not listed in
|
||||
<option>trusted-binary-caches</option>) are silently
|
||||
specified in <option>substituters</option>. When used by
|
||||
unprivileged users, untrusted substituters (i.e. those not listed
|
||||
in <option>trusted-substituters</option>) are silently
|
||||
ignored.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>signed-binary-caches</literal></term>
|
||||
<varlistentry><term><literal>require-sigs</literal></term>
|
||||
|
||||
<listitem><para>If set to <literal>*</literal>, Nix will only
|
||||
download binaries if they are signed using one of the keys listed
|
||||
in <option>binary-cache-public-keys</option>.</para></listitem>
|
||||
<listitem><para>If set to <literal>true</literal> (the default),
|
||||
any non-content-addressed path added or copied to the Nix store
|
||||
(e.g. when substituting from a binary cache) must have a valid
|
||||
signature, that is, be signed using one of the keys listed in
|
||||
<option>trusted-public-keys</option> or
|
||||
<option>secret-key-files</option>. Set to <literal>false</literal>
|
||||
to disable signature checking.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>binary-cache-public-keys</literal></term>
|
||||
<varlistentry><term><literal>trusted-public-keys</literal></term>
|
||||
|
||||
<listitem><para>A whitespace-separated list of public keys
|
||||
corresponding to the secret keys trusted to sign binary
|
||||
caches. For example:
|
||||
<listitem><para>A whitespace-separated list of public keys. When
|
||||
paths are copied from another Nix store (such as a binary cache),
|
||||
they must be signed with one of these keys. For example:
|
||||
<literal>cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
|
||||
hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>binary-caches-parallel-connections</literal></term>
|
||||
<varlistentry><term><literal>secret-key-files</literal></term>
|
||||
|
||||
<listitem><para>The maximum number of parallel HTTP connections
|
||||
used by the binary cache substituter to get NAR info files. This
|
||||
number should be high to minimise latency. It defaults to
|
||||
25.</para></listitem>
|
||||
<listitem><para>A whitespace-separated list of files containing
|
||||
secret (private) keys. These are used to sign locally-built
|
||||
paths. They can be generated using <command>nix-store
|
||||
--generate-binary-cache-key</command>. The corresponding public
|
||||
key can be distributed to other users, who can add it to
|
||||
<option>trusted-public-keys</option> in their
|
||||
<filename>nix.conf</filename>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>verify-https-binary-caches</literal></term>
|
||||
<varlistentry><term><literal>http-connections</literal></term>
|
||||
|
||||
<listitem><para>Whether HTTPS binary caches are required to have a
|
||||
certificate that can be verified. Defaults to
|
||||
<literal>true</literal>.</para></listitem>
|
||||
<listitem><para>The maximum number of parallel TCP connections
|
||||
used to fetch files from binary caches and by other downloads. It
|
||||
defaults to 25. 0 means no limit.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><literal>force-manifest</literal></term>
|
||||
<varlistentry><term><literal>netrc-file</literal></term>
|
||||
|
||||
<listitem><para>If this option is set to <literal>false</literal>
|
||||
(default) and a Nix channel provides both a manifest and a binary
|
||||
cache, only the binary cache will be used. If set to
|
||||
<literal>true</literal>, the manifest will be fetched as well.
|
||||
This is useful if you want to use binary patches (which are
|
||||
currently not supported by binary caches).</para></listitem>
|
||||
<listitem><para>If set to an absolute path to a <filename>netrc</filename>
|
||||
file, Nix will use the HTTP authentication credentials in this file when
|
||||
trying to download from a remote host through HTTP or HTTPS. Defaults to
|
||||
<filename>$NIX_CONF_DIR/netrc</filename>.</para>
|
||||
|
||||
<para>The <filename>netrc</filename> file consists of a list of
|
||||
accounts in the following format:
|
||||
|
||||
<screen>
|
||||
machine <replaceable>my-machine</replaceable>
|
||||
login <replaceable>my-username</replaceable>
|
||||
password <replaceable>my-password</replaceable>
|
||||
</screen>
|
||||
|
||||
For the exact syntax, see <link
|
||||
xlink:href="https://ec.haxx.se/usingcurl-netrc.html">the
|
||||
<literal>curl</literal> documentation.</link></para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -457,15 +490,15 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
<listitem><para>This option specifies the canonical Nix system
|
||||
name of the current installation, such as
|
||||
<literal>i686-linux</literal> or
|
||||
<literal>powerpc-darwin</literal>. Nix can only build derivations
|
||||
<literal>x86_64-darwin</literal>. Nix can only build derivations
|
||||
whose <literal>system</literal> attribute equals the value
|
||||
specified here. In general, it never makes sense to modify this
|
||||
value from its default, since you can use it to ‘lie’ about the
|
||||
platform you are building on (e.g., perform a Mac OS build on a
|
||||
Linux machine; the result would obviously be wrong). It only
|
||||
makes sense if the Nix binaries can run on multiple platforms,
|
||||
e.g., ‘universal binaries’ that run on <literal>powerpc-darwin</literal> and
|
||||
<literal>i686-darwin</literal>.</para>
|
||||
e.g., ‘universal binaries’ that run on <literal>x86_64-linux</literal> and
|
||||
<literal>i686-linux</literal>.</para>
|
||||
|
||||
<para>It defaults to the canonical Nix system name detected by
|
||||
<filename>configure</filename> at build time.</para></listitem>
|
||||
@@ -511,20 +544,6 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-log-servers"><term><literal>log-servers</literal></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>A list of URL prefixes (such as
|
||||
<literal>http://hydra.nixos.org/log</literal>) from which
|
||||
<command>nix-store -l</command> will try to fetch build logs if
|
||||
they’re not available locally.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-trusted-users"><term><literal>trusted-users</literal></term>
|
||||
|
||||
<listitem>
|
||||
@@ -538,11 +557,12 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
<literal>wheel</literal> group. The default is
|
||||
<literal>root</literal>.</para>
|
||||
|
||||
<warning><para>The users listed here have the ability to
|
||||
compromise the security of a multi-user Nix store. For instance,
|
||||
they could install Trojan horses subsequently executed by other
|
||||
users. So you should consider carefully whether to add users to
|
||||
this list.</para></warning>
|
||||
<warning><para>Adding a user to <option>trusted-users</option>
|
||||
is essentially equivalent to giving that user root access to the
|
||||
system. For example, the user can set
|
||||
<option>sandbox-paths</option> and thereby obtain read access to
|
||||
directories that are otherwise inacessible to
|
||||
them.</para></warning>
|
||||
|
||||
</listitem>
|
||||
|
||||
@@ -574,7 +594,8 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
<para>If set to <literal>true</literal>, the Nix evaluator will
|
||||
not allow access to any files outside of the Nix search path (as
|
||||
set via the <envar>NIX_PATH</envar> environment variable or the
|
||||
<option>-I</option> option). The default is
|
||||
<option>-I</option> option), or to URIs outside of
|
||||
<option>allowed-uri</option>. The default is
|
||||
<literal>false</literal>.</para>
|
||||
|
||||
</listitem>
|
||||
@@ -582,6 +603,21 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-allowed-uris"><term><literal>allowed-uris</literal></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>A list of URI prefixes to which access is allowed in
|
||||
restricted evaluation mode. For example, when set to
|
||||
<literal>https://github.com/NixOS</literal>, builtin functions
|
||||
such as <function>fetchGit</function> are allowed to access
|
||||
<literal>https://github.com/NixOS/patchelf.git</literal>.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-pre-build-hook"><term><literal>pre-build-hook</literal></term>
|
||||
|
||||
<listitem>
|
||||
@@ -607,7 +643,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
<para>Pass a list of files and directories to be included in the
|
||||
sandbox for this build. One entry per line, terminated by an empty
|
||||
line. Entries have the same format as
|
||||
<literal>build-sandbox-paths</literal>.</para>
|
||||
<literal>sandbox-paths</literal>.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
@@ -618,7 +654,7 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-build-repeat"><term><literal>build-repeat</literal></term>
|
||||
<varlistentry xml:id="conf-repeat"><term><literal>repeat</literal></term>
|
||||
|
||||
<listitem><para>How many times to repeat builds to check whether
|
||||
they are deterministic. The default value is 0. If the value is
|
||||
@@ -630,6 +666,74 @@ flag, e.g. <literal>--option gc-keep-outputs false</literal>.</para>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-sandbox-dev-shm-size"><term><literal>sandbox-dev-shm-size</literal></term>
|
||||
|
||||
<listitem><para>This option determines the maximum size of the
|
||||
<literal>tmpfs</literal> filesystem mounted on
|
||||
<filename>/dev/shm</filename> in Linux sandboxes. For the format,
|
||||
see the description of the <option>size</option> option of
|
||||
<literal>tmpfs</literal> in
|
||||
<citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>. The
|
||||
default is <literal>50%</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-allow-import-from-derivation"><term><literal>allow-import-from-derivation</literal></term>
|
||||
|
||||
<listitem><para>By default, Nix allows you to <function>import</function> from a derivation,
|
||||
allowing building at evaluation time. With this option set to false, Nix will throw an error
|
||||
when evaluating an expression that uses this feature, allowing users to ensure their evaluation
|
||||
will not require any builds to take place.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-allow-new-privileges"><term><literal>allow-new-privileges</literal></term>
|
||||
|
||||
<listitem><para>(Linux-specific.) By default, builders on Linux
|
||||
cannot acquire new privileges by calling setuid/setgid programs or
|
||||
programs that have file capabilities. For example, programs such
|
||||
as <command>sudo</command> or <command>ping</command> will
|
||||
fail. (Note that in sandbox builds, no such programs are available
|
||||
unless you bind-mount them into the sandbox via the
|
||||
<option>sandbox-paths</option> option.) You can allow the
|
||||
use of such programs by enabling this option. This is impure and
|
||||
usually undesirable, but may be useful in certain scenarios
|
||||
(e.g. to spin up containers or set up userspace network interfaces
|
||||
in tests).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="conf-hashed-mirrors"><term><literal>hashed-mirrors</literal></term>
|
||||
|
||||
<listitem><para>A list of web servers used by
|
||||
<function>builtins.fetchurl</function> to obtain files by
|
||||
hash. The default is
|
||||
<literal>http://tarballs.nixos.org/</literal>. Given a hash type
|
||||
<replaceable>ht</replaceable> and a base-16 hash
|
||||
<replaceable>h</replaceable>, Nix will try to download the file
|
||||
from
|
||||
<literal>hashed-mirror/<replaceable>ht</replaceable>/<replaceable>h</replaceable></literal>.
|
||||
This allows files to be downloaded even if they have disappeared
|
||||
from their original URI. For example, given the default mirror
|
||||
<literal>http://tarballs.nixos.org/</literal>, when building the derivation
|
||||
|
||||
<programlisting>
|
||||
builtins.fetchurl {
|
||||
url = https://example.org/foo-1.2.3.tar.xz;
|
||||
sha256 = "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae";
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
Nix will attempt to download this file from
|
||||
<literal>http://tarballs.nixos.org/sha256/2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae</literal>
|
||||
first. If it is not available there, if will try the original URI.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
|
||||
<variablelist xml:id="env-common">
|
||||
|
||||
<varlistentry><term><envar>IN_NIX_SHELL</envar></term>
|
||||
|
||||
<listitem><para>Indicator that tells if the current environment was set up by
|
||||
<command>nix-shell</command>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="env-NIX_PATH"><term><envar>NIX_PATH</envar></term>
|
||||
|
||||
@@ -123,15 +129,6 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><envar>NIX_DB_DIR</envar></term>
|
||||
|
||||
<listitem><para>Overrides the location of the Nix database (default
|
||||
<filename><replaceable>$NIX_STATE_DIR</replaceable>/db</filename>, i.e.,
|
||||
<filename><replaceable>prefix</replaceable>/var/nix/db</filename>).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><envar>NIX_CONF_DIR</envar></term>
|
||||
|
||||
<listitem><para>Overrides the location of the Nix configuration
|
||||
@@ -151,139 +148,6 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="envar-build-hook"><term><envar>NIX_BUILD_HOOK</envar></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>Specifies the location of the <emphasis>build hook</emphasis>,
|
||||
which is a program (typically some script) that Nix will call
|
||||
whenever it wants to build a derivation. This is used to implement
|
||||
distributed builds<phrase condition="manual"> (see <xref
|
||||
linkend="chap-distributed-builds" />)</phrase>.</para>
|
||||
|
||||
<!--
|
||||
The protocol by
|
||||
which the calling Nix process and the build hook communicate is as
|
||||
follows.
|
||||
|
||||
<para>The build hook is called with the following command-line
|
||||
arguments:
|
||||
|
||||
<orderedlist>
|
||||
|
||||
<listitem><para>A boolean value <literal>0</literal> or
|
||||
<literal>1</literal> specifying whether Nix can locally execute
|
||||
more builds, as per the <link
|
||||
linkend="opt-max-jobs"><option>- -max-jobs</option> option</link>.
|
||||
The purpose of this argument is to allow the hook to not have to
|
||||
maintain bookkeeping for the local machine.</para></listitem>
|
||||
|
||||
<listitem><para>The Nix platform identifier for the local machine
|
||||
(e.g., <literal>i686-linux</literal>).</para></listitem>
|
||||
|
||||
<listitem><para>The Nix platform identifier for the derivation,
|
||||
i.e., its <link linkend="attr-system"><varname>system</varname>
|
||||
attribute</link>.</para></listitem>
|
||||
|
||||
<listitem><para>The store path of the derivation.</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>On the basis of this information, and whatever persistent
|
||||
state the build hook keeps about other machines and their current
|
||||
load, it has to decide what to do with the build. It should print
|
||||
out on standard error one of the following responses (terminated by
|
||||
a newline, <literal>"\n"</literal>):
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><literal># decline</literal></term>
|
||||
|
||||
<listitem><para>The build hook is not willing or able to perform
|
||||
the build; the calling Nix process should do the build itself,
|
||||
if possible.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal># postpone</literal></term>
|
||||
|
||||
<listitem><para>The build hook cannot perform the build now, but
|
||||
can do so in the future (e.g., because all available build slots
|
||||
on remote machines are in use). The calling Nix process should
|
||||
postpone this build until at least one currently running build
|
||||
has terminated.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal># accept</literal></term>
|
||||
|
||||
<listitem><para>The build hook has accepted the
|
||||
build.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>After sending <literal># accept</literal>, the hook should
|
||||
read one line from standard input, which will be the string
|
||||
<literal>okay</literal>. It can then proceed with the build.
|
||||
Before sending <literal>okay</literal>, Nix will store in the hook’s
|
||||
current directory a number of text files that contain information
|
||||
about the derivation:
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><filename>inputs</filename></term>
|
||||
|
||||
<listitem><para>The set of store paths that are inputs to the
|
||||
build process (one per line). These have to be copied
|
||||
<emphasis>to</emphasis> the remote machine (in addition to the
|
||||
store derivation itself).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><filename>outputs</filename></term>
|
||||
|
||||
<listitem><para>The set of store paths that are outputs of the
|
||||
derivation (one per line). These have to be copied
|
||||
<emphasis>from</emphasis> the remote machine if the build
|
||||
succeeds.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><filename>references</filename></term>
|
||||
|
||||
<listitem><para>The reference graph of the inputs, in the format
|
||||
accepted by the command <command>nix-store
|
||||
- -register-validity</command>. It is necessary to run this
|
||||
command on the remote machine after copying the inputs to inform
|
||||
Nix on the remote machine that the inputs are valid
|
||||
paths.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>The hook should copy the inputs to the remote machine,
|
||||
register the validity of the inputs, perform the remote build, and
|
||||
copy the outputs back to the local machine. An exit code other than
|
||||
<literal>0</literal> indicates that the hook has failed. An exit
|
||||
code equal to 100 means that the remote build failed (as opposed to,
|
||||
e.g., a network error).</para>
|
||||
-->
|
||||
|
||||
</listitem>
|
||||
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="envar-remote"><term><envar>NIX_REMOTE</envar></term>
|
||||
|
||||
<listitem><para>This variable should be set to
|
||||
|
||||
@@ -73,11 +73,10 @@ condition="manual">See also <xref linkend="sec-channels"
|
||||
|
||||
<listitem><para>Downloads the Nix expressions of all subscribed
|
||||
channels (or only those included in
|
||||
<replaceable>names</replaceable> if specified), makes them the
|
||||
<replaceable>names</replaceable> if specified) and makes them the
|
||||
default for <command>nix-env</command> operations (by symlinking
|
||||
them from the directory <filename>~/.nix-defexpr</filename>), and
|
||||
performs a <command>nix-pull</command> on the manifests of all
|
||||
channels to make pre-built binaries available.</para></listitem>
|
||||
them from the directory
|
||||
<filename>~/.nix-defexpr</filename>).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -181,19 +180,7 @@ following files:</para>
|
||||
sufficient rights to add binary caches. For instance, in a
|
||||
multi-user Nix setup, the binary caches provided by the channels
|
||||
of the root user are used automatically, but caches corresponding
|
||||
to the channels of non-root users are ignored. Binary caches can
|
||||
be created and maintained using
|
||||
<command>nix-push</command>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><filename>MANIFEST.bz2</filename></term>
|
||||
|
||||
<listitem><para>(Deprecated in favour of binary caches.) A
|
||||
manifest as created by <command>nix-push</command>. Only used if
|
||||
<filename>binary-cache-url</filename> is not present or if the
|
||||
<filename>nix.conf</filename> option
|
||||
<option>force-manifest</option> is set.</para></listitem>
|
||||
to the channels of non-root users are ignored.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -22,14 +22,15 @@
|
||||
<arg choice='plain'><option>--to</option></arg>
|
||||
<arg choice='plain'><option>--from</option></arg>
|
||||
</group>
|
||||
<arg><option>--sign</option></arg>
|
||||
<arg><option>--gzip</option></arg>
|
||||
<!--
|
||||
<arg><option>- -show-progress</option></arg>
|
||||
-->
|
||||
<arg><option>--include-outputs</option></arg>
|
||||
<arg><option>--use-substitutes</option></arg>
|
||||
<arg><option>-s</option></arg>
|
||||
<group>
|
||||
<arg choice='plain'><option>--use-substitutes</option></arg>
|
||||
<arg choice='plain'><option>-s</option></arg>
|
||||
</group>
|
||||
<arg><option>-v</option></arg>
|
||||
<arg choice='plain'>
|
||||
<replaceable>user@</replaceable><replaceable>machine</replaceable>
|
||||
@@ -87,23 +88,6 @@ those paths. If this bothers you, use
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--sign</option></term>
|
||||
|
||||
<listitem><para>Let the sending machine cryptographically sign the
|
||||
dump of each path with the key in
|
||||
<filename><replaceable>sysconfdir</replaceable>/nix/signing-key.sec</filename>.
|
||||
If the user on the target machine does not have direct access to
|
||||
the Nix store (i.e., if the target machine has a multi-user Nix
|
||||
installation), then the target machine will check the dump against
|
||||
<filename><replaceable>sysconfdir</replaceable>/nix/signing-key.pub</filename>
|
||||
before unpacking it in its Nix store. This allows secure sharing
|
||||
of store paths between untrusted users on two machines, provided
|
||||
that there is a trust relation between the Nix installations on
|
||||
both machines (namely, they have matching public/secret
|
||||
keys).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--gzip</option></term>
|
||||
|
||||
<listitem><para>Enable compression of the SSH
|
||||
|
||||
@@ -146,8 +146,7 @@ also <xref linkend="sec-common-options" />.</phrase></para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><option>--file</option></term>
|
||||
<term><option>-f</option></term>
|
||||
<varlistentry><term><option>--file</option> / <option>-f</option> <replaceable>path</replaceable></term>
|
||||
|
||||
<listitem><para>Specifies the Nix expression (designated below as
|
||||
the <emphasis>active Nix expression</emphasis>) used by the
|
||||
@@ -166,8 +165,7 @@ also <xref linkend="sec-common-options" />.</phrase></para>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--profile</option></term>
|
||||
<term><option>-p</option></term>
|
||||
<varlistentry><term><option>--profile</option> / <option>-p</option> <replaceable>path</replaceable></term>
|
||||
|
||||
<listitem><para>Specifies the profile to be used by those
|
||||
operations that operate on a profile (designated below as the
|
||||
@@ -367,6 +365,10 @@ number of possible ways:
|
||||
linkend="rsec-nix-store-realise">realised</link> and
|
||||
installed.</para></listitem>
|
||||
|
||||
<listitem><para>By default all outputs are installed for each derivation.
|
||||
That can be reduced by setting <literal>meta.outputsToInstall</literal>.
|
||||
</para></listitem> <!-- TODO: link nixpkgs docs on the ability to override those. -->
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</para>
|
||||
@@ -489,17 +491,11 @@ set returned by calling the function defined in
|
||||
source:
|
||||
|
||||
<screen>
|
||||
$ nix-env -f pkgs/top-level/all-packages.nix -i f-spot --dry-run
|
||||
$ nix-env -f '<nixpkgs>' -iA hello --dry-run
|
||||
(dry run; not doing anything)
|
||||
installing `f-spot-0.0.10'
|
||||
the following derivations will be built:
|
||||
/nix/store/0g63jv9aagwbgci4nnzs2dkxqz84kdja-libgnomeprintui-2.12.1.tar.bz2.drv
|
||||
/nix/store/0gfarvxq6sannsdw8a1ir40j1ys2mqb4-ORBit2-2.14.2.tar.bz2.drv
|
||||
/nix/store/0i9gs5zc04668qiy60ga2rc16abkj7g8-sqlite-2.8.17.drv
|
||||
<replaceable>...</replaceable>
|
||||
the following paths will be substituted:
|
||||
/nix/store/8zbipvm4gp9jfqh9nnk1n3bary1a37gs-perl-XML-Parser-2.34
|
||||
/nix/store/b8a2bg7gnyvvvjjibp4axg9x1hzkw36c-mono-1.1.4
|
||||
installing ‘hello-2.10’
|
||||
these paths will be fetched (0.04 MiB download, 0.19 MiB unpacked):
|
||||
/nix/store/wkhdf9jinag5750mqlax6z2zbwhqb76n-hello-2.10
|
||||
<replaceable>...</replaceable></screen>
|
||||
|
||||
</para>
|
||||
@@ -1138,7 +1134,7 @@ user environment elements, etc. -->
|
||||
|
||||
<listitem><para>Print all of the meta-attributes of the
|
||||
derivation. This option is only available with
|
||||
<option>--xml</option>.</para></listitem>
|
||||
<option>--xml</option> or <option>--json</option>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<refentry 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="sec-nix-generate-patches">
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>nix-generate-patches</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">Nix</refmiscinfo>
|
||||
<refmiscinfo class="version"><xi:include href="../version.txt" parse="text"/></refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>nix-generate-patches</refname>
|
||||
<refpurpose>generates binary patches between NAR files</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>nix-generate-patches</command>
|
||||
<arg choice='plain'><replaceable>NAR-DIR</replaceable></arg>
|
||||
<arg choice='plain'><replaceable>PATCH-DIR</replaceable></arg>
|
||||
<arg choice='plain'><replaceable>PATCH-URI</replaceable></arg>
|
||||
<arg choice='plain'><replaceable>OLD-MANIFEST</replaceable></arg>
|
||||
<arg choice='plain'><replaceable>NEW-MANIFEST</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>The command <command>nix-generate-patches</command> generates
|
||||
binary patches between NAR files listed in OLD-MANIFEST and NEW-MANIFEST.
|
||||
The patches are written to the directory PATCH-DIR, and the prefix
|
||||
PATCH-URI is used to generate URIs for the patches. The patches are
|
||||
added to NEW-MANIFEST. All NARs are required to exist in NAR-DIR.
|
||||
Patches are generated between succeeding versions of packages with
|
||||
the same name.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
</refentry>
|
||||
@@ -44,7 +44,9 @@
|
||||
cryptographic hash of the contents of each
|
||||
<replaceable>path</replaceable> and prints it on standard output. By
|
||||
default, it computes an MD5 hash, but other hash algorithms are
|
||||
available as well. The hash is printed in hexadecimal.</para>
|
||||
available as well. The hash is printed in hexadecimal. To generate
|
||||
the same hash as <command>nix-prefetch-url</command> you have to
|
||||
specify multiple arguments, see below for an example.</para>
|
||||
|
||||
<para>The hash is computed over a <emphasis>serialisation</emphasis>
|
||||
of each path: a dump of the file system tree rooted at the path. This
|
||||
@@ -122,6 +124,15 @@ cryptographic hash as <literal>nix-store --dump
|
||||
|
||||
<refsection><title>Examples</title>
|
||||
|
||||
<para>Computing the same hash as <command>nix-prefetch-url</command>:
|
||||
<screen>
|
||||
$ nix-prefetch-url file://<(echo test)
|
||||
1lkgqb6fclns49861dwk9rzb6xnfkxbpws74mxnx01z9qyv1pjpj
|
||||
$ nix-hash --type sha256 --flat --base32 <(echo test)
|
||||
1lkgqb6fclns49861dwk9rzb6xnfkxbpws74mxnx01z9qyv1pjpj
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>Computing hashes:
|
||||
|
||||
<screen>
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
<refentry 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="sec-nix-install-package">
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>nix-install-package</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">Nix</refmiscinfo>
|
||||
<refmiscinfo class="version"><xi:include href="../version.txt" parse="text"/></refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>nix-install-package</refname>
|
||||
<refpurpose>install a Nix Package file</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>nix-install-package</command>
|
||||
<arg><option>--non-interactive</option></arg>
|
||||
<arg>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'><option>--profile</option></arg>
|
||||
<arg choice='plain'><option>-p</option></arg>
|
||||
</group>
|
||||
<replaceable>path</replaceable>
|
||||
</arg>
|
||||
<arg><option>--set</option></arg>
|
||||
<sbr />
|
||||
<group choice='req'>
|
||||
<arg choice='req'>
|
||||
<option>--url</option>
|
||||
<arg choice='plain'><replaceable>url</replaceable></arg>
|
||||
</arg>
|
||||
<arg choice='req'>
|
||||
<arg choice='plain'><replaceable>file</replaceable></arg>
|
||||
</arg>
|
||||
</group>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>The command <command>nix-install-package</command> interactively
|
||||
installs a Nix Package file (<filename>*.nixpkg</filename>), which is
|
||||
a small file that contains a store path to be installed along with the
|
||||
URL of a binary cache. The Nix Package file is either
|
||||
<replaceable>file</replaceable>, or automatically downloaded from
|
||||
<replaceable>url</replaceable> if the <option>--url</option> switch is
|
||||
used.</para>
|
||||
|
||||
<para><command>nix-install-package</command> is used in <link
|
||||
linkend="sec-one-click">one-click installs</link> to download and
|
||||
install pre-built binary packages with all necessary dependencies.
|
||||
<command>nix-install-package</command> is intended to be associated
|
||||
with the MIME type <literal>application/nix-package</literal> in a web
|
||||
browser so that it is invoked automatically when you click on
|
||||
<filename>*.nixpkg</filename> files. When invoked, it restarts itself
|
||||
in a terminal window (since otherwise it would be invisible when run
|
||||
from a browser), asks the user to confirm whether to install the
|
||||
package, and if so downloads and installs the package into the user’s
|
||||
current profile.</para>
|
||||
|
||||
<para>To obtain a window, <command>nix-install-package</command> tries
|
||||
to restart itself with <command>xterm</command>,
|
||||
<command>konsole</command> and
|
||||
<command>gnome-terminal</command>.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Options</title>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><option>--non-interactive</option></term>
|
||||
|
||||
<listitem><para>Do not open a new terminal window and do not ask
|
||||
for confirmation.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--profile</option></term>
|
||||
<term><option>-p</option></term>
|
||||
|
||||
<listitem><para>Install the package into the specified profile
|
||||
rather than the user’s current profile.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--set</option></term>
|
||||
|
||||
<listitem><para>Install the package as the profile so that the
|
||||
profile contains exactly the contents of the package.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Examples</title>
|
||||
|
||||
<para>To install <filename>subversion-1.4.0.nixpkg</filename> into the
|
||||
user’s current profile, without any prompting:
|
||||
|
||||
<screen>
|
||||
$ nix-install-package --non-interactive subversion-1.4.0.nixpkg</screen>
|
||||
|
||||
</para>
|
||||
|
||||
<para>To install the same package from some URL into a different
|
||||
profile:
|
||||
|
||||
<screen>
|
||||
$ nix-install-package --non-interactive -p /nix/var/nix/profiles/eelco \
|
||||
--url http://nix.cs.uu.nl/dist/nix/nixpkgs-0.10pre6622/pkgs/subversion-1.4.0-i686-linux.nixpkg</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Format of <literal>nixpkg</literal> files</title>
|
||||
|
||||
<para>A Nix Package file consists of a single line with the following
|
||||
format:
|
||||
|
||||
<screen>
|
||||
NIXPKG1 <replaceable>manifestURL</replaceable> <replaceable>name</replaceable> <replaceable>system</replaceable> <replaceable>drvPath</replaceable> <replaceable>outPath</replaceable></screen>
|
||||
|
||||
The elements are as follows:
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><literal>NIXPKG1</literal></term>
|
||||
|
||||
<listitem><para>The version of the Nix Package
|
||||
file.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><replaceable>manifestURL</replaceable></term>
|
||||
|
||||
<listitem><para>The manifest to be pulled by
|
||||
<command>nix-pull</command>. The manifest must contain
|
||||
<replaceable>outPath</replaceable>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><replaceable>name</replaceable></term>
|
||||
|
||||
<listitem><para>The symbolic name and version of the
|
||||
package.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><replaceable>system</replaceable></term>
|
||||
|
||||
<listitem><para>The platform identifier of the platform for which
|
||||
this binary package is intended.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><replaceable>drvPath</replaceable></term>
|
||||
|
||||
<listitem><para>The path in the Nix store of the derivation from
|
||||
which <replaceable>outPath</replaceable> was built. Not currently
|
||||
used.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><replaceable>outPath</replaceable></term>
|
||||
|
||||
<listitem><para>The path in the Nix store of the
|
||||
package.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><replaceable>binaryCacheURL</replaceable></term>
|
||||
|
||||
<listitem><para>The URL of a binary cache containing the closure
|
||||
of <replaceable>outPath</replaceable>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>An example follows:
|
||||
|
||||
<screen>
|
||||
NIXPKG1 http://.../nixpkgs-0.10pre6622/MANIFEST subversion-1.4.0 i686-darwin \
|
||||
/nix/store/4kh60jkp...-subversion-1.4.0.drv \
|
||||
/nix/store/nkw7wpgb...-subversion-1.4.0</screen>
|
||||
|
||||
(The line breaks (<literal>\</literal>) are for presentation purposes
|
||||
and not part of the actual file.)
|
||||
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
</refentry>
|
||||
@@ -24,6 +24,7 @@
|
||||
<arg choice='plain'>
|
||||
<option>--eval</option>
|
||||
<arg><option>--strict</option></arg>
|
||||
<arg><option>--json</option></arg>
|
||||
<arg><option>--xml</option></arg>
|
||||
</arg>
|
||||
</group>
|
||||
@@ -38,12 +39,13 @@
|
||||
</arg>
|
||||
<arg><option>--add-root</option> <replaceable>path</replaceable></arg>
|
||||
<arg><option>--indirect</option></arg>
|
||||
<group choice='req'>
|
||||
<group>
|
||||
<arg choice='plain'><option>--expr</option></arg>
|
||||
<arg choice='plain'><option>-E</option></arg>
|
||||
</group>
|
||||
<arg choice='plain' rep='repeat'><replaceable>files</replaceable></arg>
|
||||
<sbr/>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>nix-instantiate</command>
|
||||
<arg choice='plain'><option>--find-file</option></arg>
|
||||
<arg choice='plain' rep='repeat'><replaceable>files</replaceable></arg>
|
||||
@@ -115,26 +117,6 @@ input.</para>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--xml</option></term>
|
||||
|
||||
<listitem><para>When used with <option>--parse</option> and
|
||||
<option>--eval</option>, print the resulting expression as an
|
||||
XML representation of the abstract syntax tree rather than as an
|
||||
ATerm. The schema is the same as that used by the <link
|
||||
linkend="builtin-toXML"><function>toXML</function>
|
||||
built-in</link>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--json</option></term>
|
||||
|
||||
<listitem><para>When used with <option>--parse</option> and
|
||||
<option>--eval</option>, print the resulting expression as an
|
||||
JSON representation of the abstract syntax tree rather than as an
|
||||
ATerm.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--strict</option></term>
|
||||
|
||||
<listitem><para>When used with <option>--eval</option>,
|
||||
@@ -149,6 +131,24 @@ input.</para>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--json</option></term>
|
||||
|
||||
<listitem><para>When used with <option>--eval</option>, print the resulting
|
||||
value as an JSON representation of the abstract syntax tree rather
|
||||
than as an ATerm.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--xml</option></term>
|
||||
|
||||
<listitem><para>When used with <option>--eval</option>, print the resulting
|
||||
value as an XML representation of the abstract syntax tree rather than as
|
||||
an ATerm. The schema is the same as that used by the <link
|
||||
linkend="builtin-toXML"><function>toXML</function> built-in</link>.
|
||||
</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--read-write-mode</option></term>
|
||||
|
||||
<listitem><para>When used with <option>--eval</option>, perform
|
||||
|
||||
@@ -19,14 +19,16 @@
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>nix-prefetch-url</command>
|
||||
<arg><option>--version</option></arg>
|
||||
<arg><option>--type</option> <replaceable>hashAlgo</replaceable></arg>
|
||||
<arg><option>--print-path</option></arg>
|
||||
<arg><option>--unpack</option></arg>
|
||||
<arg><option>--name</option> <replaceable>name</replaceable></arg>
|
||||
<arg choice='plain'><replaceable>url</replaceable></arg>
|
||||
<arg><replaceable>hash</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>The command <command>nix-prefetch-url</command> downloads the
|
||||
@@ -91,7 +93,7 @@ downloaded file in the Nix store is also printed.</para>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--name</option></term>
|
||||
<varlistentry><term><option>--name</option> <replaceable>name</replaceable></term>
|
||||
|
||||
<listitem><para>Override the name of the file in the Nix store. By
|
||||
default, this is
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
<refentry 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="sec-nix-pull">
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>nix-pull</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">Nix</refmiscinfo>
|
||||
<refmiscinfo class="version"><xi:include href="../version.txt" parse="text"/></refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>nix-pull</refname>
|
||||
<refpurpose>register availability of pre-built binaries (deprecated)</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>nix-pull</command>
|
||||
<arg choice='plain'><replaceable>url</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<note><para>This command and the use of manifests is deprecated. It is
|
||||
better to use binary caches.</para></note>
|
||||
|
||||
<para>The command <command>nix-pull</command> obtains a list of
|
||||
pre-built store paths from the URL <replaceable>url</replaceable>, and
|
||||
for each of these store paths, registers a substitute derivation that
|
||||
downloads and unpacks it into the Nix store. This is used to speed up
|
||||
installations: if you attempt to install something that has already
|
||||
been built and stored into the network cache, Nix can transparently
|
||||
re-use the pre-built store paths.</para>
|
||||
|
||||
<para>The file at <replaceable>url</replaceable> must be compatible
|
||||
with the files created by <replaceable>nix-push</replaceable>.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Examples</title>
|
||||
|
||||
<screen>
|
||||
$ nix-pull https://nixos.org/releases/nixpkgs/nixpkgs-15.05pre54468.69858d7/MANIFEST</screen>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
</refentry>
|
||||
@@ -1,464 +0,0 @@
|
||||
<refentry 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="sec-nix-push">
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>nix-push</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="source">Nix</refmiscinfo>
|
||||
<refmiscinfo class="version"><xi:include href="../version.txt" parse="text"/></refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>nix-push</refname>
|
||||
<refpurpose>generate a binary cache</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>nix-push</command>
|
||||
<arg choice='plain'><option>--dest</option> <replaceable>dest-dir</replaceable></arg>
|
||||
<arg><option>--bzip2</option></arg>
|
||||
<arg><option>--none</option></arg>
|
||||
<arg><option>--force</option></arg>
|
||||
<arg><option>--link</option></arg>
|
||||
<arg><option>--manifest</option></arg>
|
||||
<arg><option>--manifest-path</option> <replaceable>filename</replaceable></arg>
|
||||
<arg><option>--url-prefix</option> <replaceable>url</replaceable></arg>
|
||||
<arg><option>--key-file</option> <replaceable>path</replaceable></arg>
|
||||
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>The command <command>nix-push</command> produces a
|
||||
<emphasis>binary cache</emphasis>, a directory containing compressed
|
||||
Nix archives (NARs) plus some metadata of the closure of the specified
|
||||
store paths. This directory can then be made available through a web
|
||||
server to other Nix installations, allowing them to skip building from
|
||||
source and instead download binaries from the cache
|
||||
automatically.</para>
|
||||
|
||||
<para><command>nix-push</command> performs the following actions.
|
||||
|
||||
<orderedlist>
|
||||
|
||||
<listitem><para>Each path in <replaceable>paths</replaceable> is
|
||||
built (using <link
|
||||
linkend='rsec-nix-store-realise'><command>nix-store
|
||||
--realise</command></link>).</para></listitem>
|
||||
|
||||
<listitem><para>All paths in the closure of
|
||||
<replaceable>paths</replaceable> are determined (using
|
||||
<command>nix-store --query --requisites
|
||||
--include-outputs</command>). Note that since the
|
||||
<option>--include-outputs</option> flag is used, if
|
||||
<replaceable>paths</replaceable> includes a store derivation, you
|
||||
get a combined source/binary distribution (e.g., source tarballs
|
||||
will be included).</para></listitem>
|
||||
|
||||
<listitem><para>All store paths determined in the previous step are
|
||||
packaged into a NAR (using <command>nix-store --dump</command>) and
|
||||
compressed using <command>xz</command> or <command>bzip2</command>.
|
||||
The resulting files have the extension <filename>.nar.xz</filename>
|
||||
or <filename>.nar.bz2</filename>. Also for each store path, Nix
|
||||
generates a file with extension <filename>.narinfo</filename>
|
||||
containing metadata such as the references, cryptographic hash and
|
||||
size of each path.</para></listitem>
|
||||
|
||||
<listitem><para>Optionally, a single <emphasis>manifest</emphasis>
|
||||
file is created that contains the same metadata as the
|
||||
<filename>.narinfo</filename> files. This is for compatibility with
|
||||
Nix versions prior to 1.2 (see <command>nix-pull</command> for
|
||||
details).</para></listitem>
|
||||
|
||||
<listitem><para>A file named <option>nix-cache-info</option> is
|
||||
placed in the destination directory. The existence of this file
|
||||
marks the directory as a binary cache.</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Options</title>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><option>--dest</option> <replaceable>dest-dir</replaceable></term>
|
||||
|
||||
<listitem><para>Set the destination directory to
|
||||
<replaceable>dir</replaceable>, which is created if it does not
|
||||
exist. This flag is required.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--bzip2</option></term>
|
||||
|
||||
<listitem><para>Compress NARs using <command>bzip2</command>
|
||||
instead of <command>xz</command>. The latter compresses about 30%
|
||||
better on typical archives, decompresses about twice as fast, but
|
||||
compresses a lot slower and is not supported by Nix prior to
|
||||
version 1.2.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--none</option></term>
|
||||
|
||||
<listitem><para>Do not compress NARs.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--force</option></term>
|
||||
|
||||
<listitem><para>Overwrite <filename>.narinfo</filename> files if
|
||||
they already exist.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--link</option></term>
|
||||
|
||||
<listitem><para>By default, NARs are generated in the Nix store
|
||||
and then copied to <replaceable>dest-dir</replaceable>. If this
|
||||
option is given, hard links are used instead. This only works if
|
||||
<replaceable>dest-dir</replaceable> is on the same filesystem as
|
||||
the Nix store.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--manifest</option></term>
|
||||
|
||||
<listitem><para>Force the generation of a manifest suitable for
|
||||
use by <command>nix-pull</command>. The manifest is stored as
|
||||
<filename><replaceable>dest-dir</replaceable>/MANIFEST</filename>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--manifest-path</option> <replaceable>filename</replaceable></term>
|
||||
|
||||
<listitem><para>Like <option>--manifest</option>, but store the
|
||||
manifest in <replaceable>filename</replaceable>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--url-prefix</option> <replaceable>url</replaceable></term>
|
||||
|
||||
<listitem><para>Manifests are expected to contain the absolute
|
||||
URLs of NARs. For generating these URLs, the prefix
|
||||
<replaceable>url</replaceable> is used. It defaults to
|
||||
<uri>file://<replaceable>dest-dir</replaceable></uri>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--key-file</option> <replaceable>path</replaceable></term>
|
||||
|
||||
<listitem><para>Sign the binary cache using the secret key stored
|
||||
in <replaceable>path</replaceable>. This secret key must have been
|
||||
created using <command
|
||||
linkend="rsec-nix-store-generate-binary-cache-key">nix-store
|
||||
--generate-binary-cache-key</command>. Users of this binary cache
|
||||
should add the corresponding public key to the option
|
||||
<option>binary-cache-public-keys</option> in
|
||||
<filename>nix.conf</filename>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Examples</title>
|
||||
|
||||
<para>To add the closure of Thunderbird to a binary cache:
|
||||
|
||||
<screen>
|
||||
$ nix-push --dest /tmp/cache $(nix-build -A thunderbird)
|
||||
</screen>
|
||||
|
||||
Assuming that <filename>/tmp/cache</filename> is exported by a web
|
||||
server as <uri>http://example.org/cache</uri>, you can then use this
|
||||
cache on another machine to speed up the installation of Thunderbird:
|
||||
|
||||
<screen>
|
||||
$ nix-build -A thunderbird --option binary-caches http://example.org/cache
|
||||
</screen>
|
||||
|
||||
Alternatively, you could add <literal>binary-caches =
|
||||
http://example.org/cache</literal> to
|
||||
<filename>nix.conf</filename>.</para>
|
||||
|
||||
<para>To also include build-time dependencies (such as source
|
||||
tarballs):
|
||||
|
||||
<screen>
|
||||
$ nix-push --dest /tmp/cache $(nix-instantiate -A thunderbird)
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
<para>To generate a manifest suitable for <command>nix-pull</command>:
|
||||
|
||||
<screen>
|
||||
$ nix-push --dest /tmp/cache $(nix-build -A thunderbird) --manifest
|
||||
</screen>
|
||||
|
||||
On another machine you can then do:
|
||||
|
||||
<screen>
|
||||
$ nix-pull http://example.org/cache
|
||||
</screen>
|
||||
|
||||
to cause the binaries to be used by subsequent Nix operations.</para>
|
||||
|
||||
<para>To generate a signed binary cache, you must first generate a key
|
||||
pair, in this example called <literal>cache.example.org-1</literal>,
|
||||
storing the secret key in <filename>./sk</filename> and the public key
|
||||
in <filename>./pk</filename>:
|
||||
|
||||
<screen>
|
||||
$ nix-store --generate-binary-cache-key cache.example.org-1 sk pk
|
||||
|
||||
$ cat sk
|
||||
cache.example.org-1:jcMRQYFo8pQKzTtimpQLIPeHkMYZjfhB24hGfwF+u9PuX8H8FO7q564+X3G/JDlqqIqGar3OXRRwS9N3Wh3vbw==
|
||||
|
||||
$ cat pk
|
||||
cache.example.org-1:7l/B/BTu6ueuPl9xvyQ5aqiKhmq9zl0UcEvTd1od728=
|
||||
</screen>
|
||||
|
||||
You can then generate a binary cache signed with the secret key:
|
||||
|
||||
<screen>
|
||||
$ nix-push --dest /tmp/cache --key-file ./sk $(type -p firefox)
|
||||
</screen>
|
||||
|
||||
Users who wish to verify the integrity of binaries downloaded from
|
||||
your cache would add the following to their
|
||||
<filename>nix.conf</filename>:
|
||||
|
||||
<programlisting>
|
||||
binary-caches = http://cache.example.org
|
||||
signed-binary-caches = *
|
||||
binary-cache-public-keys = cache.example.org-1:7l/B/BTu6ueuPl9xvyQ5aqiKhmq9zl0UcEvTd1od728=
|
||||
</programlisting>
|
||||
|
||||
Nix will then ignore any binary that has a missing, incorrect or
|
||||
unrecognised signature.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Binary cache format and operation</title>
|
||||
|
||||
<para>A binary cache with URL <replaceable>url</replaceable> only
|
||||
denotes a valid binary cache if the file
|
||||
<uri><replaceable>url</replaceable>/nix-cache-info</uri> exists. If
|
||||
this file does not exist (or cannot be downloaded), the cache is
|
||||
ignored. If it does exist, it must be a text file containing cache
|
||||
properties. Here’s an example:
|
||||
|
||||
<screen>
|
||||
StoreDir: /nix/store
|
||||
WantMassQuery: 1
|
||||
Priority: 10
|
||||
</screen>
|
||||
|
||||
The properties that are currently supported are:
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><literal>StoreDir</literal></term>
|
||||
|
||||
<listitem><para>The path of the Nix store to which this binary
|
||||
cache applies. Binaries are not relocatable — a binary built for
|
||||
<filename>/nix/store</filename> won’t generally work in
|
||||
<filename>/home/alice/store</filename> — so to prevent binaries
|
||||
from being used in a wrong store, a binary cache is only used if
|
||||
its <literal>StoreDir</literal> matches the local Nix
|
||||
configuration. The default is
|
||||
<filename>/nix/store</filename>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>WantMassQuery</literal></term>
|
||||
|
||||
<listitem><para>Query operations such as <command>nix-env
|
||||
-qas</command> can cause thousands of cache queries, and thus
|
||||
thousands of HTTP requests, to determine which packages are
|
||||
available in binary form. While these requests are small, not
|
||||
every server may appreciate a potential onslaught of queries. If
|
||||
<literal>WantMassQuery</literal> is set to <literal>0</literal>
|
||||
(default), “mass queries” such as <command>nix-env -qas</command>
|
||||
will skip this cache. Thus a package may appear not to have a
|
||||
binary substitute. However, the binary will still be used when
|
||||
you actually install the package. If
|
||||
<literal>WantMassQuery</literal> is set to <literal>1</literal>,
|
||||
mass queries will use this cache.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>Priority</literal></term>
|
||||
|
||||
<listitem><para>Each binary cache has a priority (defaulting to
|
||||
50). Binary caches are checked for binaries in order of ascending
|
||||
priority; thus a higher number denotes a lower priority. The
|
||||
binary cache <uri>https://cache.nixos.org</uri> has priority
|
||||
40.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>Every time Nix needs to build some store path
|
||||
<replaceable>p</replaceable>, it will check each configured binary
|
||||
cache to see if it has a NAR file for <replaceable>p</replaceable>,
|
||||
until it finds one. If no cache has a NAR, Nix will fall back to
|
||||
building the path from source (if applicable). To see if a cache with
|
||||
URL <replaceable>url</replaceable> has a binary for
|
||||
<replaceable>p</replaceable>, Nix fetches
|
||||
<replaceable>url/h</replaceable>, where <replaceable>h</replaceable>
|
||||
is the hash part of <replaceable>p</replaceable>. Thus, if we have a
|
||||
cache <uri>https://cache.nixos.org</uri> and we want to obtain the
|
||||
store path
|
||||
<screen>
|
||||
/nix/store/a8922c0h87iilxzzvwn2hmv8x210aqb9-glibc-2.7
|
||||
</screen>
|
||||
then Nix will attempt to fetch
|
||||
<screen>
|
||||
https://cache.nixos.org/a8922c0h87iilxzzvwn2hmv8x210aqb9.narinfo
|
||||
</screen>
|
||||
(Commands such as <command>nix-env -qas</command> will issue an HTTP
|
||||
HEAD request, since it only needs to know if the
|
||||
<filename>.narinfo</filename> file exists.) The
|
||||
<filename>.narinfo</filename> file is a simple text file that looks
|
||||
like this:
|
||||
|
||||
<screen>
|
||||
StorePath: /nix/store/a8922c0h87iilxzzvwn2hmv8x210aqb9-glibc-2.7
|
||||
URL: nar/0zzjpdz46mdn74v09m053yczlz4am038g8r74iy8w43gx8801h70.nar.bz2
|
||||
Compression: bzip2
|
||||
FileHash: sha256:0zzjpdz46mdn74v09m053yczlz4am038g8r74iy8w43gx8801h70
|
||||
FileSize: 24473768
|
||||
NarHash: sha256:0s491y1h9hxj5ghiizlxk7ax6jwbha00zwn7lpyd5xg5bhf60vzg
|
||||
NarSize: 109521136
|
||||
References: 2ma2k0ys8knh4an48n28vigcmc2z8773-linux-headers-2.6.23.16 ...
|
||||
Deriver: 7akyyc87ka32xwmqza9dvyg5pwx3j212-glibc-2.7.drv
|
||||
Sig: cache.example.org-1:WepnSp2UT0odDpR3NRjPVhJBHmdBgSBSTbHpdh4SCz92nGXwFY82bkPEmISoC0hGqBXDXEmB6y3Ohgna3mMgDg==
|
||||
</screen>
|
||||
|
||||
The fields are as follows:
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><literal>StorePath</literal></term>
|
||||
|
||||
<listitem><para>The full store path, including the name part
|
||||
(e.g., <literal>glibc-2.7</literal>). It must match the
|
||||
requested store path.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>URL</literal></term>
|
||||
|
||||
<listitem><para>The URL of the NAR, relative to the binary cache
|
||||
URL.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>Compression</literal></term>
|
||||
|
||||
<listitem><para>The compression method; either
|
||||
<literal>xz</literal> or
|
||||
<literal>bzip2</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>FileHash</literal></term>
|
||||
|
||||
<listitem><para>The SHA-256 hash of the compressed
|
||||
NAR.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>FileSize</literal></term>
|
||||
|
||||
<listitem><para>The size of the compressed NAR.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>NarHash</literal></term>
|
||||
|
||||
<listitem><para>The SHA-256 hash of the uncompressed NAR. This is
|
||||
equal to the hash of the store path as returned by
|
||||
<command>nix-store -q --hash
|
||||
<replaceable>p</replaceable></command>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>NarSize</literal></term>
|
||||
|
||||
<listitem><para>The size of the uncompressed NAR.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>References</literal></term>
|
||||
|
||||
<listitem><para>The references of the store path, without the Nix
|
||||
store prefix.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>Deriver</literal></term>
|
||||
|
||||
<listitem><para>The deriver of the store path, without the Nix
|
||||
store prefix. This field is optional.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>System</literal></term>
|
||||
|
||||
<listitem><para>The Nix platform type of this binary, if known.
|
||||
This field is optional.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>Sig</literal></term>
|
||||
|
||||
<listitem><para>A signature of the the form
|
||||
<literal><replaceable>key-name</replaceable>:<replaceable>sig</replaceable></literal>,
|
||||
where <replaceable>key-name</replaceable> is the symbolic name of
|
||||
the key pair used to sign and verify the cache
|
||||
(e.g. <literal>cache.example.org-1</literal>), and
|
||||
<replaceable>sig</replaceable> is the actual signature, computed
|
||||
over the <varname>StorePath</varname>, <varname>NarHash</varname>,
|
||||
<varname>NarSize</varname> and <varname>References</varname>
|
||||
fields using the <link
|
||||
xlink:href="http://ed25519.cr.yp.to/">Ed25519 public-key signature
|
||||
system</link>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
<para>Thus, in our example, after recursively ensuring that the
|
||||
references exist (e.g.,
|
||||
<filename>/nix/store/2ma2k0ys8knh4an48n28vigcmc2z8773-linux-headers-2.6.23.16</filename>),
|
||||
Nix will fetch <screen>
|
||||
https://cache.nixos.org/nar/0zzjpdz46mdn74v09m053yczlz4am038g8r74iy8w43gx8801h70.nar.bz2
|
||||
</screen> and decompress and unpack it to
|
||||
<filename>/nix/store/a8922c0h87iilxzzvwn2hmv8x210aqb9-glibc-2.7</filename>.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
</refentry>
|
||||
@@ -33,13 +33,13 @@
|
||||
<arg><option>--exclude</option> <replaceable>regexp</replaceable></arg>
|
||||
<arg><option>--pure</option></arg>
|
||||
<group choice='req'>
|
||||
<group choice='plain'>
|
||||
<group>
|
||||
<arg choice='plain'>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'><option>--packages</option></arg>
|
||||
<arg choice='plain'><option>-p</option></arg>
|
||||
</group>
|
||||
<replaceable>packages</replaceable>
|
||||
</group>
|
||||
<arg choice='plain' rep='repeat'><replaceable>packages</replaceable></arg>
|
||||
</arg>
|
||||
<arg><replaceable>path</replaceable></arg>
|
||||
</group>
|
||||
</cmdsynopsis>
|
||||
@@ -144,7 +144,7 @@ also <xref linkend="sec-common-options" />.</phrase></para>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--packages</option> / <option>-p</option></term>
|
||||
<varlistentry><term><option>--packages</option> / <option>-p</option> <replaceable>packages</replaceable>…</term>
|
||||
|
||||
<listitem><para>Set up an environment in which the specified
|
||||
packages are present. The command line arguments are interpreted
|
||||
@@ -267,7 +267,7 @@ dependencies in Nixpkgs.</para>
|
||||
|
||||
<para>The lines starting with <literal>#! nix-shell</literal> specify
|
||||
<command>nix-shell</command> options (see above). Note that you cannot
|
||||
write <literal>#1 /usr/bin/env nix-shell -i ...</literal> because
|
||||
write <literal>#! /usr/bin/env nix-shell -i ...</literal> because
|
||||
many operating systems only allow one argument in
|
||||
<literal>#!</literal> lines.</para>
|
||||
|
||||
|
||||
@@ -234,7 +234,66 @@ linkend="sec-nix-build"><command>nix-build</command></link> does.</para>
|
||||
<para>To test whether a previously-built derivation is deterministic:
|
||||
|
||||
<screen>
|
||||
$ nix-build -r '<nixpkgs>' -A hello --check -K
|
||||
$ nix-build '<nixpkgs>' -A hello --check -K
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
|
||||
<!--######################################################################-->
|
||||
|
||||
<refsection xml:id='rsec-nix-store-serve'><title>Operation <option>--serve</option></title>
|
||||
|
||||
<refsection><title>Synopsis</title>
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>nix-store</command>
|
||||
<arg choice='plain'><option>--serve</option></arg>
|
||||
<arg><option>--write</option></arg>
|
||||
</cmdsynopsis>
|
||||
|
||||
</refsection>
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>The operation <option>--serve</option> provides access to
|
||||
the Nix store over stdin and stdout, and is intended to be used
|
||||
as a means of providing Nix store access to a restricted ssh user.
|
||||
</para>
|
||||
|
||||
<para>The following flags are available:</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><option>--write</option></term>
|
||||
|
||||
<listitem><para>Allow the connected client to request the realization
|
||||
of derivations. In effect, this can be used to make the host act
|
||||
as a build slave.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<refsection><title>Examples</title>
|
||||
|
||||
<para>To turn a host into a build server, the
|
||||
<filename>authorized_keys</filename> file can be used to provide build
|
||||
access to a given SSH public key:
|
||||
|
||||
<screen>
|
||||
$ cat <<EOF >>/root/.ssh/authorized_keys
|
||||
command="nice -n20 nix-store --serve --write" ssh-rsa AAAAB3NzaC1yc2EAAAA...
|
||||
EOF
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
@@ -338,9 +397,9 @@ options control what gets deleted and in what order:
|
||||
</para>
|
||||
|
||||
<para>The behaviour of the collector is also influenced by the <link
|
||||
linkend="conf-gc-keep-outputs"><literal>gc-keep-outputs</literal></link>
|
||||
linkend="conf-keep-outputs"><literal>keep-outputs</literal></link>
|
||||
and <link
|
||||
linkend="conf-gc-keep-derivations"><literal>gc-keep-derivations</literal></link>
|
||||
linkend="conf-keep-derivations"><literal>keep-derivations</literal></link>
|
||||
variables in the Nix configuration file.</para>
|
||||
|
||||
<para>With <option>--delete</option>, the collector prints the total
|
||||
@@ -1056,17 +1115,17 @@ path).</para>
|
||||
<para>This command does not produce a <emphasis>closure</emphasis> of
|
||||
the specified paths, so if a store path references other store paths
|
||||
that are missing in the target Nix store, the import will fail. To
|
||||
copy a whole closure, do something like
|
||||
copy a whole closure, do something like:
|
||||
|
||||
<screen>
|
||||
$ nix-store --export $(nix-store -qR <replaceable>paths</replaceable>) > out</screen>
|
||||
|
||||
</para>
|
||||
To import the whole closure again, run:
|
||||
|
||||
<para>For an example of how <option>--export</option> and
|
||||
<option>--import</option> can be used, see the source of the <command
|
||||
linkend="sec-nix-copy-closure">nix-copy-closure</command>
|
||||
command.</para>
|
||||
<screen>
|
||||
$ nix-store --import < out</screen>
|
||||
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
@@ -1177,12 +1236,7 @@ the store path is used.</para>
|
||||
<filename>/nix/var/log/nix/drvs</filename>. However, there is no
|
||||
guarantee that a build log is available for any particular store path.
|
||||
For instance, if the path was downloaded as a pre-built binary through
|
||||
a substitute, then the log is unavailable. If the log is not available
|
||||
locally, then <command>nix-store</command> will try to download the
|
||||
log from the servers specified in the Nix option
|
||||
<option>log-servers</option>. For example, if it’s set to
|
||||
<literal>http://hydra.nixos.org/log</literal>, then Nix will check
|
||||
<literal>http://hydra.nixos.org/log/<replaceable>base-name</replaceable></literal>.</para>
|
||||
a substitute, then the log is unavailable.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
@@ -1289,82 +1343,6 @@ export _args; _args='-e /nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25c-default-buil
|
||||
</refsection>
|
||||
|
||||
|
||||
<!--######################################################################-->
|
||||
|
||||
<refsection><title>Operation <option>--query-failed-paths</option></title>
|
||||
|
||||
<refsection>
|
||||
<title>Synopsis</title>
|
||||
<cmdsynopsis>
|
||||
<command>nix-store</command>
|
||||
<arg choice='plain'><option>--query-failed-paths</option></arg>
|
||||
</cmdsynopsis>
|
||||
</refsection>
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>If build failure caching is enabled through the
|
||||
<literal>build-cache-failure</literal> configuration option, the
|
||||
operation <option>--query-failed-paths</option> will print out all
|
||||
store paths that have failed to build.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
<refsection><title>Example</title>
|
||||
|
||||
<screen>
|
||||
$ nix-store --query-failed-paths
|
||||
/nix/store/000zi5dcla86l92jn1g997jb06sidm7x-perl-PerlMagick-6.59
|
||||
/nix/store/0011iy7sfwbc1qj5a1f6ifjnbcdail8a-haskell-gitit-ghc7.0.4-0.8.1
|
||||
/nix/store/001c0yn1hkh86gprvrb46cxnz3pki7q3-gamin-0.1.10
|
||||
<replaceable>…</replaceable>
|
||||
</screen>
|
||||
|
||||
</refsection>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<!--######################################################################-->
|
||||
|
||||
<refsection><title>Operation <option>--clear-failed-paths</option></title>
|
||||
|
||||
<refsection>
|
||||
<title>Synopsis</title>
|
||||
<cmdsynopsis>
|
||||
<command>nix-store</command>
|
||||
<arg choice='plain'><option>--clear-failed-paths</option></arg>
|
||||
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsection>
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>If build failure caching is enabled through the
|
||||
<literal>build-cache-failure</literal> configuration option, the
|
||||
operation <option>--clear-failed-paths</option> clears the “failed”
|
||||
state of the given store paths, allowing them to be built again. This
|
||||
is useful if the failure was actually transient (e.g. because the disk
|
||||
was full).</para>
|
||||
|
||||
<para>If a path denotes a derivation, its output paths are cleared.
|
||||
You can provide the argument <literal>*</literal> to clear all store
|
||||
paths.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
<refsection><title>Example</title>
|
||||
|
||||
<screen>
|
||||
$ nix-store --clear-failed-paths /nix/store/000zi5dcla86l92jn1g997jb06sidm7x-perl-PerlMagick-6.59
|
||||
$ nix-store --clear-failed-paths *
|
||||
</screen>
|
||||
|
||||
</refsection>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
<!--######################################################################-->
|
||||
|
||||
<refsection xml:id='rsec-nix-store-generate-binary-cache-key'><title>Operation <option>--generate-binary-cache-key</option></title>
|
||||
@@ -1407,8 +1385,7 @@ parameters:
|
||||
|
||||
</orderedlist>
|
||||
|
||||
For an example, see the manual page for <command
|
||||
linkend="sec-nix-push">nix-push</command>.</para>
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
@@ -2,10 +2,18 @@
|
||||
|
||||
<arg><option>--help</option></arg>
|
||||
<arg><option>--version</option></arg>
|
||||
<arg rep='repeat'><option>--verbose</option></arg>
|
||||
<arg rep='repeat'><option>-v</option></arg>
|
||||
<arg><option>--no-build-output</option></arg>
|
||||
<arg><option>-Q</option></arg>
|
||||
<arg rep='repeat'>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'><option>--verbose</option></arg>
|
||||
<arg choice='plain'><option>-v</option></arg>
|
||||
</group>
|
||||
</arg>
|
||||
<arg>
|
||||
<group choice='plain'>
|
||||
<arg choice='plain'><option>--no-build-output</option></arg>
|
||||
<arg choice='plain'><option>-Q</option></arg>
|
||||
</group>
|
||||
</arg>
|
||||
<arg>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'><option>--max-jobs</option></arg>
|
||||
@@ -25,13 +33,20 @@
|
||||
<option>--timeout</option>
|
||||
<replaceable>number</replaceable>
|
||||
</arg>
|
||||
<arg><option>--keep-going</option></arg>
|
||||
<arg><option>-k</option></arg>
|
||||
<arg><option>--keep-failed</option></arg>
|
||||
<arg><option>-K</option></arg>
|
||||
<arg>
|
||||
<group choice='plain'>
|
||||
<arg choice='plain'><option>--keep-going</option></arg>
|
||||
<arg choice='plain'><option>-k</option></arg>
|
||||
</group>
|
||||
</arg>
|
||||
<arg>
|
||||
<group choice='plain'>
|
||||
<arg choice='plain'><option>--keep-failed</option></arg>
|
||||
<arg choice='plain'><option>-K</option></arg>
|
||||
</group>
|
||||
</arg>
|
||||
<arg><option>--fallback</option></arg>
|
||||
<arg><option>--readonly-mode</option></arg>
|
||||
<arg><option>--log-type</option> <replaceable>type</replaceable></arg>
|
||||
<arg><option>--show-trace</option></arg>
|
||||
<arg>
|
||||
<option>-I</option>
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><option>--verbose</option></term>
|
||||
<term><option>-v</option></term>
|
||||
<varlistentry><term><option>--verbose</option> / <option>-v</option></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
@@ -76,8 +75,7 @@
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><option>--no-build-output</option></term>
|
||||
<term><option>-Q</option></term>
|
||||
<varlistentry><term><option>--no-build-output</option> / <option>-Q</option></term>
|
||||
|
||||
<listitem><para>By default, output written by builders to standard
|
||||
output and standard error is echoed to the Nix command's standard
|
||||
@@ -89,13 +87,14 @@
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="opt-max-jobs"><term><option>--max-jobs</option></term>
|
||||
<term><option>-j</option></term>
|
||||
<varlistentry xml:id="opt-max-jobs"><term><option>--max-jobs</option> / <option>-j</option>
|
||||
<replaceable>number</replaceable></term>
|
||||
|
||||
<listitem><para>Sets the maximum number of build jobs that Nix will
|
||||
perform in parallel to the specified number. The default is
|
||||
specified by the <link
|
||||
linkend='conf-build-max-jobs'><literal>build-max-jobs</literal></link>
|
||||
perform in parallel to the specified number. Specify
|
||||
<literal>auto</literal> to use the number of CPUs in the system.
|
||||
The default is specified by the <link
|
||||
linkend='conf-max-jobs'><literal>max-jobs</literal></link>
|
||||
configuration setting, which itself defaults to
|
||||
<literal>1</literal>. A higher value is useful on SMP systems or to
|
||||
exploit I/O latency.</para></listitem>
|
||||
@@ -113,7 +112,7 @@
|
||||
<literal>true</literal>, the builder passes the
|
||||
<option>-j<replaceable>N</replaceable></option> flag to GNU Make.
|
||||
It defaults to the value of the <link
|
||||
linkend='conf-build-cores'><literal>build-cores</literal></link>
|
||||
linkend='conf-cores'><literal>cores</literal></link>
|
||||
configuration setting, if set, or <literal>1</literal> otherwise.
|
||||
The value <literal>0</literal> means that the builder should use all
|
||||
available CPU cores in the system.</para></listitem>
|
||||
@@ -126,7 +125,7 @@
|
||||
<listitem><para>Sets the maximum number of seconds that a builder
|
||||
can go without producing any data on standard output or standard
|
||||
error. The default is specified by the <link
|
||||
linkend='conf-build-max-silent-time'><literal>build-max-silent-time</literal></link>
|
||||
linkend='conf-max-silent-time'><literal>max-silent-time</literal></link>
|
||||
configuration setting. <literal>0</literal> means no
|
||||
time-out.</para></listitem>
|
||||
|
||||
@@ -136,14 +135,13 @@
|
||||
|
||||
<listitem><para>Sets the maximum number of seconds that a builder
|
||||
can run. The default is specified by the <link
|
||||
linkend='conf-build-timeout'><literal>build-timeout</literal></link>
|
||||
linkend='conf-timeout'><literal>timeout</literal></link>
|
||||
configuration setting. <literal>0</literal> means no
|
||||
timeout.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--keep-going</option></term>
|
||||
<term><option>-k</option></term>
|
||||
<varlistentry><term><option>--keep-going</option> / <option>-k</option></term>
|
||||
|
||||
<listitem><para>Keep going in case of failed builds, to the
|
||||
greatest extent possible. That is, if building an input of some
|
||||
@@ -155,8 +153,7 @@
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><option>--keep-failed</option></term>
|
||||
<term><option>-K</option></term>
|
||||
<varlistentry><term><option>--keep-failed</option> / <option>-K</option></term>
|
||||
|
||||
<listitem><para>Specifies that in case of a build failure, the
|
||||
temporary directory (usually in <filename>/tmp</filename>) in which
|
||||
@@ -191,6 +188,23 @@
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--no-build-hook</option></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>Disables the build hook mechanism. This allows to ignore remote
|
||||
builders if they are setup on the machine.</para>
|
||||
|
||||
<para>It's useful in cases where the bandwidth between the client and the
|
||||
remote builder is too low. In that case it can take more time to upload the
|
||||
sources to the remote builder and fetch back the result than to do the
|
||||
computation locally.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
|
||||
<varlistentry><term><option>--readonly-mode</option></term>
|
||||
|
||||
@@ -201,61 +215,6 @@
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="opt-log-type"><term><option>--log-type</option>
|
||||
<replaceable>type</replaceable></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>This option determines how the output written to standard
|
||||
error is formatted. Nix’s diagnostic messages are typically
|
||||
<emphasis>nested</emphasis>. For instance, when tracing Nix
|
||||
expression evaluation (<command>nix-env -vvvvv</command>, messages
|
||||
from subexpressions are nested inside their parent expressions. Nix
|
||||
builder output is also often nested. For instance, the Nix Packages
|
||||
generic builder nests the various build tasks (unpack, configure,
|
||||
compile, etc.), and the GNU Make in <literal>stdenv-linux</literal>
|
||||
has been patched to provide nesting for recursive Make
|
||||
invocations.</para>
|
||||
|
||||
<para><replaceable>type</replaceable> can be one of the
|
||||
following:
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><literal>pretty</literal></term>
|
||||
|
||||
<listitem><para>Pretty-print the output, indicating different
|
||||
nesting levels using spaces. This is the
|
||||
default.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>escapes</literal></term>
|
||||
|
||||
<listitem><para>Indicate nesting using escape codes that can be
|
||||
interpreted by the <command>nix-log2xml</command> tool in the
|
||||
Nix source distribution. The resulting XML file can be fed into
|
||||
the <command>log2html.xsl</command> stylesheet to create an HTML
|
||||
file that can be browsed interactively, using JavaScript to
|
||||
expand and collapse parts of the output.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>flat</literal></term>
|
||||
|
||||
<listitem><para>Remove all nesting.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></term>
|
||||
|
||||
<listitem><para>This option is accepted by
|
||||
@@ -273,9 +232,8 @@
|
||||
named <replaceable>name</replaceable>, it will call it with value
|
||||
<replaceable>value</replaceable>.</para>
|
||||
|
||||
<para>For instance, the file
|
||||
<literal>pkgs/top-level/all-packages.nix</literal> in Nixpkgs is
|
||||
actually a function:
|
||||
<para>For instance, the top-level <literal>default.nix</literal> in
|
||||
Nixpkgs is actually a function:
|
||||
|
||||
<programlisting>
|
||||
{ # The system (e.g., `i686-linux') for which to build the packages.
|
||||
|
||||
@@ -13,14 +13,8 @@ work with Nix.</para>
|
||||
<xi:include href="nix-collect-garbage.xml" />
|
||||
<xi:include href="nix-copy-closure.xml" />
|
||||
<xi:include href="nix-daemon.xml" />
|
||||
<!--
|
||||
<xi:include href="nix-generate-patches.xml" />
|
||||
-->
|
||||
<xi:include href="nix-hash.xml" />
|
||||
<xi:include href="nix-install-package.xml" />
|
||||
<xi:include href="nix-instantiate.xml" />
|
||||
<xi:include href="nix-prefetch-url.xml" />
|
||||
<xi:include href="nix-pull.xml" />
|
||||
<xi:include href="nix-push.xml" />
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -139,7 +139,7 @@ impureEnvVars = [ "http_proxy" "https_proxy" <replaceable>...</replaceable> ];
|
||||
<programlisting>
|
||||
fetchurl {
|
||||
url = http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz;
|
||||
md5 = "70c9ccf9fac07f762c24f2df2290784d";
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
@@ -150,7 +150,7 @@ fetchurl {
|
||||
<programlisting>
|
||||
fetchurl {
|
||||
url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
|
||||
md5 = "70c9ccf9fac07f762c24f2df2290784d";
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ available as <function>builtins.derivation</function>.</para>
|
||||
<varlistentry><term><function>builtins.add</function>
|
||||
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
|
||||
|
||||
<listitem><para>Return the sum of the integers
|
||||
<listitem><para>Return the sum of the numbers
|
||||
<replaceable>e1</replaceable> and
|
||||
<replaceable>e2</replaceable>.</para></listitem>
|
||||
|
||||
@@ -65,7 +65,7 @@ available as <function>builtins.derivation</function>.</para>
|
||||
<replaceable>set</replaceable></term>
|
||||
|
||||
<listitem><para>Return the names of the attributes in the set
|
||||
<replaceable>set</replaceable> in a sorted list. For instance,
|
||||
<replaceable>set</replaceable> in an alphabetically sorted list. For instance,
|
||||
<literal>builtins.attrNames { y = 1; x = "foo"; }</literal>
|
||||
evaluates to <literal>[ "x" "y" ]</literal>.</para></listitem>
|
||||
|
||||
@@ -134,6 +134,14 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><function>builtins.concatStringsSep</function>
|
||||
<replaceable>separator</replaceable> <replaceable>list</replaceable></term>
|
||||
|
||||
<listitem><para>Concatenate a list of strings with a separator
|
||||
between each element, e.g. <literal>concatStringsSep "/"
|
||||
["usr" "local" "bin"] == "usr/local/bin"</literal></para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry
|
||||
xml:id='builtin-currentSystem'><term><varname>builtins.currentSystem</varname></term>
|
||||
@@ -142,7 +150,7 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
evaluates to the Nix platform identifier for the Nix installation
|
||||
on which the expression is being evaluated, such as
|
||||
<literal>"i686-linux"</literal> or
|
||||
<literal>"powerpc-darwin"</literal>.</para></listitem>
|
||||
<literal>"x86_64-darwin"</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -204,13 +212,12 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
<varlistentry><term><function>builtins.div</function>
|
||||
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
|
||||
|
||||
<listitem><para>Return the quotient of the integers
|
||||
<listitem><para>Return the quotient of the numbers
|
||||
<replaceable>e1</replaceable> and
|
||||
<replaceable>e2</replaceable>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><function>builtins.elem</function>
|
||||
<replaceable>x</replaceable> <replaceable>xs</replaceable></term>
|
||||
|
||||
@@ -260,6 +267,24 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
<programlisting>
|
||||
with import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-14.12.tar.gz) {};
|
||||
|
||||
stdenv.mkDerivation { … }
|
||||
</programlisting>
|
||||
|
||||
Note that when obtaining the hash with <varname>nix-prefetch-url
|
||||
</varname> the option <varname>--unpack</varname> is required.
|
||||
</para>
|
||||
|
||||
<para>This function can also verify the contents against a hash.
|
||||
In that case, the function takes a set instead of a URL. The set
|
||||
requires the attribute <varname>url</varname> and the attribute
|
||||
<varname>sha256</varname>, e.g.
|
||||
|
||||
<programlisting>
|
||||
with import (fetchTarball {
|
||||
url = https://github.com/NixOS/nixpkgs-channels/archive/nixos-14.12.tar.gz;
|
||||
sha256 = "1jppksrfvbk5ypiqdz4cddxdl8z6zyzdb2srq8fcffr327ld5jj2";
|
||||
}) {};
|
||||
|
||||
stdenv.mkDerivation { … }
|
||||
</programlisting>
|
||||
|
||||
@@ -387,7 +412,7 @@ builtins.fromJSON ''{"x": [1, 2, 3], "y": null}''
|
||||
|
||||
<listitem><para>Generate list of size
|
||||
<replaceable>length</replaceable>, with each element
|
||||
<replaceable>i></replaceable> equal to the value returned by
|
||||
<replaceable>i</replaceable> equal to the value returned by
|
||||
<replaceable>generator</replaceable> <literal>i</literal>. For
|
||||
example,
|
||||
|
||||
@@ -583,6 +608,16 @@ x: x + 456</programlisting>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><function>builtins.isFloat</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
|
||||
<listitem><para>Return <literal>true</literal> if
|
||||
<replaceable>e</replaceable> evaluates to a float, and
|
||||
<literal>false</literal> otherwise.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><function>builtins.isBool</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
|
||||
@@ -620,12 +655,12 @@ x: x + 456</programlisting>
|
||||
<varlistentry><term><function>builtins.lessThan</function>
|
||||
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
|
||||
|
||||
<listitem><para>Return <literal>true</literal> if the integer
|
||||
<replaceable>e1</replaceable> is less than the integer
|
||||
<listitem><para>Return <literal>true</literal> if the number
|
||||
<replaceable>e1</replaceable> is less than the number
|
||||
<replaceable>e2</replaceable>, and <literal>false</literal>
|
||||
otherwise. Evaluation aborts if either
|
||||
<replaceable>e1</replaceable> or <replaceable>e2</replaceable>
|
||||
does not evaluate to an integer.</para></listitem>
|
||||
does not evaluate to a number.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -673,10 +708,46 @@ map (x: "foo" + x) [ "bar" "bla" "abc" ]</programlisting>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><function>builtins.match</function>
|
||||
<replaceable>regex</replaceable> <replaceable>str</replaceable></term>
|
||||
|
||||
<listitem><para>Returns a list if the <link
|
||||
xlink:href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended
|
||||
POSIX regular expression</link> <replaceable>regex</replaceable>
|
||||
matches <replaceable>str</replaceable> precisely, otherwise returns
|
||||
<literal>null</literal>. Each item in the list is a regex group.
|
||||
|
||||
<programlisting>
|
||||
builtins.match "ab" "abc"
|
||||
</programlisting>
|
||||
|
||||
Evaluates to <literal>null</literal>.
|
||||
|
||||
<programlisting>
|
||||
builtins.match "abc" "abc"
|
||||
</programlisting>
|
||||
|
||||
Evaluates to <literal>[ ]</literal>.
|
||||
|
||||
<programlisting>
|
||||
builtins.match "a(b)(c)" "abc"
|
||||
</programlisting>
|
||||
|
||||
Evaluates to <literal>[ "b" "c" ]</literal>.
|
||||
|
||||
<programlisting>
|
||||
builtins.match "[[:space:]]+([[:upper:]]+)[[:space:]]+" " FOO "
|
||||
</programlisting>
|
||||
|
||||
Evaluates to <literal>[ "foo" ]</literal>.
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><function>builtins.mul</function>
|
||||
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
|
||||
|
||||
<listitem><para>Return the product of the integers
|
||||
<listitem><para>Return the product of the numbers
|
||||
<replaceable>e1</replaceable> and
|
||||
<replaceable>e2</replaceable>.</para></listitem>
|
||||
|
||||
@@ -820,6 +891,43 @@ builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ]
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><function>builtins.split</function>
|
||||
<replaceable>regex</replaceable> <replaceable>str</replaceable></term>
|
||||
|
||||
<listitem><para>Returns a list composed of non matched strings interleaved
|
||||
with the lists of the <link
|
||||
xlink:href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended
|
||||
POSIX regular expression</link> <replaceable>regex</replaceable> matches
|
||||
of <replaceable>str</replaceable>. Each item in the lists of matched
|
||||
sequences is a regex group.
|
||||
|
||||
<programlisting>
|
||||
builtins.split "(a)b" "abc"
|
||||
</programlisting>
|
||||
|
||||
Evaluates to <literal>[ "" [ "a" ] "c" ]</literal>.
|
||||
|
||||
<programlisting>
|
||||
builtins.split "([ac])" "abc"
|
||||
</programlisting>
|
||||
|
||||
Evaluates to <literal>[ "" [ "a" ] "b" [ "c" ] "" ]</literal>.
|
||||
|
||||
<programlisting>
|
||||
builtins.split "(a)|(c)" "abc"
|
||||
</programlisting>
|
||||
|
||||
Evaluates to <literal>[ "" [ "a" null ] "b" [ null "c" ] "" ]</literal>.
|
||||
|
||||
<programlisting>
|
||||
builtins.split "([[:upper:]]+)" " FOO "
|
||||
</programlisting>
|
||||
|
||||
Evaluates to <literal>[ " " [ "FOO" ] " " ]</literal>.
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><function>builtins.stringLength</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
|
||||
@@ -833,7 +941,7 @@ builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ]
|
||||
<varlistentry><term><function>builtins.sub</function>
|
||||
<replaceable>e1</replaceable> <replaceable>e2</replaceable></term>
|
||||
|
||||
<listitem><para>Return the difference between the integers
|
||||
<listitem><para>Return the difference between the numbers
|
||||
<replaceable>e1</replaceable> and
|
||||
<replaceable>e2</replaceable>.</para></listitem>
|
||||
|
||||
@@ -853,7 +961,14 @@ builtins.sort builtins.lessThan [ 483 249 526 147 42 77 ]
|
||||
len</replaceable> lies beyond the end of the string, only the
|
||||
substring up to the end of the string is returned.
|
||||
<replaceable>start</replaceable> must be
|
||||
non-negative.</para></listitem>
|
||||
non-negative. For example,
|
||||
|
||||
<programlisting>
|
||||
builtins.substring 0 3 "nixos"
|
||||
</programlisting>
|
||||
|
||||
evaluates to <literal>"nix"</literal>.
|
||||
</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -913,8 +1028,8 @@ stdenv.mkDerivation {
|
||||
";
|
||||
|
||||
src = fetchurl {
|
||||
url = http://nix.cs.uu.nl/dist/tarballs/hello-2.1.1.tar.gz;
|
||||
md5 = "70c9ccf9fac07f762c24f2df2290784d";
|
||||
url = http://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
};
|
||||
inherit perl;
|
||||
}</programlisting>
|
||||
@@ -960,7 +1075,7 @@ in foo</programlisting>
|
||||
<varlistentry><term><function>builtins.toJSON</function> <replaceable>e</replaceable></term>
|
||||
|
||||
<listitem><para>Return a string containing a JSON representation
|
||||
of <replaceable>e</replaceable>. Strings, integers, booleans,
|
||||
of <replaceable>e</replaceable>. Strings, integers, floats, booleans,
|
||||
nulls and lists are mapped to their JSON equivalents. Sets
|
||||
(except derivations) are represented as objects. Derivations are
|
||||
translated to a JSON string containing the derivation’s output
|
||||
@@ -987,10 +1102,17 @@ in foo</programlisting>
|
||||
|
||||
<listitem><para>Convert the expression
|
||||
<replaceable>e</replaceable> to a string.
|
||||
<replaceable>e</replaceable> can be a string (in which case
|
||||
<function>toString</function> is a no-op) or a path (e.g.,
|
||||
<literal>toString /foo/bar</literal> yields
|
||||
<literal>"/foo/bar"</literal>.</para></listitem>
|
||||
<replaceable>e</replaceable> can be:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>A string (in which case the string is returned unmodified).</para></listitem>
|
||||
<listitem><para>A path (e.g., <literal>toString /foo/bar</literal> yields <literal>"/foo/bar"</literal>.</para></listitem>
|
||||
<listitem><para>A set containing <literal>{ __toString = self: ...; }</literal>.</para></listitem>
|
||||
<listitem><para>An integer.</para></listitem>
|
||||
<listitem><para>A list, in which case the string representations of its elements are joined with spaces.</para></listitem>
|
||||
<listitem><para>A Boolean (<literal>false</literal> yields <literal>""</literal>, <literal>true</literal> yields <literal>"1"</literal>.</para></listitem>
|
||||
<listitem><para><literal>null</literal>, which yields the empty string.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -1120,6 +1242,19 @@ stdenv.mkDerivation (rec {
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><function>builtins.tryEval</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
|
||||
<listitem><para>Try to evaluate <replaceable>e</replaceable>.
|
||||
Return a set containing the attributes <literal>success</literal>
|
||||
(<literal>true</literal> if <replaceable>e</replaceable> evaluated
|
||||
successfully, <literal>false</literal> if an error was thrown) and
|
||||
<literal>value</literal>, equalling <replaceable>e</replaceable>
|
||||
if successful and <literal>false</literal> otherwise.
|
||||
</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry><term><function>builtins.typeOf</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
@@ -1128,8 +1263,9 @@ stdenv.mkDerivation (rec {
|
||||
<replaceable>e</replaceable>, namely <literal>"int"</literal>,
|
||||
<literal>"bool"</literal>, <literal>"string"</literal>,
|
||||
<literal>"path"</literal>, <literal>"null"</literal>,
|
||||
<literal>"set"</literal>, <literal>"list"</literal> or
|
||||
<literal>"lambda"</literal>.</para></listitem>
|
||||
<literal>"set"</literal>, <literal>"list"</literal>,
|
||||
<literal>"lambda"</literal> or
|
||||
<literal>"float"</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ of which specify the inputs of the build.</para>
|
||||
<listitem xml:id="attr-system"><para>There must be an attribute named
|
||||
<varname>system</varname> whose value must be a string specifying a
|
||||
Nix platform identifier, such as <literal>"i686-linux"</literal> or
|
||||
<literal>"powerpc-darwin"</literal><footnote><para>To figure out
|
||||
<literal>"x86_64-darwin"</literal><footnote><para>To figure out
|
||||
your platform identifier, look at the line <quote>Checking for the
|
||||
canonical Nix system name</quote> in the output of Nix's
|
||||
<filename>configure</filename> script.</para></footnote> The build
|
||||
@@ -43,7 +43,7 @@ of which specify the inputs of the build.</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>Strings and integers are just passed
|
||||
<listitem><para>Strings and numbers are just passed
|
||||
verbatim.</para></listitem>
|
||||
|
||||
<listitem><para>A <emphasis>path</emphasis> (e.g.,
|
||||
@@ -100,7 +100,7 @@ outputs = [ "lib" "headers" "doc" ];
|
||||
<programlisting>
|
||||
buildInputs = [ pkg.lib pkg.headers ];
|
||||
</programlisting>
|
||||
The first element of <varname>output</varname> determines the
|
||||
The first element of <varname>outputs</varname> determines the
|
||||
<emphasis>default output</emphasis>. Thus, you could also write
|
||||
<programlisting>
|
||||
buildInputs = [ pkg pkg.headers ];
|
||||
|
||||
@@ -16,7 +16,7 @@ stdenv.mkDerivation { <co xml:id='ex-hello-nix-co-2' />
|
||||
builder = ./builder.sh; <co xml:id='ex-hello-nix-co-4' />
|
||||
src = fetchurl { <co xml:id='ex-hello-nix-co-5' />
|
||||
url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
|
||||
md5 = "70c9ccf9fac07f762c24f2df2290784d";
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
};
|
||||
inherit perl; <co xml:id='ex-hello-nix-co-6' />
|
||||
}</programlisting>
|
||||
@@ -108,7 +108,7 @@ the single Nix expression in that directory
|
||||
<para>The builder has to know what the sources of the package
|
||||
are. Here, the attribute <varname>src</varname> is bound to the
|
||||
result of a call to the <command>fetchurl</command> function.
|
||||
Given a URL and an MD5 hash of the expected contents of the file
|
||||
Given a URL and a SHA-256 hash of the expected contents of the file
|
||||
at that URL, this function builds a derivation that downloads the
|
||||
file and checks its hash. So the sources are a dependency that
|
||||
like all other dependencies is built before Hello itself is
|
||||
@@ -145,4 +145,4 @@ perl = perl;</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -177,13 +177,19 @@ map (concat "foo") [ "bar" "bla" "abc" ]</programlisting>
|
||||
<listitem><para>An <literal>@</literal>-pattern provides a means of referring
|
||||
to the whole value being matched:
|
||||
|
||||
<programlisting>
|
||||
args@{ x, y, z, ... }: z + y + x + args.a</programlisting>
|
||||
<programlisting> args@{ x, y, z, ... }: z + y + x + args.a</programlisting>
|
||||
|
||||
but can also be written as:
|
||||
|
||||
<programlisting> { x, y, z, ... } @ args: z + y + x + args.a</programlisting>
|
||||
|
||||
Here <varname>args</varname> is bound to the entire argument, which
|
||||
is further matched against the pattern <literal>{ x, y, z,
|
||||
... }</literal>.</para></listitem>
|
||||
|
||||
... }</literal>. <literal>@</literal>-pattern makes mainly sense with an
|
||||
ellipsis(<literal>...</literal>) as you can access attribute names as
|
||||
<literal>a</literal>, using <literal>args.a</literal>, which was given as an
|
||||
additional attribute to the function.
|
||||
</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
@@ -196,24 +202,6 @@ in concat { x = "foo"; y = "bar"; }</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para>A set that has a <literal>__functor</literal> attribute whose value
|
||||
is callable (i.e. is itself a function or a set with a
|
||||
<literal>__functor</literal> attribute whose value is callable) can be
|
||||
applied as if it were a function, with the set itself passed in first
|
||||
, e.g.,
|
||||
|
||||
<programlisting>
|
||||
let add = { __functor = self: x: x + self.x; };
|
||||
inc = add // { x = 1; };
|
||||
in inc 1
|
||||
</programlisting>
|
||||
|
||||
evaluates to <literal>2</literal>. This can be used to attach metadata to a
|
||||
function without the caller needing to treat it specially, or to implement
|
||||
a form of object-oriented programming, for example.
|
||||
|
||||
</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
|
||||
@@ -345,7 +333,20 @@ with (import ./definitions.nix); ...</programlisting>
|
||||
|
||||
makes all attributes defined in the file
|
||||
<filename>definitions.nix</filename> available as if they were defined
|
||||
locally in a <literal>rec</literal>-expression.</para>
|
||||
locally in a <literal>let</literal>-expression.</para>
|
||||
|
||||
<para>The bindings introduced by <literal>with</literal> do not shadow bindings
|
||||
introduced by other means, e.g.
|
||||
|
||||
<programlisting>
|
||||
let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; ...</programlisting>
|
||||
|
||||
establishes the same scope as
|
||||
|
||||
<programlisting>
|
||||
let a = 1; in let a = 2; in let a = 3; in let a = 4; in ...</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
@@ -359,4 +360,4 @@ character, or inline/multi-line, enclosed within <literal>/*
|
||||
</simplesect>
|
||||
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -40,6 +40,11 @@ weakest binding).</para>
|
||||
<entry>Call function <replaceable>e1</replaceable> with
|
||||
argument <replaceable>e2</replaceable>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>-</literal> <replaceable>e</replaceable></entry>
|
||||
<entry>none</entry>
|
||||
<entry>Arithmetic negation.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><replaceable>e</replaceable> <literal>?</literal>
|
||||
<replaceable>attrpath</replaceable></entry>
|
||||
@@ -55,13 +60,24 @@ weakest binding).</para>
|
||||
<entry>List concatenation.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><replaceable>e1</replaceable> <literal>+</literal> <replaceable>e2</replaceable></entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>*</literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal>/</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>left</entry>
|
||||
<entry>String or path concatenation.</entry>
|
||||
<entry>Arithmetic multiplication and division.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>+</literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal>-</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>left</entry>
|
||||
<entry>Arithmetic addition and subtraction. String or path concatenation (only by <literal>+</literal>).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>!</literal> <replaceable>e</replaceable></entry>
|
||||
<entry>left</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Boolean negation.</entry>
|
||||
</row>
|
||||
<row>
|
||||
@@ -75,16 +91,22 @@ weakest binding).</para>
|
||||
attributes).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><replaceable>e1</replaceable> <literal>==</literal>
|
||||
<replaceable>e2</replaceable></entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal><</literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal>></literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal><=</literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal>>=</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Equality.</entry>
|
||||
<entry>Arithmetic comparison.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><replaceable>e1</replaceable> <literal>!=</literal>
|
||||
<replaceable>e2</replaceable></entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>==</literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal>!=</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Inequality.</entry>
|
||||
<entry>Equality and inequality.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><replaceable>e1</replaceable> <literal>&&</literal>
|
||||
|
||||
@@ -98,13 +98,17 @@ configureFlags = "
|
||||
|
||||
<para>Since <literal>${</literal> and <literal>''</literal> have
|
||||
special meaning in indented strings, you need a way to quote them.
|
||||
<literal>${</literal> can be escaped by prefixing it with
|
||||
<literal>$</literal> can be escaped by prefixing it with
|
||||
<literal>''</literal> (that is, two single quotes), i.e.,
|
||||
<literal>''${</literal>. <literal>''</literal> can be escaped by
|
||||
<literal>''$</literal>. <literal>''</literal> can be escaped by
|
||||
prefixing it with <literal>'</literal>, i.e.,
|
||||
<literal>'''</literal>. Finally, linefeed, carriage-return and
|
||||
tab characters can be written as <literal>''\n</literal>,
|
||||
<literal>''\r</literal>, <literal>''\t</literal>.</para>
|
||||
<literal>'''</literal>. <literal>$</literal> removes any special meaning
|
||||
from the following <literal>$</literal>. Linefeed, carriage-return and tab
|
||||
characters can be written as <literal>''\n</literal>,
|
||||
<literal>''\r</literal>, <literal>''\t</literal>, and <literal>''\</literal>
|
||||
escapes any other character.
|
||||
|
||||
</para>
|
||||
|
||||
<para>Indented strings are primarily useful in that they allow
|
||||
multi-line string literals to follow the indentation of the
|
||||
@@ -140,8 +144,13 @@ stdenv.mkDerivation {
|
||||
|
||||
</listitem>
|
||||
|
||||
<listitem><para><emphasis>Integers</emphasis>, e.g.,
|
||||
<literal>123</literal>.</para></listitem>
|
||||
<listitem><para>Numbers, which can be <emphasis>integers</emphasis> (like
|
||||
<literal>123</literal>) or <emphasis>floating point</emphasis> (like
|
||||
<literal>123.43</literal> or <literal>.27e13</literal>).</para>
|
||||
|
||||
<para>Numbers are type-compatible: pure integer operations will always
|
||||
return integers, whereas any operation involving at least one floating point
|
||||
number will have a floating point number as a result.</para></listitem>
|
||||
|
||||
<listitem><para><emphasis>Paths</emphasis>, e.g.,
|
||||
<filename>/bin/sh</filename> or <filename>./builder.sh</filename>.
|
||||
@@ -162,7 +171,16 @@ stdenv.mkDerivation {
|
||||
user's home directory. e.g. <filename>~/foo</filename> would be
|
||||
equivalent to <filename>/home/edolstra/foo</filename> for a user
|
||||
whose home directory is <filename>/home/edolstra</filename>.
|
||||
</para></listitem>
|
||||
</para>
|
||||
|
||||
<para>Paths can also be specified between angle brackets, e.g.
|
||||
<literal><nixpkgs></literal>. This means that the directories
|
||||
listed in the environment variable
|
||||
<envar linkend="env-NIX_PATH">NIX_PATH</envar> will be searched
|
||||
for the given file or directory name.
|
||||
</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
<listitem><para><emphasis>Booleans</emphasis> with values
|
||||
<literal>true</literal> and
|
||||
@@ -271,6 +289,23 @@ added to the set:
|
||||
This will evaluate to <literal>{}</literal> if <literal>foo</literal>
|
||||
evaluates to <literal>false</literal>.</para>
|
||||
|
||||
<para>A set that has a <literal>__functor</literal> attribute whose value
|
||||
is callable (i.e. is itself a function or a set with a
|
||||
<literal>__functor</literal> attribute whose value is callable) can be
|
||||
applied as if it were a function, with the set itself passed in first
|
||||
, e.g.,
|
||||
|
||||
<programlisting>
|
||||
let add = { __functor = self: x: x + self.x; };
|
||||
inc = add // { x = 1; };
|
||||
in inc 1
|
||||
</programlisting>
|
||||
|
||||
evaluates to <literal>2</literal>. This can be used to attach metadata to a
|
||||
function without the caller needing to treat it specially, or to implement
|
||||
a form of object-oriented programming, for example.
|
||||
|
||||
</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
|
||||
@@ -7,15 +7,14 @@
|
||||
<title>Building and Testing</title>
|
||||
|
||||
<para>You can now try to build Hello. Of course, you could do
|
||||
<literal>nix-env -f pkgs/top-level/all-packages.nix -i hello</literal>,
|
||||
but you may not want to install a possibly broken package just yet.
|
||||
The best way to test the package is by using the command <command
|
||||
linkend="sec-nix-build">nix-build</command>, which builds a Nix
|
||||
expression and creates a symlink named <filename>result</filename> in
|
||||
the current directory:
|
||||
<literal>nix-env -i hello</literal>, but you may not want to install a
|
||||
possibly broken package just yet. The best way to test the package is by
|
||||
using the command <command linkend="sec-nix-build">nix-build</command>,
|
||||
which builds a Nix expression and creates a symlink named
|
||||
<filename>result</filename> in the current directory:
|
||||
|
||||
<screen>
|
||||
$ nix-build pkgs/top-level/all-packages.nix -A hello
|
||||
$ nix-build -A hello
|
||||
building path `/nix/store/632d2b22514d...-hello-2.1.1'
|
||||
hello-2.1.1/
|
||||
hello-2.1.1/intl/
|
||||
@@ -29,8 +28,7 @@ $ ./result/bin/hello
|
||||
Hello, world!</screen>
|
||||
|
||||
The <link linkend='opt-attr'><option>-A</option></link> option selects
|
||||
the <literal>hello</literal> attribute from
|
||||
<filename>all-packages.nix</filename>. This is faster than using the
|
||||
the <literal>hello</literal> attribute. This is faster than using the
|
||||
symbolic package name specified by the <literal>name</literal>
|
||||
attribute (which also happens to be <literal>hello</literal>) and is
|
||||
unambiguous (there can be multiple packages with the symbolic name
|
||||
@@ -69,7 +67,7 @@ block (or perform other derivations if available) until the build
|
||||
finishes:
|
||||
|
||||
<screen>
|
||||
$ nix-build pkgs/top-level/all-packages.nix -A hello
|
||||
$ nix-build -A hello
|
||||
waiting for lock on `/nix/store/0h5b7hp8d4hqfrw8igvx97x1xawrjnac-hello-2.1.1x'</screen>
|
||||
|
||||
So it is always safe to run multiple instances of Nix in parallel
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
<glossdef><para>A substitute is a command invocation stored in the
|
||||
Nix database that describes how to build a store object, bypassing
|
||||
normal the build mechanism (i.e., derivations). Typically, the
|
||||
the normal build mechanism (i.e., derivations). Typically, the
|
||||
substitute builds the store object by downloading a pre-built
|
||||
version of the store object from some server.</para></glossdef>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ $ nix-build release.nix -A build.x86_64-linux
|
||||
environment variables are set up so that those dependencies can be
|
||||
found:
|
||||
<screen>
|
||||
$ ./dev-shell
|
||||
$ nix-shell
|
||||
</screen>
|
||||
To build Nix itself in this shell:
|
||||
<screen>
|
||||
@@ -30,7 +30,7 @@ To build Nix itself in this shell:
|
||||
[nix-shell]$ configurePhase
|
||||
[nix-shell]$ make
|
||||
</screen>
|
||||
To test it:
|
||||
To install it in <literal>$(pwd)/nix</literal> and test it:
|
||||
<screen>
|
||||
[nix-shell]$ make install
|
||||
[nix-shell]$ make installcheck
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<title>Installing a Binary Distribution</title>
|
||||
|
||||
<para>If you are using Linux or Mac OS X, the easiest way to install
|
||||
<para>If you are using Linux or macOS, the easiest way to install
|
||||
Nix is to run the following command:
|
||||
|
||||
<screen>
|
||||
@@ -26,12 +26,20 @@ $ mkdir /nix
|
||||
$ chown alice /nix
|
||||
</screen>
|
||||
|
||||
The install script will modify the first writable file from amongst
|
||||
<filename>.bash_profile</filename>, <filename>.bash_login</filename>
|
||||
and <filename>.profile</filename> to source
|
||||
<filename>~/.nix-profile/etc/profile.d/nix.sh</filename>. You can set
|
||||
the <command>NIX_INSTALLER_NO_MODIFY_PROFILE</command> environment
|
||||
variable before executing the install script to disable this
|
||||
behaviour.
|
||||
|
||||
</para>
|
||||
|
||||
<!--
|
||||
<para>You can also manually download and install a binary package.
|
||||
Binary packages of the latest stable release are available for Fedora,
|
||||
Debian, Ubuntu, Mac OS X and various other systems from the <link
|
||||
Debian, Ubuntu, macOS and various other systems from the <link
|
||||
xlink:href="http://nixos.org/nix/download.html">Nix homepage</link>.
|
||||
You can also get builds of the latest development release from our
|
||||
<link
|
||||
@@ -53,6 +61,7 @@ install it like this:
|
||||
$ dpkg -i nix_1.8-1_amd64.deb</screen>
|
||||
|
||||
</para>
|
||||
-->
|
||||
|
||||
<para>You can also download a binary tarball that contains Nix and all
|
||||
its dependencies. (This is what the install script at
|
||||
@@ -79,7 +88,6 @@ other auxiliary data, if desired:
|
||||
$ rm -rf /nix</screen>
|
||||
|
||||
</para>
|
||||
-->
|
||||
|
||||
<para>You can uninstall Nix simply by running:
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ This creates 10 build users. There can never be more concurrent builds
|
||||
than the number of build users, so you may want to increase this if
|
||||
you expect to do many builds at the same time.</para>
|
||||
|
||||
<para>On Mac OS X, you can create the required group and users by
|
||||
<para>On macOS, you can create the required group and users by
|
||||
running the following script:
|
||||
|
||||
<programlisting>
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
|
||||
<listitem><para>GNU Make.</para></listitem>
|
||||
|
||||
<listitem><para>A version of GCC or Clang that supports C++11.</para></listitem>
|
||||
|
||||
<listitem><para>Perl 5.8 or higher.</para></listitem>
|
||||
<listitem><para>A version of GCC or Clang that supports C++14.</para></listitem>
|
||||
|
||||
<listitem><para><command>pkg-config</command> to locate
|
||||
dependencies. If your distribution does not provide it, you can get
|
||||
@@ -20,6 +18,10 @@
|
||||
xlink:href="http://www.freedesktop.org/wiki/Software/pkg-config"
|
||||
/>.</para></listitem>
|
||||
|
||||
<listitem><para>The OpenSSL library to calculate cryptographic hashes.
|
||||
If your distribution does not provide it, you can get it from <link
|
||||
xlink:href="https://www.openssl.org"/>.</para></listitem>
|
||||
|
||||
<listitem><para>The bzip2 compressor program and the
|
||||
<literal>libbz2</literal> library. Thus you must have bzip2
|
||||
installed, including development headers and libraries. If your
|
||||
@@ -30,11 +32,6 @@
|
||||
or higher. If your distribution does not provide it, please install
|
||||
it from <link xlink:href="http://www.sqlite.org/" />.</para></listitem>
|
||||
|
||||
<listitem><para>The Perl DBI, DBD::SQLite, and WWW::Curl libraries, which are
|
||||
available from <link
|
||||
xlink:href="http://search.cpan.org/">CPAN</link> if your
|
||||
distribution does not provide them.</para></listitem>
|
||||
|
||||
<listitem><para>The <link
|
||||
xlink:href="http://www.hboehm.info/gc/">Boehm
|
||||
garbage collector</link> to reduce the evaluator’s memory
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<listitem><para>Linux (i686, x86_64).</para></listitem>
|
||||
|
||||
<listitem><para>Mac OS X (x86_64).</para></listitem>
|
||||
<listitem><para>macOS (x86_64).</para></listitem>
|
||||
|
||||
<!--
|
||||
<listitem><para>FreeBSD (only tested on Intel).</para></listitem>
|
||||
|
||||
@@ -62,9 +62,10 @@ directories such as
|
||||
so if a package builds correctly on your system, this is because you
|
||||
specified the dependency explicitly.</para>
|
||||
|
||||
<para>Runtime dependencies are found by scanning binaries for the hash
|
||||
parts of Nix store paths (such as <literal>r8vvq9kq…</literal>). This
|
||||
sounds risky, but it works extremely well.</para>
|
||||
<para>Once a package is built, runtime dependencies are found by
|
||||
scanning binaries for the hash parts of Nix store paths (such as
|
||||
<literal>r8vvq9kq…</literal>). This sounds risky, but it works
|
||||
extremely well.</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
@@ -92,7 +93,7 @@ time window in which the package has some files from the old version
|
||||
and some files from the new version — which would be bad because a
|
||||
program might well crash if it’s started during that period.</para>
|
||||
|
||||
<para>And since package aren’t overwritten, the old versions are still
|
||||
<para>And since packages aren’t overwritten, the old versions are still
|
||||
there after an upgrade. This means that you can <emphasis>roll
|
||||
back</emphasis> to the old version:</para>
|
||||
|
||||
@@ -235,7 +236,7 @@ href="[%root%]hydra">a continuous build system</a>.</para>
|
||||
|
||||
<simplesect><title>Portability</title>
|
||||
|
||||
<para>Nix runs on Linux and Mac OS X.</para>
|
||||
<para>Nix runs on Linux and macOS.</para>
|
||||
|
||||
</simplesect>
|
||||
|
||||
@@ -260,6 +261,12 @@ xlink:href="http://nixos.org/">NixOS homepage</link>.</para>
|
||||
xlink:href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">GNU
|
||||
LGPLv2.1 or (at your option) any later version</link>.</para>
|
||||
|
||||
<para>Nix uses the <link
|
||||
xlink:href="https://github.com/arangodb/linenoise-ng">linenoise-ng
|
||||
library</link>, which has the following license:</para>
|
||||
|
||||
<programlisting><xi:include href="../../../src/linenoise/LICENSE" parse="text" /></programlisting>
|
||||
|
||||
</simplesect>
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ libxslt-1.1.28
|
||||
<step><para>Install some packages from the channel:
|
||||
|
||||
<screen>
|
||||
$ nix-env -i hello <replaceable>...</replaceable> </screen>
|
||||
$ nix-env -i hello</screen>
|
||||
|
||||
This should download pre-built packages; it should not build them
|
||||
locally (if it does, something went wrong).</para></step>
|
||||
@@ -95,18 +95,6 @@ The latter command will upgrade each installed package for which there
|
||||
is a “newer” version (as determined by comparing the version
|
||||
numbers).</para></step>
|
||||
|
||||
<!--
|
||||
<step><para>You can also install specific packages directly from
|
||||
your web browser. For instance, you can go to <link
|
||||
xlink:href="http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest"
|
||||
/> and click on any link for the individual packages for your
|
||||
platform. Associate <literal>application/nix-package</literal> with
|
||||
the program <command>nix-install-package</command>. A window should
|
||||
appear asking you whether it’s okay to install the package. Say
|
||||
<literal>Y</literal>. The package and all its dependencies will be
|
||||
installed.</para></step>
|
||||
-->
|
||||
|
||||
<step><para>If you're unhappy with the result of a
|
||||
<command>nix-env</command> action (e.g., an upgraded package turned
|
||||
out not to work properly), you can go back:
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
ifeq ($(doc_generate),yes)
|
||||
|
||||
XSLTPROC = $(xsltproc) --nonet $(xmlflags) \
|
||||
--param section.autolabel 1 \
|
||||
--param section.label.includes.component.label 1 \
|
||||
@@ -10,7 +13,7 @@ XSLTPROC = $(xsltproc) --nonet $(xmlflags) \
|
||||
--stringparam generate.toc "book toc" \
|
||||
--param keep.relative.image.uris 0
|
||||
|
||||
docbookxsl = http://docbook.sourceforge.net/release/xsl-ns/1.78.1
|
||||
docbookxsl = http://docbook.sourceforge.net/release/xsl-ns/current
|
||||
docbookrng = http://docbook.org/xml/5.0/rng/docbook.rng
|
||||
|
||||
MANUAL_SRCS := $(call rwildcard, $(d), *.xml)
|
||||
@@ -39,9 +42,9 @@ dist-files += $(d)/manual.xmli $(d)/version.txt $(d)/manual.is-valid
|
||||
# Generate man pages.
|
||||
man-pages := $(foreach n, \
|
||||
nix-env.1 nix-build.1 nix-shell.1 nix-store.1 nix-instantiate.1 \
|
||||
nix-collect-garbage.1 nix-push.1 nix-pull.1 \
|
||||
nix-collect-garbage.1 \
|
||||
nix-prefetch-url.1 nix-channel.1 \
|
||||
nix-install-package.1 nix-hash.1 nix-copy-closure.1 \
|
||||
nix-hash.1 nix-copy-closure.1 \
|
||||
nix.conf.5 nix-daemon.8, \
|
||||
$(d)/$(n))
|
||||
|
||||
@@ -71,22 +74,14 @@ $(foreach file, $(wildcard $(d)/images/callouts/*.gif), $(eval $(call install-da
|
||||
|
||||
$(eval $(call install-symlink, manual.html, $(docdir)/manual/index.html))
|
||||
|
||||
|
||||
all: $(d)/manual.html
|
||||
|
||||
|
||||
|
||||
clean-files += $(d)/manual.html
|
||||
|
||||
dist-files += $(d)/manual.html
|
||||
|
||||
|
||||
# Generate the PDF manual.
|
||||
$(d)/manual.pdf: $(d)/manual.xml $(MANUAL_SRCS) $(d)/manual.is-valid
|
||||
$(trace-gen) if test "$(dblatex)" != ""; then \
|
||||
cd doc/manual && $(XSLTPROC) --xinclude --stringparam profile.condition manual \
|
||||
$(docbookxsl)/profiling/profile.xsl manual.xml | \
|
||||
$(dblatex) -o $(notdir $@) $(dblatex_opts) -; \
|
||||
else \
|
||||
echo "Please install dblatex and rerun configure."; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
clean-files += $(d)/manual.pdf
|
||||
endif
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<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="sec-one-click">
|
||||
|
||||
<title>One-Click Installation</title>
|
||||
|
||||
<para>Often, when you want to install a specific package (e.g., from
|
||||
the <link
|
||||
xlink:href="http://nixos.org/nixpkgs/">Nix
|
||||
Packages collection</link>), subscribing to a channel is a bit
|
||||
cumbersome. And channels don’t help you at all if you want to install
|
||||
an older version of a package than the one provided by the current
|
||||
contents of the channel, or a package that has been removed from the
|
||||
channel. That’s when <emphasis>one-click installs</emphasis> come in
|
||||
handy: you can just go to the web page that contains the package,
|
||||
click on it, and it will be installed with all the necessary
|
||||
dependencies.</para>
|
||||
|
||||
<para>For instance, you can go to <link
|
||||
xlink:href="http://hydra.nixos.org/jobset/nixpkgs/trunk/channel/latest"
|
||||
/> and click on any link for the individual packages for your
|
||||
platform. The first time you do this, your browser will ask what to
|
||||
do with <literal>application/nix-package</literal> files. You should
|
||||
open them with <filename>/nix/bin/nix-install-package</filename>.
|
||||
This will open a window that asks you to confirm that you want to
|
||||
install the package. When you answer <literal>Y</literal>, the
|
||||
package and all its dependencies will be installed. This is a binary
|
||||
deployment mechanism — you get packages pre-compiled for the selected
|
||||
platform type.</para>
|
||||
|
||||
<para>You can also install <literal>application/nix-package</literal>
|
||||
files from the command line directly. See <xref
|
||||
linkend='sec-nix-install-package' /> for details.</para>
|
||||
|
||||
</chapter>
|
||||
@@ -18,7 +18,6 @@ who want to <emphasis>create</emphasis> packages should consult
|
||||
<xi:include href="profiles.xml" />
|
||||
<xi:include href="garbage-collection.xml" />
|
||||
<xi:include href="channels.xml" />
|
||||
<xi:include href="one-click.xml" />
|
||||
<xi:include href="sharing-packages.xml" />
|
||||
|
||||
</part>
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
</partintro>
|
||||
-->
|
||||
|
||||
<xi:include href="rl-1.12.xml" />
|
||||
<xi:include href="rl-1.11.10.xml" />
|
||||
<xi:include href="rl-1.11.xml" />
|
||||
<xi:include href="rl-1.10.xml" />
|
||||
<xi:include href="rl-1.9.xml" />
|
||||
|
||||
31
doc/manual/release-notes/rl-1.11.10.xml
Normal file
31
doc/manual/release-notes/rl-1.11.10.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<section 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="ssec-relnotes-1.11.10">
|
||||
|
||||
<title>Release 1.11.10 (2017-06-12)</title>
|
||||
|
||||
<para>This release fixes a security bug in Nix’s “build user” build
|
||||
isolation mechanism. Previously, Nix builders had the ability to
|
||||
create setuid binaries owned by a <literal>nixbld</literal>
|
||||
user. Such a binary could then be used by an attacker to assume a
|
||||
<literal>nixbld</literal> identity and interfere with subsequent
|
||||
builds running under the same UID.</para>
|
||||
|
||||
<para>To prevent this issue, Nix now disallows builders to create
|
||||
setuid and setgid binaries. On Linux, this is done using a seccomp BPF
|
||||
filter. Note that this imposes a small performance penalty (e.g. 1%
|
||||
when building GNU Hello). Using seccomp, we now also prevent the
|
||||
creation of extended attributes and POSIX ACLs since these cannot be
|
||||
represented in the NAR format and (in the case of POSIX ACLs) allow
|
||||
bypassing regular Nix store permissions. On macOS, the restriction is
|
||||
implemented using the existing sandbox mechanism, which now uses a
|
||||
minimal “allow all except the creation of setuid/setgid binaries”
|
||||
profile when regular sandboxing is disabled. On other platforms, the
|
||||
“build user” mechanism is now disabled.</para>
|
||||
|
||||
<para>Thanks go to Linus Heckemann for discovering and reporting this
|
||||
bug.</para>
|
||||
|
||||
</section>
|
||||
426
doc/manual/release-notes/rl-1.12.xml
Normal file
426
doc/manual/release-notes/rl-1.12.xml
Normal file
@@ -0,0 +1,426 @@
|
||||
<section 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="ssec-relnotes-1.12">
|
||||
|
||||
<title>Release 1.12 (TBA)</title>
|
||||
|
||||
<para>This release has the following new features:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>Start of new <command>nix</command> command line
|
||||
interface. This is a work in progress and the interface is subject
|
||||
to change.</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>Self-documenting: <option>--help</option> shows
|
||||
all available command-line arguments.</para></listitem>
|
||||
|
||||
<listitem><para><option>--help-config</option> shows all
|
||||
configuration options.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix build</command>: Replacement for
|
||||
<command>nix-build</command>.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix ls-store</command> and <command>nix
|
||||
ls-nar</command> allow listing the contents of a store path or
|
||||
NAR file.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix cat-store</command> and
|
||||
<command>nix cat-nar</command> allow extracting a file from a
|
||||
store path or NAR file.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix verify</command> checks whether a
|
||||
store path is unmodified and/or is trusted.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix copy-sigs</command> copies
|
||||
signatures from one store to another.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix sign-paths</command> signs store
|
||||
paths.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix copy</command> copies paths between
|
||||
arbitrary Nix stores, generalising
|
||||
<command>nix-copy-closure</command> and
|
||||
<command>nix-push</command>.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix path-info</command> shows
|
||||
information about store paths.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix run</command> starts a shell in
|
||||
which the specified packages are available.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix log</command> shows the build log
|
||||
of a package or path. If the build log is not available locally,
|
||||
it will try to obtain it from a binary cache.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix eval</command> replaces
|
||||
<command>nix-instantiate --eval</command>.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix dump-path</command> to get a NAR
|
||||
from a store path.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix edit</command> opens the source
|
||||
code of a package in an editor.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix search</command> replaces
|
||||
<command>nix-env -qa</command>. It searches the available
|
||||
packages for occurences of a search string in the attribute
|
||||
name, package name or description. It caches available packages
|
||||
to speed up searches.</para></listitem>
|
||||
|
||||
<listitem><para><command>nix why-depends</command> (d41c5eb13f4f3a37d80dbc6d3888644170c3b44a).</para></listitem>
|
||||
|
||||
<listitem><para><command>nix show-derivation</command> (e8d6ee7c1b90a2fe6d824f1a875acc56799ae6e2).</para></listitem>
|
||||
|
||||
<listitem><para><command>nix add-to-store</command> (970366266b8df712f5f9cedb45af183ef5a8357f).</para></listitem>
|
||||
|
||||
<listitem><para>Progress indicator.</para></listitem>
|
||||
|
||||
<listitem><para>All options are available as flags now
|
||||
(b8283773bd64d7da6859ed520ee19867742a03ba).</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The external program <command>nix-repl</command> has been
|
||||
integrated into Nix as <command>nix repl</command>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>New build mode <command>nix-build --hash</command> that
|
||||
builds a derivation, computes the hash of the output, and moves
|
||||
the output to the store path corresponding to what a fixed-output
|
||||
derivation with that hash would produce.
|
||||
(Add docs and examples; see d367b8e7875161e655deaa96bf8a5dd0bcf8229e)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>It is no longer necessary to set the
|
||||
<envar>NIX_REMOTE</envar> environment variable if you need to use
|
||||
the Nix daemon. Nix will use the daemon automatically if you don’t
|
||||
have write access to the Nix database.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The Nix language now supports floating point numbers. They are
|
||||
based on regular C++ <literal>float</literal> and compatible with
|
||||
existing integers and number-related operations. Export and import to and
|
||||
from JSON and XML works, too.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><command>nix-shell</command> now sets the
|
||||
<varname>IN_NIX_SHELL</varname> environment variable during
|
||||
evaluation and in the shell itself. This can be used to perform
|
||||
different actions depending on whether you’re in a Nix shell or in
|
||||
a regular build. Nixpkgs provides
|
||||
<varname>lib.inNixShell</varname> to check this variable during
|
||||
evaluation. (bb36a1a3cf3fbe6bc9d0afcc5fa0f928bed03170)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Internal: all <classname>Store</classname> classes are now
|
||||
thread-safe. <classname>RemoteStore</classname> supports multiple
|
||||
concurrent connections to the daemon. This is primarily useful in
|
||||
multi-threaded programs such as
|
||||
<command>hydra-queue-runner</command>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The dependency on Perl has been removed. As a result, some
|
||||
(obsolete) programs have been removed: <command>nix-push</command>
|
||||
(replaced by <command>nix copy</command>),
|
||||
<command>nix-pull</command> (obsoleted by binary caches),
|
||||
<command>nix-generate-patches</command>,
|
||||
<command>bsdiff</command>, <command>bspatch</command>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Improved store abstraction. Substituters
|
||||
eliminated. BinaryCacheStore, LocalBinaryCacheStore,
|
||||
HttpBinaryCacheStore, S3BinaryCacheStore (compile-time
|
||||
optional), SSHStore. Add docs + examples?
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Nix now stores signatures for local store
|
||||
paths. Locally-built paths are now signed automatically using the
|
||||
secret keys specified by the <option>secret-key-files</option>
|
||||
store option.</para>
|
||||
|
||||
<para>In addition, store paths that have been built locally are
|
||||
marked as “ultimately trusted”, and content-addressable store
|
||||
paths carry a “content-addressability assertion” that allow them
|
||||
to be trusted without any signatures.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><envar>NIX_PATH</envar> is now lazy, so URIs in the path are
|
||||
only downloaded if they are needed for evaluation.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>You can now use
|
||||
<uri>channel:<replaceable>channel-name</replaceable></uri> as a
|
||||
short-hand for
|
||||
<uri>https://nixos.org/channels/<replaceable>channel-name</replaceable>/nixexprs.tar.xz</uri>. For
|
||||
example, <literal>nix-build channel:nixos-15.09 -A hello</literal>
|
||||
will build the GNU Hello package from the
|
||||
<literal>nixos-15.09</literal> channel.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>When <option>--no-build-output</option> is given, the last
|
||||
10 lines of the build log will be shown if a build
|
||||
fails.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><function>builtins.fetchGit</function>.
|
||||
(38539b943a060d9cdfc24d6e5d997c0885b8aa2f)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal><nix/fetchurl.nix></literal> now uses the
|
||||
content-addressable tarball cache at
|
||||
<uri>http://tarballs.nixos.org/</uri>, just like
|
||||
<function>fetchurl</function> in
|
||||
Nixpkgs. (f2682e6e18a76ecbfb8a12c17e3a0ca15c084197)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Chroot Nix stores: allow the “physical” location of the Nix
|
||||
store (e.g. <filename>/home/alice/nix/store</filename>) to differ
|
||||
from its “logical” location (typically
|
||||
<filename>/nix/store</filename>). This allows non-root users to
|
||||
use Nix while still getting the benefits from prebuilt binaries
|
||||
from
|
||||
<uri>cache.nixos.org</uri>. (4494000e04122f24558e1436e66d20d89028b4bd,
|
||||
3eb621750848e0e6b30e5a79f76afbb096bb6c8a)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>On Linux, builds are now executed in a user
|
||||
namespace with uid 1000 and gid 100.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><function>builtins.fetchurl</function> and
|
||||
<function>builtins.fetchTarball</function> now support
|
||||
<varname>sha256</varname> and <varname>name</varname>
|
||||
attributes.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>HttpBinaryCacheStore</literal> (the replacement of
|
||||
<command>download-from-binary-cache</command>) now retries
|
||||
automatically on certain HTTP error codes.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Derivation attributes can now reference the outputs of the
|
||||
derivation using the <function>placeholder</function> builtin
|
||||
function. For example, the attribute
|
||||
|
||||
<programlisting>
|
||||
configureFlags = "--prefix=${placeholder "out"} --includedir=${placeholder "dev"}";
|
||||
</programlisting>
|
||||
|
||||
will cause the <envar>configureFlags</envar> environment variable
|
||||
to contain the actual store paths corresponding to the
|
||||
<literal>out</literal> and <literal>dev</literal> outputs. TODO:
|
||||
add docs.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Support for HTTP/2. This makes binary cache lookups much
|
||||
more efficient. (90ad02bf626b885a5dd8967894e2eafc953bdf92)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The <option>build-sandbox-paths</option> configuration
|
||||
option can now specify optional paths by appending a
|
||||
<literal>?</literal>, e.g. <literal>/dev/nvidiactl?</literal> will
|
||||
bind-mount <varname>/dev/nvidiactl</varname> only if it
|
||||
exists.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>More support for testing build reproducibility: when
|
||||
<option>enforce-determinism</option> is set to
|
||||
<literal>false</literal>, it’s no longer a fatal error build
|
||||
rounds produce different output
|
||||
(8bdf83f936adae6f2c907a6d2541e80d4120f051); add a hook to run
|
||||
diffoscope when build rounds produce different output
|
||||
(9a313469a4bdea2d1e8df24d16289dc2a172a169w).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Kill builds as soon as stdout/stderr is closed. This fixes a
|
||||
bug that allowed builds to hang Nix indefinitely (regardless of
|
||||
timeouts). (21948deed99a3295e4d5666e027a6ca42dc00b40)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Add support for passing structured data to builders. TODO:
|
||||
document. (6de33a9c675b187437a2e1abbcb290981a89ecb1)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><varname>exportReferencesGraph</varname>: Export more
|
||||
complete info in JSON
|
||||
format. (c2b0d8749f7e77afc1c4b3e8dd36b7ee9720af4a)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Support for
|
||||
netrc. (e6e74f987f0fa284d220432d426eb965269a97d6,
|
||||
302386f775eea309679654e5ea7c972fb6e7b9af)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Support <uri>s3://</uri> URIs in all places where Nix allows
|
||||
URIs. (9ff9c3f2f80ba4108e9c945bbfda2c64735f987b)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The <option>build-max-jobs</option> option can be set to
|
||||
<literal>auto</literal> to use the number of CPUs in the
|
||||
system. (7251d048fa812d2551b7003bc9f13a8f5d4c95a5)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Add support for Brotli compression.
|
||||
<uri>cache.nixos.org</uri> compresses build logs using
|
||||
Brotli.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Substitutions from binary caches now require signatures by
|
||||
default. This was already the case on
|
||||
NixOS. (ecbc3fedd3d5bdc5a0e1a0a51b29062f2874ac8b)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><command>nix-env</command> now ignores packages with bad
|
||||
derivation names (in particular those starting with a digit or
|
||||
containing a
|
||||
dot). (b0cb11722626e906a73f10dd9a0c9eea29faf43a)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Renamed various configuration options. (TODO: in progress)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Remote machines can now be specified on the command
|
||||
line. TODO:
|
||||
document. (1a68710d4dff609bbaf61db3e17a2573f0aadf17)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>In Linux sandbox builds, we now use
|
||||
<filename>/build</filename> instead of <filename>/tmp</filename>
|
||||
as the temporary build directory. This fixes potential security
|
||||
problems when a build accidentally stores its
|
||||
<envar>TMPDIR</envar> in some critical place, such as an
|
||||
RPATH. (eba840c8a13b465ace90172ff76a0db2899ab11b)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>In Linux sandbox builds, we now provide a default
|
||||
<filename>/bin/sh</filename> (namely <filename>ash</filename> from
|
||||
BusyBox). (a2d92bb20e82a0957067ede60e91fab256948b41)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Make all configuration options available as command line
|
||||
flags (b8283773bd64d7da6859ed520ee19867742a03ba).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Support base-64
|
||||
hashes. (c0015e87af70f539f24d2aa2bc224a9d8b84276b)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><command>nix-shell</command> now uses
|
||||
<varname>bashInteractive</varname> from Nixpkgs, rather than the
|
||||
<command>bash</command> command that happens to be in the caller’s
|
||||
<envar>PATH</envar>. This is especially important on macOS where
|
||||
the <command>bash</command> provided by the system is seriously
|
||||
outdated and cannot execute <literal>stdenv</literal>’s setup
|
||||
script.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>New builtin functions: <function>builtins.split</function>
|
||||
(b8867a0239b1930a16f9ef3f7f3e864b01416dff),
|
||||
<function>builtins.partition</function>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Automatic garbage collection.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><command>nix-store -q --roots</command> and
|
||||
<command>nix-store --gc --print-roots</command> now show temporary
|
||||
and in-memory roots.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Builders can now communicate what build phase they are in by
|
||||
writing messages to the file descriptor specified in
|
||||
<envar>NIX_LOG_FD</envar>. (88e6bb76de5564b3217be9688677d1c89101b2a3)
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
<para>Some features were removed:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>“Nested” log output. As a result,
|
||||
<command>nix-log2xml</command> was also removed.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>OpenSSL-based signing. (f435f8247553656774dd1b2c88e9de5d59cab203)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Caching of failed
|
||||
builds. (8cffec84859cec8b610a2a22ab0c4d462a9351ff)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><filename>nix-mode.el</filename> has been removed from
|
||||
Nix. It is now a separate repository in
|
||||
<uri>https://github.com/NixOS/nix-mode</uri> and can be installed
|
||||
through the MELPA package repository.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>In restricted evaluation mode
|
||||
(<option>--restrict-eval</option>), builtin functions that
|
||||
download from the network (such as <function>fetchGit</function>)
|
||||
are permitted to fetch underneath the list of URI prefixes
|
||||
specified in the option <option>allowed-uris</option>.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
<para>This release has contributions from TBD.</para>
|
||||
|
||||
</section>
|
||||
@@ -40,7 +40,7 @@ $ nix-env -i thunderbird --option binary-caches http://cache.nixos.org
|
||||
<para>Binary caches are created using <command>nix-push</command>.
|
||||
For details on the operation and format of binary caches, see the
|
||||
<command>nix-push</command> manpage. More details are provided in
|
||||
<link xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2012-September/009826.html">this
|
||||
<link xlink:href="https://nixos.org/nix-dev/2012-September/009826.html">this
|
||||
nix-dev posting</link>.</para>
|
||||
</listitem>
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ $ nix-store -l $(which xterm)
|
||||
caches).</para></listitem>
|
||||
|
||||
<listitem><para>The configuration option
|
||||
<option>build-max-jobs</option> now defaults to the number of
|
||||
available CPU cores.</para></listitem>
|
||||
<option>build-cores</option> now defaults to the number of available
|
||||
CPU cores.</para></listitem>
|
||||
|
||||
<listitem><para>Build users are now used by default when Nix is
|
||||
invoked as root. This prevents builds from accidentally running as
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
Generate a private key:
|
||||
|
||||
$ (umask 277 && openssl genrsa -out /etc/nix/signing-key.sec 2048)
|
||||
|
||||
The private key should be kept secret (only readable to the Nix daemon
|
||||
user).
|
||||
|
||||
|
||||
Generate the corresponding public key:
|
||||
|
||||
$ openssl rsa -in /etc/nix/signing-key.sec -pubout > /etc/nix/signing-key.pub
|
||||
|
||||
The public key should be copied to all machines to which you want to
|
||||
export store paths.
|
||||
|
||||
|
||||
Signing:
|
||||
|
||||
$ nix-hash --type sha256 --flat svn.nar | openssl rsautl -sign -inkey mykey.sec > svn.nar.sign
|
||||
|
||||
|
||||
Verifying a signature:
|
||||
|
||||
$ test "$(nix-hash --type sha256 --flat svn.nar)" = "$(openssl rsautl -verify -inkey mykey.pub -pubin -in svn.nar.sign)"
|
||||
10
local.mk
10
local.mk
@@ -1,16 +1,14 @@
|
||||
ifeq ($(MAKECMDGOALS), dist)
|
||||
# Make sure we are in repo root with `--git-dir`
|
||||
dist-files += $(shell git --git-dir=.git ls-files || find * -type f)
|
||||
dist-files += $(shell cat .dist-files)
|
||||
endif
|
||||
|
||||
dist-files += configure config.h.in nix.spec
|
||||
dist-files += configure config.h.in nix.spec perl/configure
|
||||
|
||||
clean-files += Makefile.config
|
||||
|
||||
GLOBAL_CXXFLAGS += -I . -I src -I src/libutil -I src/libstore -I src/libmain -I src/libexpr \
|
||||
-Wno-unneeded-internal-declaration
|
||||
GLOBAL_CXXFLAGS += -I . -I src -I src/libutil -I src/libstore -I src/libmain -I src/libexpr
|
||||
|
||||
$(foreach i, config.h $(call rwildcard, src/lib*, *.hh) src/nix-store/serve-protocol.hh, \
|
||||
$(foreach i, config.h $(call rwildcard, src/lib*, *.hh), \
|
||||
$(eval $(call install-file-in, $(i), $(includedir)/nix, 0644)))
|
||||
|
||||
$(foreach i, $(call rwildcard, src/boost, *.hpp), $(eval $(call install-file-in, $(i), $(includedir)/nix/$(patsubst src/%/,%,$(dir $(i))), 0644)))
|
||||
|
||||
155
maintainers/upload-release.pl
Executable file
155
maintainers/upload-release.pl
Executable file
@@ -0,0 +1,155 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i perl -p perl perlPackages.LWPUserAgent perlPackages.LWPProtocolHttps perlPackages.FileSlurp gnupg1
|
||||
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
use File::Basename;
|
||||
use File::Path;
|
||||
use File::Slurp;
|
||||
use JSON::PP;
|
||||
use LWP::UserAgent;
|
||||
|
||||
my $evalId = $ARGV[0] or die "Usage: $0 EVAL-ID\n";
|
||||
|
||||
my $releasesDir = "/home/eelco/mnt/releases";
|
||||
my $nixpkgsDir = "/home/eelco/Dev/nixpkgs-pristine";
|
||||
|
||||
# FIXME: cut&paste from nixos-channel-scripts.
|
||||
sub fetch {
|
||||
my ($url, $type) = @_;
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->default_header('Accept', $type) if defined $type;
|
||||
|
||||
my $response = $ua->get($url);
|
||||
die "could not download $url: ", $response->status_line, "\n" unless $response->is_success;
|
||||
|
||||
return $response->decoded_content;
|
||||
}
|
||||
|
||||
my $evalUrl = "https://hydra.nixos.org/eval/$evalId";
|
||||
my $evalInfo = decode_json(fetch($evalUrl, 'application/json'));
|
||||
#print Dumper($evalInfo);
|
||||
|
||||
my $nixRev = $evalInfo->{jobsetevalinputs}->{nix}->{revision} or die;
|
||||
|
||||
my $tarballInfo = decode_json(fetch("$evalUrl/job/tarball", 'application/json'));
|
||||
|
||||
my $releaseName = $tarballInfo->{releasename};
|
||||
$releaseName =~ /nix-(.*)$/ or die;
|
||||
my $version = $1;
|
||||
|
||||
print STDERR "Nix revision is $nixRev, version is $version\n";
|
||||
|
||||
File::Path::make_path($releasesDir);
|
||||
if (system("mountpoint -q $releasesDir") != 0) {
|
||||
system("sshfs hydra-mirror:/releases $releasesDir") == 0 or die;
|
||||
}
|
||||
|
||||
my $releaseDir = "$releasesDir/nix/$releaseName";
|
||||
File::Path::make_path($releaseDir);
|
||||
|
||||
sub downloadFile {
|
||||
my ($jobName, $productNr, $dstName) = @_;
|
||||
|
||||
my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
|
||||
|
||||
my $srcFile = $buildInfo->{buildproducts}->{$productNr}->{path} or die;
|
||||
$dstName //= basename($srcFile);
|
||||
my $dstFile = "$releaseDir/" . $dstName;
|
||||
|
||||
if (! -e $dstFile) {
|
||||
print STDERR "downloading $srcFile to $dstFile...\n";
|
||||
system("NIX_REMOTE=https://cache.nixos.org/ nix cat-store '$srcFile' > '$dstFile.tmp'") == 0
|
||||
or die "unable to fetch $srcFile\n";
|
||||
rename("$dstFile.tmp", $dstFile) or die;
|
||||
}
|
||||
|
||||
my $sha256_expected = $buildInfo->{buildproducts}->{$productNr}->{sha256hash} or die;
|
||||
my $sha256_actual = `nix hash-file --type sha256 '$dstFile'`;
|
||||
chomp $sha256_actual;
|
||||
if ($sha256_expected ne $sha256_actual) {
|
||||
print STDERR "file $dstFile is corrupt\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
write_file("$dstFile.sha256", $sha256_expected);
|
||||
|
||||
return ($dstFile, $sha256_expected);
|
||||
}
|
||||
|
||||
downloadFile("tarball", "2"); # PDF
|
||||
downloadFile("tarball", "3"); # .tar.bz2
|
||||
my ($tarball, $tarballHash) = downloadFile("tarball", "4"); # .tar.xz
|
||||
my ($tarball_i686_linux, $tarball_i686_linux_hash) = downloadFile("binaryTarball.i686-linux", "1");
|
||||
my ($tarball_x86_64_linux, $tarball_x86_64_linux_hash) = downloadFile("binaryTarball.x86_64-linux", "1");
|
||||
my ($tarball_aarch64_linux, $tarball_aarch64_linux_hash) = downloadFile("binaryTarball.aarch64-linux", "1");
|
||||
my ($tarball_x86_64_darwin, $tarball_x86_64_darwin_hash) = downloadFile("binaryTarball.x86_64-darwin", "1");
|
||||
|
||||
# Update Nixpkgs in a very hacky way.
|
||||
system("cd $nixpkgsDir && git pull") == 0 or die;
|
||||
my $oldName = `nix-instantiate --eval $nixpkgsDir -A nix.name`; chomp $oldName;
|
||||
my $oldHash = `nix-instantiate --eval $nixpkgsDir -A nix.src.outputHash`; chomp $oldHash;
|
||||
print STDERR "old stable version in Nixpkgs = $oldName / $oldHash\n";
|
||||
|
||||
my $fn = "$nixpkgsDir/pkgs/tools/package-management/nix/default.nix";
|
||||
my $oldFile = read_file($fn);
|
||||
$oldFile =~ s/$oldName/"$releaseName"/g;
|
||||
$oldFile =~ s/$oldHash/"$tarballHash"/g;
|
||||
write_file($fn, $oldFile);
|
||||
|
||||
$oldName =~ s/nix-//g;
|
||||
$oldName =~ s/"//g;
|
||||
|
||||
sub getStorePath {
|
||||
my ($jobName) = @_;
|
||||
my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
|
||||
die unless $buildInfo->{buildproducts}->{1}->{type} eq "nix-build";
|
||||
return $buildInfo->{buildproducts}->{1}->{path};
|
||||
}
|
||||
|
||||
write_file("$nixpkgsDir/nixos/modules/installer/tools/nix-fallback-paths.nix",
|
||||
"{\n" .
|
||||
" x86_64-linux = \"" . getStorePath("build.x86_64-linux") . "\";\n" .
|
||||
" i686-linux = \"" . getStorePath("build.i686-linux") . "\";\n" .
|
||||
" aarch64-linux = \"" . getStorePath("build.aarch64-linux") . "\";\n" .
|
||||
" x86_64-darwin = \"" . getStorePath("build.x86_64-darwin") . "\";\n" .
|
||||
"}\n");
|
||||
|
||||
system("cd $nixpkgsDir && git commit -a -m 'nix: $oldName -> $version'") == 0 or die;
|
||||
|
||||
# Extract the HTML manual.
|
||||
File::Path::make_path("$releaseDir/manual");
|
||||
|
||||
system("tar xvf $tarball --strip-components=3 -C $releaseDir/manual --wildcards '*/doc/manual/*.html' '*/doc/manual/*.css' '*/doc/manual/*.gif' '*/doc/manual/*.png'") == 0 or die;
|
||||
|
||||
if (! -e "$releaseDir/manual/index.html") {
|
||||
symlink("manual.html", "$releaseDir/manual/index.html") or die;
|
||||
}
|
||||
|
||||
# Update the "latest" symlink.
|
||||
symlink("$releaseName", "$releasesDir/nix/latest-tmp") or die;
|
||||
rename("$releasesDir/nix/latest-tmp", "$releasesDir/nix/latest") or die;
|
||||
|
||||
# Tag the release in Git.
|
||||
chdir("/home/eelco/Dev/nix-pristine") or die;
|
||||
system("git remote update origin") == 0 or die;
|
||||
system("git tag --force --sign $version $nixRev -m 'Tagging release $version'") == 0 or die;
|
||||
|
||||
# Update the website.
|
||||
my $siteDir = "/home/eelco/Dev/nixos-homepage-pristine";
|
||||
|
||||
system("cd $siteDir && git pull") == 0 or die;
|
||||
|
||||
write_file("$siteDir/nix-release.tt",
|
||||
"[%-\n" .
|
||||
"latestNixVersion = \"$version\"\n" .
|
||||
"nix_hash_i686_linux = \"$tarball_i686_linux_hash\"\n" .
|
||||
"nix_hash_x86_64_linux = \"$tarball_x86_64_linux_hash\"\n" .
|
||||
"nix_hash_aarch64_linux = \"$tarball_aarch64_linux_hash\"\n" .
|
||||
"nix_hash_x86_64_darwin = \"$tarball_x86_64_darwin_hash\"\n" .
|
||||
"-%]\n");
|
||||
|
||||
system("cd $siteDir && nix-shell --run 'make nix/install nix/install.sig'") == 0 or die;
|
||||
|
||||
system("cd $siteDir && git commit -a -m 'Nix $version released'") == 0 or die;
|
||||
@@ -1,23 +1,26 @@
|
||||
FROM busybox
|
||||
FROM alpine
|
||||
|
||||
RUN set -x \
|
||||
&& wget -O- http://nixos.org/releases/nix/nix-1.9/nix-1.9-x86_64-linux.tar.bz2 | \
|
||||
bzcat - | tar xf - \
|
||||
&& echo "nixbld:x:30000:nixbld1,nixbld10,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9" >> /etc/group \
|
||||
&& for i in $(seq 1 9); do echo "nixbld$i:x:3000$i:30000:::" >> /etc/passwd; done \
|
||||
&& sed -i 's/\$HOME\/\.nix-profile\/etc\/ssl\/certs\/ca-bundle\.crt/\$HOME\/\.nix-profile\/etc\/ca-bundle\.crt/g' nix-1.9-x86_64-linux/install \
|
||||
&& mkdir -m 0755 /nix && USER=root sh nix-1.9-x86_64-linux/install \
|
||||
&& echo ". /root/.nix-profile/etc/profile.d/nix.sh" >> /etc/profile \
|
||||
&& rm -r /nix-1.9-x86_64-linux
|
||||
# Enable HTTPS support in wget.
|
||||
RUN apk add --update openssl
|
||||
|
||||
# Download Nix and install it into the system.
|
||||
RUN wget -O- https://nixos.org/releases/nix/nix-1.11.14/nix-1.11.14-x86_64-linux.tar.bz2 | bzcat - | tar xf - \
|
||||
&& addgroup -g 30000 -S nixbld \
|
||||
&& for i in $(seq 1 30); do adduser -S -D -h /var/empty -g "Nix build user $i" -u $((30000 + i)) -G nixbld nixbld$i ; done \
|
||||
&& mkdir -m 0755 /nix && USER=root sh nix-*-x86_64-linux/install \
|
||||
&& ln -s /nix/var/nix/profiles/default/etc/profile.d/nix.sh /etc/profile.d/ \
|
||||
&& rm -r /nix-*-x86_64-linux \
|
||||
&& rm -r /var/cache/apk/*
|
||||
|
||||
ONBUILD ENV \
|
||||
ENV=/etc/profile \
|
||||
PATH=/root/.nix-profile/bin:/root/.nix-profile/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
|
||||
GIT_SSL_CAINFO=/root/.nix-profile/etc/ca-bundle.crt \
|
||||
SSL_CERT_FILE=/root/.nix-profile/etc/ca-bundle.crt
|
||||
PATH=/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
|
||||
GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt \
|
||||
NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt
|
||||
|
||||
ENV \
|
||||
ENV=/etc/profile \
|
||||
PATH=/root/.nix-profile/bin:/root/.nix-profile/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
|
||||
GIT_SSL_CAINFO=/root/.nix-profile/etc/ca-bundle.crt \
|
||||
SSL_CERT_FILE=/root/.nix-profile/etc/ca-bundle.crt
|
||||
PATH=/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
|
||||
GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt \
|
||||
NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt \
|
||||
NIX_PATH=/nix/var/nix/profiles/per-user/root/channels
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
The Nix Emacs mode supports syntax highlighting, somewhat sensible
|
||||
indenting, and refilling of comments.
|
||||
|
||||
To enable Nix mode in Emacs, add something like this to your ~/.emacs
|
||||
file:
|
||||
|
||||
(load "/nix/share/emacs/site-lisp/nix-mode.el")
|
||||
|
||||
This automatically causes Nix mode to be activated for all files with
|
||||
extension `.nix'.
|
||||
@@ -1 +0,0 @@
|
||||
$(eval $(call install-data-in,$(d)/nix-mode.el,$(datadir)/emacs/site-lisp))
|
||||
@@ -1,95 +0,0 @@
|
||||
;;; nix-mode.el --- Major mode for editing Nix expressions
|
||||
|
||||
;; Author: Eelco Dolstra
|
||||
;; URL: https://github.com/NixOS/nix/tree/master/misc/emacs
|
||||
;; Version: 1.0
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defconst nix-font-lock-keywords
|
||||
'("\\_<if\\_>" "\\_<then\\_>" "\\_<else\\_>" "\\_<assert\\_>" "\\_<with\\_>"
|
||||
"\\_<let\\_>" "\\_<in\\_>" "\\_<rec\\_>" "\\_<inherit\\_>" "\\_<or\\_>"
|
||||
("\\_<true\\_>" . font-lock-builtin-face)
|
||||
("\\_<false\\_>" . font-lock-builtin-face)
|
||||
("\\_<null\\_>" . font-lock-builtin-face)
|
||||
("\\_<import\\_>" . font-lock-builtin-face)
|
||||
("\\_<derivation\\_>" . font-lock-builtin-face)
|
||||
("\\_<baseNameOf\\_>" . font-lock-builtin-face)
|
||||
("\\_<toString\\_>" . font-lock-builtin-face)
|
||||
("\\_<isNull\\_>" . font-lock-builtin-face)
|
||||
("[a-zA-Z][a-zA-Z0-9\\+-\\.]*:[a-zA-Z0-9%/\\?:@&=\\+\\$,_\\.!~\\*'-]+"
|
||||
. font-lock-constant-face)
|
||||
("\\<\\([a-zA-Z_][a-zA-Z0-9_'\-\.]*\\)[ \t]*="
|
||||
(1 font-lock-variable-name-face nil nil))
|
||||
("<[a-zA-Z0-9._\\+-]+\\(/[a-zA-Z0-9._\\+-]+\\)*>"
|
||||
. font-lock-constant-face)
|
||||
("[a-zA-Z0-9._\\+-]*\\(/[a-zA-Z0-9._\\+-]+\\)+"
|
||||
. font-lock-constant-face))
|
||||
"Font lock keywords for nix.")
|
||||
|
||||
(defvar nix-mode-syntax-table
|
||||
(let ((table (make-syntax-table)))
|
||||
(modify-syntax-entry ?/ ". 14" table)
|
||||
(modify-syntax-entry ?* ". 23" table)
|
||||
(modify-syntax-entry ?# "< b" table)
|
||||
(modify-syntax-entry ?\n "> b" table)
|
||||
table)
|
||||
"Syntax table for Nix mode.")
|
||||
|
||||
(defun nix-indent-line ()
|
||||
"Indent current line in a Nix expression."
|
||||
(interactive)
|
||||
(indent-relative-maybe))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode nix-mode prog-mode "Nix"
|
||||
"Major mode for editing Nix expressions.
|
||||
|
||||
The following commands may be useful:
|
||||
|
||||
'\\[newline-and-indent]'
|
||||
Insert a newline and move the cursor to align with the previous
|
||||
non-empty line.
|
||||
|
||||
'\\[fill-paragraph]'
|
||||
Refill a paragraph so that all lines are at most `fill-column'
|
||||
lines long. This should do the right thing for comments beginning
|
||||
with `#'. However, this command doesn't work properly yet if the
|
||||
comment is adjacent to code (i.e., no intervening empty lines).
|
||||
In that case, select the text to be refilled and use
|
||||
`\\[fill-region]' instead.
|
||||
|
||||
The hook `nix-mode-hook' is run when Nix mode is started.
|
||||
|
||||
\\{nix-mode-map}
|
||||
"
|
||||
(set-syntax-table nix-mode-syntax-table)
|
||||
|
||||
;; Font lock support.
|
||||
(setq font-lock-defaults '(nix-font-lock-keywords nil nil nil nil))
|
||||
|
||||
;; Automatic indentation [C-j].
|
||||
(set (make-local-variable 'indent-line-function) 'nix-indent-line)
|
||||
|
||||
;; Indenting of comments.
|
||||
(set (make-local-variable 'comment-start) "# ")
|
||||
(set (make-local-variable 'comment-end) "")
|
||||
(set (make-local-variable 'comment-start-skip) "\\(^\\|\\s-\\);?#+ *")
|
||||
|
||||
;; Filling of comments.
|
||||
(set (make-local-variable 'adaptive-fill-mode) t)
|
||||
(set (make-local-variable 'paragraph-start) "[ \t]*\\(#+[ \t]*\\)?$")
|
||||
(set (make-local-variable 'paragraph-separate) paragraph-start))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(progn
|
||||
(add-to-list 'auto-mode-alist '("\\.nix\\'" . nix-mode))
|
||||
(add-to-list 'auto-mode-alist '("\\.nix.in\\'" . nix-mode)))
|
||||
|
||||
(provide 'nix-mode)
|
||||
|
||||
;;; nix-mode.el ends here
|
||||
113
misc/systemv/nix-daemon
Executable file
113
misc/systemv/nix-daemon
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# nix-daemon: Starts the nix package manager daemon
|
||||
#
|
||||
# chkconfig: 345 24 02
|
||||
# description: This is a daemon which enable the multi-user mode
|
||||
# of the nix package manager.
|
||||
# processname: nix-daemon
|
||||
# pidfile: /var/run/nix/nix-daemon.pid
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: 3 4 5
|
||||
# Default-Stop: 0 1 2 6
|
||||
# Short-Description: Starts the nix daemon
|
||||
# Description: This is a daemon which enable the multi-user mode
|
||||
# of the nix package manager.
|
||||
### END INIT INFO
|
||||
|
||||
NIX_DAEMON_BIN=/usr/bin/nix-daemon
|
||||
#NIX_DAEMON_USER="root"
|
||||
NIX_DAEMON_USER="nix-daemon"
|
||||
NIX_DAEMON_OPTS="--daemon"
|
||||
|
||||
umask 0022
|
||||
|
||||
if [ "$1" = 'status' ]; then
|
||||
test -x $NIX_DAEMON_BIN || exit 4
|
||||
else
|
||||
test -x $NIX_DAEMON_BIN || exit 5
|
||||
fi
|
||||
|
||||
# Source function library.
|
||||
. /etc/init.d/functions
|
||||
|
||||
LOCKFILE=/var/lock/subsys/nix-daemon
|
||||
RUNDIR=/var/run/nix
|
||||
PIDFILE=${RUNDIR}/nix-daemon.pid
|
||||
RETVAL=0
|
||||
|
||||
base=${0##*/}
|
||||
|
||||
start() {
|
||||
|
||||
mkdir -p ${RUNDIR}
|
||||
chown ${NIX_DAEMON_USER}:${NIX_DAEMON_USER} ${RUNDIR}
|
||||
|
||||
echo -n $"Starting nix daemon... "
|
||||
|
||||
daemonize -u $NIX_DAEMON_USER -p ${PIDFILE} $NIX_DAEMON_BIN $NIX_DAEMON_OPTS
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && touch ${LOCKFILE}
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n $"Shutting down nix daemon: "
|
||||
killproc -p ${PIDFILE} $NIX_DAEMON_BIN
|
||||
RETVAL=$?
|
||||
[ $RETVAL -eq 0 ] && rm -f ${LOCKFILE} ${PIDFILE}
|
||||
echo
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
reload() {
|
||||
echo -n $"Reloading nix daemon... "
|
||||
killproc -p ${PIDFILE} $NIX_DAEMON_BIN -HUP
|
||||
RETVAL=$?
|
||||
echo
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
RETVAL=0
|
||||
|
||||
# caller switch
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
status)
|
||||
status -p ${PIDFILE} $NIX_DAEMON_BIN
|
||||
RETVAL=$?
|
||||
;;
|
||||
restart)
|
||||
restart
|
||||
;;
|
||||
reload)
|
||||
reload
|
||||
;;
|
||||
condrestart)
|
||||
if [ -f $LOCKFILE ]; then
|
||||
restart
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|status|restart|condrestart}"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
||||
@@ -53,8 +53,8 @@ BUILD_SHARED_LIBS ?= 1
|
||||
|
||||
ifeq ($(BUILD_SHARED_LIBS), 1)
|
||||
ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
|
||||
GLOBAL_CFLAGS += -U__STRICT_ANSI__
|
||||
GLOBAL_CXXFLAGS += -U__STRICT_ANSI__
|
||||
GLOBAL_CFLAGS += -U__STRICT_ANSI__ -D_GNU_SOURCE
|
||||
GLOBAL_CXXFLAGS += -U__STRICT_ANSI__ -D_GNU_SOURCE
|
||||
else
|
||||
GLOBAL_CFLAGS += -fPIC
|
||||
GLOBAL_CXXFLAGS += -fPIC
|
||||
|
||||
31
mk/tests.mk
31
mk/tests.mk
@@ -7,20 +7,39 @@ define run-install-test
|
||||
|
||||
endef
|
||||
|
||||
# Color code from https://unix.stackexchange.com/a/10065
|
||||
installcheck:
|
||||
@total=0; failed=0; for i in $(_installcheck-list); do \
|
||||
@total=0; failed=0; \
|
||||
red=""; \
|
||||
green=""; \
|
||||
yellow=""; \
|
||||
normal=""; \
|
||||
if [ -t 1 ]; then \
|
||||
red="[31;1m"; \
|
||||
green="[32;1m"; \
|
||||
yellow="[33;1m"; \
|
||||
normal="[m"; \
|
||||
fi; \
|
||||
for i in $(_installcheck-list); do \
|
||||
total=$$((total + 1)); \
|
||||
echo "running test $$i"; \
|
||||
if (cd $$(dirname $$i) && $(tests-environment) $$(basename $$i)); then \
|
||||
echo "PASS: $$i"; \
|
||||
printf "running test $$i..."; \
|
||||
log="$$(cd $$(dirname $$i) && $(tests-environment) $$(basename $$i) 2>&1)"; \
|
||||
status=$$?; \
|
||||
if [ $$status -eq 0 ]; then \
|
||||
echo " [$${green}PASS$$normal]"; \
|
||||
elif [ $$status -eq 99 ]; then \
|
||||
echo " [$${yellow}SKIP$$normal]"; \
|
||||
else \
|
||||
echo "FAIL: $$i"; \
|
||||
echo " [$${red}FAIL$$normal]"; \
|
||||
echo "$$log" | sed 's/^/ /'; \
|
||||
failed=$$((failed + 1)); \
|
||||
fi; \
|
||||
done; \
|
||||
if [ "$$failed" != 0 ]; then \
|
||||
echo "$$failed out of $$total tests failed "; \
|
||||
echo "$${red}$$failed out of $$total tests failed $$normal"; \
|
||||
exit 1; \
|
||||
else \
|
||||
echo "$${green}All tests succeeded"; \
|
||||
fi
|
||||
|
||||
.PHONY: check installcheck
|
||||
|
||||
78
nix.spec.in
78
nix.spec.in
@@ -1,12 +1,14 @@
|
||||
%undefine _hardened_build
|
||||
|
||||
%global nixbld_user "nix-builder-"
|
||||
%global nixbld_group "nix-builders"
|
||||
%global nixbld_group "nixbld"
|
||||
|
||||
Summary: The Nix software deployment system
|
||||
Name: nix
|
||||
Version: @PACKAGE_VERSION@
|
||||
Release: 2%{?dist}
|
||||
License: LGPLv2+
|
||||
%if 0%{?rhel}
|
||||
%if 0%{?rhel} && 0%{?rhel} < 7
|
||||
Group: Applications/System
|
||||
%endif
|
||||
URL: http://nixos.org/
|
||||
@@ -14,19 +16,15 @@ Source0: %{name}-%{version}.tar.bz2
|
||||
%if 0%{?el5}
|
||||
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
%endif
|
||||
BuildRequires: perl(DBD::SQLite)
|
||||
BuildRequires: perl(DBI)
|
||||
BuildRequires: perl(WWW::Curl)
|
||||
BuildRequires: perl(ExtUtils::ParseXS)
|
||||
Requires: /usr/bin/perl
|
||||
Requires: curl
|
||||
Requires: perl-DBD-SQLite
|
||||
Requires: bzip2
|
||||
Requires: gzip
|
||||
Requires: xz
|
||||
Requires: libseccomp
|
||||
BuildRequires: bzip2-devel
|
||||
BuildRequires: sqlite-devel
|
||||
BuildRequires: libcurl-devel
|
||||
BuildRequires: libseccomp-devel
|
||||
|
||||
# Hack to make that shitty RPM scanning hack shut up.
|
||||
Provides: perl(Nix::SSH)
|
||||
@@ -41,7 +39,7 @@ it can be used equally well under other Unix systems.
|
||||
|
||||
%package devel
|
||||
Summary: Development files for %{name}
|
||||
%if 0%{?rhel}
|
||||
%if 0%{?rhel} && 0%{?rhel} < 7
|
||||
Group: Development/Libraries
|
||||
%endif
|
||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||
@@ -53,7 +51,7 @@ developing applications that use %{name}.
|
||||
|
||||
%package doc
|
||||
Summary: Documentation files for %{name}
|
||||
%if 0%{?rhel}
|
||||
%if 0%{?rhel} && 0%{?rhel} < 7
|
||||
Group: Documentation
|
||||
%endif
|
||||
BuildArch: noarch
|
||||
@@ -62,40 +60,8 @@ Requires: %{name} = %{version}-%{release}
|
||||
%description doc
|
||||
The %{name}-doc package contains documentation files for %{name}.
|
||||
|
||||
|
||||
%package -n emacs-%{name}
|
||||
Summary: Nix mode for Emacs
|
||||
%if 0%{?rhel}
|
||||
Group: Applications/Editors
|
||||
%endif
|
||||
BuildArch: noarch
|
||||
BuildRequires: emacs
|
||||
Requires: emacs(bin) >= %{_emacs_version}
|
||||
|
||||
%description -n emacs-%{name}
|
||||
This package provides a major mode for editing Nix expressions.
|
||||
|
||||
%package -n emacs-%{name}-el
|
||||
Summary: Elisp source files for emacs-%{name}
|
||||
%if 0%{?rhel}
|
||||
Group: Applications/Editors
|
||||
%endif
|
||||
BuildArch: noarch
|
||||
Requires: emacs-%{name} = %{version}-%{release}
|
||||
|
||||
%description -n emacs-%{name}-el
|
||||
This package contains the elisp source file for the Nix major mode for
|
||||
GNU Emacs. You do not need to install this package to run Nix. Install
|
||||
the emacs-%{name} package to edit Nix expressions with GNU Emacs.
|
||||
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
# Install Perl modules to vendor_perl
|
||||
# configure.ac need to be changed to make this global; however, this will
|
||||
# also affect NixOS. Use discretion.
|
||||
%{__sed} -i 's|perl5/site_perl/$perlversion/$perlarchname|perl5/vendor_perl|' \
|
||||
configure
|
||||
|
||||
|
||||
%build
|
||||
@@ -106,8 +72,7 @@ extraFlags=
|
||||
%configure --localstatedir=/nix/var \
|
||||
--docdir=%{_defaultdocdir}/%{name}-doc-%{version} \
|
||||
$extraFlags
|
||||
make %{?_smp_flags}
|
||||
%{_emacs_bytecompile} misc/emacs/nix-mode.el
|
||||
make -j$NIX_BUILD_CORES -l$NIX_BUILD_CORES
|
||||
|
||||
|
||||
%install
|
||||
@@ -118,6 +83,10 @@ make DESTDIR=$RPM_BUILD_ROOT install
|
||||
|
||||
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
|
||||
|
||||
# make the store
|
||||
mkdir -p $RPM_BUILD_ROOT/nix/store
|
||||
chmod 1775 $RPM_BUILD_ROOT/nix/store
|
||||
|
||||
# make per-user directories
|
||||
for d in profiles gcroots;
|
||||
do
|
||||
@@ -129,9 +98,6 @@ done
|
||||
# (until this is fixed in the relevant Makefile)
|
||||
chmod -x $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/nix.sh
|
||||
|
||||
# Copy the byte-compiled mode file by hand
|
||||
cp -p misc/emacs/nix-mode.elc $RPM_BUILD_ROOT%{_emacs_sitelispdir}/
|
||||
|
||||
# we ship this file in the base package
|
||||
rm -f $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}-doc-%{version}/README
|
||||
|
||||
@@ -155,29 +121,26 @@ done
|
||||
|
||||
%post
|
||||
chgrp %{nixbld_group} /nix/store
|
||||
chmod 1775 /nix/store
|
||||
%if ! 0%{?rhel}
|
||||
%if ! 0%{?rhel} || 0%{?rhel} >= 7
|
||||
# Enable and start Nix worker
|
||||
systemctl enable nix-daemon.socket nix-daemon.service
|
||||
systemctl start nix-daemon.socket
|
||||
%endif
|
||||
|
||||
%files
|
||||
%{_bindir}/nix-*
|
||||
%{_bindir}/nix*
|
||||
%{_libdir}/*.so
|
||||
%{perl_vendorarch}/*
|
||||
%exclude %dir %{perl_vendorarch}/auto/
|
||||
%{_prefix}/libexec/*
|
||||
%if ! 0%{?rhel}
|
||||
%if ! 0%{?rhel} || 0%{?rhel} >= 7
|
||||
%{_prefix}/lib/systemd/system/nix-daemon.socket
|
||||
%{_prefix}/lib/systemd/system/nix-daemon.service
|
||||
%endif
|
||||
%{_datadir}/emacs/site-lisp/nix-mode.el
|
||||
%{_datadir}/nix
|
||||
%{_mandir}/man1/*.1*
|
||||
%{_mandir}/man5/*.5*
|
||||
%{_mandir}/man8/*.8*
|
||||
%config(noreplace) %{_sysconfdir}/profile.d/nix.sh
|
||||
%config(noreplace) %{_sysconfdir}/profile.d/nix-daemon.sh
|
||||
/nix
|
||||
|
||||
%files devel
|
||||
@@ -187,10 +150,3 @@ systemctl start nix-daemon.socket
|
||||
%files doc
|
||||
%docdir %{_defaultdocdir}/%{name}-doc-%{version}
|
||||
%{_defaultdocdir}/%{name}-doc-%{version}
|
||||
|
||||
%files -n emacs-%{name}
|
||||
%{_emacs_sitelispdir}/*.elc
|
||||
#{_emacs_sitestartdir}/*.el
|
||||
|
||||
%files -n emacs-%{name}-el
|
||||
%{_emacs_sitelispdir}/*.el
|
||||
|
||||
14
perl/Makefile
Normal file
14
perl/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
makefiles = local.mk
|
||||
|
||||
GLOBAL_CXXFLAGS += -std=c++14 -g -Wall
|
||||
|
||||
-include Makefile.config
|
||||
|
||||
OPTIMIZE = 1
|
||||
|
||||
ifeq ($(OPTIMIZE), 1)
|
||||
GLOBAL_CFLAGS += -O3
|
||||
GLOBAL_CXXFLAGS += -O3
|
||||
endif
|
||||
|
||||
include mk/lib.mk
|
||||
18
perl/Makefile.config.in
Normal file
18
perl/Makefile.config.in
Normal file
@@ -0,0 +1,18 @@
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
HAVE_SODIUM = @HAVE_SODIUM@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
SODIUM_LIBS = @SODIUM_LIBS@
|
||||
NIX_CFLAGS = @NIX_CFLAGS@
|
||||
NIX_LIBS = @NIX_LIBS@
|
||||
nixbindir = @nixbindir@
|
||||
curl = @curl@
|
||||
nixlibexecdir = @nixlibexecdir@
|
||||
nixlocalstatedir = @nixlocalstatedir@
|
||||
perl = @perl@
|
||||
perllibdir = @perllibdir@
|
||||
nixstoredir = @nixstoredir@
|
||||
nixsysconfdir = @nixsysconfdir@
|
||||
99
perl/configure.ac
Normal file
99
perl/configure.ac
Normal file
@@ -0,0 +1,99 @@
|
||||
AC_INIT(nix-perl, m4_esyscmd([bash -c "echo -n $(cat ../version)$VERSION_SUFFIX"]))
|
||||
AC_CONFIG_SRCDIR(MANIFEST)
|
||||
AC_CONFIG_AUX_DIR(../config)
|
||||
|
||||
CFLAGS=
|
||||
CXXFLAGS=
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AX_CXX_COMPILE_STDCXX_11
|
||||
|
||||
# Use 64-bit file system calls so that we can support files > 2 GiB.
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
AC_DEFUN([NEED_PROG],
|
||||
[
|
||||
AC_PATH_PROG($1, $2)
|
||||
if test -z "$$1"; then
|
||||
AC_MSG_ERROR([$2 is required])
|
||||
fi
|
||||
])
|
||||
|
||||
NEED_PROG(perl, perl)
|
||||
NEED_PROG(curl, curl)
|
||||
NEED_PROG(bzip2, bzip2)
|
||||
NEED_PROG(xz, xz)
|
||||
|
||||
# Test that Perl has the open/fork feature (Perl 5.8.0 and beyond).
|
||||
AC_MSG_CHECKING([whether Perl is recent enough])
|
||||
if ! $perl -e 'open(FOO, "-|", "true"); while (<FOO>) { print; }; close FOO or die;'; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([Your Perl version is too old. Nix requires Perl 5.8.0 or newer.])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
|
||||
# Figure out where to install Perl modules.
|
||||
AC_MSG_CHECKING([for the Perl installation prefix])
|
||||
perlversion=$($perl -e 'use Config; print $Config{version};')
|
||||
perlarchname=$($perl -e 'use Config; print $Config{archname};')
|
||||
AC_SUBST(perllibdir, [${libdir}/perl5/site_perl/$perlversion/$perlarchname])
|
||||
AC_MSG_RESULT($perllibdir)
|
||||
|
||||
# Look for libsodium, an optional dependency.
|
||||
PKG_CHECK_MODULES([SODIUM], [libsodium],
|
||||
[AC_DEFINE([HAVE_SODIUM], [1], [Whether to use libsodium for cryptography.])
|
||||
CXXFLAGS="$SODIUM_CFLAGS $CXXFLAGS"
|
||||
have_sodium=1], [have_sodium=])
|
||||
AC_SUBST(HAVE_SODIUM, [$have_sodium])
|
||||
|
||||
# Check for the required Perl dependencies (DBI and DBD::SQLite).
|
||||
perlFlags="-I$perllibdir"
|
||||
|
||||
AC_ARG_WITH(dbi, AC_HELP_STRING([--with-dbi=PATH],
|
||||
[prefix of the Perl DBI library]),
|
||||
perlFlags="$perlFlags -I$withval")
|
||||
|
||||
AC_ARG_WITH(dbd-sqlite, AC_HELP_STRING([--with-dbd-sqlite=PATH],
|
||||
[prefix of the Perl DBD::SQLite library]),
|
||||
perlFlags="$perlFlags -I$withval")
|
||||
|
||||
AC_MSG_CHECKING([whether DBD::SQLite works])
|
||||
if ! $perl $perlFlags -e 'use DBI; use DBD::SQLite;' 2>&5; then
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_FAILURE([The Perl modules DBI and/or DBD::SQLite are missing.])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
AC_SUBST(perlFlags)
|
||||
|
||||
PKG_CHECK_MODULES([NIX], [nix-store])
|
||||
|
||||
NEED_PROG([NIX_INSTANTIATE_PROGRAM], [nix-instantiate])
|
||||
|
||||
# Get nix configure values
|
||||
nixbindir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixBinDir | tr -d \")
|
||||
nixlibexecdir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixLibexecDir | tr -d \")
|
||||
nixlocalstatedir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixLocalstateDir | tr -d \")
|
||||
nixsysconfdir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixSysconfDir | tr -d \")
|
||||
nixstoredir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixStoreDir | tr -d \")
|
||||
AC_SUBST(nixbindir)
|
||||
AC_SUBST(nixlibexecdir)
|
||||
AC_SUBST(nixlocalstatedir)
|
||||
AC_SUBST(nixsysconfdir)
|
||||
AC_SUBST(nixstoredir)
|
||||
|
||||
# Expand all variables in config.status.
|
||||
test "$prefix" = NONE && prefix=$ac_default_prefix
|
||||
test "$exec_prefix" = NONE && exec_prefix='${prefix}'
|
||||
for name in $ac_subst_vars; do
|
||||
declare $name="$(eval echo "${!name}")"
|
||||
declare $name="$(eval echo "${!name}")"
|
||||
declare $name="$(eval echo "${!name}")"
|
||||
done
|
||||
|
||||
rm -f Makefile.config
|
||||
ln -sfn ../mk mk
|
||||
|
||||
AC_CONFIG_FILES([])
|
||||
AC_OUTPUT
|
||||
@@ -4,50 +4,31 @@ use MIME::Base64;
|
||||
|
||||
$version = "@PACKAGE_VERSION@";
|
||||
|
||||
$binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
|
||||
$libexecDir = $ENV{"NIX_LIBEXEC_DIR"} || "@libexecdir@";
|
||||
$stateDir = $ENV{"NIX_STATE_DIR"} || "@localstatedir@/nix";
|
||||
$manifestDir = $ENV{"NIX_MANIFESTS_DIR"} || "@localstatedir@/nix/manifests";
|
||||
$logDir = $ENV{"NIX_LOG_DIR"} || "@localstatedir@/log/nix";
|
||||
$confDir = $ENV{"NIX_CONF_DIR"} || "@sysconfdir@/nix";
|
||||
$storeDir = $ENV{"NIX_STORE_DIR"} || "@storedir@";
|
||||
$binDir = $ENV{"NIX_BIN_DIR"} || "@nixbindir@";
|
||||
$libexecDir = $ENV{"NIX_LIBEXEC_DIR"} || "@nixlibexecdir@";
|
||||
$stateDir = $ENV{"NIX_STATE_DIR"} || "@nixlocalstatedir@/nix";
|
||||
$logDir = $ENV{"NIX_LOG_DIR"} || "@nixlocalstatedir@/log/nix";
|
||||
$confDir = $ENV{"NIX_CONF_DIR"} || "@nixsysconfdir@/nix";
|
||||
$storeDir = $ENV{"NIX_STORE_DIR"} || "@nixstoredir@";
|
||||
|
||||
$bzip2 = "@bzip2@";
|
||||
$xz = "@xz@";
|
||||
$curl = "@curl@";
|
||||
$openssl = "@openssl@";
|
||||
|
||||
$useBindings = "@perlbindings@" eq "yes";
|
||||
$useBindings = 1;
|
||||
|
||||
%config = ();
|
||||
|
||||
%binaryCachePublicKeys = ();
|
||||
|
||||
$defaultPublicKeys = "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=";
|
||||
|
||||
sub readConfig {
|
||||
if (defined $ENV{'_NIX_OPTIONS'}) {
|
||||
foreach my $s (split '\n', $ENV{'_NIX_OPTIONS'}) {
|
||||
my ($n, $v) = split '=', $s, 2;
|
||||
$config{$n} = $v;
|
||||
}
|
||||
} else {
|
||||
my $config = "$confDir/nix.conf";
|
||||
return unless -f $config;
|
||||
my $config = "$confDir/nix.conf";
|
||||
return unless -f $config;
|
||||
|
||||
open CONFIG, "<$config" or die "cannot open ‘$config’";
|
||||
while (<CONFIG>) {
|
||||
/^\s*([\w\-\.]+)\s*=\s*(.*)$/ or next;
|
||||
$config{$1} = $2;
|
||||
}
|
||||
close CONFIG;
|
||||
}
|
||||
|
||||
foreach my $s (split(/ /, $config{"binary-cache-public-keys"} // $defaultPublicKeys)) {
|
||||
my ($keyName, $publicKey) = split ":", $s;
|
||||
next unless defined $keyName && defined $publicKey;
|
||||
$binaryCachePublicKeys{$keyName} = decode_base64($publicKey);
|
||||
open CONFIG, "<$config" or die "cannot open '$config'";
|
||||
while (<CONFIG>) {
|
||||
/^\s*([\w\-\.]+)\s*=\s*(.*)$/ or next;
|
||||
$config{$1} = $2;
|
||||
}
|
||||
close CONFIG;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -10,7 +10,7 @@ use IPC::Open2;
|
||||
|
||||
|
||||
sub copyToOpen {
|
||||
my ($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $sign, $useSubstitutes) = @_;
|
||||
my ($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes) = @_;
|
||||
|
||||
$useSubstitutes = 0 if $dryRun || !defined $useSubstitutes;
|
||||
|
||||
@@ -35,81 +35,27 @@ sub copyToOpen {
|
||||
my $missingSize = 0;
|
||||
$missingSize += (queryPathInfo($_, 1))[3] foreach @missing;
|
||||
|
||||
printf STDERR "copying %d missing paths (%.2f MiB) to ‘$sshHost’...\n",
|
||||
printf STDERR "copying %d missing paths (%.2f MiB) to '$sshHost'...\n",
|
||||
scalar(@missing), $missingSize / (1024**2);
|
||||
return if $dryRun;
|
||||
|
||||
# Send the "import paths" command.
|
||||
syswrite($to, pack("L<x4", 4)) or die;
|
||||
exportPaths(fileno($to), $sign, @missing);
|
||||
readInt($from) == 1 or die "remote machine ‘$sshHost’ failed to import closure\n";
|
||||
exportPaths(fileno($to), @missing);
|
||||
readInt($from) == 1 or die "remote machine '$sshHost' failed to import closure\n";
|
||||
}
|
||||
|
||||
|
||||
sub copyTo {
|
||||
my ($sshHost, $storePaths, $includeOutputs, $dryRun, $sign, $useSubstitutes) = @_;
|
||||
my ($sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes) = @_;
|
||||
|
||||
# Connect to the remote host.
|
||||
my ($from, $to);
|
||||
eval {
|
||||
($from, $to) = connectToRemoteNix($sshHost, []);
|
||||
};
|
||||
if ($@) {
|
||||
chomp $@;
|
||||
warn "$@; falling back to old closure copying method\n";
|
||||
$@ = "";
|
||||
return oldCopyTo(@_);
|
||||
}
|
||||
my ($from, $to) = connectToRemoteNix($sshHost, []);
|
||||
|
||||
copyToOpen($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $sign, $useSubstitutes);
|
||||
copyToOpen($from, $to, $sshHost, $storePaths, $includeOutputs, $dryRun, $useSubstitutes);
|
||||
|
||||
close $to;
|
||||
}
|
||||
|
||||
|
||||
# For backwards compatibility with Nix <= 1.7. Will be removed
|
||||
# eventually.
|
||||
sub oldCopyTo {
|
||||
my ($sshHost, $storePaths, $includeOutputs, $dryRun, $sign, $useSubstitutes) = @_;
|
||||
|
||||
# Get the closure of this path.
|
||||
my @closure = reverse(topoSortPaths(computeFSClosure(0, $includeOutputs,
|
||||
map { followLinksToStorePath $_ } @{$storePaths})));
|
||||
|
||||
# Optionally use substitutes on the remote host.
|
||||
if (!$dryRun && $useSubstitutes) {
|
||||
system "ssh $sshHost @globalSshOpts nix-store -r --ignore-unknown @closure";
|
||||
# Ignore exit status because this is just an optimisation.
|
||||
}
|
||||
|
||||
# Ask the remote host which paths are invalid. Because of limits
|
||||
# to the command line length, do this in chunks. Eventually,
|
||||
# we'll want to use ‘--from-stdin’, but we can't rely on the
|
||||
# target having this option yet.
|
||||
my @missing;
|
||||
my $missingSize = 0;
|
||||
while (scalar(@closure) > 0) {
|
||||
my @ps = splice(@closure, 0, 1500);
|
||||
open(READ, "set -f; ssh $sshHost @globalSshOpts nix-store --check-validity --print-invalid @ps|");
|
||||
while (<READ>) {
|
||||
chomp;
|
||||
push @missing, $_;
|
||||
my ($deriver, $narHash, $time, $narSize, $refs) = queryPathInfo($_, 1);
|
||||
$missingSize += $narSize;
|
||||
}
|
||||
close READ or die;
|
||||
}
|
||||
|
||||
# Export the store paths and import them on the remote machine.
|
||||
if (scalar @missing > 0) {
|
||||
print STDERR "copying ", scalar @missing, " missing paths to ‘$sshHost’...\n";
|
||||
unless ($dryRun) {
|
||||
open SSH, "| ssh $sshHost @globalSshOpts 'nix-store --import' > /dev/null" or die;
|
||||
exportPaths(fileno(SSH), $sign, @missing);
|
||||
close SSH or die "copying store paths to remote machine ‘$sshHost’ failed: $?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
package Nix::GeneratePatches;
|
||||
|
||||
use strict;
|
||||
use File::Temp qw(tempdir);
|
||||
use File::stat;
|
||||
use Nix::Config;
|
||||
use Nix::Manifest;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(generatePatches propagatePatches copyPatches);
|
||||
|
||||
|
||||
# Some patch generations options.
|
||||
|
||||
# Max size of NAR archives to generate patches for.
|
||||
my $maxNarSize = $ENV{"NIX_MAX_NAR_SIZE"};
|
||||
$maxNarSize = 160 * 1024 * 1024 if !defined $maxNarSize;
|
||||
|
||||
# If patch is bigger than this fraction of full archive, reject.
|
||||
my $maxPatchFraction = $ENV{"NIX_PATCH_FRACTION"};
|
||||
$maxPatchFraction = 0.60 if !defined $maxPatchFraction;
|
||||
|
||||
my $timeLimit = $ENV{"NIX_BSDIFF_TIME_LIMIT"};
|
||||
$timeLimit = 180 if !defined $timeLimit;
|
||||
|
||||
my $hashAlgo = "sha256";
|
||||
|
||||
|
||||
sub findOutputPaths {
|
||||
my $narFiles = shift;
|
||||
|
||||
my %outPaths;
|
||||
|
||||
foreach my $p (keys %{$narFiles}) {
|
||||
|
||||
# Ignore derivations.
|
||||
next if ($p =~ /\.drv$/);
|
||||
|
||||
# Ignore builders (too much ambiguity -- they're all called
|
||||
# `builder.sh').
|
||||
next if ($p =~ /\.sh$/);
|
||||
next if ($p =~ /\.patch$/);
|
||||
|
||||
# Don't bother including tar files etc.
|
||||
next if ($p =~ /\.tar$/ || $p =~ /\.tar\.(gz|bz2|Z|lzma|xz)$/ || $p =~ /\.zip$/ || $p =~ /\.bin$/ || $p =~ /\.tgz$/ || $p =~ /\.rpm$/ || $p =~ /cvs-export$/ || $p =~ /fetchhg$/);
|
||||
|
||||
$outPaths{$p} = 1;
|
||||
}
|
||||
|
||||
return %outPaths;
|
||||
}
|
||||
|
||||
|
||||
sub getNameVersion {
|
||||
my $p = shift;
|
||||
$p =~ /\/[0-9a-z]+((?:-[a-zA-Z][^\/-]*)+)([^\/]*)$/;
|
||||
my $name = $1;
|
||||
my $version = $2;
|
||||
return undef unless defined $name && defined $version;
|
||||
$name =~ s/^-//;
|
||||
$version =~ s/^-//;
|
||||
return ($name, $version);
|
||||
}
|
||||
|
||||
|
||||
# A quick hack to get a measure of the `distance' between two
|
||||
# versions: it's just the position of the first character that differs
|
||||
# (or 999 if they are the same).
|
||||
sub versionDiff {
|
||||
my $s = shift;
|
||||
my $t = shift;
|
||||
my $i;
|
||||
return 999 if $s eq $t;
|
||||
for ($i = 0; $i < length $s; $i++) {
|
||||
return $i if $i >= length $t or
|
||||
substr($s, $i, 1) ne substr($t, $i, 1);
|
||||
}
|
||||
return $i;
|
||||
}
|
||||
|
||||
|
||||
sub getNarBz2 {
|
||||
my $narPath = shift;
|
||||
my $narFiles = shift;
|
||||
my $storePath = shift;
|
||||
|
||||
my $narFileList = $$narFiles{$storePath};
|
||||
die "missing path $storePath" unless defined $narFileList;
|
||||
|
||||
my $narFile = @{$narFileList}[0];
|
||||
die unless defined $narFile;
|
||||
|
||||
$narFile->{url} =~ /\/([^\/]+)$/;
|
||||
die unless defined $1;
|
||||
return "$narPath/$1";
|
||||
}
|
||||
|
||||
|
||||
sub containsPatch {
|
||||
my $patches = shift;
|
||||
my $storePath = shift;
|
||||
my $basePath = shift;
|
||||
my $patchList = $$patches{$storePath};
|
||||
return 0 if !defined $patchList;
|
||||
my $found = 0;
|
||||
foreach my $patch (@{$patchList}) {
|
||||
# !!! baseHash might differ
|
||||
return 1 if $patch->{basePath} eq $basePath;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
sub generatePatches {
|
||||
my ($srcNarFiles, $dstNarFiles, $srcPatches, $dstPatches, $narPath, $patchesPath, $patchesURL, $tmpDir) = @_;
|
||||
|
||||
my %srcOutPaths = findOutputPaths $srcNarFiles;
|
||||
my %dstOutPaths = findOutputPaths $dstNarFiles;
|
||||
|
||||
# For each output path in the destination, see if we need to / can
|
||||
# create a patch.
|
||||
|
||||
print STDERR "creating patches...\n";
|
||||
|
||||
foreach my $p (keys %dstOutPaths) {
|
||||
|
||||
# If exactly the same path already exists in the source, skip it.
|
||||
next if defined $srcOutPaths{$p};
|
||||
|
||||
print " $p\n";
|
||||
|
||||
# If not, then we should find the paths in the source that are
|
||||
# `most' likely to be present on a system that wants to
|
||||
# install this path.
|
||||
|
||||
(my $name, my $version) = getNameVersion $p;
|
||||
next unless defined $name && defined $version;
|
||||
|
||||
my @closest = ();
|
||||
my $closestVersion;
|
||||
my $minDist = -1; # actually, larger means closer
|
||||
|
||||
# Find all source paths with the same name.
|
||||
|
||||
foreach my $q (keys %srcOutPaths) {
|
||||
(my $name2, my $version2) = getNameVersion $q;
|
||||
next unless defined $name2 && defined $version2;
|
||||
|
||||
if ($name eq $name2) {
|
||||
|
||||
my $srcSystem = @{$$dstNarFiles{$p}}[0]->{system};
|
||||
my $dstSystem = @{$$srcNarFiles{$q}}[0]->{system};
|
||||
if (defined $srcSystem && defined $dstSystem && $srcSystem ne $dstSystem) {
|
||||
print " SKIPPING $q due to different systems ($srcSystem vs. $dstSystem)\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# If the sizes differ too much, then skip. This
|
||||
# disambiguates between, e.g., a real component and a
|
||||
# wrapper component (cf. Firefox in Nixpkgs).
|
||||
my $srcSize = @{$$srcNarFiles{$q}}[0]->{size};
|
||||
my $dstSize = @{$$dstNarFiles{$p}}[0]->{size};
|
||||
my $ratio = $srcSize / $dstSize;
|
||||
$ratio = 1 / $ratio if $ratio < 1;
|
||||
# print " SIZE $srcSize $dstSize $ratio $q\n";
|
||||
|
||||
if ($ratio >= 3) {
|
||||
print " SKIPPING $q due to size ratio $ratio ($srcSize vs. $dstSize)\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# If there are multiple matching names, include the
|
||||
# ones with the closest version numbers.
|
||||
my $dist = versionDiff $version, $version2;
|
||||
if ($dist > $minDist) {
|
||||
$minDist = $dist;
|
||||
@closest = ($q);
|
||||
$closestVersion = $version2;
|
||||
} elsif ($dist == $minDist) {
|
||||
push @closest, $q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scalar(@closest) == 0) {
|
||||
print " NO BASE: $p\n";
|
||||
next;
|
||||
}
|
||||
|
||||
foreach my $closest (@closest) {
|
||||
|
||||
# Generate a patch between $closest and $p.
|
||||
print STDERR " $p <- $closest\n";
|
||||
|
||||
# If the patch already exists, skip it.
|
||||
if (containsPatch($srcPatches, $p, $closest) ||
|
||||
containsPatch($dstPatches, $p, $closest))
|
||||
{
|
||||
print " skipping, already exists\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my $srcNarBz2 = getNarBz2 $narPath, $srcNarFiles, $closest;
|
||||
my $dstNarBz2 = getNarBz2 $narPath, $dstNarFiles, $p;
|
||||
|
||||
if (! -f $srcNarBz2) {
|
||||
warn "patch source archive $srcNarBz2 is missing\n";
|
||||
next;
|
||||
}
|
||||
|
||||
system("$Nix::Config::bzip2 -d < $srcNarBz2 > $tmpDir/A") == 0
|
||||
or die "cannot unpack $srcNarBz2";
|
||||
|
||||
if (stat("$tmpDir/A")->size >= $maxNarSize) {
|
||||
print " skipping, source is too large\n";
|
||||
next;
|
||||
}
|
||||
|
||||
system("$Nix::Config::bzip2 -d < $dstNarBz2 > $tmpDir/B") == 0
|
||||
or die "cannot unpack $dstNarBz2";
|
||||
|
||||
if (stat("$tmpDir/B")->size >= $maxNarSize) {
|
||||
print " skipping, destination is too large\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my $time1 = time();
|
||||
my $res = system("ulimit -t $timeLimit; $Nix::Config::libexecDir/nix/bsdiff $tmpDir/A $tmpDir/B $tmpDir/DIFF");
|
||||
my $time2 = time();
|
||||
if ($res) {
|
||||
warn "binary diff computation aborted after ", $time2 - $time1, " seconds\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my $baseHash = `$Nix::Config::binDir/nix-hash --flat --type $hashAlgo --base32 $tmpDir/A` or die;
|
||||
chomp $baseHash;
|
||||
|
||||
my $narHash = `$Nix::Config::binDir/nix-hash --flat --type $hashAlgo --base32 $tmpDir/B` or die;
|
||||
chomp $narHash;
|
||||
|
||||
my $narDiffHash = `$Nix::Config::binDir/nix-hash --flat --type $hashAlgo --base32 $tmpDir/DIFF` or die;
|
||||
chomp $narDiffHash;
|
||||
|
||||
my $narDiffSize = stat("$tmpDir/DIFF")->size;
|
||||
my $dstNarBz2Size = stat($dstNarBz2)->size;
|
||||
|
||||
print " size $narDiffSize; full size $dstNarBz2Size; ", $time2 - $time1, " seconds\n";
|
||||
|
||||
if ($narDiffSize >= $dstNarBz2Size) {
|
||||
print " rejecting; patch bigger than full archive\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($narDiffSize / $dstNarBz2Size >= $maxPatchFraction) {
|
||||
print " rejecting; patch too large relative to full archive\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my $finalName = "$narDiffHash.nar-bsdiff";
|
||||
|
||||
if (-e "$patchesPath/$finalName") {
|
||||
print " not copying, already exists\n";
|
||||
}
|
||||
|
||||
else {
|
||||
system("cp '$tmpDir/DIFF' '$patchesPath/$finalName.tmp'") == 0
|
||||
or die "cannot copy diff";
|
||||
rename("$patchesPath/$finalName.tmp", "$patchesPath/$finalName")
|
||||
or die "cannot rename $patchesPath/$finalName.tmp";
|
||||
}
|
||||
|
||||
# Add the patch to the manifest.
|
||||
addPatch $dstPatches, $p,
|
||||
{ url => "$patchesURL/$finalName", hash => "$hashAlgo:$narDiffHash"
|
||||
, size => $narDiffSize, basePath => $closest, baseHash => "$hashAlgo:$baseHash"
|
||||
, narHash => "$hashAlgo:$narHash", patchType => "nar-bsdiff"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Propagate useful patches from $srcPatches to $dstPatches. A patch
|
||||
# is useful if it produces either paths in the $dstNarFiles or paths
|
||||
# that can be used as the base for other useful patches.
|
||||
sub propagatePatches {
|
||||
my ($srcPatches, $dstNarFiles, $dstPatches) = @_;
|
||||
|
||||
print STDERR "propagating patches...\n";
|
||||
|
||||
my $changed;
|
||||
do {
|
||||
# !!! we repeat this to reach the transitive closure; inefficient
|
||||
$changed = 0;
|
||||
|
||||
print STDERR "loop\n";
|
||||
|
||||
my %dstBasePaths;
|
||||
foreach my $q (keys %{$dstPatches}) {
|
||||
foreach my $patch (@{$$dstPatches{$q}}) {
|
||||
$dstBasePaths{$patch->{basePath}} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $p (keys %{$srcPatches}) {
|
||||
my $patchList = $$srcPatches{$p};
|
||||
|
||||
my $include = 0;
|
||||
|
||||
# Is path $p included in the destination? If so, include
|
||||
# patches that produce it.
|
||||
$include = 1 if defined $$dstNarFiles{$p};
|
||||
|
||||
# Is path $p a path that serves as a base for paths in the
|
||||
# destination? If so, include patches that produce it.
|
||||
# !!! check baseHash
|
||||
$include = 1 if defined $dstBasePaths{$p};
|
||||
|
||||
if ($include) {
|
||||
foreach my $patch (@{$patchList}) {
|
||||
$changed = 1 if addPatch $dstPatches, $p, $patch;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} while $changed;
|
||||
}
|
||||
|
||||
|
||||
# Add all new patches in $srcPatches to $dstPatches.
|
||||
sub copyPatches {
|
||||
my ($srcPatches, $dstPatches) = @_;
|
||||
foreach my $p (keys %{$srcPatches}) {
|
||||
addPatch $dstPatches, $p, $_ foreach @{$$srcPatches{$p}};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
@@ -13,7 +13,7 @@ use Nix::Config;
|
||||
use Nix::Store;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(readManifest writeManifest updateManifestDB addPatch deleteOldManifests parseNARInfo fingerprintPath);
|
||||
our @EXPORT = qw(readManifest writeManifest addPatch parseNARInfo fingerprintPath);
|
||||
|
||||
|
||||
sub addNAR {
|
||||
@@ -60,10 +60,10 @@ sub readManifest_ {
|
||||
# Decompress the manifest if necessary.
|
||||
if ($manifest =~ /\.bz2$/) {
|
||||
open MANIFEST, "$Nix::Config::bzip2 -d < $manifest |"
|
||||
or die "cannot decompress ‘$manifest’: $!";
|
||||
or die "cannot decompress '$manifest': $!";
|
||||
} else {
|
||||
open MANIFEST, "<$manifest"
|
||||
or die "cannot open ‘$manifest’: $!";
|
||||
or die "cannot open '$manifest': $!";
|
||||
}
|
||||
|
||||
my $inside = 0;
|
||||
@@ -228,172 +228,6 @@ sub writeManifest {
|
||||
}
|
||||
|
||||
|
||||
sub updateManifestDB {
|
||||
my $manifestDir = $Nix::Config::manifestDir;
|
||||
|
||||
my @manifests = glob "$manifestDir/*.nixmanifest";
|
||||
return undef if scalar @manifests == 0;
|
||||
|
||||
mkpath($manifestDir);
|
||||
|
||||
unlink "$manifestDir/cache.sqlite"; # remove obsolete cache
|
||||
my $dbPath = "$manifestDir/cache-v2.sqlite";
|
||||
|
||||
# Open/create the database.
|
||||
our $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "")
|
||||
or die "cannot open database ‘$dbPath’";
|
||||
$dbh->{RaiseError} = 1;
|
||||
$dbh->{PrintError} = 0;
|
||||
|
||||
$dbh->do("pragma foreign_keys = on");
|
||||
$dbh->do("pragma synchronous = off"); # we can always reproduce the cache
|
||||
$dbh->do("pragma journal_mode = truncate");
|
||||
|
||||
# Initialise the database schema, if necessary.
|
||||
$dbh->do(<<EOF);
|
||||
create table if not exists Manifests (
|
||||
id integer primary key autoincrement not null,
|
||||
path text unique not null,
|
||||
timestamp integer not null
|
||||
);
|
||||
EOF
|
||||
|
||||
$dbh->do(<<EOF);
|
||||
create table if not exists NARs (
|
||||
id integer primary key autoincrement not null,
|
||||
manifest integer not null,
|
||||
storePath text not null,
|
||||
url text not null,
|
||||
compressionType text not null,
|
||||
hash text,
|
||||
size integer,
|
||||
narHash text,
|
||||
narSize integer,
|
||||
refs text,
|
||||
deriver text,
|
||||
system text,
|
||||
foreign key (manifest) references Manifests(id) on delete cascade
|
||||
);
|
||||
EOF
|
||||
|
||||
$dbh->do("create index if not exists NARs_storePath on NARs(storePath)");
|
||||
|
||||
$dbh->do(<<EOF);
|
||||
create table if not exists Patches (
|
||||
id integer primary key autoincrement not null,
|
||||
manifest integer not null,
|
||||
storePath text not null,
|
||||
basePath text not null,
|
||||
baseHash text not null,
|
||||
url text not null,
|
||||
hash text,
|
||||
size integer,
|
||||
narHash text,
|
||||
narSize integer,
|
||||
patchType text not null,
|
||||
foreign key (manifest) references Manifests(id) on delete cascade
|
||||
);
|
||||
EOF
|
||||
|
||||
$dbh->do("create index if not exists Patches_storePath on Patches(storePath)");
|
||||
|
||||
# Acquire an exclusive lock to ensure that only one process
|
||||
# updates the DB at the same time. This isn't really necessary,
|
||||
# but it prevents work duplication and lock contention in SQLite.
|
||||
my $lockFile = "$manifestDir/cache.lock";
|
||||
open MAINLOCK, ">>$lockFile" or die "unable to acquire lock ‘$lockFile’: $!\n";
|
||||
flock(MAINLOCK, LOCK_EX) or die;
|
||||
|
||||
our $insertNAR = $dbh->prepare(
|
||||
"insert into NARs(manifest, storePath, url, compressionType, hash, size, narHash, " .
|
||||
"narSize, refs, deriver, system) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") or die;
|
||||
|
||||
our $insertPatch = $dbh->prepare(
|
||||
"insert into Patches(manifest, storePath, basePath, baseHash, url, hash, " .
|
||||
"size, narHash, narSize, patchType) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
$dbh->begin_work;
|
||||
|
||||
# Read each manifest in $manifestDir and add it to the database,
|
||||
# unless we've already done so on a previous run.
|
||||
my %seen;
|
||||
|
||||
for my $manifestLink (@manifests) {
|
||||
my $manifest = Cwd::abs_path($manifestLink);
|
||||
next unless -f $manifest;
|
||||
my $timestamp = lstat($manifest)->mtime;
|
||||
$seen{$manifest} = 1;
|
||||
|
||||
next if scalar @{$dbh->selectcol_arrayref(
|
||||
"select 1 from Manifests where path = ? and timestamp = ?",
|
||||
{}, $manifest, $timestamp)} == 1;
|
||||
|
||||
print STDERR "caching $manifest...\n";
|
||||
|
||||
$dbh->do("delete from Manifests where path = ?", {}, $manifest);
|
||||
|
||||
$dbh->do("insert into Manifests(path, timestamp) values (?, ?)",
|
||||
{}, $manifest, $timestamp);
|
||||
|
||||
our $id = $dbh->last_insert_id("", "", "", "");
|
||||
|
||||
sub addNARToDB {
|
||||
my ($storePath, $narFile) = @_;
|
||||
$insertNAR->execute(
|
||||
$id, $storePath, $narFile->{url}, $narFile->{compressionType}, $narFile->{hash},
|
||||
$narFile->{size}, $narFile->{narHash}, $narFile->{narSize}, $narFile->{references},
|
||||
$narFile->{deriver}, $narFile->{system});
|
||||
};
|
||||
|
||||
sub addPatchToDB {
|
||||
my ($storePath, $patch) = @_;
|
||||
$insertPatch->execute(
|
||||
$id, $storePath, $patch->{basePath}, $patch->{baseHash}, $patch->{url},
|
||||
$patch->{hash}, $patch->{size}, $patch->{narHash}, $patch->{narSize},
|
||||
$patch->{patchType});
|
||||
};
|
||||
|
||||
my $version = readManifest_($manifest, \&addNARToDB, \&addPatchToDB);
|
||||
|
||||
if ($version < 3) {
|
||||
die "you have an old-style or corrupt manifest ‘$manifestLink’; please delete it\n";
|
||||
}
|
||||
if ($version >= 10) {
|
||||
die "manifest ‘$manifestLink’ is too new; please delete it or upgrade Nix\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Removed cached information for removed manifests from the DB.
|
||||
foreach my $manifest (@{$dbh->selectcol_arrayref("select path from Manifests")}) {
|
||||
next if defined $seen{$manifest};
|
||||
$dbh->do("delete from Manifests where path = ?", {}, $manifest);
|
||||
}
|
||||
|
||||
$dbh->commit;
|
||||
|
||||
close MAINLOCK;
|
||||
|
||||
return $dbh;
|
||||
}
|
||||
|
||||
|
||||
# Delete all old manifests downloaded from a given URL.
|
||||
sub deleteOldManifests {
|
||||
my ($url, $curUrlFile) = @_;
|
||||
for my $urlFile (glob "$Nix::Config::manifestDir/*.url") {
|
||||
next if defined $curUrlFile && $urlFile eq $curUrlFile;
|
||||
open URL, "<$urlFile" or die;
|
||||
my $url2 = <URL>;
|
||||
chomp $url2;
|
||||
close URL;
|
||||
next unless $url eq $url2;
|
||||
my $base = $urlFile; $base =~ s/.url$//;
|
||||
unlink "${base}.url";
|
||||
unlink "${base}.nixmanifest";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Return a fingerprint of a store path to be used in binary cache
|
||||
# signatures. It contains the store path, the base-32 SHA-256 hash of
|
||||
# the contents of the path, and the references.
|
||||
@@ -453,7 +287,7 @@ sub parseNARInfo {
|
||||
# FIXME: might be useful to support multiple signatures per .narinfo.
|
||||
|
||||
if (!defined $sig) {
|
||||
warn "NAR info file ‘$location’ lacks a signature; ignoring\n";
|
||||
warn "NAR info file '$location' lacks a signature; ignoring\n";
|
||||
return undef;
|
||||
}
|
||||
my ($keyName, $sig64) = split ":", $sig;
|
||||
@@ -461,7 +295,7 @@ sub parseNARInfo {
|
||||
|
||||
my $publicKey = $Nix::Config::binaryCachePublicKeys{$keyName};
|
||||
if (!defined $publicKey) {
|
||||
warn "NAR info file ‘$location’ is signed by unknown key ‘$keyName’; ignoring\n";
|
||||
warn "NAR info file '$location' is signed by unknown key '$keyName'; ignoring\n";
|
||||
return undef;
|
||||
}
|
||||
|
||||
@@ -472,12 +306,12 @@ sub parseNARInfo {
|
||||
[ map { "$Nix::Config::storeDir/$_" } @refs ]);
|
||||
};
|
||||
if ($@) {
|
||||
warn "cannot compute fingerprint of ‘$location’; ignoring\n";
|
||||
warn "cannot compute fingerprint of '$location'; ignoring\n";
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (!checkSignature($publicKey, decode_base64($sig64), $fingerprint)) {
|
||||
warn "NAR info file ‘$location’ has an incorrect signature; ignoring\n";
|
||||
warn "NAR info file '$location' has an incorrect signature; ignoring\n";
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ sub connectToRemoteNix {
|
||||
syswrite($to, pack("L<x4L<x4", $SERVE_MAGIC_1, $clientVersion)) or die;
|
||||
$magic = readInt($from);
|
||||
};
|
||||
die "unable to connect to ‘$sshHost’\n" if $@;
|
||||
die "unable to connect to '$sshHost'\n" if $@;
|
||||
die "did not get valid handshake from remote host\n" if $magic != 0x5452eecb;
|
||||
|
||||
my $serverVersion = readInt($from);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "EXTERN.h"
|
||||
#include "perl.h"
|
||||
#include "XSUB.h"
|
||||
@@ -6,10 +8,11 @@
|
||||
#undef do_open
|
||||
#undef do_close
|
||||
|
||||
#include <store-api.hh>
|
||||
#include <globals.hh>
|
||||
#include <misc.hh>
|
||||
#include <util.hh>
|
||||
#include "derivations.hh"
|
||||
#include "globals.hh"
|
||||
#include "store-api.hh"
|
||||
#include "util.hh"
|
||||
#include "crypto.hh"
|
||||
|
||||
#if HAVE_SODIUM
|
||||
#include <sodium.h>
|
||||
@@ -19,19 +22,19 @@
|
||||
using namespace nix;
|
||||
|
||||
|
||||
void doInit()
|
||||
static ref<Store> store()
|
||||
{
|
||||
if (!store) {
|
||||
static std::shared_ptr<Store> _store;
|
||||
if (!_store) {
|
||||
try {
|
||||
settings.processEnvironment();
|
||||
settings.loadConfFile();
|
||||
settings.update();
|
||||
settings.lockCPU = false;
|
||||
store = openStore();
|
||||
_store = openStore();
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
}
|
||||
return ref<Store>(_store);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +48,7 @@ PROTOTYPES: ENABLE
|
||||
|
||||
void init()
|
||||
CODE:
|
||||
doInit();
|
||||
store();
|
||||
|
||||
|
||||
void setVerbosity(int level)
|
||||
@@ -56,8 +59,7 @@ void setVerbosity(int level)
|
||||
int isValidPath(char * path)
|
||||
CODE:
|
||||
try {
|
||||
doInit();
|
||||
RETVAL = store->isValidPath(path);
|
||||
RETVAL = store()->isValidPath(path);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -68,9 +70,7 @@ int isValidPath(char * path)
|
||||
SV * queryReferences(char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
PathSet paths;
|
||||
store->queryReferences(path, paths);
|
||||
PathSet paths = store()->queryPathInfo(path)->references;
|
||||
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
@@ -81,9 +81,7 @@ SV * queryReferences(char * path)
|
||||
SV * queryPathHash(char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
Hash hash = store->queryPathHash(path);
|
||||
string s = "sha256:" + printHash32(hash);
|
||||
auto s = store()->queryPathInfo(path)->narHash.to_string();
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -93,8 +91,7 @@ SV * queryPathHash(char * path)
|
||||
SV * queryDeriver(char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
Path deriver = store->queryDeriver(path);
|
||||
auto deriver = store()->queryPathInfo(path)->deriver;
|
||||
if (deriver == "") XSRETURN_UNDEF;
|
||||
XPUSHs(sv_2mortal(newSVpv(deriver.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
@@ -105,18 +102,17 @@ SV * queryDeriver(char * path)
|
||||
SV * queryPathInfo(char * path, int base32)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
ValidPathInfo info = store->queryPathInfo(path);
|
||||
if (info.deriver == "")
|
||||
auto info = store()->queryPathInfo(path);
|
||||
if (info->deriver == "")
|
||||
XPUSHs(&PL_sv_undef);
|
||||
else
|
||||
XPUSHs(sv_2mortal(newSVpv(info.deriver.c_str(), 0)));
|
||||
string s = "sha256:" + (base32 ? printHash32(info.hash) : printHash(info.hash));
|
||||
XPUSHs(sv_2mortal(newSVpv(info->deriver.c_str(), 0)));
|
||||
auto s = info->narHash.to_string(base32 ? Base32 : Base16);
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
mXPUSHi(info.registrationTime);
|
||||
mXPUSHi(info.narSize);
|
||||
mXPUSHi(info->registrationTime);
|
||||
mXPUSHi(info->narSize);
|
||||
AV * arr = newAV();
|
||||
for (PathSet::iterator i = info.references.begin(); i != info.references.end(); ++i)
|
||||
for (PathSet::iterator i = info->references.begin(); i != info->references.end(); ++i)
|
||||
av_push(arr, newSVpv(i->c_str(), 0));
|
||||
XPUSHs(sv_2mortal(newRV((SV *) arr)));
|
||||
} catch (Error & e) {
|
||||
@@ -127,8 +123,7 @@ SV * queryPathInfo(char * path, int base32)
|
||||
SV * queryPathFromHashPart(char * hashPart)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
Path path = store->queryPathFromHashPart(hashPart);
|
||||
Path path = store()->queryPathFromHashPart(hashPart);
|
||||
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -138,10 +133,9 @@ SV * queryPathFromHashPart(char * hashPart)
|
||||
SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
PathSet paths;
|
||||
for (int n = 2; n < items; ++n)
|
||||
computeFSClosure(*store, SvPV_nolen(ST(n)), paths, flipDirection, includeOutputs);
|
||||
store()->computeFSClosure(SvPV_nolen(ST(n)), paths, flipDirection, includeOutputs);
|
||||
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
@@ -152,10 +146,9 @@ SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
|
||||
SV * topoSortPaths(...)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
PathSet paths;
|
||||
for (int n = 0; n < items; ++n) paths.insert(SvPV_nolen(ST(n)));
|
||||
Paths sorted = topoSortPaths(*store, paths);
|
||||
Paths sorted = store()->topoSortPaths(paths);
|
||||
for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i)
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
@@ -166,8 +159,7 @@ SV * topoSortPaths(...)
|
||||
SV * followLinksToStorePath(char * path)
|
||||
CODE:
|
||||
try {
|
||||
doInit();
|
||||
RETVAL = newSVpv(followLinksToStorePath(path).c_str(), 0);
|
||||
RETVAL = newSVpv(store()->followLinksToStorePath(path).c_str(), 0);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -175,25 +167,23 @@ SV * followLinksToStorePath(char * path)
|
||||
RETVAL
|
||||
|
||||
|
||||
void exportPaths(int fd, int sign, ...)
|
||||
void exportPaths(int fd, ...)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
Paths paths;
|
||||
for (int n = 2; n < items; ++n) paths.push_back(SvPV_nolen(ST(n)));
|
||||
for (int n = 1; n < items; ++n) paths.push_back(SvPV_nolen(ST(n)));
|
||||
FdSink sink(fd);
|
||||
exportPaths(*store, paths, sign, sink);
|
||||
store()->exportPaths(paths, sink);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
|
||||
|
||||
void importPaths(int fd)
|
||||
void importPaths(int fd, int dontCheckSigs)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
FdSource source(fd);
|
||||
store->importPaths(false, source);
|
||||
store()->importPaths(source, nullptr, dontCheckSigs ? NoCheckSigs : CheckSigs);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -203,7 +193,7 @@ SV * hashPath(char * algo, int base32, char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
Hash h = hashPath(parseHashType(algo), path).first;
|
||||
string s = base32 ? printHash32(h) : printHash(h);
|
||||
auto s = h.to_string(base32 ? Base32 : Base16, false);
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -214,7 +204,7 @@ SV * hashFile(char * algo, int base32, char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
Hash h = hashFile(parseHashType(algo), path);
|
||||
string s = base32 ? printHash32(h) : printHash(h);
|
||||
auto s = h.to_string(base32 ? Base32 : Base16, false);
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -225,7 +215,7 @@ SV * hashString(char * algo, int base32, char * s)
|
||||
PPCODE:
|
||||
try {
|
||||
Hash h = hashString(parseHashType(algo), s);
|
||||
string s = base32 ? printHash32(h) : printHash(h);
|
||||
auto s = h.to_string(base32 ? Base32 : Base16, false);
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -235,27 +225,20 @@ SV * hashString(char * algo, int base32, char * s)
|
||||
SV * convertHash(char * algo, char * s, int toBase32)
|
||||
PPCODE:
|
||||
try {
|
||||
Hash h = parseHash16or32(parseHashType(algo), s);
|
||||
string s = toBase32 ? printHash32(h) : printHash(h);
|
||||
Hash h(s, parseHashType(algo));
|
||||
string s = h.to_string(toBase32 ? Base32 : Base16, false);
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
|
||||
|
||||
SV * signString(SV * secretKey_, char * msg)
|
||||
SV * signString(char * secretKey_, char * msg)
|
||||
PPCODE:
|
||||
try {
|
||||
#if HAVE_SODIUM
|
||||
STRLEN secretKeyLen;
|
||||
unsigned char * secretKey = (unsigned char *) SvPV(secretKey_, secretKeyLen);
|
||||
if (secretKeyLen != crypto_sign_SECRETKEYBYTES)
|
||||
throw Error("secret key is not valid");
|
||||
|
||||
unsigned char sig[crypto_sign_BYTES];
|
||||
unsigned long long sigLen;
|
||||
crypto_sign_detached(sig, &sigLen, (unsigned char *) msg, strlen(msg), secretKey);
|
||||
XPUSHs(sv_2mortal(newSVpv((char *) sig, sigLen)));
|
||||
auto sig = SecretKey(secretKey_).signDetached(msg);
|
||||
XPUSHs(sv_2mortal(newSVpv(sig.c_str(), sig.size())));
|
||||
#else
|
||||
throw Error("Nix was not compiled with libsodium, required for signed binary cache support");
|
||||
#endif
|
||||
@@ -292,8 +275,7 @@ int checkSignature(SV * publicKey_, SV * sig_, char * msg)
|
||||
SV * addToStore(char * srcPath, int recursive, char * algo)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
Path path = store->addToStore(baseNameOf(srcPath), srcPath, recursive, parseHashType(algo));
|
||||
Path path = store()->addToStore(baseNameOf(srcPath), srcPath, recursive, parseHashType(algo));
|
||||
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -303,10 +285,8 @@ SV * addToStore(char * srcPath, int recursive, char * algo)
|
||||
SV * makeFixedOutputPath(int recursive, char * algo, char * hash, char * name)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
HashType ht = parseHashType(algo);
|
||||
Path path = makeFixedOutputPath(recursive, ht,
|
||||
parseHash16or32(ht, hash), name);
|
||||
Hash h(hash, parseHashType(algo));
|
||||
Path path = store()->makeFixedOutputPath(recursive, h, name);
|
||||
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -318,8 +298,7 @@ SV * derivationFromPath(char * drvPath)
|
||||
HV *hash;
|
||||
CODE:
|
||||
try {
|
||||
doInit();
|
||||
Derivation drv = derivationFromPath(*store, drvPath);
|
||||
Derivation drv = store()->derivationFromPath(drvPath);
|
||||
hash = newHV();
|
||||
|
||||
HV * outputs = newHV();
|
||||
@@ -361,8 +340,7 @@ SV * derivationFromPath(char * drvPath)
|
||||
void addTempRoot(char * storePath)
|
||||
PPCODE:
|
||||
try {
|
||||
doInit();
|
||||
store->addTempRoot(storePath);
|
||||
store()->addTempRoot(storePath);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ $urlRE = "(?: [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!
|
||||
|
||||
sub checkURL {
|
||||
my ($url) = @_;
|
||||
die "invalid URL ‘$url’\n" unless $url =~ /^ $urlRE $ /x;
|
||||
die "invalid URL '$url'\n" unless $url =~ /^ $urlRE $ /x;
|
||||
}
|
||||
|
||||
sub uniq {
|
||||
@@ -26,7 +26,7 @@ sub uniq {
|
||||
|
||||
sub writeFile {
|
||||
my ($fn, $s) = @_;
|
||||
open TMP, ">$fn" or die "cannot create file ‘$fn’: $!";
|
||||
open TMP, ">$fn" or die "cannot create file '$fn': $!";
|
||||
print TMP "$s" or die;
|
||||
close TMP or die;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ sub writeFile {
|
||||
sub readFile {
|
||||
local $/ = undef;
|
||||
my ($fn) = @_;
|
||||
open TMP, "<$fn" or die "cannot open file ‘$fn’: $!";
|
||||
open TMP, "<$fn" or die "cannot open file '$fn': $!";
|
||||
my $s = <TMP>;
|
||||
close TMP or die;
|
||||
return $s;
|
||||
|
||||
@@ -1,49 +1,43 @@
|
||||
nix_perl_sources := \
|
||||
$(d)/lib/Nix/Store.pm \
|
||||
$(d)/lib/Nix/Manifest.pm \
|
||||
$(d)/lib/Nix/GeneratePatches.pm \
|
||||
$(d)/lib/Nix/SSH.pm \
|
||||
$(d)/lib/Nix/CopyClosure.pm \
|
||||
$(d)/lib/Nix/Config.pm.in \
|
||||
$(d)/lib/Nix/Utils.pm
|
||||
lib/Nix/Store.pm \
|
||||
lib/Nix/Manifest.pm \
|
||||
lib/Nix/SSH.pm \
|
||||
lib/Nix/CopyClosure.pm \
|
||||
lib/Nix/Config.pm.in \
|
||||
lib/Nix/Utils.pm
|
||||
|
||||
nix_perl_modules := $(nix_perl_sources:.in=)
|
||||
|
||||
$(foreach x, $(nix_perl_modules), $(eval $(call install-data-in, $(x), $(perllibdir)/Nix)))
|
||||
|
||||
ifeq ($(perlbindings), yes)
|
||||
|
||||
$(d)/lib/Nix/Store.cc: $(d)/lib/Nix/Store.xs
|
||||
lib/Nix/Store.cc: lib/Nix/Store.xs
|
||||
$(trace-gen) xsubpp $^ -output $@
|
||||
|
||||
libraries += Store
|
||||
libraries += Store
|
||||
|
||||
Store_DIR := $(d)/lib/Nix
|
||||
Store_DIR := lib/Nix
|
||||
|
||||
Store_SOURCES := $(Store_DIR)/Store.cc
|
||||
Store_SOURCES := $(Store_DIR)/Store.cc
|
||||
|
||||
Store_CXXFLAGS = \
|
||||
-I$(shell $(perl) -e 'use Config; print $$Config{archlibexp};')/CORE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-Wno-unknown-warning-option -Wno-unused-variable -Wno-literal-suffix \
|
||||
-Wno-reserved-user-defined-literal -Wno-duplicate-decl-specifier -Wno-pointer-bool-conversion
|
||||
Store_CXXFLAGS = \
|
||||
$(NIX_CFLAGS) \
|
||||
-I$(shell perl -e 'use Config; print $$Config{archlibexp};')/CORE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-Wno-unknown-warning-option -Wno-unused-variable -Wno-literal-suffix \
|
||||
-Wno-reserved-user-defined-literal -Wno-duplicate-decl-specifier -Wno-pointer-bool-conversion
|
||||
|
||||
Store_LIBS = libstore libutil
|
||||
|
||||
Store_LDFLAGS := $(SODIUM_LIBS)
|
||||
|
||||
ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
|
||||
archlib = $(shell perl -E 'use Config; print $$Config{archlib};')
|
||||
libperl = $(shell perl -E 'use Config; print $$Config{libperl};')
|
||||
Store_LDFLAGS += $(shell find ${archlib} -name ${libperl})
|
||||
endif
|
||||
|
||||
Store_ALLOW_UNDEFINED = 1
|
||||
|
||||
Store_FORCE_INSTALL = 1
|
||||
|
||||
Store_INSTALL_DIR = $(perllibdir)/auto/Nix/Store
|
||||
Store_LDFLAGS := $(SODIUM_LIBS) $(NIX_LIBS)
|
||||
|
||||
ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
|
||||
archlib = $(shell perl -E 'use Config; print $$Config{archlib};')
|
||||
libperl = $(shell perl -E 'use Config; print $$Config{libperl};')
|
||||
Store_LDFLAGS += $(shell find ${archlib} -name ${libperl})
|
||||
endif
|
||||
|
||||
clean-files += $(d)/lib/Nix/Config.pm $(d)/lib/Nix/Store.cc
|
||||
Store_ALLOW_UNDEFINED = 1
|
||||
|
||||
Store_FORCE_INSTALL = 1
|
||||
|
||||
Store_INSTALL_DIR = $(perllibdir)/auto/Nix/Store
|
||||
|
||||
clean-files += lib/Nix/Config.pm lib/Nix/Store.cc Makefile.config
|
||||
|
||||
22
release-common.nix
Normal file
22
release-common.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{ pkgs }:
|
||||
|
||||
rec {
|
||||
sh = pkgs.busybox.override {
|
||||
useMusl = true;
|
||||
enableStatic = true;
|
||||
enableMinimal = true;
|
||||
extraConfig = ''
|
||||
CONFIG_ASH y
|
||||
CONFIG_ASH_ECHO y
|
||||
CONFIG_ASH_TEST y
|
||||
CONFIG_ASH_OPTIMIZE_FOR_SIZE y
|
||||
'';
|
||||
};
|
||||
|
||||
configureFlags =
|
||||
[ "--disable-init-state"
|
||||
"--enable-gc"
|
||||
] ++ pkgs.lib.optionals pkgs.stdenv.isLinux [
|
||||
"--with-sandbox-shell=${sh}/bin/busybox"
|
||||
];
|
||||
}
|
||||
236
release.nix
236
release.nix
@@ -1,13 +1,12 @@
|
||||
{ nix ? { outPath = ./.; revCount = 1234; shortRev = "abcdef"; }
|
||||
{ nix ? builtins.fetchGit ./.
|
||||
, nixpkgs ? fetchTarball channel:nixos-17.09
|
||||
, officialRelease ? false
|
||||
, systems ? [ "x86_64-linux" "i686-linux" "x86_64-darwin" "aarch64-linux" ]
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
pkgs = import <nixpkgs> {};
|
||||
|
||||
systems = [ "x86_64-linux" "i686-linux" "x86_64-darwin" /* "x86_64-freebsd" "i686-freebsd" */ ];
|
||||
|
||||
pkgs = import nixpkgs {};
|
||||
|
||||
jobs = rec {
|
||||
|
||||
@@ -19,29 +18,26 @@ let
|
||||
name = "nix-tarball";
|
||||
version = builtins.readFile ./version;
|
||||
versionSuffix = if officialRelease then "" else "pre${toString nix.revCount}_${nix.shortRev}";
|
||||
src = if lib.inNixShell then null else nix;
|
||||
src = nix;
|
||||
inherit officialRelease;
|
||||
|
||||
buildInputs =
|
||||
[ curl bison flex perl libxml2 libxslt bzip2 xz
|
||||
dblatex (dblatex.tex or tetex) nukeReferences pkgconfig sqlite libsodium
|
||||
[ curl bison flex libxml2 libxslt
|
||||
bzip2 xz brotli
|
||||
pkgconfig sqlite libsodium boehmgc
|
||||
docbook5 docbook5_xsl
|
||||
] ++ lib.optional (!lib.inNixShell) git;
|
||||
autoconf-archive
|
||||
] ++ lib.optional stdenv.isLinux libseccomp;
|
||||
|
||||
configureFlags = ''
|
||||
--with-dbi=${perlPackages.DBI}/${perl.libPrefix}
|
||||
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}
|
||||
--with-www-curl=${perlPackages.WWWCurl}/${perl.libPrefix}
|
||||
'';
|
||||
configureFlags = "--enable-gc";
|
||||
|
||||
postUnpack = ''
|
||||
# Clean up when building from a working tree.
|
||||
if [[ -d $sourceRoot/.git ]]; then
|
||||
git -C $sourceRoot clean -fd
|
||||
fi
|
||||
(cd source && find . -type f) | cut -c3- > source/.dist-files
|
||||
cat source/.dist-files
|
||||
'';
|
||||
|
||||
preConfigure = ''
|
||||
(cd perl ; autoreconf --install --force --verbose)
|
||||
# TeX needs a writable font cache.
|
||||
export VARTEXFONTS=$TMPDIR/texfonts
|
||||
'';
|
||||
@@ -56,45 +52,40 @@ let
|
||||
|
||||
preDist = ''
|
||||
make install docdir=$out/share/doc/nix makefiles=doc/manual/local.mk
|
||||
|
||||
make doc/manual/manual.pdf
|
||||
cp doc/manual/manual.pdf $out/manual.pdf
|
||||
|
||||
# The PDF containes filenames of included graphics (see
|
||||
# http://www.tug.org/pipermail/pdftex/2007-August/007290.html).
|
||||
# This causes a retained dependency on dblatex, which Hydra
|
||||
# doesn't like (the output of the tarball job is distributed
|
||||
# to Windows and Macs, so there should be no Linux binaries
|
||||
# in the closure).
|
||||
nuke-refs $out/manual.pdf
|
||||
|
||||
echo "doc manual $out/share/doc/nix/manual" >> $out/nix-support/hydra-build-products
|
||||
echo "doc-pdf manual $out/manual.pdf" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
build = pkgs.lib.genAttrs systems (system:
|
||||
|
||||
# FIXME: temporarily use a different branch for the Darwin build.
|
||||
with import (if system == "x86_64-darwin" then <nixpkgs-darwin> else <nixpkgs>) { inherit system; };
|
||||
with import nixpkgs { inherit system; };
|
||||
|
||||
with import ./release-common.nix { inherit pkgs; };
|
||||
|
||||
releaseTools.nixBuild {
|
||||
name = "nix";
|
||||
src = tarball;
|
||||
|
||||
buildInputs =
|
||||
[ curl perl bzip2 xz openssl pkgconfig sqlite boehmgc ]
|
||||
++ lib.optional stdenv.isLinux libsodium;
|
||||
[ curl
|
||||
bzip2 xz brotli
|
||||
openssl pkgconfig sqlite boehmgc
|
||||
|
||||
configureFlags = ''
|
||||
--disable-init-state
|
||||
--with-dbi=${perlPackages.DBI}/${perl.libPrefix}
|
||||
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}
|
||||
--with-www-curl=${perlPackages.WWWCurl}/${perl.libPrefix}
|
||||
--enable-gc
|
||||
--sysconfdir=/etc
|
||||
'';
|
||||
# Tests
|
||||
git
|
||||
mercurial
|
||||
]
|
||||
++ lib.optional stdenv.isLinux libseccomp
|
||||
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium
|
||||
++ lib.optional (stdenv.isLinux || stdenv.isDarwin)
|
||||
(aws-sdk-cpp.override {
|
||||
apis = ["s3"];
|
||||
customMemoryManagement = false;
|
||||
});
|
||||
|
||||
configureFlags = configureFlags ++
|
||||
[ "--sysconfdir=/etc" ];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
@@ -109,10 +100,35 @@ let
|
||||
});
|
||||
|
||||
|
||||
perlBindings = pkgs.lib.genAttrs systems (system:
|
||||
|
||||
let pkgs = import nixpkgs { inherit system; }; in with pkgs;
|
||||
|
||||
releaseTools.nixBuild {
|
||||
name = "nix-perl";
|
||||
src = tarball;
|
||||
|
||||
buildInputs =
|
||||
[ (builtins.getAttr system jobs.build) curl bzip2 xz pkgconfig pkgs.perl ]
|
||||
++ lib.optional (stdenv.isLinux || stdenv.isDarwin) libsodium;
|
||||
|
||||
configureFlags = ''
|
||||
--with-dbi=${perlPackages.DBI}/${pkgs.perl.libPrefix}
|
||||
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${pkgs.perl.libPrefix}
|
||||
'';
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
postUnpack = "sourceRoot=$sourceRoot/perl";
|
||||
|
||||
preBuild = "unset NIX_INDENT_MAKE";
|
||||
});
|
||||
|
||||
|
||||
binaryTarball = pkgs.lib.genAttrs systems (system:
|
||||
|
||||
# FIXME: temporarily use a different branch for the Darwin build.
|
||||
with import (if system == "x86_64-darwin" then <nixpkgs-darwin> else <nixpkgs>) { inherit system; };
|
||||
with import nixpkgs { inherit system; };
|
||||
|
||||
let
|
||||
toplevel = builtins.getAttr system jobs.build;
|
||||
@@ -121,7 +137,7 @@ let
|
||||
|
||||
runCommand "nix-binary-tarball-${version}"
|
||||
{ exportReferencesGraph = [ "closure1" toplevel "closure2" cacert ];
|
||||
buildInputs = [ perl ];
|
||||
buildInputs = [ perl shellcheck ];
|
||||
meta.description = "Distribution-independent Nix bootstrap binaries for ${system}";
|
||||
}
|
||||
''
|
||||
@@ -130,7 +146,15 @@ let
|
||||
substitute ${./scripts/install-nix-from-closure.sh} $TMPDIR/install \
|
||||
--subst-var-by nix ${toplevel} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
substitute ${./scripts/install-darwin-multi-user.sh} $TMPDIR/install-darwin-multi-user \
|
||||
--subst-var-by nix ${toplevel} \
|
||||
--subst-var-by cacert ${cacert}
|
||||
|
||||
shellcheck -e SC1090 $TMPDIR/install
|
||||
shellcheck -e SC1091,SC2002 $TMPDIR/install-darwin-multi-user
|
||||
|
||||
chmod +x $TMPDIR/install
|
||||
chmod +x $TMPDIR/install-darwin-multi-user
|
||||
dir=nix-${version}-${system}
|
||||
fn=$out/$dir.tar.bz2
|
||||
mkdir -p $out/nix-support
|
||||
@@ -142,35 +166,32 @@ let
|
||||
--transform "s,$TMPDIR/install,$dir/install," \
|
||||
--transform "s,$TMPDIR/reginfo,$dir/.reginfo," \
|
||||
--transform "s,$NIX_STORE,$dir/store,S" \
|
||||
$TMPDIR/install $TMPDIR/reginfo $storePaths
|
||||
$TMPDIR/install $TMPDIR/install-darwin-multi-user $TMPDIR/reginfo $storePaths
|
||||
'');
|
||||
|
||||
|
||||
coverage =
|
||||
with import <nixpkgs> { system = "x86_64-linux"; };
|
||||
with import nixpkgs { system = "x86_64-linux"; };
|
||||
|
||||
releaseTools.coverageAnalysis {
|
||||
name = "nix-build";
|
||||
src = tarball;
|
||||
|
||||
buildInputs =
|
||||
[ curl perl bzip2 openssl pkgconfig sqlite xz libsodium
|
||||
[ curl bzip2 openssl pkgconfig sqlite xz libsodium libseccomp
|
||||
# These are for "make check" only:
|
||||
graphviz libxml2 libxslt
|
||||
graphviz libxml2 libxslt git mercurial
|
||||
];
|
||||
|
||||
configureFlags = ''
|
||||
--disable-init-state
|
||||
--with-dbi=${perlPackages.DBI}/${perl.libPrefix}
|
||||
--with-dbd-sqlite=${perlPackages.DBDSQLite}/${perl.libPrefix}
|
||||
--with-www-curl=${perlPackages.WWWCurl}/${perl.libPrefix}
|
||||
'';
|
||||
|
||||
dontInstall = false;
|
||||
|
||||
doInstallCheck = true;
|
||||
|
||||
lcovFilter = [ "*/boost/*" "*-tab.*" ];
|
||||
lcovFilter = [ "*/boost/*" "*-tab.*" "*/nlohmann/*" "*/linenoise/*" ];
|
||||
|
||||
# We call `dot', and even though we just use it to
|
||||
# syntax-check generated dot files, it still requires some
|
||||
@@ -179,61 +200,74 @@ let
|
||||
};
|
||||
|
||||
|
||||
rpm_fedora18i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora18i386) [];
|
||||
rpm_fedora18x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora18x86_64) [];
|
||||
rpm_fedora19i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora19i386) [];
|
||||
rpm_fedora19x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora19x86_64) [];
|
||||
rpm_fedora20i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora20i386) [];
|
||||
rpm_fedora20x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora20x86_64) [];
|
||||
rpm_fedora21i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora21i386) [ "libsodium-devel" ];
|
||||
rpm_fedora21x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora21x86_64) [ "libsodium-devel" ];
|
||||
rpm_fedora25i386 = makeRPM_i686 (diskImageFuns: diskImageFuns.fedora25i386) [ "libsodium-devel" ];
|
||||
rpm_fedora25x86_64 = makeRPM_x86_64 (diskImageFunsFun: diskImageFunsFun.fedora25x86_64) [ "libsodium-devel" ];
|
||||
|
||||
|
||||
deb_debian7i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian7i386) [];
|
||||
deb_debian7x86_64 = makeDeb_x86_64 (diskImageFunsFun: diskImageFunsFun.debian7x86_64) [];
|
||||
deb_debian8i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian8i386) [ "libsodium-dev" ];
|
||||
deb_debian8x86_64 = makeDeb_x86_64 (diskImageFunsFun: diskImageFunsFun.debian8x86_64) [ "libsodium-dev" ];
|
||||
#deb_debian8i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.debian8i386) [ "libsodium-dev" ] [ "libsodium13" ];
|
||||
#deb_debian8x86_64 = makeDeb_x86_64 (diskImageFunsFun: diskImageFunsFun.debian8x86_64) [ "libsodium-dev" ] [ "libsodium13" ];
|
||||
|
||||
deb_ubuntu1210i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1210i386) [];
|
||||
deb_ubuntu1210x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1210x86_64) [];
|
||||
deb_ubuntu1304i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1304i386) [];
|
||||
deb_ubuntu1304x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1304x86_64) [];
|
||||
deb_ubuntu1310i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1310i386) [];
|
||||
deb_ubuntu1310x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1310x86_64) [];
|
||||
deb_ubuntu1404i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1404i386) [];
|
||||
deb_ubuntu1404x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1404x86_64) [];
|
||||
deb_ubuntu1410i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1410i386) [];
|
||||
deb_ubuntu1410x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1410x86_64) [];
|
||||
deb_ubuntu1504i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1504i386) [ "libsodium-dev" ];
|
||||
deb_ubuntu1504x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1504x86_64) [ "libsodium-dev" ];
|
||||
deb_ubuntu1604i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1604i386) [ "libsodium-dev" ] [ "libsodium18" ];
|
||||
deb_ubuntu1604x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1604x86_64) [ "libsodium-dev" ] [ "libsodium18" ];
|
||||
deb_ubuntu1610i386 = makeDeb_i686 (diskImageFuns: diskImageFuns.ubuntu1610i386) [ "libsodium-dev" ] [ "libsodium18" ];
|
||||
deb_ubuntu1610x86_64 = makeDeb_x86_64 (diskImageFuns: diskImageFuns.ubuntu1610x86_64) [ "libsodium-dev" ] [ "libsodium18" ];
|
||||
|
||||
|
||||
# System tests.
|
||||
tests.remoteBuilds = (import ./tests/remote-builds.nix rec {
|
||||
inherit nixpkgs;
|
||||
nix = build.x86_64-linux; system = "x86_64-linux";
|
||||
});
|
||||
|
||||
tests.nix-copy-closure = (import ./tests/nix-copy-closure.nix rec {
|
||||
inherit nixpkgs;
|
||||
nix = build.x86_64-linux; system = "x86_64-linux";
|
||||
});
|
||||
|
||||
tests.setuid = pkgs.lib.genAttrs (pkgs.lib.filter (pkgs.lib.hasSuffix "-linux") systems) (system:
|
||||
import ./tests/setuid.nix rec {
|
||||
inherit nixpkgs;
|
||||
nix = build.${system}; inherit system;
|
||||
});
|
||||
|
||||
tests.binaryTarball =
|
||||
with import <nixpkgs> { system = "x86_64-linux"; };
|
||||
with import nixpkgs { system = "x86_64-linux"; };
|
||||
vmTools.runInLinuxImage (runCommand "nix-binary-tarball-test"
|
||||
{ diskImage = vmTools.diskImages.ubuntu1204x86_64;
|
||||
}
|
||||
''
|
||||
useradd -m alice
|
||||
su - alice -c 'tar xf ${binaryTarball.x86_64-linux}/*.tar.*'
|
||||
mount -t tmpfs none /nix # Provide a writable /nix.
|
||||
mkdir /dest-nix
|
||||
mount -o bind /dest-nix /nix # Provide a writable /nix.
|
||||
chown alice /nix
|
||||
su - alice -c '_NIX_INSTALLER_TEST=1 ./nix-*/install'
|
||||
su - alice -c 'nix-store --verify'
|
||||
su - alice -c 'nix-store -qR ${build.x86_64-linux}'
|
||||
su - alice -c 'PAGER= nix-store -qR ${build.x86_64-linux}'
|
||||
mkdir -p $out/nix-support
|
||||
touch $out/nix-support/hydra-build-products
|
||||
umount /nix
|
||||
''); # */
|
||||
|
||||
tests.evalNixpkgs =
|
||||
import (nixpkgs + "/pkgs/top-level/make-tarball.nix") {
|
||||
inherit nixpkgs;
|
||||
inherit pkgs;
|
||||
nix = build.x86_64-linux;
|
||||
officialRelease = false;
|
||||
};
|
||||
|
||||
tests.evalNixOS =
|
||||
pkgs.runCommand "eval-nixos" { buildInputs = [ build.x86_64-linux ]; }
|
||||
''
|
||||
export NIX_STATE_DIR=$TMPDIR
|
||||
nix-store --init
|
||||
|
||||
nix-instantiate ${nixpkgs}/nixos/release-combined.nix -A tested --dry-run
|
||||
|
||||
touch $out
|
||||
'';
|
||||
|
||||
|
||||
# Aggregate job containing the release-critical jobs.
|
||||
release = pkgs.releaseTools.aggregate {
|
||||
@@ -241,29 +275,23 @@ let
|
||||
meta.description = "Release-critical builds";
|
||||
constituents =
|
||||
[ tarball
|
||||
#build.i686-freebsd
|
||||
build.i686-linux
|
||||
build.x86_64-darwin
|
||||
#build.x86_64-freebsd
|
||||
build.x86_64-linux
|
||||
#binaryTarball.i686-freebsd
|
||||
binaryTarball.i686-linux
|
||||
binaryTarball.x86_64-darwin
|
||||
#binaryTarball.x86_64-freebsd
|
||||
binaryTarball.x86_64-linux
|
||||
deb_debian7i386
|
||||
deb_debian7x86_64
|
||||
deb_ubuntu1404i386 # LTS
|
||||
deb_ubuntu1404x86_64 # LTS
|
||||
deb_ubuntu1504i386
|
||||
deb_ubuntu1504x86_64
|
||||
rpm_fedora20i386
|
||||
rpm_fedora20x86_64
|
||||
rpm_fedora21i386
|
||||
rpm_fedora21x86_64
|
||||
#deb_debian8i386
|
||||
#deb_debian8x86_64
|
||||
deb_ubuntu1604i386
|
||||
deb_ubuntu1604x86_64
|
||||
rpm_fedora25i386
|
||||
rpm_fedora25x86_64
|
||||
tests.remoteBuilds
|
||||
tests.nix-copy-closure
|
||||
tests.binaryTarball
|
||||
tests.evalNixpkgs
|
||||
tests.evalNixOS
|
||||
];
|
||||
};
|
||||
|
||||
@@ -276,18 +304,20 @@ let
|
||||
makeRPM =
|
||||
system: diskImageFun: extraPackages:
|
||||
|
||||
with import <nixpkgs> { inherit system; };
|
||||
with import nixpkgs { inherit system; };
|
||||
|
||||
releaseTools.rpmBuild rec {
|
||||
name = "nix-rpm";
|
||||
src = jobs.tarball;
|
||||
diskImage = (diskImageFun vmTools.diskImageFuns)
|
||||
{ extraPackages =
|
||||
[ "perl-DBD-SQLite" "perl-devel" "sqlite" "sqlite-devel" "bzip2-devel" "emacs" "perl-WWW-Curl" "libcurl-devel" "openssl-devel" "xz-devel" ]
|
||||
[ "sqlite" "sqlite-devel" "bzip2-devel" "libcurl-devel" "openssl-devel" "xz-devel" "libseccomp-devel" ]
|
||||
++ extraPackages; };
|
||||
memSize = 1024;
|
||||
# At most 2047MB can be simulated in qemu-system-i386
|
||||
memSize = 2047;
|
||||
meta.schedulingPriority = 50;
|
||||
postRPMInstall = "cd /tmp/rpmout/BUILD/nix-* && make installcheck";
|
||||
#enableParallelBuilding = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -295,25 +325,27 @@ let
|
||||
makeDeb_x86_64 = makeDeb "x86_64-linux";
|
||||
|
||||
makeDeb =
|
||||
system: diskImageFun: extraPackages:
|
||||
system: diskImageFun: extraPackages: extraDebPackages:
|
||||
|
||||
with import <nixpkgs> { inherit system; };
|
||||
with import nixpkgs { inherit system; };
|
||||
|
||||
releaseTools.debBuild {
|
||||
name = "nix-deb";
|
||||
src = jobs.tarball;
|
||||
diskImage = (diskImageFun vmTools.diskImageFuns)
|
||||
{ extraPackages =
|
||||
[ "libdbd-sqlite3-perl" "libsqlite3-dev" "libbz2-dev" "libwww-curl-perl" "libcurl-dev" "libcurl3-nss" "libssl-dev" "liblzma-dev" ]
|
||||
[ "libsqlite3-dev" "libbz2-dev" "libcurl-dev" "libcurl3-nss" "libssl-dev" "liblzma-dev" "libseccomp-dev" ]
|
||||
++ extraPackages; };
|
||||
memSize = 1024;
|
||||
meta.schedulingPriority = 50;
|
||||
postInstall = "make installcheck";
|
||||
configureFlags = "--sysconfdir=/etc";
|
||||
debRequires =
|
||||
[ "curl" "libdbd-sqlite3-perl" "libsqlite3-0" "libbz2-1.0" "bzip2" "xz-utils" "libwww-curl-perl" "libssl1.0.0" "liblzma5" ]
|
||||
++ lib.optionals (lib.elem "libsodium-dev" extraPackages) [ "libsodium13" ] ;
|
||||
[ "curl" "libsqlite3-0" "libbz2-1.0" "bzip2" "xz-utils" "libssl1.0.0" "liblzma5" "libseccomp2" ]
|
||||
++ extraDebPackages;
|
||||
debMaintainer = "Eelco Dolstra <eelco.dolstra@logicblox.com>";
|
||||
doInstallCheck = true;
|
||||
#enableParallelBuilding = true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,284 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use utf8;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
use English '-no_match_vars';
|
||||
use IO::Handle;
|
||||
use Nix::Config;
|
||||
use Nix::SSH;
|
||||
use Nix::CopyClosure;
|
||||
use Nix::Store;
|
||||
use Encode;
|
||||
no warnings('once');
|
||||
|
||||
STDERR->autoflush(1);
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
my $debug = defined $ENV{NIX_DEBUG_HOOK};
|
||||
|
||||
|
||||
# General operation:
|
||||
#
|
||||
# Try to find a free machine of type $neededSystem. We do this as
|
||||
# follows:
|
||||
# - We acquire an exclusive lock on $currentLoad/main-lock.
|
||||
# - For each machine $machine of type $neededSystem and for each $slot
|
||||
# less than the maximum load for that machine, we try to get an
|
||||
# exclusive lock on $currentLoad/$machine-$slot (without blocking).
|
||||
# If we get such a lock, we send "accept" to the caller. Otherwise,
|
||||
# we send "postpone" and exit.
|
||||
# - We release the exclusive lock on $currentLoad/main-lock.
|
||||
# - We perform the build on $neededSystem.
|
||||
# - We release the exclusive lock on $currentLoad/$machine-$slot.
|
||||
#
|
||||
# The nice thing about this scheme is that if we die prematurely, the
|
||||
# locks are released automatically.
|
||||
|
||||
|
||||
# Make sure that we don't get any SSH passphrase or host key popups -
|
||||
# if there is any problem it should fail, not do something
|
||||
# interactive.
|
||||
$ENV{"DISPLAY"} = "";
|
||||
$ENV{"SSH_ASKPASS"} = "";
|
||||
|
||||
|
||||
sub sendReply {
|
||||
my $reply = shift;
|
||||
print STDERR "# $reply\n";
|
||||
}
|
||||
|
||||
sub all { $_ || return 0 for @_; 1 }
|
||||
|
||||
|
||||
# Initialisation.
|
||||
my $loadIncreased = 0;
|
||||
|
||||
my ($localSystem, $maxSilentTime, $printBuildTrace, $buildTimeout) = @ARGV;
|
||||
|
||||
my $currentLoad = $ENV{"NIX_CURRENT_LOAD"} // "/run/nix/current-load";
|
||||
my $conf = $ENV{"NIX_REMOTE_SYSTEMS"} // "@sysconfdir@/nix/machines";
|
||||
|
||||
|
||||
sub openSlotLock {
|
||||
my ($machine, $slot) = @_;
|
||||
my $slotLockFn = "$currentLoad/" . (join '+', @{$machine->{systemTypes}}) . "-" . $machine->{hostName} . "-$slot";
|
||||
my $slotLock = new IO::Handle;
|
||||
sysopen $slotLock, "$slotLockFn", O_RDWR|O_CREAT, 0600 or die;
|
||||
return $slotLock;
|
||||
}
|
||||
|
||||
|
||||
# Read the list of machines.
|
||||
my @machines;
|
||||
if (defined $conf && -e $conf) {
|
||||
open CONF, "<$conf" or die;
|
||||
while (<CONF>) {
|
||||
chomp;
|
||||
s/\#.*$//g;
|
||||
next if /^\s*$/;
|
||||
my @tokens = split /\s/, $_;
|
||||
my @supportedFeatures = split(/,/, $tokens[5] || "");
|
||||
my @mandatoryFeatures = split(/,/, $tokens[6] || "");
|
||||
push @machines,
|
||||
{ hostName => $tokens[0]
|
||||
, systemTypes => [ split(/,/, $tokens[1]) ]
|
||||
, sshKey => $tokens[2]
|
||||
, maxJobs => int($tokens[3])
|
||||
, speedFactor => 1.0 * (defined $tokens[4] ? int($tokens[4]) : 1)
|
||||
, supportedFeatures => [ @supportedFeatures, @mandatoryFeatures ]
|
||||
, mandatoryFeatures => [ @mandatoryFeatures ]
|
||||
, enabled => 1
|
||||
};
|
||||
}
|
||||
close CONF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Wait for the calling process to ask us whether we can build some derivation.
|
||||
my ($drvPath, $hostName, $slotLock);
|
||||
my ($from, $to);
|
||||
|
||||
REQ: while (1) {
|
||||
$_ = <STDIN> || exit 0;
|
||||
(my $amWilling, my $neededSystem, $drvPath, my $requiredFeatures) = split;
|
||||
my @requiredFeatures = split /,/, $requiredFeatures;
|
||||
|
||||
my $canBuildLocally = $amWilling && ($localSystem eq $neededSystem);
|
||||
|
||||
if (!defined $currentLoad) {
|
||||
sendReply "decline";
|
||||
next;
|
||||
}
|
||||
|
||||
# Acquire the exclusive lock on $currentLoad/main-lock.
|
||||
mkdir $currentLoad, 0777 or die unless -d $currentLoad;
|
||||
my $mainLock = "$currentLoad/main-lock";
|
||||
sysopen MAINLOCK, "$mainLock", O_RDWR|O_CREAT, 0600 or die;
|
||||
flock(MAINLOCK, LOCK_EX) or die;
|
||||
|
||||
|
||||
while (1) {
|
||||
# Find all machine that can execute this build, i.e., that
|
||||
# support builds for the given platform and features, and are
|
||||
# not at their job limit.
|
||||
my $rightType = 0;
|
||||
my @available = ();
|
||||
LOOP: foreach my $cur (@machines) {
|
||||
if ($cur->{enabled}
|
||||
&& (grep { $neededSystem eq $_ } @{$cur->{systemTypes}})
|
||||
&& all(map { my $f = $_; 0 != grep { $f eq $_ } @{$cur->{supportedFeatures}} } (@requiredFeatures, @mandatoryFeatures))
|
||||
&& all(map { my $f = $_; 0 != grep { $f eq $_ } @requiredFeatures } @{$cur->{mandatoryFeatures}})
|
||||
)
|
||||
{
|
||||
$rightType = 1;
|
||||
|
||||
# We have a machine of the right type. Determine the load on
|
||||
# the machine.
|
||||
my $slot = 0;
|
||||
my $load = 0;
|
||||
my $free;
|
||||
while ($slot < $cur->{maxJobs}) {
|
||||
my $slotLock = openSlotLock($cur, $slot);
|
||||
if (flock($slotLock, LOCK_EX | LOCK_NB)) {
|
||||
$free = $slot unless defined $free;
|
||||
flock($slotLock, LOCK_UN) or die;
|
||||
} else {
|
||||
$load++;
|
||||
}
|
||||
close $slotLock;
|
||||
$slot++;
|
||||
}
|
||||
|
||||
push @available, { machine => $cur, load => $load, free => $free }
|
||||
if $load < $cur->{maxJobs};
|
||||
}
|
||||
}
|
||||
|
||||
if ($debug) {
|
||||
print STDERR "load on " . $_->{machine}->{hostName} . " = " . $_->{load} . "\n"
|
||||
foreach @available;
|
||||
}
|
||||
|
||||
|
||||
# Didn't find any available machine? Then decline or postpone.
|
||||
if (scalar @available == 0) {
|
||||
# Postpone if we have a machine of the right type, except
|
||||
# if the local system can and wants to do the build.
|
||||
if ($rightType && !$canBuildLocally) {
|
||||
sendReply "postpone";
|
||||
} else {
|
||||
sendReply "decline";
|
||||
}
|
||||
close MAINLOCK;
|
||||
next REQ;
|
||||
}
|
||||
|
||||
|
||||
# Prioritise the available machines as follows:
|
||||
# - First by load divided by speed factor, rounded to the nearest
|
||||
# integer. This causes fast machines to be preferred over slow
|
||||
# machines with similar loads.
|
||||
# - Then by speed factor.
|
||||
# - Finally by load.
|
||||
sub lf { my $x = shift; return int($x->{load} / $x->{machine}->{speedFactor} + 0.4999); }
|
||||
@available = sort
|
||||
{ lf($a) <=> lf($b)
|
||||
|| $b->{machine}->{speedFactor} <=> $a->{machine}->{speedFactor}
|
||||
|| $a->{load} <=> $b->{load}
|
||||
} @available;
|
||||
|
||||
|
||||
# Select the best available machine and lock a free slot.
|
||||
my $selected = $available[0];
|
||||
my $machine = $selected->{machine};
|
||||
|
||||
$slotLock = openSlotLock($machine, $selected->{free});
|
||||
flock($slotLock, LOCK_EX | LOCK_NB) or die;
|
||||
utime undef, undef, $slotLock;
|
||||
|
||||
close MAINLOCK;
|
||||
|
||||
|
||||
# Connect to the selected machine.
|
||||
my @sshOpts = ("-i", $machine->{sshKey});
|
||||
$hostName = $machine->{hostName};
|
||||
eval {
|
||||
($from, $to) = connectToRemoteNix($hostName, \@sshOpts, "2>&4");
|
||||
# FIXME: check if builds are inhibited.
|
||||
};
|
||||
last REQ unless $@;
|
||||
print STDERR "$@";
|
||||
warn "unable to open SSH connection to ‘$hostName’, trying other available machines...\n";
|
||||
$from = undef;
|
||||
$to = undef;
|
||||
$machine->{enabled} = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Tell Nix we've accepted the build.
|
||||
sendReply "accept";
|
||||
my @inputs = split /\s/, readline(STDIN);
|
||||
my @outputs = split /\s/, readline(STDIN);
|
||||
|
||||
|
||||
print STDERR "@ build-remote $drvPath $hostName\n" if $printBuildTrace;
|
||||
|
||||
|
||||
my $maybeSign = "";
|
||||
$maybeSign = "--sign" if -e "$Nix::Config::confDir/signing-key.sec";
|
||||
|
||||
|
||||
# Copy the derivation and its dependencies to the build machine. This
|
||||
# is guarded by an exclusive lock per machine to prevent multiple
|
||||
# build-remote instances from copying to a machine simultaneously.
|
||||
# That's undesirable because we may end up with N instances uploading
|
||||
# the same missing path simultaneously, causing the effective network
|
||||
# bandwidth and target disk speed to be divided by N.
|
||||
my $uploadLock = "$currentLoad/$hostName.upload-lock";
|
||||
sysopen UPLOADLOCK, "$uploadLock", O_RDWR|O_CREAT, 0600 or die;
|
||||
eval {
|
||||
local $SIG{ALRM} = sub { die "alarm\n" };
|
||||
# Don't wait forever, so that a process that gets stuck while
|
||||
# holding the lock doesn't block everybody else indefinitely.
|
||||
# It's safe to continue after a timeout, just (potentially)
|
||||
# inefficient.
|
||||
alarm 15 * 60;
|
||||
flock(UPLOADLOCK, LOCK_EX);
|
||||
alarm 0;
|
||||
};
|
||||
if ($@) {
|
||||
die unless $@ eq "alarm\n";
|
||||
print STDERR "somebody is hogging $uploadLock, continuing...\n";
|
||||
unlink $uploadLock;
|
||||
}
|
||||
Nix::CopyClosure::copyToOpen($from, $to, $hostName, [ $drvPath, @inputs ], 0, 0, $maybeSign ne "");
|
||||
close UPLOADLOCK;
|
||||
|
||||
|
||||
# Perform the build.
|
||||
print STDERR "building ‘$drvPath’ on ‘$hostName’\n";
|
||||
print STDERR "@ build-remote-start $drvPath $hostName\n" if $printBuildTrace;
|
||||
writeInt(6, $to) or die; # == cmdBuildPaths
|
||||
writeStrings([$drvPath], $to);
|
||||
writeInt($maxSilentTime, $to);
|
||||
writeInt($buildTimeout, $to);
|
||||
my $res = readInt($from);
|
||||
print STDERR "@ build-remote-done $drvPath $hostName\n" if $printBuildTrace;
|
||||
if ($res != 0) {
|
||||
my $msg = decode("utf-8", readString($from));
|
||||
print STDERR "error: $msg on ‘$hostName’\n";
|
||||
exit $res;
|
||||
}
|
||||
|
||||
|
||||
# Copy the output from the build machine.
|
||||
my @outputs2 = grep { !isValidPath($_) } @outputs;
|
||||
if (scalar @outputs2 > 0) {
|
||||
writeInt(5, $to); # == cmdExportPaths
|
||||
writeInt(0, $to); # don't sign
|
||||
writeStrings(\@outputs2, $to);
|
||||
$ENV{'NIX_HELD_LOCKS'} = "@outputs2"; # FIXME: ugly
|
||||
importPaths(fileno($from));
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use utf8;
|
||||
use strict;
|
||||
use File::Basename;
|
||||
use IO::Handle;
|
||||
|
||||
my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
|
||||
|
||||
|
||||
STDOUT->autoflush(1);
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
my @remoteStoresAll = split ':', ($ENV{"NIX_OTHER_STORES"} or "");
|
||||
|
||||
my @remoteStores;
|
||||
foreach my $dir (@remoteStoresAll) {
|
||||
push @remoteStores, glob($dir);
|
||||
}
|
||||
|
||||
exit if scalar @remoteStores == 0;
|
||||
print "\n";
|
||||
|
||||
|
||||
$ENV{"NIX_REMOTE"} = "";
|
||||
|
||||
|
||||
sub findStorePath {
|
||||
my $storePath = shift;
|
||||
foreach my $store (@remoteStores) {
|
||||
my $sourcePath = "$store/store/" . basename $storePath;
|
||||
next unless -e $sourcePath || -l $sourcePath;
|
||||
$ENV{"NIX_DB_DIR"} = "$store/var/nix/db";
|
||||
return ($store, $sourcePath) if
|
||||
system("$binDir/nix-store --check-validity $storePath") == 0;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
if ($ARGV[0] eq "--query") {
|
||||
|
||||
while (<STDIN>) {
|
||||
chomp;
|
||||
my ($cmd, @args) = split " ", $_;
|
||||
|
||||
if ($cmd eq "have") {
|
||||
foreach my $storePath (@args) {
|
||||
print "$storePath\n" if defined findStorePath($storePath);
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
elsif ($cmd eq "info") {
|
||||
foreach my $storePath (@args) {
|
||||
my ($store, $sourcePath) = findStorePath($storePath);
|
||||
next unless defined $store;
|
||||
|
||||
$ENV{"NIX_DB_DIR"} = "$store/var/nix/db";
|
||||
|
||||
my $deriver = `$binDir/nix-store --query --deriver $storePath`;
|
||||
die "cannot query deriver of ‘$storePath’" if $? != 0;
|
||||
chomp $deriver;
|
||||
$deriver = "" if $deriver eq "unknown-deriver";
|
||||
|
||||
my @references = split "\n",
|
||||
`$binDir/nix-store --query --references $storePath`;
|
||||
die "cannot query references of ‘$storePath’" if $? != 0;
|
||||
|
||||
my $narSize = `$binDir/nix-store --query --size $storePath`;
|
||||
die "cannot query size of ‘$storePath’" if $? != 0;
|
||||
chomp $narSize;
|
||||
|
||||
print "$storePath\n";
|
||||
print "$deriver\n";
|
||||
print scalar @references, "\n";
|
||||
print "$_\n" foreach @references;
|
||||
print "0\n";
|
||||
print "$narSize\n";
|
||||
}
|
||||
|
||||
print "\n";
|
||||
}
|
||||
|
||||
else { die "unknown command ‘$cmd’"; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
elsif ($ARGV[0] eq "--substitute") {
|
||||
die unless scalar @ARGV == 3;
|
||||
my $storePath = $ARGV[1];
|
||||
my $destPath = $ARGV[2];
|
||||
my ($store, $sourcePath) = findStorePath $storePath;
|
||||
die unless $store;
|
||||
print STDERR "\n*** Copying ‘$storePath’ from ‘$sourcePath’\n\n";
|
||||
system("@coreutils@/cp", "-rpd", $sourcePath, $destPath) == 0
|
||||
or die "cannot copy ‘$sourcePath’ to ‘$storePath’";
|
||||
print "\n"; # no hash to verify
|
||||
}
|
||||
|
||||
|
||||
else { die; }
|
||||
@@ -1,632 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use utf8;
|
||||
use DBI;
|
||||
use DBD::SQLite;
|
||||
use File::Basename;
|
||||
use IO::Select;
|
||||
use Nix::Config;
|
||||
use Nix::Store;
|
||||
use Nix::Utils;
|
||||
use Nix::Manifest;
|
||||
use WWW::Curl::Easy;
|
||||
use WWW::Curl::Multi;
|
||||
use strict;
|
||||
|
||||
STDERR->autoflush(1);
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
Nix::Config::readConfig;
|
||||
|
||||
my @caches;
|
||||
my $gotCaches = 0;
|
||||
|
||||
my $maxParallelRequests = int($Nix::Config::config{"binary-caches-parallel-connections"} // 25);
|
||||
$maxParallelRequests = 1 if $maxParallelRequests < 1;
|
||||
|
||||
my $ttlNegative = 24 * 3600; # when to purge negative lookups from the database
|
||||
my $ttlNegativeUse = 3600; # how long negative lookups are valid for non-"have" lookups
|
||||
my $didExpiration = 0;
|
||||
|
||||
my $showAfter = 5; # show that we're waiting for a request after this many seconds
|
||||
|
||||
my $debug = ($Nix::Config::config{"debug-subst"} // "") eq 1 || ($Nix::Config::config{"untrusted-debug-subst"} // "") eq 1;
|
||||
|
||||
my $cacheFileURLs = ($ENV{"_NIX_CACHE_FILE_URLS"} // "") eq 1; # for testing
|
||||
|
||||
my ($dbh, $queryCache, $insertNAR, $queryNAR, $insertNARExistence, $queryNARExistence, $expireNARExistence);
|
||||
|
||||
my $curlm = WWW::Curl::Multi->new;
|
||||
my $activeRequests = 0;
|
||||
my $curlIdCount = 1;
|
||||
my %requests;
|
||||
my %scheduled;
|
||||
my $caBundle = $ENV{"SSL_CERT_FILE"} // $ENV{"CURL_CA_BUNDLE"} // $ENV{"OPENSSL_X509_CERT_FILE"};
|
||||
$caBundle = "/etc/ssl/certs/ca-bundle.crt" if !$caBundle && -f "/etc/ssl/certs/ca-bundle.crt";
|
||||
$caBundle = "/etc/ssl/certs/ca-certificates.crt" if !$caBundle && -f "/etc/ssl/certs/ca-certificates.crt";
|
||||
|
||||
my $userName = getpwuid($<) || $ENV{"USER"} or die "cannot figure out user name";
|
||||
|
||||
my $userAgent = "Nix/$Nix::Config::version";
|
||||
|
||||
sub isTrue {
|
||||
my ($x) = @_;
|
||||
return $x eq "true" || $x eq "1";
|
||||
}
|
||||
|
||||
# FIXME: this should be cache URLs required to have valid signatures,
|
||||
# or "*" to require signatures on all binary caches.
|
||||
# FIXME: should binary caches using a key in
|
||||
# ‘binary-cache-public-keys’ be trusted by default?
|
||||
my $requireSignedBinaryCaches = ($Nix::Config::config{"signed-binary-caches"} // "0") ne "0";
|
||||
|
||||
my $curlConnectTimeout = int(
|
||||
$Nix::Config::config{"untrusted-connect-timeout"} //
|
||||
$Nix::Config::config{"connect-timeout"} //
|
||||
$ENV{"NIX_CONNECT_TIMEOUT"} // 0);
|
||||
|
||||
|
||||
sub addRequest {
|
||||
my ($storePath, $url, $head) = @_;
|
||||
|
||||
my $curl = WWW::Curl::Easy->new;
|
||||
my $curlId = $curlIdCount++;
|
||||
$requests{$curlId} = { storePath => $storePath, url => $url, handle => $curl, content => "", type => $head ? "HEAD" : "GET"
|
||||
, shown => 0, started => time() };
|
||||
|
||||
$curl->setopt(CURLOPT_PRIVATE, $curlId);
|
||||
$curl->setopt(CURLOPT_URL, $url);
|
||||
open (my $fh, ">", \$requests{$curlId}->{content});
|
||||
$curl->setopt(CURLOPT_WRITEDATA, $fh);
|
||||
$curl->setopt(CURLOPT_FOLLOWLOCATION, 1);
|
||||
$curl->setopt(CURLOPT_CAINFO, $caBundle) if defined $caBundle;
|
||||
|
||||
unless (isTrue($Nix::Config::config{"verify-https-binary-caches"} // "1")) {
|
||||
$curl->setopt(CURLOPT_SSL_VERIFYPEER, 0);
|
||||
$curl->setopt(CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
$curl->setopt(CURLOPT_USERAGENT, $userAgent);
|
||||
$curl->setopt(CURLOPT_NOBODY, 1) if $head;
|
||||
$curl->setopt(CURLOPT_FAILONERROR, 1);
|
||||
$curl->setopt(CURLOPT_CONNECTTIMEOUT, $curlConnectTimeout);
|
||||
$curl->setopt(CURLOPT_TIMEOUT, 20 * 60);
|
||||
|
||||
if ($activeRequests >= $maxParallelRequests) {
|
||||
$scheduled{$curlId} = 1;
|
||||
} else {
|
||||
$curlm->add_handle($curl);
|
||||
$activeRequests++;
|
||||
}
|
||||
|
||||
return $requests{$curlId};
|
||||
}
|
||||
|
||||
|
||||
sub processRequests {
|
||||
while ($activeRequests) {
|
||||
my ($rfds, $wfds, $efds) = $curlm->fdset();
|
||||
#print STDERR "R = @{$rfds}, W = @{$wfds}, E = @{$efds}\n";
|
||||
|
||||
# Sleep until we can read or write some data.
|
||||
if (scalar @{$rfds} + scalar @{$wfds} + scalar @{$efds} > 0) {
|
||||
IO::Select->select(IO::Select->new(@{$rfds}), IO::Select->new(@{$wfds}), IO::Select->new(@{$efds}), 1.0);
|
||||
}
|
||||
|
||||
if ($curlm->perform() != $activeRequests) {
|
||||
while (my ($id, $result) = $curlm->info_read) {
|
||||
if ($id) {
|
||||
my $request = $requests{$id} or die;
|
||||
my $handle = $request->{handle};
|
||||
$request->{result} = $result;
|
||||
$request->{httpStatus} = $handle->getinfo(CURLINFO_RESPONSE_CODE);
|
||||
|
||||
print STDERR "$request->{type} on $request->{url} [$request->{result}, $request->{httpStatus}]\n" if $debug;
|
||||
|
||||
$activeRequests--;
|
||||
delete $request->{handle};
|
||||
|
||||
if (scalar(keys %scheduled) > 0) {
|
||||
my $id2 = (keys %scheduled)[0];
|
||||
$curlm->add_handle($requests{$id2}->{handle});
|
||||
$activeRequests++;
|
||||
delete $scheduled{$id2};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $time = time();
|
||||
while (my ($key, $request) = each %requests) {
|
||||
next unless defined $request->{handle};
|
||||
next if $request->{shown};
|
||||
if ($time > $request->{started} + $showAfter) {
|
||||
print STDERR "still waiting for ‘$request->{url}’ after $showAfter seconds...\n";
|
||||
$request->{shown} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub initCache {
|
||||
my $dbPath = "$Nix::Config::stateDir/binary-cache-v3.sqlite";
|
||||
|
||||
unlink "$Nix::Config::stateDir/binary-cache-v1.sqlite";
|
||||
unlink "$Nix::Config::stateDir/binary-cache-v2.sqlite";
|
||||
|
||||
# Open/create the database.
|
||||
$dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "")
|
||||
or die "cannot open database ‘$dbPath’";
|
||||
$dbh->{RaiseError} = 1;
|
||||
$dbh->{PrintError} = 0;
|
||||
|
||||
$dbh->sqlite_busy_timeout(60 * 60 * 1000);
|
||||
|
||||
$dbh->do("pragma synchronous = off"); # we can always reproduce the cache
|
||||
$dbh->do("pragma journal_mode = truncate");
|
||||
|
||||
# Initialise the database schema, if necessary.
|
||||
$dbh->do(<<EOF);
|
||||
create table if not exists BinaryCaches (
|
||||
id integer primary key autoincrement not null,
|
||||
url text unique not null,
|
||||
timestamp integer not null,
|
||||
storeDir text not null,
|
||||
wantMassQuery integer not null,
|
||||
priority integer not null
|
||||
);
|
||||
EOF
|
||||
|
||||
$dbh->do(<<EOF);
|
||||
create table if not exists NARs (
|
||||
cache integer not null,
|
||||
storePath text not null,
|
||||
url text not null,
|
||||
compression text not null,
|
||||
fileHash text,
|
||||
fileSize integer,
|
||||
narHash text,
|
||||
narSize integer,
|
||||
refs text,
|
||||
deriver text,
|
||||
signedBy text,
|
||||
timestamp integer not null,
|
||||
primary key (cache, storePath),
|
||||
foreign key (cache) references BinaryCaches(id) on delete cascade
|
||||
);
|
||||
EOF
|
||||
|
||||
$dbh->do(<<EOF);
|
||||
create table if not exists NARExistence (
|
||||
cache integer not null,
|
||||
storePath text not null,
|
||||
exist integer not null,
|
||||
timestamp integer not null,
|
||||
primary key (cache, storePath),
|
||||
foreign key (cache) references BinaryCaches(id) on delete cascade
|
||||
);
|
||||
EOF
|
||||
|
||||
$dbh->do("create index if not exists NARExistenceByExistTimestamp on NARExistence (exist, timestamp)");
|
||||
|
||||
$queryCache = $dbh->prepare("select id, storeDir, wantMassQuery, priority from BinaryCaches where url = ?") or die;
|
||||
|
||||
$insertNAR = $dbh->prepare(
|
||||
"insert or replace into NARs(cache, storePath, url, compression, fileHash, fileSize, narHash, " .
|
||||
"narSize, refs, deriver, signedBy, timestamp) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") or die;
|
||||
|
||||
$queryNAR = $dbh->prepare("select * from NARs where cache = ? and storePath = ?") or die;
|
||||
|
||||
$insertNARExistence = $dbh->prepare(
|
||||
"insert or replace into NARExistence(cache, storePath, exist, timestamp) values (?, ?, ?, ?)") or die;
|
||||
|
||||
$queryNARExistence = $dbh->prepare("select exist, timestamp from NARExistence where cache = ? and storePath = ?") or die;
|
||||
|
||||
$expireNARExistence = $dbh->prepare("delete from NARExistence where exist = ? and timestamp < ?") or die;
|
||||
}
|
||||
|
||||
|
||||
sub getAvailableCaches {
|
||||
return if $gotCaches;
|
||||
$gotCaches = 1;
|
||||
|
||||
sub strToList {
|
||||
my ($s) = @_;
|
||||
return map { s/\/+$//; $_ } split(/ /, $s);
|
||||
}
|
||||
|
||||
my @urls = strToList($Nix::Config::config{"binary-caches"} //
|
||||
($Nix::Config::storeDir eq "/nix/store" ? "https://cache.nixos.org" : ""));
|
||||
|
||||
my $urlsFiles = $Nix::Config::config{"binary-cache-files"}
|
||||
// "$Nix::Config::stateDir/profiles/per-user/$userName/channels/binary-caches/*";
|
||||
foreach my $urlFile (glob $urlsFiles) {
|
||||
next unless -f $urlFile;
|
||||
open FILE, "<$urlFile" or die "cannot open ‘$urlFile’\n";
|
||||
my $url = <FILE>; chomp $url;
|
||||
close FILE;
|
||||
push @urls, strToList($url);
|
||||
}
|
||||
|
||||
push @urls, strToList($Nix::Config::config{"extra-binary-caches"} // "");
|
||||
|
||||
# Allow Nix daemon users to override the binary caches to a subset
|
||||
# of those listed in the config file. Note that ‘untrusted-*’
|
||||
# denotes options passed by the client.
|
||||
my @trustedUrls = uniq(@urls, strToList($Nix::Config::config{"trusted-binary-caches"} // ""));
|
||||
|
||||
if (defined $Nix::Config::config{"untrusted-binary-caches"}) {
|
||||
my @untrustedUrls = strToList $Nix::Config::config{"untrusted-binary-caches"};
|
||||
@urls = ();
|
||||
foreach my $url (@untrustedUrls) {
|
||||
die "binary cache ‘$url’ is not trusted (please add it to ‘trusted-binary-caches’ in $Nix::Config::confDir/nix.conf)\n"
|
||||
unless scalar(grep { $url eq $_ } @trustedUrls) > 0;
|
||||
push @urls, $url;
|
||||
}
|
||||
}
|
||||
|
||||
my @untrustedUrls = strToList $Nix::Config::config{"untrusted-extra-binary-caches"} // "";
|
||||
foreach my $url (@untrustedUrls) {
|
||||
unless (scalar(grep { $url eq $_ } @trustedUrls) > 0) {
|
||||
warn "binary cache ‘$url’ is not trusted (please add it to ‘trusted-binary-caches’ in $Nix::Config::confDir/nix.conf)\n";
|
||||
next;
|
||||
}
|
||||
push @urls, $url;
|
||||
}
|
||||
|
||||
foreach my $url (uniq @urls) {
|
||||
|
||||
# FIXME: not atomic.
|
||||
$queryCache->execute($url);
|
||||
my $res = $queryCache->fetchrow_hashref();
|
||||
if (defined $res) {
|
||||
next if $res->{storeDir} ne $Nix::Config::storeDir;
|
||||
push @caches, { id => $res->{id}, url => $url, wantMassQuery => $res->{wantMassQuery}, priority => $res->{priority} };
|
||||
next;
|
||||
}
|
||||
|
||||
# Get the cache info file.
|
||||
my $request = addRequest(undef, $url . "/nix-cache-info");
|
||||
processRequests;
|
||||
|
||||
if ($request->{result} != 0) {
|
||||
print STDERR "could not download ‘$request->{url}’ (" .
|
||||
($request->{result} != 0 ? "Curl error $request->{result}" : "HTTP status $request->{httpStatus}") . ")\n";
|
||||
next;
|
||||
}
|
||||
|
||||
my $storeDir = "/nix/store";
|
||||
my $wantMassQuery = 0;
|
||||
my $priority = 50;
|
||||
foreach my $line (split "\n", $request->{content}) {
|
||||
unless ($line =~ /^(.*): (.*)$/) {
|
||||
print STDERR "bad cache info file ‘$request->{url}’\n";
|
||||
return undef;
|
||||
}
|
||||
if ($1 eq "StoreDir") { $storeDir = $2; }
|
||||
elsif ($1 eq "WantMassQuery") { $wantMassQuery = int($2); }
|
||||
elsif ($1 eq "Priority") { $priority = int($2); }
|
||||
}
|
||||
|
||||
$dbh->do("insert or replace into BinaryCaches(url, timestamp, storeDir, wantMassQuery, priority) values (?, ?, ?, ?, ?)",
|
||||
{}, $url, time(), $storeDir, $wantMassQuery, $priority);
|
||||
$queryCache->execute($url);
|
||||
$res = $queryCache->fetchrow_hashref() or die;
|
||||
next if $storeDir ne $Nix::Config::storeDir;
|
||||
push @caches, { id => $res->{id}, url => $url, wantMassQuery => $wantMassQuery, priority => $priority };
|
||||
}
|
||||
|
||||
@caches = sort { $a->{priority} <=> $b->{priority} } @caches;
|
||||
|
||||
expireNegative();
|
||||
}
|
||||
|
||||
|
||||
sub shouldCache {
|
||||
my ($url) = @_;
|
||||
return $cacheFileURLs || $url !~ /^file:/;
|
||||
}
|
||||
|
||||
|
||||
sub processNARInfo {
|
||||
my ($storePath, $cache, $request) = @_;
|
||||
|
||||
if ($request->{result} != 0) {
|
||||
if ($request->{result} != 37 && $request->{httpStatus} != 404 && $request->{httpStatus} != 403) {
|
||||
print STDERR "could not download ‘$request->{url}’ (" .
|
||||
($request->{result} != 0 ? "Curl error $request->{result}" : "HTTP status $request->{httpStatus}") . ")\n";
|
||||
} else {
|
||||
$insertNARExistence->execute($cache->{id}, basename($storePath), 0, time())
|
||||
if shouldCache $request->{url};
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $narInfo = parseNARInfo($storePath, $request->{content}, $requireSignedBinaryCaches, $request->{url});
|
||||
return undef unless defined $narInfo;
|
||||
|
||||
die if $requireSignedBinaryCaches && !defined $narInfo->{signedBy};
|
||||
|
||||
# Cache the result.
|
||||
$insertNAR->execute(
|
||||
$cache->{id}, basename($storePath), $narInfo->{url}, $narInfo->{compression},
|
||||
$narInfo->{fileHash}, $narInfo->{fileSize}, $narInfo->{narHash}, $narInfo->{narSize},
|
||||
join(" ", @{$narInfo->{refs}}), $narInfo->{deriver}, $narInfo->{signedBy}, time())
|
||||
if shouldCache $request->{url};
|
||||
|
||||
return $narInfo;
|
||||
}
|
||||
|
||||
|
||||
sub getCachedInfoFrom {
|
||||
my ($storePath, $cache) = @_;
|
||||
|
||||
$queryNAR->execute($cache->{id}, basename($storePath));
|
||||
my $res = $queryNAR->fetchrow_hashref();
|
||||
return undef unless defined $res;
|
||||
|
||||
# We may previously have cached this info when signature checking
|
||||
# was disabled. In that case, ignore the cached info.
|
||||
return undef if $requireSignedBinaryCaches && !defined $res->{signedBy};
|
||||
|
||||
return
|
||||
{ url => $res->{url}
|
||||
, compression => $res->{compression}
|
||||
, fileHash => $res->{fileHash}
|
||||
, fileSize => $res->{fileSize}
|
||||
, narHash => $res->{narHash}
|
||||
, narSize => $res->{narSize}
|
||||
, refs => [ split " ", $res->{refs} ]
|
||||
, deriver => $res->{deriver}
|
||||
, signedBy => $res->{signedBy}
|
||||
} if defined $res;
|
||||
}
|
||||
|
||||
|
||||
sub negativeHit {
|
||||
my ($storePath, $cache) = @_;
|
||||
$queryNARExistence->execute($cache->{id}, basename($storePath));
|
||||
my $res = $queryNARExistence->fetchrow_hashref();
|
||||
return defined $res && $res->{exist} == 0 && time() - $res->{timestamp} < $ttlNegativeUse;
|
||||
}
|
||||
|
||||
|
||||
sub positiveHit {
|
||||
my ($storePath, $cache) = @_;
|
||||
return 1 if defined getCachedInfoFrom($storePath, $cache);
|
||||
$queryNARExistence->execute($cache->{id}, basename($storePath));
|
||||
my $res = $queryNARExistence->fetchrow_hashref();
|
||||
return defined $res && $res->{exist} == 1;
|
||||
}
|
||||
|
||||
|
||||
sub expireNegative {
|
||||
return if $didExpiration;
|
||||
$didExpiration = 1;
|
||||
my $time = time();
|
||||
# Round up to the next multiple of the TTL to ensure that we do
|
||||
# expiration only once per time interval. E.g. if $ttlNegative ==
|
||||
# 3600, we expire entries at most once per hour. This is
|
||||
# presumably faster than expiring a few entries per request (and
|
||||
# thus doing a transaction).
|
||||
my $limit = (int($time / $ttlNegative) - 1) * $ttlNegative;
|
||||
$expireNARExistence->execute($limit, 0);
|
||||
print STDERR "expired ", $expireNARExistence->rows, " negative entries\n" if $debug;
|
||||
}
|
||||
|
||||
|
||||
sub printInfo {
|
||||
my ($storePath, $info) = @_;
|
||||
print "$storePath\n";
|
||||
print $info->{deriver} ? "$Nix::Config::storeDir/$info->{deriver}" : "", "\n";
|
||||
print scalar @{$info->{refs}}, "\n";
|
||||
print "$Nix::Config::storeDir/$_\n" foreach @{$info->{refs}};
|
||||
print $info->{fileSize} || 0, "\n";
|
||||
print $info->{narSize} || 0, "\n";
|
||||
}
|
||||
|
||||
|
||||
sub infoUrl {
|
||||
my ($binaryCacheUrl, $storePath) = @_;
|
||||
my $pathHash = substr(basename($storePath), 0, 32);
|
||||
my $infoUrl = "$binaryCacheUrl/$pathHash.narinfo";
|
||||
}
|
||||
|
||||
|
||||
sub printInfoParallel {
|
||||
my @paths = @_;
|
||||
|
||||
# First print all paths for which we have cached info.
|
||||
my @left;
|
||||
foreach my $storePath (@paths) {
|
||||
my $found = 0;
|
||||
foreach my $cache (@caches) {
|
||||
my $info = getCachedInfoFrom($storePath, $cache);
|
||||
if (defined $info) {
|
||||
printInfo($storePath, $info);
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
push @left, $storePath if !$found;
|
||||
}
|
||||
|
||||
return if scalar @left == 0;
|
||||
|
||||
foreach my $cache (@caches) {
|
||||
|
||||
my @left2;
|
||||
%requests = ();
|
||||
foreach my $storePath (@left) {
|
||||
if (negativeHit($storePath, $cache)) {
|
||||
push @left2, $storePath;
|
||||
next;
|
||||
}
|
||||
addRequest($storePath, infoUrl($cache->{url}, $storePath));
|
||||
}
|
||||
|
||||
processRequests;
|
||||
|
||||
foreach my $request (values %requests) {
|
||||
my $info = processNARInfo($request->{storePath}, $cache, $request);
|
||||
if (defined $info) {
|
||||
printInfo($request->{storePath}, $info);
|
||||
} else {
|
||||
push @left2, $request->{storePath};
|
||||
}
|
||||
}
|
||||
|
||||
@left = @left2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub printSubstitutablePaths {
|
||||
my @paths = @_;
|
||||
|
||||
# First look for paths that have cached info.
|
||||
my @left;
|
||||
foreach my $storePath (@paths) {
|
||||
my $found = 0;
|
||||
foreach my $cache (@caches) {
|
||||
next unless $cache->{wantMassQuery};
|
||||
if (positiveHit($storePath, $cache)) {
|
||||
print "$storePath\n";
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
push @left, $storePath if !$found;
|
||||
}
|
||||
|
||||
return if scalar @left == 0;
|
||||
|
||||
# For remaining paths, do HEAD requests.
|
||||
foreach my $cache (@caches) {
|
||||
next unless $cache->{wantMassQuery};
|
||||
my @left2;
|
||||
%requests = ();
|
||||
foreach my $storePath (@left) {
|
||||
if (negativeHit($storePath, $cache)) {
|
||||
push @left2, $storePath;
|
||||
next;
|
||||
}
|
||||
addRequest($storePath, infoUrl($cache->{url}, $storePath), 1);
|
||||
}
|
||||
|
||||
processRequests;
|
||||
|
||||
foreach my $request (values %requests) {
|
||||
if ($request->{result} != 0) {
|
||||
if ($request->{result} != 37 && $request->{httpStatus} != 404 && $request->{httpStatus} != 403) {
|
||||
print STDERR "could not check ‘$request->{url}’ (" .
|
||||
($request->{result} != 0 ? "Curl error $request->{result}" : "HTTP status $request->{httpStatus}") . ")\n";
|
||||
} else {
|
||||
$insertNARExistence->execute($cache->{id}, basename($request->{storePath}), 0, time())
|
||||
if shouldCache $request->{url};
|
||||
}
|
||||
push @left2, $request->{storePath};
|
||||
} else {
|
||||
$insertNARExistence->execute($cache->{id}, basename($request->{storePath}), 1, time())
|
||||
if shouldCache $request->{url};
|
||||
print "$request->{storePath}\n";
|
||||
}
|
||||
}
|
||||
|
||||
@left = @left2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub downloadBinary {
|
||||
my ($storePath, $destPath) = @_;
|
||||
|
||||
foreach my $cache (@caches) {
|
||||
my $info = getCachedInfoFrom($storePath, $cache);
|
||||
|
||||
unless (defined $info) {
|
||||
next if negativeHit($storePath, $cache);
|
||||
my $request = addRequest($storePath, infoUrl($cache->{url}, $storePath));
|
||||
processRequests;
|
||||
$info = processNARInfo($storePath, $cache, $request);
|
||||
}
|
||||
|
||||
next unless defined $info;
|
||||
|
||||
my $decompressor;
|
||||
if ($info->{compression} eq "bzip2") { $decompressor = "| $Nix::Config::bzip2 -d"; }
|
||||
elsif ($info->{compression} eq "xz") { $decompressor = "| $Nix::Config::xz -d"; }
|
||||
elsif ($info->{compression} eq "none") { $decompressor = ""; }
|
||||
else {
|
||||
print STDERR "unknown compression method ‘$info->{compression}’\n";
|
||||
next;
|
||||
}
|
||||
my $url = "$cache->{url}/$info->{url}"; # FIXME: handle non-relative URLs
|
||||
die if $requireSignedBinaryCaches && !defined $info->{signedBy};
|
||||
print STDERR "\n*** Downloading ‘$url’ ", ($requireSignedBinaryCaches ? "(signed by ‘$info->{signedBy}’) " : ""), "to ‘$storePath’...\n";
|
||||
checkURL $url;
|
||||
if (system("$Nix::Config::curl --fail --location --connect-timeout $curlConnectTimeout -A '$userAgent' '$url' $decompressor | $Nix::Config::binDir/nix-store --restore $destPath") != 0) {
|
||||
warn "download of ‘$url’ failed" . ($! ? ": $!" : "") . "\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Tell Nix about the expected hash so it can verify it.
|
||||
die unless defined $info->{narHash} && $info->{narHash} ne "";
|
||||
print "$info->{narHash}\n";
|
||||
|
||||
print STDERR "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
print STDERR "could not download ‘$storePath’ from any binary cache\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
|
||||
# Bail out right away if binary caches are disabled.
|
||||
exit 0 if
|
||||
($Nix::Config::config{"use-binary-caches"} // "true") eq "false" ||
|
||||
($Nix::Config::config{"untrusted-use-binary-caches"} // "true") eq "false";
|
||||
print "\n";
|
||||
flush STDOUT;
|
||||
|
||||
initCache();
|
||||
|
||||
|
||||
if ($ARGV[0] eq "--query") {
|
||||
|
||||
while (<STDIN>) {
|
||||
getAvailableCaches;
|
||||
chomp;
|
||||
my ($cmd, @args) = split " ", $_;
|
||||
|
||||
if ($cmd eq "have") {
|
||||
print STDERR "checking binary caches for existence of @args\n" if $debug;
|
||||
printSubstitutablePaths(@args);
|
||||
print "\n";
|
||||
}
|
||||
|
||||
elsif ($cmd eq "info") {
|
||||
print STDERR "checking binary caches for info on @args\n" if $debug;
|
||||
printInfoParallel(@args);
|
||||
print "\n";
|
||||
}
|
||||
|
||||
else { die "unknown command ‘$cmd’"; }
|
||||
|
||||
flush STDOUT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
elsif ($ARGV[0] eq "--substitute") {
|
||||
my $storePath = $ARGV[1] or die;
|
||||
my $destPath = $ARGV[2] or die;
|
||||
getAvailableCaches;
|
||||
downloadBinary($storePath, $destPath);
|
||||
}
|
||||
|
||||
else {
|
||||
die;
|
||||
}
|
||||
@@ -1,376 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use utf8;
|
||||
use strict;
|
||||
use Nix::Config;
|
||||
use Nix::Manifest;
|
||||
use Nix::Store;
|
||||
use Nix::Utils;
|
||||
use POSIX qw(strftime);
|
||||
|
||||
STDOUT->autoflush(1);
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
my $logFile = "$Nix::Config::logDir/downloads";
|
||||
|
||||
# For queries, skip expensive calls to nix-hash etc. We're just
|
||||
# estimating the expected download size.
|
||||
my $fast = 1;
|
||||
|
||||
my $curl = "$Nix::Config::curl --fail --location";
|
||||
|
||||
|
||||
# Open the manifest cache and update it if necessary.
|
||||
my $dbh = updateManifestDB();
|
||||
exit 0 unless defined $dbh; # exit if there are no manifests
|
||||
print "\n";
|
||||
|
||||
|
||||
# $hashCache->{$algo}->{$path} yields the $algo-hash of $path.
|
||||
my $hashCache;
|
||||
|
||||
|
||||
sub parseHash {
|
||||
my $hash = shift;
|
||||
if ($hash =~ /^(.+):(.+)$/) {
|
||||
return ($1, $2);
|
||||
} else {
|
||||
return ("md5", $hash);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Compute the most efficient sequence of downloads to produce the
|
||||
# given path.
|
||||
sub computeSmallestDownload {
|
||||
my $targetPath = shift;
|
||||
|
||||
# Build a graph of all store paths that might contribute to the
|
||||
# construction of $targetPath, and the special node "start". The
|
||||
# edges are either patch operations, or downloads of full NAR
|
||||
# files. The latter edges only occur between "start" and a store
|
||||
# path.
|
||||
my %graph;
|
||||
|
||||
$graph{"start"} = {d => 0, pred => undef, edges => []};
|
||||
|
||||
my @queue = ();
|
||||
my $queueFront = 0;
|
||||
my %done;
|
||||
|
||||
sub addNode {
|
||||
my $graph = shift;
|
||||
my $u = shift;
|
||||
$$graph{$u} = {d => 999999999999, pred => undef, edges => []}
|
||||
unless defined $$graph{$u};
|
||||
}
|
||||
|
||||
sub addEdge {
|
||||
my $graph = shift;
|
||||
my $u = shift;
|
||||
my $v = shift;
|
||||
my $w = shift;
|
||||
my $type = shift;
|
||||
my $info = shift;
|
||||
addNode $graph, $u;
|
||||
push @{$$graph{$u}->{edges}},
|
||||
{weight => $w, start => $u, end => $v, type => $type, info => $info};
|
||||
my $n = scalar @{$$graph{$u}->{edges}};
|
||||
}
|
||||
|
||||
push @queue, $targetPath;
|
||||
|
||||
while ($queueFront < scalar @queue) {
|
||||
my $u = $queue[$queueFront++];
|
||||
next if defined $done{$u};
|
||||
$done{$u} = 1;
|
||||
|
||||
addNode \%graph, $u;
|
||||
|
||||
# If the path already exists, it has distance 0 from the
|
||||
# "start" node.
|
||||
if (isValidPath($u)) {
|
||||
addEdge \%graph, "start", $u, 0, "present", undef;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
# Add patch edges.
|
||||
my $patchList = $dbh->selectall_arrayref(
|
||||
"select * from Patches where storePath = ?",
|
||||
{ Slice => {} }, $u);
|
||||
|
||||
foreach my $patch (@{$patchList}) {
|
||||
if (isValidPath($patch->{basePath})) {
|
||||
my ($baseHashAlgo, $baseHash) = parseHash $patch->{baseHash};
|
||||
|
||||
my $hash = $hashCache->{$baseHashAlgo}->{$patch->{basePath}};
|
||||
if (!defined $hash) {
|
||||
$hash = $fast && $baseHashAlgo eq "sha256"
|
||||
? queryPathHash($patch->{basePath})
|
||||
: hashPath($baseHashAlgo, $baseHashAlgo ne "md5", $patch->{basePath});
|
||||
$hash =~ s/.*://;
|
||||
$hashCache->{$baseHashAlgo}->{$patch->{basePath}} = $hash;
|
||||
}
|
||||
|
||||
next if $hash ne $baseHash;
|
||||
}
|
||||
push @queue, $patch->{basePath};
|
||||
addEdge \%graph, $patch->{basePath}, $u, $patch->{size}, "patch", $patch;
|
||||
}
|
||||
|
||||
# Add NAR file edges to the start node.
|
||||
my $narFileList = $dbh->selectall_arrayref(
|
||||
"select * from NARs where storePath = ?",
|
||||
{ Slice => {} }, $u);
|
||||
|
||||
foreach my $narFile (@{$narFileList}) {
|
||||
# !!! how to handle files whose size is not known in advance?
|
||||
# For now, assume some arbitrary size (1 GB).
|
||||
# This has the side-effect of preferring non-Hydra downloads.
|
||||
addEdge \%graph, "start", $u, ($narFile->{size} || 1000000000), "narfile", $narFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Run Dijkstra's shortest path algorithm to determine the shortest
|
||||
# sequence of download and/or patch actions that will produce
|
||||
# $targetPath.
|
||||
|
||||
my @todo = keys %graph;
|
||||
|
||||
while (scalar @todo > 0) {
|
||||
|
||||
# Remove the closest element from the todo list.
|
||||
# !!! inefficient, use a priority queue
|
||||
@todo = sort { -($graph{$a}->{d} <=> $graph{$b}->{d}) } @todo;
|
||||
my $u = pop @todo;
|
||||
|
||||
my $u_ = $graph{$u};
|
||||
|
||||
foreach my $edge (@{$u_->{edges}}) {
|
||||
my $v_ = $graph{$edge->{end}};
|
||||
if ($v_->{d} > $u_->{d} + $edge->{weight}) {
|
||||
$v_->{d} = $u_->{d} + $edge->{weight};
|
||||
# Store the edge; to edge->start is actually the
|
||||
# predecessor.
|
||||
$v_->{pred} = $edge;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Retrieve the shortest path from "start" to $targetPath.
|
||||
my @path = ();
|
||||
my $cur = $targetPath;
|
||||
return () unless defined $graph{$targetPath}->{pred};
|
||||
while ($cur ne "start") {
|
||||
push @path, $graph{$cur}->{pred};
|
||||
$cur = $graph{$cur}->{pred}->{start};
|
||||
}
|
||||
|
||||
return @path;
|
||||
}
|
||||
|
||||
|
||||
# Parse the arguments.
|
||||
|
||||
if ($ARGV[0] eq "--query") {
|
||||
|
||||
while (<STDIN>) {
|
||||
chomp;
|
||||
my ($cmd, @args) = split " ", $_;
|
||||
|
||||
if ($cmd eq "have") {
|
||||
foreach my $storePath (@args) {
|
||||
print "$storePath\n" if scalar @{$dbh->selectcol_arrayref("select 1 from NARs where storePath = ?", {}, $storePath)} > 0;
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
elsif ($cmd eq "info") {
|
||||
foreach my $storePath (@args) {
|
||||
|
||||
my $infos = $dbh->selectall_arrayref(
|
||||
"select * from NARs where storePath = ?",
|
||||
{ Slice => {} }, $storePath);
|
||||
|
||||
next unless scalar @{$infos} > 0;
|
||||
my $info = @{$infos}[0];
|
||||
|
||||
print "$storePath\n";
|
||||
print "$info->{deriver}\n";
|
||||
my @references = split " ", $info->{refs};
|
||||
print scalar @references, "\n";
|
||||
print "$_\n" foreach @references;
|
||||
|
||||
my @path = computeSmallestDownload $storePath;
|
||||
|
||||
my $downloadSize = 0;
|
||||
while (scalar @path > 0) {
|
||||
my $edge = pop @path;
|
||||
my $u = $edge->{start};
|
||||
my $v = $edge->{end};
|
||||
if ($edge->{type} eq "patch") {
|
||||
$downloadSize += $edge->{info}->{size} || 0;
|
||||
}
|
||||
elsif ($edge->{type} eq "narfile") {
|
||||
$downloadSize += $edge->{info}->{size} || 0;
|
||||
}
|
||||
}
|
||||
|
||||
print "$downloadSize\n";
|
||||
|
||||
my $narSize = $info->{narSize} || 0;
|
||||
print "$narSize\n";
|
||||
}
|
||||
|
||||
print "\n";
|
||||
}
|
||||
|
||||
else { die "unknown command ‘$cmd’"; }
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
elsif ($ARGV[0] ne "--substitute") {
|
||||
die;
|
||||
}
|
||||
|
||||
|
||||
die unless scalar @ARGV == 3;
|
||||
my $targetPath = $ARGV[1];
|
||||
my $destPath = $ARGV[2];
|
||||
$fast = 0;
|
||||
|
||||
|
||||
# Create a temporary directory.
|
||||
my $tmpDir = mkTempDir("nix-download");
|
||||
|
||||
my $tmpNar = "$tmpDir/nar";
|
||||
my $tmpNar2 = "$tmpDir/nar2";
|
||||
|
||||
|
||||
open LOGFILE, ">>$logFile" or die "cannot open log file $logFile";
|
||||
|
||||
my $date = strftime ("%F %H:%M:%S UTC", gmtime (time));
|
||||
print LOGFILE "$$ get $targetPath $date\n";
|
||||
|
||||
print STDERR "\n*** Trying to download/patch ‘$targetPath’\n";
|
||||
|
||||
|
||||
# Compute the shortest path.
|
||||
my @path = computeSmallestDownload $targetPath;
|
||||
die "don't know how to produce $targetPath\n" if scalar @path == 0;
|
||||
|
||||
|
||||
# We don't need the manifest anymore, so close it as an optimisation:
|
||||
# if we still have SQLite locks blocking other processes (we
|
||||
# shouldn't), this gets rid of them.
|
||||
$dbh->disconnect;
|
||||
|
||||
|
||||
# Traverse the shortest path, perform the actions described by the
|
||||
# edges.
|
||||
my $curStep = 1;
|
||||
my $maxStep = scalar @path;
|
||||
|
||||
my $finalNarHash;
|
||||
|
||||
while (scalar @path > 0) {
|
||||
my $edge = pop @path;
|
||||
my $u = $edge->{start};
|
||||
my $v = $edge->{end};
|
||||
|
||||
print STDERR "\n*** Step $curStep/$maxStep: ";
|
||||
|
||||
if ($edge->{type} eq "present") {
|
||||
print STDERR "using already present path ‘$v’\n";
|
||||
print LOGFILE "$$ present $v\n";
|
||||
|
||||
if ($curStep < $maxStep) {
|
||||
# Since this is not the last step, the path will be used
|
||||
# as a base to one or more patches. So turn the base path
|
||||
# into a NAR archive, to which we can apply the patch.
|
||||
print STDERR " packing base path...\n";
|
||||
system("$Nix::Config::binDir/nix-store --dump $v > $tmpNar") == 0
|
||||
or die "cannot dump ‘$v’";
|
||||
}
|
||||
}
|
||||
|
||||
elsif ($edge->{type} eq "patch") {
|
||||
my $patch = $edge->{info};
|
||||
print STDERR "applying patch ‘$patch->{url}’ to ‘$u’ to create ‘$v’\n";
|
||||
|
||||
print LOGFILE "$$ patch $patch->{url} $patch->{size} $patch->{baseHash} $u $v\n";
|
||||
|
||||
# Download the patch.
|
||||
print STDERR " downloading patch...\n";
|
||||
my $patchPath = "$tmpDir/patch";
|
||||
checkURL $patch->{url};
|
||||
system("$curl '$patch->{url}' -o $patchPath") == 0
|
||||
or die "cannot download patch ‘$patch->{url}’\n";
|
||||
|
||||
# Apply the patch to the NAR archive produced in step 1 (for
|
||||
# the already present path) or a later step (for patch sequences).
|
||||
print STDERR " applying patch...\n";
|
||||
system("$Nix::Config::libexecDir/nix/bspatch $tmpNar $tmpNar2 $patchPath") == 0
|
||||
or die "cannot apply patch ‘$patchPath’ to $tmpNar\n";
|
||||
|
||||
if ($curStep < $maxStep) {
|
||||
# The archive will be used as the base of the next patch.
|
||||
rename "$tmpNar2", "$tmpNar" or die "cannot rename NAR archive: $!";
|
||||
} else {
|
||||
# This was the last patch. Unpack the final NAR archive
|
||||
# into the target path.
|
||||
print STDERR " unpacking patched archive...\n";
|
||||
system("$Nix::Config::binDir/nix-store --restore $destPath < $tmpNar2") == 0
|
||||
or die "cannot unpack $tmpNar2 to ‘$v’\n";
|
||||
}
|
||||
|
||||
$finalNarHash = $patch->{narHash};
|
||||
}
|
||||
|
||||
elsif ($edge->{type} eq "narfile") {
|
||||
my $narFile = $edge->{info};
|
||||
print STDERR "downloading ‘$narFile->{url}’ to ‘$v’\n";
|
||||
|
||||
my $size = $narFile->{size} || -1;
|
||||
print LOGFILE "$$ narfile $narFile->{url} $size $v\n";
|
||||
|
||||
checkURL $narFile->{url};
|
||||
|
||||
my $decompressor =
|
||||
$narFile->{compressionType} eq "bzip2" ? "| $Nix::Config::bzip2 -d" :
|
||||
$narFile->{compressionType} eq "xz" ? "| $Nix::Config::xz -d" :
|
||||
$narFile->{compressionType} eq "none" ? "" :
|
||||
die "unknown compression type ‘$narFile->{compressionType}’";
|
||||
|
||||
if ($curStep < $maxStep) {
|
||||
# The archive will be used a base to a patch.
|
||||
system("$curl '$narFile->{url}' $decompressor > $tmpNar") == 0
|
||||
or die "cannot download and unpack ‘$narFile->{url}’ to ‘$v’\n";
|
||||
} else {
|
||||
# Unpack the archive to the target path.
|
||||
system("$curl '$narFile->{url}' $decompressor | $Nix::Config::binDir/nix-store --restore '$destPath'") == 0
|
||||
or die "cannot download and unpack ‘$narFile->{url}’ to ‘$v’\n";
|
||||
}
|
||||
|
||||
$finalNarHash = $narFile->{narHash};
|
||||
}
|
||||
|
||||
$curStep++;
|
||||
}
|
||||
|
||||
|
||||
# Tell Nix about the expected hash so it can verify it.
|
||||
die "cannot check integrity of the downloaded path since its hash is not known\n"
|
||||
unless defined $finalNarHash;
|
||||
print "$finalNarHash\n";
|
||||
|
||||
|
||||
print STDERR "\n";
|
||||
print LOGFILE "$$ success\n";
|
||||
close LOGFILE;
|
||||
@@ -1,79 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use strict;
|
||||
use Nix::Utils;
|
||||
use Nix::Config;
|
||||
|
||||
|
||||
sub readProc {
|
||||
return unless -d "/proc";
|
||||
|
||||
opendir DIR, "/proc" or return;
|
||||
|
||||
foreach my $name (readdir DIR) {
|
||||
next unless $name =~ /^\d+$/;
|
||||
|
||||
my $process = "/proc/$name";
|
||||
|
||||
#print STDERR "=== $process\n";
|
||||
|
||||
my $target;
|
||||
print "$target\n" if $target = readlink "$process/exe";
|
||||
print "$target\n" if $target = readlink "$process/cwd";
|
||||
|
||||
if (opendir FDS, "$process/fd") {
|
||||
foreach my $name (readdir FDS) {
|
||||
$target = readlink "$process/fd/$name";
|
||||
print "$target\n" if $target && substr($target, 0, 1) eq "/";
|
||||
}
|
||||
closedir FDS;
|
||||
}
|
||||
|
||||
if (open MAP, "<$process/maps") {
|
||||
while (<MAP>) {
|
||||
next unless /^ \s* \S+ \s+ \S+ \s+ \S+ \s+ \S+ \s+ \S+ \s+ (\/\S+) \s* $/x;
|
||||
print "$1\n";
|
||||
}
|
||||
close MAP;
|
||||
}
|
||||
|
||||
# Get all store paths that appear in the environment of this process.
|
||||
eval {
|
||||
my $env = Nix::Utils::readFile "$process/environ";
|
||||
my @matches = $env =~ /\Q$Nix::Config::storeDir\E\/[0-9a-z]+[0-9a-zA-Z\+\-\._\?=]*/g;
|
||||
print "$_\n" foreach @matches;
|
||||
}
|
||||
}
|
||||
|
||||
closedir DIR;
|
||||
}
|
||||
|
||||
|
||||
sub lsof {
|
||||
return unless open LSOF, "lsof -n -w -F n 2> /dev/null |";
|
||||
|
||||
while (<LSOF>) {
|
||||
next unless /^n (\/ .*)$/x;
|
||||
print $1, "\n";
|
||||
}
|
||||
|
||||
close LSOF;
|
||||
}
|
||||
|
||||
|
||||
readProc;
|
||||
lsof;
|
||||
|
||||
|
||||
sub printFile {
|
||||
my ($fn) = @_;
|
||||
if (-e $fn) {
|
||||
print Nix::Utils::readFile($fn), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# This is rather NixOS-specific, so it probably shouldn't be here.
|
||||
printFile "/proc/sys/kernel/modprobe";
|
||||
printFile "/proc/sys/kernel/fbsplash";
|
||||
printFile "/proc/sys/kernel/poweroff_cmd";
|
||||
819
scripts/install-darwin-multi-user.sh
Normal file
819
scripts/install-darwin-multi-user.sh
Normal file
@@ -0,0 +1,819 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
# Sourced from:
|
||||
# - https://github.com/LnL7/nix-darwin/blob/8c29d0985d74b4a990238497c47a2542a5616b3c/bootstrap.sh
|
||||
# - https://gist.github.com/expipiplus1/e571ce88c608a1e83547c918591b149f/ac504c6c1b96e65505fbda437a28ce563408ecb0
|
||||
# - https://github.com/NixOS/nixos-org-configurations/blob/a122f418797713d519aadf02e677fce0dc1cb446/delft/scripts/nix-mac-installer.sh
|
||||
# - https://github.com/matthewbauer/macNixOS/blob/f6045394f9153edea417be90c216788e754feaba/install-macNixOS.sh
|
||||
# - https://gist.github.com/LnL7/9717bd6cdcb30b086fd7f2093e5f8494/86b26f852ce563e973acd30f796a9a416248c34a
|
||||
#
|
||||
# however tracking which bits came from which would be impossible.
|
||||
|
||||
readonly ESC='\033[0m'
|
||||
readonly BOLD='\033[38;1m'
|
||||
readonly BLUE='\033[38;34m'
|
||||
readonly BLUE_UL='\033[38;4;34m'
|
||||
readonly GREEN='\033[38;32m'
|
||||
readonly GREEN_UL='\033[38;4;32m'
|
||||
readonly RED='\033[38;31m'
|
||||
readonly RED_UL='\033[38;4;31m'
|
||||
readonly YELLOW='\033[38;33m'
|
||||
readonly YELLOW_UL='\033[38;4;33m'
|
||||
|
||||
readonly CORES=$(sysctl -n hw.ncpu)
|
||||
readonly NIX_USER_COUNT="$CORES"
|
||||
readonly NIX_BUILD_GROUP_ID="30000"
|
||||
readonly NIX_BUILD_GROUP_NAME="nixbld"
|
||||
readonly NIX_FIRST_BUILD_UID="30001"
|
||||
# Please don't change this. We don't support it, because the
|
||||
# default shell profile that comes with Nix doesn't support it.
|
||||
readonly NIX_ROOT="/nix"
|
||||
readonly PLIST_DEST=/Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
||||
|
||||
readonly PROFILE_TARGETS=("/etc/bashrc" "/etc/zshrc")
|
||||
readonly PROFILE_BACKUP_SUFFIX=".backup-before-nix"
|
||||
readonly PROFILE_NIX_FILE="$NIX_ROOT/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"
|
||||
|
||||
readonly NIX_INSTALLED_NIX="@nix@"
|
||||
readonly NIX_INSTALLED_CACERT="@cacert@"
|
||||
readonly EXTRACTED_NIX_PATH="$(dirname "$0")"
|
||||
|
||||
readonly ROOT_HOME="/var/root"
|
||||
|
||||
if [ -t 0 ]; then
|
||||
readonly IS_HEADLESS='no'
|
||||
else
|
||||
readonly IS_HEADLESS='yes'
|
||||
fi
|
||||
|
||||
headless() {
|
||||
if [ "$IS_HEADLESS" = "yes" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
contactme() {
|
||||
echo "We'd love to help if you need it."
|
||||
echo ""
|
||||
echo "If you can, open an issue at https://github.com/nixos/nix/issues"
|
||||
echo ""
|
||||
echo "Or feel free to contact the team,"
|
||||
echo " - on IRC #nixos on irc.freenode.net"
|
||||
echo " - on twitter @nixos_org"
|
||||
}
|
||||
|
||||
uninstall_directions() {
|
||||
subheader "Uninstalling nix:"
|
||||
local step=0
|
||||
|
||||
if [ -e "$PLIST_DEST" ]; then
|
||||
step=$((step + 1))
|
||||
cat <<EOF
|
||||
$step. Delete $PLIST_DEST
|
||||
|
||||
sudo launchctl unload $PLIST_DEST
|
||||
sudo rm $PLIST_DEST
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
for profile_target in "${PROFILE_TARGETS[@]}"; do
|
||||
if [ -e "$profile_target" ] && [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then
|
||||
step=$((step + 1))
|
||||
cat <<EOF
|
||||
$step. Restore $profile_target$PROFILE_BACKUP_SUFFIX back to $profile_target
|
||||
|
||||
sudo mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
|
||||
|
||||
(after this one, you may need to re-open any terminals that were
|
||||
opened while it existed.)
|
||||
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
||||
step=$((step + 1))
|
||||
cat <<EOF
|
||||
$step. Delete the files Nix added to your system:
|
||||
|
||||
sudo rm -rf /etc/nix $NIX_ROOT $ROOT_HOME/.nix-profile $ROOT_HOME/.nix-defexpr $ROOT_HOME/.nix-channels $HOME/.nix-profile $HOME/.nix-defexpr $HOME/.nix-channels
|
||||
|
||||
and that is it.
|
||||
|
||||
EOF
|
||||
|
||||
}
|
||||
|
||||
nix_user_for_core() {
|
||||
printf "nixbld%d" "$1"
|
||||
}
|
||||
|
||||
nix_uid_for_core() {
|
||||
echo $((NIX_FIRST_BUILD_UID + $1 - 1))
|
||||
}
|
||||
|
||||
dsclattr() {
|
||||
/usr/bin/dscl . -read "$1" \
|
||||
| awk "/$2/ { print \$2 }"
|
||||
}
|
||||
|
||||
_textout() {
|
||||
echo -en "$1"
|
||||
shift
|
||||
if [ "$*" = "" ]; then
|
||||
cat
|
||||
else
|
||||
echo "$@"
|
||||
fi
|
||||
echo -en "$ESC"
|
||||
}
|
||||
|
||||
header() {
|
||||
follow="---------------------------------------------------------"
|
||||
header=$(echo "---- $* $follow$follow$follow" | head -c 80)
|
||||
echo ""
|
||||
_textout "$BLUE" "$header"
|
||||
}
|
||||
|
||||
warningheader() {
|
||||
follow="---------------------------------------------------------"
|
||||
header=$(echo "---- $* $follow$follow$follow" | head -c 80)
|
||||
echo ""
|
||||
_textout "$RED" "$header"
|
||||
}
|
||||
|
||||
subheader() {
|
||||
echo ""
|
||||
_textout "$BLUE_UL" "$*"
|
||||
}
|
||||
|
||||
row() {
|
||||
printf "$BOLD%s$ESC:\\t%s\\n" "$1" "$2"
|
||||
}
|
||||
|
||||
task() {
|
||||
echo ""
|
||||
ok "~~> $1"
|
||||
}
|
||||
|
||||
bold() {
|
||||
echo "$BOLD$*$ESC"
|
||||
}
|
||||
|
||||
ok() {
|
||||
_textout "$GREEN" "$@"
|
||||
}
|
||||
|
||||
warning() {
|
||||
warningheader "warning!"
|
||||
cat
|
||||
echo ""
|
||||
}
|
||||
|
||||
failure() {
|
||||
header "oh no!"
|
||||
_textout "$RED" "$@"
|
||||
echo ""
|
||||
_textout "$RED" "$(contactme)"
|
||||
trap finish_cleanup EXIT
|
||||
exit 1
|
||||
}
|
||||
|
||||
ui_confirm() {
|
||||
_textout "$GREEN$GREEN_UL" "$1"
|
||||
|
||||
if headless; then
|
||||
echo "No TTY, assuming you would say yes :)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local prompt="[y/n] "
|
||||
echo -n "$prompt"
|
||||
while read -r y; do
|
||||
if [ "$y" = "y" ]; then
|
||||
echo ""
|
||||
return 0
|
||||
elif [ "$y" = "n" ]; then
|
||||
echo ""
|
||||
return 1
|
||||
else
|
||||
_textout "$RED" "Sorry, I didn't understand. I can only understand answers of y or n"
|
||||
echo -n "$prompt"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
return 1
|
||||
}
|
||||
|
||||
__sudo() {
|
||||
local expl="$1"
|
||||
local cmd="$2"
|
||||
shift
|
||||
header "sudo execution"
|
||||
|
||||
echo "I am executing:"
|
||||
echo ""
|
||||
printf " $ sudo %s\\n" "$cmd"
|
||||
echo ""
|
||||
echo "$expl"
|
||||
echo ""
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_sudo() {
|
||||
local expl="$1"
|
||||
shift
|
||||
if ! headless; then
|
||||
__sudo "$expl" "$*"
|
||||
fi
|
||||
sudo "$@"
|
||||
}
|
||||
|
||||
|
||||
readonly SCRATCH=$(mktemp -d -t tmp.XXXXXXXXXX)
|
||||
function finish_cleanup {
|
||||
rm -rf "$SCRATCH"
|
||||
}
|
||||
|
||||
function finish_fail {
|
||||
finish_cleanup
|
||||
|
||||
failure <<EOF
|
||||
Jeeze, something went wrong. If you can take all the output and open
|
||||
an issue, we'd love to fix the problem so nobody else has this issue.
|
||||
|
||||
:(
|
||||
EOF
|
||||
}
|
||||
trap finish_fail EXIT
|
||||
|
||||
function finish_success {
|
||||
finish_cleanup
|
||||
|
||||
ok "Alright! We're done!"
|
||||
cat <<EOF
|
||||
|
||||
Before Nix will work in your existing shells, you'll need to close
|
||||
them and open them again. Other than that, you should be ready to go.
|
||||
|
||||
Try it! Open a new terminal, and type:
|
||||
|
||||
$ nix-shell -p nix-info --run "nix-info -m"
|
||||
|
||||
Thank you for using this installer. If you have any feedback, don't
|
||||
hesitate:
|
||||
|
||||
$(contactme)
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
validate_starting_assumptions() {
|
||||
if [ "$(uname -s)" != "Darwin" ]; then
|
||||
failure "This script is for use with macOS!"
|
||||
fi
|
||||
|
||||
if [ $EUID -eq 0 ]; then
|
||||
failure <<EOF
|
||||
Please do not run this script with root privileges. We will call sudo
|
||||
when we need to.
|
||||
EOF
|
||||
fi
|
||||
|
||||
if type nix-env 2> /dev/null >&2; then
|
||||
failure <<EOF
|
||||
Nix already appears to be installed, and this tool assumes it is
|
||||
_not_ yet installed.
|
||||
|
||||
$(uninstall_directions)
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "${NIX_REMOTE:-}" != "" ]; then
|
||||
failure <<EOF
|
||||
For some reason, \$NIX_REMOTE is set. It really should not be set
|
||||
before this installer runs, and it hints that Nix is currently
|
||||
installed. Please delete the old Nix installation and start again.
|
||||
|
||||
Note: You might need to close your shell window and open a new shell
|
||||
to clear the variable.
|
||||
EOF
|
||||
fi
|
||||
|
||||
if echo "${SSL_CERT_FILE:-}" | grep -qE "(nix/var/nix|nix-profile)"; then
|
||||
failure <<EOF
|
||||
It looks like \$SSL_CERT_FILE is set to a path that used to be part of
|
||||
the old Nix installation. Please unset that variable and try again:
|
||||
|
||||
$ unset SSL_CERT_FILE
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
for file in ~/.bash_profile ~/.bash_login ~/.profile ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin; do
|
||||
if [ -f "$file" ]; then
|
||||
if grep -l "^[^#].*.nix-profile" "$file"; then
|
||||
failure <<EOF
|
||||
I found a reference to a ".nix-profile" in $file.
|
||||
This has a high chance of breaking a new nix installation. It was most
|
||||
likely put there by a previous Nix installer.
|
||||
|
||||
Please remove this reference and try running this again. You should
|
||||
also look for similar references in:
|
||||
|
||||
- ~/.bash_profile
|
||||
- ~/.bash_login
|
||||
- ~/.profile
|
||||
|
||||
or other shell init files that you may have.
|
||||
|
||||
$(uninstall_directions)
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -d /nix ]; then
|
||||
failure <<EOF
|
||||
There are some relics of a previous installation of Nix at /nix, and
|
||||
this scripts assumes Nix is _not_ yet installed. Please delete the old
|
||||
Nix installation and start again.
|
||||
|
||||
$(uninstall_directions)
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ -d /etc/nix ]; then
|
||||
failure <<EOF
|
||||
There are some relics of a previous installation of Nix at /etc/nix, and
|
||||
this scripts assumes Nix is _not_ yet installed. Please delete the old
|
||||
Nix installation and start again.
|
||||
|
||||
$(uninstall_directions)
|
||||
EOF
|
||||
fi
|
||||
|
||||
for profile_target in "${PROFILE_TARGETS[@]}"; do
|
||||
if [ -e "$profile_target$PROFILE_BACKUP_SUFFIX" ]; then
|
||||
failure <<EOF
|
||||
When this script runs, it backs up the current $profile_target to
|
||||
$profile_target$PROFILE_BACKUP_SUFFIX. This backup file already exists, though.
|
||||
|
||||
Please follow these instructions to clean up the old backup file:
|
||||
|
||||
1. Copy $profile_target and $profile_target$PROFILE_BACKUP_SUFFIX to another place, just
|
||||
in case.
|
||||
|
||||
2. Take care to make sure that $profile_target$PROFILE_BACKUP_SUFFIX doesn't look like
|
||||
it has anything nix-related in it. If it does, something is probably
|
||||
quite wrong. Please open an issue or get in touch immediately.
|
||||
|
||||
3. Take care to make sure that $profile_target doesn't look like it has
|
||||
anything nix-related in it. If it does, and $profile_target _did not_,
|
||||
run:
|
||||
|
||||
$ /usr/bin/sudo /bin/mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
|
||||
|
||||
and try again.
|
||||
EOF
|
||||
fi
|
||||
|
||||
if grep -qi "nix" "$profile_target"; then
|
||||
failure <<EOF
|
||||
It looks like $profile_target already has some Nix configuration in
|
||||
there. There should be no reason to run this again. If you're having
|
||||
trouble, please open an issue.
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
|
||||
danger_paths=("$ROOT_HOME/.nix-defexpr" "$ROOT_HOME/.nix-channels" "$ROOT_HOME/.nix-profile")
|
||||
for danger_path in "${danger_paths[@]}"; do
|
||||
if _sudo "making sure that $danger_path doesn't exist" \
|
||||
test -e "$danger_path"; then
|
||||
failure <<EOF
|
||||
I found a file at $danger_path, which is a relic of a previous
|
||||
installation. You must first delete this file before continuing.
|
||||
|
||||
$(uninstall_directions)
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
setup_report() {
|
||||
header "hardware report"
|
||||
row " Cores" "$CORES"
|
||||
|
||||
header "Nix config report"
|
||||
row " Temp Dir" "$SCRATCH"
|
||||
row " Nix Root" "$NIX_ROOT"
|
||||
row " Build Users" "$NIX_USER_COUNT"
|
||||
row " Build Group ID" "$NIX_BUILD_GROUP_ID"
|
||||
row "Build Group Name" "$NIX_BUILD_GROUP_NAME"
|
||||
if [ "${ALLOW_PREEXISTING_INSTALLATION:-}" != "" ]; then
|
||||
row "Preexisting Install" "Allowed"
|
||||
fi
|
||||
|
||||
subheader "build users:"
|
||||
|
||||
row " Username" "UID"
|
||||
for i in $(seq 1 "$NIX_USER_COUNT"); do
|
||||
row " $(nix_user_for_core "$i")" "$(nix_uid_for_core "$i")"
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
create_build_group() {
|
||||
local primary_group_id
|
||||
|
||||
task "Setting up the build group $NIX_BUILD_GROUP_NAME"
|
||||
if ! /usr/bin/dscl . -read "/Groups/$NIX_BUILD_GROUP_NAME" > /dev/null 2>&1; then
|
||||
_sudo "Create the Nix build group, $NIX_BUILD_GROUP_NAME" \
|
||||
/usr/sbin/dseditgroup -o create \
|
||||
-r "Nix build group for nix-daemon" \
|
||||
-i "$NIX_BUILD_GROUP_ID" \
|
||||
"$NIX_BUILD_GROUP_NAME" >&2
|
||||
row " Created" "Yes"
|
||||
else
|
||||
primary_group_id=$(dsclattr "/Groups/$NIX_BUILD_GROUP_NAME" "PrimaryGroupID")
|
||||
if [ "$primary_group_id" -ne "$NIX_BUILD_GROUP_ID" ]; then
|
||||
failure <<EOF
|
||||
It seems the build group $NIX_BUILD_GROUP_NAME already exists, but
|
||||
with the UID $primary_group_id. This script can't really handle
|
||||
that right now, so I'm going to give up.
|
||||
|
||||
You can fix this by editing this script and changing the
|
||||
NIX_BUILD_GROUP_ID variable near the top to from $NIX_BUILD_GROUP_ID
|
||||
to $primary_group_id and re-run.
|
||||
EOF
|
||||
else
|
||||
row " Exists" "Yes"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
create_build_user_for_core() {
|
||||
local coreid
|
||||
local username
|
||||
local uid
|
||||
|
||||
coreid="$1"
|
||||
username=$(nix_user_for_core "$coreid")
|
||||
uid=$(nix_uid_for_core "$coreid")
|
||||
dsclpath="/Users/$username"
|
||||
|
||||
task "Setting up the build user $username"
|
||||
|
||||
if ! /usr/bin/dscl . -read "$dsclpath" > /dev/null 2>&1; then
|
||||
_sudo "Creating the Nix build user, $username" \
|
||||
/usr/bin/dscl . create "$dsclpath" \
|
||||
UniqueID "${uid}"
|
||||
row " Created" "Yes"
|
||||
else
|
||||
actual_uid=$(dsclattr "$dsclpath" "UniqueID")
|
||||
if [ "$actual_uid" -ne "$uid" ]; then
|
||||
failure <<EOF
|
||||
It seems the build user $username already exists, but with the UID
|
||||
with the UID $actual_uid. This script can't really handle that right
|
||||
now, so I'm going to give up.
|
||||
|
||||
If you already created the users and you know they start from
|
||||
$actual_uid and go up from there, you can edit this script and change
|
||||
NIX_FIRST_BUILD_UID near the top of the file to $actual_uid and try
|
||||
again.
|
||||
EOF
|
||||
else
|
||||
row " Exists" "Yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$(dsclattr "$dsclpath" "IsHidden")" = "1" ]; then
|
||||
row " IsHidden" "Yes"
|
||||
else
|
||||
_sudo "in order to make $username a hidden user" \
|
||||
/usr/bin/dscl . -create "$dsclpath" "IsHidden" "1"
|
||||
row " IsHidden" "Yes"
|
||||
fi
|
||||
|
||||
if [ "$(dsclattr "$dsclpath" "NFSHomeDirectory")" = "/var/empty" ]; then
|
||||
row " NFSHomeDirectory" "/var/empty"
|
||||
else
|
||||
_sudo "in order to give $username a safe home directory" \
|
||||
/usr/bin/dscl . -create "$dsclpath" "NFSHomeDirectory" "/var/empty"
|
||||
row " NFSHomeDirectory" "/var/empty"
|
||||
fi
|
||||
|
||||
if [ "$(dsclattr "$dsclpath" "RealName")" = "Nix build user $coreid" ]; then
|
||||
row " RealName" "Nix build user $coreid"
|
||||
else
|
||||
_sudo "in order to give $username a useful name" \
|
||||
/usr/bin/dscl . -create "$dsclpath" "RealName" "Nix build user $coreid"
|
||||
row " RealName" "Nix build user $coreid"
|
||||
fi
|
||||
|
||||
if [ "$(dsclattr "$dsclpath" "UserShell")" = "/sbin/nologin" ]; then
|
||||
row " Logins Disabled" "Yes"
|
||||
else
|
||||
_sudo "in order to prevent $username from logging in" \
|
||||
/usr/bin/dscl . -create "$dsclpath" "UserShell" "/sbin/nologin"
|
||||
row " Logins Disabled" "Yes"
|
||||
fi
|
||||
|
||||
if dseditgroup -o checkmember -m "$username" "$NIX_BUILD_GROUP_NAME" > /dev/null 2>&1 ; then
|
||||
row " Member of $NIX_BUILD_GROUP_NAME" "Yes"
|
||||
else
|
||||
_sudo "Add $username to the $NIX_BUILD_GROUP_NAME group"\
|
||||
/usr/sbin/dseditgroup -o edit -t user \
|
||||
-a "$username" "$NIX_BUILD_GROUP_NAME"
|
||||
row " Member of $NIX_BUILD_GROUP_NAME" "Yes"
|
||||
fi
|
||||
|
||||
if [ "$(dsclattr "$dsclpath" "PrimaryGroupID")" = "$NIX_BUILD_GROUP_ID" ]; then
|
||||
row " PrimaryGroupID" "$NIX_BUILD_GROUP_ID"
|
||||
else
|
||||
_sudo "to let the nix daemon use this user for builds (this might seem redundant, but there are two concepts of group membership)" \
|
||||
/usr/bin/dscl . -create "$dsclpath" "PrimaryGroupID" "$NIX_BUILD_GROUP_ID"
|
||||
row " PrimaryGroupID" "$NIX_BUILD_GROUP_ID"
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
create_build_users() {
|
||||
for i in $(seq 1 "$NIX_USER_COUNT"); do
|
||||
create_build_user_for_core "$i"
|
||||
done
|
||||
}
|
||||
|
||||
create_directories() {
|
||||
_sudo "to make the basic directory structure of Nix (part 1)" \
|
||||
mkdir -pv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool}
|
||||
|
||||
_sudo "to make the basic directory structure of Nix (part 2)" \
|
||||
mkdir -pv -m 1777 /nix/var/nix/{gcroots,profiles}/per-user
|
||||
|
||||
_sudo "to make the basic directory structure of Nix (part 3)" \
|
||||
mkdir -pv -m 1775 /nix/store
|
||||
|
||||
_sudo "to make the basic directory structure of Nix (part 4)" \
|
||||
chgrp "$NIX_BUILD_GROUP_NAME" /nix/store
|
||||
|
||||
_sudo "to set up the root user's profile (part 1)" \
|
||||
mkdir -pv -m 0755 /nix/var/nix/profiles/per-user/root
|
||||
|
||||
_sudo "to set up the root user's profile (part 2)" \
|
||||
mkdir -pv -m 0700 "$ROOT_HOME/.nix-defexpr"
|
||||
|
||||
_sudo "to place the default nix daemon configuration (part 1)" \
|
||||
mkdir -pv -m 0555 /etc/nix
|
||||
}
|
||||
|
||||
place_channel_configuration() {
|
||||
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$SCRATCH/.nix-channels"
|
||||
_sudo "to set up the default system channel (part 1)" \
|
||||
install -m 0664 "$SCRATCH/.nix-channels" "$ROOT_HOME/.nix-channels"
|
||||
}
|
||||
|
||||
welcome_to_nix() {
|
||||
ok "Welcome to the Multi-User Nix Installation"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
This installation tool will set up your computer with the Nix package
|
||||
manager. This will happen in a few stages:
|
||||
|
||||
1. Make sure your computer doesn't already have Nix. If it does, I
|
||||
will show you instructions on how to clean up your old one.
|
||||
|
||||
2. Show you what we are going to install and where. Then we will ask
|
||||
if you are ready to continue.
|
||||
|
||||
3. Create the system users and groups that the Nix daemon uses to run
|
||||
builds.
|
||||
|
||||
4. Perform the basic installation of the Nix files daemon.
|
||||
|
||||
5. Configure your shell to import special Nix Profile files, so you
|
||||
can use Nix.
|
||||
|
||||
6. Start the Nix daemon.
|
||||
|
||||
EOF
|
||||
|
||||
if ui_confirm "Would you like to see a more detailed list of what we will do?"; then
|
||||
cat <<EOF
|
||||
|
||||
We will:
|
||||
|
||||
- make sure your computer doesn't already have Nix files
|
||||
(if it does, I will tell you how to clean them up.)
|
||||
- create local users (see the list above for the users we'll make)
|
||||
- create a local group ($NIX_BUILD_GROUP_NAME)
|
||||
- install Nix in to $NIX_ROOT
|
||||
- create a configuration file in /etc/nix
|
||||
- set up the "default profile" by creating some Nix-related files in
|
||||
$ROOT_HOME
|
||||
EOF
|
||||
for profile_target in "${PROFILE_TARGETS[@]}"; do
|
||||
if [ -e "$profile_target" ]; then
|
||||
cat <<EOF
|
||||
- back up $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX
|
||||
- update $profile_target to include some Nix configuration
|
||||
EOF
|
||||
fi
|
||||
done
|
||||
cat <<EOF
|
||||
- load and start a LaunchDaemon (at $PLIST_DEST) for nix-daemon
|
||||
|
||||
EOF
|
||||
if ! ui_confirm "Ready to continue?"; then
|
||||
failure <<EOF
|
||||
Okay, maybe you would like to talk to the team.
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
chat_about_sudo() {
|
||||
header "let's talk about sudo"
|
||||
|
||||
if headless; then
|
||||
cat <<EOF
|
||||
This script is going to call sudo a lot. Normally, it would show you
|
||||
exactly what commands it is running and why. However, the script is
|
||||
run in a headless fashion, like this:
|
||||
|
||||
$ curl https://nixos.org/nix/install | sh
|
||||
|
||||
or maybe in a CI pipeline. Because of that, we're going to skip the
|
||||
verbose output in the interest of brevity.
|
||||
|
||||
If you would like to
|
||||
see the output, try like this:
|
||||
|
||||
$ curl -o install-nix https://nixos.org/nix/install
|
||||
$ sh ./install-nix
|
||||
|
||||
EOF
|
||||
return 0
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
This script is going to call sudo a lot. Every time we do, it'll
|
||||
output exactly what it'll do, and why.
|
||||
|
||||
Just like this:
|
||||
EOF
|
||||
|
||||
__sudo "to demonstrate how our sudo prompts look" \
|
||||
echo "this is a sudo prompt"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
This might look scary, but everything can be undone by running just a
|
||||
few commands. We used to ask you to confirm each time sudo ran, but it
|
||||
was too many times. Instead, I'll just ask you this one time:
|
||||
|
||||
EOF
|
||||
if ui_confirm "Can we use sudo?"; then
|
||||
ok "Yay! Thanks! Let's get going!"
|
||||
else
|
||||
failure <<EOF
|
||||
That is okay, but we can't install.
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
install_from_extracted_nix() {
|
||||
(
|
||||
cd "$EXTRACTED_NIX_PATH"
|
||||
|
||||
_sudo "to copy the basic Nix files to the new store at $NIX_ROOT/store" \
|
||||
rsync -rlpt "$(pwd)/store/" "$NIX_ROOT/store/"
|
||||
|
||||
if [ -d "$NIX_INSTALLED_NIX" ]; then
|
||||
echo " Alright! We have our first nix at $NIX_INSTALLED_NIX"
|
||||
else
|
||||
failure <<EOF
|
||||
Something went wrong, and I didn't find Nix installed at
|
||||
$NIX_INSTALLED_NIX.
|
||||
EOF
|
||||
fi
|
||||
|
||||
_sudo "to initialize the Nix Database" \
|
||||
$NIX_INSTALLED_NIX/bin/nix-store --init
|
||||
|
||||
cat ./.reginfo \
|
||||
| _sudo "to load data for the first time in to the Nix Database" \
|
||||
"$NIX_INSTALLED_NIX/bin/nix-store" --load-db
|
||||
|
||||
echo " Just finished getting the nix database ready."
|
||||
)
|
||||
}
|
||||
|
||||
shell_source_lines() {
|
||||
cat <<EOF
|
||||
|
||||
# Nix
|
||||
if [ -e '$PROFILE_NIX_FILE' ]; then
|
||||
. '$PROFILE_NIX_FILE'
|
||||
fi
|
||||
# End Nix
|
||||
|
||||
EOF
|
||||
}
|
||||
configure_shell_profile() {
|
||||
for profile_target in "${PROFILE_TARGETS[@]}"; do
|
||||
if [ -e "$profile_target" ]; then
|
||||
_sudo "to back up your current $profile_target to $profile_target$PROFILE_BACKUP_SUFFIX" \
|
||||
cp "$profile_target" "$profile_target$PROFILE_BACKUP_SUFFIX"
|
||||
|
||||
shell_source_lines \
|
||||
| _sudo "extend your $profile_target with nix-daemon settings" \
|
||||
tee -a "$profile_target"
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
setup_default_profile() {
|
||||
_sudo "to installing a bootstrapping Nix in to the default Profile" \
|
||||
HOME=$ROOT_HOME "$NIX_INSTALLED_NIX/bin/nix-env" -i "$NIX_INSTALLED_NIX"
|
||||
|
||||
_sudo "to installing a bootstrapping SSL certificate just for Nix in to the default Profile" \
|
||||
HOME=$ROOT_HOME "$NIX_INSTALLED_NIX/bin/nix-env" -i "$NIX_INSTALLED_CACERT"
|
||||
|
||||
_sudo "to update the default channel in the default profile" \
|
||||
HOME=$ROOT_HOME NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt "$NIX_INSTALLED_NIX/bin/nix-channel" --update nixpkgs
|
||||
}
|
||||
|
||||
|
||||
place_nix_configuration() {
|
||||
cat <<EOF > "$SCRATCH/nix.conf"
|
||||
build-users-group = $NIX_BUILD_GROUP_NAME
|
||||
|
||||
max-jobs = $NIX_USER_COUNT
|
||||
cores = 1
|
||||
sandbox = false
|
||||
EOF
|
||||
_sudo "to place the default nix daemon configuration (part 2)" \
|
||||
install -m 0664 "$SCRATCH/nix.conf" /etc/nix/nix.conf
|
||||
}
|
||||
|
||||
configure_nix_daemon_plist() {
|
||||
_sudo "to set up the nix-daemon as a LaunchDaemon" \
|
||||
ln -sfn "/nix/var/nix/profiles/default$PLIST_DEST" "$PLIST_DEST"
|
||||
|
||||
_sudo "to load the LaunchDaemon plist for nix-daemon" \
|
||||
launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
||||
|
||||
_sudo "to start the nix-daemon" \
|
||||
launchctl start org.nixos.nix-daemon
|
||||
|
||||
}
|
||||
|
||||
|
||||
main() {
|
||||
welcome_to_nix
|
||||
chat_about_sudo
|
||||
|
||||
if [ "${ALLOW_PREEXISTING_INSTALLATION:-}" = "" ]; then
|
||||
validate_starting_assumptions
|
||||
fi
|
||||
|
||||
setup_report
|
||||
|
||||
if ! ui_confirm "Ready to continue?"; then
|
||||
ok "Alright, no changes have been made :)"
|
||||
contactme
|
||||
trap finish_cleanup EXIT
|
||||
exit 1
|
||||
fi
|
||||
|
||||
create_build_group
|
||||
create_build_users
|
||||
create_directories
|
||||
place_channel_configuration
|
||||
install_from_extracted_nix
|
||||
|
||||
configure_shell_profile
|
||||
|
||||
set +eu
|
||||
. /etc/profile
|
||||
set -eu
|
||||
|
||||
setup_default_profile
|
||||
place_nix_configuration
|
||||
configure_nix_daemon_plist
|
||||
|
||||
trap finish_success EXIT
|
||||
}
|
||||
|
||||
|
||||
main
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env bash
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
@@ -7,9 +7,9 @@ self="$(dirname "$0")"
|
||||
nix="@nix@"
|
||||
cacert="@cacert@"
|
||||
|
||||
if ! [ -e $self/.reginfo ]; then
|
||||
|
||||
if ! [ -e "$self/.reginfo" ]; then
|
||||
echo "$0: incomplete installer (.reginfo is missing)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$USER" ]; then
|
||||
@@ -17,6 +17,23 @@ if [ -z "$USER" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$HOME" ]; then
|
||||
echo "$0: \$HOME is not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# macOS support for 10.10 or higher
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
if [ $(($(sw_vers -productVersion | cut -d '.' -f 2))) -lt 10 ]; then
|
||||
echo "$0: macOS $(sw_vers -productVersion) is not supported, upgrade to 10.10 or higher"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '\e[1;31mSwitching to the Multi-User Darwin Installer\e[0m\n'
|
||||
exec "$self/install-darwin-multi-user"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
printf '\e[1;31mwarning: installing Nix as root is not supported by this script!\e[0m\n'
|
||||
fi
|
||||
@@ -25,31 +42,34 @@ echo "performing a single-user installation of Nix..." >&2
|
||||
|
||||
if ! [ -e $dest ]; then
|
||||
cmd="mkdir -m 0755 $dest && chown $USER $dest"
|
||||
echo "directory $dest does not exist; creating it by running ‘$cmd’ using sudo" >&2
|
||||
echo "directory $dest does not exist; creating it by running '$cmd' using sudo" >&2
|
||||
if ! sudo sh -c "$cmd"; then
|
||||
echo "$0: please manually run ‘$cmd’ as root to create $dest" >&2
|
||||
echo "$0: please manually run '$cmd' as root to create $dest" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! [ -w $dest ]; then
|
||||
echo "$0: directory $dest exists, but is not writable by you; please run ‘chown -R $USER $dest’ as root" >&2
|
||||
echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see http://nixos.org/nix/manual/#ssec-multi-user. If you wish to continue with a single-user install for $USER please run 'chown -R $USER $dest' as root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $dest/store
|
||||
|
||||
echo -n "copying Nix to $dest/store..." >&2
|
||||
printf "copying Nix to %s..." "${dest}/store" >&2
|
||||
|
||||
for i in $(cd $self/store >/dev/null && echo *); do
|
||||
echo -n "." >&2
|
||||
for i in $(cd "$self/store" >/dev/null && echo ./*); do
|
||||
printf "." >&2
|
||||
i_tmp="$dest/store/$i.$$"
|
||||
if [ -e "$i_tmp" ]; then
|
||||
rm -rf "$i_tmp"
|
||||
fi
|
||||
if ! [ -e "$dest/store/$i" ]; then
|
||||
cp -Rp "$self/store/$i" "$i_tmp"
|
||||
chmod -R a-w "$i_tmp"
|
||||
chmod +w "$i_tmp"
|
||||
mv "$i_tmp" "$dest/store/$i"
|
||||
chmod -w "$dest/store/$i"
|
||||
fi
|
||||
done
|
||||
echo "" >&2
|
||||
@@ -60,22 +80,22 @@ if ! $nix/bin/nix-store --init; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! $nix/bin/nix-store --load-db < $self/.reginfo; then
|
||||
if ! "$nix/bin/nix-store" --load-db < "$self/.reginfo"; then
|
||||
echo "$0: unable to register valid paths" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. $nix/etc/profile.d/nix.sh
|
||||
. "$nix/etc/profile.d/nix.sh"
|
||||
|
||||
if ! $nix/bin/nix-env -i "$nix"; then
|
||||
if ! "$nix/bin/nix-env" -i "$nix"; then
|
||||
echo "$0: unable to install Nix into your default profile" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install an SSL certificate bundle.
|
||||
if [ -z "$SSL_CERT_FILE" -o ! -f "$SSL_CERT_FILE" ]; then
|
||||
if [ -z "$NIX_SSL_CERT_FILE" ] || ! [ -f "$NIX_SSL_CERT_FILE" ]; then
|
||||
$nix/bin/nix-env -i "$cacert"
|
||||
export SSL_CERT_FILE="$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crt"
|
||||
export NIX_SSL_CERT_FILE="$HOME/.nix-profile/etc/ssl/certs/ca-bundle.crt"
|
||||
fi
|
||||
|
||||
# Subscribe the user to the Nixpkgs channel and fetch it.
|
||||
@@ -86,21 +106,25 @@ if [ -z "$_NIX_INSTALLER_TEST" ]; then
|
||||
$nix/bin/nix-channel --update nixpkgs
|
||||
fi
|
||||
|
||||
# Make the shell source nix.sh during login.
|
||||
p=$NIX_LINK/etc/profile.d/nix.sh
|
||||
|
||||
added=
|
||||
for i in .bash_profile .bash_login .profile; do
|
||||
fn="$HOME/$i"
|
||||
if [ -e "$fn" ]; then
|
||||
if ! grep -q "$p" "$fn"; then
|
||||
echo "modifying $fn..." >&2
|
||||
echo "if [ -e $p ]; then . $p; fi # added by Nix installer" >> $fn
|
||||
if [ -z "$NIX_INSTALLER_NO_MODIFY_PROFILE" ]; then
|
||||
|
||||
# Make the shell source nix.sh during login.
|
||||
p=$HOME/.nix-profile/etc/profile.d/nix.sh
|
||||
|
||||
for i in .bash_profile .bash_login .profile; do
|
||||
fn="$HOME/$i"
|
||||
if [ -w "$fn" ]; then
|
||||
if ! grep -q "$p" "$fn"; then
|
||||
echo "modifying $fn..." >&2
|
||||
echo "if [ -e $p ]; then . $p; fi # added by Nix installer" >> "$fn"
|
||||
fi
|
||||
added=1
|
||||
break
|
||||
fi
|
||||
added=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
if [ -z "$added" ]; then
|
||||
cat >&2 <<EOF
|
||||
|
||||
@@ -1,37 +1,13 @@
|
||||
nix_bin_scripts := \
|
||||
$(d)/nix-build \
|
||||
$(d)/nix-channel \
|
||||
$(d)/nix-copy-closure \
|
||||
$(d)/nix-generate-patches \
|
||||
$(d)/nix-install-package \
|
||||
$(d)/nix-pull \
|
||||
$(d)/nix-push
|
||||
|
||||
bin-scripts += $(nix_bin_scripts)
|
||||
|
||||
nix_substituters := \
|
||||
$(d)/copy-from-other-stores.pl \
|
||||
$(d)/download-from-binary-cache.pl \
|
||||
$(d)/download-using-manifests.pl
|
||||
|
||||
nix_noinst_scripts := \
|
||||
$(d)/build-remote.pl \
|
||||
$(d)/find-runtime-roots.pl \
|
||||
$(d)/resolve-system-dependencies.pl \
|
||||
$(d)/nix-http-export.cgi \
|
||||
$(d)/nix-profile.sh \
|
||||
$(d)/nix-reduce-build \
|
||||
$(nix_substituters)
|
||||
$(d)/nix-reduce-build
|
||||
|
||||
noinst-scripts += $(nix_noinst_scripts)
|
||||
|
||||
profiledir = $(sysconfdir)/profile.d
|
||||
|
||||
$(eval $(call install-file-as, $(d)/nix-profile.sh, $(profiledir)/nix.sh, 0644))
|
||||
$(eval $(call install-program-in, $(d)/find-runtime-roots.pl, $(libexecdir)/nix))
|
||||
$(eval $(call install-program-in, $(d)/build-remote.pl, $(libexecdir)/nix))
|
||||
$(eval $(call install-program-in, $(d)/resolve-system-dependencies.pl, $(libexecdir)/nix))
|
||||
$(foreach prog, $(nix_substituters), $(eval $(call install-program-in, $(prog), $(libexecdir)/nix/substituters)))
|
||||
$(eval $(call install-symlink, nix-build, $(bindir)/nix-shell))
|
||||
$(eval $(call install-file-as, $(d)/nix-profile-daemon.sh, $(profiledir)/nix-daemon.sh, 0644))
|
||||
|
||||
clean-files += $(nix_bin_scripts) $(nix_noinst_scripts)
|
||||
clean-files += $(nix_noinst_scripts)
|
||||
|
||||
@@ -1,352 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use utf8;
|
||||
use strict;
|
||||
use Nix::Config;
|
||||
use Nix::Store;
|
||||
use Nix::Utils;
|
||||
use File::Basename;
|
||||
use Text::ParseWords;
|
||||
use Cwd;
|
||||
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
my $dryRun = 0;
|
||||
my $verbose = 0;
|
||||
my $runEnv = $0 =~ /nix-shell$/;
|
||||
my $pure = 0;
|
||||
my $fromArgs = 0;
|
||||
my $packages = 0;
|
||||
my $interactive = 1;
|
||||
|
||||
my @instArgs = ();
|
||||
my @buildArgs = ();
|
||||
my @exprs = ();
|
||||
|
||||
my $shell = $ENV{SHELL} || "/bin/sh";
|
||||
my $envCommand = ""; # interactive shell
|
||||
my @envExclude = ();
|
||||
|
||||
my $myName = $runEnv ? "nix-shell" : "nix-build";
|
||||
|
||||
my $inShebang = 0;
|
||||
my $script;
|
||||
my @savedArgs;
|
||||
|
||||
my $tmpDir = mkTempDir($myName);
|
||||
|
||||
my $outLink = "./result";
|
||||
my $drvLink = "$tmpDir/derivation";
|
||||
|
||||
# Ensure that the $tmpDir is deleted.
|
||||
$SIG{'INT'} = sub { exit 1 };
|
||||
|
||||
|
||||
# Heuristic to see if we're invoked as a shebang script, namely, if we
|
||||
# have a single argument, it's the name of an executable file, and it
|
||||
# starts with "#!".
|
||||
if ($runEnv && defined $ARGV[0] && $ARGV[0] !~ /nix-shell/) {
|
||||
$script = $ARGV[0];
|
||||
if (-f $script && -x $script) {
|
||||
open SCRIPT, "<$script" or die "$0: cannot open ‘$script’: $!\n";
|
||||
my $first = <SCRIPT>;
|
||||
if ($first =~ /^\#\!/) {
|
||||
$inShebang = 1;
|
||||
@savedArgs = @ARGV; shift @savedArgs;
|
||||
@ARGV = ();
|
||||
while (<SCRIPT>) {
|
||||
chomp;
|
||||
if (/^\#\!\s*nix-shell (.*)$/) {
|
||||
push @ARGV, shellwords(/ /, $1);
|
||||
}
|
||||
}
|
||||
}
|
||||
close SCRIPT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (my $n = 0; $n < scalar @ARGV; $n++) {
|
||||
my $arg = $ARGV[$n];
|
||||
|
||||
if ($arg eq "--help") {
|
||||
exec "man $myName" or die;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--version") {
|
||||
print "$myName (Nix) $Nix::Config::version\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--add-drv-link") {
|
||||
$drvLink = "./derivation";
|
||||
}
|
||||
|
||||
elsif ($arg eq "--no-out-link" || $arg eq "--no-link") {
|
||||
$outLink = "$tmpDir/result";
|
||||
}
|
||||
|
||||
elsif ($arg eq "--drv-link") {
|
||||
$n++;
|
||||
die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
|
||||
$drvLink = $ARGV[$n];
|
||||
}
|
||||
|
||||
elsif ($arg eq "--out-link" || $arg eq "-o") {
|
||||
$n++;
|
||||
die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
|
||||
$outLink = $ARGV[$n];
|
||||
}
|
||||
|
||||
elsif ($arg eq "--attr" || $arg eq "-A" || $arg eq "-I") {
|
||||
$n++;
|
||||
die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
|
||||
push @instArgs, ($arg, $ARGV[$n]);
|
||||
}
|
||||
|
||||
elsif ($arg eq "--arg" || $arg eq "--argstr") {
|
||||
die "$0: ‘$arg’ requires two arguments\n" unless $n + 2 < scalar @ARGV;
|
||||
push @instArgs, ($arg, $ARGV[$n + 1], $ARGV[$n + 2]);
|
||||
$n += 2;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--log-type") {
|
||||
$n++;
|
||||
die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
|
||||
push @instArgs, ($arg, $ARGV[$n]);
|
||||
push @buildArgs, ($arg, $ARGV[$n]);
|
||||
}
|
||||
|
||||
elsif ($arg eq "--option") {
|
||||
die "$0: ‘$arg’ requires two arguments\n" unless $n + 2 < scalar @ARGV;
|
||||
push @instArgs, ($arg, $ARGV[$n + 1], $ARGV[$n + 2]);
|
||||
push @buildArgs, ($arg, $ARGV[$n + 1], $ARGV[$n + 2]);
|
||||
$n += 2;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--max-jobs" || $arg eq "-j" || $arg eq "--max-silent-time" || $arg eq "--log-type" || $arg eq "--cores" || $arg eq "--timeout" || $arg eq '--add-root') {
|
||||
$n++;
|
||||
die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
|
||||
push @buildArgs, ($arg, $ARGV[$n]);
|
||||
}
|
||||
|
||||
elsif ($arg eq "--dry-run") {
|
||||
push @buildArgs, "--dry-run";
|
||||
$dryRun = 1;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--show-trace") {
|
||||
push @instArgs, $arg;
|
||||
}
|
||||
|
||||
elsif ($arg eq "-") {
|
||||
@exprs = ("-");
|
||||
}
|
||||
|
||||
elsif ($arg eq "--verbose" || substr($arg, 0, 2) eq "-v") {
|
||||
push @buildArgs, $arg;
|
||||
push @instArgs, $arg;
|
||||
$verbose = 1;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--quiet" || $arg eq "--repair") {
|
||||
push @buildArgs, $arg;
|
||||
push @instArgs, $arg;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--check") {
|
||||
push @buildArgs, $arg;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--run-env") { # obsolete
|
||||
$runEnv = 1;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--command" || $arg eq "--run") {
|
||||
$n++;
|
||||
die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
|
||||
$envCommand = "$ARGV[$n]\nexit";
|
||||
$interactive = 0 if $arg eq "--run";
|
||||
}
|
||||
|
||||
elsif ($arg eq "--exclude") {
|
||||
$n++;
|
||||
die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
|
||||
push @envExclude, $ARGV[$n];
|
||||
}
|
||||
|
||||
elsif ($arg eq "--pure") { $pure = 1; }
|
||||
elsif ($arg eq "--impure") { $pure = 0; }
|
||||
|
||||
elsif ($arg eq "--expr" || $arg eq "-E") {
|
||||
$fromArgs = 1;
|
||||
push @instArgs, "--expr";
|
||||
}
|
||||
|
||||
elsif ($arg eq "--packages" || $arg eq "-p") {
|
||||
$packages = 1;
|
||||
}
|
||||
|
||||
elsif ($inShebang && $arg eq "-i") {
|
||||
$n++;
|
||||
die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
|
||||
my $interpreter = $ARGV[$n];
|
||||
# Überhack to support Perl. Perl examines the shebang and
|
||||
# executes it unless it contains the string "perl" or "indir",
|
||||
# or (undocumented) argv[0] does not contain "perl". Exploit
|
||||
# the latter by doing "exec -a".
|
||||
my $execArgs = $interpreter =~ /perl/ ? "-a PERL" : "";
|
||||
sub shellEscape {
|
||||
my $s = $_;
|
||||
$s =~ s/'/'\\''/g;
|
||||
return "'" . $s . "'";
|
||||
}
|
||||
$envCommand = "exec $execArgs $interpreter $script ${\(join ' ', (map shellEscape, @savedArgs))}";
|
||||
}
|
||||
|
||||
elsif (substr($arg, 0, 1) eq "-") {
|
||||
push @buildArgs, $arg;
|
||||
}
|
||||
|
||||
elsif ($arg eq "-Q" || $arg eq "--no-build-output") {
|
||||
push @buildArgs, $arg;
|
||||
push @instArgs, $arg;
|
||||
}
|
||||
|
||||
else {
|
||||
push @exprs, $arg;
|
||||
}
|
||||
}
|
||||
|
||||
die "$0: ‘-p’ and ‘-E’ are mutually exclusive\n" if $packages && $fromArgs;
|
||||
|
||||
if ($packages) {
|
||||
push @instArgs, "--expr";
|
||||
@exprs = (
|
||||
'with import <nixpkgs> { }; runCommand "shell" { buildInputs = [ '
|
||||
. (join " ", map { "($_)" } @exprs) . ']; } ""');
|
||||
} elsif (!$fromArgs) {
|
||||
@exprs = ("shell.nix") if scalar @exprs == 0 && $runEnv && -e "shell.nix";
|
||||
@exprs = ("default.nix") if scalar @exprs == 0;
|
||||
}
|
||||
|
||||
$ENV{'IN_NIX_SHELL'} = 1 if $runEnv;
|
||||
|
||||
|
||||
foreach my $expr (@exprs) {
|
||||
|
||||
# Instantiate.
|
||||
my @drvPaths;
|
||||
if ($expr !~ /^\/.*\.drv$/) {
|
||||
# If we're in a #! script, interpret filenames relative to the
|
||||
# script.
|
||||
$expr = dirname(Cwd::abs_path($script)) . "/" . $expr
|
||||
if $inShebang && !$packages && $expr !~ /^\//;
|
||||
|
||||
# !!! would prefer the perl 5.8.0 pipe open feature here.
|
||||
my $pid = open(DRVPATHS, "-|") || exec "$Nix::Config::binDir/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr;
|
||||
while (<DRVPATHS>) {chomp; push @drvPaths, $_;}
|
||||
if (!close DRVPATHS) {
|
||||
die "nix-instantiate killed by signal " . ($? & 127) . "\n" if ($? & 127);
|
||||
exit 1;
|
||||
}
|
||||
} else {
|
||||
push @drvPaths, $expr;
|
||||
}
|
||||
|
||||
if ($runEnv) {
|
||||
die "$0: a single derivation is required\n" if scalar @drvPaths != 1;
|
||||
my $drvPath = $drvPaths[0];
|
||||
$drvPath = (split '!',$drvPath)[0];
|
||||
$drvPath = readlink $drvPath or die "cannot read symlink ‘$drvPath’" if -l $drvPath;
|
||||
my $drv = derivationFromPath($drvPath);
|
||||
|
||||
# Build or fetch all dependencies of the derivation.
|
||||
my @inputDrvs = grep { my $x = $_; (grep { $x =~ $_ } @envExclude) == 0 } @{$drv->{inputDrvs}};
|
||||
system("$Nix::Config::binDir/nix-store", "-r", "--no-output", "--no-gc-warning", @buildArgs, @inputDrvs, @{$drv->{inputSrcs}}) == 0
|
||||
or die "$0: failed to build all dependencies\n";
|
||||
|
||||
# Set the environment.
|
||||
my $tmp = $ENV{"TMPDIR"} // $ENV{"XDG_RUNTIME_DIR"} // "/tmp";
|
||||
if ($pure) {
|
||||
foreach my $name (keys %ENV) {
|
||||
next if grep { $_ eq $name } ("HOME", "USER", "LOGNAME", "DISPLAY", "PATH", "TERM", "IN_NIX_SHELL", "TZ", "PAGER", "NIX_BUILD_SHELL");
|
||||
delete $ENV{$name};
|
||||
}
|
||||
# NixOS hack: prevent /etc/bashrc from sourcing /etc/profile.
|
||||
$ENV{'__ETC_PROFILE_SOURCED'} = 1;
|
||||
}
|
||||
$ENV{'NIX_BUILD_TOP'} = $ENV{'TMPDIR'} = $ENV{'TEMPDIR'} = $ENV{'TMP'} = $ENV{'TEMP'} = $tmp;
|
||||
$ENV{'NIX_STORE'} = $Nix::Config::storeDir;
|
||||
$ENV{$_} = $drv->{env}->{$_} foreach keys %{$drv->{env}};
|
||||
|
||||
# Run a shell using the derivation's environment. For
|
||||
# convenience, source $stdenv/setup to setup additional
|
||||
# environment variables and shell functions. Also don't lose
|
||||
# the current $PATH directories.
|
||||
my $rcfile = "$tmpDir/rc";
|
||||
writeFile(
|
||||
$rcfile,
|
||||
"rm -rf '$tmpDir'; " .
|
||||
'unset BASH_ENV; ' .
|
||||
'[ -n "$PS1" ] && [ -e ~/.bashrc ] && source ~/.bashrc; ' .
|
||||
($pure ? '' : 'p=$PATH; ' ) .
|
||||
'dontAddDisableDepTrack=1; ' .
|
||||
'[ -e $stdenv/setup ] && source $stdenv/setup; ' .
|
||||
($pure ? '' : 'PATH=$PATH:$p; unset p; ') .
|
||||
'set +e; ' .
|
||||
'[ -n "$PS1" ] && PS1="\n\[\033[1;32m\][nix-shell:\w]$\[\033[0m\] "; ' .
|
||||
'if [ "$(type -t runHook)" = function ]; then runHook shellHook; fi; ' .
|
||||
'unset NIX_ENFORCE_PURITY; ' .
|
||||
'unset NIX_INDENT_MAKE; ' .
|
||||
'shopt -u nullglob; ' .
|
||||
'unset TZ; ' . (defined $ENV{'TZ'} ? "export TZ='${ENV{'TZ'}}'; " : '') .
|
||||
$envCommand);
|
||||
$ENV{BASH_ENV} = $rcfile;
|
||||
my @args = ($ENV{NIX_BUILD_SHELL} // "bash");
|
||||
push @args, "--rcfile" if $interactive;
|
||||
push @args, $rcfile;
|
||||
exec @args;
|
||||
die;
|
||||
}
|
||||
|
||||
# Ugly hackery to make "nix-build -A foo.all" produce symlinks
|
||||
# ./result, ./result-dev, and so on, rather than ./result,
|
||||
# ./result-2-dev, and so on. This combines multiple derivation
|
||||
# paths into one "/nix/store/drv-path!out1,out2,..." argument.
|
||||
my $prevDrvPath = "";
|
||||
my @drvPaths2;
|
||||
foreach my $drvPath (@drvPaths) {
|
||||
my $p = $drvPath; my $output = "out";
|
||||
if ($drvPath =~ /(.*)!(.*)/) {
|
||||
$p = $1; $output = $2;
|
||||
} else {
|
||||
$p = $drvPath;
|
||||
}
|
||||
my $target = readlink $p or die "cannot read symlink ‘$p’";
|
||||
print STDERR "derivation is $target\n" if $verbose;
|
||||
if ($target eq $prevDrvPath) {
|
||||
push @drvPaths2, (pop @drvPaths2) . "," . $output;
|
||||
} else {
|
||||
push @drvPaths2, $target . "!" . $output;
|
||||
$prevDrvPath = $target;
|
||||
}
|
||||
}
|
||||
|
||||
# Build.
|
||||
my @outPaths;
|
||||
my $pid = open(OUTPATHS, "-|") || exec "$Nix::Config::binDir/nix-store", "--add-root", $outLink, "--indirect", "-r",
|
||||
@buildArgs, @drvPaths2;
|
||||
while (<OUTPATHS>) {chomp; push @outPaths, $_;}
|
||||
if (!close OUTPATHS) {
|
||||
die "nix-store killed by signal " . ($? & 127) . "\n" if ($? & 127);
|
||||
exit ($? >> 8 || 1);
|
||||
}
|
||||
|
||||
next if $dryRun;
|
||||
|
||||
foreach my $outPath (@outPaths) {
|
||||
my $target = readlink $outPath or die "cannot read symlink ‘$outPath’";
|
||||
print "$target\n";
|
||||
}
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use utf8;
|
||||
use strict;
|
||||
use File::Basename;
|
||||
use File::Path qw(mkpath);
|
||||
use Nix::Config;
|
||||
use Nix::Manifest;
|
||||
use File::Temp qw(tempdir);
|
||||
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
Nix::Config::readConfig;
|
||||
|
||||
my $manifestDir = $Nix::Config::manifestDir;
|
||||
|
||||
|
||||
# Turn on caching in nix-prefetch-url.
|
||||
my $channelCache = "$Nix::Config::stateDir/channel-cache";
|
||||
mkdir $channelCache, 0755 unless -e $channelCache;
|
||||
$ENV{'NIX_DOWNLOAD_CACHE'} = $channelCache if -W $channelCache;
|
||||
|
||||
# Figure out the name of the `.nix-channels' file to use.
|
||||
my $home = $ENV{"HOME"} or die '$HOME not set\n';
|
||||
my $channelsList = "$home/.nix-channels";
|
||||
my $nixDefExpr = "$home/.nix-defexpr";
|
||||
|
||||
# Figure out the name of the channels profile.
|
||||
my $userName = getpwuid($<) || $ENV{"USER"} or die "cannot figure out user name";
|
||||
my $profile = "$Nix::Config::stateDir/profiles/per-user/$userName/channels";
|
||||
mkpath(dirname $profile, 0, 0755);
|
||||
|
||||
my %channels;
|
||||
|
||||
|
||||
# Reads the list of channels.
|
||||
sub readChannels {
|
||||
return if (!-f $channelsList);
|
||||
open CHANNELS, "<$channelsList" or die "cannot open ‘$channelsList’: $!";
|
||||
while (<CHANNELS>) {
|
||||
chomp;
|
||||
next if /^\s*\#/;
|
||||
my ($url, $name) = split ' ', $_;
|
||||
$url =~ s/\/*$//; # remove trailing slashes
|
||||
$name = basename $url unless defined $name;
|
||||
$channels{$name} = $url;
|
||||
}
|
||||
close CHANNELS;
|
||||
}
|
||||
|
||||
|
||||
# Writes the list of channels.
|
||||
sub writeChannels {
|
||||
open CHANNELS, ">$channelsList" or die "cannot open ‘$channelsList’: $!";
|
||||
foreach my $name (keys %channels) {
|
||||
print CHANNELS "$channels{$name} $name\n";
|
||||
}
|
||||
close CHANNELS;
|
||||
}
|
||||
|
||||
|
||||
# Adds a channel.
|
||||
sub addChannel {
|
||||
my ($url, $name) = @_;
|
||||
die "invalid channel URL ‘$url’" unless $url =~ /^(file|http|https):\/\//;
|
||||
die "invalid channel identifier ‘$name’" unless $name =~ /^[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*$/;
|
||||
readChannels;
|
||||
$channels{$name} = $url;
|
||||
writeChannels;
|
||||
}
|
||||
|
||||
|
||||
# Remove a channel.
|
||||
sub removeChannel {
|
||||
my ($name) = @_;
|
||||
readChannels;
|
||||
my $url = $channels{$name};
|
||||
deleteOldManifests($url . "/MANIFEST", undef) if defined $url;
|
||||
delete $channels{$name};
|
||||
writeChannels;
|
||||
|
||||
system("$Nix::Config::binDir/nix-env --profile '$profile' -e '$name'") == 0
|
||||
or die "cannot remove channel ‘$name’\n";
|
||||
}
|
||||
|
||||
|
||||
# Fetch Nix expressions and pull manifests from the subscribed
|
||||
# channels.
|
||||
sub update {
|
||||
my @channelNames = @_;
|
||||
|
||||
readChannels;
|
||||
|
||||
# Download each channel.
|
||||
my $exprs = "";
|
||||
foreach my $name (keys %channels) {
|
||||
next if scalar @channelNames > 0 && ! grep { $_ eq $name } @{channelNames};
|
||||
|
||||
my $url = $channels{$name};
|
||||
my $origUrl = "$url/MANIFEST";
|
||||
|
||||
# We want to download the url to a file to see if it's a tarball while also checking if we
|
||||
# got redirected in the process, so that we can grab the various parts of a nix channel
|
||||
# definition from a consistent location if the redirect changes mid-download.
|
||||
my $tmpdir = tempdir( CLEANUP => 1 );
|
||||
my $filename;
|
||||
($url, $filename) = `cd $tmpdir && $Nix::Config::curl --silent --write-out '%{url_effective}\n%{filename_effective}' -L '$url' -O`;
|
||||
chomp $url;
|
||||
die "$0: unable to check ‘$url’\n" if $? != 0;
|
||||
|
||||
# If the URL contains a version number, append it to the name
|
||||
# attribute (so that "nix-env -q" on the channels profile
|
||||
# shows something useful).
|
||||
my $cname = $name;
|
||||
$cname .= $1 if basename($url) =~ /(-\d.*)$/;
|
||||
|
||||
my $path;
|
||||
my $ret = -1;
|
||||
if (-e "$tmpdir/$filename" && $filename =~ /\.tar\.(gz|bz2|xz)$/) {
|
||||
# Get our temporary download into the store.
|
||||
(my $hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url 'file://$tmpdir/$filename'`;
|
||||
chomp $path;
|
||||
|
||||
# Try unpacking the expressions to see if they'll be valid for us to process later.
|
||||
# Like anything in nix, this will cache the result so we don't do it again outside of the loop below.
|
||||
$ret = system("$Nix::Config::binDir/nix-build --no-out-link -E 'import <nix/unpack-channel.nix> " .
|
||||
"{ name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; }'");
|
||||
}
|
||||
|
||||
# The URL doesn't unpack directly, so let's try treating it like a full channel folder with files in it
|
||||
my $extraAttrs = "";
|
||||
if ($ret != 0) {
|
||||
# Check if the channel advertises a binary cache.
|
||||
my $binaryCacheURL = `$Nix::Config::curl --silent '$url'/binary-cache-url`;
|
||||
my $getManifest = ($Nix::Config::config{"force-manifest"} // "false") eq "true";
|
||||
if ($? == 0 && $binaryCacheURL ne "") {
|
||||
$extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; ";
|
||||
deleteOldManifests($origUrl, undef);
|
||||
} else {
|
||||
$getManifest = 1;
|
||||
}
|
||||
|
||||
if ($getManifest) {
|
||||
# No binary cache, so pull the channel manifest.
|
||||
mkdir $manifestDir, 0755 unless -e $manifestDir;
|
||||
die "$0: you do not have write permission to ‘$manifestDir’!\n" unless -W $manifestDir;
|
||||
$ENV{'NIX_ORIG_URL'} = $origUrl;
|
||||
system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
|
||||
or die "cannot pull manifest from ‘$url’\n";
|
||||
}
|
||||
|
||||
# Download the channel tarball.
|
||||
my $fullURL = "$url/nixexprs.tar.xz";
|
||||
system("$Nix::Config::curl --fail --silent --head '$fullURL' > /dev/null") == 0 or
|
||||
$fullURL = "$url/nixexprs.tar.bz2";
|
||||
print STDERR "downloading Nix expressions from ‘$fullURL’...\n";
|
||||
(my $hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url '$fullURL'`;
|
||||
die "cannot fetch ‘$fullURL’\n" if $? != 0;
|
||||
chomp $path;
|
||||
}
|
||||
|
||||
# Regardless of where it came from, add the expression representing this channel to accumulated expression
|
||||
$exprs .= "'f: f { name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; $extraAttrs }' ";
|
||||
}
|
||||
|
||||
# Unpack the channel tarballs into the Nix store and install them
|
||||
# into the channels profile.
|
||||
print STDERR "unpacking channels...\n";
|
||||
system("$Nix::Config::binDir/nix-env --profile '$profile' " .
|
||||
"-f '<nix/unpack-channel.nix>' -i -E $exprs --quiet") == 0
|
||||
or die "cannot unpack the channels";
|
||||
|
||||
# Make the channels appear in nix-env.
|
||||
unlink $nixDefExpr if -l $nixDefExpr; # old-skool ~/.nix-defexpr
|
||||
mkdir $nixDefExpr or die "cannot create directory ‘$nixDefExpr’" if !-e $nixDefExpr;
|
||||
my $channelLink = "$nixDefExpr/channels";
|
||||
unlink $channelLink; # !!! not atomic
|
||||
symlink($profile, $channelLink) or die "cannot symlink ‘$channelLink’ to ‘$profile’";
|
||||
}
|
||||
|
||||
|
||||
die "$0: argument expected\n" if scalar @ARGV == 0;
|
||||
|
||||
|
||||
while (scalar @ARGV) {
|
||||
my $arg = shift @ARGV;
|
||||
|
||||
if ($arg eq "--add") {
|
||||
die "$0: ‘--add’ requires one or two arguments\n" if scalar @ARGV < 1 || scalar @ARGV > 2;
|
||||
my $url = shift @ARGV;
|
||||
my $name = shift @ARGV;
|
||||
unless (defined $name) {
|
||||
$name = basename $url;
|
||||
$name =~ s/-unstable//;
|
||||
$name =~ s/-stable//;
|
||||
}
|
||||
addChannel($url, $name);
|
||||
last;
|
||||
}
|
||||
|
||||
if ($arg eq "--remove") {
|
||||
die "$0: ‘--remove’ requires one argument\n" if scalar @ARGV != 1;
|
||||
removeChannel(shift @ARGV);
|
||||
last;
|
||||
}
|
||||
|
||||
if ($arg eq "--list") {
|
||||
die "$0: ‘--list’ requires one argument\n" if scalar @ARGV != 0;
|
||||
readChannels;
|
||||
foreach my $name (keys %channels) {
|
||||
print "$name $channels{$name}\n";
|
||||
}
|
||||
last;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--update") {
|
||||
update(@ARGV);
|
||||
last;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--rollback") {
|
||||
die "$0: ‘--rollback’ has at most one argument\n" if scalar @ARGV > 1;
|
||||
my $generation = shift @ARGV;
|
||||
my @args = ("$Nix::Config::binDir/nix-env", "--profile", $profile);
|
||||
if (defined $generation) {
|
||||
die "invalid channel generation number ‘$generation’" unless $generation =~ /^[0-9]+$/;
|
||||
push @args, "--switch-generation", $generation;
|
||||
} else {
|
||||
push @args, "--rollback";
|
||||
}
|
||||
system(@args) == 0 or exit 1;
|
||||
last;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--help") {
|
||||
exec "man nix-channel" or die;
|
||||
}
|
||||
|
||||
elsif ($arg eq "--version") {
|
||||
print "nix-channel (Nix) $Nix::Config::version\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
else {
|
||||
die "unknown argument ‘$arg’; try ‘--help’\n";
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use utf8;
|
||||
use strict;
|
||||
use Nix::SSH;
|
||||
use Nix::Config;
|
||||
use Nix::Store;
|
||||
use Nix::CopyClosure;
|
||||
use List::Util qw(sum);
|
||||
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
if (scalar @ARGV < 1) {
|
||||
print STDERR <<EOF
|
||||
Usage: nix-copy-closure [--from | --to] HOSTNAME [--sign] [--gzip] [--bzip2] [--xz] PATHS...
|
||||
EOF
|
||||
;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
|
||||
# Get the target host.
|
||||
my $sshHost;
|
||||
my $sign = 0;
|
||||
my $toMode = 1;
|
||||
my $includeOutputs = 0;
|
||||
my $dryRun = 0;
|
||||
my $useSubstitutes = 0;
|
||||
my $verbosity = 1;
|
||||
|
||||
|
||||
# !!! Copied from nix-pack-closure, should put this in a module.
|
||||
my @storePaths = ();
|
||||
|
||||
while (@ARGV) {
|
||||
my $arg = shift @ARGV;
|
||||
|
||||
if ($arg eq "--help") {
|
||||
exec "man nix-copy-closure" or die;
|
||||
}
|
||||
elsif ($arg eq "--sign") {
|
||||
$sign = 1;
|
||||
}
|
||||
elsif ($arg eq "--gzip" || $arg eq "--bzip2" || $arg eq "--xz") {
|
||||
warn "$0: ‘$arg’ is not implemented\n" if $arg ne "--gzip";
|
||||
push @globalSshOpts, "-C";
|
||||
}
|
||||
elsif ($arg eq "--from") {
|
||||
$toMode = 0;
|
||||
}
|
||||
elsif ($arg eq "--to") {
|
||||
$toMode = 1;
|
||||
}
|
||||
elsif ($arg eq "--include-outputs") {
|
||||
$includeOutputs = 1;
|
||||
}
|
||||
elsif ($arg eq "--show-progress") {
|
||||
warn "$0: ‘$arg’ is not implemented\n";
|
||||
}
|
||||
elsif ($arg eq "--dry-run") {
|
||||
$dryRun = 1;
|
||||
}
|
||||
elsif ($arg eq "--use-substitutes" || $arg eq "-s") {
|
||||
$useSubstitutes = 1;
|
||||
}
|
||||
elsif ($arg eq "-v") {
|
||||
$verbosity++;
|
||||
setVerbosity($verbosity);
|
||||
}
|
||||
elsif (!defined $sshHost) {
|
||||
$sshHost = $arg;
|
||||
}
|
||||
else {
|
||||
push @storePaths, $arg;
|
||||
}
|
||||
}
|
||||
|
||||
die "$0: you did not specify a host name\n" unless defined $sshHost;
|
||||
|
||||
|
||||
if ($toMode) { # Copy TO the remote machine.
|
||||
Nix::CopyClosure::copyTo(
|
||||
$sshHost, [ @storePaths ],
|
||||
$includeOutputs, $dryRun, $sign, $useSubstitutes);
|
||||
}
|
||||
|
||||
else { # Copy FROM the remote machine.
|
||||
|
||||
my ($from, $to) = connectToRemoteNix($sshHost, []);
|
||||
|
||||
# Query the closure of the given store paths on the remote
|
||||
# machine. Paths are assumed to be store paths; there is no
|
||||
# resolution (following of symlinks).
|
||||
syswrite($to, pack("L<x4L<x4", 7, $includeOutputs ? 1 : 0)) or die;
|
||||
writeStrings(\@storePaths, $to);
|
||||
my @missing = grep { !isValidPath($_) } readStrings($from);
|
||||
|
||||
# Export the store paths on the remote machine and import them locally.
|
||||
if (scalar @missing > 0) {
|
||||
print STDERR "copying ", scalar @missing, " missing paths from ‘$sshHost’...\n";
|
||||
writeInt(5, $to); # == cmdExportPaths
|
||||
writeInt($sign ? 1 : 0, $to);
|
||||
writeStrings(\@missing, $to);
|
||||
importPaths(fileno($from));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use strict;
|
||||
use Nix::Manifest;
|
||||
use Nix::GeneratePatches;
|
||||
use Nix::Utils;
|
||||
|
||||
if (scalar @ARGV != 5) {
|
||||
print STDERR <<EOF;
|
||||
Usage: nix-generate-patches NAR-DIR PATCH-DIR PATCH-URI OLD-MANIFEST NEW-MANIFEST
|
||||
|
||||
This command generates binary patches between NAR files listed in
|
||||
OLD-MANIFEST and NEW-MANIFEST. The patches are written to the
|
||||
directory PATCH-DIR, and the prefix PATCH-URI is used to generate URIs
|
||||
for the patches. The patches are added to NEW-MANIFEST. All NARs are
|
||||
required to exist in NAR-DIR. Patches are generated between
|
||||
succeeding versions of packages with the same name.
|
||||
EOF
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $narPath = $ARGV[0];
|
||||
my $patchesPath = $ARGV[1];
|
||||
my $patchesURL = $ARGV[2];
|
||||
my $srcManifest = $ARGV[3];
|
||||
my $dstManifest = $ARGV[4];
|
||||
|
||||
my (%srcNarFiles, %srcLocalPaths, %srcPatches);
|
||||
readManifest $srcManifest, \%srcNarFiles, \%srcPatches;
|
||||
|
||||
my (%dstNarFiles, %dstLocalPaths, %dstPatches);
|
||||
readManifest $dstManifest, \%dstNarFiles, \%dstPatches;
|
||||
|
||||
my $tmpDir = mkTempDir("nix-generate-patches");
|
||||
|
||||
generatePatches \%srcNarFiles, \%dstNarFiles, \%srcPatches, \%dstPatches,
|
||||
$narPath, $patchesPath, $patchesURL, $tmpDir;
|
||||
|
||||
propagatePatches \%srcPatches, \%dstNarFiles, \%dstPatches;
|
||||
|
||||
# Optionally add all new patches to the manifest in $NIX_ALL_PATCHES.
|
||||
my $allPatchesFile = $ENV{"NIX_ALL_PATCHES"};
|
||||
if (defined $allPatchesFile) {
|
||||
my (%dummy, %allPatches);
|
||||
readManifest("$patchesPath/all-patches", \%dummy, \%allPatches)
|
||||
if -f $allPatchesFile;
|
||||
copyPatches \%dstPatches, \%allPatches;
|
||||
writeManifest($allPatchesFile, {}, \%allPatches, 0);
|
||||
}
|
||||
|
||||
writeManifest $dstManifest, \%dstNarFiles, \%dstPatches;
|
||||
@@ -1,143 +0,0 @@
|
||||
#! @perl@ -w @perlFlags@
|
||||
|
||||
use utf8;
|
||||
use strict;
|
||||
use Nix::Config;
|
||||
use Nix::Utils;
|
||||
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
|
||||
# Parse the command line arguments.
|
||||
my @args = @ARGV;
|
||||
|
||||
my $source;
|
||||
my $fromURL = 0;
|
||||
my @extraNixEnvArgs = ();
|
||||
my $interactive = 1;
|
||||
my $op = "--install";
|
||||
|
||||
while (scalar @args) {
|
||||
my $arg = shift @args;
|
||||
if ($arg eq "--help") {
|
||||
exec "man nix-install-package" or die;
|
||||
}
|
||||
elsif ($arg eq "--url") {
|
||||
$fromURL = 1;
|
||||
}
|
||||
elsif ($arg eq "--profile" || $arg eq "-p") {
|
||||
my $profile = shift @args;
|
||||
die "$0: ‘--profile’ requires an argument\n" if !defined $profile;
|
||||
push @extraNixEnvArgs, "-p", $profile;
|
||||
}
|
||||
elsif ($arg eq "--set") {
|
||||
$op = "--set";
|
||||
}
|
||||
elsif ($arg eq "--non-interactive") {
|
||||
$interactive = 0;
|
||||
}
|
||||
else {
|
||||
$source = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
die "$0: please specify a .nixpkg file or URL\n" unless defined $source;
|
||||
|
||||
|
||||
# Re-execute in a terminal, if necessary, so that if we're executed
|
||||
# from a web browser, the user gets to see us.
|
||||
if ($interactive && !defined $ENV{"NIX_HAVE_TERMINAL"}) {
|
||||
$ENV{"NIX_HAVE_TERMINAL"} = "1";
|
||||
$ENV{"LD_LIBRARY_PATH"} = "";
|
||||
foreach my $term ("xterm", "konsole", "gnome-terminal", "xterm") {
|
||||
exec($term, "-e", "$Nix::Config::binDir/nix-install-package", @ARGV);
|
||||
}
|
||||
die "cannot execute ‘xterm’";
|
||||
}
|
||||
|
||||
|
||||
my $tmpDir = mkTempDir("nix-install-package");
|
||||
|
||||
|
||||
sub barf {
|
||||
my $msg = shift;
|
||||
print "\nInstallation failed: $msg\n";
|
||||
<STDIN> if $interactive;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
|
||||
# Download the package description, if necessary.
|
||||
my $pkgFile = $source;
|
||||
if ($fromURL) {
|
||||
$pkgFile = "$tmpDir/tmp.nixpkg";
|
||||
system("@curl@", "-L", "--silent", $source, "-o", $pkgFile) == 0
|
||||
or barf "curl failed: $?";
|
||||
}
|
||||
|
||||
|
||||
# Read and parse the package file.
|
||||
open PKGFILE, "<$pkgFile" or barf "cannot open ‘$pkgFile’: $!";
|
||||
my $contents = <PKGFILE>;
|
||||
close PKGFILE;
|
||||
|
||||
my $nameRE = "(?: [A-Za-z0-9\+\-\.\_\?\=]+ )"; # see checkStoreName()
|
||||
my $systemRE = "(?: [A-Za-z0-9\+\-\_]+ )";
|
||||
my $pathRE = "(?: \/ [\/A-Za-z0-9\+\-\.\_\?\=]* )";
|
||||
|
||||
# Note: $pathRE doesn't check that whether we're looking at a valid
|
||||
# store path. We'll let nix-env do that.
|
||||
|
||||
$contents =~
|
||||
/ ^ \s* (\S+) \s+ ($Nix::Utils::urlRE) \s+ ($nameRE) \s+ ($systemRE) \s+ ($pathRE) \s+ ($pathRE) ( \s+ ($Nix::Utils::urlRE) )? /x
|
||||
or barf "invalid package contents";
|
||||
my $version = $1;
|
||||
my $manifestURL = $2;
|
||||
my $drvName = $3;
|
||||
my $system = $4;
|
||||
my $drvPath = $5;
|
||||
my $outPath = $6;
|
||||
my $binaryCacheURL = $8;
|
||||
|
||||
barf "invalid package version ‘$version’" unless $version eq "NIXPKG1";
|
||||
|
||||
|
||||
if ($interactive) {
|
||||
# Ask confirmation.
|
||||
print "Do you want to install ‘$drvName’ (Y/N)? ";
|
||||
my $reply = <STDIN>;
|
||||
chomp $reply;
|
||||
exit if $reply ne "y" && $reply ne "Y";
|
||||
}
|
||||
|
||||
|
||||
if (defined $binaryCacheURL) {
|
||||
|
||||
push @extraNixEnvArgs, "--option", "extra-binary-caches", $binaryCacheURL;
|
||||
|
||||
} else {
|
||||
|
||||
# Store the manifest in the temporary directory so that we don't
|
||||
# pollute /nix/var/nix/manifests. This also requires that we
|
||||
# don't use the Nix daemon (because otherwise
|
||||
# download-using-manifests won't see our NIX_MANIFESTS_DIRS
|
||||
# environment variable).
|
||||
$ENV{NIX_MANIFESTS_DIR} = $tmpDir;
|
||||
$ENV{NIX_REMOTE} = "";
|
||||
|
||||
print "\nPulling manifests...\n";
|
||||
system("$Nix::Config::binDir/nix-pull", $manifestURL) == 0
|
||||
or barf "nix-pull failed: $?";
|
||||
|
||||
}
|
||||
|
||||
|
||||
print "\nInstalling package...\n";
|
||||
system("$Nix::Config::binDir/nix-env", $op, $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0
|
||||
or barf "nix-env failed: $?";
|
||||
|
||||
|
||||
if ($interactive) {
|
||||
print "\nInstallation succeeded! Press Enter to continue.\n";
|
||||
<STDIN>;
|
||||
}
|
||||
54
scripts/nix-profile-daemon.sh.in
Normal file
54
scripts/nix-profile-daemon.sh.in
Normal file
@@ -0,0 +1,54 @@
|
||||
# Only execute this file once per shell.
|
||||
if [ -n "$__ETC_PROFILE_NIX_SOURCED" ]; then return; fi
|
||||
__ETC_PROFILE_NIX_SOURCED=1
|
||||
|
||||
# Set up secure multi-user builds: non-root users build through the
|
||||
# Nix daemon.
|
||||
if [ "$USER" != root -o ! -w @localstatedir@/nix/db ]; then
|
||||
export NIX_REMOTE=daemon
|
||||
fi
|
||||
|
||||
export NIX_USER_PROFILE_DIR="@localstatedir@/nix/profiles/per-user/$USER"
|
||||
export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile"
|
||||
|
||||
# Set up the per-user profile.
|
||||
mkdir -m 0755 -p $NIX_USER_PROFILE_DIR
|
||||
if ! test -O "$NIX_USER_PROFILE_DIR"; then
|
||||
echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2
|
||||
fi
|
||||
|
||||
if test -w $HOME; then
|
||||
if ! test -L $HOME/.nix-profile; then
|
||||
if test "$USER" != root; then
|
||||
ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile
|
||||
else
|
||||
# Root installs in the system-wide profile by default.
|
||||
ln -s @localstatedir@/nix/profiles/default $HOME/.nix-profile
|
||||
fi
|
||||
fi
|
||||
|
||||
# Subscribe the root user to the NixOS channel by default.
|
||||
if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then
|
||||
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > $HOME/.nix-channels
|
||||
fi
|
||||
|
||||
# Create the per-user garbage collector roots directory.
|
||||
NIX_USER_GCROOTS_DIR=@localstatedir@/nix/gcroots/per-user/$USER
|
||||
mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR
|
||||
if ! test -O "$NIX_USER_GCROOTS_DIR"; then
|
||||
echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2
|
||||
fi
|
||||
|
||||
# Set up a default Nix expression from which to install stuff.
|
||||
if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then
|
||||
rm -f $HOME/.nix-defexpr
|
||||
mkdir -p $HOME/.nix-defexpr
|
||||
if [ "$USER" != root ]; then
|
||||
ln -s @localstatedir@/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
export NIX_SSL_CERT_FILE="@localstatedir@/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
|
||||
export NIX_PATH="@localstatedir@/nix/profiles/per-user/root/channels"
|
||||
export PATH="$HOME/.nix-profile/bin:$HOME/.nix-profile/lib/kde4/libexec:@localstatedir@/nix/profiles/default/bin:@localstatedir@/nix/profiles/default:@localstatedir@/nix/profiles/default/lib/kde4/libexec:$PATH"
|
||||
@@ -1,35 +1,84 @@
|
||||
if [ -n "$HOME" ]; then
|
||||
NIX_LINK="$HOME/.nix-profile"
|
||||
if [ -n "$HOME" ] && [ -n "$USER" ]; then
|
||||
__savedpath="$PATH"
|
||||
export PATH=@coreutils@
|
||||
|
||||
# Set the default profile.
|
||||
if ! [ -L "$NIX_LINK" ]; then
|
||||
echo "creating $NIX_LINK" >&2
|
||||
_NIX_DEF_LINK=@localstatedir@/nix/profiles/default
|
||||
@coreutils@/ln -s "$_NIX_DEF_LINK" "$NIX_LINK"
|
||||
# Set up the per-user profile.
|
||||
# This part should be kept in sync with nixpkgs:nixos/modules/programs/shell.nix
|
||||
|
||||
NIX_LINK=$HOME/.nix-profile
|
||||
|
||||
NIX_USER_PROFILE_DIR=@localstatedir@/nix/profiles/per-user/$USER
|
||||
|
||||
mkdir -m 0755 -p "$NIX_USER_PROFILE_DIR"
|
||||
|
||||
if [ "$(stat --printf '%u' "$NIX_USER_PROFILE_DIR")" != "$(id -u)" ]; then
|
||||
echo "Nix: WARNING: bad ownership on "$NIX_USER_PROFILE_DIR", should be $(id -u)" >&2
|
||||
fi
|
||||
|
||||
export PATH=$NIX_LINK/bin:$NIX_LINK/sbin:$PATH
|
||||
if [ -w "$HOME" ]; then
|
||||
if ! [ -L "$NIX_LINK" ]; then
|
||||
echo "Nix: creating $NIX_LINK" >&2
|
||||
if [ "$USER" != root ]; then
|
||||
if ! ln -s "$NIX_USER_PROFILE_DIR"/profile "$NIX_LINK"; then
|
||||
echo "Nix: WARNING: could not create $NIX_LINK -> $NIX_USER_PROFILE_DIR/profile" >&2
|
||||
fi
|
||||
else
|
||||
# Root installs in the system-wide profile by default.
|
||||
ln -s @localstatedir@/nix/profiles/default "$NIX_LINK"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Subscribe the user to the Nixpkgs channel by default.
|
||||
if [ ! -e $HOME/.nix-channels ]; then
|
||||
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > $HOME/.nix-channels
|
||||
# Subscribe the user to the unstable Nixpkgs channel by default.
|
||||
if [ ! -e "$HOME/.nix-channels" ]; then
|
||||
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$HOME/.nix-channels"
|
||||
fi
|
||||
|
||||
# Create the per-user garbage collector roots directory.
|
||||
__user_gcroots=@localstatedir@/nix/gcroots/per-user/"$USER"
|
||||
mkdir -m 0755 -p "$__user_gcroots"
|
||||
if [ "$(stat --printf '%u' "$__user_gcroots")" != "$(id -u)" ]; then
|
||||
echo "Nix: WARNING: bad ownership on $__user_gcroots, should be $(id -u)" >&2
|
||||
fi
|
||||
unset __user_gcroots
|
||||
|
||||
# Set up a default Nix expression from which to install stuff.
|
||||
__nix_defexpr="$HOME"/.nix-defexpr
|
||||
[ -L "$__nix_defexpr" ] && rm -f "$__nix_defexpr"
|
||||
mkdir -m 0755 -p "$__nix_defexpr"
|
||||
if [ "$USER" != root ] && [ ! -L "$__nix_defexpr"/channels_root ]; then
|
||||
ln -s @localstatedir@/nix/profiles/per-user/root/channels "$__nix_defexpr"/channels_root
|
||||
fi
|
||||
unset __nix_defexpr
|
||||
fi
|
||||
|
||||
# Append ~/.nix-defexpr/channels/nixpkgs to $NIX_PATH so that
|
||||
# <nixpkgs> paths work when the user has fetched the Nixpkgs
|
||||
# channel.
|
||||
export NIX_PATH=${NIX_PATH:+$NIX_PATH:}nixpkgs=$HOME/.nix-defexpr/channels/nixpkgs
|
||||
export NIX_PATH="${NIX_PATH:+$NIX_PATH:}nixpkgs=$HOME/.nix-defexpr/channels/nixpkgs"
|
||||
|
||||
# Set $SSL_CERT_FILE so that Nixpkgs applications like curl work.
|
||||
# Set up environment.
|
||||
# This part should be kept in sync with nixpkgs:nixos/modules/programs/environment.nix
|
||||
NIX_PROFILES="@localstatedir@/nix/profiles/default $NIX_USER_PROFILE_DIR"
|
||||
|
||||
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
|
||||
if [ -e /etc/ssl/certs/ca-certificates.crt ]; then # NixOS, Ubuntu, Debian, Gentoo, Arch
|
||||
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||
export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||
elif [ -e /etc/ssl/ca-bundle.pem ]; then # openSUSE Tumbleweed
|
||||
export NIX_SSL_CERT_FILE=/etc/ssl/ca-bundle.pem
|
||||
elif [ -e /etc/ssl/certs/ca-bundle.crt ]; then # Old NixOS
|
||||
export SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt
|
||||
export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt
|
||||
elif [ -e /etc/pki/tls/certs/ca-bundle.crt ]; then # Fedora, CentOS
|
||||
export SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
|
||||
export NIX_SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
|
||||
elif [ -e "$NIX_LINK/etc/ssl/certs/ca-bundle.crt" ]; then # fall back to cacert in Nix profile
|
||||
export SSL_CERT_FILE="$NIX_LINK/etc/ssl/certs/ca-bundle.crt"
|
||||
export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ssl/certs/ca-bundle.crt"
|
||||
elif [ -e "$NIX_LINK/etc/ca-bundle.crt" ]; then # old cacert in Nix profile
|
||||
export SSL_CERT_FILE="$NIX_LINK/etc/ca-bundle.crt"
|
||||
export NIX_SSL_CERT_FILE="$NIX_LINK/etc/ca-bundle.crt"
|
||||
fi
|
||||
|
||||
if [ -n ${MANPATH} ]; then
|
||||
export MANPATH="$NIX_LINK/share/man:$MANPATH"
|
||||
fi
|
||||
|
||||
export PATH="$NIX_LINK/bin:$__savedpath"
|
||||
unset __savedpath NIX_LINK NIX_USER_PROFILE_DIR NIX_PROFILES
|
||||
fi
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user