Files
Nexus/docs/design/specs/2026-05-17-server-add-optimize-design.md
T
Your Name c9a99f4fb3 fix: 全项目文档对齐 + 代码清理
代码修复:
- 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>
2026-05-22 08:19:56 +08:00

145 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
**状态**: 已确认
## 一、需求
1. Agent API 密钥自动生成,不显示在表单
2. 密码预设下拉联动修复
3. 添加服务器后自动 SSH 安装 Agent,实时回传日志
4. 表单新增目标路径字段(必填)
5. 目标路径在列表可快速编辑
## 二、表单改造
### 字段变更
| 字段 | 变更 |
|------|------|
| 名称 | 保持 |
| 域名/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/`
```python
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` 旁 ✏️ 按钮:
```js
点击 ✏️ 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
```