Skip to content

Rework cloud-connect-dev recipe onto the spice cloud enrollment flow - #597

Merged
phillipleblanc merged 6 commits into
spiceai:trunkfrom
claudespice:fix/cloud-connect-dev-doc-links
Aug 21, 2026
Merged

Rework cloud-connect-dev recipe onto the spice cloud enrollment flow#597
phillipleblanc merged 6 commits into
spiceai:trunkfrom
claudespice:fix/cloud-connect-dev-doc-links

Conversation

@claudespice

@claudespice claudespice commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

spice connect is no longer how a runtime is connected to Spice Cloud. It retains only the deprecated <org>/<pod> Spicepod-add form and rejects every lifecycle spelling:

$ spice connect status
ERROR Invalid argument: `spice connect` only accepts the deprecated `<org>/<pod>` Spicepod form; use `spice cloud` for instance lifecycle.

The cloud-connect-dev recipe taught spice connect, spice connect status, and spice connect remove — so every cloud-facing command in it exits non-zero today. Repairing its doc links (the original scope of this PR) would have left a recipe that walks the reader down a path the CLI no longer has, so the recipe body is reworked onto the current surface. The link repairs are kept.

What changed

README.md now uses spice loginspice cloud project createspice cloud link <org>/<project>spice run, with spice cloud secrets, spice cloud status, spice cloud unlink, and spice cloud service for the rest. The portal is used only where it is genuinely the tool: editing the project Spicepod. Behaviours documented because the CLI actually does them:

  • spice cloud link enrols the directory and attaches it in one step, requires a terminal, and does not start the runtime — its own output tells you to run spice run.
  • A project holding no Spicepod is seeded from the local one, so the recipe's manual "paste spicepod.yaml into the portal" step is gone.
  • spice cloud unlink releases the instance but never deletes the project. Clean-up names spice cloud project delete separately, and says to stop the runtime first, because unlink takes the runtime lock and refuses while it is held.
  • spice cloud status reports project health and appends the local view under a Local enrolled-instance state: header, which the expected-output block gains. It reads from the control plane, so unlike the old command it does not work signed out — the README says so.

Breaking for anyone parsing --output json: the status JSON moves connection, service, and deployment under a link object; schema_version stays at the top level. That is a runtime change, not one this PR makes, but it is not discoverable from this diff and it silently breaks existing parsers.

The project is created with spice cloud project create cloud-connect-dev. --kind is the discriminator: naming one asks for a Spice-managed project and requires --region, while omitting it asks for a Cloud Connect project, which has no region to choose. --region and the hosted-runtime flags are refused rather than ignored when no kind is given, so the README says so.

validate.sh asserts that distinction, and can do it headlessly: execute_project_create resolves placement before it connects, so both refusals are argument validation that answer with no account and create nothing. The exit code is asserted alongside the message, so a future ordering change that created the project before validating it would fail the check rather than pass silently.

Secrets, and a hazard worth naming

The secrets step is spice cloud secrets set PG_PASSWORD "$SPICE_DEMO_PG_PASSWORD", confirmed with spice cloud secrets list. Linking resolves the project, so neither needs --project.

The value is a required positional argument, and there is no stdin, file, or environment formSecretsSetArgs.value is a bare String with no clap attribute, and the only stdin read in the module is the project-delete confirmation prompt. So the recipe passes the shell variable: history records the line as typed, which keeps the password out of it, but the expanded value is still in the process argument list while the command runs. The README states that plainly and points at the portal for a shared machine, rather than implying the CLI form is unconditionally safer.

spice cloud secrets get prints the value to stdout, so the confirmation step uses list, which reports names and timestamps only. validate.sh fails if the README ever reaches for get, or if it spells the password literally instead of passing the variable.

validate.sh

Its stated contract is to run with no account, no login, and no control-plane access. The old spice connect status assertions met that because the command only read local state. spice cloud status calls the control plane — offline it exits 1 with No app specified — so those checks cannot be ported. Replacing them:

  • --help assertions that the four lifecycle commands and all five service subcommands exist
  • a README/CLI drift guard that fails if the recipe reintroduces a removed spice connect spelling
  • the non-interactive refusal path, which still fails closed and still names spiced --token

Nothing in the suite sets, reads, or deletes a real secret, for the same reason a bare project create is not asserted: those commands reach the control plane, and a validator that mutates someone's cloud project when a developer happens to be logged in is a worse defect than the coverage it would buy.

Dropped: the assertion that an enrollment key is refused as a positional argument. spice cloud link fails its terminal check before argument handling, so that property is no longer reachable from this recipe's surface. The scan that fails the build if a key-shaped value appears in a recipe file is unchanged.

