diff --git a/pkg/controller/pod_volume_backup_controller.go b/pkg/controller/pod_volume_backup_controller.go index aceaab7805..d14489b2fd 100644 --- a/pkg/controller/pod_volume_backup_controller.go +++ b/pkg/controller/pod_volume_backup_controller.go @@ -793,16 +793,32 @@ func (r *PodVolumeBackupReconciler) setupExposeParam(pvb *velerov1api.PodVolumeB nodeOS, err := kube.GetNodeOS(context.Background(), pvb.Spec.Node, r.kubeClient.CoreV1()) if err != nil { log.WithError(err).Warnf("Failed to get nodeOS for node %s, use linux node-agent for hosting pod labels, annotations and tolerations", pvb.Spec.Node) + nodeOS = kube.NodeOSLinux // Default to Linux if detection fails } hostingPodLabels := map[string]string{velerov1api.PVBLabel: pvb.Name} + + // Get all labels from node-agent DaemonSet + if labels, err := nodeagent.GetAllLabelsFromNodeAgent(context.Background(), r.kubeClient, pvb.Namespace, nodeOS); err != nil { + log.WithError(err).Warn("Failed to get node-agent labels") + } else { + for k, v := range labels { + hostingPodLabels[k] = v + } + } + + // Still copy specific third-party labels for backward compatibility + // This ensures known labels are always copied even if DaemonSet lookup fails for _, k := range util.ThirdPartyLabels { if v, err := nodeagent.GetLabelValue(context.Background(), r.kubeClient, pvb.Namespace, k, nodeOS); err != nil { if err != nodeagent.ErrNodeAgentLabelNotFound { log.WithError(err).Warnf("Failed to check node-agent label, skip adding host pod label %s", k) } } else { - hostingPodLabels[k] = v + // Only add if not already present (from above loop) + if _, exists := hostingPodLabels[k]; !exists { + hostingPodLabels[k] = v + } } } diff --git a/pkg/controller/pod_volume_restore_controller.go b/pkg/controller/pod_volume_restore_controller.go index 87b2353f52..e0a7b2929a 100644 --- a/pkg/controller/pod_volume_restore_controller.go +++ b/pkg/controller/pod_volume_restore_controller.go @@ -860,16 +860,32 @@ func (r *PodVolumeRestoreReconciler) setupExposeParam(pvr *velerov1api.PodVolume nodeOS, err := kube.GetNodeOS(context.Background(), pvr.Status.Node, r.kubeClient.CoreV1()) if err != nil { log.WithError(err).Warnf("Failed to get nodeOS for node %s, use linux node-agent for hosting pod labels, annotations and tolerations", pvr.Status.Node) + nodeOS = kube.NodeOSLinux // Default to Linux if detection fails } hostingPodLabels := map[string]string{velerov1api.PVRLabel: pvr.Name} + + // Get all labels from node-agent DaemonSet + if labels, err := nodeagent.GetAllLabelsFromNodeAgent(context.Background(), r.kubeClient, pvr.Namespace, nodeOS); err != nil { + log.WithError(err).Warn("Failed to get node-agent labels") + } else { + for k, v := range labels { + hostingPodLabels[k] = v + } + } + + // Still copy specific third-party labels for backward compatibility + // This ensures known labels are always copied even if DaemonSet lookup fails for _, k := range util.ThirdPartyLabels { if v, err := nodeagent.GetLabelValue(context.Background(), r.kubeClient, pvr.Namespace, k, nodeOS); err != nil { if err != nodeagent.ErrNodeAgentLabelNotFound { log.WithError(err).Warnf("Failed to check node-agent label, skip adding host pod label %s", k) } } else { - hostingPodLabels[k] = v + // Only add if not already present (from above loop) + if _, exists := hostingPodLabels[k]; !exists { + hostingPodLabels[k] = v + } } } diff --git a/pkg/nodeagent/node_agent.go b/pkg/nodeagent/node_agent.go index a5de2465ca..6ba5df0757 100644 --- a/pkg/nodeagent/node_agent.go +++ b/pkg/nodeagent/node_agent.go @@ -268,3 +268,25 @@ func HostPodVolumeMountPath() string { func HostPodVolumeMountPathWin() string { return "\\" + HostPodVolumeMountPoint } + +// GetAllLabelsFromNodeAgent returns all labels from the node-agent DaemonSet +func GetAllLabelsFromNodeAgent(ctx context.Context, kubeClient kubernetes.Interface, namespace string, osType string) (map[string]string, error) { + dsName := daemonSet + if osType == kube.NodeOSWindows { + dsName = daemonsetWindows + } + + ds, err := kubeClient.AppsV1().DaemonSets(namespace).Get(ctx, dsName, metav1.GetOptions{}) + if err != nil { + return nil, errors.Wrapf(err, "error getting %s daemonset", dsName) + } + + labels := make(map[string]string) + if ds.Spec.Template.Labels != nil { + for k, v := range ds.Spec.Template.Labels { + labels[k] = v + } + } + + return labels, nil +}