Files
Shiju 8983642e28 fix(gateway): give image preparation its own deadline (#4038)
* feat(server): separate image preparation and admission deadlines

Give sandbox image preparation its own deadline and start the admission
deadline after preparation finishes. Persist both phases across gateway
restarts and show recovery guidance for the phase that expired.

Preserve the current service authorization schema and regenerate the Go
bindings with the preparation timestamps.

Fixes #3952
Related to #3955

Signed-off-by: Shiju <shiju@nvidia.com>

* fix(cli): simplify preparation timeout fallback selection

Use lazy Option fallbacks while preserving timeout messages and retained
sandbox behavior.

Signed-off-by: Shiju <shiju@nvidia.com>

* docs(server): clarify admission timer prerequisites

Signed-off-by: Shiju <shiju@nvidia.com>

* fix(compute): enforce deadlines during initial sandbox create

Release stalled create operations after preparation expires and preserve
the timeout diagnosis across late driver results. Keep failed-create cleanup
bound to its original attempt so another replica can retry safely.

Signed-off-by: Shiju <shiju@nvidia.com>

* test(server): satisfy deadline regression lints

Drop the create-error mutex guard before matching its cloned value and use
idiomatic iteration and timeout matching in the deadline fixtures.

Signed-off-by: Shiju <shiju@nvidia.com>

* fix(server): retain ownership of pending provisioning operations

Keep submitted create and start requests alive after caller cancellation,
monitor failure, or preparation timeout. Persist request ownership before
dispatch and retain staged uploads while the driver response is pending.

Require timeout cleanup to stop compute after driver settlement without
discarding an active cleanup claim. Fence late result handling against newer
operations, preserve failed-start recovery, and defer automatic restart while
another request owns the sandbox. Expose pending ownership in CLI JSON.

Add ordered multi-replica and cancellation regressions for the review findings.

Signed-off-by: Shiju <shiju@nvidia.com>

* fix(openshell): preserve tracing and accept ready create responses

Carry the request span into the detached provisioning worker so compute
driver calls remain attached to their parent trace after task handoff.

Update the compensation regression to require no backend DELETE when the
durable cleanup claim fails, matching the operation ownership requirement.

Accept the gateway's current Ready snapshot when a sandbox becomes ready
before CREATE returns. Do not require the client to observe an earlier
provisioning phase. Cover the Ready-only watch and command attachment.

Signed-off-by: Shiju <shiju@nvidia.com>

---------

Signed-off-by: Shiju <shiju@nvidia.com>
2026-10-03 20:48:18 +00:00
..

Protobuf API conventions

This directory defines OpenShell's gRPC contracts. These conventions are the source of truth for public protobuf API design. Apply them to new APIs and when changing existing APIs; generated SDK naming follows from these definitions.

Entity references

  • Use name for the primary resource targeted by an RPC.
  • Use the resource's role for a related resource reference, such as sandbox, provider, service, or rule.
  • Do not append _name to a canonical entity reference. Its value is already the canonical name. Descriptive values, local map keys, implementation labels, and configured registration names that are not entity references may retain the suffix. Examples include display_name, file_name, driver_name, runtime_class_name, rule_name, and middleware_name.
  • Public callers reference entities by canonical name. Keep immutable IDs at authentication, persistence, compute-driver, and other internal boundaries.

For example:

message GetSandboxRequest {
  openshell.datamodel.v1.WorkspaceSelector workspace_scope = 2;
  string name = 1;
}

message ExposeServiceRequest {
  openshell.datamodel.v1.WorkspaceSelector workspace_scope = 5;
  string sandbox = 1;
  string name = 2;
}

GetSandboxRequest.name identifies the RPC's primary resource. ExposeServiceRequest.sandbox identifies a related sandbox while name identifies the service being exposed.

Workspace scope

  • Public workspace-scoped requests declare workspace_scope before every other field. Existing wire field numbers do not need to follow declaration order.
  • Type workspace_scope as openshell.datamodel.v1.WorkspaceSelector.
  • Requests operating in one workspace require a non-empty canonical WorkspaceSelector.workspace. The default workspace is an explicit name, not an omitted-value fallback.
  • Accept WorkspaceSelector.all_workspaces only on collection-list RPCs that explicitly document and authorize cross-workspace access. The supported public collections are sandboxes, sandbox templates, providers, and services.
  • Requests whose primary resource is a workspace use name, not workspace_scope.
  • Document every request that permits an omitted selector. Current exceptions are platform provider-profile scope and authenticated sandbox bootstrap.

Field and message design

  • Prefer a dedicated request and response message for each RPC, including requests that are currently empty.
  • Use google.protobuf.Timestamp for absolute time and google.protobuf.Duration for elapsed time.
  • Use optional presence when omitted and explicitly empty values have different meanings. Do not infer presence from a protobuf scalar's default value.
  • Keep public request fields in semantic reading order. Field numbers preserve wire identity and may therefore differ from declaration order.
  • Document authorization-sensitive selector variants and omission semantics on the containing request.

Schema evolution

  • Treat field numbers and fully qualified message names as durable wire identities.
  • When removing or renaming a field, reserve its old number and source name. Do not reuse either for a different meaning.
  • Review changes against both the public descriptor closure and durable stored protobuf closure. The public_and_durable_schema_inventories_are_complete test in openshell-server owns both inventories.
  • Regenerate Rust, Python, Go, and TypeScript bindings after contract changes. Run mise run pre-commit, the affected SDK checks, and relevant server tests before submitting the change.