diff --git a/README.md b/README.md index 5a9901b4b..51418c543 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,8 @@ Everything OCM does is Cloud Native by definition. Our comprehensive [User Scena You can use the [clusteradm CLI](https://github.com/open-cluster-management-io/clusteradm) to bootstrap a control plane for multicluster management. To set up a multicluster environment with OCM enabled on your local machine, follow the instructions in [setup dev environment](solutions/setup-dev-environment). +For developers looking to contribute to OCM, see our comprehensive [Development Guide](development.md) which covers development environment setup, code standards, testing, and contribution workflows. + ## External Integrations We constantly work with other open-source projects to make multicluster management easier: diff --git a/development.md b/development.md new file mode 100644 index 000000000..f87a52113 --- /dev/null +++ b/development.md @@ -0,0 +1,402 @@ +# 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](#project-overview) +- [Development Environment Setup](#development-environment-setup) +- [Code Organization](#code-organization) +- [Development Workflow](#development-workflow) +- [Code Standards and Style](#code-standards-and-style) +- [Testing Guidelines](#testing-guidelines) +- [API Development](#api-development) +- [Build and Release](#build-and-release) +- [Troubleshooting](#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.24.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.24.0 ([installation guide](https://go.dev/doc/install)) +- Docker or Podman (container engine) +- [Kind](https://kind.sigs.k8s.io/) (local Kubernetes clusters) +- [kubectl](https://kubernetes.io/docs/tasks/tools/) (Kubernetes CLI) +- [clusteradm](https://github.com/open-cluster-management-io/clusteradm) (OCM CLI) + +### Quick Start + +1. **Create development cluster**: + ```bash + kind create cluster --name ocm-dev + ``` + +2. **Initialize OCM control plane**: + ```bash + # Replace with a concrete release (e.g., vX.Y.Z) + curl -fsSL https://raw.githubusercontent.com/open-cluster-management-io/clusteradm//hack/install.sh | bash + clusteradm init --wait --bundle-version="" + ``` + +3. **Join cluster as managed cluster**: + ```bash + clusteradm join --hub-token --hub-apiserver --wait --cluster-name cluster1 --force-internal-endpoint-lookup --bundle-version="" + clusteradm accept --clusters cluster1 + ``` + +4. **Verify installation**: + ```bash + 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 helpers +- `pkg/registration/hub/`: Hub-side registration controllers +- `pkg/registration/spoke/`: Managed cluster registration logic +- `pkg/work/hub/`: Hub-side work distribution +- `pkg/work/spoke/`: Managed cluster work application +- `pkg/placement/controllers/`: Placement scheduling and decision logic +- `pkg/addon/controllers/`: Addon lifecycle management controllers + +## Development Workflow + +### 1. Making Code Changes + +```bash +# Fork and clone the repository +git clone https://github.com//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: +```bash +IMAGE_REGISTRY=quay.io/your-org IMAGE_TAG=dev make images +``` + +Build specific component: +```bash +IMAGE_REGISTRY=quay.io/your-org IMAGE_TAG=dev make image-registration +``` + +Load images to kind cluster: +```bash +kind load docker-image quay.io/your-org/registration:dev --name ocm-dev +``` + +### 3. Testing Changes + +Update operator images: +```bash +kubectl set image -n open-cluster-management deployment/cluster-manager registration-operator=quay.io/your-org/registration-operator:dev +``` + +Update component images via CustomResource: +```bash +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`, and `golangci-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: +1. Standard library packages +2. Third-party packages +3. OCM packages + +```go +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: +```bash +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: +```bash +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 + +```bash +make test-unit # Run all unit tests +go test ./pkg/registration/... # Test specific package +``` + +### Integration Tests + +Integration tests use controller-runtime's envtest framework: + +```bash +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: + +```bash +# 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.go` files alongside source code +- **Integration tests**: `test/integration/` directory +- **E2E tests**: `test/e2e/` directory +- **Test utilities**: `test/framework/` and `pkg/*/testing/` + +### Test Writing Guidelines + +- Use Ginkgo/Gomega for BDD-style tests +- Write descriptive test names using `Describe`, `Context`, and `It` +- 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](https://github.com/open-cluster-management-io/api). To modify APIs: + +1. **Clone both repositories**: + ```bash + git clone https://github.com//api.git + git clone https://github.com//ocm.git + ``` + +2. **Make API changes** in the api repository and run: + ```bash + cd api + make update # Generates CRDs and DeepCopy methods + ``` + +3. **Use local API changes** in ocm repository: + ```bash + 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 + ``` + +4. **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: + +```bash +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/amd64` +- `linux/arm64` + +Registry configuration: +```bash +export IMAGE_REGISTRY=quay.io/open-cluster-management +export IMAGE_TAG=v0.x.x +``` + +### Available Make Targets + +```bash +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 + +1. **API Server Connection Issues**: + ```bash + kubectl cluster-info # Verify cluster connectivity + kubectl get nodes # Check cluster health + ``` + +2. **Image Pull Failures**: + ```bash + kind load docker-image # Load to kind cluster + kubectl describe pod # Check image pull status + ``` + +3. **Certificate Issues**: + ```bash + kubectl get csr # Check certificate requests + kubectl get secrets -A | grep tls # Check TLS secrets + ``` + +4. **Operator Issues**: + ```bash + kubectl logs -n open-cluster-management deployment/cluster-manager + kubectl get clustermanager cluster-manager -o yaml + ``` + +### Debug Tools + +- Enable debug logging: Set `--v=4` or higher in component flags +- Use `kubectl describe` for resource status +- Check controller logs in `open-cluster-management*` namespaces +- Verify RBAC permissions with `kubectl auth can-i` + +### Performance Debugging + +- Use `go tool pprof` for CPU/memory profiling +- Monitor metrics endpoints (when enabled) +- Check resource utilization with `kubectl top` + +## Contributing Guidelines + +1. **Submit an issue** describing proposed changes +2. **Fork and develop** following this guide +3. **Add tests** for new functionality +4. **Run quality checks**: `make verify test-unit` +5. **Submit pull request** with DCO sign-off +6. **Address review feedback** promptly + +For detailed contribution guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md). + +## Resources + +- [Project Website](https://open-cluster-management.io/) +- [Community Slack](https://kubernetes.slack.com/channels/open-cluster-mgmt) +- [API Documentation](https://github.com/open-cluster-management-io/api) +- [Addon Framework](https://github.com/open-cluster-management-io/addon-framework) +- [User Scenarios](https://open-cluster-management.io/docs/scenarios/) \ No newline at end of file