Skip to content

🤖 fix: enable best-effort SSA create-on-update fallback#82

Merged
ThomasK33 merged 1 commit intomainfrom
fix/ssa-create-on-update
Feb 13, 2026
Merged

🤖 fix: enable best-effort SSA create-on-update fallback#82
ThomasK33 merged 1 commit intomainfrom
fix/ssa-create-on-update

Conversation

@ThomasK33
Copy link
Member

Summary

Enable a best-effort create-on-update fallback in aggregated storage for coderworkspaces and codertemplates when Kubernetes calls Update with forceAllowCreate=true (SSA apply create path).

Background

Our aggregated API is a stateless proxy to Coder. SSA (kubectl apply --server-side) uses PATCH apply semantics that route through update with create-on-missing behavior. We previously rejected that path with 405 Method Not Allowed, which blocked SSA users from creating resources via server-side apply.

Implementation

  • Updated TemplateStorage.Update and WorkspaceStorage.Update to:
    • detect NotFound on existing object lookup when forceAllowCreate=true
    • materialize a create candidate via objInfo.UpdatedObject(ctx, s.New())
    • enforce defensive assertions/name checks
    • delegate to Create(...) and return created=true
  • Added prominent FIXME comments in both storage implementations documenting this as a compatibility hack and listing future options:
    1. Preferred: add first-class metadata support in Coder/codersdk for durable k8s metadata round-tripping
    2. shadow k8s metadata in ConfigMap/CRD side storage
    3. keep fallback + docs
  • Added tests:
    • TestTemplateStorageUpdateForceAllowCreateCreatesWhenMissing
    • TestWorkspaceStorageUpdateForceAllowCreateCreatesWhenMissing
  • Updated docs (docs/how-to/deploy-aggregated-apiserver.md) with SSA behavior and limitations.

Validation

  • make verify-vendor
  • go test ./internal/aggregated/storage -count=1
  • make test
  • make build
  • make lint
  • make docs-check

Risks

  • This is intentionally best-effort SSA support; durable field ownership/conflict semantics remain limited because metadata.managedFields is not persisted in the Coder backend.
  • Risk is constrained to create-on-update path for aggregated resources; existing update validation semantics remain intact.

Generated with mux • Model: openai:gpt-5.3-codex • Thinking: xhigh • Cost: $2.58

Allow aggregated storage Update() to fall back to Create() when
forceAllowCreate=true and the target coder template/workspace does not exist.

This unblocks SSA create-on-update requests while keeping existing update
validation and defensive assertions for normal update flows.

Added a prominent FIXME in both storage implementations documenting that this is
a compatibility hack and outlining future options, with the preferred long-term
fix being first-class metadata support in Coder/codersdk.

Also added storage tests for both codertemplates and coderworkspaces to validate
create-on-update behavior, and documented the SSA limitation and roadmap in the
aggregated API deployment guide.

---

_Generated with [`mux`](https://github.com/coder/mux) • Model: `openai:gpt-5.3-codex` • Thinking: `xhigh` • Cost: `$2.58`_

<!-- mux-attribution: model=openai:gpt-5.3-codex thinking=xhigh costs=2.58 -->
@ThomasK33
Copy link
Member Author

@codex review

Please review this SSA create-on-update compatibility fallback for aggregated storage, including the FIXME guidance and new coverage.

@ThomasK33 ThomasK33 merged commit 515a7e4 into main Feb 13, 2026
11 checks passed
@ThomasK33 ThomasK33 deleted the fix/ssa-create-on-update branch February 13, 2026 16:58
@ThomasK33
Copy link
Member Author

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Delightful!

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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.

1 participant