fix(gpu-monitor): update to version 1.0.1, resolving CRLF line ending issues in scripts; enhance validation and error reporting for GPU probe execution
This commit is contained in:
1 parent
e5b7daad99
commit
2b123a67a3
9 files changed
+175
-20
No files matched your search
@@ -28,6 +28,19 @@ node plugins/examples/gpu-monitor/verify-ui.mjs
|
||||
更新或切换版本会停用插件并移除自动脚本授权,需重新审核。第二个有效的 `gpu.v1` Monitor 无法同时启用。
|
||||
`native` 后台是以当前用户权限运行的可信程序,宿主 RPC 权限不构成操作系统沙箱。
|
||||
|
||||
当前版本 `1.0.1` 修复了 Windows 构建的脚本 CRLF 换行问题。构建时规范为 LF,Git 属性也固定 LF;
|
||||
已安装 `1.0.0` 时直接安装新版包并重新审核授权,无需为这次修复重新编译宿主。
|
||||
执行失败会记录退出码,缺少退出状态会单独提示,不把 stderr 或 GPU 进程列表写入日志。
|
||||
|
||||
验证最终包中的实际脚本(需要 Python;Windows 使用已安装的 WSL Ubuntu):
|
||||
|
||||
```powershell
|
||||
python plugins/examples/gpu-monitor/verify-probe.py --wsl Ubuntu
|
||||
```
|
||||
|
||||
Linux 使用 `python3 plugins/examples/gpu-monitor/verify-probe.py`。
|
||||
测试使用隔离的 `nvidia-smi` 固定样本,并验证 CRLF 失败和无 NVIDIA 工具的分支,不连接真实服务器。
|
||||
|
||||
## 行为和恢复
|
||||
|
||||
- 立即采集一次,随后按既有 GPU 间隔采集,最短 3 秒;请求不重叠,完成后安排下一轮。
|
||||
|
||||
+1
-1
@@ -82,7 +82,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nyaterm-plugin-gpu"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
dependencies = [
|
||||
"nyaterm-gpu",
|
||||
"nyaterm-plugin-sdk",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nyaterm-plugin-gpu"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
edition = "2024"
|
||||
rust-version = "1.94"
|
||||
|
||||
|
||||
@@ -9,8 +9,15 @@ impl Plugin for GpuMonitor {
|
||||
return Err(RpcError::method_not_found(method));
|
||||
}
|
||||
let result = context.host().remote_probe("gpu-overview").await?;
|
||||
if result.get("exitStatus").and_then(Value::as_u64) != Some(0) {
|
||||
return Err(RpcError::new(-32000, "GPU probe did not exit successfully"));
|
||||
match result.get("exitStatus").and_then(Value::as_u64) {
|
||||
Some(0) => {}
|
||||
Some(status) => {
|
||||
return Err(RpcError::new(
|
||||
-32000,
|
||||
format!("GPU probe failed (exit status {status})"),
|
||||
));
|
||||
}
|
||||
None => return Err(RpcError::new(-32000, "GPU probe returned no exit status")),
|
||||
}
|
||||
let output = result
|
||||
.get("stdout")
|
||||
|
||||
@@ -8,6 +8,10 @@ import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
const root = fileURLToPath(new URL("./", import.meta.url));
|
||||
const repository = path.resolve(root, "../../..");
|
||||
// Execute on Linux even when this project was created/checked out on Windows.
|
||||
const probePath = path.join(root, "assets/probes/gpu.sh");
|
||||
const probe = readFileSync(probePath, "utf8").replace(/\r\n/g, "\n");
|
||||
writeFileSync(probePath, probe);
|
||||
const translations = {};
|
||||
for (const language of ["en", "zh-CN", "zh-TW", "ko"]) {
|
||||
const locale = JSON.parse(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifestVersion": 1,
|
||||
"id": "nyaterm.gpu",
|
||||
"name": "GPU Monitor",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "NVIDIA GPU monitoring over an existing NyaTerm SSH session",
|
||||
"publisher": "NyaTerm",
|
||||
"engine": ">=1.2.12, <2.0.0",
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
"""Execute the exact packaged probe in a POSIX shell with controlled NVIDIA fixtures.
|
||||
|
||||
Windows: python plugins/examples/gpu-monitor/verify-probe.py --wsl Ubuntu
|
||||
Linux: python3 plugins/examples/gpu-monitor/verify-probe.py
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--wsl", metavar="DISTRO", help="Use an existing WSL distribution on Windows")
|
||||
parser.add_argument("--package", type=Path, default=Path(__file__).resolve().parents[3] / "temp/plugins/gpu-monitor.nyap")
|
||||
args = parser.parse_args()
|
||||
shell = ["wsl", "-d", args.wsl, "--exec", "/bin/sh"] if args.wsl else ["/bin/sh"]
|
||||
with zipfile.ZipFile(args.package) as package:
|
||||
manifest = json.loads(package.read("manifest.json"))
|
||||
assert manifest["id"] == "nyaterm.gpu"
|
||||
probe = package.read("assets/probes/gpu.sh")
|
||||
|
||||
# Reproduce the old Windows packaging failure, then exercise the actual fixed package.
|
||||
assert b"\r" not in probe, "Packaged POSIX script contains Windows CRLF line endings"
|
||||
assert not probe.startswith(b"\xef\xbb\xbf"), "Packaged script contains a UTF-8 BOM"
|
||||
assert probe.endswith(b"\n")
|
||||
def execute(script, command):
|
||||
result = subprocess.run(shell + ["-c", command], input=script, capture_output=True, timeout=20)
|
||||
return result.returncode, result.stdout, result.stderr
|
||||
|
||||
unavailable_command = "PATH=/nonexistent /bin/sh -s"
|
||||
status, _, _ = execute(probe.replace(b"\n", b"\r\n"), unavailable_command)
|
||||
assert status != 0, "CRLF regression did not reproduce in the Linux shell"
|
||||
status, stdout, _ = execute(probe, unavailable_command)
|
||||
assert status == 0 and stdout == b"GPU_AVAILABLE\t0\n", (status, stdout)
|
||||
|
||||
fixture_command = r'''set -eu
|
||||
fixture=$(mktemp -d)
|
||||
trap 'rm -rf "$fixture"' EXIT HUP INT TERM
|
||||
cat > "$fixture/nvidia-smi" <<'NYATERM_NVIDIA_FIXTURE'
|
||||
#!/bin/sh
|
||||
case "$*" in
|
||||
--query-gpu=*)
|
||||
printf '%s\n' '0, GPU-a, NVIDIA RTX 4090, 550.54, 43, 77, 31, 24564, 12345, 12219, 180.5, 450, 46, P2'
|
||||
;;
|
||||
--query-compute-apps=*)
|
||||
printf '%s\n' 'GPU-a, 4242, 2048, python'
|
||||
;;
|
||||
*)
|
||||
printf '%s\n' '| NVIDIA-SMI 550.54 Driver Version: 550.54 CUDA Version: 12.4 |'
|
||||
;;
|
||||
esac
|
||||
NYATERM_NVIDIA_FIXTURE
|
||||
chmod +x "$fixture/nvidia-smi"
|
||||
PATH="$fixture:/usr/bin:/bin" /bin/sh -s
|
||||
'''
|
||||
status, stdout, _ = execute(probe, fixture_command)
|
||||
assert status == 0, f"GPU fixture probe exited with {status}"
|
||||
for required in [b"GPU_AVAILABLE\t1\n", b"GPU_CUDA_VERSION\t12.4\n", b"GPU_CSV_BEGIN\n", b"NVIDIA RTX 4090", b"GPU_CSV_END\n", b"GPU_PROCESS_CSV_BEGIN\n", b"GPU-a, 4242, 2048, python", b"GPU_PROCESS_CSV_END\n"]:
|
||||
assert required in stdout, f"Probe did not produce {required!r}"
|
||||
print(f"GPU probe {manifest['version']} passed: exact package LF bytes, CRLF regression, unavailable and NVIDIA fixtures in a Linux/POSIX shell.")
|
||||
Reference in new issue
Block a user