Compare commits

...

68 Commits

Author SHA1 Message Date
chn
cd5838c5ef 暂存 2024-06-22 15:55:31 +08:00
chn
35253cff0a localPackages.biu: add serialize test 2024-06-19 20:06:12 +08:00
chn
91b92bd492 localPackages.hpcstat: fix 2024-06-19 11:25:08 +08:00
chn
0198626002 Merge branch 'temp' into production 2024-06-19 11:05:42 +08:00
chn
173dd4a3d7 localPackages.hpcstat: export job detail to excel 2024-06-19 11:05:27 +08:00
chn
1854e294cf modules.user.chn: add new key 2024-06-18 21:52:50 +08:00
chn
b45a9c7a62 packages.ssh: fix forwardX11 2024-06-18 21:49:51 +08:00
chn
858f4c68aa devices.vps6: xray add user 2024-06-18 19:57:32 +08:00
chn
37e6d70561 packages.server: enable mosh 2024-06-18 17:37:43 +08:00
chn
f101038f4a devices.vps7: set beesd loadAverage to 4 2024-06-18 16:01:14 +08:00
chn
412fac9692 services.redis: unset systemd start timeout 2024-06-18 16:01:08 +08:00
chn
4c7d17f001 Revert "devices.vps7: use default kernel"
This reverts commit db1e825cd6.
2024-06-18 09:51:09 +08:00
chn
e8d80daee2 services.huginn: update 2024-06-18 09:49:56 +08:00
chn
8aeb290d0f localPackages.hpcstat: sort before export 2024-06-18 01:23:00 +08:00
chn
0f37c886a4 localPackages.hpcstat: fix export 2024-06-18 01:08:50 +08:00
chn
5940da526d localPackages.hpcstat: 不导出 hpcstat 的登陆次数 2024-06-18 01:02:58 +08:00
chn
df2ac86e1a localPackages.hpcstat: export markdown instead of excel 2024-06-18 00:57:41 +08:00
chn
8bf7e2cb30 add note 2024-06-17 22:43:49 +08:00
chn
96f7056d16 devices.pc: add xanmod specialization 2024-06-17 10:14:51 +08:00
chn
5cc40727db localPackages.chn-bsub: init 2024-06-16 16:10:52 +08:00
chn
c4f8e5f61c localPackages.sbatch-tui: enhance 2024-06-16 13:37:33 +08:00
chn
03be19da5a packages.ssh: 整理 2024-06-16 13:07:38 +08:00
chn
7657fe3d14 packages.ssh: fix X11 forwarding 2024-06-16 12:36:40 +08:00
chn
9fee2a8e2a add todo 2024-06-16 09:43:22 +08:00
chn
db1e825cd6 devices.vps7: use default kernel 2024-06-14 22:46:54 +08:00
chn
670126ba0c devices.vps6: use default kernel 2024-06-14 22:37:57 +08:00
chn
92ddf86df1 Revert "remove crypton patch"
This reverts commit 2c833934e7.
2024-06-14 22:35:00 +08:00
chn
bd12de34b7 Revert "test nvidia close source driver"
This reverts commit 7576726fbe.
2024-06-14 19:04:14 +08:00
chn
a7b0906488 Revert "hardware.gpu: fix nvidia beta driver"
This reverts commit 5efee599f7.
2024-06-14 19:04:04 +08:00
chn
0ce31201a9 devices.pc: disable wakeup 2024-06-14 18:55:31 +08:00
chn
58d927b648 localPackages.sbatch-tui: add separator 2024-06-14 18:19:03 +08:00
chn
5efee599f7 hardware.gpu: fix nvidia beta driver 2024-06-14 18:18:58 +08:00
chn
2c833934e7 remove crypton patch 2024-06-14 16:48:20 +08:00
chn
c5dc456c35 services.xray: disable splice 2024-06-14 16:48:15 +08:00
chn
7576726fbe test nvidia close source driver 2024-06-14 12:48:13 +08:00
chn
6dfd6a8bf0 devices.xmupc1: update doc 2024-06-14 12:07:17 +08:00
chn
eb68d8f8b1 localPackages.sbatch-tui: support multi gpu 2024-06-14 11:58:20 +08:00
chn
46ae9f1aac devices.pc: add some bug workarounds 2024-06-14 10:17:16 +08:00
chn
bb5aee5545 hardware.gpu: nvidia beta use open-source driver, production use 535 2024-06-13 23:55:06 +08:00
chn
a8833dac7f devices.pc: use open-source nvidia drivers 2024-06-13 23:13:31 +08:00
chn
d1b3f84cf3 Revert "devices.pc: remove all kernel patches"
This reverts commit f813ffd053.
2024-06-13 23:13:07 +08:00
chn
f813ffd053 devices.pc: remove all kernel patches 2024-06-13 22:48:36 +08:00
chn
00c99adca9 packages.workstation: add mumax 2024-06-13 20:53:12 +08:00
chn
ef58de9a1d packages.workstation: add qe 2024-06-13 20:52:16 +08:00
chn
b9175a211f services.vikunja: fix 2024-06-13 18:06:12 +08:00
chn
0cb7791b84 packages.desktop: tela circle icon theme enable all color 2024-06-13 17:33:26 +08:00
chn
803af74404 devices.pc: add amdgpu workaround 2024-06-13 12:10:55 +08:00
chn
c5da42debd devices.pc: disable suspend-hibernate-no-platform bug 2024-06-12 22:49:08 +08:00
chn
e16f49b3f3 remove .clangd 2024-06-12 21:51:54 +08:00
chn
f10c385f13 packages.desktop-extra: add etcher 2024-06-12 21:47:42 +08:00
chn
f65ec24862 services.hpcstat: run diskstat every 12 hours 2024-06-12 16:32:29 +08:00
chn
73261c3e3f devices.pc: disable scx 2024-06-12 12:21:04 +08:00
chn
e50ad89bc2 Reapply "devices.pc: switch to hybrid"
This reverts commit d692bb8baf.
2024-06-12 11:15:27 +08:00
chn
5f4a79788d Reapply "system.gui: remove firefox workaround"
This reverts commit 1360a3e9fa.
2024-06-12 11:15:17 +08:00
chn
1360a3e9fa Revert "system.gui: remove firefox workaround"
This reverts commit 115a7f7753.
2024-06-12 11:11:33 +08:00
chn
d692bb8baf Revert "devices.pc: switch to hybrid"
This reverts commit 98eb945684.
2024-06-12 10:58:07 +08:00
chn
dbcf7093aa devices.pc: use rustland scheduler 2024-06-12 00:18:24 +08:00
chn
7833f37588 packages.server: remove strings 2024-06-12 00:00:42 +08:00
chn
673f241490 update chaotic 2024-06-11 23:57:23 +08:00
chn
a5be9adb53 add some basic tools 2024-06-11 22:30:45 +08:00
chn
d6a1da17fb devices.pc: try mt7921 workaround 2024-06-11 19:15:17 +08:00
chn
6e0e224530 devices.pc: remove hibernate-mt7921e bug 2024-06-11 19:01:29 +08:00
chn
1a007ab57f devices.pc: do not suspend VMs automatically 2024-06-11 18:42:48 +08:00
chn
da76976c3d devices.pc: some workaround 2024-06-11 18:21:18 +08:00
chn
b46f928964 localPackages.hpcstat: bug in deserialize, read from duc directly 2024-06-11 17:45:09 +08:00
chn
92fdc6c67d localPackages.hpcstat: export duc output 2024-06-11 16:51:10 +08:00
chn
2534f35c4d nixpkgs: update nvidia config
devices.pc: try some workaround
2024-06-11 15:13:50 +08:00
chn
f9e376920c packages.vscode: add git-graph plugin 2024-06-11 14:41:11 +08:00
58 changed files with 897 additions and 424 deletions

