Bug description
EmbeddingServer.spec.podTemplateSpec is documented as the customization mechanism for the spawned StatefulSet pod (cmd/thv-operator/api/v1beta1/embeddingserver_types.go:91-98). Validation passes for any well-formed PodTemplateSpec.
However, the controller's merge function only copies a hardcoded subset of fields:
// cmd/thv-operator/controllers/embeddingserver_controller.go:662-700
func (r *EmbeddingServerReconciler) mergePodTemplateSpec(...) {
...
if userTemplate.Spec.NodeSelector != nil { ... }
if userTemplate.Spec.Affinity != nil { ... }
if len(userTemplate.Spec.Tolerations) > 0 { ... }
if userTemplate.Spec.SecurityContext != nil { ... }
if userTemplate.Spec.ServiceAccountName != "" { ... }
// + container SecurityContext only
}
Anything else the user puts in podTemplateSpec.spec — including imagePullSecrets, volumes, volumeMounts on user-added containers, priorityClassName, topologySpreadConstraints, runtimeClassName, etc. — is silently dropped. Validation succeeds and the user has no signal that their config was ignored.
This is comparable to the closed issue #3436 (MCPServer's equivalent gap), but for EmbeddingServer.
For reference, MCPRegistry handles this correctly by starting from userPTS.DeepCopy() and merging defaults in (cmd/thv-operator/pkg/registryapi/podtemplatespec.go:404), and VirtualMCPServer handles it via strategic merge patch on raw JSON (cmd/thv-operator/controllers/virtualmcpserver_deployment.go:929).
Steps to reproduce
- Create an
EmbeddingServer whose image lives in a private registry.
- Set:
spec:
podTemplateSpec:
spec:
imagePullSecrets:
- name: regcred
- The CR is accepted; the StatefulSet's PodSpec contains no
imagePullSecrets.
- The pod fails with
ImagePullBackOff.
Expected behavior
spec.podTemplateSpec should preserve user-provided fields the same way MCPRegistry and VirtualMCPServer do.
Suggested fix
Replace the field-by-field copy in mergePodTemplateSpec with either:
- a deep-copy-and-merge approach (as in
MergePodTemplateSpecs in pkg/registryapi/podtemplatespec.go), or
- a strategic merge patch on the raw user JSON (as in
applyPodTemplateSpecToDeployment for VirtualMCPServer).
The fix should preserve all user-provided pod-spec fields, not just the currently enumerated five. Add a regression test that verifies imagePullSecrets set via podTemplateSpec reach the resulting StatefulSet pods.
Bug description
EmbeddingServer.spec.podTemplateSpecis documented as the customization mechanism for the spawned StatefulSet pod (cmd/thv-operator/api/v1beta1/embeddingserver_types.go:91-98). Validation passes for any well-formed PodTemplateSpec.However, the controller's merge function only copies a hardcoded subset of fields:
Anything else the user puts in
podTemplateSpec.spec— includingimagePullSecrets,volumes,volumeMountson user-added containers,priorityClassName,topologySpreadConstraints,runtimeClassName, etc. — is silently dropped. Validation succeeds and the user has no signal that their config was ignored.This is comparable to the closed issue #3436 (MCPServer's equivalent gap), but for EmbeddingServer.
For reference, MCPRegistry handles this correctly by starting from
userPTS.DeepCopy()and merging defaults in (cmd/thv-operator/pkg/registryapi/podtemplatespec.go:404), and VirtualMCPServer handles it via strategic merge patch on raw JSON (cmd/thv-operator/controllers/virtualmcpserver_deployment.go:929).Steps to reproduce
EmbeddingServerwhose image lives in a private registry.imagePullSecrets.ImagePullBackOff.Expected behavior
spec.podTemplateSpecshould preserve user-provided fields the same way MCPRegistry and VirtualMCPServer do.Suggested fix
Replace the field-by-field copy in
mergePodTemplateSpecwith either:MergePodTemplateSpecsinpkg/registryapi/podtemplatespec.go), orapplyPodTemplateSpecToDeploymentfor VirtualMCPServer).The fix should preserve all user-provided pod-spec fields, not just the currently enumerated five. Add a regression test that verifies
imagePullSecretsset viapodTemplateSpecreach the resulting StatefulSet pods.