mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-06 13:23:41 +00:00
Compare commits
433 Commits
netboot-sy
...
23.05
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ecab32735 | ||
|
|
96104cd70d | ||
|
|
8e037d02c5 | ||
|
|
c73d5bbe29 | ||
|
|
afc48694f2 | ||
|
|
7098a461b9 | ||
|
|
41055915ba | ||
|
|
542ccc3f66 | ||
|
|
3a70dd9299 | ||
|
|
e0c4bd5a43 | ||
|
|
a24d8907d8 | ||
|
|
79f01961e1 | ||
|
|
3c8af3ab55 | ||
|
|
8d3dea249c | ||
|
|
48f3d9f076 | ||
|
|
d5abae4393 | ||
|
|
db3bdea8aa | ||
|
|
368a647283 | ||
|
|
d6247c820e | ||
|
|
495a318fbc | ||
|
|
863f1aeaae | ||
|
|
45a7531aa7 | ||
|
|
6d633268cc | ||
|
|
d2bb180efb | ||
|
|
b742bc935f | ||
|
|
aa5def2b01 | ||
|
|
c586a8d161 | ||
|
|
0bc8042190 | ||
|
|
9ad9df906f | ||
|
|
1c4e8d50d5 | ||
|
|
f75211f50e | ||
|
|
30c0659823 | ||
|
|
ab5948439b | ||
|
|
375ecfd863 | ||
|
|
28e673c3fd | ||
|
|
db376128a9 | ||
|
|
887b93a670 | ||
|
|
46769d3fb3 | ||
|
|
08d8ab0ac0 | ||
|
|
f789a17825 | ||
|
|
cdfdc7a73d | ||
|
|
f088e9e4bf | ||
|
|
eb592ef8bb | ||
|
|
f83d0ac0dd | ||
|
|
9f3c48eea5 | ||
|
|
8b26f67c6c | ||
|
|
35a6f5fba6 | ||
|
|
91f654d57c | ||
|
|
75b9ef08a3 | ||
|
|
8c5f01ab09 | ||
|
|
8c11bacbe0 | ||
|
|
396b302063 | ||
|
|
456af4e174 | ||
|
|
836e08d4a3 | ||
|
|
150e1d646f | ||
|
|
4b2b21e057 | ||
|
|
0ac05883fd | ||
|
|
44be25f5d3 | ||
|
|
1c236e4e4b | ||
|
|
21c2ec414a | ||
|
|
0491e5b06c | ||
|
|
1c9ddfaf79 | ||
|
|
91b7c492eb | ||
|
|
6b0edc9c69 | ||
|
|
3e687616ef | ||
|
|
c8cc8f57b6 | ||
|
|
d124449613 | ||
|
|
8cc61b1760 | ||
|
|
b092d78933 | ||
|
|
302fb6f669 | ||
|
|
7f4bf64484 | ||
|
|
b0738abee5 | ||
|
|
6513727cd2 | ||
|
|
1a51bda012 | ||
|
|
b88f160f57 | ||
|
|
ebf717d1c8 | ||
|
|
199f37ef27 | ||
|
|
eaad07e492 | ||
|
|
2677e428c0 | ||
|
|
63c89cb2b2 | ||
|
|
50801ac9ce | ||
|
|
7aeb7d0a61 | ||
|
|
7f2b788a7d | ||
|
|
701cdfea20 | ||
|
|
e8e6dd43cc | ||
|
|
ebda50955b | ||
|
|
7c3e7b3316 | ||
|
|
808b8c28a6 | ||
|
|
1e41641dbc | ||
|
|
e014c1146e | ||
|
|
18b51048e7 | ||
|
|
8d245c250a | ||
|
|
dda46f49cf | ||
|
|
1c4f953551 | ||
|
|
26666e9ff0 | ||
|
|
8be013d859 | ||
|
|
f3dc1b9162 | ||
|
|
e205638d49 | ||
|
|
46853f900d | ||
|
|
df86485a0a | ||
|
|
e2696767a7 | ||
|
|
f3cf6bf825 | ||
|
|
bee04d0747 | ||
|
|
73eca51a59 | ||
|
|
56b4c2b5b1 | ||
|
|
a421d99009 | ||
|
|
5238dd1398 | ||
|
|
9bad46c9e2 | ||
|
|
c5fba7d0cc | ||
|
|
5991c8c879 | ||
|
|
d14b8ea6d4 | ||
|
|
82fbf4ed44 | ||
|
|
89b62b7d9c | ||
|
|
577d6a0770 | ||
|
|
91e5c9cd6d | ||
|
|
c982eeacaa | ||
|
|
85fcd99c25 | ||
|
|
1215b850a0 | ||
|
|
0f7f5ca1cd | ||
|
|
cc0473f1f2 | ||
|
|
768823d0d3 | ||
|
|
ce84f29a07 | ||
|
|
d4815196cf | ||
|
|
a9f370a0ab | ||
|
|
b32a7c2830 | ||
|
|
457addc5e4 | ||
|
|
274a1f5513 | ||
|
|
e0fcf8d473 | ||
|
|
bf0b59d28a | ||
|
|
a524bdb793 | ||
|
|
bb0e938339 | ||
|
|
6287b47dbf | ||
|
|
e8362b3301 | ||
|
|
3af35e0160 | ||
|
|
6b1d2713ba | ||
|
|
0f7dc597a1 | ||
|
|
6d6c02e2d1 | ||
|
|
6b78c6fff6 | ||
|
|
72a91b65a0 | ||
|
|
d5ecf14485 | ||
|
|
e59879a082 | ||
|
|
421a2a2865 | ||
|
|
299739821b | ||
|
|
b2ea8027e4 | ||
|
|
cc1d74ebb7 | ||
|
|
76eaaa955a | ||
|
|
8a12d9d2b1 | ||
|
|
aea3db7cca | ||
|
|
4a6941468c | ||
|
|
c9781594ad | ||
|
|
1f0296a3c2 | ||
|
|
ea94a9a03f | ||
|
|
ad665ad345 | ||
|
|
a97b9eb156 | ||
|
|
b8b0e887c2 | ||
|
|
6d756d6811 | ||
|
|
3406dd8fc3 | ||
|
|
d1c9b778de | ||
|
|
a7adeadc7d | ||
|
|
08510f659c | ||
|
|
442779c7da | ||
|
|
2509259b74 | ||
|
|
b8de729e7c | ||
|
|
58c3fa5e2d | ||
|
|
8a3be7b666 | ||
|
|
93c81a0355 | ||
|
|
f0ea32a015 | ||
|
|
0123c9a037 | ||
|
|
d5f9514859 | ||
|
|
090f9827ca | ||
|
|
988659956f | ||
|
|
edc5dba610 | ||
|
|
ece06e393a | ||
|
|
1de6861e51 | ||
|
|
af521cd2ae | ||
|
|
b2d02f4b32 | ||
|
|
ccaac5fbce | ||
|
|
556740604e | ||
|
|
d04b2c2d20 | ||
|
|
a188d8f164 | ||
|
|
9f50e6fd10 | ||
|
|
cc29349069 | ||
|
|
058e009d69 | ||
|
|
69983d044b | ||
|
|
3d622da1d3 | ||
|
|
5d0a53f1d5 | ||
|
|
d0d8540dba | ||
|
|
6e175cb034 | ||
|
|
35db04da32 | ||
|
|
aa28d88d0f | ||
|
|
00ce943ed2 | ||
|
|
1d821d002d | ||
|
|
b672dde513 | ||
|
|
e3aaf954ea | ||
|
|
99450b7ebd | ||
|
|
a422cd1f5b | ||
|
|
e996ea9d5d | ||
|
|
5e99b338b7 | ||
|
|
213b7e96ef | ||
|
|
28b5e66f35 | ||
|
|
e122f584b2 | ||
|
|
9b7fe8be9e | ||
|
|
02d4e45afa | ||
|
|
08a2058e17 | ||
|
|
0f99cd5301 | ||
|
|
64ed370bfc | ||
|
|
2746b294b4 | ||
|
|
9262ab08dd | ||
|
|
dfac16396a | ||
|
|
a3d0197ac9 | ||
|
|
dd8ed4f367 | ||
|
|
e7c76f733a | ||
|
|
857fe6edc9 | ||
|
|
0514bdfa1b | ||
|
|
0827d32976 | ||
|
|
6b93b785a8 | ||
|
|
10d5a68270 | ||
|
|
119e81ec25 | ||
|
|
f53631beb6 | ||
|
|
fbeebc72a5 | ||
|
|
43e777fc54 | ||
|
|
048b207b83 | ||
|
|
4976401a1b | ||
|
|
7f90e4f465 | ||
|
|
5140520c46 | ||
|
|
f5d2a562aa | ||
|
|
21bdb31acf | ||
|
|
32f83afa1d | ||
|
|
ef5edfaa02 | ||
|
|
471fa6198c | ||
|
|
f4f955bdb1 | ||
|
|
2b13371ea4 | ||
|
|
793f18cc0a | ||
|
|
85105ce9e5 | ||
|
|
3e04372002 | ||
|
|
2119607b04 | ||
|
|
fed0f6b679 | ||
|
|
52f7661302 | ||
|
|
0298ddc291 | ||
|
|
551a52bfdd | ||
|
|
78a71d663b | ||
|
|
0613dd2f7f | ||
|
|
80c96eeab6 | ||
|
|
77df69d5d4 | ||
|
|
6d511393be | ||
|
|
4a588b3dde | ||
|
|
b8237ed368 | ||
|
|
457cf1d281 | ||
|
|
c2f8c299fa | ||
|
|
9b4265a561 | ||
|
|
174545d89c | ||
|
|
c9b70da3ad | ||
|
|
7f17766e1f | ||
|
|
e3fdbb4901 | ||
|
|
223ecb9e8f | ||
|
|
efdc2d5bdc | ||
|
|
31ecd7ecbb | ||
|
|
3efe5de302 | ||
|
|
c624e77f6e | ||
|
|
04db6fa39a | ||
|
|
0ab0470e38 | ||
|
|
d6abff1574 | ||
|
|
a0135679f4 | ||
|
|
11dfe1a879 | ||
|
|
e55d24212a | ||
|
|
1fe7da90a3 | ||
|
|
ed71b5b0f7 | ||
|
|
ee70acd48c | ||
|
|
1fdfe31764 | ||
|
|
a997a4d9d3 | ||
|
|
857d4a5b6c | ||
|
|
069de7d3de | ||
|
|
cc6e2950a7 | ||
|
|
3ec17e7bb1 | ||
|
|
bd194bf1c3 | ||
|
|
250cb590d7 | ||
|
|
d6b7715a4e | ||
|
|
a1fa641087 | ||
|
|
83c738b00b | ||
|
|
04a15cb807 | ||
|
|
36ecfe225b | ||
|
|
48c9c85664 | ||
|
|
a28170c0a2 | ||
|
|
06aa417df3 | ||
|
|
9345dd394a | ||
|
|
966dd8adbf | ||
|
|
f432d56d3e | ||
|
|
1f69bc18e5 | ||
|
|
38c09c6171 | ||
|
|
2dd05e9405 | ||
|
|
e2132c5a86 | ||
|
|
f2d887176a | ||
|
|
f50a0e5265 | ||
|
|
b1b92a66d6 | ||
|
|
8739e6886d | ||
|
|
a388f4eed2 | ||
|
|
1c34225a4e | ||
|
|
62df627f4c | ||
|
|
425db8ee16 | ||
|
|
4cecc10dce | ||
|
|
8e46085919 | ||
|
|
0087595dcf | ||
|
|
8d3f727a71 | ||
|
|
ad00d58a94 | ||
|
|
41a6a73503 | ||
|
|
1ff23dda0d | ||
|
|
bfc5164718 | ||
|
|
cfb827885f | ||
|
|
2bc6602211 | ||
|
|
be5b4ac906 | ||
|
|
6497f21147 | ||
|
|
3e01645c40 | ||
|
|
7d9b9174b0 | ||
|
|
74e6f7f561 | ||
|
|
3f70e5731e | ||
|
|
0eaad3f2a2 | ||
|
|
1090358cdf | ||
|
|
f699078542 | ||
|
|
cd8ffddea1 | ||
|
|
3c261da1c3 | ||
|
|
835b889643 | ||
|
|
b123ab2d5e | ||
|
|
d3126ce1e2 | ||
|
|
a5f2d4f163 | ||
|
|
ed08a674a0 | ||
|
|
cc1aaa3622 | ||
|
|
9602964d5d | ||
|
|
d6568f8517 | ||
|
|
ac1000808e | ||
|
|
0b078833a6 | ||
|
|
e364809951 | ||
|
|
4261dbd169 | ||
|
|
8d8853e273 | ||
|
|
d5a516fb3e | ||
|
|
99f643e1e5 | ||
|
|
b024fb946f | ||
|
|
ede5abe8a8 | ||
|
|
29a1f5da8a | ||
|
|
60689d8e90 | ||
|
|
4652001fbf | ||
|
|
27b772ec41 | ||
|
|
77eef13fa1 | ||
|
|
27d8b3f96c | ||
|
|
4427ab6984 | ||
|
|
12f0d28a0d | ||
|
|
04aaf85116 | ||
|
|
14d705891f | ||
|
|
3af25a499b | ||
|
|
cbafec613f | ||
|
|
180628d1ff | ||
|
|
d062649518 | ||
|
|
6f45b048f7 | ||
|
|
9af725960d | ||
|
|
50c2d6286d | ||
|
|
8a2ccaac6b | ||
|
|
8580a5b082 | ||
|
|
18cec7ec49 | ||
|
|
1ecb1e3999 | ||
|
|
2a71badc26 | ||
|
|
9eb7c64209 | ||
|
|
2d23b78c52 | ||
|
|
9278039db1 | ||
|
|
41d0491b13 | ||
|
|
cb3978d9a3 | ||
|
|
f6a7c6e773 | ||
|
|
ca24dcc740 | ||
|
|
a9310e60df | ||
|
|
631d992dc2 | ||
|
|
001eb8b632 | ||
|
|
86e3f67337 | ||
|
|
dfc1683fe9 | ||
|
|
b0459b97a5 | ||
|
|
5f224f1ecc | ||
|
|
5ca6cfb7f9 | ||
|
|
84f2456559 | ||
|
|
78334a1869 | ||
|
|
36e5814189 | ||
|
|
9db4a3ce91 | ||
|
|
cc670234fe | ||
|
|
34e8da526f | ||
|
|
dbedb3ca64 | ||
|
|
2005b4cb36 | ||
|
|
ad13c7d4b2 | ||
|
|
daa7efafc2 | ||
|
|
e9541f5ef8 | ||
|
|
211887ae92 | ||
|
|
4ff81fbbb2 | ||
|
|
4a2c772aa4 | ||
|
|
6bcc5c7313 | ||
|
|
db62d67165 | ||
|
|
e259aab293 | ||
|
|
8f7ea8122a | ||
|
|
8d7f712c6d | ||
|
|
a2d9192c79 | ||
|
|
7503df039b | ||
|
|
88b0a6677a | ||
|
|
b2dc3d2ff7 | ||
|
|
60eb8e5a16 | ||
|
|
d69ca6f2a5 | ||
|
|
bd49ad26dc | ||
|
|
77a0718670 | ||
|
|
29b02e8a1a | ||
|
|
e860af4f68 | ||
|
|
dc190db41e | ||
|
|
b183dcf768 | ||
|
|
7e50a2399e | ||
|
|
c8b6900c66 | ||
|
|
8300aaab9e | ||
|
|
d73b4bfb70 | ||
|
|
7043f47103 | ||
|
|
157663393d | ||
|
|
0518ad2c6b | ||
|
|
1e78d6d6e0 | ||
|
|
2280d15d30 | ||
|
|
bb48e97e74 | ||
|
|
f61ba66c1f | ||
|
|
f2a02c5e98 | ||
|
|
10b3b1a274 | ||
|
|
23b868ac75 | ||
|
|
695508d5c9 | ||
|
|
cb9cb51a63 | ||
|
|
953775aa72 | ||
|
|
41cec0a1a4 | ||
|
|
24b7752252 | ||
|
|
99e8d57c5f | ||
|
|
4ac8d95088 | ||
|
|
f82ab134e9 | ||
|
|
58fa829fed | ||
|
|
ce6d6ed974 | ||
|
|
d4399a0f2c | ||
|
|
3a4e027db8 | ||
|
|
9a0a5e68bc | ||
|
|
8966c43feb |
7
.github/CODEOWNERS
vendored
7
.github/CODEOWNERS
vendored
@@ -305,10 +305,3 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
||||
/pkgs/build-support/ocaml @romildo @ulrikstrid
|
||||
/pkgs/development/compilers/ocaml @romildo @ulrikstrid
|
||||
/pkgs/development/ocaml-modules @romildo @ulrikstrid
|
||||
|
||||
# ZFS
|
||||
pkgs/os-specific/linux/zfs @raitobezarius
|
||||
nixos/lib/make-single-disk-zfs-image.nix @raitobezarius
|
||||
nixos/lib/make-multi-disk-zfs-image.nix @raitobezarius
|
||||
nixos/modules/tasks/filesystems/zfs.nix @raitobezarius
|
||||
nixos/tests/zfs.nix @raitobezarius
|
||||
|
||||
2
.github/workflows/basic-eval.yml
vendored
2
.github/workflows/basic-eval.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
# we don't limit this action to only NixOS repo since the checks are cheap and useful developer feedback
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cachix/install-nix-action@v21
|
||||
- uses: cachix/install-nix-action@v20
|
||||
- uses: cachix/cachix-action@v12
|
||||
with:
|
||||
# This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
- uses: cachix/install-nix-action@v21
|
||||
- uses: cachix/install-nix-action@v20
|
||||
with:
|
||||
# explicitly enable sandbox
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
2
.github/workflows/editorconfig.yml
vendored
2
.github/workflows/editorconfig.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
- uses: cachix/install-nix-action@v21
|
||||
- uses: cachix/install-nix-action@v20
|
||||
with:
|
||||
# nixpkgs commit is pinned so that it doesn't break
|
||||
# editorconfig-checker 2.4.0
|
||||
|
||||
2
.github/workflows/manual-nixos.yml
vendored
2
.github/workflows/manual-nixos.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
- uses: cachix/install-nix-action@v21
|
||||
- uses: cachix/install-nix-action@v20
|
||||
with:
|
||||
# explicitly enable sandbox
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
2
.github/workflows/manual-nixpkgs.yml
vendored
2
.github/workflows/manual-nixpkgs.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
with:
|
||||
# pull_request_target checks out the base branch by default
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
- uses: cachix/install-nix-action@v21
|
||||
- uses: cachix/install-nix-action@v20
|
||||
with:
|
||||
# explicitly enable sandbox
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
2
.github/workflows/manual-rendering.yml
vendored
2
.github/workflows/manual-rendering.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cachix/install-nix-action@v21
|
||||
- uses: cachix/install-nix-action@v20
|
||||
with:
|
||||
# explicitly enable sandbox
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
4
.github/workflows/periodic-merge-24h.yml
vendored
4
.github/workflows/periodic-merge-24h.yml
vendored
@@ -38,10 +38,6 @@ jobs:
|
||||
into: staging-next-22.11
|
||||
- from: staging-next-22.11
|
||||
into: staging-22.11
|
||||
- from: release-23.05
|
||||
into: staging-next-23.05
|
||||
- from: staging-next-23.05
|
||||
into: staging-23.05
|
||||
name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cachix/install-nix-action@v21
|
||||
- uses: cachix/install-nix-action@v20
|
||||
with:
|
||||
nix_path: nixpkgs=channel:nixpkgs-unstable
|
||||
- name: setup
|
||||
|
||||
@@ -8,7 +8,7 @@ A package set is available for each CUDA version, so for example
|
||||
`cudaPackages_11_6`. Within each set is a matching version of the above listed
|
||||
packages. Additionally, other versions of the packages that are packaged and
|
||||
compatible are available as well. For example, there can be a
|
||||
`cudaPackages.cudnn_8_3` package.
|
||||
`cudaPackages.cudnn_8_3_2` package.
|
||||
|
||||
To use one or more CUDA packages in an expression, give the expression a `cudaPackages` parameter, and in case CUDA is optional
|
||||
```nix
|
||||
@@ -28,7 +28,7 @@ set.
|
||||
```nix
|
||||
mypkg = let
|
||||
cudaPackages = cudaPackages_11_5.overrideScope' (final: prev: {
|
||||
cudnn = prev.cudnn_8_3;
|
||||
cudnn = prev.cudnn_8_3_2;
|
||||
}});
|
||||
in callPackage { inherit cudaPackages; };
|
||||
```
|
||||
|
||||
@@ -307,12 +307,12 @@ $ nix-env --install --attr haskellPackages.dhall-nixpkgs
|
||||
|
||||
$ nix-env --install --attr nix-prefetch-git # Used by dhall-to-nixpkgs
|
||||
|
||||
$ dhall-to-nixpkgs github https://github.com/Gabriella439/dhall-semver.git
|
||||
$ dhall-to-nixpkgs github https://github.com/Gabriel439/dhall-semver.git
|
||||
{ buildDhallGitHubPackage, Prelude }:
|
||||
buildDhallGitHubPackage {
|
||||
name = "dhall-semver";
|
||||
githubBase = "github.com";
|
||||
owner = "Gabriella439";
|
||||
owner = "Gabriel439";
|
||||
repo = "dhall-semver";
|
||||
rev = "2d44ae605302ce5dc6c657a1216887fbb96392a4";
|
||||
fetchSubmodules = false;
|
||||
|
||||
@@ -19,7 +19,7 @@ In the following is an example expression using `buildGoModule`, the following a
|
||||
To avoid updating this field when dependencies change, run `go mod vendor` in your source repo and set `vendorHash = null;`
|
||||
|
||||
To obtain the actual hash, set `vendorHash = lib.fakeSha256;` and run the build ([more details here](#sec-source-hashes)).
|
||||
- `proxyVendor`: Fetches (go mod download) and proxies the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build or if any dependency has case-insensitive conflicts which will produce platform-dependent `vendorHash` checksums.
|
||||
- `proxyVendor`: Fetches (go mod download) and proxies the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build or if any dependency has case-insensitive conflicts which will produce platform dependant `vendorHash` checksums.
|
||||
- `modPostBuild`: Shell commands to run after the build of the go-modules executes `go mod vendor`, and before calculating fixed output derivation's `vendorHash` (or `vendorSha256`). Note that if you change this attribute, you need to update `vendorHash` (or `vendorSha256`) attribute.
|
||||
|
||||
```nix
|
||||
|
||||
@@ -276,15 +276,6 @@ Defaults to `true`.
|
||||
: Whether to generate an index for interactive navigation of the HTML documentation.
|
||||
Defaults to `true` if supported.
|
||||
|
||||
`doInstallIntermediates`
|
||||
: Whether to install intermediate build products (files written to `dist/build`
|
||||
by GHC during the build process). With `enableSeparateIntermediatesOutput`,
|
||||
these files are instead installed to [a separate `intermediates`
|
||||
output.][multiple-outputs] The output can then be passed into a future build of
|
||||
the same package with the `previousIntermediates` argument to support
|
||||
incremental builds. See [“Incremental builds”](#haskell-incremental-builds) for
|
||||
more information. Defaults to `false`.
|
||||
|
||||
`enableLibraryProfiling`
|
||||
: Whether to enable [profiling][profiling] for libraries contained in the
|
||||
package. Enabled by default if supported.
|
||||
@@ -380,12 +371,6 @@ Defaults to `false`.
|
||||
: Whether to install documentation to a separate `doc` output.
|
||||
Is automatically enabled if `doHaddock` is `true`.
|
||||
|
||||
`enableSeparateIntermediatesOutput`
|
||||
: When `doInstallIntermediates` is true, whether to install intermediate build
|
||||
products to a separate `intermediates` output. See [“Incremental
|
||||
builds”](#haskell-incremental-builds) for more information. Defaults to
|
||||
`false`.
|
||||
|
||||
`allowInconsistentDependencies`
|
||||
: If enabled, allow multiple versions of the same Haskell package in the
|
||||
dependency tree at configure time. Often in such a situation compilation would
|
||||
@@ -396,11 +381,6 @@ later fail because of type mismatches. Defaults to `false`.
|
||||
when loading the library in the REPL, but requires extra build time and
|
||||
disk space. Defaults to `false`.
|
||||
|
||||
`previousIntermediates`
|
||||
: If non-null, intermediate build artifacts are copied from this input to
|
||||
`dist/build` before performing compiling. See [“Incremental
|
||||
builds”](#haskell-incremental-builds) for more information. Defaults to `null`.
|
||||
|
||||
`buildTarget`
|
||||
: Name of the executable or library to build and install.
|
||||
If unset, all available targets are built and installed.
|
||||
@@ -516,54 +496,6 @@ the [Meta-attributes section](#chap-meta) for their documentation.
|
||||
* `broken`
|
||||
* `hydraPlatforms`
|
||||
|
||||
### Incremental builds {#haskell-incremental-builds}
|
||||
|
||||
`haskellPackages.mkDerivation` supports incremental builds for GHC 9.4 and
|
||||
newer with the `doInstallIntermediates`, `enableSeparateIntermediatesOutput`,
|
||||
and `previousIntermediates` arguments.
|
||||
|
||||
The basic idea is to first perform a full build of the package in question,
|
||||
save its intermediate build products for later, and then copy those build
|
||||
products into the build directory of an incremental build performed later.
|
||||
Then, GHC will use those build artifacts to avoid recompiling unchanged
|
||||
modules.
|
||||
|
||||
For more detail on how to store and use incremental build products, see
|
||||
[Gabriella Gonzalez’ blog post “Nixpkgs support for incremental Haskell
|
||||
builds”.][incremental-builds] motivation behind this feature.
|
||||
|
||||
An incremental build for [the `turtle` package][turtle] can be performed like
|
||||
so:
|
||||
|
||||
```nix
|
||||
let
|
||||
pkgs = import <nixpkgs> {};
|
||||
inherit (pkgs) haskell;
|
||||
inherit (haskell.lib.compose) overrideCabal;
|
||||
|
||||
# Incremental builds work with GHC >=9.4.
|
||||
turtle = haskell.packages.ghc944.turtle;
|
||||
|
||||
# This will do a full build of `turtle`, while writing the intermediate build products
|
||||
# (compiled modules, etc.) to the `intermediates` output.
|
||||
turtle-full-build-with-incremental-output = overrideCabal (drv: {
|
||||
doInstallIntermediates = true;
|
||||
enableSeparateIntermediatesOutput = true;
|
||||
}) turtle;
|
||||
|
||||
# This will do an incremental build of `turtle` by copying the previously
|
||||
# compiled modules and intermediate build products into the source tree
|
||||
# before running the build.
|
||||
#
|
||||
# GHC will then naturally pick up and reuse these products, making this build
|
||||
# complete much more quickly than the previous one.
|
||||
turtle-incremental-build = overrideCabal (drv: {
|
||||
previousIntermediates = turtle-full-build-with-incremental-output.intermediates;
|
||||
}) turtle;
|
||||
in
|
||||
turtle-incremental-build
|
||||
```
|
||||
|
||||
## Development environments {#haskell-development-environments}
|
||||
|
||||
In addition to building and installing Haskell software, nixpkgs can also
|
||||
@@ -1151,11 +1083,8 @@ on the issue linked above.
|
||||
[haskell.nix]: https://input-output-hk.github.io/haskell.nix/index.html
|
||||
[HLS user guide]: https://haskell-language-server.readthedocs.io/en/latest/configuration.html#configuring-your-editor
|
||||
[hoogle]: https://wiki.haskell.org/Hoogle
|
||||
[incremental-builds]: https://www.haskellforall.com/2022/12/nixpkgs-support-for-incremental-haskell.html
|
||||
[jailbreak-cabal]: https://github.com/NixOS/jailbreak-cabal/
|
||||
[multiple-outputs]: https://nixos.org/manual/nixpkgs/stable/#chap-multiple-output
|
||||
[optparse-applicative-completions]: https://github.com/pcapriotti/optparse-applicative/blob/7726b63796aa5d0df82e926d467f039b78ca09e2/README.md#bash-zsh-and-fish-completions
|
||||
[profiling-detail]: https://cabal.readthedocs.io/en/latest/cabal-project.html#cfg-field-profiling-detail
|
||||
[profiling]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html
|
||||
[search.nixos.org]: https://search.nixos.org
|
||||
[turtle]: https://hackage.haskell.org/package/turtle
|
||||
|
||||
@@ -1514,6 +1514,10 @@ Note: There is a boolean value `lib.inNixShell` set to `true` if nix-shell is in
|
||||
Packages inside nixpkgs are written by hand. However many tools exist in
|
||||
community to help save time. No tool is preferred at the moment.
|
||||
|
||||
- [pypi2nix](https://github.com/nix-community/pypi2nix): Generate Nix
|
||||
expressions for your Python project. Note that [sharing derivations from
|
||||
pypi2nix with nixpkgs is possible but not
|
||||
encouraged](https://github.com/nix-community/pypi2nix/issues/222#issuecomment-443497376).
|
||||
- [nixpkgs-pytools](https://github.com/nix-community/nixpkgs-pytools)
|
||||
- [poetry2nix](https://github.com/nix-community/poetry2nix)
|
||||
|
||||
|
||||
@@ -123,11 +123,7 @@ rec {
|
||||
{ x = "a"; y = "b"; }
|
||||
=> { x = "a"; xa = "a"; y = "b"; yb = "b"; }
|
||||
*/
|
||||
concatMapAttrs = f: v:
|
||||
foldl' mergeAttrs { }
|
||||
(attrValues
|
||||
(mapAttrs f v)
|
||||
);
|
||||
concatMapAttrs = f: flip pipe [ (mapAttrs f) attrValues (foldl' mergeAttrs { }) ];
|
||||
|
||||
|
||||
/* Update or set specific paths of an attribute set.
|
||||
|
||||
@@ -31,7 +31,7 @@ in
|
||||
|
||||
(lazyDerivation { inherit derivation; meta.foo = true; }).meta
|
||||
|
||||
In these expressions, `derivation` _will_ be evaluated:
|
||||
In these expressions, it `derivation` _will_ be evaluated:
|
||||
|
||||
"${lazyDerivation { inherit derivation }}"
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@ let
|
||||
# Linux
|
||||
"aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux"
|
||||
"armv7l-linux" "i686-linux" "loongarch64-linux" "m68k-linux" "microblaze-linux"
|
||||
"microblazeel-linux" "mips-linux" "mips64-linux" "mips64el-linux"
|
||||
"mipsel-linux" "powerpc64-linux" "powerpc64le-linux" "riscv32-linux"
|
||||
"riscv64-linux" "s390-linux" "s390x-linux" "x86_64-linux"
|
||||
"microblazeel-linux" "mipsel-linux" "mips64el-linux" "powerpc64-linux"
|
||||
"powerpc64le-linux" "riscv32-linux" "riscv64-linux" "s390-linux"
|
||||
"s390x-linux" "x86_64-linux"
|
||||
|
||||
# MMIXware
|
||||
"mmix-mmixware"
|
||||
|
||||
@@ -91,16 +91,22 @@ rec {
|
||||
} // platforms.fuloong2f_n32;
|
||||
|
||||
# can execute on 32bit chip
|
||||
mips-linux-gnu = { config = "mips-unknown-linux-gnu"; } // platforms.gcc_mips32r2_o32;
|
||||
mipsel-linux-gnu = { config = "mipsel-unknown-linux-gnu"; } // platforms.gcc_mips32r2_o32;
|
||||
mips-linux-gnu = { config = "mips-unknown-linux-gnu"; } // platforms.gcc_mips32r2_o32;
|
||||
mipsel-linux-gnu = { config = "mipsel-unknown-linux-gnu"; } // platforms.gcc_mips32r2_o32;
|
||||
mipsisa32r6-linux-gnu = { config = "mipsisa32r6-unknown-linux-gnu"; } // platforms.gcc_mips32r6_o32;
|
||||
mipsisa32r6el-linux-gnu = { config = "mipsisa32r6el-unknown-linux-gnu"; } // platforms.gcc_mips32r6_o32;
|
||||
|
||||
# require 64bit chip (for more registers, 64-bit floating point, 64-bit "long long") but use 32bit pointers
|
||||
mips64-linux-gnuabin32 = { config = "mips64-unknown-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;
|
||||
mips64el-linux-gnuabin32 = { config = "mips64el-unknown-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;
|
||||
mips64-linux-gnuabin32 = { config = "mips64-unknown-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;
|
||||
mips64el-linux-gnuabin32 = { config = "mips64el-unknown-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;
|
||||
mipsisa64r6-linux-gnuabin32 = { config = "mipsisa64r6-unknown-linux-gnuabin32"; } // platforms.gcc_mips64r6_n32;
|
||||
mipsisa64r6el-linux-gnuabin32 = { config = "mipsisa64r6el-unknown-linux-gnuabin32"; } // platforms.gcc_mips64r6_n32;
|
||||
|
||||
# 64bit pointers
|
||||
mips64-linux-gnuabi64 = { config = "mips64-unknown-linux-gnuabi64"; } // platforms.gcc_mips64r2_64;
|
||||
mips64el-linux-gnuabi64 = { config = "mips64el-unknown-linux-gnuabi64"; } // platforms.gcc_mips64r2_64;
|
||||
mips64-linux-gnuabi64 = { config = "mips64-unknown-linux-gnuabi64"; } // platforms.gcc_mips64r2_64;
|
||||
mips64el-linux-gnuabi64 = { config = "mips64el-unknown-linux-gnuabi64"; } // platforms.gcc_mips64r2_64;
|
||||
mipsisa64r6-linux-gnuabi64 = { config = "mipsisa64r6-unknown-linux-gnuabi64"; } // platforms.gcc_mips64r6_64;
|
||||
mipsisa64r6el-linux-gnuabi64 = { config = "mipsisa64r6el-unknown-linux-gnuabi64"; } // platforms.gcc_mips64r6_64;
|
||||
|
||||
muslpi = raspberryPi // {
|
||||
config = "armv6l-unknown-linux-musleabihf";
|
||||
|
||||
@@ -91,10 +91,14 @@ rec {
|
||||
microblaze = { bits = 32; significantByte = bigEndian; family = "microblaze"; };
|
||||
microblazeel = { bits = 32; significantByte = littleEndian; family = "microblaze"; };
|
||||
|
||||
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
|
||||
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||
mips64 = { bits = 64; significantByte = bigEndian; family = "mips"; };
|
||||
mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
|
||||
mips = { bits = 32; significantByte = bigEndian; family = "mips"; };
|
||||
mipsel = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||
mipsisa32r6 = { bits = 32; significantByte = bigEndian; family = "mips"; };
|
||||
mipsisa32r6el = { bits = 32; significantByte = littleEndian; family = "mips"; };
|
||||
mips64 = { bits = 64; significantByte = bigEndian; family = "mips"; };
|
||||
mips64el = { bits = 64; significantByte = littleEndian; family = "mips"; };
|
||||
mipsisa64r6 = { bits = 64; significantByte = bigEndian; family = "mips"; };
|
||||
mipsisa64r6el = { bits = 64; significantByte = littleEndian; family = "mips"; };
|
||||
|
||||
mmix = { bits = 64; significantByte = bigEndian; family = "mmix"; };
|
||||
|
||||
|
||||
@@ -35,50 +35,58 @@ touch regular
|
||||
ln -s target symlink
|
||||
mkfifo fifo
|
||||
|
||||
expectSuccess() {
|
||||
local expr=$1
|
||||
local expectedResultRegex=$2
|
||||
if ! result=$(nix-instantiate --eval --strict --json \
|
||||
--expr "with (import <nixpkgs/lib>).filesystem; $expr"); then
|
||||
die "$expr failed to evaluate, but it was expected to succeed"
|
||||
fi
|
||||
if [[ ! "$result" =~ $expectedResultRegex ]]; then
|
||||
die "$expr == $result, but $expectedResultRegex was expected"
|
||||
checkPathType() {
|
||||
local path=$1
|
||||
local expectedPathType=$2
|
||||
local actualPathType=$(nix-instantiate --eval --strict --json 2>&1 \
|
||||
-E '{ path }: let lib = import <nixpkgs/lib>; in lib.filesystem.pathType path' \
|
||||
--argstr path "$path")
|
||||
if [[ "$actualPathType" != "$expectedPathType" ]]; then
|
||||
die "lib.filesystem.pathType \"$path\" == $actualPathType, but $expectedPathType was expected"
|
||||
fi
|
||||
}
|
||||
|
||||
expectFailure() {
|
||||
local expr=$1
|
||||
local expectedErrorRegex=$2
|
||||
if result=$(nix-instantiate --eval --strict --json 2>"$work/stderr" \
|
||||
--expr "with (import <nixpkgs/lib>).filesystem; $expr"); then
|
||||
die "$expr evaluated successfully to $result, but it was expected to fail"
|
||||
fi
|
||||
if [[ ! "$(<"$work/stderr")" =~ $expectedErrorRegex ]]; then
|
||||
die "Error was $(<"$work/stderr"), but $expectedErrorRegex was expected"
|
||||
checkPathType "/" '"directory"'
|
||||
checkPathType "$PWD/directory" '"directory"'
|
||||
checkPathType "$PWD/regular" '"regular"'
|
||||
checkPathType "$PWD/symlink" '"symlink"'
|
||||
checkPathType "$PWD/fifo" '"unknown"'
|
||||
checkPathType "$PWD/non-existent" "error: evaluation aborted with the following error message: 'lib.filesystem.pathType: Path $PWD/non-existent does not exist.'"
|
||||
|
||||
checkPathIsDirectory() {
|
||||
local path=$1
|
||||
local expectedIsDirectory=$2
|
||||
local actualIsDirectory=$(nix-instantiate --eval --strict --json 2>&1 \
|
||||
-E '{ path }: let lib = import <nixpkgs/lib>; in lib.filesystem.pathIsDirectory path' \
|
||||
--argstr path "$path")
|
||||
if [[ "$actualIsDirectory" != "$expectedIsDirectory" ]]; then
|
||||
die "lib.filesystem.pathIsDirectory \"$path\" == $actualIsDirectory, but $expectedIsDirectory was expected"
|
||||
fi
|
||||
}
|
||||
|
||||
expectSuccess "pathType /." '"directory"'
|
||||
expectSuccess "pathType $PWD/directory" '"directory"'
|
||||
expectSuccess "pathType $PWD/regular" '"regular"'
|
||||
expectSuccess "pathType $PWD/symlink" '"symlink"'
|
||||
expectSuccess "pathType $PWD/fifo" '"unknown"'
|
||||
# Different errors depending on whether the builtins.readFilePath primop is available or not
|
||||
expectFailure "pathType $PWD/non-existent" "error: (evaluation aborted with the following error message: 'lib.filesystem.pathType: Path $PWD/non-existent does not exist.'|getting status of '$PWD/non-existent': No such file or directory)"
|
||||
checkPathIsDirectory "/" "true"
|
||||
checkPathIsDirectory "$PWD/directory" "true"
|
||||
checkPathIsDirectory "$PWD/regular" "false"
|
||||
checkPathIsDirectory "$PWD/symlink" "false"
|
||||
checkPathIsDirectory "$PWD/fifo" "false"
|
||||
checkPathIsDirectory "$PWD/non-existent" "false"
|
||||
|
||||
expectSuccess "pathIsDirectory /." "true"
|
||||
expectSuccess "pathIsDirectory $PWD/directory" "true"
|
||||
expectSuccess "pathIsDirectory $PWD/regular" "false"
|
||||
expectSuccess "pathIsDirectory $PWD/symlink" "false"
|
||||
expectSuccess "pathIsDirectory $PWD/fifo" "false"
|
||||
expectSuccess "pathIsDirectory $PWD/non-existent" "false"
|
||||
checkPathIsRegularFile() {
|
||||
local path=$1
|
||||
local expectedIsRegularFile=$2
|
||||
local actualIsRegularFile=$(nix-instantiate --eval --strict --json 2>&1 \
|
||||
-E '{ path }: let lib = import <nixpkgs/lib>; in lib.filesystem.pathIsRegularFile path' \
|
||||
--argstr path "$path")
|
||||
if [[ "$actualIsRegularFile" != "$expectedIsRegularFile" ]]; then
|
||||
die "lib.filesystem.pathIsRegularFile \"$path\" == $actualIsRegularFile, but $expectedIsRegularFile was expected"
|
||||
fi
|
||||
}
|
||||
|
||||
expectSuccess "pathIsRegularFile /." "false"
|
||||
expectSuccess "pathIsRegularFile $PWD/directory" "false"
|
||||
expectSuccess "pathIsRegularFile $PWD/regular" "true"
|
||||
expectSuccess "pathIsRegularFile $PWD/symlink" "false"
|
||||
expectSuccess "pathIsRegularFile $PWD/fifo" "false"
|
||||
expectSuccess "pathIsRegularFile $PWD/non-existent" "false"
|
||||
checkPathIsRegularFile "/" "false"
|
||||
checkPathIsRegularFile "$PWD/directory" "false"
|
||||
checkPathIsRegularFile "$PWD/regular" "true"
|
||||
checkPathIsRegularFile "$PWD/symlink" "false"
|
||||
checkPathIsRegularFile "$PWD/fifo" "false"
|
||||
checkPathIsRegularFile "$PWD/non-existent" "false"
|
||||
|
||||
echo >&2 tests ok
|
||||
|
||||
@@ -378,7 +378,7 @@ checkConfigOutput '^{ }$' config.sub.nixosOk ./class-check.nix
|
||||
checkConfigError 'The module .*/module-class-is-darwin.nix was imported into nixos instead of darwin.' config.sub.nixosFail.config ./class-check.nix
|
||||
|
||||
# submoduleWith type merge with different class
|
||||
checkConfigError 'A submoduleWith option is declared multiple times with conflicting class values "darwin" and "nixos".' config.sub.mergeFail.config ./class-check.nix
|
||||
checkConfigError 'error: A submoduleWith option is declared multiple times with conflicting class values "darwin" and "nixos".' config.sub.mergeFail.config ./class-check.nix
|
||||
|
||||
# _type check
|
||||
checkConfigError 'Could not load a value as a module, because it is of type "flake", in file .*/module-imports-_type-check.nix' config.ok.config ./module-imports-_type-check.nix
|
||||
|
||||
@@ -2,63 +2,53 @@
|
||||
# Don't test properties of pkgs.lib, but rather the lib in the parent directory
|
||||
pkgs ? import ../.. {} // { lib = throw "pkgs.lib accessed, but the lib tests should use nixpkgs' lib path directly!"; },
|
||||
nix ? pkgs.nix,
|
||||
nixVersions ? [ pkgs.nixVersions.minimum nix pkgs.nixVersions.unstable ],
|
||||
}:
|
||||
|
||||
let
|
||||
testWithNix = nix:
|
||||
pkgs.runCommand "nixpkgs-lib-tests-nix-${nix.version}" {
|
||||
buildInputs = [
|
||||
(import ./check-eval.nix)
|
||||
(import ./maintainers.nix {
|
||||
inherit pkgs;
|
||||
lib = import ../.;
|
||||
})
|
||||
(import ./teams.nix {
|
||||
inherit pkgs;
|
||||
lib = import ../.;
|
||||
})
|
||||
(import ../path/tests {
|
||||
inherit pkgs;
|
||||
})
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
nix
|
||||
];
|
||||
strictDeps = true;
|
||||
} ''
|
||||
datadir="${nix}/share"
|
||||
export TEST_ROOT=$(pwd)/test-tmp
|
||||
export NIX_BUILD_HOOK=
|
||||
export NIX_CONF_DIR=$TEST_ROOT/etc
|
||||
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
||||
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
||||
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
||||
export NIX_STORE_DIR=$TEST_ROOT/store
|
||||
export PAGER=cat
|
||||
cacheDir=$TEST_ROOT/binary-cache
|
||||
pkgs.runCommand "nixpkgs-lib-tests" {
|
||||
buildInputs = [
|
||||
(import ./check-eval.nix)
|
||||
(import ./maintainers.nix {
|
||||
inherit pkgs;
|
||||
lib = import ../.;
|
||||
})
|
||||
(import ./teams.nix {
|
||||
inherit pkgs;
|
||||
lib = import ../.;
|
||||
})
|
||||
(import ../path/tests {
|
||||
inherit pkgs;
|
||||
})
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
nix
|
||||
];
|
||||
strictDeps = true;
|
||||
} ''
|
||||
datadir="${nix}/share"
|
||||
export TEST_ROOT=$(pwd)/test-tmp
|
||||
export NIX_BUILD_HOOK=
|
||||
export NIX_CONF_DIR=$TEST_ROOT/etc
|
||||
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
||||
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
||||
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
||||
export NIX_STORE_DIR=$TEST_ROOT/store
|
||||
export PAGER=cat
|
||||
cacheDir=$TEST_ROOT/binary-cache
|
||||
|
||||
mkdir -p $NIX_CONF_DIR
|
||||
echo "experimental-features = nix-command" >> $NIX_CONF_DIR/nix.conf
|
||||
mkdir -p $NIX_CONF_DIR
|
||||
echo "experimental-features = nix-command" >> $NIX_CONF_DIR/nix.conf
|
||||
|
||||
nix-store --init
|
||||
nix-store --init
|
||||
|
||||
cp -r ${../.} lib
|
||||
echo "Running lib/tests/modules.sh"
|
||||
bash lib/tests/modules.sh
|
||||
cp -r ${../.} lib
|
||||
echo "Running lib/tests/modules.sh"
|
||||
bash lib/tests/modules.sh
|
||||
|
||||
echo "Running lib/tests/filesystem.sh"
|
||||
TEST_LIB=$PWD/lib bash lib/tests/filesystem.sh
|
||||
echo "Running lib/tests/filesystem.sh"
|
||||
TEST_LIB=$PWD/lib bash lib/tests/filesystem.sh
|
||||
|
||||
echo "Running lib/tests/sources.sh"
|
||||
TEST_LIB=$PWD/lib bash lib/tests/sources.sh
|
||||
echo "Running lib/tests/sources.sh"
|
||||
TEST_LIB=$PWD/lib bash lib/tests/sources.sh
|
||||
|
||||
mkdir $out
|
||||
echo success > $out/${nix.version}
|
||||
'';
|
||||
|
||||
in
|
||||
pkgs.symlinkJoin {
|
||||
name = "nixpkgs-lib-tests";
|
||||
paths = map testWithNix nixVersions;
|
||||
}
|
||||
touch $out
|
||||
''
|
||||
|
||||
@@ -23,19 +23,14 @@ clean_up() {
|
||||
trap clean_up EXIT
|
||||
cd "$work"
|
||||
|
||||
# Crudely unquotes a JSON string by just taking everything between the first and the second quote.
|
||||
# We're only using this for resulting /nix/store paths, which can't contain " anyways,
|
||||
# nor can they contain any other characters that would need to be escaped specially in JSON
|
||||
# This way we don't need to add a dependency on e.g. jq
|
||||
crudeUnquoteJSON() {
|
||||
cut -d \" -f2
|
||||
}
|
||||
|
||||
touch {README.md,module.o,foo.bar}
|
||||
|
||||
dir="$(nix-instantiate --eval --strict --read-write-mode --json --expr '(with import <nixpkgs/lib>; "${
|
||||
# nix-instantiate doesn't write out the source, only computing the hash, so
|
||||
# this uses the experimental nix command instead.
|
||||
|
||||
dir="$(nix eval --impure --raw --expr '(with import <nixpkgs/lib>; "${
|
||||
cleanSource ./.
|
||||
}")' | crudeUnquoteJSON)"
|
||||
}")')"
|
||||
(cd "$dir"; find) | sort -f | diff -U10 - <(cat <<EOF
|
||||
.
|
||||
./foo.bar
|
||||
@@ -44,9 +39,9 @@ EOF
|
||||
) || die "cleanSource 1"
|
||||
|
||||
|
||||
dir="$(nix-instantiate --eval --strict --read-write-mode --json --expr '(with import <nixpkgs/lib>; "${
|
||||
dir="$(nix eval --impure --raw --expr '(with import <nixpkgs/lib>; "${
|
||||
cleanSourceWith { src = '"$work"'; filter = path: type: ! hasSuffix ".bar" path; }
|
||||
}")' | crudeUnquoteJSON)"
|
||||
}")')"
|
||||
(cd "$dir"; find) | sort -f | diff -U10 - <(cat <<EOF
|
||||
.
|
||||
./module.o
|
||||
@@ -54,9 +49,9 @@ dir="$(nix-instantiate --eval --strict --read-write-mode --json --expr '(with im
|
||||
EOF
|
||||
) || die "cleanSourceWith 1"
|
||||
|
||||
dir="$(nix-instantiate --eval --strict --read-write-mode --json --expr '(with import <nixpkgs/lib>; "${
|
||||
dir="$(nix eval --impure --raw --expr '(with import <nixpkgs/lib>; "${
|
||||
cleanSourceWith { src = cleanSource '"$work"'; filter = path: type: ! hasSuffix ".bar" path; }
|
||||
}")' | crudeUnquoteJSON)"
|
||||
}")')"
|
||||
(cd "$dir"; find) | sort -f | diff -U10 - <(cat <<EOF
|
||||
.
|
||||
./README.md
|
||||
|
||||
@@ -18,7 +18,7 @@ with lib.systems.doubles; lib.runTests {
|
||||
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-netbsd" "armv6l-none" "armv7a-linux" "armv7a-netbsd" "armv7l-linux" "armv7l-netbsd" "arm-none" "armv7a-darwin" ];
|
||||
testarmv7 = mseteq armv7 [ "armv7a-darwin" "armv7a-linux" "armv7l-linux" "armv7a-netbsd" "armv7l-netbsd" ];
|
||||
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd13" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ];
|
||||
testmips = mseteq mips [ "mips-linux" "mips64-linux" "mips64el-linux" "mipsel-linux" "mipsel-netbsd" ];
|
||||
testmips = mseteq mips [ "mips64el-linux" "mipsel-linux" "mipsel-netbsd" ];
|
||||
testmmix = mseteq mmix [ "mmix-mmixware" ];
|
||||
testpower = mseteq power [ "powerpc-netbsd" "powerpc-none" "powerpc64-linux" "powerpc64le-linux" "powerpcle-none" ];
|
||||
testriscv = mseteq riscv [ "riscv32-linux" "riscv64-linux" "riscv32-netbsd" "riscv64-netbsd" "riscv32-none" "riscv64-none" ];
|
||||
@@ -34,7 +34,7 @@ with lib.systems.doubles; lib.runTests {
|
||||
testredox = mseteq redox [ "x86_64-redox" ];
|
||||
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
|
||||
testillumos = mseteq illumos [ "x86_64-solaris" ];
|
||||
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "loongarch64-linux" "m68k-linux" "microblaze-linux" "microblazeel-linux" "mips-linux" "mips64-linux" "mips64el-linux" "mipsel-linux" "powerpc64-linux" "powerpc64le-linux" "riscv32-linux" "riscv64-linux" "s390-linux" "s390x-linux" "x86_64-linux" ];
|
||||
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mips64el-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" "m68k-linux" "s390-linux" "s390x-linux" "microblaze-linux" "microblazeel-linux" "loongarch64-linux" ];
|
||||
testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ];
|
||||
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
|
||||
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
|
||||
|
||||
@@ -195,7 +195,7 @@ rec {
|
||||
On each release the first letter is bumped and a new animal is chosen
|
||||
starting with that new letter.
|
||||
*/
|
||||
codeName = "Tapir";
|
||||
codeName = "Stoat";
|
||||
|
||||
/* Returns the current nixpkgs version suffix as string. */
|
||||
versionSuffix =
|
||||
|
||||
@@ -177,12 +177,6 @@
|
||||
githubId = 12578560;
|
||||
name = "Quinn Bohner";
|
||||
};
|
||||
_8-bit-fox = {
|
||||
email = "sebastian@markwaerter.de";
|
||||
github = "8-bit-fox";
|
||||
githubId = 43320117;
|
||||
name = "Sebastian Marquardt";
|
||||
};
|
||||
_9999years = {
|
||||
email = "rbt@fastmail.com";
|
||||
github = "9999years";
|
||||
@@ -1639,12 +1633,6 @@
|
||||
fingerprint = "2688 0377 C31D 9E81 9BDF 83A8 C8C6 BDDB 3847 F72B";
|
||||
}];
|
||||
};
|
||||
azd325 = {
|
||||
email = "tim.kleinschmidt@gmail.com";
|
||||
github = "Azd325";
|
||||
githubId = 426541;
|
||||
name = "Tim Kleinschmidt";
|
||||
};
|
||||
azuwis = {
|
||||
email = "azuwis@gmail.com";
|
||||
github = "azuwis";
|
||||
@@ -1875,12 +1863,6 @@
|
||||
githubId = 11135;
|
||||
name = "Berk D. Demir";
|
||||
};
|
||||
bddvlpr = {
|
||||
email = "luna@bddvlpr.com";
|
||||
github = "bddvlpr";
|
||||
githubId = 17461028;
|
||||
name = "Luna Simons";
|
||||
};
|
||||
bdesham = {
|
||||
email = "benjamin@esham.io";
|
||||
github = "bdesham";
|
||||
@@ -5265,12 +5247,6 @@
|
||||
githubId = 2489598;
|
||||
name = "Felix Breidenstein";
|
||||
};
|
||||
flemzord = {
|
||||
email = "maxence@maireaux.fr";
|
||||
github = "flemzord";
|
||||
githubId = 1952914;
|
||||
name = "Maxence Maireaux";
|
||||
};
|
||||
flexagoon = {
|
||||
email = "flexagoon@pm.me";
|
||||
github = "flexagoon";
|
||||
@@ -5422,12 +5398,6 @@
|
||||
githubId = 7551358;
|
||||
name = "Frede Emil";
|
||||
};
|
||||
Freed-Wu = {
|
||||
email = "wuzhenyu@ustc.edu";
|
||||
github = "Freed-Wu";
|
||||
githubId = 32936898;
|
||||
name = "Wu Zhenyu";
|
||||
};
|
||||
freezeboy = {
|
||||
github = "freezeboy";
|
||||
githubId = 13279982;
|
||||
@@ -5560,18 +5530,18 @@
|
||||
githubId = 606000;
|
||||
name = "Gabriel Adomnicai";
|
||||
};
|
||||
Gabriel439 = {
|
||||
email = "Gabriel439@gmail.com";
|
||||
github = "Gabriella439";
|
||||
githubId = 1313787;
|
||||
name = "Gabriel Gonzalez";
|
||||
};
|
||||
GabrielDougherty = {
|
||||
email = "contact@gabrieldougherty.com";
|
||||
github = "GabrielDougherty";
|
||||
githubId = 10541219;
|
||||
name = "Gabriel Dougherty";
|
||||
};
|
||||
Gabriella439 = {
|
||||
email = "GenuineGabriella@gmail.com";
|
||||
github = "Gabriella439";
|
||||
githubId = 1313787;
|
||||
name = "Gabriella Gonzalez";
|
||||
};
|
||||
gador = {
|
||||
email = "florian.brandes@posteo.de";
|
||||
github = "gador";
|
||||
@@ -6394,12 +6364,6 @@
|
||||
fingerprint = "45A9 9917 578C D629 9F5F B5B4 C22D 4DE4 D7B3 2D19";
|
||||
}];
|
||||
};
|
||||
hitsmaxft = {
|
||||
name = "Bhe Hongtyu";
|
||||
email = "mfthits@gmail.com";
|
||||
github = "hitsmaxft";
|
||||
githubId = 352727;
|
||||
};
|
||||
hjones2199 = {
|
||||
email = "hjones2199@gmail.com";
|
||||
github = "hjones2199";
|
||||
@@ -6433,15 +6397,6 @@
|
||||
githubId = 6074754;
|
||||
name = "Hlodver Sigurdsson";
|
||||
};
|
||||
hmajid2301 = {
|
||||
name = "Haseeb Majid";
|
||||
email = "hello@haseebmajid.dev";
|
||||
github = "hmajid2301";
|
||||
githubId = 998807;
|
||||
keys = [{
|
||||
fingerprint = "A236 785D 59F1 9076 1E9C E8EC 7828 3DB3 D233 E1F9";
|
||||
}];
|
||||
};
|
||||
hmenke = {
|
||||
name = "Henri Menke";
|
||||
email = "henri@henrimenke.de";
|
||||
@@ -6925,12 +6880,6 @@
|
||||
githubId = 137306;
|
||||
name = "Michele Catalano";
|
||||
};
|
||||
isaozler = {
|
||||
email = "isaozler@gmail.com";
|
||||
github = "isaozler";
|
||||
githubId = 1378630;
|
||||
name = "Isa Ozler";
|
||||
};
|
||||
isgy = {
|
||||
name = "isgy";
|
||||
email = "isgy@teiyg.com";
|
||||
@@ -7578,12 +7527,6 @@
|
||||
githubId = 8900;
|
||||
name = "Johan Magnus Jonsson";
|
||||
};
|
||||
jmbaur = {
|
||||
email = "jaredbaur@fastmail.com";
|
||||
github = "jmbaur";
|
||||
githubId = 45740526;
|
||||
name = "Jared Baur";
|
||||
};
|
||||
jmc-figueira = {
|
||||
email = "business+nixos@jmc-figueira.dev";
|
||||
github = "jmc-figueira";
|
||||
@@ -8999,12 +8942,6 @@
|
||||
githubId = 1572058;
|
||||
name = "Leonardo Cecchi";
|
||||
};
|
||||
leonid = {
|
||||
email = "belyaev.l@northeastern.edu";
|
||||
github = "leonidbelyaev";
|
||||
githubId = 77865363;
|
||||
name = "Leonid Belyaev";
|
||||
};
|
||||
leshainc = {
|
||||
email = "leshainc@fomalhaut.me";
|
||||
github = "LeshaInc";
|
||||
@@ -9075,12 +9012,6 @@
|
||||
githubId = 1769386;
|
||||
name = "Liam Diprose";
|
||||
};
|
||||
liberatys = {
|
||||
email = "liberatys@hey.com";
|
||||
name = "Nick Anthony Flueckiger";
|
||||
github = "liberatys";
|
||||
githubId = 35100156;
|
||||
};
|
||||
libjared = {
|
||||
email = "jared@perrycode.com";
|
||||
github = "libjared";
|
||||
@@ -10692,12 +10623,6 @@
|
||||
githubId = 708570;
|
||||
name = "Manuel Mendez";
|
||||
};
|
||||
mmusnjak = {
|
||||
email = "marko.musnjak@gmail.com";
|
||||
github = "mmusnjak";
|
||||
githubId = 668956;
|
||||
name = "Marko Mušnjak";
|
||||
};
|
||||
mnacamura = {
|
||||
email = "m.nacamura@gmail.com";
|
||||
github = "mnacamura";
|
||||
@@ -11113,11 +11038,6 @@
|
||||
githubId = 1009523;
|
||||
name = "Ashijit Pramanik";
|
||||
};
|
||||
name-snrl = {
|
||||
github = "name-snrl";
|
||||
githubId = 72071763;
|
||||
name = "Yusup Urazaev";
|
||||
};
|
||||
namore = {
|
||||
email = "namor@hemio.de";
|
||||
github = "namore";
|
||||
@@ -11503,16 +11423,6 @@
|
||||
githubId = 26231126;
|
||||
name = "Nils ANDRÉ-CHANG";
|
||||
};
|
||||
nim65s = {
|
||||
email = "guilhem.saurel@laas.fr";
|
||||
matrix = "@gsaurel:laas.fr";
|
||||
github = "nim65s";
|
||||
githubId = 131929;
|
||||
name = "Guilhem Saurel";
|
||||
keys = [{
|
||||
fingerprint = "9B1A 7906 5D2F 2B80 6C8A 5A1C 7D2A CDAF 4653 CF28";
|
||||
}];
|
||||
};
|
||||
ninjatrappeur = {
|
||||
email = "felix@alternativebit.fr";
|
||||
matrix = "@ninjatrappeur:matrix.org";
|
||||
@@ -11813,12 +11723,6 @@
|
||||
githubId = 30825096;
|
||||
name = "Ning Zhang";
|
||||
};
|
||||
oaksoaj = {
|
||||
email = "oaksoaj@riseup.net";
|
||||
name = "Oaksoaj";
|
||||
github = "oaksoaj";
|
||||
githubId = 103952141;
|
||||
};
|
||||
obadz = {
|
||||
email = "obadz-nixos@obadz.com";
|
||||
github = "obadz";
|
||||
@@ -12605,12 +12509,6 @@
|
||||
githubId = 3737;
|
||||
name = "Peter Jones";
|
||||
};
|
||||
pjrm = {
|
||||
email = "pedrojrmagalhaes@gmail.com";
|
||||
github = "pjrm";
|
||||
githubId = 4622652;
|
||||
name = "Pedro Magalhães";
|
||||
};
|
||||
pkharvey = {
|
||||
email = "kayharvey@protonmail.com";
|
||||
github = "pkharvey";
|
||||
@@ -15244,12 +15142,6 @@
|
||||
githubId = 38893265;
|
||||
name = "StrikerLulu";
|
||||
};
|
||||
stteague = {
|
||||
email = "stteague505@yahoo.com";
|
||||
github = "stteague";
|
||||
githubId = 77596767;
|
||||
name = "Scott Teague";
|
||||
};
|
||||
stumoss = {
|
||||
email = "samoss@gmail.com";
|
||||
github = "stumoss";
|
||||
@@ -15407,13 +15299,6 @@
|
||||
githubId = 20063502;
|
||||
name = "Sybrand Aarnoutse";
|
||||
};
|
||||
syboxez = {
|
||||
email = "syboxez@gmail.com";
|
||||
matrix = "@Syboxez:matrix.org";
|
||||
github = "syboxez";
|
||||
githubId = 12841859;
|
||||
name = "Syboxez Blank";
|
||||
};
|
||||
symphorien = {
|
||||
email = "symphorien_nixpkgs@xlumurb.eu";
|
||||
matrix = "@symphorien:xlumurb.eu";
|
||||
@@ -15917,12 +15802,6 @@
|
||||
github = "thielema";
|
||||
githubId = 898989;
|
||||
};
|
||||
thilobillerbeck = {
|
||||
name = "Thilo Billerbeck";
|
||||
email = "thilo.billerbeck@officerent.de";
|
||||
github = "thilobillerbeck";
|
||||
githubId = 7442383;
|
||||
};
|
||||
thled = {
|
||||
name = "Thomas Le Duc";
|
||||
email = "dev@tleduc.de";
|
||||
@@ -16017,12 +15896,6 @@
|
||||
github = "TilCreator";
|
||||
githubId = 18621411;
|
||||
};
|
||||
tillkruss = {
|
||||
name = "Till Krüss";
|
||||
email = "till@kruss.io";
|
||||
github = "tillkruss";
|
||||
githubId = 665029;
|
||||
};
|
||||
tilpner = {
|
||||
name = "Till Höppner";
|
||||
email = "nixpkgs@tilpner.com";
|
||||
@@ -17461,10 +17334,10 @@
|
||||
};
|
||||
yayayayaka = {
|
||||
email = "nixpkgs@uwu.is";
|
||||
matrix = "@yaya:uwu.is";
|
||||
matrix = "@lara:uwu.is";
|
||||
github = "yayayayaka";
|
||||
githubId = 73759599;
|
||||
name = "Yaya";
|
||||
name = "Lara A.";
|
||||
};
|
||||
ydlr = {
|
||||
name = "ydlr";
|
||||
|
||||
@@ -213,7 +213,7 @@ with lib.maintainers; {
|
||||
|
||||
dhall = {
|
||||
members = [
|
||||
Gabriella439
|
||||
Gabriel439
|
||||
ehmry
|
||||
];
|
||||
scope = "Maintain Dhall and related packages.";
|
||||
@@ -292,8 +292,6 @@ with lib.maintainers; {
|
||||
members = [
|
||||
imincik
|
||||
sikmir
|
||||
nh2
|
||||
willcohen
|
||||
];
|
||||
scope = "Maintain geospatial packages.";
|
||||
shortName = "Geospatial";
|
||||
@@ -385,6 +383,7 @@ with lib.maintainers; {
|
||||
members = [
|
||||
cleeyv
|
||||
ryantm
|
||||
yuka
|
||||
];
|
||||
scope = "Maintain Jitsi.";
|
||||
shortName = "Jitsi";
|
||||
@@ -558,15 +557,6 @@ with lib.maintainers; {
|
||||
shortName = "Minimal Bootstrap";
|
||||
};
|
||||
|
||||
mercury = {
|
||||
members = [
|
||||
_9999years
|
||||
Gabriella439
|
||||
];
|
||||
scope = "Group registry for packages maintained by Mercury";
|
||||
shortName = "Mercury Employees";
|
||||
};
|
||||
|
||||
mobile = {
|
||||
members = [
|
||||
samueldr
|
||||
@@ -604,6 +594,7 @@ with lib.maintainers; {
|
||||
lilyinstarlight
|
||||
marsam
|
||||
winter
|
||||
yuka
|
||||
];
|
||||
scope = "Maintain Node.js runtimes and build tooling.";
|
||||
shortName = "Node.js";
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
This section lists the release notes for each stable version of NixOS and current unstable revision.
|
||||
|
||||
```{=include=} sections
|
||||
rl-2311.section.md
|
||||
rl-2305.section.md
|
||||
rl-2211.section.md
|
||||
rl-2205.section.md
|
||||
|
||||
@@ -12,11 +12,11 @@ To upgrade to the latest release, follow the [upgrade chapter](https://nixos.org
|
||||
|
||||
In addition to numerous new and updated packages, this release has the following highlights:
|
||||
|
||||
- The default [Nix](https://github.com/NixOS/nix) version was updated from 2.11 to 2.13. In particular, this includes a [small language alteration](https://github.com/NixOS/nix/issues/8259) in the way floats are represented in `builtins.toJSON`. See the release notes for [2.12](https://nixos.org/manual/nix/stable/release-notes/rl-2.12.html) and [2.13](https://nixos.org/manual/nix/unstable/release-notes/rl-2.13.html) for more information.
|
||||
- The default [Nix](https://github.com/NixOS/nix) version was updated from 2.11 to 2.13. In particular, this includes a [small language alteration](https://github.com/NixOS/nix/issues/8259) in the way floats are represented in `builtins.toJSON`. See the release notes for [2.13](https://nixos.org/manual/nix/stable/release-notes/rl-2.13.html) and [2.14](https://nixos.org/manual/nix/unstable/release-notes/rl-2.14.html) for more information.
|
||||
|
||||
- The default [Linux Kernel](https://kernel.org/) was updated from version 5.15 to 6.1, see [Kernelnewbies](https://kernelnewbies.org/Linux_6.1) for what has changed. All Kernels currently shown on [kernel.org](https://kernel.org/) are available.
|
||||
- The default [Linux Kernel](https://kernel.org/) was updated from version 5.15 to 6.1, see [Kernelnewbies](https://kernelnewbies.org/Linux_6.1) for what has changed. All currently shown Kernels shown on [kernel.org](https://kernel.org/) are available.
|
||||
|
||||
- [systemd](https://systemd.io) has been updated from v252 to v253, see [the release notes](https://github.com/systemd/systemd/blob/v253/NEWS#L3-L659) for more information on the changes.
|
||||
- [systemd](https://systemd.io) has been updated from v252 to v253, see [the release notes](https://github.com/systemd/systemd/blob/main/NEWS#L21-L677) for more information on the changes.
|
||||
- Updating with `nixos-rebuild boot` and rebooting is recommended, since in some rare cases the `nixos-rebuild switch` into the new generation on a live system might fail due to missing mount units.
|
||||
|
||||
- [glibc](https://www.gnu.org/software/libc/) has been updated from version 2.35 to 2.37, see [the release notes](https://sourceware.org/glibc/wiki/Release/2.37) for what was changed.
|
||||
@@ -192,12 +192,17 @@ In addition to numerous new and updated packages, this release has the following
|
||||
};
|
||||
```
|
||||
|
||||
- Many `services.syncthing` options have been moved to `services.syncthing.settings`, as part of [RFC 42](https://github.com/NixOS/rfcs/pull/42)'s implementation, see [#226088](https://github.com/NixOS/nixpkgs/pull/226088).
|
||||
|
||||
- `podman` now uses the `netavark` network stack. Users will need to delete all of their local containers, images, volumes, etc, by running `podman system reset --force` once before upgrading their systems.
|
||||
|
||||
- `git-bug` has been updated to at least version 0.8.0, which includes backwards incompatible changes. The `git-bug-migration` package can be used to upgrade existing repositories.
|
||||
|
||||
- `graylog` has been updated to version 5, which can not be updated directly from the previously packaged version 3.3. If you had installed the previously packaged version 3.3, please follow the [upgrade path](https://go2docs.graylog.org/5-0/upgrading_graylog/upgrade_path.htm) from 3.3 to 4.0 to 4.3 to 5.0.
|
||||
|
||||
- `buildFHSUserEnv` is now called `buildFHSEnv` and uses FlatPak's Bubblewrap sandboxing tool rather than Nixpkgs' own chrootenv. The old chrootenv-based implemenation is still available via `buildFHSEnvChrootenv` but is considered deprecated and will be removed when the remaining uses inside Nixpkgs have been migrated. If your FHSEnv-wrapped application misbehaves when using the new bubblewrap implementation, please create an issue in Nixpkgs.
|
||||
|
||||
|
||||
- `buildFHSUserEnv` is now called `buildFHSEnv` and uses FlatPak's Bubblewrap sandboxing tool rather than Nixpkgs' own chrootenv. The old chrootenv-based implemenation is still available via `buildFHSEnvChrootenv` but is considered deprecated and will be removed when the remaining uses inside Nixpkgs have been migrated. If your FHSEnv-wrapped application misbehaves when using the new bubblewrap implementation, please create an issue in Nixpkgs.
|
||||
|
||||
- `nushell` has been updated to at least version 0.77.0, which includes potential breaking changes in aliases. The old aliases are now available as `old-alias` but it is recommended you migrate to the new format. See [Reworked aliases](https://www.nushell.sh/blog/2023-03-14-nushell_0_77.html#reworked-aliases-breaking-changes-kubouch).
|
||||
@@ -272,10 +277,6 @@ In addition to numerous new and updated packages, this release has the following
|
||||
|
||||
- The EC2 image module previously detected and activated swap-formatted instance store devices and partitions in stage-1 (initramfs). This behaviour has been removed. Users relying on this should provide their own implementation.
|
||||
|
||||
- `gitlab` has been upgraded from major version 15 to major version 16 and requires at least PostgreSQL 13.6. Check the [upgrade guide](#module-services-postgres-upgrading) in the NixOS manual on how to upgrade your PostgreSQL installation.
|
||||
|
||||
- `gitlab` 16 deprecates the use of external container registries, in our case `pkgs.docker-distribution`. Module users who have [`services.gitlab.registry.enable`](#opt-services.gitlab.registry.enable) set to `true` are advised to back up their state and switch to gitlab's fork by setting [`services.gitlab.registry.package`](#opt-services.gitlab.registry.package) to `pkgs.gitlab-container-registry`.
|
||||
|
||||
- `fail2ban` has been updated to 1.0.2, which has a few breaking changes compared to 0.11.2 ([changelog for 1.0.1](https://github.com/fail2ban/fail2ban/blob/1.0.1/ChangeLog), [changelog for 1.0.2](https://github.com/fail2ban/fail2ban/blob/1.0.2/ChangeLog))
|
||||
|
||||
- `albert` has been updated from 0.17.6 to 0.20.13, and 0.18.0 changed the config format and many plugins ([changelog for 0.18.0](https://github.com/albertlauncher/albert/blob/v0.18.0/CHANGELOG.md))
|
||||
@@ -544,6 +545,8 @@ In addition to numerous new and updated packages, this release has the following
|
||||
|
||||
- Booting from a volume managed by the Stratis storage management daemon is now supported. Use `fileSystems.<name>.stratis.poolUuid` to configure the pool containing the fs.
|
||||
|
||||
- Only `k3s` version 1.26 is included. Users of the `k3s_1_24` or `k3s_1_25` packages should upgrade to use the version 1.26 of the package.
|
||||
|
||||
## Nixpkgs internals {#sec-release-23.05-nixpkgs-internals}
|
||||
|
||||
- `buildDunePackage` now defaults to `strictDeps = true` which means that any library should go into `buildInputs` or `checkInputs`. Any executable that is run on the building machine should go into `nativeBuildInputs` or `nativeCheckInputs` respectively. Example of executables are `ocaml`, `findlib` and `menhir`. PPXs are libraries which are built by dune and should therefore not go into `nativeBuildInputs`.
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Release 23.11 (“Tapir”, 2023.11/??) {#sec-release-23.11}
|
||||
|
||||
## Highlights {#sec-release-23.11-highlights}
|
||||
|
||||
- FoundationDB now defaults to major version 7.
|
||||
|
||||
## New Services {#sec-release-23.11-new-services}
|
||||
|
||||
- Create the first release note entry in this section!
|
||||
|
||||
- [acme-dns](https://github.com/joohoi/acme-dns), a limited DNS server to handle ACME DNS challenges easily and securely. Available as [services.acme-dns](#opt-services.acme-dns.enable).
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
- [river](https://github.com/riverwm/river), A dynamic tiling wayland compositor. Available as [programs.river](#opt-programs.river.enable).
|
||||
|
||||
- [sitespeed-io](https://sitespeed.io), a tool that can generate metrics (timings, diagnostics) for websites. Available as [services.sitespeed-io](#opt-services.sitespeed-io.enable).
|
||||
|
||||
## Backward Incompatibilities {#sec-release-23.11-incompatibilities}
|
||||
|
||||
- The latest version of `clonehero` now stores custom content in `~/.clonehero`. See the [migration instructions](https://clonehero.net/2022/11/29/v23-to-v1-migration-instructions.html). Typically, these content files would exist along side the binary, but the previous build used a wrapper script that would store them in `~/.config/unity3d/srylain Inc_/Clone Hero`.
|
||||
|
||||
- `python3.pkgs.fetchPypi` (and `python3Packages.fetchPypi`) has been deprecated in favor of top-level `fetchPypi`.
|
||||
|
||||
- `etcd` has been updated to 3.5, you will want to read the [3.3 to 3.4](https://etcd.io/docs/v3.5/upgrades/upgrade_3_4/) and [3.4 to 3.5](https://etcd.io/docs/v3.5/upgrades/upgrade_3_5/) upgrade guides
|
||||
|
||||
- `util-linux` is now supported on Darwin and is no longer an alias to `unixtools`. Use the `unixtools.util-linux` package for access to the Apple variants of the utilities.
|
||||
|
||||
## Other Notable Changes {#sec-release-23.11-notable-changes}
|
||||
|
||||
- The Cinnamon module now enables XDG desktop integration by default. If you are experiencing collisions related to xdg-desktop-portal-gtk you can safely remove `xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];` from your NixOS configuration.
|
||||
|
||||
- A new option was added to the virtualisation module that enables specifying explicitly named network interfaces in QEMU VMs. The existing `virtualisation.vlans` is still supported for cases where the name of the network interface is irrelevant.
|
||||
|
||||
- `services.nginx` gained a `defaultListen` option at server-level with support for PROXY protocol listeners, also `proxyProtocol` is now exposed in `services.nginx.virtualHosts.<name>.listen` option. It is now possible to run PROXY listeners and non-PROXY listeners at a server-level, see [#213510](https://github.com/NixOS/nixpkgs/pull/213510/) for more details.
|
||||
@@ -855,37 +855,21 @@ class Machine:
|
||||
with self.nested(f"waiting for {regex} to appear on screen"):
|
||||
retry(screen_matches)
|
||||
|
||||
def wait_for_console_text(self, regex: str, timeout: int | None = None) -> None:
|
||||
"""
|
||||
Wait for the provided regex to appear on console.
|
||||
For each reads,
|
||||
|
||||
If timeout is None, timeout is infinite.
|
||||
|
||||
`timeout` is in seconds.
|
||||
"""
|
||||
# Buffer the console output, this is needed
|
||||
# to match multiline regexes.
|
||||
console = io.StringIO()
|
||||
|
||||
def console_matches() -> bool:
|
||||
nonlocal console
|
||||
try:
|
||||
# This will return as soon as possible and
|
||||
# sleep 1 second.
|
||||
console.write(self.last_lines.get(block=False))
|
||||
except queue.Empty:
|
||||
pass
|
||||
console.seek(0)
|
||||
matches = re.search(regex, console.read())
|
||||
return matches is not None
|
||||
|
||||
def wait_for_console_text(self, regex: str) -> None:
|
||||
with self.nested(f"waiting for {regex} to appear on console"):
|
||||
if timeout is not None:
|
||||
retry(console_matches, timeout)
|
||||
else:
|
||||
while not console_matches():
|
||||
pass
|
||||
# Buffer the console output, this is needed
|
||||
# to match multiline regexes.
|
||||
console = io.StringIO()
|
||||
while True:
|
||||
try:
|
||||
console.write(self.last_lines.get())
|
||||
except queue.Empty:
|
||||
self.sleep(1)
|
||||
continue
|
||||
console.seek(0)
|
||||
matches = re.search(regex, console.read())
|
||||
if matches is not None:
|
||||
return
|
||||
|
||||
def send_key(
|
||||
self, key: str, delay: Optional[float] = 0.01, log: Optional[bool] = True
|
||||
|
||||
@@ -12,9 +12,7 @@ let
|
||||
};
|
||||
|
||||
|
||||
vlans = map (m: (
|
||||
m.virtualisation.vlans ++
|
||||
(lib.mapAttrsToList (_: v: v.vlan) m.virtualisation.interfaces))) (lib.attrValues config.nodes);
|
||||
vlans = map (m: m.virtualisation.vlans) (lib.attrValues config.nodes);
|
||||
vms = map (m: m.system.build.vm) (lib.attrValues config.nodes);
|
||||
|
||||
nodeHostNames =
|
||||
|
||||
@@ -4,7 +4,7 @@ let
|
||||
inherit (lib)
|
||||
attrNames concatMap concatMapStrings flip forEach head
|
||||
listToAttrs mkDefault mkOption nameValuePair optionalString
|
||||
range toLower types zipListsWith zipLists
|
||||
range types zipListsWith zipLists
|
||||
mdDoc
|
||||
;
|
||||
|
||||
@@ -18,41 +18,24 @@ let
|
||||
|
||||
networkModule = { config, nodes, pkgs, ... }:
|
||||
let
|
||||
qemu-common = import ../qemu-common.nix { inherit lib pkgs; };
|
||||
|
||||
# Convert legacy VLANs to named interfaces and merge with explicit interfaces.
|
||||
vlansNumbered = forEach (zipLists config.virtualisation.vlans (range 1 255)) (v: {
|
||||
name = "eth${toString v.snd}";
|
||||
vlan = v.fst;
|
||||
assignIP = true;
|
||||
});
|
||||
explicitInterfaces = lib.mapAttrsToList (n: v: v // { name = n; }) config.virtualisation.interfaces;
|
||||
interfaces = vlansNumbered ++ explicitInterfaces;
|
||||
interfacesNumbered = zipLists interfaces (range 1 255);
|
||||
|
||||
# Automatically assign IP addresses to requested interfaces.
|
||||
assignIPs = lib.filter (i: i.assignIP) interfaces;
|
||||
ipInterfaces = forEach assignIPs (i:
|
||||
nameValuePair i.name { ipv4.addresses =
|
||||
[ { address = "192.168.${toString i.vlan}.${toString config.virtualisation.test.nodeNumber}";
|
||||
interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
|
||||
interfaces = forEach interfacesNumbered ({ fst, snd }:
|
||||
nameValuePair "eth${toString snd}" {
|
||||
ipv4.addresses =
|
||||
[{
|
||||
address = "192.168.${toString fst}.${toString config.virtualisation.test.nodeNumber}";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
});
|
||||
|
||||
qemuOptions = lib.flatten (forEach interfacesNumbered ({ fst, snd }:
|
||||
qemu-common.qemuNICFlags snd fst.vlan config.virtualisation.test.nodeNumber));
|
||||
udevRules = forEach interfacesNumbered ({ fst, snd }:
|
||||
# MAC Addresses for QEMU network devices are lowercase, and udev string comparison is case-sensitive.
|
||||
''SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="${toLower(qemu-common.qemuNicMac fst.vlan config.virtualisation.test.nodeNumber)}",NAME="${fst.name}"'');
|
||||
|
||||
networkConfig =
|
||||
{
|
||||
networking.hostName = mkDefault config.virtualisation.test.nodeName;
|
||||
|
||||
networking.interfaces = listToAttrs ipInterfaces;
|
||||
networking.interfaces = listToAttrs interfaces;
|
||||
|
||||
networking.primaryIPAddress =
|
||||
optionalString (ipInterfaces != [ ]) (head (head ipInterfaces).value.ipv4.addresses).address;
|
||||
optionalString (interfaces != [ ]) (head (head interfaces).value.ipv4.addresses).address;
|
||||
|
||||
# Put the IP addresses of all VMs in this machine's
|
||||
# /etc/hosts file. If a machine has multiple
|
||||
@@ -68,13 +51,16 @@ let
|
||||
"${config.networking.hostName}.${config.networking.domain} " +
|
||||
"${config.networking.hostName}\n"));
|
||||
|
||||
virtualisation.qemu.options = qemuOptions;
|
||||
boot.initrd.services.udev.rules = concatMapStrings (x: x + "\n") udevRules;
|
||||
virtualisation.qemu.options =
|
||||
let qemu-common = import ../qemu-common.nix { inherit lib pkgs; };
|
||||
in
|
||||
flip concatMap interfacesNumbered
|
||||
({ fst, snd }: qemu-common.qemuNICFlags snd fst config.virtualisation.test.nodeNumber);
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
key = "network-interfaces";
|
||||
key = "ip-address";
|
||||
config = networkConfig // {
|
||||
# Expose the networkConfig items for tests like nixops
|
||||
# that need to recreate the network config.
|
||||
|
||||
@@ -38,7 +38,10 @@ with lib;
|
||||
boot.loader.grub.enable = false;
|
||||
|
||||
# !!! Hack - attributes expected by other modules.
|
||||
environment.systemPackages = lib.filter (lib.meta.availableOn pkgs.stdenv.hostPlatform) [ pkgs.grub2_efi pkgs.grub2 pkgs.syslinux ];
|
||||
environment.systemPackages = [ pkgs.grub2_efi ]
|
||||
++ (if pkgs.stdenv.hostPlatform.system == "aarch64-linux"
|
||||
then []
|
||||
else [ pkgs.grub2 pkgs.syslinux ]);
|
||||
|
||||
fileSystems."/" = mkImageMediaOverride
|
||||
{ fsType = "tmpfs";
|
||||
|
||||
@@ -335,7 +335,7 @@ sub findStableDevPath {
|
||||
|
||||
my $st = stat($dev) or return $dev;
|
||||
|
||||
foreach my $dev2 (glob("/dev/stratis/*/*"), glob("/dev/disk/by-uuid/*"), glob("/dev/mapper/*"), glob("/dev/disk/by-label/*")) {
|
||||
foreach my $dev2 (glob("/dev/disk/by-uuid/*"), glob("/dev/mapper/*"), glob("/dev/disk/by-label/*")) {
|
||||
my $st2 = stat($dev2) or next;
|
||||
return $dev2 if $st->rdev == $st2->rdev;
|
||||
}
|
||||
@@ -467,17 +467,6 @@ EOF
|
||||
}
|
||||
}
|
||||
|
||||
# is this a stratis fs?
|
||||
my $stableDevPath = findStableDevPath $device;
|
||||
my $stratisPool;
|
||||
if ($stableDevPath =~ qr#/dev/stratis/(.*)/.*#) {
|
||||
my $poolName = $1;
|
||||
my ($header, @lines) = split "\n", qx/stratis pool list/;
|
||||
my $uuidIndex = index $header, 'UUID';
|
||||
my ($line) = grep /^$poolName /, @lines;
|
||||
$stratisPool = substr $line, $uuidIndex - 32, 36;
|
||||
}
|
||||
|
||||
# Don't emit tmpfs entry for /tmp, because it most likely comes from the
|
||||
# boot.tmp.useTmpfs option in configuration.nix (managed declaratively).
|
||||
next if ($mountPoint eq "/tmp" && $fsType eq "tmpfs");
|
||||
@@ -485,7 +474,7 @@ EOF
|
||||
# Emit the filesystem.
|
||||
$fileSystems .= <<EOF;
|
||||
fileSystems.\"$mountPoint\" =
|
||||
{ device = \"$stableDevPath\";
|
||||
{ device = \"${\(findStableDevPath $device)}\";
|
||||
fsType = \"$fsType\";
|
||||
EOF
|
||||
|
||||
@@ -495,12 +484,6 @@ EOF
|
||||
EOF
|
||||
}
|
||||
|
||||
if ($stratisPool) {
|
||||
$fileSystems .= <<EOF;
|
||||
stratis.poolUuid = "$stratisPool";
|
||||
EOF
|
||||
}
|
||||
|
||||
$fileSystems .= <<EOF;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ let
|
||||
DOCUMENTATION_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/learn.html";
|
||||
SUPPORT_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/community.html";
|
||||
BUG_REPORT_URL = lib.optionalString (cfg.distroId == "nixos") "https://github.com/NixOS/nixpkgs/issues";
|
||||
SUPPORT_END = "2023-12-31";
|
||||
} // lib.optionalAttrs (cfg.variant_id != null) {
|
||||
VARIANT_ID = cfg.variant_id;
|
||||
};
|
||||
@@ -143,7 +144,7 @@ in
|
||||
defaultChannel = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
default = "https://nixos.org/channels/nixos-unstable";
|
||||
default = "https://nixos.org/channels/nixos-23.05";
|
||||
description = lib.mdDoc "Default NixOS channel to which the root user is subscribed.";
|
||||
};
|
||||
|
||||
|
||||
@@ -241,6 +241,7 @@
|
||||
./programs/starship.nix
|
||||
./programs/steam.nix
|
||||
./programs/streamdeck-ui.nix
|
||||
./programs/sway.nix
|
||||
./programs/sysdig.nix
|
||||
./programs/system-config-printer.nix
|
||||
./programs/systemtap.nix
|
||||
@@ -255,9 +256,7 @@
|
||||
./programs/usbtop.nix
|
||||
./programs/vim.nix
|
||||
./programs/wavemon.nix
|
||||
./programs/wayland/river.nix
|
||||
./programs/wayland/sway.nix
|
||||
./programs/wayland/waybar.nix
|
||||
./programs/waybar.nix
|
||||
./programs/weylus.nix
|
||||
./programs/wireshark.nix
|
||||
./programs/xastir.nix
|
||||
@@ -808,7 +807,6 @@
|
||||
./services/network-filesystems/xtreemfs.nix
|
||||
./services/network-filesystems/yandex-disk.nix
|
||||
./services/networking/3proxy.nix
|
||||
./services/networking/acme-dns.nix
|
||||
./services/networking/adguardhome.nix
|
||||
./services/networking/alice-lg.nix
|
||||
./services/networking/amuled.nix
|
||||
@@ -914,7 +912,6 @@
|
||||
./services/networking/knot.nix
|
||||
./services/networking/kresd.nix
|
||||
./services/networking/lambdabot.nix
|
||||
./services/networking/legit.nix
|
||||
./services/networking/libreswan.nix
|
||||
./services/networking/lldpd.nix
|
||||
./services/networking/logmein-hamachi.nix
|
||||
@@ -1010,7 +1007,6 @@
|
||||
./services/networking/shorewall.nix
|
||||
./services/networking/shorewall6.nix
|
||||
./services/networking/shout.nix
|
||||
./services/networking/sitespeed-io.nix
|
||||
./services/networking/skydns.nix
|
||||
./services/networking/smartdns.nix
|
||||
./services/networking/smokeping.nix
|
||||
@@ -1314,6 +1310,7 @@
|
||||
./services/x11/window-managers/default.nix
|
||||
./services/x11/window-managers/fluxbox.nix
|
||||
./services/x11/window-managers/icewm.nix
|
||||
./services/x11/window-managers/bspwm.nix
|
||||
./services/x11/window-managers/katriawm.nix
|
||||
./services/x11/window-managers/metacity.nix
|
||||
./services/x11/window-managers/nimdow.nix
|
||||
@@ -1350,7 +1347,6 @@
|
||||
./system/boot/loader/raspberrypi/raspberrypi.nix
|
||||
./system/boot/loader/systemd-boot/systemd-boot.nix
|
||||
./system/boot/luksroot.nix
|
||||
./system/boot/stratisroot.nix
|
||||
./system/boot/modprobe.nix
|
||||
./system/boot/networkd.nix
|
||||
./system/boot/plymouth.nix
|
||||
|
||||
@@ -49,7 +49,7 @@ in {
|
||||
description = lib.mdDoc ''
|
||||
Sway package to use. Will override the options
|
||||
'wrapperFeatures', 'extraSessionCommands', and 'extraOptions'.
|
||||
Set to `null` to not add any Sway package to your
|
||||
Set to <code>null</code> to not add any Sway package to your
|
||||
path. This should be done if you want to use the Home Manager Sway
|
||||
module to install Sway.
|
||||
'';
|
||||
@@ -123,36 +123,41 @@ in {
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable
|
||||
(mkMerge [
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.extraSessionCommands != "" -> cfg.wrapperFeatures.base;
|
||||
message = ''
|
||||
The extraSessionCommands for Sway will not be run if
|
||||
wrapperFeatures.base is disabled.
|
||||
'';
|
||||
}
|
||||
];
|
||||
environment = {
|
||||
systemPackages = optional (cfg.package != null) cfg.package ++ cfg.extraPackages;
|
||||
# Needed for the default wallpaper:
|
||||
pathsToLink = optionals (cfg.package != null) [ "/share/backgrounds/sway" ];
|
||||
etc = {
|
||||
"sway/config.d/nixos.conf".source = pkgs.writeText "nixos.conf" ''
|
||||
# Import the most important environment variables into the D-Bus and systemd
|
||||
# user environments (e.g. required for screen sharing and Pinentry prompts):
|
||||
exec dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP
|
||||
'';
|
||||
} // optionalAttrs (cfg.package != null) {
|
||||
"sway/config".source = mkOptionDefault "${cfg.package}/etc/sway/config";
|
||||
};
|
||||
};
|
||||
# To make a Sway session available if a display manager like SDDM is enabled:
|
||||
services.xserver.displayManager.sessionPackages = optionals (cfg.package != null) [ cfg.package ]; }
|
||||
(import ./wayland-session.nix { inherit lib pkgs; })
|
||||
]);
|
||||
assertion = cfg.extraSessionCommands != "" -> cfg.wrapperFeatures.base;
|
||||
message = ''
|
||||
The extraSessionCommands for Sway will not be run if
|
||||
wrapperFeatures.base is disabled.
|
||||
'';
|
||||
}
|
||||
];
|
||||
environment = {
|
||||
systemPackages = optional (cfg.package != null) cfg.package ++ cfg.extraPackages;
|
||||
# Needed for the default wallpaper:
|
||||
pathsToLink = optionals (cfg.package != null) [ "/share/backgrounds/sway" ];
|
||||
etc = {
|
||||
"sway/config.d/nixos.conf".source = pkgs.writeText "nixos.conf" ''
|
||||
# Import the most important environment variables into the D-Bus and systemd
|
||||
# user environments (e.g. required for screen sharing and Pinentry prompts):
|
||||
exec dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP
|
||||
'';
|
||||
} // optionalAttrs (cfg.package != null) {
|
||||
"sway/config".source = mkOptionDefault "${cfg.package}/etc/sway/config";
|
||||
};
|
||||
};
|
||||
security.polkit.enable = true;
|
||||
security.pam.services.swaylock = {};
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
programs.dconf.enable = mkDefault true;
|
||||
# To make a Sway session available if a display manager like SDDM is enabled:
|
||||
services.xserver.displayManager.sessionPackages = optionals (cfg.package != null) [ cfg.package ];
|
||||
programs.xwayland.enable = mkDefault true;
|
||||
# For screen sharing (this option only has an effect with xdg.portal.enable):
|
||||
xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-wlr ];
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ primeos colemickens ];
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.programs.river;
|
||||
in {
|
||||
options.programs.river = {
|
||||
enable = mkEnableOption (lib.mdDoc "river, a dynamic tiling Wayland compositor");
|
||||
|
||||
package = mkOption {
|
||||
type = with types; nullOr package;
|
||||
default = pkgs.river;
|
||||
defaultText = literalExpression "pkgs.river";
|
||||
description = lib.mdDoc ''
|
||||
River package to use.
|
||||
Set to `null` to not add any River package to your path.
|
||||
This should be done if you want to use the Home Manager River module to install River.
|
||||
'';
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = with types; listOf package;
|
||||
default = with pkgs; [
|
||||
swaylock
|
||||
foot
|
||||
dmenu
|
||||
];
|
||||
defaultText = literalExpression ''
|
||||
with pkgs; [ swaylock foot dmenu ];
|
||||
'';
|
||||
example = literalExpression ''
|
||||
with pkgs; [
|
||||
termite rofi light
|
||||
]
|
||||
'';
|
||||
description = lib.mdDoc ''
|
||||
Extra packages to be installed system wide. See
|
||||
[Common X11 apps used on i3 with Wayland alternatives](https://github.com/swaywm/sway/wiki/i3-Migration-Guide#common-x11-apps-used-on-i3-with-wayland-alternatives)
|
||||
for a list of useful software.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
mkIf cfg.enable (mkMerge [
|
||||
{
|
||||
environment.systemPackages = optional (cfg.package != null) cfg.package ++ cfg.extraPackages;
|
||||
|
||||
# To make a river session available if a display manager like SDDM is enabled:
|
||||
services.xserver.displayManager.sessionPackages = optionals (cfg.package != null) [ cfg.package ];
|
||||
}
|
||||
(import ./wayland-session.nix { inherit lib pkgs; })
|
||||
]);
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ GaetanLepage ];
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{ lib, pkgs, ... }: with lib; {
|
||||
security = {
|
||||
polkit.enable = true;
|
||||
pam.services.swaylock = {};
|
||||
};
|
||||
|
||||
hardware.opengl.enable = mkDefault true;
|
||||
fonts.enableDefaultFonts = mkDefault true;
|
||||
|
||||
programs = {
|
||||
dconf.enable = mkDefault true;
|
||||
xwayland.enable = mkDefault true;
|
||||
};
|
||||
|
||||
xdg.portal = {
|
||||
enable = mkDefault true;
|
||||
|
||||
extraPortals = [
|
||||
# For screen sharing
|
||||
pkgs.xdg-desktop-portal-wlr
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -29,7 +29,6 @@ in {
|
||||
};
|
||||
|
||||
appservice = rec {
|
||||
id = "facebook";
|
||||
address = "http://${hostname}:${toString port}";
|
||||
hostname = "localhost";
|
||||
port = 29319;
|
||||
@@ -172,7 +171,7 @@ in {
|
||||
|
||||
services.mautrix-facebook = {
|
||||
registrationData = {
|
||||
id = cfg.settings.appservice.id;
|
||||
id = "mautrix-facebook";
|
||||
|
||||
namespaces = {
|
||||
users = [
|
||||
|
||||
@@ -49,14 +49,6 @@ in {
|
||||
options.services.dockerRegistry = {
|
||||
enable = mkEnableOption (lib.mdDoc "Docker Registry");
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
description = mdDoc "Which Docker registry package to use.";
|
||||
default = pkgs.docker-distribution;
|
||||
defaultText = literalExpression "pkgs.docker-distribution";
|
||||
example = literalExpression "pkgs.gitlab-container-registry";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
description = lib.mdDoc "Docker registry host or ip to bind to.";
|
||||
default = "127.0.0.1";
|
||||
@@ -125,7 +117,7 @@ in {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
script = ''
|
||||
${cfg.package}/bin/registry serve ${configFile}
|
||||
${pkgs.docker-distribution}/bin/registry serve ${configFile}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
@@ -144,7 +136,7 @@ in {
|
||||
serviceConfig.Type = "oneshot";
|
||||
|
||||
script = ''
|
||||
${cfg.package}/bin/registry garbage-collect ${configFile}
|
||||
${pkgs.docker-distribution}/bin/registry garbage-collect ${configFile}
|
||||
/run/current-system/systemd/bin/systemctl restart docker-registry.service
|
||||
'';
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ in {
|
||||
type = types.bool;
|
||||
};
|
||||
|
||||
package = mkPackageOptionMD pkgs "etcd" { };
|
||||
|
||||
name = mkOption {
|
||||
description = lib.mdDoc "Etcd unique node name.";
|
||||
default = config.networking.hostName;
|
||||
@@ -189,13 +187,13 @@ in {
|
||||
|
||||
serviceConfig = {
|
||||
Type = "notify";
|
||||
ExecStart = "${cfg.package}/bin/etcd";
|
||||
ExecStart = "${pkgs.etcd}/bin/etcd";
|
||||
User = "etcd";
|
||||
LimitNOFILE = 40000;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
environment.systemPackages = [ pkgs.etcd ];
|
||||
|
||||
users.users.etcd = {
|
||||
isSystemUser = true;
|
||||
|
||||
@@ -498,8 +498,7 @@ in
|
||||
|
||||
systemd.services.gitea = {
|
||||
description = "gitea";
|
||||
after = [ "network.target" ] ++ optional usePostgresql "postgresql.service" ++ optional useMysql "mysql.service";
|
||||
requires = optional usePostgresql "postgresql.service" ++ optional useMysql "mysql.service";
|
||||
after = [ "network.target" ] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ cfg.package pkgs.git pkgs.gnupg ];
|
||||
|
||||
|
||||
@@ -9,10 +9,12 @@ let
|
||||
toml = pkgs.formats.toml {};
|
||||
yaml = pkgs.formats.yaml {};
|
||||
|
||||
ruby = cfg.packages.gitlab.ruby;
|
||||
|
||||
postgresqlPackage = if config.services.postgresql.enable then
|
||||
config.services.postgresql.package
|
||||
else
|
||||
pkgs.postgresql_13;
|
||||
pkgs.postgresql_12;
|
||||
|
||||
gitlabSocket = "${cfg.statePath}/tmp/sockets/gitlab.socket";
|
||||
gitalySocket = "${cfg.statePath}/tmp/sockets/gitaly.socket";
|
||||
@@ -45,6 +47,9 @@ let
|
||||
[git]
|
||||
bin_path = "${pkgs.git}/bin/git"
|
||||
|
||||
[gitaly-ruby]
|
||||
dir = "${cfg.packages.gitaly.ruby}"
|
||||
|
||||
[gitlab-shell]
|
||||
dir = "${cfg.packages.gitlab-shell}"
|
||||
|
||||
@@ -84,9 +89,6 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
# Redis configuration file
|
||||
resqueYml = pkgs.writeText "resque.yml" (builtins.toJSON redisConfig);
|
||||
|
||||
gitlabConfig = {
|
||||
# These are the default settings from config/gitlab.example.yml
|
||||
production = flip recursiveUpdate cfg.extraConfig {
|
||||
@@ -170,6 +172,7 @@ let
|
||||
SCHEMA = "${cfg.statePath}/db/structure.sql";
|
||||
GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads";
|
||||
GITLAB_LOG_PATH = "${cfg.statePath}/log";
|
||||
GITLAB_REDIS_CONFIG_FILE = pkgs.writeText "redis.yml" (builtins.toJSON redisConfig);
|
||||
prometheus_multiproc_dir = "/run/gitlab";
|
||||
RAILS_ENV = "production";
|
||||
MALLOC_ARENA_MAX = "2";
|
||||
@@ -553,20 +556,6 @@ in {
|
||||
default = false;
|
||||
description = lib.mdDoc "Enable GitLab container registry.";
|
||||
};
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default =
|
||||
if versionAtLeast config.system.stateVersion "23.11"
|
||||
then pkgs.gitlab-container-registry
|
||||
else pkgs.docker-distribution;
|
||||
defaultText = literalExpression "pkgs.docker-distribution";
|
||||
description = lib.mdDoc ''
|
||||
Container registry package to use.
|
||||
|
||||
External container registries such as `pkgs.docker-distribution` are not supported
|
||||
anymore since GitLab 16.0.0.
|
||||
'';
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = config.services.gitlab.host;
|
||||
@@ -1081,13 +1070,6 @@ in {
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
warnings = [
|
||||
(mkIf
|
||||
(cfg.registry.enable && versionAtLeast (getVersion cfg.packages.gitlab) "16.0.0" && cfg.registry.package == pkgs.docker-distribution)
|
||||
''Support for container registries other than gitlab-container-registry has ended since GitLab 16.0.0 and is scheduled for removal in a future release.
|
||||
Please back up your data and migrate to the gitlab-container-registry package.''
|
||||
)
|
||||
];
|
||||
|
||||
assertions = [
|
||||
{
|
||||
@@ -1119,8 +1101,8 @@ in {
|
||||
message = "services.gitlab.secrets.jwsFile must be set!";
|
||||
}
|
||||
{
|
||||
assertion = versionAtLeast postgresqlPackage.version "13.6.0";
|
||||
message = "PostgreSQL >=13.6 is required to run GitLab 16. Follow the instructions in the manual section for upgrading PostgreSQL here: https://nixos.org/manual/nixos/stable/index.html#module-services-postgres-upgrading";
|
||||
assertion = versionAtLeast postgresqlPackage.version "12.0.0";
|
||||
message = "PostgreSQL >=12 is required to run GitLab 14. Follow the instructions in the manual section for upgrading PostgreSQL here: https://nixos.org/manual/nixos/stable/index.html#module-services-postgres-upgrading";
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1231,7 +1213,6 @@ in {
|
||||
services.dockerRegistry = optionalAttrs cfg.registry.enable {
|
||||
enable = true;
|
||||
enableDelete = true; # This must be true, otherwise GitLab won't manage it correctly
|
||||
package = cfg.package;
|
||||
extraConfig = {
|
||||
auth.token = {
|
||||
realm = "http${optionalString (cfg.https == true) "s"}://${cfg.host}/jwt/auth";
|
||||
@@ -1334,7 +1315,6 @@ in {
|
||||
cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db
|
||||
ln -sf ${extraGitlabRb} ${cfg.statePath}/config/initializers/extra-gitlab.rb
|
||||
ln -sf ${cableYml} ${cfg.statePath}/config/cable.yml
|
||||
ln -sf ${resqueYml} ${cfg.statePath}/config/resque.yml
|
||||
|
||||
${cfg.packages.gitlab-shell}/bin/install
|
||||
|
||||
@@ -1482,7 +1462,10 @@ in {
|
||||
partOf = [ "gitlab.target" ];
|
||||
path = with pkgs; [
|
||||
openssh
|
||||
procps # See https://gitlab.com/gitlab-org/gitaly/issues/1562
|
||||
git
|
||||
cfg.packages.gitaly.rubyEnv
|
||||
cfg.packages.gitaly.rubyEnv.wrappedRuby
|
||||
gzip
|
||||
bzip2
|
||||
];
|
||||
|
||||
@@ -165,14 +165,14 @@ in
|
||||
enableDebug = mkEnableOption (lib.mdDoc "request logs and debug endpoints");
|
||||
|
||||
proxy = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = lib.mdDoc "URL to a HTTP/HTTPS proxy.";
|
||||
};
|
||||
|
||||
proxyAuth = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = lib.mdDoc "Credentials for proxy.";
|
||||
};
|
||||
|
||||
|
||||
@@ -61,17 +61,8 @@ in
|
||||
|
||||
services.ntfy-sh.settings = {
|
||||
auth-file = mkDefault "/var/lib/ntfy-sh/user.db";
|
||||
listen-http = mkDefault "127.0.0.1:2586";
|
||||
attachment-cache-dir = mkDefault "/var/lib/ntfy-sh/attachments";
|
||||
cache-file = mkDefault "/var/lib/ntfy-sh/cache-file.db";
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"f ${cfg.settings.auth-file} 0600 ${cfg.user} ${cfg.group} - -"
|
||||
"d ${cfg.settings.attachment-cache-dir} 0700 ${cfg.user} ${cfg.group} - -"
|
||||
"f ${cfg.settings.cache-file} 0600 ${cfg.user} ${cfg.group} - -"
|
||||
];
|
||||
|
||||
systemd.services.ntfy-sh = {
|
||||
description = "Push notifications server";
|
||||
|
||||
@@ -83,7 +74,6 @@ in
|
||||
User = cfg.user;
|
||||
StateDirectory = "ntfy-sh";
|
||||
|
||||
DynamicUser = true;
|
||||
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||
PrivateTmp = true;
|
||||
NoNewPrivileges = true;
|
||||
@@ -98,8 +88,6 @@ in
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
# Upstream Recommandation
|
||||
LimitNOFILE = 20500;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ let
|
||||
"dovecot"
|
||||
"fastly"
|
||||
"fritzbox"
|
||||
"graphite"
|
||||
"influxdb"
|
||||
"ipmi"
|
||||
"json"
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
{ config, lib, pkgs, options }:
|
||||
|
||||
let
|
||||
cfg = config.services.prometheus.exporters.graphite;
|
||||
format = pkgs.formats.yaml { };
|
||||
in
|
||||
{
|
||||
port = 9108;
|
||||
extraOpts = {
|
||||
graphitePort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 9109;
|
||||
description = lib.mdDoc ''
|
||||
Port to use for the graphite server.
|
||||
'';
|
||||
};
|
||||
mappingSettings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = { };
|
||||
};
|
||||
default = { };
|
||||
description = lib.mdDoc ''
|
||||
Mapping configuration for the exporter, see
|
||||
<https://github.com/prometheus/graphite_exporter#yaml-config> for
|
||||
available options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
serviceOpts = {
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${pkgs.prometheus-graphite-exporter}/bin/graphite_exporter \
|
||||
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
|
||||
--graphite.listen-address ${cfg.listenAddress}:${toString cfg.graphitePort} \
|
||||
--graphite.mapping-config ${format.generate "mapping.yml" cfg.mappingSettings} \
|
||||
${lib.concatStringsSep " \\\n " cfg.extraFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
{ lib
|
||||
, config
|
||||
, pkgs
|
||||
, ...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.acme-dns;
|
||||
format = pkgs.formats.toml { };
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mdDoc
|
||||
mkEnableOption
|
||||
mkOption
|
||||
mkPackageOptionMD
|
||||
types
|
||||
;
|
||||
domain = "acme-dns.example.com";
|
||||
in
|
||||
{
|
||||
options.services.acme-dns = {
|
||||
enable = mkEnableOption (mdDoc "acme-dns");
|
||||
|
||||
package = mkPackageOptionMD pkgs "acme-dns" { };
|
||||
|
||||
settings = mkOption {
|
||||
description = mdDoc ''
|
||||
Free-form settings written directly to the `acme-dns.cfg` file.
|
||||
Refer to <https://github.com/joohoi/acme-dns/blob/master/README.md#configuration> for supported values.
|
||||
'';
|
||||
|
||||
default = { };
|
||||
|
||||
type = types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
general = {
|
||||
listen = mkOption {
|
||||
type = types.str;
|
||||
description = mdDoc "IP+port combination to bind and serve the DNS server on.";
|
||||
default = "[::]:53";
|
||||
example = "127.0.0.1:53";
|
||||
};
|
||||
|
||||
protocol = mkOption {
|
||||
type = types.enum [ "both" "both4" "both6" "udp" "udp4" "udp6" "tcp" "tcp4" "tcp6" ];
|
||||
description = mdDoc "Protocols to serve DNS responses on.";
|
||||
default = "both";
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = mdDoc "Domain name to serve the requests off of.";
|
||||
example = domain;
|
||||
};
|
||||
|
||||
nsname = mkOption {
|
||||
type = types.str;
|
||||
description = mdDoc "Zone name server.";
|
||||
example = domain;
|
||||
};
|
||||
|
||||
nsadmin = mkOption {
|
||||
type = types.str;
|
||||
description = mdDoc "Zone admin email address for `SOA`.";
|
||||
example = "admin.example.com";
|
||||
};
|
||||
|
||||
records = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = mdDoc "Predefined DNS records served in addition to the `_acme-challenge` TXT records.";
|
||||
example = literalExpression ''
|
||||
[
|
||||
# replace with your acme-dns server's public IPv4
|
||||
"${domain}. A 198.51.100.1"
|
||||
# replace with your acme-dns server's public IPv6
|
||||
"${domain}. AAAA 2001:db8::1"
|
||||
# ${domain} should resolve any *.${domain} records
|
||||
"${domain}. NS ${domain}."
|
||||
]
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
database = {
|
||||
engine = mkOption {
|
||||
type = types.enum [ "sqlite3" "postgres" ];
|
||||
description = mdDoc "Database engine to use.";
|
||||
default = "sqlite3";
|
||||
};
|
||||
connection = mkOption {
|
||||
type = types.str;
|
||||
description = mdDoc "Database connection string.";
|
||||
example = "postgres://user:password@localhost/acmedns";
|
||||
default = "/var/lib/acme-dns/acme-dns.db";
|
||||
};
|
||||
};
|
||||
|
||||
api = {
|
||||
ip = mkOption {
|
||||
type = types.str;
|
||||
description = mdDoc "IP to bind the HTTP API on.";
|
||||
default = "[::]";
|
||||
example = "127.0.0.1";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
description = mdDoc "Listen port for the HTTP API.";
|
||||
default = 8080;
|
||||
# acme-dns expects this value to be a string
|
||||
apply = toString;
|
||||
};
|
||||
|
||||
disable_registration = mkOption {
|
||||
type = types.bool;
|
||||
description = mdDoc "Whether to disable the HTTP registration endpoint.";
|
||||
default = false;
|
||||
example = true;
|
||||
};
|
||||
|
||||
tls = mkOption {
|
||||
type = types.enum [ "letsencrypt" "letsencryptstaging" "cert" "none" ];
|
||||
description = mdDoc "TLS backend to use.";
|
||||
default = "none";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
logconfig = {
|
||||
loglevel = mkOption {
|
||||
type = types.enum [ "error" "warning" "info" "debug" ];
|
||||
description = mdDoc "Level to log on.";
|
||||
default = "info";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.packages = [ cfg.package ];
|
||||
systemd.services.acme-dns = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
ExecStart = [ "" "${lib.getExe cfg.package} -c ${format.generate "acme-dns.toml" cfg.settings}" ];
|
||||
StateDirectory = "acme-dns";
|
||||
WorkingDirectory = "%S/acme-dns";
|
||||
DynamicUser = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkEnableOption
|
||||
mdDoc
|
||||
mkIf
|
||||
mkOption
|
||||
mkPackageOptionMD
|
||||
optionalAttrs
|
||||
optional
|
||||
types;
|
||||
|
||||
cfg = config.services.legit;
|
||||
|
||||
yaml = pkgs.formats.yaml { };
|
||||
configFile = yaml.generate "legit.yaml" cfg.settings;
|
||||
|
||||
defaultStateDir = "/var/lib/legit";
|
||||
defaultStaticDir = "${cfg.settings.repo.scanPath}/static";
|
||||
defaultTemplatesDir = "${cfg.settings.repo.scanPath}/templates";
|
||||
in
|
||||
{
|
||||
options.services.legit = {
|
||||
enable = mkEnableOption (mdDoc "legit git web frontend");
|
||||
|
||||
package = mkPackageOptionMD pkgs "legit-web" { };
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "legit";
|
||||
description = mdDoc "User account under which legit runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "legit";
|
||||
description = mdDoc "Group account under which legit runs.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
default = { };
|
||||
description = mdDoc ''
|
||||
The primary legit configuration. See the
|
||||
[sample configuration](https://github.com/icyphox/legit/blob/master/config.yaml)
|
||||
for possible values.
|
||||
'';
|
||||
type = types.submodule {
|
||||
options.repo = {
|
||||
scanPath = mkOption {
|
||||
type = types.path;
|
||||
default = defaultStateDir;
|
||||
description = mdDoc "Directory where legit will scan for repositories.";
|
||||
};
|
||||
readme = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = mdDoc "Readme files to look for.";
|
||||
};
|
||||
mainBranch = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "main" "master" ];
|
||||
description = mdDoc "Main branch to look for.";
|
||||
};
|
||||
ignore = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = mdDoc "Repositories to ignore.";
|
||||
};
|
||||
};
|
||||
options.dirs = {
|
||||
templates = mkOption {
|
||||
type = types.path;
|
||||
default = "${pkgs.legit-web}/lib/legit/templates";
|
||||
defaultText = literalExpression ''"''${pkgs.legit-web}/lib/legit/templates"'';
|
||||
description = mdDoc "Directories where template files are located.";
|
||||
};
|
||||
static = mkOption {
|
||||
type = types.path;
|
||||
default = "${pkgs.legit-web}/lib/legit/static";
|
||||
defaultText = literalExpression ''"''${pkgs.legit-web}/lib/legit/static"'';
|
||||
description = mdDoc "Directories where static files are located.";
|
||||
};
|
||||
};
|
||||
options.meta = {
|
||||
title = mkOption {
|
||||
type = types.str;
|
||||
default = "legit";
|
||||
description = mdDoc "Website title.";
|
||||
};
|
||||
description = mkOption {
|
||||
type = types.str;
|
||||
default = "git frontend";
|
||||
description = mdDoc "Website description.";
|
||||
};
|
||||
};
|
||||
options.server = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
description = mdDoc "Server name.";
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
description = mdDoc "Host address.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 5555;
|
||||
description = mdDoc "Legit port.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.groups = optionalAttrs (cfg.group == "legit") {
|
||||
"${cfg.group}" = { };
|
||||
};
|
||||
|
||||
users.users = optionalAttrs (cfg.user == "legit") {
|
||||
"${cfg.user}" = {
|
||||
group = cfg.group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.legit = {
|
||||
description = "legit git frontend";
|
||||
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ configFile ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
ExecStart = "${cfg.package}/bin/legit -config ${configFile}";
|
||||
Restart = "always";
|
||||
|
||||
WorkingDirectory = cfg.settings.repo.scanPath;
|
||||
StateDirectory = [ ] ++
|
||||
optional (cfg.settings.repo.scanPath == defaultStateDir) "legit" ++
|
||||
optional (cfg.settings.dirs.static == defaultStaticDir) "legit/static" ++
|
||||
optional (cfg.settings.dirs.templates == defaultTemplatesDir) "legit/templates";
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = [ "" ];
|
||||
DeviceAllow = [ "" ];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
ReadWritePaths = cfg.settings.repo.scanPath;
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -313,7 +313,7 @@ in
|
||||
systemd.services.murmur = {
|
||||
description = "Murmur Chat Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
preStart = ''
|
||||
${pkgs.envsubst}/bin/envsubst \
|
||||
-o /run/murmur/murmurd.ini \
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
{ lib, config, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.sitespeed-io;
|
||||
format = pkgs.formats.json { };
|
||||
in
|
||||
{
|
||||
options.services.sitespeed-io = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "Sitespeed.io");
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "sitespeed-io";
|
||||
description = lib.mdDoc "User account under which sitespeed-io runs.";
|
||||
};
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.sitespeed-io;
|
||||
defaultText = "pkgs.sitespeed-io";
|
||||
description = lib.mdDoc "Sitespeed.io package to use.";
|
||||
};
|
||||
|
||||
dataDir = lib.mkOption {
|
||||
default = "/var/lib/sitespeed-io";
|
||||
type = lib.types.str;
|
||||
description = lib.mdDoc "The base sitespeed-io data directory.";
|
||||
};
|
||||
|
||||
period = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "hourly";
|
||||
description = lib.mdDoc ''
|
||||
Systemd calendar expression when to run. See {manpage}`systemd.time(7)`.
|
||||
'';
|
||||
};
|
||||
|
||||
runs = lib.mkOption {
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
A list of run configurations. The service will call sitespeed-io once
|
||||
for every run listed here. This lets you examine different websites
|
||||
with different sitespeed-io settings.
|
||||
'';
|
||||
type = lib.types.listOf (lib.types.submodule {
|
||||
options = {
|
||||
urls = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
URLs the service should monitor.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = { };
|
||||
};
|
||||
default = { };
|
||||
description = lib.mdDoc ''
|
||||
Configuration for sitespeed-io, see
|
||||
<https://www.sitespeed.io/documentation/sitespeed.io/configuration/>
|
||||
for available options. The value here will be directly transformed to
|
||||
JSON and passed as `--config` to the program.
|
||||
'';
|
||||
};
|
||||
|
||||
extraArgs = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [];
|
||||
description = lib.mdDoc ''
|
||||
Extra command line arguments to pass to the program.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.runs != [];
|
||||
message = "At least one run must be configured.";
|
||||
}
|
||||
{
|
||||
assertion = lib.all (run: run.urls != []) cfg.runs;
|
||||
message = "All runs must have at least one url configured.";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services.sitespeed-io = {
|
||||
description = "Check website status";
|
||||
startAt = cfg.period;
|
||||
serviceConfig = {
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
User = cfg.user;
|
||||
};
|
||||
preStart = "chmod u+w -R ${cfg.dataDir}"; # Make sure things are writable
|
||||
script = (lib.concatMapStrings (run: ''
|
||||
${lib.getExe cfg.package} \
|
||||
--config ${format.generate "sitespeed.json" run.settings} \
|
||||
${lib.escapeShellArgs run.extraArgs} \
|
||||
${builtins.toFile "urls.txt" (lib.concatLines run.urls)} &
|
||||
'') cfg.runs) +
|
||||
''
|
||||
wait
|
||||
'';
|
||||
};
|
||||
|
||||
users = {
|
||||
extraUsers.${cfg.user} = {
|
||||
isSystemUser = true;
|
||||
group = cfg.user;
|
||||
home = cfg.dataDir;
|
||||
createHome = true;
|
||||
homeMode = "755";
|
||||
};
|
||||
extraGroups.${cfg.user} = { };
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -25,8 +25,6 @@ in
|
||||
options.services.thelounge = {
|
||||
enable = mkEnableOption (lib.mdDoc "The Lounge web IRC client");
|
||||
|
||||
package = mkPackageOptionMD pkgs "thelounge" { };
|
||||
|
||||
public = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
@@ -95,11 +93,11 @@ in
|
||||
serviceConfig = {
|
||||
User = "thelounge";
|
||||
StateDirectory = baseNameOf dataDir;
|
||||
ExecStart = "${getExe cfg.package} start";
|
||||
ExecStart = "${pkgs.thelounge}/bin/thelounge start";
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
environment.systemPackages = [ pkgs.thelounge ];
|
||||
};
|
||||
|
||||
meta = {
|
||||
|
||||
@@ -80,11 +80,11 @@ in
|
||||
options.services.epgstation = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc description);
|
||||
|
||||
package = lib.mkPackageOptionMD pkgs "epgstation" { };
|
||||
|
||||
ffmpeg = lib.mkPackageOptionMD pkgs "ffmpeg" {
|
||||
default = [ "ffmpeg-headless" ];
|
||||
example = "pkgs.ffmpeg-full";
|
||||
package = lib.mkOption {
|
||||
default = pkgs.epgstation;
|
||||
type = lib.types.package;
|
||||
defaultText = lib.literalExpression "pkgs.epgstation";
|
||||
description = lib.mdDoc "epgstation package to use";
|
||||
};
|
||||
|
||||
usePreconfiguredStreaming = lib.mkOption {
|
||||
@@ -278,8 +278,6 @@ in
|
||||
package = lib.mkDefault pkgs.mariadb;
|
||||
ensureDatabases = [ cfg.database.name ];
|
||||
# FIXME: enable once mysqljs supports auth_socket
|
||||
# https://github.com/mysqljs/mysql/issues/1507
|
||||
#
|
||||
# ensureUsers = [ {
|
||||
# name = username;
|
||||
# ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; };
|
||||
@@ -297,8 +295,8 @@ in
|
||||
database = cfg.database.name;
|
||||
};
|
||||
|
||||
ffmpeg = lib.mkDefault "${cfg.ffmpeg}/bin/ffmpeg";
|
||||
ffprobe = lib.mkDefault "${cfg.ffmpeg}/bin/ffprobe";
|
||||
ffmpeg = lib.mkDefault "${pkgs.ffmpeg-full}/bin/ffmpeg";
|
||||
ffprobe = lib.mkDefault "${pkgs.ffmpeg-full}/bin/ffprobe";
|
||||
|
||||
# for disambiguation with TypeScript files
|
||||
recordedFileExtension = lib.mkDefault ".m2ts";
|
||||
@@ -310,15 +308,9 @@ in
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '/var/lib/epgstation/key' - ${username} ${groupname} - -"
|
||||
"d '/var/lib/epgstation/streamfiles' - ${username} ${groupname} - -"
|
||||
"d '/var/lib/epgstation/drop' - ${username} ${groupname} - -"
|
||||
"d '/var/lib/epgstation/recorded' - ${username} ${groupname} - -"
|
||||
"d '/var/lib/epgstation/thumbnail' - ${username} ${groupname} - -"
|
||||
"d '/var/lib/epgstation/db/subscribers' - ${username} ${groupname} - -"
|
||||
"d '/var/lib/epgstation/db/migrations/mysql' - ${username} ${groupname} - -"
|
||||
"d '/var/lib/epgstation/db/migrations/postgres' - ${username} ${groupname} - -"
|
||||
"d '/var/lib/epgstation/db/migrations/sqlite' - ${username} ${groupname} - -"
|
||||
];
|
||||
|
||||
systemd.services.epgstation = {
|
||||
|
||||
@@ -1,199 +1,107 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
|
||||
cfg = config.services.code-server;
|
||||
defaultUser = "code-server";
|
||||
defaultGroup = defaultUser;
|
||||
|
||||
in {
|
||||
###### interface
|
||||
options = {
|
||||
services.code-server = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "code-server");
|
||||
enable = mkEnableOption (lib.mdDoc "code-server");
|
||||
|
||||
package = lib.mkPackageOptionMD pkgs "code-server" { };
|
||||
|
||||
extraPackages = lib.mkOption {
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
Additional packages to add to the code-server {env}`PATH`.
|
||||
'';
|
||||
example = lib.literalExpression "[ pkgs.go ]";
|
||||
type = lib.types.listOf lib.types.package;
|
||||
package = mkOption {
|
||||
default = pkgs.code-server;
|
||||
defaultText = lib.literalExpression "pkgs.code-server";
|
||||
description = lib.mdDoc "Which code-server derivation to use.";
|
||||
type = types.package;
|
||||
};
|
||||
|
||||
extraEnvironment = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
description = lib.mdDoc ''
|
||||
Additional environment variables to pass to code-server.
|
||||
'';
|
||||
extraPackages = mkOption {
|
||||
default = [ ];
|
||||
description = lib.mdDoc "Packages that are available in the PATH of code-server.";
|
||||
example = "[ pkgs.go ]";
|
||||
type = types.listOf types.package;
|
||||
};
|
||||
|
||||
extraEnvironment = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
description =
|
||||
lib.mdDoc "Additional environment variables to passed to code-server.";
|
||||
default = { };
|
||||
example = { PKG_CONFIG_PATH = "/run/current-system/sw/lib/pkgconfig"; };
|
||||
};
|
||||
|
||||
extraArguments = lib.mkOption {
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
Additional arguments to pass to code-server.
|
||||
'';
|
||||
example = lib.literalExpression ''[ "--log=info" ]'';
|
||||
type = lib.types.listOf lib.types.str;
|
||||
extraArguments = mkOption {
|
||||
default = [ "--disable-telemetry" ];
|
||||
description = lib.mdDoc "Additional arguments that passed to code-server";
|
||||
example = ''[ "--verbose" ]'';
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
|
||||
host = lib.mkOption {
|
||||
default = "localhost";
|
||||
description = lib.mdDoc ''
|
||||
The host name or IP address the server should listen to.
|
||||
'';
|
||||
type = lib.types.str;
|
||||
host = mkOption {
|
||||
default = "127.0.0.1";
|
||||
description = lib.mdDoc "The host-ip to bind to.";
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
port = mkOption {
|
||||
default = 4444;
|
||||
description = lib.mdDoc ''
|
||||
The port the server should listen to.
|
||||
'';
|
||||
type = lib.types.port;
|
||||
description = lib.mdDoc "The port where code-server runs.";
|
||||
type = types.port;
|
||||
};
|
||||
|
||||
auth = lib.mkOption {
|
||||
auth = mkOption {
|
||||
default = "password";
|
||||
description = lib.mdDoc ''
|
||||
The type of authentication to use.
|
||||
'';
|
||||
type = lib.types.enum [ "none" "password" ];
|
||||
description = lib.mdDoc "The type of authentication to use.";
|
||||
type = types.enum [ "none" "password" ];
|
||||
};
|
||||
|
||||
hashedPassword = lib.mkOption {
|
||||
hashedPassword = mkOption {
|
||||
default = "";
|
||||
description = lib.mdDoc ''
|
||||
Create the password with: `echo -n 'thisismypassword' | npx argon2-cli -e`.
|
||||
'';
|
||||
type = lib.types.str;
|
||||
description =
|
||||
lib.mdDoc "Create the password with: `echo -n 'thisismypassword' | npx argon2-cli -e`.";
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
user = mkOption {
|
||||
default = defaultUser;
|
||||
example = "yourUser";
|
||||
description = lib.mdDoc ''
|
||||
The user to run code-server as.
|
||||
By default, a user named `${defaultUser}` will be created.
|
||||
'';
|
||||
type = lib.types.str;
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
group = mkOption {
|
||||
default = defaultGroup;
|
||||
example = "yourGroup";
|
||||
description = lib.mdDoc ''
|
||||
The group to run code-server under.
|
||||
By default, a group named `${defaultGroup}` will be created.
|
||||
'';
|
||||
type = lib.types.str;
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
extraGroups = lib.mkOption {
|
||||
extraGroups = mkOption {
|
||||
default = [ ];
|
||||
description = lib.mdDoc ''
|
||||
An array of additional groups for the `${defaultUser}` user.
|
||||
'';
|
||||
description =
|
||||
lib.mdDoc "An array of additional groups for the `${defaultUser}` user.";
|
||||
example = [ "docker" ];
|
||||
type = lib.types.listOf lib.types.str;
|
||||
};
|
||||
|
||||
socket = lib.mkOption {
|
||||
default = null;
|
||||
example = "/run/code-server/socket";
|
||||
description = lib.mdDoc ''
|
||||
Path to a socket (bind-addr will be ignored).
|
||||
'';
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
};
|
||||
|
||||
socketMode = lib.mkOption {
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
File mode of the socket.
|
||||
'';
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
};
|
||||
|
||||
userDataDir = lib.mkOption {
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Path to the user data directory.
|
||||
'';
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
};
|
||||
|
||||
extensionsDir = lib.mkOption {
|
||||
default = null;
|
||||
description = lib.mdDoc ''
|
||||
Path to the extensions directory.
|
||||
'';
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
};
|
||||
|
||||
proxyDomain = lib.mkOption {
|
||||
default = null;
|
||||
example = "code-server.lan";
|
||||
description = lib.mdDoc ''
|
||||
Domain used for proxying ports.
|
||||
'';
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
};
|
||||
|
||||
disableTelemetry = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = lib.mdDoc ''
|
||||
Disable telemetry.
|
||||
'';
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
disableUpdateCheck = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = lib.mdDoc ''
|
||||
Disable update check.
|
||||
Without this flag, code-server checks every 6 hours against the latest github release and
|
||||
then notifies you once every week that a new release is available.
|
||||
'';
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
disableFileDownloads = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = lib.mdDoc ''
|
||||
Disable file downloads from Code.
|
||||
'';
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
disableWorkspaceTrust = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = lib.mdDoc ''
|
||||
Disable Workspace Trust feature.
|
||||
'';
|
||||
type = lib.types.bool;
|
||||
};
|
||||
|
||||
disableGettingStartedOverride = lib.mkOption {
|
||||
default = false;
|
||||
example = true;
|
||||
description = lib.mdDoc ''
|
||||
Disable the coder/coder override in the Help: Getting Started page.
|
||||
'';
|
||||
type = lib.types.bool;
|
||||
type = types.listOf types.str;
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
###### implementation
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.code-server = {
|
||||
description = "Code server";
|
||||
description = "VSCode server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
path = cfg.extraPackages;
|
||||
@@ -201,37 +109,18 @@ in {
|
||||
HASHED_PASSWORD = cfg.hashedPassword;
|
||||
} // cfg.extraEnvironment;
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${lib.getExe cfg.package} \
|
||||
--auth=${cfg.auth} \
|
||||
--bind-addr=${cfg.host}:${toString cfg.port} \
|
||||
'' + lib.optionalString (cfg.socket != null) ''
|
||||
--socket=${cfg.socket} \
|
||||
'' + lib.optionalString (cfg.userDataDir != null) ''
|
||||
--user-data-dir=${cfg.userDataDir} \
|
||||
'' + lib.optionalString (cfg.extensionsDir != null) ''
|
||||
--extensions-dir=${cfg.extensionsDir} \
|
||||
'' + lib.optionalString (cfg.disableTelemetry == true) ''
|
||||
--disable-telemetry \
|
||||
'' + lib.optionalString (cfg.disableUpdateCheck == true) ''
|
||||
--disable-update-check \
|
||||
'' + lib.optionalString (cfg.disableFileDownloads == true) ''
|
||||
--disable-file-downloads \
|
||||
'' + lib.optionalString (cfg.disableWorkspaceTrust == true) ''
|
||||
--disable-workspace-trust \
|
||||
'' + lib.optionalString (cfg.disableGettingStartedOverride == true) ''
|
||||
--disable-getting-started-override \
|
||||
'' + lib.escapeShellArgs cfg.extraArguments;
|
||||
ExecStart = "${cfg.package}/bin/code-server --bind-addr ${cfg.host}:${toString cfg.port} --auth ${cfg.auth} " + lib.escapeShellArgs cfg.extraArguments;
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
RuntimeDirectory = cfg.user;
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
users.users."${cfg.user}" = lib.mkMerge [
|
||||
(lib.mkIf (cfg.user == defaultUser) {
|
||||
users.users."${cfg.user}" = mkMerge [
|
||||
(mkIf (cfg.user == defaultUser) {
|
||||
isNormalUser = true;
|
||||
description = "code-server user";
|
||||
inherit (cfg) group;
|
||||
@@ -242,8 +131,9 @@ in {
|
||||
}
|
||||
];
|
||||
|
||||
users.groups."${defaultGroup}" = lib.mkIf (cfg.group == defaultGroup) { };
|
||||
users.groups."${defaultGroup}" = mkIf (cfg.group == defaultGroup) { };
|
||||
|
||||
};
|
||||
|
||||
meta.maintainers = [ lib.maintainers.stackshadow ];
|
||||
meta.maintainers = with maintainers; [ stackshadow ];
|
||||
}
|
||||
|
||||
@@ -117,9 +117,7 @@ in {
|
||||
|
||||
# PHP 8.0 is the only version which is supported/tested by upstream:
|
||||
# https://github.com/grocy/grocy/blob/v3.3.0/README.md#how-to-install
|
||||
# Compatibility with PHP 8.1 is available on their development branch:
|
||||
# https://github.com/grocy/grocy/commit/38a4ad8ec480c29a1bff057b3482fd103b036848
|
||||
phpPackage = pkgs.php81;
|
||||
phpPackage = pkgs.php80;
|
||||
|
||||
inherit (cfg.phpfpm) settings;
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ in
|
||||
|
||||
services.phpfpm.pools.limesurvey = {
|
||||
inherit user group;
|
||||
phpPackage = pkgs.php81;
|
||||
phpPackage = pkgs.php80;
|
||||
phpEnv.DBENGINE = "${cfg.database.dbEngine}";
|
||||
phpEnv.LIMESURVEY_CONFIG = "${limesurveyConfig}";
|
||||
settings = {
|
||||
@@ -288,8 +288,8 @@ in
|
||||
environment.LIMESURVEY_CONFIG = limesurveyConfig;
|
||||
script = ''
|
||||
# update or install the database as required
|
||||
${pkgs.php81}/bin/php ${pkg}/share/limesurvey/application/commands/console.php updatedb || \
|
||||
${pkgs.php81}/bin/php ${pkg}/share/limesurvey/application/commands/console.php install admin password admin admin@example.com verbose
|
||||
${pkgs.php80}/bin/php ${pkg}/share/limesurvey/application/commands/console.php updatedb || \
|
||||
${pkgs.php80}/bin/php ${pkg}/share/limesurvey/application/commands/console.php install admin password admin admin@example.com verbose
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = user;
|
||||
|
||||
@@ -586,7 +586,7 @@ in
|
||||
|
||||
# Create an outline-sequalize wrapper (a wrapper around the wrapper) that
|
||||
# has the config file's path baked in. This is necessary because there is
|
||||
# at least two occurrences of outline calling this from its own code.
|
||||
# at least one occurrence of outline calling this from its own code.
|
||||
sequelize = pkgs.writeShellScriptBin "outline-sequelize" ''
|
||||
exec ${cfg.package}/bin/outline-sequelize \
|
||||
--config $RUNTIME_DIRECTORY/database.json \
|
||||
@@ -687,18 +687,21 @@ in
|
||||
openssl rand -hex 32 > ${lib.escapeShellArg cfg.utilsSecretFile}
|
||||
fi
|
||||
|
||||
# The config file is required for the sequelize CLI.
|
||||
# The config file is required for the CLI, the DATABASE_URL environment
|
||||
# variable is read by the app.
|
||||
${if (cfg.databaseUrl == "local") then ''
|
||||
cat <<EOF > $RUNTIME_DIRECTORY/database.json
|
||||
{
|
||||
"production-ssl-disabled": {
|
||||
"production": {
|
||||
"dialect": "postgres",
|
||||
"host": "/run/postgresql",
|
||||
"username": null,
|
||||
"password": null,
|
||||
"dialect": "postgres"
|
||||
"password": null
|
||||
}
|
||||
}
|
||||
EOF
|
||||
export DATABASE_URL=${lib.escapeShellArg localPostgresqlUrl}
|
||||
export PGSSLMODE=disable
|
||||
'' else ''
|
||||
cat <<EOF > $RUNTIME_DIRECTORY/database.json
|
||||
{
|
||||
@@ -717,7 +720,11 @@ in
|
||||
}
|
||||
}
|
||||
EOF
|
||||
export DATABASE_URL=${lib.escapeShellArg cfg.databaseUrl}
|
||||
''}
|
||||
|
||||
cd $RUNTIME_DIRECTORY
|
||||
${sequelize}/bin/outline-sequelize db:migrate
|
||||
'';
|
||||
|
||||
script = ''
|
||||
@@ -774,7 +781,7 @@ in
|
||||
RuntimeDirectoryMode = "0750";
|
||||
# This working directory is required to find stuff like the set of
|
||||
# onboarding files:
|
||||
WorkingDirectory = "${cfg.package}/share/outline";
|
||||
WorkingDirectory = "${cfg.package}/share/outline/build";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -448,7 +448,7 @@ in {
|
||||
cfg.nginx
|
||||
{
|
||||
root = lib.mkForce "${pixelfed}/public/";
|
||||
locations."/".tryFiles = "$uri $uri/ /index.php?$query_string";
|
||||
locations."/".tryFiles = "$uri $uri/ /index.php?query_string";
|
||||
locations."/favicon.ico".extraConfig = ''
|
||||
access_log off; log_not_found off;
|
||||
'';
|
||||
|
||||
@@ -49,7 +49,7 @@ in
|
||||
|
||||
replication_mode = mkOption {
|
||||
default = "none";
|
||||
type = types.enum ([ "none" "1" "2" "3" "2-dangerous" "3-dangerous" "3-degraded" 1 2 3 ]);
|
||||
type = types.enum ([ "none" "1" "2" "3" 1 2 3 ]);
|
||||
apply = v: toString v;
|
||||
description = lib.mdDoc "Garage replication mode, defaults to none, see: <https://garagehq.deuxfleurs.fr/documentation/reference-manual/configuration/#replication-mode> for reference.";
|
||||
};
|
||||
@@ -80,7 +80,6 @@ in
|
||||
after = [ "network.target" "network-online.target" ];
|
||||
wants = [ "network.target" "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ configFile ];
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/garage server";
|
||||
|
||||
|
||||
@@ -309,54 +309,36 @@ let
|
||||
onlySSL = vhost.onlySSL || vhost.enableSSL;
|
||||
hasSSL = onlySSL || vhost.addSSL || vhost.forceSSL;
|
||||
|
||||
# First evaluation of defaultListen based on a set of listen lines.
|
||||
mkDefaultListenVhost = listenLines:
|
||||
# If this vhost has SSL or is a SSL rejection host.
|
||||
# We enable a TLS variant for lines without explicit ssl or ssl = true.
|
||||
optionals (hasSSL || vhost.rejectSSL)
|
||||
(map (listen: { port = cfg.defaultSSLListenPort; ssl = true; } // listen)
|
||||
(filter (listen: !(listen ? ssl) || listen.ssl) listenLines))
|
||||
# If this vhost is supposed to serve HTTP
|
||||
# We provide listen lines for those without explicit ssl or ssl = false.
|
||||
++ optionals (!onlySSL)
|
||||
(map (listen: { port = cfg.defaultHTTPListenPort; ssl = false; } // listen)
|
||||
(filter (listen: !(listen ? ssl) || !listen.ssl) listenLines));
|
||||
|
||||
defaultListen =
|
||||
if vhost.listen != [] then vhost.listen
|
||||
else
|
||||
if cfg.defaultListen != [] then mkDefaultListenVhost
|
||||
# Cleanup nulls which will mess up with //.
|
||||
# TODO: is there a better way to achieve this? i.e. mergeButIgnoreNullPlease?
|
||||
(map (listenLine: filterAttrs (_: v: (v != null)) listenLine) cfg.defaultListen)
|
||||
else
|
||||
let addrs = if vhost.listenAddresses != [] then vhost.listenAddresses else cfg.defaultListenAddresses;
|
||||
in mkDefaultListenVhost (map (addr: { inherit addr; }) addrs);
|
||||
|
||||
in optionals (hasSSL || vhost.rejectSSL) (map (addr: { inherit addr; port = cfg.defaultSSLListenPort; ssl = true; }) addrs)
|
||||
++ optionals (!onlySSL) (map (addr: { inherit addr; port = cfg.defaultHTTPListenPort; ssl = false; }) addrs);
|
||||
|
||||
hostListen =
|
||||
if vhost.forceSSL
|
||||
then filter (x: x.ssl) defaultListen
|
||||
else defaultListen;
|
||||
|
||||
listenString = { addr, port, ssl, proxyProtocol ? false, extraParameters ? [], ... }:
|
||||
listenString = { addr, port, ssl, extraParameters ? [], ... }:
|
||||
# UDP listener for QUIC transport protocol.
|
||||
(optionalString (ssl && vhost.quic) ("
|
||||
listen ${addr}:${toString port} quic "
|
||||
+ optionalString vhost.default "default_server "
|
||||
+ optionalString vhost.reuseport "reuseport "
|
||||
+ optionalString (extraParameters != []) (concatStringsSep " "
|
||||
(let inCompatibleParameters = [ "ssl" "proxy_protocol" "http2" ];
|
||||
+ optionalString (extraParameters != []) (concatStringsSep " " (
|
||||
let inCompatibleParameters = [ "ssl" "proxy_protocol" "http2" ];
|
||||
isCompatibleParameter = param: !(any (p: p == param) inCompatibleParameters);
|
||||
in filter isCompatibleParameter extraParameters))
|
||||
+ ";"))
|
||||
+ "
|
||||
|
||||
listen ${addr}:${toString port} "
|
||||
+ optionalString (ssl && vhost.http2) "http2 "
|
||||
+ optionalString ssl "ssl "
|
||||
+ optionalString vhost.default "default_server "
|
||||
+ optionalString vhost.reuseport "reuseport "
|
||||
+ optionalString proxyProtocol "proxy_protocol "
|
||||
+ optionalString (extraParameters != []) (concatStringsSep " " extraParameters)
|
||||
+ ";";
|
||||
|
||||
@@ -557,49 +539,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
defaultListen = mkOption {
|
||||
type = with types; listOf (submodule {
|
||||
options = {
|
||||
addr = mkOption {
|
||||
type = str;
|
||||
description = lib.mdDoc "IP address.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = nullOr port;
|
||||
description = lib.mdDoc "Port number.";
|
||||
default = null;
|
||||
};
|
||||
ssl = mkOption {
|
||||
type = nullOr bool;
|
||||
default = null;
|
||||
description = lib.mdDoc "Enable SSL.";
|
||||
};
|
||||
proxyProtocol = mkOption {
|
||||
type = bool;
|
||||
description = lib.mdDoc "Enable PROXY protocol.";
|
||||
default = false;
|
||||
};
|
||||
extraParameters = mkOption {
|
||||
type = listOf str;
|
||||
description = lib.mdDoc "Extra parameters of this listen directive.";
|
||||
default = [ ];
|
||||
example = [ "backlog=1024" "deferred" ];
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [];
|
||||
example = literalExpression ''[
|
||||
{ addr = "10.0.0.12"; proxyProtocol = true; ssl = true; }
|
||||
{ addr = "0.0.0.0"; }
|
||||
{ addr = "[::0]"; }
|
||||
]'';
|
||||
description = lib.mdDoc ''
|
||||
If vhosts do not specify listen, use these addresses by default.
|
||||
This option takes precedence over {option}`defaultListenAddresses` and
|
||||
other listen-related defaults options.
|
||||
'';
|
||||
};
|
||||
|
||||
defaultListenAddresses = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "0.0.0.0" ] ++ optional enableIPv6 "[::0]";
|
||||
@@ -607,7 +546,6 @@ in
|
||||
example = literalExpression ''[ "10.0.0.12" "[2002:a00:1::]" ]'';
|
||||
description = lib.mdDoc ''
|
||||
If vhosts do not specify listenAddresses, use these addresses by default.
|
||||
This is akin to writing `defaultListen = [ { addr = "0.0.0.0" } ]`.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -1140,32 +1078,6 @@ in
|
||||
which can be achieved by setting `services.nginx.package = pkgs.nginxQuic;`.
|
||||
'';
|
||||
}
|
||||
|
||||
{
|
||||
# The idea is to understand whether there is a virtual host with a listen configuration
|
||||
# that requires ACME configuration but has no HTTP listener which will make deterministically fail
|
||||
# this operation.
|
||||
# Options' priorities are the following at the moment:
|
||||
# listen (vhost) > defaultListen (server) > listenAddresses (vhost) > defaultListenAddresses (server)
|
||||
assertion =
|
||||
let
|
||||
hasAtLeastHttpListener = listenOptions: any (listenLine: if listenLine ? proxyProtocol then !listenLine.proxyProtocol else true) listenOptions;
|
||||
hasAtLeastDefaultHttpListener = if cfg.defaultListen != [] then hasAtLeastHttpListener cfg.defaultListen else (cfg.defaultListenAddresses != []);
|
||||
in
|
||||
all (host:
|
||||
let
|
||||
hasAtLeastVhostHttpListener = if host.listen != [] then hasAtLeastHttpListener host.listen else (host.listenAddresses != []);
|
||||
vhostAuthority = host.listen != [] || (cfg.defaultListen == [] && host.listenAddresses != []);
|
||||
in
|
||||
# Either vhost has precedence and we need a vhost specific http listener
|
||||
# Either vhost set nothing and inherit from server settings
|
||||
host.enableACME -> ((vhostAuthority && hasAtLeastVhostHttpListener) || (!vhostAuthority && hasAtLeastDefaultHttpListener))
|
||||
) (attrValues virtualHosts);
|
||||
message = ''
|
||||
services.nginx.virtualHosts.<name>.enableACME requires a HTTP listener
|
||||
to answer to ACME requests.
|
||||
'';
|
||||
}
|
||||
] ++ map (name: mkCertOwnershipAssertion {
|
||||
inherit (cfg) group user;
|
||||
cert = config.security.acme.certs.${name};
|
||||
|
||||
@@ -27,35 +27,12 @@ with lib;
|
||||
};
|
||||
|
||||
listen = mkOption {
|
||||
type = with types; listOf (submodule {
|
||||
options = {
|
||||
addr = mkOption {
|
||||
type = str;
|
||||
description = lib.mdDoc "IP address.";
|
||||
};
|
||||
port = mkOption {
|
||||
type = port;
|
||||
description = lib.mdDoc "Port number.";
|
||||
default = 80;
|
||||
};
|
||||
ssl = mkOption {
|
||||
type = bool;
|
||||
description = lib.mdDoc "Enable SSL.";
|
||||
default = false;
|
||||
};
|
||||
proxyProtocol = mkOption {
|
||||
type = bool;
|
||||
description = lib.mdDoc "Enable PROXY protocol.";
|
||||
default = false;
|
||||
};
|
||||
extraParameters = mkOption {
|
||||
type = listOf str;
|
||||
description = lib.mdDoc "Extra parameters of this listen directive.";
|
||||
default = [ ];
|
||||
example = [ "backlog=1024" "deferred" ];
|
||||
};
|
||||
};
|
||||
});
|
||||
type = with types; listOf (submodule { options = {
|
||||
addr = mkOption { type = str; description = lib.mdDoc "IP address."; };
|
||||
port = mkOption { type = port; description = lib.mdDoc "Port number."; default = 80; };
|
||||
ssl = mkOption { type = bool; description = lib.mdDoc "Enable SSL."; default = false; };
|
||||
extraParameters = mkOption { type = listOf str; description = lib.mdDoc "Extra parameters of this listen directive."; default = []; example = [ "backlog=1024" "deferred" ]; };
|
||||
}; });
|
||||
default = [];
|
||||
example = [
|
||||
{ addr = "195.154.1.1"; port = 443; ssl = true; }
|
||||
@@ -68,7 +45,7 @@ with lib;
|
||||
and `onlySSL`.
|
||||
|
||||
If you only want to set the addresses manually and not
|
||||
the ports, take a look at `listenAddresses`.
|
||||
the ports, take a look at `listenAddresses`
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
@@ -70,9 +70,9 @@ in
|
||||
name = mkDefault "Mint-Y-Aqua";
|
||||
package = mkDefault pkgs.cinnamon.mint-themes;
|
||||
};
|
||||
iconTheme = mkIf (notExcluded pkgs.cinnamon.mint-y-icons) {
|
||||
iconTheme = mkIf (notExcluded pkgs.cinnamon.mint-x-icons) {
|
||||
name = mkDefault "Mint-Y-Aqua";
|
||||
package = mkDefault pkgs.cinnamon.mint-y-icons;
|
||||
package = mkDefault pkgs.cinnamon.mint-x-icons;
|
||||
};
|
||||
cursorTheme = mkIf (notExcluded pkgs.cinnamon.mint-cursor-themes) {
|
||||
name = mkDefault "Bibata-Modern-Classic";
|
||||
@@ -187,15 +187,6 @@ in
|
||||
xdg.mime.enable = true;
|
||||
xdg.icons.enable = true;
|
||||
|
||||
xdg.portal.enable = true;
|
||||
xdg.portal.extraPortals = [
|
||||
pkgs.xdg-desktop-portal-xapp
|
||||
(pkgs.xdg-desktop-portal-gtk.override {
|
||||
# Do not build portals that we already have.
|
||||
buildPortalsInGnome = false;
|
||||
})
|
||||
];
|
||||
|
||||
# Override GSettings schemas
|
||||
environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-overrides}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
|
||||
|
||||
|
||||
@@ -227,16 +227,11 @@ in
|
||||
xdg.icons.enable = true;
|
||||
|
||||
xdg.portal.enable = true;
|
||||
xdg.portal.extraPortals = [
|
||||
# Some Pantheon apps enforce portal usage, we need this for e.g. notifications.
|
||||
# Currently we have buildPortalsInGnome enabled, if you run into issues related
|
||||
# to https://github.com/flatpak/xdg-desktop-portal/issues/656 please report to us.
|
||||
pkgs.xdg-desktop-portal-gtk
|
||||
] ++ (with pkgs.pantheon; [
|
||||
xdg.portal.extraPortals = with pkgs.pantheon; [
|
||||
elementary-files
|
||||
elementary-settings-daemon
|
||||
xdg-desktop-portal-pantheon
|
||||
]);
|
||||
];
|
||||
|
||||
# Override GSettings schemas
|
||||
environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
, glib
|
||||
, gobject-introspection
|
||||
, python3
|
||||
, wrapGAppsNoGuiHook
|
||||
, wrapGAppsHook
|
||||
, lib
|
||||
}:
|
||||
|
||||
@@ -18,7 +18,7 @@ python3.pkgs.buildPythonApplication {
|
||||
strictDeps = false;
|
||||
|
||||
nativeBuildInputs = [
|
||||
wrapGAppsNoGuiHook
|
||||
wrapGAppsHook
|
||||
gobject-introspection
|
||||
];
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ in
|
||||
./bspwm.nix
|
||||
./cwm.nix
|
||||
./clfswm.nix
|
||||
./dk.nix
|
||||
./dwm.nix
|
||||
./e16.nix
|
||||
./evilwm.nix
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.xserver.windowManager.dk;
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
services.xserver.windowManager.dk = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "dk");
|
||||
|
||||
package = lib.mkPackageOptionMD pkgs "dk" { };
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.xserver.windowManager.session = lib.singleton {
|
||||
name = "dk";
|
||||
start = ''
|
||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||
${cfg.package}/bin/dk &
|
||||
waitPID=$!
|
||||
'';
|
||||
};
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
};
|
||||
}
|
||||
@@ -25,11 +25,9 @@ let
|
||||
|
||||
sectionDHCPv4 = checkUnitConfig "DHCPv4" [
|
||||
(assertOnlyFields [
|
||||
"ClientIdentifier"
|
||||
"DUIDType"
|
||||
"DUIDRawData"
|
||||
])
|
||||
(assertValueOneOf "ClientIdentifier" ["mac" "duid" "duid-only"])
|
||||
];
|
||||
|
||||
sectionDHCPv6 = checkUnitConfig "DHCPv6" [
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
let
|
||||
requiredStratisFilesystems = lib.attrsets.filterAttrs (_: x: utils.fsNeededForBoot x && x.stratis.poolUuid != null) config.fileSystems;
|
||||
in
|
||||
{
|
||||
options = {};
|
||||
config = lib.mkIf (requiredStratisFilesystems != {}) {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.boot.initrd.systemd.enable;
|
||||
message = "stratis root fs requires systemd stage 1";
|
||||
}
|
||||
];
|
||||
boot.initrd = {
|
||||
systemd = {
|
||||
storePaths = [
|
||||
"${pkgs.stratisd}/lib/udev/stratis-base32-decode"
|
||||
"${pkgs.stratisd}/lib/udev/stratis-str-cmp"
|
||||
"${pkgs.lvm2.bin}/bin/dmsetup"
|
||||
"${pkgs.stratisd}/libexec/stratisd-min"
|
||||
"${pkgs.stratisd.initrd}/bin/stratis-rootfs-setup"
|
||||
];
|
||||
packages = [pkgs.stratisd.initrd];
|
||||
extraBin = {
|
||||
thin_check = "${pkgs."thin-provisioning-tools"}/bin/thin_check";
|
||||
thin_repair = "${pkgs."thin-provisioning-tools"}/bin/thin_repair";
|
||||
thin_metadata_size = "${pkgs."thin-provisioning-tools"}/bin/thin_metadata_size";
|
||||
stratis-min = "${pkgs.stratisd}/bin/stratis-min";
|
||||
};
|
||||
services =
|
||||
lib.attrsets.mapAttrs' (
|
||||
mountPoint: fileSystem: {
|
||||
name = "stratis-setup-${fileSystem.stratis.poolUuid}";
|
||||
value = {
|
||||
description = "setup for Stratis root filesystem";
|
||||
unitConfig.DefaultDependencies = "no";
|
||||
conflicts = [ "shutdown.target" "initrd-switch-root.target" ];
|
||||
onFailure = [ "emergency.target" ];
|
||||
unitConfig.OnFailureJobMode = "isolate";
|
||||
wants = [ "stratisd-min.service" "plymouth-start.service" ];
|
||||
wantedBy = [ "initrd.target" ];
|
||||
after = [ "paths.target" "plymouth-start.service" "stratisd-min.service" ];
|
||||
before = [ "initrd.target" "shutdown.target" "initrd-switch-root.target" ];
|
||||
environment.STRATIS_ROOTFS_UUID = fileSystem.stratis.poolUuid;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.stratisd.initrd}/bin/stratis-rootfs-setup";
|
||||
RemainAfterExit = "yes";
|
||||
};
|
||||
};
|
||||
}
|
||||
) requiredStratisFilesystems;
|
||||
};
|
||||
availableKernelModules = [ "dm-thin-pool" "dm-crypt" ] ++ [ "aes" "aes_generic" "blowfish" "twofish"
|
||||
"serpent" "cbc" "xts" "lrw" "sha1" "sha256" "sha512"
|
||||
"af_alg" "algif_skcipher"
|
||||
];
|
||||
services.udev.packages = [
|
||||
pkgs.stratisd.initrd
|
||||
pkgs.lvm2
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -11,145 +11,64 @@ let
|
||||
];
|
||||
in
|
||||
{
|
||||
options.services.logind = {
|
||||
extraConfig = mkOption {
|
||||
options = {
|
||||
services.logind.extraConfig = mkOption {
|
||||
default = "";
|
||||
type = types.lines;
|
||||
example = "IdleAction=lock";
|
||||
description = lib.mdDoc ''
|
||||
Extra config options for systemd-logind.
|
||||
See [logind.conf(5)](https://www.freedesktop.org/software/systemd/man/logind.conf.html)
|
||||
for available options.
|
||||
Extra config options for systemd-logind. See
|
||||
[
|
||||
logind.conf(5)](https://www.freedesktop.org/software/systemd/man/logind.conf.html) for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
killUserProcesses = mkOption {
|
||||
services.logind.killUserProcesses = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = lib.mdDoc ''
|
||||
Specifies whether the processes of a user should be killed
|
||||
when the user logs out. If true, the scope unit corresponding
|
||||
to the session and all processes inside that scope will be
|
||||
terminated. If false, the scope is "abandoned"
|
||||
(see [systemd.scope(5)](https://www.freedesktop.org/software/systemd/man/systemd.scope.html#)),
|
||||
and processes are not killed.
|
||||
terminated. If false, the scope is "abandoned" (see
|
||||
[systemd.scope(5)](https://www.freedesktop.org/software/systemd/man/systemd.scope.html#)), and processes are not killed.
|
||||
|
||||
See [logind.conf(5)](https://www.freedesktop.org/software/systemd/man/logind.conf.html#KillUserProcesses=)
|
||||
for more details.
|
||||
'';
|
||||
};
|
||||
|
||||
powerKey = mkOption {
|
||||
default = "poweroff";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the power key is pressed.
|
||||
'';
|
||||
};
|
||||
|
||||
powerKeyLongPress = mkOption {
|
||||
default = "ignore";
|
||||
example = "reboot";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the power key is long-pressed.
|
||||
'';
|
||||
};
|
||||
|
||||
rebootKey = mkOption {
|
||||
default = "reboot";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the reboot key is pressed.
|
||||
'';
|
||||
};
|
||||
|
||||
rebootKeyLongPress = mkOption {
|
||||
default = "poweroff";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the reboot key is long-pressed.
|
||||
'';
|
||||
};
|
||||
|
||||
suspendKey = mkOption {
|
||||
services.logind.lidSwitch = mkOption {
|
||||
default = "suspend";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the suspend key is pressed.
|
||||
Specifies what to be done when the laptop lid is closed.
|
||||
'';
|
||||
};
|
||||
|
||||
suspendKeyLongPress = mkOption {
|
||||
default = "hibernate";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the suspend key is long-pressed.
|
||||
'';
|
||||
};
|
||||
|
||||
hibernateKey = mkOption {
|
||||
default = "hibernate";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the hibernate key is pressed.
|
||||
'';
|
||||
};
|
||||
|
||||
hibernateKeyLongPress = mkOption {
|
||||
services.logind.lidSwitchDocked = mkOption {
|
||||
default = "ignore";
|
||||
example = "suspend";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the hibernate key is long-pressed.
|
||||
Specifies what to be done when the laptop lid is closed
|
||||
and another screen is added.
|
||||
'';
|
||||
};
|
||||
|
||||
lidSwitch = mkOption {
|
||||
default = "suspend";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the laptop lid is closed.
|
||||
'';
|
||||
};
|
||||
|
||||
lidSwitchExternalPower = mkOption {
|
||||
services.logind.lidSwitchExternalPower = mkOption {
|
||||
default = cfg.lidSwitch;
|
||||
defaultText = literalExpression "services.logind.lidSwitch";
|
||||
example = "ignore";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the laptop lid is closed
|
||||
and the system is on external power. By default use
|
||||
the same action as specified in services.logind.lidSwitch.
|
||||
'';
|
||||
};
|
||||
|
||||
lidSwitchDocked = mkOption {
|
||||
default = "ignore";
|
||||
example = "suspend";
|
||||
type = logindHandlerType;
|
||||
|
||||
description = lib.mdDoc ''
|
||||
Specifies what to do when the laptop lid is closed
|
||||
and another screen is added.
|
||||
Specifies what to do when the laptop lid is closed and the system is
|
||||
on external power. By default use the same action as specified in
|
||||
services.logind.lidSwitch.
|
||||
'';
|
||||
};
|
||||
};
|
||||
@@ -175,17 +94,9 @@ in
|
||||
"systemd/logind.conf".text = ''
|
||||
[Login]
|
||||
KillUserProcesses=${if cfg.killUserProcesses then "yes" else "no"}
|
||||
HandlePowerKey=${cfg.powerKey}
|
||||
HandlePowerKeyLongPress=${cfg.powerKeyLongPress}
|
||||
HandleRebootKey=${cfg.rebootKey}
|
||||
HandleRebootKeyLongPress=${cfg.rebootKeyLongPress}
|
||||
HandleSuspendKey=${cfg.suspendKey}
|
||||
HandleSuspendKeyLongPress=${cfg.suspendKeyLongPress}
|
||||
HandleHibernateKey=${cfg.hibernateKey}
|
||||
HandleHibernateKeyLongPress=${cfg.hibernateKeyLongPress}
|
||||
HandleLidSwitch=${cfg.lidSwitch}
|
||||
HandleLidSwitchExternalPower=${cfg.lidSwitchExternalPower}
|
||||
HandleLidSwitchDocked=${cfg.lidSwitchDocked}
|
||||
HandleLidSwitchExternalPower=${cfg.lidSwitchExternalPower}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -36,15 +36,6 @@ let
|
||||
description = lib.mdDoc "Location of the mounted file system.";
|
||||
};
|
||||
|
||||
stratis.poolUuid = lib.mkOption {
|
||||
type = types.uniq (types.nullOr types.str);
|
||||
description = lib.mdDoc ''
|
||||
UUID of the stratis pool that the fs is located in
|
||||
'';
|
||||
example = "04c68063-90a5-4235-b9dd-6180098a20d9";
|
||||
default = null;
|
||||
};
|
||||
|
||||
device = mkOption {
|
||||
default = null;
|
||||
example = "/dev/sda";
|
||||
|
||||
@@ -293,7 +293,7 @@ let
|
||||
script = ''
|
||||
# Remove Dead Interfaces
|
||||
echo "Removing old bridge ${n}..."
|
||||
ip link show dev "${n}" >/dev/null 2>&1 && ip link del "${n}"
|
||||
ip link show "${n}" >/dev/null 2>&1 && ip link del "${n}"
|
||||
|
||||
echo "Adding bridge ${n}..."
|
||||
ip link add name "${n}" type bridge
|
||||
@@ -459,7 +459,7 @@ let
|
||||
path = [ pkgs.iproute2 ];
|
||||
script = ''
|
||||
# Remove Dead Interfaces
|
||||
ip link show dev "${n}" >/dev/null 2>&1 && ip link delete "${n}"
|
||||
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
|
||||
ip link add link "${v.interface}" name "${n}" type macvlan \
|
||||
${optionalString (v.mode != null) "mode ${v.mode}"}
|
||||
ip link set "${n}" up
|
||||
@@ -517,7 +517,7 @@ let
|
||||
path = [ pkgs.iproute2 ];
|
||||
script = ''
|
||||
# Remove Dead Interfaces
|
||||
ip link show dev "${n}" >/dev/null 2>&1 && ip link delete "${n}"
|
||||
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
|
||||
ip link add name "${n}" type sit \
|
||||
${optionalString (v.remote != null) "remote \"${v.remote}\""} \
|
||||
${optionalString (v.local != null) "local \"${v.local}\""} \
|
||||
@@ -551,7 +551,7 @@ let
|
||||
path = [ pkgs.iproute2 ];
|
||||
script = ''
|
||||
# Remove Dead Interfaces
|
||||
ip link show dev "${n}" >/dev/null 2>&1 && ip link delete "${n}"
|
||||
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
|
||||
ip link add name "${n}" type ${v.type} \
|
||||
${optionalString (v.remote != null) "remote \"${v.remote}\""} \
|
||||
${optionalString (v.local != null) "local \"${v.local}\""} \
|
||||
@@ -579,7 +579,7 @@ let
|
||||
path = [ pkgs.iproute2 ];
|
||||
script = ''
|
||||
# Remove Dead Interfaces
|
||||
ip link show dev "${n}" >/dev/null 2>&1 && ip link delete "${n}"
|
||||
ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
|
||||
ip link add link "${v.interface}" name "${n}" type vlan id "${toString v.id}"
|
||||
|
||||
# We try to bring up the logical VLAN interface. If the master
|
||||
|
||||
@@ -536,53 +536,5 @@ let self = {
|
||||
"22.11".us-west-1.aarch64-linux.hvm-ebs = "ami-052d52b9e30a18562";
|
||||
"22.11".us-west-2.aarch64-linux.hvm-ebs = "ami-07418b6a4782c9521";
|
||||
|
||||
# 23.05.426.afc48694f2a
|
||||
|
||||
"23.05".eu-west-1.x86_64-linux.hvm-ebs = "ami-0fc7825fe890f87d1";
|
||||
"23.05".af-south-1.x86_64-linux.hvm-ebs = "ami-0df2f7b42bfbd53e5";
|
||||
"23.05".ap-east-1.x86_64-linux.hvm-ebs = "ami-07ba84d7321f6f4bb";
|
||||
"23.05".ap-northeast-1.x86_64-linux.hvm-ebs = "ami-0e37827874573dbbf";
|
||||
"23.05".ap-northeast-2.x86_64-linux.hvm-ebs = "ami-0ff5b3b7738651895";
|
||||
"23.05".ap-northeast-3.x86_64-linux.hvm-ebs = "ami-0a7861571eb44c70c";
|
||||
"23.05".ap-south-1.x86_64-linux.hvm-ebs = "ami-05c4802ca81d7c95b";
|
||||
"23.05".ap-southeast-1.x86_64-linux.hvm-ebs = "ami-0aee8193da16bd2db";
|
||||
"23.05".ap-southeast-2.x86_64-linux.hvm-ebs = "ami-008be032289f60d16";
|
||||
"23.05".ap-southeast-3.x86_64-linux.hvm-ebs = "ami-033debde7c1659c96";
|
||||
"23.05".ca-central-1.x86_64-linux.hvm-ebs = "ami-031821b5f83896474";
|
||||
"23.05".eu-central-1.x86_64-linux.hvm-ebs = "ami-0d6ee9d5e1c985df6";
|
||||
"23.05".eu-north-1.x86_64-linux.hvm-ebs = "ami-0cecb1f67b2a837f6";
|
||||
"23.05".eu-south-1.x86_64-linux.hvm-ebs = "ami-0f9fee15eb5a64ac4";
|
||||
"23.05".eu-west-2.x86_64-linux.hvm-ebs = "ami-0e62fef78d2c4f031";
|
||||
"23.05".eu-west-3.x86_64-linux.hvm-ebs = "ami-01a6e4c1659b08390";
|
||||
"23.05".me-south-1.x86_64-linux.hvm-ebs = "ami-0a01a7eeffa8f0fd5";
|
||||
"23.05".sa-east-1.x86_64-linux.hvm-ebs = "ami-09a1760227f929ccf";
|
||||
"23.05".us-east-1.x86_64-linux.hvm-ebs = "ami-07df5833f04703a2a";
|
||||
"23.05".us-east-2.x86_64-linux.hvm-ebs = "ami-04dd2f100d9665df5";
|
||||
"23.05".us-west-1.x86_64-linux.hvm-ebs = "ami-0fe502361fea4216c";
|
||||
"23.05".us-west-2.x86_64-linux.hvm-ebs = "ami-0749963dd978a57c7";
|
||||
|
||||
"23.05".eu-west-1.aarch64-linux.hvm-ebs = "ami-0a0609421e5638005";
|
||||
"23.05".af-south-1.aarch64-linux.hvm-ebs = "ami-05d95a055aba9373e";
|
||||
"23.05".ap-east-1.aarch64-linux.hvm-ebs = "ami-08ae0190b1357465b";
|
||||
"23.05".ap-northeast-1.aarch64-linux.hvm-ebs = "ami-09418b2049c3c9533";
|
||||
"23.05".ap-northeast-2.aarch64-linux.hvm-ebs = "ami-040713ad23b404271";
|
||||
"23.05".ap-northeast-3.aarch64-linux.hvm-ebs = "ami-0c888d6c1d989db68";
|
||||
"23.05".ap-south-1.aarch64-linux.hvm-ebs = "ami-02da38deb21545675";
|
||||
"23.05".ap-southeast-1.aarch64-linux.hvm-ebs = "ami-06df0713468bea276";
|
||||
"23.05".ap-southeast-2.aarch64-linux.hvm-ebs = "ami-0171ee37ae5104c06";
|
||||
"23.05".ap-southeast-3.aarch64-linux.hvm-ebs = "ami-075da61f5fef1fe80";
|
||||
"23.05".ca-central-1.aarch64-linux.hvm-ebs = "ami-0ba8bd0a3d0a596f8";
|
||||
"23.05".eu-central-1.aarch64-linux.hvm-ebs = "ami-0891608ae66031439";
|
||||
"23.05".eu-north-1.aarch64-linux.hvm-ebs = "ami-0a3ad7ef18d595c68";
|
||||
"23.05".eu-south-1.aarch64-linux.hvm-ebs = "ami-0fa86b680aa9a0444";
|
||||
"23.05".eu-west-2.aarch64-linux.hvm-ebs = "ami-0a415791078f05970";
|
||||
"23.05".eu-west-3.aarch64-linux.hvm-ebs = "ami-05d9b146317962e3b";
|
||||
"23.05".me-south-1.aarch64-linux.hvm-ebs = "ami-0019b591acf30aa66";
|
||||
"23.05".sa-east-1.aarch64-linux.hvm-ebs = "ami-030d6c30d91f06cc7";
|
||||
"23.05".us-east-1.aarch64-linux.hvm-ebs = "ami-0a061ca437b63df33";
|
||||
"23.05".us-east-2.aarch64-linux.hvm-ebs = "ami-0bf0b2b8fdfda30e8";
|
||||
"23.05".us-west-1.aarch64-linux.hvm-ebs = "ami-0e75c8f3deb1f842b";
|
||||
"23.05".us-west-2.aarch64-linux.hvm-ebs = "ami-0d0979d889078d036";
|
||||
|
||||
latest = self."23.05";
|
||||
latest = self."22.11";
|
||||
}; in self
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
boolToString
|
||||
mkDefault
|
||||
mkIf
|
||||
optional
|
||||
readFile
|
||||
;
|
||||
in
|
||||
|
||||
with lib;
|
||||
{
|
||||
imports = [
|
||||
../profiles/headless.nix
|
||||
@@ -75,7 +65,7 @@ in
|
||||
systemd.services.google-guest-agent = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ config.environment.etc."default/instance_configs.cfg".source ];
|
||||
path = optional config.users.mutableUsers pkgs.shadow;
|
||||
path = lib.optional config.users.mutableUsers pkgs.shadow;
|
||||
};
|
||||
systemd.services.google-startup-scripts.wantedBy = [ "multi-user.target" ];
|
||||
systemd.services.google-shutdown-scripts.wantedBy = [ "multi-user.target" ];
|
||||
@@ -86,7 +76,7 @@ in
|
||||
|
||||
users.groups.google-sudoers = mkIf config.users.mutableUsers { };
|
||||
|
||||
boot.extraModprobeConfig = readFile "${pkgs.google-guest-configs}/etc/modprobe.d/gce-blacklist.conf";
|
||||
boot.extraModprobeConfig = lib.readFile "${pkgs.google-guest-configs}/etc/modprobe.d/gce-blacklist.conf";
|
||||
|
||||
environment.etc."sysctl.d/60-gce-network-security.conf".source = "${pkgs.google-guest-configs}/etc/sysctl.d/60-gce-network-security.conf";
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
# This module creates a virtual machine from the NixOS configuration.
|
||||
# Building the `config.system.build.vm' attribute gives you a command
|
||||
# that starts a KVM/QEMU VM running the NixOS configuration defined in
|
||||
# `config'. By default, the Nix store is shared read-only with the
|
||||
# host, which makes (re)building VMs very efficient.
|
||||
# `config'. The Nix store is shared read-only with the host, which
|
||||
# makes (re)building VMs very efficient. However, it also means you
|
||||
# can't reconfigure the guest inside the guest - you need to rebuild
|
||||
# the VM in the host. On the other hand, the root filesystem is a
|
||||
# read/writable disk image persistent across VM reboots.
|
||||
|
||||
{ config, lib, pkgs, options, ... }:
|
||||
|
||||
@@ -561,8 +564,7 @@ in
|
||||
virtualisation.vlans =
|
||||
mkOption {
|
||||
type = types.listOf types.ints.unsigned;
|
||||
default = if config.virtualisation.interfaces == {} then [ 1 ] else [ ];
|
||||
defaultText = lib.literalExpression ''if config.virtualisation.interfaces == {} then [ 1 ] else [ ]'';
|
||||
default = [ 1 ];
|
||||
example = [ 1 2 ];
|
||||
description =
|
||||
lib.mdDoc ''
|
||||
@@ -577,35 +579,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.interfaces = mkOption {
|
||||
default = {};
|
||||
example = {
|
||||
enp1s0.vlan = 1;
|
||||
};
|
||||
description = lib.mdDoc ''
|
||||
Network interfaces to add to the VM.
|
||||
'';
|
||||
type = with types; attrsOf (submodule {
|
||||
options = {
|
||||
vlan = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
description = lib.mdDoc ''
|
||||
VLAN to which the network interface is connected.
|
||||
'';
|
||||
};
|
||||
|
||||
assignIP = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = lib.mdDoc ''
|
||||
Automatically assign an IP address to the network interface using the same scheme as
|
||||
virtualisation.vlans.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
virtualisation.writableStore =
|
||||
mkOption {
|
||||
type = types.bool;
|
||||
@@ -775,11 +748,12 @@ in
|
||||
default = false;
|
||||
description =
|
||||
lib.mdDoc ''
|
||||
Use a boot loader to boot the system.
|
||||
This allows, among other things, testing the boot loader.
|
||||
|
||||
If disabled, the kernel and initrd are directly booted,
|
||||
forgoing any bootloader.
|
||||
If enabled, the virtual machine will be booted using the
|
||||
regular boot loader (i.e., GRUB 1 or 2). This allows
|
||||
testing of the boot loader. If
|
||||
disabled (the default), the VM directly boots the NixOS
|
||||
kernel and initial ramdisk, bypassing the boot loader
|
||||
altogether.
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -1022,6 +996,7 @@ in
|
||||
"-netdev user,id=user.0,${forwardingOptions}${restrictNetworkOption}\"$QEMU_NET_OPTS\""
|
||||
];
|
||||
|
||||
# FIXME: Consolidate this one day.
|
||||
virtualisation.qemu.options = mkMerge [
|
||||
(mkIf cfg.qemu.virtioKeyboard [
|
||||
"-device virtio-keyboard"
|
||||
@@ -1073,12 +1048,14 @@ in
|
||||
}) cfg.emptyDiskImages)
|
||||
];
|
||||
|
||||
# Use mkVMOverride to enable building test VMs (e.g. via `nixos-rebuild
|
||||
# build-vm`) of a system configuration, where the regular value for the
|
||||
# `fileSystems' attribute should be disregarded (since those filesystems
|
||||
# don't necessarily exist in the VM).
|
||||
fileSystems = mkVMOverride cfg.fileSystems;
|
||||
|
||||
# Mount the host filesystem via 9P, and bind-mount the Nix store
|
||||
# of the host into our own filesystem. We use mkVMOverride to
|
||||
# allow this module to be applied to "normal" NixOS system
|
||||
# configuration, where the regular value for the `fileSystems'
|
||||
# attribute should be disregarded for the purpose of building a VM
|
||||
# test image (since those filesystems don't exist in the VM).
|
||||
virtualisation.fileSystems = let
|
||||
mkSharedDir = tag: share:
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ let
|
||||
|
||||
version = fileContents ../.version;
|
||||
versionSuffix =
|
||||
(if stableBranch then "." else "pre") + "${toString nixpkgs.revCount}.${nixpkgs.shortRev}";
|
||||
(if stableBranch then "." else "beta") + "${toString (nixpkgs.revCount - 487364)}.${nixpkgs.shortRev}";
|
||||
|
||||
# Run the tests for each platform. You can run a test by doing
|
||||
# e.g. ‘nix-build release.nix -A tests.login.x86_64-linux’,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"ln -s '${pkgs.aaaaxy.testing_infra}/assets/demos/benchmark.dem' '/tmp/aaaaxy/assets/demos/'",
|
||||
"""
|
||||
'${pkgs.aaaaxy.testing_infra}/scripts/regression-test-demo.sh' \
|
||||
'aaaaxy' 'on track for Any%, All Paths, No Teleports and No Coil' \
|
||||
'aaaaxy' 'on track for Any%, All Paths and No Teleports' \
|
||||
'${pkgs.aaaaxy}/bin/aaaaxy' '/tmp/aaaaxy/assets/demos/benchmark.dem'
|
||||
""",
|
||||
)
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import ./make-test-python.nix ({ ... }: {
|
||||
name = "acme-dns";
|
||||
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
services.acme-dns = {
|
||||
enable = true;
|
||||
settings = {
|
||||
general = rec {
|
||||
domain = "acme-dns.home.arpa";
|
||||
nsname = domain;
|
||||
nsadmin = "admin.home.arpa";
|
||||
records = [
|
||||
"${domain}. A 127.0.0.1"
|
||||
"${domain}. AAAA ::1"
|
||||
"${domain}. NS ${domain}."
|
||||
];
|
||||
};
|
||||
logconfig.loglevel = "debug";
|
||||
};
|
||||
};
|
||||
environment.systemPackages = with pkgs; [ curl bind ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
import json
|
||||
|
||||
machine.wait_for_unit("acme-dns.service")
|
||||
machine.wait_for_open_port(53) # dns
|
||||
machine.wait_for_open_port(8080) # http api
|
||||
|
||||
result = machine.succeed("curl --fail -X POST http://localhost:8080/register")
|
||||
print(result)
|
||||
|
||||
registration = json.loads(result)
|
||||
|
||||
machine.succeed(f'dig -t TXT @localhost {registration["fulldomain"]} | grep "SOA" | grep "admin.home.arpa"')
|
||||
|
||||
# acme-dns exspects a TXT value string length of exactly 43 chars
|
||||
txt = "___dummy_validation_token_for_txt_record___"
|
||||
|
||||
machine.succeed(
|
||||
"curl --fail -X POST http://localhost:8080/update "
|
||||
+ f' -H "X-Api-User: {registration["username"]}"'
|
||||
+ f' -H "X-Api-Key: {registration["password"]}"'
|
||||
+ f' -d \'{{"subdomain":"{registration["subdomain"]}", "txt":"{txt}"}}\'''
|
||||
)
|
||||
|
||||
assert txt in machine.succeed(f'dig -t TXT +short @localhost {registration["fulldomain"]}')
|
||||
'';
|
||||
})
|
||||
@@ -95,7 +95,6 @@ in {
|
||||
_3proxy = runTest ./3proxy.nix;
|
||||
aaaaxy = runTest ./aaaaxy.nix;
|
||||
acme = runTest ./acme.nix;
|
||||
acme-dns = handleTest ./acme-dns.nix {};
|
||||
adguardhome = runTest ./adguardhome.nix;
|
||||
aesmd = runTestOn ["x86_64-linux"] ./aesmd.nix;
|
||||
agate = runTest ./web-servers/agate.nix;
|
||||
@@ -171,7 +170,6 @@ in {
|
||||
cntr = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cntr.nix {};
|
||||
cockpit = handleTest ./cockpit.nix {};
|
||||
cockroachdb = handleTestOn ["x86_64-linux"] ./cockroachdb.nix {};
|
||||
code-server = handleTest ./code-server.nix {};
|
||||
coder = handleTest ./coder.nix {};
|
||||
collectd = handleTest ./collectd.nix {};
|
||||
connman = handleTest ./connman.nix {};
|
||||
@@ -280,7 +278,6 @@ in {
|
||||
fsck = handleTest ./fsck.nix {};
|
||||
fsck-systemd-stage-1 = handleTest ./fsck.nix { systemdStage1 = true; };
|
||||
ft2-clone = handleTest ./ft2-clone.nix {};
|
||||
legit = handleTest ./legit.nix {};
|
||||
mimir = handleTest ./mimir.nix {};
|
||||
garage = handleTest ./garage {};
|
||||
gemstash = handleTest ./gemstash.nix {};
|
||||
@@ -524,7 +521,6 @@ in {
|
||||
nginx-sandbox = handleTestOn ["x86_64-linux"] ./nginx-sandbox.nix {};
|
||||
nginx-sso = handleTest ./nginx-sso.nix {};
|
||||
nginx-variants = handleTest ./nginx-variants.nix {};
|
||||
nginx-proxyprotocol = handleTest ./nginx-proxyprotocol {};
|
||||
nifi = handleTestOn ["x86_64-linux"] ./web-apps/nifi.nix {};
|
||||
nitter = handleTest ./nitter.nix {};
|
||||
nix-ld = handleTest ./nix-ld.nix {};
|
||||
@@ -559,7 +555,6 @@ in {
|
||||
openstack-image-userdata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).userdata or {};
|
||||
opentabletdriver = handleTest ./opentabletdriver.nix {};
|
||||
owncast = handleTest ./owncast.nix {};
|
||||
outline = handleTest ./outline.nix {};
|
||||
image-contents = handleTest ./image-contents.nix {};
|
||||
openvscode-server = handleTest ./openvscode-server.nix {};
|
||||
orangefs = handleTest ./orangefs.nix {};
|
||||
@@ -614,7 +609,6 @@ in {
|
||||
postfix-raise-smtpd-tls-security-level = handleTest ./postfix-raise-smtpd-tls-security-level.nix {};
|
||||
postfixadmin = handleTest ./postfixadmin.nix {};
|
||||
postgis = handleTest ./postgis.nix {};
|
||||
apache_datasketches = handleTest ./apache_datasketches.nix {};
|
||||
postgresql = handleTest ./postgresql.nix {};
|
||||
postgresql-jit = handleTest ./postgresql-jit.nix {};
|
||||
postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {};
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||
name = "postgis";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ lsix ]; # TODO: Who's the maintener now?
|
||||
};
|
||||
|
||||
nodes = {
|
||||
master =
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
services.postgresql = let mypg = pkgs.postgresql_15; in {
|
||||
enable = true;
|
||||
package = mypg;
|
||||
extraPlugins = with mypg.pkgs; [
|
||||
apache_datasketches
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
master.wait_for_unit("postgresql")
|
||||
master.sleep(10) # Hopefully this is long enough!!
|
||||
master.succeed("sudo -u postgres psql -c 'CREATE EXTENSION datasketches;'")
|
||||
master.succeed("sudo -u postgres psql -c 'SELECT hll_sketch_to_string(hll_sketch_build(1));'")
|
||||
'';
|
||||
})
|
||||
@@ -3,7 +3,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||
|
||||
meta.maintainers = lib.teams.cinnamon.members;
|
||||
|
||||
nodes.machine = { ... }: {
|
||||
nodes.machine = { nodes, ... }: {
|
||||
imports = [ ./common/user-account.nix ];
|
||||
services.xserver.enable = true;
|
||||
services.xserver.desktopManager.cinnamon.enable = true;
|
||||
@@ -13,7 +13,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||
|
||||
testScript = { nodes, ... }:
|
||||
let
|
||||
user = nodes.machine.users.users.alice;
|
||||
user = nodes.machine.config.users.users.alice;
|
||||
uid = toString user.uid;
|
||||
bus = "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${uid}/bus";
|
||||
display = "DISPLAY=:0.0";
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import ./make-test-python.nix ({pkgs, lib, ...}:
|
||||
{
|
||||
name = "code-server";
|
||||
|
||||
nodes = {
|
||||
machine = {pkgs, ...}: {
|
||||
services.code-server = {
|
||||
enable = true;
|
||||
auth = "none";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_for_unit("code-server.service")
|
||||
machine.wait_for_open_port(4444)
|
||||
machine.succeed("curl -k --fail http://localhost:4444", timeout=10)
|
||||
'';
|
||||
|
||||
meta.maintainers = [ lib.maintainers.drupol ];
|
||||
})
|
||||
@@ -53,7 +53,7 @@ import ./make-test-python.nix ({ pkgs, ... } : let
|
||||
[ v3_req ]
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = serverAuth, clientAuth
|
||||
extendedKeyUsage = serverAuth
|
||||
subjectAltName = @alt_names
|
||||
[alt_names]
|
||||
DNS.1 = node1
|
||||
@@ -79,26 +79,23 @@ import ./make-test-python.nix ({ pkgs, ... } : let
|
||||
keyFile = etcd_key;
|
||||
certFile = etcd_cert;
|
||||
trustedCaFile = ca_pem;
|
||||
clientCertAuth = true;
|
||||
peerClientCertAuth = true;
|
||||
listenClientUrls = ["https://127.0.0.1:2379"];
|
||||
listenPeerUrls = ["https://0.0.0.0:2380"];
|
||||
};
|
||||
};
|
||||
|
||||
environment.variables = {
|
||||
ETCD_CERT_FILE = "${etcd_client_cert}";
|
||||
ETCD_KEY_FILE = "${etcd_client_key}";
|
||||
ETCD_CA_FILE = "${ca_pem}";
|
||||
ETCDCTL_ENDPOINTS = "https://127.0.0.1:2379";
|
||||
ETCDCTL_CACERT = "${ca_pem}";
|
||||
ETCDCTL_CERT = "${etcd_cert}";
|
||||
ETCDCTL_KEY = "${etcd_key}";
|
||||
ETCDCTL_CERT_FILE = "${etcd_client_cert}";
|
||||
ETCDCTL_KEY_FILE = "${etcd_client_key}";
|
||||
ETCDCTL_CA_FILE = "${ca_pem}";
|
||||
ETCDCTL_PEERS = "https://127.0.0.1:2379";
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 2380 ];
|
||||
};
|
||||
in {
|
||||
name = "etcd-cluster";
|
||||
name = "etcd";
|
||||
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ offline ];
|
||||
@@ -137,21 +134,21 @@ in {
|
||||
node2.start()
|
||||
node1.wait_for_unit("etcd.service")
|
||||
node2.wait_for_unit("etcd.service")
|
||||
node2.wait_until_succeeds("etcdctl endpoint status")
|
||||
node1.succeed("etcdctl put /foo/bar 'Hello world'")
|
||||
node2.wait_until_succeeds("etcdctl cluster-health")
|
||||
node1.succeed("etcdctl set /foo/bar 'Hello world'")
|
||||
node2.succeed("etcdctl get /foo/bar | grep 'Hello world'")
|
||||
|
||||
with subtest("should add another member"):
|
||||
node1.wait_until_succeeds("etcdctl member add node3 --peer-urls=https://node3:2380")
|
||||
node1.wait_until_succeeds("etcdctl member add node3 https://node3:2380")
|
||||
node3.start()
|
||||
node3.wait_for_unit("etcd.service")
|
||||
node3.wait_until_succeeds("etcdctl member list | grep 'node3'")
|
||||
node3.succeed("etcdctl endpoint status")
|
||||
node3.succeed("etcdctl cluster-health")
|
||||
|
||||
with subtest("should survive member crash"):
|
||||
node3.crash()
|
||||
node1.succeed("etcdctl endpoint status")
|
||||
node1.succeed("etcdctl put /foo/bar 'Hello degraded world'")
|
||||
node1.succeed("etcdctl cluster-health")
|
||||
node1.succeed("etcdctl set /foo/bar 'Hello degraded world'")
|
||||
node1.succeed("etcdctl get /foo/bar | grep 'Hello degraded world'")
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -19,7 +19,7 @@ import ./make-test-python.nix ({ pkgs, ... } : {
|
||||
node.wait_for_unit("etcd.service")
|
||||
|
||||
with subtest("should write and read some values to etcd"):
|
||||
node.succeed("etcdctl put /foo/bar 'Hello world'")
|
||||
node.succeed("etcdctl set /foo/bar 'Hello world'")
|
||||
node.succeed("etcdctl get /foo/bar | grep 'Hello world'")
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -19,13 +19,13 @@ let
|
||||
aliceUsername = "alice";
|
||||
aliceUserId = "2";
|
||||
alicePassword = "R5twyCgU0uXC71wT9BBTCqLs6HFZ7h3L";
|
||||
aliceProjectId = "1";
|
||||
aliceProjectId = "2";
|
||||
aliceProjectName = "test-alice";
|
||||
|
||||
bobUsername = "bob";
|
||||
bobUserId = "3";
|
||||
bobPassword = "XwkkBbl2SiIwabQzgcoaTbhsotijEEtF";
|
||||
bobProjectId = "2";
|
||||
bobProjectId = "3";
|
||||
in {
|
||||
name = "gitlab";
|
||||
meta.maintainers = with lib.maintainers; [ globin yayayayaka ];
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
simpleUefiGrub
|
||||
simpleUefiGrubSpecialisation
|
||||
simpleUefiSystemdBoot
|
||||
stratisRoot
|
||||
# swraid
|
||||
zfsroot
|
||||
;
|
||||
|
||||
@@ -989,39 +989,4 @@ in {
|
||||
)
|
||||
'';
|
||||
};
|
||||
} // optionalAttrs systemdStage1 {
|
||||
stratisRoot = makeInstallerTest "stratisRoot" {
|
||||
createPartitions = ''
|
||||
machine.succeed(
|
||||
"sgdisk --zap-all /dev/vda",
|
||||
"sgdisk --new=1:0:+100M --typecode=0:ef00 /dev/vda", # /boot
|
||||
"sgdisk --new=2:0:+1G --typecode=0:8200 /dev/vda", # swap
|
||||
"sgdisk --new=3:0:+5G --typecode=0:8300 /dev/vda", # /
|
||||
"udevadm settle",
|
||||
|
||||
"mkfs.vfat /dev/vda1",
|
||||
"mkswap /dev/vda2 -L swap",
|
||||
"swapon -L swap",
|
||||
"stratis pool create my-pool /dev/vda3",
|
||||
"stratis filesystem create my-pool nixos",
|
||||
"udevadm settle",
|
||||
|
||||
"mount /dev/stratis/my-pool/nixos /mnt",
|
||||
"mkdir -p /mnt/boot",
|
||||
"mount /dev/vda1 /mnt/boot"
|
||||
)
|
||||
'';
|
||||
bootLoader = "systemd-boot";
|
||||
extraInstallerConfig = { modulesPath, ...}: {
|
||||
config = {
|
||||
services.stratis.enable = true;
|
||||
environment.systemPackages = [
|
||||
pkgs.stratis-cli
|
||||
pkgs.thin-provisioning-tools
|
||||
pkgs.lvm2.bin
|
||||
pkgs.stratisd.initrd
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,27 +63,12 @@ import ./make-test-python.nix ({ pkgs, ... }:
|
||||
''
|
||||
start_all()
|
||||
server.wait_for_unit("kanidm.service")
|
||||
|
||||
with subtest("Test HTTP interface"):
|
||||
server.wait_until_succeeds("curl -sf https://${serverDomain} | grep Kanidm")
|
||||
|
||||
with subtest("Test LDAP interface"):
|
||||
server.succeed("ldapsearch -H ldaps://${serverDomain}:636 -b '${ldapBaseDN}' -x '(name=test)'")
|
||||
|
||||
with subtest("Test CLI login"):
|
||||
client.succeed("kanidm login -D anonymous")
|
||||
client.succeed("kanidm self whoami | grep anonymous@${serverDomain}")
|
||||
|
||||
with subtest("Recover idm_admin account"):
|
||||
# Must stop the server for account recovery or else kanidmd fails with
|
||||
# "unable to lock kanidm exclusive lock at /var/lib/kanidm/kanidm.db.klock".
|
||||
server.succeed("systemctl stop kanidm")
|
||||
server.succeed("su - kanidm -c 'kanidmd recover-account -c ${serverConfigFile} idm_admin 2>&1 | rg -o \'[A-Za-z0-9]{48}\' '")
|
||||
server.succeed("systemctl start kanidm")
|
||||
|
||||
with subtest("Test unixd connection"):
|
||||
client.wait_for_unit("kanidm-unixd.service")
|
||||
# TODO: client.wait_for_file("/run/kanidm-unixd/sock")
|
||||
client.wait_until_succeeds("kanidm-unix status | grep working!")
|
||||
server.wait_until_succeeds("curl -sf https://${serverDomain} | grep Kanidm")
|
||||
server.succeed("ldapsearch -H ldaps://${serverDomain}:636 -b '${ldapBaseDN}' -x '(name=test)'")
|
||||
client.succeed("kanidm login -D anonymous && kanidm self whoami | grep anonymous@${serverDomain}")
|
||||
rv, result = server.execute("kanidmd recover_account -c ${serverConfigFile} idm_admin 2>&1 | rg -o '[A-Za-z0-9]{48}'")
|
||||
assert rv == 0
|
||||
client.wait_for_unit("kanidm-unixd.service")
|
||||
client.succeed("kanidm_unixd_status | grep working!")
|
||||
'';
|
||||
})
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import ./make-test-python.nix ({ lib, pkgs, ... }:
|
||||
let
|
||||
port = 5000;
|
||||
scanPath = "/var/lib/legit";
|
||||
in
|
||||
{
|
||||
name = "legit-web";
|
||||
meta.maintainers = [ lib.maintainers.ratsclub ];
|
||||
|
||||
nodes = {
|
||||
server = { config, pkgs }: {
|
||||
services.legit = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server.port = 5000;
|
||||
repo = { inherit scanPath; };
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ pkgs.git ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = { nodes, ... }:
|
||||
let
|
||||
strPort = builtins.toString port;
|
||||
in
|
||||
''
|
||||
start_all()
|
||||
|
||||
server.wait_for_unit("network.target")
|
||||
server.wait_for_unit("legit.service")
|
||||
|
||||
server.wait_until_succeeds(
|
||||
"curl -f http://localhost:${strPort}"
|
||||
)
|
||||
|
||||
server.succeed("${pkgs.writeShellScript "setup-legit-test-repo" ''
|
||||
set -e
|
||||
git init --bare -b master ${scanPath}/some-repo
|
||||
git init -b master reference
|
||||
cd reference
|
||||
git remote add origin ${scanPath}/some-repo
|
||||
date > date.txt
|
||||
git add date.txt
|
||||
git -c user.name=test -c user.email=test@localhost commit -m 'add date'
|
||||
git push -u origin master
|
||||
''}")
|
||||
|
||||
server.wait_until_succeeds(
|
||||
"curl -f http://localhost:${strPort}/some-repo"
|
||||
)
|
||||
'';
|
||||
})
|
||||
@@ -27,8 +27,6 @@ import ./make-test-python.nix (
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
import os
|
||||
|
||||
start_all()
|
||||
|
||||
# Create a fake cache with Nginx service the static files
|
||||
|
||||
@@ -93,19 +93,18 @@ let
|
||||
name = "Static";
|
||||
nodes.router = router;
|
||||
nodes.client = { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.interfaces.enp2s0.vlan = 2;
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
defaultGateway = "192.168.1.1";
|
||||
defaultGateway6 = "fd00:1234:5678:1::1";
|
||||
interfaces.enp1s0.ipv4.addresses = [
|
||||
interfaces.eth1.ipv4.addresses = mkOverride 0 [
|
||||
{ address = "192.168.1.2"; prefixLength = 24; }
|
||||
{ address = "192.168.1.3"; prefixLength = 32; }
|
||||
{ address = "192.168.1.10"; prefixLength = 32; }
|
||||
];
|
||||
interfaces.enp2s0.ipv4.addresses = [
|
||||
interfaces.eth2.ipv4.addresses = mkOverride 0 [
|
||||
{ address = "192.168.2.2"; prefixLength = 24; }
|
||||
];
|
||||
};
|
||||
@@ -171,12 +170,12 @@ let
|
||||
# Disable test driver default config
|
||||
networking.interfaces = lib.mkForce {};
|
||||
networking.useNetworkd = networkd;
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
client.wait_for_unit("multi-user.target")
|
||||
client.wait_until_succeeds("ip addr show dev enp1s0 | grep '192.168.1'")
|
||||
client.wait_until_succeeds("ip addr show dev eth1 | grep '192.168.1'")
|
||||
client.shell_interact()
|
||||
client.succeed("ping -c 1 192.168.1.1")
|
||||
router.succeed("ping -c 1 192.168.1.1")
|
||||
@@ -188,13 +187,20 @@ let
|
||||
name = "SimpleDHCP";
|
||||
nodes.router = router;
|
||||
nodes.client = { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.interfaces.enp2s0.vlan = 2;
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
interfaces.enp1s0.useDHCP = true;
|
||||
interfaces.enp2s0.useDHCP = true;
|
||||
interfaces.eth1 = {
|
||||
ipv4.addresses = mkOverride 0 [ ];
|
||||
ipv6.addresses = mkOverride 0 [ ];
|
||||
useDHCP = true;
|
||||
};
|
||||
interfaces.eth2 = {
|
||||
ipv4.addresses = mkOverride 0 [ ];
|
||||
ipv6.addresses = mkOverride 0 [ ];
|
||||
useDHCP = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
testScript = { ... }:
|
||||
@@ -205,10 +211,10 @@ let
|
||||
router.wait_for_unit("network-online.target")
|
||||
|
||||
with subtest("Wait until we have an ip address on each interface"):
|
||||
client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q '192.168.1'")
|
||||
client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q 'fd00:1234:5678:1:'")
|
||||
client.wait_until_succeeds("ip addr show dev enp2s0 | grep -q '192.168.2'")
|
||||
client.wait_until_succeeds("ip addr show dev enp2s0 | grep -q 'fd00:1234:5678:2:'")
|
||||
client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'")
|
||||
client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'")
|
||||
client.wait_until_succeeds("ip addr show dev eth2 | grep -q '192.168.2'")
|
||||
client.wait_until_succeeds("ip addr show dev eth2 | grep -q 'fd00:1234:5678:2:'")
|
||||
|
||||
with subtest("Test vlan 1"):
|
||||
client.wait_until_succeeds("ping -c 1 192.168.1.1")
|
||||
@@ -237,15 +243,16 @@ let
|
||||
name = "OneInterfaceDHCP";
|
||||
nodes.router = router;
|
||||
nodes.client = { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.interfaces.enp2s0.vlan = 2;
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
interfaces.enp1s0 = {
|
||||
interfaces.eth1 = {
|
||||
ipv4.addresses = mkOverride 0 [ ];
|
||||
mtu = 1343;
|
||||
useDHCP = true;
|
||||
};
|
||||
interfaces.eth2.ipv4.addresses = mkOverride 0 [ ];
|
||||
};
|
||||
};
|
||||
testScript = { ... }:
|
||||
@@ -257,10 +264,10 @@ let
|
||||
router.wait_for_unit("network.target")
|
||||
|
||||
with subtest("Wait until we have an ip address on each interface"):
|
||||
client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q '192.168.1'")
|
||||
client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'")
|
||||
|
||||
with subtest("ensure MTU is set"):
|
||||
assert "mtu 1343" in client.succeed("ip link show dev enp1s0")
|
||||
assert "mtu 1343" in client.succeed("ip link show dev eth1")
|
||||
|
||||
with subtest("Test vlan 1"):
|
||||
client.wait_until_succeeds("ping -c 1 192.168.1.1")
|
||||
@@ -279,15 +286,16 @@ let
|
||||
};
|
||||
bond = let
|
||||
node = address: { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.interfaces.enp2s0.vlan = 2;
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
bonds.bond0 = {
|
||||
interfaces = [ "enp1s0" "enp2s0" ];
|
||||
interfaces = [ "eth1" "eth2" ];
|
||||
driverOptions.mode = "802.3ad";
|
||||
};
|
||||
interfaces.eth1.ipv4.addresses = mkOverride 0 [ ];
|
||||
interfaces.eth2.ipv4.addresses = mkOverride 0 [ ];
|
||||
interfaces.bond0.ipv4.addresses = mkOverride 0
|
||||
[ { inherit address; prefixLength = 30; } ];
|
||||
};
|
||||
@@ -318,11 +326,12 @@ let
|
||||
};
|
||||
bridge = let
|
||||
node = { address, vlan }: { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = vlan;
|
||||
virtualisation.vlans = [ vlan ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
interfaces.enp1s0.ipv4.addresses = [ { inherit address; prefixLength = 24; } ];
|
||||
interfaces.eth1.ipv4.addresses = mkOverride 0
|
||||
[ { inherit address; prefixLength = 24; } ];
|
||||
};
|
||||
};
|
||||
in {
|
||||
@@ -330,12 +339,11 @@ let
|
||||
nodes.client1 = node { address = "192.168.1.2"; vlan = 1; };
|
||||
nodes.client2 = node { address = "192.168.1.3"; vlan = 2; };
|
||||
nodes.router = { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.interfaces.enp2s0.vlan = 2;
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
bridges.bridge.interfaces = [ "enp1s0" "enp2s0" ];
|
||||
bridges.bridge.interfaces = [ "eth1" "eth2" ];
|
||||
interfaces.eth1.ipv4.addresses = mkOverride 0 [ ];
|
||||
interfaces.eth2.ipv4.addresses = mkOverride 0 [ ];
|
||||
interfaces.bridge.ipv4.addresses = mkOverride 0
|
||||
@@ -369,7 +377,7 @@ let
|
||||
nodes.router = router;
|
||||
nodes.client = { pkgs, ... }: with pkgs.lib; {
|
||||
environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
@@ -377,9 +385,14 @@ let
|
||||
# reverse path filtering rules for the macvlan interface seem
|
||||
# to be incorrect, causing the test to fail. Disable temporarily.
|
||||
firewall.checkReversePath = false;
|
||||
macvlans.macvlan.interface = "enp1s0";
|
||||
interfaces.enp1s0.useDHCP = true;
|
||||
interfaces.macvlan.useDHCP = true;
|
||||
macvlans.macvlan.interface = "eth1";
|
||||
interfaces.eth1 = {
|
||||
ipv4.addresses = mkOverride 0 [ ];
|
||||
useDHCP = true;
|
||||
};
|
||||
interfaces.macvlan = {
|
||||
useDHCP = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
testScript = { ... }:
|
||||
@@ -391,7 +404,7 @@ let
|
||||
router.wait_for_unit("network.target")
|
||||
|
||||
with subtest("Wait until we have an ip address on each interface"):
|
||||
client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q '192.168.1'")
|
||||
client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'")
|
||||
client.wait_until_succeeds("ip addr show dev macvlan | grep -q '192.168.1'")
|
||||
|
||||
with subtest("Print lots of diagnostic information"):
|
||||
@@ -418,22 +431,23 @@ let
|
||||
fou = {
|
||||
name = "foo-over-udp";
|
||||
nodes.machine = { ... }: {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
interfaces.enp1s0.ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
|
||||
interfaces.eth1.ipv4.addresses = mkOverride 0
|
||||
[ { address = "192.168.1.1"; prefixLength = 24; } ];
|
||||
fooOverUDP = {
|
||||
fou1 = { port = 9001; };
|
||||
fou2 = { port = 9002; protocol = 41; };
|
||||
fou3 = mkIf (!networkd)
|
||||
{ port = 9003; local.address = "192.168.1.1"; };
|
||||
fou4 = mkIf (!networkd)
|
||||
{ port = 9004; local = { address = "192.168.1.1"; dev = "enp1s0"; }; };
|
||||
{ port = 9004; local = { address = "192.168.1.1"; dev = "eth1"; }; };
|
||||
};
|
||||
};
|
||||
systemd.services = {
|
||||
fou3-fou-encap.after = optional (!networkd) "network-addresses-enp1s0.service";
|
||||
fou3-fou-encap.after = optional (!networkd) "network-addresses-eth1.service";
|
||||
};
|
||||
};
|
||||
testScript = { ... }:
|
||||
@@ -456,22 +470,22 @@ let
|
||||
"gue": None,
|
||||
"family": "inet",
|
||||
"local": "192.168.1.1",
|
||||
"dev": "enp1s0",
|
||||
"dev": "eth1",
|
||||
} in fous, "fou4 exists"
|
||||
'';
|
||||
};
|
||||
sit = let
|
||||
node = { address4, remote, address6 }: { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
sits.sit = {
|
||||
inherit remote;
|
||||
local = address4;
|
||||
dev = "enp1s0";
|
||||
dev = "eth1";
|
||||
};
|
||||
interfaces.enp1s0.ipv4.addresses = mkOverride 0
|
||||
interfaces.eth1.ipv4.addresses = mkOverride 0
|
||||
[ { address = address4; prefixLength = 24; } ];
|
||||
interfaces.sit.ipv6.addresses = mkOverride 0
|
||||
[ { address = address6; prefixLength = 64; } ];
|
||||
@@ -671,10 +685,10 @@ let
|
||||
vlan-ping = let
|
||||
baseIP = number: "10.10.10.${number}";
|
||||
vlanIP = number: "10.1.1.${number}";
|
||||
baseInterface = "enp1s0";
|
||||
baseInterface = "eth1";
|
||||
vlanInterface = "vlan42";
|
||||
node = number: {pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking = {
|
||||
#useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
@@ -771,12 +785,12 @@ let
|
||||
privacy = {
|
||||
name = "Privacy";
|
||||
nodes.router = { ... }: {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true;
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
interfaces.enp1s0.ipv6.addresses = singleton {
|
||||
interfaces.eth1.ipv6.addresses = singleton {
|
||||
address = "fd00:1234:5678:1::1";
|
||||
prefixLength = 64;
|
||||
};
|
||||
@@ -784,7 +798,7 @@ let
|
||||
services.radvd = {
|
||||
enable = true;
|
||||
config = ''
|
||||
interface enp1s0 {
|
||||
interface eth1 {
|
||||
AdvSendAdvert on;
|
||||
AdvManagedFlag on;
|
||||
AdvOtherConfigFlag on;
|
||||
@@ -798,11 +812,11 @@ let
|
||||
};
|
||||
};
|
||||
nodes.client_with_privacy = { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
interfaces.enp1s0 = {
|
||||
interfaces.eth1 = {
|
||||
tempAddress = "default";
|
||||
ipv4.addresses = mkOverride 0 [ ];
|
||||
ipv6.addresses = mkOverride 0 [ ];
|
||||
@@ -811,11 +825,11 @@ let
|
||||
};
|
||||
};
|
||||
nodes.client = { pkgs, ... }: with pkgs.lib; {
|
||||
virtualisation.interfaces.enp1s0.vlan = 1;
|
||||
virtualisation.vlans = [ 1 ];
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
interfaces.enp1s0 = {
|
||||
interfaces.eth1 = {
|
||||
tempAddress = "enabled";
|
||||
ipv4.addresses = mkOverride 0 [ ];
|
||||
ipv6.addresses = mkOverride 0 [ ];
|
||||
@@ -833,9 +847,9 @@ let
|
||||
|
||||
with subtest("Wait until we have an ip address"):
|
||||
client_with_privacy.wait_until_succeeds(
|
||||
"ip addr show dev enp1s0 | grep -q 'fd00:1234:5678:1:'"
|
||||
"ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'"
|
||||
)
|
||||
client.wait_until_succeeds("ip addr show dev enp1s0 | grep -q 'fd00:1234:5678:1:'")
|
||||
client.wait_until_succeeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'")
|
||||
|
||||
with subtest("Test vlan 1"):
|
||||
client_with_privacy.wait_until_succeeds("ping -c 1 fd00:1234:5678:1::1")
|
||||
@@ -933,7 +947,7 @@ let
|
||||
), "The IPv6 routing table has not been properly cleaned:\n{}".format(ipv6Residue)
|
||||
'';
|
||||
};
|
||||
rename = if networkd then {
|
||||
rename = {
|
||||
name = "RenameInterface";
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
virtualisation.vlans = [ 1 ];
|
||||
@@ -941,20 +955,23 @@ let
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
};
|
||||
systemd.network.links."10-custom_name" = {
|
||||
matchConfig.MACAddress = "52:54:00:12:01:01";
|
||||
linkConfig.Name = "custom_name";
|
||||
};
|
||||
};
|
||||
} //
|
||||
(if networkd
|
||||
then { systemd.network.links."10-custom_name" = {
|
||||
matchConfig.MACAddress = "52:54:00:12:01:01";
|
||||
linkConfig.Name = "custom_name";
|
||||
};
|
||||
}
|
||||
else { boot.initrd.services.udev.rules = ''
|
||||
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="52:54:00:12:01:01", KERNEL=="eth*", NAME="custom_name"
|
||||
'';
|
||||
});
|
||||
testScript = ''
|
||||
machine.succeed("udevadm settle")
|
||||
print(machine.succeed("ip link show dev custom_name"))
|
||||
'';
|
||||
} else {
|
||||
name = "RenameInterface";
|
||||
nodes = { };
|
||||
testScript = "";
|
||||
};
|
||||
nodes = { };
|
||||
# even with disabled networkd, systemd.network.links should work
|
||||
# (as it's handled by udev, not networkd)
|
||||
link = {
|
||||
@@ -998,46 +1015,6 @@ let
|
||||
machine.fail("ip address show wlan0 | grep -q ${testMac}")
|
||||
'';
|
||||
};
|
||||
naughtyInterfaceNames = let
|
||||
ifnames = [
|
||||
# flags of ip-address
|
||||
"home" "temporary" "optimistic"
|
||||
"bridge_slave" "flush"
|
||||
# flags of ip-route
|
||||
"up" "type" "nomaster" "address"
|
||||
# other
|
||||
"very_loong_name" "lowerUpper" "-"
|
||||
];
|
||||
in {
|
||||
name = "naughtyInterfaceNames";
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
networking.useNetworkd = networkd;
|
||||
networking.bridges = listToAttrs
|
||||
(flip map ifnames
|
||||
(name: { inherit name; value.interfaces = []; }));
|
||||
};
|
||||
testScript = ''
|
||||
machine.start()
|
||||
machine.wait_for_unit("network.target")
|
||||
for ifname in ${builtins.toJSON ifnames}:
|
||||
machine.wait_until_succeeds(f"ip link show dev '{ifname}' | grep -q '{ifname}'")
|
||||
'';
|
||||
};
|
||||
caseSensitiveRenaming = {
|
||||
name = "CaseSensitiveRenaming";
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
virtualisation.interfaces.enCustom.vlan = 11;
|
||||
networking = {
|
||||
useNetworkd = networkd;
|
||||
useDHCP = false;
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
machine.succeed("udevadm settle")
|
||||
print(machine.succeed("ip link show dev enCustom"))
|
||||
machine.wait_until_succeeds("ip link show dev enCustom | grep -q '52:54:00:12:0b:01")
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
in mapAttrs (const (attrs: makeTest (attrs // {
|
||||
|
||||
@@ -76,19 +76,19 @@ in
|
||||
server.wait_for_open_port(443)
|
||||
|
||||
# Check http connections
|
||||
client.succeed("curl --verbose --http3-only https://acme.test | grep 'Hello World!'")
|
||||
client.succeed("curl --verbose --http3 https://acme.test | grep 'Hello World!'")
|
||||
|
||||
# Check downloadings
|
||||
client.succeed("curl --verbose --http3-only https://acme.test/example.txt --output /tmp/example.txt")
|
||||
client.succeed("curl --verbose --http3 https://acme.test/example.txt --output /tmp/example.txt")
|
||||
client.succeed("cat /tmp/example.txt | grep 'Check http3 protocol.'")
|
||||
|
||||
# Check header reading
|
||||
client.succeed("curl --verbose --http3-only --head https://acme.test | grep 'content-type'")
|
||||
client.succeed("curl --verbose --http3-only --head https://acme.test | grep 'HTTP/3 200'")
|
||||
client.succeed("curl --verbose --http3-only --head https://acme.test/error | grep 'HTTP/3 404'")
|
||||
client.succeed("curl --verbose --http3 --head https://acme.test | grep 'content-type'")
|
||||
client.succeed("curl --verbose --http3 --head https://acme.test | grep 'HTTP/3 200'")
|
||||
client.succeed("curl --verbose --http3 --head https://acme.test/error | grep 'HTTP/3 404'")
|
||||
|
||||
# Check change User-Agent
|
||||
client.succeed("curl --verbose --http3-only --user-agent 'Curl test 3.0' https://acme.test")
|
||||
client.succeed("curl --verbose --http3 --user-agent 'Curl test 3.0' https://acme.test")
|
||||
server.succeed("cat /var/log/nginx/access.log | grep 'Curl test 3.0'")
|
||||
|
||||
server.shutdown()
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDLjCCAhagAwIBAgIIP2+4GFxOYMgwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgNGU3NTJiMB4XDTIzMDEzMDAzNDExOFoXDTQzMDEz
|
||||
MDAzNDExOFowFTETMBEGA1UEAwwKKi50ZXN0Lm5peDCCASIwDQYJKoZIhvcNAQEB
|
||||
BQADggEPADCCAQoCggEBAMarJSCzelnzTMT5GMoIKA/MXBNk5j277uI2Gq2MCky/
|
||||
DlBpx+tjSsKsz6QLBduKMF8OH5AgjrVAKQAtsVPDseY0Qcyx/5dgJjkdO4on+DFb
|
||||
V0SJ3ZhYPKACrqQ1SaoG+Xup37puw7sVR13J7oNvP6fAYRcjYqCiFC7VMjJNG4dR
|
||||
251jvWWidSc7v5CYw2AxrngtBgHeQuyG9QCJ1DRH8h6ioV7IeonwReN7noYtTWh8
|
||||
NDjGnw9HH2nYMcL91E+DWCxWVmbC9/orvYOT7u0Orho0t1w9BB0/zzcdojwQpMCv
|
||||
HahEmFQmdGbWTuI4caBeaDBJVsSwKlTcxLSS4MAZ0c8CAwEAAaN3MHUwDgYDVR0P
|
||||
AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
|
||||
Af8EAjAAMB8GA1UdIwQYMBaAFGyXySYI3gL88d7GHnGMU6wpiBf2MBUGA1UdEQQO
|
||||
MAyCCioudGVzdC5uaXgwDQYJKoZIhvcNAQELBQADggEBAJ/DpwiLVBgWyozsn++f
|
||||
kR4m0dUjnuCgpHo2EMoMZh+9og+OC0vq6WITXHaJytB3aBMxFOUTim3vwxPyWPXX
|
||||
/vy+q6jJ6QMLx1J3VIWZdmXsT+qLGbVzL/4gNoaRsLPGO06p3yVjhas+OBFx1Fee
|
||||
6kTHb82S/dzBojOJLRRo18CU9yw0FUXOPqN7HF7k2y+Twe6+iwCuCKGSFcvmRjxe
|
||||
bWy11C921bTienW0Rmq6ppFWDaUNYP8kKpMN2ViAvc0tyF6wwk5lyOiqCR+pQHJR
|
||||
H/J4qSeKDchYLKECuzd6SySz8FW/xPKogQ28zba+DBD86hpqiEJOBzxbrcN3cjUn
|
||||
7N4=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAxqslILN6WfNMxPkYyggoD8xcE2TmPbvu4jYarYwKTL8OUGnH
|
||||
62NKwqzPpAsF24owXw4fkCCOtUApAC2xU8Ox5jRBzLH/l2AmOR07iif4MVtXRInd
|
||||
mFg8oAKupDVJqgb5e6nfum7DuxVHXcnug28/p8BhFyNioKIULtUyMk0bh1HbnWO9
|
||||
ZaJ1Jzu/kJjDYDGueC0GAd5C7Ib1AInUNEfyHqKhXsh6ifBF43uehi1NaHw0OMaf
|
||||
D0cfadgxwv3UT4NYLFZWZsL3+iu9g5Pu7Q6uGjS3XD0EHT/PNx2iPBCkwK8dqESY
|
||||
VCZ0ZtZO4jhxoF5oMElWxLAqVNzEtJLgwBnRzwIDAQABAoIBAFuNGOH184cqKJGI
|
||||
3RSVJ6kIGtJRKA0A4vfZyPd61nBBhx4lcRyXOCd4LYPCFKP0DZBwWLk5V6pM89gC
|
||||
NnqMbxnPsRbcXBVtGJAvWXW0L5rHJfMOuVBwMRfnxIUljVnONv/264PlcUtwZd/h
|
||||
o4lsJeBvNg7MnrG5nyVp1+T4RZxYm1P86HLp5zyT+fdj4Cr82b9j6QpxGXEfm1jV
|
||||
QA1xr1ZkrV8fgETyaE0TBIKcdt6xNfv1mpI1RE5gaP/YzcCs/mL+G0kMar4l7pO/
|
||||
6OHXTvHz+W3G6Xlha7Wq1ADoqYz2K7VoL/OgSQhIxRNujyWR6lir7eladVrKkCzu
|
||||
uzFi/HECgYEA0vSNCIK3useSypMPHhYUVNbZ4hbK0WgqSAxfJQtL3nC7KviVMAXj
|
||||
IKVR90xuzJB+ih88KCJpH84JH90paMpW0Gq1yEae90bnWa8Nj7ULLS/Zuj0WrelU
|
||||
+DEGbx47IUPOtiLBxooxFKyIVhX3hWRwZ0pokSQzbgb5zYnlM6tqZ3cCgYEA8Rb2
|
||||
wtt0XmqEQedFacs4fobJoVWMcETjpuxYp0m5Kje/4QkptZIbspXGBgNtPBBRGg51
|
||||
AYSu8wYkGEueI77KiFDgY8AAkpOk2MrMVPszjOhUiO1oEfbT6ynOY5RDOuXcY6jo
|
||||
8RpSk46VkfVxt6LVmappqcVFtVWcAjdGfXeSLmkCgYAWP7SgMSkvidzxgJEXmzyJ
|
||||
th9EuSKq81GCR8vBHG/kBf+3iIAzkGtkBgufCXCmIpc1+hVeJkLwF8rekXTMmIqP
|
||||
cLG7bbdWXSQJUW0cuvtyyJkuC0NZFELh6knDbmzOFVi33PKS/gAvLgMzER4J843n
|
||||
VvGwXSEPeazfAKwrxuhyAQKBgQCOm5TPYlyNVNhy20h18d2zCivOoPn3luhKXtd5
|
||||
7OP4kw2PIYpoesqjcnC2MeS1eLlgfli70y5hVqqXLHOYlUzcIWr51iMAkREbo6oG
|
||||
QqkVmoAWlsfOiICGRC5vPM4f0sPwt4NCyt05p0fWFKd1hn5u7Ryfba90OfWUYfny
|
||||
UX5IsQKBgQCswer4Qc3UepkiYxGwSTxgIh4kYlmamU2I00Kar4uFAr9JsCbk98f0
|
||||
kaCUNZjrrvTwgRmdhwcpMDiMW/F4QkNk0I2unHcoAvzNop6c22VhHJU2XJhrQ57h
|
||||
n1iPiw0NLXiA4RQwMUMjtt3nqlpLOTXGtsF8TmpWPcAN2QcTxOutzw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -1,20 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDSzCCAjOgAwIBAgIITnUr3xFw4oEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgNGU3NTJiMCAXDTIzMDEzMDAzNDExOFoYDzIxMjMw
|
||||
MTMwMDM0MTE4WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSA0ZTc1MmIwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1SrJT9k3zXIXApEyL5UDlw7F6
|
||||
MMOqE5d+8ZwMccHbEKLu0ssNRY+j31tnNYQ/r5iCNeNgUZccKBgzdU0ysyw5n4tw
|
||||
0y+MTD9fCfUXYcc8pJRPRolo6zxYO9W7WJr0nfJZ+p7zFRAjRCmzXdnZjKz0EGcg
|
||||
x9mHwn//3SuLt1ItK1n3aZ6im9NlcVtunDe3lCSL0tRgy7wDGNvWDZMO49jk4AFU
|
||||
BlMqScuiNpUzYgCxNaaGMuH3M0f0YyRAxSs6FWewLtqTIaVql7HL+3PcGAhvlKEZ
|
||||
fvfaf80F9aWI88sbEddTA0s5837zEoDwGpZl3K5sPU/O3MVEHIhAY5ICG0IBAgMB
|
||||
AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||
BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRsl8kmCN4C/PHe
|
||||
xh5xjFOsKYgX9jAfBgNVHSMEGDAWgBRsl8kmCN4C/PHexh5xjFOsKYgX9jANBgkq
|
||||
hkiG9w0BAQsFAAOCAQEAmvgpU+q+TBbz+9Y2rdiIeTfeDXtMNPf+nKI3zxYztRGC
|
||||
MoKP6jCQaFSQra4BVumFLV38DoqR1pOV1ojkiyO5c/9Iym/1Wmm8LeqgsHNqSgyS
|
||||
C7wvBcb/N9PzIBQFq/RiboDoC7bqK/0zQguCmBtGceH+AVpQyfXM+P78B1EkHozu
|
||||
67igP8GfouPp2s4Vd5P2XGkA6vMgYCtFEnCbtmmo7C8B+ymhD/D9axpMKQ1OaBg9
|
||||
jfqLOlk+Rc2nYZuaDjnUmlTkYjC6EwCNe9weYkSJgQ9QzoGJLIRARsdQdsp3C2fZ
|
||||
l2UZKkDJ2GPrrc+TdaGXZTYi0uMmvQsEKZXtqAzorQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAtUqyU/ZN81yFwKRMi+VA5cOxejDDqhOXfvGcDHHB2xCi7tLL
|
||||
DUWPo99bZzWEP6+YgjXjYFGXHCgYM3VNMrMsOZ+LcNMvjEw/Xwn1F2HHPKSUT0aJ
|
||||
aOs8WDvVu1ia9J3yWfqe8xUQI0Qps13Z2Yys9BBnIMfZh8J//90ri7dSLStZ92me
|
||||
opvTZXFbbpw3t5Qki9LUYMu8Axjb1g2TDuPY5OABVAZTKknLojaVM2IAsTWmhjLh
|
||||
9zNH9GMkQMUrOhVnsC7akyGlapexy/tz3BgIb5ShGX732n/NBfWliPPLGxHXUwNL
|
||||
OfN+8xKA8BqWZdyubD1PztzFRByIQGOSAhtCAQIDAQABAoIBAQCLeAWs1kWtvTYg
|
||||
t8UzspC0slItAKrmgt//hvxYDoPmdewC8yPG+AbDOSfmRKOTIxGeyro79UjdHnNP
|
||||
0yQqpvCU/AqYJ7/inR37jXuCG3TdUHfQbSF1F9N6xb1tvYKoQYKaelYiB8g8eUnj
|
||||
dYYM+U5tDNlpvJW6/YTfYFUJzWRo3i8jj5lhbkjcJDvdOhVxMXNXJgJAymu1KysE
|
||||
N1da2l4fzmuoN82wFE9KMyYSn+LOLWBReQQmXHZPP+2LjRIVrWoFoV49k2Ylp9tH
|
||||
yeaFx1Ya/wVx3PRnSW+zebWDcc0bAua9XU3Fi42yRq5iXOyoXHyefDfJoId7+GAO
|
||||
IF2qRw9hAoGBAM1O1l4ceOEDsEBh7HWTvmfwVfkXgT6VHeI6LGEjb88FApXgT+wT
|
||||
1s1IWVVOigLl9OKQbrjqlg9xgzrPDHYRwu5/Oz3X2WaH6wlF+d+okoqls6sCEAeo
|
||||
GfzF3sKOHQyIYjttCXE5G38uhIgVFFFfK97AbUiY8egYBr0zjVXK7xINAoGBAOIN
|
||||
1pDBFBQIoKj64opm/G9lJBLUpWLBFdWXhXS6q2jNsdY1mLMRmu/RBaKSfGz7W1a/
|
||||
a2WBedjcnTWJ/84tBsn4Qj5tLl8xkcXiN/pslWzg724ZnVsbyxM9KvAdXAma3F0g
|
||||
2EsYq8mhvbAEkpE+aoM6jwOJBnMhTRZrNMKN2lbFAoGAHmZWB4lfvLG3H1FgmehO
|
||||
gUVs9X0tff7GdgD3IUsF+zlasKaOLv6hB7R2xdLjTJqQMBwCyQ6zOYYtUD/oMHNg
|
||||
0b+1HesgHbZybuUVorBrQmxWtjOP/BJABtWlrlkso/Zt1S7H/yPdlm9k4GF+qK3W
|
||||
6RzFEcLTzvH/zXQcsV9jFuECgYEAhaX+1KiC0XFkY2OpaoCHAOlAUa3NdjyIRzcF
|
||||
XUU8MINkgCxB8qUXAHCJL1wCGoDluL0FpwbM3m1YuR200tYGLIUNzVDJ2Ng6wk8E
|
||||
H5fxJGU8ydB1Gzescdx5NWt2Tet0G89ecc/NSTHKL3YUnbDUUm/dvA5YdNscc4PA
|
||||
tsIdc60CgYEArvU1MwqGQUTDKUmaM2t3qm70fbwmOViHfyTWpn4aAQR3sK16iJMm
|
||||
V+dka62L/VYs5CIbzXvCioyugUMZGJi/zIwrViRzqJQbNnPADAW4lG88UxXqHHAH
|
||||
q33ivjgd9omGFb37saKOmR44KmjUIDvSIZF4W3EPwAMEyl5mM31Ryns=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -1,144 +0,0 @@
|
||||
let
|
||||
certs = import ./snakeoil-certs.nix;
|
||||
in
|
||||
import ../make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "nginx-proxyprotocol";
|
||||
|
||||
nodes = {
|
||||
webserver = { pkgs, lib, ... }: {
|
||||
environment.systemPackages = [ pkgs.netcat ];
|
||||
security.pki.certificateFiles = [
|
||||
certs.ca.cert
|
||||
];
|
||||
|
||||
networking.extraHosts = ''
|
||||
127.0.0.5 proxy.test.nix
|
||||
127.0.0.5 noproxy.test.nix
|
||||
127.0.0.3 direct-nossl.test.nix
|
||||
127.0.0.4 unsecure-nossl.test.nix
|
||||
127.0.0.2 direct-noproxy.test.nix
|
||||
127.0.0.1 direct-proxy.test.nix
|
||||
'';
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
defaultListen = [
|
||||
{ addr = "127.0.0.1"; proxyProtocol = true; ssl = true; }
|
||||
{ addr = "127.0.0.2"; }
|
||||
{ addr = "127.0.0.3"; ssl = false; }
|
||||
{ addr = "127.0.0.4"; ssl = false; proxyProtocol = true; }
|
||||
];
|
||||
commonHttpConfig = ''
|
||||
log_format pcombined '(proxy_protocol=$proxy_protocol_addr) - (remote_addr=$remote_addr) - (realip=$realip_remote_addr) - (upstream=) - (remote_user=$remote_user) [$time_local] '
|
||||
'"$request" $status $body_bytes_sent '
|
||||
'"$http_referer" "$http_user_agent"';
|
||||
access_log /var/log/nginx/access.log pcombined;
|
||||
error_log /var/log/nginx/error.log;
|
||||
'';
|
||||
virtualHosts =
|
||||
let
|
||||
commonConfig = {
|
||||
locations."/".return = "200 '$remote_addr'";
|
||||
extraConfig = ''
|
||||
set_real_ip_from 127.0.0.5/32;
|
||||
real_ip_header proxy_protocol;
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
"*.test.nix" = commonConfig // {
|
||||
sslCertificate = certs."*.test.nix".cert;
|
||||
sslCertificateKey = certs."*.test.nix".key;
|
||||
forceSSL = true;
|
||||
};
|
||||
"direct-nossl.test.nix" = commonConfig;
|
||||
"unsecure-nossl.test.nix" = commonConfig // {
|
||||
extraConfig = ''
|
||||
real_ip_header proxy_protocol;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.sniproxy = {
|
||||
enable = true;
|
||||
config = ''
|
||||
error_log {
|
||||
syslog daemon
|
||||
}
|
||||
access_log {
|
||||
syslog daemon
|
||||
}
|
||||
listener 127.0.0.5:443 {
|
||||
protocol tls
|
||||
source 127.0.0.5
|
||||
}
|
||||
table {
|
||||
^proxy\.test\.nix$ 127.0.0.1 proxy_protocol
|
||||
^noproxy\.test\.nix$ 127.0.0.2
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
def check_origin_ip(src_ip: str, dst_url: str, failure: bool = False, proxy_protocol: bool = False, expected_ip: str | None = None):
|
||||
check = webserver.fail if failure else webserver.succeed
|
||||
if expected_ip is None:
|
||||
expected_ip = src_ip
|
||||
|
||||
return check(f"curl {'--haproxy-protocol' if proxy_protocol else '''} --interface {src_ip} --fail -L {dst_url} | grep '{expected_ip}'")
|
||||
|
||||
webserver.wait_for_unit("nginx")
|
||||
webserver.wait_for_unit("sniproxy")
|
||||
# This should be closed by virtue of ssl = true;
|
||||
webserver.wait_for_closed_port(80, "127.0.0.1")
|
||||
# This should be open by virtue of no explicit ssl
|
||||
webserver.wait_for_open_port(80, "127.0.0.2")
|
||||
# This should be open by virtue of ssl = true;
|
||||
webserver.wait_for_open_port(443, "127.0.0.1")
|
||||
# This should be open by virtue of no explicit ssl
|
||||
webserver.wait_for_open_port(443, "127.0.0.2")
|
||||
# This should be open by sniproxy
|
||||
webserver.wait_for_open_port(443, "127.0.0.5")
|
||||
# This should be closed by sniproxy
|
||||
webserver.wait_for_closed_port(80, "127.0.0.5")
|
||||
|
||||
# Sanity checks for the NGINX module
|
||||
# direct-HTTP connection to NGINX without TLS, this checks that ssl = false; works well.
|
||||
check_origin_ip("127.0.0.10", "http://direct-nossl.test.nix/")
|
||||
# webserver.execute("openssl s_client -showcerts -connect direct-noproxy.test.nix:443")
|
||||
# direct-HTTP connection to NGINX with TLS
|
||||
check_origin_ip("127.0.0.10", "http://direct-noproxy.test.nix/")
|
||||
check_origin_ip("127.0.0.10", "https://direct-noproxy.test.nix/")
|
||||
# Well, sniproxy is not listening on 80 and cannot redirect
|
||||
check_origin_ip("127.0.0.10", "http://proxy.test.nix/", failure=True)
|
||||
check_origin_ip("127.0.0.10", "http://noproxy.test.nix/", failure=True)
|
||||
|
||||
# Actual PROXY protocol related tests
|
||||
# Connecting through sniproxy should passthrough the originating IP address.
|
||||
check_origin_ip("127.0.0.10", "https://proxy.test.nix/")
|
||||
# Connecting through sniproxy to a non-PROXY protocol enabled listener should not pass the originating IP address.
|
||||
check_origin_ip("127.0.0.10", "https://noproxy.test.nix/", expected_ip="127.0.0.5")
|
||||
|
||||
# Attack tests against spoofing
|
||||
# Let's try to spoof our IP address by connecting direct-y to the PROXY protocol listener.
|
||||
# FIXME(RaitoBezarius): rewrite it using Python + (Scapy|something else) as this is too much broken unfortunately.
|
||||
# Or wait for upstream curl patch.
|
||||
# def generate_attacker_request(original_ip: str, target_ip: str, dst_url: str):
|
||||
# return f"""PROXY TCP4 {original_ip} {target_ip} 80 80
|
||||
# GET / HTTP/1.1
|
||||
# Host: {dst_url}
|
||||
|
||||
# """
|
||||
# def spoof(original_ip: str, target_ip: str, dst_url: str, tls: bool = False, expect_failure: bool = True):
|
||||
# method = webserver.fail if expect_failure else webserver.succeed
|
||||
# port = 443 if tls else 80
|
||||
# print(webserver.execute(f"cat <<EOF | nc {target_ip} {port}\n{generate_attacker_request(original_ip, target_ip, dst_url)}\nEOF"))
|
||||
# return method(f"cat <<EOF | nc {target_ip} {port} | grep {original_ip}\n{generate_attacker_request(original_ip, target_ip, dst_url)}\nEOF")
|
||||
|
||||
# check_origin_ip("127.0.0.10", "http://unsecure-nossl.test.nix", proxy_protocol=True)
|
||||
# spoof("1.1.1.1", "127.0.0.4", "direct-nossl.test.nix")
|
||||
# spoof("1.1.1.1", "127.0.0.4", "unsecure-nossl.test.nix", expect_failure=False)
|
||||
'';
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user