|
| 1 | +# EKCO — Agent Guide |
| 2 | + |
| 3 | +Compact, repo-specific guidance for OpenCode sessions. |
| 4 | + |
| 5 | +## What this is |
| 6 | + |
| 7 | +EKCO (Embedded kURL cluster operator) is a single Go binary that runs as a Kubernetes operator to maintain the health of a kURL cluster. It is **not** a library or multi-service repo. |
| 8 | + |
| 9 | +- **Language / toolchain:** Go (module `github.com/replicatedhq/ekco`) |
| 10 | +- **Entrypoint:** `cmd/ekco/main.go` |
| 11 | +- **CLI framework:** Cobra / Viper (commands live in `cmd/ekco/cli/`) |
| 12 | +- **Primary command:** `ekco operator` (long-running operator) |
| 13 | +- **Other commands:** `purge-node`, `rotate-certs`, `regen-cert`, `change-load-balancer`, `generate-haproxy-*`, `set-kubeconfig-server` (see `cmd/ekco/cli/`) |
| 14 | + |
| 15 | +## Build, test, lint |
| 16 | + |
| 17 | +Use the Makefile. Do not guess the Go version or linter config. |
| 18 | + |
| 19 | +```bash |
| 20 | +# Install tooling (golangci-lint) |
| 21 | +make deps |
| 22 | + |
| 23 | +# Full verification — order enforced by Makefile: lint -> vet -> test |
| 24 | +make test |
| 25 | + |
| 26 | +# Build binary (outputs bin/ekco) |
| 27 | +make build |
| 28 | + |
| 29 | +# Build Docker image |
| 30 | +make docker-image |
| 31 | +``` |
| 32 | + |
| 33 | +**Lint rules are non-default.** `.golangci.yaml` disables `errcheck` and `staticcheck`, and ignores all `*_test.go` files (`exclusions.paths`). Do not re-enable them locally. |
| 34 | + |
| 35 | +**Test scope:** `go test ./pkg/... ./cmd/...` — only `pkg` and `cmd`; there is no root-level test target. |
| 36 | + |
| 37 | +## Docker / deploy quirks |
| 38 | + |
| 39 | +- The Dockerfile is at `deploy/Dockerfile`, not the repo root. |
| 40 | +- `ROOK_VERSION` defaults to `1.11.8` in the Makefile and Dockerfile. |
| 41 | +- The build stage downloads Helm and pulls `rook-ceph-cluster` chart into `pkg/helm/charts`. |
| 42 | +- Git SHA / version are injected via ldflags at build time (`pkg/version`). |
| 43 | + |
| 44 | +## Manual integration testing |
| 45 | + |
| 46 | +Do **not** use `make docker-image && kubectl apply -k deploy/` — the README notes this is broken and out of sync. |
| 47 | + |
| 48 | +Current workflow (from README): |
| 49 | + |
| 50 | +1. `make build-ttl.sh` — pushes a temporary image to `ttl.sh/${USER}/ekco:12h`. |
| 51 | +2. Deploy a kURL cluster that includes EKCO. |
| 52 | +3. Patch the deployment: |
| 53 | + ```bash |
| 54 | + kubectl edit -n kurl deployment/ekc-operator |
| 55 | + # set image to ttl.sh/<user>/ekco:12h and imagePullPolicy: Always |
| 56 | + kubectl delete pod -l app=ekc-operator -n kurl |
| 57 | + ``` |
| 58 | + |
| 59 | +## Mocks |
| 60 | + |
| 61 | +Generated with `github.com/golang/mock`: |
| 62 | + |
| 63 | +```bash |
| 64 | +make generate-mocks |
| 65 | +``` |
| 66 | + |
| 67 | +This currently only covers `pkg/k8s/exec.go` → `pkg/k8s/mock/mock_exec.go`. |
| 68 | + |
| 69 | +## Monorepo boundaries |
| 70 | + |
| 71 | +There are none. The repo is a single Go module with two top-level directories: |
| 72 | + |
| 73 | +- `cmd/` — CLI commands and `main.go` |
| 74 | +- `pkg/` — operator logic, cluster controller, K8s clients, webhooks, cert rotation, object-store helpers, etc. |
| 75 | +- `deploy/` — Dockerfile, Kustomize manifests, and RBAC for the operator |
| 76 | + |
| 77 | +No frontend, no separate API service, no nested Go modules. |
| 78 | + |
| 79 | +## Key external dependencies & constraints |
| 80 | + |
| 81 | +- Deep integration with **Rook Ceph**, **Kubernetes**, **Contour**, **Velero**, **etcd**, and **Prometheus Operator**. |
| 82 | +- `go.mod` carries a large set of `replace` and `exclude` blocks inherited from Rook. Do not prune them; they resolve transitive conflicts. |
| 83 | +- CI uses `go-version-file: 'go.mod'` so the declared Go version is the source of truth. |
| 84 | + |
| 85 | +## CI / release conventions |
| 86 | + |
| 87 | +- **PRs:** `make deps test build` + `make docker-image` (pushed to `ttl.sh`). |
| 88 | +- **Main branch:** `make docker-image` pushed to `replicated/ekco:alpha`. |
| 89 | +- **Releases:** Push a semver tag `v*.*.*` (e.g. `git tag -a v0.1.0 -m "Release v0.1.0" && git push origin v0.1.0`). Image is pushed to `replicated/ekco:<tag>`. |
| 90 | +- Scheduled vulnerability scans use Grype (`.grype.yaml`) against the repo and the built image. |
| 91 | + |
| 92 | +## When in doubt |
| 93 | + |
| 94 | +- Prefer `Makefile` targets over raw `go` commands — ldflags and build args matter. |
| 95 | +- Trust executable configs (`Makefile`, `.golangci.yaml`, `.github/workflows/`) over prose in README for build/test steps. |
0 commit comments