feat: wire cmd/duckgres-controlplane via shared CLIInputs flag registrar#523
Merged
Conversation
Lifts the ~50 CLIInputs-backed CLI flag declarations out of root main.go into configresolve.RegisterCLIInputsFlags so the all-in-one duckgres binary and cmd/duckgres-controlplane share one flag table — adding a new field to CLIInputs without registering a flag fails CI loudly via the new TestRegisterCLIInputsFlagsCoversEveryCLIBackedField drift guard, instead of silently doing nothing. cmd/duckgres-controlplane is no longer a stub: it parses flags via the shared registrar plus its own bespoke set (--config, --log-level, --mode, --socket-dir, --version, --help), resolves config via configresolve.ResolveEffective, ensures TLS certs (or hands off to ACME), starts the metrics server, and calls controlplane.RunControlPlane. Local smoke run confirms it binds the PG-wire port + :9090, accepts TCP, and serves real Prometheus metrics. The libduckdb-free invariant (CI guard #499) is preserved — go list -deps reports no duckdb-go in the dep tree. Worker stays bespoke (its 14 flags ARE the documented worker-pod surface), and a --mode control-plane accept-and-validate flag mirrors the worker's --mode duckdb-service for symmetry. cliboot.InitMetrics is shared, and just test-unit now also runs ./configresolve/... so the drift guard fires on every CI pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Wires
cmd/duckgres-controlplaneto actually run, and lifts the ~50 CLIInputs-backed flag declarations out of rootmain.gointo a shared registrar so the two binaries can never drift on the resolver's CLI surface.configresolve.RegisterCLIInputsFlags(*flag.FlagSet) func() CLIInputsregisters every CLIInputs-backed CLI flag onto the provided FlagSet and returns a harvest closure that produces a populatedCLIInputs(withSet) post-Parse. Each binary calls this then adds its own bespoke (b)-bucket flags. The newTestRegisterCLIInputsFlagsCoversEveryCLIBackedFieldtest uses reflection to assert every CLIInputs field has a corresponding flag — adding a new field without a flag now fails CI loudly instead of silently doing nothing. The 6 env-only K8s pod-scheduling fields (CLAUDE.md-documented) are explicitly excluded by name.cmd/duckgres-controlplaneis no longer a stub. It:--config,--log-level,--mode,--socket-dir,--version,--help. (--modeaccepts onlycontrol-plane; symmetric withcmd/duckgres-worker's--mode duckdb-service. Loud rejection on misuse, exit 2.)configresolve.ResolveEffective, ensures TLS certs (or hands off to ACME), starts the metrics server, buildscontrolplane.ControlPlaneConfig, and callscontrolplane.RunControlPlane.--mode control-planebranch and does not importduckdbservice— CI guard ci: guard cmd/duckgres-controlplane against duckdb-go regressions #499 (go list -deps ./cmd/duckgres-controlplane | grep duckdb-goempty) is preserved.Root
main.godrops ~75 lines of inlineflag.*declarations and the corresponding ~55-lineCLIInputs{...}literal in favour ofharvestCLIInputs := configresolve.RegisterCLIInputsFlags(flag.CommandLine)+cli := harvestCLIInputs(). Bespoke flags stay inline.cliboot.InitMetricsis lifted from rootmain.goso both binaries share the Prometheus metrics-server bring-up loop with identical retry behaviour. The all-in-one binary calls it; the CP-only binary calls it; the worker correctly does not (workers in--mode duckdb-servicewould all fight over:9090).just test-unitnow also runs./configresolve/...so the drift guard fires on every CI pass.Why this exists
Phase B of the post-#521 validation pass concluded that two ~60-flag tables would inevitably drift over time, while the (b)-bucket of mode/runtime/transport flags doesn't fit a single unified registrar. The shape we landed — shared registrar for the (a) bucket, bespoke flags per binary for (b) — keeps the resolver's CLI surface honest without forcing unnatural coupling on
--mode,--repl,--psql,--duckdb-*, etc.This unblocks one of two latent gaps surfaced in the validation pass:
cmd/duckgres-controlplanewas a crash-loop stub in every matrix-CD image until now. Pre-existingcmd/duckgres-workerfixes (#521, #522) handle the worker side.Test plan
go build ./...cleango vet ./...cleanjust test-unitgreen (now includes./configresolve/...)go test -count=1 ./controlplane/...greenTestRegisterCLIInputsFlagsCoversEveryCLIBackedFieldpasses — every CLI-backed CLIInputs field maps to a registered flag, every registered flag maps to a CLIInputs fieldTestRegisterCLIInputsFlagsHarvestPropagatesValuesAndSetpasses — values andSetmap populated correctly post-Parse--version/--help/--mode standalone(rejected) all behave correctly--worker-backend process: binds PG-wire (127.0.0.1:25432), serves Prometheus on :9090, accepts TCP handshake, generates self-signed certsgo list -deps ./cmd/duckgres-controlplane | grep duckdb-gois empty (CI guard ci: guard cmd/duckgres-controlplane against duckdb-go regressions #499 preserved)🤖 Generated with Claude Code