Instructions for AI coding agents. For project overview, see README.md. For contribution guidelines, see CONTRIBUTING.md.
| Directory | Purpose |
|---|---|
apis/metal3.io/v1alpha1/ |
CRD types (BareMetalHost, HostFirmwareSettings, etc.) - separate Go module |
internal/controller/metal3.io/ |
Reconciliation logic with state machine |
internal/webhooks/metal3.io/ |
Validation/defaulting webhooks |
pkg/provisioner/ |
Provisioner interface (ironic, fixture, demo) |
pkg/hardwareutils/ |
BMC protocol handling - separate Go module |
config/ |
Kustomize manifests (CRDs, RBAC, webhooks) - auto-generated by make manifests, rarely edit directly |
hack/ |
CI scripts (prefer Make targets locally) |
test/e2e/ |
E2E tests with libvirt VMs |
CI uses GitHub Actions (.github/workflows/) and Prow.
Run these locally before submitting PRs:
Make targets:
| Command | Purpose |
|---|---|
make test |
Full verification (generate + lint + unit) |
make generate |
Regenerate Go code (deepcopy functions) |
make manifests |
Regenerate CRDs, RBAC, webhooks |
make unit |
Unit tests (requires envtest - do not use go test directly) |
make lint |
Go linting via golangci-lint (all modules) |
make mod |
Verify go.mod is tidy |
Hack scripts (auto-containerized, match CI exactly):
| Script | Purpose |
|---|---|
./hack/shellcheck.sh |
Shell script linting (shellcheck) |
./hack/markdownlint.sh |
Markdown linting (config: .markdownlint-cli2.yaml) |
./hack/manifestlint.sh |
Kubernetes manifest validation (kubeconform) |
- Go: Linting rules in
.golangci.yaml, license headers inhack/boilerplate.go.txt - Shell: Use
set -o errexit -o nounset -o pipefail - Markdown: 3-space indent for lists (
.markdownlint-cli2.yaml)
- Edit
apis/metal3.io/v1alpha1/*_types.go - Run
make generate manifests - Update webhooks in
internal/webhooks/if validation changes - Run
make test
BMO has standalone E2E tests using libvirt VMs and BMC emulators:
| Command | Purpose |
|---|---|
./hack/ci-e2e.sh |
Full E2E suite (requires libvirt, docker) |
GINKGO_FOCUS="inspection" ./hack/ci-e2e.sh |
Run specific test |
BMC_PROTOCOL=ipmi ./hack/ci-e2e.sh |
Test with IPMI protocol |
Key files: test/e2e/config/ironic.yaml, test/e2e/config/fixture.yaml
When reviewing pull requests:
- Security - Hardcoded secrets, unpinned dependencies, missing input validation
- Test coverage - New functionality should have tests
- Consistency - Match existing patterns in the codebase
- Breaking changes - Flag API/behavior changes affecting users
Focus on: internal/controller/, pkg/provisioner/, apis/, internal/webhooks/.
- Run
make unitto verify baseline - Check patterns in similar existing files
- Make minimal, surgical edits
- Run
make generate manifestsafter API changes - Run
make testbefore committing - Add tests for new functionality
- Pin external dependencies by SHA (containers, GitHub Actions, binaries)
- No hardcoded credentials
- Validate all inputs