bug(kubernetes): sandbox stuck at `Provisioning` with `replicas: 0` has no recovery path (`start`/`stop` both refuse)
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
研究方向
Start with the phase gate in start_sandbox in crates/openshell-server/src/compute/mod.rs (~L1784) and the reconcile fallthrough near derive_phase (~L6863), then see how crates/openshell-driver-kubernetes/src/driver.rs suspend_sandbox_runtime_after_dependency_failure (~L4111) sets replicas to 0. Done means a sandbox stuck in Provisioning with an empty backend either gets corrected by reconcile or can be started through the idempotent-restart path, with the workspace PVC kept. The issue offers two directions, so agree the approach with maintainers before coding.
由索引模型根據 Issue 內容生成。
描述
Summary
A sandbox can end up with the gateway's Sandbox record at phase Provisioning
while the backend Sandbox CR is at spec.replicas: 0 with no pod. In that state
there is no supported recovery path:
sandbox startis rejected — the phase gate only admitsStopped,
Completed,Starting, a failed-main-processError, or a provisioning timeout.sandbox stopis rejected — it requiresReady.- The reconcile sweep does not correct the record: with
replicas: 0/ no pod, the
Provisioningcase falls through to the reconcile/derive_phasedefault and the
stale value is perpetuated rather than corrected.
The only exits are delete + recreate, or out-of-band edits to the gateway's store.
This is a distinct variant of the "unrecoverable phase" bugs #3308
and #4209, which are Error-phase. Here the record is
Provisioning, so the recovery work in #4231 (allow stop from
Error) does not reach it, and start still rejects it. The closest mechanism match is
#2932 (a stale condition perpetuated by reconcile), fixed by
#2933.
Environment
- OpenShell:
0.1.2(gatewayghcr.io/nvidia/openshell/gateway:0.1.2, supervisor0.1.2, CLI0.1.2) - Driver: Kubernetes (agent-sandbox
v0.4.6, CRDsandboxes.agents.x-k8s.iov1alpha1) - Kubernetes:
v1.27.3(kind)
Reproduction
Non-deterministic (a race). Observed triggers:
- A node/machine reboot while the gateway is bootstrapping a sandbox — the gateway pod
restarts during cluster stabilization, and a transient dependency failure fires
suspend_sandbox_runtime_after_dependency_failure, resettingreplicas: 0while the
record is stillProvisioning. - A
stopimmediately followed bystart, leaving the record mid-transition.
Observed state
$ openshell sandbox list
NAME ... Provisioning
$ kubectl get sandboxes -n <ns> -o yaml
# spec.replicas: 0
# no openshell.ai/sandbox-runtime-bootstrapping annotation
# (no sandbox pod in the namespace)
$ openshell sandbox start <name>
Error: sandbox must be Stopped, Completed, or a failed main-process Error to start (current phase: Provisioning)
$ openshell sandbox stop <name>
Error: sandbox must be Ready to stop (current phase: Provisioning)
Root cause (pointers; as of e1f3c82ca)
- The record's
status.phaseisProvisioningbut the backend CR is empty.
start_sandboxrejects it because the gate only admits
Stopped | Completed | Starting | is_failed_main_process_result | provisioning_timeout
(crates/openshell-server/src/compute/mod.rs,start_sandbox, ~L1784). - The reconcile sweep re-derives phase from the driver snapshot; with no pod /
replicas: 0, theProvisioningcase falls through to the_ => phasedefault
(~L6564, fed byderive_phase~L6863), so the stale value is kept. suspend_sandbox_runtime_after_dependency_failure
(crates/openshell-driver-kubernetes/src/driver.rs, ~L4111) is what drives
replicas: 0on the dependency-failure path.
Expected
One of:
- The reconcile loop corrects a
Provisioningrecord whose backend reports the
sandbox as empty (no pod /replicas: 0) instead of perpetuating it — cf. #2933, which
madederive_phaseletReadywin over a staleSuspended; or startaccepts a staleProvisioningwhose backend is empty and routes it through the
existing idempotent-restart path — reusing the persisted identity and re-attaching the
existing workspace PVC — the same way theStartingbranch already does (~L1800).
Actual
No recovery short of delete + recreate. An out-of-band edit of the gateway store
(flipping Sandbox.status.phase from Provisioning to Stopped) does make start
succeed and preserves the workspace — confirming this is a fixable record desync rather
than data loss — but it is not a supported operator path.
Proposed direction
- Extend #4231's recovery approach to the
Provisioning-with-empty-backend case (not
justError), or - correct the stale
Provisioninginderive_phase/reconcile (precedent: #2933).
Either way, start from this state should reuse the persisted identity and the existing
workspace PVC (idempotent restart), not require a delete.
References
- #3308 — unrecoverable
Error, stop/start refuse (same symptom class) - #4209 — gateway restart → unrecoverable
Error(same trigger family) - #4231 — open: allow stopping errored sandboxes for recovery (in-flight recovery mechanism)
- #2932 / #2933 — stale condition perpetuated by reconcile; fix in
derive_phase(closest mechanism) - #4078 — serialize lifecycle cleanup with sandbox restart (related stop/start race)
- 主要語言
- Rust
- 星號
- 16.3k
- 分支
- 1.8k
- 平均合併
- 2 天 5 小時
- 30 天內合併 PR
- 383
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
NVIDIA/OpenShell 的其他 Issue
-
bug(sdk/go): browser login callback binds 127.0.0.1 but redirect_uri uses localhost可能重新可做 關聯的 PR 已關閉且未合併。 未關閉state:triage-needed
難度 2/5 1-3 小時 新手友好度 65/100
NVIDIA/OpenShell#4518 · 1 則留言 ·
維護者通常 1 天內回覆
-
state:triage-needed
難度 2/5 1-3 小時 新手友好度 62/100
維護者通常 1 天內回覆
-
bug(sdk/go): edge (Cloudflare Access) token is cached for the client lifetime and never reloaded未關閉state:triage-needed
難度 2/5 1-3 小時 新手友好度 72/100
NVIDIA/OpenShell#4515 · 1 則留言 ·
維護者通常 1 天內回覆
-
state:triage-needed
難度 2/5 1-3 小時 新手友好度 72/100
NVIDIA/OpenShell#4509 · 1 則留言 ·
維護者通常 1 天內回覆
-
state:triage-needed
難度 2/5 1-3 小時 新手友好度 76/100
維護者通常 1 天內回覆
相似的 Issue
-
area:ecosystem documentation
難度 2/5 1-3 小時 新手友好度 78/100
Chelis-Lang/chelis#3866 ·
維護者通常 1 天內回覆
-
enhancement
難度 2/5 1-3 小時 新手友好度 68/100
metasequoiaime/msime#8620 ·
維護者通常 1 天內回覆
-
agent-detection macos p2 triaged
難度 1/5 1 小時以內 新手友好度 90/100
維護者通常 1 天內回覆
-
bug documentation sev-0
難度 2/5 1-3 小時 新手友好度 72/100
-
難度 2/5 1-3 小時 新手友好度 86/100
維護者通常 1 天內回覆