Skip to content

wire spec-driven replicas and Redis password for VirtualMCPServer#4367

Open
yrobla wants to merge 1 commit intofeat/thv-0047-crd-type-changesfrom
issue-4215
Open

wire spec-driven replicas and Redis password for VirtualMCPServer#4367
yrobla wants to merge 1 commit intofeat/thv-0047-crd-type-changesfrom
issue-4215

Conversation

@yrobla
Copy link
Contributor

@yrobla yrobla commented Mar 25, 2026

Summary

  • Nil-passthrough for Deployment.Spec.Replicas (hands-off when spec.replicas is nil, spec-driven when set) for HPA compatibility
  • Add terminationGracePeriodSeconds (30s) to vMCP pod spec
  • Add buildRedisPasswordEnvVar: injects THV_SESSION_REDIS_PASSWORD from SessionStorageConfig.PasswordRef when provider is redis
  • Sync Spec.Replicas on update when spec.replicas is non-nil
  • deploymentNeedsUpdate detects replica drift for spec-driven scaling

Fixes #4215

Type of change

  • Bug fix
  • New feature
  • Refactoring (no behavior change)
  • Dependency update
  • Documentation
  • Other (describe):

Test plan

  • Unit tests (task test)
  • E2E tests (task test-e2e)
  • Linting (task lint-fix)
  • Manual testing (describe below)

Changes

File Change

Does this introduce a user-facing change?

Special notes for reviewers

@yrobla yrobla requested a review from Copilot March 25, 2026 15:12
@github-actions github-actions bot added the size/XS Extra small PR: < 100 lines changed label Mar 25, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the ToolHive operator’s VirtualMCPServer Deployment wiring to support HPA-compatible scaling (nil-passthrough replicas), adds a default graceful shutdown period for vMCP pods, and injects a Redis password env var when session storage is configured for Redis.

Changes:

  • Make Deployment.Spec.Replicas spec-driven with nil-passthrough to avoid fighting HPAs when spec.replicas is unset.
  • Set TerminationGracePeriodSeconds (30s) on the vMCP pod spec.
  • Inject THV_SESSION_REDIS_PASSWORD from spec.sessionStorage.passwordRef when provider == "redis", and sync replica drift on update when spec.replicas is set.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
cmd/thv-operator/controllers/virtualmcpserver_deployment.go Implements nil-passthrough replicas, adds termination grace period, and injects Redis password env var.
cmd/thv-operator/controllers/virtualmcpserver_controller.go Updates reconciliation logic to sync replicas only when spec.replicas is set; adds replica drift detection.
cmd/thv-operator/controllers/virtualmcpserver_deployment_test.go Updates expectations for nil replicas in the deployment builder test.
cmd/thv-operator/controllers/virtualmcpserver_controller_test.go Updates expectations for nil replicas in ensureDeployment test.
cmd/thv-operator/controllers/mcpserver_pod_template_test.go Removes local int64Ptr helper (now provided by package-level helper).
cmd/thv-operator/controllers/mcpserver_controller.go Adds shared int64Ptr helper used by vMCP deployment builder (and tests).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link

codecov bot commented Mar 25, 2026

Codecov Report

❌ Patch coverage is 88.88889% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.59%. Comparing base (652e872) to head (c9df348).

Files with missing lines Patch % Lines
...perator/controllers/virtualmcpserver_controller.go 40.00% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@                       Coverage Diff                       @@
##           feat/thv-0047-crd-type-changes    #4367   +/-   ##
===============================================================
  Coverage                           69.58%   69.59%           
===============================================================
  Files                                 480      480           
  Lines                               48664    48665    +1     
===============================================================
+ Hits                                33861    33866    +5     
- Misses                              12195    12196    +1     
+ Partials                             2608     2603    -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Nil-passthrough for Deployment.Spec.Replicas (hands-off when spec.replicas
  is nil, spec-driven when set) for HPA compatibility
- Add terminationGracePeriodSeconds (30s) to vMCP pod spec
- Add buildRedisPasswordEnvVar: injects THV_SESSION_REDIS_PASSWORD from
  SessionStorageConfig.PasswordRef when provider is redis
- Sync Spec.Replicas on update when spec.replicas is non-nil
- deploymentNeedsUpdate detects replica drift for spec-driven scaling

Closes: #4215
@yrobla yrobla requested a review from Copilot March 25, 2026 15:31
@github-actions github-actions bot added size/S Small PR: 100-299 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 25, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +353 to +373
// buildRedisPasswordEnvVar returns the THV_SESSION_REDIS_PASSWORD env var when
// sessionStorage.provider == "redis" and passwordRef is set; returns nil otherwise.
func (*VirtualMCPServerReconciler) buildRedisPasswordEnvVar(vmcp *mcpv1alpha1.VirtualMCPServer) []corev1.EnvVar {
if vmcp.Spec.SessionStorage == nil ||
vmcp.Spec.SessionStorage.Provider != "redis" ||
vmcp.Spec.SessionStorage.PasswordRef == nil {
return nil
}
return []corev1.EnvVar{{
Name: "THV_SESSION_REDIS_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: vmcp.Spec.SessionStorage.PasswordRef.Name,
},
Key: vmcp.Spec.SessionStorage.PasswordRef.Key,
},
},
}}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Does this follow the established pattern for how the proxy runner consumes the Redis password? Want to make sure the env var name and secret mounting approach are consistent.

deployment.Annotations = ctrlutil.MergeAnnotations(newDeployment.Annotations, deployment.Annotations)
if newDeployment.Spec.Replicas != nil {
deployment.Spec.Replicas = newDeployment.Spec.Replicas
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: MCPServer (#4364) adds a SessionStorageWarning condition when replicas > 1 without Redis session storage configured. Is the omission of an equivalent condition for VirtualMCPServer intentional?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/S Small PR: 100-299 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants