hardware-dashboard/docs/DEPLOYMENT.zh-CN.md

15 KiB
Raw Blame History

192.168.1.37 监控与定时任务技术说明

版本:v1.2,2026 年 11 月 4 日。

1. 访问与登录

设备监控页面:http://192.168.1.37:8090

定时任务入口在“问题与维护”下方,也可通过左侧“定时任务”菜单定位。手机底部有同名入口。

硬件监控仍可直接查看。定时任务能够实际执行服务器操作,因此使用独立的管理员账号登录:

  • 账号:admin。
  • 初始密码:见交付的 定时任务管理员登录信息.txt,本说明不包含密码。
  • 登录最长有效 8 小时;修改密码后所有任务管理登录均失效。
  • 此密码与 SSH root 密码相互独立,本次没有修改 SSH 密码。

页面只开放在原有局域网访问范围内。当前使用局域网 HTTP,适用于可信局域网;不应将这个具备 root 任务执行能力的入口直接映射到公网。将来如需远程公开访问,应先配置 HTTPS 和适当的访问控制。

2. 本次新增功能

“定时任务”支持:

  • 新增、编辑、启用、停用和删除任务。
  • 立即执行一次;这不会自动启用任务的定时计划。
  • 停止本次执行;与停用后续调度分开处理。
  • 查看下次计划时间、最近执行结果和是否正在执行。
  • 查看单任务执行记录,以及包含已删除任务的全局执行记录。
  • 查看开始/结束时间、耗时、退出码、标准输出和错误输出。
  • 管理员登录、退出及修改密码。

执行方式有三种:

执行方式 如何填写 说明
直接输入命令 例如 /usr/bin/nvidia-smi 使用 Bash 执行,支持管道和多行命令。
粘贴脚本内容 选择 Bash 或 Python 3,粘贴代码 可以导入本地 .sh、.py 或文本脚本到编辑框;保存后才会传给服务器。
服务器上的脚本文件 填写绝对路径和可选参数 可选择 Bash、Python 3 或按文件自身方式执行;最后一种要求文件具有执行权限。

执行身份固定为 root,因为重启服务器和维护证书通常需要管理员权限。它不是隔离的脚本沙箱:应只运行自己理解并信任的命令。

工作目录默认 /root,使用非交互执行环境,不继承某个 SSH 窗口的虚拟环境。PATH 包含常用系统目录和 /snap/bin;如需 Conda、venv 或自定义环境变量,应在脚本内明确设置。

3. 第一次添加任务

  1. 刷新页面,打开“定时任务”,点击“登录管理”。
  2. 使用交付文件中的 admin 与初始密码登录。
  3. 点击“新增任务”,填写任务名称。
  4. 选择执行方式,输入命令、脚本或服务器脚本路径。
  5. 设置执行周期,点击“检查执行周期”核对下次时间。
  6. 保持“保存后启用”不勾选,先保存为停用状态。
  7. 如适合测试,点击“执行一次”,确认执行内容,查看执行日志。
  8. 核对结果后,再启用计划。

保存任务本身不会立即执行脚本。新任务默认停用。退出登录、关闭网页或重启网页服务不会停止已经启用的系统计划。

常用模板

新增窗口提供:

  • 显卡状态检查:读取 nvidia-smi,结果保存在执行日志中。
  • 服务器定时重启:示例命令为 systemctl reboot,默认周期是每周日 03:00,默认停用。启用或立即执行前都会提示可能中断计算任务。
  • SSL 证书续签示例:检查已有的 Certbot/acme.sh 工具并调用其续签入口。它不会安装工具、申请新域名或替用户配置证书。先确认现有续签配置,以及是否已经有其他自动续签任务;Web 服务的重新加载应按实际服务配置。

本次部署没有创建或启用实际的服务器重启任务和证书续签任务,也没有执行这两类操作。

4. 执行周期

所有日历时间按 Asia/Shanghai,北京时间 UTC+8 处理,页面显示服务器当前时间。

周期 规则
每天 指定时、分。
每周 可选择一个或多个星期及时间。
每月 选择 1 至 31 日和时间;当月不存在该日期时跳过。
每隔若干分钟/小时 启用后先等待指定间隔;每次执行结束后重新计时,避免长任务造成重叠。
指定日期,仅执行一次 选择未来的日期和时间,精确到分钟;至少晚于保存时刻 30 秒。
自定义 Cron 标准五段:分、时、日、月、周。支持 *、逗号、范围、步长及常见英文月/星期名。

Cron 示例:

0 3 * * *        每天 03:00
0 3 * * 0        每周日 03:00
0 3 1 * *        每月 1 日 03:00
*/30 * * * *     每小时的 00、30 分

不支持 L、W、#、? 等扩展语法,也不接受带秒的六段 Cron。日和星期同时指定时,按传统 Cron 的“任一满足”语义处理。

