deploy: add git-pull source for host deployment

Host can now fetch code directly from GitHub instead of receiving a VM-built tarball, bypassing the VM->host scp/kex failures and stale-tar risk. Design: VM sends only two small scripts (host_git_fetch.sh + host_deploy.sh, sha-verified via the existing transfer chain, now with a chunk_key fallback that does not need SSH_PASSWORD); host clones via a read-only deploy key (SSH only, HTTPS refused, key must exist with mode 0600), checks out the exact 40-char commit, verifies HEAD, builds a tar in the same format as the VM release (DEPLOYED_COMMIT + RELEASE.json, member names without ./ prefix so host_deploy.sh tar -O works), then calls the unchanged host_deploy.sh for staging swap, backup, health and rollback. Git fetch tolerates the known intermittent host->GitHub degradation: 120s timeout, 3 attempts, 10s sleep, live untouched until host_deploy runs. VM gates: clean tree, tests, commit must be on origin/main, SSH repo only, full sha only; --source tar remains the default. Tests: deploy suite OK, including 6 new host_git_fetch simulations (success with clean tar members, unknown commit, key permissions/missing, HTTPS refusal, short sha) and 4 new deploy.py git-mode helpers plus chunk_key fallback; git-mode dry-run verified against HEAD 630d14f.
This commit is contained in:
host committed 2026-10-29 03:37:55 +08:00
1 parent 630d14fe07
commit e8e256f6e5
5 files changed
+542 -7

No files matched your search

+37
View File
@@ -65,6 +65,43 @@ python3 deploy/deploy.py <host> --tarball <包> --skip-tests
env 文件、不打印密钥;SSH 走 key,或调用方已有的
ssh-helpers pty 通道(密码只走 `SSH_PASSWORD` 环境变量)。
## Git 直拉部署(新,--source git;tar 仍是默认)
VM 侧不再建 tar、不传大包,只传两个小脚本(`host_git_fetch.sh` +
`host_deploy.sh`)并让主机用只读 deploy key 直拉 GitHub。主机在
staging 里 checkout 精确 commit、验 HEAD、本地建包,再调已有的
`host_deploy.sh` 做换目录、备份、健康、回滚;换目录逻辑一律复用,
不复制、不漂移。tar 路径不受影响,默认仍是 tar,必须显式
`--source git` 才走 git 源。
```sh
python3 deploy/deploy.py <host> --source git
python3 deploy/deploy.py <host> --source git --dry-run
```
前提(缺一不可,缺了就拒绝、live 不动):
- **主机凭证:只读 deploy key。** 仓库是私有的,裸 https 拉不到;
HTTPS token 不在本模式内。主机上生成密钥对(私钥只放主机,
权限 0600,默认路径 `/root/.ssh/id_codex_github`),把公钥以
只读方式加到 GitHub 仓库 Settings > Deploy keys;私钥绝不进
仓库、聊天或记忆,deploy.py 只传密钥路径、不传内容。主机上
已有的 SSH 密钥若只对应其它仓库(如 hatch-frontend),拉本仓
会报 Repository not found,不能复用,必须另配本仓的 key。
- **commit 必须已推到 origin/main。** VM 侧先核 commit 在
origin/main 里,主机侧再核 checkout 后的 HEAD,两处都必须
等于期望的 40 位完整 commit;短 sha、未推的本地 HEAD、HTTPS
URL 一律拒绝。绝不只 pull main:main 在部署中途移动会重演
中途部署中断的事故。
- **间歇劣化容忍。** 主机到 GitHub 的通路间歇劣化(2026-10-26、
2026-10-29 实测:15 秒超时后 2.8 秒又通,api/codeload 正常时
github.com Web 前端仍可能超时),取包单次超时 120 秒、重试
3 次、间隔 10 秒;重试耗尽才退出,live 在此之前绝不动。取包
失败时改走 tar 路径再推一次,不要反复重试 git 源。
- **小脚本传输仍走 transfer()。** 两个脚本先经 scp、再经
chunk_key 分片(密钥版,不依赖 SSH_PASSWORD)、再经 chunk
分片(密码版),每路传完验 sha;脚本传不到,部署不开始。
## 部署:deploy.sh(旧链路,已弃用,新发布不要再用)
VM 侧运行: