mirror of
https://github.com/CHN-beta/nixos.git
synced 2026-01-12 04:19:22 +08:00
Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 457bd2571c | |||
| 599b1e7ac0 | |||
| bcafae7509 | |||
| 86ff4c3feb | |||
| d3e11bae79 | |||
| d6a63ed7e5 | |||
| 8fb107b071 | |||
| c0eed934c7 | |||
| 1498a1989b | |||
| 8e029de511 | |||
| c9a231a4b2 | |||
| 4c1c00fcc5 | |||
| b0fee64fc7 | |||
| 2acd77be56 | |||
| b824220f15 | |||
| 2150fe6636 | |||
| 8f72efadd3 | |||
| 4a5e976d5b | |||
| 9858c48d90 | |||
| 2eb6f4ae67 | |||
| b4df678546 | |||
| 8bcecb9d9b | |||
| 2f40ba8166 | |||
| 7483935e93 | |||
| 8db43a7812 | |||
| 48bab70958 | |||
| 72337e2c7e | |||
| 9d0bea2683 | |||
| e4cf0007a3 | |||
| b745e79f6c | |||
| 6af5814ca6 | |||
| 527e0028de | |||
| 19c1babd3c | |||
| 4e81de1d29 | |||
| 80b9ae7d8a | |||
| 01bde3548b | |||
| 8ee26927d0 | |||
| ce4b8d824a | |||
| 4c398d466a | |||
| cba657be2a | |||
| e19d24ee28 | |||
| 475a122108 | |||
| ceb1172d69 | |||
| 2e27420fb6 | |||
| 5197fb8afe | |||
| 6a1dbc7c3d | |||
| b0d4cb637a | |||
| 524953cff7 | |||
| 04975b986e | |||
| 4b4c883448 | |||
| 0cd648767b | |||
| 377a1a9011 | |||
| 5385eb7b7a | |||
| ffc17cf127 | |||
| df3f1d0ff2 | |||
| 9e59ef502b | |||
| 33c47388a8 | |||
| 8f5567576b | |||
| 2099aa9e12 | |||
| 0dfd0219af | |||
| da4f5fa5c5 | |||
| 505f93053f | |||
| ca26d7f8e1 | |||
| 3849301a72 | |||
| a12ff043e1 | |||
| 39ed76bae4 | |||
| 5066a83d6f | |||
| f6deb524df | |||
| 7a82f92743 | |||
| 34a444cc94 | |||
| 70f3ebdc42 | |||
| b3802d7ef0 | |||
| eb92fb319e | |||
| 0b9ccc9797 | |||
| 06321475bb | |||
| c21aed27ab | |||
| 3e1b621434 | |||
| f9dc3d7357 |
@@ -54,6 +54,3 @@ creation_rules:
|
||||
- path_regex: devices/cross/secrets/chn.yaml$
|
||||
key_groups:
|
||||
- age: [ *chn, *pc, *one, *nas ]
|
||||
- path_regex: devices/cross/secrets/acme.yaml$
|
||||
key_groups:
|
||||
- age: [ *chn, *nas, *pc, *one, *srv3, *vps4, *vps6, *srv2-node0, *srv1-node0 ]
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
acme:
|
||||
token: ENC[AES256_GCM,data:Zm4vCgYbrm8wtYMYqtRkMF7hm8feTcZXITKbJgWsgagWbbHE5Z8zoA==,iv:RSRw188gjoAdhTErApuF8tBSsD+aT3LGhifcy417Qzw=,tag:4ZHfkW8aCJ6BW8mtL261yQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1dlVnM2FHWmJNSXpDTzhR
|
||||
Q2EyK3JENDFGNlFVT0pvYjExd0RDT0VQTUNBCjgwL256NnVGNXBVVG1WdmFVNWRI
|
||||
NDdLL0hkZU5JRXFYM2ZtZG5pakpVT1kKLS0tIEl3VjA1bE1lbHMwQXpwSjBENnpB
|
||||
VkpraG8vRFN6RHQ5ZWNrMDFhZGpSaVEKlpOVSF6oFpHIEAnY026JPOmyTB4MGJh1
|
||||
44R3bbMIA1Zo4uZ/lySvWum/oh9h9UTPZPYybts/0NOiX9gqcBuH7w==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age19lhcwk37jmvn6z0v4dpdfh0k4u23f76twdjknc0p7atktf37rd7s4t4wj3
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvOTJac2ljQ0FLYXIweFJp
|
||||
bXM1Sit5WDQ2N0tqdllmc2c1ek9Rd1JJZkg4Cm9sY2JybkVlYlNZSE10ZS9YSU1q
|
||||
UnRLQzNJWGV0aVUxeFFTV2M3cldJSEUKLS0tIE9MaU1BamhMTmtFQWFFNmZKQ0Jo
|
||||
WXFtcjZlVVFuVHdLaTVzNnFvYTB6RGsKOondd9JP142bPU0Jl82/LpBiFvLYBlaS
|
||||
CcP1V7NRC2gQpxHhhYRYN9fuFrWJnUzbAPaIMhMeG3sPIvS2LLwyCA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1ffvr5pqd2lfj24e3fh53s92z6h76fda3du4y4k6r3yjumdwvpfgqzj033a
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBURi9oQ2xvR3l1TU5id2Uw
|
||||
STZDWjZ6R0sxVkNZZWdYSlRDTENxU1UxKzFrCkI4UWhGZjRIVEhiU250R2VUa21y
|
||||
OWgzTWs5WEM5ZVFSS01zZHhsUlZVSkEKLS0tICtjOVIrSXcxUW9ReDFpbWtMOTEr
|
||||
MmhzbEFiVzlobXN4ang0UjZRcHZrOXcKxexbMBS/tTp4MIW93R0K/2+gdIHDYpT6
|
||||
x13rwFfMo/laZGJmtSwYQyRMacpfgsgzwq36qKCOLJ/J/ESht9AA0A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1m7nrxfw22wvp7pj8y9pdl745w95x89uu8dzl9ppsaazweqf2lqms5yshsp
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1dzZoZ0lzQ0owSXNRcHlm
|
||||
b1lqL0ZCN21YWFMyNENScnRjR1ZuVEVFWkVVCitxbW1HL3pGVHk3VndKcVpDdC9B
|
||||
dWJ4MGpZckhYZEdOM1RzNlVqajFocGcKLS0tIC9GcnZyeEtJWHFIanZCTmVuYXRW
|
||||
VThqakFKWE5tVTduZ1NkQ1h2NDdiSmcKsDg83RzJ33Q5v+DuyhYLaQCHY+bBTlY1
|
||||
roC7Nic/mTGHV9NikjJpxJUrdIZ9PZcpRFV+7HEteosTNt9WKPWOkg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1n4lhfwv7g0vhx54exmwx9yv2z04m3h2lunzpa5zdzgtcvjjuf5nqc36g8a
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvTVJ3S0sxbXRQd01TeEZX
|
||||
bEprbTQ3M1BwZy9naWNFQzlqRXdFVVRlNEZvClJyeURyZCtoaU1idlZFU0wySUFm
|
||||
TTdMM3JsbWZuY1R2TnVON2N5dGN2cVUKLS0tIE5qWmU2d1VDYVlRd09STWtRU1E3
|
||||
OGhRV29PWlpOdXFhUWU0WTg3Ni9YR0kKmnbM7HuN39AecfIGPIIr+NcNoNBwbtM3
|
||||
UHgKT6Y6JaCt5BFMFRwvB9hClQn6PUOMjkuIb0BYD2repwP0E3P8qQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1yvrl4y0r6yzcxzzkgfwshlrtsjt8uuya6rfwks09pnft7esfcyvqmrtm5q
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLYkN5ZlBGZ0pSenpIdjBh
|
||||
SmNHMHk1SzFDWFduSFZYVW5kdUZBdittTlQ4Ci9VRGR2WnRKeUcxdUF5UkZXSmZR
|
||||
dzRPbG9ITDlSWjk0ZHQ2b2Z0SnRKUFEKLS0tIERxL1NTekJWOVBmVDVIMWpkYjJB
|
||||
M2xQQnhqbGFWaVhtSnZrZXpBTWNZckEKPGZDtSOZqDhMAG46CZR7Z9TguWC0k8eV
|
||||
3RK/51cpDRP7CS6cQnYHlQycFjnL+e6sCiKZzWXQXdgoW/1DWysNHQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age164tyqklwhdm57tfm5u863mdt2xrzrrzac4py8a0j9y6kzqcjy9zsp073t6
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHV3hlbFUwQnk1RmROU2Qz
|
||||
LzhrMDdZcHFrdlF4cGRLL1dmMy92T2Zpc0M0CnJNd3BPdjNLanBCaTY3Y3lsNk9Z
|
||||
UjVLem1Hell5ZjZsdUE0Z2U4VVk2a1kKLS0tIGJUTFcyZG41T1JsRm9mdHZaYlNs
|
||||
TlBuY214bHoxcmp6ZnlLQ3Nja1c4L3cKTbEnAk/lRZi27QomwPB+xT4eLDWygDZ/
|
||||
B6H9JgCdDuh9azNx07GxCpybzMFZUQjqrzzHqfqxYqMoWKMJoHXmyA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1l4stuz0vr7gs7pqwjrmezam44702jp2vmqaqyxw0l0r42kf9updq4dfhrw
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBETU85VW9zc3p3SmtaeC9l
|
||||
TmpyOGE5WEtRUjV2VEdvb2J2aURvZFJLclFvCkt5QnI3THVUK2VHaDdzVjhNRkw2
|
||||
U25rWU96WmowNk5xTE5odFJqcFI3N1UKLS0tIHhBQ3ZKekZ6d2VSd0NRSHJGdUJV
|
||||
Y1d4TmRpRGJrUm45ajVHcDRzRG1VbUEKjZcnDgP4JqcUfixQXvwI9XSZMtiX5fwU
|
||||
FxOyTyRyxaPbS5b8RBBXrRqiIMCaOkggzcU0LZVOs+nBtqiiaqlw1Q==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1nzetyehldf3gl6pr6mu5d2cv387p8wjqn6wfpll7a3sl8us6n38s0ds633
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSNlRubFNJNVpKVFU2d2xK
|
||||
amhYSC9Tem9IeExVT2lSN1VTaUZiZ3NPZmc4CkkrclY4WitoYllsVGdUMGphU0lz
|
||||
WDhwYk5KckdTa0tlenk4Qk1odHpSb00KLS0tIDNwVnJLaCs0MzhTdVdsZVA1VVhU
|
||||
RVQ1RFdXVk9TMWFWdHhTZ2dEVU51a28Kx2iABI3gz0lVLfzpnFKJkIxDFgSkOr9M
|
||||
87HD5YsLAJ1ACiQzC+BONcdW3FZmu2K6xP/dJXgCYU+2iD39p/cJwg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-09T13:04:33Z"
|
||||
mac: ENC[AES256_GCM,data:xKqvMTW+TTKPtuHh/pSGvxXXIpeKtzVWgwKPibGX9UTIpnDNzfylmkT6OouqQyI/HTQmiL67ch6gaFSMAbXfpw7JA9YpKif6p84rs3RelKzRLKinDpUtcvWhY1DEA2nsNWOdFHxu7EZhHRbXttRoB372kdV5063MJRvwuqslMpo=,iv:T4ff9w1AYGO9JIzuJz6VbPoS19OcIy9zFvOMLp3F2LE=,tag:x5Yk7tVSilKK68ZRhAnsIw==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
@@ -36,8 +36,9 @@ telegram:
|
||||
user:
|
||||
chn: ENC[AES256_GCM,data:mTt2D+SkvVL8,iv:L0Pk5p46E2kKBdRWCGpwOKS0BsbIhZUslpIFWvkssMY=,tag:+AjbNJ1SW/8Mx1HLpWAd2w==,type:str]
|
||||
hjp: ENC[AES256_GCM,data:ZXTQhax0gT4PKw==,iv:MerbaWWC4SLazEuuJrxAxf9e5aaX9xpq9St+h9aqvMQ=,tag:x9knShK90OKZPcn9fKzvMA==,type:str]
|
||||
nginx:
|
||||
maxmind-license: ENC[AES256_GCM,data:MtmNo6hHlU75N6PvzF7P5i6Q+myV4Keb1JRXVeHxTennNpKfAndsKg==,iv:DqM91JX+1WX8Zqzha2Tm3ztFaSzKYQg+b9NvUm+6jxY=,tag:XnDTBL9MA/B8XfPZqdk7Eg==,type:str]
|
||||
maxmind: ENC[AES256_GCM,data:KfTXvxX4zzXBfNMPmZY1z5jTHTByGfH9qEo6EUAQqZ1JOtNUomOWNQ==,iv:KcexOWAXFhWfli6bAMZ+61x960trZ3iE9UYMuOtJNms=,tag:reuuIe6MkONpeT44U6yUjQ==,type:str]
|
||||
acme:
|
||||
token: ENC[AES256_GCM,data:DrNdcyf2tiZ5nmjYmsG13V63ZuZhNG1c/kkGM7eXQWvRvDbu37nKWA==,iv:xc4gtNvZ/BYG+KmT1XgFfG3Z17bBLURazG8tz4/laxE=,tag:khnYVQWjiiaQC9VsJyLV6A==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -175,7 +176,7 @@ sops:
|
||||
UnR5Y24rSTk3WUV1VUgvQUFCVUxPZUEKv/lTy02gZYn4jF1uGtm+LhJd0m59Xe99
|
||||
+unmqUDh0ZqAhJU8o0jrBiWs1lXOHU7CkIom7tGEMHGUxHkS+Z/6GQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-07-05T03:46:51Z"
|
||||
mac: ENC[AES256_GCM,data:5M0XoU1HrzWBkY8N0fObYkeVuF9o8sH4NJAHeCgN5Lqc1gdW+qUnJ4FzJlpPepw87bhWNogXSl4/qRzDFiMpSrDgqaMPhZA0E9eimm659Poe02Rj3LVTOT7UGVaUck+IVgSDx1skQ3hc+yU7ytY5grSoz6rqn4u/uW/prb9BkoQ=,iv:Tt+JNSzZQx9C+FwoCDwctVLQc5rAh5XYOnjsgCSBTJo=,tag:AIz4HnaQ4c7fkdWluiQsYQ==,type:str]
|
||||
lastmodified: "2025-07-13T00:27:59Z"
|
||||
mac: ENC[AES256_GCM,data:iBBMsGOD7nDpXDPDlB/ml06y4WVe0uq7dptn5VZSppoxGA7BmRfWq9OKueXykmgfueqC3N45KVeRh3/b+FrsIRuTl1iyKnT3pd/naGTguQBfFewhrbqNc6UaDadpEVSgYiS76A5JwEoemePPHVUboDOSe0ru3uzNk1nDh/85jRg=,iv:8/GpDArKPYPG2O41p97oQZHkmIgIVdB7OWLvMrDXlaI=,tag:sq3B5Zo7XoA151WmgtvMMw==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
let pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
|
||||
{
|
||||
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
|
||||
nixpkgs = { march = null; cuda = null; nixRoot = "/data/gpfs01/jykang/.nix"; };
|
||||
nixpkgs = { march = "haswell"; cuda = null; nixRoot = "/data/gpfs01/jykang/.nix"; nixos = false; };
|
||||
});
|
||||
in pkgs.symlinkJoin
|
||||
{
|
||||
|
||||
@@ -25,8 +25,13 @@ inputs:
|
||||
services =
|
||||
{
|
||||
sshd = {};
|
||||
xray = { client.dnsmasq.hosts."git.nas.chn.moe" = "127.0.0.1"; xmuServer = {}; };
|
||||
beesd."/".hashTableSizeMB = 10 * 128;
|
||||
xray =
|
||||
{
|
||||
client.dnsmasq = { extraInterfaces = [ "enp3s0" ]; hosts."git.nas.chn.moe" = "127.0.0.1"; };
|
||||
xmuServer = {};
|
||||
server.serverName = "xservernas.chn.moe";
|
||||
};
|
||||
beesd."/" = { hashTableSizeMB = 10 * 128; threads = 4; };
|
||||
nfs."/" = [(inputs.topInputs.self.config.dns."chn.moe".getAddress "wg1.pc")];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,6 +2,11 @@ xray-client:
|
||||
uuid: ENC[AES256_GCM,data:97aX07G5FPumdWcDxnYOs6fRgljXWuwyNXGg1d7zdbUUfNnb,iv:+wAC/DZXsg+evYFA4DMfLw5Ut3ExQl1RgZ/2AsNQDpo=,tag:ebD77muITHof+FQMydWobg==,type:str]
|
||||
wireguard: ENC[AES256_GCM,data:JaOSq474mGOoQQcdJ/j9fYo2e1vjXMPxJ69TOd079FrSkbzbIteWww5f8Xo=,iv:uy/NC2+tibL61XJDZK/spKjV9u0oXK4YzjFjYmCAL0k=,tag:en+c8cHaPvDqJL+EpQjr0g==,type:str]
|
||||
xray-xmu-server: ENC[AES256_GCM,data:3O5rFi5szla70M/c62JV4nGWKPSOREImrOucjeVYf9bde6K8,iv:PGCqlmHtaNuWOtAAeJ6O+CWFpMszijozU1OpUFrftjs=,tag:iGTOoNvQhhZy2FL9jy1KIQ==,type:str]
|
||||
xray-server:
|
||||
clients:
|
||||
#ENC[AES256_GCM,data:gToh4rgMOQ==,iv:A14sSC7ExbSZNOzzz6mOmWalSz9K6ROoSYgCqdF7j4U=,tag:1Jr2FfVQ9L2w+bWHh/NekQ==,type:comment]
|
||||
user4: ENC[AES256_GCM,data:/ZrgvlpwDlKhcHqkBRsdqqJsNUxtb3ZnC36mc8qlJ+HP4mY3,iv:R5QzXY0mC72TDB0OcF4fJt3bc5L1Z96Q+n9kNbZP7m4=,tag:tjWSEcsG0udvQZZJ/RMTJw==,type:str]
|
||||
private-key: ENC[AES256_GCM,data:34FOslwr3AZNDg4YrS95S20agGXwGJRNGnpogMR7utbt1ELUxfQkiAU1qw==,iv:4fiJCi6TJM+NIlfI1qFX/eCNhcVaCWGsLA7iMjQpATw=,tag:eLz8HlQMprQNryk5saqyVQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -22,7 +27,7 @@ sops:
|
||||
by9Rd0U0bzNiK21BQTNxN1RuQ09DQVkKJmSlzV5ppEkZFljsS17ZWmoI++fz4tJh
|
||||
kTdoAStG1zsKASHyZTsmdm3RBDO3qV1KhQC2gC7d4EiwNZngxOOZJg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-30T10:53:22Z"
|
||||
mac: ENC[AES256_GCM,data:XJIKLsszOcJfL9RDcFs7nTDfVIxUGtwhKZhkC7eCKni03b3M/sl2cIwAJ/L20Q+riP2HFcS1ljQA+SjlnY29KWr7DqJ1dM0qcqHjMSlWjurMWPgD4Lf8C7kx2J+6naYiQotQb6y7AfRF9XxAJUaHQe9DdlqHT/bmbtVW5VN1tzs=,iv:IhU7Wo19KOsqxdlSuZg3KtDc08E0dUq2Ahb1J09iLK4=,tag:N9TumoFTKEw/4DT51Lyjjg==,type:str]
|
||||
lastmodified: "2025-08-06T04:33:54Z"
|
||||
mac: ENC[AES256_GCM,data:DMLcRc1hDS0x5Gt0WA/6kfEi7KKogeKHBfuW9gndj7fPqCyyYFzW9Mn8mZ3UhWB68c25GtKyLdo9T5yFivS90JB74kEWrQn/Nfdy0wW18BOloiRwLdSipoADwYwpJtr+JGNs9R6AqIAoDcbVJrr4q6kZh/Cjue6TJiyBdI4uirU=,iv:YOn7XzKAKtzucq6h0yAgj+Ee6L3srscnvieCOmZjBeo=,tag:lnAfv2pWVf5czeTgL4donQ==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -30,5 +30,6 @@ inputs:
|
||||
};
|
||||
bugs = [ "xmunet" ];
|
||||
};
|
||||
specialisation.niri.configuration.nixos.system.gui.implementation = "niri";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -108,14 +108,14 @@ inputs:
|
||||
podman = {};
|
||||
ananicy = {};
|
||||
keyd = {};
|
||||
lumericalLicenseManager.macAddress = "74:5d:22:c7:d2:97";
|
||||
lumericalLicenseManager = { macAddress = "74:5d:22:c7:d2:97"; autoStart = false; };
|
||||
searx = {};
|
||||
kvm.aarch64 = true;
|
||||
nspawn = [ "arch" "ubuntu-22.04" "fedora" ];
|
||||
nfs."/" = [ "192.168.84.0/24" ];
|
||||
};
|
||||
bugs = [ "xmunet" "backlight" "amdpstate" "iwlwifi" ];
|
||||
packages = { mathematica = {}; vasp = {}; android-studio = {}; };
|
||||
packages = { mathematica = {}; vasp = {}; android-studio = {}; lumerical = {}; };
|
||||
};
|
||||
boot.loader.grub =
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ searx:
|
||||
secret-key: ENC[AES256_GCM,data:KhIP+Rz3rMfNgPEGTlKGvm6gl1/ZuPI=,iv:GcaLEJHKJO3n6IaeiFr9PaJ6eNx04/VjX3UgmBF429g=,tag:HkplyH9hTHUaEZ709TyitA==,type:str]
|
||||
xray-xmu-client:
|
||||
uuid: ENC[AES256_GCM,data:XiUkReTJLAxZNWFVeD6EiOtUX5tsyPLFi6QyDBdHyB4v5/mD,iv:QppdtP2CFDEVhlrmDJKYBGc1zYGJvpGYxLfsBAMxDSI=,tag:jzMSFRit+aBzWMkaa3+5hA==,type:str]
|
||||
cookie: ENC[AES256_GCM,data:fx/cqNNpI71FslngfeXFQA==,iv:xZEtOsKgS/8xNqF4B6NKI9+klrpNcraW17KKirMnEfM=,tag:YyczKED2Yo0D6I+RvMjJLg==,type:str]
|
||||
cookie: ENC[AES256_GCM,data:0jqSEZloX2/c8Zg4WTKkLw==,iv:BKLm1KMoRrH0uO6hPMsv2a7sG0AwNRrdbpmABP4BszA=,tag:pBs+rQIhhNO4Qr6q1V3MUA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -36,7 +36,7 @@ sops:
|
||||
OUlxNjdQaXdXMkZ6bnV1ek4yZ2dpbkEKpKGOAxo5Eef2jtGrg4iSzmGCeg+vTgvu
|
||||
+K8b+O19MIkGMDBm6UbYUPtc/7eqoEZRiTUzNMTmfkLVS4ul5zou9A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-30T11:24:37Z"
|
||||
mac: ENC[AES256_GCM,data:V6Gs9hCPIb42nW81Gmy1dz5LFLeX97UuzVbvst/rtuSJHdFzXKxYqIGjHNRK5mGWG/NdTXQ79ELlvpSOgKYAk6gn9ZMn9wCDDbe6spDoGBWL4Ky7mCiSPRcLZ++J+2nP0Q987kZ6IMdMWkFNJmOKWBX/nnp4/aicwyteqNHt4cI=,iv:1wWS0D4RJeWKERfqMQRB75Nh1oKSQzF+r5yOphMrg9Q=,tag:DBPZx1+X7nMLW9xsyEn62A==,type:str]
|
||||
lastmodified: "2025-08-01T07:22:50Z"
|
||||
mac: ENC[AES256_GCM,data:f4fultak/52Gq6nn1hJJYw3AMeuR3J6gcxtPDG/WKkNV+B+gtabWp5R8J8wLWFJ4C1ZsGHDYMTvTfSUlDVdm1dGpxJtFzdfoBBdajj8s2mju6nMQUFoNFRmHDZEQBdIzfXpob1+7Rsr+bBmg7HnFvjR0ozuaQP9QHsHEZxJVbnU=,iv:xh4OIom1TFgKralXw6rrOR/1xpD5SpY2tHfJUq6v41o=,tag:0QOtWN6DcGf3/gorusbXtQ==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
23
devices/r2s/default.nix
Normal file
23
devices/r2s/default.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
model.arch = "aarch64";
|
||||
system =
|
||||
{
|
||||
fileSystems =
|
||||
{
|
||||
mount.btrfs."/dev/disk/by-partlabel/r2s-root" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
swap = [ "/nix/swap/swap" ];
|
||||
};
|
||||
network = {};
|
||||
};
|
||||
services =
|
||||
{
|
||||
sshd = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -76,7 +76,18 @@ inputs:
|
||||
};
|
||||
};
|
||||
packages.vasp = {};
|
||||
user.users = [ "chn" "xll" "zem" "yjq" "gb" "wp" "hjp" "wm" "lly" "yxf" "hss" "zzn" "zqq" "qmx" ];
|
||||
user.users =
|
||||
[
|
||||
# 组内
|
||||
"chn" "xll" "zem" "yjq" "gb" "wp" "hjp" "wm" "qmx"
|
||||
# 组外
|
||||
"yxf" # 小芳同志
|
||||
"hss" # 还没见到本人
|
||||
"zzn" # 张宗南
|
||||
"zqq" # 庄芹芹
|
||||
"zgq" # 希望能接好班
|
||||
"lly" # 这谁?
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ inputs:
|
||||
network =
|
||||
{
|
||||
static.eno2 = { ip = "192.168.178.1"; mask = 24; };
|
||||
wireless = [ "409" ];
|
||||
masquerade = [ "eno2" ];
|
||||
trust = [ "eno2" ];
|
||||
};
|
||||
@@ -28,6 +27,7 @@ inputs:
|
||||
hpcstat = {};
|
||||
ollama = {};
|
||||
sshd = { groupBanner = true; motd = true; };
|
||||
speedtest = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ hpcstat:
|
||||
key: ENC[AES256_GCM,data:+Z7MRDkLLdUqDwMrkafFKkBjeCkw+zgRoAoiVEwrr+LY0uMeW8nNYoaYrfz6Ig8CMCDgX3n/DMb0ibUeN32j3HShQIStbtUxRPGpQMyH+ealbvgskGriTFpST4VPyQxNACkUpq/e+sh2CmLbKkSxhamkjKOXwsfqrBlgVbEkp7u7HkWGuAaYL1oPGt0Q94fWXwH0UVhRYZYQ2iFA/S6SEZY8gxaTIGDKUdWU9+fOHzPQ5WfhxtKYU4p4ydyfYsAt6ffqnPSx/SI72GsUCOJ4981JX8TuvnEzx3gQLVFYheK6NibTWCy6eODbvguieVOTHSvCPTrHmoP12lHVWU2kKzLwv70Jl7sXyzKHYROG0D+/z/4DKlNeotKM/IA0q2cST08/lwSKN7WDDmrt+O6xXhvwby28ZYKEsSvvrfV+VIKzHPl84ZKbUEX5xv/GHc3THfznUvKKz5PzDiqrkjCkEt5PRMsVW9A6MU1+QEUr+sXLLtcUd2CCL87c8CpwNHJx1us6vJ4ji1gu0PGoT+60,iv:yU6j9W2Hs2D34uHMJqqPFbNy2pNEZY2kzXoNdhPMSmA=,tag:TNvEfMVrhu7HrNxY8qe5mg==,type:str]
|
||||
wireless:
|
||||
#ENC[AES256_GCM,data:n9OPSJsB7yNk,iv:xQzKJxqPB7uT83m/B4UoOje6NQbPLhuHR7Hp93oNz8A=,tag:gtsTx6ALnS/7fIDd7VimOg==,type:comment]
|
||||
"409": ENC[AES256_GCM,data:XJ2apDx9E4RM7YzK6wYzxn4eBkVS3l6LIaMtUai2MZ/W0xkaixyV/g/s+cVQtgph2gEcNoLOWbsxr3h8CsrOTA==,iv:O643ytrgHKB4RM6lZKZcr0fLmS2icRnek9praw43jWc=,tag:6Pk7CmiJyvAeW/1V4mvRJQ==,type:str]
|
||||
409的5G: ENC[AES256_GCM,data:K9wm3zedoil7jHgTcb+VmbdbkG2dgrMdr3BmDRUHDVADqLANMvnUMSecggYTO4HaiI9q6uv2/BSkluanD5K4Dw==,iv:7dGET3ULKlnaDMVmkuXDek+hQPLZ2VUbPqvEOX+5jlQ=,tag:MBGmQ0NNNqX+T9EsBiWCaw==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -28,7 +28,7 @@ sops:
|
||||
M0xoL1dQR0kvMWpzN0RMNWVCTFQxNFUKj9LPjBo5NGOrGYNvu8qZ13PLYjLEWllU
|
||||
LARzEn4XgkeHckouwvxZYMCx7WxmAruRWaOvnxTIczzSNP7wIrqnkA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-07-10T10:08:37Z"
|
||||
mac: ENC[AES256_GCM,data:ELeHLFJuOUs8CFIuu08zqp56AijpxxLKlfUo6cWmqwURy/BC6CTFqkNwsD8NirCzSsNTRnwk3pAVXPjJCrk8rnnH4uqiA639h3qMdEpHJLsVhv2+ounGObW7+R/IYJQaSmBWHzZimQsAbp2eVufu3mnu3wjUOhXM6xs0ofuxLWM=,iv:M7PK2S4Okb0MhsJ6d/bJfkMUOoXUMwbWVsHiuxE6Nt4=,tag:4QwSM0dU0mY5Xs03RS1FUw==,type:str]
|
||||
lastmodified: "2025-07-12T04:13:47Z"
|
||||
mac: ENC[AES256_GCM,data:W+e5d1scvV24AdVdl7Pisp9HxsXQ/tPjN2NV/Bd0RXZNBRB7LNQrSfk1GadboBnihW0ctAQOFk66PZsxwE2czfFL2/yzFxm9Cf11Mc822ZL3BwjnQBK4uR9LJrbjL7x1lFUk9v0AIPhjrir8F6dcX8mq6++hHNN0wjGaH3J9E0Y=,iv:RK7e4Dxog+Qsgk6gxK0f8PN8oF9bjWIrTyYK67Cdras=,tag:QSKsETYXbhnvhhjavP4UiA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -36,12 +36,6 @@ inputs:
|
||||
sshd = {};
|
||||
nixvirt.instance =
|
||||
{
|
||||
alikia =
|
||||
{
|
||||
memory.sizeMB = 1024;
|
||||
cpu.count = 1;
|
||||
network = { address = 2; portForward.tcp = [{ host = 5689; guest = 22; }]; };
|
||||
};
|
||||
pen =
|
||||
{
|
||||
memory.sizeMB = 512;
|
||||
@@ -59,7 +53,7 @@ inputs:
|
||||
{ host = 22000; guest = 22000; }
|
||||
];
|
||||
udp = [{ host = 22000; guest = 22000; }];
|
||||
web = [ "natsume.nohost.me" ];
|
||||
web = { httpsProxy = [ "natsume.nohost.me" ]; httpProxy = [ "natsume.nohost.me" ]; };
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -72,7 +66,11 @@ inputs:
|
||||
{
|
||||
address = 4;
|
||||
vnc.openFirewall = false;
|
||||
portForward = { tcp = [{ host = 5693; guest = 22; }]; web = [ "example.chn.moe" ]; };
|
||||
portForward =
|
||||
{
|
||||
tcp = [{ host = 5693; guest = 22; }];
|
||||
web = { httpsProxy = [ "example.chn.moe" ]; httpProxy = [ "example.chn.moe" ]; };
|
||||
};
|
||||
};
|
||||
};
|
||||
reonokiy =
|
||||
@@ -81,6 +79,21 @@ inputs:
|
||||
cpu.count = 4;
|
||||
network = { address = 5; portForward.tcp = [{ host = 5694; guest = 22; }]; };
|
||||
};
|
||||
yumieko =
|
||||
{
|
||||
memory.sizeMB = 8 * 1024;
|
||||
cpu.count = 8;
|
||||
network =
|
||||
{
|
||||
address = 6;
|
||||
portForward =
|
||||
{
|
||||
tcp = [{ host = 5695; guest = 22; }];
|
||||
web = { httpsProxy = [ "littlewing.yumieko.com" ]; httpProxy = [ "littlewing.yumieko.com" ]; };
|
||||
};
|
||||
};
|
||||
storage.iso = "${inputs.topInputs.self.src.guix}";
|
||||
};
|
||||
};
|
||||
rsshub = {};
|
||||
misskey.instances =
|
||||
@@ -100,13 +113,13 @@ inputs:
|
||||
gitea = {};
|
||||
grafana = {};
|
||||
fail2ban = {};
|
||||
xray.server = {};
|
||||
xray = { server = {}; xmuPersist = {}; };
|
||||
podman = {};
|
||||
peertube = {};
|
||||
nginx.applications.webdav.instances."webdav.chn.moe" = {};
|
||||
open-webui.ollamaHost = "192.168.83.3";
|
||||
};
|
||||
user.users = [ "chn" "aleksana" "alikia" "pen" "reonokiy" ];
|
||||
user.users = [ "chn" "aleksana" "alikia" "pen" "reonokiy" "yumieko" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
wireguard: ENC[AES256_GCM,data:Coe4iIEnJVDb4a9KUVTRkXl4kng5Zo6x1Iyr0ErgR2b9bN287mvO6jPUPSc=,iv:fiNUUKobJjitcoxBemIah5Cl5+dSz2Q7sbiOT8bDrRM=,tag:rHfNeRGTxnyVYAu8P/2ewA==,type:str]
|
||||
nixvirt:
|
||||
alikia: ENC[AES256_GCM,data:sP3sWN0RrBU=,iv:TetUcaxsRXl0QsGAyXbVUAW12AXjChVN1/X+ku+3nO4=,tag:kBupoPqVlwHuCnwVdBJBKQ==,type:str]
|
||||
pen: ENC[AES256_GCM,data:okvzUul3UXk=,iv:hcBhsUMP8jdhhKuKdHD1lZi8ixNAC729HfMQ79UzyNk=,tag:SRRav39ScHn0O/sf86CIOw==,type:str]
|
||||
test: ENC[AES256_GCM,data:MYlMmzgbW9c=,iv:q1qPAwFTh0fj2IHBIlnrOMbTU2BnwIYzOFUHVqWCY/Q=,tag:Mb2bJJemg/LxpKI5whNvQw==,type:str]
|
||||
reonokiy: ENC[AES256_GCM,data:J/ZM0Vavmnk=,iv:ZT1cMF/JWLWmXyBx331XkBQerOhLJeOd0a53jcSC4S4=,tag:/WCwzOg5LlAS5ZaiI5DSIw==,type:str]
|
||||
yumieko: ENC[AES256_GCM,data:Nugm6tP4jxg=,iv:HweUreniPs3eDs1ucu/G/P/JZ4jfSaOAiLD2o5WeOUo=,tag:eoc1cVG7CD5WFoawDUUpnw==,type:str]
|
||||
nginx:
|
||||
detectAuth:
|
||||
chn: ENC[AES256_GCM,data:cek6iIlJXgU191uzq44rTw==,iv:r7aMj5UzH1sbKkxvS8oyw6kpIcpRygD4ype8qkmnNa0=,tag:x2jWZnnFCO0sHj/OS2BQbA==,type:str]
|
||||
@@ -84,6 +84,8 @@ peertube:
|
||||
open-webui:
|
||||
openai: ENC[AES256_GCM,data:5B1wPAOx3GsLDoYBKHWFzoyXFmn93fdcq6UC2rCt/P5zYLA4VNzfsp0=,iv:Y2gTLCmwB5wY4dhN73HRvTqSMVXbAEd+RjRbgUEuTeE=,tag:vcfNhXpG0C3twFBsm7PHwA==,type:str]
|
||||
webui: ENC[AES256_GCM,data:Lg32DZ5GC+AYzWc4WloNMQlnpsqW67s5/kXzYwE=,iv:ECncgdYoLkX9GUOX26MXFSO8JOZahUDjTdKV87IRNJ8=,tag:J/5tTR3MI0iGIVDrlacYEg==,type:str]
|
||||
xray-xmu-client:
|
||||
cookie: ENC[AES256_GCM,data:z1KI3CUfPqyiI/B/qgrNhg==,iv:QEjUlMkkF/fdwwEIGiJJ5UxFGw869qAnpApmWaRn3GY=,tag:EbdJsYEslwJbARxDoEWrDA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -104,7 +106,7 @@ sops:
|
||||
d0h3aDh5QXFZYWJFdmNVYnJxQ3pBeVUKTl0XVvtwJcz+RpSylgDPl/R8msInxvWX
|
||||
eQGmrDHibeE1V+KSDiuNzC4MVRIrOnh1beHrhnVQ86HwPVgJqs2FoQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-09T01:35:04Z"
|
||||
mac: ENC[AES256_GCM,data:q2BolEBB6Ik8yx6NHnnE3Wcl2rGVZN86dpfLJrrFOxWd8fZyfBQ/00v4dUZSZw0aQoMj1V2RBDyVtScuRiH0NVb6+RfX+0t3zTEf6guuJdurczLBz9+D51+Th3KE1uk+UjI7J+Q/TOWTvoGMj8P4XZCXQsCDIct/vbLGqNB9CgM=,iv:/6xR7KXXLejm9Iuqcxc/7IqLEckNhmaJTKzJGonSrng=,tag:XdeCoEkHefw2HqTGSchUJA==,type:str]
|
||||
lastmodified: "2025-08-01T05:55:35Z"
|
||||
mac: ENC[AES256_GCM,data:MEgCbEJ/bwx3EVWVYQjb1RbNx8OlJkqelHPbMG5DzSRgcBcllptTFCanLIPZrg4FihkHx3b41Q5xsCXbras1njh4R1FeyLVVGZH7pYjZaPF2MRaD8nYeCHKlItWUVvHQTf5bRrTOOQoo4Kmn2by/xdMWwZlZwt0aBoGnEYBxGf0=,iv:lrPlg8cM5qPgQPpIUHF6WBVglTe9YQtI28hfJSgJ1vU=,tag:tjucRsf+tt9F03Mhjf+jeg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -26,7 +26,7 @@ inputs:
|
||||
services =
|
||||
{
|
||||
sshd = {};
|
||||
xray.server = {};
|
||||
xray = { server = {}; xmuPersist = {}; };
|
||||
nginx =
|
||||
{
|
||||
streamProxy.map =
|
||||
@@ -34,6 +34,7 @@ inputs:
|
||||
"anchor.fm" = { upstream = "anchor.fm:443"; proxyProtocol = false; };
|
||||
"podcasters.spotify.com" = { upstream = "podcasters.spotify.com:443"; proxyProtocol = false; };
|
||||
"xlog.chn.moe" = { upstream = "cname.xlog.app:443"; proxyProtocol = false; };
|
||||
"xservernas.chn.moe" = { upstream = "wg0.nas.chn.moe:443"; proxyProtocol = false; };
|
||||
}
|
||||
// (builtins.listToAttrs (builtins.map
|
||||
(site: { name = "${site}.chn.moe"; value.upstream.address = "wg0.pc.chn.moe"; })
|
||||
@@ -58,6 +59,7 @@ inputs:
|
||||
mirism = {};
|
||||
fail2ban = {};
|
||||
beesd."/" = {};
|
||||
bind = {};
|
||||
};
|
||||
};
|
||||
networking.nftables.tables.forward =
|
||||
|
||||
@@ -44,6 +44,8 @@ send:
|
||||
coturn:
|
||||
auth-secret: ENC[AES256_GCM,data:50KqO4GQ1ERbCnK4IjYu6aywT+IPMtVlTzh/TE4MwWApU4pO9yqz25ENGUAKRLi4p+Ecug+Rn3InRl1b+q6bAQ==,iv:SgHkHvHg/+yA1Z5E9effgCnZMVXv5amGNUsVKErai54=,tag:PoYLV9Xr0IXXsA39n7wiTQ==,type:str]
|
||||
wireguard: ENC[AES256_GCM,data:5M7EAy/6+2UASWkjxE0Jrxwl0aNdAVZaUjQnD1wU3YvOAQ/c2DSL8hVtKf8=,iv:a2tXFf1+aP0JhdNtzP8e82KJ71m2o8nx+G0wIx4VMig=,tag:l4TS4QBz2fIkC9/GnZgHnQ==,type:str]
|
||||
xray-xmu-client:
|
||||
cookie: ENC[AES256_GCM,data:RZ2WFnsX7s/PVqA7ZKhGqw==,iv:CknFoAcHIiIwJI1IEXkFdWXcOCAZr50pfwmQN72OI8o=,tag:w2pNU1APxlSQsGMIEdE2OA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -64,7 +66,7 @@ sops:
|
||||
ZXFTU3ZCaW1pTVh0RUJzdDdGdHlPYTgK2mlgcX2kEc8+2UDdBnhUm6IIuh8V6agW
|
||||
ooxH9OEPXUVI/4JcDo4v8ZUhAyU1ehLH0Ef7PJCChOZe2KZmWSNbhA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-12T23:51:02Z"
|
||||
mac: ENC[AES256_GCM,data:3QxWxinb3a7jvmHJO1kcePNwd/igurjFWVJw/sGKBuZpo47LU+W8132b9GpKs79AedDa5BM5yu0XN+CPrkviMcNuX5a3lLy8oI22a1N8fuKjEehld1Jq/boitGIsgJgb/M0Hn6yIq1ytuWuxoj2cOvmkEfNuyWRew+htI4DhJ/E=,iv:OyCWfcn218oaA970T9miIWIGSwOFeUbtWI0xO/02Hrw=,tag:c8riJplInFN1ZSPH3ze0QQ==,type:str]
|
||||
lastmodified: "2025-08-01T05:54:47Z"
|
||||
mac: ENC[AES256_GCM,data:OtHwr58A1UOfYxQR88ay76fWmAyWPl5YtNbAiv0LXPLZPRtLGBJKuTjMaHr17AMepFZ+u5IPV2r8z1AUDj0opLXlv3Ik/DJ2PCcQTOBH+/lnSgzJKWfdCip9/wFR6N3dT0PKKLuBiURB9ZCYmtnq6E5+Guadc6ATYDSEpwbENZQ=,iv:kXsYMGjAtUlv1UqFU8Xv0zagohnpHkzSI72mq5HKY7k=,tag:KR+1A8l2VvbzDZV/00hbJg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -3,7 +3,7 @@ let
|
||||
pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
|
||||
{
|
||||
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
|
||||
nixpkgs = { march = null; cuda = null; nixRoot = "/public/home/xmuhk/.nix"; };
|
||||
nixpkgs = { march = null; cuda = null; nixRoot = "/public/home/xmuhk/.nix"; nixos = false; };
|
||||
});
|
||||
lumericalLicenseManager =
|
||||
let
|
||||
|
||||
159
flake.lock
generated
159
flake.lock
generated
@@ -583,6 +583,62 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri": {
|
||||
"inputs": {
|
||||
"niri-stable": "niri-stable",
|
||||
"niri-unstable": "niri-unstable",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-stable": "nixpkgs-stable",
|
||||
"xwayland-satellite-stable": "xwayland-satellite-stable",
|
||||
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1752569955,
|
||||
"narHash": "sha256-a21pjNhJYJ+OTQmBJ3NluU65PvMb54/mA7aEWJh5s/4=",
|
||||
"owner": "sodiboo",
|
||||
"repo": "niri-flake",
|
||||
"rev": "8fc18813bf6ceaabb3063050819a20807e11279b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "sodiboo",
|
||||
"repo": "niri-flake",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri-stable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1748151941,
|
||||
"narHash": "sha256-z4viQZLgC2bIJ3VrzQnR+q2F3gAOEQpU1H5xHtX/2fs=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "8ba57fcf25d2fc9565131684a839d58703f1dae7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "YaLTeR",
|
||||
"ref": "v25.05.1",
|
||||
"repo": "niri",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1752565554,
|
||||
"narHash": "sha256-BLLMN6oOarMdIm59AX8uypaXZHBhGfd6L3VURfqQTX8=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "007d35541db1bae32b7b43891af88831325ba068",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-flatpak": {
|
||||
"locked": {
|
||||
"lastModified": 1749394952,
|
||||
@@ -697,16 +753,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1751630609,
|
||||
"narHash": "sha256-mJ1XnKiLnNapGSUwyGdFD8tmQTzuJm8z3qaFC27guqE=",
|
||||
"owner": "CHN-beta",
|
||||
"lastModified": 1752480373,
|
||||
"narHash": "sha256-JHQbm+OcGp32wAsXTE/FLYGNpb+4GLi5oTvCxwSoBOA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b263408b62d74a1e7a298fc47135653a70c227aa",
|
||||
"rev": "62e0f05ede1da0d54515d4ea8ce9c733f12d9f08",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "CHN-beta",
|
||||
"ref": "nixos-25.05",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -790,13 +846,29 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1752308619,
|
||||
"narHash": "sha256-pzrVLKRQNPrii06Rm09Q0i0dq3wt2t2pciT/GNq5EZQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "650e572363c091045cdbc5b36b0f4c1f614d3058",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1750554037,
|
||||
"narHash": "sha256-XE/lFNhz5lsriMm/yjXkvSZz5DfvKJLUjsS6pP8EC50=",
|
||||
"lastModified": 1752553852,
|
||||
"narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
|
||||
"owner": "CHN-beta",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f6b1f449aa69592d8f9bce2d4141766b667294ac",
|
||||
"rev": "72d2707fa09a82bae26845eadb136ce94fd96a3e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -806,6 +878,22 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1754960695,
|
||||
"narHash": "sha256-cv73dyWKY6SBW1ECp0E4v3c51qyYmV+N7NwE0skh/cQ=",
|
||||
"owner": "CHN-beta",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cc56ae5eb2e7c66d90332ddaa2c50196a66ec02b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "CHN-beta",
|
||||
"ref": "nixos-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixvirt": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@@ -1080,11 +1168,12 @@
|
||||
"mumax": "mumax",
|
||||
"nameof": "nameof",
|
||||
"nc4nix": "nc4nix",
|
||||
"niri": "niri",
|
||||
"nix-flatpak": "nix-flatpak",
|
||||
"nix-index-database": "nix-index-database",
|
||||
"nix-vscode-extensions": "nix-vscode-extensions",
|
||||
"nixos-wallpaper": "nixos-wallpaper",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs-2305": "nixpkgs-2305",
|
||||
"nixpkgs-2311": "nixpkgs-2311",
|
||||
"nixpkgs-2411": "nixpkgs-2411",
|
||||
@@ -1101,6 +1190,7 @@
|
||||
"rsshub": "rsshub",
|
||||
"rycee": "rycee",
|
||||
"sops-nix": "sops-nix",
|
||||
"speedtest": "speedtest",
|
||||
"sqlite-orm": "sqlite-orm",
|
||||
"sticker": "sticker",
|
||||
"stickerpicker": "stickerpicker",
|
||||
@@ -1164,6 +1254,22 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"speedtest": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1739473165,
|
||||
"narHash": "sha256-QimemnDZXlL5Ip+RFD0uxO21Aaol3kCw6Mf/0E3jHQc=",
|
||||
"owner": "librespeed",
|
||||
"repo": "speedtest",
|
||||
"rev": "a1c43977ad9bf73f09f81e8df3c22ea914ab9131",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "librespeed",
|
||||
"repo": "speedtest",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"sqlite-orm": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@@ -1406,6 +1512,39 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"xwayland-satellite-stable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1748488455,
|
||||
"narHash": "sha256-IiLr1alzKFIy5tGGpDlabQbe6LV1c9ABvkH6T5WmyRI=",
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"rev": "3ba30b149f9eb2bbf42cf4758d2158ca8cceef73",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Supreeeme",
|
||||
"ref": "v0.6",
|
||||
"repo": "xwayland-satellite",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"xwayland-satellite-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1752338000,
|
||||
"narHash": "sha256-Fxlp/yKtynug0jyuauAmvZU2SzHCfwlwWf85j+IvQ0U=",
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"rev": "ba78881a68182ce338041846164cbfed0d70935c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"zpp-bits": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
winapps = { url = "github:winapps-org/winapps/feat-nix-packaging"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
nixvirt = { url = "github:CHN-beta/NixVirt"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
buildproxy = { url = "github:polygon/nix-buildproxy"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
niri.url = "github:sodiboo/niri-flake";
|
||||
|
||||
misskey = { url = "git+https://github.com/CHN-beta/misskey?submodules=1"; flake = false; };
|
||||
rsshub = { url = "github:DIYgod/RSSHub"; flake = false; };
|
||||
@@ -61,6 +62,7 @@
|
||||
mac-style = { url = "github:SergioRibera/s4rchiso-plymouth-theme?lfs=1"; flake = false; };
|
||||
phono3py = { url = "github:phonopy/phono3py"; flake = false; };
|
||||
sticker = { url = "git+https://git.chn.moe/chn/sticker.git?lfs=1"; flake = false; };
|
||||
speedtest = { url = "github:librespeed/speedtest"; flake = false; };
|
||||
};
|
||||
|
||||
outputs = inputs: let localLib = import ./flake/lib inputs.nixpkgs.lib; in
|
||||
|
||||
@@ -9,7 +9,7 @@ let
|
||||
vps6 =
|
||||
[
|
||||
"blog" "catalog" "coturn" "element" "initrd.vps6" "misskey" "sticker" "synapse-admin" "tgapi"
|
||||
"ua" "xserver2" "xserver2.vps6" "铜锣湾实验室"
|
||||
"ua" "xserver2" "xserver2.vps6" "铜锣湾实验室" "xservernas"
|
||||
];
|
||||
"xlog.autoroute" = [ "xlog" ];
|
||||
"wg0.srv1-node0" = [ "wg0.srv1" ];
|
||||
@@ -38,6 +38,7 @@ let
|
||||
srv1-node1 = "192.168.178.2";
|
||||
srv1-node2 = "192.168.178.3";
|
||||
srv2-node1 = "192.168.178.2";
|
||||
"409test" = "192.168.1.5";
|
||||
};
|
||||
wireguard = import ./wireguard.nix;
|
||||
in
|
||||
@@ -56,11 +57,7 @@ in
|
||||
{ type = "TXT"; value = "v=spf1 include:mxlogin.com -all"; }
|
||||
];
|
||||
"_xlog-challenge.xlog" = { type = "TXT"; value = "chn"; };
|
||||
autoroute =
|
||||
{
|
||||
type = "NS";
|
||||
values = builtins.map (suffix: "ns1.huaweicloud-dns.${suffix}.") [ "cn" "com" "net" "org" ];
|
||||
};
|
||||
autoroute = { type = "NS"; values = "vps6.chn.moe."; };
|
||||
"mail" = { type = "CNAME"; value = "tuesday.mxrouting.net."; };
|
||||
"webmail" = { type = "CNAME"; value = "tuesday.mxrouting.net."; };
|
||||
"x._domainkey" =
|
||||
|
||||
13
flake/lib/buildNixpkgsConfig/boost188.patch
Normal file
13
flake/lib/buildNixpkgsConfig/boost188.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/boost/process/v2/stdio.hpp b/boost/process/v2/stdio.hpp
|
||||
index 01d0216..4084e46 100644
|
||||
--- a/boost/process/v2/stdio.hpp
|
||||
+++ b/boost/process/v2/stdio.hpp
|
||||
@@ -184,7 +184,7 @@ struct process_io_binding
|
||||
process_io_binding & operator=(const process_io_binding &) = delete;
|
||||
|
||||
process_io_binding(process_io_binding && other) noexcept
|
||||
- : fd(other.fd), fd_needs_closing(other.fd), ec(other.ec)
|
||||
+ : fd(other.fd), fd_needs_closing(other.fd_needs_closing), ec(other.ec)
|
||||
{
|
||||
other.fd = target;
|
||||
other.fd_needs_closing = false;
|
||||
@@ -1,9 +1,13 @@
|
||||
# inputs = { lib, topInputs, ...}; nixpkgs = { march, cuda, nixRoot };
|
||||
# inputs = { lib, topInputs, ...}; nixpkgs = { march, cuda, nixRoot, nixos, arch };
|
||||
{ inputs, nixpkgs }:
|
||||
let
|
||||
platformConfig =
|
||||
if nixpkgs.march == null then { system = "x86_64-linux"; }
|
||||
else { hostPlatform = { system = "x86_64-linux"; gcc = { arch = nixpkgs.march; tune = nixpkgs.march; }; }; };
|
||||
if nixpkgs.march == null then { system = "${nixpkgs.arch or "x86_64"}-linux"; }
|
||||
else
|
||||
{
|
||||
${if nixpkgs.nixos then "hostPlatform" else "localSystem"} =
|
||||
{ system = "${nixpkgs.arch or "x86_64"}-linux"; gcc = { arch = nixpkgs.march; tune = nixpkgs.march; }; };
|
||||
};
|
||||
cudaConfig = inputs.lib.optionalAttrs (nixpkgs.cuda != null)
|
||||
(
|
||||
{ cudaSupport = true; }
|
||||
@@ -65,7 +69,9 @@ in platformConfig //
|
||||
patches = prev.patches or [] ++ [ ./root.patch ];
|
||||
cmakeFlags = prev.cmakeFlags ++ [ "-DCMAKE_CXX_STANDARD=23" ];
|
||||
});
|
||||
boost188 = prev.boost188.overrideAttrs (prev: { patches = prev.patches or [] ++ [ ./boost188.patch ]; });
|
||||
inherit (final.pkgs-2411) iio-sensor-proxy;
|
||||
inherit (final.pkgs-unstable) bees;
|
||||
}
|
||||
// (
|
||||
let
|
||||
@@ -82,7 +88,7 @@ in platformConfig //
|
||||
};
|
||||
packages = name: import inputs.topInputs.${source.${name}.source or source.${name}}
|
||||
{
|
||||
localSystem = platformConfig.hostPlatform or { inherit (platformConfig) system; };
|
||||
localSystem = platformConfig.hostPlatform or platformConfig.localSystem or platformConfig;
|
||||
inherit config;
|
||||
overlays = [(source.${name}.overlay or (_: _: {}))];
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ inputs, localLib }:
|
||||
let
|
||||
singles = [ "nas" "pc" "vps4" "vps6" "one" "srv3" "test" "test-pc" "test-pc-vm" ];
|
||||
singles = [ "nas" "pc" "vps4" "vps6" "one" "srv3" "r2s" ];
|
||||
cluster = { srv1 = 3; srv2 = 2; };
|
||||
deviceModules = builtins.listToAttrs
|
||||
(
|
||||
@@ -25,9 +25,9 @@ let
|
||||
(localLib.attrsToList cluster)))
|
||||
);
|
||||
in builtins.mapAttrs
|
||||
(_: v: inputs.nixpkgs.lib.nixosSystem
|
||||
(n: v: inputs.nixpkgs.lib.nixosSystem
|
||||
{
|
||||
system = "x86_64-linux";
|
||||
system = null;
|
||||
specialArgs = { topInputs = inputs; inherit localLib; };
|
||||
modules = localLib.mkModules v;
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
|
||||
{
|
||||
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
|
||||
nixpkgs = { march = null; cuda = null; nixRoot = null; };
|
||||
nixpkgs = { march = null; cuda = null; nixRoot = null; nixos = false; };
|
||||
});
|
||||
hpcstat =
|
||||
let
|
||||
@@ -36,19 +36,17 @@
|
||||
else if builtins.isAttrs x then builtins.concatMap getDrv (builtins.attrValues x)
|
||||
else if builtins.isList x then builtins.concatMap getDrv x
|
||||
else [];
|
||||
in pkgs.concatText "src" (getDrv (inputs.self.outputs.src));
|
||||
in pkgs.writeText "src" (builtins.concatStringsSep "\n" (getDrv inputs.self.outputs.src));
|
||||
dns-push = pkgs.callPackage ./dns
|
||||
{
|
||||
inherit localLib;
|
||||
tokenPath = inputs.self.nixosConfigurations.pc.config.sops.secrets."acme/token".path;
|
||||
tokenPath = inputs.self.nixosConfigurations.pc.config.nixos.system.sops.secrets."acme/token".path;
|
||||
octodns = pkgs.octodns.withProviders (_: with pkgs.octodns-providers; [ cloudflare ]);
|
||||
};
|
||||
archive =
|
||||
let devices =
|
||||
[ "nas" "one" "pc" "srv1-node0" "srv1-node1" "srv1-node2" "srv2-node0" "srv2-node1" "srv3" "vps4" "vps6" ];
|
||||
in pkgs.writeText "archive" (builtins.concatStringsSep "\n" (builtins.map
|
||||
(d: "${inputs.self.outputs.nixosConfigurations.${d}.config.system.build.toplevel}") devices));
|
||||
archive = pkgs.writeText "archive" (builtins.concatStringsSep "\n" (builtins.concatLists
|
||||
[
|
||||
(inputs.nixpkgs.lib.mapAttrsToList (_: v: v.config.system.build.toplevel) inputs.self.outputs.nixosConfigurations)
|
||||
[ src ]
|
||||
]));
|
||||
}
|
||||
// (builtins.listToAttrs (builtins.map
|
||||
(system: { inherit (system) name; value = system.value.config.system.build.toplevel; })
|
||||
(localLib.attrsToList inputs.self.outputs.nixosConfigurations)))
|
||||
// (builtins.mapAttrs (_: v: v.config.system.build.toplevel) inputs.self.outputs.nixosConfigurations)
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
hashMode = "recursive";
|
||||
message = "Source file not found.";
|
||||
};
|
||||
image = "7bb3a43bd1ad6103a57f700b13d11d486b6ea117838201e4a29d79b33ac72e3a";
|
||||
image = "6803f9562b941c23db81a2eae5914561f96fa748536199a010fe6f24922b2878";
|
||||
imageFile = pkgs.requireFile
|
||||
{
|
||||
name = "lumericalLicenseManager.tar";
|
||||
@@ -110,13 +110,13 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
vesta =
|
||||
vesta = rec
|
||||
{
|
||||
version = "3.90.5a";
|
||||
version = "3.5.8";
|
||||
src = pkgs.fetchurl
|
||||
{
|
||||
url = "https://jp-minerals.org/vesta/archives/testing/VESTA-gtk3-x86_64.tar.bz2";
|
||||
sha256 = "0y277m2xvjyzx8hncc3ka73lir8x6x2xckjac9fdzg03z0jnpqzf";
|
||||
url = "https://jp-minerals.org/vesta/archives/${version}/VESTA-gtk3.tar.bz2";
|
||||
sha256 = "1y4dhqhk0jy7kbkkx2c6lsrm5lirn796mq67r5j1s7xkq8jz1gkq";
|
||||
};
|
||||
desktopFile = pkgs.fetchurl
|
||||
{
|
||||
@@ -180,7 +180,7 @@
|
||||
"intel.oneapi.lin.compilers-common,v=2025.1.1+10"
|
||||
];
|
||||
};
|
||||
rsshub = pkgs.dockerTools.pullImage
|
||||
rsshub = pkgs.dockerTools.pullImage
|
||||
{
|
||||
imageName = "diygod/rsshub";
|
||||
imageDigest = "sha256:1f9d97263033752bf5e20c66a75e134e6045b6d69ae843c1f6610add696f8c22";
|
||||
@@ -188,4 +188,20 @@
|
||||
finalImageName = "rsshub";
|
||||
finalImageTag = "latest";
|
||||
};
|
||||
atat = pkgs.fetchurl
|
||||
{
|
||||
url = "https://axelvandewalle.github.io/www-avdw/atat/atat3_50.tar.gz";
|
||||
sha256 = "14sblzqsi5bxfhsjbq256bc2gfd7zrxyf5za0iaw77b592ppjg3m";
|
||||
};
|
||||
atomkit = pkgs.fetchurl
|
||||
{
|
||||
url = "mirror://sourceforge/atomkit/Binaries/atomkit.0.9.0.linux.x64.tar.gz";
|
||||
sha256 = "0y9z7wva7zikh83w9q431lgn3bqkh1v5w6iz90dwc75wqwk0w5jr";
|
||||
};
|
||||
guix = pkgs.fetchurl
|
||||
{
|
||||
url = "https://ci.guix.gnu.org/download/2857";
|
||||
name = "guix.iso";
|
||||
sha256 = "0xqabnay8wwqc1a96db8ix1a6bhvgm84s5is1q67rr432q7gqgd4";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ inputs: let inherit (inputs) topInputs; in
|
||||
topInputs.catppuccin.nixosModules.catppuccin
|
||||
topInputs.aagl.nixosModules.default
|
||||
topInputs.nixvirt.nixosModules.default
|
||||
topInputs.niri.nixosModules.niri
|
||||
{ config.niri-flake.cache.enable = false; }
|
||||
# TODO: Remove after next release
|
||||
"${topInputs.nixpkgs-unstable}/nixos/modules/services/hardware/lact.nix"
|
||||
(inputs:
|
||||
|
||||
@@ -2,7 +2,7 @@ inputs:
|
||||
{
|
||||
options.nixos.hardware.cpu = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.enum [ "intel" "amd" ];
|
||||
type = types.nullOr (types.enum [ "intel" "amd" ]);
|
||||
default = let inherit (inputs.config.nixos.system.nixpkgs) march; in
|
||||
if march == null then null
|
||||
else if inputs.lib.hasPrefix "znver" march then "amd"
|
||||
|
||||
@@ -31,14 +31,18 @@ inputs:
|
||||
(
|
||||
let gpus = inputs.lib.strings.splitString "+" gpu.type; in
|
||||
{
|
||||
boot.initrd.availableKernelModules =
|
||||
let modules =
|
||||
{
|
||||
intel = [ "i915" ];
|
||||
nvidia = []; # early loading breaks resume from hibernation
|
||||
amd = [];
|
||||
};
|
||||
in builtins.concatLists (builtins.map (gpu: modules.${gpu}) gpus);
|
||||
boot =
|
||||
{
|
||||
initrd.availableKernelModules =
|
||||
let modules =
|
||||
{
|
||||
intel = [ "i915" ];
|
||||
nvidia = []; # early loading breaks resume from hibernation
|
||||
amd = [];
|
||||
};
|
||||
in builtins.concatLists (builtins.map (gpu: modules.${gpu}) gpus);
|
||||
blacklistedKernelModules = [ "nouveau" ];
|
||||
};
|
||||
hardware =
|
||||
{
|
||||
graphics =
|
||||
@@ -66,7 +70,6 @@ inputs:
|
||||
prime.allowExternalGpu = true;
|
||||
};
|
||||
};
|
||||
boot.blacklistedKernelModules = [ "nouveau" ];
|
||||
services.xserver.videoDrivers =
|
||||
let driver = { intel = "modesetting"; amd = "amdgpu"; nvidia = "nvidia"; };
|
||||
in builtins.map (gpu: driver.${gpu}) gpus;
|
||||
@@ -78,6 +81,14 @@ inputs:
|
||||
amd = [];
|
||||
};
|
||||
in builtins.concatLists (builtins.map (gpu: packages.${gpu}) gpus);
|
||||
environment.etc."nvidia/nvidia-application-profiles-rc.d/vram" = inputs.lib.mkIf (builtins.elem "nvidia" gpus)
|
||||
{
|
||||
source = inputs.pkgs.writeText "save-vram" (builtins.toJSON
|
||||
{
|
||||
rules = [{ pattern = { feature = "true"; matches = ""; }; profile = "save-vram"; }];
|
||||
profiles = [{ name = "save-vram"; settings = [{ key = "GLVidHeapReuseRatio"; value = 0; }]; }];
|
||||
});
|
||||
};
|
||||
}
|
||||
)
|
||||
# nvidia prime offload
|
||||
|
||||
@@ -3,6 +3,7 @@ inputs:
|
||||
options.nixos.model = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
hostname = mkOption { type = types.nonEmptyStr; };
|
||||
arch = mkOption { type = types.nonEmptyStr; default = "x86_64"; };
|
||||
type = mkOption { type = types.enum [ "minimal" "desktop" "server" ]; default = "minimal"; };
|
||||
private = mkOption { type = types.bool; default = false; };
|
||||
cluster = mkOption
|
||||
|
||||
@@ -160,6 +160,7 @@ inputs:
|
||||
honkers-railway-launcher = { enable = true; package = inputs.pkgs.honkers-railway-launcher; };
|
||||
sleepy-launcher = { enable = true; package = inputs.pkgs.sleepy-launcher; };
|
||||
alvr = { enable = true; openFirewall = true; };
|
||||
localsend.enable = true;
|
||||
};
|
||||
services = { pcscd.enable = true; lact.enable = true; };
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ inputs:
|
||||
beep dos2unix gnugrep pv tmux screen parallel tldr cowsay jq yq ipfetch localPackages.pslist
|
||||
fastfetch reptyr duc ncdu progress libva-utils ksh neofetch dateutils kitty glib
|
||||
# lsxx
|
||||
pciutils usbutils lshw util-linux lsof dmidecode lm_sensors hwloc acpica-tools
|
||||
pciutils usbutils lshw util-linux lsof dmidecode lm_sensors hwloc acpica-tools ethtool
|
||||
# top
|
||||
iotop iftop htop btop powertop s-tui
|
||||
# editor
|
||||
@@ -22,11 +22,13 @@ inputs:
|
||||
# file manager
|
||||
tree eza trash-cli lsd broot file xdg-ninja mlocate
|
||||
# compress
|
||||
pigz upx unzip zip lzip p7zip rar
|
||||
pigz upx unzip zip lzip p7zip
|
||||
(if inputs.pkgs.stdenv.hostPlatform.linuxArch == "x86_64" then rar else emptyDirectory)
|
||||
# file system management
|
||||
sshfs e2fsprogs compsize exfatprogs
|
||||
# disk management
|
||||
smartmontools hdparm gptfdisk megacli
|
||||
smartmontools hdparm gptfdisk
|
||||
(if inputs.pkgs.stdenv.hostPlatform.linuxArch == "x86_64" then megacli else emptyDirectory)
|
||||
# encryption and authentication
|
||||
apacheHttpd openssl ssh-to-age gnupg age sops pam_u2f yubico-piv-tool libfido2
|
||||
# networking
|
||||
|
||||
@@ -10,6 +10,7 @@ inputs:
|
||||
[
|
||||
localPackages.vasp.intel localPackages.vasp.vtst localPackages.vaspkit wannier90
|
||||
(if inputs.config.nixos.system.nixpkgs.cuda != null then localPackages.vasp.nvidia else emptyDirectory)
|
||||
localPackages.atomkit (inputs.lib.mkAfter localPackages.atat)
|
||||
];
|
||||
_pythonPackages = [(_: [ localPackages.py4vasp ])];
|
||||
};
|
||||
|
||||
@@ -35,7 +35,7 @@ inputs:
|
||||
}
|
||||
{
|
||||
programs.zsh = inputs.lib.mkIf
|
||||
(builtins.elem home-inputs.config.home.username [ "chn" "root" "aleksana" "alikia" ])
|
||||
(builtins.elem home-inputs.config.home.username [ "chn" "root" "aleksana" "alikia" "hjp" ])
|
||||
{
|
||||
plugins =
|
||||
[
|
||||
|
||||
@@ -34,21 +34,21 @@ inputs:
|
||||
name = builtins.elemAt cert.value.domains 0;
|
||||
value =
|
||||
{
|
||||
credentialsFile = inputs.config.sops.templates."acme/cloudflare.ini".path;
|
||||
credentialsFile = inputs.config.nixos.system.sops.templates."acme/cloudflare.ini".path;
|
||||
extraDomainNames = builtins.tail cert.value.domains;
|
||||
group = inputs.lib.mkIf (cert.value.group != null) cert.value.group;
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList acme.cert));
|
||||
};
|
||||
sops =
|
||||
nixos.system.sops =
|
||||
{
|
||||
templates."acme/cloudflare.ini".content =
|
||||
''
|
||||
CLOUDFLARE_DNS_API_TOKEN=${inputs.config.sops.placeholder."acme/token"}
|
||||
CLOUDFLARE_DNS_API_TOKEN=${inputs.config.nixos.system.sops.placeholder."acme/token"}
|
||||
CLOUDFLARE_PROPAGATION_TIMEOUT=300
|
||||
'';
|
||||
secrets."acme/token".sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/acme.yaml";
|
||||
secrets."acme/token" = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,24 +15,19 @@ inputs:
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) beesd; in inputs.lib.mkIf (beesd != null)
|
||||
{
|
||||
services.beesd.filesystems = builtins.listToAttrs (builtins.map
|
||||
(fs:
|
||||
services.beesd.filesystems = inputs.lib.mapAttrs'
|
||||
(n: v: inputs.lib.nameValuePair (inputs.utils.escapeSystemdPath n)
|
||||
{
|
||||
name = inputs.utils.escapeSystemdPath fs.name;
|
||||
value =
|
||||
{
|
||||
spec = fs.name;
|
||||
inherit (fs.value) hashTableSizeMB;
|
||||
extraOptions =
|
||||
[
|
||||
"--thread-count" "${builtins.toString fs.value.threads}"
|
||||
"--loadavg-target" "${builtins.toString fs.value.loadAverage}"
|
||||
"--scan-mode" "3"
|
||||
"--verbose" "4"
|
||||
];
|
||||
};
|
||||
spec = n;
|
||||
inherit (v) hashTableSizeMB;
|
||||
extraOptions =
|
||||
[
|
||||
"--thread-count" "${builtins.toString v.threads}"
|
||||
"--loadavg-target" "${builtins.toString v.loadAverage}"
|
||||
"--verbose" "4"
|
||||
];
|
||||
})
|
||||
(inputs.localLib.attrsToList beesd));
|
||||
beesd;
|
||||
nixos.packages.packages._packages = [ inputs.pkgs.bees ];
|
||||
};
|
||||
}
|
||||
|
||||
82
modules/services/bind.nix
Normal file
82
modules/services/bind.nix
Normal file
@@ -0,0 +1,82 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.bind = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule (submoduleInputs: {})); default = null; };
|
||||
config = let inherit (inputs.config.nixos.services) bind; in inputs.lib.mkIf (bind != null)
|
||||
{
|
||||
services.bind =
|
||||
let
|
||||
chinaZone = inputs.pkgs.writeText "autoroute.chn.moe.china.zone"
|
||||
''
|
||||
$ORIGIN autoroute.chn.moe.
|
||||
$TTL 3600
|
||||
@ IN SOA vps6.chn.moe. chn.chn.moe. (
|
||||
2024071301 ; serial
|
||||
3600 ; refresh
|
||||
600 ; retry
|
||||
604800 ; expire
|
||||
300 ; minimum
|
||||
)
|
||||
@ IN NS vps6.chn.moe.
|
||||
@ IN A ${inputs.topInputs.self.config.dns."chn.moe".getAddress "vps6"}
|
||||
'';
|
||||
globalZone = inputs.pkgs.writeText "autoroute.chn.moe.zone"
|
||||
''
|
||||
$ORIGIN autoroute.chn.moe.
|
||||
$TTL 3600
|
||||
@ IN SOA vps6.chn.moe. chn.chn.moe. (
|
||||
2024071301 ; serial
|
||||
3600 ; refresh
|
||||
600 ; retry
|
||||
604800 ; expire
|
||||
300 ; minimum
|
||||
)
|
||||
@ IN NS vps6.chn.moe.
|
||||
@ IN A ${inputs.topInputs.self.config.dns."chn.moe".getAddress "srv3"}
|
||||
'';
|
||||
nullZone = inputs.pkgs.writeText "null.zone" "";
|
||||
in
|
||||
{
|
||||
enable = true;
|
||||
package = inputs.pkgs.bind.overrideAttrs
|
||||
(prev: { buildInputs = prev.buildInputs ++ [ inputs.pkgs.libmaxminddb ]; });
|
||||
listenOn = [(inputs.topInputs.self.config.dns."chn.moe".getAddress "vps6")];
|
||||
extraOptions =
|
||||
''
|
||||
recursion no;
|
||||
geoip-directory "${inputs.config.services.geoipupdate.settings.DatabaseDirectory}";
|
||||
'';
|
||||
extraConfig =
|
||||
''
|
||||
acl "china" {
|
||||
geoip country CN;
|
||||
};
|
||||
|
||||
view "china" {
|
||||
match-clients { china; };
|
||||
zone "autoroute.chn.moe" {
|
||||
type master;
|
||||
file "${chinaZone}";
|
||||
};
|
||||
zone "." {
|
||||
type hint;
|
||||
file "${nullZone}";
|
||||
};
|
||||
};
|
||||
view "global" {
|
||||
match-clients { any; };
|
||||
zone "autoroute.chn.moe" {
|
||||
type master;
|
||||
file "${globalZone}";
|
||||
};
|
||||
zone "." {
|
||||
type hint;
|
||||
file "${nullZone}";
|
||||
};
|
||||
};
|
||||
'';
|
||||
};
|
||||
nixos.services.geoipupdate = {};
|
||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
}
|
||||
@@ -14,14 +14,17 @@ inputs:
|
||||
{
|
||||
enable = true;
|
||||
use-auth-secret = true;
|
||||
static-auth-secret-file = inputs.config.sops.secrets."coturn/auth-secret".path;
|
||||
static-auth-secret-file = inputs.config.nixos.system.sops.secrets."coturn/auth-secret".path;
|
||||
realm = coturn.hostname;
|
||||
cert = "${keydir}/full.pem";
|
||||
pkey = "${keydir}/key.pem";
|
||||
no-cli = true;
|
||||
};
|
||||
sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
|
||||
nixos.services.acme.cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
|
||||
nixos =
|
||||
{
|
||||
system.sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
|
||||
services.acme.cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
|
||||
};
|
||||
networking.firewall = with inputs.config.services.coturn;
|
||||
{
|
||||
allowedUDPPorts = [ listening-port tls-listening-port ];
|
||||
|
||||
@@ -15,19 +15,18 @@ inputs:
|
||||
enable = true;
|
||||
baseUrl = "https://${freshrss.hostname}";
|
||||
defaultUser = "chn";
|
||||
passwordFile = inputs.config.sops.secrets."freshrss/chn".path;
|
||||
database = { type = "mysql"; passFile = inputs.config.sops.secrets."freshrss/db".path; };
|
||||
};
|
||||
sops.secrets =
|
||||
{
|
||||
"freshrss/chn".owner = inputs.config.users.users.freshrss.name;
|
||||
"freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; };
|
||||
passwordFile = inputs.config.nixos.system.sops.secrets."freshrss/chn".path;
|
||||
database = { type = "mysql"; passFile = inputs.config.nixos.system.sops.secrets."freshrss/db".path; };
|
||||
};
|
||||
systemd.services.freshrss-config.after = [ "mysql.service" ];
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
mariadb = { enable = true; instances.freshrss = {}; };
|
||||
nginx.https.${freshrss.hostname}.global.configName = "freshrss";
|
||||
services = { mariadb.instances.freshrss = {}; nginx.https.${freshrss.hostname}.global.configName = "freshrss"; };
|
||||
system.sops.secrets =
|
||||
{
|
||||
"freshrss/chn".owner = inputs.config.users.users.freshrss.name;
|
||||
"freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; };
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
19
modules/services/geoipupdate.nix
Normal file
19
modules/services/geoipupdate.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.geoipupdate = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.services) geoipupdate; in inputs.lib.mkIf (geoipupdate != null)
|
||||
{
|
||||
services.geoipupdate =
|
||||
{
|
||||
enable = true;
|
||||
settings =
|
||||
{
|
||||
AccountID = 901296;
|
||||
LicenseKey = inputs.config.nixos.system.sops.secrets."maxmind".path;
|
||||
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
|
||||
};
|
||||
};
|
||||
nixos.system.sops.secrets."maxmind" = {};
|
||||
};
|
||||
}
|
||||
@@ -19,9 +19,13 @@ inputs:
|
||||
{
|
||||
enable = true;
|
||||
lfs.enable = true;
|
||||
mailerPasswordFile = inputs.config.sops.secrets."gitea/mail".path;
|
||||
mailerPasswordFile = inputs.config.nixos.system.sops.secrets."gitea/mail".path;
|
||||
database =
|
||||
{ createDatabase = false; type = "postgres"; passwordFile = inputs.config.sops.secrets."gitea/db".path; };
|
||||
{
|
||||
createDatabase = false;
|
||||
type = "postgres";
|
||||
passwordFile = inputs.config.nixos.system.sops.secrets."gitea/db".path;
|
||||
};
|
||||
settings =
|
||||
{
|
||||
session.COOKIE_SECURE = true;
|
||||
@@ -48,26 +52,29 @@ inputs:
|
||||
[ "DEFAULT" "MIGRATE" "MIRROR" "CLONE" "PULL" "GC" ]);
|
||||
};
|
||||
};
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
nginx.https.${gitea.hostname}.location =
|
||||
system.sops.secrets =
|
||||
{
|
||||
"/".proxy.upstream = "http://127.0.0.1:3002";
|
||||
"/robots.txt".static.root =
|
||||
let robotsFile = inputs.pkgs.fetchurl
|
||||
{
|
||||
url = "https://gitea.com/robots.txt";
|
||||
sha256 = "144c5s3la4a85c9lygcnxhbxs3w5y23bkhhqx69fbp9yiqyxdkk2";
|
||||
};
|
||||
in "${inputs.pkgs.runCommand "robots.txt" {} "mkdir -p $out; cp ${robotsFile} $out/robots.txt"}";
|
||||
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
|
||||
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
|
||||
"mail/bot" = {};
|
||||
};
|
||||
services =
|
||||
{
|
||||
nginx.https.${gitea.hostname}.location =
|
||||
{
|
||||
"/".proxy.upstream = "http://127.0.0.1:3002";
|
||||
"/robots.txt".static.root =
|
||||
let robotsFile = inputs.pkgs.fetchurl
|
||||
{
|
||||
url = "https://gitea.com/robots.txt";
|
||||
sha256 = "144c5s3la4a85c9lygcnxhbxs3w5y23bkhhqx69fbp9yiqyxdkk2";
|
||||
};
|
||||
in "${inputs.pkgs.runCommand "robots.txt" {} "mkdir -p $out; cp ${robotsFile} $out/robots.txt"}";
|
||||
};
|
||||
postgresql.instances.gitea = {};
|
||||
};
|
||||
postgresql.instances.gitea = {};
|
||||
};
|
||||
sops.secrets =
|
||||
{
|
||||
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
|
||||
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
|
||||
"mail/bot" = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ inputs:
|
||||
enabled = true;
|
||||
host = "mail.chn.moe";
|
||||
user = "bot@chn.moe";
|
||||
password = "$__file{${inputs.config.sops.secrets."grafana/mail".path}}";
|
||||
password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/mail".path}}";
|
||||
from_address = "bot@chn.moe";
|
||||
ehlo_identity = grafana.hostname;
|
||||
startTLS_policy = "MandatoryStartTLS";
|
||||
@@ -32,9 +32,9 @@ inputs:
|
||||
server = { root_url = "https://${grafana.hostname}"; http_port = 3001; enable_gzip = true; };
|
||||
security =
|
||||
{
|
||||
secret_key = "$__file{${inputs.config.sops.secrets."grafana/secret".path}}";
|
||||
secret_key = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/secret".path}}";
|
||||
admin_user = "chn";
|
||||
admin_password = "$__file{${inputs.config.sops.secrets."grafana/chn".path}}";
|
||||
admin_password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/chn".path}}";
|
||||
admin_email = "chn@chn.moe";
|
||||
};
|
||||
database =
|
||||
@@ -42,7 +42,7 @@ inputs:
|
||||
type = "postgres";
|
||||
host = "127.0.0.1:5432";
|
||||
user = "grafana";
|
||||
password = "$__file{${inputs.config.sops.secrets."grafana/db".path}}";
|
||||
password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/db".path}}";
|
||||
};
|
||||
};
|
||||
provision =
|
||||
@@ -78,18 +78,21 @@ inputs:
|
||||
extraFlags = [ "--storage.tsdb.max-block-chunk-segment-size=16MB" ];
|
||||
};
|
||||
};
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
nginx.https.${grafana.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3001"; websocket = true; };
|
||||
postgresql.instances.grafana = {};
|
||||
};
|
||||
sops.secrets = let owner = inputs.config.systemd.services.grafana.serviceConfig.User; in
|
||||
{
|
||||
"grafana/mail" = { owner = owner; key = "mail/bot"; };
|
||||
"grafana/secret".owner = owner;
|
||||
"grafana/chn".owner = owner;
|
||||
"grafana/db" = { owner = owner; key = "postgresql/grafana"; };
|
||||
"mail/bot" = {};
|
||||
services =
|
||||
{
|
||||
nginx.https.${grafana.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3001"; websocket = true; };
|
||||
postgresql.instances.grafana = {};
|
||||
};
|
||||
system.sops.secrets = let owner = inputs.config.systemd.services.grafana.serviceConfig.User; in
|
||||
{
|
||||
"grafana/mail" = { owner = owner; key = "mail/bot"; };
|
||||
"grafana/secret".owner = owner;
|
||||
"grafana/chn".owner = owner;
|
||||
"grafana/db" = { owner = owner; key = "postgresql/grafana"; };
|
||||
"mail/bot" = {};
|
||||
};
|
||||
};
|
||||
environment.persistence."/nix/nodatacow".directories =
|
||||
[{ directory = "/var/lib/prometheus2"; user = "prometheus"; group = "prometheus"; mode = "0700"; }];
|
||||
|
||||
@@ -15,13 +15,13 @@ inputs:
|
||||
grep = "${inputs.pkgs.gnugrep}/bin/grep";
|
||||
curl = "${inputs.pkgs.curl}/bin/curl";
|
||||
cat = "${inputs.pkgs.coreutils}/bin/cat";
|
||||
token = inputs.config.sops.secrets."telegram/token".path;
|
||||
chat = inputs.config.sops.secrets."telegram/user/chn".path;
|
||||
token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
|
||||
chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
|
||||
date = "${inputs.pkgs.coreutils}/bin/date";
|
||||
hpcstat = "${inputs.pkgs.localPackages.hpcstat}/bin/hpcstat";
|
||||
ssh = "${inputs.pkgs.openssh}/bin/ssh -i ${key} -o StrictHostKeyChecking=no"
|
||||
+ " -o ForwardAgent=yes -o AddKeysToAgent=yes";
|
||||
key = inputs.config.sops.secrets."hpcstat/key".path;
|
||||
key = inputs.config.nixos.system.sops.secrets."hpcstat/key".path;
|
||||
jykang = "${inputs.topInputs.self}/devices/jykang.xmuhpc/files";
|
||||
ssh-agent = "${inputs.pkgs.openssh}/bin/ssh-agent";
|
||||
in
|
||||
@@ -105,10 +105,10 @@ inputs:
|
||||
(inputs.localLib.attrsToList calenders));
|
||||
tmpfiles.rules = [ "d /var/lib/hpcstat 0700 hpcstat hpcstat" ];
|
||||
};
|
||||
sops.secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in
|
||||
nixos.system.sops.secrets =
|
||||
{
|
||||
"telegram/token" = { group = "telegram"; mode = "0440"; inherit sopsFile; };
|
||||
"telegram/user/chn" = { group = "telegram"; mode = "0440"; inherit sopsFile; };
|
||||
"telegram/token" = { group = "telegram"; mode = "0440"; };
|
||||
"telegram/user/chn" = { group = "telegram"; mode = "0440"; };
|
||||
"hpcstat/key" = { owner = "hpcstat"; group = "hpcstat"; };
|
||||
};
|
||||
users =
|
||||
|
||||
@@ -10,35 +10,37 @@ inputs:
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) httpapi; in inputs.lib.mkIf (httpapi != null)
|
||||
{
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
phpfpm.instances.httpapi = {};
|
||||
nginx.https.${httpapi.hostname}.location =
|
||||
services =
|
||||
{
|
||||
"/files".static.root = "/srv/api";
|
||||
"/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; };
|
||||
"/notify.php".php =
|
||||
phpfpm.instances.httpapi = {};
|
||||
nginx.https.${httpapi.hostname}.location =
|
||||
{
|
||||
root = builtins.dirOf inputs.config.sops.templates."httpapi/notify.php".path;
|
||||
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpapi.fastcgi;
|
||||
"/files".static.root = "/srv/api";
|
||||
"/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; };
|
||||
"/notify.php".php =
|
||||
{
|
||||
root = builtins.dirOf inputs.config.nixos.system.sops.templates."httpapi/notify.php".path;
|
||||
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpapi.fastcgi;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates."httpapi/notify.php" =
|
||||
system.sops =
|
||||
{
|
||||
owner = inputs.config.users.users.httpapi.name;
|
||||
group = inputs.config.users.users.httpapi.group;
|
||||
content =
|
||||
let
|
||||
placeholder = inputs.config.sops.placeholder;
|
||||
request = "https://api.telegram.org/bot${placeholder."telegram/token"}"
|
||||
+ "/sendMessage?chat_id=${placeholder."telegram/user/chn"}&text=";
|
||||
in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>'';
|
||||
templates."httpapi/notify.php" =
|
||||
{
|
||||
owner = inputs.config.users.users.httpapi.name;
|
||||
group = inputs.config.users.users.httpapi.group;
|
||||
content =
|
||||
let
|
||||
inherit (inputs.config.sops) placeholder;
|
||||
request = "https://api.telegram.org/bot${placeholder."telegram/token"}"
|
||||
+ "/sendMessage?chat_id=${placeholder."telegram/user/chn"}&text=";
|
||||
in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>'';
|
||||
};
|
||||
secrets = { "telegram/token" = {}; "telegram/user/chn" = {}; };
|
||||
};
|
||||
secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in
|
||||
{ "telegram/token" = { inherit sopsFile; }; "telegram/user/chn" = { inherit sopsFile; }; };
|
||||
};
|
||||
systemd.tmpfiles.rules = [ "d /srv/api 0700 nginx nginx" "Z /srv/api - nginx nginx" ];
|
||||
};
|
||||
|
||||
@@ -15,30 +15,7 @@ inputs:
|
||||
image = "ghcr.io/huginn/huginn:latest";
|
||||
imageFile = inputs.topInputs.self.src.huginn;
|
||||
ports = [ "127.0.0.1:3000:3000/tcp" ];
|
||||
environmentFiles = [ inputs.config.sops.templates."huginn/env".path ];
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates."huginn/env".content = let placeholder = inputs.config.sops.placeholder; in
|
||||
''
|
||||
MYSQL_PORT_3306_TCP_ADDR=host.containers.internal
|
||||
HUGINN_DATABASE_NAME=huginn
|
||||
HUGINN_DATABASE_USERNAME=huginn
|
||||
HUGINN_DATABASE_PASSWORD=${placeholder."mariadb/huginn"}
|
||||
DOMAIN=${huginn.hostname}
|
||||
RAILS_ENV=production
|
||||
FORCE_SSL=true
|
||||
INVITATION_CODE=${placeholder."huginn/invitationCode"}
|
||||
SMTP_DOMAIN=mail.chn.moe
|
||||
SMTP_USER_NAME=bot@chn.moe
|
||||
SMTP_PASSWORD="${placeholder."mail/bot"}"
|
||||
SMTP_SERVER=mail.chn.moe
|
||||
SMTP_SSL=true
|
||||
EMAIL_FROM_ADDRESS=bot@chn.moe
|
||||
TIMEZONE=Beijing
|
||||
DO_NOT_CREATE_DATABASE=true
|
||||
'';
|
||||
secrets = { "huginn/invitationCode" = {}; "mail/bot" = {}; };
|
||||
environmentFiles = [ inputs.config.nixos.system.sops.templates."huginn/env".path ];
|
||||
};
|
||||
nixos =
|
||||
{
|
||||
@@ -48,6 +25,29 @@ inputs:
|
||||
mariadb.instances.huginn = {};
|
||||
podman = {};
|
||||
};
|
||||
system.sops =
|
||||
{
|
||||
templates."huginn/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
|
||||
''
|
||||
MYSQL_PORT_3306_TCP_ADDR=host.containers.internal
|
||||
HUGINN_DATABASE_NAME=huginn
|
||||
HUGINN_DATABASE_USERNAME=huginn
|
||||
HUGINN_DATABASE_PASSWORD=${placeholder."mariadb/huginn"}
|
||||
DOMAIN=${huginn.hostname}
|
||||
RAILS_ENV=production
|
||||
FORCE_SSL=true
|
||||
INVITATION_CODE=${placeholder."huginn/invitationCode"}
|
||||
SMTP_DOMAIN=mail.chn.moe
|
||||
SMTP_USER_NAME=bot@chn.moe
|
||||
SMTP_PASSWORD="${placeholder."mail/bot"}"
|
||||
SMTP_SERVER=mail.chn.moe
|
||||
SMTP_SSL=true
|
||||
EMAIL_FROM_ADDRESS=bot@chn.moe
|
||||
TIMEZONE=Beijing
|
||||
DO_NOT_CREATE_DATABASE=true
|
||||
'';
|
||||
secrets = { "huginn/invitationCode" = {}; "mail/bot" = {}; };
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ inputs:
|
||||
default = if inputs.config.nixos.system.network != null then "00:01:23:45:67:89" else null;
|
||||
};
|
||||
createFakeInterface = mkOption { type = types.bool; default = inputs.config.nixos.system.network != null; };
|
||||
autoStart = mkOption { type = types.bool; default = true; };
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
@@ -27,11 +28,16 @@ inputs:
|
||||
in [ "${license}:/home/ansys_inc/shared_files/licensing/license_files/ansyslmd.lic" ];
|
||||
};
|
||||
nixos.services.podman = {};
|
||||
systemd.network = inputs.lib.mkIf lumericalLicenseManager.createFakeInterface
|
||||
systemd =
|
||||
{
|
||||
netdevs.ensFakeLumerical.netdevConfig = { Kind = "dummy"; Name = "ensFakeLumerical"; };
|
||||
networks."10-ensFakeLumerical" =
|
||||
{ matchConfig.Name = "ensFakeLumerical"; linkConfig.MACAddress = lumericalLicenseManager.macAddress; };
|
||||
network = inputs.lib.mkIf lumericalLicenseManager.createFakeInterface
|
||||
{
|
||||
netdevs.ensFakeLumerical.netdevConfig = { Kind = "dummy"; Name = "ensFakeLumerical"; };
|
||||
networks."10-ensFakeLumerical" =
|
||||
{ matchConfig.Name = "ensFakeLumerical"; linkConfig.MACAddress = lumericalLicenseManager.macAddress; };
|
||||
};
|
||||
services.podman-lumericalLicenseManager.wantedBy =
|
||||
inputs.lib.mkIf (!lumericalLicenseManager.autoStart) (inputs.lib.mkForce []);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,13 +40,13 @@ inputs:
|
||||
let
|
||||
passwordFile =
|
||||
if db.value.passwordFile or null != null then db.value.passwordFile
|
||||
else inputs.config.sops.secrets."mariadb/${db.value.user}".path;
|
||||
else inputs.config.nixos.system.sops.secrets."mariadb/${db.value.user}".path;
|
||||
mysql = "${inputs.config.services.mysql.package}/bin/mysql";
|
||||
in
|
||||
# force user use password auth
|
||||
''echo "ALTER USER '${db.value.user}' IDENTIFIED BY '$(cat ${passwordFile})';" | ${mysql} -N'')
|
||||
(inputs.localLib.attrsToList mariadb.instances)));
|
||||
sops.secrets = builtins.listToAttrs (builtins.map
|
||||
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
|
||||
(db: { name = "mariadb/${db.value.user}"; value.owner = inputs.config.users.users.mysql.name; })
|
||||
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList mariadb.instances)));
|
||||
environment.persistence."/nix/nodatacow".directories =
|
||||
|
||||
@@ -22,7 +22,8 @@ inputs:
|
||||
after = [ "network.target" "redis-misskey-${instance.name}.service" "postgresql.service" ];
|
||||
requires = after;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment.MISSKEY_CONFIG_YML = inputs.config.sops.templates."misskey/${instance.name}.yml".path;
|
||||
environment.MISSKEY_CONFIG_YML =
|
||||
inputs.config.nixos.system.sops.templates."misskey/${instance.name}.yml".path;
|
||||
serviceConfig = rec
|
||||
{
|
||||
User = "misskey-${instance.name}";
|
||||
@@ -53,50 +54,6 @@ inputs:
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
sops.templates = builtins.listToAttrs (builtins.map
|
||||
(instance:
|
||||
{
|
||||
name = "misskey/${instance.name}.yml";
|
||||
value =
|
||||
{
|
||||
content =
|
||||
let
|
||||
placeholder = inputs.config.sops.placeholder;
|
||||
redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}";
|
||||
in
|
||||
''
|
||||
url: https://${instance.value.hostname}/
|
||||
port: ${toString instance.value.port}
|
||||
db:
|
||||
host: 127.0.0.1
|
||||
port: 5432
|
||||
db: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||
user: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||
pass: ${placeholder."postgresql/misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"}
|
||||
extra:
|
||||
statement_timeout: 600000
|
||||
dbReplications: false
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
port: ${builtins.toString redis.port}
|
||||
pass: ${placeholder."redis/misskey-${instance.name}"}
|
||||
id: 'aid'
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
proxyRemoteFiles: true
|
||||
signToActivityPubGet: true
|
||||
maxFileSize: 1073741824
|
||||
fulltextSearch:
|
||||
provider: sqlPgroonga
|
||||
'';
|
||||
owner = "misskey-${instance.name}";
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
users = inputs.lib.mkMerge (builtins.map
|
||||
(instance:
|
||||
{
|
||||
@@ -111,19 +68,66 @@ inputs:
|
||||
groups."misskey-${instance.name}".gid = inputs.config.nixos.user.gid."misskey-${instance.name}";
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
redis.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
postgresql.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
nginx.https = builtins.listToAttrs (builtins.map
|
||||
(instance: with instance.value;
|
||||
services =
|
||||
{
|
||||
redis.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
postgresql.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
nginx.https = builtins.listToAttrs (builtins.map
|
||||
(instance: with instance.value;
|
||||
{
|
||||
name = hostname;
|
||||
value.location."/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
};
|
||||
system.sops.templates = builtins.listToAttrs (builtins.map
|
||||
(instance:
|
||||
{
|
||||
name = hostname;
|
||||
value.location."/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
|
||||
name = "misskey/${instance.name}.yml";
|
||||
value =
|
||||
{
|
||||
content =
|
||||
let
|
||||
placeholder = inputs.config.nixos.system.sops.placeholder;
|
||||
redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}";
|
||||
in
|
||||
''
|
||||
url: https://${instance.value.hostname}/
|
||||
port: ${toString instance.value.port}
|
||||
db:
|
||||
host: 127.0.0.1
|
||||
port: 5432
|
||||
db: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||
user: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||
pass: ${placeholder."postgresql/misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"}
|
||||
extra:
|
||||
statement_timeout: 600000
|
||||
dbReplications: false
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
port: ${builtins.toString redis.port}
|
||||
pass: ${placeholder."redis/misskey-${instance.name}"}
|
||||
id: 'aid'
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
proxyRemoteFiles: true
|
||||
signToActivityPubGet: true
|
||||
maxFileSize: 1073741824
|
||||
fulltextSearch:
|
||||
provider: sqlPgroonga
|
||||
'';
|
||||
owner = "misskey-${instance.name}";
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
};
|
||||
|
||||
@@ -21,9 +21,9 @@ inputs:
|
||||
config =
|
||||
{
|
||||
dbtype = "pgsql";
|
||||
dbpassFile = inputs.config.sops.secrets."nextcloud/postgresql".path;
|
||||
dbpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/postgresql".path;
|
||||
adminuser = "admin";
|
||||
adminpassFile = inputs.config.sops.secrets."nextcloud/admin".path;
|
||||
adminpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/admin".path;
|
||||
};
|
||||
configureRedis = true;
|
||||
settings =
|
||||
@@ -39,7 +39,7 @@ inputs:
|
||||
overwriteprotocol = "https";
|
||||
default_phone_region = "CN";
|
||||
};
|
||||
secretFile = inputs.config.sops.templates."nextcloud/secret".path;
|
||||
secretFile = inputs.config.nixos.system.sops.templates."nextcloud/secret".path;
|
||||
extraApps =
|
||||
let
|
||||
version = inputs.lib.versions.major inputs.config.services.nextcloud.package.version;
|
||||
@@ -59,27 +59,30 @@ inputs:
|
||||
(package: { name = package; value = inputs.pkgs.fetchNextcloudApp (getInfo package); })
|
||||
[ "phonetrack" "twofactor_webauthn" "calendar" ]);
|
||||
};
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
postgresql.instances.nextcloud = {};
|
||||
redis.instances.nextcloud.port = 3499;
|
||||
nginx.https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates."nextcloud/secret" =
|
||||
system.sops =
|
||||
{
|
||||
content = builtins.toJSON
|
||||
templates."nextcloud/secret" =
|
||||
{
|
||||
redis.password = inputs.config.sops.placeholder."redis/nextcloud";
|
||||
mail_smtppassword = inputs.config.sops.placeholder."mail/bot";
|
||||
content = builtins.toJSON
|
||||
{
|
||||
redis.password = inputs.config.nixos.system.sops.placeholder."redis/nextcloud";
|
||||
mail_smtppassword = inputs.config.nixos.system.sops.placeholder."mail/bot";
|
||||
};
|
||||
owner = inputs.config.users.users.nextcloud.name;
|
||||
};
|
||||
secrets =
|
||||
{
|
||||
"nextcloud/postgresql" = { key = "postgresql/nextcloud"; owner = inputs.config.users.users.nextcloud.name; };
|
||||
"nextcloud/admin".owner = inputs.config.users.users.nextcloud.name;
|
||||
};
|
||||
owner = inputs.config.users.users.nextcloud.name;
|
||||
};
|
||||
secrets =
|
||||
services =
|
||||
{
|
||||
"nextcloud/postgresql" = { key = "postgresql/nextcloud"; owner = inputs.config.users.users.nextcloud.name; };
|
||||
"nextcloud/admin".owner = inputs.config.users.users.nextcloud.name;
|
||||
postgresql.instances.nextcloud = {};
|
||||
redis.instances.nextcloud.port = 3499;
|
||||
nginx.https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
|
||||
};
|
||||
};
|
||||
systemd.services.nextcloud-setup = rec { requires = [ "postgresql.service" ]; after = requires; };
|
||||
|
||||
@@ -25,87 +25,70 @@ inputs:
|
||||
config = let inherit (inputs.config.nixos.services) nginx; in inputs.lib.mkIf
|
||||
(nginx.http != {} || nginx.https != {} || nginx.streamProxy.map != {} || nginx.transparentProxy.map != {})
|
||||
{
|
||||
services =
|
||||
services.nginx =
|
||||
{
|
||||
nginx =
|
||||
{
|
||||
enable = true;
|
||||
enableReload = true;
|
||||
eventsConfig =
|
||||
''
|
||||
worker_connections 524288;
|
||||
use epoll;
|
||||
'';
|
||||
commonHttpConfig =
|
||||
''
|
||||
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
|
||||
$geoip2_data_country_code country iso_code;
|
||||
}
|
||||
log_format http '[$time_local] $remote_addr-$geoip2_data_country_code "$host"'
|
||||
' $request_length $bytes_sent $status "$request" referer: "$http_referer" ua: "$http_user_agent"';
|
||||
access_log syslog:server=unix:/dev/log http;
|
||||
proxy_ssl_server_name on;
|
||||
proxy_ssl_session_reuse off;
|
||||
send_timeout 1d;
|
||||
# nginx will try to redirect https://blog.chn.moe/docs to https://blog.chn.moe:3068/docs/ in default
|
||||
# this make it redirect to /docs/ without hostname
|
||||
absolute_redirect off;
|
||||
# allow realip module to set ip
|
||||
set_real_ip_from 0.0.0.0/0;
|
||||
real_ip_header proxy_protocol;
|
||||
'';
|
||||
proxyTimeout = "1d";
|
||||
recommendedZstdSettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
# do not set Host header
|
||||
recommendedProxySettings = false;
|
||||
recommendedProxySettingsNoHost = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedBrotliSettings = true;
|
||||
clientMaxBodySize = "0";
|
||||
package =
|
||||
let nginx-geoip2 =
|
||||
{
|
||||
name = "ngx_http_geoip2_module";
|
||||
src = inputs.pkgs.fetchFromGitHub
|
||||
{
|
||||
owner = "leev";
|
||||
repo = "ngx_http_geoip2_module";
|
||||
rev = "a607a41a8115fecfc05b5c283c81532a3d605425";
|
||||
hash = "sha256-CkmaeEa1iEAabJEDu3FhBUR7QF38koGYlyx+pyKZV9Y=";
|
||||
};
|
||||
meta.license = [];
|
||||
};
|
||||
in (inputs.pkgs.nginxMainline.override (prev: { modules = prev.modules ++ [ nginx-geoip2 ]; }))
|
||||
.overrideAttrs (prev: { buildInputs = prev.buildInputs ++ [ inputs.pkgs.libmaxminddb ]; });
|
||||
streamConfig =
|
||||
''
|
||||
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
|
||||
$geoip2_data_country_code country iso_code;
|
||||
}
|
||||
resolver 8.8.8.8;
|
||||
'';
|
||||
# anyway to use host dns?
|
||||
resolver.addresses = [ "8.8.8.8" ];
|
||||
};
|
||||
geoipupdate =
|
||||
{
|
||||
enable = true;
|
||||
settings =
|
||||
enable = true;
|
||||
enableReload = true;
|
||||
eventsConfig =
|
||||
''
|
||||
worker_connections 524288;
|
||||
use epoll;
|
||||
'';
|
||||
commonHttpConfig =
|
||||
''
|
||||
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
|
||||
$geoip2_data_country_code country iso_code;
|
||||
}
|
||||
log_format http '[$time_local] $remote_addr-$geoip2_data_country_code "$host"'
|
||||
' $request_length $bytes_sent $status "$request" referer: "$http_referer" ua: "$http_user_agent"';
|
||||
access_log syslog:server=unix:/dev/log http;
|
||||
proxy_ssl_server_name on;
|
||||
proxy_ssl_session_reuse off;
|
||||
send_timeout 1d;
|
||||
# nginx will try to redirect https://blog.chn.moe/docs to https://blog.chn.moe:3068/docs/ in default
|
||||
# this make it redirect to /docs/ without hostname
|
||||
absolute_redirect off;
|
||||
# allow realip module to set ip
|
||||
set_real_ip_from 0.0.0.0/0;
|
||||
real_ip_header proxy_protocol;
|
||||
'';
|
||||
proxyTimeout = "1d";
|
||||
recommendedZstdSettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
# do not set Host header
|
||||
recommendedProxySettings = false;
|
||||
recommendedProxySettingsNoHost = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedBrotliSettings = true;
|
||||
clientMaxBodySize = "0";
|
||||
package =
|
||||
let nginx-geoip2 =
|
||||
{
|
||||
AccountID = 901296;
|
||||
LicenseKey = inputs.config.sops.secrets."nginx/maxmind-license".path;
|
||||
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
|
||||
name = "ngx_http_geoip2_module";
|
||||
src = inputs.pkgs.fetchFromGitHub
|
||||
{
|
||||
owner = "leev";
|
||||
repo = "ngx_http_geoip2_module";
|
||||
rev = "a607a41a8115fecfc05b5c283c81532a3d605425";
|
||||
hash = "sha256-CkmaeEa1iEAabJEDu3FhBUR7QF38koGYlyx+pyKZV9Y=";
|
||||
};
|
||||
meta.license = [];
|
||||
};
|
||||
};
|
||||
in (inputs.pkgs.nginxMainline.override (prev: { modules = prev.modules ++ [ nginx-geoip2 ]; }))
|
||||
.overrideAttrs (prev: { buildInputs = prev.buildInputs ++ [ inputs.pkgs.libmaxminddb ]; });
|
||||
streamConfig =
|
||||
''
|
||||
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
|
||||
$geoip2_data_country_code country iso_code;
|
||||
}
|
||||
resolver 8.8.8.8;
|
||||
'';
|
||||
# anyway to use host dns?
|
||||
resolver.addresses = [ "8.8.8.8" ];
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
sops.secrets."nginx/maxmind-license" =
|
||||
{
|
||||
owner = inputs.config.users.users.nginx.name;
|
||||
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
|
||||
};
|
||||
nixos.services.geoipupdate = {};
|
||||
systemd.services.nginx.serviceConfig =
|
||||
{
|
||||
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||
|
||||
@@ -177,7 +177,7 @@ inputs:
|
||||
basicAuthFile = inputs.lib.mkIf (site.value.global.detectAuth != null)
|
||||
(
|
||||
let secret = "nginx/templates/detectAuth/${inputs.lib.strings.escapeURL site.name}-global";
|
||||
in inputs.config.sops.templates.${secret}.path
|
||||
in inputs.config.nixos.system.sops.templates.${secret}.path
|
||||
);
|
||||
extraConfig = builtins.concatStringsSep "\n"
|
||||
(
|
||||
@@ -227,7 +227,7 @@ inputs:
|
||||
let
|
||||
inherit (inputs.lib.strings) escapeURL;
|
||||
secret = "nginx/templates/detectAuth/${escapeURL site.name}/${escapeURL location.name}";
|
||||
in inputs.config.sops.templates.${secret}.path
|
||||
in inputs.config.nixos.system.sops.templates.${secret}.path
|
||||
);
|
||||
root = inputs.lib.mkIf (location.value.root or null != null) location.value.root;
|
||||
}
|
||||
@@ -247,7 +247,7 @@ inputs:
|
||||
++ (inputs.lib.optionals (location.value.addAuth != null)
|
||||
(
|
||||
let authFile = "nginx/templates/addAuth/${location.value.addAuth}";
|
||||
in [ "include ${inputs.config.sops.templates.${authFile}.path};" ]
|
||||
in [ "include ${inputs.config.nixos.system.sops.templates.${authFile}.path};" ]
|
||||
))
|
||||
);
|
||||
};
|
||||
@@ -285,114 +285,108 @@ inputs:
|
||||
};
|
||||
})
|
||||
sites);
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
nginx =
|
||||
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
|
||||
let listens = builtins.filter
|
||||
(listen: listen.value.addToTransparentProxy)
|
||||
(builtins.concatLists (builtins.map
|
||||
(site: builtins.map (listen: { inherit (site) name; value = listen; }) site.value.listens)
|
||||
sites));
|
||||
in
|
||||
{
|
||||
transparentProxy.map = builtins.listToAttrs (builtins.map
|
||||
(site:
|
||||
{
|
||||
inherit (site) name;
|
||||
value = with nginx.global; httpsPort + (if site.value.http2 then httpsPortShift.http2 else 0);
|
||||
})
|
||||
(builtins.filter (listen: !listen.value.proxyProtocol) listens));
|
||||
streamProxy.map = builtins.listToAttrs (builtins.map
|
||||
(site:
|
||||
{
|
||||
inherit (site) name;
|
||||
value =
|
||||
services =
|
||||
{
|
||||
nginx =
|
||||
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
|
||||
let listens = builtins.filter
|
||||
(listen: listen.value.addToTransparentProxy)
|
||||
(builtins.concatLists (builtins.map
|
||||
(site: builtins.map (listen: { inherit (site) name; value = listen; }) site.value.listens)
|
||||
sites));
|
||||
in
|
||||
{
|
||||
transparentProxy.map = builtins.listToAttrs (builtins.map
|
||||
(site:
|
||||
{
|
||||
upstream.port = with nginx.global; httpsPort + httpsPortShift.proxyProtocol
|
||||
+ (if site.value.http2 then httpsPortShift.http2 else 0);
|
||||
proxyProtocol = true;
|
||||
rewriteHttps = inputs.lib.mkDefault false;
|
||||
};
|
||||
})
|
||||
(builtins.filter (listen: listen.value.proxyProtocol) listens));
|
||||
http = builtins.listToAttrs (builtins.map
|
||||
(site: { inherit (site) name; value.rewriteHttps = {}; })
|
||||
(builtins.filter (site: site.value.global.rewriteHttps) sites));
|
||||
};
|
||||
acme.cert = builtins.listToAttrs (builtins.map
|
||||
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
|
||||
sites);
|
||||
};
|
||||
sops =
|
||||
let
|
||||
inherit (inputs.lib.strings) escapeURL;
|
||||
detectAuthUsers = builtins.concatLists (builtins.map
|
||||
(site:
|
||||
(
|
||||
(builtins.map
|
||||
inherit (site) name;
|
||||
value = with nginx.global; httpsPort + (if site.value.http2 then httpsPortShift.http2 else 0);
|
||||
})
|
||||
(builtins.filter (listen: !listen.value.proxyProtocol) listens));
|
||||
streamProxy.map = builtins.listToAttrs (builtins.map
|
||||
(site:
|
||||
{
|
||||
inherit (site) name;
|
||||
value =
|
||||
{
|
||||
upstream.port = with nginx.global; httpsPort + httpsPortShift.proxyProtocol
|
||||
+ (if site.value.http2 then httpsPortShift.http2 else 0);
|
||||
proxyProtocol = true;
|
||||
rewriteHttps = inputs.lib.mkDefault false;
|
||||
};
|
||||
})
|
||||
(builtins.filter (listen: listen.value.proxyProtocol) listens));
|
||||
http = builtins.listToAttrs (builtins.map
|
||||
(site: { inherit (site) name; value.rewriteHttps = {}; })
|
||||
(builtins.filter (site: site.value.global.rewriteHttps) sites));
|
||||
};
|
||||
acme.cert = builtins.listToAttrs (builtins.map
|
||||
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
|
||||
sites);
|
||||
};
|
||||
system.sops =
|
||||
let
|
||||
inherit (inputs.lib.strings) escapeURL;
|
||||
detectAuthUsers = builtins.concatLists (builtins.map
|
||||
(site:
|
||||
(
|
||||
(builtins.map
|
||||
(location:
|
||||
{
|
||||
name = "${escapeURL site.name}/${escapeURL location.name}";
|
||||
value = location.value.detectAuth.users;
|
||||
})
|
||||
(builtins.filter (location: location.value.detectAuth or null != null) site.value.locations))
|
||||
++ (inputs.lib.optionals (site.value.global.detectAuth != null)
|
||||
[ { name = "${escapeURL site.name}-global"; value = site.value.global.detectAuth.users; } ])
|
||||
))
|
||||
sites);
|
||||
addAuth = builtins.concatLists (builtins.map
|
||||
(site: builtins.map
|
||||
(location:
|
||||
{
|
||||
name = "${escapeURL site.name}/${escapeURL location.name}";
|
||||
value = location.value.detectAuth.users;
|
||||
value = location.value.addAuth;
|
||||
})
|
||||
(builtins.filter (location: location.value.detectAuth or null != null) site.value.locations))
|
||||
++ (inputs.lib.optionals (site.value.global.detectAuth != null)
|
||||
[ { name = "${escapeURL site.name}-global"; value = site.value.global.detectAuth.users; } ])
|
||||
))
|
||||
sites);
|
||||
addAuth = builtins.concatLists (builtins.map
|
||||
(site: builtins.map
|
||||
(location:
|
||||
{
|
||||
name = "${escapeURL site.name}/${escapeURL location.name}";
|
||||
value = location.value.addAuth;
|
||||
})
|
||||
(builtins.filter (location: location.value.addAuth or null != null) site.value.locations)
|
||||
)
|
||||
sites);
|
||||
in
|
||||
{
|
||||
templates = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(detectAuth:
|
||||
{
|
||||
name = "nginx/templates/detectAuth/${detectAuth.name}";
|
||||
value =
|
||||
(builtins.filter (location: location.value.addAuth or null != null) site.value.locations)
|
||||
)
|
||||
sites);
|
||||
in
|
||||
{
|
||||
templates = let inherit (inputs.config.nixos.system.sops) placeholder; in builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(detectAuth: inputs.lib.nameValuePair "nginx/templates/detectAuth/${detectAuth.name}"
|
||||
{
|
||||
owner = inputs.config.users.users.nginx.name;
|
||||
content = builtins.concatStringsSep "\n" (builtins.map
|
||||
(user: "${user}:{PLAIN}${inputs.config.sops.placeholder."nginx/detectAuth/${user}"}")
|
||||
(user: "${user}:{PLAIN}${placeholder."nginx/detectAuth/${user}"}")
|
||||
detectAuth.value);
|
||||
};
|
||||
})
|
||||
detectAuthUsers)
|
||||
++ (builtins.map
|
||||
(addAuth:
|
||||
{
|
||||
name = "nginx/templates/addAuth/${addAuth.name}";
|
||||
value =
|
||||
})
|
||||
detectAuthUsers)
|
||||
++ (builtins.map
|
||||
(addAuth: inputs.lib.nameValuePair "nginx/templates/addAuth/${addAuth.name}"
|
||||
{
|
||||
owner = inputs.config.users.users.nginx.name;
|
||||
content =
|
||||
let placeholder = inputs.config.sops.placeholder."nginx/addAuth/${addAuth.value}";
|
||||
in ''proxy_set_header Authorization "Basic ${placeholder}";'';
|
||||
};
|
||||
})
|
||||
addAuth)
|
||||
);
|
||||
secrets = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(secret: { name = "nginx/detectAuth/${secret}"; value = {}; })
|
||||
(inputs.lib.unique (builtins.concatLists (builtins.map (detectAuth: detectAuth.value)
|
||||
detectAuthUsers))))
|
||||
++ (builtins.map
|
||||
(secret: { name = "nginx/addAuth/${secret}"; value = {}; })
|
||||
(inputs.lib.unique (builtins.map (addAuth: addAuth.value) addAuth)))
|
||||
);
|
||||
};
|
||||
''proxy_set_header Authorization "Basic ${placeholder."nginx/addAuth/${addAuth.value}"}";'';
|
||||
})
|
||||
addAuth)
|
||||
);
|
||||
secrets = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(secret: { name = "nginx/detectAuth/${secret}"; value = {}; })
|
||||
(inputs.lib.unique (builtins.concatLists (builtins.map (detectAuth: detectAuth.value)
|
||||
detectAuthUsers))))
|
||||
++ (builtins.map
|
||||
(secret: { name = "nginx/addAuth/${secret}"; value = {}; })
|
||||
(inputs.lib.unique (builtins.map (addAuth: addAuth.value) addAuth)))
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
]);
|
||||
|
||||
@@ -38,34 +38,48 @@ inputs:
|
||||
access_log syslog:server=unix:/dev/log transparent_proxy;
|
||||
}
|
||||
'';
|
||||
# TODO: use existing options
|
||||
systemd.services.nginx-proxy =
|
||||
let
|
||||
ip = "${inputs.pkgs.iproute2}/bin/ip";
|
||||
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
|
||||
''
|
||||
${ip} rule add fwmark 2/2 table 200
|
||||
${ip} route add local 0.0.0.0/0 dev lo table 200
|
||||
'';
|
||||
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
|
||||
''
|
||||
${ip} rule del fwmark 2/2 table 200
|
||||
${ip} route del local 0.0.0.0/0 dev lo table 200
|
||||
'';
|
||||
in
|
||||
systemd =
|
||||
{
|
||||
services = inputs.lib.mkIf (inputs.config.nixos.system.network == null)
|
||||
{
|
||||
description = "nginx transparent proxy";
|
||||
after = [ "network.target" ];
|
||||
serviceConfig =
|
||||
{
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = start;
|
||||
ExecStop = stop;
|
||||
};
|
||||
wants = [ "network.target" ];
|
||||
wantedBy= [ "multi-user.target" ];
|
||||
nginx-proxy =
|
||||
let
|
||||
ip = "${inputs.pkgs.iproute2}/bin/ip";
|
||||
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
|
||||
''
|
||||
${ip} rule add fwmark 2/2 table 200
|
||||
${ip} route add local 0.0.0.0/0 dev lo table 200
|
||||
'';
|
||||
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
|
||||
''
|
||||
${ip} rule del fwmark 2/2 table 200
|
||||
${ip} route del local 0.0.0.0/0 dev lo table 200
|
||||
'';
|
||||
in
|
||||
{
|
||||
description = "nginx transparent proxy";
|
||||
after = [ "network.target" ];
|
||||
serviceConfig =
|
||||
{
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = start;
|
||||
ExecStop = stop;
|
||||
};
|
||||
wants = [ "network.target" ];
|
||||
wantedBy= [ "multi-user.target" ];
|
||||
};
|
||||
};
|
||||
network.networks = inputs.lib.mkIf (inputs.config.nixos.system.network != null)
|
||||
{
|
||||
"10-custom" =
|
||||
{
|
||||
matchConfig.Name = "lo";
|
||||
routes = [{ Table = 200; Destination = "0.0.0.0/0"; Type = "local"; }];
|
||||
routingPolicyRules = [{ FirewallMark = "2/2"; Table = 200; }];
|
||||
};
|
||||
};
|
||||
};
|
||||
networking.nftables.tables.nginx =
|
||||
{
|
||||
family = "inet";
|
||||
|
||||
@@ -15,12 +15,15 @@ inputs:
|
||||
enable = true;
|
||||
package = inputs.pkgs.nix-serve-ng;
|
||||
openFirewall = true;
|
||||
secretKeyFile = inputs.config.sops.secrets."store/signingKey".path;
|
||||
secretKeyFile = inputs.config.nixos.system.sops.secrets."store/signingKey".path;
|
||||
# curl -L cache.nixos.org/nix-cache-info
|
||||
# use this cache after official one
|
||||
extraParams = "--priority 50";
|
||||
};
|
||||
sops.secrets."store/signingKey" = {};
|
||||
nixos.services.nginx.https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000";
|
||||
nixos =
|
||||
{
|
||||
system.sops.secrets."store/signingKey" = {};
|
||||
services.nginx.https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ inputs:
|
||||
{
|
||||
name = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
|
||||
nodatacow = mkOption { type = types.bool; default = false; };
|
||||
iso = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||
};
|
||||
memory =
|
||||
{
|
||||
@@ -54,7 +55,12 @@ inputs:
|
||||
default = [];
|
||||
};
|
||||
udp = tcp;
|
||||
web = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||
web = rec
|
||||
{
|
||||
httpsProxy = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||
httpProxy = httpsProxy;
|
||||
httpRedirect = httpsProxy;
|
||||
};
|
||||
};
|
||||
};
|
||||
};}));
|
||||
@@ -83,7 +89,7 @@ inputs:
|
||||
domains = builtins.map
|
||||
(vm:
|
||||
{
|
||||
definition = inputs.config.sops.templates."nixvirt/${vm.name}.xml".path;
|
||||
definition = inputs.config.nixos.system.sops.templates."nixvirt/${vm.name}.xml".path;
|
||||
active = true;
|
||||
restart = false;
|
||||
})
|
||||
@@ -122,146 +128,143 @@ inputs:
|
||||
vnc_listen = "0.0.0.0"
|
||||
'';
|
||||
};
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
nginx =
|
||||
let hosts = builtins.concatLists (builtins.map
|
||||
(vm: builtins.map
|
||||
(domain:
|
||||
{
|
||||
inherit domain;
|
||||
ip = "192.168.${builtins.toString nixvirt.subnet}.${builtins.toString vm.network.address}";
|
||||
})
|
||||
vm.network.portForward.web)
|
||||
(builtins.attrValues nixvirt.instance));
|
||||
in
|
||||
{
|
||||
transparentProxy.map = builtins.listToAttrs (builtins.map
|
||||
(host: { name = host.domain; value = "${host.ip}" + ":443"; }) hosts);
|
||||
http = builtins.listToAttrs (builtins.map
|
||||
(host: { name = host.domain; value.proxy.upstream = "http://${host.ip}" + ":80"; }) hosts);
|
||||
};
|
||||
kvm = {};
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates = builtins.listToAttrs (builtins.map
|
||||
(vm:
|
||||
{
|
||||
name = "nixvirt/${vm.name}.xml";
|
||||
value.content = inputs.topInputs.nixvirt.lib.domain.getXML
|
||||
# port from 8bcc23e27a62297254d0e9c87281e650ff777132
|
||||
system.sops =
|
||||
{
|
||||
templates = inputs.lib.mapAttrs'
|
||||
(n: v: inputs.lib.nameValuePair "nixvirt/${n}.xml"
|
||||
{
|
||||
inherit (vm) name;
|
||||
inherit (vm.value) uuid;
|
||||
type = "kvm";
|
||||
vcpu = { placement = "static"; count = vm.value.cpu.count; };
|
||||
cputune = inputs.lib.optionalAttrs (vm.value.cpu.set != null)
|
||||
content = inputs.topInputs.nixvirt.lib.domain.getXML
|
||||
# port from 8bcc23e27a62297254d0e9c87281e650ff777132
|
||||
{
|
||||
vcpupin = builtins.genList
|
||||
(cpu: { vcpu = cpu; cpuset = builtins.elemAt vm.value.cpu.set cpu; })
|
||||
vm.value.cpu.count;
|
||||
};
|
||||
memory =
|
||||
{
|
||||
count = vm.value.memory.sizeMB;
|
||||
unit = "MiB";
|
||||
nosharepages = vm.value.memory.dedicated;
|
||||
locked = vm.value.memory.dedicated;
|
||||
};
|
||||
os =
|
||||
{
|
||||
type = "hvm";
|
||||
arch = "x86_64";
|
||||
machine = "q35";
|
||||
bootmenu = { enable = true; timeout = 15000; };
|
||||
loader = { readonly = true; type = "pflash"; path = "/run/libvirt/nix-ovmf/OVMF_CODE.fd"; };
|
||||
nvram =
|
||||
name = n;
|
||||
inherit (v) uuid;
|
||||
type = "kvm";
|
||||
vcpu = { placement = "static"; count = v.cpu.count; };
|
||||
cputune = inputs.lib.optionalAttrs (v.cpu.set != null)
|
||||
{
|
||||
template = "/run/libvirt/nix-ovmf/OVMF_VARS.fd";
|
||||
path = "/var/lib/libvirt/qemu/nvram/${vm.name}_VARS.fd";
|
||||
templateFormat = "raw";
|
||||
format = "raw";
|
||||
vcpupin = builtins.genList (cpu: { vcpu = cpu; cpuset = builtins.elemAt v.cpu.set cpu; }) v.cpu.count;
|
||||
};
|
||||
};
|
||||
features = { acpi = {}; apic = {}; };
|
||||
cpu =
|
||||
{
|
||||
mode = "host-passthrough";
|
||||
topology =
|
||||
memory =
|
||||
{
|
||||
sockets = 1;
|
||||
dies = 1;
|
||||
cores = if vm.value.cpu.hyprthread then vm.value.cpu.count / 2 else vm.value.cpu.count;
|
||||
threads = if vm.value.cpu.hyprthread then 2 else 1;
|
||||
count = v.memory.sizeMB;
|
||||
unit = "MiB";
|
||||
nosharepages = v.memory.dedicated;
|
||||
locked = v.memory.dedicated;
|
||||
};
|
||||
};
|
||||
clock =
|
||||
{
|
||||
offset = "utc";
|
||||
timer =
|
||||
[
|
||||
{ name = "rtc"; tickpolicy = "catchup"; }
|
||||
{ name = "pit"; tickpolicy = "delay"; }
|
||||
{ name = "hpet"; present = false; }
|
||||
];
|
||||
};
|
||||
devices =
|
||||
{
|
||||
emulator = "${inputs.config.virtualisation.libvirtd.qemu.package}/bin/qemu-system-x86_64";
|
||||
disk =
|
||||
[
|
||||
os =
|
||||
{
|
||||
type = "hvm";
|
||||
arch = "x86_64";
|
||||
machine = "q35";
|
||||
bootmenu = { enable = true; timeout = 15000; };
|
||||
loader = { readonly = true; type = "pflash"; path = "/run/libvirt/nix-ovmf/OVMF_CODE.fd"; };
|
||||
nvram =
|
||||
{
|
||||
type = "file";
|
||||
device = "disk";
|
||||
driver = { name = "qemu"; type = "raw"; cache = "writeback"; discard = "unmap"; };
|
||||
source.file = "${if vm.value.storage.nodatacow then "/nix/nodatacow" else ""}/var/lib/libvirt/images/"
|
||||
+ "${vm.value.storage.name}.img";
|
||||
target = { dev = "vda"; bus = "virtio"; };
|
||||
boot.order = 1;
|
||||
}
|
||||
template = "/run/libvirt/nix-ovmf/OVMF_VARS.fd";
|
||||
path = "/var/lib/libvirt/qemu/nvram/${n}_VARS.fd";
|
||||
templateFormat = "raw";
|
||||
format = "raw";
|
||||
};
|
||||
};
|
||||
features = { acpi = {}; apic = {}; };
|
||||
cpu =
|
||||
{
|
||||
mode = "host-passthrough";
|
||||
topology =
|
||||
{
|
||||
type = "file";
|
||||
device = "cdrom";
|
||||
driver = { name = "qemu"; type = "raw"; };
|
||||
source.file = "${inputs.topInputs.self.src.iso.netboot}";
|
||||
target = { dev = "sdc"; bus = "sata"; };
|
||||
readonly = true;
|
||||
boot.order = 10;
|
||||
}
|
||||
];
|
||||
interface =
|
||||
{
|
||||
type = "bridge";
|
||||
model.type = "virtio";
|
||||
mac.address = vm.value.network.mac;
|
||||
source.bridge = if vm.value.network.bridge then "nixvirt" else "virbr0";
|
||||
sockets = 1;
|
||||
dies = 1;
|
||||
cores = if v.cpu.hyprthread then v.cpu.count / 2 else v.cpu.count;
|
||||
threads = if v.cpu.hyprthread then 2 else 1;
|
||||
};
|
||||
};
|
||||
input =
|
||||
[
|
||||
{ type = "tablet"; bus = "usb"; }
|
||||
{ type = "mouse"; bus = "ps2"; }
|
||||
{ type = "keyboard"; bus = "ps2"; }
|
||||
];
|
||||
graphics =
|
||||
clock =
|
||||
{
|
||||
type = "vnc";
|
||||
autoport = false;
|
||||
port = vm.value.network.vnc.port;
|
||||
listen.type = "address";
|
||||
passwd = inputs.config.sops.placeholder."nixvirt/${vm.name}";
|
||||
offset = "utc";
|
||||
timer =
|
||||
[
|
||||
{ name = "rtc"; tickpolicy = "catchup"; }
|
||||
{ name = "pit"; tickpolicy = "delay"; }
|
||||
{ name = "hpet"; present = false; }
|
||||
];
|
||||
};
|
||||
devices =
|
||||
{
|
||||
emulator = "${inputs.config.virtualisation.libvirtd.qemu.package}/bin/qemu-system-x86_64";
|
||||
disk =
|
||||
[
|
||||
{
|
||||
type = "file";
|
||||
device = "disk";
|
||||
driver = { name = "qemu"; type = "raw"; cache = "writeback"; discard = "unmap"; };
|
||||
source.file = "${if v.storage.nodatacow then "/nix/nodatacow" else ""}/var/lib/libvirt/images/"
|
||||
+ "${v.storage.name}.img";
|
||||
target = { dev = "vda"; bus = "virtio"; };
|
||||
boot.order = 1;
|
||||
}
|
||||
{
|
||||
type = "file";
|
||||
device = "cdrom";
|
||||
driver = { name = "qemu"; type = "raw"; };
|
||||
source.file =
|
||||
if v.storage.iso == null then "${inputs.topInputs.self.src.iso.netboot}" else v.storage.iso;
|
||||
target = { dev = "sdc"; bus = "sata"; };
|
||||
readonly = true;
|
||||
boot.order = 10;
|
||||
}
|
||||
];
|
||||
interface =
|
||||
{
|
||||
type = "bridge";
|
||||
model.type = "virtio";
|
||||
mac.address = v.network.mac;
|
||||
source.bridge = if v.network.bridge then "nixvirt" else "virbr0";
|
||||
};
|
||||
input =
|
||||
[
|
||||
{ type = "tablet"; bus = "usb"; }
|
||||
{ type = "mouse"; bus = "ps2"; }
|
||||
{ type = "keyboard"; bus = "ps2"; }
|
||||
];
|
||||
graphics =
|
||||
{
|
||||
type = "vnc";
|
||||
autoport = false;
|
||||
port = v.network.vnc.port;
|
||||
listen.type = "address";
|
||||
passwd = inputs.config.sops.placeholder."nixvirt/${n}";
|
||||
};
|
||||
video.model = { type = "qxl"; ram = 65536; vram = 65536; vgamem = 16384; heads = 1; primary = true; };
|
||||
rng = { model = "virtio"; backend = { model = "random"; source = /dev/urandom; }; };
|
||||
};
|
||||
video.model = { type = "qxl"; ram = 65536; vram = 65536; vgamem = 16384; heads = 1; primary = true; };
|
||||
rng = { model = "virtio"; backend = { model = "random"; source = /dev/urandom; }; };
|
||||
};
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList nixvirt.instance));
|
||||
secrets = builtins.listToAttrs (builtins.map
|
||||
(vm: { name = "nixvirt/${vm}"; value = {}; }) (builtins.attrNames nixvirt.instance));
|
||||
placeholder = builtins.listToAttrs (builtins.map
|
||||
(vm: { name = "nixvirt/${vm}"; value = builtins.hashString "sha256" "nixvirt/${vm}"; })
|
||||
(builtins.attrNames nixvirt.instance));
|
||||
})
|
||||
nixvirt.instance;
|
||||
secrets = inputs.lib.mapAttrs' (n: _: inputs.lib.nameValuePair "nixvirt/${n}" {}) nixvirt.instance;
|
||||
};
|
||||
services =
|
||||
{
|
||||
nginx = inputs.lib.mkMerge (builtins.map
|
||||
(vm: let ip = "192.168.${builtins.toString nixvirt.subnet}.${builtins.toString vm.network.address}"; in
|
||||
{
|
||||
transparentProxy.map = builtins.listToAttrs (builtins.map
|
||||
(host: inputs.lib.nameValuePair host "${ip}:443")
|
||||
vm.network.portForward.web.httpsProxy);
|
||||
http = inputs.lib.mkMerge
|
||||
[
|
||||
(builtins.listToAttrs (builtins.map
|
||||
(host: inputs.lib.nameValuePair host { proxy.upstream = "http://${ip}" + ":80"; })
|
||||
vm.network.portForward.web.httpProxy))
|
||||
(builtins.listToAttrs (builtins.map
|
||||
(host: inputs.lib.nameValuePair host { rewriteHttps = {}; })
|
||||
vm.network.portForward.web.httpRedirect))
|
||||
];
|
||||
})
|
||||
(builtins.attrValues nixvirt.instance or {}));
|
||||
kvm = {};
|
||||
};
|
||||
};
|
||||
security.wrappers.vm =
|
||||
{
|
||||
|
||||
@@ -28,19 +28,22 @@ inputs:
|
||||
ENABLE_IMAGE_GENERATION = "True";
|
||||
IMAGES_OPENAI_API_BASE_URL = "https://oa.api2d.net/v1";
|
||||
};
|
||||
environmentFile = inputs.config.sops.templates."open-webui.env".path;
|
||||
environmentFile = inputs.config.nixos.system.sops.templates."open-webui.env".path;
|
||||
};
|
||||
sops =
|
||||
nixos =
|
||||
{
|
||||
templates."open-webui.env".content = let inherit (inputs.config.sops) placeholder; in
|
||||
''
|
||||
OPENAI_API_KEY=${placeholder."open-webui/openai"}
|
||||
WEBUI_SECRET_KEY=${placeholder."open-webui/webui"}
|
||||
IMAGES_OPENAI_API_KEY=${placeholder."open-webui/openai"}
|
||||
'';
|
||||
secrets = { "open-webui/openai" = {}; "open-webui/webui" = {}; };
|
||||
system.sops =
|
||||
{
|
||||
templates."open-webui.env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
|
||||
''
|
||||
OPENAI_API_KEY=${placeholder."open-webui/openai"}
|
||||
WEBUI_SECRET_KEY=${placeholder."open-webui/webui"}
|
||||
IMAGES_OPENAI_API_KEY=${placeholder."open-webui/openai"}
|
||||
'';
|
||||
secrets = { "open-webui/openai" = {}; "open-webui/webui" = {}; };
|
||||
};
|
||||
services.nginx.https."${open-webui.hostname}".location."/".proxy =
|
||||
{ upstream = "http://127.0.0.1:8080"; websocket = true; };
|
||||
};
|
||||
nixos.services.nginx.https."${open-webui.hostname}".location."/".proxy =
|
||||
{ upstream = "http://127.0.0.1:8080"; websocket = true; };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,48 +17,46 @@ inputs:
|
||||
listenHttp = 5046;
|
||||
listenWeb = 443;
|
||||
enableWebHttps = true;
|
||||
serviceEnvironmentFile = inputs.config.sops.templates."peertube/env".path;
|
||||
secrets.secretsFile = inputs.config.sops.secrets."peertube/secrets".path;
|
||||
serviceEnvironmentFile = inputs.config.nixos.system.sops.templates."peertube/env".path;
|
||||
secrets.secretsFile = inputs.config.nixos.system.sops.secrets."peertube/secrets".path;
|
||||
configureNginx = true;
|
||||
database =
|
||||
{
|
||||
createLocally = true;
|
||||
host = "127.0.0.1";
|
||||
passwordFile = inputs.config.sops.secrets."peertube/postgresql".path;
|
||||
passwordFile = inputs.config.nixos.system.sops.secrets."peertube/postgresql".path;
|
||||
};
|
||||
redis =
|
||||
{
|
||||
host = "127.0.0.1";
|
||||
port = 7599;
|
||||
passwordFile = inputs.config.sops.secrets."redis/peertube".path;
|
||||
};
|
||||
smtp.passwordFile = inputs.config.sops.secrets."peertube/smtp".path;
|
||||
settings.smtp =
|
||||
{
|
||||
host = "mail.chn.moe";
|
||||
username = "bot@chn.moe";
|
||||
from_address = "bot@chn.moe";
|
||||
passwordFile = inputs.config.nixos.system.sops.secrets."redis/peertube".path;
|
||||
};
|
||||
smtp.passwordFile = inputs.config.nixos.system.sops.secrets."peertube/smtp".path;
|
||||
settings.smtp = { host = "mail.chn.moe"; username = "bot@chn.moe"; from_address = "bot@chn.moe"; };
|
||||
};
|
||||
sops =
|
||||
nixos =
|
||||
{
|
||||
templates."peertube/env".content =
|
||||
''
|
||||
PT_INITIAL_ROOT_PASSWORD=${inputs.config.sops.placeholder."peertube/password"}
|
||||
'';
|
||||
secrets =
|
||||
system.sops =
|
||||
{
|
||||
"peertube/postgresql" = { owner = inputs.config.services.peertube.user; key = "postgresql/peertube"; };
|
||||
"peertube/password" = {};
|
||||
"peertube/secrets".owner = inputs.config.services.peertube.user;
|
||||
"peertube/smtp" = { owner = inputs.config.services.peertube.user; key = "mail/bot"; };
|
||||
templates."peertube/env".content =
|
||||
''
|
||||
PT_INITIAL_ROOT_PASSWORD=${inputs.config.nixos.system.sops.placeholder."peertube/password"}
|
||||
'';
|
||||
secrets =
|
||||
{
|
||||
"peertube/postgresql" = { owner = inputs.config.services.peertube.user; key = "postgresql/peertube"; };
|
||||
"peertube/password" = {};
|
||||
"peertube/secrets".owner = inputs.config.services.peertube.user;
|
||||
"peertube/smtp" = { owner = inputs.config.services.peertube.user; key = "mail/bot"; };
|
||||
};
|
||||
};
|
||||
services =
|
||||
{
|
||||
nginx.https.${peertube.hostname}.global.configName = peertube.hostname;
|
||||
postgresql.instances.peertube = {};
|
||||
redis.instances.peertube.port = 7599;
|
||||
};
|
||||
};
|
||||
nixos.services =
|
||||
{
|
||||
nginx.https.${peertube.hostname}.global.configName = peertube.hostname;
|
||||
postgresql.instances.peertube = {};
|
||||
redis.instances.peertube.port = 7599;
|
||||
};
|
||||
systemd.services.peertube.after = [ "redis-peertube.service" ];
|
||||
};
|
||||
|
||||
@@ -23,21 +23,24 @@ inputs:
|
||||
{
|
||||
after = [ "mariadb.service" ];
|
||||
requires = [ "mariadb.service" ];
|
||||
serviceConfig.EnvironmentFile = inputs.config.sops.templates."photoprism/env".path;
|
||||
serviceConfig.EnvironmentFile = inputs.config.nixos.system.sops.templates."photoprism/env".path;
|
||||
};
|
||||
sops =
|
||||
nixos =
|
||||
{
|
||||
templates."photoprism/env".content = let placeholder = inputs.config.sops.placeholder; in
|
||||
''
|
||||
PHOTOPRISM_ADMIN_PASSWORD=${placeholder."photoprism/adminPassword"}
|
||||
PHOTOPRISM_DATABASE_PASSWORD=${placeholder."mariadb/photoprism"}
|
||||
'';
|
||||
secrets."photoprism/adminPassword" = {};
|
||||
};
|
||||
nixos.services =
|
||||
{
|
||||
mariadb.instances.photoprism = {};
|
||||
nginx.https."photoprism.chn.moe".location."/".proxy = { upstream = "http://127.0.0.1:2342"; websocket = true; };
|
||||
system.sops =
|
||||
{
|
||||
templates."photoprism/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
|
||||
''
|
||||
PHOTOPRISM_ADMIN_PASSWORD=${placeholder."photoprism/adminPassword"}
|
||||
PHOTOPRISM_DATABASE_PASSWORD=${placeholder."mariadb/photoprism"}
|
||||
'';
|
||||
secrets."photoprism/adminPassword" = {};
|
||||
};
|
||||
services =
|
||||
{
|
||||
mariadb.instances.photoprism = {};
|
||||
nginx.https."photoprism.chn.moe".location."/".proxy = { upstream = "http://127.0.0.1:2342"; websocket = true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ inputs:
|
||||
let
|
||||
passwordFile =
|
||||
if db.value.passwordFile or null != null then db.value.passwordFile
|
||||
else inputs.config.sops.secrets."postgresql/${db.value.user}".path;
|
||||
else inputs.config.nixos.system.sops.secrets."postgresql/${db.value.user}".path;
|
||||
initializeFlag =
|
||||
if db.value.initializeFlags != {} then
|
||||
" WITH "
|
||||
@@ -85,7 +85,7 @@ inputs:
|
||||
+ " | grep -E '^${db.value.user}$' -q"
|
||||
+ " || $PSQL -tAc \"ALTER DATABASE ${db.value.database} OWNER TO ${db.value.user}\"")
|
||||
(inputs.localLib.attrsToList postgresql.instances)));
|
||||
sops.secrets = builtins.listToAttrs (builtins.map
|
||||
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
|
||||
(db: { name = "postgresql/${db.value.user}"; value.owner = inputs.config.users.users.postgres.name; })
|
||||
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList postgresql.instances)));
|
||||
environment.persistence."/nix/nodatacow".directories = inputs.lib.mkIf postgresql.nodatacow
|
||||
|
||||
@@ -28,12 +28,13 @@ inputs:
|
||||
# unixSocket = null; # bug
|
||||
unixSocketPerm = 600;
|
||||
requirePassFile =
|
||||
if server.value.passwordFile == null then inputs.config.sops.secrets."redis/${server.name}".path
|
||||
if server.value.passwordFile == null
|
||||
then inputs.config.nixos.system.sops.secrets."redis/${server.name}".path
|
||||
else server.value.passwordFile;
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList redis.instances));
|
||||
sops.secrets = builtins.listToAttrs (builtins.map
|
||||
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
|
||||
(server: { name = "redis/${server.name}"; value.owner = inputs.config.users.users.${server.value.user}.name; })
|
||||
(builtins.filter (server: server.value.passwordFile == null) (inputs.localLib.attrsToList redis.instances)));
|
||||
systemd.services = builtins.listToAttrs (builtins.map
|
||||
|
||||
@@ -15,34 +15,37 @@ inputs:
|
||||
image = "rsshub:latest";
|
||||
imageFile = inputs.topInputs.self.src.rsshub;
|
||||
ports = [ "127.0.0.1:5221:5221/tcp" ];
|
||||
environmentFiles = [ inputs.config.sops.templates."rsshub/env".path ];
|
||||
environmentFiles = [ inputs.config.nixos.system.sops.templates."rsshub/env".path ];
|
||||
};
|
||||
sops =
|
||||
nixos =
|
||||
{
|
||||
templates."rsshub/env".content = let placeholder = inputs.config.sops.placeholder; in
|
||||
''
|
||||
PORT=5221
|
||||
CACHE_TYPE=memory
|
||||
PIXIV_REFRESHTOKEN='${placeholder."rsshub/pixiv-refreshtoken"}'
|
||||
YOUTUBE_KEY='${placeholder."rsshub/youtube-key"}'
|
||||
YOUTUBE_CLIENT_ID='${placeholder."rsshub/youtube-client-id"}'
|
||||
YOUTUBE_CLIENT_SECRET='${placeholder."rsshub/youtube-client-secret"}'
|
||||
YOUTUBE_REFRESH_TOKEN='${placeholder."rsshub/youtube-refresh-token"}'
|
||||
TWITTER_AUTH_TOKEN='${placeholder."rsshub/twitter-auth-token"}'
|
||||
ZHIHU_COOKIES='${placeholder."rsshub/zhihu-cookies"}'
|
||||
XDG_CONFIG_HOME='/var/cache/rsshub/chromium'
|
||||
XDG_CACHE_HOME='/var/cache/rsshub/chromium'
|
||||
BILIBILI_COOKIE_data0='${placeholder."rsshub/bilibili-cookie"}'
|
||||
'';
|
||||
secrets = (builtins.listToAttrs (builtins.map (secret: { name = "rsshub/${secret}"; value = {}; })
|
||||
[
|
||||
"pixiv-refreshtoken"
|
||||
"youtube-key" "youtube-client-id" "youtube-client-secret" "youtube-refresh-token"
|
||||
"twitter-auth-token"
|
||||
"bilibili-cookie"
|
||||
"zhihu-cookies"
|
||||
]));
|
||||
system.sops =
|
||||
{
|
||||
templates."rsshub/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
|
||||
''
|
||||
PORT=5221
|
||||
CACHE_TYPE=memory
|
||||
PIXIV_REFRESHTOKEN='${placeholder."rsshub/pixiv-refreshtoken"}'
|
||||
YOUTUBE_KEY='${placeholder."rsshub/youtube-key"}'
|
||||
YOUTUBE_CLIENT_ID='${placeholder."rsshub/youtube-client-id"}'
|
||||
YOUTUBE_CLIENT_SECRET='${placeholder."rsshub/youtube-client-secret"}'
|
||||
YOUTUBE_REFRESH_TOKEN='${placeholder."rsshub/youtube-refresh-token"}'
|
||||
TWITTER_AUTH_TOKEN='${placeholder."rsshub/twitter-auth-token"}'
|
||||
ZHIHU_COOKIES='${placeholder."rsshub/zhihu-cookies"}'
|
||||
XDG_CONFIG_HOME='/var/cache/rsshub/chromium'
|
||||
XDG_CACHE_HOME='/var/cache/rsshub/chromium'
|
||||
BILIBILI_COOKIE_data0='${placeholder."rsshub/bilibili-cookie"}'
|
||||
'';
|
||||
secrets = (builtins.listToAttrs (builtins.map (secret: inputs.lib.nameValuePair "rsshub/${secret}" {})
|
||||
[
|
||||
"pixiv-refreshtoken"
|
||||
"youtube-key" "youtube-client-id" "youtube-client-secret" "youtube-refresh-token"
|
||||
"twitter-auth-token"
|
||||
"bilibili-cookie"
|
||||
"zhihu-cookies"
|
||||
]));
|
||||
};
|
||||
services.nginx.https.${rsshub.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5221";
|
||||
};
|
||||
nixos.services.nginx.https.${rsshub.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5221";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,16 +14,19 @@ inputs:
|
||||
{
|
||||
enable = true;
|
||||
settings.server = { port = 8081; bind_address = "127.0.0.1"; secret_key = "@SEARX_SECRET_KEY@"; };
|
||||
environmentFile = inputs.config.sops.templates."searx.env".path;
|
||||
environmentFile = inputs.config.nixos.system.sops.templates."searx.env".path;
|
||||
};
|
||||
sops =
|
||||
nixos =
|
||||
{
|
||||
templates."searx.env".content = let inherit (inputs.config.sops) placeholder; in
|
||||
''
|
||||
SEARX_SECRET_KEY=${placeholder."searx/secret-key"}
|
||||
'';
|
||||
secrets."searx/secret-key" = {};
|
||||
system.sops =
|
||||
{
|
||||
templates."searx.env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
|
||||
''
|
||||
SEARX_SECRET_KEY=${placeholder."searx/secret-key"}
|
||||
'';
|
||||
secrets."searx/secret-key" = {};
|
||||
};
|
||||
services.nginx.https.${searx.hostname}.location."/".proxy.upstream = "http://127.0.0.1:8081";
|
||||
};
|
||||
nixos.services.nginx.https.${searx.hostname}.location."/".proxy.upstream = "http://127.0.0.1:8081";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ inputs:
|
||||
createLocally = false;
|
||||
host = "127.0.0.1";
|
||||
port = 9184;
|
||||
passwordFile = inputs.config.sops.secrets."redis/send".path;
|
||||
passwordFile = inputs.config.nixos.system.sops.secrets."redis/send".path;
|
||||
};
|
||||
};
|
||||
systemd.services.send.after = [ "redis-send.service" ];
|
||||
|
||||
@@ -177,7 +177,7 @@ inputs:
|
||||
# ConstrainDevices=yes
|
||||
'';
|
||||
};
|
||||
munge = { enable = true; password = inputs.config.sops.secrets."munge.key".path; };
|
||||
munge = { enable = true; password = inputs.config.nixos.system.sops.secrets."munge.key".path; };
|
||||
};
|
||||
systemd.services.slurmd.environment =
|
||||
let gpus = slurm.node.${inputs.config.nixos.model.hostname}.gpus or null;
|
||||
@@ -186,12 +186,16 @@ inputs:
|
||||
CUDA_PATH = "${inputs.pkgs.cudatoolkit}";
|
||||
LD_LIBRARY_PATH = "${inputs.config.hardware.nvidia.package}/lib";
|
||||
};
|
||||
sops.secrets."munge.key" =
|
||||
nixos.system.sops.secrets."munge.key" =
|
||||
{
|
||||
format = "binary";
|
||||
sopsFile = inputs.localLib.mkConditional (inputs.config.nixos.model.cluster == null)
|
||||
"${builtins.dirOf inputs.config.sops.defaultSopsFile}/munge.key"
|
||||
"${inputs.config.nixos.system.sops.clusterSopsDir}/munge.key";
|
||||
sopsFile =
|
||||
let
|
||||
devicePath = "${inputs.topInputs.self}/devices";
|
||||
inherit (inputs.config.nixos) model;
|
||||
in inputs.localLib.mkConditional (model.cluster == null)
|
||||
"${devicePath}/${model.hostname}/secrets/munge.key"
|
||||
"${devicePath}/${model.cluster.clusterName}/secrets/munge.key";
|
||||
owner = inputs.config.systemd.services.munged.serviceConfig.User;
|
||||
};
|
||||
environment.sessionVariables = { SLURM_UNBUFFEREDIO = "1"; SLURM_CPU_BIND = "v"; };
|
||||
@@ -206,7 +210,7 @@ inputs:
|
||||
{
|
||||
enable = true;
|
||||
dbdHost = "localhost";
|
||||
storagePassFile = inputs.config.sops.secrets."slurm/db".path;
|
||||
storagePassFile = inputs.config.nixos.system.sops.secrets."slurm/db".path;
|
||||
extraConfig =
|
||||
''
|
||||
StorageHost=*
|
||||
@@ -224,24 +228,20 @@ inputs:
|
||||
services.slurmctld = { after = [ "suid-sgid-wrappers.service" ]; serviceConfig.MemorySwapMax = "0"; };
|
||||
tmpfiles.rules = [ "d /var/log/slurmctld 700 slurm slurm" ];
|
||||
};
|
||||
sops =
|
||||
nixos.system.sops =
|
||||
{
|
||||
secrets = { "slurm/db" = { owner = "slurm"; key = "mariadb/slurm"; }; }
|
||||
// builtins.listToAttrs (builtins.map
|
||||
(n:
|
||||
{
|
||||
name = "telegram/${n}";
|
||||
value.sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
|
||||
})
|
||||
(n: inputs.lib.nameValuePair "telegram/${n}" {})
|
||||
[ "token" "user/chn" "user/hjp" ]);
|
||||
templates."info.yaml" =
|
||||
{
|
||||
owner = "slurm";
|
||||
content = let inherit (inputs.config.sops) placeholder; in builtins.toJSON
|
||||
content = let inherit (inputs.config.nixos.system.sops) placeholder; in builtins.toJSON
|
||||
{
|
||||
token = placeholder."telegram/token";
|
||||
user = builtins.listToAttrs (builtins.map (n: { name = n; value = placeholder."telegram/user/${n}"; })
|
||||
[ "chn" "hjp" ]);
|
||||
user = builtins.listToAttrs (builtins.map
|
||||
(n: inputs.lib.nameValuePair n placeholder."telegram/user/${n}") [ "chn" "hjp" ]);
|
||||
slurmConf = "${inputs.config.services.slurm.etcSlurm}/slurm.conf";
|
||||
};
|
||||
};
|
||||
@@ -252,7 +252,7 @@ inputs:
|
||||
let info = inputs.pkgs.localPackages.info.override
|
||||
{
|
||||
slurm = inputs.config.services.slurm.package;
|
||||
configFile = inputs.config.sops.templates."info.yaml".path;
|
||||
configFile = inputs.config.nixos.system.sops.templates."info.yaml".path;
|
||||
};
|
||||
in "${info}/bin/info";
|
||||
program = "slurm-info";
|
||||
|
||||
24
modules/services/speedtest.nix
Normal file
24
modules/services/speedtest.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.speedtest = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
hostname = mkOption { type = types.nonEmptyStr; default = "409test.chn.moe"; };
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) speedtest; in inputs.lib.mkIf (speedtest != null)
|
||||
{
|
||||
nixos.services =
|
||||
{
|
||||
phpfpm.instances.speedtest = {};
|
||||
nginx.https.${speedtest.hostname} = let pkg = inputs.pkgs.localPackages.speedtest; in
|
||||
{
|
||||
global.root = "${pkg}";
|
||||
location."~ ^.+?\.php(/.*)?$".php =
|
||||
{ root = "${pkg}"; fastcgiPass = inputs.config.nixos.services.phpfpm.instances.speedtest.fastcgi; };
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -43,7 +43,7 @@ inputs:
|
||||
let
|
||||
package = inputs.pkgs.matrix-synapse.override
|
||||
{ extras = [ "url-preview" "postgres" "redis" ]; plugins = []; };
|
||||
config = inputs.config.sops.templates."synapse/${instance.name}/config.yaml".path;
|
||||
config = inputs.config.nixos.system.sops.templates."synapse/${instance.name}/config.yaml".path;
|
||||
homeserver = "${package}/bin/synapse_homeserver";
|
||||
in
|
||||
{
|
||||
@@ -100,143 +100,145 @@ inputs:
|
||||
];
|
||||
})
|
||||
(inputs.localLib.attrsToList synapse.instances));
|
||||
sops = inputs.lib.mkMerge (builtins.map
|
||||
(instance:
|
||||
{
|
||||
templates."synapse/${instance.name}/config.yaml" =
|
||||
{
|
||||
owner = "synapse-${instance.name}";
|
||||
group = "synapse-${instance.name}";
|
||||
content =
|
||||
let
|
||||
inherit (inputs.config.sops) placeholder;
|
||||
in builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "${instance.name}.yaml"
|
||||
{
|
||||
server_name = instance.value.matrixHostname;
|
||||
public_baseurl = "https://${instance.value.hostname}/";
|
||||
listeners =
|
||||
[{
|
||||
bind_addresses = [ "127.0.0.1" ];
|
||||
inherit (instance.value) port;
|
||||
resources = [{ names = [ "client" "federation" ]; compress = false; }];
|
||||
tls = false;
|
||||
type = "http";
|
||||
x_forwarded = true;
|
||||
}];
|
||||
database =
|
||||
{
|
||||
name = "psycopg2";
|
||||
args = let name = "synapse_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; in
|
||||
{
|
||||
user = name;
|
||||
password = placeholder."postgresql/${name}";
|
||||
database = name;
|
||||
host = "127.0.0.1";
|
||||
port = "5432";
|
||||
};
|
||||
allow_unsafe_locale = true;
|
||||
};
|
||||
redis =
|
||||
{
|
||||
enabled = true;
|
||||
port = instance.value.redisPort;
|
||||
password = placeholder."redis/synapse-${instance.name}";
|
||||
};
|
||||
turn_shared_secret = placeholder."synapse/${instance.name}/coturn";
|
||||
registration_shared_secret = placeholder."synapse/${instance.name}/registration";
|
||||
macaroon_secret_key = placeholder."synapse/${instance.name}/macaroon";
|
||||
form_secret = placeholder."synapse/${instance.name}/form";
|
||||
signing_key_path = inputs.config.sops.secrets."synapse/${instance.name}/signing-key".path;
|
||||
email =
|
||||
{
|
||||
smtp_host = "mail.chn.moe";
|
||||
smtp_port = 25;
|
||||
smtp_user = "bot@chn.moe";
|
||||
smtp_pass = placeholder."mail/bot";
|
||||
require_transport_security = true;
|
||||
notif_from = "Your Friendly %(app)s homeserver <bot@chn.moe>";
|
||||
app_name = "Haonan Chen's synapse";
|
||||
};
|
||||
admin_contact = "mailto:chn@chn.moe";
|
||||
enable_registration = true;
|
||||
registrations_require_3pid = [ "email" ];
|
||||
registration_requires_token = true;
|
||||
turn_uris = [ "turns:coturn.chn.moe" "turn:coturn.chn.moe" ];
|
||||
max_upload_size = "1024M";
|
||||
web_client_location = "https://element.chn.moe/";
|
||||
report_stats = true;
|
||||
trusted_key_servers =
|
||||
[{
|
||||
server_name = "matrix.org";
|
||||
verify_keys."ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
|
||||
}];
|
||||
suppress_key_server_warning = true;
|
||||
log_config = (inputs.pkgs.formats.yaml {}).generate "log.yaml"
|
||||
{
|
||||
version = 1;
|
||||
formatters.precise.format =
|
||||
"%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s";
|
||||
handlers.console = { class = "logging.StreamHandler"; formatter = "precise"; };
|
||||
root = { level = "INFO"; handlers = [ "console" ]; };
|
||||
disable_existing_loggers = true;
|
||||
};
|
||||
pid_file = "/run/synapse-${instance.name}.pid";
|
||||
media_store_path = "/var/lib/synapse/${instance.name}/media_store";
|
||||
presence.enabled = true;
|
||||
url_preview_enabled = true;
|
||||
url_preview_ip_range_blacklist =
|
||||
[
|
||||
"10.0.0.0/8" "100.64.0.0/10" "127.0.0.0/8" "169.254.0.0/16" "172.16.0.0/12" "192.0.0.0/24"
|
||||
"192.0.2.0/24" "192.168.0.0/16" "192.88.99.0/24" "198.18.0.0/15" "198.51.100.0/24" "2001:db8::/32"
|
||||
"203.0.113.0/24" "224.0.0.0/4" "::1/128" "fc00::/7" "fe80::/10" "fec0::/10" "ff00::/8"
|
||||
];
|
||||
max_image_pixels = "32M";
|
||||
dynamic_thumbnails = false;
|
||||
# this is required for displaying thumbnails in sticker widgets
|
||||
enable_authenticated_media = false;
|
||||
});
|
||||
};
|
||||
secrets = (builtins.listToAttrs (builtins.map
|
||||
(secret: { name = "synapse/${instance.name}/${secret}"; value = {}; })
|
||||
[ "coturn" "registration" "macaroon" "form" ]))
|
||||
// { "synapse/${instance.name}/signing-key".owner = "synapse-${instance.name}"; }
|
||||
// { "mail/bot" = {}; };
|
||||
})
|
||||
(inputs.localLib.attrsToList synapse.instances));
|
||||
nixos.services =
|
||||
nixos =
|
||||
{
|
||||
postgresql.instances = builtins.listToAttrs (builtins.map
|
||||
system.sops = inputs.lib.mkMerge (builtins.map
|
||||
(instance:
|
||||
{
|
||||
name = "synapse_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}";
|
||||
value.initializeFlags = { TEMPLATE = "template0"; LC_CTYPE = "C"; LC_COLLATE = "C"; };
|
||||
})
|
||||
(inputs.localLib.attrsToList synapse.instances));
|
||||
redis.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "synapse-${instance.name}"; value.port = instance.value.redisPort; })
|
||||
(inputs.localLib.attrsToList synapse.instances));
|
||||
nginx.https = builtins.listToAttrs (builtins.map
|
||||
(instance: with instance.value;
|
||||
{
|
||||
name = hostname;
|
||||
value.location =
|
||||
templates."synapse/${instance.name}/config.yaml" =
|
||||
{
|
||||
"/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
|
||||
"/.well-known/matrix/server".static =
|
||||
{
|
||||
root = builtins.toString (inputs.pkgs.writeTextFile
|
||||
owner = "synapse-${instance.name}";
|
||||
content =
|
||||
let
|
||||
inherit (inputs.config.nixos.system.sops) placeholder;
|
||||
in builtins.readFile ((inputs.pkgs.formats.yaml {}).generate "${instance.name}.yaml"
|
||||
{
|
||||
name = "server";
|
||||
text = builtins.toJSON
|
||||
server_name = instance.value.matrixHostname;
|
||||
public_baseurl = "https://${instance.value.hostname}/";
|
||||
listeners =
|
||||
[{
|
||||
bind_addresses = [ "127.0.0.1" ];
|
||||
inherit (instance.value) port;
|
||||
resources = [{ names = [ "client" "federation" ]; compress = false; }];
|
||||
tls = false;
|
||||
type = "http";
|
||||
x_forwarded = true;
|
||||
}];
|
||||
database =
|
||||
{
|
||||
"m.server" = "${hostname}:443";
|
||||
name = "psycopg2";
|
||||
args = let name = "synapse_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; in
|
||||
{
|
||||
user = name;
|
||||
password = placeholder."postgresql/${name}";
|
||||
database = name;
|
||||
host = "127.0.0.1";
|
||||
port = "5432";
|
||||
};
|
||||
allow_unsafe_locale = true;
|
||||
};
|
||||
destination = "/.well-known/matrix/server";
|
||||
redis =
|
||||
{
|
||||
enabled = true;
|
||||
port = instance.value.redisPort;
|
||||
password = placeholder."redis/synapse-${instance.name}";
|
||||
};
|
||||
turn_shared_secret = placeholder."synapse/${instance.name}/coturn";
|
||||
registration_shared_secret = placeholder."synapse/${instance.name}/registration";
|
||||
macaroon_secret_key = placeholder."synapse/${instance.name}/macaroon";
|
||||
form_secret = placeholder."synapse/${instance.name}/form";
|
||||
signing_key_path = inputs.config.nixos.system.sops.secrets."synapse/${instance.name}/signing-key".path;
|
||||
email =
|
||||
{
|
||||
smtp_host = "mail.chn.moe";
|
||||
smtp_port = 25;
|
||||
smtp_user = "bot@chn.moe";
|
||||
smtp_pass = placeholder."mail/bot";
|
||||
require_transport_security = true;
|
||||
notif_from = "Your Friendly %(app)s homeserver <bot@chn.moe>";
|
||||
app_name = "Haonan Chen's synapse";
|
||||
};
|
||||
admin_contact = "mailto:chn@chn.moe";
|
||||
enable_registration = true;
|
||||
registrations_require_3pid = [ "email" ];
|
||||
registration_requires_token = true;
|
||||
turn_uris = [ "turns:coturn.chn.moe" "turn:coturn.chn.moe" ];
|
||||
max_upload_size = "1024M";
|
||||
web_client_location = "https://element.chn.moe/";
|
||||
report_stats = true;
|
||||
trusted_key_servers =
|
||||
[{
|
||||
server_name = "matrix.org";
|
||||
verify_keys."ed25519:auto" = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
|
||||
}];
|
||||
suppress_key_server_warning = true;
|
||||
log_config = (inputs.pkgs.formats.yaml {}).generate "log.yaml"
|
||||
{
|
||||
version = 1;
|
||||
formatters.precise.format =
|
||||
"%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s";
|
||||
handlers.console = { class = "logging.StreamHandler"; formatter = "precise"; };
|
||||
root = { level = "INFO"; handlers = [ "console" ]; };
|
||||
disable_existing_loggers = true;
|
||||
};
|
||||
pid_file = "/run/synapse-${instance.name}.pid";
|
||||
media_store_path = "/var/lib/synapse/${instance.name}/media_store";
|
||||
presence.enabled = true;
|
||||
url_preview_enabled = true;
|
||||
url_preview_ip_range_blacklist =
|
||||
[
|
||||
"10.0.0.0/8" "100.64.0.0/10" "127.0.0.0/8" "169.254.0.0/16" "172.16.0.0/12" "192.0.0.0/24"
|
||||
"192.0.2.0/24" "192.168.0.0/16" "192.88.99.0/24" "198.18.0.0/15" "198.51.100.0/24" "2001:db8::/32"
|
||||
"203.0.113.0/24" "224.0.0.0/4" "::1/128" "fc00::/7" "fe80::/10" "fec0::/10" "ff00::/8"
|
||||
];
|
||||
max_image_pixels = "32M";
|
||||
dynamic_thumbnails = false;
|
||||
# this is required for displaying thumbnails in sticker widgets
|
||||
enable_authenticated_media = false;
|
||||
});
|
||||
};
|
||||
};
|
||||
secrets = (builtins.listToAttrs (builtins.map
|
||||
(secret: { name = "synapse/${instance.name}/${secret}"; value = {}; })
|
||||
[ "coturn" "registration" "macaroon" "form" ]))
|
||||
// { "synapse/${instance.name}/signing-key".owner = "synapse-${instance.name}"; }
|
||||
// { "mail/bot" = {}; };
|
||||
})
|
||||
(inputs.localLib.attrsToList synapse.instances));
|
||||
services =
|
||||
{
|
||||
postgresql.instances = builtins.listToAttrs (builtins.map
|
||||
(instance:
|
||||
{
|
||||
name = "synapse_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}";
|
||||
value.initializeFlags = { TEMPLATE = "template0"; LC_CTYPE = "C"; LC_COLLATE = "C"; };
|
||||
})
|
||||
(inputs.localLib.attrsToList synapse.instances));
|
||||
redis.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "synapse-${instance.name}"; value.port = instance.value.redisPort; })
|
||||
(inputs.localLib.attrsToList synapse.instances));
|
||||
nginx.https = builtins.listToAttrs (builtins.map
|
||||
(instance: with instance.value;
|
||||
{
|
||||
name = hostname;
|
||||
value.location =
|
||||
{
|
||||
"/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
|
||||
"/.well-known/matrix/server".static =
|
||||
{
|
||||
root = builtins.toString (inputs.pkgs.writeTextFile
|
||||
{
|
||||
name = "server";
|
||||
text = builtins.toJSON
|
||||
{
|
||||
"m.server" = "${hostname}:443";
|
||||
};
|
||||
destination = "/.well-known/matrix/server";
|
||||
});
|
||||
};
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList synapse.instances));
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,29 +25,32 @@ inputs:
|
||||
SMTP_SECURITY = "force_tls";
|
||||
SMTP_USERNAME = "bot@chn.moe";
|
||||
};
|
||||
environmentFile = inputs.config.sops.templates."vaultwarden.env".path;
|
||||
environmentFile = inputs.config.nixos.system.sops.templates."vaultwarden.env".path;
|
||||
};
|
||||
sops =
|
||||
nixos =
|
||||
{
|
||||
templates."vaultwarden.env" = let placeholder = inputs.config.sops.placeholder; in
|
||||
system.sops =
|
||||
{
|
||||
owner = "vaultwarden";
|
||||
group = "vaultwarden";
|
||||
content =
|
||||
''
|
||||
DATABASE_URL=postgresql://vaultwarden:${placeholder."postgresql/vaultwarden"}@localhost/vaultwarden
|
||||
ADMIN_TOKEN=${placeholder."vaultwarden/admin_token"}
|
||||
SMTP_PASSWORD=${placeholder."mail/bot"}
|
||||
'';
|
||||
templates."vaultwarden.env" = let inherit (inputs.config.nixos.system.sops) placeholder; in
|
||||
{
|
||||
owner = "vaultwarden";
|
||||
group = "vaultwarden";
|
||||
content =
|
||||
''
|
||||
DATABASE_URL=postgresql://vaultwarden:${placeholder."postgresql/vaultwarden"}@localhost/vaultwarden
|
||||
ADMIN_TOKEN=${placeholder."vaultwarden/admin_token"}
|
||||
SMTP_PASSWORD=${placeholder."mail/bot"}
|
||||
'';
|
||||
};
|
||||
secrets = { "vaultwarden/admin_token" = {}; "mail/bot" = {}; };
|
||||
};
|
||||
services =
|
||||
{
|
||||
postgresql.instances.vaultwarden = {};
|
||||
nginx.https.${vaultwarden.hostname}.location."/".proxy =
|
||||
{ upstream = "http://127.0.0.1:8000"; websocket = true; };
|
||||
};
|
||||
secrets = { "vaultwarden/admin_token" = {}; "mail/bot" = {}; };
|
||||
};
|
||||
systemd.services.vaultwarden.after = [ "postgresql.service" ];
|
||||
nixos.services =
|
||||
{
|
||||
postgresql.instances.vaultwarden = {};
|
||||
nginx.https.${vaultwarden.hostname}.location."/".proxy =
|
||||
{ upstream = "http://127.0.0.1:8000"; websocket = true; };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ inputs:
|
||||
{
|
||||
inherit (wg.value) listenPort;
|
||||
ips = [ "${wg.value.ip}/${builtins.toString wg.value.netmask}" ];
|
||||
privateKeyFile = inputs.config.sops.secrets.wireguard.path;
|
||||
privateKeyFile = inputs.config.nixos.system.sops.secrets.wireguard.path;
|
||||
peers = builtins.map
|
||||
(peer:
|
||||
{
|
||||
@@ -45,6 +45,6 @@ inputs:
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList wireguard));
|
||||
sops.secrets.wireguard = {};
|
||||
nixos.system.sops.secrets.wireguard = {};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ inputs:
|
||||
};
|
||||
resolved.enable = false;
|
||||
};
|
||||
sops =
|
||||
nixos.system.sops =
|
||||
{
|
||||
templates."xray-client.json" =
|
||||
{
|
||||
@@ -120,7 +120,7 @@ inputs:
|
||||
port = 443;
|
||||
users =
|
||||
[{
|
||||
id = inputs.config.sops.placeholder."xray-client/uuid";
|
||||
id = inputs.config.nixos.system.sops.placeholder."xray-client/uuid";
|
||||
encryption = "none";
|
||||
flow = "xtls-rprx-vision-udp443";
|
||||
}];
|
||||
@@ -173,45 +173,63 @@ inputs:
|
||||
};
|
||||
secrets."xray-client/uuid" = {};
|
||||
};
|
||||
systemd.services =
|
||||
systemd =
|
||||
{
|
||||
xray-client =
|
||||
{
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = "exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-client.json".path}";
|
||||
serviceConfig =
|
||||
services = inputs.lib.mkMerge
|
||||
[
|
||||
{
|
||||
User = "v2ray";
|
||||
Group = "v2ray";
|
||||
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||||
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||||
NoNewPrivileges = true;
|
||||
LimitNPROC = 65536;
|
||||
LimitNOFILE = 524288;
|
||||
CPUSchedulingPolicy = "rr";
|
||||
};
|
||||
restartTriggers = [ inputs.config.sops.templates."xray-client.json".file ];
|
||||
};
|
||||
v2ray-forwarder =
|
||||
{
|
||||
description = "v2ray-forwarder Daemon";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = let ip = "${inputs.pkgs.iproute2}/bin/ip"; in
|
||||
xray-client =
|
||||
{
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script = let config = inputs.config.nixos.system.sops.templates."xray-client.json".path; in
|
||||
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
|
||||
serviceConfig =
|
||||
{
|
||||
User = "v2ray";
|
||||
Group = "v2ray";
|
||||
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||||
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||||
NoNewPrivileges = true;
|
||||
LimitNPROC = 65536;
|
||||
LimitNOFILE = 524288;
|
||||
CPUSchedulingPolicy = "rr";
|
||||
};
|
||||
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-client.json".file ];
|
||||
};
|
||||
}
|
||||
(inputs.lib.mkIf (inputs.config.nixos.system.network == null)
|
||||
{
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = inputs.pkgs.writeShellScript "v2ray-forwarder.start"
|
||||
''
|
||||
${ip} rule add fwmark 1/1 table 100
|
||||
${ip} route add local 0.0.0.0/0 dev lo table 100
|
||||
'';
|
||||
ExecStop = inputs.pkgs.writeShellScript "v2ray-forwarder.stop"
|
||||
''
|
||||
${ip} rule del fwmark 1/1 table 100
|
||||
${ip} route del local 0.0.0.0/0 dev lo table 100
|
||||
'';
|
||||
v2ray-forwarder =
|
||||
{
|
||||
description = "v2ray-forwarder Daemon";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = let ip = "${inputs.pkgs.iproute2}/bin/ip"; in
|
||||
{
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = inputs.pkgs.writeShellScript "v2ray-forwarder.start"
|
||||
''
|
||||
${ip} rule add fwmark 1/1 table 100
|
||||
${ip} route add local 0.0.0.0/0 dev lo table 100
|
||||
'';
|
||||
ExecStop = inputs.pkgs.writeShellScript "v2ray-forwarder.stop"
|
||||
''
|
||||
${ip} rule del fwmark 1/1 table 100
|
||||
${ip} route del local 0.0.0.0/0 dev lo table 100
|
||||
'';
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
network.networks = inputs.lib.mkIf (inputs.config.nixos.system.network != null)
|
||||
{
|
||||
"10-custom" =
|
||||
{
|
||||
matchConfig.Name = "lo";
|
||||
routes = [{ Table = 100; Destination = "0.0.0.0/0"; Type = "local"; }];
|
||||
routingPolicyRules = [{ FirewallMark = "1/1"; Table = 100; }];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -10,136 +10,144 @@ inputs:
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services.xray) server; in inputs.lib.mkIf (server != null)
|
||||
(
|
||||
let userList = builtins.attrNames
|
||||
(inputs.pkgs.localPackages.fromYaml (builtins.readFile inputs.config.sops.defaultSopsFile)).xray-server.clients;
|
||||
let userList = builtins.map (user: builtins.elemAt user 2) (builtins.filter
|
||||
(user: builtins.length user == 3 && inputs.lib.lists.hasPrefix [ "xray-server" "clients" ] user)
|
||||
inputs.config.nixos.system.sops.availableKeys);
|
||||
in
|
||||
{
|
||||
sops =
|
||||
nixos =
|
||||
{
|
||||
templates."xray-server.json" =
|
||||
system.sops =
|
||||
{
|
||||
owner = inputs.config.users.users.v2ray.name;
|
||||
group = inputs.config.users.users.v2ray.group;
|
||||
content = builtins.toJSON
|
||||
templates."xray-server.json" =
|
||||
{
|
||||
log.loglevel = "warning";
|
||||
inbounds =
|
||||
[
|
||||
(
|
||||
let fallbackPort = builtins.toString
|
||||
(with inputs.config.nixos.services.nginx.global; httpsPort + httpsPortShift.http2);
|
||||
in
|
||||
owner = inputs.config.users.users.v2ray.name;
|
||||
group = inputs.config.users.users.v2ray.group;
|
||||
content = builtins.toJSON
|
||||
{
|
||||
log.loglevel = "warning";
|
||||
inbounds =
|
||||
[
|
||||
(
|
||||
let fallbackPort = builtins.toString
|
||||
(with inputs.config.nixos.services.nginx.global; httpsPort + httpsPortShift.http2);
|
||||
in
|
||||
{
|
||||
port = 4726;
|
||||
listen = "127.0.0.1";
|
||||
protocol = "vless";
|
||||
settings =
|
||||
{
|
||||
clients = builtins.map
|
||||
(n:
|
||||
{
|
||||
id = inputs.config.nixos.system.sops.placeholder."xray-server/clients/${n}";
|
||||
flow = "xtls-rprx-vision";
|
||||
email = "${n}@xray.chn.moe";
|
||||
})
|
||||
userList;
|
||||
decryption = "none";
|
||||
fallbacks = [{ dest = "127.0.0.1:${fallbackPort}"; }];
|
||||
};
|
||||
streamSettings =
|
||||
{
|
||||
network = "raw";
|
||||
security = "reality";
|
||||
realitySettings =
|
||||
{
|
||||
dest = "127.0.0.1:${fallbackPort}";
|
||||
serverNames = [ server.serverName ];
|
||||
privateKey = inputs.config.nixos.system.sops.placeholder."xray-server/private-key";
|
||||
minClientVer = "1.8.0";
|
||||
shortIds = [ "" ];
|
||||
};
|
||||
};
|
||||
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; routeOnly = true; };
|
||||
tag = "in-legacy";
|
||||
}
|
||||
)
|
||||
{
|
||||
port = 4726;
|
||||
port = 4638;
|
||||
listen = "127.0.0.1";
|
||||
protocol = "vless";
|
||||
settings =
|
||||
{
|
||||
clients = builtins.map
|
||||
(n:
|
||||
{
|
||||
id = inputs.config.sops.placeholder."xray-server/clients/${n}";
|
||||
flow = "xtls-rprx-vision";
|
||||
email = "${n}@xray.chn.moe";
|
||||
})
|
||||
userList;
|
||||
decryption = "none";
|
||||
fallbacks = [{ dest = "127.0.0.1:${fallbackPort}"; }];
|
||||
};
|
||||
streamSettings =
|
||||
{
|
||||
network = "raw";
|
||||
security = "reality";
|
||||
realitySettings =
|
||||
{
|
||||
dest = "127.0.0.1:${fallbackPort}";
|
||||
serverNames = [ server.serverName ];
|
||||
privateKey = inputs.config.sops.placeholder."xray-server/private-key";
|
||||
minClientVer = "1.8.0";
|
||||
shortIds = [ "" ];
|
||||
};
|
||||
};
|
||||
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; routeOnly = true; };
|
||||
tag = "in-legacy";
|
||||
settings = { clients = [{ id = "be01f0a0-9976-42f5-b9ab-866eba6ed393"; }]; decryption = "none"; };
|
||||
streamSettings.network = "raw";
|
||||
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; };
|
||||
tag = "in-localdns";
|
||||
}
|
||||
)
|
||||
{
|
||||
port = 4638;
|
||||
listen = "127.0.0.1";
|
||||
protocol = "vless";
|
||||
settings = { clients = [{ id = "be01f0a0-9976-42f5-b9ab-866eba6ed393"; }]; decryption = "none"; };
|
||||
streamSettings.network = "raw";
|
||||
sniffing = { enabled = true; destOverride = [ "http" "tls" "quic" ]; };
|
||||
tag = "in-localdns";
|
||||
}
|
||||
{
|
||||
listen = "127.0.0.1";
|
||||
port = 6149;
|
||||
protocol = "dokodemo-door";
|
||||
settings.address = "127.0.0.1";
|
||||
tag = "api";
|
||||
}
|
||||
];
|
||||
outbounds =
|
||||
[
|
||||
{ protocol = "freedom"; tag = "freedom"; }
|
||||
{
|
||||
protocol = "vless";
|
||||
settings.vnext =
|
||||
[{
|
||||
address = "127.0.0.1";
|
||||
port = 4638;
|
||||
users = [{ id = "be01f0a0-9976-42f5-b9ab-866eba6ed393"; encryption = "none"; }];
|
||||
}];
|
||||
streamSettings.network = "raw";
|
||||
tag = "loopback-localdns";
|
||||
}
|
||||
];
|
||||
routing =
|
||||
{
|
||||
domainStrategy = "AsIs";
|
||||
rules = builtins.map (rule: rule // { type = "field"; })
|
||||
[
|
||||
{
|
||||
inboundTag = [ "in-legacy" ];
|
||||
domain = [ "domain:openai.com" ];
|
||||
outboundTag = "loopback-localdns";
|
||||
listen = "127.0.0.1";
|
||||
port = 6149;
|
||||
protocol = "dokodemo-door";
|
||||
settings.address = "127.0.0.1";
|
||||
tag = "api";
|
||||
}
|
||||
{ inboundTag = [ "in-legacy" ]; outboundTag = "freedom"; }
|
||||
{ inboundTag = [ "in-localdns" ]; outboundTag = "freedom"; }
|
||||
{ inboundTag = [ "api" ]; outboundTag = "api"; }
|
||||
];
|
||||
};
|
||||
stats = {};
|
||||
api = { tag = "api"; services = [ "StatsService" ]; };
|
||||
policy =
|
||||
{
|
||||
levels."0" = { statsUserUplink = true; statsUserDownlink = true; };
|
||||
system =
|
||||
outbounds =
|
||||
[
|
||||
{ protocol = "freedom"; tag = "freedom"; }
|
||||
{
|
||||
protocol = "vless";
|
||||
settings.vnext =
|
||||
[{
|
||||
address = "127.0.0.1";
|
||||
port = 4638;
|
||||
users = [{ id = "be01f0a0-9976-42f5-b9ab-866eba6ed393"; encryption = "none"; }];
|
||||
}];
|
||||
streamSettings.network = "raw";
|
||||
tag = "loopback-localdns";
|
||||
}
|
||||
];
|
||||
routing =
|
||||
{
|
||||
statsInboundUplink = true;
|
||||
statsInboundDownlink = true;
|
||||
statsOutboundUplink = true;
|
||||
statsOutboundDownlink = true;
|
||||
domainStrategy = "AsIs";
|
||||
rules = builtins.map (rule: rule // { type = "field"; })
|
||||
[
|
||||
{
|
||||
inboundTag = [ "in-legacy" ];
|
||||
domain = [ "domain:openai.com" ];
|
||||
outboundTag = "loopback-localdns";
|
||||
}
|
||||
{ inboundTag = [ "in-legacy" ]; outboundTag = "freedom"; }
|
||||
{ inboundTag = [ "in-localdns" ]; outboundTag = "freedom"; }
|
||||
{ inboundTag = [ "api" ]; outboundTag = "api"; }
|
||||
];
|
||||
};
|
||||
stats = {};
|
||||
api = { tag = "api"; services = [ "StatsService" ]; };
|
||||
policy =
|
||||
{
|
||||
levels."0" = { statsUserUplink = true; statsUserDownlink = true; };
|
||||
system =
|
||||
{
|
||||
statsInboundUplink = true;
|
||||
statsInboundDownlink = true;
|
||||
statsOutboundUplink = true;
|
||||
statsOutboundDownlink = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
secrets = builtins.listToAttrs
|
||||
(builtins.map (n: inputs.lib.nameValuePair "xray-server/clients/${n}" {}) userList)
|
||||
// (builtins.listToAttrs (builtins.map
|
||||
(name: inputs.lib.nameValuePair "telegram/${name}" { group = "telegram"; mode = "0440"; })
|
||||
[ "token" "user/chn" ]))
|
||||
// { "xray-server/private-key" = {}; };
|
||||
};
|
||||
secrets = builtins.listToAttrs
|
||||
(builtins.map (n: { name = "xray-server/clients/${n}"; value = {}; }) userList)
|
||||
// (builtins.listToAttrs (builtins.map
|
||||
(name:
|
||||
services =
|
||||
{
|
||||
acme.cert.${server.serverName}.group = inputs.config.users.users.nginx.group;
|
||||
nginx =
|
||||
{
|
||||
transparentProxy.map.${server.serverName} = 4726;
|
||||
https.${server.serverName} =
|
||||
{
|
||||
name = "telegram/${name}";
|
||||
value =
|
||||
{
|
||||
group = "telegram";
|
||||
mode = "0440";
|
||||
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
|
||||
};
|
||||
})
|
||||
[ "token" "user/chn" ]))
|
||||
// { "xray-server/private-key" = {}; };
|
||||
listen.main = { proxyProtocol = false; addToTransparentProxy = false; };
|
||||
location."/".return.return = "400";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
systemd =
|
||||
{
|
||||
@@ -149,8 +157,8 @@ inputs:
|
||||
{
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script =
|
||||
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-server.json".path}";
|
||||
script = let config = inputs.config.nixos.system.sops.templates."xray-server.json".path; in
|
||||
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
|
||||
serviceConfig =
|
||||
{
|
||||
User = "v2ray";
|
||||
@@ -160,7 +168,7 @@ inputs:
|
||||
LimitNPROC = 65536;
|
||||
LimitNOFILE = 524288;
|
||||
};
|
||||
restartTriggers = [ inputs.config.sops.templates."xray-server.json".file ];
|
||||
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-server.json".file ];
|
||||
};
|
||||
xray-stat =
|
||||
{
|
||||
@@ -172,8 +180,8 @@ inputs:
|
||||
jq = "${inputs.pkgs.jq}/bin/jq";
|
||||
sed = "${inputs.pkgs.gnused}/bin/sed";
|
||||
cat = "${inputs.pkgs.coreutils}/bin/cat";
|
||||
token = inputs.config.sops.secrets."telegram/token".path;
|
||||
chat = inputs.config.sops.secrets."telegram/user/chn".path;
|
||||
token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
|
||||
chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
|
||||
in
|
||||
''
|
||||
message='${inputs.config.nixos.model.hostname} xray:\n'
|
||||
@@ -216,19 +224,6 @@ inputs:
|
||||
telegram.gid = inputs.config.nixos.user.gid.telegram;
|
||||
};
|
||||
};
|
||||
nixos.services =
|
||||
{
|
||||
acme.cert.${server.serverName}.group = inputs.config.users.users.nginx.group;
|
||||
nginx =
|
||||
{
|
||||
transparentProxy.map.${server.serverName} = 4726;
|
||||
https.${server.serverName} =
|
||||
{
|
||||
listen.main = { proxyProtocol = false; addToTransparentProxy = false; };
|
||||
location."/".return.return = "400";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ inputs:
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services.xray) xmuClient; in inputs.lib.mkIf (xmuClient != null)
|
||||
{
|
||||
sops =
|
||||
nixos.system.sops =
|
||||
{
|
||||
templates."xray-xmu-client.json" =
|
||||
{
|
||||
@@ -37,7 +37,8 @@ inputs:
|
||||
[{
|
||||
address = "webvpn.xmu.edu.cn";
|
||||
port = 443;
|
||||
users = [{ id = inputs.config.sops.placeholder."xray-xmu-client/uuid"; encryption = "none"; }];
|
||||
users =
|
||||
[{ id = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/uuid"; encryption = "none"; }];
|
||||
}];
|
||||
streamSettings =
|
||||
{
|
||||
@@ -45,24 +46,12 @@ inputs:
|
||||
security = "tls";
|
||||
xhttpSettings =
|
||||
{
|
||||
path =
|
||||
let
|
||||
inherit (xmuClient) hostname;
|
||||
paddedLength = ((builtins.div ((builtins.stringLength hostname) - 1) 16) + 1) * 16;
|
||||
paddedString = builtins.concatStringsSep ""
|
||||
(builtins.genList
|
||||
(n: if n < builtins.stringLength hostname then builtins.substring n 1 hostname else "0")
|
||||
paddedLength);
|
||||
paddedHex = inputs.pkgs.localPackages.aes128CfbHex
|
||||
{ data = hostname; key = "wrdvpnisthebest!"; iv = "wrdvpnisthebest!"; };
|
||||
prefix = builtins.concatStringsSep "" (builtins.map
|
||||
(c: inputs.lib.toHexString (inputs.lib.strings.charToInt c))
|
||||
(inputs.lib.stringToCharacters "wrdvpnisthebest!"));
|
||||
in "/https/${prefix}${paddedHex}/xsession";
|
||||
path = "${inputs.pkgs.localPackages.webvpnPath xmuClient.hostname}/xsession";
|
||||
mode = "packet-up";
|
||||
security = "tls";
|
||||
extra.headers.Cookie = "show_vpn=0; heartbeat=1; show_faq=0; "
|
||||
+ "wengine_vpn_ticketwebvpn_xmu_edu_cn=${inputs.config.sops.placeholder."xray-xmu-client/cookie"}";
|
||||
extra.headers.Cookie =
|
||||
let ticket = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/cookie";
|
||||
in "show_vpn=0; heartbeat=1; show_faq=0; wengine_vpn_ticketwebvpn_xmu_edu_cn=${ticket}";
|
||||
};
|
||||
tlsSettings.alpn = [ "http/1.1" ];
|
||||
};
|
||||
@@ -77,8 +66,8 @@ inputs:
|
||||
{
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script =
|
||||
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-xmu-client.json".path}";
|
||||
script = let config = inputs.config.nixos.system.sops.templates."xray-xmu-client.json".path; in
|
||||
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
|
||||
serviceConfig =
|
||||
{
|
||||
User = "v2ray";
|
||||
@@ -90,7 +79,7 @@ inputs:
|
||||
LimitNOFILE = 524288;
|
||||
CPUSchedulingPolicy = "rr";
|
||||
};
|
||||
restartTriggers = [ inputs.config.sops.templates."xray-xmu-client.json".file ];
|
||||
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-xmu-client.json".file ];
|
||||
};
|
||||
};
|
||||
users =
|
||||
|
||||
57
modules/services/xray/xmuPersist.nix
Normal file
57
modules/services/xray/xmuPersist.nix
Normal file
@@ -0,0 +1,57 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.xray.xmuPersist = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule (submoduleInputs: { options =
|
||||
{
|
||||
keepAliveHost = mkOption { type = types.nonEmptyStr; default = "blog.chn.moe"; };
|
||||
};}));
|
||||
default = null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services.xray) xmuPersist; in inputs.lib.mkIf (xmuPersist != null)
|
||||
{
|
||||
nixos.system.sops =
|
||||
{
|
||||
templates."xray-xmu-persist-cookie.txt" =
|
||||
{
|
||||
owner = inputs.config.users.users.v2ray.name;
|
||||
group = inputs.config.users.users.v2ray.group;
|
||||
content = let cookie = inputs.config.nixos.system.sops.placeholder."xray-xmu-client/cookie"; in
|
||||
''
|
||||
.webvpn.xmu.edu.cn TRUE / TRUE 0 wengine_vpn_ticketwebvpn_xmu_edu_cn ${cookie}
|
||||
webvpn.xmu.edu.cn FALSE / TRUE 0 show_vpn 0
|
||||
webvpn.xmu.edu.cn FALSE / TRUE 0 heartbeat 1
|
||||
webvpn.xmu.edu.cn FALSE / TRUE 0 show_faq 0
|
||||
webvpn.xmu.edu.cn FALSE / FALSE 0 refresh 0
|
||||
'';
|
||||
};
|
||||
secrets."xray-xmu-client/cookie" = {};
|
||||
};
|
||||
systemd =
|
||||
{
|
||||
services.xray-xmu-persist =
|
||||
{
|
||||
script =
|
||||
let
|
||||
curl = "${inputs.pkgs.curl}/bin/curl";
|
||||
cookie = inputs.config.nixos.system.sops.templates."xray-xmu-persist-cookie.txt".path;
|
||||
in
|
||||
''
|
||||
${curl} -s -o /dev/null -w "%{http_code}\n" -b ${cookie} \
|
||||
"https://webvpn.xmu.edu.cn${inputs.pkgs.localPackages.webvpnPath xmuPersist.keepAliveHost}/";
|
||||
'';
|
||||
serviceConfig = { Type = "oneshot"; User = "v2ray"; Group = "v2ray"; };
|
||||
};
|
||||
timers.xray-xmu-persist =
|
||||
{
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = { OnCalendar = "*-*-* *:*:00"; Unit = "xray-xmu-persist.service"; };
|
||||
};
|
||||
};
|
||||
users =
|
||||
{
|
||||
users.v2ray = { uid = inputs.config.nixos.user.uid.v2ray; group = "v2ray"; isSystemUser = true; };
|
||||
groups.v2ray.gid = inputs.config.nixos.user.gid.v2ray;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -10,12 +10,11 @@ inputs:
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services.xray) xmuServer; in inputs.lib.mkIf (xmuServer != null)
|
||||
{
|
||||
sops =
|
||||
nixos.system.sops =
|
||||
{
|
||||
templates."xray-xmu-server.json" =
|
||||
{
|
||||
owner = inputs.config.users.users.v2ray.name;
|
||||
group = inputs.config.users.users.v2ray.group;
|
||||
content = builtins.toJSON
|
||||
{
|
||||
log.loglevel = "warning";
|
||||
@@ -24,8 +23,12 @@ inputs:
|
||||
port = 4727;
|
||||
listen = "127.0.0.1";
|
||||
protocol = "vless";
|
||||
settings = { clients = [{ id = inputs.config.sops.placeholder."xray-xmu-server"; }]; decryption = "none"; };
|
||||
streamSettings = { network = "xhttp"; xhttpSettings = { mode = "stream-one"; path = "/xsession"; }; };
|
||||
settings =
|
||||
{
|
||||
clients = [{ id = inputs.config.nixos.system.sops.placeholder."xray-xmu-server"; }];
|
||||
decryption = "none";
|
||||
};
|
||||
streamSettings = { network = "xhttp"; xhttpSettings = { mode = "packet-up"; path = "/xsession"; }; };
|
||||
tag = "in";
|
||||
}];
|
||||
outbounds = [{ protocol = "freedom"; tag = "freedom"; }];
|
||||
@@ -37,8 +40,8 @@ inputs:
|
||||
{
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
script =
|
||||
"exec ${inputs.pkgs.xray}/bin/xray -config ${inputs.config.sops.templates."xray-xmu-server.json".path}";
|
||||
script = let config = inputs.config.nixos.system.sops.templates."xray-xmu-server.json".path; in
|
||||
"exec ${inputs.pkgs.xray}/bin/xray -config ${config}";
|
||||
serviceConfig =
|
||||
{
|
||||
User = "v2ray";
|
||||
@@ -49,7 +52,7 @@ inputs:
|
||||
LimitNPROC = 65536;
|
||||
LimitNOFILE = 524288;
|
||||
};
|
||||
restartTriggers = [ inputs.config.sops.templates."xray-xmu-server.json".file ];
|
||||
restartTriggers = [ inputs.config.nixos.system.sops.templates."xray-xmu-server.json".file ];
|
||||
};
|
||||
users =
|
||||
{
|
||||
|
||||
@@ -85,6 +85,7 @@ inputs:
|
||||
kernelParams = [ "resume_offset=${builtins.toString fileSystems.resume.offset}" ];
|
||||
};
|
||||
nixos.system.kernel.patches = [ "hibernate-progress" ];
|
||||
systemd.sleep.extraConfig = "HibernateMode=reboot";
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,80 +1,87 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.system.grub = let inherit (inputs.lib) mkOption types; in
|
||||
options.nixos.system.grub = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
timeout = mkOption { type = types.int; default = 15; };
|
||||
windowsEntries = mkOption { type = types.attrsOf types.nonEmptyStr; default = {}; };
|
||||
# "efi" using efi, "efiRemovable" using efi with install grub removable, or dev path like "/dev/sda" using bios
|
||||
installDevice = mkOption { type = types.str; default = "efi"; };
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
timeout = mkOption { type = types.int; default = 15; };
|
||||
windowsEntries = mkOption { type = types.attrsOf types.nonEmptyStr; default = {}; };
|
||||
# "efi" using efi, "efiRemovable" using efi with install grub removable, or dev path like "/dev/sda" using bios
|
||||
installDevice = mkOption { type = types.str; default = "efi"; };
|
||||
};});
|
||||
# use grub as default, if disabled, use uboot
|
||||
default = {};
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.system) grub; in inputs.lib.mkMerge
|
||||
[
|
||||
# general settings
|
||||
{ boot.loader.grub = { enable = true; useOSProber = false; }; }
|
||||
# grub timeout
|
||||
{ boot.loader.timeout = grub.timeout; }
|
||||
# grub install
|
||||
{
|
||||
boot.loader =
|
||||
config = let inherit (inputs.config.nixos.system) grub; in inputs.localLib.mkConditional (grub != null)
|
||||
(inputs.lib.mkMerge
|
||||
[
|
||||
# general settings
|
||||
{ boot.loader.grub = { enable = true; useOSProber = false; }; }
|
||||
# grub timeout
|
||||
{ boot.loader.timeout = grub.timeout; }
|
||||
# grub install
|
||||
{
|
||||
grub =
|
||||
boot.loader =
|
||||
{
|
||||
device = if builtins.elem grub.installDevice [ "efi" "efiRemovable" ] then "nodev" else grub.installDevice;
|
||||
efiSupport = builtins.elem grub.installDevice [ "efi" "efiRemovable" ];
|
||||
efiInstallAsRemovable = grub.installDevice == "efiRemovable";
|
||||
grub =
|
||||
{
|
||||
device = if builtins.elem grub.installDevice [ "efi" "efiRemovable" ] then "nodev" else grub.installDevice;
|
||||
efiSupport = builtins.elem grub.installDevice [ "efi" "efiRemovable" ];
|
||||
efiInstallAsRemovable = grub.installDevice == "efiRemovable";
|
||||
};
|
||||
efi.canTouchEfiVariables = grub.installDevice == "efi";
|
||||
};
|
||||
efi.canTouchEfiVariables = grub.installDevice == "efi";
|
||||
};
|
||||
}
|
||||
# extra grub entries
|
||||
{
|
||||
boot.loader.grub =
|
||||
}
|
||||
# extra grub entries
|
||||
{
|
||||
memtest86.enable = true;
|
||||
extraFiles = inputs.lib.mkIf (builtins.elem grub.installDevice [ "efi" "efiRemovable" ])
|
||||
{ "shell.efi" = "${inputs.pkgs.genericPackages.edk2-uefi-shell}/shell.efi"; };
|
||||
extraEntries = inputs.lib.mkMerge (builtins.concatLists
|
||||
[
|
||||
(builtins.map
|
||||
(system:
|
||||
''
|
||||
menuentry "${system.value}" {
|
||||
insmod part_gpt
|
||||
insmod fat
|
||||
insmod search_fs_uuid
|
||||
insmod chain
|
||||
search --fs-uuid --set=root ${system.name}
|
||||
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
|
||||
}
|
||||
'')
|
||||
(inputs.localLib.attrsToList grub.windowsEntries))
|
||||
boot.loader.grub =
|
||||
{
|
||||
memtest86.enable = true;
|
||||
extraFiles = inputs.lib.mkIf (builtins.elem grub.installDevice [ "efi" "efiRemovable" ])
|
||||
{ "shell.efi" = "${inputs.pkgs.genericPackages.edk2-uefi-shell}/shell.efi"; };
|
||||
extraEntries = inputs.lib.mkMerge (builtins.concatLists
|
||||
[
|
||||
''
|
||||
menuentry "System shutdown" {
|
||||
echo "System shutting down..."
|
||||
halt
|
||||
}
|
||||
menuentry "System restart" {
|
||||
echo "System rebooting..."
|
||||
reboot
|
||||
}
|
||||
''
|
||||
(
|
||||
inputs.lib.optionalString (builtins.elem grub.installDevice [ "efi" "efiRemovable" ])
|
||||
(builtins.map
|
||||
(system:
|
||||
''
|
||||
menuentry 'UEFI Firmware Settings' --id 'uefi-firmware' {
|
||||
fwsetup
|
||||
}
|
||||
menuentry "UEFI Shell" {
|
||||
menuentry "${system.value}" {
|
||||
insmod part_gpt
|
||||
insmod fat
|
||||
insmod search_fs_uuid
|
||||
insmod chain
|
||||
chainloader @bootRoot@/shell.efi
|
||||
search --fs-uuid --set=root ${system.name}
|
||||
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
|
||||
}
|
||||
'')
|
||||
(inputs.localLib.attrsToList grub.windowsEntries))
|
||||
[
|
||||
''
|
||||
menuentry "System shutdown" {
|
||||
echo "System shutting down..."
|
||||
halt
|
||||
}
|
||||
menuentry "System restart" {
|
||||
echo "System rebooting..."
|
||||
reboot
|
||||
}
|
||||
''
|
||||
)
|
||||
]
|
||||
]);
|
||||
};
|
||||
}
|
||||
];
|
||||
(
|
||||
inputs.lib.optionalString (builtins.elem grub.installDevice [ "efi" "efiRemovable" ])
|
||||
''
|
||||
menuentry 'UEFI Firmware Settings' --id 'uefi-firmware' {
|
||||
fwsetup
|
||||
}
|
||||
menuentry "UEFI Shell" {
|
||||
insmod fat
|
||||
insmod chain
|
||||
chainloader @bootRoot@/shell.efi
|
||||
}
|
||||
''
|
||||
)
|
||||
]
|
||||
]);
|
||||
};
|
||||
}
|
||||
])
|
||||
({});
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ inputs:
|
||||
{
|
||||
options.nixos.system.gui = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
implementation = mkOption { type = types.enum [ "kde" ]; default = "kde"; };
|
||||
implementation = mkOption { type = types.enum [ "kde" "niri" ]; default = "kde"; };
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.system) gui; in inputs.lib.mkMerge
|
||||
[
|
||||
@@ -46,6 +46,7 @@ inputs:
|
||||
config.gtk =
|
||||
{
|
||||
enable = true;
|
||||
theme.name = "Breeze";
|
||||
gtk2 =
|
||||
{
|
||||
extraConfig = ''gtk-im-module="fcitx"'';
|
||||
@@ -62,5 +63,10 @@ inputs:
|
||||
environment.plasma6.excludePackages = inputs.lib.mkIf (gui.implementation == "kde")
|
||||
[ inputs.pkgs.kdePackages.plasma-nm ];
|
||||
})
|
||||
# niri
|
||||
(inputs.lib.mkIf (gui.implementation == "niri")
|
||||
{
|
||||
programs.niri.enable = true;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ inputs:
|
||||
{
|
||||
variant = mkOption
|
||||
{
|
||||
type = types.nullOr (types.enum [ "nixos" "xanmod-lts" "xanmod-latest" ]);
|
||||
type = types.nullOr (types.enum [ "nixos" "xanmod-lts" "xanmod-latest" "xanmod-unstable" ]);
|
||||
default = "xanmod-lts";
|
||||
};
|
||||
patches = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||
@@ -31,8 +31,6 @@ inputs:
|
||||
"bnx2x" "tg3"
|
||||
# network for srv2
|
||||
"e1000e" "igb" "atlantic" "igc"
|
||||
# temp wireless for nas
|
||||
"r8712u"
|
||||
# network for srv3
|
||||
"igb"
|
||||
# touchscreen for one
|
||||
|
||||
@@ -25,8 +25,12 @@ inputs:
|
||||
};});
|
||||
default = {};
|
||||
};
|
||||
# wpa_passphrase SSID(wifi name) PSK(password)
|
||||
wireless = mkOption { type = types.nullOr (types.listOf types.nonEmptyStr); default = null; };
|
||||
wireless =
|
||||
{
|
||||
# wpa_passphrase SSID(wifi name) PSK(password)
|
||||
networks = mkOption { type = types.nullOr (types.listOf types.nonEmptyStr); default = null; };
|
||||
fourAddr = mkOption { type = types.bool; default = false; };
|
||||
};
|
||||
trust = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||
masquerade = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||
};});
|
||||
@@ -140,27 +144,31 @@ inputs:
|
||||
networking =
|
||||
{
|
||||
useNetworkd = true;
|
||||
wireless = inputs.lib.mkIf (network.wireless != null)
|
||||
wireless = inputs.lib.mkIf (network.wireless.networks != null)
|
||||
{
|
||||
enable = true;
|
||||
# wpa_passphrase SSID password
|
||||
networks = builtins.listToAttrs (builtins.map
|
||||
(network: { name = network; value.pskRaw = "ext:${network}"; }) network.wireless);
|
||||
secretsFile = inputs.config.sops.templates."wireless.env".path;
|
||||
(network: { name = network; value.pskRaw = "ext:${network}"; }) network.wireless.networks);
|
||||
secretsFile = inputs.config.nixos.system.sops.templates."wireless.env".path;
|
||||
};
|
||||
firewall.trustedInterfaces = network.trust;
|
||||
};
|
||||
# dnsable dns fallback, use provided dns servers or no dns
|
||||
services.resolved.fallbackDns = [];
|
||||
sops = inputs.lib.mkIf (network.wireless != null)
|
||||
nixos.system.sops = inputs.lib.mkIf (network.wireless.networks != null)
|
||||
{
|
||||
templates."wireless.env".content = builtins.concatStringsSep "\n" (builtins.map
|
||||
(network: "${network}=${inputs.config.sops.placeholder."wireless/${network}"}")
|
||||
network.wireless);
|
||||
(network: "${network}=${inputs.config.nixos.system.sops.placeholder."wireless/${network}"}")
|
||||
network.wireless.networks);
|
||||
secrets = builtins.listToAttrs (builtins.map
|
||||
(network: { name = "wireless/${network}"; value = {}; })
|
||||
network.wireless);
|
||||
(network: inputs.lib.nameValuePair "wireless/${network}" {})
|
||||
network.wireless.networks);
|
||||
};
|
||||
services.udev.extraRules = inputs.lib.mkIf (network.wireless.fourAddr)
|
||||
''
|
||||
ACTION=="add", SUBSYSTEM=="net", ENV{INTERFACE}=="wlp*", RUN+="${inputs.pkgs.iw}/bin/iw dev %k set 4addr on"
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.system.nix-ld = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = {}; };
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if inputs.config.nixos.model.arch == "x86_64" then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.system) nix-ld; in inputs.lib.mkIf (nix-ld != null)
|
||||
{
|
||||
programs.nix-ld =
|
||||
|
||||
@@ -105,26 +105,26 @@ inputs:
|
||||
protocol = "ssh-ng";
|
||||
systems = [ "x86_64-linux" ];
|
||||
sshUser = "nix-ssh";
|
||||
sshKey = inputs.config.sops.secrets."nix/remote".path;
|
||||
sshKey = inputs.config.nixos.system.sops.secrets."nix/remote".path;
|
||||
maxJobs = 1;
|
||||
mandatoryFeatures = [ "big-parallel" ];
|
||||
supportedFeatures = builtins.map (f: "gccarch-${f}") v;
|
||||
})
|
||||
nix.remote.master.host;
|
||||
};
|
||||
sops.secrets."nix/remote" = {};
|
||||
nixos.system.sops.secrets."nix/remote" = {};
|
||||
})
|
||||
(inputs.lib.mkIf nix.githubToken.enable
|
||||
{
|
||||
nix.extraOptions = "!include ${inputs.config.sops.templates."nix-github.conf".path}";
|
||||
sops =
|
||||
nix.extraOptions = "!include ${inputs.config.nixos.system.sops.templates."nix-github.conf".path}";
|
||||
nixos.system.sops =
|
||||
{
|
||||
templates."nix-github.conf" =
|
||||
{
|
||||
content = "access-tokens = github.com=${inputs.config.sops.placeholder."github/token"}";
|
||||
content = "access-tokens = github.com=${inputs.config.nixos.system.sops.placeholder."github/token"}";
|
||||
mode = "0444";
|
||||
};
|
||||
secrets."github/token".sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml";
|
||||
secrets."github/token" = {};
|
||||
};
|
||||
})
|
||||
# c++ include path
|
||||
|
||||
@@ -15,7 +15,11 @@ inputs:
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.system) nixpkgs; in
|
||||
{
|
||||
nixpkgs = inputs.localLib.buildNixpkgsConfig { inherit inputs; nixpkgs = nixpkgs // { nixRoot = null; }; };
|
||||
nixpkgs = inputs.localLib.buildNixpkgsConfig
|
||||
{
|
||||
inherit inputs;
|
||||
nixpkgs = nixpkgs // { nixRoot = null; nixos = true; inherit (inputs.config.nixos.model) arch; };
|
||||
};
|
||||
boot.kernelPatches = inputs.lib.mkIf (nixpkgs.march != null)
|
||||
[{
|
||||
name = "native kernel";
|
||||
|
||||
@@ -2,38 +2,118 @@ inputs:
|
||||
{
|
||||
options.nixos.system.sops = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
crossSopsDir = mkOption
|
||||
secrets = mkOption
|
||||
{
|
||||
type = types.nonEmptyStr;
|
||||
default = "${inputs.topInputs.self}/devices/cross/secrets";
|
||||
readOnly = true;
|
||||
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
||||
{
|
||||
path = mkOption
|
||||
{
|
||||
type = types.path;
|
||||
default = inputs.config.sops.secrets.${submoduleInputs.config._module.args.name}.path;
|
||||
readOnly = true;
|
||||
};
|
||||
key = mkOption { type = types.str; default = submoduleInputs.config._module.args.name; };
|
||||
format = mkOption { type = types.enum [ "yaml" "binary" ]; default = "yaml"; };
|
||||
mode = mkOption { type = types.str; default = "0400"; };
|
||||
owner = mkOption { type = types.nullOr types.str; default = null; };
|
||||
group = mkOption { type = types.nullOr types.str; default = null; };
|
||||
sopsFile = mkOption
|
||||
{
|
||||
type = types.path;
|
||||
default =
|
||||
let secretFileIndex =
|
||||
inputs.lib.lists.findFirstIndex (x: x) null
|
||||
(builtins.map
|
||||
(file: inputs.lib.hasAttrByPath (inputs.lib.splitString "/" submoduleInputs.config.key)
|
||||
(inputs.pkgs.localPackages.fromYaml (builtins.readFile file)))
|
||||
inputs.config.nixos.system.sops.defaultSopsFile);
|
||||
in
|
||||
if secretFileIndex == null then builtins.abort "No sops file found for ${submoduleInputs.config.key}"
|
||||
else builtins.elemAt inputs.config.nixos.system.sops.defaultSopsFile secretFileIndex;
|
||||
};
|
||||
neededForUsers = mkOption { type = types.bool; default = false; };
|
||||
};}));
|
||||
default = {};
|
||||
};
|
||||
clusterSopsDir = mkOption
|
||||
templates = mkOption
|
||||
{
|
||||
type = types.nullOr types.nonEmptyStr;
|
||||
default = if (inputs.config.nixos.model.cluster == null) then null
|
||||
else "${inputs.topInputs.self}/devices/${inputs.config.nixos.model.cluster.clusterName}/secrets";
|
||||
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
||||
{
|
||||
content = mkOption { type = types.str; };
|
||||
path = mkOption
|
||||
{
|
||||
type = types.path;
|
||||
default = inputs.config.sops.templates.${submoduleInputs.config._module.args.name}.path;
|
||||
readOnly = true;
|
||||
};
|
||||
owner = mkOption { type = types.nullOr types.str; default = null; };
|
||||
group = mkOption { type = types.nullOr types.str; default = null; };
|
||||
mode = mkOption { type = types.str; default = "0400"; };
|
||||
file = mkOption
|
||||
{
|
||||
type = types.path;
|
||||
default = inputs.config.sops.templates.${submoduleInputs.config._module.args.name}.file;
|
||||
readOnly = true;
|
||||
};
|
||||
};}));
|
||||
default = {};
|
||||
};
|
||||
# define default in config
|
||||
placeholder = mkOption { type = types.attrsOf types.str; };
|
||||
defaultSopsFile = mkOption
|
||||
{
|
||||
type = types.nonEmptyListOf types.path;
|
||||
readOnly = true;
|
||||
default =
|
||||
let
|
||||
defaultSopsFile = path:
|
||||
if builtins.pathExists "${path}/secrets.yaml" then [ "${path}/secrets.yaml" ]
|
||||
else if builtins.pathExists "${path}/secrets/default.yaml" then [ "${path}/secrets/default.yaml" ]
|
||||
else [];
|
||||
devicePath = "${inputs.topInputs.self}/devices";
|
||||
inherit (inputs.config.nixos) model;
|
||||
in
|
||||
[]
|
||||
++ (inputs.lib.optionals (model.cluster == null) (defaultSopsFile "${devicePath}/${model.hostname}"))
|
||||
++ (inputs.lib.optionals (model.cluster != null)
|
||||
(
|
||||
(defaultSopsFile "${devicePath}/${model.cluster.clusterName}/${model.cluster.nodeName}")
|
||||
++ (defaultSopsFile "${devicePath}/${model.cluster.clusterName}")
|
||||
))
|
||||
++ (inputs.lib.optionals model.private [ "${devicePath}/cross/secrets/chn.yaml" ])
|
||||
++ (defaultSopsFile "${devicePath}/cross");
|
||||
};
|
||||
availableKeys = mkOption
|
||||
{
|
||||
type = types.listOf (types.listOf types.str);
|
||||
readOnly = true;
|
||||
default =
|
||||
let getPath = x:
|
||||
if builtins.typeOf x == "string" then [[]]
|
||||
else if builtins.typeOf x == "set"
|
||||
then builtins.concatLists (inputs.lib.mapAttrsToList (n: v: builtins.map (l: [ n ] ++ l) (getPath v)) x)
|
||||
# simply ignore list, they are sops metadata
|
||||
else if builtins.typeOf x == "list" then [[]]
|
||||
else builtins.abort "Invalid type for availableKeys, get type ${builtins.typeOf x}";
|
||||
in builtins.concatLists (builtins.map
|
||||
(f: getPath (inputs.pkgs.localPackages.fromYaml (builtins.readFile f)))
|
||||
inputs.config.nixos.system.sops.defaultSopsFile);
|
||||
};
|
||||
};
|
||||
config =
|
||||
{
|
||||
nixos.system.sops.placeholder = builtins.mapAttrs
|
||||
(n: _: inputs.lib.mkOptionDefault "sops${builtins.hashString "sha256" n}sops")
|
||||
inputs.config.nixos.system.sops.secrets;
|
||||
sops =
|
||||
{
|
||||
defaultSopsFile =
|
||||
let deviceDir =
|
||||
if (inputs.config.nixos.model.cluster == null) then
|
||||
"${inputs.topInputs.self}/devices/${inputs.config.nixos.model.hostname}"
|
||||
else
|
||||
"${inputs.topInputs.self}/devices/${inputs.config.nixos.model.cluster.clusterName}"
|
||||
+ "/${inputs.config.nixos.model.cluster.nodeName}";
|
||||
in inputs.lib.mkMerge
|
||||
[
|
||||
(inputs.lib.mkIf (builtins.pathExists "${deviceDir}/secrets.yaml") "${deviceDir}/secrets.yaml")
|
||||
(inputs.lib.mkIf (builtins.pathExists "${deviceDir}/secrets/default.yaml")
|
||||
"${deviceDir}/secrets/default.yaml")
|
||||
];
|
||||
# sops start before impermanence, so we need to use the absolute path
|
||||
secrets = builtins.mapAttrs
|
||||
(n: v: { inherit (v) key format mode owner group sopsFile neededForUsers; })
|
||||
inputs.config.nixos.system.sops.secrets;
|
||||
templates = builtins.mapAttrs
|
||||
(n: v: { inherit (v) content owner group mode; })
|
||||
inputs.config.nixos.system.sops.templates;
|
||||
inherit (inputs.config.nixos.system.sops) placeholder;
|
||||
age.sshKeyPaths = [ "/nix/persistent/etc/ssh/ssh_host_ed25519_key" ];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -5,12 +5,8 @@ inputs:
|
||||
home-manager.users.chn = homeInputs:
|
||||
{
|
||||
config.xdg.configFile."sops/age/keys.txt".source =
|
||||
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.sops.secrets."chn/age".path;
|
||||
};
|
||||
sops.secrets."chn/age" =
|
||||
{
|
||||
owner = "chn";
|
||||
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml";
|
||||
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.nixos.system.sops.secrets."chn/age".path;
|
||||
};
|
||||
nixos.system.sops.secrets."chn/age".owner = "chn";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,30 +40,23 @@ inputs:
|
||||
{
|
||||
name = ".ssh/id_${type}";
|
||||
value.source = homeInputs.config.lib.file.mkOutOfStoreSymlink
|
||||
inputs.config.sops.secrets."chn/${type}".path;
|
||||
inputs.config.nixos.system.sops.secrets."chn/${type}".path;
|
||||
})
|
||||
[ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" ]
|
||||
))
|
||||
// {
|
||||
".ssh/xmuhk_id_rsa".source =
|
||||
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.sops.secrets."chn/xmuhk".path;
|
||||
homeInputs.config.lib.file.mkOutOfStoreSymlink inputs.config.nixos.system.sops.secrets."chn/xmuhk".path;
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
sops.secrets = inputs.lib.mkIf inputs.config.nixos.model.private (inputs.lib.mkMerge
|
||||
nixos.system.sops.secrets = inputs.lib.mkIf inputs.config.nixos.model.private (inputs.lib.mkMerge
|
||||
[
|
||||
(builtins.listToAttrs (builtins.map
|
||||
(name:
|
||||
{
|
||||
name = "chn/${name}";
|
||||
value = { owner = "chn"; sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; };
|
||||
})
|
||||
(name: inputs.lib.nameValuePair "chn/${name}" { owner = "chn"; })
|
||||
[ "rsa" "rsa.ppk" "ed25519" "ed25519_sk" "xmuhk" ]))
|
||||
{
|
||||
"root/ed25519_sk" =
|
||||
{ key = "chn/ed25519_sk"; sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/chn.yaml"; };
|
||||
}
|
||||
{ "root/ed25519_sk".key = "chn/ed25519_sk"; }
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ inputs:
|
||||
zqq = 1021;
|
||||
zgq = 1022;
|
||||
qmx = 1023;
|
||||
yumieko = 1024;
|
||||
misskey-misskey = 2000;
|
||||
misskey-misskey-old = 2001;
|
||||
frp = 2002;
|
||||
@@ -47,6 +48,7 @@ inputs:
|
||||
synapse-synapse = 2009;
|
||||
synapse-matrix = 2010;
|
||||
hpcstat = 2011;
|
||||
speedtest = 2012;
|
||||
};
|
||||
};
|
||||
gid = mkOption
|
||||
@@ -101,17 +103,15 @@ inputs:
|
||||
}
|
||||
# set hashedPassword if it exist in secrets
|
||||
(
|
||||
let
|
||||
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
|
||||
secrets = inputs.pkgs.localPackages.fromYaml (builtins.readFile sopsFile);
|
||||
hashedPasswordExist = userName: (secrets ? users) && ((secrets.users or {}) ? ${userName});
|
||||
let hashedPasswordExist = userName: inputs.lib.lists.any
|
||||
(inputs.lib.lists.hasPrefix [ "users" userName ]) inputs.config.nixos.system.sops.availableKeys;
|
||||
in
|
||||
{
|
||||
users.users = builtins.listToAttrs (builtins.map
|
||||
(name: { inherit name; value.hashedPasswordFile = inputs.config.sops.secrets."users/${name}".path; })
|
||||
(builtins.filter (user: hashedPasswordExist user) user.users));
|
||||
sops.secrets = builtins.listToAttrs (builtins.map
|
||||
(name: { name = "users/${name}"; value = { neededForUsers = true; inherit sopsFile; }; })
|
||||
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
|
||||
(name: inputs.lib.nameValuePair "users/${name}" { neededForUsers = true; })
|
||||
(builtins.filter (user: hashedPasswordExist user) user.users));
|
||||
}
|
||||
)
|
||||
@@ -143,7 +143,7 @@ inputs:
|
||||
home.file = inputs.lib.mkIf inputs.config.nixos.model.private
|
||||
{
|
||||
".ssh/id_ed25519_sk".source = homeInputs.config.lib.file.mkOutOfStoreSymlink
|
||||
inputs.config.sops.secrets."root/ed25519_sk".path;
|
||||
inputs.config.nixos.system.sops.secrets."root/ed25519_sk".path;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,9 +4,10 @@ inputs:
|
||||
{
|
||||
home-manager.users.hjp.config.programs.zsh.initContent =
|
||||
''
|
||||
export PATH=$PATH:/home/hjp/software/intel/oneapi/compiler/latest/bin
|
||||
export PATH=$PATH:/home/hjp/software/intel/oneapi/compiler/latest/bin:/home/hjp/software/atomkit.0.9.0/bin
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/hjp/software/intel/oneapi/compiler/latest/lib
|
||||
'';
|
||||
users.users.hjp.extraGroups = [ "wheel" ];
|
||||
users.users.hjp.extraGroups = inputs.lib.mkIf (inputs.config.nixos.model.cluster.clusterName or null == "srv2")
|
||||
[ "wheel" ];
|
||||
};
|
||||
}
|
||||
|
||||
1
modules/user/yumieko/id_rsa.pub
Normal file
1
modules/user/yumieko/id_rsa.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDeTErlX48PWEPz+fO2tvXiYOoOHHxUk5ACoA1zb5zhVBcbXDPTBo31W+nKRqSztOPhR2ABe8zw37eN3cvBtR3XvkZdtKyCd9OGhYI0WTV+97ZxO3Wi5t7hI72gzdPHnPJyK4aZUGEV2b+pSHJ1ONjYX6w6beh8TyZm1ch3Cc95lnOrvGIgWt3d34WVbP/+ubuDXM4Hx2HKBgTvKxmpXIyhXGTC7IF7nT8EX8NcW58w4nTBGBStf4MU1P1lgOJTJlcKJyw2IGxYMJTD9qgYvCQffqmK1mf2eCh+AGA7oqIrzQ1tfF3mp4V91aD3QngXow79lHBPuefGxqGjjMmaKcm6/OuIlPC7HtA2jn+TM32SlRN1mgSkpjiwpneinuFPYSqpcQpRHQDaPWhOC0xMzBXhM+9GXpQc6ntGWYW8inyhY6sDRborQPIFG/dZg8M720mkhP4xOs/7l8hmxk+6uD4dK6yimCvlcMvX7Rk/aJ+Bb8IfCAQSd+xff87w0Z5MpGAKpx0T33vKleSbanTEZh73KZzQvrgoZCuBHUOv/yN/r6s2evIA8lvmDqdbpNsxo7/+avRLyK6cjoj5IipcPNtTwaaNkTGC/YE+TOQI+iBAsMvmr8542m06lQXqkfAElE8TvAmR6BLIFO33Byy31x3L4AVWbWo/uWw9xs8ziir9Jw== minkieyume@gmail.com
|
||||
18
packages/atat.nix
Normal file
18
packages/atat.nix
Normal file
@@ -0,0 +1,18 @@
|
||||
{ stdenv, src, perl, coreutils }: stdenv.mkDerivation
|
||||
{
|
||||
name = "atat";
|
||||
inherit src;
|
||||
nativeBuildInputs = [ perl ];
|
||||
configurePhase =
|
||||
''
|
||||
patchShebangs src
|
||||
echo "#!/bin/sh" > safecp
|
||||
echo "cp \"\$@\"" >> safecp
|
||||
'';
|
||||
buildPhase = "make -C src -j$NIX_BUILD_CORES";
|
||||
installPhase =
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
make -C src BINDIR=$out/bin install
|
||||
'';
|
||||
}
|
||||
16
packages/atomkit.nix
Normal file
16
packages/atomkit.nix
Normal file
@@ -0,0 +1,16 @@
|
||||
{ stdenv, src, autoPatchelfHook, xorg }: stdenv.mkDerivation
|
||||
{
|
||||
name = "atomkit";
|
||||
inherit src;
|
||||
dontConfigure = true;
|
||||
dontBuild = true;
|
||||
buildInputs = [ stdenv.cc.cc xorg.libX11 ];
|
||||
nativeBuildInputs = [ autoPatchelfHook ];
|
||||
installPhase =
|
||||
''
|
||||
runHook preInstall
|
||||
mkdir -p $out
|
||||
cp -r * $out
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
||||
@@ -13,7 +13,8 @@ endif()
|
||||
|
||||
find_package(magic_enum REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem system)
|
||||
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem system process stacktrace_from_exception
|
||||
stacktrace_backtrace)
|
||||
find_package(range-v3 REQUIRED)
|
||||
find_path(NAMEOF_INCLUDE_DIR nameof.hpp REQUIRED)
|
||||
find_package(Eigen3 REQUIRED)
|
||||
@@ -35,7 +36,7 @@ target_include_directories(biu PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_D
|
||||
${LIBBACKTRACE_INCLUDE_DIR} ${POCKETFFT_INCLUDE_DIR})
|
||||
target_link_libraries(biu PUBLIC magic_enum::magic_enum fmt::fmt Boost::headers Boost::iostreams Boost::filesystem
|
||||
range-v3::range-v3 Eigen3::Eigen HighFive TgBot::TgBot ${LIBBACKTRACE_LIBRARY} hdf5::hdf5 concurrencpp::concurrencpp
|
||||
yaml-cpp::yaml-cpp glaze::glaze)
|
||||
yaml-cpp::yaml-cpp glaze::glaze Boost::process Boost::stacktrace_from_exception Boost::stacktrace_backtrace)
|
||||
target_compile_features(biu PUBLIC cxx_std_23)
|
||||
target_compile_options(biu PUBLIC -Wno-gnu-string-literal-operator-template)
|
||||
install(TARGETS biu EXPORT biuTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
@@ -56,6 +57,7 @@ set_property(TARGET test-serialize PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRE
|
||||
add_test(NAME test-serialize COMMAND test-serialize)
|
||||
add_executable(test-process test/process.cpp)
|
||||
target_link_libraries(test-process PRIVATE biu)
|
||||
target_compile_definitions(test-process PRIVATE BIU_LOGGER_SOURCE_ROOT="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set_property(TARGET test-process PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
|
||||
add_test(NAME test-process COMMAND test-process)
|
||||
add_executable(test-eigen test/eigen.cpp)
|
||||
@@ -84,7 +86,7 @@ set_property(TARGET test-yaml PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
|
||||
add_test(NAME test-yaml COMMAND test-yaml)
|
||||
add_executable(test-logger test/logger.cpp)
|
||||
target_link_libraries(test-logger PRIVATE biu)
|
||||
target_compile_definitions(test-logger PRIVATE BIU_LOGGER_DEBUG BIU_LOGGER_SOURCE_ROOT="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
target_compile_definitions(test-logger PRIVATE BIU_LOGGER_SOURCE_ROOT="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set_property(TARGET test-logger PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
|
||||
add_test(NAME test-logger COMMAND test-logger)
|
||||
add_executable(test-glaze test/glaze.cpp)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/biuTargets.cmake")
|
||||
find_package(magic_enum REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem system)
|
||||
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem system process stacktrace_from_exception
|
||||
stacktrace_backtrace)
|
||||
find_package(range-v3 REQUIRED)
|
||||
find_path(NAMEOF_INCLUDE_DIR nameof.hpp REQUIRED)
|
||||
find_package(Eigen3 REQUIRED)
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
src = ./.;
|
||||
buildInputs =
|
||||
[
|
||||
magic-enum fmt boost range-v3 nameof zpp-bits eigen highfive tgbot-cpp libbacktrace hdf5
|
||||
concurrencpp pocketfft yaml-cpp glaze
|
||||
magic-enum fmt boost range-v3 nameof zpp-bits eigen libbacktrace hdf5
|
||||
concurrencpp pocketfft yaml-cpp glaze (highfive.override { inherit boost; }) (tgbot-cpp.override { inherit boost; })
|
||||
];
|
||||
propagatedBuildInputs = buildInputs;
|
||||
nativeBuildInputs = [ cmake ];
|
||||
|
||||
@@ -17,3 +17,4 @@
|
||||
# include <biu/serialize.tpp>
|
||||
# include <biu/glaze.tpp>
|
||||
# include <range/v3/all.hpp>
|
||||
# include <biu/process.tpp>
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace biu
|
||||
public: ValueType get(this auto&& self);
|
||||
public: operator ValueType(this auto&& self);
|
||||
|
||||
protected: template <bool Throw = false> auto lock_(this auto&& self, auto&& condition_function, auto timeout);
|
||||
protected: template <bool Throw> auto lock_(this auto&& self, auto&& condition_function, auto timeout);
|
||||
|
||||
// Apply a function to stored value.
|
||||
// Wait for some time (if provided) until condition funciton returns true (if provided)
|
||||
@@ -45,6 +45,7 @@ namespace biu
|
||||
// NoReturn: throw exception if timeout, ignore function result, and return *this, if true;
|
||||
// return bool or std::optional wrapped result of function, if false.
|
||||
// Useful when chaining multiple apply() calls.
|
||||
// timeout 只考虑 condition_function 的超时,不考虑锁本身的超时。
|
||||
public: template <bool NoReturn = false> decltype(auto) apply
|
||||
(this auto&& self, auto&& function, auto&& condition_function, auto&& timeout);
|
||||
public: template <bool NoReturn = false> decltype(auto) apply
|
||||
@@ -54,8 +55,7 @@ namespace biu
|
||||
// Wait until condition funciton returns true or *this, with an optional timeout
|
||||
public: template <bool NoReturn = false> decltype(auto) wait
|
||||
(this auto&& self, auto&& condition_function, auto timeout);
|
||||
public: template <bool NoReturn = false> decltype(auto) wait
|
||||
(this auto&& self, auto&& condition_function);
|
||||
public: decltype(auto) wait(this auto&& self, auto&& condition_function);
|
||||
|
||||
// Attain lock from outside when constructing, and release when destructing.
|
||||
// Throw: same effect as NoReturn.
|
||||
|
||||
@@ -41,8 +41,11 @@ namespace biu
|
||||
(this auto&& self, auto&& condition_function, auto timeout)
|
||||
{
|
||||
if constexpr (Nullptr<decltype(condition_function)>)
|
||||
{
|
||||
static_assert(Nullptr<decltype(timeout)>);
|
||||
return Guard<std::is_const_v<decltype(self)>>
|
||||
(std::unique_lock{self.Mutex_}, std::experimental::make_observer(&self), {});
|
||||
}
|
||||
else if constexpr (Nullptr<decltype(timeout)>)
|
||||
{
|
||||
std::unique_lock lock(self.Mutex_);
|
||||
@@ -70,28 +73,35 @@ namespace biu
|
||||
using function_return_type = std::invoke_result_t<decltype(function), MoveQualifiers<decltype(self), ValueType>>;
|
||||
auto&& lock = std::forward<decltype(self)>(self).template lock_<NoReturn>
|
||||
(std::forward<decltype(condition_function)>(condition_function), timeout);
|
||||
// 如果得到的是 optional
|
||||
// 如果 lock 是 optional
|
||||
if constexpr (SpecializationOf<std::remove_cvref_t<decltype(lock)>, std::optional>)
|
||||
// 如果超时了,返回 false 或者对应的 nullopt
|
||||
// 如果超时了,这时 NoReturn 一定是 false,返回 false 或者对应的 nullopt
|
||||
if (!lock)
|
||||
{
|
||||
static_assert(!NoReturn);
|
||||
if constexpr (std::is_void_v<function_return_type>) return false;
|
||||
else return std::optional<function_return_type>();
|
||||
}
|
||||
// 否则,执行函数
|
||||
else
|
||||
// 如果函数本身返回 void,则返回 true 或者 *this
|
||||
if constexpr (std::is_void_v<function_return_type>)
|
||||
{
|
||||
std::forward<decltype(function)>(function)
|
||||
(std::forward<MoveQualifiers<decltype(self), ValueType>>(self.Value_));
|
||||
// 如果函数本身返回 void 并且不可能超时,返回 *this,否则返回 true
|
||||
if constexpr (Nullptr<decltype(condition_function)> || Nullptr<decltype(timeout)>)
|
||||
return std::forward<decltype(self)>(self);
|
||||
// 如果要求不返回结果,则返回 *this
|
||||
if constexpr (NoReturn) return std::forward<decltype(self)>(self);
|
||||
// 否则,返回 true
|
||||
else return true;
|
||||
}
|
||||
// 否则,返回函数的返回值或者 std::optional 包装的结果
|
||||
else
|
||||
{
|
||||
auto&& result = std::forward<decltype(function)>(function)
|
||||
(std::forward<MoveQualifiers<decltype(self), ValueType>>(self.Value_));
|
||||
return std::make_optional(std::forward<decltype(result)>(result));
|
||||
if constexpr (NoReturn)
|
||||
return std::forward<decltype(self)>(self);
|
||||
else return std::make_optional(std::forward<decltype(result)>(result));
|
||||
}
|
||||
// 否则,说明不可能超时,返回函数的返回值或者 *this
|
||||
else
|
||||
@@ -125,15 +135,15 @@ namespace biu
|
||||
template <DecayedType ValueType> template <bool NoReturn> decltype(auto) Atomic<ValueType>::wait
|
||||
(this auto&& self, auto&& condition_function, auto timeout)
|
||||
{
|
||||
auto result = std::forward<decltype(self)>(self).template lock_<NoReturn>
|
||||
auto&& result = std::forward<decltype(self)>(self).template lock_<NoReturn>
|
||||
(std::forward<decltype(condition_function)>(condition_function), timeout);
|
||||
if constexpr (SpecializationOf<decltype(result), std::optional>) return result.has_value();
|
||||
else return std::forward<decltype(result)>(result);
|
||||
else return std::forward<decltype(self)>(self);
|
||||
}
|
||||
template <DecayedType ValueType> template <bool NoReturn> decltype(auto) Atomic<ValueType>::wait
|
||||
template <DecayedType ValueType> decltype(auto) Atomic<ValueType>::wait
|
||||
(this auto&& self, auto&& condition_function)
|
||||
{
|
||||
return std::forward<decltype(self)>(self).template wait<NoReturn>
|
||||
return std::forward<decltype(self)>(self).template wait<false>
|
||||
(std::forward<decltype(condition_function)>(condition_function), nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,27 +74,6 @@ namespace biu
|
||||
template <typename T, typename Fallback = void> using FallbackIfNoTypeDeclared
|
||||
= typename detail_::FallbackIfNoTypeDeclaredHelper<T, Fallback>::Type;
|
||||
|
||||
namespace detail_
|
||||
{
|
||||
struct ExecMode { bool DirectStdin = false, DirectStdout = false, DirectStderr = false, SearchPath = false; };
|
||||
template <ExecMode Mode> struct ExecResult
|
||||
{
|
||||
int ExitCode;
|
||||
std::conditional_t<Mode.DirectStdout, Empty, std::string> Stdout;
|
||||
std::conditional_t<Mode.DirectStderr, Empty, std::string> Stderr;
|
||||
operator bool() const;
|
||||
};
|
||||
template <ExecMode Mode> struct ExecInput
|
||||
{
|
||||
std::conditional_t<Mode.SearchPath, std::string, std::filesystem::path> Program;
|
||||
std::vector<std::string> Args;
|
||||
std::conditional_t<Mode.DirectStdin, Empty, std::string> Stdin = {};
|
||||
std::map<std::string, std::string> ExtraEnv = {};
|
||||
std::optional<std::chrono::milliseconds> Timeout;
|
||||
};
|
||||
}
|
||||
template <detail_::ExecMode Mode = {}> detail_::ExecResult<Mode> exec(detail_::ExecInput<Mode> input);
|
||||
|
||||
template <typename Array> concurrencpp::generator<std::pair<Array, std::size_t>> sequence(Array from, Array to);
|
||||
template <typename Array> concurrencpp::generator<std::pair<Array, std::size_t>> sequence(Array to);
|
||||
|
||||
@@ -120,9 +99,11 @@ namespace biu
|
||||
constexpr detail_::ToLvalueHelper toLvalue;
|
||||
|
||||
template <typename Function, typename T, typename... Ts> void for_each(Function&& function, T&& arg, Ts&&... args);
|
||||
|
||||
template <typename T> decltype(auto) perfect_return(T&& obj);
|
||||
}
|
||||
using common::hash, common::unused, common::block_forever, common::is_interactive, common::env, common::int128_t,
|
||||
common::uint128_t, common::Empty, common::CaseInsensitiveStringLessComparator, common::RemoveMemberPointer,
|
||||
common::MoveQualifiers, common::FallbackIfNoTypeDeclared, common::exec, common::sequence, common::read,
|
||||
common::toLvalue, common::for_each;
|
||||
common::MoveQualifiers, common::FallbackIfNoTypeDeclared, common::sequence, common::read,
|
||||
common::toLvalue, common::for_each, common::perfect_return;
|
||||
}
|
||||
|
||||
@@ -75,4 +75,18 @@ namespace biu::common
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> decltype(auto) perfect_return(T&& obj)
|
||||
{
|
||||
// 不允许返回右值引用
|
||||
static_assert(!std::is_rvalue_reference_v<T>);
|
||||
// 左值引用则返回左值引用
|
||||
if constexpr (std::is_lvalue_reference_v<T>) return (obj);
|
||||
// 否则,假定可以移动,并返回值
|
||||
else
|
||||
{
|
||||
static_assert(std::is_move_constructible_v<std::remove_reference_t<T>>);
|
||||
return std::move(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# include <fmt/format.h>
|
||||
# include <fmt/ostream.h>
|
||||
# include <yaml-cpp/yaml.h>
|
||||
# include <boost/stacktrace.hpp>
|
||||
|
||||
namespace biu
|
||||
{
|
||||
@@ -77,4 +78,6 @@ namespace fmt
|
||||
: basic_ostream_formatter<Char> {};
|
||||
|
||||
template <typename Char> struct formatter<YAML::Node, Char> : basic_ostream_formatter<Char> {};
|
||||
template <typename Char> struct formatter<boost::stacktrace::basic_stacktrace<>, Char>
|
||||
: basic_ostream_formatter<Char> {};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# pragma once
|
||||
# include <map>
|
||||
# define BOOST_STACKTRACE_USE_BACKTRACE
|
||||
# include <boost/stacktrace.hpp>
|
||||
# include <biu/atomic.hpp>
|
||||
|
||||
@@ -94,10 +95,10 @@ namespace biu
|
||||
public: [[gnu::always_inline]] inline void info(const std::string& message) const;
|
||||
public: [[gnu::always_inline]] inline void debug(const std::string& message) const;
|
||||
|
||||
public: template <typename FinalException> [[gnu::always_inline]] void print_exception
|
||||
public: [[gnu::always_inline]] inline void print_exception
|
||||
(
|
||||
const std::string& type, const std::string& message, const boost::stacktrace::stacktrace& stacktrace,
|
||||
CalledBy<Exception<FinalException>>
|
||||
std::optional<std::pair<std::string, std::string>> type_and_message,
|
||||
const boost::stacktrace::stacktrace& stacktrace
|
||||
) const;
|
||||
};
|
||||
friend class Guard;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# pragma once
|
||||
# define BOOST_STACKTRACE_USE_BACKTRACE
|
||||
# include <fmt/chrono.h>
|
||||
# include <tgbot/tgbot.h>
|
||||
# include <biu/logger.hpp>
|
||||
@@ -67,14 +66,20 @@ namespace biu
|
||||
template <typename FinalException> Logger::Exception<FinalException>::Exception(const std::string& message)
|
||||
{
|
||||
Logger::Guard log(message);
|
||||
log.print_exception<FinalException>(nameof::nameof_full_type<FinalException>(), message, Stacktrace_, {});
|
||||
log.print_exception
|
||||
(std::pair<std::string, std::string>(nameof::nameof_full_type<FinalException>(), message), Stacktrace_);
|
||||
}
|
||||
|
||||
template <typename Function> inline void Logger::try_exec(Function&& function)
|
||||
{
|
||||
Logger::Guard log;
|
||||
try { function(); }
|
||||
catch (...) { log.error(boost::current_exception_diagnostic_information()); }
|
||||
catch (...)
|
||||
{
|
||||
log.error(boost::current_exception_diagnostic_information());
|
||||
log.print_exception
|
||||
(std::nullopt, boost::stacktrace::stacktrace::from_current_exception());
|
||||
}
|
||||
}
|
||||
|
||||
inline thread_local unsigned Logger::Guard::Indent_ = 0;
|
||||
@@ -115,14 +120,10 @@ namespace biu
|
||||
void Logger::Guard::operator()() const { debug("reached after {} ms."_f(get_time_ms())); }
|
||||
template <Logger::Level L> void Logger::Guard::log(const std::string& message) const
|
||||
{
|
||||
# ifndef BIU_LOGGER_DEBUG
|
||||
if constexpr (L == Level::Debug) return;
|
||||
# endif
|
||||
if (auto&& lock = LoggerConfig_.lock(); lock->Level >= L)
|
||||
{
|
||||
static_assert(std::same_as<std::size_t, std::uint64_t>);
|
||||
auto time = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
|
||||
# ifdef BIU_LOGGER_DEBUG
|
||||
boost::stacktrace::stacktrace stack;
|
||||
# ifdef BIU_LOGGER_SOURCE_ROOT
|
||||
auto source_root = std::string_view(BIU_LOGGER_SOURCE_ROOT "/");
|
||||
@@ -141,11 +142,6 @@ namespace biu
|
||||
stack[0].source_line() == 0 ? "??"s : "{}"_f(stack[0].source_line()),
|
||||
stack[0].name()
|
||||
) << std::flush;
|
||||
# else
|
||||
*lock->Stream << "[ {:%T} {:02x} {:02} ] {}\n"_f
|
||||
(time, get_thread_id() % std::numeric_limits<std::uint16_t>::max(), Indent_, message)
|
||||
<< std::flush;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
void Logger::Guard::error(const std::string& message) const { log<Level::Error>(message); }
|
||||
@@ -158,13 +154,13 @@ namespace biu
|
||||
return std::forward<T>(value);
|
||||
}
|
||||
|
||||
template <typename FinalException> inline void Logger::Guard::print_exception
|
||||
inline void Logger::Guard::print_exception
|
||||
(
|
||||
const std::string& type, const std::string& message, const boost::stacktrace::stacktrace& stacktrace,
|
||||
CalledBy<Exception<FinalException>>
|
||||
std::optional<std::pair<std::string, std::string>> type_and_message,
|
||||
const boost::stacktrace::stacktrace& stacktrace
|
||||
) const
|
||||
{
|
||||
log<Level::Error>("{}: {}"_f(type, message));
|
||||
if (type_and_message) log<Level::Error>("{}: {}"_f(type_and_message->first, type_and_message->second));
|
||||
if (auto&& lock = LoggerConfig_.lock(); lock->Level >= Logger::Level::Error)
|
||||
{
|
||||
static_assert(std::same_as<std::size_t, std::uint64_t>);
|
||||
|
||||
36
packages/biu/include/biu/process.hpp
Normal file
36
packages/biu/include/biu/process.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
# pragma once
|
||||
# include <biu/common.hpp>
|
||||
|
||||
namespace biu
|
||||
{
|
||||
namespace process
|
||||
{
|
||||
enum class IoType { Direct, Close, String };
|
||||
namespace detail_
|
||||
{
|
||||
struct ExecMode
|
||||
{
|
||||
bool SearchPath = false, ModifyEnv = false, Timeout = false;
|
||||
IoType Stdin = IoType::Direct, Stdout = IoType::Direct, Stderr = IoType::Direct;
|
||||
};
|
||||
template <ExecMode Mode> struct ExecResult
|
||||
{
|
||||
int ExitCode;
|
||||
std::conditional_t<Mode.Stdout == IoType::String, std::string, Empty> Stdout;
|
||||
std::conditional_t<Mode.Stderr == IoType::String, std::string, Empty> Stderr;
|
||||
operator bool() const;
|
||||
};
|
||||
template <ExecMode Mode> struct ExecInput
|
||||
{
|
||||
std::conditional_t<Mode.SearchPath, std::string, std::filesystem::path> Program;
|
||||
std::vector<std::string> Args;
|
||||
std::conditional_t<Mode.Stdin == IoType::String, std::string, Empty> Stdin = {};
|
||||
std::conditional_t<Mode.ModifyEnv, std::map<std::string, std::string>, Empty> ExtraEnv = {};
|
||||
std::conditional_t<Mode.Timeout, std::chrono::milliseconds, Empty> Timeout = {};
|
||||
};
|
||||
}
|
||||
template <detail_::ExecMode Mode = {}, typename... Ts>
|
||||
detail_::ExecResult<Mode> exec(detail_::ExecInput<Mode> input, Ts&&... args);
|
||||
}
|
||||
using process::exec, process::IoType;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user