Cron 是日历触发,和“上次结束后再间隔 N 分钟”不同。例如长任务执行 10 分钟,再间隔 5 分钟,下一次大约在本次开始 15 分钟后。

开机、错过与长任务

  • 日历任务设置 Persistent=false,服务器关机期间错过的执行时间不补跑,避免开机后补执行重启类任务。
  • 同一个任务由固定 systemd 服务承载,并有文件锁,不会同时重叠执行两份。
  • 一个任务执行超时后会被停止。默认最长 1800 秒,可在高级设置中改为 10 至 86400 秒。
  • 关闭网页只会关闭查看界面,不会停止系统定时器。
  • 本机历史上出现过时钟回拨。启用重启等任务前,应核对页面显示的服务器时间;定时调度依赖服务器时钟和系统校时状态。

部署验证时,服务器时区为 Asia/Shanghai,系统报告 NTPSynchronized=yes。

5. 看懂执行结果

显示 意义
尚未执行 没有记录到执行。
执行中 本次进程仍在运行。
执行成功 命令正常退出,退出码为 0。
执行失败 命令退出码非 0,或启动过程中发生错误。
超时已停止 达到设置的最长执行时间,已停止本次进程。
已停止 本次进程被停止,可能是手动操作或系统停止服务。
执行被中断 执行期间系统重启或进程中断,未取得完整结果。

成功只表示脚本返回了 0,不保证某个证书一定已更新、备份一定可恢复或某个业务结果一定正确;这些应结合脚本输出核对。

“停用”只取消将来的调度,不会强制中止已经开始的执行。“停止本次”会终止执行进程,脚本可能尚未完成修改,操作前会提示确认。

目前单任务窗口展示最近 40 次执行,全局窗口展示最近 80 次。服务器执行记录按 90 天清理;每次输出上限约 512 KiB,网页每次读取最后 128 KiB。输出与脚本快照还有合计 256 MiB 的空间限制,较旧文件可能提前清理,执行状态元数据仍保留至期限。

删除任务会停用计划并移除模块生成的定时器,保留已有执行记录。历史记录可在“全部执行记录”查看。

6. 参考与技术栈

界面参考 宝塔 Linux 面板 计划任务的组织方式:任务列表、执行周期、Shell 脚本、启停、手动执行和执行日志。本次功能自行编写,沿用已有监控页面的深色风格,没有安装宝塔,也没有复制其面板源码。

原监控布局仍参考:

  • Zabbix:设备总览和告警分级。
  • Netdata:实时指标展示。
  • Grafana:历史曲线、图例和时间范围。
部分 使用技术
监控与任务前端 HTML、CSS、原生 JavaScript、原生 <dialog> 对话框。
曲线 原生 SVG,保留原有 CPU、内存、GPU 温度、功耗和利用率历史。
网页后端 Python 3.12 标准库,ThreadingHTTPServer。
数据库 SQLite,WAL 模式;监控数据与任务数据分库存储。
系统调度 systemd .timer 和 .service,不是浏览器内的倒计时。
网页与特权服务通信 本机 Unix socket,限制连接进程身份。
管理密码 随机盐、PBKDF2-HMAC-SHA256,240000 次迭代。
登录态 内存会话、HttpOnly/SameSite=Strict Cookie;写操作同时检查 Origin 与 CSRF。
执行控制 独立进程组、文件锁、超时、停止信号、限量输出、执行审计。

没有新增 npm、pip 或外部 CDN 依赖。服务器不需要 Node.js;开发阶段使用 Node.js 检查 JavaScript 语法。

7. 为什么要拆成两个服务

flowchart LR
    A[浏览器:监控与任务界面] --> B[hardware-dashboard\n普通账号\nHTTP 8090]
    B --> C[(原监控数据库)]
    B -->|本机 Unix socket\n验证会话与 CSRF| D[hardware-taskd\nroot 任务管理服务]
    D --> E[(独立任务数据库\nroot 专用目录)]
    D --> F[systemd 定时器]
    F --> G[task_exec\n执行指定任务]
    G --> H[执行日志与结果]
    H --> D

硬件网页继续使用原来的 hardware-dashboard 普通账号。新增 root 服务只通过本机 Unix socket 接收经验证的任务操作,不额外开放网络端口。

任务内容不插入 systemd 的 ExecStart。生成的服务只启动固定的执行器和经过验证的任务 ID;执行器从 root 专用数据库读取任务内容。这避免任务名称、换行或参数变成 systemd 单元配置。

上传或粘贴的脚本文本会统一换行为 Linux 格式。服务器脚本路径和参数以独立参数列表传递;命令内容模式则按管理员输入交给 Bash 执行。

root 服务不是恶意脚本隔离环境。管理员既然有权输入 root 命令,就应当视为具有服务器管理员权限。

