Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/operator/v1/vlagent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ type VLAgentSpec struct {
// PodDisruptionBudget created by operator
// +optional
PodDisruptionBudget *vmv1beta1.EmbeddedPodDisruptionBudgetSpec `json:"podDisruptionBudget,omitempty"`
// StatefulStorage configures storage for StatefulSet
// Storage configures storage for StatefulSet
// +optional
Storage *vmv1beta1.StorageSpec `json:"storage,omitempty"`
// StatefulRollingUpdateStrategy allows configuration for strategyType
// RollingUpdateStrategy allows configuration for strategyType
// set it to RollingUpdate for disabling operator statefulSet rollingUpdate
// +optional
RollingUpdateStrategy appsv1.StatefulSetUpdateStrategyType `json:"rollingUpdateStrategy,omitempty"`
Expand Down
4 changes: 2 additions & 2 deletions config/crd/overlay/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,7 @@ spec:
type: integer
rollingUpdateStrategy:
description: |-
StatefulRollingUpdateStrategy allows configuration for strategyType
RollingUpdateStrategy allows configuration for strategyType
set it to RollingUpdate for disabling operator statefulSet rollingUpdate
type: string
runtimeClassName:
Expand Down Expand Up @@ -1357,7 +1357,7 @@ spec:
type: object
x-kubernetes-preserve-unknown-fields: true
storage:
description: StatefulStorage configures storage for StatefulSet
description: Storage configures storage for StatefulSet
properties:
disableMountSubPath:
description: |-
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ SECURITY: upgrade Go builder from Go1.25.4 to Go1.25.5. See [the list of issues
* BUGFIX: [vmoperator](https://docs.victoriametrics.com/operator/): remove orphaned ServiceAccount and RBAC resources. See [#1665](https://github.com/VictoriaMetrics/operator/issues/1665).
* 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.
* 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`.
* 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).

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

Expand Down
4 changes: 2 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,15 @@ Appears in: [VLAgent](#vlagent)
| replicaCount<a href="#vlagentspec-replicacount" id="vlagentspec-replicacount">#</a><br/>_integer_ | _(Optional)_<br/>ReplicaCount is the expected size of the Application. |
| 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 |
| 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. |
| 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 |
| 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 |
| 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/ |
| schedulerName<a href="#vlagentspec-schedulername" id="vlagentspec-schedulername">#</a><br/>_string_ | _(Optional)_<br/>SchedulerName - defines kubernetes scheduler name |
| 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 |
| 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. |
| 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 |
| serviceScrapeSpec<a href="#vlagentspec-servicescrapespec" id="vlagentspec-servicescrapespec">#</a><br/>_[VMServiceScrapeSpec](#vmservicescrapespec)_ | _(Optional)_<br/>ServiceScrapeSpec that will be added to vlagent VMServiceScrape spec |
| serviceSpec<a href="#vlagentspec-servicespec" id="vlagentspec-servicespec">#</a><br/>_[AdditionalServiceSpec](#additionalservicespec)_ | _(Optional)_<br/>ServiceSpec that will be added to vlagent service spec |
| storage<a href="#vlagentspec-storage" id="vlagentspec-storage">#</a><br/>_[StorageSpec](#storagespec)_ | _(Optional)_<br/>StatefulStorage configures storage for StatefulSet |
| storage<a href="#vlagentspec-storage" id="vlagentspec-storage">#</a><br/>_[StorageSpec](#storagespec)_ | _(Optional)_<br/>Storage configures storage for StatefulSet |
| syslogSpec<a href="#vlagentspec-syslogspec" id="vlagentspec-syslogspec">#</a><br/>_[SyslogServerSpec](#syslogserverspec)_ | _(Optional)_<br/>SyslogSpec defines syslog listener configuration |
| terminationGracePeriodSeconds<a href="#vlagentspec-terminationgraceperiodseconds" id="vlagentspec-terminationgraceperiodseconds">#</a><br/>_integer_ | _(Optional)_<br/>TerminationGracePeriodSeconds period for container graceful termination |
| 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. |
Expand Down
25 changes: 4 additions & 21 deletions internal/controller/operator/factory/build/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ func VMBackupManager(
ctx context.Context,
cr *vmv1beta1.VMBackup,
port string,
storagePath, dataVolumeName string,
storagePath string,
mounts []corev1.VolumeMount,
extraArgs map[string]string,
isCluster bool,
license *vmv1beta1.License,
Expand Down Expand Up @@ -85,16 +86,7 @@ func VMBackupManager(

var ports []corev1.ContainerPort
ports = append(ports, corev1.ContainerPort{Name: "http", Protocol: "TCP", ContainerPort: intstr.Parse(cr.Port).IntVal})

mounts := []corev1.VolumeMount{
{
Name: dataVolumeName,
MountPath: storagePath,
ReadOnly: false,
},
}
mounts = append(mounts, cr.VolumeMounts...)

if cr.CredentialsSecret != nil {
mounts = append(mounts, corev1.VolumeMount{
Name: k8stools.SanitizeVolumeName("secret-" + cr.CredentialsSecret.Name),
Expand Down Expand Up @@ -171,9 +163,9 @@ func VMBackupManager(
// VMRestore conditionally creates vmrestore container
func VMRestore(
cr *vmv1beta1.VMBackup,
storagePath, dataVolumeName string,
storagePath string,
mounts []corev1.VolumeMount,
) (*corev1.Container, error) {

args := []string{
fmt.Sprintf("-storageDataPath=%s", storagePath),
"-eula",
Expand All @@ -197,16 +189,7 @@ func VMRestore(

var ports []corev1.ContainerPort
ports = append(ports, corev1.ContainerPort{Name: "http", Protocol: "TCP", ContainerPort: intstr.Parse(cr.Port).IntVal})

mounts := []corev1.VolumeMount{
{
Name: dataVolumeName,
MountPath: storagePath,
ReadOnly: false,
},
}
mounts = append(mounts, cr.VolumeMounts...)

if cr.CredentialsSecret != nil {
mounts = append(mounts, corev1.VolumeMount{
Name: k8stools.SanitizeVolumeName("secret-" + cr.CredentialsSecret.Name),
Expand Down
48 changes: 48 additions & 0 deletions internal/controller/operator/factory/build/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package build

import (
"fmt"
"path/filepath"
"strings"

corev1 "k8s.io/api/core/v1"
Expand All @@ -15,6 +16,7 @@ import (
)

const probeTimeoutSeconds int32 = 5
const DataVolumeName = "data"

type probeCRD interface {
Probe() *vmv1beta1.EmbeddedProbes
Expand Down Expand Up @@ -535,3 +537,49 @@ func AddSyslogTLSConfigToVolumes(dstVolumes []corev1.Volume, dstMounts []corev1.
}
return dstVolumes, dstMounts
}

func StorageVolumeMountsTo(volumes []corev1.Volume, mounts []corev1.VolumeMount, pvcSrc *corev1.PersistentVolumeClaimVolumeSource, storagePath, dataVolumeName string) ([]corev1.Volume, []corev1.VolumeMount, error) {
foundMount := false
for _, volumeMount := range mounts {
rel, err := filepath.Rel(volumeMount.MountPath, storagePath)
if err == nil && !strings.HasPrefix(rel, "..") {
if volumeMount.Name == dataVolumeName {
foundMount = true
break
}
return nil, nil, fmt.Errorf(
"unexpected volume=%q mounted to path=%q, which is reserved for volume=%q, path=%q",
volumeMount.Name, volumeMount.MountPath, dataVolumeName, storagePath)
} else {
if volumeMount.Name != dataVolumeName {
continue
}
return nil, nil, fmt.Errorf(
"unexpected volume=%q mounted to path=%q, expected path=%q",
volumeMount.Name, volumeMount.MountPath, dataVolumeName)
}
}
if !foundMount {
mounts = append([]corev1.VolumeMount{{
Name: dataVolumeName,
MountPath: storagePath,
}}, mounts...)
}

for _, volume := range volumes {
if volume.Name == dataVolumeName {
return volumes, mounts, nil
}
}
var source corev1.VolumeSource
if pvcSrc != nil {
source.PersistentVolumeClaim = pvcSrc
} else {
source.EmptyDir = &corev1.EmptyDirVolumeSource{}
}
volumes = append([]corev1.Volume{{
Name: dataVolumeName,
VolumeSource: source,
}}, volumes...)
return volumes, mounts, nil
}
Loading
Loading