You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Summary
Adds baseline controller-runtime scaffolding for a new
`CoderControlPlane` API and controller.
### Changes
- Added `api/v1alpha1` package with group/version registration and
`CoderControlPlane` types.
- Generated deepcopy methods for the new API types.
- Added `internal/controller/CoderControlPlaneReconciler` scaffold with
no-op reconcile flow and RBAC markers.
- Replaced hello-world `main.go` with controller-runtime manager
bootstrap and reconciler wiring.
- Replaced hello-world tests with scaffold smoke tests for scheme
registration and defensive setup assertions.
- Replaced placeholder `make codegen` target with a repeatable vendored
deepcopy generator script.
### Validation
- `make codegen`
- `make test`
- `make build`
- `make verify-vendor`
---
<details>
<summary>📋 Implementation Plan</summary>
# Plan: Add baseline `CoderControlPlane` controller-runtime scaffolding
## Context / Why
The repository is currently a bootstrap "hello world" binary. This PR
should introduce a **minimal but extensible** controller-runtime
scaffold for a new resource `CoderControlPlane` with only placeholder
API fields (`spec.image` and a placeholder status field). The goal is to
create a clean template that future PRs can copy for additional
resources/controllers, without prematurely adding business logic.
## Evidence
- **Sub-agent report `349d2b2a6f`**: no existing API
types/CRDs/controllers; recommended `api/v1alpha1` + controller skeleton
layout.
- **Sub-agent report `7e4a92efeb`**: no manager/controller wiring yet;
`main.go` is still hello-world and needs controller-runtime manager
setup.
- **`main.go` (lines 1-16)**: prints `hello world`; no Kubernetes
manager bootstrap.
- **`main_test.go` (lines 1-11)**: only tests `helloMessage()`.
- **`Makefile` (lines 1-28)**: has vendor/test/build plus placeholder
`codegen` echo target.
- **`go.mod` (lines 5-10)**: already includes
`sigs.k8s.io/controller-runtime`, `k8s.io/apimachinery`, and
`k8s.io/client-go`, so baseline deps for scaffolding are present.
- **Repo tree**: no `api/`, `internal/controller/`, or `config/`
scaffold exists yet.
These sources are sufficient because they confirm this PR must establish
first-time scaffolding rather than extending existing controller code.
## Implementation details (ordered)
1. **Create API group/version package for CR registration**
- Add `api/v1alpha1/doc.go` and `api/v1alpha1/groupversion_info.go`.
- Define `GroupVersion`, `SchemeBuilder`, and `AddToScheme` so future
resources can register in the same package.
- Keep this package intentionally reusable for additional resource
types.
```go
// api/v1alpha1/groupversion_info.go
package v1alpha1
var (
GroupVersion = schema.GroupVersion{Group: "coder.com", Version:
"v1alpha1"}
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
AddToScheme = SchemeBuilder.AddToScheme
)
```
2. **Add `CoderControlPlane` API type with placeholder spec/status**
- Add `api/v1alpha1/codercontrolplane_types.go` containing:
- `CoderControlPlaneSpec` with placeholder field:
- `Image string \`json:"image,omitempty"\``
- `CoderControlPlaneStatus` with a placeholder (e.g. `Phase string`).
- Root/list objects (`CoderControlPlane`, `CoderControlPlaneList`).
- Include kubebuilder markers (`object:root`, `subresource:status`) so
this shape can become CRD/RBAC generation input later.
- Ensure types are registered via `SchemeBuilder.Register(...)`.
```go
type CoderControlPlaneSpec struct {
Image string `json:"image,omitempty"`
}
type CoderControlPlaneStatus struct {
Phase string `json:"phase,omitempty"`
}
```
3. **Add controller skeleton with no-op reconcile**
- Add `internal/controller/codercontrolplane_controller.go` with:
- `CoderControlPlaneReconciler` struct (`client.Client`, `Scheme
*runtime.Scheme`).
- `Reconcile(ctx, req)` that fetches the object and exits without
business logic.
- `SetupWithManager(mgr)` using `For(&v1alpha1.CoderControlPlane{})`.
- RBAC markers for base resource/status/finalizers.
- Include explicit TODO comments for future extension points
(finalizers, status progression, child resources).
- Keep defensive checks in setup/reconcile paths (fail fast on
impossible states, consistent with repository style).
```go
func (r *CoderControlPlaneReconciler) Reconcile(ctx context.Context, req
ctrl.Request) (ctrl.Result, error) {
cp := &coderv1alpha1.CoderControlPlane{}
if err := r.Get(ctx, req.NamespacedName, cp); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// TODO: add reconciliation logic in follow-up PRs.
return ctrl.Result{}, nil
}
```
4. **Replace hello-world entrypoint with manager wiring**
- Update `main.go` to initialize a controller-runtime manager:
- Build scheme and register `client-go` built-ins + `api/v1alpha1`.
- Construct manager from in-cluster/kubeconfig.
- Register `CoderControlPlaneReconciler`.
- Start manager with signal handler.
- Remove `helloMessage()` usage from runtime path; convert to standard
controller bootstrap logging/error handling.
```go
if err := coderv1alpha1.AddToScheme(scheme); err != nil {
setupLog.Error(err, "unable to add Coder API to scheme")
os.Exit(1)
}
if err := (&controller.CoderControlPlaneReconciler{Client:
mgr.GetClient(), Scheme: mgr.GetScheme()}).SetupWithManager(mgr); err !=
nil {
setupLog.Error(err, "unable to create controller", "controller",
"CoderControlPlane")
os.Exit(1)
}
```
5. **Update tests from hello-world to scaffold smoke checks**
- Replace/remove `main_test.go` hello-world assertion.
- Add minimal compile/smoke-focused tests for the new scaffold (e.g.,
scheme registration test for `CoderControlPlane` GVK, optional
lightweight setup test).
- Keep tests intentionally light for this scaffolding PR; defer
envtest-heavy behavior checks to follow-ups.
6. **Tighten build/codegen ergonomics just enough for repeatability**
- Update `Makefile` so `codegen` is no longer a placeholder message;
make it run whichever generation step is chosen for this PR (at minimum
deepcopy generation workflow or explicit TODO-backed command stub used
by CI/docs).
- Keep changes minimal: enough to make adding the *next*
resource/controller follow a repeatable pattern.
<details>
<summary>Why keep this minimal?</summary>
This PR’s purpose is structural scaffolding. Avoid introducing broad
deployment manifests or full envtest harness unless strictly required
for compilation/testing. The next PRs can incrementally add richer
generation, manifests, and reconcile behavior.
</details>
## Validation plan
- Run formatting/import fixes on touched Go files.
- Run `make test`.
- Run `make build`.
- If `codegen` is updated in this PR, run `make codegen` and ensure
generated artifacts are committed and `make test` still passes.
## Out of scope for this PR
- Non-placeholder spec/status semantics.
- Finalizer workflows, child resource orchestration, rollout logic.
- Production-grade status conditions/events.
- Multi-resource controller abstractions beyond what is needed to
establish the template layout.
</details>
---
_Generated with [`mux`](https://github.com/coder/mux) • Model:
`openai:gpt-5.3-codex` • Thinking: `xhigh`_
0 commit comments