8. 文件与数据库位置

以下均在 192.168.1.37:

路径 内容
/opt/hardware-dashboard/server.py 网页 HTTP 和监控 API;新增任务 API 代理。
/opt/hardware-dashboard/static/tasks.js 任务表单、登录、启停、执行和日志交互。
/opt/hardware-dashboard/task_core.py 校验、周期转换、任务数据库和 systemd 管理。
/opt/hardware-dashboard/taskd.py 本机任务服务、会话验证、审计和清理。
/opt/hardware-dashboard/task_exec.py 单次执行、输出、超时与退出结果。
/etc/systemd/system/hardware-taskd.service 新增任务管理常驻服务。
/etc/systemd/system/hwjob-任务ID.timer 本模块为已创建任务生成的定时器。
/etc/systemd/system/hwjob-任务ID.service 对应的执行服务。
/run/hardware-taskd/control.sock 普通网页与 root 服务之间的本机通信入口。
/etc/hardware-task-admin.json 管理密码的盐与散列,仅 root 可读。
/var/lib/hardware-taskd/tasks.sqlite3 任务定义、执行元数据和审计。
/var/lib/hardware-taskd/scripts/ 脚本内容模式的执行快照。
/var/log/hardware-taskd/ 每次执行的输出日志,仅经管理登录读取。
/var/lib/hardware-dashboard/monitor.sqlite3 原来的性能和硬件日志数据库,继续保留。
/root/hardware-task-admin-login.txt 初始登录信息的服务器副本,仅 root 可读。

原有 hwlog 命令、硬件采集器及性能历史继续运行。本模块只管理自己创建的 hwjob-* 单元,不接管现有 crontab、系统 timer 或其他面板任务。

9. 常用维护命令

# 查看网页服务与任务服务
systemctl status hardware-dashboard.service hardware-taskd.service

# 查看任务管理服务自身报错
journalctl -u hardware-taskd.service -n 50 --no-pager

# 查看本模块的全部系统定时器
systemctl list-timers --all 'hwjob-*.timer'

# 查看某个任务的系统层日志,任务 ID 可从页面或数据库查出
# 将下方 32 位 ID 替换成实际值,不要把说明文字直接输入命令
systemctl status hwjob-0123456789abcdef0123456789abcdef.service

# 重启网页服务:不会取消已启用的任务
systemctl restart hardware-dashboard.service

# 重启任务管理服务:已有网页登录会失效,系统定时器仍独立运行
systemctl restart hardware-taskd.service

忘记任务管理密码时,可通过 SSH 以 root 执行以下命令。新密码在交互输入,不放进命令行参数:

python3 /opt/hardware-dashboard/taskd.py password
systemctl restart hardware-taskd.service

只停止网页或任务管理进程,不等于停用计划。要停止后续执行,应先在页面将对应任务停用;需要立即中断时再使用“停止本次”。

10. 备份与回退

本次更新前的网页代码备份:/opt/hardware-dashboard-backup.vNWXhLKD/。

任务数据库与监控数据库分开。备份正在运行的 SQLite 应使用 SQLite 的备份接口,不能只复制主文件而忽略 WAL。备份任务数据库、管理密码散列和脚本/日志时,应继续保持 root 专用权限。

如需回退界面,先在页面停用所有不再需要的任务,再停止任务管理服务并恢复代码。只恢复旧网页代码不会自动删除或停用已经生成的系统定时器。

11. 已完成的验证

自动化测试

16 项本地和服务器测试通过,覆盖:

  • 原监控数据、问题合并、时钟回拨及过期状态。
  • 每日/每周/每月/间隔周期与 Cron 字段解析。
  • Cron 日期和星期的 OR 语义、非法范围和步长。
  • 任务名称与脚本内容不会成为 systemd 单元配置指令。
  • 未登录和错误 CSRF 不会调用特权任务操作。
  • 修改密码使所有旧会话失效。
  • 日志读取量上限与路径编号验证。

服务器真实执行验证

使用明确命名的“部署验证”任务,确认了:

验证内容 实际结果
手动打印命令 成功,退出码 0。
指定日期自动触发 在计划时间由 systemd 自动执行,记录为 scheduled,退出码 0。
Python 脚本内容 成功,输出 PYTHON_TASK_OK。
服务器已有文件执行 成功,输出 EXISTING_FILE_OK。
主动返回退出码 7 正确显示失败,保留错误输出。
10 秒超时 约 10 秒后停止,显示超时。
手动停止等待任务 正确停止并记录状态。
编辑、启用和停用 页面与系统定时器状态一致。
未登录、错误来源、错误 CSRF 分别被 HTTP 401/403 拒绝。

这些测试仅打印信息或短暂等待,没有执行重启、关机、证书续签或修改现有业务配置。测试计划在交付前移除,历史中保留有“部署验证”字样的执行记录。