mirror of
https://github.com/CHN-beta/nixos.git
synced 2026-01-13 12:19:22 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e9c9778cf | |||
| a9e3fbb3d8 | |||
| f44140eb69 |
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -1 +1,6 @@
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.icm filter=lfs diff=lfs merge=lfs -text
|
||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||
*.webp filter=lfs diff=lfs merge=lfs -text
|
||||
*.efi filter=lfs diff=lfs merge=lfs -text
|
||||
flake/branch.nix merge=ours
|
||||
|
||||
@@ -36,9 +36,10 @@ telegram:
|
||||
user:
|
||||
chn: ENC[AES256_GCM,data:mTt2D+SkvVL8,iv:L0Pk5p46E2kKBdRWCGpwOKS0BsbIhZUslpIFWvkssMY=,tag:+AjbNJ1SW/8Mx1HLpWAd2w==,type:str]
|
||||
hjp: ENC[AES256_GCM,data:ZXTQhax0gT4PKw==,iv:MerbaWWC4SLazEuuJrxAxf9e5aaX9xpq9St+h9aqvMQ=,tag:x9knShK90OKZPcn9fKzvMA==,type:str]
|
||||
maxmind: ENC[AES256_GCM,data:KfTXvxX4zzXBfNMPmZY1z5jTHTByGfH9qEo6EUAQqZ1JOtNUomOWNQ==,iv:KcexOWAXFhWfli6bAMZ+61x960trZ3iE9UYMuOtJNms=,tag:reuuIe6MkONpeT44U6yUjQ==,type:str]
|
||||
acme:
|
||||
token: ENC[AES256_GCM,data:DrNdcyf2tiZ5nmjYmsG13V63ZuZhNG1c/kkGM7eXQWvRvDbu37nKWA==,iv:xc4gtNvZ/BYG+KmT1XgFfG3Z17bBLURazG8tz4/laxE=,tag:khnYVQWjiiaQC9VsJyLV6A==,type:str]
|
||||
token: ENC[AES256_GCM,data:M8/R019chds8zr2BqnRnKP40NZxwq4fz06NaOeOOFYecLyDjIOq5mg==,iv:VPr4XD0Y+6G1P1xwMDyrWPiTvCYdiMV0nPcmqCvIA3Y=,tag:KEyCIHRmRkNviA4bMTMybg==,type:str]
|
||||
nginx:
|
||||
maxmind-license: ENC[AES256_GCM,data:MtmNo6hHlU75N6PvzF7P5i6Q+myV4Keb1JRXVeHxTennNpKfAndsKg==,iv:DqM91JX+1WX8Zqzha2Tm3ztFaSzKYQg+b9NvUm+6jxY=,tag:XnDTBL9MA/B8XfPZqdk7Eg==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -176,7 +177,7 @@ sops:
|
||||
UnR5Y24rSTk3WUV1VUgvQUFCVUxPZUEKv/lTy02gZYn4jF1uGtm+LhJd0m59Xe99
|
||||
+unmqUDh0ZqAhJU8o0jrBiWs1lXOHU7CkIom7tGEMHGUxHkS+Z/6GQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-07-13T00:27:59Z"
|
||||
mac: ENC[AES256_GCM,data:iBBMsGOD7nDpXDPDlB/ml06y4WVe0uq7dptn5VZSppoxGA7BmRfWq9OKueXykmgfueqC3N45KVeRh3/b+FrsIRuTl1iyKnT3pd/naGTguQBfFewhrbqNc6UaDadpEVSgYiS76A5JwEoemePPHVUboDOSe0ru3uzNk1nDh/85jRg=,iv:8/GpDArKPYPG2O41p97oQZHkmIgIVdB7OWLvMrDXlaI=,tag:sq3B5Zo7XoA151WmgtvMMw==,type:str]
|
||||
lastmodified: "2025-07-05T04:25:07Z"
|
||||
mac: ENC[AES256_GCM,data:x7wXcdExnf3grO9uS90dQMCSTgJiCyz5sdiek4EnYPsb/EVXfbzYnOo05T3ns8nNfQb6jCKBr/TZO6ZhOneaa/b8uZrG3c4EtDRVptm6+8PydgG5pv5ZiVLb83XR/t11xLWyzc8livLiTPb2RT0UglznOWCGPz20ULoI+JphGGc=,iv:iE7sRIyY2Espmaushcb0VJMjUZYhSGAqRdhmQRMkndU=,tag:0qsijRFyFshIKZTwVbvntw==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
# sudo nix build --store 'local?store=/data/gpfs01/jykang/.nix/store&state=/data/gpfs01/jykang/.nix/state&log=/data/gpfs01/jykang/.nix/log' .#jykang
|
||||
# sudo nix-store --store 'local?store=/data/gpfs01/jykang/.nix/store&state=/data/gpfs01/jykang/.nix/state&log=/data/gpfs01/jykang/.nix/log' -qR ./result | grep -Fxv -f <(ssh jykang find .nix/store -maxdepth 1 -exec realpath '{}' '\;') | sudo xargs nix-store --store 'local?store=/data/gpfs01/jykang/.nix/store&state=/data/gpfs01/jykang/.nix/state&log=/data/gpfs01/jykang/.nix/log' --export | xz -T0 | pv > jykang.nar.xz
|
||||
# cat data.nar | nix-store --import
|
||||
{ inputs, localLib }:
|
||||
let pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
|
||||
# sudo nix build --store 'local?store=/data/gpfs01/jykang/.nix/store&real=/nix/store' .#jykang
|
||||
# sudo nix-store --store 'local?store=/data/gpfs01/jykang/.nix/store&real=/nix/store' -qR ./result | sudo xargs nix-store --store 'local?store=/data/gpfs01/jykang/.nix/store&real=/nix/store' --export > data.nar
|
||||
# cat data.nar | nix-store --import
|
||||
inputs:
|
||||
let pkgs = import inputs.nixpkgs (import ../../modules/system/nixpkgs/buildNixpkgsConfig.nix
|
||||
{
|
||||
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
|
||||
nixpkgs = { march = "haswell"; cuda = null; nixRoot = "/data/gpfs01/jykang/.nix"; nixos = false; };
|
||||
nixpkgs = { march = null; cuda = null; nixRoot = "/data/gpfs01/jykang/.nix"; };
|
||||
});
|
||||
in pkgs.symlinkJoin
|
||||
{
|
||||
name = "jykang";
|
||||
paths = with pkgs; [ hello iotop gnuplot localPackages.vaspkit pv btop ];
|
||||
paths = with pkgs; [ hello iotop gnuplot localPackages.vaspkit ];
|
||||
postBuild = "echo ${inputs.self.rev or "dirty"} > $out/.version";
|
||||
passthru = { inherit pkgs; };
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ if [ -f /etc/bashrc ]; then
|
||||
fi
|
||||
|
||||
if [ -z "${BASHRC_SOURCED-}" ]; then
|
||||
export PATH=$HOME/.nix/state/gcroots/current/bin:$HPCSTAT_SSH_BINDIR:$PATH:$HOME/bin:$HOME/linwei/chn/software/scripts
|
||||
export PATH=$HPCSTAT_SSH_BINDIR:$PATH:$HOME/bin:$HOME/linwei/chn/software/scripts:$HOME/.nix/state/gcroots/current/bin
|
||||
export BASHRC_SOURCED=1
|
||||
if [ "${HPCSTAT_SUBACCOUNT}" == "lyj" ]; then
|
||||
export PATH=$HOME/wuyaping/lyj/bin:$PATH
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
store = local?store=/data/gpfs01/jykang/.nix/store&state=/data/gpfs01/jykang/.nix/state&log=/data/gpfs01/jykang/.nix/log
|
||||
experimental-features = flakes nix-command
|
||||
@@ -10,7 +10,6 @@ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGwUhEAFHjkbUfOf0ng8I80YbKisbSeY4lq/byinV7lh
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF5bg5cayOLfnfUBJz8LeyaYfP41s9pIqUgXn6w9xtvR lly
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBoDGk9HYphkngx2Ix/vef2ZntdVNK1kbS9pY8+TzI41 yxf
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJi6O1Sf1BBV1dYyH1jcHiws+ntwVfV29+6Paq1CQaET hss
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFlBxisj3sU9QC8UC5gX6sakf7G03ybbkmHtD2cybuZA qmx
|
||||
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCmJoiGO5YD3lbbIOJ99Al2xxm6QS9q+dTCTtlALjYI5f9ICGZJT8PEGlV9BBNCRQdgb3i2LBzQi90Tq1oG6/PcTV3Mto2TawLz5+2+ym29eIq1QIhVTLmZskK815FpawWqxY6+xpGU3vP1WjrFBbhGtl+CCaN+P2TWNkrR8FjG2144hdAlFfEEqfQC+TXbsyJCYoExuxGDJo8ae0JGbz9w1A1UbjnHwKnoxvirTFEbw9IHJIcTdUwuQKOrwydboCOqeaHt74+BnnCOZhpYqMDacrknHITN4GfFFzbs6FsE8NAwFk6yvkNXXzoe60iveNXtCIYuWjG517LQgHAC5BdaPgqzYNg+eqSul72e+jjRs+KDioNqvprw+TcBBO1lXZ2VQFyWyAdV2Foyaz3Wk5qYlOpX/9JLEp6H3cU0XCFR25FdXmjQ4oXN1QEe+2akV8MQ9cWhFhDcbY8Q1EiMWpBVC1xbt4FwE8VCTByZOZsQ0wPVe/vkjANOo+brS3tsR18= 00@xmuhpc
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCxcIWDQxVyIRqCGR4uWtrh4tLc025+q6du2GVsox8IzmBFkjNY8Au5GIMP5BKRstxFdg3f/wam8krckUN9rv5+OHB9U8HGz77Xs0FktqRVNMaDPdptePZQJ9A9eW3kkFDfQnORJtiVcEWfUBS3pi0QFOHylnG27YyC/Vjx9tjvtJWKsQEVTFJbFHPdi+G7lHTpqIGx+/a2JN9O6uVujXXYvjSVXsd+CWB9VMZMvYCIz2Ecb6RqR3brj4FhRRl8zyCj+J4ACYFdGWL98fTab2uPHbpVeKrefFFA43JOD/4zwBx/uw7MAQAq0GunTV3FpBfIAQHWgftf2fSlbz20oPjCwdYn9ZuGJOBUroryex7AKZmnSYM3biLHcctQfZtxqVPEU3W/62MUsI/kZb9RcF24JRksMoS2XWTiv2HFf5ijQGLXXOjqiTlGncwiKf65DwkDBsSxzgbXk5Uo86viq6UITFXPx/RytU+SUiN4Wb7wcBTjt/+tyQd1uqc7+3DCDXk= 01@xmuhpc
|
||||
|
||||
@@ -4,7 +4,7 @@ inputs:
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
model = { type = "server"; private = true; };
|
||||
model.private = true;
|
||||
system =
|
||||
{
|
||||
fileSystems =
|
||||
@@ -21,18 +21,13 @@ inputs:
|
||||
nixpkgs.march = "silvermont";
|
||||
network = {};
|
||||
};
|
||||
hardware.gpu.type = "intel";
|
||||
hardware = { cpus = [ "intel" ]; gpu.type = "intel"; };
|
||||
services =
|
||||
{
|
||||
sshd = {};
|
||||
xray =
|
||||
{
|
||||
client.dnsmasq = { extraInterfaces = [ "enp3s0" ]; hosts."git.nas.chn.moe" = "127.0.0.1"; };
|
||||
xmuServer = {};
|
||||
server.serverName = "xservernas.chn.moe";
|
||||
};
|
||||
beesd."/" = { hashTableSizeMB = 10 * 128; threads = 4; };
|
||||
nfs."/" = [(inputs.topInputs.self.config.dns."chn.moe".getAddress "wg1.pc")];
|
||||
xray.client.dnsmasq.hosts."git.nas.chn.moe" = "127.0.0.1";
|
||||
beesd."/".hashTableSizeMB = 10 * 128;
|
||||
nfs."/" = inputs.topInputs.self.config.dns."chn.moe".getAddress "wg1.pc";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
xray-client:
|
||||
uuid: ENC[AES256_GCM,data:97aX07G5FPumdWcDxnYOs6fRgljXWuwyNXGg1d7zdbUUfNnb,iv:+wAC/DZXsg+evYFA4DMfLw5Ut3ExQl1RgZ/2AsNQDpo=,tag:ebD77muITHof+FQMydWobg==,type:str]
|
||||
wireguard: ENC[AES256_GCM,data:JaOSq474mGOoQQcdJ/j9fYo2e1vjXMPxJ69TOd079FrSkbzbIteWww5f8Xo=,iv:uy/NC2+tibL61XJDZK/spKjV9u0oXK4YzjFjYmCAL0k=,tag:en+c8cHaPvDqJL+EpQjr0g==,type:str]
|
||||
xray-xmu-server: ENC[AES256_GCM,data:3O5rFi5szla70M/c62JV4nGWKPSOREImrOucjeVYf9bde6K8,iv:PGCqlmHtaNuWOtAAeJ6O+CWFpMszijozU1OpUFrftjs=,tag:iGTOoNvQhhZy2FL9jy1KIQ==,type:str]
|
||||
xray-server:
|
||||
clients:
|
||||
#ENC[AES256_GCM,data:gToh4rgMOQ==,iv:A14sSC7ExbSZNOzzz6mOmWalSz9K6ROoSYgCqdF7j4U=,tag:1Jr2FfVQ9L2w+bWHh/NekQ==,type:comment]
|
||||
user4: ENC[AES256_GCM,data:/ZrgvlpwDlKhcHqkBRsdqqJsNUxtb3ZnC36mc8qlJ+HP4mY3,iv:R5QzXY0mC72TDB0OcF4fJt3bc5L1Z96Q+n9kNbZP7m4=,tag:tjWSEcsG0udvQZZJ/RMTJw==,type:str]
|
||||
private-key: ENC[AES256_GCM,data:34FOslwr3AZNDg4YrS95S20agGXwGJRNGnpogMR7utbt1ELUxfQkiAU1qw==,iv:4fiJCi6TJM+NIlfI1qFX/eCNhcVaCWGsLA7iMjQpATw=,tag:eLz8HlQMprQNryk5saqyVQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -27,7 +21,7 @@ sops:
|
||||
by9Rd0U0bzNiK21BQTNxN1RuQ09DQVkKJmSlzV5ppEkZFljsS17ZWmoI++fz4tJh
|
||||
kTdoAStG1zsKASHyZTsmdm3RBDO3qV1KhQC2gC7d4EiwNZngxOOZJg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-08-06T04:33:54Z"
|
||||
mac: ENC[AES256_GCM,data:DMLcRc1hDS0x5Gt0WA/6kfEi7KKogeKHBfuW9gndj7fPqCyyYFzW9Mn8mZ3UhWB68c25GtKyLdo9T5yFivS90JB74kEWrQn/Nfdy0wW18BOloiRwLdSipoADwYwpJtr+JGNs9R6AqIAoDcbVJrr4q6kZh/Cjue6TJiyBdI4uirU=,iv:YOn7XzKAKtzucq6h0yAgj+Ee6L3srscnvieCOmZjBeo=,tag:lnAfv2pWVf5czeTgL4donQ==,type:str]
|
||||
lastmodified: "2025-06-09T01:22:01Z"
|
||||
mac: ENC[AES256_GCM,data:OxRUW3e2SXTTdb7Iwvsf/UaHsTIVxohJwRIFExh5N/dJhU9Ui8omKBjkooiGaysrZEVEZNAWSp2zvTPXUdZrtW2fikyhF6Fsg7jUFFTqhV/sjYMy7gISbfkcGF9SuYGByuuySyXPqsfg+ESeBmMVZiqDSEPYJWu+q8OwThdhsAM=,iv:UnSfmuxcV+tr7wd59Xg0MG2QbP2uOshVhN5C++9ZSzA=,tag:cWiG85xv2OuiBOoAlvVBGw==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -17,19 +17,18 @@ inputs:
|
||||
luks.auto."/dev/disk/by-partlabel/one-root" = { mapper = "root"; ssd = true; };
|
||||
swap = [ "/nix/swap/swap" ];
|
||||
resume = { device = "/dev/mapper/root"; offset = 4728064; };
|
||||
rollingRootfs = {};
|
||||
};
|
||||
nixpkgs.march = "tigerlake";
|
||||
};
|
||||
hardware.gpu.type = "intel";
|
||||
hardware = { cpus = [ "intel" ]; gpu.type = "intel"; };
|
||||
services =
|
||||
{
|
||||
xray.client = {};
|
||||
beesd."/".hashTableSizeMB = 64;
|
||||
sshd = {};
|
||||
waydroid = {};
|
||||
};
|
||||
bugs = [ "xmunet" ];
|
||||
};
|
||||
specialisation.niri.configuration.nixos.system.gui.implementation = "niri";
|
||||
};
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -17,7 +17,6 @@ inputs:
|
||||
"/nix" = "/nix";
|
||||
"/nix/rootfs/current" = "/";
|
||||
"/nix/remote/jykang.xmuhpc" = "/data/gpfs01/jykang/.nix";
|
||||
"/nix/remote/xmuhk" = "/public/home/xmuhk/.nix";
|
||||
};
|
||||
nfs."${inputs.topInputs.self.config.dns."chn.moe".getAddress "wg1.nas"}:/" =
|
||||
{ mountPoint = "/nix/remote/nas"; hard = false; };
|
||||
@@ -29,35 +28,38 @@ inputs:
|
||||
{ mapper = "swap"; ssd = true; before = [ "root1" ]; };
|
||||
};
|
||||
swap = [ "/dev/mapper/swap" ];
|
||||
resume = "/dev/mapper/swap";
|
||||
rollingRootfs = {};
|
||||
};
|
||||
grub.windowsEntries."08D3-10DE" = "Windows";
|
||||
nix =
|
||||
{
|
||||
marches =
|
||||
[
|
||||
"znver2" "znver3" "znver4"
|
||||
# FXSR SAHF XSAVE
|
||||
"sandybridge"
|
||||
# FXSR PREFETCHW RDRND SAHF
|
||||
"silvermont"
|
||||
# SAHF FXSR XSAVE RDRND LZCNT HLE
|
||||
"haswell"
|
||||
# FXSR HLE LZCNT PREFETCHW RDRND SAHF XSAVE
|
||||
"broadwell"
|
||||
# FXSR HLE LZCNT PREFETCHW RDRND SAHF SGX XSAVE
|
||||
"skylake" "cascadelake"
|
||||
# SAHF FXSR XSAVE RDRND LZCNT HLE PREFETCHW SGX MOVDIRI MOVDIR64B AVX512VP2INTERSECT KEYLOCKER
|
||||
"tigerlake"
|
||||
# AVX-VNNI CLDEMOTE GFNI-SSE HRESET KL LZCNT MOVDIR64B MOVDIRI PCONFIG PREFETCHW PTWRITE RDRND
|
||||
# SERIALIZE SGX WAITPKG WIDEKL XSAVE XSAVEOPT
|
||||
"alderlake"
|
||||
];
|
||||
remote.master.host.srv2-node0 = [ "skylake" ];
|
||||
};
|
||||
nix.marches =
|
||||
[
|
||||
"znver2" "znver3" "znver4"
|
||||
# FXSR SAHF XSAVE
|
||||
"sandybridge"
|
||||
# FXSR PREFETCHW RDRND SAHF
|
||||
"silvermont"
|
||||
# SAHF FXSR XSAVE RDRND LZCNT HLE
|
||||
"haswell"
|
||||
# FXSR HLE LZCNT PREFETCHW RDRND SAHF XSAVE
|
||||
"broadwell"
|
||||
# FXSR HLE LZCNT PREFETCHW RDRND SAHF SGX XSAVE
|
||||
"skylake" "cascadelake"
|
||||
# SAHF FXSR XSAVE RDRND LZCNT HLE PREFETCHW SGX MOVDIRI MOVDIR64B AVX512VP2INTERSECT KEYLOCKER
|
||||
"tigerlake"
|
||||
# AVX-VNNI CLDEMOTE GFNI-SSE HRESET KL LZCNT MOVDIR64B MOVDIRI PCONFIG PREFETCHW PTWRITE RDRND
|
||||
# SERIALIZE SGX WAITPKG WIDEKL XSAVE XSAVEOPT
|
||||
"alderlake"
|
||||
];
|
||||
nixpkgs = { march = "znver4"; cuda.capabilities = [ "8.9" ]; };
|
||||
sysctl.laptop-mode = 5;
|
||||
};
|
||||
hardware = { gpu = { type = "nvidia"; nvidia.dynamicBoost = true; }; legion = {}; };
|
||||
hardware =
|
||||
{
|
||||
cpus = [ "amd" ];
|
||||
gpu = { type = "nvidia"; nvidia.dynamicBoost = true; };
|
||||
legion = {};
|
||||
};
|
||||
services =
|
||||
{
|
||||
samba =
|
||||
@@ -72,17 +74,14 @@ inputs:
|
||||
};
|
||||
};
|
||||
sshd = {};
|
||||
xray =
|
||||
{
|
||||
client.dnsmasq.hosts = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(name: { inherit name; value = "144.34.225.59"; })
|
||||
[ "mirism.one" "beta.mirism.one" "ng01.mirism.one" "initrd.vps6.chn.moe" ])
|
||||
)
|
||||
// { "4006024680.com" = "192.168.199.1"; };
|
||||
xmuClient = {};
|
||||
};
|
||||
xray.client.dnsmasq.hosts = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(name: { inherit name; value = "144.34.225.59"; })
|
||||
[ "mirism.one" "beta.mirism.one" "ng01.mirism.one" "initrd.vps6.chn.moe" ])
|
||||
)
|
||||
// { "4006024680.com" = "192.168.199.1"; };
|
||||
acme.cert."debug.mirism.one" = {};
|
||||
nix-serve = {};
|
||||
misskey.instances.misskey.hostname = "xn--qbtm095lrg0bfka60z.chn.moe";
|
||||
beesd."/" = { hashTableSizeMB = 4 * 128; threads = 4; };
|
||||
@@ -105,17 +104,17 @@ inputs:
|
||||
};
|
||||
};
|
||||
ollama = {};
|
||||
podman = {};
|
||||
docker = {};
|
||||
ananicy = {};
|
||||
keyd = {};
|
||||
lumericalLicenseManager = { macAddress = "74:5d:22:c7:d2:97"; autoStart = false; };
|
||||
searx = {};
|
||||
kvm.aarch64 = true;
|
||||
kvm = {};
|
||||
nspawn = [ "arch" "ubuntu-22.04" "fedora" ];
|
||||
nfs."/" = [ "192.168.84.0/24" ];
|
||||
nfs."/" = "192.168.84.0/24";
|
||||
};
|
||||
bugs = [ "xmunet" "backlight" "amdpstate" "iwlwifi" ];
|
||||
packages = { mathematica = {}; vasp = {}; android-studio = {}; lumerical = {}; };
|
||||
packages = { android-studio = {}; mathematica = {}; vasp = {}; lammps = {}; };
|
||||
user.users = [ "chn" "test" ];
|
||||
};
|
||||
boot.loader.grub =
|
||||
{
|
||||
|
||||
@@ -13,10 +13,11 @@ nix:
|
||||
remote: ENC[AES256_GCM,data:uosYkxTCB0wiY+Uufk//OcBZFN3EzbZoQGZ95M9eZMjQ5AobAZqosi4laE+EMcZL1CqYqlWXaSoEUOB8biUaZPseo+1AX1TlmUgZ7QpkfOX0VKZu01C6C+lVyqVqMFq6z1BFyX/oeITMIfnd4a/2KwJCHLAZ4hMkJ5p+aJwByKGa3N/2m41HH/1S3z7pYQWj7YJxunTPPG6WNSiRncQki11rvmddwnXmsBF89+jW1Phge8U295haC57T5oIGPxR645IeTK4ZUlL8eVuZ+BhsnwbkYcaxvjSwe+DOIVPupR8GW+gis7KxwE89kqvnQhinamexcPUz4lGHlqO/Xn6jrJx6T/wXF+19epAzeHapYte3dTWNsdPwPLPJihT16YT5fwrLnH3zq8kexWz1crmnCGUoaBs4S2tHWHLgv2lTv0IHLx5F6ijpDBj/Avg9YILIURzdeea+rBxdycHasUDTVlJtYKRH5J+WbAKWI+oJ5qmXjIRUYL+O9xIUfOGO+1b3xs8MYxRWuvDV2P88N8vN,iv:yQQp5wjbSVn1oia5yL7d6GF9Vo704G0iOQRGMbzQHzg=,tag:bpBag5y5n+7ojOa8QOcDvA==,type:str]
|
||||
searx:
|
||||
secret-key: ENC[AES256_GCM,data:KhIP+Rz3rMfNgPEGTlKGvm6gl1/ZuPI=,iv:GcaLEJHKJO3n6IaeiFr9PaJ6eNx04/VjX3UgmBF429g=,tag:HkplyH9hTHUaEZ709TyitA==,type:str]
|
||||
xray-xmu-client:
|
||||
uuid: ENC[AES256_GCM,data:XiUkReTJLAxZNWFVeD6EiOtUX5tsyPLFi6QyDBdHyB4v5/mD,iv:QppdtP2CFDEVhlrmDJKYBGc1zYGJvpGYxLfsBAMxDSI=,tag:jzMSFRit+aBzWMkaa3+5hA==,type:str]
|
||||
cookie: ENC[AES256_GCM,data:0jqSEZloX2/c8Zg4WTKkLw==,iv:BKLm1KMoRrH0uO6hPMsv2a7sG0AwNRrdbpmABP4BszA=,tag:pBs+rQIhhNO4Qr6q1V3MUA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
enc: |
|
||||
@@ -36,7 +37,8 @@ sops:
|
||||
OUlxNjdQaXdXMkZ6bnV1ek4yZ2dpbkEKpKGOAxo5Eef2jtGrg4iSzmGCeg+vTgvu
|
||||
+K8b+O19MIkGMDBm6UbYUPtc/7eqoEZRiTUzNMTmfkLVS4ul5zou9A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-08-01T07:22:50Z"
|
||||
mac: ENC[AES256_GCM,data:f4fultak/52Gq6nn1hJJYw3AMeuR3J6gcxtPDG/WKkNV+B+gtabWp5R8J8wLWFJ4C1ZsGHDYMTvTfSUlDVdm1dGpxJtFzdfoBBdajj8s2mju6nMQUFoNFRmHDZEQBdIzfXpob1+7Rsr+bBmg7HnFvjR0ozuaQP9QHsHEZxJVbnU=,iv:xh4OIom1TFgKralXw6rrOR/1xpD5SpY2tHfJUq6v41o=,tag:0QOtWN6DcGf3/gorusbXtQ==,type:str]
|
||||
lastmodified: "2025-05-24T11:27:02Z"
|
||||
mac: ENC[AES256_GCM,data:uNkThOX3NEUeiaJVavZ0rCpQRT+GbRXADiMuAwb/tg38fBrKQeUO9ohicl/UfiDFRTfCaiuH3T757jX2b51go2s0B6n7DOvPYYZ5EWGnM69RFxrdDfWfge8n8/SHmuKR9dPJb/eSa8HAs8uDnqBPoR5SqG5lnyZs3a7P/kjK2T4=,iv:snmnuYmcuyhGs4YrIGFLmDffFE9yecB/vsM0MvxBR4k=,tag:vbqA7jvVCFHvLoLmKbfO4g==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
model.arch = "aarch64";
|
||||
system =
|
||||
{
|
||||
fileSystems =
|
||||
{
|
||||
mount.btrfs."/dev/disk/by-partlabel/r2s-root" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
swap = [ "/nix/swap/swap" ];
|
||||
};
|
||||
network = {};
|
||||
};
|
||||
services =
|
||||
{
|
||||
sshd = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -16,8 +16,10 @@ inputs:
|
||||
{ "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
swap = [ "/nix/swap/swap" ];
|
||||
rollingRootfs = {};
|
||||
};
|
||||
};
|
||||
hardware.cpus = [ "intel" ];
|
||||
services =
|
||||
{
|
||||
sshd.passwordAuthentication = true;
|
||||
@@ -60,7 +62,7 @@ inputs:
|
||||
];
|
||||
};
|
||||
};
|
||||
packages = { vasp = {}; lumerical = {}; };
|
||||
packages.vasp = {};
|
||||
user.users = [ "chn" "xll" "zem" "yjq" "gb" "wp" "hjp" "wm" "GROUPIII-1" "GROUPIII-2" "GROUPIII-3" "zgq" ];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -24,7 +24,6 @@ inputs:
|
||||
sshd.motd = true;
|
||||
xray.client.dnsmasq.extraInterfaces = [ "eno146" ];
|
||||
beesd."/" = { hashTableSizeMB = 128; threads = 4; };
|
||||
xrdp = { enable = true; hostname = [ "srv1.chn.moe" ]; };
|
||||
samba = { hostsAllowed = ""; shares = { home.path = "/home"; root.path = "/"; }; };
|
||||
};
|
||||
packages.packages._prebuildPackages =
|
||||
|
||||
@@ -7,13 +7,18 @@ inputs:
|
||||
model.type = "server";
|
||||
system =
|
||||
{
|
||||
fileSystems.mount = let inherit (inputs.config.nixos.model.cluster) clusterName nodeName; in
|
||||
fileSystems =
|
||||
{
|
||||
vfat."/dev/disk/by-partlabel/${clusterName}-${nodeName}-boot" = "/boot";
|
||||
btrfs."/dev/disk/by-partlabel/${clusterName}-${nodeName}-root1" =
|
||||
{ "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
nfs."${inputs.topInputs.self.config.dns."chn.moe".getAddress "wg1.pc"}:/" =
|
||||
{ mountPoint = "/nix/remote/pc"; hard = false; };
|
||||
mount = let inherit (inputs.config.nixos.model.cluster) clusterName nodeName; in
|
||||
{
|
||||
vfat."/dev/disk/by-partlabel/${clusterName}-${nodeName}-boot" = "/boot";
|
||||
btrfs."/dev/disk/by-partlabel/${clusterName}-${nodeName}-root1" =
|
||||
{ "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
nfs."${inputs.topInputs.self.config.dns."chn.moe".getAddress "wg1.pc"}:/" =
|
||||
{ mountPoint = "/nix/remote/pc"; hard = false; };
|
||||
};
|
||||
swap = [ "/nix/swap/swap" ];
|
||||
rollingRootfs = {};
|
||||
};
|
||||
nixpkgs.cuda.capabilities =
|
||||
[
|
||||
@@ -75,19 +80,8 @@ inputs:
|
||||
};
|
||||
};
|
||||
};
|
||||
packages.vasp = {};
|
||||
user.users =
|
||||
[
|
||||
# 组内
|
||||
"chn" "xll" "zem" "yjq" "gb" "wp" "hjp" "wm" "qmx"
|
||||
# 组外
|
||||
"yxf" # 小芳同志
|
||||
"hss" # 还没见到本人
|
||||
"zzn" # 张宗南
|
||||
"zqq" # 庄芹芹
|
||||
"zgq" # 希望能接好班
|
||||
"lly" # 这谁?
|
||||
];
|
||||
packages = { vasp = {}; mumax = {}; lammps = {}; };
|
||||
user.users = [ "chn" "xll" "zem" "yjq" "gb" "wp" "hjp" "wm" "lly" "yxf" "hss" "zzn" "zqq" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,29 +5,27 @@ inputs:
|
||||
nixos =
|
||||
{
|
||||
model.cluster.nodeType = "master";
|
||||
hardware.cpus = [ "intel" ];
|
||||
system =
|
||||
{
|
||||
nixpkgs.march = "skylake";
|
||||
network =
|
||||
{
|
||||
static.eno2 = { ip = "192.168.178.1"; mask = 24; };
|
||||
wireless = [ "457的5G" ];
|
||||
masquerade = [ "eno2" ];
|
||||
trust = [ "eno2" ];
|
||||
};
|
||||
nix.remote.slave = {};
|
||||
fileSystems.swap = [ "/dev/disk/by-partlabel/srv2-node0-swap" ];
|
||||
};
|
||||
services =
|
||||
{
|
||||
xray.client = { dnsmasq = { extraInterfaces = [ "eno2" ]; hosts."hpc.xmu.edu.cn" = "121.192.191.11"; }; };
|
||||
beesd."/" = { hashTableSizeMB = 16 * 128; loadAverage = 8; };
|
||||
xrdp = { enable = true; hostname = [ "srv2.chn.moe" ]; };
|
||||
samba = { hostsAllowed = ""; shares = { home.path = "/home"; root.path = "/"; }; };
|
||||
groupshare = {};
|
||||
hpcstat = {};
|
||||
ollama = {};
|
||||
sshd = { groupBanner = true; motd = true; };
|
||||
speedtest = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -6,9 +6,13 @@ mariadb:
|
||||
hpcstat:
|
||||
key: ENC[AES256_GCM,data:+Z7MRDkLLdUqDwMrkafFKkBjeCkw+zgRoAoiVEwrr+LY0uMeW8nNYoaYrfz6Ig8CMCDgX3n/DMb0ibUeN32j3HShQIStbtUxRPGpQMyH+ealbvgskGriTFpST4VPyQxNACkUpq/e+sh2CmLbKkSxhamkjKOXwsfqrBlgVbEkp7u7HkWGuAaYL1oPGt0Q94fWXwH0UVhRYZYQ2iFA/S6SEZY8gxaTIGDKUdWU9+fOHzPQ5WfhxtKYU4p4ydyfYsAt6ffqnPSx/SI72GsUCOJ4981JX8TuvnEzx3gQLVFYheK6NibTWCy6eODbvguieVOTHSvCPTrHmoP12lHVWU2kKzLwv70Jl7sXyzKHYROG0D+/z/4DKlNeotKM/IA0q2cST08/lwSKN7WDDmrt+O6xXhvwby28ZYKEsSvvrfV+VIKzHPl84ZKbUEX5xv/GHc3THfznUvKKz5PzDiqrkjCkEt5PRMsVW9A6MU1+QEUr+sXLLtcUd2CCL87c8CpwNHJx1us6vJ4ji1gu0PGoT+60,iv:yU6j9W2Hs2D34uHMJqqPFbNy2pNEZY2kzXoNdhPMSmA=,tag:TNvEfMVrhu7HrNxY8qe5mg==,type:str]
|
||||
wireless:
|
||||
#ENC[AES256_GCM,data:n9OPSJsB7yNk,iv:xQzKJxqPB7uT83m/B4UoOje6NQbPLhuHR7Hp93oNz8A=,tag:gtsTx6ALnS/7fIDd7VimOg==,type:comment]
|
||||
409的5G: ENC[AES256_GCM,data:K9wm3zedoil7jHgTcb+VmbdbkG2dgrMdr3BmDRUHDVADqLANMvnUMSecggYTO4HaiI9q6uv2/BSkluanD5K4Dw==,iv:7dGET3ULKlnaDMVmkuXDek+hQPLZ2VUbPqvEOX+5jlQ=,tag:MBGmQ0NNNqX+T9EsBiWCaw==,type:str]
|
||||
#ENC[AES256_GCM,data:xrg3Wxj/ghbWgg==,iv:6stu7voI5no2Y3YmnMrvTS8hev3eqjoWAyD5zTgyehc=,tag:cxkS7y7S1oM+/SJmlT10fw==,type:comment]
|
||||
457的5G: ENC[AES256_GCM,data:QjHlyGU4JIYymyh41T+c33T3EOpbqDOoD3U+v6/BzjlWLLeZQXU2hwPCVh4fi2bwn7yNkp4ygAYmFPVPZWoT1A==,iv:Tc6Guzsn5hkjWH6UWSb1KlfWCBXIi2OWdn/wttmCXnQ=,tag:FhyH6JmjSTuqSeFy+GyQhg==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
enc: |
|
||||
@@ -28,7 +32,8 @@ sops:
|
||||
M0xoL1dQR0kvMWpzN0RMNWVCTFQxNFUKj9LPjBo5NGOrGYNvu8qZ13PLYjLEWllU
|
||||
LARzEn4XgkeHckouwvxZYMCx7WxmAruRWaOvnxTIczzSNP7wIrqnkA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-07-12T04:13:47Z"
|
||||
mac: ENC[AES256_GCM,data:W+e5d1scvV24AdVdl7Pisp9HxsXQ/tPjN2NV/Bd0RXZNBRB7LNQrSfk1GadboBnihW0ctAQOFk66PZsxwE2czfFL2/yzFxm9Cf11Mc822ZL3BwjnQBK4uR9LJrbjL7x1lFUk9v0AIPhjrir8F6dcX8mq6++hHNN0wjGaH3J9E0Y=,iv:RK7e4Dxog+Qsgk6gxK0f8PN8oF9bjWIrTyYK67Cdras=,tag:QSKsETYXbhnvhhjavP4UiA==,type:str]
|
||||
lastmodified: "2025-04-10T10:44:43Z"
|
||||
mac: ENC[AES256_GCM,data:6EeWT8IiCGyRdR/9WDoTTM8bBuhzf2LtP1kahCgfvFpU6g5HB+qG5O0eXaL0DMKg7OQJKHIS/wZVaEierVwno0CnP1WR7y9l6Rlab2nVG4YCNkEkwqZgIWFOUi0aZrZQc7WC3rUk1gxiJK38nEa4ebk8oqAbyHyKHsFAeUcMbqA=,iv:oqRLvYsXct+OwcymXslEH4o03vLNeV2eU/4zK8R+gKs=,tag:0d1DYjCGRewUd4aHPIpFSw==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
version: 3.9.2
|
||||
|
||||
@@ -4,6 +4,7 @@ inputs:
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
hardware.cpus = [ "amd" ];
|
||||
system =
|
||||
{
|
||||
nixpkgs.march = "znver3";
|
||||
@@ -13,7 +14,6 @@ inputs:
|
||||
{ ip = "192.168.178.2"; mask = 24; gateway = "192.168.178.1"; dns = "192.168.178.1"; };
|
||||
trust = [ "enp58s0" ];
|
||||
};
|
||||
fileSystems.swap = [ "/nix/swap/swap" ];
|
||||
};
|
||||
services.beesd."/".hashTableSizeMB = 64;
|
||||
};
|
||||
|
||||
@@ -41,9 +41,10 @@
|
||||
独立的 IPv6 免费,但暂不支持(技术上没有准备好,如果有人有需要我就去准备)。
|
||||
* 只卖朋友和朋友的朋友(总之得有人保证别拿去做坏事)。
|
||||
若此定价对您来说仍然难以接受,可以联系我,打五折或者免费。
|
||||
* 此价格 2025 年 9 月 17 日前有效。之后大概率也不会调整,但保留调整的权利。
|
||||
* 此价格有效期三个月(2025-05-17 至 2025-08-17)。
|
||||
05-17 前免费,08-17 后定价会视情况调整(例如将流量计入收费项目,内存部分相应降价),在那之前会公布新的定价。
|
||||
* 预计收入无法覆盖成本。如果某个月的收入高于成本,承诺会将多出的部分捐出去。
|
||||
* 非 kvm 虚拟机的服务(例如,只跑一个 podman 容器,只跑某一个服务)定价私聊,大致上是上方价格再加上我的工作成本(事少的免费,事多的就要实收了)。
|
||||
* 非 kvm 虚拟机的服务(例如,只跑一个 docker 容器,只跑某一个服务)定价私聊,大致上是上方价格再加上我的工作成本(事少的免费,事多的就要实收了)。
|
||||
* 配置随时可以调整。所以按照自己这个月够用的来就行,不需要为未来留余量。但每次调整都需要重启虚拟机。
|
||||
* 母鸡价格 40 美元每月,配置在下方列出。
|
||||
* 机房: LAX3 (IP:srv3.chn.moe)
|
||||
|
||||
@@ -15,6 +15,7 @@ inputs:
|
||||
btrfs."/dev/mapper/root1" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
swap = [ "/dev/mapper/swap" ];
|
||||
rollingRootfs = {};
|
||||
};
|
||||
nixpkgs.march = "haswell";
|
||||
initrd.sshd = {};
|
||||
@@ -30,12 +31,19 @@ inputs:
|
||||
};
|
||||
};
|
||||
};
|
||||
hardware.cpus = [ "intel" ];
|
||||
services =
|
||||
{
|
||||
beesd."/" = { hashTableSizeMB = 128; threads = 4;};
|
||||
sshd = {};
|
||||
nixvirt.instance =
|
||||
{
|
||||
alikia =
|
||||
{
|
||||
memory.sizeMB = 1024;
|
||||
cpu.count = 1;
|
||||
network = { address = 2; portForward.tcp = [{ host = 5689; guest = 22; }]; };
|
||||
};
|
||||
pen =
|
||||
{
|
||||
memory.sizeMB = 512;
|
||||
@@ -53,24 +61,20 @@ inputs:
|
||||
{ host = 22000; guest = 22000; }
|
||||
];
|
||||
udp = [{ host = 22000; guest = 22000; }];
|
||||
web = { httpsProxy = [ "natsume.nohost.me" ]; httpProxy = [ "natsume.nohost.me" ]; };
|
||||
web = [ "natsume.nohost.me" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
test =
|
||||
{
|
||||
owner = "chn";
|
||||
memory.sizeMB = 4096;
|
||||
cpu.count = 4;
|
||||
memory.sizeMB = 512;
|
||||
cpu.count = 1;
|
||||
network =
|
||||
{
|
||||
address = 4;
|
||||
vnc.openFirewall = false;
|
||||
portForward =
|
||||
{
|
||||
tcp = [{ host = 5693; guest = 22; }];
|
||||
web = { httpsProxy = [ "example.chn.moe" ]; httpProxy = [ "example.chn.moe" ]; };
|
||||
};
|
||||
portForward = { tcp = [{ host = 5693; guest = 22; }]; web = [ "example.chn.moe" ]; };
|
||||
};
|
||||
};
|
||||
reonokiy =
|
||||
@@ -79,21 +83,6 @@ inputs:
|
||||
cpu.count = 4;
|
||||
network = { address = 5; portForward.tcp = [{ host = 5694; guest = 22; }]; };
|
||||
};
|
||||
yumieko =
|
||||
{
|
||||
memory.sizeMB = 8 * 1024;
|
||||
cpu.count = 8;
|
||||
network =
|
||||
{
|
||||
address = 6;
|
||||
portForward =
|
||||
{
|
||||
tcp = [{ host = 5695; guest = 22; }];
|
||||
web = { httpsProxy = [ "littlewing.yumieko.com" ]; httpProxy = [ "littlewing.yumieko.com" ]; };
|
||||
};
|
||||
};
|
||||
storage.iso = "${inputs.topInputs.self.src.guix}";
|
||||
};
|
||||
};
|
||||
rsshub = {};
|
||||
misskey.instances =
|
||||
@@ -103,23 +92,23 @@ inputs:
|
||||
synapse.matrixHostname = "synapse.chn.moe";
|
||||
matrix = { port = 8009; redisPort = 6380; };
|
||||
};
|
||||
vaultwarden = {};
|
||||
photoprism = {};
|
||||
vaultwarden.enable = true;
|
||||
photoprism.enable = true;
|
||||
nextcloud = {};
|
||||
freshrss = {};
|
||||
send = {};
|
||||
huginn = {};
|
||||
httpapi = {};
|
||||
gitea = {};
|
||||
httpapi.enable = true;
|
||||
gitea = { enable = true; ssh = {}; };
|
||||
grafana = {};
|
||||
fail2ban = {};
|
||||
xray = { server = {}; xmuPersist = {}; };
|
||||
podman = {};
|
||||
xray.server = {};
|
||||
docker = {};
|
||||
peertube = {};
|
||||
nginx.applications.webdav.instances."webdav.chn.moe" = {};
|
||||
open-webui.ollamaHost = "192.168.83.3";
|
||||
};
|
||||
user.users = [ "chn" "aleksana" "alikia" "pen" "reonokiy" "yumieko" ];
|
||||
user.users = [ "chn" "aleksana" "alikia" "pen" "reonokiy" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
wireguard: ENC[AES256_GCM,data:Coe4iIEnJVDb4a9KUVTRkXl4kng5Zo6x1Iyr0ErgR2b9bN287mvO6jPUPSc=,iv:fiNUUKobJjitcoxBemIah5Cl5+dSz2Q7sbiOT8bDrRM=,tag:rHfNeRGTxnyVYAu8P/2ewA==,type:str]
|
||||
nixvirt:
|
||||
alikia: ENC[AES256_GCM,data:sP3sWN0RrBU=,iv:TetUcaxsRXl0QsGAyXbVUAW12AXjChVN1/X+ku+3nO4=,tag:kBupoPqVlwHuCnwVdBJBKQ==,type:str]
|
||||
pen: ENC[AES256_GCM,data:okvzUul3UXk=,iv:hcBhsUMP8jdhhKuKdHD1lZi8ixNAC729HfMQ79UzyNk=,tag:SRRav39ScHn0O/sf86CIOw==,type:str]
|
||||
test: ENC[AES256_GCM,data:MYlMmzgbW9c=,iv:q1qPAwFTh0fj2IHBIlnrOMbTU2BnwIYzOFUHVqWCY/Q=,tag:Mb2bJJemg/LxpKI5whNvQw==,type:str]
|
||||
reonokiy: ENC[AES256_GCM,data:J/ZM0Vavmnk=,iv:ZT1cMF/JWLWmXyBx331XkBQerOhLJeOd0a53jcSC4S4=,tag:/WCwzOg5LlAS5ZaiI5DSIw==,type:str]
|
||||
yumieko: ENC[AES256_GCM,data:Nugm6tP4jxg=,iv:HweUreniPs3eDs1ucu/G/P/JZ4jfSaOAiLD2o5WeOUo=,tag:eoc1cVG7CD5WFoawDUUpnw==,type:str]
|
||||
nginx:
|
||||
detectAuth:
|
||||
chn: ENC[AES256_GCM,data:cek6iIlJXgU191uzq44rTw==,iv:r7aMj5UzH1sbKkxvS8oyw6kpIcpRygD4ype8qkmnNa0=,tag:x2jWZnnFCO0sHj/OS2BQbA==,type:str]
|
||||
@@ -84,8 +84,6 @@ peertube:
|
||||
open-webui:
|
||||
openai: ENC[AES256_GCM,data:5B1wPAOx3GsLDoYBKHWFzoyXFmn93fdcq6UC2rCt/P5zYLA4VNzfsp0=,iv:Y2gTLCmwB5wY4dhN73HRvTqSMVXbAEd+RjRbgUEuTeE=,tag:vcfNhXpG0C3twFBsm7PHwA==,type:str]
|
||||
webui: ENC[AES256_GCM,data:Lg32DZ5GC+AYzWc4WloNMQlnpsqW67s5/kXzYwE=,iv:ECncgdYoLkX9GUOX26MXFSO8JOZahUDjTdKV87IRNJ8=,tag:J/5tTR3MI0iGIVDrlacYEg==,type:str]
|
||||
xray-xmu-client:
|
||||
cookie: ENC[AES256_GCM,data:z1KI3CUfPqyiI/B/qgrNhg==,iv:QEjUlMkkF/fdwwEIGiJJ5UxFGw869qAnpApmWaRn3GY=,tag:EbdJsYEslwJbARxDoEWrDA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -106,7 +104,7 @@ sops:
|
||||
d0h3aDh5QXFZYWJFdmNVYnJxQ3pBeVUKTl0XVvtwJcz+RpSylgDPl/R8msInxvWX
|
||||
eQGmrDHibeE1V+KSDiuNzC4MVRIrOnh1beHrhnVQ86HwPVgJqs2FoQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-08-01T05:55:35Z"
|
||||
mac: ENC[AES256_GCM,data:MEgCbEJ/bwx3EVWVYQjb1RbNx8OlJkqelHPbMG5DzSRgcBcllptTFCanLIPZrg4FihkHx3b41Q5xsCXbras1njh4R1FeyLVVGZH7pYjZaPF2MRaD8nYeCHKlItWUVvHQTf5bRrTOOQoo4Kmn2by/xdMWwZlZwt0aBoGnEYBxGf0=,iv:lrPlg8cM5qPgQPpIUHF6WBVglTe9YQtI28hfJSgJ1vU=,tag:tjucRsf+tt9F03Mhjf+jeg==,type:str]
|
||||
lastmodified: "2025-06-09T01:35:04Z"
|
||||
mac: ENC[AES256_GCM,data:q2BolEBB6Ik8yx6NHnnE3Wcl2rGVZN86dpfLJrrFOxWd8fZyfBQ/00v4dUZSZw0aQoMj1V2RBDyVtScuRiH0NVb6+RfX+0t3zTEf6guuJdurczLBz9+D51+Th3KE1uk+UjI7J+Q/TOWTvoGMj8P4XZCXQsCDIct/vbLGqNB9CgM=,iv:/6xR7KXXLejm9Iuqcxc/7IqLEckNhmaJTKzJGonSrng=,tag:XdeCoEkHefw2HqTGSchUJA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
25
devices/test-pc-vm/default.nix
Normal file
25
devices/test-pc-vm/default.nix
Normal file
@@ -0,0 +1,25 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
system =
|
||||
{
|
||||
fileSystems =
|
||||
{
|
||||
mount =
|
||||
{
|
||||
vfat."/dev/disk/by-partlabel/test-boot" = "/boot";
|
||||
btrfs."/dev/disk/by-partlabel/test-root1" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
rollingRootfs = {};
|
||||
};
|
||||
nixpkgs.march = "znver4";
|
||||
network = {};
|
||||
};
|
||||
hardware.cpus = [ "amd" ];
|
||||
services.sshd = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
26
devices/test-pc-vm/secrets.yaml
Normal file
26
devices/test-pc-vm/secrets.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
nixvirt:
|
||||
chn: ENC[AES256_GCM,data:0llBtdnPLl8=,iv:0w0huoNCvIiaL77Thj1iAwRY5edDlN7I4mMwiNKCzOc=,tag:Eh1b7dymn7jQtL5/rsxC1Q==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTcldLRERrOHdadVA4RXdQ
|
||||
dmsxL1o5aDdJTitqdXBzRWxqVmZKUzFtTlUwCnc2a1N4WUNEVUhsSlFuSExjR0Rl
|
||||
TlFnNjVpUkpmbWdxYW5oblk5dGQ0THMKLS0tIDFBa0FKQXBPYThFTUwvd2tIaU9p
|
||||
TERYVkp3dkUxU2ZaTnFRamRKclRRa1EKosUuvJXekUIxIHL8s/QuZf+hCXQS5dMC
|
||||
HqZ74f/jvIW8i/Etu29VtK3n8MD8W1EenhJjfxOvhpRpLpzQP2GImg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1vgqvdqqe3mn0gvh0hydvu9c5f9yn5vek08cagyvwjhyta6utpvuq00g9c2
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMK2F0R1JRR2t6NDhXVnVD
|
||||
Unh5QmxDaGJtWmhsb1ZDRkMzUlpSeU9GL3lNCkU0ZVYxaWs3MHZDQlNHS25WMTl3
|
||||
VVVtQUlxeXNQNVQrSTdSbWYzSmlPVGMKLS0tIDlyRm1tYlR3WU9ISjc2T3BSY2FP
|
||||
Z3h2QWh6eDB6L1krbU9SS050dUhEamMKHnvdCmLuhuIfeBRs3LJ6IEatqrlMJNnc
|
||||
vhPTVgfn+M8dGo+odTTwlvr5XGzE5cMSxGtdSE33JsbBFfVyaPCFjQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-05-16T05:29:11Z"
|
||||
mac: ENC[AES256_GCM,data:s1HBVQUDbYP63EntEXe/+9mqFj2zGEtx3ibFauBYmjJvtvw2hs44ODNebMxjasT8zTYICJWWZJxwMvpUs/CbcmSjPAXTV8379lzlOmG2wZLezF+9jWdJi3ZDvM9Y1D0/4GnaIRHof/+kPn/ykFE/gQhP5PQ4OtoV+VTR2fuwDaA=,iv:TUTM8tyZxiAjU3afazfmse+LL53hrSFSCIX4KIDyQq8=,tag:Vx4GsOPAXaZz0rEjsJS8sw==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
52
devices/test-pc/default.nix
Normal file
52
devices/test-pc/default.nix
Normal file
@@ -0,0 +1,52 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
system =
|
||||
{
|
||||
fileSystems =
|
||||
{
|
||||
mount =
|
||||
{
|
||||
vfat."/dev/disk/by-partlabel/test-boot" = "/boot";
|
||||
btrfs."/dev/disk/by-partlabel/test-root1" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
rollingRootfs = {};
|
||||
};
|
||||
nixpkgs.march = "znver4";
|
||||
network = { dhcp = [ "nixvirt" ]; bridge.nixvirt.interfaces = [ "enp1s0" ]; };
|
||||
};
|
||||
hardware.cpus = [ "amd" ];
|
||||
services =
|
||||
{
|
||||
sshd = {};
|
||||
nixvirt =
|
||||
{
|
||||
subnet = 123;
|
||||
instance =
|
||||
{
|
||||
chn =
|
||||
{
|
||||
memory = { sizeMB = 2048; dedicated = true; };
|
||||
cpu = { count = 4; set = builtins.genList builtins.toString 4; };
|
||||
network =
|
||||
{
|
||||
bridge = true;
|
||||
vnc.port = 15901;
|
||||
};
|
||||
};
|
||||
chn2 =
|
||||
{
|
||||
owner = "chn";
|
||||
memory.sizeMB = 2048;
|
||||
cpu.count = 4;
|
||||
network = { address = 3; portForward.tcp = [{ host = 5694; guest = 22; }]; };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
27
devices/test-pc/secrets.yaml
Normal file
27
devices/test-pc/secrets.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
nixvirt:
|
||||
chn: ENC[AES256_GCM,data:0llBtdnPLl8=,iv:0w0huoNCvIiaL77Thj1iAwRY5edDlN7I4mMwiNKCzOc=,tag:Eh1b7dymn7jQtL5/rsxC1Q==,type:str]
|
||||
chn2: ENC[AES256_GCM,data:vlvFNwMfTMg=,iv:DKgX3DCvkfADF/Pj31bRTx/dfTiMxv/JaeN76Kppob8=,tag:SOioaCz/CvvLn2jB+08THQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2SGQ0R20zci9aU1l4d2Fs
|
||||
YkRZQ1FGUW1vSEd3S3FBdGlSTXB4dW54UVJJCk5MMEFZSzdYTFRQL1FRZUFWTXFh
|
||||
cC90bUx2dkdHUFVoMkhyNjR6U0w1QTAKLS0tIDZHZE4yNlV4cFBTVGN4c3VYZXZ5
|
||||
enZoU21MQ2VJbHlhSnhwUkNXZjV6OXcKzvdz1TNs/PDISx+QSi6cJ8vWNtZo4jfD
|
||||
qsrwpxvHou/wptLzYg5gXQuXB0izpOW/AtqA1XqLcTUbLzcRhqFvMg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age17a8y4yr2ckuek67rt786ujuf7705gvj3vv6ezktxxmgayea9zcyqet7hgc
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtWUJVZmdVbWxXck5EY0tR
|
||||
cFRwZTlWVVpObjFneE95bXNPSUxjNE1DTlg0ClNQRy8yVmF6QWxuY3RGLzdJVEE4
|
||||
WXEwb1NGVUlJWFRqeWlyN1J0eE15QnMKLS0tIENRQWJ0VXlzNHV6MXh0QUVRZlJu
|
||||
RFFteDMzeGltVER3QjlpdUllZVNJS3MKyOMAu5xYr1z0YlNDFvaE4l4bposMTPUJ
|
||||
K13yerfRBxDlOrMhG/lSovusBPkmS3HejDedGgYi1WMvgLuOkNWZ2A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-05-18T01:55:44Z"
|
||||
mac: ENC[AES256_GCM,data:wGHagytOT30EgjPezkaLXrqml/tn8oMzplYgThb9JbnXJzpCMnZnXeAlnRW/zdXY+Vt+kRfGCm2W/3sif5wB+gu5DCIeGC6OZy9brMVIQLceQ6Wp7IwPTDjMIGYtqe+T3QX6LFAMPUVZOHNBL9eRdO27G2TGP1ojH69MwNt4aQo=,iv:Rn26bQ8crsVFbLAxPcvLeQWwRP484rS/UFnmg8xeTwc=,tag:zs4S6VPNKFUZU6xxC2rIuQ==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
29
devices/test/default.nix
Normal file
29
devices/test/default.nix
Normal file
@@ -0,0 +1,29 @@
|
||||
inputs:
|
||||
{
|
||||
config =
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
system =
|
||||
{
|
||||
fileSystems =
|
||||
{
|
||||
mount =
|
||||
{
|
||||
vfat."/dev/disk/by-partlabel/test-boot" = "/boot";
|
||||
btrfs."/dev/disk/by-partlabel/test-root1" = { "/nix" = "/nix"; "/nix/rootfs/current" = "/"; };
|
||||
};
|
||||
rollingRootfs = {};
|
||||
};
|
||||
nixpkgs.march = "haswell";
|
||||
network = {};
|
||||
};
|
||||
hardware.cpus = [ "intel" ];
|
||||
services =
|
||||
{
|
||||
sshd = {};
|
||||
nginx = { enable = true; applications.example = {}; };
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
30
devices/test/secrets.yaml
Normal file
30
devices/test/secrets.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
hello: ENC[AES256_GCM,data:y6Kl7kHqgft7T1eiFEeIppvosCACIcVWIQm6TzjS6RgUkJEg17GEZFRy2zTvVg==,iv:wChah8rTtEkkR8pRHO9NdhaGBwsTrrP+tPp7k2SOdn0=,tag:jRdYgJoKz+Q+/m8l/03JoQ==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTcldLRERrOHdadVA4RXdQ
|
||||
dmsxL1o5aDdJTitqdXBzRWxqVmZKUzFtTlUwCnc2a1N4WUNEVUhsSlFuSExjR0Rl
|
||||
TlFnNjVpUkpmbWdxYW5oblk5dGQ0THMKLS0tIDFBa0FKQXBPYThFTUwvd2tIaU9p
|
||||
TERYVkp3dkUxU2ZaTnFRamRKclRRa1EKosUuvJXekUIxIHL8s/QuZf+hCXQS5dMC
|
||||
HqZ74f/jvIW8i/Etu29VtK3n8MD8W1EenhJjfxOvhpRpLpzQP2GImg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age1vgqvdqqe3mn0gvh0hydvu9c5f9yn5vek08cagyvwjhyta6utpvuq00g9c2
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMK2F0R1JRR2t6NDhXVnVD
|
||||
Unh5QmxDaGJtWmhsb1ZDRkMzUlpSeU9GL3lNCkU0ZVYxaWs3MHZDQlNHS25WMTl3
|
||||
VVVtQUlxeXNQNVQrSTdSbWYzSmlPVGMKLS0tIDlyRm1tYlR3WU9ISjc2T3BSY2FP
|
||||
Z3h2QWh6eDB6L1krbU9SS050dUhEamMKHnvdCmLuhuIfeBRs3LJ6IEatqrlMJNnc
|
||||
vhPTVgfn+M8dGo+odTTwlvr5XGzE5cMSxGtdSE33JsbBFfVyaPCFjQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-05-10T03:54:30Z"
|
||||
mac: ENC[AES256_GCM,data:JMr6ybbOk7tDZKUo11bd0xwUfLUuE4DIB5sYOCEVuaXLpDirgMgNSQgayqnnYDLOC7kGA7wDbbcxWhdaT8TcyYwdeha3SgA9mjkruPtOZ4R+ozfLDeqa59h2P+xronaOCDdl9G2JbhLA+k/S2ImBP43iPbcycJViSQs0RrntMxY=,iv:3ZILO4L01r4I2SJWOxe4pp9XLWo6KPPl3t/IbIf07+8=,tag:jhf73Y42fOYmeQS2oA0qSA==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.9.2
|
||||
@@ -17,6 +17,7 @@ inputs:
|
||||
};
|
||||
};
|
||||
swap = [ "/nix/swap/swap" ];
|
||||
rollingRootfs = {};
|
||||
};
|
||||
grub.installDevice = "/dev/disk/by-path/pci-0000:00:04.0";
|
||||
nixpkgs.march = "znver2";
|
||||
|
||||
@@ -20,6 +20,8 @@ xray-server:
|
||||
user9: ENC[AES256_GCM,data:HgSVrry+nKGW9X9N6h8hsI9VETKtSEi+/ZC9QvNZW4zETQxt,iv:ERgmCDPBpboA/+Sxeq6BvWoMxsv3Kkczqb/mbXz9pOk=,tag:bklzRg9toKy//6T8xdtbRw==,type:str]
|
||||
#ENC[AES256_GCM,data:2sHxXec=,iv:aA61+cmDw4rHab7RuRRK3eUDx5d6gpmfw4RpQ6Nd0mc=,tag:H9kovJyn3Te3ir9X234VGA==,type:comment]
|
||||
user10: ENC[AES256_GCM,data:CqrwaZp1fHd/WEGQH3xWI8DZ2/AavCqwTtwZeHmnrct5yoD3,iv:IBOHGQlw+uQt8Ryp/mCDcglfSPNXvvHOjNnrT+7nOHQ=,tag:tEkGEtPaOBK+P3LrQzOLsQ==,type:str]
|
||||
#ENC[AES256_GCM,data:oB64XheVxA==,iv:Ci9apSqTHQ02IFhqVvlC3hO8yWRKELVtJE3H/CUgFyY=,tag:4uV2aYzzZAUW+OZf7QEVPg==,type:comment]
|
||||
user11: ENC[AES256_GCM,data:pk9b5lFhuAfhKMcTUIdlx6eQHn+MJaPQEs6flmUhhHA2ygj/,iv:UGuPrxJPh+V7vSFjmgmBc9vhg7qye5SrNCFiiTcnDk0=,tag:D/B4PTafZe4r/W/dVWC2CA==,type:str]
|
||||
#ENC[AES256_GCM,data:Rw4BWXZutQ==,iv:rXe2i1G/xQkpBl0wh6VIzaNoidCc3JL4sy6v5hcOF/M=,tag:2tZyH8B0ZL7XptKHk6TcAQ==,type:comment]
|
||||
user12: ENC[AES256_GCM,data:CsbquwEn+iOKCzda8z26FYk2i5aPk2xzqGIYORiD4lotvnFE,iv:zHPmlT4LAc6NDjXrExze23dZZFIj0c1eR4WW74cu+qs=,tag:5MDFrZNgv54mK05ImSvpkw==,type:str]
|
||||
#ENC[AES256_GCM,data:vqYkwGVcQ8yZbA==,iv:1ckVSiAgjuT/K0MuVHe8D2hHE7X2qxCHpb+y6nrFCsI=,tag:so9oFl6bXlJT2O+prplazw==,type:comment]
|
||||
@@ -60,7 +62,7 @@ sops:
|
||||
Ri9hM3NRTkM4Q1lDdmdPemEweEFBUmcKNLL5qH+JeFWX0GovkPFVVAnz+4tmfG6/
|
||||
1jN8YqbMIxf5/L8tauXPf0iIiHa6pUcjtDZPr/OEmeXebmF6Bh9u9Q==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-06-09T07:42:38Z"
|
||||
mac: ENC[AES256_GCM,data:fQm8aI6KdoJVxcl4MQP7Q6EZVqmmLFo9A3Hjo/tKZA+VOYvQWFBxIKwy5Cj0SBi4pWsSjwG6pJZ7m6Wh/dDK4KlgkoaXgAYj+efHtScOH5Gkb0sTpAkHNL+/CJ/cO1doXiXRGj47fn1QB9o9WBaomtOWQbzDts4eFs9pdm8TAq4=,iv:91Ilig4j0ELHEatTY7ALKwwr8AzYnRwhKbdWDcufZF4=,tag:UfwaudQTNKu+uryCZjo3mw==,type:str]
|
||||
lastmodified: "2025-06-09T01:35:34Z"
|
||||
mac: ENC[AES256_GCM,data:40uhvaJNu1ELo6xHYECEOTE0lVcrcMmZKJpLmE28D2pyXnl6UQza0j9O7944+Ii+VroSvm7juB86gR8/x6URabQF0l2HTiYtBvyPicxdobB209i5JSULiCUe1zlfz8WyQ4VnPAJ9SJny59ucMYxMh8RM4UPtXWLs5whcqt5ooSk=,iv:5odm078cRXnwTA233NV7edcYTfMmTLFLrGRhE/oi8SU=,tag:2t06LMMrRkmbAQbCad6URA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -17,6 +17,7 @@ inputs:
|
||||
};
|
||||
};
|
||||
swap = [ "/nix/swap/swap" ];
|
||||
rollingRootfs = {};
|
||||
};
|
||||
grub.installDevice = "/dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:0";
|
||||
nixpkgs.march = "znver2";
|
||||
@@ -26,7 +27,8 @@ inputs:
|
||||
services =
|
||||
{
|
||||
sshd = {};
|
||||
xray = { server = {}; xmuPersist = {}; };
|
||||
xray.server = {};
|
||||
frpServer = { enable = true; serverName = "frp.chn.moe"; };
|
||||
nginx =
|
||||
{
|
||||
streamProxy.map =
|
||||
@@ -34,7 +36,6 @@ inputs:
|
||||
"anchor.fm" = { upstream = "anchor.fm:443"; proxyProtocol = false; };
|
||||
"podcasters.spotify.com" = { upstream = "podcasters.spotify.com:443"; proxyProtocol = false; };
|
||||
"xlog.chn.moe" = { upstream = "cname.xlog.app:443"; proxyProtocol = false; };
|
||||
"xservernas.chn.moe" = { upstream = "wg0.nas.chn.moe:443"; proxyProtocol = false; };
|
||||
}
|
||||
// (builtins.listToAttrs (builtins.map
|
||||
(site: { name = "${site}.chn.moe"; value.upstream.address = "wg0.pc.chn.moe"; })
|
||||
@@ -47,7 +48,7 @@ inputs:
|
||||
element.instances."element.chn.moe" = {};
|
||||
synapse-admin.instances."synapse-admin.chn.moe" = {};
|
||||
catalog.enable = true;
|
||||
main = {};
|
||||
main.enable = true;
|
||||
nekomia.enable = true;
|
||||
blog = {};
|
||||
sticker = {};
|
||||
@@ -56,10 +57,9 @@ inputs:
|
||||
};
|
||||
coturn = {};
|
||||
httpua = {};
|
||||
mirism = {};
|
||||
mirism.enable = true;
|
||||
fail2ban = {};
|
||||
beesd."/" = {};
|
||||
bind = {};
|
||||
};
|
||||
};
|
||||
networking.nftables.tables.forward =
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
frp:
|
||||
token: ENC[AES256_GCM,data:T8b1ku4HNCNSJ+33QgIt1GILFA4wTu3Qd0rDqHPVgdqsGo0R90k0u8z+dElSO7q9PapTqUbZ,iv:hwnMu6JxfYLgw4TyhujX5dI2IAytgZh+Bexhgta6ATQ=,tag:lqgwvXlS/jGPxasmk5Vh3w==,type:str]
|
||||
xray-server:
|
||||
clients:
|
||||
#ENC[AES256_GCM,data:DXEC,iv:SZ1AhmK6fWQ/HGDk97kDUcRN84zQMp99eiz4SpRhig8=,tag:Fkdf28ZvB8XKCxSYdjuuHw==,type:comment]
|
||||
@@ -20,6 +22,8 @@ xray-server:
|
||||
user9: ENC[AES256_GCM,data:+SA+VcZcy5ckuS/46Dn093VvuqxrIACuqMAMx6Ko5yw0DVdW,iv:TeLXb1WI7uhcPDkXYSlKIxdE6Kz+nCnlB+ZYpWcaF4I=,tag:YB0sPD9yHMARhiMJs7JKcA==,type:str]
|
||||
#ENC[AES256_GCM,data:eCl1bK4=,iv:oYA2CFW6OGGrRYx6OHRYJpbEyFh575UjztvHaXA8UG8=,tag:Pw7xsisQB2Dd0KJeWFq6bQ==,type:comment]
|
||||
user10: ENC[AES256_GCM,data:Pec0CVGia/ZIaq7WerZlr0/waJ/Ev1OKwt7V3PBxBSFMLi7p,iv:wYTdhv4Xoe58KBIwV1vk/V4IcdVzQrBgmzGaRD7qHQs=,tag:IZVt5LmjTUge8XntujJlTA==,type:str]
|
||||
#ENC[AES256_GCM,data:+s3MMeNU5Q==,iv:CUrg+nNxCpJFbHQmMNXmSE+JcZK6Dfu8cGwtznx3CFY=,tag:G5CYMtao+hz3hs0fPVPmcw==,type:comment]
|
||||
user11: ENC[AES256_GCM,data:IFIVzbnZCyn0j7AG0ClBT4byyZyVtRk1JqlWsojqPIVenek2,iv:ONdq1qIXG2kbAjuM/tHSPxce7oD/MHcBw1pBYm9DlEk=,tag:OuzeX0K+fSO7jWadb1uSRQ==,type:str]
|
||||
#ENC[AES256_GCM,data:spyQkQIHwg==,iv:7+0DUK95MPH7lpr+GMbbLu4/5yA11/4gTuLhQKlStfE=,tag:G/gIXML8UhYoCi9FfoTvSA==,type:comment]
|
||||
user12: ENC[AES256_GCM,data:iTZViWyKkCU1y6mvB0NzkXf3I98U/+nCs21ZD6M285YKaU6q,iv:vFgA3sv/7ENcw3gyJLiiHLwroXtVJjAxZXViqjXF3mQ=,tag:u3b9Uu6TIPPYX0TW5X5Sjg==,type:str]
|
||||
#ENC[AES256_GCM,data:HueqiREBet2bxQ==,iv:WCjTAGg2gXgBSvY3zc/YyB/1X0XjvphPduVXLsjOwH8=,tag:wC+On6lyyYQ1Dt/BHDvONw==,type:comment]
|
||||
@@ -44,8 +48,6 @@ send:
|
||||
coturn:
|
||||
auth-secret: ENC[AES256_GCM,data:50KqO4GQ1ERbCnK4IjYu6aywT+IPMtVlTzh/TE4MwWApU4pO9yqz25ENGUAKRLi4p+Ecug+Rn3InRl1b+q6bAQ==,iv:SgHkHvHg/+yA1Z5E9effgCnZMVXv5amGNUsVKErai54=,tag:PoYLV9Xr0IXXsA39n7wiTQ==,type:str]
|
||||
wireguard: ENC[AES256_GCM,data:5M7EAy/6+2UASWkjxE0Jrxwl0aNdAVZaUjQnD1wU3YvOAQ/c2DSL8hVtKf8=,iv:a2tXFf1+aP0JhdNtzP8e82KJ71m2o8nx+G0wIx4VMig=,tag:l4TS4QBz2fIkC9/GnZgHnQ==,type:str]
|
||||
xray-xmu-client:
|
||||
cookie: ENC[AES256_GCM,data:RZ2WFnsX7s/PVqA7ZKhGqw==,iv:CknFoAcHIiIwJI1IEXkFdWXcOCAZr50pfwmQN72OI8o=,tag:w2pNU1APxlSQsGMIEdE2OA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age19ax6vm3pv8rph5tq3mmehd9sy9jk823tw8svsd790r0lkslycquqvlwz9m
|
||||
@@ -66,7 +68,7 @@ sops:
|
||||
ZXFTU3ZCaW1pTVh0RUJzdDdGdHlPYTgK2mlgcX2kEc8+2UDdBnhUm6IIuh8V6agW
|
||||
ooxH9OEPXUVI/4JcDo4v8ZUhAyU1ehLH0Ef7PJCChOZe2KZmWSNbhA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2025-08-01T05:54:47Z"
|
||||
mac: ENC[AES256_GCM,data:OtHwr58A1UOfYxQR88ay76fWmAyWPl5YtNbAiv0LXPLZPRtLGBJKuTjMaHr17AMepFZ+u5IPV2r8z1AUDj0opLXlv3Ik/DJ2PCcQTOBH+/lnSgzJKWfdCip9/wFR6N3dT0PKKLuBiURB9ZCYmtnq6E5+Guadc6ATYDSEpwbENZQ=,iv:kXsYMGjAtUlv1UqFU8Xv0zagohnpHkzSI72mq5HKY7k=,tag:KR+1A8l2VvbzDZV/00hbJg==,type:str]
|
||||
lastmodified: "2025-06-09T01:33:33Z"
|
||||
mac: ENC[AES256_GCM,data:sRZaOvmwZqoxNFKrWtY19t4As7CEu1kXNR1XWO1uo28KEWQJ2n9HLRsdinjG70j/bFyTkXXiBz6Vlhx2RkdhHURKxe/UKuv/5szuGV/aE0NUGu+jYIaSbbIZpv1FkuUYuRFbuaSJnejEyQYW9ahaJYAJgXutqMY/e4xgUJ7Ooeo=,iv:PvAvKe/23u+aPP2moiNrkEqi0CgP9VCwfzcKC8S8Z1w=,tag:YburNo3mniyi4jyUjMF8DQ==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.10.2
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# install nix
|
||||
|
||||
1. Build nix using `nix build github:NixOS/nixpkgs/nixos-24.11#nixStatic`, upload, create symlink `nix-store` `nix-build` etc. pointing to it.
|
||||
2. Upload `.config/nix/nix.conf`.
|
||||
|
||||
# install or update packages
|
||||
|
||||
1. On nixos, make sure `/public/home/xmuhk/.nix` is mounted correctly.
|
||||
2. Build using `sudo nix build --store 'local?store=/public/home/xmuhk/.nix/store&state=/public/home/xmuhk/.nix/state&log=/public/home/xmuhk/.nix/log' .#xmuhk` .
|
||||
3. Diff store using `sudo nix-store --store 'local?store=/public/home/xmuhk/.nix/store&state=/public/home/xmuhk/.nix/state&log=/public/home/xmuhk/.nix/log' -qR ./result | grep -Fxv -f <(ssh xmuhk find .nix/store -maxdepth 1 -exec realpath '{}' '\;') | sudo xargs nix-store --store 'local?store=/public/home/xmuhk/.nix/store&state=/public/home/xmuhk/.nix/state&log=/public/home/xmuhk/.nix/log' --export | xz -T0 | pv > xmuhk.nar.xz` .
|
||||
4. Upload `xmuhk.nar.xz` to hpc.
|
||||
5. On hpc, `pv xmuhk.nar.xz | xz -d | nix-store --import` .
|
||||
6. Create gcroot using `nix build /xxx-xmuhk -o .nix/state/gcroots/current`, where `/xxx-xmuhk` is the last path printed by `nix-store --import` .
|
||||
@@ -1,69 +0,0 @@
|
||||
{ inputs, localLib }:
|
||||
let
|
||||
pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
|
||||
{
|
||||
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
|
||||
nixpkgs = { march = null; cuda = null; nixRoot = "/public/home/xmuhk/.nix"; nixos = false; };
|
||||
});
|
||||
lumericalLicenseManager =
|
||||
let
|
||||
ip = "${pkgs.iproute2}/bin/ip";
|
||||
awk = "${pkgs.gawk}/bin/awk";
|
||||
sed = "${pkgs.gnused}/bin/sed";
|
||||
chmod = "${pkgs.coreutils}/bin/chmod";
|
||||
sing = "/public/software/singularity/singularity-3.8.3/bin/singularity";
|
||||
in pkgs.writeShellScriptBin "lumericalLicenseManager"
|
||||
''
|
||||
echo "Cleaning up..."
|
||||
${sing} instance stop lumericalLicenseManager || true
|
||||
[ -d /tmp/lumerical ] && chmod -R u+w /tmp/lumerical && rm -rf /tmp/lumerical || true
|
||||
mkdir -p /tmp/lumerical
|
||||
while true; do
|
||||
if ! ss -tan | grep -q ".*TIME-WAIT .*:1084 "; then break; fi
|
||||
sleep 10
|
||||
done
|
||||
|
||||
echo "Extracting image..."
|
||||
${sing} build --sandbox /tmp/lumerical/lumericalLicenseManager \
|
||||
${inputs.self.src.lumerical.licenseManager.sifImageFile}
|
||||
mkdir /tmp/lumerical/lumericalLicenseManager/public
|
||||
|
||||
echo 'Searching for en* interface...'
|
||||
iface=$(${ip} -o link show | ${awk} -F': ' '/^[0-9]+: en/ {print $2; exit}')
|
||||
if [ -n "$iface" ]; then
|
||||
echo "Found interface: $iface"
|
||||
echo 'Extracting MAC address...'
|
||||
mac=$(${ip} link show "$iface" | ${awk} '/link\/ether/ {print $2}' | ${sed} 's/://g')
|
||||
echo "Extracted MAC address: $mac"
|
||||
else
|
||||
echo "No interface starting with 'en' found." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo 'Creating license file...'
|
||||
${sed} -i "s|xxxxxxxxxxxxx|$mac|" \
|
||||
/tmp/lumerical/lumericalLicenseManager/home/ansys_inc/shared_files/licensing/license_files/ansyslmd.lic
|
||||
${sed} -i 's|2022.1231|2035.1231|g' \
|
||||
/tmp/lumerical/lumericalLicenseManager/home/ansys_inc/shared_files/licensing/license_files/ansyslmd.lic
|
||||
|
||||
echo "Starting license manager..."
|
||||
${sing} instance start --writable /tmp/lumerical/lumericalLicenseManager lumericalLicenseManager
|
||||
${sing} exec instance://lumericalLicenseManager /bin/sh -c \
|
||||
"pushd /home/ansys_inc/shared_files/licensing; (./start_ansysli &); (./start_lmcenter &); tail -f /dev/null"
|
||||
|
||||
cleanup() {
|
||||
echo "Stopping license manager..."
|
||||
${sing} instance stop lumericalLicenseManager
|
||||
chmod -R u+w /tmp/lumerical && rm -rf /tmp/lumerical
|
||||
}
|
||||
trap cleanup SIGINT SIGTERM SIGHUP EXIT
|
||||
tail -f /dev/null
|
||||
'';
|
||||
in pkgs.symlinkJoin
|
||||
{
|
||||
name = "xmuhk";
|
||||
paths = (with pkgs; [ hello btop htop iotop pv localPackages.lumerical.lumerical.cmd ])
|
||||
++ [ lumericalLicenseManager ];
|
||||
postBuild = "echo ${inputs.self.rev or "dirty"} > $out/.version";
|
||||
passthru = { inherit pkgs; };
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
store = local?store=/public/home/xmuhk/.nix/store&state=/public/home/xmuhk/.nix/state&log=/public/home/xmuhk/.nix/log
|
||||
experimental-features = flakes nix-command
|
||||
490
flake.lock
generated
490
flake.lock
generated
@@ -1,27 +1,5 @@
|
||||
{
|
||||
"nodes": {
|
||||
"aagl": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1750597708,
|
||||
"narHash": "sha256-jpoh3tk4F4C0MZsXYqFt1fqm4qYOcyu3RtJlmpabpDo=",
|
||||
"owner": "ezKEa",
|
||||
"repo": "aagl-gtk-on-nix",
|
||||
"rev": "5e4851010e05030553f2265ced86b155dfe0bb93",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ezKEa",
|
||||
"ref": "release-25.05",
|
||||
"repo": "aagl-gtk-on-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"blog": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@@ -149,27 +127,6 @@
|
||||
}
|
||||
},
|
||||
"devshell": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nur-linyinfeng",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1741473158,
|
||||
"narHash": "sha256-kWNaq6wQUbUMlPgw8Y+9/9wP0F8SHkjy24/mN3UAppg=",
|
||||
"owner": "numtide",
|
||||
"repo": "devshell",
|
||||
"rev": "7c9e793ebe66bcba8292989a68c0419b737a22a0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "devshell",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"devshell_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nur-xddxdd",
|
||||
@@ -209,11 +166,11 @@
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1733328505,
|
||||
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -223,22 +180,6 @@
|
||||
}
|
||||
},
|
||||
"flake-compat_2": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1747046372,
|
||||
"narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_3": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
@@ -254,58 +195,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_4": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_5": {
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"revCount": 57,
|
||||
"type": "tarball",
|
||||
"url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nur-linyinfeng",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1749398372,
|
||||
"narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_2": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
@@ -359,42 +249,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_3": {
|
||||
"inputs": {
|
||||
"systems": "systems_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_4": {
|
||||
"inputs": {
|
||||
"systems": "systems_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@@ -583,77 +437,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri": {
|
||||
"inputs": {
|
||||
"niri-stable": "niri-stable",
|
||||
"niri-unstable": "niri-unstable",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-stable": "nixpkgs-stable",
|
||||
"xwayland-satellite-stable": "xwayland-satellite-stable",
|
||||
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1752569955,
|
||||
"narHash": "sha256-a21pjNhJYJ+OTQmBJ3NluU65PvMb54/mA7aEWJh5s/4=",
|
||||
"owner": "sodiboo",
|
||||
"repo": "niri-flake",
|
||||
"rev": "8fc18813bf6ceaabb3063050819a20807e11279b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "sodiboo",
|
||||
"repo": "niri-flake",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri-stable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1748151941,
|
||||
"narHash": "sha256-z4viQZLgC2bIJ3VrzQnR+q2F3gAOEQpU1H5xHtX/2fs=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "8ba57fcf25d2fc9565131684a839d58703f1dae7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "YaLTeR",
|
||||
"ref": "v25.05.1",
|
||||
"repo": "niri",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"niri-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1752565554,
|
||||
"narHash": "sha256-BLLMN6oOarMdIm59AX8uypaXZHBhGfd6L3VURfqQTX8=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "007d35541db1bae32b7b43891af88831325ba068",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-flatpak": {
|
||||
"locked": {
|
||||
"lastModified": 1749394952,
|
||||
"narHash": "sha256-WbWkzIvB0gqAdBLghdmUpGveY7MlAS2iMj3VEJnJ9yE=",
|
||||
"owner": "gmodena",
|
||||
"repo": "nix-flatpak",
|
||||
"rev": "64c6e53a3999957c19ab95cda78bde466d8374cc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "gmodena",
|
||||
"repo": "nix-flatpak",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-index-database": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@@ -717,22 +500,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1750646418,
|
||||
"narHash": "sha256-4UAN+W0Lp4xnUiHYXUXAPX18t+bn6c4Btry2RqM9JHY=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "1f426f65ac4e6bf808923eb6f8b8c2bfba3d18c5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-wallpaper": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@@ -753,16 +520,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1752480373,
|
||||
"narHash": "sha256-JHQbm+OcGp32wAsXTE/FLYGNpb+4GLi5oTvCxwSoBOA=",
|
||||
"owner": "NixOS",
|
||||
"lastModified": 1749016257,
|
||||
"narHash": "sha256-Vi+QhXm6Kau233v7ijtdD5aNpE4RpnUjRUhXGwi7pxk=",
|
||||
"owner": "CHN-beta",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "62e0f05ede1da0d54515d4ea8ce9c733f12d9f08",
|
||||
"rev": "5835771b10e3197408d3ac7d32558c8e2ae0ab8d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"owner": "CHN-beta",
|
||||
"ref": "nixos-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -846,29 +613,13 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1752308619,
|
||||
"narHash": "sha256-pzrVLKRQNPrii06Rm09Q0i0dq3wt2t2pciT/GNq5EZQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "650e572363c091045cdbc5b36b0f4c1f614d3058",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1752553852,
|
||||
"narHash": "sha256-LwWRsENAZJKUdD3SpLluwDmdXY9F45ZEgCb0X+xgOL0=",
|
||||
"lastModified": 1746921044,
|
||||
"narHash": "sha256-R4hz/Wl2QZDbgj09u9tDdQKY8SS9JIm0F2wc9LKOjD0=",
|
||||
"owner": "CHN-beta",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "72d2707fa09a82bae26845eadb136ce94fd96a3e",
|
||||
"rev": "5d04a9f5d569ed7632ee926021d6ab35729fd8d4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -878,22 +629,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1754960695,
|
||||
"narHash": "sha256-cv73dyWKY6SBW1ECp0E4v3c51qyYmV+N7NwE0skh/cQ=",
|
||||
"owner": "CHN-beta",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "cc56ae5eb2e7c66d90332ddaa2c50196a66ec02b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "CHN-beta",
|
||||
"ref": "nixos-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixvirt": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@@ -930,45 +665,18 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nur-linyinfeng": {
|
||||
"inputs": {
|
||||
"devshell": "devshell",
|
||||
"flake-compat": "flake-compat_2",
|
||||
"flake-parts": "flake-parts",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixos-stable": "nixos-stable",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nvfetcher": "nvfetcher",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1751049834,
|
||||
"narHash": "sha256-xgLH6/ZtQJKWsham0Cj0nKGY8hde2fY8vZgSM5JfRik=",
|
||||
"owner": "linyinfeng",
|
||||
"repo": "nur-packages",
|
||||
"rev": "d7a4ee64345bae20e75f40d6f35c705d22c216d4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "linyinfeng",
|
||||
"repo": "nur-packages",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nur-xddxdd": {
|
||||
"inputs": {
|
||||
"devshell": "devshell_2",
|
||||
"flake-parts": "flake-parts_2",
|
||||
"devshell": "devshell",
|
||||
"flake-parts": "flake-parts",
|
||||
"nix-index-database": "nix-index-database_2",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-24_05": "nixpkgs-24_05",
|
||||
"nvfetcher": "nvfetcher_2",
|
||||
"nvfetcher": "nvfetcher",
|
||||
"pre-commit-hooks-nix": "pre-commit-hooks-nix",
|
||||
"treefmt-nix": "treefmt-nix_2"
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1748081225,
|
||||
@@ -986,37 +694,8 @@
|
||||
},
|
||||
"nvfetcher": {
|
||||
"inputs": {
|
||||
"flake-compat": [
|
||||
"nur-linyinfeng",
|
||||
"flake-compat"
|
||||
],
|
||||
"flake-utils": [
|
||||
"nur-linyinfeng",
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nur-linyinfeng",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1732501185,
|
||||
"narHash": "sha256-Z0BpHelaGQsE5VD9hBsBHsvMU9h+Xt0kfkDJyFivZOU=",
|
||||
"owner": "berberman",
|
||||
"repo": "nvfetcher",
|
||||
"rev": "bdb14eab6fe9cefc29efe01e60c3a3f616d6b62a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "berberman",
|
||||
"repo": "nvfetcher",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nvfetcher_2": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_3",
|
||||
"flake-utils": "flake-utils_3",
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": [
|
||||
"nur-xddxdd",
|
||||
"nixpkgs"
|
||||
@@ -1110,7 +789,7 @@
|
||||
},
|
||||
"pre-commit-hooks-nix": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_4",
|
||||
"flake-compat": "flake-compat_2",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nur-xddxdd",
|
||||
@@ -1149,7 +828,6 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"aagl": "aagl",
|
||||
"blog": "blog",
|
||||
"bscpkgs": "bscpkgs",
|
||||
"buildproxy": "buildproxy",
|
||||
@@ -1168,19 +846,16 @@
|
||||
"mumax": "mumax",
|
||||
"nameof": "nameof",
|
||||
"nc4nix": "nc4nix",
|
||||
"niri": "niri",
|
||||
"nix-flatpak": "nix-flatpak",
|
||||
"nix-index-database": "nix-index-database",
|
||||
"nix-vscode-extensions": "nix-vscode-extensions",
|
||||
"nixos-wallpaper": "nixos-wallpaper",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-2305": "nixpkgs-2305",
|
||||
"nixpkgs-2311": "nixpkgs-2311",
|
||||
"nixpkgs-2411": "nixpkgs-2411",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"nixvirt": "nixvirt",
|
||||
"nu-scripts": "nu-scripts",
|
||||
"nur-linyinfeng": "nur-linyinfeng",
|
||||
"nur-xddxdd": "nur-xddxdd",
|
||||
"openxlsx": "openxlsx",
|
||||
"phono3py": "phono3py",
|
||||
@@ -1190,7 +865,6 @@
|
||||
"rsshub": "rsshub",
|
||||
"rycee": "rycee",
|
||||
"sops-nix": "sops-nix",
|
||||
"speedtest": "speedtest",
|
||||
"sqlite-orm": "sqlite-orm",
|
||||
"sticker": "sticker",
|
||||
"stickerpicker": "stickerpicker",
|
||||
@@ -1198,7 +872,6 @@
|
||||
"ufo": "ufo",
|
||||
"v-sim": "v-sim",
|
||||
"vaspberry": "vaspberry",
|
||||
"winapps": "winapps",
|
||||
"zpp-bits": "zpp-bits"
|
||||
}
|
||||
},
|
||||
@@ -1254,22 +927,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"speedtest": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1739473165,
|
||||
"narHash": "sha256-QimemnDZXlL5Ip+RFD0uxO21Aaol3kCw6Mf/0E3jHQc=",
|
||||
"owner": "librespeed",
|
||||
"repo": "speedtest",
|
||||
"rev": "a1c43977ad9bf73f09f81e8df3c22ea914ab9131",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "librespeed",
|
||||
"repo": "speedtest",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"sqlite-orm": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@@ -1350,36 +1007,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_3": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_4": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"tgbot-cpp": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@@ -1397,27 +1024,6 @@
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nur-linyinfeng",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1750931469,
|
||||
"narHash": "sha256-0IEdQB1nS+uViQw4k3VGUXntjkDp7aAlqcxdewb/hAc=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "ac8e6f32e11e9c7f153823abc3ab007f2a65d3e1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nur-xddxdd",
|
||||
@@ -1489,62 +1095,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"winapps": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_5",
|
||||
"flake-utils": "flake-utils_4",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1730460191,
|
||||
"narHash": "sha256-CWaNjs2kOpmsR8ieVwqcd7EAz5Kd3y8I5huZyYgGqlA=",
|
||||
"owner": "winapps-org",
|
||||
"repo": "winapps",
|
||||
"rev": "b18efc4497c0994182bbe482808583c11cc51a2e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "winapps-org",
|
||||
"ref": "feat-nix-packaging",
|
||||
"repo": "winapps",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"xwayland-satellite-stable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1748488455,
|
||||
"narHash": "sha256-IiLr1alzKFIy5tGGpDlabQbe6LV1c9ABvkH6T5WmyRI=",
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"rev": "3ba30b149f9eb2bbf42cf4758d2158ca8cceef73",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Supreeeme",
|
||||
"ref": "v0.6",
|
||||
"repo": "xwayland-satellite",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"xwayland-satellite-unstable": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1752338000,
|
||||
"narHash": "sha256-Fxlp/yKtynug0jyuauAmvZU2SzHCfwlwWf85j+IvQ0U=",
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"rev": "ba78881a68182ce338041846164cbfed0d70935c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Supreeeme",
|
||||
"repo": "xwayland-satellite",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"zpp-bits": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
inputs =
|
||||
{
|
||||
self.lfs = true;
|
||||
nixpkgs.url = "github:CHN-beta/nixpkgs/nixos-25.05";
|
||||
nixpkgs-2411.url = "github:CHN-beta/nixpkgs/nixos-24.11";
|
||||
nixpkgs-2311.url = "github:CHN-beta/nixpkgs/nixos-23.11";
|
||||
@@ -23,15 +24,10 @@
|
||||
url = "github:pjones/plasma-manager";
|
||||
inputs = { nixpkgs.follows = "nixpkgs"; home-manager.follows = "home-manager"; };
|
||||
};
|
||||
nur-linyinfeng = { url = "github:linyinfeng/nur-packages"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
nix-flatpak.url = "github:gmodena/nix-flatpak";
|
||||
catppuccin = { url = "github:catppuccin/nix"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
bscpkgs = { url = "github:CHN-beta/bscpkgs"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
aagl = { url = "github:ezKEa/aagl-gtk-on-nix/release-25.05"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
winapps = { url = "github:winapps-org/winapps/feat-nix-packaging"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
nixvirt = { url = "github:CHN-beta/NixVirt"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
buildproxy = { url = "github:polygon/nix-buildproxy"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
niri.url = "github:sodiboo/niri-flake";
|
||||
|
||||
misskey = { url = "git+https://github.com/CHN-beta/misskey?submodules=1"; flake = false; };
|
||||
rsshub = { url = "github:DIYgod/RSSHub"; flake = false; };
|
||||
@@ -62,10 +58,9 @@
|
||||
mac-style = { url = "github:SergioRibera/s4rchiso-plymouth-theme?lfs=1"; flake = false; };
|
||||
phono3py = { url = "github:phonopy/phono3py"; flake = false; };
|
||||
sticker = { url = "git+https://git.chn.moe/chn/sticker.git?lfs=1"; flake = false; };
|
||||
speedtest = { url = "github:librespeed/speedtest"; flake = false; };
|
||||
};
|
||||
|
||||
outputs = inputs: let localLib = import ./flake/lib inputs.nixpkgs.lib; in
|
||||
outputs = inputs: let localLib = import ./flake/lib.nix inputs.nixpkgs.lib; in
|
||||
{
|
||||
packages.x86_64-linux = import ./flake/packages.nix { inherit inputs localLib; };
|
||||
nixosConfigurations = import ./flake/nixos.nix { inherit inputs localLib; };
|
||||
|
||||
@@ -4,12 +4,12 @@ let
|
||||
{
|
||||
autoroute = [ "api" "git" "grafana" "matrix" "peertube" "send" "synapse" "vikunja" "铜锣湾" ];
|
||||
nas = [ "initrd.nas" ];
|
||||
office = [ "srv2-node0" "xserverxmu" ];
|
||||
office = [ "srv2-node0" ];
|
||||
vps4 = [ "initrd.vps4" "xserver2.vps4" ];
|
||||
vps6 =
|
||||
[
|
||||
"blog" "catalog" "coturn" "element" "initrd.vps6" "misskey" "sticker" "synapse-admin" "tgapi"
|
||||
"ua" "xserver2" "xserver2.vps6" "铜锣湾实验室" "xservernas"
|
||||
"blog" "catalog" "coturn" "element" "frp" "initrd.vps6" "misskey" "sticker" "synapse-admin" "tgapi"
|
||||
"ua" "xserver2" "xserver2.vps6" "铜锣湾实验室"
|
||||
];
|
||||
"xlog.autoroute" = [ "xlog" ];
|
||||
"wg0.srv1-node0" = [ "wg0.srv1" ];
|
||||
@@ -29,7 +29,7 @@ let
|
||||
nas = "192.168.1.2";
|
||||
pc = "192.168.1.3";
|
||||
one = "192.168.1.4";
|
||||
office = "210.34.16.20";
|
||||
office = "210.34.16.60";
|
||||
srv1-node0 = "59.77.36.250";
|
||||
vps4 = "104.234.37.61";
|
||||
vps6 = "144.34.225.59";
|
||||
@@ -38,7 +38,6 @@ let
|
||||
srv1-node1 = "192.168.178.2";
|
||||
srv1-node2 = "192.168.178.3";
|
||||
srv2-node1 = "192.168.178.2";
|
||||
"409test" = "192.168.1.5";
|
||||
};
|
||||
wireguard = import ./wireguard.nix;
|
||||
in
|
||||
@@ -57,7 +56,11 @@ in
|
||||
{ type = "TXT"; value = "v=spf1 include:mxlogin.com -all"; }
|
||||
];
|
||||
"_xlog-challenge.xlog" = { type = "TXT"; value = "chn"; };
|
||||
autoroute = { type = "NS"; values = "vps6.chn.moe."; };
|
||||
autoroute =
|
||||
{
|
||||
type = "NS";
|
||||
values = builtins.map (suffix: "ns1.huaweicloud-dns.${suffix}.") [ "cn" "com" "net" "org" ];
|
||||
};
|
||||
"mail" = { type = "CNAME"; value = "tuesday.mxrouting.net."; };
|
||||
"webmail" = { type = "CNAME"; value = "tuesday.mxrouting.net."; };
|
||||
"x._domainkey" =
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
lib: rec
|
||||
{
|
||||
inherit (lib) attrsToList;
|
||||
attrsToList = attrs: builtins.map (name: { inherit name; value = attrs.${name}; }) (builtins.attrNames attrs);
|
||||
mkConditional = condition: trueResult: falseResult: let inherit (lib) mkMerge mkIf; in
|
||||
mkMerge [ ( mkIf condition trueResult ) ( mkIf (!condition) falseResult ) ];
|
||||
|
||||
@@ -86,6 +86,4 @@ lib: rec
|
||||
if (builtins.typeOf pattern) != "list" then throw "pattern should be a list"
|
||||
else if pattern == [] then origin
|
||||
else deepReplace (builtins.tail pattern) (replace ((builtins.head pattern) // { content = origin; }));
|
||||
|
||||
buildNixpkgsConfig = import ./buildNixpkgsConfig;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/boost/process/v2/stdio.hpp b/boost/process/v2/stdio.hpp
|
||||
index 01d0216..4084e46 100644
|
||||
--- a/boost/process/v2/stdio.hpp
|
||||
+++ b/boost/process/v2/stdio.hpp
|
||||
@@ -184,7 +184,7 @@ struct process_io_binding
|
||||
process_io_binding & operator=(const process_io_binding &) = delete;
|
||||
|
||||
process_io_binding(process_io_binding && other) noexcept
|
||||
- : fd(other.fd), fd_needs_closing(other.fd), ec(other.ec)
|
||||
+ : fd(other.fd), fd_needs_closing(other.fd_needs_closing), ec(other.ec)
|
||||
{
|
||||
other.fd = target;
|
||||
other.fd_needs_closing = false;
|
||||
@@ -1,6 +1,6 @@
|
||||
{ inputs, localLib }:
|
||||
let
|
||||
singles = [ "nas" "pc" "vps4" "vps6" "one" "srv3" "r2s" ];
|
||||
singles = [ "nas" "pc" "vps4" "vps6" "one" "srv3" "test" "test-pc" "test-pc-vm" ];
|
||||
cluster = { srv1 = 3; srv2 = 2; };
|
||||
deviceModules = builtins.listToAttrs
|
||||
(
|
||||
@@ -25,9 +25,9 @@ let
|
||||
(localLib.attrsToList cluster)))
|
||||
);
|
||||
in builtins.mapAttrs
|
||||
(n: v: inputs.nixpkgs.lib.nixosSystem
|
||||
(_: v: inputs.nixpkgs.lib.nixosSystem
|
||||
{
|
||||
system = null;
|
||||
system = "x86_64-linux";
|
||||
specialArgs = { topInputs = inputs; inherit localLib; };
|
||||
modules = localLib.mkModules v;
|
||||
})
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
{ inputs, localLib }: rec
|
||||
{
|
||||
pkgs = import inputs.nixpkgs (localLib.buildNixpkgsConfig
|
||||
pkgs = (import inputs.nixpkgs
|
||||
{
|
||||
inputs = { inherit (inputs.nixpkgs) lib; topInputs = inputs; };
|
||||
nixpkgs = { march = null; cuda = null; nixRoot = null; nixos = false; };
|
||||
system = "x86_64-linux";
|
||||
config.allowUnfree = true;
|
||||
overlays = [ inputs.self.overlays.default ];
|
||||
});
|
||||
hpcstat =
|
||||
let
|
||||
openssh = (pkgs.pkgsStatic.openssh.override { withLdns = false; etcDir = null; }).overrideAttrs
|
||||
(prev: { doCheck = false; patches = prev.patches ++ [ ../packages/hpcstat/openssh.patch ];});
|
||||
duc = pkgs.pkgsStatic.duc.override { enableCairo = false; cairo = null; pango = null; };
|
||||
glaze = pkgs.pkgs-2411.pkgsStatic.glaze.overrideAttrs
|
||||
glaze = pkgs.pkgsStatic.glaze.overrideAttrs
|
||||
(prev: { cmakeFlags = prev.cmakeFlags ++ [ "-Dglaze_ENABLE_FUZZING=OFF" ]; });
|
||||
# pkgsStatic.clangStdenv have a bug
|
||||
# https://github.com/NixOS/nixpkgs/issues/177129
|
||||
@@ -28,25 +29,26 @@
|
||||
gfortran = pkgs.pkgsStatic.gfortran;
|
||||
lapack = pkgs.pkgsStatic.openblas;
|
||||
};
|
||||
jykang = import ../devices/jykang.xmuhpc { inherit inputs localLib; };
|
||||
xmuhk = import ../devices/xmuhk { inherit inputs localLib; };
|
||||
jykang = import ../devices/jykang.xmuhpc inputs;
|
||||
src =
|
||||
let getDrv = x:
|
||||
if pkgs.lib.isDerivation x then [ x ]
|
||||
else if builtins.isAttrs x then builtins.concatMap getDrv (builtins.attrValues x)
|
||||
else if builtins.isList x then builtins.concatMap getDrv x
|
||||
else [];
|
||||
in pkgs.writeText "src" (builtins.concatStringsSep "\n" (getDrv inputs.self.outputs.src));
|
||||
in pkgs.concatText "src" (getDrv (inputs.self.outputs.src));
|
||||
dns-push = pkgs.callPackage ./dns
|
||||
{
|
||||
inherit localLib;
|
||||
tokenPath = inputs.self.nixosConfigurations.pc.config.nixos.system.sops.secrets."acme/token".path;
|
||||
tokenPath = inputs.self.nixosConfigurations.pc.config.sops.secrets."acme/token".path;
|
||||
octodns = pkgs.octodns.withProviders (_: with pkgs.octodns-providers; [ cloudflare ]);
|
||||
};
|
||||
archive = pkgs.writeText "archive" (builtins.concatStringsSep "\n" (builtins.concatLists
|
||||
[
|
||||
(inputs.nixpkgs.lib.mapAttrsToList (_: v: v.config.system.build.toplevel) inputs.self.outputs.nixosConfigurations)
|
||||
[ src ]
|
||||
]));
|
||||
archive =
|
||||
let devices =
|
||||
[ "nas" "one" "pc" "srv1-node0" "srv1-node1" "srv1-node2" "srv2-node0" "srv2-node1" "srv3" "vps4" "vps6" ];
|
||||
in pkgs.writeText "archive" (builtins.concatStringsSep "\n" (builtins.map
|
||||
(d: "${inputs.self.outputs.nixosConfigurations.${d}.config.system.build.toplevel}") devices));
|
||||
}
|
||||
// (builtins.mapAttrs (_: v: v.config.system.build.toplevel) inputs.self.outputs.nixosConfigurations)
|
||||
// (builtins.listToAttrs (builtins.map
|
||||
(system: { inherit (system) name; value = system.value.config.system.build.toplevel; })
|
||||
(localLib.attrsToList inputs.self.outputs.nixosConfigurations)))
|
||||
|
||||
@@ -64,59 +64,13 @@
|
||||
finalImageTag = "latest";
|
||||
};
|
||||
misskey = {};
|
||||
lumerical =
|
||||
vesta =
|
||||
{
|
||||
lumerical = pkgs.requireFile
|
||||
{
|
||||
name = "lumerical.zip";
|
||||
sha256 = "03nfacykfzal29jdmygrgkl0fqsc3yqp4ig86h1h9sirci87k94c";
|
||||
hashMode = "recursive";
|
||||
message = "Source not found.";
|
||||
};
|
||||
licenseManager =
|
||||
{
|
||||
crack = pkgs.requireFile
|
||||
{
|
||||
name = "crack";
|
||||
sha256 = "1a1k3nlaidi0kk2xxamb4pm46iiz6k3sxynhd65y8riylrkck3md";
|
||||
hashMode = "recursive";
|
||||
message = "Source file not found.";
|
||||
};
|
||||
src = pkgs.requireFile
|
||||
{
|
||||
name = "src";
|
||||
sha256 = "1h93r0bb37279dzghi3k2axf0b8g0mgacw0lcww5j3sx0sqjbg4l";
|
||||
hashMode = "recursive";
|
||||
message = "Source file not found.";
|
||||
};
|
||||
image = "6803f9562b941c23db81a2eae5914561f96fa748536199a010fe6f24922b2878";
|
||||
imageFile = pkgs.requireFile
|
||||
{
|
||||
name = "lumericalLicenseManager.tar";
|
||||
sha256 = "ftEZADv8Mgo5coNKs+gxPZPl/YTV3FMMgrF3wUIBEiQ=";
|
||||
message = "Source not found.";
|
||||
};
|
||||
license = pkgs.requireFile
|
||||
{
|
||||
name = "license";
|
||||
sha256 = "07rwin14py6pl1brka7krz7k2g9x41h7ks7dmp1lxdassan86484";
|
||||
message = "Source file not found.";
|
||||
};
|
||||
sifImageFile = pkgs.requireFile
|
||||
{
|
||||
name = "lumericalLicenseManager.sif";
|
||||
sha256 = "i0HGLiRWoKuQYYx44GBkDBbyUvFLbfFShi/hx7KBSuU=";
|
||||
message = "Source file not found.";
|
||||
};
|
||||
};
|
||||
};
|
||||
vesta = rec
|
||||
{
|
||||
version = "3.5.8";
|
||||
version = "3.90.5a";
|
||||
src = pkgs.fetchurl
|
||||
{
|
||||
url = "https://jp-minerals.org/vesta/archives/${version}/VESTA-gtk3.tar.bz2";
|
||||
sha256 = "1y4dhqhk0jy7kbkkx2c6lsrm5lirn796mq67r5j1s7xkq8jz1gkq";
|
||||
url = "https://jp-minerals.org/vesta/archives/testing/VESTA-gtk3-x86_64.tar.bz2";
|
||||
sha256 = "0y277m2xvjyzx8hncc3ka73lir8x6x2xckjac9fdzg03z0jnpqzf";
|
||||
};
|
||||
desktopFile = pkgs.fetchurl
|
||||
{
|
||||
@@ -180,7 +134,7 @@
|
||||
"intel.oneapi.lin.compilers-common,v=2025.1.1+10"
|
||||
];
|
||||
};
|
||||
rsshub = pkgs.dockerTools.pullImage
|
||||
rsshub = pkgs.dockerTools.pullImage
|
||||
{
|
||||
imageName = "diygod/rsshub";
|
||||
imageDigest = "sha256:1f9d97263033752bf5e20c66a75e134e6045b6d69ae843c1f6610add696f8c22";
|
||||
@@ -188,20 +142,4 @@
|
||||
finalImageName = "rsshub";
|
||||
finalImageTag = "latest";
|
||||
};
|
||||
atat = pkgs.fetchurl
|
||||
{
|
||||
url = "https://axelvandewalle.github.io/www-avdw/atat/atat3_50.tar.gz";
|
||||
sha256 = "14sblzqsi5bxfhsjbq256bc2gfd7zrxyf5za0iaw77b592ppjg3m";
|
||||
};
|
||||
atomkit = pkgs.fetchurl
|
||||
{
|
||||
url = "mirror://sourceforge/atomkit/Binaries/atomkit.0.9.0.linux.x64.tar.gz";
|
||||
sha256 = "0y9z7wva7zikh83w9q431lgn3bqkh1v5w6iz90dwc75wqwk0w5jr";
|
||||
};
|
||||
guix = pkgs.fetchurl
|
||||
{
|
||||
url = "https://ci.guix.gnu.org/download/2857";
|
||||
name = "guix.iso";
|
||||
sha256 = "0xqabnay8wwqc1a96db8ix1a6bhvgm84s5is1q67rr432q7gqgd4";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,12 +12,8 @@ let bugs =
|
||||
(attrs: { patches = attrs.patches ++ [ ./xmunet.patch ];}); };
|
||||
backlight.boot.kernelParams = [ "nvidia.NVreg_RegistryDwords=EnableBrightnessControl=1" ];
|
||||
amdpstate.boot.kernelParams = [ "amd_pstate=active" ];
|
||||
iwlwifi.boot.extraModprobeConfig =
|
||||
''
|
||||
options iwlwifi power_save=0
|
||||
options iwlmvm power_scheme=1
|
||||
options iwlwifi uapsd_disable=1
|
||||
'';
|
||||
iwlwifi.nixos.system.kernel.modules.modprobeConfig =
|
||||
[ "options iwlwifi power_save=0" "options iwlmvm power_scheme=1" "options iwlwifi uapsd_disable=1" ];
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
@@ -6,14 +6,8 @@ inputs: let inherit (inputs) topInputs; in
|
||||
topInputs.sops-nix.nixosModules.sops
|
||||
topInputs.nix-index-database.nixosModules.nix-index
|
||||
topInputs.impermanence.nixosModules.impermanence
|
||||
topInputs.nix-flatpak.nixosModules.nix-flatpak
|
||||
topInputs.catppuccin.nixosModules.catppuccin
|
||||
topInputs.aagl.nixosModules.default
|
||||
topInputs.nixvirt.nixosModules.default
|
||||
topInputs.niri.nixosModules.niri
|
||||
{ config.niri-flake.cache.enable = false; }
|
||||
# TODO: Remove after next release
|
||||
"${topInputs.nixpkgs-unstable}/nixos/modules/services/hardware/lact.nix"
|
||||
(inputs:
|
||||
{
|
||||
config =
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.hardware.cpu = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.enum [ "intel" "amd" ]);
|
||||
default = let inherit (inputs.config.nixos.system.nixpkgs) march; in
|
||||
if march == null then null
|
||||
else if inputs.lib.hasPrefix "znver" march then "amd"
|
||||
else if (inputs.lib.hasSuffix "lake" march)
|
||||
|| (builtins.elem march [ "sandybridge" "silvermont" "haswell" "broadwell" ])
|
||||
then "intel"
|
||||
else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.hardware) cpu; in inputs.lib.mkIf (cpu != null) (inputs.lib.mkMerge
|
||||
[
|
||||
(inputs.lib.mkIf (cpu == "intel")
|
||||
{
|
||||
hardware.cpu.intel.updateMicrocode = true;
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "intel_cstate" "aesni_intel" "intel_cstate" "intel_uncore" "intel_uncore_frequency" "intel_powerclamp" ];
|
||||
})
|
||||
(inputs.lib.mkIf (cpu == "amd")
|
||||
{
|
||||
hardware.cpu.amd = { updateMicrocode = true; ryzen-smu.enable = true; };
|
||||
environment.systemPackages = with inputs.pkgs; [ zenmonitor ];
|
||||
programs.ryzen-monitor-ng.enable = true;
|
||||
})
|
||||
]);
|
||||
}
|
||||
26
modules/hardware/cpus.nix
Normal file
26
modules/hardware/cpus.nix
Normal file
@@ -0,0 +1,26 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.hardware.cpus = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.listOf (types.enum [ "intel" "amd" ]); default = []; };
|
||||
config = let inherit (inputs.config.nixos.hardware) cpus; in inputs.lib.mkIf (cpus != [])
|
||||
{
|
||||
hardware.cpu = builtins.listToAttrs
|
||||
(builtins.map (name: { inherit name; value = { updateMicrocode = true; }; }) cpus);
|
||||
boot =
|
||||
{
|
||||
initrd.availableKernelModules =
|
||||
let modules =
|
||||
{
|
||||
intel =
|
||||
[
|
||||
"intel_cstate" "aesni_intel" "intel_cstate" "intel_uncore" "intel_uncore_frequency" "intel_powerclamp"
|
||||
];
|
||||
amd = [];
|
||||
};
|
||||
in builtins.concatLists (builtins.map (cpu: modules.${cpu}) cpus);
|
||||
};
|
||||
environment.systemPackages =
|
||||
let packages = with inputs.pkgs; { intel = []; amd = [ zenmonitor ]; };
|
||||
in builtins.concatLists (builtins.map (cpu: packages.${cpu}) cpus);
|
||||
};
|
||||
}
|
||||
@@ -31,18 +31,14 @@ inputs:
|
||||
(
|
||||
let gpus = inputs.lib.strings.splitString "+" gpu.type; in
|
||||
{
|
||||
boot =
|
||||
{
|
||||
initrd.availableKernelModules =
|
||||
let modules =
|
||||
{
|
||||
intel = [ "i915" ];
|
||||
nvidia = []; # early loading breaks resume from hibernation
|
||||
amd = [];
|
||||
};
|
||||
in builtins.concatLists (builtins.map (gpu: modules.${gpu}) gpus);
|
||||
blacklistedKernelModules = [ "nouveau" ];
|
||||
};
|
||||
boot.initrd.availableKernelModules =
|
||||
let modules =
|
||||
{
|
||||
intel = [ "i915" ];
|
||||
nvidia = []; # early loading breaks resume from hibernation
|
||||
amd = [];
|
||||
};
|
||||
in builtins.concatLists (builtins.map (gpu: modules.${gpu}) gpus);
|
||||
hardware =
|
||||
{
|
||||
graphics =
|
||||
@@ -70,6 +66,7 @@ inputs:
|
||||
prime.allowExternalGpu = true;
|
||||
};
|
||||
};
|
||||
boot.blacklistedKernelModules = [ "nouveau" ];
|
||||
services.xserver.videoDrivers =
|
||||
let driver = { intel = "modesetting"; amd = "amdgpu"; nvidia = "nvidia"; };
|
||||
in builtins.map (gpu: driver.${gpu}) gpus;
|
||||
@@ -81,14 +78,6 @@ inputs:
|
||||
amd = [];
|
||||
};
|
||||
in builtins.concatLists (builtins.map (gpu: packages.${gpu}) gpus);
|
||||
environment.etc."nvidia/nvidia-application-profiles-rc.d/vram" = inputs.lib.mkIf (builtins.elem "nvidia" gpus)
|
||||
{
|
||||
source = inputs.pkgs.writeText "save-vram" (builtins.toJSON
|
||||
{
|
||||
rules = [{ pattern = { feature = "true"; matches = ""; }; profile = "save-vram"; }];
|
||||
profiles = [{ name = "save-vram"; settings = [{ key = "GLVidHeapReuseRatio"; value = 0; }]; }];
|
||||
});
|
||||
};
|
||||
}
|
||||
)
|
||||
# nvidia prime offload
|
||||
|
||||
@@ -3,7 +3,6 @@ inputs:
|
||||
options.nixos.model = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
hostname = mkOption { type = types.nonEmptyStr; };
|
||||
arch = mkOption { type = types.nonEmptyStr; default = "x86_64"; };
|
||||
type = mkOption { type = types.enum [ "minimal" "desktop" "server" ]; default = "minimal"; };
|
||||
private = mkOption { type = types.bool; default = false; };
|
||||
cluster = mkOption
|
||||
|
||||
@@ -3,7 +3,7 @@ inputs:
|
||||
options.nixos.packages.chromium = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if builtins.elem inputs.config.nixos.model.type [ "desktop" "server" ] then {} else null;
|
||||
default = if inputs.config.nixos.model.type == "desktop" then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.packages) chromium; in inputs.lib.mkIf (chromium != null)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ inputs:
|
||||
options.nixos.packages.desktop = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if builtins.elem inputs.config.nixos.model.type [ "desktop" "server" ] then {} else null;
|
||||
default = if inputs.config.nixos.model.type == "desktop" then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.packages) desktop; in inputs.lib.mkIf (desktop != null)
|
||||
{
|
||||
@@ -15,8 +15,7 @@ inputs:
|
||||
[
|
||||
# system management
|
||||
# TODO: module should add yubikey-touch-detector into path
|
||||
gparted wayland-utils clinfo glxinfo vulkan-tools dracut yubikey-touch-detector btrfs-assistant snapper-gui
|
||||
kdePackages.qtstyleplugin-kvantum ventoy-full cpu-x wl-mirror geekbench xpra
|
||||
gparted yubikey-touch-detector btrfs-assistant kdePackages.qtstyleplugin-kvantum cpu-x wl-mirror xpra
|
||||
(
|
||||
writeShellScriptBin "xclip"
|
||||
''
|
||||
@@ -24,84 +23,57 @@ inputs:
|
||||
else exec ${wl-clipboard-x11}/bin/xclip "$@"; fi
|
||||
''
|
||||
)
|
||||
# color management
|
||||
argyllcms xcalib
|
||||
# networking
|
||||
remmina putty mtr-gui
|
||||
remmina putty kdePackages.krdc
|
||||
# media
|
||||
mpv nomacs simplescreenrecorder imagemagick gimp-with-plugins netease-cloud-music-gtk qcm
|
||||
waifu2x-converter-cpp blender paraview vlc whalebird spotify obs-studio
|
||||
(inkscape-with-extensions.override { inkscapeExtensions = null; })
|
||||
# terminal
|
||||
warp-terminal
|
||||
mpv nomacs simplescreenrecorder imagemagick gimp-with-plugins qcm waifu2x-converter-cpp blender paraview vlc
|
||||
obs-studio (inkscape-with-extensions.override { inkscapeExtensions = null; }) kdePackages.kcolorchooser
|
||||
kdePackages.kdenlive
|
||||
# development
|
||||
adb-sync scrcpy dbeaver-bin cling aircrack-ng
|
||||
weston cage openbox krita fprettify # jetbrains.clion
|
||||
# desktop sharing
|
||||
rustdesk-flutter
|
||||
adb-sync scrcpy dbeaver-bin aircrack-ng fprettify
|
||||
# password and key management
|
||||
yubikey-manager yubikey-manager-qt yubikey-personalization yubikey-personalization-gui bitwarden hashcat
|
||||
electrum jabref john crunch
|
||||
kdePackages.kleopatra
|
||||
# download
|
||||
qbittorrent nur-xddxdd.baidupcs-go wgetpaste onedrive onedrivegui rclone
|
||||
qbittorrent wgetpaste rclone
|
||||
# editor
|
||||
typora appflowy notion-app-enhanced joplin-desktop standardnotes logseq obsidian code-cursor
|
||||
typora
|
||||
# news
|
||||
fluent-reader rssguard newsflash newsboat follow
|
||||
fluent-reader newsflash follow
|
||||
# nix tools
|
||||
nixpkgs-fmt appimage-run nixd nix-serve node2nix nix-prefetch-github prefetch-npm-deps nix-prefetch-docker
|
||||
nix-template nil bundix
|
||||
nixpkgs-fmt nixd nix-serve nix-prefetch-github prefetch-npm-deps nix-prefetch-docker
|
||||
# required by vscode nix tools
|
||||
nil
|
||||
# instant messager
|
||||
element-desktop telegram-desktop discord zoom-us slack nheko hexchat halloy
|
||||
fluffychat signal-desktop qq nur-xddxdd.wechat-uos-sandboxed cinny-desktop
|
||||
element-desktop telegram-desktop discord zoom-us slack nheko
|
||||
# browser
|
||||
google-chrome tor-browser
|
||||
# office
|
||||
crow-translate zotero pandoc texliveFull poppler_utils pdftk pdfchain davinci-resolve
|
||||
ydict texstudio panoply pspp libreoffice-qt6-fresh ocrmypdf typst # paperwork
|
||||
crow-translate zotero pandoc texliveFull poppler_utils pdftk pdfchain activitywatch
|
||||
ydict pspp libreoffice-qt6-fresh ocrmypdf typst
|
||||
# required by ltex-plus.vscode-ltex-plus
|
||||
ltex-ls ltex-ls-plus
|
||||
# matplot++ needs old gnuplot
|
||||
pkgs-2311.gnuplot
|
||||
inputs.pkgs.pkgs-2311.gnuplot
|
||||
# math, physics and chemistry
|
||||
octaveFull ovito localPackages.vesta localPackages.v-sim jmol mpi geogebra6 localPackages.ufo
|
||||
(quantum-espresso.override
|
||||
{
|
||||
stdenv = gcc14Stdenv;
|
||||
gfortran = gfortran14;
|
||||
wannier90 = wannier90.overrideAttrs { buildFlags = [ "dynlib" ]; };
|
||||
})
|
||||
pkgs-2311.hdfview numbat qalculate-qt
|
||||
(if inputs.config.nixos.system.nixpkgs.cuda != null then localPackages.mumax else emptyDirectory)
|
||||
(if inputs.config.nixos.system.nixpkgs.cuda != null
|
||||
then (lammps.override { stdenv = cudaPackages.backendStdenv; }).overrideAttrs (prev:
|
||||
{
|
||||
cmakeFlags = prev.cmakeFlags ++
|
||||
[ "-DPKG_GPU=on" "-DGPU_API=cuda" "-DCMAKE_POLICY_DEFAULT_CMP0146=OLD" ];
|
||||
nativeBuildInputs = prev.nativeBuildInputs ++ [ cudaPackages.cudatoolkit ];
|
||||
buildInputs = prev.buildInputs ++ [ mpi ];
|
||||
})
|
||||
else lammps-mpi)
|
||||
octaveFull mpi geogebra6 qalculate-qt
|
||||
# virtualization
|
||||
virt-viewer bottles wineWowPackages.stagingFull genymotion playonlinux
|
||||
bottles wineWowPackages.stagingFull
|
||||
# media
|
||||
nur-xddxdd.svp
|
||||
# for kdenlive auto subtitle
|
||||
openai-whisper
|
||||
]
|
||||
++ (builtins.filter (p: !((p.meta.broken or false) || (builtins.elem p.pname or null [ "falkon" "kalzium" ])))
|
||||
(builtins.filter inputs.lib.isDerivation (builtins.attrValues kdePackages.kdeGear)));
|
||||
];
|
||||
_pythonPackages = [(pythonPackages: with pythonPackages;
|
||||
[
|
||||
phonopy scipy scikit-learn jupyterlab autograd inputs.pkgs.localPackages.phono3py
|
||||
tensorflow keras numpy
|
||||
scipy scikit-learn jupyterlab autograd numpy
|
||||
])];
|
||||
};
|
||||
user.sharedModules =
|
||||
[{
|
||||
config.programs =
|
||||
{
|
||||
plasma = inputs.lib.mkIf (inputs.config.nixos.system.gui.implementation == "kde")
|
||||
plasma =
|
||||
{
|
||||
enable = true;
|
||||
configFile =
|
||||
@@ -147,21 +119,9 @@ inputs:
|
||||
adb.enable = true;
|
||||
wireshark = { enable = true; package = inputs.pkgs.wireshark; };
|
||||
yubikey-touch-detector.enable = true;
|
||||
kdeconnect.enable = inputs.lib.mkIf (inputs.config.nixos.system.gui.implementation == "kde") true;
|
||||
kde-pim = inputs.lib.mkIf (inputs.config.nixos.system.gui.implementation == "kde")
|
||||
{ enable = true; kmail = true; };
|
||||
coolercontrol =
|
||||
{
|
||||
enable = true;
|
||||
nvidiaSupport = if inputs.config.nixos.hardware.gpu.type == null then false
|
||||
else inputs.lib.hasSuffix "nvidia" inputs.config.nixos.hardware.gpu.type;
|
||||
};
|
||||
anime-game-launcher = { enable = true; package = inputs.pkgs.anime-game-launcher; };
|
||||
honkers-railway-launcher = { enable = true; package = inputs.pkgs.honkers-railway-launcher; };
|
||||
sleepy-launcher = { enable = true; package = inputs.pkgs.sleepy-launcher; };
|
||||
alvr = { enable = true; openFirewall = true; };
|
||||
localsend.enable = true;
|
||||
kdeconnect.enable = true;
|
||||
kde-pim = { enable = true; kmail = true; };
|
||||
};
|
||||
services = { pcscd.enable = true; lact.enable = true; };
|
||||
services.pcscd.enable = true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ inputs:
|
||||
options.nixos.packages.firefox = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if builtins.elem inputs.config.nixos.model.type [ "desktop" "server" ] then {} else null;
|
||||
default = if inputs.config.nixos.model.type == "desktop" then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.packages) firefox; in inputs.lib.mkIf (firefox != null)
|
||||
{
|
||||
@@ -24,11 +24,7 @@ inputs:
|
||||
{
|
||||
enable = true;
|
||||
nativeMessagingHosts = with inputs.pkgs;
|
||||
(
|
||||
[ uget-integrator ]
|
||||
++ (inputs.lib.optionals (inputs.config.nixos.system.gui.implementation == "kde")
|
||||
[ kdePackages.plasma-browser-integration ])
|
||||
);
|
||||
[ kdePackages.plasma-browser-integration uget-integrator ];
|
||||
# TODO: use fixed-version of plugins
|
||||
policies.DefaultDownloadDirectory = "\${home}/Downloads";
|
||||
profiles.default =
|
||||
@@ -37,9 +33,8 @@ inputs:
|
||||
[
|
||||
tampermonkey bitwarden cookies-txt dualsub firefox-color i-dont-care-about-cookies
|
||||
metamask pakkujs rsshub-radar rsspreview tabliss tree-style-tab ublock-origin
|
||||
wappalyzer grammarly zotero-connector smartproxy kiss-translator
|
||||
] ++ (inputs.lib.optionals (inputs.config.nixos.system.gui.implementation == "kde")
|
||||
[ plasma-integration ]);
|
||||
wappalyzer grammarly plasma-integration zotero-connector smartproxy kiss-translator
|
||||
];
|
||||
search = { default = "google"; force = true; };
|
||||
userChrome = builtins.readFile "${inputs.topInputs.lepton}/userChrome.css";
|
||||
userContent = builtins.readFile "${inputs.topInputs.lepton}/userContent.css";
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.packages.flatpak = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if builtins.elem inputs.config.nixos.model.type [ "desktop" "server" ] then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.packages) flatpak; in inputs.lib.mkIf (flatpak != null)
|
||||
{
|
||||
services.flatpak = { enable = true; uninstallUnmanaged = true; };
|
||||
};
|
||||
}
|
||||
23
modules/packages/lammps.nix
Normal file
23
modules/packages/lammps.nix
Normal file
@@ -0,0 +1,23 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.packages.lammps = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.packages) lammps; in inputs.lib.mkIf (lammps != null)
|
||||
{
|
||||
nixos.packages =
|
||||
{
|
||||
molecule = {};
|
||||
packages._packages =
|
||||
let cuda = let inherit (inputs.config.nixos.system.nixpkgs) cuda; in cuda.capabilities or null != null;
|
||||
in
|
||||
if cuda then [((inputs.pkgs.lammps.override { stdenv = inputs.pkgs.cudaPackages.backendStdenv; })
|
||||
.overrideAttrs (prev:
|
||||
{
|
||||
cmakeFlags = prev.cmakeFlags ++ [ "-DPKG_GPU=on" "-DGPU_API=cuda" "-DCMAKE_POLICY_DEFAULT_CMP0146=OLD" ];
|
||||
nativeBuildInputs = prev.nativeBuildInputs ++ [ inputs.pkgs.cudaPackages.cudatoolkit ];
|
||||
buildInputs = prev.buildInputs ++ [ inputs.pkgs.mpi ];
|
||||
}))]
|
||||
else [ inputs.pkgs.lammps-mpi ];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.packages.lumerical = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.packages) lumerical; in inputs.lib.mkIf (lumerical != null)
|
||||
{
|
||||
nixos =
|
||||
{
|
||||
packages.packages._packages = [ inputs.pkgs.localPackages.lumerical.lumerical.cmd ];
|
||||
services.lumericalLicenseManager = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -12,7 +12,7 @@ inputs:
|
||||
beep dos2unix gnugrep pv tmux screen parallel tldr cowsay jq yq ipfetch localPackages.pslist
|
||||
fastfetch reptyr duc ncdu progress libva-utils ksh neofetch dateutils kitty glib
|
||||
# lsxx
|
||||
pciutils usbutils lshw util-linux lsof dmidecode lm_sensors hwloc acpica-tools ethtool
|
||||
pciutils usbutils lshw util-linux lsof dmidecode lm_sensors hwloc acpica-tools
|
||||
# top
|
||||
iotop iftop htop btop powertop s-tui
|
||||
# editor
|
||||
@@ -22,40 +22,26 @@ inputs:
|
||||
# file manager
|
||||
tree eza trash-cli lsd broot file xdg-ninja mlocate
|
||||
# compress
|
||||
pigz upx unzip zip lzip p7zip
|
||||
(if inputs.pkgs.stdenv.hostPlatform.linuxArch == "x86_64" then rar else emptyDirectory)
|
||||
pigz upx unzip zip lzip p7zip rar
|
||||
# file system management
|
||||
sshfs e2fsprogs compsize exfatprogs
|
||||
# disk management
|
||||
smartmontools hdparm gptfdisk
|
||||
(if inputs.pkgs.stdenv.hostPlatform.linuxArch == "x86_64" then megacli else emptyDirectory)
|
||||
smartmontools hdparm gptfdisk megacli
|
||||
# encryption and authentication
|
||||
apacheHttpd openssl ssh-to-age gnupg age sops pam_u2f yubico-piv-tool libfido2
|
||||
# networking
|
||||
ipset iptables iproute2 dig nettools traceroute tcping-go whois tcpdump nmap inetutils wireguard-tools openvpn
|
||||
parted
|
||||
ipset iptables iproute2 dig nettools traceroute tcping-go whois tcpdump nmap inetutils wireguard-tools
|
||||
# nix tools
|
||||
nix-output-monitor nix-tree ssh-to-age nix-inspect
|
||||
# development
|
||||
gdb try rr hexo-cli gh nix-init hugo
|
||||
gdb try inputs.topInputs.plasma-manager.packages.${inputs.pkgs.system}.rc2nix rr hexo-cli gh nix-init hugo
|
||||
(octodns.withProviders (_: with octodns-providers; [ cloudflare ]))
|
||||
# stupid things
|
||||
toilet lolcat localPackages.stickerpicker graph-easy
|
||||
# office
|
||||
pdfgrep ffmpeg-full hdf5
|
||||
]
|
||||
++ (with inputs.config.boot.kernelPackages; [ cpupower usbip ])
|
||||
++ (inputs.lib.optionals (inputs.config.nixos.system.gui.implementation == "kde")
|
||||
[ inputs.topInputs.plasma-manager.packages.${inputs.pkgs.system}.rc2nix ]);
|
||||
_pythonPackages = [(pythonPackages: with pythonPackages;
|
||||
[
|
||||
openai python-telegram-bot fastapi-cli pypdf2 pandas matplotlib plotly gunicorn redis jinja2 certifi
|
||||
charset-normalizer idna orjson psycopg2 inquirerpy requests tqdm pydbus
|
||||
# allow pandas read odf
|
||||
odfpy
|
||||
# for vasp plot-workfunc.py
|
||||
ase
|
||||
])];
|
||||
++ (with inputs.config.boot.kernelPackages; [ cpupower usbip ]);
|
||||
};
|
||||
programs =
|
||||
{
|
||||
|
||||
20
modules/packages/molecule.nix
Normal file
20
modules/packages/molecule.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.packages.molecule = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if inputs.config.nixos.model.type == "desktop" then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.packages) molecule; in inputs.lib.mkIf (molecule != null)
|
||||
{
|
||||
nixos.packages.packages =
|
||||
{
|
||||
_packages = with inputs.pkgs;
|
||||
[ ovito localPackages.vesta localPackages.v-sim localPackages.ufo inputs.pkgs.pkgs-2311.hdfview ];
|
||||
_pythonPackages = [(pythonPackages: with pythonPackages;
|
||||
[
|
||||
phonopy inputs.pkgs.localPackages.phono3py
|
||||
])];
|
||||
};
|
||||
};
|
||||
}
|
||||
9
modules/packages/mumax.nix
Normal file
9
modules/packages/mumax.nix
Normal file
@@ -0,0 +1,9 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.packages.mumax = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.packages) mumax; in inputs.lib.mkIf (mumax != null)
|
||||
{
|
||||
nixos.packages.packages._packages = [ inputs.pkgs.localPackages.mumax ];
|
||||
};
|
||||
}
|
||||
@@ -3,7 +3,7 @@ inputs:
|
||||
options.nixos.packages.steam = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if builtins.elem inputs.config.nixos.model.type [ "desktop" "server" ] then {} else null;
|
||||
default = if inputs.config.nixos.model.type == "desktop" then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.packages) steam; in inputs.lib.mkIf (steam != null)
|
||||
{
|
||||
|
||||
@@ -4,15 +4,20 @@ inputs:
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.packages) vasp; in inputs.lib.mkIf (vasp != null)
|
||||
{
|
||||
nixos.packages.packages = with inputs.pkgs;
|
||||
nixos.packages =
|
||||
{
|
||||
_packages =
|
||||
[
|
||||
localPackages.vasp.intel localPackages.vasp.vtst localPackages.vaspkit wannier90
|
||||
(if inputs.config.nixos.system.nixpkgs.cuda != null then localPackages.vasp.nvidia else emptyDirectory)
|
||||
localPackages.atomkit (inputs.lib.mkAfter localPackages.atat)
|
||||
];
|
||||
_pythonPackages = [(_: [ localPackages.py4vasp ])];
|
||||
molecule = {};
|
||||
packages = with inputs.pkgs;
|
||||
{
|
||||
_packages =
|
||||
(
|
||||
[ localPackages.vasp.intel localPackages.vasp.vtst localPackages.vaspkit wannier90 ]
|
||||
++ (inputs.lib.optional
|
||||
(let inherit (inputs.config.nixos.system.nixpkgs) cuda; in cuda.capabilities or null != null)
|
||||
localPackages.vasp.nvidia)
|
||||
);
|
||||
_pythonPackages = [(_: [ localPackages.py4vasp ])];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ inputs:
|
||||
options.nixos.packages.vscode = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if builtins.elem inputs.config.nixos.model.type [ "desktop" "server" ] then {} else null;
|
||||
default = if inputs.config.nixos.model.type == "desktop" then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.packages) vscode; in inputs.lib.mkIf (vscode != null)
|
||||
{
|
||||
@@ -72,12 +72,9 @@ inputs:
|
||||
ltex-plus.vscode-ltex-plus
|
||||
]
|
||||
# jupyter
|
||||
# TODO: pick all extensions from nixpkgs or nix-vscode-extensions, explicitly
|
||||
# TODO: use last release
|
||||
++ (with vscode-extensions.ms-toolsai;
|
||||
[
|
||||
jupyter jupyter-keymap jupyter-renderers vscode-jupyter-cell-tags vscode-jupyter-slideshow
|
||||
datawrangler
|
||||
]);
|
||||
[ jupyter jupyter-keymap jupyter-renderers vscode-jupyter-cell-tags vscode-jupyter-slideshow ]);
|
||||
extraFlags = builtins.concatStringsSep " " inputs.config.nixos.packages.packages._vscodeEnvFlags;
|
||||
}
|
||||
)];
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.packages.winapps = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule {});
|
||||
default = if builtins.elem inputs.config.nixos.model.type [ "desktop" "server" ] then {} else null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.packages) winapps; in inputs.lib.mkIf (winapps != null)
|
||||
{
|
||||
nixos.packages.packages._packages =
|
||||
[
|
||||
(inputs.pkgs.callPackage "${inputs.topInputs.winapps}/packages/winapps" {})
|
||||
(inputs.pkgs.runCommand "winapps-windows" {}
|
||||
''
|
||||
mkdir -p $out/share/applications
|
||||
cp ${inputs.pkgs.replaceVars ./windows.desktop { path = inputs.topInputs.winapps; }} \
|
||||
$out/share/applications/windows.desktop
|
||||
'')
|
||||
]
|
||||
++ builtins.map
|
||||
(p: inputs.pkgs.runCommand "winapps-${p}" {}
|
||||
''
|
||||
mkdir -p $out/share/applications
|
||||
source ${inputs.topInputs.winapps}/apps/${p}/info
|
||||
# replace \ with \\
|
||||
WIN_EXECUTABLE=$(echo $WIN_EXECUTABLE | sed 's/\\/\\\\/g')
|
||||
# replace space with \s
|
||||
WIN_EXECUTABLE=$(echo $WIN_EXECUTABLE | sed 's/ /\\s/g')
|
||||
cat > $out/share/applications/${p}.desktop << EOF
|
||||
[Desktop Entry]
|
||||
Name=$NAME
|
||||
Exec=winapps manual "$WIN_EXECUTABLE" %F
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=${inputs.topInputs.winapps}/apps/${p}/icon.svg
|
||||
StartupWMClass=$FULL_NAME
|
||||
Comment=$FULL_NAME
|
||||
Categories=$CATEGORIES
|
||||
MimeType=$MIME_TYPES
|
||||
EOF
|
||||
'')
|
||||
[
|
||||
"access-o365" "acrobat-x-pro" "cmd" "excel-o365" "explorer" "illustrator-cc" "powerpoint-o365"
|
||||
"visual-studio-comm" "word-o365"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=Windows
|
||||
Exec=winapps windows %F
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=@path@/icons/windows.svg
|
||||
StartupWMClass=Micorosoft Windows
|
||||
Comment=Micorosoft Windows
|
||||
Categories=Windows
|
||||
@@ -35,7 +35,7 @@ inputs:
|
||||
}
|
||||
{
|
||||
programs.zsh = inputs.lib.mkIf
|
||||
(builtins.elem home-inputs.config.home.username [ "chn" "root" "aleksana" "alikia" "hjp" ])
|
||||
(builtins.elem home-inputs.config.home.username [ "chn" "root" "aleksana" "alikia" ])
|
||||
{
|
||||
plugins =
|
||||
[
|
||||
@@ -63,7 +63,6 @@ inputs:
|
||||
[[ ! -r "$P10K_INSTANT_PROMPT" ]] || source "$P10K_INSTANT_PROMPT"
|
||||
HYPHEN_INSENSITIVE="true"
|
||||
export PATH=~/bin:$PATH
|
||||
zstyle ':vcs_info:*' disable-patterns "/nix/remote/*"
|
||||
'';
|
||||
oh-my-zsh.theme = "";
|
||||
};
|
||||
|
||||
@@ -34,21 +34,21 @@ inputs:
|
||||
name = builtins.elemAt cert.value.domains 0;
|
||||
value =
|
||||
{
|
||||
credentialsFile = inputs.config.nixos.system.sops.templates."acme/cloudflare.ini".path;
|
||||
credentialsFile = inputs.config.sops.templates."acme/cloudflare.ini".path;
|
||||
extraDomainNames = builtins.tail cert.value.domains;
|
||||
group = inputs.lib.mkIf (cert.value.group != null) cert.value.group;
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList acme.cert));
|
||||
};
|
||||
nixos.system.sops =
|
||||
sops =
|
||||
{
|
||||
templates."acme/cloudflare.ini".content =
|
||||
''
|
||||
CLOUDFLARE_DNS_API_TOKEN=${inputs.config.nixos.system.sops.placeholder."acme/token"}
|
||||
CLOUDFLARE_DNS_API_TOKEN=${inputs.config.sops.placeholder."acme/token"}
|
||||
CLOUDFLARE_PROPAGATION_TIMEOUT=300
|
||||
'';
|
||||
secrets."acme/token" = {};
|
||||
secrets."acme/token".sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,19 +15,25 @@ inputs:
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) beesd; in inputs.lib.mkIf (beesd != null)
|
||||
{
|
||||
services.beesd.filesystems = inputs.lib.mapAttrs'
|
||||
(n: v: inputs.lib.nameValuePair (inputs.utils.escapeSystemdPath n)
|
||||
services.beesd.filesystems = builtins.listToAttrs (builtins.map
|
||||
(fs:
|
||||
{
|
||||
spec = n;
|
||||
inherit (v) hashTableSizeMB;
|
||||
extraOptions =
|
||||
[
|
||||
"--thread-count" "${builtins.toString v.threads}"
|
||||
"--loadavg-target" "${builtins.toString v.loadAverage}"
|
||||
"--verbose" "4"
|
||||
];
|
||||
name = inputs.utils.escapeSystemdPath fs.name;
|
||||
value =
|
||||
{
|
||||
spec = fs.name;
|
||||
inherit (fs.value) hashTableSizeMB;
|
||||
extraOptions =
|
||||
[
|
||||
"--workaround-btrfs-send"
|
||||
"--thread-count" "${builtins.toString fs.value.threads}"
|
||||
"--loadavg-target" "${builtins.toString fs.value.loadAverage}"
|
||||
"--scan-mode" "3"
|
||||
"--verbose" "4"
|
||||
];
|
||||
};
|
||||
})
|
||||
beesd;
|
||||
(inputs.localLib.attrsToList beesd));
|
||||
nixos.packages.packages._packages = [ inputs.pkgs.bees ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.bind = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule (submoduleInputs: {})); default = null; };
|
||||
config = let inherit (inputs.config.nixos.services) bind; in inputs.lib.mkIf (bind != null)
|
||||
{
|
||||
services.bind =
|
||||
let
|
||||
chinaZone = inputs.pkgs.writeText "autoroute.chn.moe.china.zone"
|
||||
''
|
||||
$ORIGIN autoroute.chn.moe.
|
||||
$TTL 3600
|
||||
@ IN SOA vps6.chn.moe. chn.chn.moe. (
|
||||
2024071301 ; serial
|
||||
3600 ; refresh
|
||||
600 ; retry
|
||||
604800 ; expire
|
||||
300 ; minimum
|
||||
)
|
||||
@ IN NS vps6.chn.moe.
|
||||
@ IN A ${inputs.topInputs.self.config.dns."chn.moe".getAddress "vps6"}
|
||||
'';
|
||||
globalZone = inputs.pkgs.writeText "autoroute.chn.moe.zone"
|
||||
''
|
||||
$ORIGIN autoroute.chn.moe.
|
||||
$TTL 3600
|
||||
@ IN SOA vps6.chn.moe. chn.chn.moe. (
|
||||
2024071301 ; serial
|
||||
3600 ; refresh
|
||||
600 ; retry
|
||||
604800 ; expire
|
||||
300 ; minimum
|
||||
)
|
||||
@ IN NS vps6.chn.moe.
|
||||
@ IN A ${inputs.topInputs.self.config.dns."chn.moe".getAddress "srv3"}
|
||||
'';
|
||||
nullZone = inputs.pkgs.writeText "null.zone" "";
|
||||
in
|
||||
{
|
||||
enable = true;
|
||||
package = inputs.pkgs.bind.overrideAttrs
|
||||
(prev: { buildInputs = prev.buildInputs ++ [ inputs.pkgs.libmaxminddb ]; });
|
||||
listenOn = [(inputs.topInputs.self.config.dns."chn.moe".getAddress "vps6")];
|
||||
extraOptions =
|
||||
''
|
||||
recursion no;
|
||||
geoip-directory "${inputs.config.services.geoipupdate.settings.DatabaseDirectory}";
|
||||
'';
|
||||
extraConfig =
|
||||
''
|
||||
acl "china" {
|
||||
geoip country CN;
|
||||
};
|
||||
|
||||
view "china" {
|
||||
match-clients { china; };
|
||||
zone "autoroute.chn.moe" {
|
||||
type master;
|
||||
file "${chinaZone}";
|
||||
};
|
||||
zone "." {
|
||||
type hint;
|
||||
file "${nullZone}";
|
||||
};
|
||||
};
|
||||
view "global" {
|
||||
match-clients { any; };
|
||||
zone "autoroute.chn.moe" {
|
||||
type master;
|
||||
file "${globalZone}";
|
||||
};
|
||||
zone "." {
|
||||
type hint;
|
||||
file "${nullZone}";
|
||||
};
|
||||
};
|
||||
'';
|
||||
};
|
||||
nixos.services.geoipupdate = {};
|
||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
}
|
||||
@@ -14,17 +14,14 @@ inputs:
|
||||
{
|
||||
enable = true;
|
||||
use-auth-secret = true;
|
||||
static-auth-secret-file = inputs.config.nixos.system.sops.secrets."coturn/auth-secret".path;
|
||||
static-auth-secret-file = inputs.config.sops.secrets."coturn/auth-secret".path;
|
||||
realm = coturn.hostname;
|
||||
cert = "${keydir}/full.pem";
|
||||
pkey = "${keydir}/key.pem";
|
||||
no-cli = true;
|
||||
};
|
||||
nixos =
|
||||
{
|
||||
system.sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
|
||||
services.acme.cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
|
||||
};
|
||||
sops.secrets."coturn/auth-secret".owner = inputs.config.systemd.services.coturn.serviceConfig.User;
|
||||
nixos.services.acme.cert.${coturn.hostname}.group = inputs.config.systemd.services.coturn.serviceConfig.Group;
|
||||
networking.firewall = with inputs.config.services.coturn;
|
||||
{
|
||||
allowedUDPPorts = [ listening-port tls-listening-port ];
|
||||
|
||||
31
modules/services/docker.nix
Normal file
31
modules/services/docker.nix
Normal file
@@ -0,0 +1,31 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.docker = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.services) docker; in inputs.lib.mkIf (docker != null)
|
||||
{
|
||||
virtualisation.docker =
|
||||
{
|
||||
enable = true;
|
||||
# prevent create btrfs subvol
|
||||
storageDriver = "overlay2";
|
||||
daemon.settings.dns = [ "1.1.1.1" ];
|
||||
rootless =
|
||||
{
|
||||
enable = true;
|
||||
setSocketVariable = true;
|
||||
daemon.settings =
|
||||
{
|
||||
features.buildkit = true;
|
||||
# dns 127.0.0.1 make docker not work
|
||||
dns = [ "1.1.1.1" ];
|
||||
# prevent create btrfs subvol
|
||||
storage-driver = "overlay2";
|
||||
live-restore = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
hardware.nvidia-container-toolkit.enable = inputs.lib.mkIf (inputs.config.nixos.system.nixpkgs.cuda != null) true;
|
||||
networking.firewall.trustedInterfaces = [ "docker0" ];
|
||||
};
|
||||
}
|
||||
@@ -15,18 +15,19 @@ inputs:
|
||||
enable = true;
|
||||
baseUrl = "https://${freshrss.hostname}";
|
||||
defaultUser = "chn";
|
||||
passwordFile = inputs.config.nixos.system.sops.secrets."freshrss/chn".path;
|
||||
database = { type = "mysql"; passFile = inputs.config.nixos.system.sops.secrets."freshrss/db".path; };
|
||||
passwordFile = inputs.config.sops.secrets."freshrss/chn".path;
|
||||
database = { type = "mysql"; passFile = inputs.config.sops.secrets."freshrss/db".path; };
|
||||
};
|
||||
sops.secrets =
|
||||
{
|
||||
"freshrss/chn".owner = inputs.config.users.users.freshrss.name;
|
||||
"freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; };
|
||||
};
|
||||
systemd.services.freshrss-config.after = [ "mysql.service" ];
|
||||
nixos =
|
||||
nixos.services =
|
||||
{
|
||||
services = { mariadb.instances.freshrss = {}; nginx.https.${freshrss.hostname}.global.configName = "freshrss"; };
|
||||
system.sops.secrets =
|
||||
{
|
||||
"freshrss/chn".owner = inputs.config.users.users.freshrss.name;
|
||||
"freshrss/db" = { owner = inputs.config.users.users.freshrss.name; key = "mariadb/freshrss"; };
|
||||
};
|
||||
mariadb = { enable = true; instances.freshrss = {}; };
|
||||
nginx.https.${freshrss.hostname}.global.configName = "freshrss";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
203
modules/services/frp.nix
Normal file
203
modules/services/frp.nix
Normal file
@@ -0,0 +1,203 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
frpClient =
|
||||
{
|
||||
enable = mkOption { type = types.bool; default = false; };
|
||||
serverName = mkOption { type = types.nonEmptyStr; };
|
||||
user = mkOption { type = types.nonEmptyStr; };
|
||||
tcp = mkOption
|
||||
{
|
||||
type = types.attrsOf (types.submodule (inputs:
|
||||
{
|
||||
options =
|
||||
{
|
||||
localIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
|
||||
localPort = mkOption { type = types.ints.unsigned; };
|
||||
remoteIp = mkOption { type = types.nonEmptyStr; default = "127.0.0.1"; };
|
||||
remotePort = mkOption { type = types.ints.unsigned; default = inputs.config.localPort; };
|
||||
};
|
||||
}));
|
||||
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 =
|
||||
{
|
||||
enable = mkOption { type = types.bool; default = false; };
|
||||
serverName = mkOption { type = types.nonEmptyStr; };
|
||||
};
|
||||
};
|
||||
config =
|
||||
let
|
||||
inherit (inputs.lib) mkMerge mkIf;
|
||||
inherit (inputs.lib.strings) splitString;
|
||||
inherit (inputs.localLib) attrsToList;
|
||||
inherit (inputs.config.nixos.services) frpClient frpServer;
|
||||
inherit (builtins) map listToAttrs;
|
||||
in mkMerge
|
||||
[
|
||||
(
|
||||
mkIf frpClient.enable
|
||||
{
|
||||
systemd.services.frpc =
|
||||
let
|
||||
frpc = "${inputs.pkgs.frp}/bin/frpc";
|
||||
config = inputs.config.sops.templates."frpc.json";
|
||||
in
|
||||
{
|
||||
description = "Frp Client Service";
|
||||
after = [ "network.target" ];
|
||||
serviceConfig =
|
||||
{
|
||||
Type = "simple";
|
||||
User = "frp";
|
||||
Restart = "always";
|
||||
RestartSec = "5s";
|
||||
ExecStart = "${frpc} -c ${config.path}";
|
||||
LimitNOFILE = 1048576;
|
||||
};
|
||||
wantedBy= [ "multi-user.target" ];
|
||||
restartTriggers = [ config.file ];
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates."frpc.json" =
|
||||
{
|
||||
owner = inputs.config.users.users.frp.name;
|
||||
group = inputs.config.users.users.frp.group;
|
||||
content = builtins.toJSON
|
||||
{
|
||||
auth.token = inputs.config.sops.placeholder."frp/token";
|
||||
user = frpClient.user;
|
||||
serverAddr = frpClient.serverName;
|
||||
serverPort = 7000;
|
||||
proxies =
|
||||
(map
|
||||
(tcp:
|
||||
{
|
||||
name = tcp.name;
|
||||
type = "tcp";
|
||||
transport.useCompression = true;
|
||||
inherit (tcp.value) localIp localPort remotePort;
|
||||
})
|
||||
(attrsToList frpClient.tcp))
|
||||
++ (map
|
||||
(stcp:
|
||||
{
|
||||
name = stcp.name;
|
||||
type = "stcp";
|
||||
transport.useCompression = true;
|
||||
secretKey = inputs.config.sops.placeholder."frp/stcp/${stcp.name}";
|
||||
allowUsers = [ "*" ];
|
||||
inherit (stcp.value) localIp localPort;
|
||||
})
|
||||
(attrsToList frpClient.stcp));
|
||||
visitors = map
|
||||
(stcp:
|
||||
{
|
||||
name = stcp.name;
|
||||
type = "stcp";
|
||||
transport.useCompression = 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 = 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.user.uid.frp; group = "frp"; isSystemUser = true; };
|
||||
groups.frp.gid = inputs.config.nixos.user.gid.frp;
|
||||
};
|
||||
}
|
||||
)
|
||||
(
|
||||
mkIf frpServer.enable
|
||||
{
|
||||
systemd.services.frps =
|
||||
let
|
||||
frps = "${inputs.pkgs.frp}/bin/frps";
|
||||
config = inputs.config.sops.templates."frps.json";
|
||||
in
|
||||
{
|
||||
description = "Frp Server Service";
|
||||
after = [ "network.target" ];
|
||||
serviceConfig =
|
||||
{
|
||||
Type = "simple";
|
||||
User = "frp";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
ExecStart = "${frps} -c ${config.path}";
|
||||
LimitNOFILE = 1048576;
|
||||
};
|
||||
wantedBy= [ "multi-user.target" ];
|
||||
restartTriggers = [ config.file ];
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates."frps.json" =
|
||||
{
|
||||
owner = inputs.config.users.users.frp.name;
|
||||
group = inputs.config.users.users.frp.group;
|
||||
content = builtins.toJSON
|
||||
{
|
||||
auth.token = inputs.config.sops.placeholder."frp/token";
|
||||
transport.tls = let cert = inputs.config.security.acme.certs.${frpServer.serverName}.directory; in
|
||||
{
|
||||
force = true;
|
||||
certFile = "${cert}/full.pem";
|
||||
keyFile = "${cert}/key.pem";
|
||||
serverName = frpServer.serverName;
|
||||
};
|
||||
};
|
||||
};
|
||||
secrets."frp/token" = {};
|
||||
};
|
||||
nixos.services.acme.cert.${frpServer.serverName}.group = "frp";
|
||||
users =
|
||||
{
|
||||
users.frp = { uid = inputs.config.nixos.user.uid.frp; group = "frp"; isSystemUser = true; };
|
||||
groups.frp.gid = inputs.config.nixos.user.gid.frp;
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 7000 ];
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.geoipupdate = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.services) geoipupdate; in inputs.lib.mkIf (geoipupdate != null)
|
||||
{
|
||||
services.geoipupdate =
|
||||
{
|
||||
enable = true;
|
||||
settings =
|
||||
{
|
||||
AccountID = 901296;
|
||||
LicenseKey = inputs.config.nixos.system.sops.secrets."maxmind".path;
|
||||
EditionIDs = [ "GeoLite2-ASN" "GeoLite2-City" "GeoLite2-Country" ];
|
||||
};
|
||||
};
|
||||
nixos.system.sops.secrets."maxmind" = {};
|
||||
};
|
||||
}
|
||||
@@ -1,31 +1,28 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.gitea = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
options.nixos.services.gitea = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
type = types.nullOr (types.submodule { options =
|
||||
enable = mkOption { type = types.bool; default = false; };
|
||||
hostname = mkOption { type = types.str; default = "git.chn.moe"; };
|
||||
ssh = mkOption
|
||||
{
|
||||
hostname = mkOption { type = types.str; default = "git.chn.moe"; };
|
||||
ssh =
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
hostname = mkOption { type = types.str; default = "ssh.${inputs.config.nixos.services.gitea.hostname}"; };
|
||||
port = mkOption { type = types.nullOr types.ints.unsigned; default = null; };
|
||||
};
|
||||
};});
|
||||
default = null;
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) gitea; in inputs.lib.mkIf (gitea != null)
|
||||
config = let inherit (inputs.config.nixos.services) gitea; in inputs.lib.mkIf gitea.enable
|
||||
{
|
||||
services.gitea =
|
||||
{
|
||||
enable = true;
|
||||
lfs.enable = true;
|
||||
mailerPasswordFile = inputs.config.nixos.system.sops.secrets."gitea/mail".path;
|
||||
mailerPasswordFile = inputs.config.sops.secrets."gitea/mail".path;
|
||||
database =
|
||||
{
|
||||
createDatabase = false;
|
||||
type = "postgres";
|
||||
passwordFile = inputs.config.nixos.system.sops.secrets."gitea/db".path;
|
||||
};
|
||||
{ createDatabase = false; type = "postgres"; passwordFile = inputs.config.sops.secrets."gitea/db".path; };
|
||||
settings =
|
||||
{
|
||||
session.COOKIE_SECURE = true;
|
||||
@@ -34,8 +31,8 @@ inputs:
|
||||
ROOT_URL = "https://${gitea.hostname}";
|
||||
DOMAIN = gitea.hostname;
|
||||
HTTP_PORT = 3002;
|
||||
SSH_DOMAIN = gitea.ssh.hostname;
|
||||
SSH_PORT = inputs.lib.mkIf (gitea.ssh.port != null) gitea.ssh.port;
|
||||
SSH_DOMAIN = inputs.lib.mkIf (gitea.ssh != null) gitea.ssh.hostname;
|
||||
SSH_PORT = inputs.lib.mkIf ((gitea.ssh.port or null) != null) gitea.ssh.port;
|
||||
};
|
||||
mailer =
|
||||
{
|
||||
@@ -52,17 +49,12 @@ inputs:
|
||||
[ "DEFAULT" "MIGRATE" "MIRROR" "CLONE" "PULL" "GC" ]);
|
||||
};
|
||||
};
|
||||
nixos =
|
||||
nixos.services =
|
||||
{
|
||||
system.sops.secrets =
|
||||
nginx =
|
||||
{
|
||||
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
|
||||
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
|
||||
"mail/bot" = {};
|
||||
};
|
||||
services =
|
||||
{
|
||||
nginx.https.${gitea.hostname}.location =
|
||||
enable = true;
|
||||
https.${gitea.hostname}.location =
|
||||
{
|
||||
"/".proxy.upstream = "http://127.0.0.1:3002";
|
||||
"/robots.txt".static.root =
|
||||
@@ -73,8 +65,14 @@ inputs:
|
||||
};
|
||||
in "${inputs.pkgs.runCommand "robots.txt" {} "mkdir -p $out; cp ${robotsFile} $out/robots.txt"}";
|
||||
};
|
||||
postgresql.instances.gitea = {};
|
||||
};
|
||||
postgresql.instances.gitea = {};
|
||||
};
|
||||
sops.secrets =
|
||||
{
|
||||
"gitea/mail" = { owner = "gitea"; key = "mail/bot"; };
|
||||
"gitea/db" = { owner = "gitea"; key = "postgresql/gitea"; };
|
||||
"mail/bot" = {};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ inputs:
|
||||
enabled = true;
|
||||
host = "mail.chn.moe";
|
||||
user = "bot@chn.moe";
|
||||
password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/mail".path}}";
|
||||
password = "$__file{${inputs.config.sops.secrets."grafana/mail".path}}";
|
||||
from_address = "bot@chn.moe";
|
||||
ehlo_identity = grafana.hostname;
|
||||
startTLS_policy = "MandatoryStartTLS";
|
||||
@@ -32,9 +32,9 @@ inputs:
|
||||
server = { root_url = "https://${grafana.hostname}"; http_port = 3001; enable_gzip = true; };
|
||||
security =
|
||||
{
|
||||
secret_key = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/secret".path}}";
|
||||
secret_key = "$__file{${inputs.config.sops.secrets."grafana/secret".path}}";
|
||||
admin_user = "chn";
|
||||
admin_password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/chn".path}}";
|
||||
admin_password = "$__file{${inputs.config.sops.secrets."grafana/chn".path}}";
|
||||
admin_email = "chn@chn.moe";
|
||||
};
|
||||
database =
|
||||
@@ -42,7 +42,7 @@ inputs:
|
||||
type = "postgres";
|
||||
host = "127.0.0.1:5432";
|
||||
user = "grafana";
|
||||
password = "$__file{${inputs.config.nixos.system.sops.secrets."grafana/db".path}}";
|
||||
password = "$__file{${inputs.config.sops.secrets."grafana/db".path}}";
|
||||
};
|
||||
};
|
||||
provision =
|
||||
@@ -78,21 +78,23 @@ inputs:
|
||||
extraFlags = [ "--storage.tsdb.max-block-chunk-segment-size=16MB" ];
|
||||
};
|
||||
};
|
||||
nixos =
|
||||
nixos.services =
|
||||
{
|
||||
services =
|
||||
nginx =
|
||||
{
|
||||
nginx.https.${grafana.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3001"; websocket = true; };
|
||||
postgresql.instances.grafana = {};
|
||||
};
|
||||
system.sops.secrets = let owner = inputs.config.systemd.services.grafana.serviceConfig.User; in
|
||||
{
|
||||
"grafana/mail" = { owner = owner; key = "mail/bot"; };
|
||||
"grafana/secret".owner = owner;
|
||||
"grafana/chn".owner = owner;
|
||||
"grafana/db" = { owner = owner; key = "postgresql/grafana"; };
|
||||
"mail/bot" = {};
|
||||
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" = {};
|
||||
};
|
||||
environment.persistence."/nix/nodatacow".directories =
|
||||
[{ directory = "/var/lib/prometheus2"; user = "prometheus"; group = "prometheus"; mode = "0700"; }];
|
||||
|
||||
@@ -15,13 +15,13 @@ inputs:
|
||||
grep = "${inputs.pkgs.gnugrep}/bin/grep";
|
||||
curl = "${inputs.pkgs.curl}/bin/curl";
|
||||
cat = "${inputs.pkgs.coreutils}/bin/cat";
|
||||
token = inputs.config.nixos.system.sops.secrets."telegram/token".path;
|
||||
chat = inputs.config.nixos.system.sops.secrets."telegram/user/chn".path;
|
||||
token = inputs.config.sops.secrets."telegram/token".path;
|
||||
chat = inputs.config.sops.secrets."telegram/user/chn".path;
|
||||
date = "${inputs.pkgs.coreutils}/bin/date";
|
||||
hpcstat = "${inputs.pkgs.localPackages.hpcstat}/bin/hpcstat";
|
||||
ssh = "${inputs.pkgs.openssh}/bin/ssh -i ${key} -o StrictHostKeyChecking=no"
|
||||
+ " -o ForwardAgent=yes -o AddKeysToAgent=yes";
|
||||
key = inputs.config.nixos.system.sops.secrets."hpcstat/key".path;
|
||||
key = inputs.config.sops.secrets."hpcstat/key".path;
|
||||
jykang = "${inputs.topInputs.self}/devices/jykang.xmuhpc/files";
|
||||
ssh-agent = "${inputs.pkgs.openssh}/bin/ssh-agent";
|
||||
in
|
||||
@@ -105,10 +105,10 @@ inputs:
|
||||
(inputs.localLib.attrsToList calenders));
|
||||
tmpfiles.rules = [ "d /var/lib/hpcstat 0700 hpcstat hpcstat" ];
|
||||
};
|
||||
nixos.system.sops.secrets =
|
||||
sops.secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in
|
||||
{
|
||||
"telegram/token" = { group = "telegram"; mode = "0440"; };
|
||||
"telegram/user/chn" = { group = "telegram"; mode = "0440"; };
|
||||
"telegram/token" = { group = "telegram"; mode = "0440"; inherit sopsFile; };
|
||||
"telegram/user/chn" = { group = "telegram"; mode = "0440"; inherit sopsFile; };
|
||||
"hpcstat/key" = { owner = "hpcstat"; group = "hpcstat"; };
|
||||
};
|
||||
users =
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.httpapi = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
options.nixos.services.httpapi = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
hostname = mkOption { type = types.nonEmptyStr; default = "api.chn.moe"; };
|
||||
};});
|
||||
default = null;
|
||||
enable = mkOption { type = types.bool; default = false; };
|
||||
hostname = mkOption { type = types.nonEmptyStr; default = "api.chn.moe"; };
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) httpapi; in inputs.lib.mkIf (httpapi != null)
|
||||
{
|
||||
nixos =
|
||||
config =
|
||||
let
|
||||
inherit (inputs.config.nixos.services) httpapi;
|
||||
inherit (inputs.lib) mkIf;
|
||||
inherit (builtins) toString map;
|
||||
in mkIf httpapi.enable
|
||||
{
|
||||
services =
|
||||
nixos.services =
|
||||
{
|
||||
phpfpm.instances.httpapi = {};
|
||||
nginx.https.${httpapi.hostname}.location =
|
||||
@@ -21,12 +21,12 @@ inputs:
|
||||
"/led".static = { root = "/srv/api"; detectAuth.users = [ "led" ]; };
|
||||
"/notify.php".php =
|
||||
{
|
||||
root = builtins.dirOf inputs.config.nixos.system.sops.templates."httpapi/notify.php".path;
|
||||
root = builtins.dirOf inputs.config.sops.templates."httpapi/notify.php".path;
|
||||
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpapi.fastcgi;
|
||||
};
|
||||
};
|
||||
};
|
||||
system.sops =
|
||||
sops =
|
||||
{
|
||||
templates."httpapi/notify.php" =
|
||||
{
|
||||
@@ -34,14 +34,14 @@ inputs:
|
||||
group = inputs.config.users.users.httpapi.group;
|
||||
content =
|
||||
let
|
||||
inherit (inputs.config.sops) placeholder;
|
||||
placeholder = inputs.config.sops.placeholder;
|
||||
request = "https://api.telegram.org/bot${placeholder."telegram/token"}"
|
||||
+ "/sendMessage?chat_id=${placeholder."telegram/user/chn"}&text=";
|
||||
in ''<?php print file_get_contents("${request}".urlencode($_GET["message"])); ?>'';
|
||||
};
|
||||
secrets = { "telegram/token" = {}; "telegram/user/chn" = {}; };
|
||||
secrets = let sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml"; in
|
||||
{ "telegram/token" = { inherit sopsFile; }; "telegram/user/chn" = { inherit sopsFile; }; };
|
||||
};
|
||||
systemd.tmpfiles.rules = [ "d /srv/api 0700 nginx nginx" "Z /srv/api - nginx nginx" ];
|
||||
};
|
||||
systemd.tmpfiles.rules = [ "d /srv/api 0700 nginx nginx" "Z /srv/api - nginx nginx" ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,10 +14,7 @@ inputs:
|
||||
{
|
||||
phpfpm.instances.httpua = {};
|
||||
nginx.http.${httpua.hostname}.php =
|
||||
{
|
||||
root = builtins.toString (inputs.pkgs.writeTextDir "index.php" "<?php echo $_SERVER['HTTP_USER_AGENT']; ?>");
|
||||
fastcgiPass = inputs.config.nixos.services.phpfpm.instances.httpua.fastcgi;
|
||||
};
|
||||
{ root = "${./.}"; 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']; ?>
|
||||
@@ -15,38 +15,43 @@ inputs:
|
||||
image = "ghcr.io/huginn/huginn:latest";
|
||||
imageFile = inputs.topInputs.self.src.huginn;
|
||||
ports = [ "127.0.0.1:3000:3000/tcp" ];
|
||||
environmentFiles = [ inputs.config.nixos.system.sops.templates."huginn/env".path ];
|
||||
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
|
||||
environmentFiles = [ inputs.config.sops.templates."huginn/env".path ];
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates."huginn/env".content = let placeholder = inputs.config.sops.placeholder; in
|
||||
''
|
||||
MYSQL_PORT_3306_TCP_ADDR=host.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 =
|
||||
{
|
||||
nginx.https.${huginn.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3000"; websocket = true; };
|
||||
nginx =
|
||||
{
|
||||
enable = true;
|
||||
https.${huginn.hostname}.location."/".proxy = { upstream = "http://127.0.0.1:3000"; websocket = true; };
|
||||
};
|
||||
mariadb.instances.huginn = {};
|
||||
podman = {};
|
||||
};
|
||||
system.sops =
|
||||
{
|
||||
templates."huginn/env".content = let inherit (inputs.config.nixos.system.sops) placeholder; in
|
||||
''
|
||||
MYSQL_PORT_3306_TCP_ADDR=host.containers.internal
|
||||
HUGINN_DATABASE_NAME=huginn
|
||||
HUGINN_DATABASE_USERNAME=huginn
|
||||
HUGINN_DATABASE_PASSWORD=${placeholder."mariadb/huginn"}
|
||||
DOMAIN=${huginn.hostname}
|
||||
RAILS_ENV=production
|
||||
FORCE_SSL=true
|
||||
INVITATION_CODE=${placeholder."huginn/invitationCode"}
|
||||
SMTP_DOMAIN=mail.chn.moe
|
||||
SMTP_USER_NAME=bot@chn.moe
|
||||
SMTP_PASSWORD="${placeholder."mail/bot"}"
|
||||
SMTP_SERVER=mail.chn.moe
|
||||
SMTP_SSL=true
|
||||
EMAIL_FROM_ADDRESS=bot@chn.moe
|
||||
TIMEZONE=Beijing
|
||||
DO_NOT_CREATE_DATABASE=true
|
||||
'';
|
||||
secrets = { "huginn/invitationCode" = {}; "mail/bot" = {}; };
|
||||
docker = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -5,17 +5,21 @@ inputs:
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
nodatacow = mkOption { type = types.bool; default = false; };
|
||||
aarch64 = mkOption { type = types.bool; default = false; };
|
||||
autoSuspend = mkOption { type = types.listOf types.nonEmptyStr; default = []; };
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) kvm; in inputs.lib.mkIf (kvm != null)
|
||||
{
|
||||
nix.settings.system-features = [ "kvm" ];
|
||||
boot = let inherit (inputs.config.nixos.hardware) cpu; in
|
||||
boot =
|
||||
{
|
||||
kernelModules = { intel = [ "kvm-intel" ]; amd = []; }.${cpu};
|
||||
extraModprobeConfig = { intel = "options kvm_intel nested=1"; amd = ""; }.${cpu};
|
||||
kernelModules =
|
||||
let modules = { intel = [ "kvm-intel" ]; amd = []; };
|
||||
in builtins.concatLists (builtins.map (cpu: modules.${cpu}) inputs.config.nixos.hardware.cpus);
|
||||
extraModprobeConfig =
|
||||
let configs = { intel = "options kvm_intel nested=1"; amd = ""; };
|
||||
in builtins.concatStringsSep "\n" (builtins.map (cpu: configs.${cpu}) inputs.config.nixos.hardware.cpus);
|
||||
};
|
||||
virtualisation =
|
||||
{
|
||||
@@ -29,8 +33,7 @@ inputs:
|
||||
parallelShutdown = 4;
|
||||
qemu =
|
||||
{
|
||||
ovmf.packages = with inputs.pkgs;
|
||||
([ OVMF.fd ] ++ inputs.lib.optionals kvm.aarch64 [ pkgsCross.aarch64-multiplatform.OVMF.fd ]);
|
||||
ovmf.packages = with inputs.pkgs; [ OVMF.fd pkgsCross.aarch64-multiplatform.OVMF.fd ];
|
||||
swtpm.enable = true;
|
||||
};
|
||||
};
|
||||
@@ -40,17 +43,82 @@ inputs:
|
||||
{
|
||||
persistence."/nix/nodatacow".directories = inputs.lib.mkIf kvm.nodatacow
|
||||
[{ directory = "/var/lib/libvirt/images"; mode = "0711"; }];
|
||||
systemPackages = with inputs.pkgs;
|
||||
[ win-spice guestfs-tools virt-manager virt-viewer inputs.config.virtualisation.libvirtd.qemu.package ];
|
||||
systemPackages = with inputs.pkgs; [ qemu_full win-spice guestfs-tools virt-manager virt-viewer ];
|
||||
};
|
||||
systemd.mounts =
|
||||
[{
|
||||
what = "${inputs.topInputs.nixvirt.lib.guest-install.virtio-win.iso}";
|
||||
where = "/var/lib/libvirt/images/virtio-win.iso";
|
||||
options = "bind";
|
||||
wantedBy = [ "local-fs.target" ];
|
||||
}];
|
||||
# libvirt does not setup "allow udp {53, 67}" by default
|
||||
systemd =
|
||||
{
|
||||
services =
|
||||
let
|
||||
virsh = "${inputs.pkgs.libvirt}/bin/virsh";
|
||||
hibernate = inputs.pkgs.writeShellScript "libvirt-hibernate"
|
||||
''
|
||||
if [ "$(LANG=C ${virsh} domstate $1)" = 'running' ]
|
||||
then
|
||||
if ${virsh} dompmsuspend "$1" disk
|
||||
then
|
||||
echo "Waiting for $1 to suspend"
|
||||
while ! [ "$(LANG=C ${virsh} domstate $1)" = 'shut off' ]
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
echo "$1 suspended"
|
||||
touch "/tmp/libvirt.$1.suspended"
|
||||
else
|
||||
echo "Failed to suspend $1"
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
resume = inputs.pkgs.writeShellScript "libvirt-resume"
|
||||
''
|
||||
if [ "$(LANG=C ${virsh} domstate $1)" = 'shut off' ] && [ -f "/tmp/libvirt.$1.suspended" ]
|
||||
then
|
||||
if ${virsh} start "$1"
|
||||
then
|
||||
echo "Waiting for $1 to resume"
|
||||
while ! [ "$(LANG=C ${virsh} domstate $1)" = 'running' ]
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
echo "$1 resumed"
|
||||
rm "/tmp/libvirt.$1.suspended"
|
||||
else
|
||||
echo "Failed to resume $1"
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
makeHibernate = machine:
|
||||
{
|
||||
name = "libvirt-hibernate-${machine}";
|
||||
value =
|
||||
{
|
||||
description = "libvirt hibernate ${machine}";
|
||||
wantedBy = [ "systemd-hibernate.service" "systemd-suspend.service" ];
|
||||
before = [ "systemd-hibernate.service" "systemd-suspend.service" ];
|
||||
serviceConfig = { Type = "oneshot"; ExecStart = "${hibernate} ${machine}"; };
|
||||
};
|
||||
};
|
||||
makeResume = machine:
|
||||
{
|
||||
name = "libvirt-resume-${machine}";
|
||||
value =
|
||||
{
|
||||
description = "libvirt resume ${machine}";
|
||||
wantedBy = [ "systemd-hibernate.service" "systemd-suspend.service" ];
|
||||
after = [ "systemd-hibernate.service" "systemd-suspend.service" ];
|
||||
serviceConfig = { Type = "oneshot"; ExecStart = "${resume} ${machine}"; };
|
||||
};
|
||||
};
|
||||
makeServices = serviceFunction: builtins.map serviceFunction kvm.autoSuspend;
|
||||
in builtins.listToAttrs (makeServices makeHibernate ++ makeServices makeResume);
|
||||
mounts =
|
||||
[{
|
||||
what = "${inputs.topInputs.nixvirt.lib.guest-install.virtio-win.iso}";
|
||||
where = "/var/lib/libvirt/images/virtio-win.iso";
|
||||
options = "bind";
|
||||
wantedBy = [ "local-fs.target" ];
|
||||
}];
|
||||
};
|
||||
# workaround a libvirt bug
|
||||
# https://github.com/NixOS/nixpkgs/issues/263359#issuecomment-1987267279
|
||||
networking.firewall.interfaces."virbr*".allowedUDPPorts = [ 53 67 ];
|
||||
hardware.ksm.enable = true;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# 大概这样做:
|
||||
# cp -r ~/repo/stuff/44/Lumerical_Suite_2023_R1_CentOS/{LicenseManager,Crack,License} .
|
||||
# podman build .
|
||||
# podman image save --format oci-archive 6803f9562b941c23db81a2eae5914561f96fa748536199a010fe6f24922b2878 -o image.tar
|
||||
# singularity build image.sif oci-archive://image.tar
|
||||
# nix store add-file ./image.tar --name lumericalLicenseManager.tar
|
||||
# nix hash file /nix/store/v626n153vdr8sib52623gx1ych8zfsa6-lumericalLicenseManager.tar
|
||||
# nix store add-file ./image.sif --name lumericalLicenseManager.sif
|
||||
# nix hash file /nix/store/wr4i09smarzwyn1g2jhxlpkxghcwa01l-lumericalLicenseManager.sif
|
||||
|
||||
FROM centos:7
|
||||
|
||||
USER root
|
||||
|
||||
COPY ./LicenseManager /tmp/LicenseManager
|
||||
RUN chmod +x /tmp/LicenseManager/INSTALL && \
|
||||
/tmp/LicenseManager/INSTALL -silent -install_dir /home/ansys_inc -lm && \
|
||||
rm -rf /tmp/LicenseManager
|
||||
COPY ./Crack/ansys_inc/ /home/ansys_inc
|
||||
# RUN sed -i "s|127.0.0.1|0.0.0.0|g" /home/ansys_inc/shared_files/licensing/tools/tomcat/conf/server.xml
|
||||
RUN chmod -R 777 /home/ansys_inc
|
||||
RUN ln -s ld-linux-x86-64.so.2 /lib64/ld-lsb-x86-64.so.3
|
||||
COPY ./License/license.txt /home/ansys_inc/shared_files/licensing/license_files/ansyslmd.lic
|
||||
|
||||
WORKDIR /home/ansys_inc/shared_files/licensing
|
||||
CMD ["/bin/sh", "-c", "(./start_ansysli &); (./start_lmcenter &); tail -f /dev/null"]
|
||||
@@ -1,43 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.lumericalLicenseManager = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
macAddress = mkOption
|
||||
{
|
||||
type = types.str;
|
||||
default = if inputs.config.nixos.system.network != null then "00:01:23:45:67:89" else null;
|
||||
};
|
||||
createFakeInterface = mkOption { type = types.bool; default = inputs.config.nixos.system.network != null; };
|
||||
autoStart = mkOption { type = types.bool; default = true; };
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) lumericalLicenseManager;
|
||||
in inputs.lib.mkIf (lumericalLicenseManager != null)
|
||||
{
|
||||
virtualisation.oci-containers.containers.lumericalLicenseManager =
|
||||
{
|
||||
inherit (inputs.topInputs.self.src.lumerical.licenseManager) image imageFile;
|
||||
extraOptions = [ "--network=host" ];
|
||||
volumes =
|
||||
let
|
||||
macAddress = builtins.replaceStrings [ ":" ] [ "" ] lumericalLicenseManager.macAddress;
|
||||
license = inputs.pkgs.localPackages.lumerical.license.override { inherit macAddress; };
|
||||
in [ "${license}:/home/ansys_inc/shared_files/licensing/license_files/ansyslmd.lic" ];
|
||||
};
|
||||
nixos.services.podman = {};
|
||||
systemd =
|
||||
{
|
||||
network = inputs.lib.mkIf lumericalLicenseManager.createFakeInterface
|
||||
{
|
||||
netdevs.ensFakeLumerical.netdevConfig = { Kind = "dummy"; Name = "ensFakeLumerical"; };
|
||||
networks."10-ensFakeLumerical" =
|
||||
{ matchConfig.Name = "ensFakeLumerical"; linkConfig.MACAddress = lumericalLicenseManager.macAddress; };
|
||||
};
|
||||
services.podman-lumericalLicenseManager.wantedBy =
|
||||
inputs.lib.mkIf (!lumericalLicenseManager.autoStart) (inputs.lib.mkForce []);
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -40,13 +40,13 @@ inputs:
|
||||
let
|
||||
passwordFile =
|
||||
if db.value.passwordFile or null != null then db.value.passwordFile
|
||||
else inputs.config.nixos.system.sops.secrets."mariadb/${db.value.user}".path;
|
||||
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'')
|
||||
(inputs.localLib.attrsToList mariadb.instances)));
|
||||
nixos.system.sops.secrets = builtins.listToAttrs (builtins.map
|
||||
sops.secrets = builtins.listToAttrs (builtins.map
|
||||
(db: { name = "mariadb/${db.value.user}"; value.owner = inputs.config.users.users.mysql.name; })
|
||||
(builtins.filter (db: db.value.passwordFile == null) (inputs.localLib.attrsToList mariadb.instances)));
|
||||
environment.persistence."/nix/nodatacow".directories =
|
||||
|
||||
@@ -1,60 +1,75 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.mirism = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.services) mirism; in inputs.lib.mkIf (mirism != null)
|
||||
options.nixos.services.mirism = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
users =
|
||||
{
|
||||
users.mirism = { uid = inputs.config.nixos.user.uid.mirism; group = "mirism"; isSystemUser = true; };
|
||||
groups.mirism.gid = inputs.config.nixos.user.gid.mirism;
|
||||
};
|
||||
systemd =
|
||||
{
|
||||
services = builtins.listToAttrs (builtins.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-old}/bin/${instance}";
|
||||
RuntimeMaxSec = "1d";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
})
|
||||
[ "ng01" "beta" ]);
|
||||
tmpfiles.rules = builtins.concatLists (builtins.map
|
||||
(dir: [ "d /srv/${dir}mirism 0700 nginx nginx" "Z /srv/${dir}mirism - nginx nginx" ])
|
||||
[ "" "entry." ]);
|
||||
};
|
||||
nixos.services =
|
||||
{
|
||||
nginx =
|
||||
{
|
||||
transparentProxy.map = { "ng01.mirism.one" = 7411; "beta.mirism.one" = 9114; };
|
||||
https = builtins.listToAttrs (builtins.map
|
||||
(instance: inputs.lib.nameValuePair "${instance}mirism.one"
|
||||
{ location."/".static = { root = "/srv/${instance}mirism"; index = [ "index.html" ]; }; })
|
||||
[ "entry." "" ]);
|
||||
};
|
||||
acme.cert = { "ng01.mirism.one".group = "mirism"; "beta.mirism.one".group = "mirism"; };
|
||||
};
|
||||
environment.etc = builtins.listToAttrs (builtins.concatLists (builtins.map
|
||||
(instance:
|
||||
[
|
||||
(inputs.lib.nameValuePair "letsencrypt/live/${instance}.mirism.one/fullchain.pem"
|
||||
{ source = "${inputs.config.security.acme.certs."${instance}.mirism.one".directory}/fullchain.pem"; })
|
||||
(inputs.lib.nameValuePair "letsencrypt/live/${instance}.mirism.one/privkey.pem"
|
||||
{ source = "${inputs.config.security.acme.certs."${instance}.mirism.one".directory}/key.pem"; })
|
||||
])
|
||||
[ "ng01" "beta" ]));
|
||||
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.user.uid.mirism; group = "mirism"; isSystemUser = true; };
|
||||
groups.mirism.gid = inputs.config.nixos.user.gid.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-old}/bin/${instance}";
|
||||
RuntimeMaxSec = "1d";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
})
|
||||
[ "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.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" ]));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ inputs:
|
||||
after = [ "network.target" "redis-misskey-${instance.name}.service" "postgresql.service" ];
|
||||
requires = after;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment.MISSKEY_CONFIG_YML =
|
||||
inputs.config.nixos.system.sops.templates."misskey/${instance.name}.yml".path;
|
||||
environment.MISSKEY_CONFIG_YML = inputs.config.sops.templates."misskey/${instance.name}.yml".path;
|
||||
serviceConfig = rec
|
||||
{
|
||||
User = "misskey-${instance.name}";
|
||||
@@ -54,6 +53,50 @@ inputs:
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
sops.templates = builtins.listToAttrs (builtins.map
|
||||
(instance:
|
||||
{
|
||||
name = "misskey/${instance.name}.yml";
|
||||
value =
|
||||
{
|
||||
content =
|
||||
let
|
||||
placeholder = inputs.config.sops.placeholder;
|
||||
redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}";
|
||||
in
|
||||
''
|
||||
url: https://${instance.value.hostname}/
|
||||
port: ${toString instance.value.port}
|
||||
db:
|
||||
host: 127.0.0.1
|
||||
port: 5432
|
||||
db: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||
user: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||
pass: ${placeholder."postgresql/misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"}
|
||||
extra:
|
||||
statement_timeout: 600000
|
||||
dbReplications: false
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
port: ${builtins.toString redis.port}
|
||||
pass: ${placeholder."redis/misskey-${instance.name}"}
|
||||
id: 'aid'
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
proxyRemoteFiles: true
|
||||
signToActivityPubGet: true
|
||||
maxFileSize: 1073741824
|
||||
fulltextSearch:
|
||||
provider: sqlPgroonga
|
||||
'';
|
||||
owner = "misskey-${instance.name}";
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
users = inputs.lib.mkMerge (builtins.map
|
||||
(instance:
|
||||
{
|
||||
@@ -68,17 +111,18 @@ inputs:
|
||||
groups."misskey-${instance.name}".gid = inputs.config.nixos.user.gid."misskey-${instance.name}";
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
nixos =
|
||||
nixos.services =
|
||||
{
|
||||
services =
|
||||
redis.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
postgresql.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
nginx =
|
||||
{
|
||||
redis.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "misskey-${instance.name}"; value.port = instance.value.redis.port; })
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
postgresql.instances = builtins.listToAttrs (builtins.map
|
||||
(instance: { name = "misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"; value = {}; })
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
nginx.https = builtins.listToAttrs (builtins.map
|
||||
enable = inputs.lib.mkIf (misskey.instances != {}) true;
|
||||
https = builtins.listToAttrs (builtins.map
|
||||
(instance: with instance.value;
|
||||
{
|
||||
name = hostname;
|
||||
@@ -86,50 +130,6 @@ inputs:
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
};
|
||||
system.sops.templates = builtins.listToAttrs (builtins.map
|
||||
(instance:
|
||||
{
|
||||
name = "misskey/${instance.name}.yml";
|
||||
value =
|
||||
{
|
||||
content =
|
||||
let
|
||||
placeholder = inputs.config.nixos.system.sops.placeholder;
|
||||
redis = inputs.config.nixos.services.redis.instances."misskey-${instance.name}";
|
||||
in
|
||||
''
|
||||
url: https://${instance.value.hostname}/
|
||||
port: ${toString instance.value.port}
|
||||
db:
|
||||
host: 127.0.0.1
|
||||
port: 5432
|
||||
db: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||
user: misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}
|
||||
pass: ${placeholder."postgresql/misskey_${builtins.replaceStrings [ "-" ] [ "_" ] instance.name}"}
|
||||
extra:
|
||||
statement_timeout: 600000
|
||||
dbReplications: false
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
port: ${builtins.toString redis.port}
|
||||
pass: ${placeholder."redis/misskey-${instance.name}"}
|
||||
id: 'aid'
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
proxyRemoteFiles: true
|
||||
signToActivityPubGet: true
|
||||
maxFileSize: 1073741824
|
||||
fulltextSearch:
|
||||
provider: sqlPgroonga
|
||||
'';
|
||||
owner = "misskey-${instance.name}";
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList misskey.instances));
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ inputs:
|
||||
config =
|
||||
{
|
||||
dbtype = "pgsql";
|
||||
dbpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/postgresql".path;
|
||||
dbpassFile = inputs.config.sops.secrets."nextcloud/postgresql".path;
|
||||
adminuser = "admin";
|
||||
adminpassFile = inputs.config.nixos.system.sops.secrets."nextcloud/admin".path;
|
||||
adminpassFile = inputs.config.sops.secrets."nextcloud/admin".path;
|
||||
};
|
||||
configureRedis = true;
|
||||
settings =
|
||||
@@ -39,7 +39,7 @@ inputs:
|
||||
overwriteprotocol = "https";
|
||||
default_phone_region = "CN";
|
||||
};
|
||||
secretFile = inputs.config.nixos.system.sops.templates."nextcloud/secret".path;
|
||||
secretFile = inputs.config.sops.templates."nextcloud/secret".path;
|
||||
extraApps =
|
||||
let
|
||||
version = inputs.lib.versions.major inputs.config.services.nextcloud.package.version;
|
||||
@@ -59,30 +59,27 @@ inputs:
|
||||
(package: { name = package; value = inputs.pkgs.fetchNextcloudApp (getInfo package); })
|
||||
[ "phonetrack" "twofactor_webauthn" "calendar" ]);
|
||||
};
|
||||
nixos =
|
||||
nixos.services =
|
||||
{
|
||||
system.sops =
|
||||
postgresql.instances.nextcloud = {};
|
||||
redis.instances.nextcloud.port = 3499;
|
||||
nginx = { enable = true; https.${nextcloud.hostname}.global.configName = nextcloud.hostname; };
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates."nextcloud/secret" =
|
||||
{
|
||||
templates."nextcloud/secret" =
|
||||
content = builtins.toJSON
|
||||
{
|
||||
content = builtins.toJSON
|
||||
{
|
||||
redis.password = inputs.config.nixos.system.sops.placeholder."redis/nextcloud";
|
||||
mail_smtppassword = inputs.config.nixos.system.sops.placeholder."mail/bot";
|
||||
};
|
||||
owner = inputs.config.users.users.nextcloud.name;
|
||||
};
|
||||
secrets =
|
||||
{
|
||||
"nextcloud/postgresql" = { key = "postgresql/nextcloud"; owner = inputs.config.users.users.nextcloud.name; };
|
||||
"nextcloud/admin".owner = inputs.config.users.users.nextcloud.name;
|
||||
redis.password = inputs.config.sops.placeholder."redis/nextcloud";
|
||||
mail_smtppassword = inputs.config.sops.placeholder."mail/bot";
|
||||
};
|
||||
owner = inputs.config.users.users.nextcloud.name;
|
||||
};
|
||||
services =
|
||||
secrets =
|
||||
{
|
||||
postgresql.instances.nextcloud = {};
|
||||
redis.instances.nextcloud.port = 3499;
|
||||
nginx.https.${nextcloud.hostname}.global.configName = nextcloud.hostname;
|
||||
"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,16 +1,20 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.nfs = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.attrsOf (types.nonEmptyListOf types.nonEmptyStr); default = {}; }; # export = accessLimit
|
||||
{ type = types.attrsOf types.nonEmptyStr; default = {}; }; # export = accessLimit
|
||||
config = let inherit (inputs.config.nixos.services) nfs; in inputs.lib.mkIf (nfs != {})
|
||||
{
|
||||
services.nfs.server =
|
||||
services =
|
||||
{
|
||||
enable = true;
|
||||
exports =
|
||||
let clientString = clients: builtins.concatStringsSep " " (builtins.map
|
||||
(client: "${client}(rw,no_root_squash,sync,crossmnt)") clients);
|
||||
in inputs.lib.concatLines (inputs.lib.mapAttrsToList (n: v: "${n} ${clientString v}") nfs);
|
||||
rpcbind.enable = true;
|
||||
nfs.server =
|
||||
{
|
||||
enable = true;
|
||||
exports = builtins.concatStringsSep "\n" (builtins.map
|
||||
(export: "${export.name} ${export.value}(rw,no_root_squash,sync,crossmnt)")
|
||||
(inputs.localLib.attrsToList nfs));
|
||||
};
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 2049 ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.nginx.applications.main = let inherit (inputs.lib) mkOption types; in mkOption
|
||||
{ type = types.nullOr (types.submodule {}); default = null; };
|
||||
config = let inherit (inputs.config.nixos.services.nginx.applications) main; in inputs.lib.mkIf (main != null)
|
||||
options.nixos.services.nginx.applications.main = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
nixos.services.nginx.https."chn.moe".location =
|
||||
{
|
||||
"/".return.return = "302 https://xn--s8w913fdga.chn.moe/@chn";
|
||||
"/.well-known/matrix/server".proxy = { setHeaders.Host = "matrix.chn.moe"; upstream = "https://matrix.chn.moe"; };
|
||||
};
|
||||
enable = mkOption { type = types.bool; default = false; };
|
||||
};
|
||||
config =
|
||||
let
|
||||
inherit (inputs.config.nixos.services.nginx.applications) main;
|
||||
inherit (inputs.lib) mkIf;
|
||||
in mkIf main.enable
|
||||
{
|
||||
nixos.services.nginx.https."chn.moe".location =
|
||||
{
|
||||
"/".return.return = "302 https://xn--s8w913fdga.chn.moe/@chn";
|
||||
"/.well-known/matrix/server".proxy =
|
||||
{
|
||||
setHeaders.Host = "matrix.chn.moe";
|
||||
upstream = "https://matrix.chn.moe";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ inputs:
|
||||
imports = inputs.localLib.findModules ./.;
|
||||
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
|
||||
@@ -15,86 +16,824 @@ inputs:
|
||||
{
|
||||
httpsPort = 3065;
|
||||
httpsPortShift = { http2 = 1; proxyProtocol = 2; };
|
||||
httpsLocationTypes = [ "proxy" "static" "php" "return" "alias" ];
|
||||
httpTypes = [ "rewriteHttps" "php" "proxy" ];
|
||||
httpsLocationTypes = [ "proxy" "static" "php" "return" "cgi" "alias" ];
|
||||
httpTypes = [ "rewriteHttps" "php" ];
|
||||
streamPort = 5575;
|
||||
streamPortShift.proxyProtocol = 1;
|
||||
streamPortShift = { proxyProtocol = 1; };
|
||||
};
|
||||
};
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) nginx; in inputs.lib.mkIf
|
||||
(nginx.http != {} || nginx.https != {} || nginx.streamProxy.map != {} || nginx.transparentProxy.map != {})
|
||||
{
|
||||
services.nginx =
|
||||
transparentProxy =
|
||||
{
|
||||
enable = true;
|
||||
enableReload = true;
|
||||
eventsConfig =
|
||||
''
|
||||
worker_connections 524288;
|
||||
use epoll;
|
||||
'';
|
||||
commonHttpConfig =
|
||||
''
|
||||
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
|
||||
$geoip2_data_country_code country iso_code;
|
||||
}
|
||||
log_format http '[$time_local] $remote_addr-$geoip2_data_country_code "$host"'
|
||||
' $request_length $bytes_sent $status "$request" referer: "$http_referer" ua: "$http_user_agent"';
|
||||
access_log syslog:server=unix:/dev/log http;
|
||||
proxy_ssl_server_name on;
|
||||
proxy_ssl_session_reuse off;
|
||||
send_timeout 1d;
|
||||
# nginx will try to redirect https://blog.chn.moe/docs to https://blog.chn.moe:3068/docs/ in default
|
||||
# this make it redirect to /docs/ without hostname
|
||||
absolute_redirect off;
|
||||
# allow realip module to set ip
|
||||
set_real_ip_from 0.0.0.0/0;
|
||||
real_ip_header proxy_protocol;
|
||||
'';
|
||||
proxyTimeout = "1d";
|
||||
recommendedZstdSettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
# do not set Host header
|
||||
recommendedProxySettings = false;
|
||||
recommendedProxySettingsNoHost = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedBrotliSettings = true;
|
||||
clientMaxBodySize = "0";
|
||||
package =
|
||||
let nginx-geoip2 =
|
||||
{
|
||||
name = "ngx_http_geoip2_module";
|
||||
src = inputs.pkgs.fetchFromGitHub
|
||||
# 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.oneOf
|
||||
[
|
||||
# proxy to 127.0.0.1:${specified port}
|
||||
types.ints.unsigned
|
||||
# proxy to specified ip:port
|
||||
types.nonEmptyStr
|
||||
]);
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
streamProxy =
|
||||
{
|
||||
map = mkOption
|
||||
{
|
||||
type = types.attrsOf (types.oneOf
|
||||
[
|
||||
# proxy to specified ip:port without proxyProtocol
|
||||
types.nonEmptyStr
|
||||
(types.submodule { options =
|
||||
{
|
||||
owner = "leev";
|
||||
repo = "ngx_http_geoip2_module";
|
||||
rev = "a607a41a8115fecfc05b5c283c81532a3d605425";
|
||||
hash = "sha256-CkmaeEa1iEAabJEDu3FhBUR7QF38koGYlyx+pyKZV9Y=";
|
||||
};
|
||||
meta.license = [];
|
||||
};
|
||||
in (inputs.pkgs.nginxMainline.override (prev: { modules = prev.modules ++ [ nginx-geoip2 ]; }))
|
||||
.overrideAttrs (prev: { buildInputs = prev.buildInputs ++ [ inputs.pkgs.libmaxminddb ]; });
|
||||
streamConfig =
|
||||
''
|
||||
geoip2 ${inputs.config.services.geoipupdate.settings.DatabaseDirectory}/GeoLite2-Country.mmdb {
|
||||
$geoip2_data_country_code country iso_code;
|
||||
}
|
||||
resolver 8.8.8.8;
|
||||
'';
|
||||
# anyway to use host dns?
|
||||
resolver.addresses = [ "8.8.8.8" ];
|
||||
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 = {};
|
||||
};
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
nixos.services.geoipupdate = {};
|
||||
systemd.services.nginx.serviceConfig =
|
||||
https = mkOption
|
||||
{
|
||||
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||
LimitNPROC = 65536;
|
||||
LimitNOFILE = 524288;
|
||||
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;
|
||||
};
|
||||
proxy = mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
upstream = mkOption { type = types.nonEmptyStr; };
|
||||
websocket = mkOption { type = types.bool; default = false; };
|
||||
setHeaders = mkOption
|
||||
{
|
||||
type = types.attrsOf types.str;
|
||||
default.Host = submoduleInputs.config._module.args.name;
|
||||
};
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
};}));
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
config =
|
||||
let
|
||||
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 inputs.lib.mkIf nginx.enable (inputs.lib.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 1d;
|
||||
# nginx will try to redirect https://blog.chn.moe/docs to https://blog.chn.moe:3068/docs/ in default
|
||||
# this make it redirect to /docs/ without hostname
|
||||
absolute_redirect off;
|
||||
# allow realip module to set ip
|
||||
set_real_ip_from 0.0.0.0/0;
|
||||
real_ip_header proxy_protocol;
|
||||
'';
|
||||
proxyTimeout = "1d";
|
||||
recommendedZstdSettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
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;
|
||||
sopsFile = "${inputs.config.nixos.system.sops.crossSopsDir}/default.yaml";
|
||||
};
|
||||
systemd.services.nginx.serviceConfig =
|
||||
{
|
||||
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||
LimitNPROC = 65536;
|
||||
LimitNOFILE = 524288;
|
||||
};
|
||||
}
|
||||
# transparentProxy
|
||||
(inputs.lib.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 " (builtins.map
|
||||
(x:
|
||||
let upstrem = if builtins.isInt x.value then "127.0.0.1:${builtins.toString x.value}" else x.value;
|
||||
in ''"${x.name}" ${upstrem};'')
|
||||
(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;
|
||||
}
|
||||
'';
|
||||
# TODO: use existing options
|
||||
systemd.services.nginx-proxy =
|
||||
let
|
||||
ip = "${inputs.pkgs.iproute2}/bin/ip";
|
||||
start = inputs.pkgs.writeShellScript "nginx-proxy.start"
|
||||
''
|
||||
${ip} rule add fwmark 2/2 table 200
|
||||
${ip} route add local 0.0.0.0/0 dev lo table 200
|
||||
'';
|
||||
stop = inputs.pkgs.writeShellScript "nginx-proxy.stop"
|
||||
''
|
||||
${ip} rule del fwmark 2/2 table 200
|
||||
${ip} route del local 0.0.0.0/0 dev lo table 200
|
||||
'';
|
||||
in
|
||||
{
|
||||
description = "nginx transparent proxy";
|
||||
after = [ "network.target" ];
|
||||
serviceConfig =
|
||||
{
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = start;
|
||||
ExecStop = stop;
|
||||
};
|
||||
wants = [ "network.target" ];
|
||||
wantedBy= [ "multi-user.target" ];
|
||||
};
|
||||
networking.nftables.tables.nginx =
|
||||
{
|
||||
family = "inet";
|
||||
content =
|
||||
''
|
||||
chain output {
|
||||
type route hook output priority mangle; policy accept;
|
||||
# 由本机发出、gid 为 nginx、但源地址不是本地监听的地址,说明是透明代理的第一个包,将这个流标记
|
||||
# 但这个包本身不需要处理,正常路由即可。
|
||||
meta skgid ${builtins.toString inputs.config.users.groups.nginx.gid} fib saddr type != local \
|
||||
ct state new counter ct mark set ct mark | 2
|
||||
# 由本机发出、作为透明代理的回复,它不能按照通常的路由,它需要被打上标记并被路由到本地
|
||||
# 这对应于透明代理到本地的服务的情况
|
||||
ct mark & 2 == 2 ct direction reply counter meta mark set meta mark | 2 accept
|
||||
return
|
||||
}
|
||||
# 还需要处理透明代理到其它机器的情况,它们的回复需要在 prerouting 中标记
|
||||
chain prerouting {
|
||||
type filter hook prerouting priority mangle; policy accept;
|
||||
ct mark & 2 == 2 ct direction reply counter meta mark set meta mark | 2 accept
|
||||
return
|
||||
}
|
||||
'';
|
||||
};
|
||||
})
|
||||
# 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 = inputs.lib.mkIf (site.value.global.root != null) site.value.global.root;
|
||||
basicAuthFile = inputs.lib.mkIf (site.value.global.detectAuth != null)
|
||||
(
|
||||
let secret = "nginx/templates/detectAuth/${inputs.lib.strings.escapeURL site.name}-global";
|
||||
in inputs.config.sops.templates.${secret}.path
|
||||
);
|
||||
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 = inputs.lib.mkIf listen.http2 [ "http2" ];
|
||||
})
|
||||
site.value.listens;
|
||||
# do not automatically add http2 listen
|
||||
http2 = false;
|
||||
onlySSL = true;
|
||||
useACMEHost = inputs.lib.mkIf (site.value.global.tlsCert == null) site.name;
|
||||
sslCertificate = inputs.lib.mkIf (site.value.global.tlsCert != null)
|
||||
"${site.value.global.tlsCert}/fullchain.pem";
|
||||
sslCertificateKey = inputs.lib.mkIf (site.value.global.tlsCert != null)
|
||||
"${site.value.global.tlsCert}/privkey.pem";
|
||||
locations = listToAttrs (map
|
||||
(location:
|
||||
{
|
||||
inherit (location) name;
|
||||
value =
|
||||
{
|
||||
basicAuthFile = inputs.lib.mkIf (location.value.detectAuth or null != null)
|
||||
(
|
||||
let
|
||||
inherit (inputs.lib.strings) escapeURL;
|
||||
secret = "nginx/templates/detectAuth/${escapeURL site.name}/${escapeURL location.name}";
|
||||
in inputs.config.sops.templates.${secret}.path
|
||||
);
|
||||
root = inputs.lib.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 = inputs.lib.mkIf (builtins.typeOf location.value.index == "list")
|
||||
(concatStringsSep " " location.value.index);
|
||||
tryFiles = inputs.lib.mkIf (location.value.tryFiles != null)
|
||||
(concatStringsSep " " location.value.tryFiles);
|
||||
extraConfig = inputs.lib.mkMerge
|
||||
[
|
||||
(inputs.lib.mkIf (location.value.index == "auto") "autoindex on;")
|
||||
(inputs.lib.mkIf (location.value.charset != null) "charset ${location.value.charset};")
|
||||
(inputs.lib.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 = inputs.lib.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 = inputs.lib.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.cert = listToAttrs (map
|
||||
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
|
||||
sites);
|
||||
};
|
||||
sops =
|
||||
let
|
||||
inherit (inputs.lib.strings) escapeURL;
|
||||
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 {})
|
||||
// (if site.value.proxy != null then
|
||||
{
|
||||
locations."/" =
|
||||
{
|
||||
proxyPass = site.value.proxy.upstream;
|
||||
proxyWebsockets = site.value.proxy.websocket;
|
||||
recommendedProxySettings = false;
|
||||
recommendedProxySettingsNoHost = true;
|
||||
extraConfig = builtins.concatStringsSep "\n" (builtins.map
|
||||
(header: ''proxy_set_header ${header.name} "${header.value}";'')
|
||||
(inputs.localLib.attrsToList site.value.proxy.setHeaders));
|
||||
};
|
||||
}
|
||||
else {});
|
||||
})
|
||||
(attrsToList nginx.http));
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.nginx.http = let inherit (inputs.lib) mkOption types; in 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;
|
||||
};
|
||||
proxy = mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
upstream = mkOption { type = types.nonEmptyStr; };
|
||||
websocket = mkOption { type = types.bool; default = false; };
|
||||
setHeaders = mkOption
|
||||
{ type = types.attrsOf types.str; default.Host = submoduleInputs.config._module.args.name; };
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
};}));
|
||||
default = {};
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) nginx; in inputs.lib.mkIf (nginx.http != {})
|
||||
{
|
||||
assertions = inputs.lib.mapAttrsToList
|
||||
(n: v:
|
||||
{
|
||||
assertion = (inputs.lib.count (x: x != null) (builtins.map (type: v.${type}) nginx.global.httpTypes)) <= 1;
|
||||
message = "Only one type shuold be specified in ${n}";
|
||||
})
|
||||
nginx.http;
|
||||
services.nginx.virtualHosts = inputs.lib.mapAttrs'
|
||||
(n: v:
|
||||
{
|
||||
name = "http.${n}";
|
||||
value = { serverName = n; listen = [ { addr = "0.0.0.0"; port = 80; } ]; }
|
||||
// (inputs.lib.optionalAttrs (v.rewriteHttps != null)
|
||||
{ locations."/".return = "301 https://${v.rewriteHttps.hostname}$request_uri"; })
|
||||
// (inputs.lib.optionalAttrs (v.php != null)
|
||||
{
|
||||
extraConfig = "index index.php;";
|
||||
root = v.php.root;
|
||||
locations."~ ^.+?.php(/.*)?$".extraConfig =
|
||||
''
|
||||
fastcgi_pass ${v.php.fastcgiPass};
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
include ${inputs.config.services.nginx.package}/conf/fastcgi.conf;
|
||||
'';
|
||||
})
|
||||
// (inputs.lib.optionalAttrs (v.proxy != null)
|
||||
{
|
||||
locations."/" =
|
||||
{
|
||||
proxyPass = v.proxy.upstream;
|
||||
proxyWebsockets = v.proxy.websocket;
|
||||
extraConfig = builtins.concatStringsSep "\n" (inputs.lib.mapAttrsToList
|
||||
(n: v: ''proxy_set_header ${n} "${v}";'')
|
||||
v.proxy.setHeaders);
|
||||
};
|
||||
});
|
||||
})
|
||||
nginx.http;
|
||||
};
|
||||
}
|
||||
@@ -1,393 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.nginx.https = let inherit (inputs.lib) mkOption types; in 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; };
|
||||
grpc = 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;
|
||||
};
|
||||
alias = mkOption
|
||||
{
|
||||
type = types.nullOr (types.submodule { options =
|
||||
{
|
||||
path = mkOption { type = types.nonEmptyStr; };
|
||||
};});
|
||||
default = null;
|
||||
};
|
||||
};});
|
||||
default = {};
|
||||
};
|
||||
};}));
|
||||
default = {};
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) nginx; in inputs.lib.mkIf (nginx.https != {}) (inputs.lib.mkMerge
|
||||
[
|
||||
# https assertions
|
||||
{
|
||||
# only one type should be specified in each location
|
||||
assertions =
|
||||
(
|
||||
(builtins.map
|
||||
(location:
|
||||
{
|
||||
assertion = 1 >= (inputs.lib.count (x: x != null)
|
||||
(builtins.map (type: location.value.${type}) nginx.global.httpsLocationTypes));
|
||||
message = "Only one type shuold be specified in ${location.name}";
|
||||
})
|
||||
(builtins.concatLists (inputs.lib.mapAttrsToList
|
||||
(sn: sv: (inputs.lib.mapAttrsToList (ln: lv: inputs.lib.nameValuePair "${sn} ${ln}" lv) sv.location))
|
||||
nginx.https)))
|
||||
# root should be specified either in global or in each location
|
||||
++ (builtins.map
|
||||
(location:
|
||||
{
|
||||
assertion = (location.value.root or "") != null;
|
||||
message = "Root should be specified in ${location.name}";
|
||||
})
|
||||
(builtins.concatLists (builtins.map
|
||||
(site: (inputs.lib.mapAttrsToList
|
||||
(n: v: inputs.lib.nameValuePair "${site.name} ${n}" v)
|
||||
site.value.location))
|
||||
(builtins.filter (site: site.value.global.root == null) (inputs.localLib.attrsToList nginx.https)))))
|
||||
);
|
||||
}
|
||||
# https
|
||||
(
|
||||
# merge different types of locations
|
||||
let sites = inputs.lib.mapAttrsToList
|
||||
(sn: sv: inputs.lib.nameValuePair sn
|
||||
{
|
||||
inherit (sv) global;
|
||||
listens = builtins.attrValues sv.listen;
|
||||
locations = inputs.lib.mapAttrsToList
|
||||
(ln: lv: inputs.lib.nameValuePair ln
|
||||
(
|
||||
let _ = builtins.head (builtins.filter (type: type.value != null) (inputs.localLib.attrsToList lv));
|
||||
in _.value // { type = _.name; }
|
||||
))
|
||||
sv.location;
|
||||
})
|
||||
nginx.https;
|
||||
in
|
||||
{
|
||||
services.nginx.virtualHosts = builtins.listToAttrs (builtins.map
|
||||
(site:
|
||||
{
|
||||
name = site.value.global.configName;
|
||||
value =
|
||||
{
|
||||
serverName = site.name;
|
||||
root = inputs.lib.mkIf (site.value.global.root != null) site.value.global.root;
|
||||
basicAuthFile = inputs.lib.mkIf (site.value.global.detectAuth != null)
|
||||
(
|
||||
let secret = "nginx/templates/detectAuth/${inputs.lib.strings.escapeURL site.name}-global";
|
||||
in inputs.config.nixos.system.sops.templates.${secret}.path
|
||||
);
|
||||
extraConfig = builtins.concatStringsSep "\n"
|
||||
(
|
||||
(
|
||||
let inherit (site.value.global) index; in
|
||||
if (builtins.typeOf index == "list") then [ "index ${builtins.concatStringsSep " " index};" ]
|
||||
else if (index == "auto") then [ "autoindex on;" ]
|
||||
else []
|
||||
)
|
||||
++ (
|
||||
let inherit (site.value.global) detectAuth;
|
||||
in inputs.lib.optionals (detectAuth != null) [ ''auth_basic "${detectAuth.text}"'' ]
|
||||
)
|
||||
++ (
|
||||
let inherit (site.value.global) charset;
|
||||
in inputs.lib.optionals (charset != null) [ "charset ${charset};" ]
|
||||
)
|
||||
);
|
||||
listen = builtins.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 = inputs.lib.mkIf listen.http2 [ "http2" ];
|
||||
})
|
||||
site.value.listens;
|
||||
# do not automatically add http2 listen
|
||||
http2 = false;
|
||||
onlySSL = true;
|
||||
useACMEHost = inputs.lib.mkIf (site.value.global.tlsCert == null) site.name;
|
||||
sslCertificate = inputs.lib.mkIf (site.value.global.tlsCert != null)
|
||||
"${site.value.global.tlsCert}/fullchain.pem";
|
||||
sslCertificateKey = inputs.lib.mkIf (site.value.global.tlsCert != null)
|
||||
"${site.value.global.tlsCert}/privkey.pem";
|
||||
locations = builtins.listToAttrs (builtins.map
|
||||
(location:
|
||||
{
|
||||
inherit (location) name;
|
||||
value =
|
||||
{
|
||||
basicAuthFile = inputs.lib.mkIf (location.value.detectAuth or null != null)
|
||||
(
|
||||
let
|
||||
inherit (inputs.lib.strings) escapeURL;
|
||||
secret = "nginx/templates/detectAuth/${escapeURL site.name}/${escapeURL location.name}";
|
||||
in inputs.config.nixos.system.sops.templates.${secret}.path
|
||||
);
|
||||
root = inputs.lib.mkIf (location.value.root or null != null) location.value.root;
|
||||
}
|
||||
// {
|
||||
proxy =
|
||||
{
|
||||
proxyWebsockets = location.value.websocket;
|
||||
extraConfig = builtins.concatStringsSep "\n"
|
||||
(
|
||||
[ "${if location.value.grpc then "grpc" else "proxy"}_pass ${location.value.upstream};" ]
|
||||
++ (inputs.lib.mapAttrsToList (n: v: ''proxy_set_header ${n} "${v}";'')
|
||||
location.value.setHeaders)
|
||||
++ (inputs.lib.optionals
|
||||
(location.value.detectAuth != null || site.value.global.detectAuth != null)
|
||||
[ "proxy_hide_header Authorization;" ]
|
||||
)
|
||||
++ (inputs.lib.optionals (location.value.addAuth != null)
|
||||
(
|
||||
let authFile = "nginx/templates/addAuth/${location.value.addAuth}";
|
||||
in [ "include ${inputs.config.nixos.system.sops.templates.${authFile}.path};" ]
|
||||
))
|
||||
);
|
||||
};
|
||||
static =
|
||||
{
|
||||
index = inputs.lib.mkIf (builtins.typeOf location.value.index == "list")
|
||||
(builtins.concatStringsSep " " location.value.index);
|
||||
tryFiles = inputs.lib.mkIf (location.value.tryFiles != null)
|
||||
(builtins.concatStringsSep " " location.value.tryFiles);
|
||||
extraConfig = inputs.lib.mkMerge
|
||||
[
|
||||
(inputs.lib.mkIf (location.value.index == "auto") "autoindex on;")
|
||||
(inputs.lib.mkIf (location.value.charset != null) "charset ${location.value.charset};")
|
||||
(inputs.lib.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;
|
||||
alias.alias = location.value.path;
|
||||
}.${location.value.type};
|
||||
})
|
||||
site.value.locations);
|
||||
};
|
||||
})
|
||||
sites);
|
||||
nixos =
|
||||
{
|
||||
services =
|
||||
{
|
||||
nginx =
|
||||
# { name = domain; value = listen = { http2 = xxx, proxyProtocol = xxx }; }
|
||||
let listens = builtins.filter
|
||||
(listen: listen.value.addToTransparentProxy)
|
||||
(builtins.concatLists (builtins.map
|
||||
(site: builtins.map (listen: { inherit (site) name; value = listen; }) site.value.listens)
|
||||
sites));
|
||||
in
|
||||
{
|
||||
transparentProxy.map = builtins.listToAttrs (builtins.map
|
||||
(site:
|
||||
{
|
||||
inherit (site) name;
|
||||
value = with nginx.global; httpsPort + (if site.value.http2 then httpsPortShift.http2 else 0);
|
||||
})
|
||||
(builtins.filter (listen: !listen.value.proxyProtocol) listens));
|
||||
streamProxy.map = builtins.listToAttrs (builtins.map
|
||||
(site:
|
||||
{
|
||||
inherit (site) name;
|
||||
value =
|
||||
{
|
||||
upstream.port = with nginx.global; httpsPort + httpsPortShift.proxyProtocol
|
||||
+ (if site.value.http2 then httpsPortShift.http2 else 0);
|
||||
proxyProtocol = true;
|
||||
rewriteHttps = inputs.lib.mkDefault false;
|
||||
};
|
||||
})
|
||||
(builtins.filter (listen: listen.value.proxyProtocol) listens));
|
||||
http = builtins.listToAttrs (builtins.map
|
||||
(site: { inherit (site) name; value.rewriteHttps = {}; })
|
||||
(builtins.filter (site: site.value.global.rewriteHttps) sites));
|
||||
};
|
||||
acme.cert = builtins.listToAttrs (builtins.map
|
||||
(site: { inherit (site) name; value.group = inputs.config.services.nginx.group; })
|
||||
sites);
|
||||
};
|
||||
system.sops =
|
||||
let
|
||||
inherit (inputs.lib.strings) escapeURL;
|
||||
detectAuthUsers = builtins.concatLists (builtins.map
|
||||
(site:
|
||||
(
|
||||
(builtins.map
|
||||
(location:
|
||||
{
|
||||
name = "${escapeURL site.name}/${escapeURL location.name}";
|
||||
value = location.value.detectAuth.users;
|
||||
})
|
||||
(builtins.filter (location: location.value.detectAuth or null != null) site.value.locations))
|
||||
++ (inputs.lib.optionals (site.value.global.detectAuth != null)
|
||||
[ { name = "${escapeURL site.name}-global"; value = site.value.global.detectAuth.users; } ])
|
||||
))
|
||||
sites);
|
||||
addAuth = builtins.concatLists (builtins.map
|
||||
(site: builtins.map
|
||||
(location:
|
||||
{
|
||||
name = "${escapeURL site.name}/${escapeURL location.name}";
|
||||
value = location.value.addAuth;
|
||||
})
|
||||
(builtins.filter (location: location.value.addAuth or null != null) site.value.locations)
|
||||
)
|
||||
sites);
|
||||
in
|
||||
{
|
||||
templates = let inherit (inputs.config.nixos.system.sops) placeholder; in builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(detectAuth: inputs.lib.nameValuePair "nginx/templates/detectAuth/${detectAuth.name}"
|
||||
{
|
||||
owner = inputs.config.users.users.nginx.name;
|
||||
content = builtins.concatStringsSep "\n" (builtins.map
|
||||
(user: "${user}:{PLAIN}${placeholder."nginx/detectAuth/${user}"}")
|
||||
detectAuth.value);
|
||||
})
|
||||
detectAuthUsers)
|
||||
++ (builtins.map
|
||||
(addAuth: inputs.lib.nameValuePair "nginx/templates/addAuth/${addAuth.name}"
|
||||
{
|
||||
owner = inputs.config.users.users.nginx.name;
|
||||
content =
|
||||
''proxy_set_header Authorization "Basic ${placeholder."nginx/addAuth/${addAuth.value}"}";'';
|
||||
})
|
||||
addAuth)
|
||||
);
|
||||
secrets = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(secret: { name = "nginx/detectAuth/${secret}"; value = {}; })
|
||||
(inputs.lib.unique (builtins.concatLists (builtins.map (detectAuth: detectAuth.value)
|
||||
detectAuthUsers))))
|
||||
++ (builtins.map
|
||||
(secret: { name = "nginx/addAuth/${secret}"; value = {}; })
|
||||
(inputs.lib.unique (builtins.map (addAuth: addAuth.value) addAuth)))
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
]);
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
options.nixos.services.nginx.streamProxy = let inherit (inputs.lib) mkOption types; in
|
||||
{
|
||||
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 = {};
|
||||
};
|
||||
};
|
||||
config = let inherit (inputs.config.nixos.services) nginx; in inputs.lib.mkIf (nginx.streamProxy.map != {})
|
||||
{
|
||||
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 {
|
||||
${builtins.concatStringsSep "\n " (inputs.lib.mapAttrsToList
|
||||
(n: v:
|
||||
let
|
||||
upstream =
|
||||
if (builtins.typeOf v.upstream == "string") then v.upstream
|
||||
else
|
||||
let port = with nginx.global;
|
||||
if v.upstream.port == null then
|
||||
httpsPort + httpsPortShift.http2 + (if v.proxyProtocol then httpsPortShift.proxyProtocol else 0)
|
||||
else v.upstream.port;
|
||||
in "${v.upstream.address}:${builtins.toString port}";
|
||||
in ''"${n}" "${upstream}";'')
|
||||
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:${builtins.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 = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(site: { inherit (site) name; value = nginx.global.streamPort; })
|
||||
(builtins.filter
|
||||
(site: (!(site.value.proxyProtocol or false) && (site.value.addToTransparentProxy or true)))
|
||||
(inputs.localLib.attrsToList nginx.streamProxy.map)))
|
||||
++ (builtins.map
|
||||
(site: { inherit (site) name; value = with nginx.global; streamPort + streamPortShift.proxyProtocol; })
|
||||
(builtins.filter
|
||||
(site: ((site.value.proxyProtocol or false) && (site.value.addToTransparentProxy or true)))
|
||||
(inputs.localLib.attrsToList nginx.streamProxy.map)))
|
||||
);
|
||||
http = builtins.listToAttrs (builtins.map
|
||||
(site: { inherit (site) name; value.rewriteHttps = {}; })
|
||||
(builtins.filter (site: site.value.rewriteHttps or false) (inputs.localLib.attrsToList nginx.streamProxy.map)));
|
||||
};
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user