Skip to content

fix(server): make resourceLimits/image/entrypoint optional when poolRef is set#883

Merged
hittyt merged 5 commits into
opensandbox-group:mainfrom
longsuizhi:fix/pool-mode-optional-fields
May 17, 2026
Merged

fix(server): make resourceLimits/image/entrypoint optional when poolRef is set#883
hittyt merged 5 commits into
opensandbox-group:mainfrom
longsuizhi:fix/pool-mode-optional-fields

Conversation

@longsuizhi
Copy link
Copy Markdown
Contributor

@longsuizhi longsuizhi commented May 13, 2026

Summary

When creating a sandbox from a pre-configured Pool (via extensions.poolRef), the image, entrypoint, and resourceLimits are all defined in the Pool CRD template. Currently the API requires callers to provide dummy values for these fields, which is unnecessary and error-prone.

Fixes #885

Changes

  • schema.py: Make resource_limits Optional[ResourceLimits] with None default; skip image/snapshotId/entrypoint validation when poolRef is present; reject snapshotId + poolRef combination; add explicit resourceLimits required check for non-pool requests
  • kubernetes_service.py: Skip resolve_sandbox_image_from_request and ensure_entrypoint when poolRef is set; guard _ensure_image_auth_support against None image
  • docker_service.py: Reject poolRef on Docker provider (unsupported); guard against None resource_limits
  • container_ops.py: Guard against None resource_limits
  • specs/sandbox-lifecycle.yml: Remove required: [resourceLimits], document pool mode behavior, clarify snapshotId is rejected with poolRef

Before (422 error)

curl -X POST /sandboxes -d '{"extensions": {"poolRef": "my-pool"}}'
# => 422: "resourceLimits: Field required"

curl -X POST /sandboxes -d '{"extensions": {"poolRef": "my-pool"}, "resourceLimits": {"cpu": "1", "memory": "1Gi"}}'
# => 422: "Exactly one of image or snapshotId must be provided."

After

curl -X POST /sandboxes -d '{"extensions": {"poolRef": "my-pool"}}'
# => 202: sandbox created from pool

Testing

  • All 1038 existing tests pass (uv run pytest tests/ -x -q)
  • Verified on a live K8s cluster: pool-mode sandbox creation works with dummy fields (current workaround) and will work without them after this fix

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 13, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ea9127778

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread server/opensandbox_server/api/schema.py
Comment thread server/opensandbox_server/api/schema.py
…ef is set

When creating a sandbox from a pre-configured Pool (via extensions.poolRef),
the image, entrypoint, and resourceLimits are all defined in the Pool CRD
template. Requiring callers to provide dummy values for these fields is
unnecessary and error-prone.

Changes:
- Make resource_limits Optional with None default in CreateSandboxRequest
- Skip image/snapshotId/entrypoint validation when poolRef is present
- Add explicit resourceLimits required check for non-pool requests
- Guard against None resource_limits in Docker provider code paths
@longsuizhi longsuizhi force-pushed the fix/pool-mode-optional-fields branch from 9ea9127 to 2abe9a5 Compare May 13, 2026 13:08
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2abe9a55ed

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread server/opensandbox_server/api/schema.py
Comment thread server/opensandbox_server/api/schema.py
- Skip image/entrypoint resolution in K8s service layer when poolRef is set
- Reject poolRef on Docker provider (unsupported)
- Reject snapshotId when poolRef is set (conflicting fields)
- Update specs/sandbox-lifecycle.yml: remove required constraint on
  resourceLimits, document pool mode behavior
- All 1038 tests pass
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c34c0154a3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread server/opensandbox_server/services/k8s/kubernetes_service.py
Comment thread server/opensandbox_server/api/schema.py
Comment thread specs/sandbox-lifecycle.yml
Comment thread specs/sandbox-lifecycle.yml
…docs

- Fix AttributeError when image is None in pool mode (P1)
- Clarify in spec that snapshotId is rejected (not optional) with poolRef
@Pangjiping
Copy link
Copy Markdown
Collaborator

Thanks for your submission, this is a very valuable fix. I'll review and merge it as soon as possible. 😊

@Pangjiping
Copy link
Copy Markdown
Collaborator

Pangjiping commented May 14, 2026

Zero new tests for the changed validation paths. The PR modifies 5 files and relaxes a required-field constraint, but no test exercises the new behavior. 1038 existing tests pass, but they only cover the old behavior (everything required).

Specific missing coverage:

  1. Happy path pool mode — POST /sandboxes with only poolRef, no resourceLimits/image/entrypoint. Should return 202. This is the entire point of the PR and it's untested.
  2. snapshotId + poolRef rejection — new validation rule rejects this combination. No test.
  3. resourceLimits still required without poolRef — new explicit ValueError when resource_limits is None and no poolRef. No test.
  4. Docker provider rejects poolRef — new HTTPException with SANDBOX::UNSUPPORTED_POOL_REF. No test.
  5. request.image is None guard in _ensure_image_auth_support — new None-check to avoid AttributeError on None.auth. No test.

…n, Docker guard, and image auth

- Schema: poolRef-only happy path, poolRef+snapshotId rejection, resourceLimits
  still required without poolRef, blank poolRef ignored
- Docker: rejects poolRef with SANDBOX::UNSUPPORTED_POOL_REF
- K8s: pool mode skips image/entrypoint validation, image auth guard handles
  None image without AttributeError

All 1046 tests pass (8 new).
@longsuizhi
Copy link
Copy Markdown
Contributor Author

longsuizhi commented May 14, 2026

Thanks for the detailed review @Pangjiping! I just pushed a commit (0c1356b3) that adds tests for all 5 cases you mentioned:

  1. Pool mode happy path — poolRef only, no image/entrypoint/resourceLimits → validates OK
  2. snapshotId + poolRef rejection — should raise ValidationError
  3. resourceLimits still required without poolRef — standard mode unchanged
  4. Docker provider rejects poolRef — returns 400 with SANDBOX::UNSUPPORTED_POOL_REF
  5. _ensure_image_auth_support None image guard — no AttributeError when request.image is None

Also added a few extra edge cases (blank poolRef ignored, poolRef with optional env/metadata, K8s service-level pool mode skip). All 1046 tests pass now (8 new ones).

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c1356b3b2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread specs/sandbox-lifecycle.yml
Comment thread server/opensandbox_server/api/schema.py
When poolRef is set and snapshotId is whitespace-only (e.g. '   '),
the validator now clears it to None before returning. This prevents
downstream code from treating a truthy whitespace string as a real
snapshot ID (e.g. writing an invalid Kubernetes label).

Adds test_pool_mode_normalizes_blank_snapshot_id to cover this edge case.
Copy link
Copy Markdown
Collaborator

@Pangjiping Pangjiping left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Collaborator

@hittyt hittyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@hittyt hittyt merged commit 5203bef into opensandbox-group:main May 17, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working component/server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(server): make resourceLimits/image/entrypoint optional when poolRef is set

5 participants