Skip to content

Kubernetes publisher: WithPersistentVolume name-match propagates invalid mount source name (containing dots) into StatefulSet podSpec volumes[].name #17169

@mitchdenny

Description

@mitchdenny

Discovered while testing E2E PV durability for #16929 (issue #16999).

Symptom

When binding a Postgres resource to a first-class KubernetesPersistentVolumeResource using the name-match overload, the publisher generates an invalid StatefulSet:

StatefulSet.apps "pg-statefulset" is invalid:
  spec.template.spec.volumes[0].name: Invalid value:
    "k8sdeploypvtest.apphost-d10c8f5ce6-pg-data": must not contain dots
  spec.template.spec.containers[0].volumeMounts[0].name: Not found:
    "k8sdeploypvtest.apphost-d10c8f5ce6-pg-data"

Repro

var pgData = k8s.AddPersistentVolume("pg-data")
    .WithStorageClass("standard")
    .WithCapacity("1Gi")
    .WithAccessMode(PersistentVolumeAccessMode.ReadWriteOnce);

// No-arg WithDataVolume auto-generates a unique mount source name of the
// form "{AppHost}.{hash}-{name}" — e.g. "k8sdeploypvtest.apphost-d10c8f5ce6-pg-data"
var postgres = builder.AddPostgres("pg")
    .WithDataVolume()
    .WithPersistentVolume(pgData);

Root cause

KubernetesPersistentVolumeExtensions.WithPersistentVolume(IResourceBuilder<KubernetesPersistentVolumeResource>) matches the workload's existing ContainerMountAnnotation by source name and reuses that source name as the K8s volumes[].name ref in the podSpec. K8s requires that name to be a DNS_LABEL (lowercase, alphanumeric + dashes, no dots), but the auto-generated mount source can contain dots.

The PVC itself is named correctly (pg-data, the PV resource name) — only the podSpec ref is broken.

Workaround

Pass an explicit name to WithDataVolume("pg-data") so it matches the PV name directly. Used by the new E2E test (KubernetesDeployWithPersistentVolumeTests) to unblock CI.

Suggested fix

Normalize the mount source name to a DNS_LABEL when materializing the podSpec volume entry. The reference table built in KubernetesPublishingContext already has the binding-by-name, so we just need to apply something like HelmExtensions.ToKubernetesResourceName (or equivalent) at the podSpec-emit site.

cc @mitchdenny

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-area-labelAn area label is needed to ensure this gets routed to the appropriate area ownerstriage:bot-seenAspire triage bot has seen this issue

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions