Move to apply-only operator lifecycle; retire kubectl unbounded install
- Dominant language
- Go
- Stars
- 28
- Forks
- 11
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 55
Description
## Summary
Follow-up to PR #386. That PR made the **operator the owner of CRD lifecycle**: `unbounded-operator` now installs and upgrades all CRDs at startup (`operator.BootstrapCRDs`), and `kubectl unbounded install` no longer applies CRDs. Environment-specific operator settings moved to the `unbounded-operator-config` ConfigMap (surfaced via `envFrom`, with each operator flag defaulting from the matching env var).
The long-term goal is for cluster install/maintenance to be **`kubectl apply -f operator-manifests.yaml`** with no imperative `install` step - upgrades come "for free" via an operator image rollout (the operator re-runs the CRD bootstrap and re-applies component workloads).
## Remaining work to retire `kubectl unbounded install`
- [ ] **Default `api-server-endpoint` without a kubeconfig.** `install` currently derives it from the kubeconfig server and writes it into `unbounded-operator-config`. A pure `kubectl apply` has no kubeconfig-derived value, so the operator needs a story here (explicit ConfigMap edit is required today; decide whether to document that as the contract or provide a smarter default). The in-cluster endpoint is **not** usable because it must be reachable by remote nodes dialing back.
- [ ] **Move image/namespace overrides from install flags to the manifest.** `--operator-image`, `--metalman-image`, and `--namespace` overrides become kustomize/env edits on the applied manifest. Namespace is already implicit via `POD_NAMESPACE`.
- [ ] **Ship a versioned `operator-manifests.yaml` release artifact** (single applyable bundle: namespace, SA, RBAC, ConfigMap, Deployment) so `kubectl apply -f ` is the supported entrypoint.
- [ ] **Decide the fate of `kubectl unbounded site init`** (keep as a client-side convenience for writing `Site` YAML, or document raw `Site` manifests).
- [ ] **Remove `install`** and its tests once the above land; update docs and the upgrade e2e.
- [ ] **(Optional) Typed `OperatorConfig` CRD** if the config surface grows enough to want schema validation/status (the ConfigMap is sufficient for the current small surface).
- [ ] **(Optional) Config hot-reload.** Editing `unbounded-operator-config` currently requires `kubectl rollout restart deployment/unbounded-operator` (env is read once at start). If desired, switch to a mounted config file + fsnotify (consistent with how `machina-config` is mounted).
## Context (already landed in PR #386)
- Operator installs CRDs at startup (`internal/operator/bootstrap.go`), pre-manager, idempotent SSA + wait-for-Established.
- Reconcile loop no longer applies CRDs; a `GenerationChangedPredicate` filters status-only Site updates.
- `install` applies only the operator manifests and writes `UNBOUNDED_API_SERVER_ENDPOINT` into `unbounded-operator-config`.
- Operator flags default from env (`UNBOUNDED_API_SERVER_ENDPOINT`, `UNBOUNDED_REAP_LEGACY_RESOURCES`) via `envFrom`.
Contributor guide
Research direction
Start with internal/operator/bootstrap.go and the changes from PR #386, then trace the install command, operator manifests, install tests, and upgrade e2e. Resolve the endpoint and override decisions, produce a versioned applyable operator-manifests.yaml, and remove install only after the listed tests and documentation are updated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- devops, infrastructure
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100