feat(cli): publish workloads on a URL with --http-port - #289
Conversation
|
Implementation notes, kept out of the description: This should not merge before network-services-operator#411. Two platform-side prerequisites #411 flags, neither addressed here:
Verification: |
Deploying a workload with an HTTP port now ends with a URL. Previously --port opened a port and gave the developer nothing to point a browser at. --http-port declares the workload an HTTP service and publishes it on a Datum-managed HTTPS URL, backed by a NetworkService and an HTTPProxy that load-balance across every city the workload runs in. --no-http removes it. --port is removed and hard-errors rather than aliasing to --http-port: silently aliasing would publish every existing workload on the next upgrade. Adds `compute open` (heroku/fly/railway convention) and a `compute domains` group for listing domains, showing one workload's URL in detail with per-city backend health, and attaching custom hostnames. Surfaces the URL in `compute workloads` and includes it in `compute destroy`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
deploy calls Declare on every run, so the common case is a workload that already has a URL. Pin that a redeploy neither recreates it nor churns it when nothing changed, that a changed port is written through, and that the canonical hostname survives — reissuing it would silently break every reference a developer has already shared. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Advanced proxy configuration — custom hostnames, DNS verification, path routing, certificates — belongs to dedicated ALB tooling, not the compute plugin. This plugin publishes a URL and stops there. Removes `compute domains` and `compute open`. The per-city backend health view moves into `workloads describe`, which already exists and is where a developer debugging their own workload looks; its health row is labelled Serving so it reads distinctly from the workload's own Health line. deploy still reads and carries forward the custom hostnames already on the proxy, and still fails closed if it cannot read them. That matters more now, not less: hostnames are configured out of band, so a redeploy that clobbered them would break something this plugin never saw being set up. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
57ac16a to
38b91f6
Compare
Stacking on the locations work leaves the URL views speaking the old vocabulary. The per-location backend table said CITY, and its next-steps line told users to run 'compute instances --city=', a flag that no longer exists — the suggested command would have failed. Renames url.Location.City to Location, the column to LOCATION, and the suggested flag to --location, so every place a URL reports where it is serving from uses one word for it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CI's golangci-lint run fails on this branch: deployFromFlags crossed the gocyclo limit at 32 once the locations validation and the HTTP service handling both landed in it, and two test fixtures wrote "http" where the httpPortName constant already exists. Lifts the three mutually exclusive placement flags into resolveLocationSelector, which is pure and now has the coverage the inline version never could — everything else in deployFromFlags needs a control plane behind the activation gate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
kevwilliams
left a comment
There was a problem hiding this comment.
Flag wiring is correct: --http-port validates 1-65535, rejects combination with --no-http and with -f, and --port hard-errors instead of silently aliasing. The already-published case is handled well — declare/apply reads back existing custom hostnames and reuses the managed hostname from status so a redeploy never clobbers or reissues a URL (verified by dedicated idempotence/redeploy tests), and destroy tears down the NetworkService/HTTPProxy with a leftover-cleanup path for partial failures. Help text, examples, and commit messages are clear and describe the migration rationale. No hold.
Main moved placement from city codes to locations (#264), added runtime classes (#259), published a shared instance-type catalog, and grew `datumctl compute deploy` a URL-publishing path (#289). The assistant's workload-creation surface was rebuilt on top of those rather than beside them. Semantic resolutions: - Placements are locations. `workloadspec.Placement` drops `CityCodes` for `Locations []string` plus `LocationSelector`, exactly one of which must be set; render emits `spec.placements[].locations` or the selector and refuses an empty or malformed one, the way admission does. The render tool's schema, its notes, the diff summary, the workload-create skill, llms-full.txt and the README all say "location" and point the model at `compute_locations_list` for the names, with `locationSelector` named as the way to place in every location of a city or region. - Location resolution keeps main's structure. `SourceServiceAvailability` is gone; `locations.ListAvailableLocations` is built on main's `AvailableLocations` and errors with `ErrAvailabilityNotServed` when the control plane serves no availability, so `compute_locations_list` still fails loud rather than reporting a project with nowhere to run. The manager's placement reads, which treat an unserved kind as no gate at all, are unchanged. The tool now reports `placeable` and `ready` alongside the name, city code and topology. - Instance types read `pkg/instancetype`. `validation.SupportedInstanceTypes` and the duplicated sizing table in the agent are deleted, along with TODO(#137): the catalog is the single source now. - Runtime classes: `workloadspec.Input` gains an optional `RuntimeClass`, passed through verbatim with no default, so the server picks its own. - `internal/cmd/compute/deploy/deploy.go` is main's version wholesale, for `--location`, `--location-selector`, `--city` and `--http-port`. The CLI no longer renders through workloadspec, so the parity test that pinned the two together is deleted rather than left stale. - Docs take main's triage-skill changes with this branch's `compute_` renames on top, and workload-create now says that a public HTTPS URL is published separately — today only by `datumctl compute deploy --http-port` — so `ports` makes a port reachable on the instance's address, not on a managed URL. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Deploying a workload with an HTTP port now ends with a URL you can open. Previously
--portopened a port and gave the developer nothing to point a browser at — the flag's own help text said "expose" and nothing was exposed.This plugin publishes a URL and stops there. Custom hostnames, path routing, certificates, and the rest of proxy configuration belong to dedicated ALB tooling, so there are no new commands here — just a flag, and the URL showing up where a developer already looks.
The experience
Deploy and get a URL, in one command:
Deploy without an HTTP port and it says so, rather than leaving you guessing the way
--portdid:Find it again in the list, or pull it out of
-o jsonfor a script:workloads describegains the URL with per-location backend health. This is the view that makes multi-location serving visible, which it previously was not — a developer could deploy to two locations and have no way to see that only one was taking traffic:--no-httpremoves the URL, anddestroynames what it is about to take down before asking:Breaking change:
--port→--http-port--portsaid what is listening, not who can reach it. Every comparable platform makes the declared role decide exposure instead: Heroku routes theweb:process, Render makes you pick Web Service or Private Service, Fly's port setting lives inside an[http_service]block.--http-portcarries that meaning in the name, so it needs no second flag to confirm you meant it.--no-httpremoves it.--portis removed and errors rather than quietly becoming--http-port, because quietly aliasing it would put every existing workload on the public internet the next time someone upgraded:Redeploying is safe and boring: an unchanged redeploy changes nothing, leaving
--http-portoff keeps the port the workload already has, and the URL is never reissued — so anything already pointing at it keeps working, including hostnames configured through ALB tooling that this plugin never set up itself.Product rationale and the scope boundaries are in
docs/enhancements/datumctl-compute-urls.md.Stacked on #264 — review that first; this branch targets it, not
main.