🤖 feat: single-binary dual application (controller + aggregated API server)#11
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f875bf32ba
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Addressed feedback: added |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 582530c2f9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Added |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
db10e33 to
10f715b
Compare
…PI server - Add metav1.AddToGroupVersion for v1 OptionsExternalVersion so ListOptions is registered in the scheme (required by GenericAPIServer.InstallAPIGroup). - Add metav1.AddMetaToScheme for Table/PartialObjectMetadata types. - Implement rest.SingularNameProvider on WorkspaceStorage and TemplateStorage (required by newer k8s.io/apiserver resource registration).
Address review feedback: controller deployment was missing serviceAccountName, running as default SA. Add dedicated coder-k8s-controller ServiceAccount and reference it.
…olPlane access Add RBAC rules matching kubebuilder markers on CoderControlPlaneReconciler: - get/list/watch/create/update/patch/delete on codercontrolplanes - get/update/patch on codercontrolplanes/status - update on codercontrolplanes/finalizers
- Group var declarations in storage files (gofumpt) - Add package-level doc comments for all new packages (revive)
10f715b to
e6a93a9
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e6a93a9bf6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The e2e deployment had no args, which now fails since --app is required. Pass --app=controller explicitly.
|
@codex review Addressed: added |
|
Codex Review: Didn't find any major issues. Keep them coming! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Transforms the
coder-k8sbinary into a dual-application binary that supports two independent modes via--app=controller|aggregated-apiserver, running from the same container image.Background
The project needs an aggregated API server alongside the existing controller to serve
CoderWorkspaceandCoderTemplateresources viaaggregation.coder.com/v1alpha1. Both applications must run independently — the aggregated API server does not depend on controller-runtime.Implementation
Mode-based dispatch
main.gointo a thin entrypoint that delegates to a testablerun(args)function inapp_dispatch.go--app=controllerstarts the existing controller-runtime manager (extracted intointernal/app/controllerapp/)--app=aggregated-apiserverstarts the new aggregated API server (internal/app/apiserverapp/)--appvalues fail fast with assertion-style errorsAggregated API types
aggregation.coder.com/v1alpha1with two resources:CoderWorkspace—spec.running bool,status.autoShutdown *metav1.TimeCoderTemplate— same schemak8s.io/apimachinery/pkg/runtime.SchemeBuilder(not controller-runtime wrapper)hack/update-codegen.shAggregated API server
GenericAPIServerwith self-signed TLS, anonymous auth, allow-all authz (scaffold defaults)rest.Storage,rest.Getter,rest.Lister,rest.Scoper,rest.SingularNameProviderdefaultandsandboxnamespacesSkipOpenAPIInstallation=truefor the scaffold phaseDeployment manifests
deploy/controller-deployment.yaml— Deployment with--app=controllerdeploy/apiserver-deployment.yaml— Deployment with--app=aggregated-apiserverdeploy/apiserver-service.yaml— Service for the aggregated API serverdeploy/apiserver-apiservice.yaml— APIService registration forv1alpha1.aggregation.coder.comdeploy/rbac.yaml— ServiceAccount, auth-delegator ClusterRoleBinding, authentication-reader RoleBindingTests
Validation
make test✅ — all tests passmake build✅ — binary compilesmake verify-vendor✅ — vendor is in syncgofmt -l✅ — no formatting issuesRisks
SkipOpenAPIInstallation=true); full OpenAPI serving requires generated definitions.📋 Implementation Plan
Plan: Single-binary dual application (
controller+ aggregated API server)Context / Why
We need one
coder-k8sbinary that can run two distinct applications:CoderWorkspaceandCoderTemplate.Per your direction, the aggregated API server must run independently from the controller-runtime instance. The cleanest shape is mode-based dispatch in one binary (one process runs one mode), with separate deployments using the same container image.
Evidence
main.gocurrently always starts controller-runtime and has no mode dispatch.Dockerfile.goreleaserhas a single entrypoint (/coder-k8s), which supports argument-based mode selection without changing images.go.moddoes not includek8s.io/apiserveryet.CoderControlPlane; no aggregated API group/resources exist yet.hack/update-codegen.shcurrently generates deepcopy only forapi/v1alpha1.Implementation details
Refactor startup into explicit app modes in the existing root binary
main.gobinary and add a required/validated selector flag (e.g.--app=controller|aggregated-apiserver).Move current controller-runtime wiring behind
runControllermain.gointo a dedicated package (e.g.internal/app/controllerapp).--app=controlleris functionally equivalent to current behavior.manager != nil,reconciler dependencies != nil).Add aggregated API types for
CoderWorkspaceandCoderTemplateapi/aggregation/v1alpha1(groupaggregation.coder.com, versionv1alpha1).spec.running boolstatus.autoShutdown *metav1.TimeImplement aggregated API server app behind
runAggregatedAPIServerk8s.io/apiserver(+ any required companion libs likek8s.io/component-base).GenericAPIServerconfig with delegated authn/authz and secure serving.aggregation.coder.com/v1alpha1) with two resources:coderworkspacescodertemplatesAdd hardcoded storage implementations for scaffolding
internal/aggregated/storage/...).rest.Storage+rest.Getter+rest.Listerwith deterministic hardcoded objects.autoShutdowntimestamps.Update codegen and wiring scripts
hack/update-codegen.shto include both API packages:./api/v1alpha1./api/aggregation/v1alpha1go listresults.Deploy as two independent apps from one image
v1alpha1.aggregation.coder.com).system:auth-delegatorandextension-apiserver-authentication-reader).Tests and validation
make codegen,make verify-vendor,make test,make build.Design choice: one process per mode (not both at once)
This keeps operational boundaries clear and matches your requirement that the aggregated API server run independently from controller-runtime. If we later want an "all" mode, we can add it explicitly without changing this base architecture.
Generated with
mux• Model:anthropic:claude-opus-4-6• Thinking:xhigh• Cost:$0.36