From f947092f1a213ddb82f80522c6980e70140b168b Mon Sep 17 00:00:00 2001 From: lyndon-li <98304688+Lyndon-Li@users.noreply.github.com> Date: Wed, 12 Nov 2025 02:02:56 +0800 Subject: [PATCH] cache volume for PVR (#9397) Signed-off-by: Lyndon-Li --- changelogs/unreleased/9397-Lyndon-Li | 1 + pkg/cmd/cli/nodeagent/server.go | 2 +- .../pod_volume_restore_controller.go | 28 +++++++++++++++++-- .../pod_volume_restore_controller_test.go | 2 +- 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 changelogs/unreleased/9397-Lyndon-Li diff --git a/changelogs/unreleased/9397-Lyndon-Li b/changelogs/unreleased/9397-Lyndon-Li new file mode 100644 index 000000000..b5291f6c8 --- /dev/null +++ b/changelogs/unreleased/9397-Lyndon-Li @@ -0,0 +1 @@ +Cache volume for PVR \ No newline at end of file diff --git a/pkg/cmd/cli/nodeagent/server.go b/pkg/cmd/cli/nodeagent/server.go index f155ae01e..779088784 100644 --- a/pkg/cmd/cli/nodeagent/server.go +++ b/pkg/cmd/cli/nodeagent/server.go @@ -363,7 +363,7 @@ func (s *nodeAgentServer) run() { s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerPodVolumeBackup) } - pvrReconciler := controller.NewPodVolumeRestoreReconciler(s.mgr.GetClient(), s.mgr, s.kubeClient, s.dataPathMgr, s.vgdpCounter, s.nodeName, s.config.dataMoverPrepareTimeout, s.config.resourceTimeout, podResources, s.logger, dataMovePriorityClass, privilegedFsBackup) + pvrReconciler := controller.NewPodVolumeRestoreReconciler(s.mgr.GetClient(), s.mgr, s.kubeClient, s.dataPathMgr, s.vgdpCounter, s.nodeName, s.config.dataMoverPrepareTimeout, s.config.resourceTimeout, s.backupRepoConfigs, cachePVCConfig, podResources, s.logger, dataMovePriorityClass, privilegedFsBackup, s.repoConfigMgr) if err := pvrReconciler.SetupWithManager(s.mgr); err != nil { s.logger.WithError(err).Fatal("Unable to create the pod volume restore controller") } diff --git a/pkg/controller/pod_volume_restore_controller.go b/pkg/controller/pod_volume_restore_controller.go index 0ed06b980..87b2353f5 100644 --- a/pkg/controller/pod_volume_restore_controller.go +++ b/pkg/controller/pod_volume_restore_controller.go @@ -48,15 +48,18 @@ import ( "github.com/vmware-tanzu/velero/pkg/datapath" "github.com/vmware-tanzu/velero/pkg/exposer" "github.com/vmware-tanzu/velero/pkg/nodeagent" + repository "github.com/vmware-tanzu/velero/pkg/repository/manager" "github.com/vmware-tanzu/velero/pkg/restorehelper" + velerotypes "github.com/vmware-tanzu/velero/pkg/types" "github.com/vmware-tanzu/velero/pkg/uploader" "github.com/vmware-tanzu/velero/pkg/util" "github.com/vmware-tanzu/velero/pkg/util/kube" ) func NewPodVolumeRestoreReconciler(client client.Client, mgr manager.Manager, kubeClient kubernetes.Interface, dataPathMgr *datapath.Manager, - counter *exposer.VgdpCounter, nodeName string, preparingTimeout time.Duration, resourceTimeout time.Duration, podResources corev1api.ResourceRequirements, - logger logrus.FieldLogger, dataMovePriorityClass string, privileged bool) *PodVolumeRestoreReconciler { + counter *exposer.VgdpCounter, nodeName string, preparingTimeout time.Duration, resourceTimeout time.Duration, backupRepoConfigs map[string]string, + cacheVolumeConfigs *velerotypes.CachePVC, podResources corev1api.ResourceRequirements, logger logrus.FieldLogger, dataMovePriorityClass string, + privileged bool, repoConfigMgr repository.ConfigManager) *PodVolumeRestoreReconciler { return &PodVolumeRestoreReconciler{ client: client, mgr: mgr, @@ -65,6 +68,8 @@ func NewPodVolumeRestoreReconciler(client client.Client, mgr manager.Manager, ku nodeName: nodeName, clock: &clocks.RealClock{}, podResources: podResources, + backupRepoConfigs: backupRepoConfigs, + cacheVolumeConfigs: cacheVolumeConfigs, dataPathMgr: dataPathMgr, vgdpCounter: counter, preparingTimeout: preparingTimeout, @@ -73,6 +78,7 @@ func NewPodVolumeRestoreReconciler(client client.Client, mgr manager.Manager, ku cancelledPVR: make(map[string]time.Time), dataMovePriorityClass: dataMovePriorityClass, privileged: privileged, + repoConfigMgr: repoConfigMgr, } } @@ -84,6 +90,8 @@ type PodVolumeRestoreReconciler struct { nodeName string clock clocks.WithTickerAndDelayedExecution podResources corev1api.ResourceRequirements + backupRepoConfigs map[string]string + cacheVolumeConfigs *velerotypes.CachePVC exposer exposer.PodVolumeExposer dataPathMgr *datapath.Manager vgdpCounter *exposer.VgdpCounter @@ -92,6 +100,7 @@ type PodVolumeRestoreReconciler struct { cancelledPVR map[string]time.Time dataMovePriorityClass string privileged bool + repoConfigMgr repository.ConfigManager } // +kubebuilder:rbac:groups=velero.io,resources=podvolumerestores,verbs=get;list;watch;create;update;patch;delete @@ -886,6 +895,19 @@ func (r *PodVolumeRestoreReconciler) setupExposeParam(pvr *velerov1api.PodVolume } } + var cacheVolume *exposer.CacheConfigs + if r.cacheVolumeConfigs != nil { + if limit, err := r.repoConfigMgr.ClientSideCacheLimit(velerov1api.BackupRepositoryTypeKopia, r.backupRepoConfigs); err != nil { + log.WithError(err).Warnf("Failed to get client side cache limit for repo type %s from configs %v", velerov1api.BackupRepositoryTypeKopia, r.backupRepoConfigs) + } else { + cacheVolume = &exposer.CacheConfigs{ + Limit: limit, + StorageClass: r.cacheVolumeConfigs.StorageClass, + ResidentThreshold: r.cacheVolumeConfigs.ResidentThreshold, + } + } + } + return exposer.PodVolumeExposeParam{ Type: exposer.PodVolumeExposeTypeRestore, ClientNamespace: pvr.Spec.Pod.Namespace, @@ -896,6 +918,8 @@ func (r *PodVolumeRestoreReconciler) setupExposeParam(pvr *velerov1api.PodVolume HostingPodTolerations: hostingPodTolerations, OperationTimeout: r.resourceTimeout, Resources: r.podResources, + RestoreSize: pvr.Spec.SnapshotSize, + CacheVolume: cacheVolume, // Priority class name for the data mover pod, retrieved from node-agent-configmap PriorityClassName: r.dataMovePriorityClass, Privileged: r.privileged, diff --git a/pkg/controller/pod_volume_restore_controller_test.go b/pkg/controller/pod_volume_restore_controller_test.go index e993815b5..be09f9c62 100644 --- a/pkg/controller/pod_volume_restore_controller_test.go +++ b/pkg/controller/pod_volume_restore_controller_test.go @@ -617,7 +617,7 @@ func initPodVolumeRestoreReconcilerWithError(objects []runtime.Object, cliObj [] dataPathMgr := datapath.NewManager(1) - return NewPodVolumeRestoreReconciler(fakeClient, nil, fakeKubeClient, dataPathMgr, nil, "test-node", time.Minute*5, time.Minute, corev1api.ResourceRequirements{}, velerotest.NewLogger(), "", false), nil + return NewPodVolumeRestoreReconciler(fakeClient, nil, fakeKubeClient, dataPathMgr, nil, "test-node", time.Minute*5, time.Minute, nil, nil, corev1api.ResourceRequirements{}, velerotest.NewLogger(), "", false, nil), nil } func TestPodVolumeRestoreReconcile(t *testing.T) {