Repository navigation
fix(console): name a sandbox driver outage and confirm a full pod quota - #2686
Conversation
…ver outage The Pod quota pending reason now requires the refused ResourceQuota's status to still show every Pod used (finding 1623). GET /installation marks an empty OpenClaw mode list caused by a Sandbox Driver outage with openclaw.sandboxDriverUnavailable, and Create Agent says to retry instead of reconfiguring (finding 1624). Pre-discovery hints, the capability description and docs no longer promise both OpenClaw modes (finding 1625). Tests cover the Embedded and Sandbox-provisioned Harness skips of the quota check and move the provisioning outage test's retry cancellation into teardown.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Update on The small patch below lets your existing, specific refusal own the explanation. The summary says only that the selected mode is unavailable; the contradictory draft/deploy promise clears. No second copy of the driver, Preset, or permission decision. The new assertions failed on the published UI and passed with this patch. A separate positive control returned Embedded as genuinely available and confirmed the original summary and draft explanation remain. This is a browser copy result with local fixture and controlled Installation shapes, not a live provider, write-path, or whole-PR claim. Separately, the #2685 polling change combined cleanly with your earlier Applyable UI + regression assertion diff against fc61ab3--- a/apps/controller/src/console/agents/create.mjs
+++ b/apps/controller/src/console/agents/create.mjs
@@ -1707,7 +1707,9 @@
openclawModeUnavailable.textContent = modeRefusal;
}
openclawModeUnavailable.hidden = !modeRefusal;
- runtimeModeSummary.textContent = ` · ${mode.value === "dedicated" ? "Dedicated" : "Embedded"}`;
+ runtimeModeSummary.textContent = modeRefusal
+ ? " · Execution mode unavailable"
+ : ` · ${mode.value === "dedicated" ? "Dedicated" : "Embedded"}`;
const modeHint = form.querySelector("#execution-mode-hint");
if (modeHint) {
modeHint.textContent = sandboxDriverOutage
@@ -1721,11 +1723,13 @@
: "Codex uses Dedicated execution. OpenClaw uses Dedicated execution with a Sandbox Driver that provisions it, and Embedded execution without a Sandbox Driver. Slack requires Dedicated execution.";
}
if (capabilityDiscoveryDone) {
- const nextStatus = shouldProvision()
- ? "Dedicated Agents are provisioned and deployed when created."
- : mode.value === "embedded"
- ? "Embedded Agents are saved as drafts. Deploy them from the Agent page after creation."
- : "This installation creates draft Agents for later deployment.";
+ const nextStatus = modeRefusal
+ ? ""
+ : shouldProvision()
+ ? "Dedicated Agents are provisioned and deployed when created."
+ : mode.value === "embedded"
+ ? "Embedded Agents are saved as drafts. Deploy them from the Agent page after creation."
+ : "This installation creates draft Agents for later deployment.";
if (capabilityStatus.textContent !== nextStatus) {
capabilityStatus.textContent = nextStatus;
}
--- a/tests/browser/console-create-agent-provisioning-400.test.mjs
+++ b/tests/browser/console-create-agent-provisioning-400.test.mjs
@@ -1102,6 +1102,11 @@
.filter({ hasText: /operator-managed credentials|^Agents cannot be created / });
await alert.waitFor();
assert.equal(await alert.textContent(), text, JSON.stringify(openclaw));
+ assert.match(
+ await page.locator(".launch-runtime summary").innerText(),
+ /Execution mode unavailable/,
+ );
+ assert.equal(await page.locator("#create-agent-form > [role=status]").innerText(), "");
assert.equal(await page.getByLabel("Execution mode").inputValue(), "embedded");
assert.equal(
await page.getByRole("button", { name: "Create Agent", exact: true }).isDisabled(), |
Review follow-ups: Agent save answers 503 for Codex too while the selected Sandbox Driver is unavailable, so the outage alert and hints cover both harnesses and Create Agent stays disabled. Quota reads are deduplicated per pass by plane, Namespace and name; the provisioning test teardown closes the app and pool even if a cancellation assert fails; the deployment doc keeps "gateway connection".
|
ClawSweeper status: review started. I am starting a fresh review of this pull request: fix(console): name a sandbox driver outage and confirm a full pod quota This is item 1/1 in the current shard. Shard 0/1. This temporary status tracks the active review worker. The completed review will appear in the durable ClawSweeper review comment. Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted. |
Problem
Three low findings from an audit of #2674 and #2675:
NAMESPACE_POD_QUOTA_EXCEEDEDcame from the Deployment'sReplicaFailurecondition. That condition keeps the first refusal since the last successful create, and the next create can wait up to 1000 s of ReplicaSet backoff. So "The Namespace's Pod quota is full" could stay up for about 16 minutes after a user stopped an Agent. It also kept naming the Pod quota after a CPU or memory quota became the real blocker.GET /installationreportsopenclaw.executionModes: []. Create Agent then showed the permanent refusal ("its selected Sandbox Driver refuses Embedded execution ... ask an administrator to select a Sandbox Driver ..."). Admission answers a retryable 503 in the same state.create-and-deploy.mdsaid "OpenClaw starts Embedded". Before discovery, the console hints said "OpenClaw supports Dedicated or Embedded execution". The capability description said the list is what Agent save accepts, but save accepts Dedicated without a qualifying Sandbox Driver; only deploy refuses it.Change
NAMESPACE_POD_QUOTA_EXCEEDEDonly while that quota's status still showsused >= hardforpodsorcount/pods. A freed Pod, a raised limit, a CPU-only blocker, a deleted quota or an unreadable quota reports nothing, so the plain wait orWORKLOAD_UNSCHEDULABLEshows instead. Each quota is read at most once per pass, keyed by plane, Namespace and name. No new permissions: the worker's tenant role already hasgetonresourcequotas, in both charts, because it reconcilesopenclaw-quota.capabilities.openclawgains an optionalsandboxDriverUnavailable: true, present only when the selected Sandbox Driver is unavailable. It is additive and follows thenativeWorkers"present only when" pattern. Agent save answers 503 for every harness in that state, so Create Agent now says, for OpenClaw and Codex alike: "Agents cannot be created right now: this installation's Sandbox Driver is unavailable. Reload this page to check again, or ask an administrator if it persists." It keeps Create disabled and no longer tells anyone to reconfigure. The harness and mode hints say the same.create-and-deploy.md,harness-execution.mdanddeployment.mdare updated. OpenAPI andapi.mdare regenerated.Verification
tests/conformance/kubernetes-compute.test.mjs,configuration-occ.test.mjs,occ-api-security.test.mjs: 439/439 pass.tests/browser/console-create-agent-provisioning-400.test.mjsandconsole-agents.test.mjs: 57/57 pass.tests/integration/postgres-agent-provisioning.test.mjs, run against a prepared PostgreSQL (before and after the review changes): 54/54 pass. A probe that fails the outage test right after its first attempt leaves the workfailed_permanent/PROVISIONING_CANCELLED, so teardown cancels it. With the old inline cancel, that work stayed queued.tsc --build, eslint on the touched files, prettier,openapi:check. Word counts (real counter): harness-execution 2465, create-and-deploy 2483, deployment 2480.>instead of>=; unparsable quantity counted as full; onlypods(nocount/pods); fixed quota name instead of the refused one; read error treated as full; missing hard limit treated as0; no read dedupe; dedupe key without the Namespace. One mutant survives: dropping the plane from the dedupe key. The fixture serves both planes from one store, so it cannot tell them apart.taskset -c 0,1), on the code before and after the review changes.resourcequotas getin the custom-RBAC docs (the chart roles already grant it, and a missing grant only drops the sentence), and checking quotas when the first refusal was for CPU (a known gap, not a regression).Pages/Create Agent / OpenClaw during a Sandbox Driver outage(createOpenclawSandboxDriverOutage). Media below.Story
createOpenclawSandboxDriverOutage(media commita419d1d09019, removed before squash):walkthrough
Risks
getonresourcequotas. In that case the wait falls back to the plain or unschedulable wording; it is never wrong.