-
Notifications
You must be signed in to change notification settings - Fork 198
CRD type changes and manifest regeneration for MCPServer and VirtualMCPServer scaling #4206
Description
Description
Add the SessionStorageConfig shared struct and scaling fields to both CRDs, then regenerate deepcopy and CRD manifests. Specifically:
- MCPServer types (
mcpserver_types.go): AddSessionStorageConfigstruct,Replicas *int32,BackendReplicas *int32, andSessionStorage *SessionStorageConfigtoMCPServerSpec. - VirtualMCPServer types (
virtualmcpserver_types.go): AddReplicas *int32andSessionStorage *SessionStorageConfigtoVirtualMCPServerSpec, reusing theSessionStorageConfigstruct defined above. - Regeneration: Run
task operator-generateandtask operator-manifeststo regeneratezz_generated.deepcopy.goand the CRD YAML files.
These changes are the foundation for horizontal scaling support in the ToolHive operator (THV-0047). All downstream reconciler and deployment-builder tasks depend on this compilable, up-to-date API surface.
Note: Originally split into three tasks (TASK-001 #267, TASK-002 #269, TASK-003 #275). Merged because all three are always shipped in a single PR — the type changes and regeneration are inseparable from a compilation standpoint.
Parent epic: stacklok/stacklok-epics#264
Dependencies: None (root task)
Blocks: TASK-002 (MCPServer Reconciler), TASK-003 (MCPServer RunConfig Injection), TASK-004 (VirtualMCPServer Deployment Builder), TASK-005 (VirtualMCPServer ConfigMap Injection), TASK-006 (Unit Tests)
Acceptance Criteria
MCPServer types (mcpserver_types.go)
-
SessionStorageConfigstruct is defined with fields:Provider(required, enummemory|redis),Address(optional),DB(optional int32, default 0),KeyPrefix(optional), andPasswordRef(optional*SecretKeyRef) - CEL validation rule on
SessionStorageConfigenforces thataddressis required whenprovider == "redis" -
MCPServerSpecincludesReplicas *int32,BackendReplicas *int32, andSessionStorage *SessionStorageConfigwith// +optionalandomitemptytags -
PasswordRefreuses the existingSecretKeyReftype — not redeclared
VirtualMCPServer types (virtualmcpserver_types.go)
-
VirtualMCPServerSpecincludesReplicas *int32andSessionStorage *SessionStorageConfigwith// +optionalandomitemptytags -
SessionStorageConfigis referenced frommcpserver_types.go— not redeclared in this file
Regeneration
-
task operator-generateruns without error and regenerateszz_generated.deepcopy.gowithDeepCopyIntoforSessionStorageConfigand updated deepcopy for both specs -
task operator-manifestsregenerates CRD YAMLs indeploy/charts/operator-crds/files/crds/including the CEL validation rule and enum constraints -
go build ./cmd/thv-operator/...passes after regeneration -
go test ./cmd/thv-operator/...passes after regeneration - All generated files committed in the same PR
- Code reviewed and approved
Technical Approach
Step 1 — MCPServer types
Add SessionStorageConfig struct and three new fields to MCPServerSpec in mcpserver_types.go. Follow the +optional pattern for pointer fields (OIDCConfig, AuthzConfig). Use +kubebuilder:validation:Enum=memory;redis on Provider and a struct-level +kubebuilder:validation:XValidation rule for the address-required-for-redis constraint.
// +kubebuilder:validation:XValidation:rule="self.provider == 'redis' ? has(self.address) : true",message="address is required when provider is redis"
type SessionStorageConfig struct {
// +kubebuilder:validation:Enum=memory;redis
// +kubebuilder:validation:Required
Provider string `json:"provider"`
// +optional
Address string `json:"address,omitempty"`
// +kubebuilder:default=0
// +optional
DB int32 `json:"db,omitempty"`
// +optional
KeyPrefix string `json:"keyPrefix,omitempty"`
// +optional
PasswordRef *SecretKeyRef `json:"passwordRef,omitempty"`
}New MCPServerSpec fields:
// +optional
Replicas *int32 `json:"replicas,omitempty"`
// +optional
BackendReplicas *int32 `json:"backendReplicas,omitempty"`
// +optional
SessionStorage *SessionStorageConfig `json:"sessionStorage,omitempty"`Step 2 — VirtualMCPServer types
Add two new fields to VirtualMCPServerSpec in virtualmcpserver_types.go after EmbeddingServerRef:
// +optional
Replicas *int32 `json:"replicas,omitempty"`
// +optional
SessionStorage *SessionStorageConfig `json:"sessionStorage,omitempty"`Step 3 — Regeneration
task operator-generate # regenerates zz_generated.deepcopy.go
task operator-manifests # regenerates CRD YAMLs + Helm wrappers
go build ./cmd/thv-operator/...
go test -ldflags=-extldflags=-Wl,-w ./cmd/thv-operator/... 2>&1 | grep -v '/test-integration'Do not run task crdref-gen (documentation generation, out of scope).
Code Pointers
cmd/thv-operator/api/v1alpha1/mcpserver_types.go— AddSessionStorageConfigstruct and three newMCPServerSpecfieldscmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go— Add two new fields toVirtualMCPServerSpeccmd/thv-operator/api/v1alpha1/mcpexternalauthconfig_types.go— Source ofSecretKeyRef(lines 561–569) and CEL validation patterns (lines 44–49)cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go— Regenerated; do not edit by hand
Out of Scope
- Reconciler logic changes — TASK-002 through TASK-005
- Unit tests for reconciler behavior — TASK-006
runner.RunConfigchanges — TASK-003
References
- Epic THV-0047: stacklok/stacklok-epics#264
- RFC THV-0047: RFC: Horizontal Scaling for vMCP and Proxy Runner toolhive-rfcs#47
- Merged from: Add go:// transport protocol for golang containers #269 (VirtualMCPServer CRD Type Changes), Fix StatefulSet container configuration in Kubernetes runtime #275 (Regenerate Deepcopy and CRD Manifests)