Skip to content

Commit a3ea3a1

Browse files
vlsingle, vmsingle: do not mount emptyDir if data volume is present in
1 parent c4f8482 commit a3ea3a1

File tree

13 files changed

+308
-162
lines changed

13 files changed

+308
-162
lines changed

api/operator/v1/vlagent_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ type VLAgentSpec struct {
5555
// PodDisruptionBudget created by operator
5656
// +optional
5757
PodDisruptionBudget *vmv1beta1.EmbeddedPodDisruptionBudgetSpec `json:"podDisruptionBudget,omitempty"`
58-
// StatefulStorage configures storage for StatefulSet
58+
// Storage configures storage for StatefulSet
5959
// +optional
6060
Storage *vmv1beta1.StorageSpec `json:"storage,omitempty"`
61-
// StatefulRollingUpdateStrategy allows configuration for strategyType
61+
// RollingUpdateStrategy allows configuration for strategyType
6262
// set it to RollingUpdate for disabling operator statefulSet rollingUpdate
6363
// +optional
6464
RollingUpdateStrategy appsv1.StatefulSetUpdateStrategyType `json:"rollingUpdateStrategy,omitempty"`

config/crd/overlay/crd.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ spec:
12671267
type: integer
12681268
rollingUpdateStrategy:
12691269
description: |-
1270-
StatefulRollingUpdateStrategy allows configuration for strategyType
1270+
RollingUpdateStrategy allows configuration for strategyType
12711271
set it to RollingUpdate for disabling operator statefulSet rollingUpdate
12721272
type: string
12731273
runtimeClassName:
@@ -1357,7 +1357,7 @@ spec:
13571357
type: object
13581358
x-kubernetes-preserve-unknown-fields: true
13591359
storage:
1360-
description: StatefulStorage configures storage for StatefulSet
1360+
description: Storage configures storage for StatefulSet
13611361
properties:
13621362
disableMountSubPath:
13631363
description: |-

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ SECURITY: upgrade Go builder from Go1.25.4 to Go1.25.5. See [the list of issues
2424
* BUGFIX: [vmoperator](https://docs.victoriametrics.com/operator/): remove orphaned ServiceAccount and RBAC resources. See [#1665](https://github.com/VictoriaMetrics/operator/issues/1665).
2525
* BUGFIX: [vmanomaly](https://docs.victoriametrics.com/operator/resources/vmanomaly/): properly handle configuration which is missing `reader.queries` in either `configRawYaml` or `configSecret`. Previously, it would lead to panic.
2626
* BUGFIX: [vmanomaly](https://docs.victoriametrics.com/operator/resources/vmanomaly/): fix configuration parsing when running in [UI mode](https://docs.victoriametrics.com/anomaly-detection/ui/). Previously, configuration required to use `preset: ui:version` instead of `preset: ui`.
27+
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/operator/resources/vmsingle/), [vlsingle](https://docs.victoriametrics.com/operator/resources/vlsingle/) and [vmalertmanager](https://docs.victoriametrics.com/operator/resources/vmalertmanager): do not mount emptydir if storage data volume is already present in volumes list. Before it was impossible to mount external PVC without overriding default storageDataPath using `spec.extraArgs` and without having unneeded emptydir listed among pod volumes. Related issues [#1477](https://github.com/VictoriaMetrics/operator/issues/1477).
2728

2829
## [v0.66.0](https://github.com/VictoriaMetrics/operator/releases/tag/v0.66.0)
2930

docs/api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,15 +253,15 @@ Appears in: [VLAgent](#vlagent)
253253
| replicaCount<a href="#vlagentspec-replicacount" id="vlagentspec-replicacount">#</a><br/>_integer_ | _(Optional)_<br/>ReplicaCount is the expected size of the Application. |
254254
| resources<a href="#vlagentspec-resources" id="vlagentspec-resources">#</a><br/>_[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#resourcerequirements-v1-core)_ | _(Optional)_<br/>Resources container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/<br />if not defined default resources from operator config will be used |
255255
| revisionHistoryLimitCount<a href="#vlagentspec-revisionhistorylimitcount" id="vlagentspec-revisionhistorylimitcount">#</a><br/>_integer_ | _(Optional)_<br/>The number of old ReplicaSets to retain to allow rollback in deployment or<br />maximum number of revisions that will be maintained in the Deployment revision history.<br />Has no effect at StatefulSets<br />Defaults to 10. |
256-
| rollingUpdateStrategy<a href="#vlagentspec-rollingupdatestrategy" id="vlagentspec-rollingupdatestrategy">#</a><br/>_[StatefulSetUpdateStrategyType](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#statefulsetupdatestrategytype-v1-apps)_ | _(Optional)_<br/>StatefulRollingUpdateStrategy allows configuration for strategyType<br />set it to RollingUpdate for disabling operator statefulSet rollingUpdate |
256+
| rollingUpdateStrategy<a href="#vlagentspec-rollingupdatestrategy" id="vlagentspec-rollingupdatestrategy">#</a><br/>_[StatefulSetUpdateStrategyType](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#statefulsetupdatestrategytype-v1-apps)_ | _(Optional)_<br/>RollingUpdateStrategy allows configuration for strategyType<br />set it to RollingUpdate for disabling operator statefulSet rollingUpdate |
257257
| runtimeClassName<a href="#vlagentspec-runtimeclassname" id="vlagentspec-runtimeclassname">#</a><br/>_string_ | _(Optional)_<br/>RuntimeClassName - defines runtime class for kubernetes pod.<br />https://kubernetes.io/docs/concepts/containers/runtime-class/ |
258258
| schedulerName<a href="#vlagentspec-schedulername" id="vlagentspec-schedulername">#</a><br/>_string_ | _(Optional)_<br/>SchedulerName - defines kubernetes scheduler name |
259259
| secrets<a href="#vlagentspec-secrets" id="vlagentspec-secrets">#</a><br/>_string array_ | _(Optional)_<br/>Secrets is a list of Secrets in the same namespace as the Application<br />object, which shall be mounted into the Application container<br />at /etc/vm/secrets/SECRET_NAME folder |
260260
| securityContext<a href="#vlagentspec-securitycontext" id="vlagentspec-securitycontext">#</a><br/>_[SecurityContext](#securitycontext)_ | _(Optional)_<br/>SecurityContext holds pod-level security attributes and common container settings.<br />This defaults to the default PodSecurityContext. |
261261
| serviceAccountName<a href="#vlagentspec-serviceaccountname" id="vlagentspec-serviceaccountname">#</a><br/>_string_ | _(Optional)_<br/>ServiceAccountName is the name of the ServiceAccount to use to run the pods |
262262
| serviceScrapeSpec<a href="#vlagentspec-servicescrapespec" id="vlagentspec-servicescrapespec">#</a><br/>_[VMServiceScrapeSpec](#vmservicescrapespec)_ | _(Optional)_<br/>ServiceScrapeSpec that will be added to vlagent VMServiceScrape spec |
263263
| serviceSpec<a href="#vlagentspec-servicespec" id="vlagentspec-servicespec">#</a><br/>_[AdditionalServiceSpec](#additionalservicespec)_ | _(Optional)_<br/>ServiceSpec that will be added to vlagent service spec |
264-
| storage<a href="#vlagentspec-storage" id="vlagentspec-storage">#</a><br/>_[StorageSpec](#storagespec)_ | _(Optional)_<br/>StatefulStorage configures storage for StatefulSet |
264+
| storage<a href="#vlagentspec-storage" id="vlagentspec-storage">#</a><br/>_[StorageSpec](#storagespec)_ | _(Optional)_<br/>Storage configures storage for StatefulSet |
265265
| syslogSpec<a href="#vlagentspec-syslogspec" id="vlagentspec-syslogspec">#</a><br/>_[SyslogServerSpec](#syslogserverspec)_ | _(Optional)_<br/>SyslogSpec defines syslog listener configuration |
266266
| terminationGracePeriodSeconds<a href="#vlagentspec-terminationgraceperiodseconds" id="vlagentspec-terminationgraceperiodseconds">#</a><br/>_integer_ | _(Optional)_<br/>TerminationGracePeriodSeconds period for container graceful termination |
267267
| tolerations<a href="#vlagentspec-tolerations" id="vlagentspec-tolerations">#</a><br/>_[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#toleration-v1-core) array_ | _(Optional)_<br/>Tolerations If specified, the pod's tolerations. |

internal/controller/operator/factory/build/container.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,3 +535,47 @@ func AddSyslogTLSConfigToVolumes(dstVolumes []corev1.Volume, dstMounts []corev1.
535535
}
536536
return dstVolumes, dstMounts
537537
}
538+
539+
func StorageVolumeMountsTo(volumes []corev1.Volume, mounts []corev1.VolumeMount, pvcSrc *corev1.PersistentVolumeClaimVolumeSource, volumeName, storagePath string) ([]corev1.Volume, []corev1.VolumeMount) {
540+
var alreadyMounted bool
541+
for _, volumeMount := range mounts {
542+
if volumeMount.Name == volumeName {
543+
alreadyMounted = true
544+
break
545+
}
546+
}
547+
if !alreadyMounted {
548+
mounts = append(mounts, corev1.VolumeMount{
549+
Name: volumeName,
550+
MountPath: storagePath,
551+
})
552+
}
553+
if pvcSrc != nil {
554+
volumes = append(volumes, corev1.Volume{
555+
Name: volumeName,
556+
VolumeSource: corev1.VolumeSource{
557+
PersistentVolumeClaim: pvcSrc,
558+
},
559+
})
560+
return volumes, mounts
561+
}
562+
563+
var volumePresent bool
564+
for _, volume := range volumes {
565+
if volume.Name == volumeName {
566+
volumePresent = true
567+
break
568+
}
569+
}
570+
if volumePresent {
571+
return volumes, mounts
572+
}
573+
574+
volumes = append(volumes, corev1.Volume{
575+
Name: volumeName,
576+
VolumeSource: corev1.VolumeSource{
577+
EmptyDir: &corev1.EmptyDirVolumeSource{},
578+
},
579+
})
580+
return volumes, mounts
581+
}

internal/controller/operator/factory/build/container_test.go

Lines changed: 175 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ func Test_buildProbe(t *testing.T) {
4545
cr testBuildProbeCR
4646
validate func(corev1.Container) error
4747
}
48-
4948
f := func(o opts) {
5049
t.Helper()
5150
got := Probe(o.container, o.cr)
@@ -349,5 +348,180 @@ func TestAddSyslogArgsTo(t *testing.T) {
349348
"-syslog.compressMethod.udp=zstd",
350349
}
351350
f(&spec, expected)
351+
}
352+
353+
func TestStorageVolumeMountsTo(t *testing.T) {
354+
type opts struct {
355+
pvcSrc *corev1.PersistentVolumeClaimVolumeSource
356+
volumeName string
357+
storagePath string
358+
volumes []corev1.Volume
359+
expectedVolumes []corev1.Volume
360+
mounts []corev1.VolumeMount
361+
expectedMounts []corev1.VolumeMount
362+
}
363+
f := func(o opts) {
364+
t.Helper()
365+
gotVolumes, gotMounts := StorageVolumeMountsTo(o.volumes, o.mounts, o.pvcSrc, o.volumeName, o.storagePath)
366+
assert.Equal(t, o.expectedMounts, gotMounts)
367+
assert.Equal(t, o.expectedVolumes, gotVolumes)
368+
}
369+
370+
// no PVC spec and no volumes and mounts
371+
f(opts{
372+
volumeName: "test",
373+
storagePath: "/test",
374+
expectedVolumes: []corev1.Volume{{
375+
Name: "test",
376+
VolumeSource: corev1.VolumeSource{
377+
EmptyDir: &corev1.EmptyDirVolumeSource{},
378+
},
379+
}},
380+
expectedMounts: []corev1.VolumeMount{{
381+
Name: "test",
382+
MountPath: "/test",
383+
}},
384+
})
385+
386+
// with PVC spec and no volumes and mounts
387+
f(opts{
388+
volumeName: "test",
389+
storagePath: "/test",
390+
pvcSrc: &corev1.PersistentVolumeClaimVolumeSource{
391+
ClaimName: "test-claim",
392+
},
393+
expectedVolumes: []corev1.Volume{{
394+
Name: "test",
395+
VolumeSource: corev1.VolumeSource{
396+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
397+
ClaimName: "test-claim",
398+
},
399+
},
400+
}},
401+
expectedMounts: []corev1.VolumeMount{{
402+
Name: "test",
403+
MountPath: "/test",
404+
}},
405+
})
406+
407+
// with PVC spec and matching data volume
408+
f(opts{
409+
volumes: []corev1.Volume{{
410+
Name: "test",
411+
VolumeSource: corev1.VolumeSource{
412+
AWSElasticBlockStore: &corev1.AWSElasticBlockStoreVolumeSource{
413+
VolumeID: "aws-volume",
414+
},
415+
},
416+
}},
417+
volumeName: "test",
418+
storagePath: "/test",
419+
pvcSrc: &corev1.PersistentVolumeClaimVolumeSource{
420+
ClaimName: "test-claim",
421+
},
422+
expectedVolumes: []corev1.Volume{
423+
{
424+
Name: "test",
425+
VolumeSource: corev1.VolumeSource{
426+
AWSElasticBlockStore: &corev1.AWSElasticBlockStoreVolumeSource{
427+
VolumeID: "aws-volume",
428+
},
429+
},
430+
},
431+
{
432+
Name: "test",
433+
VolumeSource: corev1.VolumeSource{
434+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
435+
ClaimName: "test-claim",
436+
},
437+
},
438+
},
439+
},
440+
expectedMounts: []corev1.VolumeMount{{
441+
Name: "test",
442+
MountPath: "/test",
443+
}},
444+
})
352445

446+
// with PVC spec and not matching data volume
447+
f(opts{
448+
volumes: []corev1.Volume{{
449+
Name: "extra",
450+
VolumeSource: corev1.VolumeSource{
451+
AWSElasticBlockStore: &corev1.AWSElasticBlockStoreVolumeSource{
452+
VolumeID: "aws-volume",
453+
},
454+
},
455+
}},
456+
volumeName: "test",
457+
storagePath: "/test",
458+
pvcSrc: &corev1.PersistentVolumeClaimVolumeSource{
459+
ClaimName: "test-claim",
460+
},
461+
expectedVolumes: []corev1.Volume{
462+
{
463+
Name: "extra",
464+
VolumeSource: corev1.VolumeSource{
465+
AWSElasticBlockStore: &corev1.AWSElasticBlockStoreVolumeSource{
466+
VolumeID: "aws-volume",
467+
},
468+
},
469+
},
470+
{
471+
Name: "test",
472+
VolumeSource: corev1.VolumeSource{
473+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
474+
ClaimName: "test-claim",
475+
},
476+
},
477+
},
478+
},
479+
expectedMounts: []corev1.VolumeMount{{
480+
Name: "test",
481+
MountPath: "/test",
482+
}},
483+
})
484+
485+
// with PVC spec and existing data volume mount
486+
f(opts{
487+
volumes: []corev1.Volume{{
488+
Name: "extra",
489+
VolumeSource: corev1.VolumeSource{
490+
AWSElasticBlockStore: &corev1.AWSElasticBlockStoreVolumeSource{
491+
VolumeID: "aws-volume",
492+
},
493+
},
494+
}},
495+
mounts: []corev1.VolumeMount{{
496+
Name: "test",
497+
MountPath: "/other-path",
498+
}},
499+
volumeName: "test",
500+
storagePath: "/test",
501+
pvcSrc: &corev1.PersistentVolumeClaimVolumeSource{
502+
ClaimName: "test-claim",
503+
},
504+
expectedVolumes: []corev1.Volume{
505+
{
506+
Name: "extra",
507+
VolumeSource: corev1.VolumeSource{
508+
AWSElasticBlockStore: &corev1.AWSElasticBlockStoreVolumeSource{
509+
VolumeID: "aws-volume",
510+
},
511+
},
512+
},
513+
{
514+
Name: "test",
515+
VolumeSource: corev1.VolumeSource{
516+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
517+
ClaimName: "test-claim",
518+
},
519+
},
520+
},
521+
},
522+
expectedMounts: []corev1.VolumeMount{{
523+
Name: "test",
524+
MountPath: "/other-path",
525+
}},
526+
})
353527
}

internal/controller/operator/factory/vlsingle/vlogs.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func makeVLogsPodSpec(r *vmv1beta1.VLogs) (*corev1.PodTemplateSpec, error) {
150150
// if customStorageDataPath is not empty, do not add pvc.
151151
shouldAddPVC := r.Spec.StorageDataPath == ""
152152

153-
storagePath := vlsingleDataDir
153+
storagePath := dataDataDir
154154
if r.Spec.StorageDataPath != "" {
155155
storagePath = r.Spec.StorageDataPath
156156
}
@@ -186,14 +186,14 @@ func makeVLogsPodSpec(r *vmv1beta1.VLogs) (*corev1.PodTemplateSpec, error) {
186186

187187
if storageSpec == nil {
188188
volumes = append(volumes, corev1.Volume{
189-
Name: vlsingleDataVolumeName,
189+
Name: dataVolumeName,
190190
VolumeSource: corev1.VolumeSource{
191191
EmptyDir: &corev1.EmptyDirVolumeSource{},
192192
},
193193
})
194194
} else if shouldAddPVC {
195195
volumes = append(volumes, corev1.Volume{
196-
Name: vlsingleDataVolumeName,
196+
Name: dataVolumeName,
197197
VolumeSource: corev1.VolumeSource{
198198
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
199199
ClaimName: r.PrefixedName(),
@@ -204,7 +204,7 @@ func makeVLogsPodSpec(r *vmv1beta1.VLogs) (*corev1.PodTemplateSpec, error) {
204204
volumes = append(volumes, r.Spec.Volumes...)
205205
vmMounts := []corev1.VolumeMount{
206206
{
207-
Name: vlsingleDataVolumeName,
207+
Name: dataVolumeName,
208208
MountPath: storagePath,
209209
},
210210
}

0 commit comments

Comments
 (0)