Verified against

  • The shipped binary, not the release notes: spice cloud --help and the link / unlink / status / service / project create subcommand helps.
  • Source, for the strings and ordering the README quotes: bin/spice/src/commands/cloud/mod.rs (execute_link output, execute_unlink runtime lock, execute_status local-state header and JSON shape) and bin/spice/src/commands/connect/status.rs ( secrets: {n} delivered: {names}).
  • Links: every URL in the README re-checked with curl -sL -o /dev/null -w '%{http_code}' — 4/4 return 200. /docs/next/ is the correct prefix today because the released paths still 404: Cloud Connect is new in v2.2 and no version-2.2.x snapshot has been cut yet. When v2.2 is published these pages are snapshotted and also resolve at /docs/deployment/cloud/cloud-connect, which is then the better link for a recipe whose readers run the stable CLI — /docs/next/ tracks trunk and drifts from it. Worth revisiting at that point.
  • The spice connect CLI reference link is removed rather than repointed — the spice cloud reference page is not published yet (/docs/cli/reference/cloud and /docs/next/cli/reference/cloud both 404). It can be added in a follow-up once that page exists.

Evidence

./cloud-connect-dev/validate.sh, run locally against a v2.2 CLI:

before:  18 passed, 12 failed   TEST FAILED
after:   43 passed,  0 failed   TEST PASSED

All 12 prior failures were the spice connect assertions.

Note on CI: validate-cloud-connect-dev installs the stable CLI, which still predates v2.2, so the workflow takes the version gate and reports the "not validated" notice — a green check there is not evidence for the CLI-dependent assertions, which were exercised locally against v2.2 and start running in CI when v2.2 ships.

The checks that only read README.md need no CLI, so they now sit above the gate and do run in CI: 23 checks, up from 16, including the guard that fails if the recipe ever spells the database password literally instead of passing $SPICE_DEMO_PG_PASSWORD. That is the check that most needs to run on every pull request, and it previously never did.

Sweep

The rest of the cookbook was checked for spice connect. Five other files match only in ordinary prose — "the replication user Spice connects with", "Spice connects to Unity Catalog", "the Spice connector accepts the dot form" — and no file anywhere uses the still-supported deprecated spice connect <org>/<pod> pod-add form. No other recipe needs a change.

…e published pages

Both Cloud Connect links 404: /docs/deployment/cloud/cloud-connect and
/docs/deployment/cloud/cloud-connect/service are unreleased pages, published
under /docs/next/ until v2.2 ships. The `spice connect` CLI reference
resolves at the released path, but that page documents the superseded command
(no `spice connect service install`, no `spiced --token`), so it points at
/docs/next/ too — the flow this recipe and its validate.sh assert.

Also align the docker-compose.yml comment with the README's PG_PASSWORD, since
the README states that secret names are matched exactly.
@claudespice claudespice added bug Something isn't working documentation Improvements or additions to documentation labels Aug 19, 2026
@claudespice claudespice self-assigned this Aug 19, 2026
`spice connect` no longer enrolls a runtime with Spice Cloud. It retains only
the deprecated `<org>/<pod>` Spicepod-add form and rejects every lifecycle
spelling. This recipe walked the reader through `spice connect`,
`spice connect status`, and `spice connect remove`, all of which now exit
non-zero.

Rewrite it on the shipped surface — `spice cloud login`, `spice cloud link
<org>/<project>`, `spice cloud status`, `spice cloud unlink`, and `spice cloud
service` — verified against the CLI binary and bin/spice/src/commands/cloud
rather than against release notes:

- `spice cloud link` enrolls the directory and attaches it in one step, needs a
  terminal, and does not start the runtime; its own output tells you to run
  `spice run`.
- A project holding no Spicepod is seeded from the local one, so the manual
  "paste spicepod.yaml into the portal" step is no longer needed.
- `spice cloud unlink` releases the instance but never deletes the project.
  Clean-up names `spice cloud project delete` separately, and says to stop the
  runtime first, because unlink takes the runtime lock and refuses otherwise.
- `spice cloud status` reports project health and appends the local view under
  a `Local enrolled-instance state:` header, which the expected output gains.

