c9a99f4fb3
代码修复: - web/agent/agent.py: datetime.utcnow() → datetime.now(timezone.utc) - requirements.txt: 移除 paramiko==3.5.0 (已无活跃引用) - 删除 server/infrastructure/ssh/pool.py (DEPRECATED, 无引用) 连接池三层对齐 (config.py/.env.example/session.py): - DB_POOL_SIZE 100→160, DB_MAX_OVERFLOW 100→120 - 基于 MySQL max_connections=400, install.php 公式 文档修复 (21项): - P0: 硬编码域名/IP替换为配置变量占位符 - P1: 10个过时设计文档加归档标注 (引用旧文件结构) - P2: step-3-webssh报告 paramiko引用修正 - 6份审查报告连接池参数勘误 100/100→160/120 - ECC安全报告 EC5 datetime.utcnow 标记已修复 - docs/README.md 文档索引重写 - docs/memory/mem_nexus_overview.md 移除硬编码凭证 - docs/project/tech-stack-inventory.md paramiko标记已移除 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.6 KiB
4.6 KiB
servers.php 添加服务器优化 — 设计规格
⚠️ 已归档 — 2026-05-22 本文档引用的文件结构已过时:
web/servers.php已迁移到web/app/servers.html(Tailwind CSS v4 + Alpine.js);server/services/agent_installer.py未独立创建,安装逻辑集成在 server_service.py 中。功能已实现,保留本文档供历史参考。
日期: 2026-05-17 状态: 已确认
一、需求
- Agent API 密钥自动生成,不显示在表单
- 密码预设下拉联动修复
- 添加服务器后自动 SSH 安装 Agent,实时回传日志
- 表单新增目标路径字段(必填)
- 目标路径在列表可快速编辑
二、表单改造
字段变更
| 字段 | 变更 |
|---|---|
| 名称 | 保持 |
| 域名/IP | 保持,必填 |
| SSH端口 | 保持,默认22 |
| SSH用户名 | 保持,默认root |
| 认证方式 | 保持(密码/密钥) |
| 密码预设 | 保持,修复 datalist 联动 |
| SSH密码 | 必填(需要 SSH 安装 Agent) |
| SSH密钥路径 | 保持(认证方式=密钥时显示) |
| 目标路径 | 新增,必填,target_path |
| Agent端口 | 隐藏,默认8601 |
| Agent密钥 | 隐藏,后端自动生成 bin2hex(random_bytes(16)) |
移除字段
agent_api_key输入框 — 从表单移除
三、提交流程
3.1 后端 — POST /api/servers/
def create_server(server_data):
# 1. 自动生成 agent_api_key
server_data.agent_api_key = secrets.token_hex(16) # 32 位 hex
# 2. 创建 server 记录
server = Server(**server_data.model_dump())
db.add(server); db.commit()
# 3. 后台异步安装 Agent
asyncio.create_task(install_agent_async(server.id))
return server
3.2 异步安装 — install_agent_async()
1. 从 DB 读取 server 信息(IP/端口/用户名/密码/目标路径)
2. SSH 连接子服务器
3. 执行命令(通过 Redis pub/sub 逐行回传):
curl -fsSL https://${NEXUS_DOMAIN}/agent/install.sh | bash -s -- \
--url http://${NEXUS_DOMAIN}:8600 \
--key <agent_api_key> \
--dirs <target_path>
4. 安装完成 → 更新 server.is_online 状态
5. Redis PUBLISH install:{server_id}:done {"ok": true}
3.3 进度传输
SSH exec_command(install_cmd)
→ stdout.readline() 逐行
→ Redis PUBLISH install:{id}:log {percent: N, line: "..."}
→ WebSocket → 前端渲染
Redis key 设计:
install:{server_id}:log— pub/sub 频道,逐行日志install:{server_id}:state— JSON{percent, status: "running|done|failed", error}
四、前端 — 服务器列表
4.1 安装进度显示
◐ web-02 [安装中 ████████░░ 80%]
↑ 点击弹出日志对话框
is_online == false && install_state == "running"→ 显示进度条- 点击进度/状态 →
install_dialog弹出,显示实时日志 - 安装完成 →
is_online = true,进度条消失,显示绿点 - WebSocket 监听
install:{id}:log,无需轮询
4.2 日志对话框
┌─ 安装日志: web-02 ──────────────────┐
│ [1/5] 安装依赖... ✓ │
│ [2/5] 创建目录... ✓ │
│ [3/5] 下载 Agent... ✓ │
│ [4/5] 配置 systemd... ✓ │
│ [5/5] 启动 Agent... ✓ │
│ ✅ 安装完成! │
│ [关闭] │
└──────────────────────────────────────┘
4.3 目标路径快速编辑
每行 target_path 旁 ✏️ 按钮:
点击 ✏️ → target_path 变为 input → 回车 → PUT /api/servers/{id} {target_path: "新路径"}
五、涉及文件
| 文件 | 变更 |
|---|---|
web/servers.php |
表单字段调整 + 安装进度 + 快捷编辑 |
server/api/servers.py |
create_server 自动生成密钥 + 异步安装入口 |
server/services/agent_installer.py |
新建 — SSH 安装 Agent + Redis 进度推送 |
server/main.py |
WebSocket 转发 install:{id}:log → 前端 |
六、错误处理
| 场景 | 处理 |
|---|---|
| SSH 连接失败 | install_state = "failed", 显示红色错误,可手动重试 |
| 安装超时(120s) | 超时自动标记失败 |
| 密钥冲突 | 重新生成,重试一次 |
| WebSocket 断开 | 重连后从 Redis 读取当前状态恢复 |
七、安装进度状态机
pending → running → done
→ failed → (手动重试)→ pending