|
| 1 | +# AGENTS.md - AI Coding Assistant Briefing |
| 2 | + |
| 3 | +This document serves as a comprehensive briefing for AI coding assistants working with the operator-controller |
| 4 | +repository. It covers the WHAT, WHY, and HOW of contributing to this codebase. |
| 5 | + |
| 6 | +--- |
| 7 | + |
| 8 | +## Architecture Overview |
| 9 | + |
| 10 | +operator-controller is the central component of Operator Lifecycle Manager (OLM) v1, extending Kubernetes with APIs to |
| 11 | +install and manage cluster extensions. The project follows a microservices architecture with two main binaries: |
| 12 | + |
| 13 | +**operator-controller** |
| 14 | + - manages `ClusterExtension` and `ClusterExtensionRevision` CRDs |
| 15 | + - resolves bundles from configured source |
| 16 | + - unpacks bundles and renders manifests from them |
| 17 | + - applies manifests with phase-based rollouts |
| 18 | + - monitors extension lifecycle |
| 19 | + |
| 20 | +**catalogd** |
| 21 | + - manages user-defined `ClusterCatalog` resources to make references catalog metadata available to the cluster. |
| 22 | + - unpacks and serves operator catalog content via HTTP. |
| 23 | + - serves catalog metadata to clients in the cluster that need to use or present information about the contents of the |
| 24 | + catalog. For example, operator-controller queries catalogd for available bundles. |
| 25 | + |
| 26 | +--- |
| 27 | + |
| 28 | +## Tech Stack |
| 29 | + |
| 30 | +**Languages:** |
| 31 | +- **Go:** The Go version used by the project often lags the latest upstream available version in order to give |
| 32 | + integrators the ability to consume the latest versions of OLMv1 without being required to also consume the latest |
| 33 | + versions of Go. |
| 34 | +- **Runtime Platform:** Linux containers (multi-arch: amd64, arm64, ppc64le, s390x) |
| 35 | +- **Developer Platform:** Generally macOS and Linux. It is important that all shell commands used in Makefiles and |
| 36 | + other helper scripts work on both Linux and macOS. |
| 37 | + |
| 38 | +**Core Frameworks:** |
| 39 | +- **Kubernetes:** client-go, api, apimachinery |
| 40 | +- **controller-runtime** |
| 41 | +- **operator-framework/api:** For OLMv0 API types that are relevant to OLMv1 |
| 42 | +- **operator-registry** For file-based catalog (FBC) processing |
| 43 | +- **Helm:** helm-operator-plugins (which depends on helm itself) |
| 44 | + |
| 45 | +**Key Dependencies:** |
| 46 | +- **cert-manager** |
| 47 | +- **boxcutter (package-operator.run)** |
| 48 | + |
| 49 | +**Container Base:** |
| 50 | +- Base image: `gcr.io/distroless/static:nonroot` |
| 51 | +- User: `65532:65532` (non-root) |
| 52 | + |
| 53 | +**Build Tags:** |
| 54 | +- `containers_image_openpgp` - required for image handling |
| 55 | + |
| 56 | +**Tools (managed via .bingo/):** |
| 57 | +- controller-gen, golangci-lint, goreleaser, helm, kind, kustomize, setup-envtest, operator-sdk |
| 58 | + |
| 59 | +--- |
| 60 | + |
| 61 | +## Build & Test Commands |
| 62 | + |
| 63 | +### Build |
| 64 | + |
| 65 | +```bash |
| 66 | +# Build for local platform |
| 67 | +make build |
| 68 | + |
| 69 | +# Build for Linux (required for docker) |
| 70 | +make build-linux |
| 71 | + |
| 72 | +# Build docker images |
| 73 | +make docker-build |
| 74 | + |
| 75 | +# Full release build |
| 76 | +make release |
| 77 | +``` |
| 78 | + |
| 79 | +### Test |
| 80 | + |
| 81 | +```bash |
| 82 | +# Unit tests (uses ENVTEST) |
| 83 | +make test-unit |
| 84 | + |
| 85 | +# E2E tests |
| 86 | +make test-e2e # Standard features |
| 87 | +make test-experimental-e2e # Experimental features |
| 88 | +make test-extension-developer-e2e # Extension developer workflow |
| 89 | + |
| 90 | +# Regression tests |
| 91 | +make test-regression |
| 92 | + |
| 93 | +# All (non-upgrade, non-experimental) tests |
| 94 | +make test |
| 95 | +``` |
| 96 | + |
| 97 | +### Linting & Verification |
| 98 | + |
| 99 | +```bash |
| 100 | +# Run golangci-lint |
| 101 | +make lint |
| 102 | + |
| 103 | +# Run helm lint |
| 104 | +make lint-helm |
| 105 | + |
| 106 | +# Verify all generated code is up-to-date |
| 107 | +make verify |
| 108 | + |
| 109 | +# Format code |
| 110 | +make fmt |
| 111 | + |
| 112 | +# Fix lint issues automatically |
| 113 | +make fix-lint |
| 114 | +``` |
| 115 | + |
| 116 | +### Local Development |
| 117 | + |
| 118 | +```bash |
| 119 | +# Create kind cluster and deploy |
| 120 | +make run # Standard manifest |
| 121 | +make run-experimental # Experimental manifest |
| 122 | + |
| 123 | +# OR step by step: |
| 124 | +make kind-cluster # Create cluster |
| 125 | +make docker-build # Build images |
| 126 | +make kind-load # Load into kind |
| 127 | +make kind-deploy # Deploy manifests |
| 128 | +make wait # Wait for ready |
| 129 | + |
| 130 | +# Clean up |
| 131 | +make kind-clean |
| 132 | +``` |
| 133 | + |
| 134 | +### Manifest Generation |
| 135 | + |
| 136 | +```bash |
| 137 | +# Generate CRDs and manifests |
| 138 | +make manifests |
| 139 | + |
| 140 | +# Update CRDs and reference docs (when Go-based API definitions change) |
| 141 | +make update-crds crd-ref-docs |
| 142 | + |
| 143 | +# Generate code (DeepCopy methods) |
| 144 | +make generate |
| 145 | +``` |
| 146 | + |
| 147 | +--- |
| 148 | + |
| 149 | +## Conventions & Patterns |
| 150 | + |
| 151 | +### Folder Structure |
| 152 | + |
| 153 | +``` |
| 154 | +/ |
| 155 | +├── api/v1/ # API definitions (CRD types) |
| 156 | +├── cmd/ # Main entry points |
| 157 | +│ ├── operator-controller/ # Operator controller binary |
| 158 | +│ └── catalogd/ # Catalogd binary |
| 159 | +├── internal/ # Private implementation |
| 160 | +│ ├── operator-controller/ # Operator controller internals |
| 161 | +│ ├── catalogd/ # Catalogd internals |
| 162 | +│ └── shared/ # Shared utilities |
| 163 | +├── helm/ # Helm charts |
| 164 | +│ ├── olmv1/ # Main OLM v1 chart |
| 165 | +│ │ ├── base/ # Base manifests & CRDs |
| 166 | +│ │ ├── templates/ # Helm templates |
| 167 | +│ │ └── values.yaml # Default values |
| 168 | +│ └── prometheus/ # Prometheus monitoring |
| 169 | +├── test/ # Test suites |
| 170 | +│ ├── e2e/ # End-to-end tests |
| 171 | +│ ├── extension-developer-e2e/ # Extension developer tests |
| 172 | +│ ├── upgrade-e2e/ # Upgrade tests |
| 173 | +│ └── regression/ # Regression tests |
| 174 | +├── docs/ # Documentation (mkdocs) |
| 175 | +├── hack/ # Scripts and tools |
| 176 | +├── config/samples # Example manifests for ClusterCatalog and ClusterExtension |
| 177 | +├── manifests/ # Generated manifests |
| 178 | +├── .github/workflows/ # CI/CD workflows |
| 179 | +├── OWNERS # Defines approver and reviewer groups |
| 180 | +└── OWNERS_ALIASES # Defined group membership |
| 181 | +
|
| 182 | +``` |
| 183 | + |
| 184 | +### Naming Conventions |
| 185 | + |
| 186 | +- **Controllers:** `{resource}_controller.go` |
| 187 | +- **Tests:** `{name}_test.go` |
| 188 | +- **Internal packages:** lowercase, no underscores |
| 189 | +- **Generated files:** `zz_generated.*.go` |
| 190 | +- **CRDs:** `{group}.{domain}_{resources}.yaml` |
| 191 | + |
| 192 | +### Core APIs |
| 193 | + |
| 194 | +- **Primary CRDs:** |
| 195 | + - `ClusterExtension` - declares desired extension installations |
| 196 | + - `ClusterExtensionRevision` - revision management (experimental) |
| 197 | + - `ClusterCatalog` - catalog source definitions |
| 198 | +- **API domain:** `olm.operatorframework.io` |
| 199 | + - This is the API group of our user-facing CRDs |
| 200 | + - This is also the domain that should be used in ALL label and annotation prefixes that are generated by OLMv1) |
| 201 | +- **API version:** `v1` |
| 202 | + |
| 203 | +### Feature Gates |
| 204 | + |
| 205 | +Two manifest variants exist: |
| 206 | +- **Standard:** Production-ready features |
| 207 | +- **Experimental:** Features under development/testing (includes `ClusterExtensionRevision` API) |
| 208 | + |
| 209 | +--- |
| 210 | + |
| 211 | +## Git Workflows |
| 212 | + |
| 213 | +### Branching Strategy |
| 214 | + |
| 215 | +- **Main branch:** `main` (default, protected) |
| 216 | +- **Release branches:** `release-v{MAJOR}.{MINOR}` (e.g., `release-v1.2`) |
| 217 | +- **Feature branches:** Created from `main`, usually in forks, merged via PR |
| 218 | + |
| 219 | +### Commit Message Format |
| 220 | + |
| 221 | +``` |
| 222 | +<High-level description> |
| 223 | +
|
| 224 | +<Detailed description> |
| 225 | +``` |
| 226 | + |
| 227 | +### PR Requirements |
| 228 | + |
| 229 | +- Must pass all CI checks (unit-test, e2e, sanity, lint) |
| 230 | +- Must have both `approved` and `lgtm` labels (from repository approvers and reviewers) |
| 231 | +- DCO sign-off required (Developer Certificate of Origin) |
| 232 | +- Reasonable title and description |
| 233 | +- Draft PRs: prefix with "WIP:" or use GitHub draft feature |
| 234 | +- PR title must use specific prefix based on the type of the PR: |
| 235 | + - ⚠ (:warning:, major/breaking change) |
| 236 | + - ✨ (:sparkles:, minor/compatible change) |
| 237 | + - 🐛 (:bug:, patch/bug fix) |
| 238 | + - 📖 (:book:, docs) |
| 239 | + - 🌱 (:seedling:, other) |
| 240 | + |
| 241 | +### CI Workflows |
| 242 | + |
| 243 | +- `unit-test.yaml` - Unit tests with coverage |
| 244 | +- `e2e.yaml` - Multiple e2e test suites (7 variants) |
| 245 | +- `sanity.yaml` - Verification, linting, helm linting |
| 246 | +- `test-regression.yaml` - Regression tests |
| 247 | +- `go-apidiff.yaml` - API compatibility checks |
| 248 | +- `crd-diff.yaml` - CRD compatibility verification |
| 249 | +- `release.yaml` - Automated releases on tags |
| 250 | + |
| 251 | +### Release Process |
| 252 | + |
| 253 | +- **Semantic versioning:** `vMAJOR.MINOR.PATCH` |
| 254 | +- Tags trigger automated release via goreleaser |
| 255 | +- Patch releases from `release-v*` branches |
| 256 | +- Major/minor releases from `main` branch |
| 257 | +- Creates multi-arch container images |
| 258 | +- Generates release manifests and install scripts |
| 259 | + |
| 260 | +--- |
| 261 | + |
| 262 | +## Boundaries (What Not to Touch) |
| 263 | + |
| 264 | +### Generated Files (require special process) |
| 265 | + |
| 266 | +**Schema Files:** |
| 267 | +- `/api/v1/zz_generated.deepcopy.go` - Generated by controller-gen |
| 268 | +- `/helm/olmv1/base/*/crd/standard/*.yaml` - Standard CRDs (generated) |
| 269 | +- `/helm/olmv1/base/*/crd/experimental/*.yaml` - Experimental CRDs (generated) |
| 270 | +- **Process:** Modify types in `/api/v1/*_types.go`, then run `make manifests` |
| 271 | + |
| 272 | +**Generated Manifests:** |
| 273 | +- `/manifests/standard.yaml` - Generated by `make manifests` |
| 274 | +- `/manifests/experimental.yaml` - Generated by `make manifests` |
| 275 | +- `/manifests/standard-e2e.yaml` - Generated by `make manifests` |
| 276 | +- `/manifests/experimental-e2e.yaml` - Generated by `make manifests` |
| 277 | +- **Process:** Modify Helm charts in `/helm/olmv1/`, then run `make manifests |
| 278 | + |
| 279 | +**Generated Docs:** |
| 280 | +- `/docs/api-reference/olmv1-api-reference.md` - Generated by `make crd-ref-docs` |
| 281 | +- **Process:** Requires regeneration whenever API definitions change (`api/*/*_types.go`) |
| 282 | + |
| 283 | +### CI/CD & Project Metadata |
| 284 | + |
| 285 | +**Never modify without explicit permission:** |
| 286 | +- `/.github/workflows/*.yaml` - CI pipelines (consult team) |
| 287 | +- `/.goreleaser.yml` - Release configuration |
| 288 | +- `/Makefile` - Core build logic (discuss changes first) |
| 289 | +- `/go.mod` - Dependencies (use `make tidy`, avoid Go version bumps without discussion) |
| 290 | +- `/PROJECT` - Kubebuilder project config |
| 291 | +- `/OWNERS` & `/OWNERS_ALIASES` - Maintainer lists |
| 292 | +- `/CODEOWNERS` - Code ownership |
| 293 | +- `/mkdocs.yml` - Documentation site config |
| 294 | +- `/.bingo/*.mod` - Tool dependencies (managed by bingo) |
| 295 | +- `/.golangci.yaml` - Linter configuration |
| 296 | +- `/kind-config.yaml` - Kind cluster config |
| 297 | + |
| 298 | +### Helm Charts (requires careful review) |
| 299 | + |
| 300 | +- `/helm/olmv1/Chart.yaml` - Chart metadata |
| 301 | +- `/helm/olmv1/values.yaml` - Default values |
| 302 | +- `/helm/olmv1/templates/*.yaml` - Chart templates |
| 303 | + |
| 304 | +### Security & Compliance |
| 305 | + |
| 306 | +- `/DCO` - Developer Certificate of Origin |
| 307 | +- `/LICENSE` - Apache 2.0 license |
| 308 | +- `/codecov.yml` - Code coverage config |
| 309 | + |
| 310 | +--- |
| 311 | + |
| 312 | +## Important Notes for AI Agents |
| 313 | + |
| 314 | +1. **Never commit to `main` directly** - always use PRs |
| 315 | +2. **CRD changes** require running `make update-crds` and may break compatibility |
| 316 | +3. **API changes** in `/api/v1/` trigger CRD and CRD reference docs regeneration |
| 317 | +4. **Generated files** must be committed after running generators |
| 318 | +5. **Helm changes** require `make manifests` to update manifests |
| 319 | +6. **Go version changes** need community discussion (see CONTRIBUTING.md) |
| 320 | +7. **Dependencies:** 2-week cooldown policy for non-critical updates |
| 321 | + |
| 322 | +### Development Workflow |
| 323 | + |
| 324 | +1. Make changes to source code |
| 325 | +2. Run `make verify` to ensure generated code is updated |
| 326 | +3. Run `make lint` and `make test-unit` |
| 327 | +4. Commit both source and generated files |
| 328 | +5. CI will verify everything is in sync |
| 329 | + |
| 330 | +### Key Components to Understand |
| 331 | + |
| 332 | +**operator-controller:** |
| 333 | +- `ClusterExtension` controller - manages extension installations |
| 334 | +- `ClusterExtensionRevision` controller - manages revision lifecycle |
| 335 | +- Resolver - bundle version selection |
| 336 | +- Applier - applies manifests to cluster |
| 337 | +- Content Manager - manages extension content |
| 338 | + |
| 339 | +**catalogd:** |
| 340 | +- Catalog controllers - manage catalog unpacking |
| 341 | +- Storage - catalog storage backend |
| 342 | +- Server utilities - HTTP server for catalog content |
| 343 | + |
| 344 | +--- |
| 345 | + |
| 346 | +**Last Updated:** 2025-12-10 |
0 commit comments