Skip to content

feat(snapshots): expose imageUri end-to-end (spec, server, all SDKs)#1053

Open
ferponse wants to merge 3 commits into
opensandbox-group:mainfrom
ferponse:feat/snapshot-imageuri-complete
Open

feat(snapshots): expose imageUri end-to-end (spec, server, all SDKs)#1053
ferponse wants to merge 3 commits into
opensandbox-group:mainfrom
ferponse:feat/snapshot-imageuri-complete

Conversation

@ferponse

@ferponse ferponse commented Jun 13, 2026

Copy link
Copy Markdown

Summary

Closes #1077.

A Ready snapshot already produces a portable OCI restore image internally, but it is never surfaced on the public snapshot contract, so callers cannot restore a sandbox from that image (e.g. to move a sandbox across clusters) without patching the server. This exposes it end-to-end as imageUri, across the spec, the server, and all SDKs.

Spec

  • Add the optional imageUri to the Snapshot schema in specs/sandbox-lifecycle.yml (the source of truth the SDK clients generate from).

Server

  • Add image_uri/imageUri to the Snapshot response model and populate it from the record's restore image in _to_snapshot_response, only once the snapshot is Ready.

Generated clients (regenerated from the spec)

  • python: regenerated the lifecycle Snapshot model (openapi-python-client); mapped onto the domain SnapshotInfo in the converter.
  • javascript: regenerated api/lifecycle.ts (openapi-typescript); mapped onto the domain snapshot model.
  • kotlin: regenerates the lifecycle client from the spec at build time; adds imageUri to SnapshotInfo and maps it in SandboxModelConverter.

Hand-written clients (no spec codegen — field added by hand)

  • go: the lifecycle types are hand-written, so the field was added directly to types.go (ImageURI string \json:"imageUri,omitempty"``).
  • csharp: the snapshot model is hand-written, so Models/Sandboxes.cs gets string? ImageUri and Adapters/SandboxesAdapter.cs parses imageUri from the response JSON.

imageUri is optional and only populated once the snapshot is Ready (null/omitted otherwise), so the change is additive and backward compatible.

Testing

  • Not run (explain why)
  • Unit tests
  • Integration tests
  • e2e / manual verification

Per SDK + server (all green):

  • kotlin: ./gradlew spotlessCheck :sandbox:test; SandboxesAdapterTest asserts getSnapshot parses imageUri.
  • python: uv run ruff check / pyright / pytest -k snapshot; lifecycle Snapshot regenerated via scripts/generate_api.py.
  • javascript: typecheck / build + unit tests.
  • go: build / vet / test.
  • csharp: dotnet test.
  • server: pytest tests/test_snapshot_service.py tests/test_routes_snapshots.py; the service test asserts the response exposes imageUri only when Ready.

Breaking Changes

  • None
  • Yes (describe impact and migration path)

Additive optional field; null/omitted unless the snapshot is Ready.

Checklist

  • Linked Issue or clearly described motivation — Expose the snapshot restore image (imageUri) end-to-end #1077
  • Added/updated docs (if needed) — regenerated the docs spec bundle (docs/public/api/spec-inline.js) from sandbox-lifecycle.yml
  • Added/updated tests (if needed)
  • Security impact considered — exposes the OCI restore image reference the caller needs to restore; gated on Ready, no new privileged data
  • Backward compatibility considered — additive optional field

Co-authored-by: Atenea Agent srv_atenea_gitlab@ofidona.net

A Ready snapshot already produces a portable OCI restore image internally,
but it was never surfaced on the public snapshot contract, so callers could
not restore a sandbox from the image (e.g. to move it across clusters)
without patching the server. Expose it as `imageUri`.

- spec: add optional `imageUri` to the Snapshot schema in sandbox-lifecycle.yml.
- server: add `image_uri`/`imageUri` to the Snapshot response model and populate
  it from the record's restore image in `_to_snapshot_response`; assert it on the
  Ready-snapshot service test.
- kotlin sdk: add `imageUri` to SnapshotInfo and map it in the converter; assert
  it in SandboxesAdapterTest.
- python sdk: add `image_uri` to the domain SnapshotInfo and map it in the
  converter; regenerate the lifecycle Snapshot model from the spec.

Additive and optional (null/omitted until the snapshot is Ready), so it is
backward compatible. Other language SDKs can surface the same field as a
follow-up.

Co-authored-by: Atenea Agent <srv_atenea_gitlab@ofidona.net>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ This PR has no labels. Please add one based on the changes.

Changed directories: sdks、server、specs.

📋 Recommended labels (based on changed files):

  • component/server ⬅️
  • documentation ⬅️
  • sdks ⬅️

Other available labels:

  • bug - Something isn't working
  • dependencies - Pull requests that update a dependency file
  • feature - New feature or request
  • packages - Changes for package, image and configuration

💡 Tip: Use feature for new functionality or improvements, bug for fixes.

cc @ferponse

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

Copy link
Copy Markdown

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: 39aabdd50e

ℹ️ 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/services/snapshot_service.py Outdated
- server: only serialize imageUri when the snapshot is Ready, so a Ready
  snapshot later marked Deleting/Failed no longer leaks its restore image;
  add a test asserting the gate.
- kotlin: add a binary-compatibility secondary constructor to SnapshotInfo
  preserving the pre-imageUri JVM signature for already-compiled callers.
- sdk parity: surface imageUri on the Go (SnapshotInfo struct), C#
  (SnapshotInfo model + ParseSnapshotInfo converter) and JavaScript
  (SnapshotInfo type) snapshot models so the spec field is end-to-end and
  not silently dropped by those clients.

Co-authored-by: Atenea Agent <srv_atenea_gitlab@ofidona.net>

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

Copy link
Copy Markdown

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: 68a65f9398

ℹ️ 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 specs/sandbox-lifecycle.yml
Keep the checked-in artifacts generated from sandbox-lifecycle.yml in sync
with the new imageUri field:
- regenerate the JS lifecycle OpenAPI types (Snapshot schema) so
  ApiGetSnapshotOk / the internal LifecyclePaths contract expose imageUri.
- regenerate docs/public/api/spec-inline.js (the published API reference
  bundle) via scripts/spec-doc/generate-spec.js.

Co-authored-by: Atenea Agent <srv_atenea_gitlab@ofidona.net>
@ferponse ferponse changed the title feat(snapshots): expose imageUri end-to-end (spec + server + Kotlin/Python SDK) feat(snapshots): expose imageUri end-to-end (spec, server, all SDKs) Jun 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose the snapshot restore image (imageUri) end-to-end

1 participant