# Changelog — 2026-06-11 rsync 推送非 root 自动 sudo 提权

## 摘要

文件推送（rsync）与文件管理对齐：**非 root SSH 用户**在默认 `files_elevation=auto_sudo` 下，远程接收端自动使用 `sudo -n rsync`，不再裸连导致宝塔 `www:www` 站点目录 Permission denied。

## 动机

- 用户反馈：温胜夜两台子机推送失败，诊断 `touch` 权限被拒绝
- 产品设计已定：除 root 外默认 `auto_sudo` 自动提权；此前 rsync 推送未接入该策略

## 变更

| 文件 | 说明 |
|------|------|
| `server/utils/rsync_elevation.py` | 非 root 且非 `off` → `--rsync-path=sudo -n rsync` |
| `server/application/services/sync_engine_v2.py` | `_rsync_push` 接入提权；日志含 `rsync=sudo` |
| `server/api/sync_v2.py` | 诊断写入测试走 `exec_ssh_command_with_fallback` |
| `server/api/servers.py` | `setup-files-sudo` 模板增加 rsync |
| `docs/deploy/nexus-files-sudoers.example` | 增加 rsync |
| `server/infrastructure/ssh/files_capability.py` | 白名单探测含 rsync，提示推送 |
| `scripts/batch_patch_files_sudoers.py` | 批量补全 sudoers（含 rsync） |
| `scripts/batch_patch_files_sudoers.sh` | 包装入口 |
| `tests/test_nexus_files_sudoers.py` | 模板单测 |

## 迁移 / 重启

- 需重启 API / 重建 Docker 镜像
- **目标机**：已有 `nexus-files` sudoers 须补 `/usr/bin/rsync`（或重新点「一键配置 sudo」）
- 无 DB 迁移

## 验证

```bash
pytest tests/test_rsync_elevation.py tests/test_nexus_files_sudoers.py tests/test_rsync_push_permissions.py -q
bash scripts/batch_patch_files_sudoers.sh --name 温胜夜
```

部署后：非 root 服务器推送 → `sync_logs.push_permission` 含 `rsync=sudo`；诊断写入 ✓（或 `path_elevated=true`）。

## 回滚

Revert 上述文件；推送恢复为仅 root 可写 www 目录（或手动 chmod）。
