# 2026-05-27 批量按钮修复 + 审计日志中文化 + terminal断开反馈 + 远程安装按钮修复 + Agent安装sudo兼容

## 变更摘要
1. 修复 servers.html 批量"安装 Agent"按钮：hasAgent 判断从 `agent_api_key_set` 改为 `agent_version`，解决未安装 Agent 的服务器按钮不可用的问题
2. 所有后端 AuditLog detail 字段统一为中文（此前混杂英文如 `name=xxx`、`WebSSH to xxx` 等）
3. audit.html 操作列和目标类型列显示中文映射（`create_server` → `添加服务器`）
4. audit.html 新增 ACTION_NAMES 覆盖所有已知 action 类型（含 webssh_token、refresh_token_mismatch 等）
5. mcp/Nexus_server.py deploy 流程修复：git pull 先于 gate check + origin/main 替代 origin/master
6. **修复详情面板"远程安装"按钮始终禁用的 bug**：`s._base_url` 不存在于服务器对象，改为从新 API `GET /api/servers/meta/api_base_url` 获取全局 `NEXUS_API_BASE_URL`
7. `api_base_url` 加入 DB_OVERRIDE_MAP，可在设置页面管理
8. 安装向导新增 `api_base_url` 写入 MySQL settings 表
9. 启动时自动迁移：若 MySQL 缺 `api_base_url` 但 `.env` 有值，自动插入
10. **Agent install.sh 非 root 用户兼容**：自动检测当前用户，非 root 时使用 `sudo` 执行 `mkdir`/`apt-get`/`systemctl`/`tee` 等特权操作，解决 Ubuntu 等非 root SSH 用户无法写入 `/opt` 的问题
11. **后端 _sudo_wrap 辅助函数**：`servers.py` 新增 `_sudo_wrap(cmd, ssh_user)` — 非 root 用户自动配置 NOPASSWD sudo（写入 `/etc/sudoers.d/nexus-agent`），命令执行后自动清理；应用于 install-agent / batch-install / upgrade-agent / batch-upgrade 共 4 个端点
12. **install.sh venv 创建 set -e 兼容**：`python3 -m venv` 在缺 `python3-venv` 的 Ubuntu 系统上返回 exit 1，`set -e` 导致脚本直接退出，apt-get 安装 python3-venv 的回退逻辑从未执行。修复：首次 venv 创建加 `|| true` 允许失败，然后检查 activate 是否存在再走回退路径

## 动机
1. 批量操作中，`agent_api_key_set=True` 不等于 Agent 已安装（只代表生成了 Key），导致武汉市风莞溪服务器（有 Key 但无 Agent）的"安装"按钮被错误禁用
2. 审计日志详情混合中英文，运维人员阅读不便
3. MCP deploy 工具先执行 gate check 再 git pull，导致 changelog/audit 文件不在磁盘上被 BLOCK
4. **详情面板"远程安装"按钮始终禁用**：`s._base_url` 是前端代码中的错误引用（`API_BASE_URL` 是全局设置，不是服务器的字段），导致所有服务器都无法远程安装 Agent
5. **非 root 用户远程安装 Agent 失败**：Ubuntu 等系统默认用户（如 `ubuntu`）无 `/opt` 写权限，install.sh 直接 `mkdir -p /opt/nexus-agent` 报 `Permission denied`
6. **install.sh venv 创建被 set -e 终止**：Ubuntu 24.04 默认未安装 `python3-venv`，`python3 -m venv` 返回 exit 1，`set -e` 导致脚本直接退出，apt-get 安装 python3-venv 的回退逻辑从未执行

## 涉及文件

### 前端
- `web/app/servers.html` — updateBatchBar() hasAgent 从 `s.agent_api_key_set` 改为 `s.agent_version`；loadAgentInstall() base_url_conf 从 `s._base_url` 改为 `_apiBaseUrl`（从新 API 加载）；新增 `loadApiBaseUrl()` 函数
- `web/app/audit.html` — 新增 ACTION_NAMES / TARGET_NAMES 中文映射（覆盖所有已知 action/target_type）
- `web/app/settings.html` — 基础设施区块新增 `api_base_url`（主站对外 URL）

### Agent 安装脚本
- `web/agent/install.sh` — 新增非 root 用户 sudo 兼容：`id -u` 检测 → `$SUDO` 变量 → `mkdir`/`apt-get`/`chown`/`tee`/`systemctl` 全部走 sudo；venv 创建加 `|| true` 兼容 set -e

### 后端
- `server/api/servers.py` — 新增 `GET /api/servers/meta/api_base_url` 端点（返回 `settings.API_BASE_URL`）
- `server/config.py` — DB_OVERRIDE_MAP 新增 `api_base_url` → `API_BASE_URL`；新增 `ensure_api_base_url_in_db()` 启动迁移方法
- `server/main.py` — 启动时调用 `settings.ensure_api_base_url_in_db(session)` 迁移现有安装的 api_base_url
- `server/api/install.py` — 安装向导 settings_kv 新增 `api_base_url`
- `server/api/auth.py` — 修改密码详情
- `server/api/servers.py` — 服务器创建/更新/删除/Agent操作详情
- `server/api/scripts.py` — 凭据/脚本操作详情
- `server/api/assets.py` — 平台/节点操作详情
- `server/api/settings.py` — 设置/调度/预设/重试操作详情
- `server/api/webssh.py` — WebSSH 连接/断开详情
- `server/api/sync_v2.py` — 文件操作详情
- `server/api/agent.py` — 长任务回调详情
- `server/background/script_execution_flush.py` — 执行刷新详情
- `server/application/services/auth_service.py` — 登录/TOTP/Token/WebSSH令牌详情
- `server/application/services/script_service.py` — 脚本/凭据/执行详情
- `server/application/services/sync_engine_v2.py` — 文件推送详情

### MCP
- `mcp/Nexus_server.py` — deploy: git pull 先于 gate check + origin/main

## 技术细节
- `agent_version` 由 Agent 心跳时写入（如 `"2.0.0"`），未安装 Agent 时为 `None`
- `agent_api_key_set` 仍保留在安装命令上下文中使用（检测是否生成了 Key，是安装的前提条件）
- `API_BASE_URL` 是全局设置（来自 `.env` 的 `NEXUS_API_BASE_URL`），不是服务器字段
- 前端通过 `GET /api/servers/meta/api_base_url` 获取值，缓存到 `_apiBaseUrl` 变量
- `api_base_url` 加入 `DB_OVERRIDE_MAP` 后，设置页面可查看/修改，MySQL 中的值会覆盖 `.env`
- 启动迁移逻辑：若 MySQL settings 表无 `api_base_url` 行但有 `.env` 值，自动插入（仅一次）
- 前端 ACTION_NAMES 映射覆盖所有已知 action 类型，未知 action 仍显示原始英文值
- 历史数据（已存入 MySQL 的 detail）不会追溯更改，仅新操作生效
- MCP deploy 流程：git pull → gate check → supervisorctl restart
- install.sh sudo 兼容：`id -u == 0` 时 `SUDO=""`，否则检查 `sudo` 可用性；`$SUDO mkdir -p /opt/nexus-agent` + `$SUDO chown` 给当前用户 → 后续 venv/pip 无需 sudo；`$SUDO tee /etc/systemd/system/nexus-agent.service` + `$SUDO systemctl` 处理 systemd 操作
- install.sh venv `set -e` 兼容：首次 `python3 -m venv` 加 `2>/dev/null || true`，允许在缺 `python3-venv` 时失败不退出；然后检查 `.venv/bin/activate` 是否存在，不存在则 `$SUDO apt-get install python3-venv` 后重试

## 需要迁移/重启
- 是：后端 Python 需重启（新端点 + 启动迁移逻辑 + DB_OVERRIDE_MAP 变更）
- 否：无数据库 schema 迁移（仅向 settings 表插入一行）

## 验证方式
1. 选择未安装 Agent 的服务器 → "安装 Agent" 按钮可点击 ✅
2. 选择已安装 Agent 的服务器 → "升级 Agent" 按钮可点击 ✅
3. 审计日志页面操作列显示中文 ✅
4. 新操作审计日志详情显示中文 ✅
5. MCP deploy 工具流程正确（git pull 先于 gate check）✅
6. 详情面板：有 agent_api_key 的服务器 → "远程安装"按钮可用 ✅
7. 详情面板：无 API Key 的服务器 → 显示"请先生成 Key"警告 ✅
8. 设置页面 → 基础设施区块显示"主站对外 URL" ✅
9. 启动日志 → 显示 "Migrated api_base_url to MySQL settings table" ✅
10. 非 root 用户远程安装 Agent → install.sh 自动使用 sudo，`/opt/nexus-agent` 创建成功 ✅
11. root 用户远程安装 Agent → install.sh 无 sudo 前缀，行为不变 ✅
12. 缺 python3-venv 的 Ubuntu → install.sh 自动 apt-get install python3-venv 后重试 ✅

## 进度条
☑实现 ☑WSL验证 ☑审计8步 ☑部署 ☑健康检查 ☑浏览器验证 ☑changelog
