Skip to content

fix(storage): boot sidecar-free config for registry interface collection - #232

Merged
ytallo merged 2 commits into
mainfrom
fix/storage-publish-rustfs-sidecar
Jun 6, 2026
Merged

fix(storage): boot sidecar-free config for registry interface collection#232
ytallo merged 2 commits into
mainfrom
fix/storage-publish-rustfs-sidecar

Conversation

@ytallo

@ytallo ytallo commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Problem

The storage worker's registry publish fails (run 27064591120) at Start local worker for interface collection — never reaching POST /publish.

Worker log from the failed run:

INFO storage: starting name="storage" config=./config.yaml url=ws://127.0.0.1:49134/
Error: {"code":"LOCAL_BACKEND_BIN_NOT_FOUND","reason":"set $RUSTFS_BIN, place a rustfs binary next to storage, or install rustfs on PATH"}

Root cause

storage spawns a rustfs sidecar at startup whenever its config declares a provider: local bucket (src/main.rs needs_local). The default config.yaml declares one (scratch). The prebuilt release binary bundles no rustfs, and in CI $RUSTFS_BIN is unset with rustfs off PATH — so the worker exits before it connects/registers with the engine. The publish job then sees a dead process and fails.

This is unique to storage (only worker with a boot-time sidecar) and surfaced on its first publish. Everywhere else storage runs (e2e), rustfs is provisioned externally via run-tests.sh::ensure_rustfs() — the publish workflow had no equivalent.

Fix

Interface collection only needs the worker to connect and register its functions/trigger types — not a working backend. Those registrations are config-independent.

  • storage/config.collect.yaml — sidecar-free collection config: one dummy S3 bucket, no local bucket → needs_local=false → no rustfs spawn. Passes config validation (requires ≥1 bucket) and builds a lazy S3 client with no network call at startup.
  • .github/workflows/_publish-registry.ymlrelease-binary and cargo-run paths now launch with --config config.collect.yaml when a worker ships one. Opt-in and generic; only storage has the file today.

Test plan

Verified locally with rustfs absent and $RUSTFS_BIN unset (identical to CI):

Run Config Result
Control config.yaml exit=1LOCAL_BACKEND_BIN_NOT_FOUND (reproduces CI)
Fix config.collect.yaml survives startup, no rustfs touched, backend ready … provider="s3", storage registered 4 functions and 2 trigger types

The fix run connected to a live engine and registered fully, then shut down cleanly on SIGTERM — i.e. interface collection would now succeed.

Notes

  • To publish storage, cut a new tag (e.g. storage/v0.1.3) or re-create storage/v0.1.2 after merge so the job picks up both files.
  • Separate follow-up: confirm how rustfs reaches a real deployment — the e2e auto-fetch is test-only, so a user installing storage with the default local bucket would hit the same crash unless rustfs ships with it or RUSTFS_BIN is set.

Summary by CodeRabbit

  • Chores
    • Workflows updated to optionally use a local collection configuration when present, improving reliability of the interface-collection step during publishing and CI.
    • Added a publish-workflow-specific no-network collection configuration (uses a static, unreachable storage endpoint) to prevent startup failures during automated interface registration.

The storage worker spawns a rustfs sidecar at startup whenever its config
declares a `provider: local` bucket. The default config.yaml declares one
(`scratch`), so the prebuilt release binary -- which bundles no rustfs and
runs with $RUSTFS_BIN unset and rustfs off PATH -- exits on boot with
LOCAL_BACKEND_BIN_NOT_FOUND before it registers with the engine. The publish
job's interface-collection step then sees a dead process and fails, so
POST /publish never runs.

Add storage/config.collect.yaml (one dummy S3 bucket, no local bucket ->
needs_local=false -> no sidecar spawn) and teach _publish-registry.yml to
launch with `--config config.collect.yaml` when a worker ships one. The
registered interface (4 functions + 2 trigger types) is config-independent,
so the collected manifest is identical.
@vercel

vercel Bot commented Jun 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview, Comment Jun 6, 2026 4:16pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a5ffa61b-8afa-4fc8-b6c0-b899ce1e12ba

📥 Commits

Reviewing files that changed from the base of the PR and between 225f52b and 37cc9dc.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

📝 Walkthrough

Walkthrough

Adds a sidecar-free storage/config.collect.yaml and updates publish and CI workflows to detect and pass --config ./config.collect.yaml to the worker when that file exists during interface collection startup.

Changes

Interface collection configuration

Layer / File(s) Summary
Sidecar-free interface collection config
storage/config.collect.yaml
Defines an S3 bucket with placeholder credentials and a loopback-only endpoint to prevent network access during interface collection.
Publish workflow conditional config support
.github/workflows/_publish-registry.yml
release-binary and cargo-run paths now conditionally add --config ./config.collect.yaml to worker invocation when the file exists.
CI job conditional config support
.github/workflows/ci.yml
interface-smoke job's "Start worker from source" step detects WORKER/config.collect.yaml and passes --config ./config.collect.yaml when present.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • iii-hq/workers#68: Touches _publish-registry.yml worker startup and argument handling similar to these changes.
  • iii-hq/workers#76: Earlier change to the release-binary path for starting the prebuilt worker; this PR further adjusts that startup to pass a conditional config.
  • iii-hq/workers#67: Related edits around the publish workflow's interface-collection step and payload collection.

Suggested reviewers

  • sergiofilhowz
  • andersonleal

Poem

🐰 A tiny config hops in neat and spry,

No sidecars nudged, no network sigh,
The worker checks and, if it finds the file,
It starts with args and gathers with a smile,
Hooray — interfaces collected in style!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a sidecar-free config for registry interface collection to fix a startup failure in the publish workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/storage-publish-rustfs-sidecar

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 14 skipped (no docs/).

Layer Result
structure
vale
ai
render

Four for four. Nicely done.

The `interface boot smoke` job in ci.yml is the PR-side mirror of the publish
interface collection: it builds each changed Rust worker from source and boots
it to read back its registered interface. Like the publish flow, it booted the
worker with its default config — so storage crashed on startup with
LOCAL_BACKEND_BIN_NOT_FOUND (default config.yaml declares a local bucket that
spawns a rustfs sidecar unavailable in CI).

Apply the same config.collect.yaml convention here: launch with
`--config config.collect.yaml` when a worker ships one. Kept in lockstep with
_publish-registry.yml so the smoke check keeps mirroring the publish boot.
@ytallo

ytallo commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up: the first push surfaced a second boot path with the same root cause — the storage: interface boot smoke job in ci.yml (the PR-side mirror of the publish interface collection) also booted the default config and crashed on the missing rustfs sidecar. Added commit 37cc9dc applying the same config.collect.yaml convention there, kept in lockstep with _publish-registry.yml. All checks now green, including the storage e2e harness.

@ytallo
ytallo merged commit 3928bf1 into main Jun 6, 2026
14 checks passed
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