The project is created in the portal: `spice cloud project create` still
requires `--region` on trunk, so it cannot yet create the unattached Cloud
Connect project this flow needs (spiceai/spiceai#13333).

validate.sh is rewritten over the same surface. Its contract is to run with no
account, no login, and no control-plane access, and the `spice connect status`
assertions met it because that command only read local state. `spice cloud
status` calls the control plane, so those checks cannot be ported. In their
place: `--help` assertions over the lifecycle and service commands, a
README/CLI drift guard that fails if the recipe reintroduces a removed
spelling, and the non-interactive refusal path, which still fails closed and
still names `spiced --token`.

Dropped: the assertion that an enrollment key is refused as a positional
argument. `spice cloud link` fails its terminal check before argument handling,
so that property is no longer reachable from this recipe's surface.

The doc-link repairs from the base commit are kept. The `spice connect` CLI
reference link is removed rather than repointed, because the `spice cloud`
reference page is not published yet; it can be added once it is. Every
remaining link was re-checked and returns HTTP 200.

./validate.sh before this change: 18 passed, 12 failed, TEST FAILED.
./validate.sh after:              33 passed,  0 failed, TEST PASSED.
@phillipleblanc phillipleblanc changed the title Fix cloud-connect-dev recipe: repair two 404 Cloud Connect doc links Rework cloud-connect-dev recipe onto the spice cloud enrollment flow Aug 20, 2026
The CLI's own failure hint for an unauthenticated link reads "Run `spice
login`, then retry `spice cloud link`". A reader who gets stuck reads the
error before they re-read the recipe, so the recipe uses the same spelling.

Also say that `spice cloud status` reads from Spice Cloud and needs that
session: it reports project health from the control plane, so unlike the
purely local checks in validate.sh it does not work signed out.
`spice cloud project create <name>` with no `--kind` creates the unattached
Cloud Connect project that `spice cloud link` attaches to, so the recipe no
longer sends the reader to the portal to make one. Setup is CLI end to end:
`spice login`, `spice cloud project create`, `spice cloud link`, `spice run`.

`--kind` is the discriminator. Naming one asks for a Spice-managed project and
requires `--region`; omitting it asks for a Cloud Connect project, which has no
region to choose. `--region` and the hosted-runtime flags are refused rather
than ignored when no kind is given, so the README says so.

validate.sh asserts that distinction. `execute_project_create` resolves
placement before it connects, so both refusals are argument validation: they
answer with no account and create nothing. The exit code is asserted alongside
the message, so a future ordering change that created the project before
validating it would fail the check rather than pass silently.

`spice cloud link` still requires a terminal and a user login. Creating the
project from the CLI does not change that.

./validate.sh: 37 passed, 0 failed, TEST PASSED (was 33 passed, 0 failed).
@phillipleblanc phillipleblanc self-assigned this Aug 21, 2026
`spice cloud secrets set PG_PASSWORD "$SPICE_DEMO_PG_PASSWORD"` replaces the
portal walkthrough, and `spice cloud secrets list` confirms it. Linking resolves
the project, so neither needs `--project`.

The value is a required positional argument. There is no stdin, file, or
environment form: `SecretsSetArgs.value` is a bare `String` with no clap
attribute, and the only stdin read in the module is the project-delete prompt.
So the recipe passes the shell variable, which keeps the password out of shell
history — history records the line as typed — but the expanded value is still in
the process argument list while the command runs, and the README says so and
points at the portal for a shared machine.

`spice cloud secrets get` prints the value to stdout, so the confirmation step
uses `list`, which reports names and timestamps only.

validate.sh asserts the four subcommands exist and that the README passes the
password by variable and never calls `secrets get`. Nothing sets, reads, or
deletes a real secret: these commands reach the control plane, and a validator
that mutates a cloud project when a developer happens to be logged in is worse
than the coverage it would buy.

The compose comment tracks the credential to the project rather than to the
portal, which is where it now goes.

./validate.sh: 43 passed, 0 failed, TEST PASSED (was 37 passed, 0 failed).
README URLs re-checked: 4/4 HTTP 200.
The checks that only read README.md need no CLI, but sat below the version
gate with the ones that do. CI installs the stable CLI, so the gate skips
everything under it and those checks never ran there — including the guard
that fails if the recipe spells the database password literally instead of
passing \$SPICE_DEMO_PG_PASSWORD. That is the one check that most needs to
run on every pull request.

Group them into a README section above the gate. The CLI sections keep only
what actually needs a CLI: the --help listings, the project-kind refusals, and
the non-interactive link refusal.

No assertion is added or removed. Locally, where the gate passes, the suite is
unchanged at 43 passed, 0 failed. On a CI image whose CLI predates the flow,
the checks that run before the gate go from 16 to 23.
@phillipleblanc
phillipleblanc merged commit 82f460f into spiceai:trunk Aug 21, 2026
1 check 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 documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants