fix(1panel): 安装向导脱敏、配置一致性与 nx update 门控回滚

- /state 白名单脱敏;init-db db_port 修复;connection-check 后清空 redis_pass
- install.html sessionStorage token 与无 token 友好提示
- nx update: 镜像 import 门控、健康失败自动回滚、PENDING=0 回写、卷双写
- Redis 容器改名密码迁移;备份失败默认 WARN;update.sh 管道 ROOT 回退
This commit is contained in:
Nexus Deploy
2026-06-06 17:40:30 +08:00
parent 850038a3ec
commit 5a56e5a8cb
14 changed files with 557 additions and 48 deletions
+50 -1
View File
@@ -783,6 +783,53 @@ def _configure_guardian(install_dir: str, api_port: str) -> list[str]:
return results
_INSTALL_STATE_PUBLIC_KEYS = frozenset({
"step",
"system_name",
"db_host",
"db_port",
"db_name",
"db_user",
"redis_host",
"redis_port",
"redis_db",
"site_url",
"api_port",
"pool_size",
"max_overflow",
"install_dir",
"docker_mode",
"guardian_results",
"installed",
"locked",
"has_token",
})
def _public_install_state(state: dict) -> dict:
"""Return install state safe for GET /state (no install_token or redis_pass)."""
out = {k: state[k] for k in _INSTALL_STATE_PUBLIC_KEYS if k in state}
if state.get("install_token"):
out["has_token"] = True
return out
def _clear_state_redis_pass() -> None:
"""Remove redis_pass from install state after connection-check repair wrote .env."""
if not STATE_FILE.is_file():
return
import json
try:
state = json.loads(read_utf8_text(STATE_FILE))
except (json.JSONDecodeError, OSError):
return
if not state.get("redis_pass"):
return
state["redis_pass"] = ""
write_utf8_lf(STATE_FILE, json.dumps(state, ensure_ascii=False) + "\n")
def _finalize_install_lock() -> None:
"""Write install lock marker and remove wizard state file."""
_sync_env_to_persist_volume()
@@ -985,6 +1032,7 @@ async def connection_check():
if resolved != redis_url and not _is_locked():
_patch_env_redis_url(resolved)
redis_repaired = True
_clear_state_redis_pass()
redis_ok, redis_msg = True, msg
resolved_display = _mask_redis_url(resolved)
@@ -1008,6 +1056,7 @@ async def init_db(req: InitDbRequest):
db_url = _make_db_url(req)
site_url = req.site_url.rstrip("/") if req.site_url else f"http://127.0.0.1:{req.api_port}"
db_port = int(req.db_port)
checks, cred_ok, redis_url = await _credential_checks(req)
if not cred_ok:
@@ -1318,6 +1367,6 @@ async def get_install_state():
state = json.loads(read_utf8_text(STATE_FILE))
state["installed"] = _is_installed()
state["locked"] = _is_locked()
return state
return _public_install_state(state)
except Exception:
return {"step": 1, "installed": _is_installed(), "locked": _is_locked()}