Skip to content

Commit 6a30bca

Browse files
authored
Merge pull request #2 from numtide/multi-go-module-setup
Multi go module setup
2 parents 6f40394 + 60e4f3c commit 6a30bca

File tree

13 files changed

+121
-50
lines changed

13 files changed

+121
-50
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ result-*
77

88
# generic
99
dist/
10+
11+
# Go
12+
go.work

config/.gitkeep

Whitespace-only changes.

docs/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,14 @@ The operator creates and manages all necessary Kubernetes resources for these co
3131

3232
```
3333
multigres-operator/
34-
├── api/v1alpha1/ # CRD definitions
34+
├── go.mod # Root module
3535
├── cmd/multigres-operator/ # Main entry point
36-
└── internal/ # Controller and resource builders
36+
└── pkg/ # Multi-module structure
37+
├── cluster-handler/ # Cluster orchestration (separate module)
38+
├── data-handler/ # Data plane management (separate module)
39+
└── resource-handler/ # Component resources (separate module)
40+
41+
Note: go.work can be created locally for development. It is in .gitignore
3742
```
3843

3944
### Documentation and Configuration

docs/architecture.md

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,68 @@
4040

4141
```
4242
multigres-operator/
43-
├── api/v1alpha1/ # CRD definitions and types
43+
├── go.mod # Root module (primarily for cmd)
4444
├── cmd/multigres-operator/ # Main entry point
45-
├── internal/
46-
│ ├── controller/ # Main reconciler and component reconcilers
47-
│ │ ├── etcd/
48-
│ │ ├── multigateway/
49-
│ │ ├── multiorch/
50-
│ │ └── multipooler/
51-
│ ├── resources/ # Pure resource builder functions
52-
│ ├── webhook/ # Admission webhooks (defaulting, validation)
53-
│ └── testutil/ # Test helpers and utilities
45+
├── pkg/
46+
│ ├── cluster-handler/ # Cluster-level orchestration (separate Go module)
47+
│ │ ├── go.mod
48+
│ │ └── controller/
49+
│ │ └── multigrescluster/ # MultigresCluster reconciler
50+
│ ├── data-handler/ # Data plane management (separate Go module)
51+
│ │ ├── go.mod
52+
│ │ └── controller/
53+
│ │ └── cell/ # Cell reconciler
54+
│ └── resource-handler/ # Component resources (separate Go module)
55+
│ ├── go.mod
56+
│ └── controller/
57+
│ ├── multigateway/
58+
│ ├── multiorch/
59+
│ ├── multipooler/
60+
│ └── etcd/
5461
├── config/ # Kubernetes manifests for operator deployment
5562
├── docs/ # Architecture, conventions, and development guides
5663
└── plans/ # Planning documents
57-
```
58-
59-
### API Layer (`api/v1alpha1`)
60-
- **Purpose**: Defines Multigres custom resource schema
61-
- **Components**: MultigresSpec, MultigresStatus, component specs (MultiGatewaySpec, MultiOrchSpec, MultiPoolerSpec, EtcdSpec)
62-
- **Validation**: Kubebuilder markers for OpenAPI validation and defaults
6364
64-
### Controller Layer (`internal/controller`)
65-
- **MultigresReconciler**: Main controller - manages lifecycle, finalizers, status aggregation
66-
- **Component Reconcilers**: etcd, multigateway, multiorch, multipooler reconcilers run in parallel
67-
- **Responsibilities**: Create/update resources, check component health, update status
65+
Note: go.work file can be created locally for development convenience. It is in .gitignore.
66+
```
6867

69-
### Resource Layer (`internal/resources`)
70-
- **Pure Functions**: Build Kubernetes manifests (Deployments, StatefulSets, Services, HPAs)
71-
- **Label Management**: Consistent label generation for resource selection
72-
- **No Side Effects**: Same input always produces same output
68+
### Multi-Module Architecture
69+
70+
The operator is organized into three independent Go modules with clear separation of concerns. Developers can use **Go workspaces** locally (`go.work`) for easier cross-module development, though this file is not committed to the repository:
71+
72+
#### Cluster Handler Module (`pkg/cluster-handler`)
73+
- **Purpose**: High-level cluster orchestration
74+
- **Responsibilities**:
75+
- Uses the `MultigresCluster` custom resource as its primary input
76+
- Coordinates creation of child resources (MultiGateway, MultiOrch, MultiPooler, Etcd, Cell)
77+
- Aggregates status from child resources
78+
- Handles cluster-wide lifecycle (finalizers, upgrades)
79+
- **Independence**: Can be tested and versioned separately from resource handlers
80+
81+
#### Data Handler Module (`pkg/data-handler`)
82+
- **Purpose**: Data plane management and topology
83+
- **Responsibilities**:
84+
- Uses the `Cell` custom resource as its primary input (data topology abstraction)
85+
- Handles data plane configuration and routing
86+
- Coordinates with Vitess/Multigres data components
87+
- **Independence**: Data plane logic isolated from control plane and resource management
88+
89+
#### Resource Handler Module (`pkg/resource-handler`)
90+
- **Purpose**: Individual component resource management
91+
- **Responsibilities**:
92+
- Uses the `MultiGateway`, `MultiOrch`, `MultiPooler`, `Etcd` custom resources as its primary inputs
93+
- Creates and reconciles Kubernetes resources (Deployments, StatefulSets, Services, HPAs)
94+
- Implements pure resource builder functions
95+
- Component-specific health checking and status reporting
96+
- **Independence**: Component reconcilers can evolve independently of cluster orchestration
97+
98+
### Benefits of Multi-Module Structure
99+
100+
- **Clear Boundaries**: Each module has distinct responsibilities and can be understood independently
101+
- **Independent Testing**: Unit and integration tests scoped to each module
102+
- **Parallel Development**: Teams can work on different modules without conflicts
103+
- **Selective Imports**: Main binary only imports what it needs from each module
104+
- **Version Flexibility**: Modules can evolve at different paces (though currently developed in lockstep)
73105

74106
## Core Components
75107

@@ -85,14 +117,14 @@ The operator follows a standard Kubernetes reconciliation pattern:
85117

86118
### Component Reconcilers
87119

88-
Each Multigres component has its own reconciler:
120+
The **resource-handler** module contains individual reconcilers for each Multigres component:
89121

90-
- **etcd Reconciler**: Manages StatefulSet for etcd cluster, headless and client Services
91-
- **multigateway Reconciler**: Manages Deployment, Service, and optional HPA for MultiGateway
92-
- **multiorch Reconciler**: Manages Deployment and optional HPA for MultiOrch
93-
- **multipooler Reconciler**: Manages StatefulSet with multi-container pods (pooler, pgctld, postgres), and optional HPA
122+
- **etcd Reconciler** (`pkg/resource-handler/controller/etcd`): Manages StatefulSet for etcd cluster, headless and client Services
123+
- **multigateway Reconciler** (`pkg/resource-handler/controller/multigateway`): Manages Deployment, Service, and optional HPA for MultiGateway
124+
- **multiorch Reconciler** (`pkg/resource-handler/controller/multiorch`): Manages Deployment and optional HPA for MultiOrch
125+
- **multipooler Reconciler** (`pkg/resource-handler/controller/multipooler`): Manages StatefulSet with multi-container pods (pooler, pgctld, postgres), and optional HPA
94126

95-
All component reconcilers run in parallel.
127+
All component reconcilers run in parallel and are independent of each other.
96128

97129
### Resource Builders
98130

@@ -146,8 +178,8 @@ Current preference is init container pattern (same as Istio, NGINX Ingress), but
146178
## Technology Stack
147179

148180
### Language and Runtime
149-
- **Language**: Go 1.24+
150-
- **Key Features**: Concurrency, interfaces, strong typing
181+
- **Language**: Go 1.25+
182+
- **Key Features**: Concurrency, interfaces, strong typing, workspaces for multi-module projects
151183

152184
### Key Dependencies
153185
- **Framework**: Kubebuilder v3 - scaffolding and patterns for Kubernetes operators

docs/implementation-guide.md

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
## Development Environment
66

77
### Language Configuration
8-
- **Language**: Go 1.24+
9-
- **Build System**: Make for task orchestration, Go modules for dependencies
10-
- **Project Structure**: Standard Kubebuilder layout - `api/`, `cmd/`, `internal/`, `config/`
8+
- **Language**: Go 1.25+
9+
- **Build System**: Make for task orchestration, Go workspaces for multi-module management
10+
- **Project Structure**: Multi-module workspace - `go.work`, `pkg/{module}/`, `cmd/`, `config/`
1111
- **Linting**: golangci-lint (configured in `.golangci.yml`)
1212

1313
### Required Tools
14-
- **go**: 1.24 or higher
14+
- **go**: 1.25 or higher (workspace support required)
1515
- **kubectl**: Kubernetes CLI for cluster interaction
1616
- **kind**: Local Kubernetes cluster for testing (or other local cluster)
1717
- **kubebuilder**: Optional - for regenerating CRDs and scaffolding
@@ -22,10 +22,14 @@
2222
- **kustomize**: Included with kubectl 1.14+, used for manifest management
2323

2424
### Dependency Management
25-
- **Go Modules**: `go.mod` and `go.sum` for dependency tracking
26-
- **Version Pinning**: Pin controller-runtime and client-go to compatible versions
27-
- **Vendor Directory**: Not used - rely on module cache
28-
- **Updating Dependencies**: Use `go get -u` carefully, test thoroughly after updates
25+
- **Per-Module Dependencies**: Each module (`cluster-handler`, `data-handler`, `resource-handler`) has its own `go.mod` and `go.sum`
26+
- **Version Pinning**: Pin controller-runtime and client-go to compatible versions in each module
27+
- **Go Workspaces (Local Only)**:
28+
- Create `go.work` locally for easier multi-module development: `go work init ./pkg/cluster-handler ./pkg/data-handler ./pkg/resource-handler`
29+
- `go.work` is in `.gitignore`
30+
- **IMPORTANT**: `go.work` MUST NOT be committed - committing it would break the build and cause artifacts to ignore pinned versions
31+
- Workspaces simplify local development by allowing cross-module references without publishing
32+
- **Updating Dependencies**: Update in each module separately with `go get -u`, test thoroughly after updates
2933

3034
## Coding Standards
3135

@@ -64,15 +68,17 @@ Common markers:
6468
6569
### Testing Strategy
6670
67-
**Unit Tests** (internal/resources, internal/webhook):
71+
**Unit Tests** (per module):
6872
- Test pure resource builder functions with table-driven tests
6973
- Mock nothing - builders are pure functions
7074
- Focus on correct Kubernetes manifest generation
75+
- Run tests in each module: `cd pkg/resource-handler && go test ./...`
7176
72-
**Integration Tests** (internal/controller):
77+
**Integration Tests** (per module):
7378
- Use `envtest` - provides real Kubernetes API without full cluster
7479
- Test reconciliation loops end-to-end
7580
- Verify resource creation, updates, and status updates
81+
- Each module has its own integration tests scoped to its controllers
7682
7783
**Test Commands**:
7884
```bash
@@ -145,12 +151,13 @@ make manifests
145151
make install
146152
```
147153
148-
**Controller Changes** (`internal/controller/`):
149-
- Run `make test` frequently during development
154+
**Controller Changes** (`pkg/{module}/controller/`):
155+
- Run tests in the specific module: `cd pkg/resource-handler && go test ./...`
150156
- Integration tests catch reconciliation bugs early
151157
- Use `make run` for quick iteration (no docker build needed)
158+
- Changes in one module don't require rebuilding others during local development
152159
153-
**Resource Builder Changes** (`internal/resources/`):
154-
- Write/update table-driven tests first
155-
- Run `make test` - very fast feedback loop
156-
- Integration tests verify end-to-end behavior
160+
**Module-Specific Development**:
161+
- **Resource Handler** (`pkg/resource-handler`): Component reconcilers and resource builders
162+
- **Cluster Handler** (`pkg/cluster-handler`): MultigresCluster orchestration logic
163+
- **Data Handler** (`pkg/data-handler`): Cell management and data plane configuration

internal/.gitkeep

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package multigrescluster
2+
3+
func Dummy() string {
4+
return "dummy string from cluster-handler's multigrescluster controller"
5+
}

pkg/cluster-handler/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/numtide/multigres-operator/pkg/cluster-handler
2+
3+
go 1.25.0
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package cell
2+
3+
func Dummy() string {
4+
return "dummy string from data-handler's cell controller"
5+
}

pkg/data-handler/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/numtide/multigres-operator/pkg/data-handler
2+
3+
go 1.25.0

0 commit comments

Comments
 (0)