mirror of
https://github.com/CHN-beta/nixos.git
synced 2026-01-12 04:59:23 +08:00
Compare commits
476 Commits
docker
...
13652e7c0e
| Author | SHA1 | Date | |
|---|---|---|---|
| 13652e7c0e | |||
| 2160e453eb | |||
| 71acf32da3 | |||
| aac7bad20a | |||
| 1d9a3ad2c0 | |||
| f55576883c | |||
| e71a08586d | |||
| 8c2b6530a6 | |||
| 38d3d8c7df | |||
| 72e1e0140a | |||
| 59dbfaa70f | |||
| 75e2b84c4c | |||
| 9cfd30db6a | |||
| 02a2d399d6 | |||
| eb25e31c70 | |||
| 6265e41ca7 | |||
| 6f36cfe007 | |||
| b8abc4a326 | |||
| 59b053886b | |||
| 1769069057 | |||
| 9801e53230 | |||
| 9ea81dfe9e | |||
| c6c9bbafae | |||
| f906e9d556 | |||
| 4ffd5aebd5 | |||
| 8724c23fde | |||
| 808058596f | |||
| 36b37daf2e | |||
| 45ec3e74b7 | |||
| f5724e10a4 | |||
| 183d805a8f | |||
| ca7668cbd5 | |||
| 2462e85b70 | |||
| a6b4077114 | |||
| e5b13ace75 | |||
| b861d7bfb9 | |||
| 2d8c36d108 | |||
| 9ec9597421 | |||
| 469919c75a | |||
| 9e14036e57 | |||
| 839e56e52c | |||
| 087b4f0a7f | |||
| 99b891a4cb | |||
| 73d6b46a4b | |||
| d15794e7b1 | |||
| 417e924b04 | |||
| f4d12652c2 | |||
| 219d3fbb20 | |||
| d44a9c4ddb | |||
| 266692c74a | |||
| c1a8043322 | |||
| d330f60909 | |||
| 2b16dde96d | |||
| 6369cf7842 | |||
| 0dff3a17c0 | |||
| 05dddf63b1 | |||
| 73c29c5f82 | |||
| d6b6f449b8 | |||
| 1b0d9e9a2d | |||
| 625bcaf448 | |||
| 7bfbc43a50 | |||
| 2463a8c1af | |||
| b9fa645334 | |||
| 78b132cc58 | |||
| 608774790b | |||
| 9ccb3d3316 | |||
| a0f7af141a | |||
| f65433eb1e | |||
| a9d0f4d8f9 | |||
| 651604da94 | |||
| bb3d4db6f5 | |||
| 7dfcd83071 | |||
| b1d885f62c | |||
| cb849daf0a | |||
| 66ba4864a7 | |||
| 9a4aaedb9a | |||
| 902fd30be8 | |||
| e12d3a7349 | |||
| b767b11e8a | |||
| b5eeef1147 | |||
| e07abc0ad5 | |||
| 07050cd9cd | |||
| 9097917855 | |||
| 18e9922846 | |||
| 11058dc731 | |||
| 8872c18810 | |||
| 8c3d74abaf | |||
| d83062faf0 | |||
| 87eb5cb8fc | |||
| 1faa6103ca | |||
| 38c419f291 | |||
| a5ddab766b | |||
| a0c9b62c0e | |||
| 5a30ebe7b6 | |||
| 6fd53808e6 | |||
| e372278343 | |||
| d13364fa42 | |||
| 666990c1a9 | |||
| 13363f42a1 | |||
| f642e11739 | |||
| ed6b68eb89 | |||
| 396ee9fc73 | |||
| 44ae89efee | |||
| 36e1faee0c | |||
| 1080a2dacf | |||
| f9e35b8837 | |||
| dfad8c1df7 | |||
| 6444e76b49 | |||
| c2864ad7a0 | |||
| 136d02b0eb | |||
| 97158555e4 | |||
| 3deeb55dbd | |||
| 2184dfa34f | |||
| 94d74eac46 | |||
| 2bf0d49e52 | |||
| 73ddbd00a9 | |||
| 1deffccf00 | |||
| bac20eae3e | |||
| 6057c5079f | |||
| 2ab7119ea9 | |||
| 56a34a9f73 | |||
| 693967cf49 | |||
| d273fd6046 | |||
| 73a509b1ba | |||
| df7ff0516c | |||
| 2b3c0e61c5 | |||
| 47406cd0a5 | |||
| 36a702a9a2 | |||
| b42024378b | |||
| 7f68855c7d | |||
| 38c7491640 | |||
| 18ca4d7a00 | |||
| d52d0e3139 | |||
| fecf4816dc | |||
| 3d92e9e593 | |||
| d54d37b8f2 | |||
| 44e843ae5f | |||
| ec07725983 | |||
| bc40195d0f | |||
| 7561442593 | |||
| b240f8d04c | |||
| 10691aa076 | |||
| 8599296ff5 | |||
| 86e89c7310 | |||
| 367c78abd7 | |||
| 50025a78a1 | |||
| 7c08aa5b05 | |||
| 24727ea5f0 | |||
| 04d411d16f | |||
| 84a2bc2eac | |||
| 616a366221 | |||
| 757f0f63bf | |||
| 083cf9524c | |||
| 19729fb334 | |||
| da4a7e33ff | |||
| ff5780ca42 | |||
| 9bdb9c8293 | |||
| f51f9c9992 | |||
| f5777bc89d | |||
| 54f2458f69 | |||
| d0ff526f82 | |||
| e7708c5647 | |||
| c38d84a1b1 | |||
| 4e44953e75 | |||
| be8cf779c9 | |||
| 3209e0aa60 | |||
| 7bba7613a2 | |||
| e78c263248 | |||
| 3ab09c31bb | |||
| ae468cb654 | |||
| 2615d82fea | |||
| 3d2ad2e800 | |||
| 15e9cf917e | |||
| b0619ec108 | |||
| 3c29b08a08 | |||
| ed794ac95f | |||
| 17a462ad04 | |||
| 994360d473 | |||
| c32cff7349 | |||
| 97468b121b | |||
| 8cbad5dc58 | |||
| 790aa5fa2e | |||
| 3cfedc26c9 | |||
| d2479b229e | |||
| 87684a981d | |||
| 3386b3bd2b | |||
| 86cb0a4d85 | |||
| 7c96745618 | |||
| 2a515f2a9b | |||
| 5f4fea3df6 | |||
| d53c5493e1 | |||
| 8750ee1b8b | |||
| d9c956bca1 | |||
| 1f529b55e1 | |||
| 888f438031 | |||
| 7aadd673cd | |||
| f227925d38 | |||
| 90839e445d | |||
| 57d07fc326 | |||
| 91228c3053 | |||
| 3e8237286d | |||
| 3f670636e8 | |||
| 8191eec21e | |||
| fed092c67c | |||
| 44ee17f2ff | |||
| a898902f9e | |||
| 00dd5ae7ad | |||
| d274730437 | |||
| 333ed600ef | |||
| 05cd6dd1c8 | |||
| b1e2497054 | |||
| 0e56ee4293 | |||
| 0294805326 | |||
| 218b6c6140 | |||
| f908883f18 | |||
| 4d81aa8ca7 | |||
| 98fafdd331 | |||
| 2549be1e55 | |||
| 3d261febd2 | |||
| 12cdc43f17 | |||
| fd799befd3 | |||
| 69cb43e6f5 | |||
| 7122474023 | |||
| ebc8f80476 | |||
| 855d24c1ea | |||
| aa74e0911c | |||
| ad4f316339 | |||
| f8c0295bd5 | |||
| 72801ad14c | |||
| c975bcba51 | |||
| 967f7f155e | |||
| bc351ff0d4 | |||
| 35c183f9dc | |||
| 90a3604ac7 | |||
| dd1ac653a3 | |||
| 8a88c8f6a7 | |||
| ad6e94ec09 | |||
| 6b384443e2 | |||
| 21080d7d61 | |||
| 8a3b3313f7 | |||
| 7b3a23d19f | |||
| dea55cdc70 | |||
| 1216a2c674 | |||
| 3de91db3fd | |||
| 297fcee5df | |||
| 95e42f969c | |||
| 2ae484fcc9 | |||
| 4d0cc3e30c | |||
| 09a687f65a | |||
| 8f7c6db841 | |||
| d225de887d | |||
| ed98f26185 | |||
| f1173b45b4 | |||
| 0204420d4f | |||
| c991429151 | |||
| 7c391d6666 | |||
| 6beec31dc1 | |||
| 0e4d8368e9 | |||
| 36f71df435 | |||
| 7b73bdb9f3 | |||
| 4e05896b4f | |||
| 44d8553aef | |||
| dfe5f20346 | |||
| 42162dc08c | |||
| 9ef9c4daa7 | |||
| 7afa093d25 | |||
| c26ea843eb | |||
| 2b73a6549e | |||
| ad12157fe1 | |||
| f628e55fab | |||
| 2444ff5d27 | |||
| 97ec3061e7 | |||
| e2c61c6aaa | |||
| 550ef39dcf | |||
| b2ef263267 | |||
| a686d8259b | |||
| 057e5a5d51 | |||
| 9e36962acb | |||
| 0941aaf2ee | |||
| 3197b26b10 | |||
| ea4b2cbeb8 | |||
| 65bd74aa2d | |||
| 00572e7b29 | |||
| 5be30df0af | |||
| e4219ddefb | |||
| 108cf36835 | |||
| 5645c3d1bd | |||
| 4a56408a7a | |||
| c8d6ed06a6 | |||
| b6122fde21 | |||
| 85ed0026cb | |||
| 7ef8b41350 | |||
| 856ccc5281 | |||
| fb924cd8e0 | |||
| 66e602e750 | |||
| 570b82015e | |||
| eaa5a7f7a3 | |||
| f38b2b3596 | |||
| c1eb35b7d8 | |||
| 0b90b9831f | |||
| a56011bf6d | |||
| 4bb77b3351 | |||
| 2982615a25 | |||
| 279483923e | |||
| 1334fe2b47 | |||
| 954dd962bc | |||
| 62255316be | |||
| b2aa00afa6 | |||
| 41d14eff54 | |||
| 97e25871ae | |||
| b59f68d3b1 | |||
| dc4a836bbb | |||
| a6cddb2f7f | |||
| f05d75d041 | |||
| df76f20ff5 | |||
| 7133b45ffe | |||
| 4370b99ee6 | |||
| bfd47d1dcf | |||
| 9b89e61f20 | |||
| f1e4bfd9bc | |||
| 62aa651c15 | |||
| 5ffdec57c0 | |||
| e20527b4cd | |||
| be54e681c3 | |||
| fe9c7b9363 | |||
| 62c3c6ab29 | |||
| f97db074e6 | |||
| 22ef0c27f5 | |||
| f6a5022aca | |||
| 53020f6373 | |||
| 089fd25d8c | |||
| effb920c82 | |||
| a2c316a6f7 | |||
| 857625884d | |||
| 56a63df3c2 | |||
| fee894fa0a | |||
| 723e859079 | |||
| 864b4c06eb | |||
| 9ec12f8bfc | |||
| 27515d37fe | |||
| cbec6f8d8d | |||
| 4a7c532b31 | |||
| 50aba26cfc | |||
| d7a781ad1a | |||
| 625c3264af | |||
| 9f78a34e6a | |||
| b72c8a43fa | |||
| 286fc162c9 | |||
| 47126a7429 | |||
| be3c0e5821 | |||
| 14f62cf255 | |||
| 60f3ccc506 | |||
| 2bac21f4cf | |||
| ea02adcf4d | |||
| 7fb51ba080 | |||
| 6020e071c0 | |||
| c83c90050a | |||
| 15d89d99ad | |||
| 4b5078a76c | |||
| 073aa595d3 | |||
| 2b5349ae06 | |||
| 3f62ee0dcd | |||
| b9f5478c26 | |||
| 11ee42d876 | |||
| d7adea94eb | |||
| 990a5cf0be | |||
| 2cbe5945b7 | |||
| e06623ce79 | |||
| 4eeae31498 | |||
| 9c75d2ac8d | |||
| f2b88fa5a3 | |||
| 259a1cc6f9 | |||
| e4d1320373 | |||
| 4f24bcce18 | |||
| e3336b95f8 | |||
| 97952ec828 | |||
| 66bcb54311 | |||
| a0ef3198c2 | |||
| 68b94f7216 | |||
| b533b80f31 | |||
| a7315cd8b5 | |||
| 0a6a8fdd7b | |||
| d6d0a0e230 | |||
| 8d583b626f | |||
| 14ef69b54a | |||
| b69d4648b5 | |||
| 2efb0afcfe | |||
| 70e6430750 | |||
| 3dc8a2d73a | |||
| 795d55baee | |||
| 705d279a94 | |||
| d88610f3b7 | |||
| e832412f3b | |||
| 78b27d3ae5 | |||
| a694ada2ee | |||
| bacfb9ccf2 | |||
| fbe4c21e9a | |||
| 4340106787 | |||
| f42e1df555 | |||
| 63664f4fc7 | |||
| 33b96bd46f | |||
| 106112d16f | |||
| 38b6378160 | |||
| 33f7702330 | |||
| 556ac1994d | |||
| 99aa6ecbf7 | |||
| fde802ebfc | |||
| 1118e86d62 | |||
| ca59f06646 | |||
| 9eec3611d4 | |||
| 3f54c4256c | |||
| 91d7ab5b8f | |||
| dcf7f8ace0 | |||
| b7d524671a | |||
| f9a5581410 | |||
| 8c70c96d8e | |||
| 1957d68247 | |||
| ceb91a8ed8 | |||
| 093b27a225 | |||
| 79cad7f58a | |||
| 84ad6e3ae4 | |||
| 6318b938c2 | |||
| e21c7a916a | |||
| bdd8e82b4c | |||
| e967a2511f | |||
| b509fd7a51 | |||
| 0259ee11ec | |||
| 473c4f4d17 | |||
| 469b765f99 | |||
| ad7be5bc2b | |||
| fefd22a7eb | |||
| e4076219e1 | |||
| 8dc5b34cc1 | |||
| 4f39c1a1f3 | |||
| cf6e8dff66 | |||
| cb9665bbb6 | |||
| a419838515 | |||
| 164c5737d2 | |||
| 91ba3d8ec2 | |||
| 9fd8c2d7c6 | |||
| 11efee5bb3 | |||
| 677e8111bf | |||
| d48beec819 | |||
| 6bf6eabaa3 | |||
| 273fcbb7c5 | |||
| 22aadba0da | |||
| 5555396f5d | |||
| d935330515 | |||
| a215b50761 | |||
| 52fd57469e | |||
| b003a1be43 | |||
| 4bd0b01d9b | |||
| c3901eeeb8 | |||
| 77c4a604e9 | |||
| 7c361dab09 | |||
| b9efd5eb70 | |||
| 1a2d11cef8 | |||
| bfec0e24a0 | |||
| de9945635b | |||
| 915fcc348d | |||
| 91475e40d3 | |||
| 565b7dd6bc | |||
| 5a2b46898d | |||
| 3850b9bc05 | |||
| fb8c3cf89d | |||
| df5be06957 | |||
| 894607b933 | |||
| aec4d38497 | |||
| 2312a8398c | |||
| 2e4a542c06 | |||
| 69c7177b73 | |||
| 981643af44 | |||
| 5f88cd5cf5 | |||
| a519053c2a | |||
| 34c0ee6ced | |||
| bdc7945e71 |
22
.sops.yaml
22
.sops.yaml
@@ -4,44 +4,40 @@ keys: # cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age
|
|||||||
- &vps6 age164tyqklwhdm57tfm5u863mdt2xrzrrzac4py8a0j9y6kzqcjy9zsp073t6
|
- &vps6 age164tyqklwhdm57tfm5u863mdt2xrzrrzac4py8a0j9y6kzqcjy9zsp073t6
|
||||||
- &vps7 age137x7csalutwvfygvvzpemlsywvdxj3j4z93a50z2sjx03w6zau8q3r5902
|
- &vps7 age137x7csalutwvfygvvzpemlsywvdxj3j4z93a50z2sjx03w6zau8q3r5902
|
||||||
- &yoga age1qrea4twxdhd7fnvlq5v45528c90qy6hp2wa55kghsxzgut6n6fxs7w6u42
|
- &yoga age1qrea4twxdhd7fnvlq5v45528c90qy6hp2wa55kghsxzgut6n6fxs7w6u42
|
||||||
- &pe age1cahahn9hp265dkhduaec65vugk8fct2vt9ur6y54m4mgmyx4v4fq0etjhv
|
|
||||||
- &nas age19lhcwk37jmvn6z0v4dpdfh0k4u23f76twdjknc0p7atktf37rd7s4t4wj3
|
- &nas age19lhcwk37jmvn6z0v4dpdfh0k4u23f76twdjknc0p7atktf37rd7s4t4wj3
|
||||||
|
- &xmupc1 age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: secrets/pc\.yaml$
|
- path_regex: secrets/pc/.*$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *chn
|
- *chn
|
||||||
- *pc
|
- *pc
|
||||||
- path_regex: secrets/vps6\.yaml$
|
- path_regex: secrets/vps6/.*$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *chn
|
- *chn
|
||||||
- *vps6
|
- *vps6
|
||||||
- path_regex: secrets/vps4\.yaml$
|
- path_regex: secrets/vps7/.*$
|
||||||
key_groups:
|
|
||||||
- age:
|
|
||||||
- *chn
|
|
||||||
- path_regex: secrets/vps7\.yaml$
|
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *chn
|
- *chn
|
||||||
- *vps7
|
- *vps7
|
||||||
- path_regex: secrets/nas\.yaml$
|
- path_regex: secrets/nas/.*$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *chn
|
- *chn
|
||||||
- *nas
|
- *nas
|
||||||
- path_regex: secrets/xmupc1\.yaml$
|
- path_regex: secrets/xmupc1/.*$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *chn
|
- *chn
|
||||||
- path_regex: secrets/yoga\.yaml$
|
- path_regex: secrets/yoga/.*$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *chn
|
- *chn
|
||||||
- *yoga
|
- *yoga
|
||||||
- path_regex: secrets/pe\.yaml$
|
- path_regex: secrets/xmupc1/.*$
|
||||||
key_groups:
|
key_groups:
|
||||||
- age:
|
- age:
|
||||||
- *chn
|
- *chn
|
||||||
- *pe
|
- *xmupc1
|
||||||
|
|||||||
791
flake.lock
generated
791
flake.lock
generated
File diff suppressed because it is too large
Load Diff
566
flake.nix
566
flake.nix
@@ -3,22 +3,26 @@
|
|||||||
|
|
||||||
inputs =
|
inputs =
|
||||||
{
|
{
|
||||||
nixpkgs.url = "github:CHN-beta/nixpkgs/nixos-23.05";
|
nixpkgs.url = "github:CHN-beta/nixpkgs/nixos-23.11";
|
||||||
nixpkgs-unstable.url = "github:CHN-beta/nixpkgs/nixos-unstable";
|
nixpkgs-unstable.url = "github:CHN-beta/nixpkgs/nixos-unstable";
|
||||||
home-manager = { url = "github:nix-community/home-manager/release-23.05"; inputs.nixpkgs.follows = "nixpkgs"; };
|
nixpkgs-2305.url = "github:CHN-beta/nixpkgs/nixos-23.05";
|
||||||
|
home-manager = { url = "github:nix-community/home-manager/release-23.11"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
sops-nix =
|
sops-nix =
|
||||||
{
|
{
|
||||||
url = "github:Mic92/sops-nix";
|
url = "github:Mic92/sops-nix";
|
||||||
inputs = { nixpkgs.follows = "nixpkgs"; nixpkgs-stable.follows = "nixpkgs"; };
|
inputs = { nixpkgs.follows = "nixpkgs"; nixpkgs-stable.follows = "nixpkgs"; };
|
||||||
};
|
};
|
||||||
touchix = { url = "github:CHN-beta/touchix"; inputs.nixpkgs.follows = "nixpkgs"; };
|
|
||||||
aagl = { url = "github:ezKEa/aagl-gtk-on-nix"; inputs.nixpkgs.follows = "nixpkgs"; };
|
aagl = { url = "github:ezKEa/aagl-gtk-on-nix"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
nix-index-database = { url = "github:Mic92/nix-index-database"; inputs.nixpkgs.follows = "nixpkgs"; };
|
nix-index-database = { url = "github:Mic92/nix-index-database"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
nur.url = "github:nix-community/NUR";
|
nur.url = "github:nix-community/NUR";
|
||||||
nixos-cn = { url = "github:nixos-cn/flakes"; inputs.nixpkgs.follows = "nixpkgs"; };
|
nixos-cn = { url = "github:nixos-cn/flakes"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
nur-xddxdd = { url = "github:xddxdd/nur-packages"; inputs.nixpkgs.follows = "nixpkgs"; };
|
nur-xddxdd = { url = "github:xddxdd/nur-packages"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
nix-vscode-extensions = { url = "github:nix-community/nix-vscode-extensions"; inputs.nixpkgs.follows = "nixpkgs"; };
|
nix-vscode-extensions = { url = "github:nix-community/nix-vscode-extensions"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
nix-alien = { url = "github:thiagokokada/nix-alien"; inputs.nix-index-database.follows = "nix-index-database"; };
|
nix-alien =
|
||||||
|
{
|
||||||
|
url = "github:thiagokokada/nix-alien";
|
||||||
|
inputs = { nixpkgs.follows = "nixpkgs"; nix-index-database.follows = "nix-index-database"; };
|
||||||
|
};
|
||||||
impermanence.url = "github:nix-community/impermanence";
|
impermanence.url = "github:nix-community/impermanence";
|
||||||
qchem = { url = "github:Nix-QChem/NixOS-QChem"; inputs.nixpkgs.follows = "nixpkgs"; };
|
qchem = { url = "github:Nix-QChem/NixOS-QChem"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
nixd = { url = "github:nix-community/nixd"; inputs.nixpkgs.follows = "nixpkgs"; };
|
nixd = { url = "github:nix-community/nixd"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
@@ -28,6 +32,12 @@
|
|||||||
pnpm2nix-nzbr = { url = "github:CHN-beta/pnpm2nix-nzbr"; inputs.nixpkgs.follows = "nixpkgs"; };
|
pnpm2nix-nzbr = { url = "github:CHN-beta/pnpm2nix-nzbr"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
lmix = { url = "github:CHN-beta/lmix"; inputs.nixpkgs.follows = "nixpkgs"; };
|
lmix = { url = "github:CHN-beta/lmix"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
dguibert-nur-packages = { url = "github:CHN-beta/dguibert-nur-packages"; inputs.nixpkgs.follows = "nixpkgs"; };
|
dguibert-nur-packages = { url = "github:CHN-beta/dguibert-nur-packages"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
|
plasma-manager =
|
||||||
|
{
|
||||||
|
url = "github:pjones/plasma-manager";
|
||||||
|
inputs = { nixpkgs.follows = "nixpkgs"; home-manager.follows = "home-manager"; };
|
||||||
|
};
|
||||||
|
nix-doom-emacs = { url = "github:nix-community/nix-doom-emacs"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs:
|
outputs = inputs:
|
||||||
@@ -49,32 +59,16 @@
|
|||||||
name = system;
|
name = system;
|
||||||
value = inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel;
|
value = inputs.self.outputs.nixosConfigurations.${system}.config.system.build.toplevel;
|
||||||
})
|
})
|
||||||
[ "pc" "vps6" "vps7" "nas" "yoga" ])
|
[ "pc" "vps6" "vps7" "nas" "yoga" "xmupc1" ])
|
||||||
);
|
);
|
||||||
nixosConfigurations = builtins.listToAttrs (builtins.map
|
# ssh-keygen -t rsa -C root@pe -f /mnt/nix/persistent/etc/ssh/ssh_host_rsa_key
|
||||||
(system:
|
# ssh-keygen -t ed25519 -C root@pe -f /mnt/nix/persistent/etc/ssh/ssh_host_ed25519_key
|
||||||
{
|
# systemd-machine-id-setup --root=/mnt/nix/persistent
|
||||||
name = system.name;
|
nixosConfigurations =
|
||||||
value = inputs.nixpkgs.lib.nixosSystem
|
let
|
||||||
|
system =
|
||||||
{
|
{
|
||||||
system = "x86_64-linux";
|
pc =
|
||||||
specialArgs = { topInputs = inputs; inherit localLib; };
|
|
||||||
modules = localLib.mkModules
|
|
||||||
(
|
|
||||||
[
|
|
||||||
(inputs: { config.nixpkgs.overlays = [(final: prev:
|
|
||||||
{ localPackages = (import ./local/pkgs { inherit (inputs) lib; pkgs = final; }); })]; })
|
|
||||||
./modules
|
|
||||||
]
|
|
||||||
++ system.value
|
|
||||||
);
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(localLib.attrsToList
|
|
||||||
{
|
|
||||||
"pc" =
|
|
||||||
[
|
|
||||||
(inputs: { config.nixos =
|
|
||||||
{
|
{
|
||||||
system =
|
system =
|
||||||
{
|
{
|
||||||
@@ -92,10 +86,9 @@
|
|||||||
decrypt.auto =
|
decrypt.auto =
|
||||||
{
|
{
|
||||||
"/dev/disk/by-uuid/55fdd19f-0f1d-4c37-bd4e-6df44fc31f26" = { mapper = "root"; ssd = true; };
|
"/dev/disk/by-uuid/55fdd19f-0f1d-4c37-bd4e-6df44fc31f26" = { mapper = "root"; ssd = true; };
|
||||||
"/dev/md/swap" = { mapper = "swap"; ssd = true; before = [ "root" ]; };
|
"/dev/disk/by-uuid/4be45329-a054-4c20-8965-8c5b7ee6b35d" =
|
||||||
|
{ mapper = "swap"; ssd = true; before = [ "root" ]; };
|
||||||
};
|
};
|
||||||
mdadm =
|
|
||||||
"ARRAY /dev/md/swap metadata=1.2 name=pc:swap UUID=2b546b8d:e38007c8:02990dd1:df9e23a4";
|
|
||||||
swap = [ "/dev/mapper/swap" ];
|
swap = [ "/dev/mapper/swap" ];
|
||||||
resume = "/dev/mapper/swap";
|
resume = "/dev/mapper/swap";
|
||||||
rollingRootfs = { device = "/dev/mapper/root"; path = "/nix/rootfs"; };
|
rollingRootfs = { device = "/dev/mapper/root"; path = "/nix/rootfs"; };
|
||||||
@@ -121,17 +114,12 @@
|
|||||||
];
|
];
|
||||||
keepOutputs = true;
|
keepOutputs = true;
|
||||||
};
|
};
|
||||||
nixpkgs = { march = "alderlake"; cudaSupport = true; };
|
nixpkgs =
|
||||||
gui = { enable = true; preferred = true; };
|
{ march = "alderlake"; cuda = { enable = true; capabilities = [ "8.6" ]; forwardCompat = false; }; };
|
||||||
kernel =
|
kernel.patches = [ "cjktty" ];
|
||||||
{
|
|
||||||
patches = [ "cjktty" "preempt" ];
|
|
||||||
modules.modprobeConfig = [ "options iwlmvm power_scheme=1" "options iwlwifi uapsd_disable=1" ];
|
|
||||||
};
|
|
||||||
impermanence.enable = true;
|
impermanence.enable = true;
|
||||||
networking =
|
networking.hostname = "pc";
|
||||||
{ hostname = "pc"; nebula = { enable = true; lighthouse = "vps6.chn.moe"; useRelay = true; }; };
|
sysctl.laptop-mode = 5;
|
||||||
sops = { enable = true; keyPathPrefix = "/nix/persistent"; };
|
|
||||||
};
|
};
|
||||||
hardware =
|
hardware =
|
||||||
{
|
{
|
||||||
@@ -141,17 +129,10 @@
|
|||||||
joystick.enable = true;
|
joystick.enable = true;
|
||||||
printer.enable = true;
|
printer.enable = true;
|
||||||
sound.enable = true;
|
sound.enable = true;
|
||||||
prime =
|
prime = { enable = true; mode = "offload"; busId = { intel = "PCI:0:2:0"; nvidia = "PCI:1:0:0"; }; };
|
||||||
{ enable = true; mode = "offload"; busId = { intel = "PCI:0:2:0"; nvidia = "PCI:1:0:0"; };};
|
|
||||||
gamemode.drmDevice = 1;
|
gamemode.drmDevice = 1;
|
||||||
};
|
};
|
||||||
packages =
|
packages.packageSet = "workstation";
|
||||||
{
|
|
||||||
packageSet = "workstation";
|
|
||||||
extraPrebuildPackages = with inputs.pkgs; [ llvmPackages_git.stdenv ];
|
|
||||||
extraPythonPackages = [(pythonPackages:
|
|
||||||
[ inputs.pkgs.localPackages.upho inputs.pkgs.localPackages.spectral ])];
|
|
||||||
};
|
|
||||||
virtualization =
|
virtualization =
|
||||||
{
|
{
|
||||||
waydroid.enable = true;
|
waydroid.enable = true;
|
||||||
@@ -162,7 +143,7 @@
|
|||||||
};
|
};
|
||||||
services =
|
services =
|
||||||
{
|
{
|
||||||
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
|
snapper.enable = true;
|
||||||
fontconfig.enable = true;
|
fontconfig.enable = true;
|
||||||
samba =
|
samba =
|
||||||
{
|
{
|
||||||
@@ -188,41 +169,44 @@
|
|||||||
extraInterfaces = [ "docker0" ];
|
extraInterfaces = [ "docker0" ];
|
||||||
hosts =
|
hosts =
|
||||||
{
|
{
|
||||||
"mirism.one" = "216.24.188.24";
|
"mirism.one" = "74.211.99.69";
|
||||||
"beta.mirism.one" = "216.24.188.24";
|
"beta.mirism.one" = "74.211.99.69";
|
||||||
"ng01.mirism.one" = "216.24.188.24";
|
"ng01.mirism.one" = "74.211.99.69";
|
||||||
"debug.mirism.one" = "127.0.0.1";
|
"debug.mirism.one" = "127.0.0.1";
|
||||||
"initrd.vps6.chn.moe" = "74.211.99.69";
|
"initrd.vps6.chn.moe" = "74.211.99.69";
|
||||||
"nix-store.chn.moe" = "127.0.0.1";
|
"nix-store.chn.moe" = "127.0.0.1";
|
||||||
|
"initrd.nas.chn.moe" = "192.168.1.185";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
firewall.trustedInterfaces = [ "virbr0" "waydroid0" ];
|
firewall.trustedInterfaces = [ "virbr0" "waydroid0" ];
|
||||||
acme = { enable = true; certs = [ "debug.mirism.one" ]; };
|
acme = { enable = true; cert."debug.mirism.one" = {}; };
|
||||||
frpClient =
|
frpClient =
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = true;
|
||||||
serverName = "frp.chn.moe";
|
serverName = "frp.chn.moe";
|
||||||
user = "pc";
|
user = "pc";
|
||||||
tcp.store = { localPort = 443; remotePort = 7676; };
|
stcpVisitor."yy.vnc".localPort = 6187;
|
||||||
};
|
};
|
||||||
nix-serve = { enable = true; hostname = "nix-store.chn.moe"; };
|
nix-serve = { enable = true; hostname = "nix-store.chn.moe"; };
|
||||||
smartd.enable = true;
|
smartd.enable = true;
|
||||||
nginx = { enable = true; transparentProxy.enable = false; };
|
misskey.instances.misskey.hostname = "xn--qbtm095lrg0bfka60z.chn.moe";
|
||||||
misskey = { enable = true; hostname = "xn--qbtm095lrg0bfka60z.chn.moe"; };
|
beesd = { enable = true; instances.root = { device = "/"; hashTableSizeMB = 2048; }; };
|
||||||
misskey-proxy."xn--qbtm095lrg0bfka60z.chn.moe" = {};
|
wireguard =
|
||||||
huginn.enable = true;
|
{
|
||||||
|
enable = true;
|
||||||
|
peers = [ "vps6" ];
|
||||||
|
publicKey = "l1gFSDCeBxyf/BipXNvoEvVvLqPgdil84nmr5q6+EEw=";
|
||||||
|
wireguardIp = "192.168.83.3";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
bugs =
|
bugs =
|
||||||
[
|
[
|
||||||
"intel-hdmi" "suspend-hibernate-no-platform" "hibernate-iwlwifi" "suspend-lid-no-wakeup" "xmunet"
|
"suspend-hibernate-no-platform" "hibernate-iwlwifi" "suspend-lid-no-wakeup" "xmunet"
|
||||||
"suspend-hibernate-waydroid" "embree"
|
"suspend-hibernate-waydroid"
|
||||||
];
|
];
|
||||||
};})
|
};
|
||||||
];
|
vps6 =
|
||||||
"vps6" =
|
|
||||||
[
|
|
||||||
(inputs: { config.nixos =
|
|
||||||
{
|
{
|
||||||
system =
|
system =
|
||||||
{
|
{
|
||||||
@@ -248,60 +232,56 @@
|
|||||||
grub.installDevice = "/dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:0";
|
grub.installDevice = "/dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:0";
|
||||||
nixpkgs.march = "sandybridge";
|
nixpkgs.march = "sandybridge";
|
||||||
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
||||||
initrd =
|
initrd.sshd.enable = true;
|
||||||
{
|
|
||||||
network.enable = true;
|
|
||||||
sshd = { enable = true; hostKeys = [ "/nix/persistent/etc/ssh/initrd_ssh_host_ed25519_key" ]; };
|
|
||||||
};
|
|
||||||
kernel.patches = [ "preempt" ];
|
|
||||||
impermanence.enable = true;
|
impermanence.enable = true;
|
||||||
networking = { hostname = "vps6"; nebula.enable = true; };
|
networking.hostname = "vps6";
|
||||||
sops = { enable = true; keyPathPrefix = "/nix/persistent"; };
|
|
||||||
};
|
};
|
||||||
packages.packageSet = "server";
|
packages.packageSet = "server";
|
||||||
services =
|
services =
|
||||||
{
|
{
|
||||||
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
|
snapper.enable = true;
|
||||||
sshd.enable = true;
|
sshd.enable = true;
|
||||||
xrayServer = { enable = true; serverName = "vps6.xserver.chn.moe"; };
|
xrayServer = { enable = true; serverName = "vps6.xserver.chn.moe"; };
|
||||||
frpServer = { enable = true; serverName = "frp.chn.moe"; };
|
frpServer = { enable = true; serverName = "frp.chn.moe"; };
|
||||||
nginx =
|
nginx =
|
||||||
{
|
{
|
||||||
enable = true;
|
streamProxy.map =
|
||||||
transparentProxy =
|
|
||||||
{
|
{
|
||||||
externalIp = "74.211.99.69";
|
"anchor.fm" = { upstream = "anchor.fm:443"; proxyProtocol = false; };
|
||||||
map =
|
"podcasters.spotify.com" = { upstream = "podcasters.spotify.com:443"; proxyProtocol = false; };
|
||||||
{
|
"xlog.chn.moe" = { upstream = "cname.xlog.app:443"; proxyProtocol = false; };
|
||||||
"ng01.mirism.one" = 7411;
|
}
|
||||||
"beta.mirism.one" = 9114;
|
// (builtins.listToAttrs (builtins.map
|
||||||
};
|
(site: { name = "${site}.chn.moe"; value.upstream.address = "wireguard.pc.chn.moe"; })
|
||||||
};
|
[ "nix-store" "xn--qbtm095lrg0bfka60z" ]))
|
||||||
streamProxy =
|
// (builtins.listToAttrs (builtins.map
|
||||||
|
(site: { name = "${site}.chn.moe"; value.upstream.address = "wireguard.vps7.chn.moe"; })
|
||||||
|
[ "xn--s8w913fdga" "misskey" "synapse" "matrix" "send" "kkmeeting" "api" "git" "grafana" ]));
|
||||||
|
applications =
|
||||||
{
|
{
|
||||||
enable = true;
|
element.instances."element.chn.moe" = {};
|
||||||
map =
|
synapse-admin.instances."synapse-admin.chn.moe" = {};
|
||||||
{
|
catalog.enable = true;
|
||||||
"nix-store.chn.moe" = { upstream = "internal.pc.chn.moe"; rewriteHttps = true; };
|
blog.enable = true;
|
||||||
"anchor.fm" = { upstream = "anchor.fm:443"; rewriteHttps = true; };
|
main.enable = true;
|
||||||
"podcasters.spotify.com" = { upstream = "podcasters.spotify.com:443"; rewriteHttps = true; };
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
misskey-proxy =
|
|
||||||
{
|
|
||||||
"xn--qbtm095lrg0bfka60z.chn.moe".upstream.address = "internal.pc.chn.moe";
|
|
||||||
"xn--s8w913fdga.chn.moe".upstream.address = "internal.vps7.chn.moe";
|
|
||||||
};
|
|
||||||
coturn.enable = true;
|
coturn.enable = true;
|
||||||
synapse-proxy."synapse.chn.moe".upstream.address = "internal.vps7.chn.moe";
|
httpua.enable = true;
|
||||||
vaultwarden-proxy = { enable = true; upstream.address = "internal.vps7.chn.moe"; };
|
mirism.enable = true;
|
||||||
|
fail2ban.enable = true;
|
||||||
|
wireguard =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
peers = [ "pc" "nas" "vps7" ];
|
||||||
|
publicKey = "AVOsYUKQQCvo3ctst3vNi8XSVWo1Wh15066aHh+KpF4=";
|
||||||
|
wireguardIp = "192.168.83.1";
|
||||||
|
externalIp = "74.211.99.69";
|
||||||
|
lighthouse = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};})
|
};
|
||||||
];
|
vps7 =
|
||||||
"vps7" =
|
|
||||||
[
|
|
||||||
(inputs: { config.nixos =
|
|
||||||
{
|
{
|
||||||
system =
|
system =
|
||||||
{
|
{
|
||||||
@@ -327,42 +307,55 @@
|
|||||||
grub.installDevice = "/dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:0";
|
grub.installDevice = "/dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:0";
|
||||||
nixpkgs.march = "broadwell";
|
nixpkgs.march = "broadwell";
|
||||||
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
||||||
initrd =
|
initrd.sshd.enable = true;
|
||||||
{
|
|
||||||
network.enable = true;
|
|
||||||
sshd = { enable = true; hostKeys = [ "/nix/persistent/etc/ssh/initrd_ssh_host_ed25519_key" ]; };
|
|
||||||
};
|
|
||||||
kernel.patches = [ "preempt" ];
|
|
||||||
impermanence.enable = true;
|
impermanence.enable = true;
|
||||||
networking = { hostname = "vps7"; nebula = { enable = true; lighthouse = "vps6.chn.moe"; }; };
|
networking.hostname = "vps7";
|
||||||
sops = { enable = true; keyPathPrefix = "/nix/persistent"; };
|
gui.preferred = false;
|
||||||
gui.enable = true;
|
|
||||||
};
|
|
||||||
packages =
|
|
||||||
{
|
|
||||||
packageSet = "desktop";
|
|
||||||
};
|
};
|
||||||
|
packages.packageSet = "desktop";
|
||||||
services =
|
services =
|
||||||
{
|
{
|
||||||
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
|
snapper.enable = true;
|
||||||
|
fontconfig.enable = true;
|
||||||
sshd.enable = true;
|
sshd.enable = true;
|
||||||
rsshub.enable = true;
|
rsshub.enable = true;
|
||||||
nginx = { enable = true; transparentProxy.externalIp = "95.111.228.40"; };
|
|
||||||
wallabag.enable = true;
|
wallabag.enable = true;
|
||||||
misskey = { enable = true; hostname = "xn--s8w913fdga.chn.moe"; };
|
misskey.instances =
|
||||||
misskey-proxy."xn--s8w913fdga.chn.moe" = {};
|
{
|
||||||
synapse.enable = true;
|
misskey.hostname = "xn--s8w913fdga.chn.moe";
|
||||||
synapse-proxy."synapse.chn.moe" = {};
|
misskey-old = { port = 9727; redis.port = 3546; meilisearch.enable = false; };
|
||||||
xrdp = { enable = true; hostname = "vps7.chn.moe"; };
|
};
|
||||||
|
synapse.instances =
|
||||||
|
{
|
||||||
|
synapse.matrixHostname = "synapse.chn.moe";
|
||||||
|
matrix = { port = 8009; redisPort = 6380; hostname = "matrix.chn.moe"; };
|
||||||
|
};
|
||||||
|
xrdp = { enable = true; hostname = [ "vps7.chn.moe" ]; };
|
||||||
vaultwarden.enable = true;
|
vaultwarden.enable = true;
|
||||||
vaultwarden-proxy.enable = true;
|
beesd = { enable = true; instances.root = { device = "/"; hashTableSizeMB = 1024; }; };
|
||||||
# huginn.enable = true;
|
photoprism.enable = true;
|
||||||
|
nextcloud.enable = true;
|
||||||
|
freshrss.enable = true;
|
||||||
|
send.enable = true;
|
||||||
|
huginn.enable = true;
|
||||||
|
fz-new-order.enable = true;
|
||||||
|
nginx.applications = { kkmeeting.enable = true; webdav.instances."webdav.chn.moe" = {}; };
|
||||||
|
httpapi.enable = true;
|
||||||
|
mastodon.enable = true;
|
||||||
|
gitea.enable = true;
|
||||||
|
grafana.enable = true;
|
||||||
|
fail2ban.enable = true;
|
||||||
|
wireguard =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
peers = [ "vps6" ];
|
||||||
|
publicKey = "n056ppNxC9oECcW7wEbALnw8GeW7nrMImtexKWYVUBk=";
|
||||||
|
wireguardIp = "192.168.83.2";
|
||||||
|
externalIp = "95.111.228.40";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};})
|
};
|
||||||
];
|
nas =
|
||||||
"nas" =
|
|
||||||
[
|
|
||||||
(inputs: { config.nixos =
|
|
||||||
{
|
{
|
||||||
system =
|
system =
|
||||||
{
|
{
|
||||||
@@ -381,46 +374,44 @@
|
|||||||
"/nix/persistent" = "/nix/persistent";
|
"/nix/persistent" = "/nix/persistent";
|
||||||
"/nix/nodatacow" = "/nix/nodatacow";
|
"/nix/nodatacow" = "/nix/nodatacow";
|
||||||
"/nix/rootfs/current" = "/";
|
"/nix/rootfs/current" = "/";
|
||||||
|
"/nix/backup" = "/nix/backup";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
decrypt.auto =
|
decrypt.manual =
|
||||||
{
|
{
|
||||||
"/dev/disk/by-uuid/5cf1d19d-b4a5-4e67-8e10-f63f0d5bb649".mapper = "root1";
|
enable = true;
|
||||||
"/dev/disk/by-uuid/aa684baf-fd8a-459c-99ba-11eb7636cb0d".mapper = "root2";
|
devices =
|
||||||
"/dev/disk/by-uuid/a779198f-cce9-4c3d-a64a-9ec45f6f5495" = { mapper = "nix"; ssd = true; };
|
{
|
||||||
|
"/dev/disk/by-uuid/5cf1d19d-b4a5-4e67-8e10-f63f0d5bb649".mapper = "root1";
|
||||||
|
"/dev/disk/by-uuid/aa684baf-fd8a-459c-99ba-11eb7636cb0d".mapper = "root2";
|
||||||
|
"/dev/disk/by-uuid/a779198f-cce9-4c3d-a64a-9ec45f6f5495" = { mapper = "nix"; ssd = true; };
|
||||||
|
};
|
||||||
|
delayedMount = [ "/" "/nix" ];
|
||||||
};
|
};
|
||||||
|
swap = [ "/nix/swap/swap" ];
|
||||||
rollingRootfs = { device = "/dev/mapper/root1"; path = "/nix/rootfs"; };
|
rollingRootfs = { device = "/dev/mapper/root1"; path = "/nix/rootfs"; };
|
||||||
};
|
};
|
||||||
|
initrd.sshd.enable = true;
|
||||||
grub.installDevice = "efi";
|
grub.installDevice = "efi";
|
||||||
nixpkgs.march = "silvermont";
|
nixpkgs.march = "silvermont";
|
||||||
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
||||||
kernel.patches = [ "cjktty" "preempt" ];
|
kernel.patches = [ "cjktty" ];
|
||||||
impermanence.enable = true;
|
impermanence.enable = true;
|
||||||
networking =
|
networking.hostname = "nas";
|
||||||
{ hostname = "nas"; nebula = { enable = true; lighthouse = "vps6.chn.moe"; useRelay = true; }; };
|
gui.preferred = false;
|
||||||
sops = { enable = true; keyPathPrefix = "/nix/persistent"; };
|
|
||||||
gui.enable = true;
|
|
||||||
};
|
|
||||||
hardware =
|
|
||||||
{
|
|
||||||
cpus = [ "intel" ];
|
|
||||||
gpus = [ "intel" ];
|
|
||||||
};
|
};
|
||||||
|
hardware = { cpus = [ "intel" ]; gpus = [ "intel" ]; };
|
||||||
packages.packageSet = "desktop";
|
packages.packageSet = "desktop";
|
||||||
services =
|
services =
|
||||||
{
|
{
|
||||||
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
|
snapper.enable = true;
|
||||||
fontconfig.enable = true;
|
fontconfig.enable = true;
|
||||||
samba =
|
samba =
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = true;
|
||||||
hostsAllowed = "192.168. 127.";
|
hostsAllowed = "192.168. 127.";
|
||||||
shares =
|
shares = { home.path = "/home"; root.path = "/"; };
|
||||||
{
|
|
||||||
home.path = "/home";
|
|
||||||
root.path = "/";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
sshd = { enable = true; passwordAuthentication = true; };
|
sshd = { enable = true; passwordAuthentication = true; };
|
||||||
xrayClient =
|
xrayClient =
|
||||||
@@ -433,136 +424,34 @@
|
|||||||
xrdp = { enable = true; hostname = [ "nas.chn.moe" "office.chn.moe" ]; };
|
xrdp = { enable = true; hostname = [ "nas.chn.moe" "office.chn.moe" ]; };
|
||||||
groupshare.enable = true;
|
groupshare.enable = true;
|
||||||
smartd.enable = true;
|
smartd.enable = true;
|
||||||
};
|
beesd =
|
||||||
users = [ "root" "chn" "xll" "zem" "yjq" "yxy" ];
|
|
||||||
};})
|
|
||||||
];
|
|
||||||
"xmupc1" =
|
|
||||||
[
|
|
||||||
(inputs: { config.nixos =
|
|
||||||
{
|
|
||||||
system =
|
|
||||||
{
|
|
||||||
fileSystems =
|
|
||||||
{
|
|
||||||
mount =
|
|
||||||
{
|
|
||||||
vfat."/dev/disk/by-uuid/3F57-0EBE" = "/boot/efi";
|
|
||||||
btrfs =
|
|
||||||
{
|
|
||||||
"/dev/disk/by-uuid/02e426ec-cfa2-4a18-b3a5-57ef04d66614"."/" = "/boot";
|
|
||||||
"/dev/mapper/root" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
decrypt.auto =
|
|
||||||
{
|
|
||||||
"/dev/disk/by-uuid/55fdd19f-0f1d-4c37-bd4e-6df44fc31f26" = { mapper = "root"; ssd = true; };
|
|
||||||
"/dev/md/swap" = { mapper = "swap"; ssd = true; before = [ "root" ]; };
|
|
||||||
};
|
|
||||||
mdadm =
|
|
||||||
"ARRAY /dev/md/swap metadata=1.2 name=pc:swap UUID=2b546b8d:e38007c8:02990dd1:df9e23a4";
|
|
||||||
swap = [ "/dev/mapper/swap" ];
|
|
||||||
resume = "/dev/mapper/swap";
|
|
||||||
rollingRootfs = { device = "/dev/mapper/root"; path = "/nix/rootfs"; };
|
|
||||||
};
|
|
||||||
grub.installDevice = "efi";
|
|
||||||
nixpkgs = { march = "znver3"; cudaSupport = true; };
|
|
||||||
nix =
|
|
||||||
{
|
|
||||||
marches =
|
|
||||||
[
|
|
||||||
"znver3" "znver2"
|
|
||||||
# PREFETCHW RDRND XSAVE XSAVEOPT PTWRITE SGX GFNI-SSE MOVDIRI MOVDIR64B CLDEMOTE WAITPKG LZCNT
|
|
||||||
# PCONFIG SERIALIZE HRESET KL WIDEKL AVX-VNNI
|
|
||||||
"alderlake"
|
|
||||||
# SAHF FXSR XSAVE
|
|
||||||
"sandybridge"
|
|
||||||
# SAHF FXSR PREFETCHW RDRND
|
|
||||||
"silvermont"
|
|
||||||
];
|
|
||||||
substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
|
||||||
};
|
|
||||||
gui.enable = true;
|
|
||||||
kernel =
|
|
||||||
{
|
|
||||||
patches = [ "cjktty" "preempt" ];
|
|
||||||
modules.modprobeConfig = [ "options iwlmvm power_scheme=1" "options iwlwifi uapsd_disable=1" ];
|
|
||||||
};
|
|
||||||
impermanence.enable = true;
|
|
||||||
networking.hostname = "xmupc1";
|
|
||||||
sops = { enable = true; keyPathPrefix = "/nix/persistent"; };
|
|
||||||
};
|
|
||||||
hardware =
|
|
||||||
{
|
|
||||||
cpus = [ "intel" ];
|
|
||||||
gpus = [ "intel" "nvidia" ];
|
|
||||||
bluetooth.enable = true;
|
|
||||||
joystick.enable = true;
|
|
||||||
printer.enable = true;
|
|
||||||
sound.enable = true;
|
|
||||||
prime =
|
|
||||||
{ enable = true; mode = "offload"; busId = { intel = "PCI:0:2:0"; nvidia = "PCI:1:0:0"; };};
|
|
||||||
};
|
|
||||||
packages.packageSet = "workstation";
|
|
||||||
virtualization =
|
|
||||||
{
|
|
||||||
docker.enable = true;
|
|
||||||
kvmHost = { enable = true; gui = true; };
|
|
||||||
};
|
|
||||||
services =
|
|
||||||
{
|
|
||||||
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
|
|
||||||
fontconfig.enable = true;
|
|
||||||
samba =
|
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = true;
|
||||||
hostsAllowed = "192.168. 127.";
|
instances =
|
||||||
shares =
|
|
||||||
{
|
{
|
||||||
media.path = "/run/media/chn";
|
root = { device = "/"; hashTableSizeMB = 2048; };
|
||||||
home.path = "/home/chn";
|
nix = { device = "/nix"; hashTableSizeMB = 128; };
|
||||||
mnt.path = "/mnt";
|
|
||||||
share.path = "/home/chn/share";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
sshd.enable = true;
|
|
||||||
xrayClient =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
serverAddress = "74.211.99.69";
|
|
||||||
serverName = "vps6.xserver.chn.moe";
|
|
||||||
dns =
|
|
||||||
{
|
|
||||||
extraInterfaces = [ "docker0" ];
|
|
||||||
hosts =
|
|
||||||
{
|
|
||||||
"mirism.one" = "216.24.188.24";
|
|
||||||
"beta.mirism.one" = "216.24.188.24";
|
|
||||||
"ng01.mirism.one" = "216.24.188.24";
|
|
||||||
"debug.mirism.one" = "127.0.0.1";
|
|
||||||
"initrd.vps6.chn.moe" = "74.211.99.69";
|
|
||||||
"nix-store.chn.moe" = "127.0.0.1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
firewall.trustedInterfaces = [ "virbr0" ];
|
|
||||||
frpClient =
|
frpClient =
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = true;
|
||||||
serverName = "frp.chn.moe";
|
serverName = "frp.chn.moe";
|
||||||
user = "xmupc1";
|
user = "nas";
|
||||||
tcp.store = { localPort = 443; remotePort = 7676; };
|
stcp.hpc = { localIp = "hpc.xmu.edu.cn"; localPort = 22; };
|
||||||
|
};
|
||||||
|
nginx = { enable = true; applications.webdav.instances."local.webdav.chn.moe" = {}; };
|
||||||
|
wireguard =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
peers = [ "vps6" ];
|
||||||
|
publicKey = "xCYRbZEaGloMk7Awr00UR3JcDJy4AzVp4QvGNoyEgFY=";
|
||||||
|
wireguardIp = "192.168.83.4";
|
||||||
};
|
};
|
||||||
smartd.enable = true;
|
|
||||||
nginx = { enable = true; transparentProxy.enable = false; };
|
|
||||||
postgresql.enable = true;
|
|
||||||
};
|
};
|
||||||
bugs = [ "xmunet" "firefox" "embree" ];
|
users.users = [ "chn" "xll" "zem" "yjq" "yxy" ];
|
||||||
};})
|
};
|
||||||
];
|
yoga =
|
||||||
"yoga" =
|
|
||||||
[
|
|
||||||
(inputs: { config.nixos =
|
|
||||||
{
|
{
|
||||||
system =
|
system =
|
||||||
{
|
{
|
||||||
@@ -583,13 +472,11 @@
|
|||||||
rollingRootfs = { device = "/dev/mapper/root"; path = "/nix/rootfs"; };
|
rollingRootfs = { device = "/dev/mapper/root"; path = "/nix/rootfs"; };
|
||||||
};
|
};
|
||||||
nixpkgs.march = "silvermont";
|
nixpkgs.march = "silvermont";
|
||||||
gui.enable = true;
|
|
||||||
grub.installDevice = "efi";
|
grub.installDevice = "efi";
|
||||||
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
||||||
kernel.patches = [ "cjktty" "preempt" ];
|
kernel.patches = [ "cjktty" ];
|
||||||
impermanence.enable = true;
|
impermanence.enable = true;
|
||||||
networking.hostname = "yoga";
|
networking.hostname = "yoga";
|
||||||
sops = { enable = true; keyPathPrefix = "/nix/persistent"; };
|
|
||||||
};
|
};
|
||||||
hardware =
|
hardware =
|
||||||
{
|
{
|
||||||
@@ -599,12 +486,13 @@
|
|||||||
joystick.enable = true;
|
joystick.enable = true;
|
||||||
printer.enable = true;
|
printer.enable = true;
|
||||||
sound.enable = true;
|
sound.enable = true;
|
||||||
|
halo-keyboard.enable = true;
|
||||||
};
|
};
|
||||||
packages.packageSet = "desktop";
|
packages.packageSet = "desktop-fat";
|
||||||
virtualization.docker.enable = true;
|
virtualization.docker.enable = true;
|
||||||
services =
|
services =
|
||||||
{
|
{
|
||||||
snapper = { enable = true; configs.persistent = "/nix/persistent"; };
|
snapper.enable = true;
|
||||||
fontconfig.enable = true;
|
fontconfig.enable = true;
|
||||||
sshd.enable = true;
|
sshd.enable = true;
|
||||||
xrayClient =
|
xrayClient =
|
||||||
@@ -615,11 +503,122 @@
|
|||||||
dns.extraInterfaces = [ "docker0" ];
|
dns.extraInterfaces = [ "docker0" ];
|
||||||
};
|
};
|
||||||
firewall.trustedInterfaces = [ "virbr0" ];
|
firewall.trustedInterfaces = [ "virbr0" ];
|
||||||
smartd.enable = true;
|
|
||||||
};
|
};
|
||||||
};})
|
bugs = [ "xmunet" ];
|
||||||
];
|
};
|
||||||
}));
|
xmupc1 =
|
||||||
|
{
|
||||||
|
system =
|
||||||
|
{
|
||||||
|
fileSystems =
|
||||||
|
{
|
||||||
|
mount =
|
||||||
|
{
|
||||||
|
vfat."/dev/disk/by-uuid/3F57-0EBE" = "/boot/efi";
|
||||||
|
btrfs =
|
||||||
|
{
|
||||||
|
"/dev/disk/by-uuid/02e426ec-cfa2-4a18-b3a5-57ef04d66614"."/" = "/boot";
|
||||||
|
"/dev/mapper/root" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
swap = [ "/dev/mapper/swap" ];
|
||||||
|
resume = "/dev/mapper/swap";
|
||||||
|
rollingRootfs = { device = "/dev/mapper/root"; path = "/nix/rootfs"; };
|
||||||
|
};
|
||||||
|
grub.installDevice = "efi";
|
||||||
|
nixpkgs =
|
||||||
|
{
|
||||||
|
march = "znver3";
|
||||||
|
cuda =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
capabilities =
|
||||||
|
[
|
||||||
|
# 2080 Ti
|
||||||
|
"7.5"
|
||||||
|
# 3090
|
||||||
|
"8.6"
|
||||||
|
# 4090
|
||||||
|
"8.9"
|
||||||
|
];
|
||||||
|
forwardCompat = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
gui.preferred = false;
|
||||||
|
kernel.patches = [ "cjktty" ];
|
||||||
|
impermanence.enable = true;
|
||||||
|
networking.hostname = "xmupc1";
|
||||||
|
};
|
||||||
|
hardware =
|
||||||
|
{
|
||||||
|
cpus = [ "amd" ];
|
||||||
|
gpus = [ "nvidia" ];
|
||||||
|
bluetooth.enable = true;
|
||||||
|
joystick.enable = true;
|
||||||
|
printer.enable = true;
|
||||||
|
sound.enable = true;
|
||||||
|
gamemode.drmDevice = 1;
|
||||||
|
};
|
||||||
|
packages.packageSet = "workstation";
|
||||||
|
virtualization = { docker.enable = true; kvmHost = { enable = true; gui = true; }; };
|
||||||
|
services =
|
||||||
|
{
|
||||||
|
snapper.enable = true;
|
||||||
|
fontconfig.enable = true;
|
||||||
|
samba =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
private = true;
|
||||||
|
hostsAllowed = "192.168. 127.";
|
||||||
|
shares =
|
||||||
|
{
|
||||||
|
media.path = "/run/media/chn";
|
||||||
|
home.path = "/home/chn";
|
||||||
|
mnt.path = "/mnt";
|
||||||
|
share.path = "/home/chn/share";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
sshd.enable = true;
|
||||||
|
xrayClient =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
serverAddress = "74.211.99.69";
|
||||||
|
serverName = "vps6.xserver.chn.moe";
|
||||||
|
dns.extraInterfaces = [ "docker0" ];
|
||||||
|
};
|
||||||
|
firewall.trustedInterfaces = [ "virbr0" "waydroid0" ];
|
||||||
|
acme = { enable = true; cert."debug.mirism.one" = {}; };
|
||||||
|
smartd.enable = true;
|
||||||
|
beesd = { enable = true; instances.root = { device = "/nix/persistent"; hashTableSizeMB = 2048; }; };
|
||||||
|
wireguard =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
peers = [ "vps6" ];
|
||||||
|
publicKey = "JEY7D4ANfTpevjXNvGDYO6aGwtBGRXsf/iwNwjwDRQk=";
|
||||||
|
wireguardIp = "192.168.83.5";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
bugs = [ "xmunet" "firefox" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in builtins.listToAttrs (builtins.map
|
||||||
|
(system:
|
||||||
|
{
|
||||||
|
name = system.name;
|
||||||
|
value = inputs.nixpkgs.lib.nixosSystem
|
||||||
|
{
|
||||||
|
system = "x86_64-linux";
|
||||||
|
specialArgs = { topInputs = inputs; inherit localLib; };
|
||||||
|
modules = localLib.mkModules
|
||||||
|
[
|
||||||
|
(inputs: { config.nixpkgs.overlays = [(final: prev:
|
||||||
|
{ localPackages = (import ./local/pkgs { inherit (inputs) lib; pkgs = final; }); })]; })
|
||||||
|
./modules
|
||||||
|
{ config.nixos = system.value; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(localLib.attrsToList system));
|
||||||
# sudo HTTPS_PROXY=socks5://127.0.0.1:10884 nixos-install --flake .#bootstrap --option substituters http://127.0.0.1:5000 --option require-sigs false --option system-features gccarch-silvermont
|
# sudo HTTPS_PROXY=socks5://127.0.0.1:10884 nixos-install --flake .#bootstrap --option substituters http://127.0.0.1:5000 --option require-sigs false --option system-features gccarch-silvermont
|
||||||
# nix-serve -p 5000
|
# nix-serve -p 5000
|
||||||
# nix copy --substitute-on-destination --to ssh://server /run/current-system
|
# nix copy --substitute-on-destination --to ssh://server /run/current-system
|
||||||
@@ -652,10 +651,13 @@
|
|||||||
{
|
{
|
||||||
hostname = node;
|
hostname = node;
|
||||||
profiles.system.path = inputs.self.nixosConfigurations.${node}.pkgs.deploy-rs.lib.activate.nixos
|
profiles.system.path = inputs.self.nixosConfigurations.${node}.pkgs.deploy-rs.lib.activate.nixos
|
||||||
inputs.self.nixosConfigurations.${node};
|
inputs.self.nixosConfigurations.${node};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
[ "vps6" "vps7" "nas" ]);
|
[ "vps6" "vps7" "nas" "yoga" ]);
|
||||||
};
|
};
|
||||||
|
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks inputs.self.deploy) inputs.deploy-rs.lib;
|
||||||
|
overlays.default = final: prev:
|
||||||
|
{ localPackages = (import ./local/pkgs { inherit (inputs) lib; pkgs = final; }); };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,4 +32,9 @@ lib:
|
|||||||
in
|
in
|
||||||
# Split into lines. Strip leading tabs. Concat back to string.
|
# Split into lines. Strip leading tabs. Concat back to string.
|
||||||
builtins.concatStringsSep "\n" (stripTabs (lib.strings.splitString "\n" text));
|
builtins.concatStringsSep "\n" (stripTabs (lib.strings.splitString "\n" text));
|
||||||
|
|
||||||
|
# find an element in a list, return the index
|
||||||
|
findIndex = e: list:
|
||||||
|
let findIndex_ = i: list: if (builtins.elemAt list i) == e then i else findIndex_ (i + 1) list;
|
||||||
|
in findIndex_ 0 list;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
lib, stdenv, fetchsvn, xorg, libdrm
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec
|
|
||||||
{
|
|
||||||
pname = "12to11";
|
|
||||||
version = "193";
|
|
||||||
src = fetchsvn
|
|
||||||
{
|
|
||||||
url = "svn://svn.code.sf.net/p/twelveto11/code";
|
|
||||||
rev = version;
|
|
||||||
sha256 = "12csy55f2xxj03c5b60dvip68mz8cggic6751y3hvj22ar4ncaaj";
|
|
||||||
};
|
|
||||||
postPatch =
|
|
||||||
''
|
|
||||||
for i in *.c
|
|
||||||
do
|
|
||||||
sed -i -e "s|#include <drm_fourcc.h>|#include <libdrm/drm_fourcc.h>|" $i
|
|
||||||
done
|
|
||||||
for i in tests/*.c
|
|
||||||
do
|
|
||||||
sed -i -e "s|#include <drm/drm_fourcc.h>|#include <libdrm/drm_fourcc.h>|" $i
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
|
|
||||||
nativeBuildInputs = [ ];
|
|
||||||
buildInputs = [ xorg.imake libdrm.dev ];
|
|
||||||
}
|
|
||||||
17
local/pkgs/biu/default.nix
Normal file
17
local/pkgs/biu/default.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
stdenv, fetchFromGitHub, cmake, pkg-config, ninja,
|
||||||
|
fmt, boost, magic-enum, libbacktrace, concurrencpp, tgbot-cpp, nameof, eigen, range-v3
|
||||||
|
}: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
name = "libbiu";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "CHN-beta";
|
||||||
|
repo = "biu";
|
||||||
|
rev = "8ed2e52968f98d3a6ddbd01e86e57604ba3a7f54";
|
||||||
|
sha256 = "OqQ+QkjjIbpve/xn/DJA7ONw/bBg5zGNr+VJjc3o+K8=";
|
||||||
|
};
|
||||||
|
nativeBuildInputs = [ cmake pkg-config ninja ];
|
||||||
|
buildInputs = [ fmt boost magic-enum libbacktrace concurrencpp tgbot-cpp nameof eigen range-v3 ];
|
||||||
|
propagatedBuildInputs = buildInputs;
|
||||||
|
}
|
||||||
18
local/pkgs/chromiumos-touch-keyboard/default.nix
Normal file
18
local/pkgs/chromiumos-touch-keyboard/default.nix
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{ lib, stdenv, fetchFromGitHub, fetchurl, cmake }: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
pname = "chromiumos-touch-keyboard";
|
||||||
|
version = "1.4.1";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "CHN-beta";
|
||||||
|
repo = "chromiumos_touch_keyboard";
|
||||||
|
rev = "32b72240ccac751a1b983152f65aa5b19503ffcf";
|
||||||
|
sha256 = "eFesDSBS2VzTOVfepgXYGynWvkrCSdCV9C/gcG/Ocbg=";
|
||||||
|
};
|
||||||
|
cmakeFlags = [ "-DCMAKE_CXX_FLAGS=-Wno-error=stringop-truncation" ];
|
||||||
|
nativeBuildInputs = [ cmake ];
|
||||||
|
postInstall =
|
||||||
|
''
|
||||||
|
cp $out/etc/touch_keyboard/layouts/YB1-X9x-pc105.csv $out/etc/touch_keyboard/layout.csv
|
||||||
|
'';
|
||||||
|
}
|
||||||
30
local/pkgs/citation-style-language/default.nix
Normal file
30
local/pkgs/citation-style-language/default.nix
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{ stdenvNoCC, texlive, fetchFromGitHub }: stdenvNoCC.mkDerivation (finalAttrs: rec
|
||||||
|
{
|
||||||
|
pname = "citation-style-language";
|
||||||
|
version = "0.4.5";
|
||||||
|
passthru = {
|
||||||
|
pkgs = [ finalAttrs.finalPackage ];
|
||||||
|
tlDeps = with texlive; [ latex ];
|
||||||
|
tlType = "run";
|
||||||
|
};
|
||||||
|
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "zepinglee";
|
||||||
|
repo = "citeproc-lua";
|
||||||
|
rev = "v${version}";
|
||||||
|
sha256 = "XH+GH+t/10hr4bfaod8F9JPxmBnAQlDmpSvQNDQsslM=";
|
||||||
|
fetchSubmodules = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [ texlive.combined.scheme-full ];
|
||||||
|
dontConfigure = true;
|
||||||
|
dontBuild = true;
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
runHook preInstall
|
||||||
|
export TEXMFHOME=$out
|
||||||
|
l3build install
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
})
|
||||||
@@ -10,9 +10,4 @@
|
|||||||
sha256 = "4qT29YVjKEWcMrI5R5Ps8aD4grAAgz5VOxANjpp1oTo=";
|
sha256 = "4qT29YVjKEWcMrI5R5Ps8aD4grAAgz5VOxANjpp1oTo=";
|
||||||
};
|
};
|
||||||
nativeBuildInputs = [ cmake ];
|
nativeBuildInputs = [ cmake ];
|
||||||
postInstall =
|
|
||||||
''
|
|
||||||
mv $out/include/concurrencpp-${version}/concurrencpp $out/include
|
|
||||||
rm -rf $out/include/concurrencpp-${version}
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
local/pkgs/cppcoro/cppcoro-include-utility.patch
Normal file
12
local/pkgs/cppcoro/cppcoro-include-utility.patch
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/lib/static_thread_pool.cpp b/lib/static_thread_pool.cpp
|
||||||
|
index 989a6a9..0b91b9c 100644
|
||||||
|
--- a/lib/static_thread_pool.cpp
|
||||||
|
+++ b/lib/static_thread_pool.cpp
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <mutex>
|
||||||
|
#include <chrono>
|
||||||
|
+#include <utility>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
13
local/pkgs/cppcoro/default.nix
Normal file
13
local/pkgs/cppcoro/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{ stdenv, fetchFromGitHub, cmake }: stdenv.mkDerivation
|
||||||
|
{
|
||||||
|
name = "cppcoro";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "Garcia6l20";
|
||||||
|
repo = "cppcoro";
|
||||||
|
rev = "e1d53e620b0eee828915ada179cd7ca8e66ca855";
|
||||||
|
sha256 = "luBkf1x5kqXaVbQM01yWRmA5QvrQNZkFVCjRctJdnXc=";
|
||||||
|
};
|
||||||
|
nativeBuildInputs = [ cmake ];
|
||||||
|
patches = [ ./cppcoro-include-utility.patch ];
|
||||||
|
}
|
||||||
18
local/pkgs/date/default.nix
Normal file
18
local/pkgs/date/default.nix
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{ stdenv, fetchFromGitHub }: stdenv.mkDerivation
|
||||||
|
{
|
||||||
|
name = "date";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "HowardHinnant";
|
||||||
|
repo = "date";
|
||||||
|
rev = "cc4685a21e4a4fdae707ad1233c61bbaff241f93";
|
||||||
|
sha256 = "KilhBEeLMvHtS76Gu0UhzE8lhS1+sCwQ1UL4pswKXTs=";
|
||||||
|
};
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
runHook preInstall
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r $src/{include,src} $out
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -1,15 +1,11 @@
|
|||||||
{ lib, pkgs }: with pkgs;
|
{ lib, pkgs }: with pkgs; rec
|
||||||
{
|
{
|
||||||
typora = callPackage ./typora {};
|
typora = callPackage ./typora {};
|
||||||
upho = python3Packages.callPackage ./upho {};
|
|
||||||
spectral = python3Packages.callPackage ./spectral {};
|
|
||||||
vesta = callPackage ./vesta {};
|
vesta = callPackage ./vesta {};
|
||||||
oneapi = callPackage ./oneapi {};
|
oneapi = callPackage ./oneapi {};
|
||||||
send = callPackage ./send {};
|
|
||||||
rsshub = callPackage ./rsshub {};
|
rsshub = callPackage ./rsshub {};
|
||||||
misskey = callPackage ./misskey {};
|
misskey = callPackage ./misskey {};
|
||||||
mk-meili-mgn = callPackage ./mk-meili-mgn {};
|
mk-meili-mgn = callPackage ./mk-meili-mgn {};
|
||||||
phonon-unfolding = callPackage ./phonon-unfolding {};
|
|
||||||
# vasp = callPackage ./vasp
|
# vasp = callPackage ./vasp
|
||||||
# {
|
# {
|
||||||
# stdenv = pkgs.lmix-pkgs.intel21Stdenv;
|
# stdenv = pkgs.lmix-pkgs.intel21Stdenv;
|
||||||
@@ -22,8 +18,31 @@
|
|||||||
openmpi = pkgs.openmpi.override { cudaSupport = false; };
|
openmpi = pkgs.openmpi.override { cudaSupport = false; };
|
||||||
};
|
};
|
||||||
vaspkit = callPackage ./vaspkit { attrsToList = (import ../lib lib).attrsToList; };
|
vaspkit = callPackage ./vaspkit { attrsToList = (import ../lib lib).attrsToList; };
|
||||||
# "12to11" = callPackage ./12to11 {};
|
|
||||||
huginn = callPackage ./huginn {};
|
|
||||||
v_sim = callPackage ./v_sim {};
|
v_sim = callPackage ./v_sim {};
|
||||||
concurrencpp = callPackage ./concurrencpp { stdenv = gcc13Stdenv; };
|
concurrencpp = callPackage ./concurrencpp { stdenv = gcc13Stdenv; };
|
||||||
|
eigengdb = python3Packages.callPackage ./eigengdb {};
|
||||||
|
nodesoup = callPackage ./nodesoup {};
|
||||||
|
matplotplusplus = callPackage ./matplotplusplus { inherit nodesoup glad; };
|
||||||
|
zpp-bits = callPackage ./zpp-bits {};
|
||||||
|
eigen = callPackage ./eigen {};
|
||||||
|
nameof = callPackage ./nameof {};
|
||||||
|
pslist = callPackage ./pslist {};
|
||||||
|
glad = callPackage ./glad {};
|
||||||
|
chromiumos-touch-keyboard = callPackage ./chromiumos-touch-keyboard {};
|
||||||
|
yoga-support = callPackage ./yoga-support {};
|
||||||
|
tgbot-cpp = callPackage ./tgbot-cpp {};
|
||||||
|
biu = callPackage ./biu { inherit concurrencpp tgbot-cpp nameof; stdenv = gcc13Stdenv; };
|
||||||
|
citation-style-language = callPackage ./citation-style-language {};
|
||||||
|
mirism = callPackage ./mirism
|
||||||
|
{
|
||||||
|
inherit cppcoro nameof tgbot-cpp date;
|
||||||
|
nghttp2 = nghttp2-2305.override { enableAsioLib = true; };
|
||||||
|
};
|
||||||
|
cppcoro = callPackage ./cppcoro {};
|
||||||
|
date = callPackage ./date {};
|
||||||
|
esbonio = python3Packages.callPackage ./esbonio {};
|
||||||
|
pix2tex = python3Packages.callPackage ./pix2tex {};
|
||||||
|
pyreadline3 = python3Packages.callPackage ./pyreadline3 {};
|
||||||
|
torchdata = python3Packages.callPackage ./torchdata {};
|
||||||
|
torchtext = python3Packages.callPackage ./torchtext { inherit torchdata; };
|
||||||
}
|
}
|
||||||
|
|||||||
12
local/pkgs/eigen/default.nix
Normal file
12
local/pkgs/eigen/default.nix
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{ lib, stdenv, fetchFromGitLab, cmake }: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
name = "eigen";
|
||||||
|
src = fetchFromGitLab
|
||||||
|
{
|
||||||
|
owner = "libeigen";
|
||||||
|
repo = name;
|
||||||
|
rev = "6d829e766ff1b1ab867d93631163cbc63ed5798f";
|
||||||
|
sha256 = "BXUnizcRPrOyiPpoyYJ4VVOjlG49aj80mgzPKmEYPKU=";
|
||||||
|
};
|
||||||
|
nativeBuildInputs = [ cmake ];
|
||||||
|
}
|
||||||
15
local/pkgs/eigengdb/default.nix
Normal file
15
local/pkgs/eigengdb/default.nix
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{ lib, fetchFromGitHub, buildPythonPackage, numpy, gdb }: buildPythonPackage
|
||||||
|
{
|
||||||
|
name = "eigengdb";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "dmillard";
|
||||||
|
repo = "eigengdb";
|
||||||
|
rev = "c741edef3f07f33429056eff48d79a62733ed494";
|
||||||
|
sha256 = "MTqOaWsKhWaPs3G5F/6bYZmQI5qS2hEGKGa3mwbgFaY=";
|
||||||
|
};
|
||||||
|
doCheck = false;
|
||||||
|
buildInputs = [ gdb ];
|
||||||
|
nativeBuildInputs = [ gdb ];
|
||||||
|
propagatedBuildInputs = [ numpy ];
|
||||||
|
}
|
||||||
11
local/pkgs/esbonio/default.nix
Normal file
11
local/pkgs/esbonio/default.nix
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{ lib, fetchPypi, buildPythonPackage }: buildPythonPackage rec
|
||||||
|
{
|
||||||
|
pname = "esbonio";
|
||||||
|
version = "0.16.3";
|
||||||
|
src = fetchPypi
|
||||||
|
{
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "1ggxdzl95fy0zxpyd1pcylhif1x604wk4wy7sv9322hc84b708zx";
|
||||||
|
};
|
||||||
|
doCheck = false;
|
||||||
|
}
|
||||||
14
local/pkgs/glad/default.nix
Normal file
14
local/pkgs/glad/default.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{ lib, stdenv, fetchFromGitHub, cmake, python3 }: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
pname = "glad";
|
||||||
|
version = "0.1.36";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "Dav1dde";
|
||||||
|
repo = "glad";
|
||||||
|
rev = "v${version}";
|
||||||
|
sha256 = "FtkPz0xchwmqE+QgS+nSJVYaAfJSTUmZsObV/IPypVQ=";
|
||||||
|
};
|
||||||
|
cmakeFlags = [ "-DGLAD_REPRODUCIBLE=ON" "-DGLAD_INSTALL=ON" ];
|
||||||
|
nativeBuildInputs = [ cmake python3 ];
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
{ lib, stdenv, bundlerEnv, fetchFromGitHub }:
|
|
||||||
let
|
|
||||||
pname = "huginn";
|
|
||||||
version = "20230723";
|
|
||||||
src = fetchFromGitHub
|
|
||||||
{
|
|
||||||
owner = "CHN-beta";
|
|
||||||
repo = "huginn";
|
|
||||||
rev = "a02977ad420a01b6460634af19f714db4a8f8f36";
|
|
||||||
hash = "sha256-Ty2EDCIjbvcf3PzPupcV4s7ZfAFTuYEjSfy0m+Yt3j4=";
|
|
||||||
};
|
|
||||||
gems = bundlerEnv
|
|
||||||
{
|
|
||||||
name = "${pname}-${version}-gems";
|
|
||||||
gemdir = "${src}";
|
|
||||||
gemfile = "${src}/Gemfile";
|
|
||||||
lockfile = "${src}/Gemfile.lock";
|
|
||||||
gemset = "${src}/gemset.nix";
|
|
||||||
copyGemFiles = true;
|
|
||||||
};
|
|
||||||
in stdenv.mkDerivation
|
|
||||||
{
|
|
||||||
inherit pname version src;
|
|
||||||
buildInputs = [ gems gems.wrappedRuby ];
|
|
||||||
installPhase =
|
|
||||||
''
|
|
||||||
false
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
25
local/pkgs/matplotplusplus/default.nix
Normal file
25
local/pkgs/matplotplusplus/default.nix
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
stdenv, fetchFromGitHub, cmake, pkg-config, substituteAll,
|
||||||
|
gnuplot, libjpeg, libtiff, zlib, libpng, lapack, blas, fftw, opencv, nodesoup, cimg, glfw, libGL, python3, glad
|
||||||
|
}: stdenv.mkDerivation
|
||||||
|
{
|
||||||
|
pname = "matplotplusplus";
|
||||||
|
version = "1.2.0";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "alandefreitas";
|
||||||
|
repo = "matplotplusplus";
|
||||||
|
rev = "a40344efa9dc5ea0c312e6e9ef4eb7238d98dc12";
|
||||||
|
sha256 = "6/dH/Rl2aAb8b+Ji5LwzkC+GWPOCBnYCrjy0qk8u/+I=";
|
||||||
|
};
|
||||||
|
cmakeFlags =
|
||||||
|
[
|
||||||
|
"-DBUILD_SHARED_LIBS=ON" "-DMATPLOTPP_BUILD_SHARED_LIBS=ON" "-DMATPLOTPP_BUILD_EXAMPLES=OFF"
|
||||||
|
"-DMATPLOTPP_WITH_SYSTEM_NODESOUP=ON" "-DMATPLOTPP_WITH_SYSTEM_CIMG=ON"
|
||||||
|
"-DMATPLOTPP_BUILD_EXPERIMENTAL_OPENGL_BACKEND=ON" "-DGLAD_REPRODUCIBLE=ON"
|
||||||
|
];
|
||||||
|
buildInputs = [ gnuplot libjpeg libtiff zlib libpng lapack blas fftw opencv nodesoup cimg glfw libGL glad ];
|
||||||
|
nativeBuildInputs = [ cmake pkg-config python3 ];
|
||||||
|
propagatedBuildInputs = [ libGL glad glfw ];
|
||||||
|
propagatedNativeBuildInputs = [ python3 ];
|
||||||
|
}
|
||||||
29
local/pkgs/mirism/default.nix
Normal file
29
local/pkgs/mirism/default.nix
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
lib, stdenv, requireFile,
|
||||||
|
boost, nghttp2, brotli, nameof, cppcoro, tgbot-cpp, libbacktrace, fmt, date
|
||||||
|
}: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
name = "mirism";
|
||||||
|
# nix-store --query --hash $(nix store add-path . --name 'mirism')
|
||||||
|
src = requireFile
|
||||||
|
{
|
||||||
|
inherit name;
|
||||||
|
sha256 = "1q3f4q4ln9dz68dfc35jybgv861f7acqiiykkm7jxviz8jdgn8c7";
|
||||||
|
hashMode = "recursive";
|
||||||
|
message = "Source file not found.";
|
||||||
|
};
|
||||||
|
buildInputs = [ boost nghttp2.dev brotli nameof cppcoro tgbot-cpp libbacktrace fmt date ];
|
||||||
|
buildPhase =
|
||||||
|
''
|
||||||
|
runHook preBuild
|
||||||
|
make ng01 beta
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
runHook preInstall
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp build/{ng01,beta} $out/bin
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
lib, stdenv, mkPnpmPackage, fetchFromGitHub, nodejs_20, writeShellScript, buildFHSEnv,
|
lib, stdenv, mkPnpmPackage, fetchFromGitHub, fetchurl, nodejs_20, writeShellScript, buildFHSEnv,
|
||||||
bash, cypress, vips, pkg-config
|
bash, cypress, vips, pkg-config
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
pname = "misskey";
|
pname = "misskey";
|
||||||
version = "13.14.2";
|
version = "2023.11.1";
|
||||||
src = fetchFromGitHub
|
src = fetchFromGitHub
|
||||||
{
|
{
|
||||||
owner = "CHN-beta";
|
owner = "CHN-beta";
|
||||||
repo = "misskey";
|
repo = "misskey";
|
||||||
rev = "e02ecb3819f6f05352d43b64ae59fa1bd683e2e0";
|
rev = "1e5134816cc23600a0448a62b34aadfe573c3bbc";
|
||||||
hash = "sha256-zsYM67LYUn+bI6kbdW9blftxw5TUxCdzlfaOOEgZz+Q=";
|
sha256 = "ihkFVTpwEELmxAw4Lw01pWr8j6u2oLpfcw3laVUFCO4=";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
originalPnpmPackage = mkPnpmPackage
|
originalPnpmPackage = mkPnpmPackage
|
||||||
@@ -26,14 +26,66 @@ let
|
|||||||
export NODE_ENV=production
|
export NODE_ENV=production
|
||||||
pnpm run migrateandstart
|
pnpm run migrateandstart
|
||||||
'';
|
'';
|
||||||
|
re2 = stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
pname = "re2";
|
||||||
|
version = "1.20.8";
|
||||||
|
srcs =
|
||||||
|
[
|
||||||
|
(fetchurl
|
||||||
|
{
|
||||||
|
url = "https://github.com/uhop/node-re2/releases/download/1.20.8/linux-x64-120.br";
|
||||||
|
sha256 = "0f2l658xxc2112mbqpkyfic3vhjgdyafbfi14b6n40skyd6lijcq";
|
||||||
|
})
|
||||||
|
(fetchurl
|
||||||
|
{
|
||||||
|
url = "https://github.com/uhop/node-re2/releases/download/1.20.8/linux-x64-120.gz";
|
||||||
|
sha256 = "1v5n8i16188xpwx1jr8gcc1a99v83hlbh5hldl4i376vh0lwsxlq";
|
||||||
|
})
|
||||||
|
(fetchurl
|
||||||
|
{
|
||||||
|
url = "https://github.com/uhop/node-re2/releases/download/1.20.8/linux-x64-115.br";
|
||||||
|
sha256 = "0cyqmgqk5cwik27wh4ynaf94v4w6p1fsavm07xh8xfmdim2sr9kd";
|
||||||
|
})
|
||||||
|
(fetchurl
|
||||||
|
{
|
||||||
|
url = "https://github.com/uhop/node-re2/releases/download/1.20.8/linux-x64-115.gz";
|
||||||
|
sha256 = "0i3iykw13d5qfd5s6pq6kx6cbd64vfb3w65f9bnj87qz44la84ic";
|
||||||
|
})
|
||||||
|
(fetchurl
|
||||||
|
{
|
||||||
|
url = "https://github.com/uhop/node-re2/releases/download/1.20.8/linux-x64-108.br";
|
||||||
|
sha256 = "1467frfapqhi839r2v0p0wh76si3lihwzwgl9098mj7mwhjfl4lx";
|
||||||
|
})
|
||||||
|
(fetchurl
|
||||||
|
{
|
||||||
|
url = "https://github.com/uhop/node-re2/releases/download/1.20.8/linux-x64-108.gz";
|
||||||
|
sha256 = "0hykpqdrn55x83v1kzz6bdvrp24hgz3rwmwbdfl2saz576krzg1c";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
mkdir -p $out/${version}
|
||||||
|
for i in $srcs
|
||||||
|
do
|
||||||
|
cp $i $out/${version}/''${i#*-}
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
stdenv.mkDerivation
|
stdenv.mkDerivation rec
|
||||||
{
|
{
|
||||||
inherit version src pname;
|
inherit version src pname;
|
||||||
nativeBuildInputs =
|
buildInputs =
|
||||||
[ bash nodejs_20 nodejs_20.pkgs.typescript nodejs_20.pkgs.pnpm nodejs_20.pkgs.gulp cypress vips pkg-config ];
|
[
|
||||||
|
bash nodejs_20 nodejs_20.pkgs.typescript nodejs_20.pkgs.pnpm nodejs_20.pkgs.gulp cypress vips pkg-config
|
||||||
|
];
|
||||||
|
nativeBuildInputs = buildInputs;
|
||||||
CYPRESS_RUN_BINARY = "${cypress}/bin/Cypress";
|
CYPRESS_RUN_BINARY = "${cypress}/bin/Cypress";
|
||||||
NODE_ENV = "production";
|
NODE_ENV = "production";
|
||||||
|
RE2_DOWNLOAD_MIRROR = "${re2}";
|
||||||
|
RE2_DOWNLOAD_SKIP_PATH = "true";
|
||||||
configurePhase =
|
configurePhase =
|
||||||
''
|
''
|
||||||
export HOME=$NIX_BUILD_TOP # Some packages need a writable HOME
|
export HOME=$NIX_BUILD_TOP # Some packages need a writable HOME
|
||||||
@@ -67,4 +119,8 @@ in
|
|||||||
mkdir -p $out/files
|
mkdir -p $out/files
|
||||||
runHook postInstall
|
runHook postInstall
|
||||||
'';
|
'';
|
||||||
|
passthru =
|
||||||
|
{
|
||||||
|
inherit originalPnpmPackage startScript re2;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
20
local/pkgs/nameof/default.nix
Normal file
20
local/pkgs/nameof/default.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{ lib, stdenv, fetchFromGitHub }: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
pname = "nameof";
|
||||||
|
version = "0.10.3";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "Neargye";
|
||||||
|
repo = pname;
|
||||||
|
rev = "v${version}";
|
||||||
|
sha256 = "eHG0Y/BQGbwTrBHjq9SeSiIXaVqWp7PxIq7vCIECYPk=";
|
||||||
|
};
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
runHook preInstall
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r $src/include $out
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
}
|
||||||
13
local/pkgs/nodesoup/default.nix
Normal file
13
local/pkgs/nodesoup/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{ stdenv, fetchFromGitHub, cmake, pkg-config, cairo, pcre2, xorg }: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
name = "nodesoup";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "olvb";
|
||||||
|
repo = "nodesoup";
|
||||||
|
rev = "3158ad082bb0cd1abee75418b12b35522dbca74f";
|
||||||
|
sha256 = "tFLq6QC3U3uvcuWsdRy2wnwcmAfH2MkI2oMcAiUBHSo=";
|
||||||
|
};
|
||||||
|
buildInputs = [ cairo pcre2.dev xorg.libXdmcp.dev ];
|
||||||
|
nativeBuildInputs = [ cmake pkg-config ];
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
stdenv, fetchFromGitHub, gfortran, blas
|
|
||||||
}:
|
|
||||||
stdenv.mkDerivation
|
|
||||||
{
|
|
||||||
pname = "phonon-unfolding";
|
|
||||||
version = "0";
|
|
||||||
src = fetchFromGitHub
|
|
||||||
{
|
|
||||||
owner = "CHN-beta";
|
|
||||||
repo = "phonon_unfolding";
|
|
||||||
rev = "ec363ef2bad0ee18a0839a1681ea9915c0b72e1d";
|
|
||||||
hash = "sha256-zDTbtYk5OXf//6eS4gEF7IvrpWcRAz18ue48IDZnfSk=";
|
|
||||||
};
|
|
||||||
buildInputs = [ blas ];
|
|
||||||
nativeBuildInputs = [ gfortran ];
|
|
||||||
buildPhase =
|
|
||||||
''
|
|
||||||
gfortran PhononUnfoldingModule.f90 -o PhononUnfoldingModule.mod -c
|
|
||||||
gfortran PhononUnfolding.f90 -c -o PhononUnfolding.mod
|
|
||||||
gfortran PhononUnfolding.mod PhononUnfoldingModule.mod -o PhononUnfolding -lblas
|
|
||||||
'';
|
|
||||||
installPhase =
|
|
||||||
''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
cp PhononUnfolding $out/bin
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
32
local/pkgs/pix2tex/default.nix
Normal file
32
local/pkgs/pix2tex/default.nix
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
lib, fetchFromGitHub, buildPythonPackage,
|
||||||
|
# general dependencies:
|
||||||
|
tqdm, munch, torch, opencv, requests, einops, transformers, tokenizers, numpy, pillow, pyyaml, pandas, timm,
|
||||||
|
albumentations,
|
||||||
|
# gui
|
||||||
|
pyqt6, pyqt6-webengine, pyside6, pynput, screeninfo,
|
||||||
|
# api
|
||||||
|
streamlit, fastapi, uvicorn, python-multipart,
|
||||||
|
# training
|
||||||
|
# python-Levenshtein, torchtext, imagesize
|
||||||
|
# highlight
|
||||||
|
pygments
|
||||||
|
}: buildPythonPackage
|
||||||
|
{
|
||||||
|
name = "pix2tex";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "lukas-blecher";
|
||||||
|
repo = "LaTeX-OCR";
|
||||||
|
rev = "1781514fb8c92ea9f94057295fdae0e683f4648e";
|
||||||
|
hash = "sha256-I3B8eH7zV2zIogDt9znkEzp4EeBjY6NfI4jsl+v/8aM=";
|
||||||
|
};
|
||||||
|
patches = [ ./remove-version-requires.patch ];
|
||||||
|
propagatedBuildInputs =
|
||||||
|
[
|
||||||
|
tqdm munch torch opencv requests einops transformers tokenizers numpy pillow pyyaml pandas timm albumentations
|
||||||
|
pyqt6 pyqt6-webengine pyside6 pynput screeninfo
|
||||||
|
streamlit fastapi uvicorn python-multipart
|
||||||
|
pygments
|
||||||
|
];
|
||||||
|
}
|
||||||
13
local/pkgs/pix2tex/remove-version-requires.patch
Normal file
13
local/pkgs/pix2tex/remove-version-requires.patch
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/setup.py b/setup.py
|
||||||
|
index 29b26cb..511012f 100644
|
||||||
|
--- a/setup.py
|
||||||
|
+++ b/setup.py
|
||||||
|
@@ -64,7 +64,7 @@ setuptools.setup(
|
||||||
|
'Pillow>=9.1.0',
|
||||||
|
'PyYAML>=5.4.1',
|
||||||
|
'pandas>=1.0.0',
|
||||||
|
- 'timm==0.5.4',
|
||||||
|
+ 'timm>=0.5.4',
|
||||||
|
'albumentations>=0.5.2',
|
||||||
|
'pyreadline3>=3.4.1; platform_system=="Windows"',
|
||||||
|
],
|
||||||
27
local/pkgs/pslist/default.nix
Normal file
27
local/pkgs/pslist/default.nix
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# http://launchpadlibrarian.net/632309499/pslist_1.4.0-4_all.deb
|
||||||
|
# https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/pslist/1.4.0-4/pslist_1.4.0.orig.tar.xz
|
||||||
|
{ lib, stdenv, fetchzip, perl, procps }: stdenv.mkDerivation
|
||||||
|
{
|
||||||
|
pname = "pslist";
|
||||||
|
version = "1.4.0";
|
||||||
|
src = fetchzip
|
||||||
|
{
|
||||||
|
url = "https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/pslist/1.4.0-4/pslist_1.4.0.orig.tar.xz";
|
||||||
|
sha256 = "1sp1h7ccniz658ms331npffpa9iz8llig43d9mlysll420nb3xqv";
|
||||||
|
};
|
||||||
|
buildInstall = [ perl procps ];
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp $src/pslist $out/bin
|
||||||
|
ln -s pslist $out/bin/rkill
|
||||||
|
ln -s pslist $out/bin/rrenice
|
||||||
|
mkdir -p $out/share/man/man1
|
||||||
|
cp $src/pslist.1 $out/share/man/man1
|
||||||
|
ln -s pslist.1 $out/share/man/man1/rkill.1
|
||||||
|
ln -s pslist.1 $out/share/man/man1/rrenice.1
|
||||||
|
|
||||||
|
sed -i 's|/usr/bin/perl|${perl}/bin/perl|' $out/bin/pslist
|
||||||
|
sed -i 's|/bin/ps|${procps}/bin/ps|' $out/bin/pslist
|
||||||
|
'';
|
||||||
|
}
|
||||||
14
local/pkgs/pyreadline3/default.nix
Normal file
14
local/pkgs/pyreadline3/default.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
lib, fetchFromGitHub, buildPythonPackage
|
||||||
|
}: buildPythonPackage rec
|
||||||
|
{
|
||||||
|
pname = "pyreadline3";
|
||||||
|
version = "3.4.1";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "pyreadline3";
|
||||||
|
repo = "pyreadline3";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-02/gkx955NupVKXSu/xBQQtY4SEP4zxbNQYg1oQ/nGY=";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,21 +3,20 @@
|
|||||||
chromium, bash
|
chromium, bash
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
pname = "rsshub";
|
name = "rsshub";
|
||||||
version = "20230829";
|
|
||||||
src = fetchFromGitHub
|
src = fetchFromGitHub
|
||||||
{
|
{
|
||||||
owner = "DIYgod";
|
owner = "DIYgod";
|
||||||
repo = "RSSHub";
|
repo = "RSSHub";
|
||||||
rev = "afcf9774260dc6505263cf0428970e890f2f7b1d";
|
rev = "38a5b0c193bf77d71c4eea33db6e76bc8b565d0b";
|
||||||
hash = "sha256-BQFE0Z5DsFTf0tylQ0NN89hCdXT/Y2M+YPa/10ccOVg=";
|
hash = "sha256-gJsT9W2fFiy2IG89E5th49DpBHsPMfsdONyzAKDG48c=";
|
||||||
};
|
};
|
||||||
originalPnpmPackage = mkPnpmPackage { inherit pname version src nodejs; };
|
originalPnpmPackage = mkPnpmPackage { inherit name src nodejs; };
|
||||||
nodeModules = originalPnpmPackage.nodeModules.overrideAttrs { PUPPETEER_SKIP_DOWNLOAD = true; };
|
nodeModules = originalPnpmPackage.nodeModules.overrideAttrs { PUPPETEER_SKIP_DOWNLOAD = true; };
|
||||||
rsshub-unwrapped = stdenv.mkDerivation
|
rsshub-unwrapped = stdenv.mkDerivation
|
||||||
{
|
{
|
||||||
inherit version src;
|
inherit src;
|
||||||
pname = "${pname}-unwrapped";
|
name = "${name}-unwrapped";
|
||||||
configurePhase =
|
configurePhase =
|
||||||
''
|
''
|
||||||
export HOME=$NIX_BUILD_TOP # Some packages need a writable HOME
|
export HOME=$NIX_BUILD_TOP # Some packages need a writable HOME
|
||||||
@@ -44,9 +43,9 @@ let
|
|||||||
export CHROMIUM_EXECUTABLE_PATH=chromium
|
export CHROMIUM_EXECUTABLE_PATH=chromium
|
||||||
pnpm start
|
pnpm start
|
||||||
'';
|
'';
|
||||||
in stdenv.mkDerivation rec
|
in stdenv.mkDerivation
|
||||||
{
|
{
|
||||||
inherit pname version;
|
inherit name;
|
||||||
phases = [ "installPhase" ];
|
phases = [ "installPhase" ];
|
||||||
installPhase =
|
installPhase =
|
||||||
''
|
''
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
{ buildNpmPackage, fetchFromGitHub, nodejs-16_x }:
|
|
||||||
buildNpmPackage.override { nodejs = nodejs-16_x; }
|
|
||||||
{
|
|
||||||
pname = "send";
|
|
||||||
version = "3.4.23";
|
|
||||||
src = fetchFromGitHub
|
|
||||||
{
|
|
||||||
owner = "timvisee";
|
|
||||||
repo = "send";
|
|
||||||
rev = "6ad2885a168148fb996d3983457bc39527c7c8e5";
|
|
||||||
hash = "sha256-/w9KhktDVSAmp6EVIRHFM63mppsIzYSm5F7CQQd/2+E=";
|
|
||||||
};
|
|
||||||
npmDepsHash = "sha256-r1iaurKuhpP0sevB5pFdtv9j1ikM1fKL7Jgakh4FzTI=";
|
|
||||||
makeCacheWritable = true;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
lib, fetchPypi, buildPythonPackage,
|
|
||||||
numpy, pillow, wxPython_4_2, matplotlib, ipython, pyopengl
|
|
||||||
}: buildPythonPackage rec
|
|
||||||
{
|
|
||||||
pname = "spectral";
|
|
||||||
version = "0.23.1";
|
|
||||||
src = fetchPypi
|
|
||||||
{
|
|
||||||
inherit pname version;
|
|
||||||
sha256 = "sha256-4YIic1Je81g7J6lmIm1Vr+CefSmnI2z82LwN+x+Wj8I=";
|
|
||||||
};
|
|
||||||
doCheck = false;
|
|
||||||
propagatedBuildInputs = [ numpy pillow wxPython_4_2 matplotlib ipython pyopengl ];
|
|
||||||
}
|
|
||||||
15
local/pkgs/tgbot-cpp/default.nix
Normal file
15
local/pkgs/tgbot-cpp/default.nix
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{ stdenv, fetchFromGitHub, cmake, pkg-config, boost, openssl, zlib, curl }: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
pname = "tgbot-cpp";
|
||||||
|
version = "1.7.2";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "reo7sp";
|
||||||
|
repo = "tgbot-cpp";
|
||||||
|
rev = "v${version}";
|
||||||
|
sha256 = "TKirSxEUqFB1WtzNEfU4EJK3p7V5xcFIvA2+QVX7TlA=";
|
||||||
|
};
|
||||||
|
nativeBuildInputs = [ cmake pkg-config ];
|
||||||
|
buildInputs = [ boost openssl zlib curl.dev ];
|
||||||
|
propagatedBuildInputs = buildInputs;
|
||||||
|
}
|
||||||
20
local/pkgs/torchdata/default.nix
Normal file
20
local/pkgs/torchdata/default.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
lib, fetchFromGitHub, buildPythonPackage,
|
||||||
|
torch, urllib3, requests, cmake, pkg-config, ninja
|
||||||
|
}: buildPythonPackage rec
|
||||||
|
{
|
||||||
|
pname = "torchdata";
|
||||||
|
version = "0.7.1";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "pytorch";
|
||||||
|
repo = "data";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-SOeu+mI4p2tHX0YyctrDBcrz2/zYcwH9GGJ+6ytRmjQ=";
|
||||||
|
fetchSubmodules = true;
|
||||||
|
};
|
||||||
|
dontUseCmakeConfigure = true;
|
||||||
|
pyproject = true;
|
||||||
|
propagatedBuildInputs = [ torch urllib3 requests ];
|
||||||
|
nativeBuildInputs = [ cmake pkg-config ninja ];
|
||||||
|
}
|
||||||
20
local/pkgs/torchtext/default.nix
Normal file
20
local/pkgs/torchtext/default.nix
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
lib, fetchFromGitHub, buildPythonPackage,
|
||||||
|
tqdm, requests, torch, numpy, torchdata, cmake
|
||||||
|
}: buildPythonPackage rec
|
||||||
|
{
|
||||||
|
pname = "torchtext";
|
||||||
|
version = "0.16.1";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "pytorch";
|
||||||
|
repo = "text";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-4a33AWdd1VZwRL5vTawo0yplpw+qcNMetbfE1h1kafE=";
|
||||||
|
fetchSubmodules = true;
|
||||||
|
};
|
||||||
|
dontUseCmakeConfigure = true;
|
||||||
|
pyproject = true;
|
||||||
|
propagatedBuildInputs = [ tqdm requests torch numpy torchdata ];
|
||||||
|
nativeBuildInputs = [ cmake ];
|
||||||
|
}
|
||||||
@@ -3,11 +3,11 @@ let
|
|||||||
typora-dist = stdenv.mkDerivation rec
|
typora-dist = stdenv.mkDerivation rec
|
||||||
{
|
{
|
||||||
pname = "typora-dist";
|
pname = "typora-dist";
|
||||||
version = "1.6.6";
|
version = "1.7.6";
|
||||||
src = fetchurl
|
src = fetchurl
|
||||||
{
|
{
|
||||||
url = "https://download.typora.io/linux/typora_${version}_amd64.deb";
|
url = "https://download.typora.io/linux/typora_${version}_amd64.deb";
|
||||||
sha256 = "sha256-77mCgmsROLhfuOmOOyl2C5Ug2NfqEvcD+kMA3aiAQtA=";
|
sha256 = "19xgv83zk3mhniswwrb341sr9j4sb9pqy47jamrmkc3w8famxpd3";
|
||||||
};
|
};
|
||||||
|
|
||||||
dontFixup = true;
|
dontFixup = true;
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
{ lib, fetchFromGitHub, buildPythonPackage, numpy, h5py, phonopy }: buildPythonPackage rec
|
|
||||||
{
|
|
||||||
pname = "upho";
|
|
||||||
version = "0.6.6";
|
|
||||||
src = fetchFromGitHub
|
|
||||||
{
|
|
||||||
owner = "CHN-beta";
|
|
||||||
repo = "upho";
|
|
||||||
rev = "0f27ac6918e8972c70692816438e4ac37ec6b348";
|
|
||||||
sha256 = "sha256-NvoV+AUH9MmGT4ohrLAAvpLs8APP2DOKYlZVliHrVRM=";
|
|
||||||
};
|
|
||||||
doCheck = false;
|
|
||||||
propagatedBuildInputs = [ numpy h5py phonopy ];
|
|
||||||
}
|
|
||||||
24
local/pkgs/yoga-support/default.nix
Normal file
24
local/pkgs/yoga-support/default.nix
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{ lib, stdenv, fetchFromGitHub, python3 }:
|
||||||
|
let
|
||||||
|
python = python3.withPackages (ps: with ps; [ evdev pyudev ]);
|
||||||
|
in stdenv.mkDerivation
|
||||||
|
{
|
||||||
|
name = "yogabook-support";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "jekhor";
|
||||||
|
repo = "yogabook-support";
|
||||||
|
rev = "8ecf7861e469ba4094115fff0e81d537135e3f22";
|
||||||
|
sha256 = "4UtiQooCaeUDHc9YE9EQRJ2MNKvOqqCv85k0YyI2BO4=";
|
||||||
|
};
|
||||||
|
buildInputs = [ python ];
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp pen-key-handler yogabook-modes-handler $out/bin
|
||||||
|
mkdir -p $out/lib/udev/rules.d
|
||||||
|
cp 61-sensor-yogabook.rules $out/lib/udev/rules.d
|
||||||
|
mkdir -p $out/lib/udev/hwdb.d
|
||||||
|
cp 61-sensor-yogabook.hwdb $out/lib/udev/hwdb.d
|
||||||
|
'';
|
||||||
|
}
|
||||||
18
local/pkgs/zpp-bits/default.nix
Normal file
18
local/pkgs/zpp-bits/default.nix
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{ stdenv, fetchFromGitHub }: stdenv.mkDerivation rec
|
||||||
|
{
|
||||||
|
pname = "zpp-bits";
|
||||||
|
version = "4.4.19";
|
||||||
|
src = fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "eyalz800";
|
||||||
|
repo = "zpp_bits";
|
||||||
|
rev = "v${version}";
|
||||||
|
sha256 = "ejIwrvCFALuBQbQhTfzjBb11oMR/akKnboB60GWbjlQ=";
|
||||||
|
};
|
||||||
|
phases = [ "installPhase" ];
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
mkdir -p $out/include
|
||||||
|
cp $src/zpp_bits.h $out/include
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -5,8 +5,6 @@ inputs:
|
|||||||
inherit (inputs.lib) mkMerge mkIf mkOption types;
|
inherit (inputs.lib) mkMerge mkIf mkOption types;
|
||||||
bugs =
|
bugs =
|
||||||
{
|
{
|
||||||
# intel i915 hdmi
|
|
||||||
intel-hdmi.boot.kernelPatches = [{ name = "intel-hdmi"; patch = ./intel-hdmi.patch; }];
|
|
||||||
# suspend & hibernate do not use platform
|
# suspend & hibernate do not use platform
|
||||||
suspend-hibernate-no-platform.systemd.sleep.extraConfig =
|
suspend-hibernate-no-platform.systemd.sleep.extraConfig =
|
||||||
''
|
''
|
||||||
@@ -14,18 +12,23 @@ inputs:
|
|||||||
HibernateMode=shutdown
|
HibernateMode=shutdown
|
||||||
'';
|
'';
|
||||||
# reload iwlwifi after resume from hibernate
|
# reload iwlwifi after resume from hibernate
|
||||||
hibernate-iwlwifi.systemd.services.reload-iwlwifi-after-hibernate =
|
hibernate-iwlwifi =
|
||||||
{
|
{
|
||||||
description = "reload iwlwifi after resume from hibernate";
|
systemd.services.reload-iwlwifi-after-hibernate =
|
||||||
after = [ "systemd-hibernate.service" ];
|
{
|
||||||
serviceConfig.Type = "oneshot";
|
description = "reload iwlwifi after resume from hibernate";
|
||||||
script = let modprobe = "${inputs.pkgs.kmod}/bin/modprobe"; in
|
after = [ "systemd-hibernate.service" ];
|
||||||
''
|
serviceConfig.Type = "oneshot";
|
||||||
${modprobe} -r iwlwifi
|
script = let modprobe = "${inputs.pkgs.kmod}/bin/modprobe"; in
|
||||||
${modprobe} iwlwifi
|
''
|
||||||
echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
|
${modprobe} -r iwlwifi
|
||||||
'';
|
${modprobe} iwlwifi
|
||||||
wantedBy = [ "systemd-hibernate.service" ];
|
echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
|
||||||
|
'';
|
||||||
|
wantedBy = [ "systemd-hibernate.service" ];
|
||||||
|
};
|
||||||
|
nixos.system.kernel.modules.modprobeConfig =
|
||||||
|
[ "options iwlmvm power_scheme=1" "options iwlwifi uapsd_disable=1" ];
|
||||||
};
|
};
|
||||||
# disable wakeup on lid open
|
# disable wakeup on lid open
|
||||||
suspend-lid-no-wakeup.systemd.services.lid-no-wakeup =
|
suspend-lid-no-wakeup.systemd.services.lid-no-wakeup =
|
||||||
@@ -42,14 +45,16 @@ inputs:
|
|||||||
then
|
then
|
||||||
echo LID0 > /proc/acpi/wakeup
|
echo LID0 > /proc/acpi/wakeup
|
||||||
fi
|
fi
|
||||||
|
if ${cat} /proc/acpi/wakeup | ${grep} XHCI | ${grep} -q enabled
|
||||||
|
then
|
||||||
|
echo XHCI > /proc/acpi/wakeup
|
||||||
|
fi
|
||||||
'';
|
'';
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
};
|
};
|
||||||
# xmunet use old encryption
|
# xmunet use old encryption
|
||||||
xmunet.nixpkgs.config.packageOverrides = pkgs:
|
xmunet.nixpkgs.config.packageOverrides = pkgs: { wpa_supplicant = pkgs.wpa_supplicant.overrideAttrs
|
||||||
{
|
(attrs: { patches = attrs.patches ++ [ ./xmunet.patch ];}); };
|
||||||
wpa_supplicant = pkgs.wpa_supplicant.overrideAttrs (attrs: { patches = attrs.patches ++ [ ./xmunet.patch ];});
|
|
||||||
};
|
|
||||||
suspend-hibernate-waydroid.systemd.services =
|
suspend-hibernate-waydroid.systemd.services =
|
||||||
let
|
let
|
||||||
systemctl = "${inputs.pkgs.systemd}/bin/systemctl";
|
systemctl = "${inputs.pkgs.systemd}/bin/systemctl";
|
||||||
@@ -73,8 +78,6 @@ inputs:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
firefox.programs.firefox.enable = inputs.lib.mkForce false;
|
firefox.programs.firefox.enable = inputs.lib.mkForce false;
|
||||||
embree.nixpkgs.overlays =
|
|
||||||
[(final: prev: { embree = prev.embree.override { stdenv = final.genericPackages.stdenv; }; })];
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
|
|
||||||
index 55544d484318..d6f257f8fd14 100644
|
|
||||||
--- a/drivers/gpu/drm/i915/display/intel_bios.c
|
|
||||||
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
|
|
||||||
@@ -2708,7 +2708,7 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
|
|
||||||
if (i915->display.vbt.ports[port]) {
|
|
||||||
drm_dbg_kms(&i915->drm,
|
|
||||||
"More than one child device for port %c in VBT, using the first.\n",
|
|
||||||
port_name(port));
|
|
||||||
- return;
|
|
||||||
+ // return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sanitize_device_type(devdata, port);
|
|
||||||
@@ -13,23 +13,38 @@ inputs:
|
|||||||
topInputs.nur.nixosModules.nur
|
topInputs.nur.nixosModules.nur
|
||||||
topInputs.nur-xddxdd.nixosModules.setupOverlay
|
topInputs.nur-xddxdd.nixosModules.setupOverlay
|
||||||
topInputs.impermanence.nixosModules.impermanence
|
topInputs.impermanence.nixosModules.impermanence
|
||||||
(inputs: { config.nixpkgs.overlays =
|
(inputs:
|
||||||
[
|
{
|
||||||
topInputs.qchem.overlays.default
|
config =
|
||||||
topInputs.nixd.overlays.default
|
|
||||||
topInputs.nix-alien.overlays.default
|
|
||||||
topInputs.napalm.overlays.default
|
|
||||||
topInputs.pnpm2nix-nzbr.overlays.default
|
|
||||||
topInputs.lmix.overlays.default
|
|
||||||
(import "${topInputs.dguibert-nur-packages}/overlays/nvhpc-overlay")
|
|
||||||
(final: prev:
|
|
||||||
{
|
{
|
||||||
touchix = topInputs.touchix.packages."${prev.system}";
|
nixpkgs.overlays =
|
||||||
nix-vscode-extensions = topInputs.nix-vscode-extensions.extensions."${prev.system}";
|
[
|
||||||
nur-xddxdd = topInputs.nur-xddxdd.overlays.default final prev;
|
topInputs.qchem.overlays.default
|
||||||
deploy-rs = { inherit (prev) deploy-rs; inherit ((topInputs.deploy-rs.overlay final prev).deploy-rs) lib; };
|
topInputs.nixd.overlays.default
|
||||||
})
|
topInputs.nix-alien.overlays.default
|
||||||
];})
|
topInputs.napalm.overlays.default
|
||||||
|
topInputs.pnpm2nix-nzbr.overlays.default
|
||||||
|
topInputs.lmix.overlays.default
|
||||||
|
topInputs.aagl.overlays.default
|
||||||
|
(import "${topInputs.dguibert-nur-packages}/overlays/nvhpc-overlay")
|
||||||
|
(final: prev:
|
||||||
|
{
|
||||||
|
nix-vscode-extensions = topInputs.nix-vscode-extensions.extensions."${prev.system}";
|
||||||
|
nur-xddxdd = topInputs.nur-xddxdd.overlays.default final prev;
|
||||||
|
deploy-rs =
|
||||||
|
{ inherit (prev) deploy-rs; inherit ((topInputs.deploy-rs.overlay final prev).deploy-rs) lib; };
|
||||||
|
# needed by mirism
|
||||||
|
nghttp2-2305 =
|
||||||
|
inputs.pkgs.callPackage "${inputs.topInputs.nixpkgs-2305}/pkgs/development/libraries/nghttp2" {};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
home-manager.sharedModules =
|
||||||
|
[
|
||||||
|
topInputs.plasma-manager.homeManagerModules.plasma-manager
|
||||||
|
topInputs.nix-doom-emacs.hmModule
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
./hardware ./packages ./system ./virtualization ./services ./bugs ./users
|
./hardware ./packages ./system ./virtualization ./services ./bugs ./users
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ inputs:
|
|||||||
printer.enable = mkOption { type = types.bool; default = false; };
|
printer.enable = mkOption { type = types.bool; default = false; };
|
||||||
sound.enable = mkOption { type = types.bool; default = false; };
|
sound.enable = mkOption { type = types.bool; default = false; };
|
||||||
cpus = mkOption { type = types.listOf (types.enum [ "intel" "amd" ]); default = []; };
|
cpus = mkOption { type = types.listOf (types.enum [ "intel" "amd" ]); default = []; };
|
||||||
gpus = mkOption { type = types.listOf (types.enum [ "intel" "nvidia" ]); default = []; };
|
gpus = mkOption { type = types.listOf (types.enum [ "intel" "nvidia" "amd" ]); default = []; };
|
||||||
prime =
|
prime =
|
||||||
{
|
{
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
@@ -15,6 +15,7 @@ inputs:
|
|||||||
busId = mkOption { type = types.attrsOf types.str; default = {}; };
|
busId = mkOption { type = types.attrsOf types.str; default = {}; };
|
||||||
};
|
};
|
||||||
gamemode.drmDevice = mkOption { type = types.int; default = 0; };
|
gamemode.drmDevice = mkOption { type = types.int; default = 0; };
|
||||||
|
halo-keyboard.enable = mkOption { type = types.bool; default = false; };
|
||||||
};
|
};
|
||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
@@ -70,7 +71,10 @@ inputs:
|
|||||||
let
|
let
|
||||||
modules =
|
modules =
|
||||||
{
|
{
|
||||||
intel = [ "intel_cstate" "aesni_intel" ];
|
intel =
|
||||||
|
[
|
||||||
|
"intel_cstate" "aesni_intel" "intel_cstate" "intel_uncore" "intel_uncore_frequency" "intel_powerclamp"
|
||||||
|
];
|
||||||
amd = [];
|
amd = [];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
@@ -87,6 +91,7 @@ inputs:
|
|||||||
{
|
{
|
||||||
intel = [ "i915" ];
|
intel = [ "i915" ];
|
||||||
nvidia = [ "nvidia" "nvidia_drm" "nvidia_modeset" "nvidia_uvm" ];
|
nvidia = [ "nvidia" "nvidia_drm" "nvidia_modeset" "nvidia_uvm" ];
|
||||||
|
amd = [ "amdgpu" ];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
concatLists (map (gpu: modules.${gpu}) hardware.gpus);
|
concatLists (map (gpu: modules.${gpu}) hardware.gpus);
|
||||||
@@ -103,6 +108,7 @@ inputs:
|
|||||||
{
|
{
|
||||||
intel = [ intel-compute-runtime intel-media-driver libvdpau-va-gl ]; # intel-vaapi-driver
|
intel = [ intel-compute-runtime intel-media-driver libvdpau-va-gl ]; # intel-vaapi-driver
|
||||||
nvidia = [ vaapiVdpau ];
|
nvidia = [ vaapiVdpau ];
|
||||||
|
amd = [];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
concatLists (map (gpu: packages.${gpu}) hardware.gpus);
|
concatLists (map (gpu: packages.${gpu}) hardware.gpus);
|
||||||
@@ -142,5 +148,73 @@ inputs:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
{ programs.gamemode.settings.gpu.gpu_device = "${toString hardware.gamemode.drmDevice}"; }
|
{ programs.gamemode.settings.gpu.gpu_device = "${toString hardware.gamemode.drmDevice}"; }
|
||||||
|
# halo-keyboard
|
||||||
|
(mkIf hardware.halo-keyboard.enable
|
||||||
|
(
|
||||||
|
let
|
||||||
|
keyboard = inputs.pkgs.localPackages.chromiumos-touch-keyboard;
|
||||||
|
support = inputs.pkgs.localPackages.yoga-support;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.udev.packages = [ keyboard support ];
|
||||||
|
systemd.services =
|
||||||
|
{
|
||||||
|
touch-keyboard-handler.serviceConfig =
|
||||||
|
{
|
||||||
|
Type = "simple";
|
||||||
|
WorkingDirectory = "/etc/touch_keyboard";
|
||||||
|
ExecStart = "${keyboard}/bin/touch_keyboard_handler";
|
||||||
|
};
|
||||||
|
yogabook-modes-handler.serviceConfig =
|
||||||
|
{
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${support}/bin/yogabook-modes-handler";
|
||||||
|
StandardOutput = "journal";
|
||||||
|
};
|
||||||
|
monitor-sensor =
|
||||||
|
{
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
|
serviceConfig =
|
||||||
|
{
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${inputs.pkgs.iio-sensor-proxy}/bin/monitor-sensor --hinge";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
environment.etc."touch_keyboard".source = "${keyboard}/etc/touch_keyboard";
|
||||||
|
boot.initrd =
|
||||||
|
{
|
||||||
|
services.udev.packages = [ keyboard support ];
|
||||||
|
systemd =
|
||||||
|
{
|
||||||
|
extraBin =
|
||||||
|
{
|
||||||
|
touch_keyboard_handler = "${keyboard}/bin/touch_keyboard_handler";
|
||||||
|
yogabook-modes-handler = "${support}/bin/yogabook-modes-handler";
|
||||||
|
};
|
||||||
|
services =
|
||||||
|
{
|
||||||
|
touch-keyboard-handler =
|
||||||
|
{
|
||||||
|
serviceConfig =
|
||||||
|
{
|
||||||
|
Type = "simple";
|
||||||
|
WorkingDirectory = "/etc/touch_keyboard";
|
||||||
|
ExecStart = "${keyboard}/bin/touch_keyboard_handler";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
yogabook-modes-handler.serviceConfig =
|
||||||
|
{
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${support}/bin/yogabook-modes-handler";
|
||||||
|
StandardOutput = "journal";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
extraFiles."/etc/touch_keyboard".source = "${keyboard}/etc/touch_keyboard";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,472 +1,64 @@
|
|||||||
inputs:
|
inputs:
|
||||||
{
|
{
|
||||||
options.nixos.packages = let inherit (inputs.lib) mkOption types; in
|
imports = inputs.localLib.mkModules
|
||||||
{
|
[
|
||||||
packageSet = mkOption
|
./server
|
||||||
{
|
./desktop
|
||||||
type = types.enum
|
./desktop-fat
|
||||||
|
./workstation
|
||||||
|
];
|
||||||
|
options.nixos.packages =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkOption types;
|
||||||
|
packageSets =
|
||||||
[
|
[
|
||||||
# no gui, only used for specific purpose
|
# no gui, only used for specific purpose
|
||||||
"server"
|
"server"
|
||||||
# gui, for daily use, but not install large programs such as matlab
|
# gui, for daily use, but not install large programs such as matlab
|
||||||
"desktop"
|
"desktop"
|
||||||
|
"desktop-fat"
|
||||||
# nearly everything
|
# nearly everything
|
||||||
"workstation"
|
"workstation"
|
||||||
];
|
];
|
||||||
default = "server";
|
in
|
||||||
};
|
|
||||||
extraPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
excludePackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
extraPythonPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
excludePythonPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
extraPrebuildPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
excludePrebuildPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
_packages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
_pythonPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
_prebuildPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
|
||||||
};
|
|
||||||
config = let inherit (inputs.lib) mkMerge mkIf; inherit (inputs.localLib) stripeTabs; in mkMerge
|
|
||||||
[
|
|
||||||
# >= server
|
|
||||||
{
|
{
|
||||||
nixos.packages = with inputs.pkgs;
|
packageSet = mkOption { type = types.enum packageSets; default = "server"; };
|
||||||
|
extraPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
|
excludePackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
|
extraPythonPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
|
excludePythonPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
|
extraPrebuildPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
|
excludePrebuildPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
|
_packageSets = mkOption
|
||||||
{
|
{
|
||||||
_packages =
|
type = types.listOf types.nonEmptyStr;
|
||||||
[
|
readOnly = true;
|
||||||
# shell
|
default = builtins.genList (i: builtins.elemAt packageSets i)
|
||||||
ksh
|
((inputs.localLib.findIndex inputs.config.nixos.packages.packageSet packageSets) + 1);
|
||||||
# basic tools
|
|
||||||
beep dos2unix gnugrep pv tmux screen parallel tldr cowsay jq zellij neofetch ipfetch
|
|
||||||
# lsxx
|
|
||||||
pciutils usbutils lshw util-linux lsof
|
|
||||||
# top
|
|
||||||
iotop iftop htop btop powertop s-tui
|
|
||||||
# editor
|
|
||||||
nano bat
|
|
||||||
# downloader
|
|
||||||
wget aria2 curl
|
|
||||||
# file manager
|
|
||||||
tree exa trash-cli lsd broot file xdg-ninja mlocate
|
|
||||||
# compress
|
|
||||||
pigz rar upx unzip zip lzip p7zip
|
|
||||||
# file system management
|
|
||||||
sshfs e2fsprogs adb-sync duperemove compsize
|
|
||||||
# disk management
|
|
||||||
smartmontools hdparm
|
|
||||||
# encryption and authentication
|
|
||||||
apacheHttpd openssl ssh-to-age gnupg age sops pam_u2f yubico-piv-tool
|
|
||||||
# networking
|
|
||||||
ipset iptables iproute2 dig nettools traceroute tcping-go whois tcpdump nmap inetutils
|
|
||||||
# nix tools
|
|
||||||
nix-output-monitor nix-tree
|
|
||||||
# office
|
|
||||||
todo-txt-cli
|
|
||||||
] ++ (with inputs.config.boot.kernelPackages; [ cpupower usbip ]);
|
|
||||||
_pythonPackages = [(pythonPackages: with pythonPackages;
|
|
||||||
[
|
|
||||||
inquirerpy requests python-telegram-bot tqdm fastapi pypdf2 pandas matplotlib plotly gunicorn redis jinja2
|
|
||||||
certifi charset-normalizer idna orjson psycopg2
|
|
||||||
])];
|
|
||||||
};
|
};
|
||||||
programs =
|
_packages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
{
|
_pythonPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
nix-index-database.comma.enable = true;
|
_prebuildPackages = mkOption { type = types.listOf types.unspecified; default = []; };
|
||||||
nix-index.enable = true;
|
};
|
||||||
zsh =
|
config =
|
||||||
{
|
let
|
||||||
enable = true;
|
inherit (builtins) concatLists map;
|
||||||
syntaxHighlighting.enable = true;
|
in
|
||||||
autosuggestions.enable = true;
|
|
||||||
enableCompletion = true;
|
|
||||||
ohMyZsh =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
plugins = [ "git" "colored-man-pages" "extract" "history-substring-search" "autojump" ];
|
|
||||||
customPkgs = with inputs.pkgs; [ zsh-nix-shell ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
ccache.enable = true;
|
|
||||||
command-not-found.enable = false;
|
|
||||||
adb.enable = true;
|
|
||||||
gnupg.agent = { enable = true; enableSSHSupport = true; };
|
|
||||||
autojump.enable = true;
|
|
||||||
git =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
package = inputs.pkgs.gitFull;
|
|
||||||
lfs.enable = true;
|
|
||||||
config =
|
|
||||||
{
|
|
||||||
init.defaultBranch = "main";
|
|
||||||
core = { quotepath = false; editor = "vim"; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
services =
|
|
||||||
{
|
|
||||||
fwupd.enable = true;
|
|
||||||
udev.packages = with inputs.pkgs; [ yubikey-personalization libfido2 ];
|
|
||||||
};
|
|
||||||
nix.settings.extra-sandbox-paths = [ inputs.config.programs.ccache.cacheDir ];
|
|
||||||
nixpkgs.config =
|
|
||||||
{
|
|
||||||
permittedInsecurePackages = with inputs.pkgs;
|
|
||||||
[
|
|
||||||
openssl_1_1.name electron_19.name nodejs-16_x.name python2.name electron_12.name
|
|
||||||
];
|
|
||||||
allowUnfree = true;
|
|
||||||
};
|
|
||||||
home-manager =
|
|
||||||
{
|
|
||||||
useGlobalPkgs = true;
|
|
||||||
useUserPackages = true;
|
|
||||||
sharedModules =
|
|
||||||
[{
|
|
||||||
home.stateVersion = "22.11";
|
|
||||||
programs =
|
|
||||||
{
|
|
||||||
zsh =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
initExtraBeforeCompInit =
|
|
||||||
''
|
|
||||||
# p10k instant prompt
|
|
||||||
typeset -g POWERLEVEL9K_INSTANT_PROMPT=off
|
|
||||||
P10K_INSTANT_PROMPT="$XDG_CACHE_HOME/p10k-instant-prompt-''${(%):-%n}.zsh"
|
|
||||||
[[ ! -r "$P10K_INSTANT_PROMPT" ]] || source "$P10K_INSTANT_PROMPT"
|
|
||||||
HYPHEN_INSENSITIVE="true"
|
|
||||||
export PATH=~/bin:$PATH
|
|
||||||
function br
|
|
||||||
{
|
|
||||||
local cmd cmd_file code
|
|
||||||
cmd_file=$(mktemp)
|
|
||||||
if broot --outcmd "$cmd_file" "$@"; then
|
|
||||||
cmd=$(<"$cmd_file")
|
|
||||||
command rm -f "$cmd_file"
|
|
||||||
eval "$cmd"
|
|
||||||
else
|
|
||||||
code=$?
|
|
||||||
command rm -f "$cmd_file"
|
|
||||||
return "$code"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
alias todo="todo.sh"
|
|
||||||
'';
|
|
||||||
plugins =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
file = "powerlevel10k.zsh-theme";
|
|
||||||
name = "powerlevel10k";
|
|
||||||
src = "${inputs.pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
file = "p10k.zsh";
|
|
||||||
name = "powerlevel10k-config";
|
|
||||||
src = ./p10k-config;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "zsh-lsd";
|
|
||||||
src = inputs.pkgs.fetchFromGitHub
|
|
||||||
{
|
|
||||||
owner = "z-shell";
|
|
||||||
repo = "zsh-lsd";
|
|
||||||
rev = "029a9cb0a9b39c9eb6c5b5100dd9182813332250";
|
|
||||||
sha256 = "sha256-oWjWnhiimlGBMaZlZB+OM47jd9hporKlPNwCx6524Rk=";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
history =
|
|
||||||
{
|
|
||||||
extended = true;
|
|
||||||
save = 100000000;
|
|
||||||
size = 100000000;
|
|
||||||
share = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
direnv = { enable = true; nix-direnv.enable = true; };
|
|
||||||
git =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
lfs.enable = true;
|
|
||||||
extraConfig =
|
|
||||||
{
|
|
||||||
core.editor = if inputs.config.nixos.system.gui.preferred then "code --wait" else "vim";
|
|
||||||
advice.detachedHead = false;
|
|
||||||
merge.conflictstyle = "diff3";
|
|
||||||
diff.colorMoved = "default";
|
|
||||||
};
|
|
||||||
package = inputs.pkgs.gitFull;
|
|
||||||
delta =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
options =
|
|
||||||
{
|
|
||||||
side-by-side = true;
|
|
||||||
navigate = true;
|
|
||||||
syntax-theme = "GitHub";
|
|
||||||
light = true;
|
|
||||||
zero-style = "syntax white";
|
|
||||||
line-numbers-zero-style = "#ffffff";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
ssh =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
controlMaster = "auto";
|
|
||||||
controlPersist = "1m";
|
|
||||||
compression = true;
|
|
||||||
};
|
|
||||||
vim =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
defaultEditor = true;
|
|
||||||
packageConfigurable = inputs.config.programs.vim.package;
|
|
||||||
settings =
|
|
||||||
{
|
|
||||||
number = true;
|
|
||||||
expandtab = false;
|
|
||||||
shiftwidth = 2;
|
|
||||||
tabstop = 2;
|
|
||||||
};
|
|
||||||
extraConfig =
|
|
||||||
''
|
|
||||||
set clipboard=unnamedplus
|
|
||||||
colorscheme evening
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
# >= desktop
|
|
||||||
(
|
|
||||||
mkIf (builtins.elem inputs.config.nixos.packages.packageSet [ "desktop" "workstation" ] )
|
|
||||||
{
|
|
||||||
nixos.packages = with inputs.pkgs;
|
|
||||||
{
|
|
||||||
_packages =
|
|
||||||
[
|
|
||||||
# system management
|
|
||||||
gparted snapper-gui libsForQt5.qtstyleplugin-kvantum wl-clipboard-x11 kio-fuse wl-mirror
|
|
||||||
wayland-utils clinfo glxinfo vulkan-tools dracut etcher
|
|
||||||
# nix tools
|
|
||||||
ssh-to-age deploy-rs.deploy-rs nixpkgs-fmt
|
|
||||||
# instant messager
|
|
||||||
element-desktop telegram-desktop discord inputs.config.nur.repos.linyinfeng.wemeet # native
|
|
||||||
cinny-desktop # nur-xddxdd.wine-wechat thunder
|
|
||||||
# browser
|
|
||||||
google-chrome
|
|
||||||
# networking
|
|
||||||
remmina putty mtr-gui
|
|
||||||
# password and key management
|
|
||||||
bitwarden yubikey-manager yubikey-manager-qt yubikey-personalization yubikey-personalization-gui
|
|
||||||
# download
|
|
||||||
qbittorrent yt-dlp nur-xddxdd.baidupcs-go wgetpaste
|
|
||||||
# office
|
|
||||||
unstablePackages.crow-translate zotero pandoc
|
|
||||||
# development
|
|
||||||
scrcpy
|
|
||||||
# media
|
|
||||||
spotify yesplaymusic mpv nomacs simplescreenrecorder imagemagick gimp netease-cloud-music-gtk vlc
|
|
||||||
# text editor
|
|
||||||
localPackages.typora
|
|
||||||
# themes
|
|
||||||
orchis-theme tela-circle-icon-theme plasma-overdose-kde-theme materia-kde-theme graphite-kde-theme
|
|
||||||
arc-kde-theme materia-theme
|
|
||||||
# news
|
|
||||||
fluent-reader rssguard
|
|
||||||
# davinci-resolve playonlinux
|
|
||||||
weston cage openbox krita
|
|
||||||
genymotion
|
|
||||||
(
|
|
||||||
vscode-with-extensions.override
|
|
||||||
{
|
|
||||||
vscodeExtensions = with nix-vscode-extensions.vscode-marketplace;
|
|
||||||
(with equinusocio; [ vsc-community-material-theme vsc-material-theme-icons ])
|
|
||||||
++ (with github; [ copilot copilot-chat copilot-labs github-vscode-theme ])
|
|
||||||
++ (with intellsmi; [ comment-translate deepl-translate ])
|
|
||||||
++ (with ms-python; [ isort python vscode-pylance ])
|
|
||||||
++ (with ms-toolsai;
|
|
||||||
[
|
|
||||||
jupyter jupyter-keymap jupyter-renderers vscode-jupyter-cell-tags vscode-jupyter-slideshow
|
|
||||||
])
|
|
||||||
++ (with ms-vscode;
|
|
||||||
[
|
|
||||||
cmake-tools cpptools cpptools-extension-pack cpptools-themes hexeditor remote-explorer
|
|
||||||
test-adapter-converter
|
|
||||||
])
|
|
||||||
++ (with ms-vscode-remote; [ remote-ssh remote-containers remote-ssh-edit ])
|
|
||||||
++ [
|
|
||||||
donjayamanne.githistory genieai.chatgpt-vscode fabiospampinato.vscode-diff cschlosser.doxdocgen
|
|
||||||
llvm-vs-code-extensions.vscode-clangd ms-ceintl.vscode-language-pack-zh-hans oderwat.indent-rainbow
|
|
||||||
twxs.cmake guyutongxue.cpp-reference znck.grammarly thfriedrich.lammps leetcode.vscode-leetcode
|
|
||||||
james-yu.latex-workshop gimly81.matlab affenwiesel.matlab-formatter ckolkman.vscode-postgres
|
|
||||||
yzhang.markdown-all-in-one pkief.material-icon-theme bbenoist.nix ms-ossdata.vscode-postgresql
|
|
||||||
redhat.vscode-xml dotjoshjohnson.xml jnoortheen.nix-ide xdebug.php-debug hbenl.vscode-test-explorer
|
|
||||||
jeff-hykin.better-cpp-syntax fredericbonnet.cmake-test-adapter mesonbuild.mesonbuild
|
|
||||||
hirse.vscode-ungit fortran-lang.linter-gfortran tboox.xmake-vscode ccls-project.ccls
|
|
||||||
feiskyer.chatgpt-copilot yukiuuh2936.vscode-modern-fortran-formatter wolframresearch.wolfram
|
|
||||||
njpipeorgan.wolfram-language-notebook brettm12345.nixfmt-vscode
|
|
||||||
];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
] ++ (with inputs.lib; filter isDerivation (attrValues plasma5Packages.kdeGear));
|
|
||||||
};
|
|
||||||
programs =
|
|
||||||
{
|
|
||||||
steam.enable = true;
|
|
||||||
kdeconnect.enable = true;
|
|
||||||
wireshark = { enable = true; package = inputs.pkgs.wireshark; };
|
|
||||||
firefox =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
languagePacks = [ "zh-CN" "en-US" ];
|
|
||||||
nativeMessagingHosts.firefoxpwa = true;
|
|
||||||
};
|
|
||||||
vim.package = inputs.pkgs.genericPackages.vim-full;
|
|
||||||
};
|
|
||||||
nixpkgs.config.packageOverrides = pkgs:
|
|
||||||
{
|
|
||||||
telegram-desktop = pkgs.telegram-desktop.overrideAttrs (attrs:
|
|
||||||
{
|
|
||||||
patches = (if (attrs ? patches) then attrs.patches else []) ++ [ ./telegram.patch ];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
services.pcscd.enable = true;
|
|
||||||
home-manager.sharedModules =
|
|
||||||
[{
|
|
||||||
programs =
|
|
||||||
{
|
|
||||||
chromium =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
extensions =
|
|
||||||
[
|
|
||||||
{ id = "mpkodccbngfoacfalldjimigbofkhgjn"; } # Aria2 Explorer
|
|
||||||
{ id = "nngceckbapebfimnlniiiahkandclblb"; } # Bitwarden
|
|
||||||
{ id = "kbfnbcaeplbcioakkpcpgfkobkghlhen"; } # Grammarly
|
|
||||||
{ id = "ihnfpdchjnmlehnoeffgcbakfmdjcckn"; } # Pixiv Fanbox Downloader
|
|
||||||
{ id = "cimiefiiaegbelhefglklhhakcgmhkai"; } # Plasma Integration
|
|
||||||
{ id = "dkndmhgdcmjdmkdonmbgjpijejdcilfh"; } # Powerful Pixiv Downloader
|
|
||||||
{ id = "padekgcemlokbadohgkifijomclgjgif"; } # Proxy SwitchyOmega
|
|
||||||
{ id = "kefjpfngnndepjbopdmoebkipbgkggaa"; } # RSSHub Radar
|
|
||||||
{ id = "abpdnfjocnmdomablahdcfnoggeeiedb"; } # Save All Resources
|
|
||||||
{ id = "nbokbjkabcmbfdlbddjidfmibcpneigj"; } # SmoothScroll
|
|
||||||
{ id = "onepmapfbjohnegdmfhndpefjkppbjkm"; } # SuperCopy 超级复制
|
|
||||||
{ id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # uBlock Origin
|
|
||||||
{ id = "gppongmhjkpfnbhagpmjfkannfbllamg"; } # Wappalyzer
|
|
||||||
{ id = "hkbdddpiemdeibjoknnofflfgbgnebcm"; } # YouTube™ 双字幕
|
|
||||||
{ id = "ekhagklcjbdpajgpjgmbionohlpdbjgc"; } # Zotero Connector
|
|
||||||
{ id = "ikhdkkncnoglghljlkmcimlnlhkeamad"; } # 划词翻译
|
|
||||||
{ id = "dhdgffkkebhmkfjojejmpbldmpobfkfo"; } # 篡改猴
|
|
||||||
{ id = "hipekcciheckooncpjeljhnekcoolahp"; } # Tabliss
|
|
||||||
];
|
|
||||||
};
|
|
||||||
obs-studio =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
plugins = with inputs.pkgs.obs-studio-plugins;
|
|
||||||
[ wlrobs obs-vaapi obs-nvfbc droidcam-obs obs-vkcapture ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
home.file.".config/baloofilerc".text =
|
|
||||||
''
|
|
||||||
[Basic Settings]
|
|
||||||
Indexing-Enabled=false
|
|
||||||
'';
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
# >= workstation
|
|
||||||
(
|
|
||||||
mkIf (inputs.config.nixos.packages.packageSet == "workstation")
|
|
||||||
{
|
|
||||||
nixos.packages = with inputs.pkgs;
|
|
||||||
{
|
|
||||||
_packages =
|
|
||||||
[
|
|
||||||
# nix tools
|
|
||||||
nix-template appimage-run nil nixd nix-alien nix-serve node2nix nix-prefetch-github prefetch-npm-deps
|
|
||||||
nix-prefetch-docker pnpm-lock-export bundix
|
|
||||||
# instant messager
|
|
||||||
zoom-us signal-desktop qq nur-xddxdd.wechat-uos slack # jail
|
|
||||||
# office
|
|
||||||
libreoffice-qt texlive.combined.scheme-full texstudio poppler_utils pdftk gnuplot pdfchain
|
|
||||||
# development
|
|
||||||
jetbrains.clion android-studio dbeaver cling clang-tools_16 ccls fprettify
|
|
||||||
# media
|
|
||||||
nur-xddxdd.svp obs-studio waifu2x-converter-cpp inkscape blender
|
|
||||||
# virtualization
|
|
||||||
wine virt-viewer bottles # wine64
|
|
||||||
# text editor
|
|
||||||
appflowy notion-app-enhanced joplin-desktop standardnotes
|
|
||||||
# math, physics and chemistry
|
|
||||||
mathematica octave root ovito paraview localPackages.vesta qchem.quantum-espresso
|
|
||||||
localPackages.vasp localPackages.phonon-unfolding localPackages.vaspkit jmol localPackages.v_sim
|
|
||||||
# news
|
|
||||||
newsflash newsboat
|
|
||||||
];
|
|
||||||
_pythonPackages = [(pythonPackages: with pythonPackages;
|
|
||||||
[
|
|
||||||
phonopy tensorflow keras openai scipy scikit-learn
|
|
||||||
])];
|
|
||||||
_prebuildPackages =
|
|
||||||
[
|
|
||||||
httplib magic-enum xtensor boost cereal cxxopts ftxui yaml-cpp gfortran gcc10 python2 gcc13Stdenv
|
|
||||||
];
|
|
||||||
};
|
|
||||||
programs =
|
|
||||||
{
|
|
||||||
anime-game-launcher.enable = true;
|
|
||||||
honkers-railway-launcher.enable = true;
|
|
||||||
nix-ld.enable = true;
|
|
||||||
gamemode =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
settings =
|
|
||||||
{
|
|
||||||
general.renice = 10;
|
|
||||||
gpu =
|
|
||||||
{
|
|
||||||
apply_gpu_optimisations = "accept-responsibility";
|
|
||||||
nv_powermizer_mode = 1;
|
|
||||||
};
|
|
||||||
custom = let notify-send = "${inputs.pkgs.libnotify}/bin/notify-send"; in
|
|
||||||
{
|
|
||||||
start = "${notify-send} 'GameMode started'";
|
|
||||||
end = "${notify-send} 'GameMode ended'";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
chromium =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
extraOpts =
|
|
||||||
{
|
|
||||||
PasswordManagerEnabled = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
# apply package configs
|
|
||||||
{
|
{
|
||||||
environment.systemPackages = let inherit (inputs.lib.lists) subtractLists; in with inputs.config.nixos.packages;
|
environment.systemPackages = let inherit (inputs.lib.lists) subtractLists; in with inputs.config.nixos.packages;
|
||||||
(subtractLists excludePackages (_packages ++ extraPackages))
|
(subtractLists excludePackages (_packages ++ extraPackages))
|
||||||
++ [
|
++ [
|
||||||
(inputs.pkgs.python3.withPackages (pythonPackages:
|
(inputs.pkgs.python3.withPackages (pythonPackages:
|
||||||
subtractLists
|
subtractLists
|
||||||
(builtins.concatLists (builtins.map (packageFunction: packageFunction pythonPackages)
|
(concatLists (map (packageFunction: packageFunction pythonPackages) excludePythonPackages))
|
||||||
excludePythonPackages))
|
(concatLists (map (packageFunction: packageFunction pythonPackages)
|
||||||
(builtins.concatLists (builtins.map (packageFunction: packageFunction pythonPackages)
|
|
||||||
(_pythonPackages ++ extraPythonPackages)))))
|
(_pythonPackages ++ extraPythonPackages)))))
|
||||||
(inputs.pkgs.callPackage ({ stdenv }: stdenv.mkDerivation
|
(inputs.pkgs.callPackage ({ stdenv }: stdenv.mkDerivation
|
||||||
{
|
{
|
||||||
name = "prebuild-packages";
|
name = "prebuild-packages";
|
||||||
propagateBuildInputs = subtractLists excludePrebuildPackages (_prebuildPackages ++ extraPrebuildPackages);
|
propagateBuildInputs = subtractLists excludePrebuildPackages (_prebuildPackages ++ extraPrebuildPackages);
|
||||||
phases = [ "installPhase" ];
|
phases = [ "installPhase" ];
|
||||||
installPhase = stripeTabs
|
installPhase =
|
||||||
''
|
''
|
||||||
runHook preInstall
|
runHook preInstall
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
@@ -474,8 +66,7 @@ inputs:
|
|||||||
'';
|
'';
|
||||||
}) {})
|
}) {})
|
||||||
];
|
];
|
||||||
}
|
};
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# programs.firejail =
|
# programs.firejail =
|
||||||
@@ -578,4 +169,4 @@ inputs:
|
|||||||
# x11-misc/optimus-manager
|
# x11-misc/optimus-manager
|
||||||
# x11-misc/unclutter-xfixes
|
# x11-misc/unclutter-xfixes
|
||||||
|
|
||||||
# ++ ( with inputs.pkgs.pkgsCross.mingwW64.buildPackages; [ gcc ] );
|
# ++ ( with inputs.pkgs.pkgsCross.mingwW64.buildPackages; [ gcc ] );
|
||||||
|
|||||||
39
modules/packages/desktop-fat/chromium.nix
Normal file
39
modules/packages/desktop-fat/chromium.nix
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf (builtins.elem "desktop-fat" inputs.config.nixos.packages._packageSets)
|
||||||
|
{
|
||||||
|
nixos.users.sharedModules =
|
||||||
|
[{
|
||||||
|
config.programs.chromium =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
extensions =
|
||||||
|
[
|
||||||
|
{ id = "mpkodccbngfoacfalldjimigbofkhgjn"; } # Aria2 Explorer
|
||||||
|
{ id = "nngceckbapebfimnlniiiahkandclblb"; } # Bitwarden
|
||||||
|
{ id = "kbfnbcaeplbcioakkpcpgfkobkghlhen"; } # Grammarly
|
||||||
|
{ id = "ihnfpdchjnmlehnoeffgcbakfmdjcckn"; } # Pixiv Fanbox Downloader
|
||||||
|
{ id = "cimiefiiaegbelhefglklhhakcgmhkai"; } # Plasma Integration
|
||||||
|
{ id = "dkndmhgdcmjdmkdonmbgjpijejdcilfh"; } # Powerful Pixiv Downloader
|
||||||
|
{ id = "padekgcemlokbadohgkifijomclgjgif"; } # Proxy SwitchyOmega
|
||||||
|
{ id = "kefjpfngnndepjbopdmoebkipbgkggaa"; } # RSSHub Radar
|
||||||
|
{ id = "abpdnfjocnmdomablahdcfnoggeeiedb"; } # Save All Resources
|
||||||
|
{ id = "nbokbjkabcmbfdlbddjidfmibcpneigj"; } # SmoothScroll
|
||||||
|
{ id = "onepmapfbjohnegdmfhndpefjkppbjkm"; } # SuperCopy 超级复制
|
||||||
|
{ id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # uBlock Origin
|
||||||
|
{ id = "gppongmhjkpfnbhagpmjfkannfbllamg"; } # Wappalyzer
|
||||||
|
{ id = "hkbdddpiemdeibjoknnofflfgbgnebcm"; } # YouTube™ 双字幕
|
||||||
|
{ id = "ekhagklcjbdpajgpjgmbionohlpdbjgc"; } # Zotero Connector
|
||||||
|
{ id = "ikhdkkncnoglghljlkmcimlnlhkeamad"; } # 划词翻译
|
||||||
|
{ id = "dhdgffkkebhmkfjojejmpbldmpobfkfo"; } # 篡改猴
|
||||||
|
{ id = "hipekcciheckooncpjeljhnekcoolahp"; } # Tabliss
|
||||||
|
{ id = "nkbihfbeogaeaoehlefnkodbefgpgknn"; } # MetaMask
|
||||||
|
{ id = "bpoadfkcbjbfhfodiogcnhhhpibjhbnh"; } # 沉浸式翻译
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
}
|
||||||
47
modules/packages/desktop-fat/default.nix
Normal file
47
modules/packages/desktop-fat/default.nix
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
imports = inputs.localLib.mkModules
|
||||||
|
[
|
||||||
|
./chromium.nix
|
||||||
|
];
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf (builtins.elem "desktop-fat" inputs.config.nixos.packages._packageSets)
|
||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{
|
||||||
|
packages = with inputs.pkgs;
|
||||||
|
{
|
||||||
|
_packages =
|
||||||
|
[
|
||||||
|
# system management
|
||||||
|
etcher btrfs-assistant snapper-gui libsForQt5.qtstyleplugin-kvantum
|
||||||
|
# password and key management
|
||||||
|
yubikey-manager yubikey-manager-qt yubikey-personalization yubikey-personalization-gui bitwarden
|
||||||
|
# download
|
||||||
|
qbittorrent nur-xddxdd.baidupcs-go wgetpaste
|
||||||
|
# development
|
||||||
|
scrcpy weston cage openbox krita
|
||||||
|
# media
|
||||||
|
spotify yesplaymusic simplescreenrecorder imagemagick gimp netease-cloud-music-gtk vlc
|
||||||
|
# editor
|
||||||
|
localPackages.typora
|
||||||
|
# themes
|
||||||
|
orchis-theme plasma-overdose-kde-theme materia-kde-theme graphite-kde-theme arc-kde-theme materia-theme
|
||||||
|
# news
|
||||||
|
fluent-reader
|
||||||
|
# nix tools
|
||||||
|
deploy-rs.deploy-rs nixpkgs-fmt
|
||||||
|
# instant messager
|
||||||
|
element-desktop telegram-desktop discord fluffychat
|
||||||
|
# browser
|
||||||
|
google-chrome
|
||||||
|
# office
|
||||||
|
crow-translate zotero pandoc ydict
|
||||||
|
] ++ (with inputs.lib; filter isDerivation (attrValues plasma5Packages.kdeGear));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
programs = { steam.enable = true; kdeconnect.enable = true; };
|
||||||
|
};
|
||||||
|
}
|
||||||
49
modules/packages/desktop/default.nix
Normal file
49
modules/packages/desktop/default.nix
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
imports = inputs.localLib.mkModules [ ./vscode.nix ];
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf (builtins.elem "desktop" inputs.config.nixos.packages._packageSets)
|
||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{
|
||||||
|
packages._packages = with inputs.pkgs;
|
||||||
|
[
|
||||||
|
# system management
|
||||||
|
gparted wl-clipboard-x11 kio-fuse
|
||||||
|
wayland-utils clinfo glxinfo vulkan-tools dracut
|
||||||
|
# networking
|
||||||
|
remmina putty mtr-gui
|
||||||
|
# media
|
||||||
|
mpv nomacs
|
||||||
|
# themes
|
||||||
|
tela-circle-icon-theme
|
||||||
|
];
|
||||||
|
users.sharedModules =
|
||||||
|
[{
|
||||||
|
config.home.file.".config/baloofilerc".text =
|
||||||
|
''
|
||||||
|
[Basic Settings]
|
||||||
|
Indexing-Enabled=false
|
||||||
|
'';
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
programs =
|
||||||
|
{
|
||||||
|
adb.enable = true;
|
||||||
|
wireshark = { enable = true; package = inputs.pkgs.wireshark; };
|
||||||
|
firefox = { enable = true; languagePacks = [ "zh-CN" "en-US" ]; };
|
||||||
|
vim.package = inputs.pkgs.vim-full;
|
||||||
|
};
|
||||||
|
nixpkgs.config.packageOverrides = pkgs:
|
||||||
|
{
|
||||||
|
telegram-desktop = pkgs.telegram-desktop.overrideAttrs (attrs:
|
||||||
|
{
|
||||||
|
patches = (if (attrs ? patches) then attrs.patches else []) ++ [ ./telegram.patch ];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
services.pcscd.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
57
modules/packages/desktop/vscode.nix
Normal file
57
modules/packages/desktop/vscode.nix
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf (builtins.elem "desktop" inputs.config.nixos.packages._packageSets)
|
||||||
|
{
|
||||||
|
nixos.packages = with inputs.pkgs;
|
||||||
|
{
|
||||||
|
_packages =
|
||||||
|
[(
|
||||||
|
vscode-with-extensions.override
|
||||||
|
{
|
||||||
|
vscodeExtensions = with nix-vscode-extensions.vscode-marketplace;
|
||||||
|
(with equinusocio; [ vsc-community-material-theme vsc-material-theme-icons ])
|
||||||
|
++ (with github; [ copilot copilot-chat github-vscode-theme ])
|
||||||
|
++ (with intellsmi; [ comment-translate deepl-translate ])
|
||||||
|
++ (with ms-python; [ isort python vscode-pylance ])
|
||||||
|
++ (with ms-toolsai;
|
||||||
|
[
|
||||||
|
jupyter jupyter-keymap jupyter-renderers vscode-jupyter-cell-tags vscode-jupyter-slideshow
|
||||||
|
])
|
||||||
|
++ (with ms-vscode;
|
||||||
|
[
|
||||||
|
cmake-tools cpptools cpptools-extension-pack cpptools-themes hexeditor remote-explorer
|
||||||
|
test-adapter-converter
|
||||||
|
])
|
||||||
|
++ (with ms-vscode-remote; [ remote-ssh remote-containers remote-ssh-edit ])
|
||||||
|
++ [
|
||||||
|
donjayamanne.githistory genieai.chatgpt-vscode fabiospampinato.vscode-diff cschlosser.doxdocgen
|
||||||
|
llvm-vs-code-extensions.vscode-clangd ms-ceintl.vscode-language-pack-zh-hans
|
||||||
|
oderwat.indent-rainbow
|
||||||
|
twxs.cmake guyutongxue.cpp-reference znck.grammarly thfriedrich.lammps leetcode.vscode-leetcode
|
||||||
|
james-yu.latex-workshop gimly81.matlab affenwiesel.matlab-formatter ckolkman.vscode-postgres
|
||||||
|
yzhang.markdown-all-in-one pkief.material-icon-theme bbenoist.nix ms-ossdata.vscode-postgresql
|
||||||
|
redhat.vscode-xml dotjoshjohnson.xml jnoortheen.nix-ide xdebug.php-debug
|
||||||
|
hbenl.vscode-test-explorer
|
||||||
|
jeff-hykin.better-cpp-syntax fredericbonnet.cmake-test-adapter mesonbuild.mesonbuild
|
||||||
|
hirse.vscode-ungit fortran-lang.linter-gfortran tboox.xmake-vscode ccls-project.ccls
|
||||||
|
feiskyer.chatgpt-copilot yukiuuh2936.vscode-modern-fortran-formatter wolframresearch.wolfram
|
||||||
|
njpipeorgan.wolfram-language-notebook brettm12345.nixfmt-vscode webfreak.debug
|
||||||
|
gruntfuggly.todo-tree
|
||||||
|
# restrctured text
|
||||||
|
lextudio.restructuredtext trond-snekvik.simple-rst
|
||||||
|
# markdown
|
||||||
|
shd101wyy.markdown-preview-enhanced
|
||||||
|
];
|
||||||
|
}
|
||||||
|
)];
|
||||||
|
_pythonPackages = [(pythonPackages: with pythonPackages;
|
||||||
|
[
|
||||||
|
# required by vscode extensions restrucuredtext
|
||||||
|
localPackages.esbonio
|
||||||
|
])];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
203
modules/packages/server/default.nix
Normal file
203
modules/packages/server/default.nix
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
imports = inputs.localLib.mkModules
|
||||||
|
[
|
||||||
|
./ssh
|
||||||
|
];
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (builtins) concatLists map listToAttrs;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
in mkIf (builtins.elem "server" inputs.config.nixos.packages._packageSets)
|
||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{
|
||||||
|
packages = with inputs.pkgs;
|
||||||
|
{
|
||||||
|
_packages =
|
||||||
|
[
|
||||||
|
# shell
|
||||||
|
ksh
|
||||||
|
# basic tools
|
||||||
|
beep dos2unix gnugrep pv tmux screen parallel tldr cowsay jq zellij neofetch ipfetch localPackages.pslist
|
||||||
|
fastfetch reptyr
|
||||||
|
# lsxx
|
||||||
|
pciutils usbutils lshw util-linux lsof
|
||||||
|
# top
|
||||||
|
iotop iftop htop btop powertop s-tui
|
||||||
|
# editor
|
||||||
|
nano bat
|
||||||
|
# downloader
|
||||||
|
wget aria2 curl yt-dlp
|
||||||
|
# file manager
|
||||||
|
tree eza trash-cli lsd broot file xdg-ninja mlocate
|
||||||
|
# compress
|
||||||
|
pigz rar upx unzip zip lzip p7zip
|
||||||
|
# file system management
|
||||||
|
sshfs e2fsprogs adb-sync duperemove compsize exfatprogs
|
||||||
|
# disk management
|
||||||
|
smartmontools hdparm
|
||||||
|
# encryption and authentication
|
||||||
|
apacheHttpd openssl ssh-to-age gnupg age sops pam_u2f yubico-piv-tool
|
||||||
|
# networking
|
||||||
|
ipset iptables iproute2 dig nettools traceroute tcping-go whois tcpdump nmap inetutils wireguard-tools
|
||||||
|
# nix tools
|
||||||
|
nix-output-monitor nix-tree ssh-to-age
|
||||||
|
# office
|
||||||
|
todo-txt-cli
|
||||||
|
# development
|
||||||
|
gdb try inputs.topInputs.plasma-manager.packages.x86_64-linux.rc2nix
|
||||||
|
] ++ (with inputs.config.boot.kernelPackages; [ cpupower usbip ]);
|
||||||
|
};
|
||||||
|
users.sharedModules = [(home-inputs:
|
||||||
|
{
|
||||||
|
config.programs =
|
||||||
|
{
|
||||||
|
zsh =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
initExtraBeforeCompInit =
|
||||||
|
''
|
||||||
|
# p10k instant prompt
|
||||||
|
P10K_INSTANT_PROMPT="$XDG_CACHE_HOME/p10k-instant-prompt-''${(%):-%n}.zsh"
|
||||||
|
[[ ! -r "$P10K_INSTANT_PROMPT" ]] || source "$P10K_INSTANT_PROMPT"
|
||||||
|
HYPHEN_INSENSITIVE="true"
|
||||||
|
export PATH=~/bin:$PATH
|
||||||
|
function br
|
||||||
|
{
|
||||||
|
local cmd cmd_file code
|
||||||
|
cmd_file=$(mktemp)
|
||||||
|
if broot --outcmd "$cmd_file" "$@"; then
|
||||||
|
cmd=$(<"$cmd_file")
|
||||||
|
command rm -f "$cmd_file"
|
||||||
|
eval "$cmd"
|
||||||
|
else
|
||||||
|
code=$?
|
||||||
|
command rm -f "$cmd_file"
|
||||||
|
return "$code"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
alias todo="todo.sh"
|
||||||
|
'';
|
||||||
|
plugins =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
file = "powerlevel10k.zsh-theme";
|
||||||
|
name = "powerlevel10k";
|
||||||
|
src = "${inputs.pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
file = "p10k.zsh";
|
||||||
|
name = "powerlevel10k-config";
|
||||||
|
src = ./p10k-config;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "zsh-lsd";
|
||||||
|
src = inputs.pkgs.fetchFromGitHub
|
||||||
|
{
|
||||||
|
owner = "z-shell";
|
||||||
|
repo = "zsh-lsd";
|
||||||
|
rev = "029a9cb0a9b39c9eb6c5b5100dd9182813332250";
|
||||||
|
sha256 = "sha256-oWjWnhiimlGBMaZlZB+OM47jd9hporKlPNwCx6524Rk=";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
history =
|
||||||
|
{
|
||||||
|
path = "${home-inputs.config.xdg.dataHome}/zsh/zsh_history";
|
||||||
|
extended = true;
|
||||||
|
save = 100000000;
|
||||||
|
size = 100000000;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
direnv = { enable = true; nix-direnv.enable = true; };
|
||||||
|
git =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
lfs.enable = true;
|
||||||
|
extraConfig =
|
||||||
|
{
|
||||||
|
core.editor = if inputs.config.nixos.system.gui.preferred then "code --wait" else "vim";
|
||||||
|
advice.detachedHead = false;
|
||||||
|
merge.conflictstyle = "diff3";
|
||||||
|
diff.colorMoved = "default";
|
||||||
|
};
|
||||||
|
package = inputs.pkgs.gitFull;
|
||||||
|
delta =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
options =
|
||||||
|
{
|
||||||
|
side-by-side = true;
|
||||||
|
navigate = true;
|
||||||
|
syntax-theme = "GitHub";
|
||||||
|
light = true;
|
||||||
|
zero-style = "syntax white";
|
||||||
|
line-numbers-zero-style = "#ffffff";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
vim =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
defaultEditor = true;
|
||||||
|
packageConfigurable = inputs.config.programs.vim.package;
|
||||||
|
settings =
|
||||||
|
{
|
||||||
|
number = true;
|
||||||
|
expandtab = false;
|
||||||
|
shiftwidth = 2;
|
||||||
|
tabstop = 2;
|
||||||
|
};
|
||||||
|
extraConfig =
|
||||||
|
''
|
||||||
|
set clipboard=unnamedplus
|
||||||
|
colorscheme evening
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})];
|
||||||
|
};
|
||||||
|
programs =
|
||||||
|
{
|
||||||
|
nix-index-database.comma.enable = true;
|
||||||
|
nix-index.enable = true;
|
||||||
|
zsh =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
syntaxHighlighting.enable = true;
|
||||||
|
autosuggestions.enable = true;
|
||||||
|
enableCompletion = true;
|
||||||
|
ohMyZsh =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
plugins = [ "git" "colored-man-pages" "extract" "history-substring-search" "autojump" ];
|
||||||
|
customPkgs = with inputs.pkgs; [ zsh-nix-shell ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
command-not-found.enable = false;
|
||||||
|
gnupg.agent = { enable = true; enableSSHSupport = true; };
|
||||||
|
autojump.enable = true;
|
||||||
|
git =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
package = inputs.pkgs.gitFull;
|
||||||
|
lfs.enable = true;
|
||||||
|
config =
|
||||||
|
{
|
||||||
|
init.defaultBranch = "main";
|
||||||
|
core = { quotepath = false; editor = "vim"; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
yazi.enable = true;
|
||||||
|
mosh.enable = true;
|
||||||
|
};
|
||||||
|
services =
|
||||||
|
{
|
||||||
|
fwupd.enable = true;
|
||||||
|
udev.packages = with inputs.pkgs; [ yubikey-personalization libfido2 ];
|
||||||
|
};
|
||||||
|
home-manager = { useGlobalPkgs = true; useUserPackages = true; };
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -855,7 +855,7 @@
|
|||||||
#
|
#
|
||||||
# These variables correspond to the last line of the output of `todo.sh -p ls`:
|
# These variables correspond to the last line of the output of `todo.sh -p ls`:
|
||||||
#
|
#
|
||||||
# TODO: 24 of 42 tasks shown
|
# TO DO: 24 of 42 tasks shown
|
||||||
#
|
#
|
||||||
# Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT.
|
# Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT.
|
||||||
#
|
#
|
||||||
@@ -1686,7 +1686,7 @@
|
|||||||
# - verbose: Enable instant prompt and print a warning when detecting console output during
|
# - verbose: Enable instant prompt and print a warning when detecting console output during
|
||||||
# zsh initialization. Choose this if you've never tried instant prompt, haven't
|
# zsh initialization. Choose this if you've never tried instant prompt, haven't
|
||||||
# seen the warning, or if you are unsure what this all means.
|
# seen the warning, or if you are unsure what this all means.
|
||||||
typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose
|
typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet
|
||||||
|
|
||||||
# Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized.
|
# Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized.
|
||||||
# For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload
|
# For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload
|
||||||
146
modules/packages/server/ssh/default.nix
Normal file
146
modules/packages/server/ssh/default.nix
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (builtins) concatLists map listToAttrs;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
in mkIf (builtins.elem "server" inputs.config.nixos.packages._packageSets)
|
||||||
|
{
|
||||||
|
services.openssh.knownHosts =
|
||||||
|
let
|
||||||
|
servers =
|
||||||
|
{
|
||||||
|
vps6 =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO5ZcvyRyOnUCuRtqrM/Qf+AdUe3a5bhbnfyhw2FSLDZ";
|
||||||
|
hostnames = [ "vps6.chn.moe" "wireguard.vps6.chn.moe" "74.211.99.69" "192.168.83.1" ];
|
||||||
|
};
|
||||||
|
"initrd.vps6" =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB4DKB/zzUYco5ap6k9+UxeO04LL12eGvkmQstnYxgnS";
|
||||||
|
hostnames = [ "initrd.vps6.chn.moe" "74.211.99.69" ];
|
||||||
|
};
|
||||||
|
vps7 =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF5XkdilejDAlg5hZZD0oq69k8fQpe9hIJylTo/aLRgY";
|
||||||
|
hostnames = [ "vps7.chn.moe" "wireguard.vps7.chn.moe" "ssh.git.chn.moe" "95.111.228.40" "192.168.83.2" ];
|
||||||
|
};
|
||||||
|
"initrd.vps7" =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGZyQpdQmEZw3nLERFmk2tS1gpSvXwW0Eish9UfhrRxC";
|
||||||
|
hostnames = [ "initrd.vps7.chn.moe" "95.111.228.40" ];
|
||||||
|
};
|
||||||
|
nas =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIktNbEcDMKlibXg54u7QOLt0755qB/P4vfjwca8xY6V";
|
||||||
|
hostnames = [ "wireguard.nas.chn.moe" "[office.chn.moe]:5440" "192.168.1.185" "192.168.83.4" ];
|
||||||
|
};
|
||||||
|
"initrd.nas" =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAoMu0HEaFQsnlJL0L6isnkNZdRq0OiDXyaX3+fl3NjT";
|
||||||
|
hostnames = [ "initrd.nas.chn.moe" "[office.chn.moe]:5440" "192.168.1.185" ];
|
||||||
|
};
|
||||||
|
pc =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMSfREi19OSwQnhdsE8wiNwGSFFJwNGN0M5gN+sdrrLJ";
|
||||||
|
hostnames = [ "wireguard.pc.chn.moe" "192.168.83.3" ];
|
||||||
|
};
|
||||||
|
hpc =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDVpsQW3kZt5alHC6mZhay3ZEe2fRGziG4YJWCv2nn/O";
|
||||||
|
hostnames = [ "hpc.xmu.edu.cn" ];
|
||||||
|
};
|
||||||
|
github =
|
||||||
|
{
|
||||||
|
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
|
||||||
|
hostnames = [ "github.com" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in listToAttrs (concatLists (map
|
||||||
|
(server:
|
||||||
|
(
|
||||||
|
if builtins.pathExists ./ssh/${server.name}_rsa.pub then
|
||||||
|
[{
|
||||||
|
name = "${server.name}-rsa";
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
publicKey = builtins.readFile ./ssh/${server.name}_rsa.pub;
|
||||||
|
hostNames = server.value.hostnames;
|
||||||
|
};
|
||||||
|
}]
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
++ (
|
||||||
|
if builtins.pathExists ./ssh/${server.name}_ecdsa.pub then
|
||||||
|
[{
|
||||||
|
name = "${server.name}-ecdsa";
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
publicKey = builtins.readFile ./ssh/${server.name}_ecdsa.pub;
|
||||||
|
hostNames = server.value.hostnames;
|
||||||
|
};
|
||||||
|
}]
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
++ (
|
||||||
|
if server.value ? ed25519 then
|
||||||
|
[{
|
||||||
|
name = "${server.name}-ed25519";
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
publicKey = server.value.ed25519;
|
||||||
|
hostNames = server.value.hostnames;
|
||||||
|
};
|
||||||
|
}]
|
||||||
|
else []
|
||||||
|
))
|
||||||
|
(attrsToList servers)));
|
||||||
|
nixos.users.sharedModules =
|
||||||
|
[{
|
||||||
|
config.programs.ssh =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
controlMaster = "auto";
|
||||||
|
controlPersist = "1m";
|
||||||
|
compression = true;
|
||||||
|
matchBlocks = builtins.listToAttrs
|
||||||
|
(
|
||||||
|
(builtins.map
|
||||||
|
(host: { name = host; value = { inherit host; hostname = "${host}.chn.moe"; }; })
|
||||||
|
[ "vps6" "wireguard.vps6" "vps7" "wireguard.vps7" "wireguard.pc" "wireguard.nas" ])
|
||||||
|
++ (builtins.map
|
||||||
|
(host:
|
||||||
|
{
|
||||||
|
name = host;
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
host = host;
|
||||||
|
hostname = "hpc.xmu.edu.cn";
|
||||||
|
user = host;
|
||||||
|
extraOptions =
|
||||||
|
{
|
||||||
|
PubkeyAcceptedAlgorithms = "+ssh-rsa";
|
||||||
|
HostkeyAlgorithms = "+ssh-rsa";
|
||||||
|
SetEnv = "TERM=chn_unset_ls_colors:xterm-256color";
|
||||||
|
# in .bash_profile:
|
||||||
|
# if [[ $TERM == chn_unset_ls_colors* ]]; then
|
||||||
|
# export TERM=${TERM#*:}
|
||||||
|
# export CHN_LS_USE_COLOR=1
|
||||||
|
# fi
|
||||||
|
# in .bashrc
|
||||||
|
# [ -n "$CHN_LS_USE_COLOR" ] && alias ls="ls --color=auto"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
[ "wlin" "jykang" "hwang" ])
|
||||||
|
)
|
||||||
|
// {
|
||||||
|
xmupc1 = { host = "xmupc1"; hostname = "office.chn.moe"; port = 6007; };
|
||||||
|
nas = { host = "nas"; hostname = "office.chn.moe"; port = 5440; };
|
||||||
|
gitea = { host = "gitea"; hostname = "ssh.git.chn.moe"; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
}
|
||||||
1
modules/packages/server/ssh/github_ecdsa.pub
Normal file
1
modules/packages/server/ssh/github_ecdsa.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
|
||||||
1
modules/packages/server/ssh/github_rsa.pub
Normal file
1
modules/packages/server/ssh/github_rsa.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
|
||||||
1
modules/packages/server/ssh/hpc_ecdsa.pub
Normal file
1
modules/packages/server/ssh/hpc_ecdsa.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDkkl7A9kWWBoi4b5g6Vus70ja1KhPfcZZjeU1/QbYdN8PRRw/hsGklrhefslKRbym/TMFS0ko0g5WUi9G5vbGw=
|
||||||
1
modules/packages/server/ssh/hpc_rsa.pub
Normal file
1
modules/packages/server/ssh/hpc_rsa.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgs8MvV2nczjGMZ548tuAhgvCEd4uHu0VhLDSwQG7Nh/UR4Pgc5T9Nf7Vfwg96Lah/pwD5my4RaWis6bLMmlkYyDBKFBOsGYQUe5J5XfZdxk8pz+7L0Hq6gPfAZAdNlUiuFVKsvkE+NF42NgJyXSYQicPbu5LQiFwZGXlW20+LO8uBQ1y1xabKVpg8XGwordduL99VepwEzeLK/st+UVfW+mKgxkf9TuxvD2fuYIDZM7y2rXqcjf4/6OXA5kACsYK1MgZSFxgO/m6+1uCC1qBDseMTA3D+Tsjf9VtcqUE9dMd/dJ/uuILHJ0+oIqkykTCecPLgJY3Vh8rAtln/lbId
|
||||||
1
modules/packages/server/ssh/nas_rsa.pub
Normal file
1
modules/packages/server/ssh/nas_rsa.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC0+xafJMnOGCHv6OLljaq8iJ3ZBaIezv7AJ9rVWJXFg/QJRYBwct35c4zaVom7If8F+Ss+BTLMp33HZ8gLpoat6LkjARjy65Ycog3NOnEposX2JjZEYXDbovxEmcJkDXAIVmnaBUi3r22z4UI8OqsHPeRXj017O0yQrQQYEAw/IO/tSNQZt2k8JHxAX50UTqGFdgkriO1fYHBocq48m0nn3sXrMuM3yBe5zy3NngOHxMn7UxjECmAElsuu/nu1x083pRnv5NSa+JxDGJ+S6Zhj3nGGNwZesa51I4cJjsYLxgmO/NxL1J86bDp6HhK9C9799ruG60pGTw6HcvbKTgx7klUgn4936wsy7qukWqp53MvqrLSJkRb/HHU9zZqvzcjbwet+Iv1OAAok5QC88j7Jgenk3nbZw4BNFd2r/8rOZuXheDnMKOa61dXxnvoAO3Euk0RPdZqW1slT/DDyD/kB6TPY7yOywNURNnrwzfSsmravKi6bGA5t2Ehhpf2LETM=
|
||||||
1
modules/packages/server/ssh/pc_rsa.pub
Normal file
1
modules/packages/server/ssh/pc_rsa.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDOyU7VvusseL2tDp7JkIXKGxRGQNHpYWVAPraUj17Xls7Z9e7HO6+GBiGP+bB9tZbzsoTNGHdXg8VaJmf98QAhhg0FcUb6IvWmfmPWzQ0MC8L+USqdDpaH7s9SOZF/yveNYCR5GOMmFdSW4OPVYIOrjPltDIe5S1SN2nOXvjxbLmuoMjg+5U4F0ii0ZaCRuMVDskeift+Amxe7iRnSzeDbECd0rJhaUb8gf3shz0Hp9lRUMej7cJH8LLP3m0s3Vk+kasKntz18MpJ6/3n+fR2aK75qkcq9FZaFA4tSIabh9eKoxlRCy7g8Qj6nNStW+ys/a1UYBFgAoTyE7e47o3dpcxR5oMLbeDwhOstWL0YOjEH1K5Wyj3eEOT71C6kuQBPcCJQ9q9hknRpW0mWe9Q6qaAzTgE9LLssijr/yTfYQk7zKEyo0i4f6buOfmyYZfnzfnCB3LiJKa98TVEEzrKYHIO44LwIkNf/YHOMDknzjYpav6HfDy+AebRHZFYhGax1YP/tP0Ve/FSq5rh6Vwuqa/zyfFUPZmZVf+EYXK7DdyuBhEZhBEu6QrjY60NRMTMLpnUZMcZXRAz9byMpAGcCYQv6gjU99ps8AkRjZNkn+FpAtDGT+oJxixQwyZMSxZ+ZuzkZGyBMeMplZXMMLICGZ2LRAgT0bxXLZUxHJBLwwnw==
|
||||||
1
modules/packages/server/ssh/vps6_rsa.pub
Normal file
1
modules/packages/server/ssh/vps6_rsa.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDYiP+ELuG5KTmafVjBkY0ZSggJg+mDkvZpF8d7NljMst0YwKWV3IgHnkAGXdTd7jlRgm9HH6oc8rP2R6Q8EJmfr+xcL1IQIWKuYAoddHlpe2Ds4EE74xbgm5Elf7FpdYNHUH9XyVmMmIhVSpLw2N10jUhvYqw+h+xC2nObEKZuBOt/lqrTGbC/EMv3+sDv0ApBh8lKt2yfjt88pnAj1LKPANDgIYSyQOllHQWeUY/eD/5Qc9XWR3uWclslVaxriRmEA0sNZlOFCeRIyDbYpSzQBdcnojkwt7Z5kjhaqGlT9g00fdiqO0OMaeY/G8ki3QxqjONqTEDqK+DpEZFO6jyZARcY6ki0ANc0AO4qosEC3gEbAvVwyPwDFtyDggMTHlTzaw8iakMGSDEk10zKaUOgZYLzC2yCWYYQS5mae9wC1gkXIGD51/laeq2E7NpM+nha6kp9weLVyvwf0DLfwsiP+0qlCLrxBLTSRa0HQ+BnQMi4r16Ss7YJwLf/oXrbOVk=
|
||||||
1
modules/packages/server/ssh/vps7_rsa.pub
Normal file
1
modules/packages/server/ssh/vps7_rsa.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDFwb7qi9/DvhpMvu43LRlTEC+3kPAA0KNeyk4FT4HlpRE/yxMxN6tgrP9vcx2c6TMfkRwIJKDcBuVVtKOVx+SDZo+nQBxpSz73v1qSmqlsy8D4gCk0a7cLgStb3Cvh0UZjJ5nVnxjzqY2CFnpnKYGmxL+a3qTj1KYPuA2wSsxkYVcHUfDj/uTtEDdRPaNTACsUxe1a57T/Tsjp+321+zKldYreozaABEBsexf9Z34+3vZvyQcfDB3QuxlBRPJBLik80QllpNpE1bqol8swoGEPbl/Ac7tNy+GtlwTG9SH1povmoT9K+8tjJaG2pD+z+vvgZQtJQh+aczYmEBJRZp3ksw1JH4eGqTWG/SDat9Isnx2NDhJe12b9izniDciuBScNySAazIDPidsCMUYjc9kgWdSOiODOtodj5IB+KazFVJgfpmzPv97LHVdjvR74usrgbFw2mYCw2YEiL3xjDYpQGmXSNklsQLwJiBe59oyS4QNpNYQzYD9StjgRIdvtmiM=
|
||||||
104
modules/packages/workstation/default.nix
Normal file
104
modules/packages/workstation/default.nix
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf (builtins.elem "workstation" inputs.config.nixos.packages._packageSets)
|
||||||
|
{
|
||||||
|
nixos =
|
||||||
|
{
|
||||||
|
packages = with inputs.pkgs;
|
||||||
|
{
|
||||||
|
_packages =
|
||||||
|
[
|
||||||
|
# password and key management
|
||||||
|
electrum jabref
|
||||||
|
# system management
|
||||||
|
wl-mirror ventoy-full
|
||||||
|
# nix tools
|
||||||
|
nix-template appimage-run nil nixd nix-alien nix-serve node2nix nix-prefetch-github prefetch-npm-deps
|
||||||
|
nix-prefetch-docker pnpm-lock-export bundix
|
||||||
|
# instant messager
|
||||||
|
zoom-us signal-desktop qq nur-xddxdd.wechat-uos slack inputs.config.nur.repos.linyinfeng.wemeet
|
||||||
|
cinny-desktop nheko
|
||||||
|
# office
|
||||||
|
libreoffice-qt texstudio poppler_utils pdftk gnuplot pdfchain hdfview
|
||||||
|
(texlive.combine { inherit (texlive) scheme-full; inherit (localPackages) citation-style-language; })
|
||||||
|
# development
|
||||||
|
jetbrains.clion android-studio dbeaver cling clang-tools_16 ccls fprettify aircrack-ng
|
||||||
|
# media
|
||||||
|
nur-xddxdd.svp obs-studio waifu2x-converter-cpp inkscape blender
|
||||||
|
# virtualization
|
||||||
|
wineWowPackages.stagingFull virt-viewer bottles # wine64
|
||||||
|
# text editor
|
||||||
|
appflowy notion-app-enhanced joplin-desktop standardnotes logseq
|
||||||
|
# math, physics and chemistry
|
||||||
|
mathematica octaveFull root ovito paraview localPackages.vesta qchem.quantum-espresso
|
||||||
|
localPackages.vasp localPackages.vaspkit jmol localPackages.v_sim
|
||||||
|
# encryption and password management
|
||||||
|
john crunch hashcat
|
||||||
|
# container and vm
|
||||||
|
genymotion # davinci-resolve playonlinux
|
||||||
|
# browser
|
||||||
|
microsoft-edge
|
||||||
|
# news
|
||||||
|
rssguard newsflash newsboat
|
||||||
|
];
|
||||||
|
_pythonPackages = [(pythonPackages: with pythonPackages;
|
||||||
|
[
|
||||||
|
phonopy tensorflow keras openai scipy scikit-learn jupyterlab autograd
|
||||||
|
# localPackages.pix2tex
|
||||||
|
inquirerpy requests python-telegram-bot tqdm fastapi pypdf2 pandas matplotlib plotly gunicorn redis jinja2
|
||||||
|
certifi charset-normalizer idna orjson psycopg2 localPackages.eigengdb
|
||||||
|
])];
|
||||||
|
_prebuildPackages =
|
||||||
|
[
|
||||||
|
httplib magic-enum xtensor boost cereal cxxopts ftxui yaml-cpp gfortran gcc10 python2
|
||||||
|
gcc13Stdenv
|
||||||
|
];
|
||||||
|
};
|
||||||
|
users.sharedModules =
|
||||||
|
[{
|
||||||
|
config.programs =
|
||||||
|
{
|
||||||
|
obs-studio =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
plugins = with inputs.pkgs.obs-studio-plugins;
|
||||||
|
[ wlrobs obs-vaapi obs-nvfbc droidcam-obs obs-vkcapture ];
|
||||||
|
};
|
||||||
|
doom-emacs = { enable = true; doomPrivateDir = ./doom.d; };
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
programs =
|
||||||
|
{
|
||||||
|
anime-game-launcher = { enable = true; package = inputs.pkgs.anime-game-launcher; };
|
||||||
|
honkers-railway-launcher = { enable = true; package = inputs.pkgs.honkers-railway-launcher; };
|
||||||
|
nix-ld.enable = true;
|
||||||
|
gamemode =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
settings =
|
||||||
|
{
|
||||||
|
general.renice = 10;
|
||||||
|
gpu =
|
||||||
|
{
|
||||||
|
apply_gpu_optimisations = "accept-responsibility";
|
||||||
|
nv_powermizer_mode = 1;
|
||||||
|
};
|
||||||
|
custom = let notify-send = "${inputs.pkgs.libnotify}/bin/notify-send"; in
|
||||||
|
{
|
||||||
|
start = "${notify-send} 'GameMode started'";
|
||||||
|
end = "${notify-send} 'GameMode ended'";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
chromium =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
extraOpts.PasswordManagerEnabled = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
0
modules/packages/workstation/doom.d/config.el
Normal file
0
modules/packages/workstation/doom.d/config.el
Normal file
191
modules/packages/workstation/doom.d/init.el
Normal file
191
modules/packages/workstation/doom.d/init.el
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
;;; init.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; This file controls what Doom modules are enabled and what order they load
|
||||||
|
;; in. Remember to run 'doom sync' after modifying it!
|
||||||
|
|
||||||
|
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
|
||||||
|
;; documentation. There you'll find a "Module Index" link where you'll find
|
||||||
|
;; a comprehensive list of Doom's modules and what flags they support.
|
||||||
|
|
||||||
|
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
|
||||||
|
;; 'C-c c k' for non-vim users) to view its documentation. This works on
|
||||||
|
;; flags as well (those symbols that start with a plus).
|
||||||
|
;;
|
||||||
|
;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
|
||||||
|
;; directory (for easy access to its source code).
|
||||||
|
|
||||||
|
(doom! :input
|
||||||
|
;;chinese
|
||||||
|
;;japanese
|
||||||
|
;;layout ; auie,ctsrnm is the superior home row
|
||||||
|
|
||||||
|
:completion
|
||||||
|
company ; the ultimate code completion backend
|
||||||
|
;;helm ; the *other* search engine for love and life
|
||||||
|
;;ido ; the other *other* search engine...
|
||||||
|
;;ivy ; a search engine for love and life
|
||||||
|
vertico ; the search engine of the future
|
||||||
|
|
||||||
|
:ui
|
||||||
|
;;deft ; notational velocity for Emacs
|
||||||
|
doom ; what makes DOOM look the way it does
|
||||||
|
doom-dashboard ; a nifty splash screen for Emacs
|
||||||
|
doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||||||
|
;;(emoji +unicode) ; 🙂
|
||||||
|
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
|
||||||
|
;;hydra
|
||||||
|
;;indent-guides ; highlighted indent columns
|
||||||
|
;;ligatures ; ligatures and symbols to make your code pretty again
|
||||||
|
;;minimap ; show a map of the code on the side
|
||||||
|
modeline ; snazzy, Atom-inspired modeline, plus API
|
||||||
|
;;nav-flash ; blink cursor line after big motions
|
||||||
|
;;neotree ; a project drawer, like NERDTree for vim
|
||||||
|
ophints ; highlight the region an operation acts on
|
||||||
|
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
||||||
|
;;tabs ; a tab bar for Emacs
|
||||||
|
;;treemacs ; a project drawer, like neotree but cooler
|
||||||
|
;;unicode ; extended unicode support for various languages
|
||||||
|
vc-gutter ; vcs diff in the fringe
|
||||||
|
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||||
|
;;window-select ; visually switch windows
|
||||||
|
workspaces ; tab emulation, persistence & separate workspaces
|
||||||
|
;;zen ; distraction-free coding or writing
|
||||||
|
|
||||||
|
:editor
|
||||||
|
(evil +everywhere); come to the dark side, we have cookies
|
||||||
|
file-templates ; auto-snippets for empty files
|
||||||
|
fold ; (nigh) universal code folding
|
||||||
|
;;(format +onsave) ; automated prettiness
|
||||||
|
;;god ; run Emacs commands without modifier keys
|
||||||
|
;;lispy ; vim for lisp, for people who don't like vim
|
||||||
|
;;multiple-cursors ; editing in many places at once
|
||||||
|
;;objed ; text object editing for the innocent
|
||||||
|
;;parinfer ; turn lisp into python, sort of
|
||||||
|
;;rotate-text ; cycle region at point between text candidates
|
||||||
|
snippets ; my elves. They type so I don't have to
|
||||||
|
;;word-wrap ; soft wrapping with language-aware indent
|
||||||
|
|
||||||
|
:emacs
|
||||||
|
dired ; making dired pretty [functional]
|
||||||
|
electric ; smarter, keyword-based electric-indent
|
||||||
|
;;ibuffer ; interactive buffer management
|
||||||
|
undo ; persistent, smarter undo for your inevitable mistakes
|
||||||
|
vc ; version-control and Emacs, sitting in a tree
|
||||||
|
|
||||||
|
:term
|
||||||
|
;;eshell ; the elisp shell that works everywhere
|
||||||
|
;;shell ; simple shell REPL for Emacs
|
||||||
|
;;term ; basic terminal emulator for Emacs
|
||||||
|
;;vterm ; the best terminal emulation in Emacs
|
||||||
|
|
||||||
|
:checkers
|
||||||
|
syntax ; tasing you for every semicolon you forget
|
||||||
|
;;(spell +flyspell) ; tasing you for misspelling mispelling
|
||||||
|
;;grammar ; tasing grammar mistake every you make
|
||||||
|
|
||||||
|
:tools
|
||||||
|
;;ansible
|
||||||
|
;;biblio ; Writes a PhD for you (citation needed)
|
||||||
|
;;debugger ; FIXME stepping through code, to help you add bugs
|
||||||
|
;;direnv
|
||||||
|
;;docker
|
||||||
|
;;editorconfig ; let someone else argue about tabs vs spaces
|
||||||
|
;;ein ; tame Jupyter notebooks with emacs
|
||||||
|
(eval +overlay) ; run code, run (also, repls)
|
||||||
|
;;gist ; interacting with github gists
|
||||||
|
lookup ; navigate your code and its documentation
|
||||||
|
;;lsp ; M-x vscode
|
||||||
|
magit ; a git porcelain for Emacs
|
||||||
|
;;make ; run make tasks from Emacs
|
||||||
|
;;pass ; password manager for nerds
|
||||||
|
;;pdf ; pdf enhancements
|
||||||
|
;;prodigy ; FIXME managing external services & code builders
|
||||||
|
;;rgb ; creating color strings
|
||||||
|
;;taskrunner ; taskrunner for all your projects
|
||||||
|
;;terraform ; infrastructure as code
|
||||||
|
;;tmux ; an API for interacting with tmux
|
||||||
|
;;upload ; map local to remote projects via ssh/ftp
|
||||||
|
|
||||||
|
:os
|
||||||
|
(:if IS-MAC macos) ; improve compatibility with macOS
|
||||||
|
;;tty ; improve the terminal Emacs experience
|
||||||
|
|
||||||
|
:lang
|
||||||
|
;;agda ; types of types of types of types...
|
||||||
|
;;beancount ; mind the GAAP
|
||||||
|
;;cc ; C > C++ == 1
|
||||||
|
;;clojure ; java with a lisp
|
||||||
|
;;common-lisp ; if you've seen one lisp, you've seen them all
|
||||||
|
;;coq ; proofs-as-programs
|
||||||
|
;;crystal ; ruby at the speed of c
|
||||||
|
;;csharp ; unity, .NET, and mono shenanigans
|
||||||
|
;;data ; config/data formats
|
||||||
|
;;(dart +flutter) ; paint ui and not much else
|
||||||
|
;;dhall
|
||||||
|
;;elixir ; erlang done right
|
||||||
|
;;elm ; care for a cup of TEA?
|
||||||
|
emacs-lisp ; drown in parentheses
|
||||||
|
;;erlang ; an elegant language for a more civilized age
|
||||||
|
;;ess ; emacs speaks statistics
|
||||||
|
;;factor
|
||||||
|
;;faust ; dsp, but you get to keep your soul
|
||||||
|
;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER)
|
||||||
|
;;fsharp ; ML stands for Microsoft's Language
|
||||||
|
;;fstar ; (dependent) types and (monadic) effects and Z3
|
||||||
|
;;gdscript ; the language you waited for
|
||||||
|
;;(go +lsp) ; the hipster dialect
|
||||||
|
;;(haskell +lsp) ; a language that's lazier than I am
|
||||||
|
;;hy ; readability of scheme w/ speed of python
|
||||||
|
;;idris ; a language you can depend on
|
||||||
|
;;json ; At least it ain't XML
|
||||||
|
;;(java +meghanada) ; the poster child for carpal tunnel syndrome
|
||||||
|
;;javascript ; all(hope(abandon(ye(who(enter(here))))))
|
||||||
|
;;julia ; a better, faster MATLAB
|
||||||
|
;;kotlin ; a better, slicker Java(Script)
|
||||||
|
;;latex ; writing papers in Emacs has never been so fun
|
||||||
|
;;lean ; for folks with too much to prove
|
||||||
|
;;ledger ; be audit you can be
|
||||||
|
;;lua ; one-based indices? one-based indices
|
||||||
|
markdown ; writing docs for people to ignore
|
||||||
|
;;nim ; python + lisp at the speed of c
|
||||||
|
;;nix ; I hereby declare "nix geht mehr!"
|
||||||
|
;;ocaml ; an objective camel
|
||||||
|
org ; organize your plain life in plain text
|
||||||
|
;;php ; perl's insecure younger brother
|
||||||
|
;;plantuml ; diagrams for confusing people more
|
||||||
|
;;purescript ; javascript, but functional
|
||||||
|
;;python ; beautiful is better than ugly
|
||||||
|
;;qt ; the 'cutest' gui framework ever
|
||||||
|
;;racket ; a DSL for DSLs
|
||||||
|
;;raku ; the artist formerly known as perl6
|
||||||
|
;;rest ; Emacs as a REST client
|
||||||
|
;;rst ; ReST in peace
|
||||||
|
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||||
|
;;rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||||
|
;;scala ; java, but good
|
||||||
|
;;(scheme +guile) ; a fully conniving family of lisps
|
||||||
|
sh ; she sells {ba,z,fi}sh shells on the C xor
|
||||||
|
;;sml
|
||||||
|
;;solidity ; do you need a blockchain? No.
|
||||||
|
;;swift ; who asked for emoji variables?
|
||||||
|
;;terra ; Earth and Moon in alignment for performance.
|
||||||
|
;;web ; the tubes
|
||||||
|
;;yaml ; JSON, but readable
|
||||||
|
;;zig ; C, but simpler
|
||||||
|
|
||||||
|
:email
|
||||||
|
;;(mu4e +org +gmail)
|
||||||
|
;;notmuch
|
||||||
|
;;(wanderlust +gmail)
|
||||||
|
|
||||||
|
:app
|
||||||
|
;;calendar
|
||||||
|
;;emms
|
||||||
|
;;everywhere ; *leave* Emacs!? You must be joking
|
||||||
|
;;irc ; how neckbeards socialize
|
||||||
|
;;(rss +org) ; emacs as an RSS reader
|
||||||
|
;;twitter ; twitter client https://twitter.com/vnought
|
||||||
|
|
||||||
|
:config
|
||||||
|
;;literate
|
||||||
|
(default +bindings +smartparens))
|
||||||
0
modules/packages/workstation/doom.d/packages.el
Normal file
0
modules/packages/workstation/doom.d/packages.el
Normal file
@@ -3,10 +3,15 @@ inputs:
|
|||||||
options.nixos.services.acme = let inherit (inputs.lib) mkOption types; in
|
options.nixos.services.acme = let inherit (inputs.lib) mkOption types; in
|
||||||
{
|
{
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
certs = mkOption
|
cert = mkOption
|
||||||
{
|
{
|
||||||
type = types.listOf (types.oneOf [ types.nonEmptyStr (types.listOf types.nonEmptyStr) ]);
|
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
||||||
default = [];
|
{
|
||||||
|
domains = mkOption
|
||||||
|
{ type = types.nonEmptyListOf types.nonEmptyStr; default = [ submoduleInputs.config._module.args.name ]; };
|
||||||
|
group = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
|
};}));
|
||||||
|
default = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config =
|
config =
|
||||||
@@ -14,6 +19,7 @@ inputs:
|
|||||||
inherit (inputs.lib) mkIf;
|
inherit (inputs.lib) mkIf;
|
||||||
inherit (inputs.config.nixos.services) acme;
|
inherit (inputs.config.nixos.services) acme;
|
||||||
inherit (builtins) map listToAttrs;
|
inherit (builtins) map listToAttrs;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
in mkIf acme.enable
|
in mkIf acme.enable
|
||||||
{
|
{
|
||||||
security.acme =
|
security.acme =
|
||||||
@@ -23,16 +29,17 @@ inputs:
|
|||||||
certs = listToAttrs (map
|
certs = listToAttrs (map
|
||||||
(cert:
|
(cert:
|
||||||
{
|
{
|
||||||
name = if builtins.typeOf cert == "string" then cert else builtins.elemAt cert 0;
|
name = builtins.elemAt cert.value.domains 0;
|
||||||
value =
|
value =
|
||||||
{
|
{
|
||||||
dnsResolver = "8.8.8.8";
|
dnsResolver = "8.8.8.8";
|
||||||
dnsProvider = "cloudflare";
|
dnsProvider = "cloudflare";
|
||||||
credentialsFile = inputs.config.sops.secrets."acme/cloudflare.ini".path;
|
credentialsFile = inputs.config.sops.secrets."acme/cloudflare.ini".path;
|
||||||
extraDomainNames = if builtins.typeOf cert == "string" then [] else builtins.tail cert;
|
extraDomainNames = builtins.tail cert.value.domains;
|
||||||
|
group = mkIf (cert.value.group != null) cert.value.group;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
acme.certs);
|
(attrsToList acme.cert));
|
||||||
};
|
};
|
||||||
sops.secrets."acme/cloudflare.ini" = {};
|
sops.secrets."acme/cloudflare.ini" = {};
|
||||||
};
|
};
|
||||||
|
|||||||
51
modules/services/akkoma.nix
Normal file
51
modules/services/akkoma.nix
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.akkoma = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.str; default = "akkoma.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) akkoma;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf akkoma.enable
|
||||||
|
{
|
||||||
|
services.akkoma =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
config.":pleroma" =
|
||||||
|
{
|
||||||
|
"Pleroma.Web.Endpoint".url.host = akkoma.hostname;
|
||||||
|
"Pleroma.Repo" =
|
||||||
|
{
|
||||||
|
adapter = (inputs.pkgs.formats.elixirConf { }).lib.mkRaw "Ecto.Adapters.Postgres";
|
||||||
|
hostname = "127.0.0.1";
|
||||||
|
username = "akkoma";
|
||||||
|
password._secret = inputs.config.sops.secrets."akkoma/db".path;
|
||||||
|
database = "akkoma";
|
||||||
|
};
|
||||||
|
":instance" =
|
||||||
|
{
|
||||||
|
name = "艹";
|
||||||
|
email = "grass@grass.squre";
|
||||||
|
description = "艹艹艹艹艹";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
nginx =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
https."${akkoma.hostname}" =
|
||||||
|
{
|
||||||
|
global.tlsCert = "/var/lib/akkoma";
|
||||||
|
location."/".proxy = { upstream = "http://127.0.0.1:4000"; websocket = true; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
postgresql.instances.akkoma = {};
|
||||||
|
};
|
||||||
|
sops.secrets."akkoma/db" = { owner = "akkoma"; key = "postgresql/akkoma"; };
|
||||||
|
};
|
||||||
|
}
|
||||||
47
modules/services/beesd.nix
Normal file
47
modules/services/beesd.nix
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.beesd = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
instances = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.oneOf
|
||||||
|
[
|
||||||
|
types.nonEmptyStr
|
||||||
|
(types.submodule { options =
|
||||||
|
{ device = mkOption { type = types.nonEmptyStr; }; hashTableSizeMB = mkOption { type = types.int; }; };})
|
||||||
|
]);
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) beesd;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (builtins) map listToAttrs;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
in mkIf beesd.enable
|
||||||
|
{
|
||||||
|
services.beesd.filesystems = listToAttrs (map
|
||||||
|
(instance:
|
||||||
|
{
|
||||||
|
inherit (instance) name;
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
spec = instance.value.device or instance.value;
|
||||||
|
hashTableSizeMB = instance.value.hashTableSizeMB or 1024;
|
||||||
|
extraOptions = [ "--thread-count" "1" "--scan-mode" "3" ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(attrsToList beesd.instances));
|
||||||
|
systemd.slices.system-beesd.sliceConfig =
|
||||||
|
{
|
||||||
|
CPUSchedulingPolicy = "idle";
|
||||||
|
IOSchedulingClass = "idle";
|
||||||
|
IOSchedulingPriority = 4;
|
||||||
|
IOAccounting = true;
|
||||||
|
IOWeight = 1;
|
||||||
|
Nice = 19;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -11,22 +11,22 @@ inputs:
|
|||||||
inherit (inputs.lib) mkIf;
|
inherit (inputs.lib) mkIf;
|
||||||
in mkIf coturn.enable
|
in mkIf coturn.enable
|
||||||
{
|
{
|
||||||
services.coturn =
|
services.coturn = let keydir = inputs.config.security.acme.certs.${coturn.hostname}.directory; in
|
||||||
let
|
{
|
||||||
keydir = inputs.config.security.acme.certs.${coturn.hostname}.directory;
|
enable = true;
|
||||||
in
|
use-auth-secret = true;
|
||||||
{
|
static-auth-secret-file = inputs.config.sops.secrets."coturn/auth-secret".path;
|
||||||
enable = true;
|
realm = coturn.hostname;
|
||||||
use-auth-secret = true;
|
cert = "${keydir}/full.pem";
|
||||||
static-auth-secret-file = inputs.config.sops.secrets."coturn/auth-secret".path;
|
pkey = "${keydir}/key.pem";
|
||||||
realm = coturn.hostname;
|
no-cli = true;
|
||||||
cert = "${keydir}/full.pem";
|
};
|
||||||
pkey = "${keydir}/key.pem";
|
|
||||||
no-cli = true;
|
|
||||||
};
|
|
||||||
sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
|
sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
|
||||||
nixos.services.acme = { enable = true; certs = [ coturn.hostname ]; };
|
nixos.services.acme =
|
||||||
security.acme.certs.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
|
{
|
||||||
|
enable = true;
|
||||||
|
cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
|
||||||
|
};
|
||||||
networking.firewall = with inputs.config.services.coturn;
|
networking.firewall = with inputs.config.services.coturn;
|
||||||
{
|
{
|
||||||
allowedUDPPorts = [ listening-port tls-listening-port ];
|
allowedUDPPorts = [ listening-port tls-listening-port ];
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ inputs:
|
|||||||
./redis.nix
|
./redis.nix
|
||||||
./rsshub.nix
|
./rsshub.nix
|
||||||
./misskey.nix
|
./misskey.nix
|
||||||
./nginx.nix
|
./nginx
|
||||||
./meilisearch.nix
|
./meilisearch.nix
|
||||||
./xray.nix
|
./xray.nix
|
||||||
./coturn.nix
|
./coturn.nix
|
||||||
@@ -19,27 +19,34 @@ inputs:
|
|||||||
./sshd.nix
|
./sshd.nix
|
||||||
./vaultwarden.nix
|
./vaultwarden.nix
|
||||||
./frp.nix
|
./frp.nix
|
||||||
./docker.nix
|
./beesd.nix
|
||||||
|
./snapper.nix
|
||||||
|
./mariadb.nix
|
||||||
|
./photoprism.nix
|
||||||
|
./nextcloud.nix
|
||||||
|
./freshrss.nix
|
||||||
|
./kmscon.nix
|
||||||
|
./fontconfig.nix
|
||||||
|
./nix-serve.nix
|
||||||
|
./send.nix
|
||||||
./huginn.nix
|
./huginn.nix
|
||||||
|
./httpua
|
||||||
|
./fz-new-order
|
||||||
|
./httpapi.nix
|
||||||
|
./mirism.nix
|
||||||
|
./mastodon.nix
|
||||||
|
./gitea.nix
|
||||||
|
./grafana.nix
|
||||||
|
./fail2ban.nix
|
||||||
|
./wireguard.nix
|
||||||
|
./akkoma.nix
|
||||||
];
|
];
|
||||||
options.nixos.services = let inherit (inputs.lib) mkOption types; in
|
options.nixos.services = let inherit (inputs.lib) mkOption types; in
|
||||||
{
|
{
|
||||||
snapper =
|
|
||||||
{
|
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
|
||||||
configs = mkOption { type = types.attrsOf types.nonEmptyStr; default = {}; };
|
|
||||||
};
|
|
||||||
kmscon.enable = mkOption { type = types.bool; default = false; };
|
|
||||||
fontconfig.enable = mkOption { type = types.bool; default = false; };
|
|
||||||
firewall.trustedInterfaces = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
firewall.trustedInterfaces = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||||
nix-serve =
|
|
||||||
{
|
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
|
||||||
hostname = mkOption { type = types.nonEmptyStr; };
|
|
||||||
};
|
|
||||||
smartd.enable = mkOption { type = types.bool; default = false; };
|
smartd.enable = mkOption { type = types.bool; default = false; };
|
||||||
fileshelter.enable = mkOption { type = types.bool; default = false; };
|
|
||||||
wallabag.enable = mkOption { type = types.bool; default = false; };
|
wallabag.enable = mkOption { type = types.bool; default = false; };
|
||||||
|
noisetorch.enable = mkOption { type = types.bool; default = inputs.config.nixos.system.gui.preferred; };
|
||||||
};
|
};
|
||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
@@ -49,81 +56,7 @@ inputs:
|
|||||||
inherit (builtins) map listToAttrs toString;
|
inherit (builtins) map listToAttrs toString;
|
||||||
in mkMerge
|
in mkMerge
|
||||||
[
|
[
|
||||||
(
|
|
||||||
mkIf services.snapper.enable
|
|
||||||
{
|
|
||||||
services.snapper.configs =
|
|
||||||
let
|
|
||||||
f = (config:
|
|
||||||
{
|
|
||||||
inherit (config) name;
|
|
||||||
value =
|
|
||||||
{
|
|
||||||
SUBVOLUME = config.value;
|
|
||||||
TIMELINE_CREATE = true;
|
|
||||||
TIMELINE_CLEANUP = true;
|
|
||||||
TIMELINE_MIN_AGE = 1800;
|
|
||||||
TIMELINE_LIMIT_HOURLY = "10";
|
|
||||||
TIMELINE_LIMIT_DAILY = "7";
|
|
||||||
TIMELINE_LIMIT_WEEKLY = "1";
|
|
||||||
TIMELINE_LIMIT_MONTHLY = "0";
|
|
||||||
TIMELINE_LIMIT_YEARLY = "0";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
in
|
|
||||||
listToAttrs (map f (attrsToList services.snapper.configs));
|
|
||||||
nixpkgs.config.packageOverrides = pkgs:
|
|
||||||
{
|
|
||||||
snapper = pkgs.snapper.overrideAttrs (attrs:
|
|
||||||
{
|
|
||||||
patches = (if (attrs ? patches) then attrs.patches else []) ++ [ ./snapper.patch ];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
(
|
|
||||||
mkIf services.kmscon.enable
|
|
||||||
{
|
|
||||||
services.kmscon =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
fonts = [{ name = "FiraCode Nerd Font Mono"; package = inputs.pkgs.nerdfonts; }];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
(
|
|
||||||
mkIf services.fontconfig.enable
|
|
||||||
{
|
|
||||||
fonts =
|
|
||||||
{
|
|
||||||
fontDir.enable = true;
|
|
||||||
fonts = with inputs.pkgs;
|
|
||||||
[ noto-fonts source-han-sans source-han-serif source-code-pro hack-font jetbrains-mono nerdfonts ];
|
|
||||||
fontconfig.defaultFonts =
|
|
||||||
{
|
|
||||||
emoji = [ "Noto Color Emoji" ];
|
|
||||||
monospace = [ "Noto Sans Mono CJK SC" "Sarasa Mono SC" "DejaVu Sans Mono"];
|
|
||||||
sansSerif = [ "Noto Sans CJK SC" "Source Han Sans SC" "DejaVu Sans" ];
|
|
||||||
serif = [ "Noto Serif CJK SC" "Source Han Serif SC" "DejaVu Serif" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
{ networking.firewall.trustedInterfaces = services.firewall.trustedInterfaces; }
|
{ networking.firewall.trustedInterfaces = services.firewall.trustedInterfaces; }
|
||||||
(
|
|
||||||
mkIf services.nix-serve.enable
|
|
||||||
{
|
|
||||||
services.nix-serve =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
secretKeyFile = inputs.config.sops.secrets."store/signingKey".path;
|
|
||||||
};
|
|
||||||
sops.secrets."store/signingKey" = {};
|
|
||||||
nixos.services.nginx.httpProxy.${services.nix-serve.hostname} =
|
|
||||||
{ rewriteHttps = true; locations."/".upstream = "http://127.0.0.1:5000"; };
|
|
||||||
}
|
|
||||||
)
|
|
||||||
(mkIf services.smartd.enable { services.smartd.enable = true; })
|
(mkIf services.smartd.enable { services.smartd.enable = true; })
|
||||||
(
|
(
|
||||||
mkIf services.wallabag.enable
|
mkIf services.wallabag.enable
|
||||||
@@ -143,11 +76,6 @@ inputs:
|
|||||||
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
|
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
|
||||||
environmentFiles = [ inputs.config.sops.templates."wallabag/env".path ];
|
environmentFiles = [ inputs.config.sops.templates."wallabag/env".path ];
|
||||||
};
|
};
|
||||||
# systemd.services.docker-wallabag.serviceConfig =
|
|
||||||
# {
|
|
||||||
# User = "wallabag";
|
|
||||||
# Group = "wallabag";
|
|
||||||
# };
|
|
||||||
sops =
|
sops =
|
||||||
{
|
{
|
||||||
templates."wallabag/env".content =
|
templates."wallabag/env".content =
|
||||||
@@ -171,33 +99,7 @@ inputs:
|
|||||||
# SYMFONY__ENV__MAILER_DSN=smtp://bot%%40chn.moe@${placeholder."mail/bot-encoded"}:mail.chn.moe
|
# SYMFONY__ENV__MAILER_DSN=smtp://bot%%40chn.moe@${placeholder."mail/bot-encoded"}:mail.chn.moe
|
||||||
# SYMFONY__ENV__FROM_EMAIL=bot@chn.moe
|
# SYMFONY__ENV__FROM_EMAIL=bot@chn.moe
|
||||||
# SYMFONY__ENV__TWOFACTOR_SENDER=bot@chn.moe
|
# SYMFONY__ENV__TWOFACTOR_SENDER=bot@chn.moe
|
||||||
secrets =
|
secrets."mail/bot-encoded" = {};
|
||||||
{
|
|
||||||
"redis/wallabag".owner = inputs.config.users.users.redis-wallabag.name;
|
|
||||||
"postgresql/wallabag" = {};
|
|
||||||
"mail/bot-encoded" = {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
services =
|
|
||||||
{
|
|
||||||
redis.servers.wallabag =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
bind = null;
|
|
||||||
port = 8790;
|
|
||||||
requirePassFile = inputs.config.sops.secrets."redis/wallabag".path;
|
|
||||||
};
|
|
||||||
postgresql =
|
|
||||||
{
|
|
||||||
ensureDatabases = [ "wallabag" ];
|
|
||||||
ensureUsers =
|
|
||||||
[{
|
|
||||||
name = "wallabag";
|
|
||||||
ensurePermissions."DATABASE \"wallabag\"" = "ALL PRIVILEGES";
|
|
||||||
}];
|
|
||||||
# ALTER DATABASE db_name OWNER TO new_owner_name
|
|
||||||
# sudo docker exec -t wallabag /var/www/wallabag/bin/console wallabag:install --env=prod --no-interaction
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
nixos =
|
nixos =
|
||||||
{
|
{
|
||||||
@@ -206,22 +108,15 @@ inputs:
|
|||||||
nginx =
|
nginx =
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = true;
|
||||||
httpProxy."wallabag.chn.moe" =
|
https."wallabag.chn.moe".location."/".proxy.upstream = "http://127.0.0.1:4398";
|
||||||
{
|
|
||||||
rewriteHttps = true;
|
|
||||||
locations."/" = { upstream = "http://127.0.0.1:4398"; setHeaders.Host = "wallabag.chn.moe"; };
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
postgresql.enable = true;
|
postgresql = { enable = true; instances.wallabag = {}; };
|
||||||
|
redis.instances.wallabag = { user = "root"; port = 8790; };
|
||||||
};
|
};
|
||||||
virtualization.docker.enable = true;
|
virtualization.docker.enable = true;
|
||||||
};
|
};
|
||||||
# users =
|
|
||||||
# {
|
|
||||||
# users.wallabag = { isSystemUser = true; group = "wallabag"; autoSubUidGidRange = true; };
|
|
||||||
# groups.wallabag = {};
|
|
||||||
# };
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
(mkIf services.noisetorch.enable { programs.noisetorch.enable = true; })
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,133 +0,0 @@
|
|||||||
inputs:
|
|
||||||
{
|
|
||||||
options.nixos.services.docker = let inherit (inputs.lib) mkOption types; in mkOption
|
|
||||||
{
|
|
||||||
type = types.attrsOf (types.submodule (inputs: { options =
|
|
||||||
{
|
|
||||||
user = mkOption { type = types.nonEmptyStr; default = inputs.config._module.args.name; };
|
|
||||||
image = mkOption { type = types.package; };
|
|
||||||
imageName =
|
|
||||||
mkOption { type = types.nonEmptyStr; default = with inputs.config.image; (imageName + ":" + imageTag); };
|
|
||||||
ports = mkOption
|
|
||||||
{
|
|
||||||
type = types.listOf (types.oneOf
|
|
||||||
[
|
|
||||||
types.ints.unsigned
|
|
||||||
types.submodule (inputs: { options =
|
|
||||||
{
|
|
||||||
hostIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
|
|
||||||
hostPort = mkOption { type = types.ints.unsigned; };
|
|
||||||
containerPort = mkOption { type = types.ints.unsigned; };
|
|
||||||
protocol = mkOption { type = types.enum [ "tcp" "udp" ]; default = "tcp"; };
|
|
||||||
};})
|
|
||||||
]);
|
|
||||||
default = [];
|
|
||||||
};
|
|
||||||
environmentFile = mkOption { type = types.oneOf [ types.bool types.nonEmptyStr ]; default = false; };
|
|
||||||
};}));
|
|
||||||
default = {};
|
|
||||||
};
|
|
||||||
config =
|
|
||||||
let
|
|
||||||
inherit (inputs.lib) mkIf;
|
|
||||||
inherit (builtins) listToAttrs map concatLists;
|
|
||||||
inherit (inputs.localLib) attrsToList;
|
|
||||||
inherit (inputs.config.nixos.services) docker;
|
|
||||||
in mkIf (docker != {})
|
|
||||||
{
|
|
||||||
virtualisation.oci-containers.containers = listToAttrs (map
|
|
||||||
(container:
|
|
||||||
{
|
|
||||||
name = "${container.name}";
|
|
||||||
value =
|
|
||||||
{
|
|
||||||
image = container.value.imageName;
|
|
||||||
imageFile = container.value.image;
|
|
||||||
ports = map
|
|
||||||
(port:
|
|
||||||
(
|
|
||||||
if builtins.typeOf port == "int" then toString port
|
|
||||||
else ("${port.value.hostIp}:${toString port.value.hostPort}"
|
|
||||||
+ ":${toString port.value.containerPort}/${port.value.protocol}")
|
|
||||||
))
|
|
||||||
container.value.ports;
|
|
||||||
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
|
|
||||||
environmentFiles =
|
|
||||||
if builtins.typeOf container.value.environmentFile == "bool" && container.value.environmentFile
|
|
||||||
then [ inputs.config.sops.templates."${container.name}.env".path ]
|
|
||||||
else if builtins.typeOf container.value.environmentFile == "bool" then []
|
|
||||||
else [ container.value.environmentFile ];
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(attrsToList docker));
|
|
||||||
systemd =
|
|
||||||
{
|
|
||||||
services = listToAttrs (concatLists (map
|
|
||||||
(container: let user = container.value.user; in
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name = "docker-${user}-daemon";
|
|
||||||
value = let originalService = inputs.config.systemd.user.services.docker; in
|
|
||||||
{
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
inherit (originalService) description path;
|
|
||||||
environment.XDG_RUNTIME_DIR = "/run/docker-rootless/${user}";
|
|
||||||
serviceConfig = originalService.serviceConfig //
|
|
||||||
{
|
|
||||||
User = user;
|
|
||||||
Group = user;
|
|
||||||
# AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
|
||||||
ExecStart = originalService.serviceConfig.ExecStart
|
|
||||||
+ " -H unix:///var/run/docker-rootless/${user}/docker.sock";
|
|
||||||
};
|
|
||||||
unitConfig = { inherit (originalService.unitConfig) StartLimitInterval; };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "docker-${container.name}";
|
|
||||||
value =
|
|
||||||
{
|
|
||||||
requires = [ "docker-${user}-daemon.service" ];
|
|
||||||
after = [ "docker-${user}-daemon.service" ];
|
|
||||||
environment =
|
|
||||||
{
|
|
||||||
XDG_RUNTIME_DIR = "/run/docker-rootless/${user}";
|
|
||||||
DOCKER_HOST = "unix:///run/docker-rootless/${user}/docker.sock";
|
|
||||||
};
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
User = user;
|
|
||||||
Group = user;
|
|
||||||
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
|
||||||
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
])
|
|
||||||
(attrsToList docker)));
|
|
||||||
tmpfiles.rules = map
|
|
||||||
(container: with container.value; "d /run/docker-rootless/${user} 0755 ${user} ${user}")
|
|
||||||
(attrsToList docker);
|
|
||||||
};
|
|
||||||
nixos.virtualization.docker.enable = true;
|
|
||||||
users =
|
|
||||||
{
|
|
||||||
users = listToAttrs (map
|
|
||||||
(container:
|
|
||||||
{
|
|
||||||
name = container.value.user;
|
|
||||||
value =
|
|
||||||
{
|
|
||||||
isSystemUser = true;
|
|
||||||
group = container.value.user;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
home = "/run/docker-rootless/${container.value.user}";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(attrsToList docker));
|
|
||||||
groups = listToAttrs (map
|
|
||||||
(container: { name = container.value.user; value = {}; })
|
|
||||||
(attrsToList docker));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
19
modules/services/fail2ban.nix
Normal file
19
modules/services/fail2ban.nix
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.fail2ban = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) fail2ban;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf fail2ban.enable
|
||||||
|
{
|
||||||
|
services.fail2ban =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
ignoreIP = [ "127.0.0.0/8" "192.168.0.0/16" "vps6.chn.moe" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
27
modules/services/fontconfig.nix
Normal file
27
modules/services/fontconfig.nix
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.fontconfig = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (inputs.config.nixos.services) fontconfig;
|
||||||
|
in mkIf fontconfig.enable
|
||||||
|
{
|
||||||
|
fonts =
|
||||||
|
{
|
||||||
|
fontDir.enable = true;
|
||||||
|
packages = with inputs.pkgs;
|
||||||
|
[ noto-fonts source-han-sans source-han-serif source-code-pro hack-font jetbrains-mono nerdfonts ];
|
||||||
|
fontconfig.defaultFonts =
|
||||||
|
{
|
||||||
|
emoji = [ "Noto Color Emoji" ];
|
||||||
|
monospace = [ "Noto Sans Mono CJK SC" "Sarasa Mono SC" "DejaVu Sans Mono"];
|
||||||
|
sansSerif = [ "Noto Sans CJK SC" "Source Han Sans SC" "DejaVu Sans" ];
|
||||||
|
serif = [ "Noto Serif CJK SC" "Source Han Serif SC" "DejaVu Serif" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
52
modules/services/freshrss.nix
Normal file
52
modules/services/freshrss.nix
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.freshrss = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.str; default = "freshrss.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) freshrss;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf freshrss.enable
|
||||||
|
{
|
||||||
|
services.freshrss =
|
||||||
|
{
|
||||||
|
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; };
|
||||||
|
virtualHost = null;
|
||||||
|
};
|
||||||
|
sops.secrets =
|
||||||
|
{
|
||||||
|
"freshrss/chn".owner = inputs.config.users.users.freshrss.name;
|
||||||
|
"freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; };
|
||||||
|
};
|
||||||
|
systemd.services.freshrss-config.after = [ "mysql.service" ];
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
mariadb = { enable = true; instances.freshrss = {}; };
|
||||||
|
nginx.https.${freshrss.hostname} =
|
||||||
|
{
|
||||||
|
location =
|
||||||
|
{
|
||||||
|
"/".static =
|
||||||
|
{
|
||||||
|
root = "${inputs.pkgs.freshrss}/p";
|
||||||
|
index = [ "index.php" ];
|
||||||
|
tryFiles = [ "$uri" "$uri/" "$uri/index.php" ];
|
||||||
|
};
|
||||||
|
"~ ^.+?\.php(/.*)?$".php =
|
||||||
|
{
|
||||||
|
root = "${inputs.pkgs.freshrss}/p";
|
||||||
|
fastcgiPass =
|
||||||
|
"unix:${inputs.config.services.phpfpm.pools.${inputs.config.services.freshrss.pool}.socket}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -21,6 +21,30 @@ inputs:
|
|||||||
}));
|
}));
|
||||||
default = {};
|
default = {};
|
||||||
};
|
};
|
||||||
|
stcp = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule (inputs:
|
||||||
|
{
|
||||||
|
options =
|
||||||
|
{
|
||||||
|
localIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
|
||||||
|
localPort = mkOption { type = types.ints.unsigned; };
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
stcpVisitor = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule (inputs:
|
||||||
|
{
|
||||||
|
options =
|
||||||
|
{
|
||||||
|
localIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
|
||||||
|
localPort = mkOption { type = types.ints.unsigned; };
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
frpServer =
|
frpServer =
|
||||||
{
|
{
|
||||||
@@ -31,6 +55,7 @@ inputs:
|
|||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
inherit (inputs.lib) mkMerge mkIf;
|
inherit (inputs.lib) mkMerge mkIf;
|
||||||
|
inherit (inputs.lib.strings) splitString;
|
||||||
inherit (inputs.localLib) attrsToList;
|
inherit (inputs.localLib) attrsToList;
|
||||||
inherit (inputs.config.nixos.services) frpClient frpServer;
|
inherit (inputs.config.nixos.services) frpClient frpServer;
|
||||||
inherit (builtins) map listToAttrs;
|
inherit (builtins) map listToAttrs;
|
||||||
@@ -42,7 +67,7 @@ inputs:
|
|||||||
systemd.services.frpc =
|
systemd.services.frpc =
|
||||||
let
|
let
|
||||||
frpc = "${inputs.pkgs.frp}/bin/frpc";
|
frpc = "${inputs.pkgs.frp}/bin/frpc";
|
||||||
config = inputs.config.sops.templates."frpc.ini";
|
config = inputs.config.sops.templates."frpc.json";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
description = "Frp Client Service";
|
description = "Frp Client Service";
|
||||||
@@ -61,42 +86,64 @@ inputs:
|
|||||||
};
|
};
|
||||||
sops =
|
sops =
|
||||||
{
|
{
|
||||||
templates."frpc.ini" =
|
templates."frpc.json" =
|
||||||
{
|
{
|
||||||
owner = inputs.config.users.users.frp.name;
|
owner = inputs.config.users.users.frp.name;
|
||||||
group = inputs.config.users.users.frp.group;
|
group = inputs.config.users.users.frp.group;
|
||||||
content = inputs.lib.generators.toINI {}
|
content = builtins.toJSON
|
||||||
(
|
{
|
||||||
{
|
auth.token = inputs.config.sops.placeholder."frp/token";
|
||||||
common =
|
user = frpClient.user;
|
||||||
{
|
serverAddr = frpClient.serverName;
|
||||||
server_addr = frpClient.serverName;
|
serverPort = 7000;
|
||||||
server_port = 7000;
|
proxies =
|
||||||
token = inputs.config.sops.placeholder."frp/token";
|
(map
|
||||||
user = frpClient.user;
|
|
||||||
tls_enable = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// (listToAttrs (map
|
|
||||||
(tcp:
|
(tcp:
|
||||||
{
|
{
|
||||||
name = tcp.name;
|
name = tcp.name;
|
||||||
value =
|
type = "tcp";
|
||||||
{
|
transport.useCompression = true;
|
||||||
type = "tcp";
|
inherit (tcp.value) localIp localPort remotePort;
|
||||||
local_ip = tcp.value.localIp;
|
|
||||||
local_port = tcp.value.localPort;
|
|
||||||
remote_port = tcp.value.remotePort;
|
|
||||||
use_compression = true;
|
|
||||||
};
|
|
||||||
})
|
})
|
||||||
(attrsToList frpClient.tcp))
|
(attrsToList frpClient.tcp))
|
||||||
)
|
++ (map
|
||||||
);
|
(stcp:
|
||||||
|
{
|
||||||
|
name = stcp.name;
|
||||||
|
type = "stcp";
|
||||||
|
transport.useCompression = true;
|
||||||
|
secretKey = inputs.config.sops.placeholder."frp/stcp/${stcp.name}";
|
||||||
|
inherit (stcp.value) localIp localPort;
|
||||||
|
})
|
||||||
|
(attrsToList frpClient.stcp));
|
||||||
|
visitors = map
|
||||||
|
(stcp:
|
||||||
|
{
|
||||||
|
name = stcp.name;
|
||||||
|
type = "stcp";
|
||||||
|
transport = { useCompression = true; tls.enable = true; };
|
||||||
|
secretKey = inputs.config.sops.placeholder."frp/stcp/${stcp.name}";
|
||||||
|
serverUser = builtins.elemAt (splitString "." stcp.name) 0;
|
||||||
|
serverName = builtins.elemAt (splitString "." stcp.name) 1;
|
||||||
|
bindAddr = stcp.value.localIp;
|
||||||
|
bindPort = stcp.value.localPort;
|
||||||
|
})
|
||||||
|
(attrsToList frpClient.stcpVisitor);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
secrets."frp/token" = {};
|
secrets = listToAttrs
|
||||||
|
(
|
||||||
|
[{ name = "frp/token"; value = {}; }]
|
||||||
|
++ (map
|
||||||
|
(stcp: { name = "frp/stcp/${stcp.name}"; value = {}; })
|
||||||
|
(attrsToList (with frpClient; stcp // stcpVisitor)))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
users =
|
||||||
|
{
|
||||||
|
users.frp = { uid = inputs.config.nixos.system.user.user.frp; group = "frp"; isSystemUser = true; };
|
||||||
|
groups.frp.gid = inputs.config.nixos.system.user.group.frp;
|
||||||
};
|
};
|
||||||
users = { users.frp = { isSystemUser = true; group = "frp"; }; groups.frp = {}; };
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
@@ -105,7 +152,7 @@ inputs:
|
|||||||
systemd.services.frps =
|
systemd.services.frps =
|
||||||
let
|
let
|
||||||
frps = "${inputs.pkgs.frp}/bin/frps";
|
frps = "${inputs.pkgs.frp}/bin/frps";
|
||||||
config = inputs.config.sops.templates."frps.ini";
|
config = inputs.config.sops.templates."frps.json";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
description = "Frp Server Service";
|
description = "Frp Server Service";
|
||||||
@@ -124,29 +171,30 @@ inputs:
|
|||||||
};
|
};
|
||||||
sops =
|
sops =
|
||||||
{
|
{
|
||||||
templates."frps.ini" =
|
templates."frps.json" =
|
||||||
{
|
{
|
||||||
owner = inputs.config.users.users.frp.name;
|
owner = inputs.config.users.users.frp.name;
|
||||||
group = inputs.config.users.users.frp.group;
|
group = inputs.config.users.users.frp.group;
|
||||||
content = inputs.lib.generators.toINI {}
|
content = builtins.toJSON
|
||||||
{
|
{
|
||||||
common = let cert = inputs.config.security.acme.certs.${frpServer.serverName}.directory; in
|
auth.token = inputs.config.sops.placeholder."frp/token";
|
||||||
|
transport.tls = let cert = inputs.config.security.acme.certs.${frpServer.serverName}.directory; in
|
||||||
{
|
{
|
||||||
bind_port = 7000;
|
force = true;
|
||||||
bind_udp_port = 7000;
|
certFile = "${cert}/full.pem";
|
||||||
token = inputs.config.sops.placeholder."frp/token";
|
keyFile = "${cert}/key.pem";
|
||||||
tls_cert_file = "${cert}/full.pem";
|
serverName = frpServer.serverName;
|
||||||
tls_key_file = "${cert}/key.pem";
|
|
||||||
tls_only = true;
|
|
||||||
user_conn_timeout = 30;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
secrets."frp/token" = {};
|
secrets."frp/token" = {};
|
||||||
};
|
};
|
||||||
nixos.services.acme = { enable = true; certs = [ frpServer.serverName ]; };
|
nixos.services.acme = { enable = true; cert.${frpServer.serverName}.group = "frp"; };
|
||||||
security.acme.certs.${frpServer.serverName}.group = "frp";
|
users =
|
||||||
users = { users.frp = { isSystemUser = true; group = "frp"; }; groups.frp = {}; };
|
{
|
||||||
|
users.frp = { uid = inputs.config.nixos.system.user.user.frp; group = "frp"; isSystemUser = true; };
|
||||||
|
groups.frp.gid = inputs.config.nixos.system.user.group.frp;
|
||||||
|
};
|
||||||
networking.firewall.allowedTCPPorts = [ 7000 ];
|
networking.firewall.allowedTCPPorts = [ 7000 ];
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
115
modules/services/fz-new-order/default.nix
Normal file
115
modules/services/fz-new-order/default.nix
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.fz-new-order = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) fz-new-order;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (builtins) map listToAttrs toString concatLists;
|
||||||
|
in mkIf fz-new-order.enable
|
||||||
|
{
|
||||||
|
users =
|
||||||
|
{
|
||||||
|
users.fz-new-order =
|
||||||
|
{
|
||||||
|
uid = inputs.config.nixos.system.user.user.fz-new-order;
|
||||||
|
group = "fz-new-order";
|
||||||
|
home = "/var/lib/fz-new-order";
|
||||||
|
createHome = true;
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
groups.fz-new-order.gid = inputs.config.nixos.system.user.group.fz-new-order;
|
||||||
|
};
|
||||||
|
systemd =
|
||||||
|
{
|
||||||
|
timers.fz-new-order =
|
||||||
|
{
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig =
|
||||||
|
{
|
||||||
|
OnBootSec = "10m";
|
||||||
|
OnUnitActiveSec = "10m";
|
||||||
|
Unit = "fz-new-order.service";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.fz-new-order = rec
|
||||||
|
{
|
||||||
|
description = "fz-new-order";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
requires = after;
|
||||||
|
serviceConfig =
|
||||||
|
{
|
||||||
|
User = inputs.config.users.users."fz-new-order".name;
|
||||||
|
Group = inputs.config.users.users."fz-new-order".group;
|
||||||
|
WorkingDirectory = "/var/lib/fz-new-order";
|
||||||
|
ExecStart =
|
||||||
|
let
|
||||||
|
src = inputs.pkgs.substituteAll
|
||||||
|
{
|
||||||
|
src = ./main.cpp;
|
||||||
|
config_file = inputs.config.sops.templates."fz-new-order/config.json".path;
|
||||||
|
};
|
||||||
|
binary = inputs.pkgs.stdenv.mkDerivation
|
||||||
|
{
|
||||||
|
name = "fz-new-order";
|
||||||
|
inherit src;
|
||||||
|
buildInputs = with inputs.pkgs; [ jsoncpp.dev cereal fmt httplib ];
|
||||||
|
dontUnpack = true;
|
||||||
|
buildPhase =
|
||||||
|
''
|
||||||
|
runHook preBuild
|
||||||
|
g++ -std=c++20 -O2 -o fz-new-order ${src} -ljsoncpp -lfmt
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
installPhase =
|
||||||
|
''
|
||||||
|
runHook preInstall
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp fz-new-order $out/bin/fz-new-order
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in "${binary}/bin/fz-new-order";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
tmpfiles.rules =
|
||||||
|
[
|
||||||
|
"d /var/lib/fz-new-order 0700 fz-new-order fz-new-order"
|
||||||
|
"Z /var/lib/fz-new-order - fz-new-order fz-new-order"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
sops = let userNum = 6; configNum = 2; in
|
||||||
|
{
|
||||||
|
templates."fz-new-order/config.json" =
|
||||||
|
{
|
||||||
|
owner = inputs.config.users.users."fz-new-order".name;
|
||||||
|
group = inputs.config.users.users."fz-new-order".group;
|
||||||
|
content = let placeholder = inputs.config.sops.placeholder; in builtins.toJSON
|
||||||
|
{
|
||||||
|
manager = placeholder."fz-new-order/manager";
|
||||||
|
token = placeholder."fz-new-order/token";
|
||||||
|
uids = map (j: placeholder."fz-new-order/uids/user${toString j}") (builtins.genList (n: n) userNum);
|
||||||
|
config = map
|
||||||
|
(i: listToAttrs (map
|
||||||
|
(attrName: { name = attrName; value = placeholder."fz-new-order/config${toString i}/${attrName}"; })
|
||||||
|
[ "username" "password" "comment" ]))
|
||||||
|
(builtins.genList (n: n) configNum);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
secrets =
|
||||||
|
{ "fz-new-order/manager" = {}; "fz-new-order/token" = {}; }
|
||||||
|
// (listToAttrs (map
|
||||||
|
(i: { name = "fz-new-order/uids/user${toString i}"; value = {}; })
|
||||||
|
(builtins.genList (n: n) userNum)))
|
||||||
|
// (listToAttrs (concatLists (map
|
||||||
|
(i: map
|
||||||
|
(attrName: { name = "fz-new-order/config${toString i}/${attrName}"; value = {}; })
|
||||||
|
[ "username" "password" "comment" ])
|
||||||
|
(builtins.genList (n: n) configNum))));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
254
modules/services/fz-new-order/main.cpp
Normal file
254
modules/services/fz-new-order/main.cpp
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
# include <iostream>
|
||||||
|
# include <set>
|
||||||
|
# include <sstream>
|
||||||
|
# include <filesystem>
|
||||||
|
# include <cereal/types/set.hpp>
|
||||||
|
# include <cereal/archives/json.hpp>
|
||||||
|
# include <fmt/format.h>
|
||||||
|
# include <fmt/ranges.h>
|
||||||
|
# include <httplib.h>
|
||||||
|
# include <json/json.h>
|
||||||
|
|
||||||
|
std::string urlencode(std::string s)
|
||||||
|
{
|
||||||
|
auto hexchar = [](unsigned char c, unsigned char &hex1, unsigned char &hex2)
|
||||||
|
{
|
||||||
|
hex1 = c / 16;
|
||||||
|
hex2 = c % 16;
|
||||||
|
hex1 += hex1 <= 9 ? '0' : 'a' - 10;
|
||||||
|
hex2 += hex2 <= 9 ? '0' : 'a' - 10;
|
||||||
|
};
|
||||||
|
const char *str = s.c_str();
|
||||||
|
std::vector<char> v(s.size());
|
||||||
|
v.clear();
|
||||||
|
for (std::size_t i = 0, l = s.size(); i < l; i++)
|
||||||
|
{
|
||||||
|
char c = str[i];
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(c >= '0' && c <= '9')
|
||||||
|
|| (c >= 'a' && c <= 'z')
|
||||||
|
|| (c >= 'A' && c <= 'Z')
|
||||||
|
|| c == '-' || c == '_' || c == '.' || c == '!' || c == '~'
|
||||||
|
|| c == '*' || c == '\'' || c == '(' || c == ')'
|
||||||
|
)
|
||||||
|
v.push_back(c);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v.push_back('%');
|
||||||
|
unsigned char d1, d2;
|
||||||
|
hexchar(c, d1, d2);
|
||||||
|
v.push_back(d1);
|
||||||
|
v.push_back(d2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::string(v.cbegin(), v.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
void oneshot
|
||||||
|
(
|
||||||
|
const std::string& username, const std::string& password, const std::string& comment,
|
||||||
|
const std::set<std::string>& wxuser, const std::set<std::string>& manager, const std::string& token
|
||||||
|
)
|
||||||
|
{
|
||||||
|
httplib::Client fzclient("http://scmv9.fengzhansy.com:8882");
|
||||||
|
httplib::Client wxclient("http://wxpusher.zjiecode.com");
|
||||||
|
auto& log = std::clog;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get JSESSIONID
|
||||||
|
auto cookie_jsessionid = [&]() -> std::string
|
||||||
|
{
|
||||||
|
log << "get /scmv9/login.jsp\n";
|
||||||
|
auto result = fzclient.Get("/scmv9/login.jsp");
|
||||||
|
if (result.error() != httplib::Error::Success)
|
||||||
|
throw std::runtime_error("request failed");
|
||||||
|
auto it = result.value().headers.find("Set-Cookie");
|
||||||
|
if (it == result.value().headers.end() || it->first != "Set-Cookie")
|
||||||
|
throw std::runtime_error("find cookie failed");
|
||||||
|
log << fmt::format("set_cookie JSESSIONID {}\n", it->second.substr(0, it->second.find(';')));
|
||||||
|
return it->second.substr(0, it->second.find(';'));
|
||||||
|
}();
|
||||||
|
|
||||||
|
// login
|
||||||
|
auto cookie_pppp = [&]() -> std::string
|
||||||
|
{
|
||||||
|
auto body = fmt::format("method=dologinajax&rand=1234&userc={}&mdid=P&passw={}", username, password);
|
||||||
|
httplib::Headers headers =
|
||||||
|
{
|
||||||
|
{ "X-Requested-With", "XMLHttpRequest" },
|
||||||
|
{
|
||||||
|
"User-Agent",
|
||||||
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"
|
||||||
|
},
|
||||||
|
{ "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" },
|
||||||
|
{ "Origin", "http://scmv9.fengzhansy.com:8882" },
|
||||||
|
{ "Referer", "http://scmv9.fengzhansy.com:8882/scmv9/login.jsp" },
|
||||||
|
{ "Cookie", cookie_jsessionid }
|
||||||
|
};
|
||||||
|
log << "post /scmv9/data.jsp\n";
|
||||||
|
auto result = fzclient.Post("/scmv9/data.jsp", headers, body, "application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
|
if (result.error() != httplib::Error::Success)
|
||||||
|
throw std::runtime_error("request failed");
|
||||||
|
log << fmt::format("set_cookie pppp {}\n", fmt::format("pppp={}%40{}", username, password));
|
||||||
|
return fmt::format("pppp={}%40{}", username, password);
|
||||||
|
}();
|
||||||
|
|
||||||
|
// get order list
|
||||||
|
auto order_list = [&]() -> std::map<std::string, std::pair<std::string, std::string>>
|
||||||
|
{
|
||||||
|
auto body = fmt::format("method=dgate&rand=1234&op=scmmgr_pcggl&nv%5B%5D=opmode&nv%5B%5D=dd_qry&nv%5B%5D=bill&nv%5B%5D=&nv%5B%5D=storeid&nv%5B%5D=&nv%5B%5D=vendorid&nv%5B%5D={}&nv%5B%5D=qr_status&nv%5B%5D=&nv%5B%5D=ddprt&nv%5B%5D=%25&nv%5B%5D=fdate&nv%5B%5D=&nv%5B%5D=tdate&nv%5B%5D=&nv%5B%5D=shfdate&nv%5B%5D=&nv%5B%5D=shtdate&nv%5B%5D=&nv%5B%5D=fy_pno&nv%5B%5D=1&nv%5B%5D=fy_psize&nv%5B%5D=10", username);
|
||||||
|
httplib::Headers headers =
|
||||||
|
{
|
||||||
|
{ "X-Requested-With", "XMLHttpRequest" },
|
||||||
|
{
|
||||||
|
"User-Agent",
|
||||||
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"
|
||||||
|
},
|
||||||
|
{ "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" },
|
||||||
|
{ "Origin", "http://scmv9.fengzhansy.com:8882"
|
||||||
|
},
|
||||||
|
{ "Referer", "http://scmv9.fengzhansy.com:8882/scmv9/SCM/cggl_po_qry.jsp" },
|
||||||
|
{ "Cookie", fmt::format("{}; {}", cookie_jsessionid, cookie_pppp) }
|
||||||
|
};
|
||||||
|
log << "post /scmv9/data.jsp\n";
|
||||||
|
auto result = fzclient.Post("/scmv9/data.jsp", headers, body, "application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
|
if (result.error() != httplib::Error::Success)
|
||||||
|
throw std::runtime_error("request failed");
|
||||||
|
log << fmt::format("get result {}\n", result.value().body);
|
||||||
|
std::stringstream result_body(result.value().body);
|
||||||
|
Json::Value root;
|
||||||
|
result_body >> root;
|
||||||
|
std::map<std::string, std::pair<std::string, std::string>> orders;
|
||||||
|
for (unsigned i = 0; i < root["dt"][1].size(); i++)
|
||||||
|
{
|
||||||
|
log << fmt::format
|
||||||
|
(
|
||||||
|
"insert order {} {} {}\n", root["dt"][1][i].asString(), root["dt"][2][i].asString(),
|
||||||
|
root["dt"][4][i].asString()
|
||||||
|
);
|
||||||
|
orders.insert({root["dt"][1][i].asString(), {root["dt"][2][i].asString(), root["dt"][4][i].asString()}});
|
||||||
|
}
|
||||||
|
return orders;
|
||||||
|
}();
|
||||||
|
|
||||||
|
// read order old
|
||||||
|
auto order_old = [&]() -> std::set<std::string>
|
||||||
|
{
|
||||||
|
if (!std::filesystem::exists("orders.json"))
|
||||||
|
return {};
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ifstream ins("orders.json");
|
||||||
|
cereal::JSONInputArchive ina(ins);
|
||||||
|
std::set<std::string> data;
|
||||||
|
cereal::load(ina, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
// push new order info
|
||||||
|
for (const auto& order : order_list)
|
||||||
|
if (!order_old.contains(order.first))
|
||||||
|
{
|
||||||
|
for (const auto& user : manager)
|
||||||
|
{
|
||||||
|
auto path = fmt::format
|
||||||
|
(
|
||||||
|
"/api/send/message/?appToken={}&content={}&uid={}",
|
||||||
|
token, urlencode(fmt::format("push {}", order.first)), user
|
||||||
|
);
|
||||||
|
auto wxresult = wxclient.Get(path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto body = fmt::format
|
||||||
|
(
|
||||||
|
"method=dgate&rand=1234&op=scmmgr_pcggl&nv%5B%5D=opmode&nv%5B%5D=ddsp_qry&nv%5B%5D=bill&nv%5B%5D={}",
|
||||||
|
order.first
|
||||||
|
);
|
||||||
|
httplib::Headers headers =
|
||||||
|
{
|
||||||
|
{ "X-Requested-With", "XMLHttpRequest" },
|
||||||
|
{
|
||||||
|
"User-Agent",
|
||||||
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"
|
||||||
|
},
|
||||||
|
{ "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" },
|
||||||
|
{ "Origin", "http://scmv9.fengzhansy.com:8882" },
|
||||||
|
{ "Referer", "http://scmv9.fengzhansy.com:8882/scmv9/SCM/cggl_po_qry.jsp" },
|
||||||
|
{ "Cookie", fmt::format("{}; {}", cookie_jsessionid, cookie_pppp) }
|
||||||
|
};
|
||||||
|
log << "post /scmv9/data.jsp\n";
|
||||||
|
auto result = fzclient.Post
|
||||||
|
("/scmv9/data.jsp", headers, body, "application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
|
if (result.error() != httplib::Error::Success)
|
||||||
|
throw std::runtime_error("request failed");
|
||||||
|
log << fmt::format("get result {}\n", result.value().body);
|
||||||
|
std::stringstream result_body(result.value().body);
|
||||||
|
Json::Value root;
|
||||||
|
result_body >> root;
|
||||||
|
|
||||||
|
std::stringstream push_body;
|
||||||
|
double all_cost = 0;
|
||||||
|
push_body << fmt::format
|
||||||
|
(
|
||||||
|
"{} {} {}店\n", comment, order.second.second.substr(order.second.second.find('-') + 1),
|
||||||
|
order.second.first.substr(1, 2)
|
||||||
|
);
|
||||||
|
for (unsigned i = 0; i < root["dt"][6].size(); i++)
|
||||||
|
{
|
||||||
|
push_body << fmt::format
|
||||||
|
(
|
||||||
|
"{} {}{}\n", root["dt"][6][i].asString().substr(root["dt"][6][i].asString().length() - 4),
|
||||||
|
root["dt"][7][i].asString(), root["dt"][5][i].asString()
|
||||||
|
);
|
||||||
|
// 订货金额 maybe empty ???
|
||||||
|
if (root["dt"][10][i].asString() != "")
|
||||||
|
all_cost += std::stod(root["dt"][10][i].asString());
|
||||||
|
}
|
||||||
|
push_body << fmt::format("共{:.2f}元\n", all_cost);
|
||||||
|
log << fmt::format("push to wx {}\n", push_body.str());
|
||||||
|
auto encoded = urlencode(push_body.str());
|
||||||
|
|
||||||
|
for (const auto& wxu : wxuser)
|
||||||
|
{
|
||||||
|
auto path = fmt::format
|
||||||
|
("/api/send/message/?appToken={}&content={}&uid={}", token, encoded, wxu);
|
||||||
|
auto wxresult = wxclient.Get(path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save data
|
||||||
|
{
|
||||||
|
for (const auto& order : order_list)
|
||||||
|
if (!order_old.contains(order.first))
|
||||||
|
order_old.insert(order.first);
|
||||||
|
std::ofstream os("orders.json");
|
||||||
|
cereal::JSONOutputArchive oa(os);
|
||||||
|
cereal::save(oa, order_old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
log << ex.what() << "\n" << std::flush;
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
Json::Value configs;
|
||||||
|
std::ifstream("@config_file@") >> configs;
|
||||||
|
auto config_uids = configs["uids"];
|
||||||
|
std::set<std::string> uids;
|
||||||
|
for (auto& uid : config_uids)
|
||||||
|
uids.insert(uid.asString());
|
||||||
|
for (auto& config : configs["config"])
|
||||||
|
oneshot
|
||||||
|
(
|
||||||
|
config["username"].asString(), config["password"].asString(), config["comment"].asString(),
|
||||||
|
uids, { configs["manager"].asString() }, configs["token"].asString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
54
modules/services/gitea.nix
Normal file
54
modules/services/gitea.nix
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.gitea = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.str; default = "git.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) gitea;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf gitea.enable
|
||||||
|
{
|
||||||
|
services.gitea =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
lfs.enable = true;
|
||||||
|
mailerPasswordFile = inputs.config.sops.secrets."gitea/mail".path;
|
||||||
|
database =
|
||||||
|
{ createDatabase = false; type = "postgres"; passwordFile = inputs.config.sops.secrets."gitea/db".path; };
|
||||||
|
settings =
|
||||||
|
{
|
||||||
|
session.COOKIE_SECURE = true;
|
||||||
|
server =
|
||||||
|
{
|
||||||
|
ROOT_URL = "https://${gitea.hostname}";
|
||||||
|
DOMAIN = gitea.hostname;
|
||||||
|
HTTP_PORT = 3002;
|
||||||
|
SSH_DOMAIN = "ssh.${gitea.hostname}";
|
||||||
|
};
|
||||||
|
mailer =
|
||||||
|
{
|
||||||
|
ENABLED = true;
|
||||||
|
FROM = "bot@chn.moe";
|
||||||
|
PROTOCOL = "smtps";
|
||||||
|
SMTP_ADDR = "mail.chn.moe";
|
||||||
|
SMTP_PORT = 465;
|
||||||
|
USER = "bot@chn.moe";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
nginx = { enable = true; https."${gitea.hostname}".location."/".proxy.upstream = "http://127.0.0.1:3002"; };
|
||||||
|
postgresql.instances.gitea = {};
|
||||||
|
};
|
||||||
|
sops.secrets =
|
||||||
|
{
|
||||||
|
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
|
||||||
|
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
|
||||||
|
"mail/bot" = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
67
modules/services/grafana.nix
Normal file
67
modules/services/grafana.nix
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.grafana = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.str; default = "grafana.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) grafana;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf grafana.enable
|
||||||
|
{
|
||||||
|
services.grafana =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
declarativePlugins = with inputs.pkgs.grafanaPlugins; [];
|
||||||
|
settings =
|
||||||
|
{
|
||||||
|
users = { verify_email_enabled = true; default_language = "zh-CN"; allow_sign_up = true; };
|
||||||
|
smtp =
|
||||||
|
{
|
||||||
|
enabled = true;
|
||||||
|
host = "mail.chn.moe";
|
||||||
|
user = "bot@chn.moe";
|
||||||
|
password = "$__file{${inputs.config.sops.secrets."grafana/mail".path}}";
|
||||||
|
from_address = "bot@chn.moe";
|
||||||
|
ehlo_identity = grafana.hostname;
|
||||||
|
startTLS_policy = "MandatoryStartTLS";
|
||||||
|
};
|
||||||
|
server = { root_url = "https://${grafana.hostname}"; http_port = 3001; enable_gzip = true; };
|
||||||
|
security =
|
||||||
|
{
|
||||||
|
secret_key = "$__file{${inputs.config.sops.secrets."grafana/secret".path}}";
|
||||||
|
admin_user = "chn";
|
||||||
|
admin_password = "$__file{${inputs.config.sops.secrets."grafana/chn".path}}";
|
||||||
|
admin_email = "chn@chn.moe";
|
||||||
|
};
|
||||||
|
database =
|
||||||
|
{
|
||||||
|
type = "postgres";
|
||||||
|
host = "127.0.0.1:5432";
|
||||||
|
user = "grafana";
|
||||||
|
password = "$__file{${inputs.config.sops.secrets."grafana/db".path}}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
nginx =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
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" = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -9,28 +9,37 @@ inputs:
|
|||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
inherit (inputs.lib) mkIf;
|
inherit (inputs.lib) mkIf;
|
||||||
inherit (builtins) listToAttrs map concatLists;
|
inherit (builtins) listToAttrs map concatLists concatStringsSep;
|
||||||
inherit (inputs.config.nixos.services) groupshare;
|
inherit (inputs.config.nixos.services) groupshare;
|
||||||
users = inputs.config.users.groups.groupshare.members;
|
users = inputs.config.users.groups.groupshare.members;
|
||||||
in mkIf groupshare.enable
|
in mkIf groupshare.enable
|
||||||
{
|
{
|
||||||
users.groups.groupshare = {};
|
users.groups.groupshare.gid = inputs.config.nixos.system.user.group.groupshare;
|
||||||
systemd.tmpfiles.rules = [ "d /var/lib/groupshare" ]
|
systemd.tmpfiles.rules = [ "d /var/lib/groupshare" ]
|
||||||
++ (concatLists (map
|
++ (concatLists (map
|
||||||
(user:
|
(user:
|
||||||
[
|
[
|
||||||
"d /var/lib/groupshare/${user} 2750 ${user} groupshare"
|
"d /var/lib/groupshare/${user} 2750 ${user} groupshare"
|
||||||
# systemd 253 does not support 'X' bit, it should be manually set
|
"Z /var/lib/groupshare/${user} - ${user} groupshare"
|
||||||
# sudo setfacl -m 'xxx' dir
|
("A /var/lib/groupshare/${user} - - - - "
|
||||||
# ("a /var/lib/groupshare/${user} - - - - "
|
# d 指 default, 即目录下新创建的文件和目录的权限
|
||||||
# + "d:u:${user}:rwX,u:${user}:rwX,d:g:groupshare:r-X,g:groupshare:r-X,d:o::---,o::---,d:m::r-x,m::r-x")
|
# 大写 X 指仅给目录执行权限
|
||||||
|
# m 指 mask, 即对于所有者以外的用户, 该用户的权限最大为 m 指定的权限
|
||||||
|
+ (concatStringsSep "," (concatLists (map
|
||||||
|
(perm: [ "d:${perm}" perm ])
|
||||||
|
[ "u:${user}:rwX" "g:groupshare:r-X" "o::---" "m::r-x" ]))))
|
||||||
])
|
])
|
||||||
users));
|
users));
|
||||||
fileSystems = listToAttrs (map
|
fileSystems = listToAttrs (map
|
||||||
(mountPoint:
|
(mountPoint:
|
||||||
{
|
{
|
||||||
name = mountPoint;
|
name = mountPoint;
|
||||||
value = { device = "/var/lib/groupshare"; options = [ "bind" ]; depends = [ "/home" "/var/lib" ]; };
|
value =
|
||||||
|
{
|
||||||
|
device = "/var/lib/groupshare";
|
||||||
|
options = [ "bind" "private" "x-gvfs-hide" "X-fstrim.notrim" ];
|
||||||
|
depends = [ "/home" "/var/lib" ];
|
||||||
|
};
|
||||||
})
|
})
|
||||||
groupshare.mountPoints);
|
groupshare.mountPoints);
|
||||||
};
|
};
|
||||||
|
|||||||
45
modules/services/httpapi.nix
Normal file
45
modules/services/httpapi.nix
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.httpapi = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; default = "api.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) httpapi;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (builtins) toString map;
|
||||||
|
in mkIf httpapi.enable
|
||||||
|
{
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
phpfpm.instances.httpapi = {};
|
||||||
|
nginx.https.${httpapi.hostname}.location =
|
||||||
|
{
|
||||||
|
"/files".static.root = "/srv/api";
|
||||||
|
"/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; };
|
||||||
|
"/notify.php".php =
|
||||||
|
{
|
||||||
|
root = builtins.dirOf inputs.config.sops.templates."httpapi/notify.php".path;
|
||||||
|
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpapi.fastcgi;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
sops =
|
||||||
|
{
|
||||||
|
templates."httpapi/notify.php" =
|
||||||
|
{
|
||||||
|
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/${placeholder."httpapi/token"}/sendMessage?chat_id=861886506&text=";
|
||||||
|
in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>'';
|
||||||
|
};
|
||||||
|
secrets."httpapi/token" = {};
|
||||||
|
};
|
||||||
|
systemd.tmpfiles.rules = [ "d /srv/api 0700 nginx nginx" "Z /srv/api - nginx nginx" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
25
modules/services/httpua/default.nix
Normal file
25
modules/services/httpua/default.nix
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.httpua = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; default = "ua.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) httpua;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (builtins) toString;
|
||||||
|
in mkIf httpua.enable
|
||||||
|
{
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
phpfpm.instances.httpua = {};
|
||||||
|
nginx.http.${httpua.hostname}.php =
|
||||||
|
{
|
||||||
|
root = toString ./.;
|
||||||
|
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpua.fastcgi;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
1
modules/services/httpua/index.php
Normal file
1
modules/services/httpua/index.php
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?php echo $_SERVER['HTTP_USER_AGENT']; ?>
|
||||||
@@ -3,56 +3,64 @@ inputs:
|
|||||||
options.nixos.services.huginn = let inherit (inputs.lib) mkOption types; in
|
options.nixos.services.huginn = let inherit (inputs.lib) mkOption types; in
|
||||||
{
|
{
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; default = "huginn.chn.moe"; };
|
||||||
};
|
};
|
||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
inherit (inputs.lib) mkIf;
|
inherit (inputs.lib) mkIf;
|
||||||
inherit (inputs.config.nixos.services) huginn;
|
inherit (inputs.config.nixos.services) huginn;
|
||||||
inherit (builtins) listToAttrs;
|
|
||||||
in mkIf huginn.enable
|
in mkIf huginn.enable
|
||||||
{
|
{
|
||||||
nixos.services =
|
virtualisation.oci-containers.containers.huginn =
|
||||||
{
|
{
|
||||||
docker.huginn =
|
image = "huginn/huginn:2d5fcafc507da3e8c115c3479e9116a0758c5375";
|
||||||
|
imageFile = inputs.pkgs.dockerTools.pullImage
|
||||||
{
|
{
|
||||||
image = inputs.pkgs.dockerTools.pullImage
|
imageName = "ghcr.io/huginn/huginn";
|
||||||
{
|
imageDigest = "sha256:aa694519b196485c6c31582dde007859fc8b8bbe9b1d4d94c6db8558843d0458";
|
||||||
imageName = "huginn/huginn";
|
sha256 = "0471v20d7ilwx81kyrxjcb90nnmqyyi9mwazbpy3z4rhnzv7pz76";
|
||||||
imageDigest = "sha256:dbe871597d43232add81d1adfc5ad9f5cf9dcb5e1f1ba3d669598c20b96ab6c1";
|
finalImageName = "huginn/huginn";
|
||||||
sha256 = "sha256-P8bfzjW5gHCVv0kaEAi9xAe5c0aQXypJkYUfFtE8SVM=";
|
finalImageTag = "2d5fcafc507da3e8c115c3479e9116a0758c5375";
|
||||||
finalImageName = "huginn/huginn";
|
|
||||||
finalImageTag = "2d5fcafc507da3e8c115c3479e9116a0758c5375";
|
|
||||||
};
|
|
||||||
ports = [ 3000 ];
|
|
||||||
environmentFile = true;
|
|
||||||
};
|
};
|
||||||
postgresql = { enable = true; instances.huginn = {}; };
|
ports = [ "127.0.0.1:3000:3000/tcp" ];
|
||||||
|
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
|
||||||
|
environmentFiles = [ inputs.config.sops.templates."huginn/env".path ];
|
||||||
};
|
};
|
||||||
sops =
|
sops =
|
||||||
{
|
{
|
||||||
templates."huginn.env" =
|
templates."huginn/env".content = let placeholder = inputs.config.sops.placeholder; in
|
||||||
|
''
|
||||||
|
MYSQL_PORT_3306_TCP_ADDR=host.docker.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" = {}; };
|
||||||
|
};
|
||||||
|
nixos =
|
||||||
|
{
|
||||||
|
services =
|
||||||
{
|
{
|
||||||
content = let placeholder = inputs.config.sops.placeholder; in
|
nginx =
|
||||||
''
|
{
|
||||||
MYSQL_PORT_3306_TCP_ADDR=host.docker.internal
|
enable = true;
|
||||||
HUGINN_DATABASE_NAME=huginn
|
https."${huginn.hostname}".location."/".proxy = { upstream = "http://127.0.0.1:3000"; websocket = true; };
|
||||||
HUGINN_DATABASE_USERNAME=huginn
|
};
|
||||||
HUGINN_DATABASE_PASSWORD=${placeholder."postgresql/huginn"}
|
mariadb.instances.huginn = {};
|
||||||
DOMAIN=huginn.chn.moe
|
|
||||||
RAILS_ENV=production
|
|
||||||
FORCE_SSL=true
|
|
||||||
INVITATION_CODE=${placeholder."huginn/invitation_code"}
|
|
||||||
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
|
|
||||||
'';
|
|
||||||
owner = inputs.config.users.users.huginn.name;
|
|
||||||
};
|
};
|
||||||
secrets = listToAttrs (map (secret: { name = secret; value = {}; }) [ "huginn/invitation_code" "mail/bot" ]);
|
virtualization.docker.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
19
modules/services/kmscon.nix
Normal file
19
modules/services/kmscon.nix
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.kmscon = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (inputs.config.nixos.services) kmscon;
|
||||||
|
in mkIf kmscon.enable
|
||||||
|
{
|
||||||
|
services.kmscon =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
fonts = [{ name = "FiraCode Nerd Font Mono"; package = inputs.pkgs.nerdfonts; }];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
59
modules/services/mariadb.nix
Normal file
59
modules/services/mariadb.nix
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.mariadb = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
instances = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
||||||
|
{
|
||||||
|
database = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
|
||||||
|
user = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
|
||||||
|
passwordFile = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
|
};}));
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) mariadb;
|
||||||
|
inherit (inputs.lib) mkAfter mkIf;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
inherit (builtins) map listToAttrs concatStringsSep filter;
|
||||||
|
in mkIf mariadb.enable
|
||||||
|
{
|
||||||
|
services =
|
||||||
|
{
|
||||||
|
mysql =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
package = inputs.pkgs.mariadb;
|
||||||
|
settings.mysqld.skip_name_resolve = true;
|
||||||
|
ensureDatabases = map (db: db.value.database) (attrsToList mariadb.instances);
|
||||||
|
ensureUsers = map
|
||||||
|
(db: { name = db.value.user; ensurePermissions."${db.value.database}.*" = "ALL PRIVILEGES"; })
|
||||||
|
(attrsToList mariadb.instances);
|
||||||
|
};
|
||||||
|
mysqlBackup =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
singleTransaction = true;
|
||||||
|
databases = map (db: db.value.database) (attrsToList mariadb.instances);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.mysql.postStart = mkAfter (concatStringsSep "\n" (map
|
||||||
|
(db:
|
||||||
|
let
|
||||||
|
passwordFile =
|
||||||
|
if db.value.passwordFile or null != null then db.value.passwordFile
|
||||||
|
else inputs.config.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'')
|
||||||
|
(attrsToList mariadb.instances)));
|
||||||
|
sops.secrets = listToAttrs (map
|
||||||
|
(db: { name = "mariadb/${db.value.user}"; value.owner = inputs.config.users.users.mysql.name; })
|
||||||
|
(filter (db: db.value.passwordFile == null) (attrsToList mariadb.instances)));
|
||||||
|
};
|
||||||
|
}
|
||||||
83
modules/services/mastodon.nix
Normal file
83
modules/services/mastodon.nix
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.mastodon = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.str; default = "dudu.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) mastodon;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (builtins) toString;
|
||||||
|
in mkIf mastodon.enable
|
||||||
|
{
|
||||||
|
services.mastodon =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
streamingProcesses = 1;
|
||||||
|
enableUnixSocket = false;
|
||||||
|
localDomain = mastodon.hostname;
|
||||||
|
database =
|
||||||
|
{
|
||||||
|
createLocally = false;
|
||||||
|
host = "127.0.0.1";
|
||||||
|
passwordFile = inputs.config.sops.secrets."mastodon/postgresql".path;
|
||||||
|
};
|
||||||
|
redis.createLocally = false;
|
||||||
|
smtp =
|
||||||
|
{
|
||||||
|
createLocally = false;
|
||||||
|
user = "bot@chn.moe";
|
||||||
|
port = 465;
|
||||||
|
passwordFile = inputs.config.sops.secrets."mastodon/mail".path;
|
||||||
|
host = "mail.chn.moe";
|
||||||
|
fromAddress = "bot@chn.moe";
|
||||||
|
authenticate = true;
|
||||||
|
};
|
||||||
|
extraEnvFiles = [ inputs.config.sops.templates."mastodon/env".path ];
|
||||||
|
};
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
postgresql = { enable = true; instances.mastodon = {}; };
|
||||||
|
redis.instances.mastodon.port = inputs.config.services.mastodon.redis.port;
|
||||||
|
nginx =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
https."${mastodon.hostname}".location =
|
||||||
|
{
|
||||||
|
"/system/".alias.path = "/var/lib/mastodon/public-system/";
|
||||||
|
"/".static =
|
||||||
|
{ root = "${inputs.config.services.mastodon.package}/public"; tryFiles = [ "$uri" "@proxy" ]; };
|
||||||
|
"@proxy".proxy =
|
||||||
|
{ upstream = "http://127.0.0.1:${toString inputs.config.services.mastodon.webPort}"; websocket = true; };
|
||||||
|
"/api/v1/streaming/".proxy =
|
||||||
|
{
|
||||||
|
upstream = "http://unix:/run/mastodon-streaming/streaming-1.socket";
|
||||||
|
websocket = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
sops =
|
||||||
|
{
|
||||||
|
secrets =
|
||||||
|
{
|
||||||
|
"mastodon/mail" = { owner = "mastodon"; key = "mail/bot"; };
|
||||||
|
"mastodon/postgresql" = { owner = "mastodon"; key = "postgresql/mastodon"; };
|
||||||
|
};
|
||||||
|
templates."mastodon/env" =
|
||||||
|
{
|
||||||
|
owner = "mastodon";
|
||||||
|
content =
|
||||||
|
''
|
||||||
|
REDIS_PASSWORD=${inputs.config.sops.placeholder."redis/mastodon"}
|
||||||
|
SMTP_SSL=true
|
||||||
|
SMTP_AUTH_METHOD=plain
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
environment.systemPackages = [ inputs.config.services.mastodon.package ];
|
||||||
|
# sudo -u mastodon mastodon-tootctl accounts modify chn --role Owner
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -11,12 +11,13 @@ inputs:
|
|||||||
};}));
|
};}));
|
||||||
default = {};
|
default = {};
|
||||||
};
|
};
|
||||||
|
ioLimitDevice = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
};
|
};
|
||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
inherit (inputs.config.nixos.services) meilisearch;
|
inherit (inputs.config.nixos.services) meilisearch;
|
||||||
inherit (inputs.localLib) stripeTabs attrsToList;
|
inherit (inputs.localLib) stripeTabs attrsToList;
|
||||||
inherit (builtins) map listToAttrs;
|
inherit (builtins) map listToAttrs concatLists;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
systemd =
|
systemd =
|
||||||
@@ -37,7 +38,7 @@ inputs:
|
|||||||
Group = inputs.config.users.users.${instance.value.user}.group;
|
Group = inputs.config.users.users.${instance.value.user}.group;
|
||||||
ExecStart =
|
ExecStart =
|
||||||
let
|
let
|
||||||
meilisearch = inputs.pkgs.unstablePackages.meilisearch.overrideAttrs (prev:
|
meilisearch = inputs.pkgs.meilisearch.overrideAttrs (prev:
|
||||||
{
|
{
|
||||||
RUSTFLAGS = prev.RUSTFLAGS or [] ++ [ "-Clto=true" "-Cpanic=abort" "-Cembed-bitcode=yes"]
|
RUSTFLAGS = prev.RUSTFLAGS or [] ++ [ "-Clto=true" "-Cpanic=abort" "-Cembed-bitcode=yes"]
|
||||||
++ (
|
++ (
|
||||||
@@ -60,18 +61,27 @@ inputs:
|
|||||||
IOWeight = 1;
|
IOWeight = 1;
|
||||||
Nice = 19;
|
Nice = 19;
|
||||||
Slice = "-.slice";
|
Slice = "-.slice";
|
||||||
};
|
}
|
||||||
|
// (if meilisearch.ioLimitDevice != null then
|
||||||
|
{
|
||||||
|
IOReadBandwidthMax = "${meilisearch.ioLimitDevice} 20M";
|
||||||
|
IOWriteBandwidthMax = "${meilisearch.ioLimitDevice} 20M";
|
||||||
|
# iostat -dx 1
|
||||||
|
IOReadIOPSMax = "${meilisearch.ioLimitDevice} 100";
|
||||||
|
IOWriteIOPSMax = "${meilisearch.ioLimitDevice} 100";
|
||||||
|
} else {});
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
(attrsToList meilisearch.instances));
|
(attrsToList meilisearch.instances));
|
||||||
tmpfiles.rules = map
|
tmpfiles.rules = concatLists (map
|
||||||
(instance:
|
(instance:
|
||||||
let
|
let
|
||||||
user = instance.value.user;
|
user = instance.value.user;
|
||||||
group = inputs.config.users.users.${instance.value.user}.group;
|
group = inputs.config.users.users.${instance.value.user}.group;
|
||||||
|
dir = "/var/lib/meilisearch/${instance.name}";
|
||||||
in
|
in
|
||||||
"d /var/lib/meilisearch/${instance.name} 0700 ${user} ${group}")
|
[ "d ${dir} 0700 ${user} ${group}" "Z ${dir} - ${user} ${group}" ])
|
||||||
(attrsToList meilisearch.instances);
|
(attrsToList meilisearch.instances));
|
||||||
};
|
};
|
||||||
sops =
|
sops =
|
||||||
{
|
{
|
||||||
@@ -89,10 +99,10 @@ inputs:
|
|||||||
env = "production"
|
env = "production"
|
||||||
dump_dir = "/var/lib/meilisearch/${instance.name}/dumps"
|
dump_dir = "/var/lib/meilisearch/${instance.name}/dumps"
|
||||||
log_level = "INFO"
|
log_level = "INFO"
|
||||||
max_indexing_memory = "8Gb"
|
max_indexing_memory = "16Gb"
|
||||||
max_indexing_threads = 1
|
max_indexing_threads = 1
|
||||||
'';
|
'';
|
||||||
owner = inputs.config.users.users.misskey.name;
|
owner = instance.value.user;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
(attrsToList meilisearch.instances));
|
(attrsToList meilisearch.instances));
|
||||||
|
|||||||
73
modules/services/mirism.nix
Normal file
73
modules/services/mirism.nix
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.mirism = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) mirism;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
inherit (builtins) map listToAttrs toString concatLists;
|
||||||
|
in mkIf mirism.enable
|
||||||
|
{
|
||||||
|
users =
|
||||||
|
{
|
||||||
|
users.mirism = { uid = inputs.config.nixos.system.user.user.mirism; group = "mirism"; isSystemUser = true; };
|
||||||
|
groups.mirism.gid = inputs.config.nixos.system.user.group.mirism;
|
||||||
|
};
|
||||||
|
systemd =
|
||||||
|
{
|
||||||
|
services = listToAttrs (map
|
||||||
|
(instance:
|
||||||
|
{
|
||||||
|
name = "mirism-${instance}";
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
description = "mirism ${instance}";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig =
|
||||||
|
{
|
||||||
|
User = inputs.config.users.users.mirism.name;
|
||||||
|
Group = inputs.config.users.users.mirism.group;
|
||||||
|
ExecStart = "${inputs.pkgs.localPackages.mirism}/bin/${instance}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
[ "ng01" "beta" ]);
|
||||||
|
tmpfiles.rules = concatLists (map
|
||||||
|
(dir: [ "d /srv/${dir}mirism 0700 nginx nginx" "Z /srv/${dir}mirism - nginx nginx" ])
|
||||||
|
[ "" "entry." ]);
|
||||||
|
};
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
nginx =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
transparentProxy.map = { "ng01.mirism.one" = 7411; "beta.mirism.one" = 9114; };
|
||||||
|
https = listToAttrs (map
|
||||||
|
(instance:
|
||||||
|
{
|
||||||
|
name = "${instance}mirism.one";
|
||||||
|
value.location."/".static = { root = "/srv/${instance}mirism"; index = [ "index.html" ]; };
|
||||||
|
})
|
||||||
|
[ "entry." "" ]);
|
||||||
|
};
|
||||||
|
acme = { enable = true; cert = { "ng01.mirism.one".group = "mirism"; "beta.mirism.one".group = "mirism"; }; };
|
||||||
|
};
|
||||||
|
environment.etc = listToAttrs (concatLists (map
|
||||||
|
(instance:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name = "letsencrypt/live/${instance}.mirism.one/fullchain.pem";
|
||||||
|
value.source = "${inputs.config.security.acme.certs."${instance}.mirism.one".directory}/fullchain.pem";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "letsencrypt/live/${instance}.mirism.one/privkey.pem";
|
||||||
|
value.source = "${inputs.config.security.acme.certs."${instance}.mirism.one".directory}/key.pem";
|
||||||
|
}
|
||||||
|
])
|
||||||
|
[ "ng01" "beta" ]));
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,157 +1,173 @@
|
|||||||
inputs:
|
inputs:
|
||||||
{
|
{
|
||||||
options.nixos.services = let inherit (inputs.lib) mkOption types; in
|
options.nixos.services.misskey.instances = let inherit (inputs.lib) mkOption types; in mkOption
|
||||||
{
|
{
|
||||||
misskey =
|
type = types.attrsOf (types.submodule { options =
|
||||||
{
|
{
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
|
||||||
autoStart = mkOption { type = types.bool; default = true; };
|
autoStart = mkOption { type = types.bool; default = true; };
|
||||||
port = mkOption { type = types.ints.unsigned; default = 9726; };
|
port = mkOption { type = types.ints.unsigned; default = 9726; };
|
||||||
hostname = mkOption { type = types.str; default = "misskey.chn.moe"; };
|
redis.port = mkOption { type = types.ints.unsigned; default = 3545; };
|
||||||
};
|
hostname = mkOption { type = types.nonEmptyStr; default = "misskey.chn.moe"; };
|
||||||
misskey-proxy = mkOption
|
meilisearch =
|
||||||
{
|
|
||||||
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
|
||||||
{
|
{
|
||||||
hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
|
enable = mkOption { type = types.bool; default = true; };
|
||||||
upstream = mkOption
|
port = mkOption { type = types.ints.unsigned; default = 7700; };
|
||||||
{
|
};
|
||||||
type = types.oneOf [ types.nonEmptyStr (types.submodule { options =
|
};});
|
||||||
{
|
default = {};
|
||||||
address = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
|
|
||||||
port = mkOption { type = types.ints.unsigned; default = 9726; };
|
|
||||||
};})];
|
|
||||||
default = "127.0.0.1:9726";
|
|
||||||
};
|
|
||||||
};}));
|
|
||||||
default = {};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
config =
|
config =
|
||||||
let
|
let
|
||||||
inherit (inputs.config.nixos.services) misskey misskey-proxy;
|
inherit (inputs.config.nixos.services) misskey;
|
||||||
inherit (inputs.localLib) stripeTabs attrsToList;
|
inherit (inputs.localLib) attrsToList;
|
||||||
inherit (inputs.lib) mkIf mkMerge;
|
inherit (inputs.lib) mkMerge mkIf;
|
||||||
inherit (builtins) map listToAttrs toString replaceStrings;
|
inherit (builtins) map listToAttrs toString replaceStrings filter;
|
||||||
in mkMerge
|
in
|
||||||
[
|
{
|
||||||
(mkIf misskey.enable
|
systemd = mkMerge (map
|
||||||
{
|
(instance:
|
||||||
systemd =
|
|
||||||
{
|
{
|
||||||
services.misskey =
|
services."misskey-${instance.name}" = rec
|
||||||
{
|
{
|
||||||
description = "misskey";
|
enable = instance.value.autoStart;
|
||||||
after = [ "network.target" "redis-misskey.service" "postgresql.service" "meilisearch-misskey.service" ];
|
description = "misskey ${instance.name}";
|
||||||
requires = [ "network.target" "redis-misskey.service" "postgresql.service" "meilisearch-misskey.service" ];
|
after = [ "network.target" "redis-misskey-${instance.name}.service" "postgresql.service" ]
|
||||||
|
++ (if instance.value.meilisearch.enable then [ "meilisearch-misskey-${instance.name}.service" ]
|
||||||
|
else []);
|
||||||
|
requires = after;
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
environment.MISSKEY_CONFIG_YML = inputs.config.sops.templates."misskey/default.yml".path;
|
environment.MISSKEY_CONFIG_YML = inputs.config.sops.templates."misskey/${instance.name}.yml".path;
|
||||||
serviceConfig = rec
|
serviceConfig = rec
|
||||||
{
|
{
|
||||||
User = inputs.config.users.users.misskey.name;
|
User = inputs.config.users.users."misskey-${instance.name}".name;
|
||||||
Group = inputs.config.users.users.misskey.group;
|
Group = inputs.config.users.users."misskey-${instance.name}".group;
|
||||||
WorkingDirectory = "/var/lib/misskey/work";
|
WorkingDirectory = "/var/lib/misskey/${instance.name}/work";
|
||||||
ExecStart = "${WorkingDirectory}/bin/misskey";
|
ExecStart = "${WorkingDirectory}/bin/misskey";
|
||||||
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
|
||||||
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RuntimeMaxSec = "1d";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
tmpfiles.rules = [ "d /var/lib/misskey/files 0700 misskey misskey" ];
|
tmpfiles.rules = let dir = "/var/lib/misskey/${instance.name}/files"; owner = "misskey-${instance.name}"; in
|
||||||
};
|
[ "d ${dir} 0700 ${owner} ${owner}" "Z ${dir} - ${owner} ${owner}" ];
|
||||||
fileSystems =
|
})
|
||||||
|
(attrsToList misskey.instances));
|
||||||
|
fileSystems = mkMerge (map
|
||||||
|
(instance:
|
||||||
{
|
{
|
||||||
"/var/lib/misskey/work" =
|
"/var/lib/misskey/${instance.name}/work" =
|
||||||
{
|
{
|
||||||
device = "${inputs.pkgs.localPackages.misskey}";
|
device = "${inputs.pkgs.localPackages.misskey}";
|
||||||
options = [ "bind" "private" "x-gvfs-hide" ];
|
options = [ "bind" "private" "x-gvfs-hide" "X-fstrim.notrim" ];
|
||||||
};
|
};
|
||||||
"/var/lib/misskey/work/files" =
|
"/var/lib/misskey/${instance.name}/work/files" =
|
||||||
{
|
{
|
||||||
device = "/var/lib/misskey/files";
|
device = "/var/lib/misskey/${instance.name}/files";
|
||||||
options = [ "bind" "private" "x-gvfs-hide" ];
|
options = [ "bind" "private" "x-gvfs-hide" "X-fstrim.notrim" ];
|
||||||
};
|
};
|
||||||
};
|
})
|
||||||
sops.templates."misskey/default.yml" =
|
(attrsToList misskey.instances));
|
||||||
|
sops.templates = listToAttrs (map
|
||||||
|
(instance:
|
||||||
{
|
{
|
||||||
content =
|
name = "misskey/${instance.name}.yml";
|
||||||
let
|
value =
|
||||||
placeholder = inputs.config.sops.placeholder;
|
{
|
||||||
misskey = inputs.config.nixos.services.misskey;
|
content =
|
||||||
redis = inputs.config.nixos.services.redis.instances.misskey;
|
let
|
||||||
in
|
placeholder = inputs.config.sops.placeholder;
|
||||||
''
|
redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}";
|
||||||
url: https://${misskey.hostname}/
|
meilisearch = inputs.config.nixos.services.meilisearch.instances."misskey-${instance.name}";
|
||||||
port: ${toString misskey.port}
|
in
|
||||||
db:
|
''
|
||||||
host: 127.0.0.1
|
url: https://${instance.value.hostname}/
|
||||||
port: 5432
|
port: ${toString instance.value.port}
|
||||||
db: misskey
|
db:
|
||||||
user: misskey
|
host: 127.0.0.1
|
||||||
pass: ${placeholder."postgresql/misskey"}
|
port: 5432
|
||||||
extra:
|
db: misskey_${replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||||
statement_timeout: 60000
|
user: misskey_${replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||||
dbReplications: false
|
pass: ${placeholder."postgresql/misskey_${replaceStrings [ "-" ] [ "_" ] instance.name}"}
|
||||||
redis:
|
extra:
|
||||||
host: 127.0.0.1
|
statement_timeout: 60000
|
||||||
port: ${toString redis.port}
|
dbReplications: false
|
||||||
pass: ${placeholder."redis/misskey"}
|
redis:
|
||||||
meilisearch:
|
host: 127.0.0.1
|
||||||
host: 127.0.0.1
|
port: ${toString redis.port}
|
||||||
port: 7700
|
pass: ${placeholder."redis/misskey-${instance.name}"}
|
||||||
apiKey: ${placeholder."meilisearch/misskey"}
|
id: 'aid'
|
||||||
ssl: false
|
proxyBypassHosts:
|
||||||
index: misskey
|
- api.deepl.com
|
||||||
scope: global
|
- api-free.deepl.com
|
||||||
id: 'aid'
|
- www.recaptcha.net
|
||||||
proxyBypassHosts:
|
- hcaptcha.com
|
||||||
- api.deepl.com
|
- challenges.cloudflare.com
|
||||||
- api-free.deepl.com
|
proxyRemoteFiles: true
|
||||||
- www.recaptcha.net
|
signToActivityPubGet: true
|
||||||
- hcaptcha.com
|
maxFileSize: 1073741824
|
||||||
- challenges.cloudflare.com
|
''
|
||||||
proxyRemoteFiles: true
|
+ (if instance.value.meilisearch.enable then
|
||||||
signToActivityPubGet: true
|
''
|
||||||
maxFileSize: 1073741824
|
meilisearch:
|
||||||
'';
|
host: 127.0.0.1
|
||||||
owner = inputs.config.users.users.misskey.name;
|
port: ${toString meilisearch.port}
|
||||||
};
|
apiKey: ${placeholder."meilisearch/misskey-${instance.name}"}
|
||||||
users =
|
ssl: false
|
||||||
|
index: misskey
|
||||||
|
scope: globa
|
||||||
|
'' else "");
|
||||||
|
owner = inputs.config.users.users."misskey-${instance.name}".name;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(attrsToList misskey.instances));
|
||||||
|
users = mkMerge (map
|
||||||
|
(instance:
|
||||||
{
|
{
|
||||||
users.misskey = { isSystemUser = true; group = "misskey"; home = "/var/lib/misskey"; createHome = true; };
|
users."misskey-${instance.name}" =
|
||||||
groups.misskey = {};
|
{
|
||||||
};
|
uid = inputs.config.nixos.system.user.user."misskey-${instance.name}";
|
||||||
nixos.services =
|
group = "misskey-${instance.name}";
|
||||||
{
|
home = "/var/lib/misskey/${instance.name}";
|
||||||
redis.instances.misskey.port = 3545;
|
createHome = true;
|
||||||
postgresql = { enable = true; instances.misskey = {}; };
|
isSystemUser = true;
|
||||||
meilisearch.instances.misskey = { user = inputs.config.users.users.misskey.name; port = 7700; };
|
};
|
||||||
};
|
groups."misskey-${instance.name}".gid = inputs.config.nixos.system.user.group."misskey-${instance.name}";
|
||||||
})
|
})
|
||||||
(mkIf (misskey-proxy != {})
|
(attrsToList misskey.instances));
|
||||||
|
nixos.services =
|
||||||
{
|
{
|
||||||
nixos.services.nginx =
|
redis.instances = listToAttrs (map
|
||||||
|
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
|
||||||
|
(attrsToList misskey.instances));
|
||||||
|
postgresql =
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = mkIf (misskey.instances != {}) true;
|
||||||
httpProxy = listToAttrs (map
|
instances = listToAttrs (map
|
||||||
(proxy: with proxy.value;
|
(instance: { name = "misskey_${replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
|
||||||
|
(attrsToList misskey.instances));
|
||||||
|
};
|
||||||
|
meilisearch.instances = listToAttrs (map
|
||||||
|
(instance:
|
||||||
|
{
|
||||||
|
name = "misskey-${instance.name}";
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
user = inputs.config.users.users."misskey-${instance.name}".name;
|
||||||
|
port = instance.value.meilisearch.port;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(filter (instance: instance.value.meilisearch.enable) (attrsToList misskey.instances)));
|
||||||
|
nginx =
|
||||||
|
{
|
||||||
|
enable = mkIf (misskey.instances != {}) true;
|
||||||
|
https = listToAttrs (map
|
||||||
|
(instance: with instance.value;
|
||||||
{
|
{
|
||||||
name = hostname;
|
name = hostname;
|
||||||
value =
|
value.location."/".proxy = { upstream = "http://127.0.0.1:${toString port}"; websocket = true; };
|
||||||
{
|
|
||||||
rewriteHttps = true;
|
|
||||||
locations."/" =
|
|
||||||
{
|
|
||||||
upstream = if builtins.typeOf upstream == "string" then "http://${upstream}"
|
|
||||||
else "http://${upstream.address}:${toString upstream.port}";
|
|
||||||
websocket = true;
|
|
||||||
setHeaders.Host = hostname;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
})
|
})
|
||||||
(attrsToList misskey-proxy));
|
(attrsToList misskey.instances));
|
||||||
};
|
};
|
||||||
})
|
};
|
||||||
];
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
98
modules/services/nextcloud.nix
Normal file
98
modules/services/nextcloud.nix
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nextcloud = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; default = "nextcloud.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services) nextcloud;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
inherit (inputs.lib) mkIf mkMerge;
|
||||||
|
inherit (builtins) map listToAttrs toString replaceStrings filter toJSON;
|
||||||
|
in mkIf nextcloud.enable
|
||||||
|
{
|
||||||
|
services.nextcloud =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
hostName = nextcloud.hostname;
|
||||||
|
appstoreEnable = false;
|
||||||
|
https = true;
|
||||||
|
package = inputs.pkgs.nextcloud27;
|
||||||
|
maxUploadSize = "10G";
|
||||||
|
config =
|
||||||
|
{
|
||||||
|
dbtype = "pgsql";
|
||||||
|
dbpassFile = inputs.config.sops.secrets."nextcloud/postgresql".path;
|
||||||
|
dbport = 5432;
|
||||||
|
adminuser = "admin";
|
||||||
|
adminpassFile = inputs.config.sops.secrets."nextcloud/admin".path;
|
||||||
|
overwriteProtocol = "https";
|
||||||
|
defaultPhoneRegion = "CN";
|
||||||
|
};
|
||||||
|
configureRedis = true;
|
||||||
|
extraOptions =
|
||||||
|
{
|
||||||
|
mail_domain = "chn.moe";
|
||||||
|
mail_from_address = "bot";
|
||||||
|
mail_smtphost = "mail.chn.moe";
|
||||||
|
mail_smtpport = 465;
|
||||||
|
mail_smtpsecure = "ssl";
|
||||||
|
mail_smtpauth = true;
|
||||||
|
mail_smtpname = "bot@chn.moe";
|
||||||
|
updatechecker = false;
|
||||||
|
};
|
||||||
|
secretFile = inputs.config.sops.templates."nextcloud/secret".path;
|
||||||
|
extraApps =
|
||||||
|
let
|
||||||
|
githubRelease = repo: file: "https://github.com/${repo}/releases/download/${file}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# nix-prefetch-url --unpack
|
||||||
|
maps = inputs.pkgs.fetchNextcloudApp
|
||||||
|
{
|
||||||
|
url = githubRelease "nextcloud/maps" "v1.1.1/maps-1.1.1.tar.gz";
|
||||||
|
sha256 = "1rcmqnm5364h5gaq1yy6b6d7k17napgn0yc9ymrnn75bps9s71v9";
|
||||||
|
license = "agpl3";
|
||||||
|
};
|
||||||
|
phonetrack = inputs.pkgs.fetchNextcloudApp
|
||||||
|
{
|
||||||
|
url = githubRelease "julien-nc/phonetrack" "v0.7.6/phonetrack-0.7.6.tar.gz";
|
||||||
|
sha256 = "1p15vw7c5c1h08czyxi1r6svjd5hjmnc0i6is4vl3xq2kfjmcyyx";
|
||||||
|
license = "agpl3";
|
||||||
|
};
|
||||||
|
twofactor_webauthn = inputs.pkgs.fetchNextcloudApp
|
||||||
|
{
|
||||||
|
url = githubRelease "nextcloud-releases/twofactor_webauthn" "v1.3.0/twofactor_webauthn-v1.3.0.tar.gz";
|
||||||
|
sha256 = "0z6m2chq5kxc8f10g6n1lh51yi10svy2qp5gp0v8xs71apqcc2wx";
|
||||||
|
license = "agpl3";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
postgresql = { enable = true; instances.nextcloud = {}; };
|
||||||
|
redis.instances.nextcloud.port = 3499;
|
||||||
|
nginx = { enable = true; https.${nextcloud.hostname}.global.configName = nextcloud.hostname; };
|
||||||
|
};
|
||||||
|
sops =
|
||||||
|
{
|
||||||
|
templates."nextcloud/secret" =
|
||||||
|
{
|
||||||
|
content = toJSON
|
||||||
|
{
|
||||||
|
redis.password = inputs.config.sops.placeholder."redis/nextcloud";
|
||||||
|
mail_smtppassword = inputs.config.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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.nextcloud-setup = rec { requires = [ "postgresql.service" ]; after = requires; };
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,338 +0,0 @@
|
|||||||
inputs:
|
|
||||||
{
|
|
||||||
options.nixos.services.nginx = let inherit (inputs.lib) mkOption types; in
|
|
||||||
{
|
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
|
||||||
transparentProxy =
|
|
||||||
{
|
|
||||||
enable = mkOption { type = types.bool; default = true; };
|
|
||||||
externalIp = mkOption { type = types.nonEmptyStr; };
|
|
||||||
map = mkOption { type = types.attrsOf types.ints.unsigned; default = {};};
|
|
||||||
};
|
|
||||||
httpProxy = mkOption
|
|
||||||
{
|
|
||||||
type = types.attrsOf (types.submodule { options =
|
|
||||||
{
|
|
||||||
rewriteHttps = mkOption { type = types.bool; default = false; };
|
|
||||||
http2 = mkOption { type = types.bool; default = true; };
|
|
||||||
addAuth = mkOption { type = types.bool; default = false; };
|
|
||||||
detectAuth = mkOption { type = types.bool; default = false; };
|
|
||||||
locations = mkOption
|
|
||||||
{
|
|
||||||
type = types.attrsOf (types.submodule { options =
|
|
||||||
{
|
|
||||||
upstream = mkOption { type = types.nonEmptyStr; };
|
|
||||||
websocket = mkOption { type = types.bool; default = false; };
|
|
||||||
setHeaders = mkOption { type = types.attrsOf types.str; default = {}; };
|
|
||||||
};});
|
|
||||||
};
|
|
||||||
};});
|
|
||||||
default = {};
|
|
||||||
};
|
|
||||||
streamProxy =
|
|
||||||
{
|
|
||||||
enable = mkOption { type = types.bool; default = false; };
|
|
||||||
port = mkOption { type = types.ints.unsigned; default = 5575; };
|
|
||||||
map = mkOption
|
|
||||||
{
|
|
||||||
type = types.attrsOf (types.oneOf
|
|
||||||
[
|
|
||||||
types.nonEmptyStr
|
|
||||||
(types.submodule { options =
|
|
||||||
{
|
|
||||||
upstream = mkOption { type = types.nonEmptyStr; };
|
|
||||||
rewriteHttps = mkOption { type = types.bool; default = false; };
|
|
||||||
};})
|
|
||||||
]);
|
|
||||||
default = {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config =
|
|
||||||
let
|
|
||||||
inherit (inputs.lib) mkMerge mkIf;
|
|
||||||
inherit (inputs.localLib) stripeTabs attrsToList;
|
|
||||||
inherit (inputs.config.nixos.services) nginx;
|
|
||||||
inherit (builtins) map listToAttrs concatStringsSep toString filter attrValues;
|
|
||||||
in mkMerge
|
|
||||||
[
|
|
||||||
(mkIf nginx.enable
|
|
||||||
{
|
|
||||||
services =
|
|
||||||
{
|
|
||||||
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 10m;
|
|
||||||
'';
|
|
||||||
proxyTimeout = "10m";
|
|
||||||
virtualHosts = listToAttrs (map
|
|
||||||
(site:
|
|
||||||
{
|
|
||||||
inherit (site) name;
|
|
||||||
value =
|
|
||||||
{
|
|
||||||
serverName = site.name;
|
|
||||||
listen = [ { addr = "127.0.0.1"; port = (if site.value.http2 then 443 else 3065); ssl = true; } ]
|
|
||||||
++ (if site.value.rewriteHttps then [ { addr = "0.0.0.0"; port = 80; } ] else []);
|
|
||||||
useACMEHost = site.name;
|
|
||||||
locations = listToAttrs (map
|
|
||||||
(location:
|
|
||||||
{
|
|
||||||
inherit (location) name;
|
|
||||||
value =
|
|
||||||
{
|
|
||||||
proxyPass = location.value.upstream;
|
|
||||||
proxyWebsockets = location.value.websocket;
|
|
||||||
recommendedProxySettings = false;
|
|
||||||
recommendedProxySettingsNoHost = true;
|
|
||||||
extraConfig = concatStringsSep "\n"
|
|
||||||
(
|
|
||||||
(map
|
|
||||||
(header: ''proxy_set_header ${header.name} "${header.value}";'')
|
|
||||||
(attrsToList location.value.setHeaders))
|
|
||||||
++ (if site.value.detectAuth then ["proxy_hide_header Authorization;"] else [])
|
|
||||||
++ (
|
|
||||||
if site.value.addAuth then
|
|
||||||
["include ${inputs.config.sops.templates."nginx/addAuth/${site.name}-template".path};"]
|
|
||||||
else [])
|
|
||||||
);
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(attrsToList site.value.locations));
|
|
||||||
forceSSL = site.value.rewriteHttps;
|
|
||||||
http2 = site.value.http2;
|
|
||||||
basicAuthFile =
|
|
||||||
if site.value.detectAuth then inputs.config.sops.secrets."nginx/detectAuth/${site.name}".path
|
|
||||||
else null;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(attrsToList nginx.httpProxy));
|
|
||||||
recommendedZstdSettings = true;
|
|
||||||
recommendedTlsSettings = true;
|
|
||||||
recommendedProxySettings = 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;
|
|
||||||
'';
|
|
||||||
# todo: use host dns
|
|
||||||
resolver.addresses = [ "8.8.8.8" ];
|
|
||||||
};
|
|
||||||
geoipupdate =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
settings =
|
|
||||||
{
|
|
||||||
AccountID = 901296;
|
|
||||||
LicenseKey = inputs.config.sops.secrets."nginx/maxmind-license".path;
|
|
||||||
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
sops =
|
|
||||||
{
|
|
||||||
templates = listToAttrs (map
|
|
||||||
(site:
|
|
||||||
{
|
|
||||||
name = "nginx/addAuth/${site.name}-template";
|
|
||||||
value =
|
|
||||||
{
|
|
||||||
content =
|
|
||||||
let placeholder = inputs.config.sops.placeholder."nginx/addAuth/${site.name}";
|
|
||||||
in ''proxy_set_header Authorization "Basic ${placeholder}";'';
|
|
||||||
owner = inputs.config.users.users.nginx.name;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(filter (site: site.value.addAuth) (attrsToList nginx.httpProxy)));
|
|
||||||
secrets = { "nginx/maxmind-license".owner = inputs.config.users.users.nginx.name; }
|
|
||||||
// (listToAttrs (map
|
|
||||||
(site: { name = "nginx/detectAuth/${site.name}"; value.owner = inputs.config.users.users.nginx.name; })
|
|
||||||
(filter (site: site.value.detectAuth) (attrsToList nginx.httpProxy))))
|
|
||||||
// (listToAttrs (map
|
|
||||||
(site: { name = "nginx/addAuth/${site.name}"; value = {}; })
|
|
||||||
(filter (site: site.value.addAuth) (attrsToList nginx.httpProxy))));
|
|
||||||
};
|
|
||||||
systemd.services.nginx.serviceConfig =
|
|
||||||
{
|
|
||||||
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
|
||||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
|
||||||
LimitNPROC = 65536;
|
|
||||||
LimitNOFILE = 524288;
|
|
||||||
};
|
|
||||||
nixos.services.acme =
|
|
||||||
{
|
|
||||||
enable = true;
|
|
||||||
certs = map (cert: cert.name) (attrsToList nginx.httpProxy);
|
|
||||||
};
|
|
||||||
security.acme.certs = listToAttrs (map
|
|
||||||
(cert: { inherit (cert) name; value.group = inputs.config.services.nginx.group; })
|
|
||||||
(attrsToList nginx.httpProxy));
|
|
||||||
})
|
|
||||||
(mkIf nginx.transparentProxy.enable
|
|
||||||
{
|
|
||||||
services.nginx.streamConfig =
|
|
||||||
''
|
|
||||||
log_format transparent_proxy '[$time_local] $remote_addr-$geoip2_data_country_code '
|
|
||||||
'"$ssl_preread_server_name"->$transparent_proxy_backend $bytes_sent $bytes_received';
|
|
||||||
map $ssl_preread_server_name $transparent_proxy_backend
|
|
||||||
{
|
|
||||||
${concatStringsSep "\n" (map
|
|
||||||
(x: '' "${x.name}" 127.0.0.1:${toString x.value};'')
|
|
||||||
(
|
|
||||||
(attrsToList nginx.transparentProxy.map)
|
|
||||||
++ (map
|
|
||||||
(site: { name = site.name; value = (if site.value.http2 then 443 else 3065); })
|
|
||||||
(attrsToList nginx.httpProxy)
|
|
||||||
)
|
|
||||||
))}
|
|
||||||
default 127.0.0.1:443;
|
|
||||||
}
|
|
||||||
server
|
|
||||||
{
|
|
||||||
listen ${nginx.transparentProxy.externalIp}:443;
|
|
||||||
ssl_preread on;
|
|
||||||
proxy_bind $remote_addr transparent;
|
|
||||||
proxy_pass $transparent_proxy_backend;
|
|
||||||
proxy_connect_timeout 1s;
|
|
||||||
proxy_socket_keepalive on;
|
|
||||||
proxy_buffer_size 128k;
|
|
||||||
access_log syslog:server=unix:/dev/log transparent_proxy;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
|
||||||
systemd.services.nginx-proxy =
|
|
||||||
let
|
|
||||||
ipset = "${inputs.pkgs.ipset}/bin/ipset";
|
|
||||||
iptables = "${inputs.pkgs.iptables}/bin/iptables";
|
|
||||||
ip = "${inputs.pkgs.iproute}/bin/ip";
|
|
||||||
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
|
|
||||||
(
|
|
||||||
''
|
|
||||||
${ipset} create nginx_proxy_port bitmap:port range 0-65535
|
|
||||||
${iptables} -t mangle -N nginx_proxy_mark
|
|
||||||
${iptables} -t mangle -A OUTPUT -j nginx_proxy_mark
|
|
||||||
${iptables} -t mangle -A nginx_proxy_mark -s 127.0.0.1 -p tcp \
|
|
||||||
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
|
|
||||||
${iptables} -t mangle -N nginx_proxy
|
|
||||||
${iptables} -t mangle -A PREROUTING -j nginx_proxy
|
|
||||||
${iptables} -t mangle -A nginx_proxy -s 127.0.0.1 -p tcp \
|
|
||||||
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
|
|
||||||
${ip} rule add fwmark 2/2 table 200
|
|
||||||
${ip} route add local 0.0.0.0/0 dev lo table 200
|
|
||||||
''
|
|
||||||
+ concatStringsSep "\n" (map
|
|
||||||
(port: ''${ipset} add nginx_proxy_port ${toString port}'')
|
|
||||||
(inputs.lib.unique ((attrValues nginx.transparentProxy.map) ++ [ 443 3065 ])))
|
|
||||||
);
|
|
||||||
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
|
|
||||||
''
|
|
||||||
${iptables} -t mangle -F nginx_proxy_mark
|
|
||||||
${iptables} -t mangle -D OUTPUT -j nginx_proxy_mark
|
|
||||||
${iptables} -t mangle -X nginx_proxy_mark
|
|
||||||
${iptables} -t mangle -F nginx_proxy
|
|
||||||
${iptables} -t mangle -D PREROUTING -j nginx_proxy
|
|
||||||
${iptables} -t mangle -X nginx_proxy
|
|
||||||
${ip} rule del fwmark 2/2 table 200
|
|
||||||
${ip} route del local 0.0.0.0/0 dev lo table 200
|
|
||||||
${ipset} destroy nginx_proxy_port
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
description = "nginx transparent proxy";
|
|
||||||
after = [ "network.target" ];
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
Type = "simple";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
ExecStart = start;
|
|
||||||
ExecStop = stop;
|
|
||||||
};
|
|
||||||
wants = [ "network.target" ];
|
|
||||||
wantedBy= [ "multi-user.target" ];
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(mkIf nginx.streamProxy.enable
|
|
||||||
{
|
|
||||||
services.nginx =
|
|
||||||
{
|
|
||||||
streamConfig =
|
|
||||||
''
|
|
||||||
log_format stream_proxy '[$time_local] $remote_addr-$geoip2_data_country_code '
|
|
||||||
'"$ssl_preread_server_name"->$stream_proxy_backend $bytes_sent $bytes_received';
|
|
||||||
map $ssl_preread_server_name $stream_proxy_backend
|
|
||||||
{
|
|
||||||
${concatStringsSep "\n" (map
|
|
||||||
(x: '' "${x.name}" "${x.value.upstream or x.value}";'')
|
|
||||||
(attrsToList nginx.streamProxy.map))}
|
|
||||||
}
|
|
||||||
server
|
|
||||||
{
|
|
||||||
listen 127.0.0.1:${toString nginx.streamProxy.port};
|
|
||||||
ssl_preread on;
|
|
||||||
proxy_pass $stream_proxy_backend;
|
|
||||||
proxy_connect_timeout 10s;
|
|
||||||
proxy_socket_keepalive on;
|
|
||||||
proxy_buffer_size 128k;
|
|
||||||
access_log syslog:server=unix:/dev/log stream_proxy;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
virtualHosts = listToAttrs (map
|
|
||||||
(site:
|
|
||||||
{
|
|
||||||
inherit (site) name;
|
|
||||||
value =
|
|
||||||
{
|
|
||||||
serverName = site.name;
|
|
||||||
listen = [ { addr = "0.0.0.0"; port = 80; } ];
|
|
||||||
locations."/".return = "301 https://${site.name}$request_uri";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(filter (site: site.value.rewriteHttps or false) (attrsToList nginx.streamProxy.map)));
|
|
||||||
};
|
|
||||||
nixos.services.nginx.transparentProxy.map = listToAttrs (map
|
|
||||||
(site: { name = site.name; value = nginx.streamProxy.port; })
|
|
||||||
(attrsToList nginx.streamProxy.map));
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
||||||
17
modules/services/nginx/applications/blog.nix
Normal file
17
modules/services/nginx/applications/blog.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nginx.applications.blog = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services.nginx.applications) blog;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf blog.enable
|
||||||
|
{
|
||||||
|
nixos.services.nginx.https."blog.chn.moe".location."/".static =
|
||||||
|
{ root = "/srv/blog"; index = [ "index.html" ]; };
|
||||||
|
systemd.tmpfiles.rules = [ "d /srv/blog 0700 nginx nginx" "Z /srv/blog - nginx nginx" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
17
modules/services/nginx/applications/catalog.nix
Normal file
17
modules/services/nginx/applications/catalog.nix
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nginx.applications.catalog = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services.nginx.applications) catalog;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf catalog.enable
|
||||||
|
{
|
||||||
|
nixos.services.nginx.https."catalog.chn.moe".location."/".static =
|
||||||
|
{ root = "/srv/catalog"; index = [ "index.html" ]; };
|
||||||
|
systemd.tmpfiles.rules = [ "d /srv/catalog 0700 nginx nginx" "Z /srv/catalog - nginx nginx" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
13
modules/services/nginx/applications/default.nix
Normal file
13
modules/services/nginx/applications/default.nix
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
imports = inputs.localLib.mkModules
|
||||||
|
[
|
||||||
|
./element.nix
|
||||||
|
./synapse-admin.nix
|
||||||
|
./kkmeeting.nix
|
||||||
|
./webdav.nix
|
||||||
|
./blog.nix
|
||||||
|
./catalog.nix
|
||||||
|
./main.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
38
modules/services/nginx/applications/element.nix
Normal file
38
modules/services/nginx/applications/element.nix
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nginx.applications.element.instances = let inherit (inputs.lib) mkOption types; in mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
||||||
|
{
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
|
||||||
|
defaultServer = mkOption { type = types.nullOr types.nonEmptyStr; default = "matrix.chn.moe"; };
|
||||||
|
};}));
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services.nginx.applications.element) instances;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
inherit (builtins) map listToAttrs toString;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixos.services.nginx.https = listToAttrs (map
|
||||||
|
(instance: with instance.value;
|
||||||
|
{
|
||||||
|
name = hostname;
|
||||||
|
value.location."/".static =
|
||||||
|
{
|
||||||
|
root =
|
||||||
|
if defaultServer == null then toString inputs.pkgs.element-web
|
||||||
|
else toString (inputs.pkgs.element-web.override { conf =
|
||||||
|
{
|
||||||
|
default_server_config."m.homeserver" =
|
||||||
|
{ base_url = "https://${defaultServer}"; server_name = defaultServer; };
|
||||||
|
disable_guests = false;
|
||||||
|
};});
|
||||||
|
index = [ "index.html" ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(attrsToList instances));
|
||||||
|
};
|
||||||
|
}
|
||||||
18
modules/services/nginx/applications/kkmeeting.nix
Normal file
18
modules/services/nginx/applications/kkmeeting.nix
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nginx.applications.kkmeeting = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; default = "kkmeeting.chn.moe"; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services.nginx.applications) kkmeeting;
|
||||||
|
inherit (inputs.lib) mkIf;
|
||||||
|
in mkIf kkmeeting.enable
|
||||||
|
{
|
||||||
|
nixos.services.nginx.https.${kkmeeting.hostname}.location."/".static =
|
||||||
|
{ root = "/srv/kkmeeting"; index = "auto"; charset = "utf-8"; };
|
||||||
|
systemd.tmpfiles.rules = [ "d /srv/kkmeeting 0700 nginx nginx" "Z /srv/kkmeeting - nginx nginx" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
22
modules/services/nginx/applications/main.nix
Normal file
22
modules/services/nginx/applications/main.nix
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nginx.applications.main = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services.nginx.applications) main;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixos.services.nginx.https."chn.moe".location =
|
||||||
|
{
|
||||||
|
"/".return.return = "302 https://xn--s8w913fdga.chn.moe/@chn";
|
||||||
|
"/.well-known/matrix/server".proxy =
|
||||||
|
{
|
||||||
|
setHeaders.Host = "synapse.chn.moe";
|
||||||
|
upstream = "https://synapse.chn.moe";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
26
modules/services/nginx/applications/synapse-admin.nix
Normal file
26
modules/services/nginx/applications/synapse-admin.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nginx.applications.synapse-admin.instances =
|
||||||
|
let inherit (inputs.lib) mkOption types; in mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
||||||
|
{ hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; }; };}));
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services.nginx.applications.synapse-admin) instances;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
inherit (builtins) map listToAttrs;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixos.services.nginx.https = listToAttrs (map
|
||||||
|
(site: with site.value;
|
||||||
|
{
|
||||||
|
name = hostname;
|
||||||
|
value.location."/".static =
|
||||||
|
{ root = "${inputs.pkgs.synapse-admin}"; index = [ "index.html" ]; };
|
||||||
|
})
|
||||||
|
(attrsToList instances));
|
||||||
|
};
|
||||||
|
}
|
||||||
36
modules/services/nginx/applications/webdav.nix
Normal file
36
modules/services/nginx/applications/webdav.nix
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nginx.applications.webdav.instances = let inherit (inputs.lib) mkOption types; in mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
||||||
|
{
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
|
||||||
|
path = mkOption { type = types.nonEmptyStr; default = "/srv/webdav"; };
|
||||||
|
users = mkOption { type = types.nonEmptyListOf types.nonEmptyStr; default = [ "chn" ]; };
|
||||||
|
};}));
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.config.nixos.services.nginx.applications.webdav) instances;
|
||||||
|
inherit (builtins) map listToAttrs attrValues;
|
||||||
|
inherit (inputs.lib) mkMerge;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixos.services.nginx.https = listToAttrs (map
|
||||||
|
(site:
|
||||||
|
{
|
||||||
|
name = site.hostname;
|
||||||
|
value.location."/".static =
|
||||||
|
{ root = site.path; index = "auto"; charset = "utf-8"; webdav = true; detectAuth.users = site.users; };
|
||||||
|
})
|
||||||
|
(attrValues instances));
|
||||||
|
systemd = mkMerge (map
|
||||||
|
(site:
|
||||||
|
{
|
||||||
|
tmpfiles.rules = [ "d ${site.path} 0700 nginx nginx" "Z ${site.path} - nginx nginx" ];
|
||||||
|
services.nginx.serviceConfig.ReadWritePaths = [ site.path ];
|
||||||
|
})
|
||||||
|
(attrValues instances));
|
||||||
|
};
|
||||||
|
}
|
||||||
788
modules/services/nginx/default.nix
Normal file
788
modules/services/nginx/default.nix
Normal file
@@ -0,0 +1,788 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
imports = inputs.localLib.mkModules
|
||||||
|
[
|
||||||
|
./applications
|
||||||
|
];
|
||||||
|
options.nixos.services.nginx = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
# transparentProxy -> https(with proxyProtocol) or transparentProxy -> streamProxy -> https(with proxyProtocol)
|
||||||
|
# https without proxyProtocol listen on private ip, with proxyProtocol listen on all ip
|
||||||
|
# streamProxy listen on private ip
|
||||||
|
# transparentProxy listen on public ip
|
||||||
|
global = mkOption
|
||||||
|
{
|
||||||
|
type = types.anything;
|
||||||
|
readOnly = true;
|
||||||
|
default =
|
||||||
|
{
|
||||||
|
httpsPort = 3065;
|
||||||
|
httpsPortShift = { http2 = 1; proxyProtocol = 2; };
|
||||||
|
httpsLocationTypes = [ "proxy" "static" "php" "return" "cgi" "alias" ];
|
||||||
|
httpTypes = [ "rewriteHttps" "php" ];
|
||||||
|
streamPort = 5575;
|
||||||
|
streamPortShift = { proxyProtocol = 1; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
transparentProxy =
|
||||||
|
{
|
||||||
|
# only disable in some rare cases
|
||||||
|
enable = mkOption { type = types.bool; default = true; };
|
||||||
|
externalIp = mkOption { type = types.listOf types.nonEmptyStr; default = [ "0.0.0.0" ]; };
|
||||||
|
# proxy to 127.0.0.1:${specified port}
|
||||||
|
map = mkOption { type = types.attrsOf types.ints.unsigned; default = {}; };
|
||||||
|
};
|
||||||
|
streamProxy =
|
||||||
|
{
|
||||||
|
map = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.oneOf
|
||||||
|
[
|
||||||
|
# proxy to specified ip:port without proxyProtocol
|
||||||
|
types.nonEmptyStr
|
||||||
|
(types.submodule { options =
|
||||||
|
{
|
||||||
|
upstream = mkOption
|
||||||
|
{
|
||||||
|
type = types.oneOf
|
||||||
|
[
|
||||||
|
# proxy to specified ip:port with or without proxyProtocol
|
||||||
|
types.nonEmptyStr
|
||||||
|
(types.submodule { options =
|
||||||
|
{
|
||||||
|
address = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
|
||||||
|
# if port not specified, guess from proxyProtocol enabled or not, assume http2 enabled
|
||||||
|
port = mkOption { type = types.nullOr types.ints.unsigned; default = null; };
|
||||||
|
};})
|
||||||
|
];
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
proxyProtocol = mkOption { type = types.bool; default = true; };
|
||||||
|
addToTransparentProxy = mkOption { type = types.bool; default = true; };
|
||||||
|
rewriteHttps = mkOption { type = types.bool; default = true; };
|
||||||
|
};})
|
||||||
|
]);
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
https = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule (siteSubmoduleInputs: { options =
|
||||||
|
{
|
||||||
|
global =
|
||||||
|
{
|
||||||
|
configName = mkOption
|
||||||
|
{
|
||||||
|
type = types.nonEmptyStr;
|
||||||
|
default = "https:${siteSubmoduleInputs.config._module.args.name}";
|
||||||
|
};
|
||||||
|
root = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
|
index = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.oneOf [ (types.enum [ "auto" ]) (types.nonEmptyListOf types.nonEmptyStr) ]);
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
charset = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
|
detectAuth = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{
|
||||||
|
text = mkOption { type = types.nonEmptyStr; default = "Restricted Content"; };
|
||||||
|
users = mkOption { type = types.nonEmptyListOf types.nonEmptyStr; };
|
||||||
|
};});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
rewriteHttps = mkOption { type = types.bool; default = true; };
|
||||||
|
tlsCert = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
|
};
|
||||||
|
listen = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule { options =
|
||||||
|
{
|
||||||
|
http2 = mkOption { type = types.bool; default = true; };
|
||||||
|
proxyProtocol = mkOption { type = types.bool; default = true; };
|
||||||
|
# if proxyProtocol not enabled, add to transparentProxy only
|
||||||
|
# if proxyProtocol enabled, add to transparentProxy and streamProxy
|
||||||
|
addToTransparentProxy = mkOption { type = types.bool; default = true; };
|
||||||
|
};});
|
||||||
|
default.main = {};
|
||||||
|
};
|
||||||
|
location = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule { options =
|
||||||
|
let
|
||||||
|
genericOptions =
|
||||||
|
{
|
||||||
|
# should be set to non null value if global root is null
|
||||||
|
root = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
|
detectAuth = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{
|
||||||
|
text = mkOption { type = types.nonEmptyStr; default = "Restricted Content"; };
|
||||||
|
users = mkOption { type = types.nonEmptyListOf types.nonEmptyStr; };
|
||||||
|
};});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# only one should be specified
|
||||||
|
proxy = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{
|
||||||
|
inherit (genericOptions) detectAuth;
|
||||||
|
upstream = mkOption { type = types.nonEmptyStr; };
|
||||||
|
websocket = mkOption { type = types.bool; default = false; };
|
||||||
|
setHeaders = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default.Host = siteSubmoduleInputs.config._module.args.name;
|
||||||
|
};
|
||||||
|
# echo -n "username:password" | base64
|
||||||
|
addAuth = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
|
};});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
static = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{
|
||||||
|
inherit (genericOptions) detectAuth root;
|
||||||
|
index = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr
|
||||||
|
(types.oneOf [ (types.enum [ "auto" ]) (types.nonEmptyListOf types.nonEmptyStr) ]);
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
charset = mkOption { type = types.nullOr types.nonEmptyStr; default = null; };
|
||||||
|
tryFiles = mkOption { type = types.nullOr (types.nonEmptyListOf types.nonEmptyStr); default = null; };
|
||||||
|
webdav = mkOption { type = types.bool; default = false; };
|
||||||
|
};});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
php = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{ inherit (genericOptions) detectAuth root; fastcgiPass = mkOption { type = types.nonEmptyStr; };};});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
return = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{ return = mkOption { type = types.nonEmptyStr; }; };});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
cgi = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options = { inherit (genericOptions) detectAuth root; };});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
alias = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{
|
||||||
|
path = mkOption { type = types.nonEmptyStr; };
|
||||||
|
};});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};});
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};}));
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
http = mkOption
|
||||||
|
{
|
||||||
|
type = types.attrsOf (types.submodule (submoduleInputs: { options =
|
||||||
|
{
|
||||||
|
rewriteHttps = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; default = submoduleInputs.config._module.args.name; };
|
||||||
|
};});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
php = mkOption
|
||||||
|
{
|
||||||
|
type = types.nullOr (types.submodule { options =
|
||||||
|
{ root = mkOption { type = types.nonEmptyStr; }; fastcgiPass = mkOption { type = types.nonEmptyStr; };};});
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};}));
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkMerge mkIf mkDefault;
|
||||||
|
inherit (inputs.lib.strings) escapeURL;
|
||||||
|
inherit (inputs.localLib) attrsToList;
|
||||||
|
inherit (inputs.config.nixos.services) nginx;
|
||||||
|
inherit (builtins) map listToAttrs concatStringsSep toString filter attrValues concatLists;
|
||||||
|
concatAttrs = list: listToAttrs (concatLists (map (attrs: attrsToList attrs) list));
|
||||||
|
in mkIf nginx.enable (mkMerge
|
||||||
|
[
|
||||||
|
# generic config
|
||||||
|
{
|
||||||
|
services =
|
||||||
|
{
|
||||||
|
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 10m;
|
||||||
|
'';
|
||||||
|
proxyTimeout = "10m";
|
||||||
|
recommendedZstdSettings = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
recommendedProxySettings = 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;
|
||||||
|
'';
|
||||||
|
# todo: use host dns
|
||||||
|
resolver.addresses = [ "8.8.8.8" ];
|
||||||
|
};
|
||||||
|
geoipupdate =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
settings =
|
||||||
|
{
|
||||||
|
AccountID = 901296;
|
||||||
|
LicenseKey = inputs.config.sops.secrets."nginx/maxmind-license".path;
|
||||||
|
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
sops.secrets = { "nginx/maxmind-license".owner = inputs.config.users.users.nginx.name; };
|
||||||
|
systemd.services.nginx.serviceConfig =
|
||||||
|
{
|
||||||
|
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||||
|
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||||
|
LimitNPROC = 65536;
|
||||||
|
LimitNOFILE = 524288;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
# transparentProxy
|
||||||
|
(mkIf nginx.transparentProxy.enable
|
||||||
|
{
|
||||||
|
services.nginx.streamConfig =
|
||||||
|
''
|
||||||
|
log_format transparent_proxy '[$time_local] $remote_addr-$geoip2_data_country_code '
|
||||||
|
'"$ssl_preread_server_name"->$transparent_proxy_backend $bytes_sent $bytes_received';
|
||||||
|
map $ssl_preread_server_name $transparent_proxy_backend {
|
||||||
|
${concatStringsSep "\n " (map
|
||||||
|
(x: ''"${x.name}" 127.0.0.1:${toString x.value};'')
|
||||||
|
(attrsToList nginx.transparentProxy.map))}
|
||||||
|
default 127.0.0.1:${toString (with nginx.global; (httpsPort + httpsPortShift.http2))};
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
${concatStringsSep "\n " (map (ip: "listen ${ip}:443;") nginx.transparentProxy.externalIp)}
|
||||||
|
ssl_preread on;
|
||||||
|
proxy_bind $remote_addr transparent;
|
||||||
|
proxy_pass $transparent_proxy_backend;
|
||||||
|
proxy_connect_timeout 1s;
|
||||||
|
proxy_socket_keepalive on;
|
||||||
|
proxy_buffer_size 128k;
|
||||||
|
access_log syslog:server=unix:/dev/log transparent_proxy;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
systemd.services.nginx-proxy =
|
||||||
|
let
|
||||||
|
ipset = "${inputs.pkgs.ipset}/bin/ipset";
|
||||||
|
iptables = "${inputs.pkgs.iptables}/bin/iptables";
|
||||||
|
ip = "${inputs.pkgs.iproute}/bin/ip";
|
||||||
|
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
|
||||||
|
(
|
||||||
|
''
|
||||||
|
${ipset} create nginx_proxy_port bitmap:port range 0-65535
|
||||||
|
${iptables} -t mangle -N nginx_proxy_mark
|
||||||
|
${iptables} -t mangle -A OUTPUT -j nginx_proxy_mark
|
||||||
|
${iptables} -t mangle -A nginx_proxy_mark -s 127.0.0.1 -p tcp \
|
||||||
|
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
|
||||||
|
${iptables} -t mangle -N nginx_proxy
|
||||||
|
${iptables} -t mangle -A PREROUTING -j nginx_proxy
|
||||||
|
${iptables} -t mangle -A nginx_proxy -s 127.0.0.1 -p tcp \
|
||||||
|
-m set --match-set nginx_proxy_port src -j MARK --set-mark 2/2
|
||||||
|
${ip} rule add fwmark 2/2 table 200
|
||||||
|
${ip} route add local 0.0.0.0/0 dev lo table 200
|
||||||
|
''
|
||||||
|
+ concatStringsSep "\n " (map
|
||||||
|
(port: ''${ipset} add nginx_proxy_port ${toString port}'')
|
||||||
|
(inputs.lib.unique (attrValues nginx.transparentProxy.map)))
|
||||||
|
);
|
||||||
|
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
|
||||||
|
''
|
||||||
|
${iptables} -t mangle -F nginx_proxy_mark
|
||||||
|
${iptables} -t mangle -D OUTPUT -j nginx_proxy_mark
|
||||||
|
${iptables} -t mangle -X nginx_proxy_mark
|
||||||
|
${iptables} -t mangle -F nginx_proxy
|
||||||
|
${iptables} -t mangle -D PREROUTING -j nginx_proxy
|
||||||
|
${iptables} -t mangle -X nginx_proxy
|
||||||
|
${ip} rule del fwmark 2/2 table 200
|
||||||
|
${ip} route del local 0.0.0.0/0 dev lo table 200
|
||||||
|
${ipset} destroy nginx_proxy_port
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
description = "nginx transparent proxy";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
serviceConfig =
|
||||||
|
{
|
||||||
|
Type = "simple";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = start;
|
||||||
|
ExecStop = stop;
|
||||||
|
};
|
||||||
|
wants = [ "network.target" ];
|
||||||
|
wantedBy= [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
# streamProxy
|
||||||
|
{
|
||||||
|
services.nginx.streamConfig =
|
||||||
|
''
|
||||||
|
log_format stream_proxy '[$time_local] $remote_addr-$geoip2_data_country_code '
|
||||||
|
'"$ssl_preread_server_name"->$stream_proxy_backend $bytes_sent $bytes_received';
|
||||||
|
map $ssl_preread_server_name $stream_proxy_backend {
|
||||||
|
${concatStringsSep "\n " (map
|
||||||
|
(x:
|
||||||
|
let
|
||||||
|
upstream =
|
||||||
|
if (builtins.typeOf x.value.upstream == "string") then
|
||||||
|
x.value.upstream
|
||||||
|
else
|
||||||
|
let
|
||||||
|
port = with nginx.global;
|
||||||
|
if x.value.upstream.port == null then
|
||||||
|
httpsPort + httpsPortShift.http2
|
||||||
|
+ (if x.value.proxyProtocol then httpsPortShift.proxyProtocol else 0)
|
||||||
|
else x.value.upstream.port;
|
||||||
|
in "${x.value.upstream.address}:${toString port}";
|
||||||
|
in ''"${x.name}" "${upstream}";'')
|
||||||
|
(attrsToList nginx.streamProxy.map))}
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
listen 127.0.0.1:${toString nginx.global.streamPort};
|
||||||
|
ssl_preread on;
|
||||||
|
proxy_pass $stream_proxy_backend;
|
||||||
|
proxy_connect_timeout 10s;
|
||||||
|
proxy_socket_keepalive on;
|
||||||
|
proxy_buffer_size 128k;
|
||||||
|
access_log syslog:server=unix:/dev/log stream_proxy;
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
listen 127.0.0.1:${toString (with nginx.global; (streamPort + streamPortShift.proxyProtocol))};
|
||||||
|
proxy_protocol on;
|
||||||
|
ssl_preread on;
|
||||||
|
proxy_pass $stream_proxy_backend;
|
||||||
|
proxy_connect_timeout 10s;
|
||||||
|
proxy_socket_keepalive on;
|
||||||
|
proxy_buffer_size 128k;
|
||||||
|
access_log syslog:server=unix:/dev/log stream_proxy;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
nixos.services.nginx =
|
||||||
|
{
|
||||||
|
transparentProxy.map = listToAttrs
|
||||||
|
(
|
||||||
|
(map
|
||||||
|
(site: { inherit (site) name; value = nginx.global.streamPort; })
|
||||||
|
(filter
|
||||||
|
(site: (!(site.value.proxyProtocol or false) && (site.value.addToTransparentProxy or true)))
|
||||||
|
(attrsToList nginx.streamProxy.map)))
|
||||||
|
++ (map
|
||||||
|
(site: { inherit (site) name; value = with nginx.global; streamPort + streamPortShift.proxyProtocol; })
|
||||||
|
(filter
|
||||||
|
(site: ((site.value.proxyProtocol or false) && (site.value.addToTransparentProxy or true)))
|
||||||
|
(attrsToList nginx.streamProxy.map)))
|
||||||
|
);
|
||||||
|
http = listToAttrs (map
|
||||||
|
(site: { inherit (site) name; value.rewriteHttps = {}; })
|
||||||
|
(filter (site: site.value.rewriteHttps or false) (attrsToList nginx.streamProxy.map)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
# https assertions
|
||||||
|
{
|
||||||
|
# only one type should be specified in each location
|
||||||
|
assertions =
|
||||||
|
(
|
||||||
|
(map
|
||||||
|
(location:
|
||||||
|
{
|
||||||
|
assertion = (inputs.lib.count
|
||||||
|
(x: x != null)
|
||||||
|
(map (type: location.value.${type}) nginx.global.httpsLocationTypes)) <= 1;
|
||||||
|
message = "Only one type shuold be specified in ${location.name}";
|
||||||
|
})
|
||||||
|
(concatLists (map
|
||||||
|
(site: (map
|
||||||
|
(location: { inherit (location) value; name = "${site.name} ${location.name}"; })
|
||||||
|
(attrsToList site.value.location)))
|
||||||
|
(attrsToList nginx.https))))
|
||||||
|
# root should be specified either in global or in each location
|
||||||
|
++ (map
|
||||||
|
(location:
|
||||||
|
{
|
||||||
|
assertion = (location.value.root or "") != null;
|
||||||
|
message = "Root should be specified in ${location.name}";
|
||||||
|
})
|
||||||
|
(concatLists (map
|
||||||
|
(site: (map
|
||||||
|
(location: { inherit (location) value; name = "${site.name} ${location.name}"; })
|
||||||
|
(attrsToList site.value.location)))
|
||||||
|
(filter (site: site.value.global.root == null) (attrsToList nginx.https)))))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
# https
|
||||||
|
(
|
||||||
|
let
|
||||||
|
# merge different types of locations
|
||||||
|
sites = map
|
||||||
|
(site:
|
||||||
|
{
|
||||||
|
inherit (site) name;
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
inherit (site.value) global;
|
||||||
|
listens = attrValues site.value.listen;
|
||||||
|
locations = map
|
||||||
|
(location:
|
||||||
|
{
|
||||||
|
inherit (location) name;
|
||||||
|
value =
|
||||||
|
let _ = builtins.head (filter (type: type.value != null) (attrsToList location.value));
|
||||||
|
in _.value // { type = _.name; };
|
||||||
|
})
|
||||||
|
(attrsToList site.value.location);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(attrsToList nginx.https);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services =
|
||||||
|
{
|
||||||
|
nginx.virtualHosts = listToAttrs (map
|
||||||
|
(site:
|
||||||
|
{
|
||||||
|
name = site.value.global.configName;
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
serverName = site.name;
|
||||||
|
root = mkIf (site.value.global.root != null) site.value.global.root;
|
||||||
|
basicAuthFile = mkIf (site.value.global.detectAuth != null)
|
||||||
|
inputs.config.sops.templates."nginx/templates/detectAuth/${escapeURL site.name}-global".path;
|
||||||
|
extraConfig = concatStringsSep "\n"
|
||||||
|
(
|
||||||
|
(
|
||||||
|
let inherit (site.value.global) index; in
|
||||||
|
if (builtins.typeOf index == "list") then [ "index ${concatStringsSep " " index};" ]
|
||||||
|
else if (index == "auto") then [ "autoindex on;" ]
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
++ (
|
||||||
|
let inherit (site.value.global) detectAuth; in
|
||||||
|
if (detectAuth != null) then [ ''auth_basic "${detectAuth.text}"'' ] else []
|
||||||
|
)
|
||||||
|
++ (
|
||||||
|
let inherit (site.value.global) charset; in
|
||||||
|
if (charset != null) then [ "charset ${charset};" ] else []
|
||||||
|
)
|
||||||
|
);
|
||||||
|
listen = map
|
||||||
|
(listen:
|
||||||
|
{
|
||||||
|
addr = if listen.proxyProtocol then "0.0.0.0" else "127.0.0.1";
|
||||||
|
port = with nginx.global; httpsPort
|
||||||
|
+ (if listen.http2 then httpsPortShift.http2 else 0)
|
||||||
|
+ (if listen.proxyProtocol then httpsPortShift.proxyProtocol else 0);
|
||||||
|
ssl = true;
|
||||||
|
proxyProtocol = listen.proxyProtocol;
|
||||||
|
extraParameters = mkIf listen.http2 [ "http2" ];
|
||||||
|
})
|
||||||
|
site.value.listens;
|
||||||
|
# do not automatically add http2 listen
|
||||||
|
http2 = false;
|
||||||
|
onlySSL = true;
|
||||||
|
useACMEHost = mkIf (site.value.global.tlsCert == null) site.name;
|
||||||
|
sslCertificate = mkIf (site.value.global.tlsCert != null)
|
||||||
|
"${site.value.global.tlsCert}/fullchain.pem";
|
||||||
|
sslCertificateKey = mkIf (site.value.global.tlsCert != null)
|
||||||
|
"${site.value.global.tlsCert}/privkey.pem";
|
||||||
|
locations = listToAttrs (map
|
||||||
|
(location:
|
||||||
|
{
|
||||||
|
inherit (location) name;
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
basicAuthFile = mkIf (location.value.detectAuth or null != null)
|
||||||
|
inputs.config.sops.templates
|
||||||
|
."nginx/templates/detectAuth/${escapeURL site.name}/${escapeURL location.name}".path;
|
||||||
|
root = mkIf (location.value.root or null != null) location.value.root;
|
||||||
|
}
|
||||||
|
// {
|
||||||
|
proxy =
|
||||||
|
{
|
||||||
|
proxyPass = location.value.upstream;
|
||||||
|
proxyWebsockets = location.value.websocket;
|
||||||
|
recommendedProxySettings = false;
|
||||||
|
recommendedProxySettingsNoHost = true;
|
||||||
|
extraConfig = concatStringsSep "\n"
|
||||||
|
(
|
||||||
|
(map
|
||||||
|
(header: ''proxy_set_header ${header.name} "${header.value}";'')
|
||||||
|
(attrsToList location.value.setHeaders))
|
||||||
|
++ (
|
||||||
|
if location.value.detectAuth != null || site.value.global.detectAuth != null
|
||||||
|
then [ "proxy_hide_header Authorization;" ]
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
++ (
|
||||||
|
if location.value.addAuth != null then
|
||||||
|
let authFile = "nginx/templates/addAuth/${location.value.addAuth}";
|
||||||
|
in [ "include ${inputs.config.sops.templates.${authFile}.path};" ]
|
||||||
|
else [])
|
||||||
|
);
|
||||||
|
};
|
||||||
|
static =
|
||||||
|
{
|
||||||
|
index = mkIf (builtins.typeOf location.value.index == "list")
|
||||||
|
(concatStringsSep " " location.value.index);
|
||||||
|
tryFiles = mkIf (location.value.tryFiles != null)
|
||||||
|
(concatStringsSep " " location.value.tryFiles);
|
||||||
|
extraConfig = mkMerge
|
||||||
|
[
|
||||||
|
(mkIf (location.value.index == "auto") "autoindex on;")
|
||||||
|
(mkIf (location.value.charset != null) "charset ${location.value.charset};")
|
||||||
|
(mkIf location.value.webdav
|
||||||
|
''
|
||||||
|
dav_access user:rw group:rw;
|
||||||
|
dav_methods PUT DELETE MKCOL COPY MOVE;
|
||||||
|
dav_ext_methods PROPFIND OPTIONS;
|
||||||
|
create_full_put_path on;
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
php.extraConfig =
|
||||||
|
''
|
||||||
|
fastcgi_pass ${location.value.fastcgiPass};
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
include ${inputs.config.services.nginx.package}/conf/fastcgi.conf;
|
||||||
|
'';
|
||||||
|
return.return = location.value.return;
|
||||||
|
cgi.extraConfig =
|
||||||
|
''
|
||||||
|
include ${inputs.config.services.nginx.package}/conf/fastcgi.conf;
|
||||||
|
fastcgi_pass unix:${inputs.config.services.fcgiwrap.socketAddress};
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
'';
|
||||||
|
alias.alias = location.value.path;
|
||||||
|
}.${location.value.type};
|
||||||
|
})
|
||||||
|
site.value.locations);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
sites);
|
||||||
|
fcgiwrap = mkIf
|
||||||
|
(
|
||||||
|
filter (site: site != []) (map
|
||||||
|
(site: filter (location: location.value.type == "cgi") site.value.locations)
|
||||||
|
sites)
|
||||||
|
!= []
|
||||||
|
)
|
||||||
|
(with inputs.config.users.users.nginx; { enable = true; user = name; inherit group; });
|
||||||
|
};
|
||||||
|
nixos.services =
|
||||||
|
{
|
||||||
|
nginx =
|
||||||
|
let
|
||||||
|
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
|
||||||
|
listens = filter
|
||||||
|
(listen: listen.value.addToTransparentProxy)
|
||||||
|
(concatLists (map
|
||||||
|
(site: map (listen: { inherit (site) name; value = listen; }) site.value.listens)
|
||||||
|
sites));
|
||||||
|
in
|
||||||
|
{
|
||||||
|
transparentProxy.map = listToAttrs (map
|
||||||
|
(site:
|
||||||
|
{
|
||||||
|
inherit (site) name;
|
||||||
|
value = with nginx.global; httpsPort + (if site.value.http2 then httpsPortShift.http2 else 0);
|
||||||
|
})
|
||||||
|
(filter (listen: !listen.value.proxyProtocol) listens));
|
||||||
|
streamProxy.map = listToAttrs (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 = mkDefault false;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(filter (listen: listen.value.proxyProtocol) listens));
|
||||||
|
http = listToAttrs (map
|
||||||
|
(site: { inherit (site) name; value.rewriteHttps = {}; })
|
||||||
|
(filter (site: site.value.global.rewriteHttps) sites));
|
||||||
|
};
|
||||||
|
acme =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
cert = listToAttrs (map
|
||||||
|
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
|
||||||
|
sites);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
sops =
|
||||||
|
let
|
||||||
|
detectAuthUsers = concatLists (map
|
||||||
|
(site:
|
||||||
|
(
|
||||||
|
(map
|
||||||
|
(location:
|
||||||
|
{
|
||||||
|
name = "${escapeURL site.name}/${escapeURL location.name}";
|
||||||
|
value = location.value.detectAuth.users;
|
||||||
|
})
|
||||||
|
(filter (location: location.value.detectAuth or null != null) site.value.locations))
|
||||||
|
++ (if site.value.global.detectAuth != null then
|
||||||
|
[ { name = "${escapeURL site.name}-global"; value = site.value.global.detectAuth.users; } ]
|
||||||
|
else [])
|
||||||
|
))
|
||||||
|
sites);
|
||||||
|
addAuth = concatLists (map
|
||||||
|
(site: map
|
||||||
|
(location:
|
||||||
|
{
|
||||||
|
name = "${escapeURL site.name}/${escapeURL location.name}";
|
||||||
|
value = location.value.addAuth;
|
||||||
|
})
|
||||||
|
(filter (location: location.value.addAuth or null != null) site.value.locations)
|
||||||
|
)
|
||||||
|
sites);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
templates = listToAttrs
|
||||||
|
(
|
||||||
|
(map
|
||||||
|
(detectAuth:
|
||||||
|
{
|
||||||
|
name = "nginx/templates/detectAuth/${detectAuth.name}";
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
owner = inputs.config.users.users.nginx.name;
|
||||||
|
content = concatStringsSep "\n" (map
|
||||||
|
(user: "${user}:{PLAIN}${inputs.config.sops.placeholder."nginx/detectAuth/${user}"}")
|
||||||
|
detectAuth.value);
|
||||||
|
};
|
||||||
|
})
|
||||||
|
detectAuthUsers)
|
||||||
|
++ (map
|
||||||
|
(addAuth:
|
||||||
|
{
|
||||||
|
name = "nginx/templates/addAuth/${addAuth.name}";
|
||||||
|
value =
|
||||||
|
{
|
||||||
|
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 = listToAttrs
|
||||||
|
(
|
||||||
|
(map
|
||||||
|
(secret: { name = "nginx/detectAuth/${secret}"; value = {}; })
|
||||||
|
(inputs.lib.unique (concatLists (map (detectAuth: detectAuth.value) detectAuthUsers))))
|
||||||
|
++ (map
|
||||||
|
(secret: { name = "nginx/addAuth/${secret}"; value = {}; })
|
||||||
|
(inputs.lib.unique (map (addAuth: addAuth.value) addAuth)))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
# http
|
||||||
|
{
|
||||||
|
assertions = map
|
||||||
|
(site:
|
||||||
|
{
|
||||||
|
assertion = (inputs.lib.count (x: x != null) (map (type: site.value.${type}) nginx.global.httpTypes)) <= 1;
|
||||||
|
message = "Only one type shuold be specified in ${site.name}";
|
||||||
|
})
|
||||||
|
(attrsToList nginx.http);
|
||||||
|
services.nginx.virtualHosts = listToAttrs (map
|
||||||
|
(site:
|
||||||
|
{
|
||||||
|
name = "http.${site.name}";
|
||||||
|
value = { serverName = site.name; listen = [ { addr = "0.0.0.0"; port = 80; } ]; }
|
||||||
|
// (if site.value.rewriteHttps != null then
|
||||||
|
{ locations."/".return = "301 https://${site.value.rewriteHttps.hostname}$request_uri"; }
|
||||||
|
else {})
|
||||||
|
// (if site.value.php != null then
|
||||||
|
{
|
||||||
|
extraConfig = "index index.php;";
|
||||||
|
root = site.value.php.root;
|
||||||
|
locations."~ ^.+?.php(/.*)?$".extraConfig =
|
||||||
|
''
|
||||||
|
fastcgi_pass ${site.value.php.fastcgiPass};
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
include ${inputs.config.services.nginx.package}/conf/fastcgi.conf;
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
else {});
|
||||||
|
})
|
||||||
|
(attrsToList nginx.http));
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
26
modules/services/nix-serve.nix
Normal file
26
modules/services/nix-serve.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
inputs:
|
||||||
|
{
|
||||||
|
options.nixos.services.nix-serve = let inherit (inputs.lib) mkOption types; in
|
||||||
|
{
|
||||||
|
enable = mkOption { type = types.bool; default = false; };
|
||||||
|
hostname = mkOption { type = types.nonEmptyStr; };
|
||||||
|
};
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
inherit (inputs.lib) mkMerge mkIf;
|
||||||
|
inherit (inputs.localLib) stripeTabs attrsToList;
|
||||||
|
inherit (inputs.config.nixos.services) nix-serve;
|
||||||
|
inherit (builtins) map listToAttrs toString;
|
||||||
|
in mkIf nix-serve.enable
|
||||||
|
{
|
||||||
|
services.nix-serve =
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
secretKeyFile = inputs.config.sops.secrets."store/signingKey".path;
|
||||||
|
};
|
||||||
|
sops.secrets."store/signingKey" = {};
|
||||||
|
nixos.services.nginx =
|
||||||
|
{ enable = true; https.${nix-serve.hostname}.location."/".proxy.upstream = "http://127.0.0.1:5000"; };
|
||||||
|
};
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user