# 宝塔 bootstrap:真安装检测 + config 目录自愈 **日期**:2026-07-08 ## 摘要 SSH bootstrap 写 `api.json` 前校验 `class/common.py` 存在(空 `panel` 目录不再误判为已装宝塔);写盘前 `makedirs` config 目录,避免 `FileNotFoundError` 被归类为模糊的 `ssh_command_failed`。 ## 动机 新机 **山西鑫途汇**(`42.193.230.144`)入库时仅有空 `/www/server/panel/`,一键登录反复 `ssh_command_failed`;同公司 M 机宝塔正常。根因是远程脚本只检查 `panel` 目录存在,写 `config/api.json` 时父目录缺失崩溃。 ## 涉及文件 - `server/infrastructure/btpanel/ssh_bootstrap.py` — `common.py` 检测、`os.makedirs` config - `tests/test_btpanel_ssh_bootstrap.py` — 远程脚本断言 ## 迁移 / 重启 仅后端;`rsync-local-to-server.sh` + Docker `upgrade --skip-git`。 ## 验证 ```bash .venv/bin/pytest tests/test_btpanel_ssh_bootstrap.py -q ``` 生产:对 `bt_installed=false` 的机器一键登录应返回 `bt_not_installed`(installing 状态),不再 `ssh_command_failed`。 ## 2026-07-08 热修(回归) - **根因**:2026-06-21「一键登录自动 bootstrap」在 `bootstrap` 失败时直接 `raise`,不再走 SSH `tools.py` 临时登录;新机 API 未就绪时整链中断。 - **修复**:`create_login_url` 对非凭据类 bootstrap 错误(如 `ssh_command_failed`)记录 warning 后 **继续 SSH 回退**;仅 `ssh_auth_failed` / `ssh_no_credentials` 等硬失败仍中断。