fix: Agent 升级命令添加 sudo 前缀(非 root 用户)

systemctl restart 需要 root 权限,非 root SSH 用户必须加 sudo。
之前 _sudo_wrap 只设置了免密 sudoers 但命令本身没带 sudo,
导致升级时 "Interactive authentication required" 失败。
同时修复单台升级和批量升级的 rollback 命令。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-05-30 14:28:49 +08:00
parent deffa8a8f4
commit 913fd16bb9
+9 -6
View File
@@ -655,6 +655,7 @@ async def batch_upgrade_agent(
install_dir = "/opt/nexus-agent"
venv_python = f"{install_dir}/.venv/bin/python"
ssh_user = (server.username or "root").strip()
batch_systemctl_prefix = "sudo " if ssh_user != "root" else ""
upgrade_cmd = _sudo_wrap(
f"(command -v rsync >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y -qq rsync) || (yum install -y -q rsync) || (dnf install -y -q rsync)) "
@@ -662,9 +663,9 @@ async def batch_upgrade_agent(
f"&& {venv_python} -m pip install -q fastapi==0.115.6 uvicorn==0.34.0 httpx==0.28.1 psutil python-multipart==0.0.19 "
f"&& cp {install_dir}/agent.py {install_dir}/agent.py.bak "
f"&& curl -fsSL {shlex.quote(agent_url)} -o {install_dir}/agent.py "
f"&& systemctl restart nexus-agent "
f"&& {batch_systemctl_prefix}systemctl restart nexus-agent "
f"&& sleep 2 "
f"&& systemctl is-active nexus-agent "
f"&& {batch_systemctl_prefix}systemctl is-active nexus-agent "
f"&& echo 'upgrade_ok'",
ssh_user,
)
@@ -675,7 +676,7 @@ async def batch_upgrade_agent(
# Attempt rollback
try:
rollback = _sudo_wrap(
f"cp {install_dir}/agent.py.bak {install_dir}/agent.py && systemctl restart nexus-agent",
f"cp {install_dir}/agent.py.bak {install_dir}/agent.py && {batch_systemctl_prefix}systemctl restart nexus-agent",
ssh_user,
)
await exec_ssh_command(server, rollback, timeout=30)
@@ -1427,13 +1428,15 @@ async def upgrade_agent(
backup_cmd = f"cp {install_dir}/agent.py {install_dir}/agent.py.bak"
# Step 4: pip install + backup + download new agent.py → restart service
# For non-root users, systemctl needs sudo (even after _sudo_wrap sets up NOPASSWD)
systemctl_prefix = "sudo " if ssh_user != "root" else ""
upgrade_cmd = _sudo_wrap(
f"{pip_cmd} "
f"&& {backup_cmd} "
f"&& curl -fsSL {shlex.quote(agent_url)} -o {install_dir}/agent.py "
f"&& systemctl restart nexus-agent "
f"&& {systemctl_prefix}systemctl restart nexus-agent "
f"&& sleep 2 "
f"&& systemctl is-active nexus-agent "
f"&& {systemctl_prefix}systemctl is-active nexus-agent "
f"&& echo 'upgrade_ok'",
ssh_user,
)
@@ -1449,7 +1452,7 @@ async def upgrade_agent(
# Rollback: restore backup and restart
rollback_cmd = _sudo_wrap(
f"cp {install_dir}/agent.py.bak {install_dir}/agent.py "
f"&& systemctl restart nexus-agent",
f"&& {systemctl_prefix}systemctl restart nexus-agent",
ssh_user,
)
try: