mirror of
https://github.com/CHN-beta/nixos.git
synced 2026-01-12 09:49:22 +08:00
Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd5838c5ef | |||
| 35253cff0a | |||
| 91b92bd492 | |||
| 0198626002 | |||
| 173dd4a3d7 | |||
| 1854e294cf | |||
| b45a9c7a62 | |||
| 858f4c68aa | |||
| 37e6d70561 | |||
| f101038f4a | |||
| 412fac9692 | |||
| 4c7d17f001 | |||
| e8d80daee2 | |||
| 8aeb290d0f | |||
| 0f37c886a4 | |||
| 5940da526d | |||
| df2ac86e1a | |||
| 8bf7e2cb30 | |||
| 96f7056d16 | |||
| 5cc40727db | |||
| c4f8e5f61c | |||
| 03be19da5a | |||
| 7657fe3d14 | |||
| 9fee2a8e2a | |||
| db1e825cd6 | |||
| 670126ba0c | |||
| 92ddf86df1 | |||
| bd12de34b7 | |||
| a7b0906488 | |||
| 0ce31201a9 | |||
| 58d927b648 | |||
| 5efee599f7 | |||
| 2c833934e7 | |||
| c5dc456c35 | |||
| 7576726fbe | |||
| 6dfd6a8bf0 | |||
| eb68d8f8b1 | |||
| 46ae9f1aac | |||
| bb5aee5545 | |||
| a8833dac7f | |||
| d1b3f84cf3 | |||
| f813ffd053 | |||
| 00c99adca9 | |||
| ef58de9a1d | |||
| b9175a211f | |||
| 0cb7791b84 | |||
| 803af74404 | |||
| c5da42debd | |||
| e16f49b3f3 | |||
| f10c385f13 | |||
| f65ec24862 | |||
| 73261c3e3f | |||
| e50ad89bc2 | |||
| 5f4a79788d | |||
| 1360a3e9fa | |||
| d692bb8baf | |||
| dbcf7093aa | |||
| 7833f37588 | |||
| 673f241490 | |||
| a5be9adb53 | |||
| d6a1da17fb | |||
| 6e0e224530 | |||
| 1a007ab57f | |||
| da76976c3d | |||
| b46f928964 | |||
| 92fdc6c67d | |||
| 2534f35c4d | |||
| f9e376920c |
@@ -75,7 +75,7 @@ inputs:
|
||||
{
|
||||
waydroid.enable = true;
|
||||
docker.enable = true;
|
||||
kvmHost = { enable = true; gui = true; autoSuspend = [ "win10" "hardconnect" ]; };
|
||||
kvmHost = { enable = true; gui = true; };
|
||||
nspawn = [ "arch" "ubuntu-22.04" "fedora" ];
|
||||
};
|
||||
services =
|
||||
@@ -141,9 +141,17 @@ inputs:
|
||||
};
|
||||
xrdp = { enable = true; hostname = [ "pc.chn.moe" ]; };
|
||||
};
|
||||
bugs = [ "xmunet" "backlight" "amdpstate" "hibernate-mt7921e" "suspend-hibernate-no-platform" ];
|
||||
bugs = [ "xmunet" "backlight" "amdpstate" ];
|
||||
};
|
||||
boot.kernelParams = [ "acpi_osi=!" ''acpi_osi="Windows 2015"'' ];
|
||||
boot.kernelParams =
|
||||
[
|
||||
"acpi_osi=!" ''acpi_osi="Windows 2015"''
|
||||
"mt7921e.disable_aspm=y" # 避免休眠恢复后无 wifi,似乎有时还是有问题
|
||||
"amdgpu.sg_display=0" # 混合模式下避免外接屏幕闪烁,和内置外接屏幕延迟
|
||||
"acpi.ec_no_wakeup" # 睡眠时避免开盖唤醒,似乎没有用
|
||||
];
|
||||
# 禁止鼠标等在睡眠时唤醒
|
||||
services.udev.extraRules = ''ACTION=="add", ATTR{power/wakeup}="disabled"'';
|
||||
networking.extraHosts = "74.211.99.69 mirism.one beta.mirism.one ng01.mirism.one";
|
||||
services.colord.enable = true;
|
||||
environment.persistence."/nix/archive" =
|
||||
@@ -164,6 +172,11 @@ inputs:
|
||||
};
|
||||
system.nixos.tags = [ "nvidia" ];
|
||||
};
|
||||
xanmod.configuration =
|
||||
{
|
||||
nixos.system.kernel.variant = inputs.lib.mkForce "xanmod-latest";
|
||||
system.nixos.tags = [ "xanmod" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,13 +30,13 @@ inputs:
|
||||
nix.substituters = [ "https://cache.nixos.org/" "https://nix-store.chn.moe" ];
|
||||
initrd.sshd.enable = true;
|
||||
networking = { hostname = "vps6"; networkd = {}; };
|
||||
kernel.variant = "cachyos-server";
|
||||
# do not use cachyos kernel, beesd + cachyos kernel + heavy io = system freeze, not sure why
|
||||
};
|
||||
services =
|
||||
{
|
||||
snapper.enable = true;
|
||||
sshd = {};
|
||||
xray.server = { serverName = "vps6.xserver.chn.moe"; userNumber = 18; };
|
||||
xray.server = { serverName = "vps6.xserver.chn.moe"; userNumber = 19; };
|
||||
frpServer = { enable = true; serverName = "frp.chn.moe"; };
|
||||
nginx =
|
||||
{
|
||||
|
||||
@@ -40,6 +40,8 @@ xray-server:
|
||||
user16: ENC[AES256_GCM,data:fo6KJXlPDn7+FmxjEJQo9d79rDYemLFx6LanYZcJpKJR7Gxq,iv:yEUKPNZ9idrSqyVO9fhksP/7bjPMT/LzNK2VSq503/c=,tag:M87D44SIo9JzDB3ZyKu7fA==,type:str]
|
||||
#ENC[AES256_GCM,data:/Kec+CdtnT11EA==,iv:DnmbWfgriaE6XAnMqq2UXhHhN+Rd/3YRodKVUCJo6p4=,tag:NimqZpbslKxwzoljaZqEdw==,type:comment]
|
||||
user17: ENC[AES256_GCM,data:gQInIcNFxJuCSsMDGq4yTp5JdMMmJRy1tY3PGLoLuuIXWV0a,iv:ya4n9Z7T9/bxeHqi5QqwJprEzDMsT6X0BuEXRS67wWk=,tag:RcjQfAHv8uc3PgN5c4bySA==,type:str]
|
||||
#ENC[AES256_GCM,data:h7E4P6BiGjktYg==,iv:DhkK3NNppBqo3sXt9U7kbgfaBPYcSEX2hu6VOAesDiE=,tag:XoVbZklwCmU1EBhv0ujcSw==,type:comment]
|
||||
user18: ENC[AES256_GCM,data:dssxPEv8srXydunolaaDAYYo+BOXhp2PoqidOWH3z6NYBpyB,iv:WCLcMMwQJiHZBwreQpaOZp2saXvjBwgYUqSf7HQhMgA=,tag:5jsAVcgAgO+7JhBINz6tzQ==,type:str]
|
||||
private-key: ENC[AES256_GCM,data:ts/LRGFAsYqvGvkvlxUI42IW1a8cGsSkpZhMDd3QVceRKvhPb1SRDaXoSw==,iv:6xX9xFIFUNlLBZ6CPBOz9JbHpvC4+QG9ZaCZcWdl12c=,tag:DYIa+QTV8vyl1l7OKKykTw==,type:str]
|
||||
nginx:
|
||||
#ENC[AES256_GCM,data:85LrqdTMIhSa,iv:mIQPYz8VPd5AxeMCQEdTGMD0Iqa5QEAa5+8JVFaj3JM=,tag:TcZd7S3WRPpEV9lHI1fzbw==,type:comment]
|
||||
@@ -83,8 +85,8 @@ sops:
|
||||
ZXFTU3ZCaW1pTVh0RUJzdDdGdHlPYTgK2mlgcX2kEc8+2UDdBnhUm6IIuh8V6agW
|
||||
ooxH9OEPXUVI/4JcDo4v8ZUhAyU1ehLH0Ef7PJCChOZe2KZmWSNbhA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-05-25T09:01:19Z"
|
||||
mac: ENC[AES256_GCM,data:xYK5VTYHwryDcH0fhnezn5aYQ+XAPAJ7PIrL1ygKw3F/rAwRQlWk0/zmqypmpqbPX4mAJKzDfgoTNh8iUtF8ehmfOS+7OPUTuKVRvPI39HfcJbRN3/oOdN40AXSa5cZjgKrAGdhWvwyw0WdDMkRfwJztAR5Jj0dKzZ5THW+5zSs=,iv:Y5UUe1I95ltiVcUPBUcmIpnKHFfAlQmcF8ZlxZht1i4=,tag:3mA/epV254+P7WkkuhDOqg==,type:str]
|
||||
lastmodified: "2024-06-18T11:57:30Z"
|
||||
mac: ENC[AES256_GCM,data:63Bxo5BTq/CyLE90e3nkaJ0A7nvgZHlocSuZixurNXzr5Ow7X+KOxM6fOCSLt7NpGiSxu5a3jJi/piNIvYEHyflhWEqdJuC6mYdVp35U0WezcKwkwwdP+Nvx+nf6m2JHdZ4d2uGOM+Er4f59TSAI+dB5GeT4KZ1PJy9Ai/pr6cs=,iv:rx1c3iCtp+Nti2tzrvWe6vLoKfX10LXd2q+1HTKlQEA=,tag:FIAp+yEM2O+wJrWiNRAfow==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
||||
|
||||
@@ -46,7 +46,7 @@ inputs:
|
||||
matrix = { port = 8009; redisPort = 6380; slidingSyncPort = 9001; };
|
||||
};
|
||||
vaultwarden.enable = true;
|
||||
beesd.instances.root = { device = "/"; hashTableSizeMB = 1024; };
|
||||
beesd.instances.root = { device = "/"; hashTableSizeMB = 1024; loadAverage = 4; };
|
||||
photoprism.enable = true;
|
||||
nextcloud = {};
|
||||
freshrss.enable = true;
|
||||
|
||||
@@ -16,10 +16,25 @@ SLURM 是一个用来对任务排队的系统,轮到某个任务时,再调
|
||||
|
||||
## 常用命令
|
||||
|
||||
我做了一个 TUI 界面,用起来比较简单,大多情况下可以满足需求。命令为:
|
||||
|
||||
```bash
|
||||
sbatch-tui
|
||||
```
|
||||
|
||||
或
|
||||
|
||||
```bash
|
||||
sbatch
|
||||
```
|
||||
|
||||
如果需要在提交任务时指定更详细的细节,或者要编写脚本批量提交任务,则在 `sbatch` 后面加上参数,这时是直接调用来自 SLURM 的 `sbatch` 命令。
|
||||
常用的参数见下文。更详细的内容见 SLURM 的官方文档。
|
||||
|
||||
提交一个 VASP GPU 任务的例子:
|
||||
|
||||
```bash
|
||||
sbatch --gpus=1 --ntasks-per-gpu=1 --job-name="my great job" vasp-nvidia-640
|
||||
sbatch --gpus=1 --ntasks-per-gpu=1 --job-name="my great job" vasp-nvidia
|
||||
```
|
||||
|
||||
* `--gpus` 指定使用GPU 的情况:
|
||||
@@ -30,12 +45,12 @@ sbatch --gpus=1 --ntasks-per-gpu=1 --job-name="my great job" vasp-nvidia-640
|
||||
* `--ntasks-per-gpu=1` 对于 VASP 来说一定要写。
|
||||
* `--job-name=xxx` 指定任务的名字。可以简写为 `-J`。也可以不指定。
|
||||
* 默认情况下,一个 task 会搭配分配一个 CPU 核(一个线程),一般已经够用。如果一定要修改,用 `--cpus-per-task`。
|
||||
* `vasp-nvidia-640` 指调用 std 版本,要使用 gam 或 ncl 版本时,写为例如 `vasp-nvidia-640-gam`。
|
||||
* `vasp-nvidia` 指调用 std 版本,要使用 gam 或 ncl 版本时,写为例如 `vasp-nvidia-gam`。
|
||||
|
||||
提交一个 VASP CPU 任务的例子:
|
||||
|
||||
```bash
|
||||
sbatch --ntasks=4 --cpus-per-task=4 --hint=nomultithread --job-name="my great job" vasp-intel-640
|
||||
sbatch --ntasks=4 --cpus-per-task=4 --hint=nomultithread --job-name="my great job" vasp-intel
|
||||
```
|
||||
|
||||
* `--ntasks=4 --cpus-per-task=4` 指定使用占用多少核。
|
||||
@@ -45,7 +60,7 @@ sbatch --ntasks=4 --cpus-per-task=4 --hint=nomultithread --job-name="my great jo
|
||||
* 对于 xmupc2:`--ntasks=4 --cpus-per-task=10`。
|
||||
* `--hint=nomultithread` 记得写。
|
||||
* `--job-name=xxx` 指定任务的名字。可以简写为 `-J`。也可以不指定。
|
||||
* `vasp-intel-640` 指调用 std 版本,要使用 gam 或 ncl 版本时,写为例如 `vasp-intel-640-gam`。
|
||||
* `vasp-intel` 指调用 std 版本,要使用 gam 或 ncl 版本时,写为例如 `vasp-intel-gam`。
|
||||
|
||||
要把其它程序提交到队列里,也是类似的写法。请自行举一反三。
|
||||
|
||||
@@ -186,7 +201,6 @@ samba 就是 windows 共享文件夹的那个协议。
|
||||
|
||||
VASP 有很多很多个版本,具体来说:
|
||||
|
||||
* VASP 多个版本可以共存,但为了简单只安装了 6.4.0 版本。
|
||||
* VASP 可以用不同的编译器编译。目前安装的有:nvidia、intel。nvidia 使用 GPU 计算,intel 能用 CPU 计算。其它版本性能不佳,没有安装。
|
||||
* VASP 的 std/gam/ncl 版本有一点区别,一般用 std,只有一个 gamma 点的时候用 gam 会快一点,系统中存在方向不平行的磁矩时必须用 ncl。
|
||||
* 无论哪个版本,都集成了下面这些补丁:
|
||||
@@ -199,14 +213,14 @@ VASP 有很多很多个版本,具体来说:
|
||||
如何提交 VASP 到队列系统已经在上面介绍过了。下面的例子是,如果要直接运行一个任务的写法:
|
||||
|
||||
```bash
|
||||
vasp-nvidia-640-env mpirun -np 1 -x CUDA_DEVICE_ORDER=PCI_BUS_ID -x CUDA_VISIBLE_DEVICES=0 -x OMP_NUM_THREADS=4 vasp-std
|
||||
vasp-intel-640-env mpirun -n 2 -genv OMP_NUM_THREADS=4 vasp-std
|
||||
vasp-nvidia-env mpirun -np 1 -x CUDA_DEVICE_ORDER=PCI_BUS_ID -x CUDA_VISIBLE_DEVICES=0 -x OMP_NUM_THREADS=4 vasp-std
|
||||
vasp-intel-env mpirun -n 2 -genv OMP_NUM_THREADS=4 vasp-std
|
||||
```
|
||||
|
||||
其中 `CUDA_VISIBLE_DEVICES` 用于指定用哪几个显卡计算(多个显卡用逗号分隔)。
|
||||
要查看显卡的编号,可以用 `CUDA_DEVICE_ORDER=PCI_BUS_ID vasp-nvidia-640-env nvaccelinfo` 命令。
|
||||
要查看显卡的编号,可以用 `CUDA_DEVICE_ORDER=PCI_BUS_ID vasp-nvidia-env nvaccelinfo` 命令。
|
||||
|
||||
这里 `vasp-xxx-6.4.0` 命令的作用是,进入一个安装了对应版本的 VASP 的环境,实际上和 VASP 关系不大;
|
||||
这里 `vasp-xxx-env` 命令的作用是,进入一个安装了对应版本的 VASP 的环境,实际上和 VASP 关系不大;
|
||||
后面的 `mpirun xxx` 才是真的调用 VASP。
|
||||
所以实际上你也可以在这个环境里做别的事情,例如执行上面的 `nvaccelinfo` 命令。
|
||||
|
||||
|
||||
60
flake.lock
generated
60
flake.lock
generated
@@ -43,11 +43,11 @@
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1711742460,
|
||||
"narHash": "sha256-0O4v6e4a1toxXZ2gf5INhg4WPE5C5T+SVvsBt+45Mcc=",
|
||||
"lastModified": 1717279440,
|
||||
"narHash": "sha256-kH04ReTjxOpQumgWnqy40vvQLSnLGxWP6RF3nq5Esrk=",
|
||||
"owner": "zhaofengli",
|
||||
"repo": "attic",
|
||||
"rev": "4dbdbee45728d8ce5788db6461aaaa89d98081f0",
|
||||
"rev": "717cc95983cdc357bc347d70be20ced21f935843",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -131,11 +131,11 @@
|
||||
"yafas": "yafas"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717397536,
|
||||
"narHash": "sha256-Tea0kay1a8RDEhnwgpbqbaUmDgv0nn+tpDWr3vQOptU=",
|
||||
"lastModified": 1718116047,
|
||||
"narHash": "sha256-wt5smsz3nOV8USu2X1ZCQQXJEr9Zvf08pREx/Tpeoos=",
|
||||
"owner": "chaotic-cx",
|
||||
"repo": "nyx",
|
||||
"rev": "674c54d623c62f6c21cd2dc7e0a73c4b718aca00",
|
||||
"rev": "1ebc5065368a2d800930eb401ce955b99f876b8b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -242,11 +242,11 @@
|
||||
"rocksdb": "rocksdb"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1716883613,
|
||||
"narHash": "sha256-1fJyH76Pfx863Uk5jpPtpmyAIZcCk1luPD0cmPnhUNU=",
|
||||
"lastModified": 1718077083,
|
||||
"narHash": "sha256-VxakGnd1Gpjyd3fBu8MDuliWd11lJIjPW2Ev61OAguc=",
|
||||
"owner": "girlbossceo",
|
||||
"repo": "conduwuit",
|
||||
"rev": "f4cfc77a577e0dfd152878830294c8eb3fe47861",
|
||||
"rev": "305dfc3b426e71c69612a2f12dcd255c4d0e8cde",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -279,11 +279,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717025063,
|
||||
"narHash": "sha256-dIubLa56W9sNNz0e8jGxrX3CAkPXsq7snuFA/Ie6dn8=",
|
||||
"lastModified": 1718078026,
|
||||
"narHash": "sha256-LbQabH6h86ZzTvDnaZHmMwedRZNB2jYtUQzmoqWQoJ8=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "480dff0be03dac0e51a8dfc26e882b0d123a450e",
|
||||
"rev": "a3f0c63eed74a516298932b9b1627dd80b9c3892",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -548,11 +548,11 @@
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717223092,
|
||||
"narHash": "sha256-ih8NPk3Jn5EAILOGQZ+KS5NLmu6QmwohJX+36MaTAQE=",
|
||||
"lastModified": 1717827974,
|
||||
"narHash": "sha256-ixopuTeTouxqTxfMuzs6IaRttbT8JqRW5C9Q/57WxQw=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "9a025daf6799e3af80b677f0af57ef76432c3fcf",
|
||||
"rev": "ab655c627777ab5f9964652fe23bbb1dfbd687a8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -990,11 +990,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717012808,
|
||||
"narHash": "sha256-Wn0fbjqmpIiuPUWnvxu85a9sPYtSd/2tcPDhAYW54RM=",
|
||||
"lastModified": 1718081048,
|
||||
"narHash": "sha256-dwKvamucNK8gB6RTTfnBeBbBgjARQgHQph8PdHZoL3s=",
|
||||
"owner": "Jovian-Experiments",
|
||||
"repo": "Jovian-NixOS",
|
||||
"rev": "a8e6557f29fa0cbcc2c54d15f9664c14ae2a3e98",
|
||||
"rev": "f27db3a9a8c21a65c1ef50cacca3ef2bfff04cb9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1016,11 +1016,11 @@
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717207276,
|
||||
"narHash": "sha256-XUbdBIFCN4LRadBs0w7G/2cfMT5C3/6oxfgJB6m7S5U=",
|
||||
"lastModified": 1718103647,
|
||||
"narHash": "sha256-+QNxty2pzIG+P6gHPa2+cV3ZOS4TZcumP+bEubIqMmI=",
|
||||
"owner": "martinvonz",
|
||||
"repo": "jj",
|
||||
"rev": "5e7cb3435e0c8febc4648ba6651ba527cb0350b3",
|
||||
"rev": "556c7291c1948f235789bfaa096e24fbd2e22b43",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1200,11 +1200,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1716990063,
|
||||
"narHash": "sha256-0Vv125wrFCJgSUSQRqhuHQOopWbOc8ICVeY/d2wAjOg=",
|
||||
"lastModified": 1718032071,
|
||||
"narHash": "sha256-xAcK+PKIR1Z12fDMHlr2e0jzO9eIFHmRtCc8lp8MQNM=",
|
||||
"owner": "YaLTeR",
|
||||
"repo": "niri",
|
||||
"rev": "c8e46b9d172dfa2ca89d82b87055b8e39622f80c",
|
||||
"rev": "22a948cc759498923c1e9806580962cdd2d7b3e2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1444,11 +1444,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1717818640,
|
||||
"narHash": "sha256-VGTlViTvrMJa/ot1Lctbl8pXuT7pRWx/ixR0PypanrY=",
|
||||
"lastModified": 1718293815,
|
||||
"narHash": "sha256-M8Begx/FQ5dtR+FaV1+Ff7Siq5FX2dvbFIYHNoGPdOg=",
|
||||
"owner": "CHN-beta",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2a0d2928bd5a2f8e5eda397387c4cff9695b13d4",
|
||||
"rev": "ecd5c77a9a8b4f041b4bcb649cd219189e85987d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -2018,11 +2018,11 @@
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1717169693,
|
||||
"narHash": "sha256-qBruki5NHrSqIw5ulxtwFmVsb6W/aOKOMjsCJjfalA4=",
|
||||
"lastModified": 1717583671,
|
||||
"narHash": "sha256-+lRAmz92CNUxorqWusgJbL9VE1eKCnQQojglRemzwkw=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "d6d735e6f20ef78b16a79886fe28bd69cf059504",
|
||||
"rev": "48bbdd6a74f3176987d5c809894ac33957000d19",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
in pkgs.pkgsStatic.localPackages.hpcstat.override
|
||||
{ inherit openssh duc; standalone = true; version = inputs.self.rev or "dirty"; };
|
||||
ufo = pkgs.pkgsStatic.localPackages.ufo.override { version = inputs.self.rev or "dirty"; };
|
||||
chn-bsub = pkgs.pkgsStatic.localPackages.chn-bsub;
|
||||
nixpkgs = pkgs;
|
||||
}
|
||||
// (
|
||||
@@ -207,6 +208,12 @@
|
||||
packages = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
chn-bsub = pkgs.mkShell
|
||||
{
|
||||
inputsFrom = with pkgs.localPackages; [ chn-bsub ];
|
||||
buildInputs = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
CompileFlags:
|
||||
Add: [ -Wall, -Wextra, -std=c++23 ]
|
||||
Compiler: g++
|
||||
Compiler: g++
|
||||
|
||||
@@ -13,7 +13,7 @@ endif()
|
||||
|
||||
find_package(magic_enum REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS headers iostreams)
|
||||
find_package(Boost REQUIRED COMPONENTS headers iostreams filesystem)
|
||||
find_package(Eigen3 REQUIRED)
|
||||
find_package(range-v3 REQUIRED)
|
||||
find_path(NAMEOF_INCLUDE_DIR nameof.hpp REQUIRED)
|
||||
@@ -22,9 +22,9 @@ find_path(ZPP_BITS_INCLUDE_DIR zpp_bits.h REQUIRED)
|
||||
add_library(biu src/common.cpp)
|
||||
target_include_directories(biu PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> ${NAMEOF_INCLUDE_DIR} ${ZPP_BITS_INCLUDE_DIR})
|
||||
target_link_libraries(biu PUBLIC magic_enum::magic_enum fmt::fmt Boost::headers Boost::iostreams Eigen3::Eigen
|
||||
range-v3::range-v3)
|
||||
set_property(TARGET biu PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF)
|
||||
target_link_libraries(biu PUBLIC magic_enum::magic_enum fmt::fmt Boost::headers Boost::iostreams Boost::filesystem
|
||||
Eigen3::Eigen range-v3::range-v3)
|
||||
set_property(TARGET biu PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
|
||||
install(TARGETS biu EXPORT biuTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
@@ -35,3 +35,9 @@ install(FILES biuConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/biu)
|
||||
get_property(ImportedTargets DIRECTORY "${CMAKE_SOURCE_DIR}" PROPERTY IMPORTED_TARGETS)
|
||||
message("Imported targets: ${ImportedTargets}")
|
||||
message("List of compile features: ${CMAKE_CXX_COMPILE_FEATURES}")
|
||||
|
||||
include(CTest)
|
||||
add_executable(test-serialize test/serialize.cpp)
|
||||
target_link_libraries(test-serialize PRIVATE biu)
|
||||
set_property(TARGET test-serialize PROPERTY CXX_STANDARD 23 CXX_STANDARD_REQUIRED ON)
|
||||
add_test(NAME test-serialize COMMAND test-serialize)
|
||||
|
||||
@@ -8,4 +8,5 @@
|
||||
buildInputs = [ magic-enum fmt boost eigen range-v3 nameof zpp-bits ];
|
||||
propagatedBuildInputs = buildInputs;
|
||||
nativeBuildInputs = [ cmake ];
|
||||
doCheck = true;
|
||||
}
|
||||
|
||||
17
local/pkgs/biu/test/serialize.cpp
Normal file
17
local/pkgs/biu/test/serialize.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
# include <biu.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
struct student
|
||||
{
|
||||
int number;
|
||||
std::string name;
|
||||
std::vector<std::optional<double>> grade;
|
||||
using serialize = zpp::bits::members<3>;
|
||||
auto operator<=>(const student&) const = default;
|
||||
};
|
||||
student bob{ 123, "Bob", { 3.5, std::nullopt, 4.0 } };
|
||||
auto serialized_bob = biu::serialize(bob);
|
||||
auto bob2 = biu::deserialize<student>(serialized_bob);
|
||||
assert(bob == bob2);
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
CompileFlags:
|
||||
Add: [ -Wall, -Wextra, -std=c++23 ]
|
||||
Compiler: gcc
|
||||
Compiler: g++
|
||||
1
local/pkgs/chn-bsub/.envrc
Normal file
1
local/pkgs/chn-bsub/.envrc
Normal file
@@ -0,0 +1 @@
|
||||
use flake .#chn-bsub
|
||||
27
local/pkgs/chn-bsub/CMakeLists.txt
Normal file
27
local/pkgs/chn-bsub/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(chn-bsub VERSION 0.0.0 LANGUAGES CXX)
|
||||
enable_testing()
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message("Setting build type to 'Release' as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
find_package(ftxui REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS filesystem iostreams)
|
||||
find_package(range-v3 REQUIRED)
|
||||
find_package(biu REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
|
||||
add_executable(chn-bsub src/main.cpp)
|
||||
target_compile_features(chn-bsub PUBLIC cxx_std_23)
|
||||
target_link_libraries(chn-bsub PRIVATE fmt::fmt ftxui::screen ftxui::dom ftxui::component Boost::filesystem
|
||||
range-v3::range-v3 biu::biu nlohmann_json::nlohmann_json)
|
||||
|
||||
install(TARGETS chn-bsub RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
get_property(ImportedTargets DIRECTORY "${CMAKE_SOURCE_DIR}" PROPERTY IMPORTED_TARGETS)
|
||||
message("Imported targets: ${ImportedTargets}")
|
||||
message("List of compile features: ${CMAKE_CXX_COMPILE_FEATURES}")
|
||||
12
local/pkgs/chn-bsub/default.nix
Normal file
12
local/pkgs/chn-bsub/default.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
stdenv, lib, sbatchConfig ? null, substituteAll, runCommand,
|
||||
cmake, pkg-config, ftxui, biu, nlohmann_json
|
||||
}:
|
||||
stdenv.mkDerivation
|
||||
{
|
||||
name = "chn-bsub";
|
||||
src = ./.;
|
||||
buildInputs = [ ftxui biu nlohmann_json ];
|
||||
nativeBuildInputs = [ cmake pkg-config ];
|
||||
postInstall = "ln -s chn-bsub $out/bin/chn_bsub";
|
||||
}
|
||||
338
local/pkgs/chn-bsub/src/main.cpp
Normal file
338
local/pkgs/chn-bsub/src/main.cpp
Normal file
@@ -0,0 +1,338 @@
|
||||
# include <map>
|
||||
# include <filesystem>
|
||||
# include <ftxui/component/component.hpp>
|
||||
# include <ftxui/component/component_options.hpp>
|
||||
# include <ftxui/component/screen_interactive.hpp>
|
||||
# include <ftxui/dom/table.hpp>
|
||||
# include <boost/process.hpp>
|
||||
# include <boost/algorithm/string.hpp>
|
||||
# include <range/v3/range.hpp>
|
||||
# include <range/v3/view.hpp>
|
||||
# include <nlohmann/json.hpp>
|
||||
# include <biu.hpp>
|
||||
|
||||
using namespace biu::literals;
|
||||
|
||||
int main()
|
||||
{
|
||||
// 需要绑定到界面上的变量
|
||||
struct
|
||||
{
|
||||
std::array<int, 3> vasp_version_selected = { 0, 0, 0 };
|
||||
std::vector<std::string> vasp_version_entries_level1 = { "640", "631" };
|
||||
std::map<std::string, std::vector<std::string>> vasp_version_entries_level2 =
|
||||
{
|
||||
{ "640", { "(default)", "fixc", "optcell_vtst_wannier90", "shmem", "vtst" }},
|
||||
{ "631", { "shmem" } }
|
||||
};
|
||||
std::vector<std::string> vasp_version_entries_level3 = { "std", "gam", "ncl" };
|
||||
|
||||
int queue_selected = 0;
|
||||
std::vector<std::string> queue_entries =
|
||||
{
|
||||
"normal_1day", "normal_1day_new", "ocean_530_1day", "ocean6226R_1day",
|
||||
"normal_1week", "normal_2week", "normal"
|
||||
};
|
||||
std::atomic<bool> queue_detail_show = false;
|
||||
std::map<std::string, std::string> queue_hosts =
|
||||
{
|
||||
{ "normal_1day", "normal_1day" },
|
||||
{ "normal_1day_new", "charge_s_normal" },
|
||||
{ "ocean_530_1day", "hd_sd530" },
|
||||
{ "ocean6226R_1day", "hd_sd530_6226R" },
|
||||
{ "normal_1week", "normal_1week" },
|
||||
{ "normal_2week", "b_node" },
|
||||
{ "normal", "cnodes" }
|
||||
};
|
||||
std::map<std::string, std::string> queue_timelimit =
|
||||
{
|
||||
{ "normal_1day", "1 day" },
|
||||
{ "normal_1day_new", "1 day" },
|
||||
{ "ocean_530_1day", "1 day" },
|
||||
{ "ocean6226R_1day", "1 day" },
|
||||
{ "normal_1week", "7 day" },
|
||||
{ "normal_2week", "14 day" },
|
||||
{ "normal", "14 day" }
|
||||
};
|
||||
std::optional<std::vector<std::vector<std::string>>> queue_detail = [this]
|
||||
-> std::optional<std::vector<std::vector<std::string>>>
|
||||
{
|
||||
std::vector<std::vector<std::string>> result;
|
||||
result.push_back({ "number of nodes (total/busy/free)" });
|
||||
for (auto& queue : queue_entries)
|
||||
{
|
||||
if
|
||||
(
|
||||
auto result = biu::exec<{.SearchPath=true}>
|
||||
("bhosts", { "-o", "hname max run", "-json", queue_hosts[queue] });
|
||||
!result
|
||||
)
|
||||
return std::nullopt;
|
||||
else
|
||||
{
|
||||
auto json = nlohmann::json::parse(result.Stdout);
|
||||
auto total = json["HOSTS"].get<std::size_t>();
|
||||
auto records = json["RECORDS"].get<std::vector<nlohmann::json>>();
|
||||
auto busy = (records
|
||||
| ranges::views::filter
|
||||
([](auto& record){ return record["RUN"].template get<std::size_t>() > 0; })).size();
|
||||
auto free = total - busy;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}();
|
||||
std::string ncores = "";
|
||||
std::string job_name = []
|
||||
{
|
||||
// /data/gpfs01/jykang/linwei/chn/lammps-SiC
|
||||
std::vector<std::string> paths;
|
||||
boost::split(paths, std::filesystem::current_path().string(), boost::is_any_of("/"));
|
||||
if (paths.size() < 7) return "my-great-job"s;
|
||||
else return paths[5] + "_" + paths.back();
|
||||
}();
|
||||
std::string bsub = "";
|
||||
std::string user_command = "";
|
||||
} state;
|
||||
|
||||
// 为组件增加标题栏和分割线
|
||||
auto with_title = [](std::string title)
|
||||
{
|
||||
return [title](ftxui::Element element)
|
||||
{
|
||||
return ftxui::vbox
|
||||
(ftxui::text(title) | ftxui::bgcolor(ftxui::Color::Blue), element, ftxui::separatorLight());
|
||||
};
|
||||
};
|
||||
// 为组件增加空白以填充界面
|
||||
auto with_padding = [](ftxui::Element element) -> ftxui::Element
|
||||
{
|
||||
auto empty = ftxui::emptyElement() | ftxui::flex_grow;
|
||||
return ftxui::vbox(empty, ftxui::hbox(empty, element | ftxui::center, empty), empty);
|
||||
};
|
||||
// 在组件左边增加分割线
|
||||
auto with_separator = [](ftxui::Element element)
|
||||
{ return ftxui::hbox(ftxui::separatorLight(), element); };
|
||||
// 在组件左边增加小标题
|
||||
auto with_subtitle = [](std::string title)
|
||||
{ return [title](ftxui::Element element) { return ftxui::hbox(ftxui::text(title), element); }; };
|
||||
|
||||
// 构建界面
|
||||
auto screen = ftxui::ScreenInteractive::Fullscreen();
|
||||
auto request_interface = ftxui::Container::Vertical
|
||||
({
|
||||
ftxui::Container::Horizontal
|
||||
({
|
||||
ftxui::Menu(&state.vasp_version_entries_level1, &state.vasp_version_selected[0]),
|
||||
ftxui::Container::Tab
|
||||
(
|
||||
{
|
||||
ftxui::Menu(&state.vasp_version_entries_level2[0], &state.vasp_version_selected[1]),
|
||||
ftxui::Menu(&state.vasp_version_entries_level2[1], &state.vasp_version_selected[1])
|
||||
},
|
||||
&state.vasp_version_selected[0]
|
||||
) | with_separator,
|
||||
ftxui::Menu(&state.vasp_version_entries_level3, &state.vasp_version_selected[2]) | with_separator
|
||||
}) | with_title("VASP version"),
|
||||
ftxui::Container::Horizontal
|
||||
({
|
||||
ftxui::Menu(&state.queue_entries, &state.queue_selected) | with_title("Queue\n"),
|
||||
ftxui::Table
|
||||
(
|
||||
state.queue_detail
|
||||
| ranges::views::transform([](auto& line){ line | ranges::views::transform([](auto& text){ return ftxui::text() }) })
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<ftxui::Component> vasp_version_level2_children;
|
||||
for (auto& i : state.vasp_version_entries_level1)
|
||||
vasp_version_level2_children.push_back(ftxui::Menu
|
||||
(
|
||||
&state.vasp_version_entries_level2[i],
|
||||
&state.vasp_version_selected[1]
|
||||
));
|
||||
auto vasp_version_level2 = ftxui::Container::Tab
|
||||
(
|
||||
vasp_version_level2_children,
|
||||
&state.vasp_version_selected[0]
|
||||
) | ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 27);
|
||||
})
|
||||
|
||||
|
||||
|
||||
ftxui::Menu(&state.vasp_version_entries, &state.vasp_version_selected)
|
||||
| with_title("Select VASP version:"),
|
||||
ftxui::Container::Horizontal
|
||||
({
|
||||
ftxui::Menu(&state.device_type_entries, &state.device_type_selected),
|
||||
ftxui::Container::Vertical([&]
|
||||
{
|
||||
std::vector<std::shared_ptr<ftxui::ComponentBase>> devices;
|
||||
auto checkbox_option = ftxui::CheckboxOption::Simple();
|
||||
checkbox_option.transform = [](const ftxui::EntryState& s)
|
||||
{
|
||||
auto prefix = ftxui::text(s.state ? "[X] " : "[ ] ");
|
||||
auto t = ftxui::text(s.label);
|
||||
if (s.active) t |= ftxui::bold;
|
||||
if (s.focused) t |= ftxui::inverted;
|
||||
return ftxui::hbox({prefix, t});
|
||||
};
|
||||
for (int i = 0; i < state.device_selected.size(); i++)
|
||||
devices.push_back(ftxui::Checkbox
|
||||
(state.device_entries[i], &state.device_selected[i], checkbox_option));
|
||||
return devices;
|
||||
}()) | with_separator | ftxui::Maybe([&]{ return state.device_type_selected == 1; }),
|
||||
ftxui::Container::Vertical
|
||||
({
|
||||
ftxui::Input(&state.mpi_threads) | ftxui::size(ftxui::WIDTH, ftxui::GREATER_THAN, 3)
|
||||
| with_subtitle("MPI threads: "),
|
||||
ftxui::Input(&state.openmp_threads) | ftxui::size(ftxui::WIDTH, ftxui::GREATER_THAN, 3)
|
||||
| with_subtitle("OpenMP threads: ")
|
||||
}) | with_separator | ftxui::Maybe([&]{ return state.device_type_selected == 2; }),
|
||||
}) | with_title("Select device:"),
|
||||
ftxui::Input(&state.job_name) | with_title("Job name:"),
|
||||
ftxui::Input(&state.output_file) | with_title("Output file:"),
|
||||
ftxui::Container::Horizontal
|
||||
({
|
||||
ftxui::Button("Continue",
|
||||
[&]{ state.user_command = "continue"; screen.ExitLoopClosure()(); }),
|
||||
ftxui::Button("Quit",
|
||||
[&]{ state.user_command = "quit"; screen.ExitLoopClosure()(); })
|
||||
})
|
||||
}) | ftxui::borderHeavy | with_padding;
|
||||
|
||||
[&state, &screen]
|
||||
{
|
||||
auto vasp_version_level1 = ftxui::Menu
|
||||
(&state.vasp_version_entries_level1, &state.vasp_version_selected[0])
|
||||
| ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 8);
|
||||
std::vector<ftxui::Component> vasp_version_level2_children;
|
||||
for (auto& i : state.vasp_version_entries_level1)
|
||||
vasp_version_level2_children.push_back(ftxui::Menu
|
||||
(
|
||||
&state.vasp_version_entries_level2[i],
|
||||
&state.vasp_version_selected[1]
|
||||
));
|
||||
auto vasp_version_level2 = ftxui::Container::Tab
|
||||
(
|
||||
vasp_version_level2_children,
|
||||
&state.vasp_version_selected[0]
|
||||
) | ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 27);
|
||||
auto vasp_version_level3 = ftxui::Menu
|
||||
(&state.vasp_version_entries_level3, &state.vasp_version_selected[2])
|
||||
| ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 8);
|
||||
auto vasp_version = component_with_title("Select vasp version:",
|
||||
ftxui::Container::Horizontal
|
||||
({vasp_version_level1, vasp_version_level2, vasp_version_level3})
|
||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 5));
|
||||
auto queue = component_with_title("Select queue:",
|
||||
ftxui::Menu(&state.queue_entries, &state.queue_selected)
|
||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 6));
|
||||
auto ncores = component_with_title("Input cores you want to use:",
|
||||
ftxui::Input(&state.ncores, "(leave blank to use all cores)"))
|
||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 3);
|
||||
auto job_name = component_with_title("Job name:",
|
||||
ftxui::Input(&state.job_name, ""))
|
||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 3);
|
||||
auto continue_button = ftxui::Button("Continue",
|
||||
[&]{state.user_command = "continue"; screen.ExitLoopClosure()();});
|
||||
auto quit_button = ftxui::Button("Quit",
|
||||
[&]{state.user_command = "quit"; screen.ExitLoopClosure()();});
|
||||
return ftxui::Container::Vertical
|
||||
({
|
||||
vasp_version, queue, ncores, job_name,
|
||||
ftxui::Container::Horizontal({continue_button, quit_button})
|
||||
}) | ftxui::borderHeavy
|
||||
| ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 47)
|
||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 24);
|
||||
}();
|
||||
auto confirm_interface = [&state, &screen, &component_with_title]
|
||||
{
|
||||
ftxui::InputOption input_option;
|
||||
input_option.multiline = true;
|
||||
return ftxui::Container::Vertical
|
||||
({
|
||||
component_with_title
|
||||
(
|
||||
"Double check & modify submit command:",
|
||||
ftxui::Input(&state.bsub, "", input_option)
|
||||
)
|
||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 7),
|
||||
ftxui::Container::Horizontal
|
||||
({
|
||||
ftxui::Button("Submit",
|
||||
[&]{state.user_command = "submit"; screen.ExitLoopClosure()();}),
|
||||
ftxui::Button("Quit",
|
||||
[&]{state.user_command = "quit"; screen.ExitLoopClosure()();}),
|
||||
ftxui::Button("Back",
|
||||
[&]{state.user_command = "back"; screen.ExitLoopClosure()();})
|
||||
}),
|
||||
ftxui::Renderer([]{return ftxui::vbox
|
||||
({
|
||||
ftxui::separator(),
|
||||
ftxui::text("Source code:"),
|
||||
ftxui::text("https://github.com/CHN-beta/chn_bsub.git"),
|
||||
ftxui::text("Star & PR are welcome!"),
|
||||
});})
|
||||
}) | ftxui::borderHeavy
|
||||
| ftxui::size(ftxui::WIDTH, ftxui::EQUAL, 47)
|
||||
| ftxui::size(ftxui::HEIGHT, ftxui::EQUAL, 14);
|
||||
}();
|
||||
|
||||
// 实际投递任务
|
||||
auto submit = [](std::string bsub)
|
||||
{
|
||||
// replace \n with space
|
||||
boost::replace_all(bsub, "\n", " ");
|
||||
auto process = boost::process::child
|
||||
(
|
||||
boost::process::search_path("sh"), "-c", bsub,
|
||||
boost::process::std_in.close(),
|
||||
boost::process::std_out > stdout,
|
||||
boost::process::std_err > stderr
|
||||
);
|
||||
process.wait();
|
||||
};
|
||||
|
||||
// 进入事件循环
|
||||
while (true)
|
||||
{
|
||||
screen.Loop(request_interface);
|
||||
if (state.user_command == "quit")
|
||||
return EXIT_FAILURE;
|
||||
else if (state.user_command != "continue")
|
||||
throw std::runtime_error("user_command is not recognized");
|
||||
state.bsub = fmt::format
|
||||
(
|
||||
"bsub -J '{}'\n-q {}\n-n {}\n-R 'span[hosts=1]'\n-o 'output.txt'\nchn_vasp.sh {}",
|
||||
state.job_name,
|
||||
state.queue_entries[state.queue_selected],
|
||||
state.ncores.empty() ? state.max_cores[state.queue_entries[state.queue_selected]] :
|
||||
std::stoi(state.ncores),
|
||||
[&]
|
||||
{
|
||||
auto version_level1 = state.vasp_version_entries_level1[state.vasp_version_selected[0]];
|
||||
auto version_level2 = state.vasp_version_entries_level2[version_level1]
|
||||
[state.vasp_version_selected[1]];
|
||||
auto version_level3 = state.vasp_version_entries_level3[state.vasp_version_selected[2]];
|
||||
return fmt::format
|
||||
(
|
||||
"{}{}_{}",
|
||||
version_level1,
|
||||
version_level2 == "(default)" ? ""s : "_" + version_level2,
|
||||
version_level3
|
||||
);
|
||||
}()
|
||||
);
|
||||
screen.Loop(confirm_interface);
|
||||
if (state.user_command == "quit")
|
||||
return EXIT_FAILURE;
|
||||
else if (state.user_command == "back")
|
||||
continue;
|
||||
else if (state.user_command != "submit")
|
||||
throw std::runtime_error("user_command is not recognized");
|
||||
submit(state.bsub);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ inputs: rec
|
||||
{ src = inputs.topInputs.kylin-virtual-keyboard; };
|
||||
biu = inputs.pkgs.callPackage ./biu { inherit nameof zpp-bits; };
|
||||
zxorm = inputs.pkgs.callPackage ./zxorm { src = inputs.topInputs.zxorm; };
|
||||
hpcstat = inputs.pkgs.callPackage ./hpcstat { inherit nameof sqlite-orm zpp-bits date openxlsx biu; };
|
||||
hpcstat = inputs.pkgs.callPackage ./hpcstat { inherit nameof sqlite-orm zpp-bits date biu openxlsx; };
|
||||
openxlsx = inputs.pkgs.callPackage ./openxlsx { src = inputs.topInputs.openxlsx; };
|
||||
sqlite-orm = inputs.pkgs.callPackage ./sqlite-orm { src = inputs.topInputs.sqlite-orm; };
|
||||
mkPnpmPackage = inputs.pkgs.callPackage ./mkPnpmPackage.nix {};
|
||||
@@ -81,6 +81,7 @@ inputs: rec
|
||||
sbatch-tui = inputs.pkgs.callPackage ./sbatch-tui { inherit biu; };
|
||||
ufo = inputs.pkgs.callPackage ./ufo
|
||||
{ inherit concurrencpp biu glad matplotplusplus zpp-bits; tbb = inputs.pkgs.tbb_2021_11; };
|
||||
chn-bsub = inputs.pkgs.callPackage ./chn-bsub { inherit biu; };
|
||||
|
||||
fromYaml = content: builtins.fromJSON (builtins.readFile
|
||||
(inputs.pkgs.runCommand "toJSON" {}
|
||||
|
||||
@@ -18,18 +18,18 @@ find_path(ZPP_BITS_INCLUDE_DIR zpp_bits.h REQUIRED)
|
||||
find_package(range-v3 REQUIRED)
|
||||
find_path(NAMEOF_INCLUDE_DIR nameof.hpp REQUIRED)
|
||||
find_package(date REQUIRED)
|
||||
find_package(OpenXLSX REQUIRED)
|
||||
find_package(httplib REQUIRED)
|
||||
find_package(termcolor REQUIRED)
|
||||
find_package(biu REQUIRED)
|
||||
find_package(OpenXLSX REQUIRED)
|
||||
|
||||
add_executable(hpcstat src/main.cpp src/env.cpp src/keys.cpp src/ssh.cpp src/sql.cpp src/lfs.cpp src/common.cpp
|
||||
src/push.cpp src/disk.cpp)
|
||||
target_compile_features(hpcstat PRIVATE cxx_std_23)
|
||||
target_include_directories(hpcstat PRIVATE ${PROJECT_SOURCE_DIR}/include ${ZPP_BITS_INCLUDE_DIR})
|
||||
target_link_libraries(hpcstat PRIVATE Boost::headers Boost::filesystem sqlite_orm::sqlite_orm
|
||||
nlohmann_json::nlohmann_json range-v3::range-v3 date::date date::date-tz OpenXLSX::OpenXLSX httplib::httplib
|
||||
termcolor::termcolor biu::biu)
|
||||
nlohmann_json::nlohmann_json range-v3::range-v3 date::date date::date-tz httplib::httplib
|
||||
termcolor::termcolor biu::biu OpenXLSX::OpenXLSX)
|
||||
target_compile_definitions(hpcstat PRIVATE HPCSTAT_VERSION="${HPCSTAT_VERSION}")
|
||||
|
||||
install(TARGETS hpcstat RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
stdenv, cmake, pkg-config, standalone ? false, version ? null, makeWrapper, lib,
|
||||
boost, fmt, sqlite-orm, nlohmann_json, zpp-bits, range-v3, nameof, openssh, sqlite, date, openxlsx, httplib, openssl,
|
||||
boost, fmt, sqlite-orm, nlohmann_json, zpp-bits, range-v3, nameof, openssh, sqlite, date, httplib, openssl, openxlsx,
|
||||
termcolor, duc, biu
|
||||
}: stdenv.mkDerivation
|
||||
{
|
||||
name = "hpcstat";
|
||||
src = ./.;
|
||||
buildInputs =
|
||||
[ boost fmt sqlite-orm nlohmann_json zpp-bits range-v3 nameof sqlite date openxlsx httplib termcolor openssl biu ];
|
||||
[ boost fmt sqlite-orm nlohmann_json zpp-bits range-v3 nameof sqlite date httplib termcolor openssl biu openxlsx ];
|
||||
nativeBuildInputs = [ cmake pkg-config makeWrapper ];
|
||||
cmakeFlags = lib.optionals (version != null) [ "-DHPCSTAT_VERSION=${version}" ];
|
||||
postInstall =
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace hpcstat::disk
|
||||
std::string Time;
|
||||
using serialize = zpp::bits::members<4>;
|
||||
};
|
||||
// 刷新 duc 数据库,并读取
|
||||
std::optional<Usage> stat();
|
||||
// 刷新 duc 数据库
|
||||
bool stat();
|
||||
// 从 duc 数据库中读取数据
|
||||
std::optional<Usage> get();
|
||||
}
|
||||
|
||||
@@ -62,12 +62,10 @@ namespace hpcstat::sql
|
||||
// 三个字符串分别是序列化后的数据,签名,指纹
|
||||
std::optional<std::vector<std::tuple<std::string, std::string, std::string>>>
|
||||
verify(std::string old_db, std::string new_db);
|
||||
// 将某个月份的数据导出到文件
|
||||
// 将某个月份的数据导出
|
||||
bool export_data(long start_time, long end_time, std::string filename);
|
||||
// 检查任务状态,返回有变化的任务 id、名称、现在的状态、提交时的 key、subaccount
|
||||
// 如果没有找到提交时的信息,则忽略这个任务
|
||||
std::optional<std::map<unsigned, std::tuple<std::string, std::string, std::string, std::optional<std::string>>>>
|
||||
check_job_status();
|
||||
// 获取最新的磁盘使用情况
|
||||
std::optional<std::string> get_disk();
|
||||
}
|
||||
|
||||
@@ -20,17 +20,17 @@ namespace hpcstat::disk
|
||||
{ "zhanhuahan", false }
|
||||
};
|
||||
|
||||
std::optional<Usage> stat()
|
||||
bool stat()
|
||||
{
|
||||
if (auto homedir = env::env("HOME"); !homedir)
|
||||
{ std::cerr << "HOME not set\n"; return {}; }
|
||||
{ std::cerr << "HOME not set\n"; return false; }
|
||||
else if (auto ducbindir = env::env("HPCSTAT_DUC_BINDIR"); !ducbindir)
|
||||
{ std::cerr << "HPCSTAT_DUC_BINDIR not set\n"; return {}; }
|
||||
{ std::cerr << "HPCSTAT_DUC_BINDIR not set\n"; return false; }
|
||||
else if (auto datadir = env::env("HPCSTAT_DATADIR"); !datadir)
|
||||
{ std::cerr << "HPCSTAT_DATADIR not set\n"; return {}; }
|
||||
{ std::cerr << "HPCSTAT_DATADIR not set\n"; return false; }
|
||||
else if
|
||||
(
|
||||
auto result = biu::exec
|
||||
auto result = biu::exec<{.DirectStdout = true, .DirectStderr = true}>
|
||||
(
|
||||
// duc index -d ./duc.db -p ~
|
||||
"{}/duc"_f(*ducbindir),
|
||||
@@ -38,7 +38,18 @@ namespace hpcstat::disk
|
||||
);
|
||||
!result
|
||||
)
|
||||
{ std::cerr << "failed to index\n"; return {}; }
|
||||
{ std::cerr << "failed to index\n"; return false; }
|
||||
else return true;
|
||||
}
|
||||
|
||||
std::optional<Usage> get()
|
||||
{
|
||||
if (auto homedir = env::env("HOME"); !homedir)
|
||||
{ std::cerr << "HOME not set\n"; return {}; }
|
||||
else if (auto ducbindir = env::env("HPCSTAT_DUC_BINDIR"); !ducbindir)
|
||||
{ std::cerr << "HPCSTAT_DUC_BINDIR not set\n"; return {}; }
|
||||
else if (auto datadir = env::env("HPCSTAT_DATADIR"); !datadir)
|
||||
{ std::cerr << "HPCSTAT_DATADIR not set\n"; return {}; }
|
||||
else
|
||||
{
|
||||
auto get_size = [&](std::optional<std::string> path) -> std::optional<double>
|
||||
@@ -87,7 +98,7 @@ namespace hpcstat::disk
|
||||
{
|
||||
std::smatch match;
|
||||
// search string like 2024-06-08 13:45:19
|
||||
if (!std::regex_search(result.Stdout, match, std::regex(R"((\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}))")))
|
||||
if (!std::regex_search(result.Stdout, match, R"((\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}))"_re))
|
||||
{ std::cerr << "failed to parse {}\n"_f(result.Stdout); return {}; }
|
||||
return match[1];
|
||||
}
|
||||
|
||||
@@ -56,12 +56,11 @@ int main(int argc, const char** argv)
|
||||
{
|
||||
std::cout << "\33[2K\rLogged in as {} (Fingerprint: SHA256:{}{}).\n"_f
|
||||
(Keys[*fp].Username, *fp, sub_account ? " Subaccount {}"_f(*sub_account) : "");
|
||||
if (auto sql_data = sql::get_disk(); !sql_data)
|
||||
if (auto disk_stat = disk::get(); !disk_stat)
|
||||
std::cerr << "Failed to get disk usage statistic.\n";
|
||||
else
|
||||
{
|
||||
auto disk_stat = biu::deserialize<disk::Usage>(*sql_data);
|
||||
double percent = disk_stat.Total / 800 * 100;
|
||||
double percent = disk_stat->Total / 800 * 100;
|
||||
auto color = percent > 95 ? termcolor::red<char> :
|
||||
percent > 80 ? termcolor::yellow<char> : termcolor::green<char>;
|
||||
auto bgcolor = percent > 95 ? termcolor::on_red<char> :
|
||||
@@ -69,15 +68,15 @@ int main(int argc, const char** argv)
|
||||
std::cout
|
||||
<< color << "disk usage: " << termcolor::reset
|
||||
<< bgcolor << termcolor::white
|
||||
<< "{:.1f}% ({:.1f}GB / ~800GB)"_f(percent, disk_stat.Total) << termcolor::reset
|
||||
<< color << " (estimated, counted at {})\n"_f(disk_stat.Time) << termcolor::reset;
|
||||
<< "{:.1f}% ({:.1f}GB / ~800GB)"_f(percent, disk_stat->Total) << termcolor::reset
|
||||
<< color << " (estimated, counted at {})\n"_f(disk_stat->Time) << termcolor::reset;
|
||||
if (percent > 80)
|
||||
{
|
||||
std::cout << color << "Top 3 directories owned by teacher:\n";
|
||||
for (auto& [name, size] : disk_stat.Teacher | ranges::views::take(3))
|
||||
for (auto& [name, size] : disk_stat->Teacher | ranges::views::take(3))
|
||||
std::cout << " {:.1f}GB {}\n"_f(size, name);
|
||||
std::cout << color << "Top 3 directories owned by student:\n";
|
||||
for (auto& [name, size] : disk_stat.Student | ranges::views::take(3))
|
||||
for (auto& [name, size] : disk_stat->Student | ranges::views::take(3))
|
||||
std::cout << " {:.1f}GB {}\n"_f(size, name);
|
||||
std::cout << termcolor::reset;
|
||||
}
|
||||
@@ -168,8 +167,7 @@ int main(int argc, const char** argv)
|
||||
auto end = sys_seconds(sys_days(month(month_n) / 1 / year_n + months(1)))
|
||||
.time_since_epoch().count();
|
||||
lock.lock();
|
||||
if (!sql::export_data(begin, end, "hpcstat-{}-{}.xlsx"_f(year_n, month_n)))
|
||||
return 1;
|
||||
if (!sql::export_data(begin, end, "{}{}.xlsx"_f(year_n, month_n))) return 1;
|
||||
}
|
||||
else if (args[1] == "push")
|
||||
{
|
||||
@@ -179,23 +177,7 @@ int main(int argc, const char** argv)
|
||||
}
|
||||
else if (args[1] == "version") { std::cout << HPCSTAT_VERSION << std::endl; }
|
||||
else if (args[1] == "diskstat")
|
||||
{
|
||||
auto stat_thread = std::async(std::launch::async, []{ return disk::stat(); });
|
||||
std::cout << "Waiting for disk usage statistic to be collected... 0s" << std::flush;
|
||||
for (unsigned i = 1; stat_thread.wait_for(1s) != std::future_status::ready; i++)
|
||||
std::cout << "\rWaiting for disk usage statistic to be collected... {}s"_f(i) << std::flush;
|
||||
if (!stat_thread.get()) { std::cerr << "Failed to collect disk usage statistic.\n"; return 1; }
|
||||
else
|
||||
{
|
||||
lock.lock();
|
||||
if
|
||||
(
|
||||
auto write_result = sql::writedb(sql::DiskData{.Data = biu::serialize<char>(*stat_thread.get())});
|
||||
!write_result
|
||||
)
|
||||
{ std::cerr << "Failed to write disk usage statistic to database.\n"; return 1; }
|
||||
}
|
||||
}
|
||||
{ if (!disk::stat()) { std::cerr << "Failed to collect disk usage statistic.\n"; return 1; } }
|
||||
else { std::cerr << "Unknown command.\n"; return 1; }
|
||||
}
|
||||
catch (...) { std::cerr << boost::current_exception_diagnostic_information() << std::endl; return 1; }
|
||||
|
||||
@@ -68,12 +68,6 @@ namespace hpcstat::sql
|
||||
sqlite_orm::make_column("id", &CheckJobData::Id, sqlite_orm::primary_key().autoincrement()),
|
||||
sqlite_orm::make_column("job_id", &CheckJobData::JobId),
|
||||
sqlite_orm::make_column("status", &CheckJobData::Status)
|
||||
),
|
||||
sqlite_orm::make_table
|
||||
(
|
||||
"disk",
|
||||
sqlite_orm::make_column("id", &DiskData::Id, sqlite_orm::primary_key().autoincrement()),
|
||||
sqlite_orm::make_column("data", &DiskData::Data)
|
||||
)
|
||||
));};
|
||||
if (!dbfile)
|
||||
@@ -98,7 +92,6 @@ namespace hpcstat::sql
|
||||
template bool writedb(LogoutData);
|
||||
template bool writedb(SubmitJobData);
|
||||
template bool writedb(FinishJobData);
|
||||
template bool writedb(DiskData);
|
||||
std::optional<std::set<unsigned>> finishjob_remove_existed(std::map<unsigned, std::string> jobid_submit_time)
|
||||
{
|
||||
if (auto conn = connect(); !conn) return std::nullopt;
|
||||
@@ -195,24 +188,25 @@ namespace hpcstat::sql
|
||||
if (auto conn = connect(); !conn) return false;
|
||||
else
|
||||
{
|
||||
struct StatResult
|
||||
// 对于一个账户的总计
|
||||
struct StatAccount
|
||||
{
|
||||
double CpuTime = 0;
|
||||
unsigned LoginInteractive = 0, LoginNonInteractive = 0, SubmitJob = 0, FinishJobSuccess = 0,
|
||||
FinishJobFailed = 0;
|
||||
StatResult& operator+=(const StatResult& rhs)
|
||||
{
|
||||
CpuTime += rhs.CpuTime;
|
||||
LoginInteractive += rhs.LoginInteractive;
|
||||
LoginNonInteractive += rhs.LoginNonInteractive;
|
||||
SubmitJob += rhs.SubmitJob;
|
||||
FinishJobSuccess += rhs.FinishJobSuccess;
|
||||
FinishJobFailed += rhs.FinishJobFailed;
|
||||
return *this;
|
||||
}
|
||||
unsigned LoginInteractive = 0, LoginNonInteractive = 0, FinishJobSuccess = 0, FinishJobFailed = 0;
|
||||
};
|
||||
// Key SubAccount -> StatResult
|
||||
std::map<std::pair<std::string, std::optional<std::string>>, StatResult> stat;
|
||||
// Key SubAccount -> StatAccount
|
||||
std::map<std::pair<std::string, std::string>, StatAccount> stat_subaccount;
|
||||
// Key -> StatAccount
|
||||
std::map<std::optional<std::string>, StatAccount> stat_account;
|
||||
// 每一个任务
|
||||
struct StatJob
|
||||
{
|
||||
unsigned JobId;
|
||||
std::optional<std::string> Key, SubmitDir, JobCommand;
|
||||
std::string JobResult, SubmitTime, JobDetail;
|
||||
double CpuTime;
|
||||
};
|
||||
std::vector<StatJob> stat_job;
|
||||
// CpuTime & FinishJobSuccess & FinishJobFailed
|
||||
for
|
||||
(
|
||||
@@ -220,14 +214,37 @@ namespace hpcstat::sql
|
||||
(sqlite_orm::between(&FinishJobData::Time, start_time, end_time)))
|
||||
)
|
||||
{
|
||||
auto job_in_submit = search_job_in_submit
|
||||
(conn, it.JobId, it.SubmitTime);
|
||||
std::pair<std::string, std::optional<std::string>> key;
|
||||
if (!job_in_submit) key = { "", {} };
|
||||
else key = std::make_pair(job_in_submit->Key, job_in_submit->Subaccount);
|
||||
stat[key].CpuTime += it.CpuTime / 3600;
|
||||
if (it.JobResult == "DONE") stat[key].FinishJobSuccess++;
|
||||
else stat[key].FinishJobFailed++;
|
||||
stat_job.push_back
|
||||
({
|
||||
.JobId = it.JobId, .JobResult = it.JobResult, .SubmitTime = it.SubmitTime, .JobDetail = it.JobDetail,
|
||||
.CpuTime = it.CpuTime / 3600
|
||||
});
|
||||
if (auto job_in_submit = search_job_in_submit
|
||||
(conn, it.JobId, it.SubmitTime))
|
||||
{
|
||||
{
|
||||
auto& _ = stat_job.back();
|
||||
_.Key = job_in_submit->Key;
|
||||
_.SubmitDir = job_in_submit->SubmitDir;
|
||||
_.JobCommand = job_in_submit->JobCommand;
|
||||
}
|
||||
stat_account[job_in_submit->Key].CpuTime += it.CpuTime / 3600;
|
||||
if (it.JobResult == "DONE") stat_account[job_in_submit->Key].FinishJobSuccess++;
|
||||
else stat_account[job_in_submit->Key].FinishJobFailed++;
|
||||
if (job_in_submit->Subaccount)
|
||||
{
|
||||
stat_subaccount[{job_in_submit->Key, *job_in_submit->Subaccount}].CpuTime += it.CpuTime / 3600;
|
||||
if (it.JobResult == "DONE")
|
||||
stat_subaccount[{job_in_submit->Key, *job_in_submit->Subaccount}].FinishJobSuccess++;
|
||||
else stat_subaccount[{job_in_submit->Key, *job_in_submit->Subaccount}].FinishJobFailed++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stat_account[std::nullopt].CpuTime += it.CpuTime / 3600;
|
||||
if (it.JobResult == "DONE") stat_account[std::nullopt].FinishJobSuccess++;
|
||||
else stat_account[std::nullopt].FinishJobFailed++;
|
||||
}
|
||||
}
|
||||
// LoginInteractive & LoginNonInteractive
|
||||
for
|
||||
@@ -236,61 +253,58 @@ namespace hpcstat::sql
|
||||
(sqlite_orm::between(&LoginData::Time, start_time, end_time)))
|
||||
)
|
||||
{
|
||||
auto key = std::make_pair(it.Key, it.Subaccount);
|
||||
if (it.Interactive) stat[key].LoginInteractive++; else stat[key].LoginNonInteractive++;
|
||||
if (Keys[it.Key].Username == "hpcstat") continue;
|
||||
if (it.Interactive) stat_account[it.Key].LoginInteractive++; else stat_account[it.Key].LoginNonInteractive++;
|
||||
if (it.Subaccount)
|
||||
{
|
||||
if (it.Interactive) stat_subaccount[{it.Key, *it.Subaccount}].LoginInteractive++;
|
||||
else stat_subaccount[{it.Key, *it.Subaccount}].LoginNonInteractive++;
|
||||
}
|
||||
}
|
||||
// SubmitJob
|
||||
for
|
||||
(
|
||||
auto& it : conn->get_all<SubmitJobData>(sqlite_orm::where
|
||||
(sqlite_orm::between(&SubmitJobData::Time, start_time, end_time)))
|
||||
)
|
||||
stat[{it.Key,it.Subaccount }].SubmitJob++;
|
||||
// add all result with subaccount into result without subaccount
|
||||
std::map<std::string, StatResult> stat_without_subaccount;
|
||||
for (auto& [key, value] : stat) stat_without_subaccount[key.first] += value;
|
||||
// remove all result without subaccount
|
||||
std::erase_if(stat, [](auto& it) { return !it.first.second; });
|
||||
// write to excel
|
||||
// export to markdown
|
||||
std::cout << "| 账号 | 使用核时 | 登陆次数(总计/交互式/非交互式) | 完成任务(总计/成功/失败) | SSH密钥编号::指纹 |\n";
|
||||
std::cout << "| :--: | :--: | :--: | :--: | :--: |\n";
|
||||
std::vector<std::pair<std::optional<std::string>, StatAccount>> stat_account_vector
|
||||
(stat_account.begin(), stat_account.end());
|
||||
auto compare = [](auto& a, auto& b)
|
||||
{
|
||||
if (a.first)
|
||||
{ if (b.first) return Keys[*a.first].PubkeyFilename < Keys[*b.first].PubkeyFilename; else return true; }
|
||||
else return false;
|
||||
};
|
||||
std::sort(stat_account_vector.begin(), stat_account_vector.end(), compare);
|
||||
for (auto& [key, stat] : stat_account_vector)
|
||||
std::cout << "| {} | {:.2f} | {}/{}/{} | {}/{}/{} | `{}` |\n"_f
|
||||
(
|
||||
key ? Keys[*key].Username : "(unknown)", stat.CpuTime,
|
||||
stat.LoginInteractive + stat.LoginNonInteractive, stat.LoginInteractive, stat.LoginNonInteractive,
|
||||
stat.FinishJobSuccess + stat.FinishJobFailed, stat.FinishJobSuccess, stat.FinishJobFailed,
|
||||
key ? "{}::SHA256:{}"_f(Keys[*key].PubkeyFilename, *key) : "(unknown)"
|
||||
);
|
||||
for (auto& [key_subaccount, stat] : stat_subaccount)
|
||||
std::cout << "| {}::{} | {:.2f} | {} | {} | {} | {} | `{}::{}` |\n"_f
|
||||
(
|
||||
Keys[key_subaccount.first].Username, key_subaccount.second, stat.CpuTime,
|
||||
stat.LoginInteractive, stat.LoginNonInteractive, stat.FinishJobSuccess, stat.FinishJobFailed,
|
||||
Keys[key_subaccount.first].PubkeyFilename, key_subaccount.first
|
||||
);
|
||||
// export to excel
|
||||
OpenXLSX::XLDocument doc;
|
||||
doc.create(filename);
|
||||
doc.workbook().addWorksheet("Statistics");
|
||||
auto wks1 = doc.workbook().worksheet("Statistics");
|
||||
auto wks1 = doc.workbook().worksheet("Sheet1");
|
||||
wks1.row(1).values() = std::vector<std::string>
|
||||
{
|
||||
"Username", "FingerPrint", "CpuTime", "LoginInteractive", "LoginNonInteractive",
|
||||
"SubmitJob", "FinishJobSuccess", "FinishJobFailed"
|
||||
"用户", "任务ID", "结果", "核时", "提交时间", "提交时当前目录", "提交命令",
|
||||
"详情"
|
||||
};
|
||||
for
|
||||
(
|
||||
auto [row, it] = std::tuple(2, stat_without_subaccount.begin());
|
||||
it != stat_without_subaccount.end();
|
||||
it++, row++
|
||||
)
|
||||
for (auto [row, it] = std::tuple(2, stat_job.begin()); it != stat_job.end(); it++, row++)
|
||||
wks1.row(row).values() = std::vector<std::string>
|
||||
{
|
||||
Keys.contains(it->first) ? Keys[it->first].Username : "(unknown)", it->first,
|
||||
"{:.2f}"_f(it->second.CpuTime), "{}"_f(it->second.LoginInteractive),
|
||||
"{}"_f(it->second.LoginNonInteractive), "{}"_f(it->second.SubmitJob),
|
||||
"{}"_f(it->second.FinishJobSuccess), "{}"_f(it->second.FinishJobFailed)
|
||||
Keys.contains(*it->Key) ? Keys[*it->Key].Username : "(unknown)",
|
||||
"{}"_f(it->JobId), it->JobResult, "{:.2f}"_f(it->CpuTime), it->SubmitTime,
|
||||
it->SubmitDir.value_or("(unknown)"), it->JobCommand.value_or("(unknown)"),
|
||||
it->JobDetail
|
||||
};
|
||||
doc.workbook().addWorksheet("StatisticsWithSubAccount");
|
||||
auto wks2 = doc.workbook().worksheet("StatisticsWithSubAccount");
|
||||
wks2.row(1).values() = std::vector<std::string>
|
||||
{
|
||||
"Username::SubAccount", "CpuTime", "LoginInteractive", "LoginNonInteractive",
|
||||
"SubmitJob", "FinishJobSuccess", "FinishJobFailed"
|
||||
};
|
||||
for (auto [row, it] = std::tuple(2, stat.begin()); it != stat.end(); it++, row++)
|
||||
wks2.row(row).values() = std::vector<std::string>
|
||||
{
|
||||
(Keys.contains(it->first.first) ? Keys[it->first.first].Username : "(unknown)")
|
||||
+ "::" + *it->first.second,
|
||||
"{:.2f}"_f(it->second.CpuTime), "{}"_f(it->second.LoginInteractive),
|
||||
"{}"_f(it->second.LoginNonInteractive), "{}"_f(it->second.SubmitJob),
|
||||
"{}"_f(it->second.FinishJobSuccess), "{}"_f(it->second.FinishJobFailed)
|
||||
};
|
||||
doc.workbook().deleteSheet("Sheet1");
|
||||
doc.save();
|
||||
return true;
|
||||
}
|
||||
@@ -326,16 +340,4 @@ namespace hpcstat::sql
|
||||
return result;
|
||||
}
|
||||
}
|
||||
std::optional<std::string> get_disk()
|
||||
{
|
||||
if (auto conn = connect(); !conn) return {};
|
||||
else if
|
||||
(
|
||||
auto result =
|
||||
conn->get_all<DiskData>(sqlite_orm::order_by(&DiskData::Id).desc(), sqlite_orm::limit(1));
|
||||
result.size() != 1
|
||||
)
|
||||
return {};
|
||||
else return result[0].Data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,15 @@ int main()
|
||||
{
|
||||
int vasp_version_selected = 0;
|
||||
std::vector<std::string> vasp_version_entries = { "std", "gam", "ncl" };
|
||||
int device_selected = 0;
|
||||
std::vector<std::string> device_entries = []
|
||||
{
|
||||
std::vector<std::string> devices(Device.GpuIds.size() + 2);
|
||||
for (std::size_t i = 0; i < Device.GpuIds.size(); ++i)
|
||||
devices[i + 1] = Device.GpuIds[i];
|
||||
devices[0] = "any single GPU";
|
||||
devices.back() = "CPU";
|
||||
return devices;
|
||||
}();
|
||||
int device_type_selected = 0;
|
||||
std::vector<std::string> device_type_entries = { "any single GPU", "manually select GPU", "CPU" };
|
||||
std::deque<bool> device_selected = std::deque<bool>(Device.GpuIds.size(), false);
|
||||
std::vector<std::string> device_entries = Device.GpuIds;
|
||||
std::string job_name = std::filesystem::current_path().filename().string();
|
||||
std::string output_file = "output.txt";
|
||||
std::string mpi_threads = std::to_string(Device.CpuMpiThreads);
|
||||
std::string openmp_threads = std::to_string(Device.CpuOpenmpThreads);
|
||||
|
||||
std::string user_command;
|
||||
std::string submit_command;
|
||||
} state;
|
||||
@@ -45,6 +44,12 @@ int main()
|
||||
auto empty = ftxui::emptyElement() | ftxui::flex_grow;
|
||||
return ftxui::vbox(empty, ftxui::hbox(empty, element | ftxui::center, empty), empty);
|
||||
};
|
||||
// 在组件左边增加分割线
|
||||
auto with_separator = [](ftxui::Element element)
|
||||
{ return ftxui::hbox(ftxui::separatorLight(), element); };
|
||||
// 在组件左边增加小标题
|
||||
auto with_subtitle = [](std::string title)
|
||||
{ return [title](ftxui::Element element) { return ftxui::hbox(ftxui::text(title), element); }; };
|
||||
|
||||
// 构建界面
|
||||
auto screen = ftxui::ScreenInteractive::Fullscreen();
|
||||
@@ -52,8 +57,36 @@ int main()
|
||||
({
|
||||
ftxui::Menu(&state.vasp_version_entries, &state.vasp_version_selected)
|
||||
| with_title("Select VASP version:"),
|
||||
ftxui::Menu(&state.device_entries, &state.device_selected)
|
||||
| with_title("Select device:"),
|
||||
ftxui::Container::Horizontal
|
||||
({
|
||||
ftxui::Menu(&state.device_type_entries, &state.device_type_selected),
|
||||
ftxui::Container::Vertical([&]
|
||||
{
|
||||
std::vector<std::shared_ptr<ftxui::ComponentBase>> devices;
|
||||
auto checkbox_option = ftxui::CheckboxOption::Simple();
|
||||
checkbox_option.transform = [](const ftxui::EntryState& s)
|
||||
{
|
||||
auto prefix = ftxui::text(s.state ? "[X] " : "[ ] ");
|
||||
auto t = ftxui::text(s.label);
|
||||
if (s.active) t |= ftxui::bold;
|
||||
if (s.focused) t |= ftxui::inverted;
|
||||
return ftxui::hbox({prefix, t});
|
||||
};
|
||||
for (int i = 0; i < state.device_selected.size(); i++)
|
||||
devices.push_back(ftxui::Checkbox
|
||||
(state.device_entries[i], &state.device_selected[i], checkbox_option));
|
||||
return devices;
|
||||
}()) | with_separator | ftxui::Maybe([&]{ return state.device_type_selected == 1; }),
|
||||
ftxui::Container::Vertical
|
||||
({
|
||||
ftxui::Input(&state.mpi_threads) | ftxui::size(ftxui::WIDTH, ftxui::GREATER_THAN, 3)
|
||||
| with_subtitle("MPI threads: "),
|
||||
ftxui::Input(&state.openmp_threads) | ftxui::size(ftxui::WIDTH, ftxui::GREATER_THAN, 3)
|
||||
| with_subtitle("OpenMP threads: ")
|
||||
}) | with_separator | ftxui::Maybe([&]{ return state.device_type_selected == 2; }),
|
||||
}) | with_title("Select device:"),
|
||||
ftxui::Input(&state.job_name) | with_title("Job name:"),
|
||||
ftxui::Input(&state.output_file) | with_title("Output file:"),
|
||||
ftxui::Container::Horizontal
|
||||
({
|
||||
ftxui::Button("Continue",
|
||||
@@ -90,35 +123,37 @@ int main()
|
||||
while (true)
|
||||
{
|
||||
screen.Loop(request_interface);
|
||||
if (state.user_command == "quit")
|
||||
return EXIT_FAILURE;
|
||||
else if (state.user_command != "continue")
|
||||
throw std::runtime_error("user_command is not recognized");
|
||||
else if (state.device_selected < 0 || state.device_selected >= state.device_entries.size())
|
||||
throw std::runtime_error("device_selected is out of range");
|
||||
else if (state.device_selected == 0) state.submit_command =
|
||||
"sbatch --ntasks=1\n--gpus=1\n--job-name='{}'\n--output=output.txt\nvasp-nvidia-{}"_f
|
||||
(std::filesystem::current_path().filename().string(), state.vasp_version_entries[state.vasp_version_selected]);
|
||||
else if (state.device_selected == state.device_entries.size() - 1) state.submit_command =
|
||||
"sbatch --ntasks={}\n--cpus-per-task={}\n--hint=nomultithread\n--job-name='{}'\n--output=output.txt"
|
||||
if (state.user_command == "quit") return EXIT_FAILURE;
|
||||
else if (state.device_type_selected == 0)
|
||||
state.submit_command =
|
||||
"sbatch --ntasks=1\n--gpus=1\n--job-name='{}'\n--output='{}'\nvasp-nvidia-{}"_f
|
||||
(state.job_name, state.output_file, state.vasp_version_entries[state.vasp_version_selected]);
|
||||
else if (state.device_type_selected == 2)
|
||||
state.submit_command =
|
||||
"sbatch --ntasks={}\n--cpus-per-task={}\n--hint=nomultithread\n--job-name='{}'\n--output='{}'"
|
||||
"\nvasp-intel-{}"_f
|
||||
(
|
||||
Device.CpuMpiThreads, Device.CpuOpenmpThreads, std::filesystem::current_path().filename().string(),
|
||||
state.vasp_version_entries[state.vasp_version_selected]
|
||||
);
|
||||
else state.submit_command =
|
||||
"sbatch --ntasks=1\n--gpus={}:1\n--job-name='{}'\n--output=output.txt\nvasp-nvidia-{}"_f
|
||||
(
|
||||
state.device_entries[state.device_selected], std::filesystem::current_path().filename().string(),
|
||||
state.vasp_version_entries[state.vasp_version_selected]
|
||||
);
|
||||
(
|
||||
state.mpi_threads, state.openmp_threads, state.job_name, state.output_file,
|
||||
state.vasp_version_entries[state.vasp_version_selected]
|
||||
);
|
||||
else
|
||||
{
|
||||
std::vector<std::string> selected_gpus;
|
||||
for (int i = 0; i < state.device_selected.size(); i++)
|
||||
if (state.device_selected[i]) selected_gpus.push_back(state.device_entries[i]);
|
||||
state.submit_command =
|
||||
"sbatch --ntasks={}\n--gres={}\n--job-name='{}'\n--output='{}'\nvasp-nvidia-{}"_f
|
||||
(
|
||||
selected_gpus.size(),
|
||||
selected_gpus
|
||||
| ranges::views::transform([](auto& entry) { return "gpu:{}:1"_f(entry); })
|
||||
| ranges::views::join(',') | ranges::to<std::string>,
|
||||
state.job_name, state.output_file, state.vasp_version_entries[state.vasp_version_selected]
|
||||
);
|
||||
}
|
||||
screen.Loop(confirm_interface);
|
||||
if (state.user_command == "quit")
|
||||
return EXIT_FAILURE;
|
||||
else if (state.user_command == "back")
|
||||
continue;
|
||||
else if (state.user_command != "submit")
|
||||
throw std::runtime_error("user_command is not recognized");
|
||||
if (state.user_command == "quit") return EXIT_FAILURE;
|
||||
else if (state.user_command == "back") continue;
|
||||
submit(state.submit_command);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ inputs:
|
||||
topInputs.impermanence.nixosModules.impermanence
|
||||
topInputs.nix-flatpak.nixosModules.nix-flatpak
|
||||
topInputs.chaotic.nixosModules.default
|
||||
{ config.chaotic.nyx.overlay.onTopOf = "user-pkgs"; }
|
||||
topInputs.catppuccin.nixosModules.catppuccin
|
||||
(inputs:
|
||||
{
|
||||
|
||||
@@ -64,8 +64,12 @@ inputs:
|
||||
dynamicBoost.enable = inputs.lib.mkIf gpu.nvidia.dynamicBoost true;
|
||||
nvidiaSettings = true;
|
||||
forceFullCompositionPipeline = true;
|
||||
package = inputs.config.boot.kernelPackages.nvidiaPackages.${gpu.nvidia.driver};
|
||||
package =
|
||||
let actualDriver = { production = "legacy_535"; }.${gpu.nvidia.driver} or gpu.nvidia.driver;
|
||||
in inputs.config.boot.kernelPackages.nvidiaPackages.${actualDriver};
|
||||
prime.allowExternalGpu = true;
|
||||
# nvidia 555 package have some bug, should use open
|
||||
open = inputs.lib.mkIf (gpu.nvidia.driver == "beta") true;
|
||||
};
|
||||
};
|
||||
boot =
|
||||
|
||||
@@ -9,7 +9,8 @@ inputs:
|
||||
_packages =
|
||||
[
|
||||
# system management
|
||||
btrfs-assistant snapper-gui kdePackages.qtstyleplugin-kvantum ventoy-full cpu-x # etcher
|
||||
btrfs-assistant snapper-gui kdePackages.qtstyleplugin-kvantum ventoy-full cpu-x
|
||||
inputs.pkgs."pkgs-23.11".etcher
|
||||
# password and key management
|
||||
yubikey-manager yubikey-manager-qt yubikey-personalization yubikey-personalization-gui bitwarden
|
||||
# download
|
||||
|
||||
@@ -26,11 +26,12 @@ inputs:
|
||||
# media
|
||||
mpv nomacs
|
||||
# themes
|
||||
tela-circle-icon-theme localPackages.win11os-kde localPackages.fluent-kde localPackages.blurred-wallpaper
|
||||
localPackages.win11os-kde localPackages.fluent-kde localPackages.blurred-wallpaper
|
||||
localPackages.slate utterly-nord-plasma utterly-round-plasma-style catppuccin catppuccin-sddm
|
||||
catppuccin-cursors catppuccinifier-gui catppuccinifier-cli catppuccin-plymouth
|
||||
(catppuccin-kde.override { flavour = [ "latte" ]; })
|
||||
(catppuccin-gtk.override { variant = "latte"; })
|
||||
(tela-circle-icon-theme.override { allColorVariants = true; })
|
||||
# terminal
|
||||
warp-terminal
|
||||
# development
|
||||
|
||||
@@ -26,11 +26,7 @@ inputs:
|
||||
])];
|
||||
};
|
||||
};
|
||||
programs =
|
||||
{
|
||||
yazi.enable = true;
|
||||
mosh.enable = true;
|
||||
};
|
||||
programs.yazi.enable = true;
|
||||
services.fwupd.enable = true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ inputs:
|
||||
[
|
||||
# basic tools
|
||||
beep dos2unix gnugrep pv tmux screen parallel tldr cowsay jq zellij ipfetch localPackages.pslist
|
||||
fastfetch reptyr nushellFull duc
|
||||
fastfetch reptyr nushellFull duc ncdu progress
|
||||
# lsxx
|
||||
pciutils usbutils lshw util-linux lsof dmidecode lm_sensors
|
||||
# top
|
||||
@@ -43,6 +43,7 @@ inputs:
|
||||
command-not-found.enable = false;
|
||||
autojump.enable = true;
|
||||
direnv = { enable = true; nix-direnv.enable = true; };
|
||||
mosh.enable = true;
|
||||
};
|
||||
services.udev.packages = with inputs.pkgs; [ yubikey-personalization libfido2 ];
|
||||
home-manager = { useGlobalPkgs = true; useUserPackages = true; };
|
||||
|
||||
137
modules/packages/ssh.nix
Normal file
137
modules/packages/ssh.nix
Normal file
@@ -0,0 +1,137 @@
|
||||
inputs:
|
||||
{
|
||||
config = inputs.lib.mkIf (builtins.elem "server" inputs.config.nixos.packages._packageSets)
|
||||
{
|
||||
services.openssh.knownHosts =
|
||||
let servers =
|
||||
{
|
||||
vps6 =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIO5ZcvyRyOnUCuRtqrM/Qf+AdUe3a5bhbnfyhw2FSLDZ";
|
||||
hostnames = [ "vps6.chn.moe" "wireguard.vps6.chn.moe" "74.211.99.69" "192.168.83.1" ];
|
||||
};
|
||||
"initrd.vps6" =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIB4DKB/zzUYco5ap6k9+UxeO04LL12eGvkmQstnYxgnS";
|
||||
hostnames = [ "initrd.vps6.chn.moe" "74.211.99.69" ];
|
||||
};
|
||||
vps7 =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIF5XkdilejDAlg5hZZD0oq69k8fQpe9hIJylTo/aLRgY";
|
||||
hostnames = [ "vps7.chn.moe" "wireguard.vps7.chn.moe" "ssh.git.chn.moe" "95.111.228.40" "192.168.83.2" ];
|
||||
};
|
||||
"initrd.vps7" =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIGZyQpdQmEZw3nLERFmk2tS1gpSvXwW0Eish9UfhrRxC";
|
||||
hostnames = [ "initrd.vps7.chn.moe" "95.111.228.40" ];
|
||||
};
|
||||
nas =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIIktNbEcDMKlibXg54u7QOLt0755qB/P4vfjwca8xY6V";
|
||||
hostnames = [ "wireguard.nas.chn.moe" "[office.chn.moe]:5440" "192.168.1.185" "192.168.83.4" ];
|
||||
};
|
||||
"initrd.nas" =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIAoMu0HEaFQsnlJL0L6isnkNZdRq0OiDXyaX3+fl3NjT";
|
||||
hostnames = [ "initrd.nas.chn.moe" "[office.chn.moe]:5440" "192.168.1.185" ];
|
||||
};
|
||||
surface =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIFdm3DcfHdcLP0oSpVrWwIZ/b9lZuakBSPwCFz2BdTJ7";
|
||||
hostnames = [ "192.168.1.166" "wireguard.surface.chn.moe" "192.168.83.5" ];
|
||||
};
|
||||
pc =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIMSfREi19OSwQnhdsE8wiNwGSFFJwNGN0M5gN+sdrrLJ";
|
||||
hostnames = [ "wireguard.pc.chn.moe" "[office.chn.moe]:3673" "192.168.1.105" "192.168.83.3" ];
|
||||
};
|
||||
hpc =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIDVpsQW3kZt5alHC6mZhay3ZEe2fRGziG4YJWCv2nn/O";
|
||||
hostnames = [ "hpc.xmu.edu.cn" ];
|
||||
};
|
||||
github =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
|
||||
hostnames = [ "github.com" ];
|
||||
};
|
||||
xmupc1 =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAINTvfywkKRwMrVp73HfHTfjhac2Tn9qX/lRjLr09ycHp";
|
||||
hostnames = [ "[office.chn.moe]:6007" "[xmupc1.chn.moe]:6007" "wireguard.xmupc1.chn.moe" "192.168.83.6" ];
|
||||
};
|
||||
xmupc2 =
|
||||
{
|
||||
ed25519 = "AAAAC3NzaC1lZDI1NTE5AAAAIJZ/+divGnDr0x+UlknA84Tfu6TPD+zBGmxWZY4Z38P6";
|
||||
hostnames = [ "[xmupc2.chn.moe]:6394" "wireguard.xmupc2.chn.moe" "192.168.83.7" ];
|
||||
};
|
||||
};
|
||||
in builtins.listToAttrs (builtins.map
|
||||
(server:
|
||||
{
|
||||
inherit (server) name;
|
||||
value =
|
||||
{
|
||||
publicKey = "ssh-ed25519 ${server.value.ed25519}";
|
||||
hostNames = server.value.hostnames;
|
||||
};
|
||||
})
|
||||
(inputs.localLib.attrsToList servers));
|
||||
programs.ssh =
|
||||
{
|
||||
startAgent = true;
|
||||
enableAskPassword = true;
|
||||
askPassword = "${inputs.pkgs.systemd}/bin/systemd-ask-password";
|
||||
extraConfig = "AddKeysToAgent yes";
|
||||
};
|
||||
environment.sessionVariables.SSH_ASKPASS_REQUIRE = "prefer";
|
||||
nixos.user.sharedModules =
|
||||
[(hmInputs: {
|
||||
config.programs.ssh =
|
||||
{
|
||||
enable = true;
|
||||
controlMaster = "auto";
|
||||
controlPersist = "1m";
|
||||
compression = true;
|
||||
matchBlocks = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(host: { name = host; value = { inherit host; hostname = "${host}.chn.moe"; }; })
|
||||
[ "vps6" "wireguard.vps6" "vps7" "wireguard.vps7" "wireguard.nas" ])
|
||||
++ (builtins.map
|
||||
(host: { name = host; value = { inherit host; hostname = "${host}.chn.moe"; forwardX11 = true; }; })
|
||||
[ "wireguard.pc" "wireguard.surface" "wireguard.xmupc1" "wireguard.xmupc2" ])
|
||||
++ (builtins.map
|
||||
(host:
|
||||
{
|
||||
name = host;
|
||||
value =
|
||||
{
|
||||
host = host;
|
||||
hostname = "hpc.xmu.edu.cn";
|
||||
user = host;
|
||||
setEnv.TERM = "chn_unset_ls_colors:xterm-256color";
|
||||
};
|
||||
})
|
||||
[ "wlin" "hwang" ])
|
||||
)
|
||||
// {
|
||||
xmupc1 = { host = "xmupc1"; hostname = "xmupc1.chn.moe"; port = 6007; forwardX11 = true; };
|
||||
xmupc2 = { host = "xmupc2"; hostname = "xmupc2.chn.moe"; port = 6394; forwardX11 = true; };
|
||||
nas = { host = "nas"; hostname = "office.chn.moe"; port = 5440; };
|
||||
pc = { host = "pc"; hostname = "office.chn.moe"; port = 3673; forwardX11 = true; };
|
||||
surface = { host = "surface"; hostname = "192.168.1.166"; forwardX11 = true; };
|
||||
gitea = { host = "gitea"; hostname = "ssh.git.chn.moe"; };
|
||||
jykang =
|
||||
{
|
||||
host = "jykang";
|
||||
hostname = "hpc.xmu.edu.cn";
|
||||
user = "jykang";
|
||||
forwardAgent = true;
|
||||
extraOptions.AddKeysToAgent = "yes";
|
||||
};
|
||||
};
|
||||
};
|
||||
})];
|
||||
};
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
inputs:
|
||||
{
|
||||
config = inputs.lib.mkIf (builtins.elem "server" inputs.config.nixos.packages._packageSets)
|
||||
{
|
||||
services.openssh.knownHosts =
|
||||
let
|
||||
servers =
|
||||
{
|
||||
vps6 =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO5ZcvyRyOnUCuRtqrM/Qf+AdUe3a5bhbnfyhw2FSLDZ";
|
||||
hostnames = [ "vps6.chn.moe" "wireguard.vps6.chn.moe" "74.211.99.69" "192.168.83.1" ];
|
||||
};
|
||||
"initrd.vps6" =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB4DKB/zzUYco5ap6k9+UxeO04LL12eGvkmQstnYxgnS";
|
||||
hostnames = [ "initrd.vps6.chn.moe" "74.211.99.69" ];
|
||||
};
|
||||
vps7 =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF5XkdilejDAlg5hZZD0oq69k8fQpe9hIJylTo/aLRgY";
|
||||
hostnames = [ "vps7.chn.moe" "wireguard.vps7.chn.moe" "ssh.git.chn.moe" "95.111.228.40" "192.168.83.2" ];
|
||||
};
|
||||
"initrd.vps7" =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGZyQpdQmEZw3nLERFmk2tS1gpSvXwW0Eish9UfhrRxC";
|
||||
hostnames = [ "initrd.vps7.chn.moe" "95.111.228.40" ];
|
||||
};
|
||||
nas =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIktNbEcDMKlibXg54u7QOLt0755qB/P4vfjwca8xY6V";
|
||||
hostnames = [ "wireguard.nas.chn.moe" "[office.chn.moe]:5440" "192.168.1.185" "192.168.83.4" ];
|
||||
};
|
||||
"initrd.nas" =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAoMu0HEaFQsnlJL0L6isnkNZdRq0OiDXyaX3+fl3NjT";
|
||||
hostnames = [ "initrd.nas.chn.moe" "[office.chn.moe]:5440" "192.168.1.185" ];
|
||||
};
|
||||
surface =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdm3DcfHdcLP0oSpVrWwIZ/b9lZuakBSPwCFz2BdTJ7";
|
||||
hostnames = [ "192.168.1.166" "wireguard.surface.chn.moe" "192.168.83.5" ];
|
||||
};
|
||||
pc =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMSfREi19OSwQnhdsE8wiNwGSFFJwNGN0M5gN+sdrrLJ";
|
||||
hostnames = [ "wireguard.pc.chn.moe" "[office.chn.moe]:3673" "192.168.1.105" "192.168.83.3" ];
|
||||
};
|
||||
hpc =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDVpsQW3kZt5alHC6mZhay3ZEe2fRGziG4YJWCv2nn/O";
|
||||
hostnames = [ "hpc.xmu.edu.cn" ];
|
||||
};
|
||||
github =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
|
||||
hostnames = [ "github.com" ];
|
||||
};
|
||||
xmupc1 =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINTvfywkKRwMrVp73HfHTfjhac2Tn9qX/lRjLr09ycHp";
|
||||
hostnames = [ "[office.chn.moe]:6007" "[xmupc1.chn.moe]:6007" "wireguard.xmupc1.chn.moe" "192.168.83.6" ];
|
||||
};
|
||||
xmupc2 =
|
||||
{
|
||||
ed25519 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJZ/+divGnDr0x+UlknA84Tfu6TPD+zBGmxWZY4Z38P6";
|
||||
hostnames = [ "[xmupc2.chn.moe]:6394" "wireguard.xmupc2.chn.moe" "192.168.83.7" ];
|
||||
};
|
||||
};
|
||||
in builtins.listToAttrs (builtins.concatLists (builtins.map
|
||||
(server:
|
||||
(
|
||||
if builtins.pathExists ./ssh/${server.name}_rsa.pub then
|
||||
[{
|
||||
name = "${server.name}-rsa";
|
||||
value =
|
||||
{
|
||||
publicKey = builtins.readFile ./ssh/${server.name}_rsa.pub;
|
||||
hostNames = server.value.hostnames;
|
||||
};
|
||||
}]
|
||||
else []
|
||||
)
|
||||
++ (
|
||||
if builtins.pathExists ./ssh/${server.name}_ecdsa.pub then
|
||||
[{
|
||||
name = "${server.name}-ecdsa";
|
||||
value =
|
||||
{
|
||||
publicKey = builtins.readFile ./ssh/${server.name}_ecdsa.pub;
|
||||
hostNames = server.value.hostnames;
|
||||
};
|
||||
}]
|
||||
else []
|
||||
)
|
||||
++ (
|
||||
if server.value ? ed25519 then
|
||||
[{
|
||||
name = "${server.name}-ed25519";
|
||||
value =
|
||||
{
|
||||
publicKey = server.value.ed25519;
|
||||
hostNames = server.value.hostnames;
|
||||
};
|
||||
}]
|
||||
else []
|
||||
))
|
||||
(inputs.localLib.attrsToList servers)));
|
||||
programs.ssh =
|
||||
{
|
||||
startAgent = true;
|
||||
enableAskPassword = true;
|
||||
askPassword = "${inputs.pkgs.systemd}/bin/systemd-ask-password";
|
||||
extraConfig = "AddKeysToAgent yes";
|
||||
};
|
||||
environment.sessionVariables.SSH_ASKPASS_REQUIRE = "prefer";
|
||||
nixos.user.sharedModules =
|
||||
[(hmInputs: {
|
||||
config.programs.ssh =
|
||||
{
|
||||
enable = true;
|
||||
controlMaster = "auto";
|
||||
controlPersist = "1m";
|
||||
compression = true;
|
||||
matchBlocks = builtins.listToAttrs
|
||||
(
|
||||
(builtins.map
|
||||
(host: { name = host; value = { inherit host; hostname = "${host}.chn.moe"; }; })
|
||||
[
|
||||
"vps6" "wireguard.vps6" "vps7" "wireguard.vps7" "wireguard.pc" "wireguard.nas" "wireguard.surface"
|
||||
"wireguard.xmupc1" "wireguard.xmupc2"
|
||||
])
|
||||
++ (builtins.map
|
||||
(host:
|
||||
{
|
||||
name = host;
|
||||
value =
|
||||
{
|
||||
host = host;
|
||||
hostname = "hpc.xmu.edu.cn";
|
||||
user = host;
|
||||
setEnv.TERM = "chn_unset_ls_colors:xterm-256color";
|
||||
};
|
||||
})
|
||||
[ "wlin" "hwang" ])
|
||||
)
|
||||
// {
|
||||
xmupc1 = { host = "xmupc1"; hostname = "xmupc1.chn.moe"; port = 6007; };
|
||||
xmupc2 = { host = "xmupc2"; hostname = "xmupc2.chn.moe"; port = 6394; };
|
||||
nas = { host = "nas"; hostname = "office.chn.moe"; port = 5440; };
|
||||
pc = { host = "pc"; hostname = "office.chn.moe"; port = 3673; };
|
||||
surface = { host = "surface"; hostname = "192.168.1.166"; };
|
||||
gitea = { host = "gitea"; hostname = "ssh.git.chn.moe"; };
|
||||
jykang =
|
||||
{
|
||||
host = "jykang";
|
||||
hostname = "hpc.xmu.edu.cn";
|
||||
user = "jykang";
|
||||
forwardAgent = true;
|
||||
extraOptions.AddKeysToAgent = "yes";
|
||||
};
|
||||
};
|
||||
};
|
||||
})];
|
||||
};
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
|
||||
@@ -1 +0,0 @@
|
||||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDkkl7A9kWWBoi4b5g6Vus70ja1KhPfcZZjeU1/QbYdN8PRRw/hsGklrhefslKRbym/TMFS0ko0g5WUi9G5vbGw=
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgs8MvV2nczjGMZ548tuAhgvCEd4uHu0VhLDSwQG7Nh/UR4Pgc5T9Nf7Vfwg96Lah/pwD5my4RaWis6bLMmlkYyDBKFBOsGYQUe5J5XfZdxk8pz+7L0Hq6gPfAZAdNlUiuFVKsvkE+NF42NgJyXSYQicPbu5LQiFwZGXlW20+LO8uBQ1y1xabKVpg8XGwordduL99VepwEzeLK/st+UVfW+mKgxkf9TuxvD2fuYIDZM7y2rXqcjf4/6OXA5kACsYK1MgZSFxgO/m6+1uCC1qBDseMTA3D+Tsjf9VtcqUE9dMd/dJ/uuILHJ0+oIqkykTCecPLgJY3Vh8rAtln/lbId
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC0+xafJMnOGCHv6OLljaq8iJ3ZBaIezv7AJ9rVWJXFg/QJRYBwct35c4zaVom7If8F+Ss+BTLMp33HZ8gLpoat6LkjARjy65Ycog3NOnEposX2JjZEYXDbovxEmcJkDXAIVmnaBUi3r22z4UI8OqsHPeRXj017O0yQrQQYEAw/IO/tSNQZt2k8JHxAX50UTqGFdgkriO1fYHBocq48m0nn3sXrMuM3yBe5zy3NngOHxMn7UxjECmAElsuu/nu1x083pRnv5NSa+JxDGJ+S6Zhj3nGGNwZesa51I4cJjsYLxgmO/NxL1J86bDp6HhK9C9799ruG60pGTw6HcvbKTgx7klUgn4936wsy7qukWqp53MvqrLSJkRb/HHU9zZqvzcjbwet+Iv1OAAok5QC88j7Jgenk3nbZw4BNFd2r/8rOZuXheDnMKOa61dXxnvoAO3Euk0RPdZqW1slT/DDyD/kB6TPY7yOywNURNnrwzfSsmravKi6bGA5t2Ehhpf2LETM=
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDOyU7VvusseL2tDp7JkIXKGxRGQNHpYWVAPraUj17Xls7Z9e7HO6+GBiGP+bB9tZbzsoTNGHdXg8VaJmf98QAhhg0FcUb6IvWmfmPWzQ0MC8L+USqdDpaH7s9SOZF/yveNYCR5GOMmFdSW4OPVYIOrjPltDIe5S1SN2nOXvjxbLmuoMjg+5U4F0ii0ZaCRuMVDskeift+Amxe7iRnSzeDbECd0rJhaUb8gf3shz0Hp9lRUMej7cJH8LLP3m0s3Vk+kasKntz18MpJ6/3n+fR2aK75qkcq9FZaFA4tSIabh9eKoxlRCy7g8Qj6nNStW+ys/a1UYBFgAoTyE7e47o3dpcxR5oMLbeDwhOstWL0YOjEH1K5Wyj3eEOT71C6kuQBPcCJQ9q9hknRpW0mWe9Q6qaAzTgE9LLssijr/yTfYQk7zKEyo0i4f6buOfmyYZfnzfnCB3LiJKa98TVEEzrKYHIO44LwIkNf/YHOMDknzjYpav6HfDy+AebRHZFYhGax1YP/tP0Ve/FSq5rh6Vwuqa/zyfFUPZmZVf+EYXK7DdyuBhEZhBEu6QrjY60NRMTMLpnUZMcZXRAz9byMpAGcCYQv6gjU99ps8AkRjZNkn+FpAtDGT+oJxixQwyZMSxZ+ZuzkZGyBMeMplZXMMLICGZ2LRAgT0bxXLZUxHJBLwwnw==
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDJAyDl52UVGFPTV/rXFERrXAMY5qZ3g+tpg9HOGdw86G4Nr8Xp/cTxZjF4kSfIkSrGblAV9Lm4US0fW3pGOQu5qQrSAENxqHxdlEyzt7izyF2CklDUeTjs3KHOIZMvSli4z014NPcswBbjwB9Lyrw0fCQ9P1vYkrUHEzL2SMxdack1EQPcMF4MxblDqc+eQhdMCkKE8T1Cb1ZqxeLVMPn9CwjG18JoxL+/xs+MjcsSXYWcoqYTfgfhguMbh0D4Eo32MHS/IzRSxnOHJxhG5xYePcyBlb/CxQuYA+RTqKNE85j7GcL2oEmeZ1b++/9qFT9grwVh+UOBRO2xiMzKDF24nXPJ+eLyd6Z/3swGT4rTVDnrXV5eZUkWLHN093IdLJCTtPVrKV9OxEKr5sU2W0edpirNrlGq7/MYkJX9EbQctDFA69XfQkZlGK9xGutqSgEaVlY54fS0Due+NDrNBPfMKJ9MTmFDOY+NYn05El2rMD39OKbGbCR5ASwSSBlcQeE=
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDYiP+ELuG5KTmafVjBkY0ZSggJg+mDkvZpF8d7NljMst0YwKWV3IgHnkAGXdTd7jlRgm9HH6oc8rP2R6Q8EJmfr+xcL1IQIWKuYAoddHlpe2Ds4EE74xbgm5Elf7FpdYNHUH9XyVmMmIhVSpLw2N10jUhvYqw+h+xC2nObEKZuBOt/lqrTGbC/EMv3+sDv0ApBh8lKt2yfjt88pnAj1LKPANDgIYSyQOllHQWeUY/eD/5Qc9XWR3uWclslVaxriRmEA0sNZlOFCeRIyDbYpSzQBdcnojkwt7Z5kjhaqGlT9g00fdiqO0OMaeY/G8ki3QxqjONqTEDqK+DpEZFO6jyZARcY6ki0ANc0AO4qosEC3gEbAvVwyPwDFtyDggMTHlTzaw8iakMGSDEk10zKaUOgZYLzC2yCWYYQS5mae9wC1gkXIGD51/laeq2E7NpM+nha6kp9weLVyvwf0DLfwsiP+0qlCLrxBLTSRa0HQ+BnQMi4r16Ss7YJwLf/oXrbOVk=
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDFwb7qi9/DvhpMvu43LRlTEC+3kPAA0KNeyk4FT4HlpRE/yxMxN6tgrP9vcx2c6TMfkRwIJKDcBuVVtKOVx+SDZo+nQBxpSz73v1qSmqlsy8D4gCk0a7cLgStb3Cvh0UZjJ5nVnxjzqY2CFnpnKYGmxL+a3qTj1KYPuA2wSsxkYVcHUfDj/uTtEDdRPaNTACsUxe1a57T/Tsjp+321+zKldYreozaABEBsexf9Z34+3vZvyQcfDB3QuxlBRPJBLik80QllpNpE1bqol8swoGEPbl/Ac7tNy+GtlwTG9SH1povmoT9K+8tjJaG2pD+z+vvgZQtJQh+aczYmEBJRZp3ksw1JH4eGqTWG/SDat9Isnx2NDhJe12b9izniDciuBScNySAazIDPidsCMUYjc9kgWdSOiODOtodj5IB+KazFVJgfpmzPv97LHVdjvR74usrgbFw2mYCw2YEiL3xjDYpQGmXSNklsQLwJiBe59oyS4QNpNYQzYD9StjgRIdvtmiM=
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDVbOvoFVaGkqYzIWsmMFlpkE+TDAONOWWaJBQ0K4fiOLy7uh02b/jYNZrbllPDP+Gq+ikYEJnJX2ceDsh9mLtJTznBQXgJOMUZDYy0enu7hYLKMmRTgJntzHjMbZENMhP+I3N9JnQ1PQz7lICg1xkEBQm2CESYCCjo0rJKYplPH1bo02myEazKlKTn6tu40ysrYOoJO8+jwbUDqtWATjSZtgYojuh6dbIoK3O+Ntgwl4W0NqXEqXYXTWpU0qKOqAsP/9F9WJ5d1wVNNbvmcAJ26dkYaiPCNgW4MGTucAgoxM6IPVVj9U+OEZLoCPsqAGCT02vH5MoDNTmGaSv0DjuYOzz5C+jAhMCznXFXCI4bfawvuda/WwGIniB5iKNSBZt3XxYyUw4YBcVCNiWUt9bIgEvnR4E8HYHdjNrbQ0Z58L6DcPSySLQer7C658Vo/nRUlBq6lIWYhcdjxHHkP9iFtuFW1HmoUKkuaLl+uiflrSppX9wt8eaPwGgGIHkLwgc=
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCa7ZRmIAtuGd58MQXnJnPqmad+6u8JiBKb7+xEfMmVdeVtJ5lEfXCkZ0vbSMxnGZCLL3eVxdejaGToLw+ArEJ1cl6KzZdsdGy1wATFtJj4oYHtZ/MXg+qulNR4nQ6DGWfGR7FEXjZNaJfVuLBFBmUlsbotBdhaAJzw5+nnIxY5d86nfqzsYstMqB/1ZHLRTV9h/jp8XNgnUu1BR/oVk4eMvzTUbr42LedeB1anLnI0+ycAzol/XMpsUNuRLVhYhMbg9rpyoZF1WMBTjG2Jnv9JtCpJlnZaOjzh3eD8PBuyZtGyya7QxVkhH4ULUMNnuyi8E0IOJwdN4cQi61fa7rLtsYfUrN2w0nI/WRLiBxiuPbvq4tKeHi8DpM/MrUbZONY2eFo4CaX9sxYN6U65jDfsbK3x6Za0HhVt8zcPLGgESm4Y6O8YTQrdbpL1ifNFX2Y9B++FQw2iRoqa6U0Wrs6SfVQFp1RqnqSl6fLOCixl16PpHWqRilweKbg3uIMEqEc=
|
||||
@@ -58,6 +58,8 @@ inputs:
|
||||
yutengjing.open-in-external-app
|
||||
# ChatGPT-like plugin
|
||||
codeium.codeium
|
||||
# git graph
|
||||
mhutchie.git-graph
|
||||
];
|
||||
}
|
||||
)];
|
||||
|
||||
@@ -28,7 +28,8 @@ inputs:
|
||||
appflowy notion-app-enhanced joplin-desktop standardnotes logseq
|
||||
# math, physics and chemistry
|
||||
(mathematica.overrideAttrs (prev: { postInstall = prev.postInstall or "" + "ln -s ${src} $out/src"; }))
|
||||
paraview jmol mpi # quantum-espresso # localPackages.mumax
|
||||
(quantum-espresso.override { stdenv = gcc14Stdenv; gfortran = gfortran14; })
|
||||
paraview jmol mpi localPackages.mumax
|
||||
# encryption and password management
|
||||
john crunch hashcat
|
||||
# container and vm
|
||||
|
||||
@@ -77,7 +77,7 @@ inputs:
|
||||
{
|
||||
finishjob = "*-*-* *:*:00";
|
||||
backupdb = "*-*-* *:00/10:00";
|
||||
diskstat = "*-*-* 03:00:00";
|
||||
diskstat = "*-*-* 03/12:00:00";
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
@@ -13,14 +13,14 @@ inputs:
|
||||
{
|
||||
virtualisation.oci-containers.containers.huginn =
|
||||
{
|
||||
image = "huginn/huginn:2d5fcafc507da3e8c115c3479e9116a0758c5375";
|
||||
image = "huginn/huginn:5a1509b51188e0d16868be893c983d6fcfd232a5";
|
||||
imageFile = inputs.pkgs.dockerTools.pullImage
|
||||
{
|
||||
imageName = "ghcr.io/huginn/huginn";
|
||||
imageDigest = "sha256:aa694519b196485c6c31582dde007859fc8b8bbe9b1d4d94c6db8558843d0458";
|
||||
sha256 = "0471v20d7ilwx81kyrxjcb90nnmqyyi9mwazbpy3z4rhnzv7pz76";
|
||||
imageDigest = "sha256:6f7a5b41457b94490210221a8bd3aae32d4ebfc2652f97c14919aa8036d7294e";
|
||||
sha256 = "1ha6c6bwdpdl98cwwxw5fan0j77ylgaziidqhnyh6anpzq35f540";
|
||||
finalImageName = "huginn/huginn";
|
||||
finalImageTag = "2d5fcafc507da3e8c115c3479e9116a0758c5375";
|
||||
finalImageTag = "5a1509b51188e0d16868be893c983d6fcfd232a5";
|
||||
};
|
||||
ports = [ "127.0.0.1:3000:3000/tcp" ];
|
||||
extraOptions = [ "--add-host=host.docker.internal:host-gateway" ];
|
||||
|
||||
@@ -36,5 +36,8 @@ inputs:
|
||||
sops.secrets = builtins.listToAttrs (builtins.map
|
||||
(server: { name = "redis/${server.name}"; value.owner = inputs.config.users.users.${server.value.user}.name; })
|
||||
(builtins.filter (server: server.value.passwordFile == null) (inputs.localLib.attrsToList redis.instances)));
|
||||
systemd.services = builtins.listToAttrs (builtins.map
|
||||
(server: { name = "redis-${server}"; value.serviceConfig.TimeoutStartSec = 0; })
|
||||
(builtins.attrNames redis.instances));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,7 +38,11 @@ inputs:
|
||||
nixos.services =
|
||||
{
|
||||
postgresql.instances.vikunja = {};
|
||||
nginx = { enable = true; https.${vikunja.hostname}.global.configName = vikunja.hostname; };
|
||||
nginx =
|
||||
{
|
||||
enable = true;
|
||||
https.${vikunja.hostname}.location."/".proxy.upstream = "http://127.0.0.1:${builtins.toString vikunja.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,7 +50,13 @@ inputs:
|
||||
{
|
||||
services =
|
||||
{
|
||||
xray = { enable = true; settingsFile = inputs.config.sops.templates."xray-client.json".path; };
|
||||
xray =
|
||||
{
|
||||
enable = true;
|
||||
settingsFile = inputs.config.sops.templates."xray-client.json".path;
|
||||
package = inputs.pkgs.xray.overrideAttrs
|
||||
(prev: { patches = prev.patches or [] ++ [ ./disable-splice.patch ];});
|
||||
};
|
||||
dnsmasq =
|
||||
{
|
||||
enable = true;
|
||||
@@ -328,7 +334,13 @@ inputs:
|
||||
(
|
||||
inputs.lib.mkIf (xray.server != null) (let userList = builtins.genList (n: n) xray.server.userNumber; in
|
||||
{
|
||||
services.xray = { enable = true; settingsFile = inputs.config.sops.templates."xray-server.json".path; };
|
||||
services.xray =
|
||||
{
|
||||
enable = true;
|
||||
settingsFile = inputs.config.sops.templates."xray-server.json".path;
|
||||
package = inputs.pkgs.xray.overrideAttrs
|
||||
(prev: { patches = prev.patches or [] ++ [ ./disable-splice.patch ];});
|
||||
};
|
||||
sops =
|
||||
{
|
||||
templates."xray-server.json" =
|
||||
16
modules/services/xray/disable-splice.patch
Normal file
16
modules/services/xray/disable-splice.patch
Normal file
@@ -0,0 +1,16 @@
|
||||
diff --git a/disable-splice.patch b/disable-splice.patch
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
diff --git a/proxy/proxy.go b/proxy/proxy.go
|
||||
index 6a5a179..ca71241 100644
|
||||
--- a/proxy/proxy.go
|
||||
+++ b/proxy/proxy.go
|
||||
@@ -474,7 +474,7 @@ func CopyRawConnIfExist(ctx context.Context, readerConn net.Conn, writerConn net
|
||||
readerConn, readCounter, _ := UnwrapRawConn(readerConn)
|
||||
writerConn, _, writeCounter := UnwrapRawConn(writerConn)
|
||||
reader := buf.NewReader(readerConn)
|
||||
- if inbound := session.InboundFromContext(ctx); inbound != nil {
|
||||
+ if inbound := session.InboundFromContext(ctx); false {
|
||||
if tc, ok := writerConn.(*net.TCPConn); ok && readerConn != nil && writerConn != nil && (runtime.GOOS == "linux" || runtime.GOOS == "android") {
|
||||
for inbound.CanSpliceCopy != 3 {
|
||||
if inbound.CanSpliceCopy == 1 {
|
||||
@@ -74,6 +74,7 @@ inputs:
|
||||
source =
|
||||
{
|
||||
unstablePackages = "nixpkgs-unstable";
|
||||
"pkgs-23.11" = "nixpkgs-23.11";
|
||||
"pkgs-23.05" = "nixpkgs-23.05";
|
||||
"pkgs-22.11" = "nixpkgs-22.11";
|
||||
"pkgs-22.05" = "nixpkgs-22.05";
|
||||
|
||||
@@ -10,7 +10,6 @@ inputs:
|
||||
(builtins.attrNames inputs.config.users.groups);
|
||||
autoSubUidGidRange = true;
|
||||
hashedPassword = "$y$j9T$xJwVBoGENJEDSesJ0LfkU1$VEExaw7UZtFyB4VY1yirJvl7qS7oiF49KbEBrV0.hhC";
|
||||
openssh.authorizedKeys.keys = [(builtins.readFile ./id_ed25519_sk.pub)];
|
||||
};
|
||||
home-manager.users.chn =
|
||||
{
|
||||
|
||||
1
modules/user/chn/id_ed25519.pub
Normal file
1
modules/user/chn/id_ed25519.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOH3AvxMlB3omzH6SFQt0Z5+f05x9nMJpFfSLH4OIYV+ chn@pc
|
||||
@@ -1 +0,0 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDXlhoouWG+arWJz02vBP/lxpG2tUjx8jhGBnDeNyMu0OtGcnHMAWcb3YDP0A2XJIVFBCCZMM2REwnSNbHRSCl1mTdRbelfjA+7Jqn1wnrDXkAOG3S8WYXryPGpvavu6lgW7p+dIhGiTLWwRbFH+epFTn1hZ3A1UofVIWTOPdoOnx6k7DpQtIVMWiIXLg0jIkOZiTMr3jKfzLMBAqQ1xbCV2tVwbEY02yxxyxIznbpSPReyn1RDLWyqqLRd/oqGPzzhEXNGNAZWnSoItkYq9Bxh2AvMBihiTir3FEVPDgDLtS5LUpM93PV1yTr6JyCPAod9UAxpfBYzHKse0KCQFoZH chn@chn-PC
|
||||
@@ -69,7 +69,7 @@ inputs:
|
||||
keys = [ "rsa" "ed25519" "ed25519_sk" ];
|
||||
getKey = user: key: inputs.lib.optional (builtins.pathExists ./${user}/id_${key}.pub)
|
||||
(builtins.readFile ./${user}/id_${key}.pub);
|
||||
in inputs.lib.mkDefault (builtins.concatLists (builtins.map (key: getKey userName key) keys));
|
||||
in builtins.concatLists (builtins.map (key: getKey userName key) keys);
|
||||
};
|
||||
})
|
||||
user.users);
|
||||
@@ -106,7 +106,8 @@ inputs:
|
||||
users.users.root =
|
||||
{
|
||||
shell = inputs.pkgs.zsh;
|
||||
openssh.authorizedKeys.keys = [(builtins.readFile ./chn/id_ed25519_sk.pub)];
|
||||
openssh.authorizedKeys.keys =
|
||||
[ (builtins.readFile ./chn/id_ed25519_sk.pub) (builtins.readFile ./chn/id_ed25519.pub) ];
|
||||
hashedPassword = "$y$j9T$.UyKKvDnmlJaYZAh6./rf/$65dRqishAiqxCE6LEMjqruwJPZte7uiyYLVKpzdZNH5";
|
||||
};
|
||||
home-manager.users.root =
|
||||
|
||||
Reference in New Issue
Block a user