feat(oabctl): K8sDriver skeleton — apply/scale/delete against a Deployment (slice 3b) - #99
Open
brettchien wants to merge 1 commit into
Conversation
…yment (slice 3b)
Second ProvisionDriver impl, behind kube-rs. Scope deliberately narrow:
- apply(): builds a k8s Deployment from an OABServiceManifest (image,
command = `openab run -c <configFrom>` — same convention EcsDriver uses,
env NAMESPACE/NAME/BOOTSTRAP_FROM, cpu/memory as resource requests+limits,
service account / node selector / tolerations from KubernetesRuntime),
server-side-applies it. Deployment name is `oab-{name}` — OAB's own
`namespace` maps directly onto the k8s namespace (already an isolation
boundary, the same job it does for ECS's flat `oab-{ns}-{name}` naming),
so unlike ECS there's no need to fold namespace into the resource name.
- scale(): patches replicas, same 0/1-only constraint as EcsDriver.
- delete(): deletes the Deployment, idempotent on 404.
- Kubeconfig context resolution: `K8sDriver::from_context(Option<&str>)` —
`None` uses the kubeconfig's current context, same "ambient default,
explicit override" shape aws_config uses. This is also how orbstack's
local cluster gets targeted later (3f) — just another context, no
special-casing.
Explicitly NOT handled yet, and apply() bails loudly rather than silently
mis-deploying if a manifest needs them:
- spec.bundleFrom (persona/skills bundle) — needs a ConfigMap/volume carrier,
sub-slice 3c.
- spec.secrets — ECS resolves into Secret.valueFrom ARNs; k8s needs a
different output shape (a Secret key selector), sub-slice 3d.
Also out of scope for this PR: observing k8s state into the canonical
6-state (status.rs's ECS service_status/instance_status has no k8s
counterpart yet — a new agent-lifecycle RuntimeDriver impl per ADR-2's
6-state<->k8s mapping table). Substantial enough to land as its own
follow-up rather than growing this one further.
Adds kube 0.99 + k8s-openapi 0.24 (rustls-tls, no openssl).
Stacked on #98 (3a) — this branch is 3a's branch + the K8sDriver commit;
GitHub will show 3a+3b combined in the diff until #98 merges, at which point
the diff narrows to just this. 7 new unit tests, 92/92 total green, clippy
-D warnings clean.
Ref: studio#97 (K8s driver — ADR #63 slice 3, sub-slice tracking)
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
Sub-slice 3b of #97 (K8s driver — ADR #63 slice 3):
K8sDriver, a secondProvisionDriverimplementation behindkube-rs, alongsideEcsDriver.apply()— builds a k8sDeploymentfrom anOABServiceManifestand server-side-applies it: image,command = ["openab","run","-c",configFrom](same conventionEcsDriveruses), envNAMESPACE/NAME/BOOTSTRAP_FROM, cpu/memory as resource requests+limits,serviceAccountName/nodeSelector/tolerationsfromKubernetesRuntime.scale()— patchesspec.replicas, same 0/1-only constraint as ECS (single bot token).delete()— deletes the Deployment, idempotent on 404.K8sDriver::from_context(Option<&str>)— kubeconfig context resolution;Noneuses the kubeconfig's current context (same "ambient default, explicit override" shapeaws_configgivesEcsDriver). This is also the path orbstack's local cluster will use later (3f) — just another context.oab-{name}, in the k8s namespace = OAB's ownmetadata.namespacedirectly (a k8s namespace is already an isolation boundary, same job OAB'snamespacedoes for ECS's flatoab-{ns}-{name}) — so no need to fold namespace into the resource name like ECS does.Explicitly out of scope (bails loudly, doesn't silently mis-deploy)
spec.bundleFrom— needs a ConfigMap/volume carrier. Sub-slice 3c.spec.secrets— ECS resolves intoSecret.valueFromARNs; k8s needs a different output shape (a Secret key selector). Sub-slice 3d.status.rs's ECSservice_status/instance_statushas no k8s counterpart — needs a newagent-lifecycleRuntimeDriverimpl per ADR-2's 6-state⇄k8s mapping table). Big enough to be its own follow-up rather than growing this PR.K8sDriverintostudio_api's actual dispatch —studio_api's functions takeaws_config::SdkConfig, meaningless for k8s; real dispatch needs the driver-selection inputFleetBinding(3f) provides.K8sDriverconforms toProvisionDriverand has its own test suite, same "declare the seam, second side fills in when it exists" precedent asmanifest::Runtime::Kubernetesitself.Stacking note
Branched from #98 (3a, still unmerged) — 3a's own follow-up commit fixed
ProvisionDriver's ECS-leaky signature (clustermoved onto the driver instance) right before this, whichK8sDriverneeded anyway. GitHub will show 3a+3b combined in the diff until #98 merges; the diff narrows to just this once it does.Testing
cargo test -p oabctl(92/92, 7 new) +cargo clippy -p oabctl --all-targets -- -D warnings— both clean, viaCARGO_PROFILE_DEV_DEBUG=0(this box's 21G disk + memory can't build full debug info for the aws-sdk+kube dependency tree — full-workspace build deferred to CI as usual here).Ref #97.