.agents/design/core/ai/sandbox/opensandbox-pvc-lifecycle.md
状态:已完成
最后核对:2026-08-04
OpenSandbox 的 Kubernetes 归档链路存在真实竞态,但不是两个同名 PVC 会同时存在。旧 PVC
处于 Terminating 时,Kubernetes 不会让引用它的新 Pod 正常运行;PVC 对象删除也不等于
PV、VolumeAttachment 或存储后端已经完成卸载。
原实现把 DELETE 的 2xx 当作删除完成、把任意 GET 200 当作可用 PVC,并在 lifecycle lease 外
预取 restore volume 配置,因此可能过早发布 archived 或把正在删除的 claim 带入恢复。
remove() 返回时,调用开始时锁定的 PVC UID 已消失或已被新 UID 替换。ensure() 不返回带 deletionTimestamp 的 PVC。archived。只读取 metadata.uid 和 metadata.deletionTimestamp,统一转换为 absent、active(uid)、
deleting(uid)。
ensure:活动 PVC 直接复用;删除中的 PVC 等待目标 UID 消失或被替换后重新读取;不存在时
创建,201 返回成功,409 退避后重读,其他错误立即失败。
remove:不存在幂等成功;删除中的 PVC 等待目标 UID 结束;活动 PVC 使用 UID precondition
删除,并等待目标 UID 消失或被替换。默认最长等待 5 分钟、轮询间隔 500 毫秒,超时交给上层
durable lifecycle 记录失败并重试。
archive 阶段:
claimed -> archiveUploaded -> providerDeleted -> volumeDeleted -> archived
providerDeleted 只删除 Provider。volumeDeleted 删除并等待 OpenSandbox volume;其他 Provider 通过空操作完成该 checkpoint。providerDeleted 时,重试会继续 volume 删除,不重放归档上传。restore 不再在调用 restore 前预取 volume。创建恢复 Sandbox 的 step 在 lease、状态重读和
operation claim 完成后调用 getSessionVolumeConfig();恢复函数返回实际 VolumeManagerResult,
runtime client 直接复用。若恢复没有执行创建 step,再在外层获取当前配置。
sessionId 切换为 app 预先持久化的 claimName;FastGPT app
与 volume-manager 按同一版本整体升级,不支持混用版本。DockerVolumeDriver 不执行 Kubernetes 状态解析、轮询或 UID precondition。opensandbox 使用 volume-manager;Docker 不产生额外 volume 请求。git diff --check。claimName HTTP 合同不增加旧版
sessionId 兼容层。VM_VOLUME_NAME_PREFIX 配置需以原值迁移到
AGENT_SANDBOX_OPENSANDBOX_VOLUME_NAME_PREFIX。running 快路径只能在 Mongo 中的 storage 与 client 预读 storage 一致时刷新活跃时间,并且不能 通过 touch 回写 storage。若 CAS 失败,必须进入 lifecycle lease,在锁内重读实例,并以当前已提交的 workspace claim 重建 OpenSandbox provider。这样旧 client 既不能覆盖 restore 提交的新 generation, 也不能继续用旧 generation 自愈远端资源。
旧版本可能停在 legacyMigrating/targetEnsured,但尚未把旧确定性 volume 名写入 storage。新版本
检测到该 checkpoint 且缺少 workspace claim 时,按旧命名规则恢复 claim,并以同阶段 CAS 原子补写
storage,再继续安装归档。claimed 阶段仍使用 generation 0 的新命名规则。
AGENT_SANDBOX_OPENSANDBOX_IMAGE 是 OpenSandbox 唯一的运行态镜像配置入口,必须配置完整镜像地址(包括
tag)。AGENT_SANDBOX_OPENSANDBOX_IMAGE_REPO 和 AGENT_SANDBOX_OPENSANDBOX_IMAGE_TAG 已移除,不再作为
兼容回退;启用 opensandbox 时缺少完整镜像变量必须阻止服务启动。
claimName 由 app 生成并持久化,volume-manager 不恢复 VM_VOLUME_NAME_PREFIX 配置,也不参与
命名或资源归属判断。volumeNamePrefix 只用于生成新 generation 的 claimName;删除时直接使用 Mongo 中持久化的
完整 claimName,不依赖当前 prefix 配置。这样配置变更不会阻断旧 PVC 的清理。targetEnsured checkpoint 缺少 storage 的恢复路径。