feat(chv-guest): 轻量镜像 + Gitea 双向同步(停全量版,改 Ubuntu Minimal)
- build.sh 改轻量:Ubuntu Minimal 底座、apt 精简(git/ssh/cloud-init/
python3/pip/curl/ca-certificates/xz-utils/fonts-wqy-microhei)、
Playwright + chromium-headless-shell、去 B-16 +12G 扩盘;
加 git + gt 1.0.0(官方 install.sh + SHA256 校验,GITEA_CLI_VERSION
钉 1.0.0)与 chv-sync 启动钩子(cloud-init runcmd)
- B-19(新发现):dpkg freeze 的 ${Package} 会被客机 shell 展开
成空,284 行全空白;加反斜杠转义,探针实测已出真实版本
- buildinfo.py:轻量 contents、chromium-headless-shell、gt_version
- generate/check_lockfile.py:gt/chv-sync 声明来源、headless-shell 映射
- chv-sync.sh(新):boot/pull/push/status,分叉/脏树失败关闭,
凭证走 seed 盘 guest-env,不进镜像
- README §1/§2/§3/§4 改轻量口径,新增 §7 Gitea 双向同步
- tests:ChvSyncTest 6 项(本地 bare 仓当远端);针对性测试 144 项全过
This commit is contained in:
1 parent
9e60d5dfaa
commit
4d09518338
7 files changed
+452
-73
No files matched your search
+54
-16
@@ -10,8 +10,10 @@
|
||||
|
||||
## 1. 镜像定位
|
||||
|
||||
- 基础:Ubuntu 云镜像(与 `cloud/docker/Dockerfile` 的任务镜像
|
||||
对齐能力,不是另起一套环境口径)。
|
||||
- 基础:Ubuntu Minimal 24.04 官方云镜像(轻量口径,2026-11-06
|
||||
用户定:停掉 5.5G 全量版,不再对齐 Manus,不做三面板/
|
||||
多租户/生产级全套;只装 codex + Python + SSH + cloud-init
|
||||
+ 薄客机 agent + git + gt + 最小中文字体)。
|
||||
- 载体:Cloud Hypervisor 直接内核启动(vmlinux)+ raw 磁盘
|
||||
镜像,执行器用 `CHV_KERNEL` / `CHV_ROOTFS` 指向它们。
|
||||
- 客内 host.py 位置:`/app/host.py`(与 Docker 的 `/app:ro`
|
||||
@@ -21,20 +23,22 @@
|
||||
生产凭证。模型 key 由客机 cloud-init 预置的运行环境变量名
|
||||
注入(与 Docker 的 `-e <名>` 同款惯例),不写进镜像层。
|
||||
|
||||
## 2. 内容清单(按现有 Docker 任务镜像能力对齐)
|
||||
## 2. 内容清单(轻量口径,2026-11-06 用户定)
|
||||
|
||||
| 类别 | 内容 | 来源/版本口径 |
|
||||
| --- | --- | --- |
|
||||
| 语言与工具链 | Python 3.12、git(Node.js 不装:Playwright 驱动是 Python playwright,见 PLAYWRIGHT=1 分支;任务镜像 Dockerfile 里也没有 Node.js,本清单不虚构它) | 与任务镜像同款大版本,构建时钉小版本并记入构建日志 |
|
||||
| 文档/图片工具 | pandoc、poppler-utils(pdftotext)、latexmk、texlive-latex-base、python-docx、openpyxl、python-pptx、PyMuPDF、Pillow | 逐项照抄 `cloud/docker/Dockerfile` 的 apt/pip 清单,不擅自加减 |
|
||||
| 语言与工具链 | Python 3.12、git、curl、ca-certificates、xz-utils(Node.js 不装:Playwright 驱动是 Python playwright,见 PLAYWRIGHT=1 分支;任务镜像 Dockerfile 里也没有 Node.js,本清单不虚构它) | 构建时钉小版本并记入构建日志 |
|
||||
| 文档/图片工具 | 已裁剪:pandoc、poppler-utils、latexmk、texlive-latex-base、python-docx、openpyxl、python-pptx、PyMuPDF、Pillow 不在轻量镜像内 | 全量版曾照抄 `cloud/docker/Dockerfile` 的 apt/pip 清单,轻量版按用户决定砍掉 |
|
||||
| agent 引擎 | codex、codex-code-mode-host、codex-resources/bwrap(成套,约 367M,缺 sibling 直接构建失败) | codex 0.164.0-alpha.9(与生产任务镜像一致);`CODEX_BIN_DIR` 由构建方提供,bin/ 不进仓库 |
|
||||
| 浏览器 | Playwright + Chromium(浏览器自动化 MCP 用,PLAYWRIGHT=1 时才装) | Python playwright 装当时的 Chromium,未在 BUILDINFO 里钉浏览器版本——这是已知缺口,不是已钉死 |
|
||||
| 客机基础 | openssh-server(SSH 通道用)、cloud-init、qemu-guest-agent(可选,宿主信息用) | sshd 只允许 key 登录,禁止密码登录——build.sh 写入 /etc/ssh/sshd_config.d/99-chv.conf 并经 sshd -t + grep 断言(feat-chv-secfix,M8,此前只是文档声称) |
|
||||
| 浏览器 | Playwright + chromium-headless-shell(默认装,不要完整 Chromium) | Python playwright 装当时的 headless-shell,版本以 ms-playwright 缓存目录名记入 BUILDINFO.versions.chromium |
|
||||
| 客机基础 | openssh-server(SSH 通道用)、cloud-init(qemu-guest-agent 已裁剪,CHV 不用它) | sshd 只允许 key 登录,禁止密码登录——build.sh 写入 /etc/ssh/sshd_config.d/99-chv.conf 并经 sshd -t + grep 断言(feat-chv-secfix,M8,此前只是文档声称) |
|
||||
| Gitea 同步 | gt 1.0.0(官方 install.sh + SHA256 校验)、chv-sync(启动时 clone、显式 pull/push 的同步脚本) | 凭证走 seed 盘 /etc/chv/guest-env(0600)投递,不进镜像;见 §7 |
|
||||
| 任务代码 | codex-app-server 仓库代码置于 `/app`(host.py 入口) | 版本见 §3,不挂载宿主代码目录(VM 与宿主无共享路径) |
|
||||
|
||||
中文 LaTeX 说明:与 Docker 镜像同款口径——xelatex + CJK
|
||||
字体会再增数百 MB,本清单不默认包含;需要时单独一版镜像,
|
||||
不在本轨悄悄加。
|
||||
不在本轨悄悄加。字体只留最小的 fonts-wqy-microhei(中文能
|
||||
看),不要全套 fonts-noto-cjk。
|
||||
|
||||
## 3. 版本化
|
||||
|
||||
@@ -52,21 +56,24 @@ chv-guest-<ubuntu 版本>-<codex 版本>-<仓库 commit 短 hash>
|
||||
- `vmlinux`(与 Ubuntu 云镜像配套的内核)
|
||||
- `disk.raw`(根文件系统镜像)
|
||||
- `BUILDINFO.json`:`{ubuntu, codex_version, repo_commit, built_at,
|
||||
contents: [清单逐项名]}`——注意:build.sh 生成的 contents 只有
|
||||
名字列表,没有逐项版本号(feat-chv-fix 纠正 §3 旧措辞);
|
||||
逐项版本只留在构建日志里,未进 BUILDINFO,这是已知缺口。
|
||||
contents: [清单逐项名]}`——contents 只有名字列表;逐项版本
|
||||
在 `versions` 里(B-02:dpkg + pip freeze 从客机读回,
|
||||
chromium 以 ms-playwright 缓存目录名记,gt 以 gt_version 记),
|
||||
`generate_lockfile.py` / `check_lockfile.py` 以它为唯一来源。
|
||||
|
||||
## 4. 构建脚本(补缺口轨:已从骨架改成真实步骤)
|
||||
|
||||
见 `build.sh`:参数校验 → 下载 Ubuntu 云镜像 → qemu-img
|
||||
转 raw → virt-customize 装 §2 清单、拷入 codex 成套二进制
|
||||
与仓库代码到 /app、写 host key 不重生成配置 →
|
||||
见 `build.sh`:参数校验 → 下载 Ubuntu Minimal 云镜像(SHA256
|
||||
必填)→ qemu-img 转 raw(轻量版不扩盘,底座根分区 2.4G 够用;
|
||||
全量版 B-16 的 +12G 扩盘已删除)→ virt-customize 装 §2 清单、
|
||||
拷入 codex 成套二进制与仓库代码到 /app、装 gt 1.0.0、拷入
|
||||
chv-sync 并写 cloud-init 启动钩子、写 host key 不重生成配置 →
|
||||
virt-get-kernel 取内核 → 生成并校验 BUILDINFO.json。
|
||||
`./build.sh --dry-run out/` 只打印命令、不执行、不要求
|
||||
KVM;全量模式在无 /dev/kvm 的机器上第一步就明确退出
|
||||
(`CHV_GUEST_BUILD needs a KVM host`),绝不假装构建成功。
|
||||
本轨未在真机上跑过全量模式,镜像未建成、未发布,仍属
|
||||
“需 KVM 宿主实测”项。
|
||||
全量版曾在 WSL KVM 宿主(ajpkmq6i)上跑过四轮真机构建,
|
||||
轻量版沿用同一宿主与流程,构建记录见 `~/workspace/chv-prod-audit/`。
|
||||
|
||||
## 5. Host key 首启注入硬性要求(补缺口轨新增)
|
||||
|
||||
@@ -99,3 +106,34 @@ KVM;全量模式在无 /dev/kvm 的机器上第一步就明确退出
|
||||
磁盘,任务之间文件系统独立;reuse 模式仅单租户实验,preflight 拦截(须同时设 CHV_REUSE_SINGLE_TENANT_EXPERIMENT=1 并审计放行,feat-chv-fix)。
|
||||
- 快照基准:`CHV_SNAPSHOT_URL` 指向的快照必须由本镜像的干净
|
||||
启动状态制成(pause 后 snapshot),预热池用它做干净 VM 来源。
|
||||
|
||||
## 7. Gitea 双向同步(用户工作区口径,2026-11-06 追加)
|
||||
|
||||
主角是用户,不是 agent:用户在 Gitea 上的仓库在 VM 启动时
|
||||
clone 到 `~/workspace`,用完再同步回 Gitea;VM 是用户的工作
|
||||
区,Gitea 是权威远端。同步口径沿用 Git Workspace Platform
|
||||
已定的规则:分叉或冲突时失败关闭,不强制覆盖、不自动
|
||||
rebase、不静默丢提交。
|
||||
|
||||
- 凭证:seed 盘投递 `/etc/chv/guest-env`(0600,root 所有),
|
||||
含 `GITEA_URL` / `GITEA_USER` / `GITEA_TOKEN` / `SYNC_REPO`
|
||||
/ 可选 `SYNC_BRANCH` / 可选 `GITEA_EMAIL`。token 绝不进镜像、
|
||||
代码、日志;`chv-sync boot`(root,cloud-init runcmd 调)把
|
||||
token 写进 `/home/chv/.git-credentials`(0600,git credential
|
||||
store 标准机制),再以 chv 身份 clone;`pull` / `push` /
|
||||
`status` 以 chv 身份跑,只用已落盘的 credential,不再读
|
||||
guest-env。无 guest-env 的启动静默不同步,VM 照常用。
|
||||
- 行为:`boot` 只在未 clone 时 clone,已 clone 则静默退出,
|
||||
不自动 pull(避免重启时覆盖进行中的工作);`pull` 要求
|
||||
工作树干净且只接受 fast-forward;`push` 无 upstream 时
|
||||
`push -u origin HEAD`,否则普通 push,非 fast-forward 即
|
||||
失败,绝不 `--force`。
|
||||
- gt 1.0.0 随镜像装好(官方 install.sh + SHA256 校验),登录
|
||||
不 baked:运行时用 `GITEA_TOKEN` + `GITEA_CLI_HOST` 环境变量
|
||||
即可用(`gt repo list` 等),或在 VM 里 `gt auth login`。
|
||||
- 验收(用户视角):VM 启动后仓在 `~/workspace` 且是最新
|
||||
HEAD;VM 内改文件 commit push 后 Gitea 网页可见该提交;
|
||||
Gitea 上改一次后 VM 内 pull 能同步回来。双向都通才算集成通。
|
||||
- 残留:执行器生成 seed 时自动写 guest-env 的集成未做(本轨
|
||||
验收用手工 seed 测通链路);专用 token 与测试仓名须用户给,
|
||||
本轨不自编 token、不动生产 Gitea 配置。
|
||||
Reference in new issue
Block a user