Skip to content

feat: datumctl compute plugin — deploy and manage workloads from the CLI#113

Draft
scotwells wants to merge 8 commits into
mainfrom
feat/datumctl-compute-plugin
Draft

feat: datumctl compute plugin — deploy and manage workloads from the CLI#113
scotwells wants to merge 8 commits into
mainfrom
feat/datumctl-compute-plugin

Conversation

@scotwells
Copy link
Copy Markdown
Contributor

Summary

Adds the datumctl compute plugin so developers can deploy and manage containerized workloads on Datum Cloud directly from the CLI.

Commands shipped:

  • deploy — push a container image as a workload with flags or a manifest file; waits for rollout
  • destroy — tear down a workload with a confirmation prompt
  • status — show workload health, per-city placement summary, and the active revision
  • instances — list all running instances across cities, with describe for full detail
  • scale — adjust minimum replica count across all placements
  • rollout — watch live rollout progress, browse revision history, and roll back to any prior revision
  • restart — trigger a rolling restart of a workload or a specific city
  • quota — inspect per-city instance usage and surface quota-exceeded messages

Revision history is stored as a ConfigMap per workload so rollout history and rollout undo work without server-side tracking.

Dependencies

What's not included

  • logs — telemetry service not yet implemented
  • Tests — next step is adding envtest-based integration tests for each command
  • cities / instance-types resource listing commands

Related

Closes #98. Design proposal in #111.

scotwells and others added 7 commits May 22, 2026 16:49
Adds the datumctl-compute plugin binary with commands for deploying and
managing containerized workloads on Datum Cloud via the developer CLI.

Commands:
- deploy     — create or update a workload from flags or a manifest file
- destroy    — delete a workload and clean up its revision history
- status     — show health, placement summary, and recent revision info
- instances  — list and describe running instances across cities
- scale      — adjust minimum replica count across placements
- rollout    — watch live progress, view history, and roll back revisions
- restart    — trigger a rolling restart of a workload or specific city
- quota      — inspect per-city instance usage and quota headroom

Closes #98. Depends on datum-cloud/datumctl#198.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Within a project's virtual control plane, all resources live in the
"default" namespace — the project slug is only used to route to the
right control plane URL. Updated all commands to use
util.ResourceNamespace ("default") instead of the project name as the
k8s namespace.

Also corrects the instance type default from "d1-standard-2" to
"datumcloud/d1-standard-2" to match the format the admission webhook
requires.

Discovered while testing against the staging environment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The datumctl module requirement was upgrading controller-runtime to
v0.23.3, which broke compatibility with multicluster-runtime and milo.
Eliminated the dependency by:

- Inlining the --plugin-manifest protocol in main.go
- Reading DATUM_API_HOST and DATUM_CREDENTIALS_HELPER from env directly
  in util/client.go instead of via plugin.Context()/plugin.Token()
- Reading DATUM_ORG from env in root.go instead of via plugin.NewRootCmd
- Dropping the now-unreachable internal/cmd/compute/client.go

Also updates CI workflows to use go-version-file instead of a pinned
go 1.24.0, and bumps golangci-lint to v2.12.2 which supports go 1.25.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Upgrades controller-runtime from v0.21.0 to v0.23.3 and multicluster-runtime
from v0.21.0-alpha.8 to v0.23.3, which unblocks adding go.datum.net/datumctl
as a direct dependency.

The CLI plugin (datumctl-compute) now uses the official datumctl plugin SDK:
- plugin.ServeManifest() for the --plugin-manifest protocol
- plugin.NewRootCmd() for pre-wired org/project/output flags
- plugin.Context() and plugin.Token() for credential access

Controller breaking changes addressed: ClusterName distinct type, Watches
callback signature, NewWebhookManagedBy generic API. A local milo provider
fork is added at internal/provider/milo since the upstream package hasn't
been updated for the ClusterName type change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Addresses 63 lint findings across errcheck, goconst, gocyclo, gofmt,
prealloc, staticcheck, and unparam linters:

- gofmt/goimports: reformat cmd/main.go, deploy.go, util/client.go, webhook
- errcheck: assign discarded fmt.Fprint* and Flush returns to _
- staticcheck: update webhook to generic admission.Defaulter[T]/Validator[T]
  with WithDefaulter/WithValidator; fix SA4010 unused append in quota.go;
  remove redundant .ObjectMeta selectors in restart.go
- unparam: rename four never-used function parameters to _
- gocyclo: extract helpers from watch.Rollout and quota.runQuota to reduce
  cyclomatic complexity below threshold
- goconst: extract repeated string literals to named constants across
  controllers, validation, and tests
- prealloc: preallocate slices with known capacity in validation and tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- errcheck: fix unchecked fmt.Fprint* returns in deploy, quota, rollout, scale
- prealloc: preallocate allErrs in workload_validation.go and stateful test
- gofmt: reformat destroy.go, instances.go, rollout.go

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- golangci.yml: exclude errcheck for internal/cmd/* — ignoring write
  errors on stdout/stderr is idiomatic in CLI tools
- prealloc: preallocate allErrs in validateScaleSettingMetrics
- gofmt: reformat status.go, instance_controller_test.go

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wire ValidArgsFunction on every command that accepts a workload name
(deploy, destroy, restart, rollout, rollout history, rollout undo,
scale, status) and register flag completion for instances --workload.

All completions call a shared CompleteWorkloadNames helper in
internal/cmd/compute/util that fetches live workload names from the
API and always returns ShellCompDirectiveNoFileComp so the shell
never falls back to filename completion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

Define the UX, DX, and AX for deploying and managing compute workloads

1 participant