feat: unify fleet config schema across ecs and k8s runtimes - #145
Merged
Conversation
fleets.toml (AWS) and fleets-k8s.toml (k8s) were two independent
types/files (FleetBinding/K8sFleetBinding) — the same anti-pattern the
2026-08-18 openab-pty thread flagged ("one control plane, multiple
kinds": a new runtime should be a variant of the existing schema, not
a parallel one), and inconsistent with manifest.rs::Runtime's existing
tagged-enum precedent.
FleetBinding now carries a `runtime: FleetRuntime` (ecs default, or
k8s) with ECS-only (cluster/region/profile) and k8s-only
(context/namespace) fields alongside shared ones. migrate_legacy_k8s_bindings
folds an existing fleets-k8s.toml into fleets.toml once at startup and
renames the legacy file to .migrated (never deletes it).
Ref: Brett 2026-09-06 ("fleet config should host ecs and k8s and all
later possible options").
Brett 2026-09-06: runtime should always be explicit in fleets.toml, not silently inferred. Adds normalize_bindings_runtime_field (wired into OabMcp::from_env ahead of migrate_legacy_k8s_bindings) to rewrite pre-existing entries with an explicit `runtime = "ecs"` line once, since every binding written before this field existed was ECS.
fleet_config/fleet_config_write now read/write both ecs and k8s runtime fleets from the one fleets.toml; k8s_fleet_config/ k8s_fleet_config_write are gone (nothing else in this crate referenced the old parallel fleets-k8s.toml path). from_env runs the two studio-cp migrations (normalize then merge-legacy-k8s) before loading bindings. target() rejects naming a k8s-runtime fleet from an ecs-only tool with a clear error instead of a type error.
Mirrors the oab-mcp tool removal — fleet_config/fleet_config_write now cover both runtimes. NOTE: this crate (studio-desktop) can't be built or tested in this environment (not in the workspace, needs macOS/ GTK system libs — only the bundle-macos CI job builds it). Reviewed by hand against the surrounding bridge functions' pattern; no local signal.
Collapses the console-side split that mirrored the old Rust one: FleetConfigEntry now carries `runtime: "ecs" | "k8s"` with the two runtimes' fields alongside each other; fleetsK8sToml.ts is gone (appendFleetBlock in fleetToml.ts takes a runtime discriminant and writes the matching TOML keys, `runtime = "..."` always first since it's required now). deploy.ts's wizard always reads/writes through the one fleetConfig()/writeFleetConfig(), no more isK8s source-method branching. render.ts shows cluster (ecs) or context/namespace (k8s) depending on the fleet's runtime. main.ts's selectFleet declines to switch the roster view onto a k8s fleet (no cluster to point reads at) instead of silently breaking — k8s fleets still have no roster/observe UI, a separate, larger gap from this schema unification (flagged to Brett already). typecheck + vitest (101/101) + production build all pass.
… fleet Brett 2026-09-06: an empty members array should be written explicitly, not omitted — omitting it reads as "forgot to migrate this field", not "deliberately whole-namespace." (The console's appendFleetBlock already always wrote members for newly-created fleets; this only affects the legacy fleets-k8s.toml migration path.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brett (2026-09-06): the fleet config should host ECS and k8s (and later runtimes) under one schema, not a parallel file/type per runtime. This was flagged before — ADR-2 ("RuntimeDriver is the only layer with vendor terms"),
manifest.rs::Runtime's tagged-enum precedent, and the 2026-08-18 openab-pty discussion ("one control plane, multiple kinds") — but theFleetBinding/K8sFleetBindingconfig-binding layer never got the same treatment when k8s support landed (studio#63 slice 3f).studio-cp:FleetBinding/K8sFleetBinding(two structs, two files —fleets.toml/fleets-k8s.toml) collapse into oneFleetBindingwith a requiredruntime: "ecs" | "k8s"field (no default — Brett: explicit, not inferred) plus ECS-only (cluster/region/profile) and k8s-only (context/namespace) fields side by side.OabMcp::from_envin order: (1)normalize_bindings_runtime_field— rewrites any pre-existingfleets.tomlentry lackingruntimeto addruntime = "ecs"explicitly (targeted line insertion, not a TOML reserialize — comments/layout survive); (2)migrate_legacy_k8s_bindings— folds a legacyfleets-k8s.toml's entries intofleets.tomlasruntime = "k8s"blocks, renaming the old file to.migrated(never deleted).oab-mcp:k8s_fleet_config/k8s_fleet_config_writetools removed;fleet_config/fleet_config_writenow read/write both runtimes from the one file.src-tauri: matching bridge-command removal. Not locally verifiable —studio-desktopisn't in this workspace and needs macOS/GTK system libs this environment doesn't have; only thebundle-macosCI job builds it. Reviewed by hand against the surrounding bridge functions' pattern.FleetConfig/K8sFleetConfigtypes collapse into one (FleetConfigEntry.runtimediscriminant);fleetsK8sToml.tsis gone,appendFleetBlockinfleetToml.tstakes a runtime discriminant and writes the matching keys.deploy.ts's New Fleet wizard always goes through the onefleetConfig()/writeFleetConfig().render.tsshows cluster (ecs) or context/namespace (k8s) per fleet.Known gap, not introduced by this PR: k8s fleets still have no roster/observe UI in the console (
main.ts's tick/refresh/selectFleet are ECS-cluster-keyed) —selectFleetdeclines to switch onto a k8s fleet with a clear message rather than silently breaking. This was already a known gap before this PR (k8s fleets simply weren't visible in the config panel at all); this PR makes them visible in the Fleets list without pretending the roster-switch works yet.Test plan
cargo test -p studio-cp --lib— 35/35 passing (incl. migration + normalize round-trip tests)cargo test -p oab-mcp --lib— 3/3 passingcargo check --workspace --exclude studio-desktop— cleannpm run typecheck(console) — passesnpm test(console, vitest) — 101/101 passingnpm run build(console) — passesfleets-k8s.tomlafter first launch on this branch, and thatsrc-tauri's bridge removal doesn't break the New Fleet wizard's k8s path (no local signal for this layer)🤖 Generated with Claude Code