View File

@@ -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" ];
};
};
};
}

View File

@@ -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 =
{

View File

@@ -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

View File

@@ -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;

View File

@@ -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
View File

@@ -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": {

View File

@@ -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";
};
};
};
}

View File

@@ -1,3 +1,3 @@
CompileFlags:
Add: [ -Wall, -Wextra, -std=c++23 ]
Compiler: g++
Compiler: g++

View File

@@ -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)

View File

@@ -8,4 +8,5 @@
buildInputs = [ magic-enum fmt boost eigen range-v3 nameof zpp-bits ];
propagatedBuildInputs = buildInputs;
nativeBuildInputs = [ cmake ];
doCheck = true;
}

View 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);
}

View File

@@ -1,3 +1,3 @@
CompileFlags:
Add: [ -Wall, -Wextra, -std=c++23 ]
Compiler: gcc
Compiler: g++

View File

@@ -0,0 +1 @@
use flake .#chn-bsub

View 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}")

View 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";
}

View 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;
}
}

View File

@@ -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" {}

View File

@@ -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})

View File

@@ -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 =

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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];
}

View File

@@ -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; }

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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:
{

View File

@@ -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 =

View File

@@ -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

View File

@@ -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

View File

@@ -26,11 +26,7 @@ inputs:
])];
};
};
programs =
{
yazi.enable = true;
mosh.enable = true;
};
programs.yazi.enable = true;
services.fwupd.enable = true;
};
}

View File

@@ -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
View 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";
};
};
};
})];
};
}

View File

@@ -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";
};
};
};
})];
};
}

View File

@@ -1 +0,0 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=

View File

@@ -1 +0,0 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDkkl7A9kWWBoi4b5g6Vus70ja1KhPfcZZjeU1/QbYdN8PRRw/hsGklrhefslKRbym/TMFS0ko0g5WUi9G5vbGw=

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgs8MvV2nczjGMZ548tuAhgvCEd4uHu0VhLDSwQG7Nh/UR4Pgc5T9Nf7Vfwg96Lah/pwD5my4RaWis6bLMmlkYyDBKFBOsGYQUe5J5XfZdxk8pz+7L0Hq6gPfAZAdNlUiuFVKsvkE+NF42NgJyXSYQicPbu5LQiFwZGXlW20+LO8uBQ1y1xabKVpg8XGwordduL99VepwEzeLK/st+UVfW+mKgxkf9TuxvD2fuYIDZM7y2rXqcjf4/6OXA5kACsYK1MgZSFxgO/m6+1uCC1qBDseMTA3D+Tsjf9VtcqUE9dMd/dJ/uuILHJ0+oIqkykTCecPLgJY3Vh8rAtln/lbId

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC0+xafJMnOGCHv6OLljaq8iJ3ZBaIezv7AJ9rVWJXFg/QJRYBwct35c4zaVom7If8F+Ss+BTLMp33HZ8gLpoat6LkjARjy65Ycog3NOnEposX2JjZEYXDbovxEmcJkDXAIVmnaBUi3r22z4UI8OqsHPeRXj017O0yQrQQYEAw/IO/tSNQZt2k8JHxAX50UTqGFdgkriO1fYHBocq48m0nn3sXrMuM3yBe5zy3NngOHxMn7UxjECmAElsuu/nu1x083pRnv5NSa+JxDGJ+S6Zhj3nGGNwZesa51I4cJjsYLxgmO/NxL1J86bDp6HhK9C9799ruG60pGTw6HcvbKTgx7klUgn4936wsy7qukWqp53MvqrLSJkRb/HHU9zZqvzcjbwet+Iv1OAAok5QC88j7Jgenk3nbZw4BNFd2r/8rOZuXheDnMKOa61dXxnvoAO3Euk0RPdZqW1slT/DDyD/kB6TPY7yOywNURNnrwzfSsmravKi6bGA5t2Ehhpf2LETM=

View File

@@ -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==

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDJAyDl52UVGFPTV/rXFERrXAMY5qZ3g+tpg9HOGdw86G4Nr8Xp/cTxZjF4kSfIkSrGblAV9Lm4US0fW3pGOQu5qQrSAENxqHxdlEyzt7izyF2CklDUeTjs3KHOIZMvSli4z014NPcswBbjwB9Lyrw0fCQ9P1vYkrUHEzL2SMxdack1EQPcMF4MxblDqc+eQhdMCkKE8T1Cb1ZqxeLVMPn9CwjG18JoxL+/xs+MjcsSXYWcoqYTfgfhguMbh0D4Eo32MHS/IzRSxnOHJxhG5xYePcyBlb/CxQuYA+RTqKNE85j7GcL2oEmeZ1b++/9qFT9grwVh+UOBRO2xiMzKDF24nXPJ+eLyd6Z/3swGT4rTVDnrXV5eZUkWLHN093IdLJCTtPVrKV9OxEKr5sU2W0edpirNrlGq7/MYkJX9EbQctDFA69XfQkZlGK9xGutqSgEaVlY54fS0Due+NDrNBPfMKJ9MTmFDOY+NYn05El2rMD39OKbGbCR5ASwSSBlcQeE=

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDYiP+ELuG5KTmafVjBkY0ZSggJg+mDkvZpF8d7NljMst0YwKWV3IgHnkAGXdTd7jlRgm9HH6oc8rP2R6Q8EJmfr+xcL1IQIWKuYAoddHlpe2Ds4EE74xbgm5Elf7FpdYNHUH9XyVmMmIhVSpLw2N10jUhvYqw+h+xC2nObEKZuBOt/lqrTGbC/EMv3+sDv0ApBh8lKt2yfjt88pnAj1LKPANDgIYSyQOllHQWeUY/eD/5Qc9XWR3uWclslVaxriRmEA0sNZlOFCeRIyDbYpSzQBdcnojkwt7Z5kjhaqGlT9g00fdiqO0OMaeY/G8ki3QxqjONqTEDqK+DpEZFO6jyZARcY6ki0ANc0AO4qosEC3gEbAvVwyPwDFtyDggMTHlTzaw8iakMGSDEk10zKaUOgZYLzC2yCWYYQS5mae9wC1gkXIGD51/laeq2E7NpM+nha6kp9weLVyvwf0DLfwsiP+0qlCLrxBLTSRa0HQ+BnQMi4r16Ss7YJwLf/oXrbOVk=

View File

@@ -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=

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDVbOvoFVaGkqYzIWsmMFlpkE+TDAONOWWaJBQ0K4fiOLy7uh02b/jYNZrbllPDP+Gq+ikYEJnJX2ceDsh9mLtJTznBQXgJOMUZDYy0enu7hYLKMmRTgJntzHjMbZENMhP+I3N9JnQ1PQz7lICg1xkEBQm2CESYCCjo0rJKYplPH1bo02myEazKlKTn6tu40ysrYOoJO8+jwbUDqtWATjSZtgYojuh6dbIoK3O+Ntgwl4W0NqXEqXYXTWpU0qKOqAsP/9F9WJ5d1wVNNbvmcAJ26dkYaiPCNgW4MGTucAgoxM6IPVVj9U+OEZLoCPsqAGCT02vH5MoDNTmGaSv0DjuYOzz5C+jAhMCznXFXCI4bfawvuda/WwGIniB5iKNSBZt3XxYyUw4YBcVCNiWUt9bIgEvnR4E8HYHdjNrbQ0Z58L6DcPSySLQer7C658Vo/nRUlBq6lIWYhcdjxHHkP9iFtuFW1HmoUKkuaLl+uiflrSppX9wt8eaPwGgGIHkLwgc=

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCa7ZRmIAtuGd58MQXnJnPqmad+6u8JiBKb7+xEfMmVdeVtJ5lEfXCkZ0vbSMxnGZCLL3eVxdejaGToLw+ArEJ1cl6KzZdsdGy1wATFtJj4oYHtZ/MXg+qulNR4nQ6DGWfGR7FEXjZNaJfVuLBFBmUlsbotBdhaAJzw5+nnIxY5d86nfqzsYstMqB/1ZHLRTV9h/jp8XNgnUu1BR/oVk4eMvzTUbr42LedeB1anLnI0+ycAzol/XMpsUNuRLVhYhMbg9rpyoZF1WMBTjG2Jnv9JtCpJlnZaOjzh3eD8PBuyZtGyya7QxVkhH4ULUMNnuyi8E0IOJwdN4cQi61fa7rLtsYfUrN2w0nI/WRLiBxiuPbvq4tKeHi8DpM/MrUbZONY2eFo4CaX9sxYN6U65jDfsbK3x6Za0HhVt8zcPLGgESm4Y6O8YTQrdbpL1ifNFX2Y9B++FQw2iRoqa6U0Wrs6SfVQFp1RqnqSl6fLOCixl16PpHWqRilweKbg3uIMEqEc=

View File

@@ -58,6 +58,8 @@ inputs:
yutengjing.open-in-external-app
# ChatGPT-like plugin
codeium.codeium
# git graph
mhutchie.git-graph
];
}
)];

View File

@@ -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

View File

@@ -77,7 +77,7 @@ inputs:
{
finishjob = "*-*-* *:*:00";
backupdb = "*-*-* *:00/10:00";
diskstat = "*-*-* 03:00:00";
diskstat = "*-*-* 03/12:00:00";
};
in
{

View File

@@ -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" ];

View File

@@ -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));
};
}

View File

@@ -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}";
};
};
};
}

View File

@@ -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" =

View 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 {

View File

@@ -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";

View File

@@ -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 =
{

View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOH3AvxMlB3omzH6SFQt0Z5+f05x9nMJpFfSLH4OIYV+ chn@pc

View File

@@ -1 +0,0 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDXlhoouWG+arWJz02vBP/lxpG2tUjx8jhGBnDeNyMu0OtGcnHMAWcb3YDP0A2XJIVFBCCZMM2REwnSNbHRSCl1mTdRbelfjA+7Jqn1wnrDXkAOG3S8WYXryPGpvavu6lgW7p+dIhGiTLWwRbFH+epFTn1hZ3A1UofVIWTOPdoOnx6k7DpQtIVMWiIXLg0jIkOZiTMr3jKfzLMBAqQ1xbCV2tVwbEY02yxxyxIznbpSPReyn1RDLWyqqLRd/oqGPzzhEXNGNAZWnSoItkYq9Bxh2AvMBihiTir3FEVPDgDLtS5LUpM93PV1yTr6JyCPAod9UAxpfBYzHKse0KCQFoZH chn@chn-PC

View File

@@ -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 =

View File

@@ -1,4 +1,5 @@
* 使用 wrap 好的 intel 编译器。
* 在挂载根目录前(创建 rootfs 时),按用户复制需要的文件
* 布置 sunshine
* 挑选一个好看的主题
* 切换到 kde 6.1,使用 krdp
* 尝试一些别的计算软件