🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Qing Hao <qhao@redhat.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
12 KiB
Development Guide
This document provides comprehensive guidelines for new contributors developing the Open Cluster Management (OCM) project. It also serves as a reference for AI tools performing code reviews and analysis.
Table of Contents
- Project Overview
- Development Environment Setup
- Code Organization
- Development Workflow
- Code Standards and Style
- Testing Guidelines
- API Development
- Build and Release
- Troubleshooting
Project Overview
Open Cluster Management (OCM) is a CNCF sandbox project that provides multicluster and multicloud management capabilities for Kubernetes. The project consists of five core components:
- registration: Manages cluster registration and certificate lifecycle
- placement: Handles content placement decisions across clusters
- work: Distributes and applies manifests to managed clusters
- registration-operator: Deploys and manages OCM components
- addon-manager: Manages OCM add-ons lifecycle
Key Technologies
- Language: Go 1.25.0
- Framework: Kubernetes operators with controller-runtime
- Build System: Make with OpenShift build machinery
- Testing: Ginkgo/Gomega for BDD-style tests
- Packaging: Helm charts and OLM bundles
Development Environment Setup
Prerequisites
- Go 1.25.0 (installation guide)
- Docker or Podman (container engine)
- Kind (local Kubernetes clusters)
- kubectl (Kubernetes CLI)
- clusteradm (OCM CLI)
Quick Start
-
Create development cluster:
kind create cluster --name ocm-dev -
Initialize OCM control plane:
# Replace <TAG> with a concrete release (e.g., vX.Y.Z) curl -fsSL https://raw.githubusercontent.com/open-cluster-management-io/clusteradm/<TAG>/hack/install.sh | bash clusteradm init --wait --bundle-version="<BUNDLE_VERSION>" -
Join cluster as managed cluster:
clusteradm join --hub-token <token> --hub-apiserver <url> --wait --cluster-name cluster1 --force-internal-endpoint-lookup --bundle-version="<BUNDLE_VERSION>" clusteradm accept --clusters cluster1 -
Verify installation:
kubectl get clustermanager,managedcluster kubectl get pods -A | grep open-cluster-management
Code Organization
ocm/
├── cmd/ # Main applications entry points
│ ├── addon/ # Addon manager
│ ├── placement/ # Placement controller
│ ├── registration/ # Registration controller
│ ├── registration-operator/ # Operator
│ ├── server/ # GRPC server
│ └── work/ # Work controller
├── pkg/ # Core business logic
│ ├── addon/ # Addon framework and controllers
│ ├── operator/ # Operator controllers
│ ├── placement/ # Placement logic and controllers
│ ├── registration/ # Registration logic
│ └── work/ # Work distribution logic
├── manifests/ # Deployment manifests
├── deploy/ # Helm charts and OLM bundles
├── test/ # Test suites
│ ├── e2e/ # End-to-end tests
│ └── integration/ # Integration tests
└── solutions/ # Usage examples and solutions
Key Packages
pkg/common/: Shared utilities and helperspkg/registration/hub/: Hub-side registration controllerspkg/registration/spoke/: Managed cluster registration logicpkg/work/hub/: Hub-side work distributionpkg/work/spoke/: Managed cluster work applicationpkg/placement/controllers/: Placement scheduling and decision logicpkg/addon/controllers/: Addon lifecycle management controllers
Development Workflow
1. Making Code Changes
# Fork and clone the repository
git clone https://github.com/<your-username>/ocm.git
cd ocm
# Create feature branch
git checkout -b feature/your-feature-name
# Make changes and commit with DCO sign-off
git commit -s -m "Add new feature: description"
2. Building Images
Build all images:
IMAGE_REGISTRY=quay.io/your-org IMAGE_TAG=dev make images
Build specific component:
IMAGE_REGISTRY=quay.io/your-org IMAGE_TAG=dev make image-registration
Load images to kind cluster:
kind load docker-image quay.io/your-org/registration:dev --name ocm-dev
3. Testing Changes
Update operator images:
kubectl set image -n open-cluster-management deployment/cluster-manager registration-operator=quay.io/your-org/registration-operator:dev
Update component images via CustomResource:
kubectl edit clustermanager cluster-manager # For hub components
kubectl edit klusterlet klusterlet # For spoke components
Code Standards and Style
Go Code Style
- Follow standard Go conventions: Use
gofmt,go vet, andgolangci-lint - Variable naming: Use camelCase for local variables, PascalCase for exported items
- Comments: Write clear comments for exported functions and complex logic
- Interface design: Keep interfaces small and focused (interface segregation principle)
Import Organization
Imports must be organized in the following order:
- Standard library packages
- Third-party packages
- OCM packages
import (
// Standard library
"context"
"fmt"
"time"
// Third-party
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
// OCM packages
"open-cluster-management.io/api/cluster/v1"
"open-cluster-management.io/ocm/pkg/common/helpers"
)
Code Quality Requirements
All code must pass these checks:
make verify # Run all verification checks
make verify-gocilint # Linting with golangci-lint
make verify-fmt-imports # Import formatting verification
make verify-crds # CRD consistency checks
Auto-format imports:
make fmt-imports # Automatically format import statements
Naming Conventions
- Files: Use snake_case (e.g.,
cluster_controller.go) - Packages: Use lowercase, single words when possible
- Constants: Use CamelCase (PascalCase for exported constants); reserve ALL_CAPS only when mirroring external specs
- Controllers: Suffix with
Controller(e.g.,PlacementController) - Interfaces: Use descriptive names, often ending with
-er(e.g.,ClusterLister)
Documentation Standards
- All exported functions, types, and constants must have comments
- Comments should start with the name of the item being documented
- Use complete sentences and proper punctuation
- Include examples for complex APIs
Testing Guidelines
Unit Tests
make test-unit # Run all unit tests
go test ./pkg/registration/... # Test specific package
Integration Tests
Integration tests use controller-runtime's envtest framework:
make test-integration # All integration tests
make test-registration-integration # Registration only
make test-placement-integration # Placement only
make test-work-integration # Work only
make test-addon-integration # Addon only
E2E Tests
End-to-end tests run against real clusters and require a kind cluster with proper setup:
# 1. Create kind cluster and set KUBECONFIG
kind get kubeconfig --name ocm-e2e > /tmp/kubeconfig-ocm-e2e
export KUBECONFIG=/tmp/kubeconfig-ocm-e2e
# 2. Run E2E tests with required variables
IMAGE_TAG=e2e KLUSTERLET_DEPLOY_MODE=Singleton make test-e2e
E2E test variables:
IMAGE_TAG: Tag for container images (default: latest)KLUSTERLET_DEPLOY_MODE: Deployment mode (Default, Singleton, SingletonHosted)MANAGED_CLUSTER_NAME: Name of the managed cluster (default: cluster1)KUBECONFIG: Must be set to point to test cluster
Test Organization
- Unit tests:
*_test.gofiles alongside source code - Integration tests:
test/integration/directory - E2E tests:
test/e2e/directory - Test utilities:
test/framework/andpkg/*/testing/
Test Writing Guidelines
- Use Ginkgo/Gomega for BDD-style tests
- Write descriptive test names using
Describe,Context, andIt - Use table-driven tests for multiple scenarios
- Mock external dependencies appropriately
- Ensure tests are deterministic and can run in parallel
API Development
Modifying APIs
OCM APIs are defined in the separate api repository. To modify APIs:
-
Clone both repositories:
git clone https://github.com/<your-username>/api.git git clone https://github.com/<your-username>/ocm.git -
Make API changes in the api repository and run:
cd api make update # Generates CRDs and DeepCopy methods -
Use local API changes in ocm repository:
cd ocm go mod edit -replace open-cluster-management.io/api=/path/to/local/api go mod tidy && go mod vendor make update # Updates CRDs, Helm charts, and operator manifests -
Remove replace directive before submitting PR
Update Process
The make update command handles:
- CRD copying from api repository
- Helm chart updates
- Operator manifest generation
- ClusterServiceVersion updates
Build and Release
Build System
The project uses OpenShift's build-machinery-go:
make all # Build all binaries
make images # Build all container images
make update # Update all generated manifests
Image Build
Images are built for multiple architectures:
linux/amd64linux/arm64
Registry configuration:
export IMAGE_REGISTRY=quay.io/open-cluster-management
export IMAGE_TAG=v0.x.x
Available Make Targets
make build # Build binaries
make images # Build container images
make test-unit # Run unit tests
make test-integration # Run integration tests
make test-e2e # Run E2E tests
make verify # Run all verification checks
make update # Update generated files
make clean # Clean build artifacts
Troubleshooting
Common Issues
-
API Server Connection Issues:
kubectl cluster-info # Verify cluster connectivity kubectl get nodes # Check cluster health -
Image Pull Failures:
kind load docker-image <image> # Load to kind cluster kubectl describe pod <pod> # Check image pull status -
Certificate Issues:
kubectl get csr # Check certificate requests kubectl get secrets -A | grep tls # Check TLS secrets -
Operator Issues:
kubectl logs -n open-cluster-management deployment/cluster-manager kubectl get clustermanager cluster-manager -o yaml
Debug Tools
- Enable debug logging: Set
--v=4or higher in component flags - Use
kubectl describefor resource status - Check controller logs in
open-cluster-management*namespaces - Verify RBAC permissions with
kubectl auth can-i
Performance Debugging
- Use
go tool pproffor CPU/memory profiling - Monitor metrics endpoints (when enabled)
- Check resource utilization with
kubectl top
Contributing Guidelines
- Submit an issue describing proposed changes
- Fork and develop following this guide
- Add tests for new functionality
- Run quality checks:
make verify test-unit - Submit pull request with DCO sign-off
- Address review feedback promptly
For detailed contribution guidelines, see CONTRIBUTING.md.