diff --git a/changelogs/unreleased/9532-Lyndon-Li‎ b/changelogs/unreleased/9532-Lyndon-Li similarity index 100% rename from changelogs/unreleased/9532-Lyndon-Li‎ rename to changelogs/unreleased/9532-Lyndon-Li diff --git a/changelogs/unreleased/9533-Lyndon-Li‎‎ b/changelogs/unreleased/9533-Lyndon-Li‎‎ new file mode 100644 index 000000000..acd2b37cb --- /dev/null +++ b/changelogs/unreleased/9533-Lyndon-Li‎‎ @@ -0,0 +1 @@ +Fix issue #9496, support customized host os \ No newline at end of file diff --git a/pkg/exposer/csi_snapshot.go b/pkg/exposer/csi_snapshot.go index 637cd7c07..079a4b527 100644 --- a/pkg/exposer/csi_snapshot.go +++ b/pkg/exposer/csi_snapshot.go @@ -330,7 +330,8 @@ func (e *csiSnapshotExposer) GetExposed(ctx context.Context, ownerObject corev1a curLog.WithField("pod", pod.Name).Infof("Backup volume is found in pod at index %v", i) var nodeOS *string - if os, found := pod.Spec.NodeSelector[kube.NodeOSLabel]; found { + if pod.Spec.OS != nil { + os := string(pod.Spec.OS.Name) nodeOS = &os } @@ -654,6 +655,10 @@ func (e *csiSnapshotExposer) createBackupPod( args = append(args, podInfo.logFormatArgs...) args = append(args, podInfo.logLevelArgs...) + if affinity == nil { + affinity = &kube.LoadAffinity{} + } + var securityCtx *corev1api.PodSecurityContext nodeSelector := map[string]string{} podOS := corev1api.PodOS{} @@ -665,9 +670,14 @@ func (e *csiSnapshotExposer) createBackupPod( }, } - nodeSelector[kube.NodeOSLabel] = kube.NodeOSWindows podOS.Name = kube.NodeOSWindows + affinity.NodeSelector.MatchExpressions = append(affinity.NodeSelector.MatchExpressions, metav1.LabelSelectorRequirement{ + Key: kube.NodeOSLabel, + Values: []string{kube.NodeOSWindows}, + Operator: metav1.LabelSelectorOpIn, + }) + toleration = append(toleration, []corev1api.Toleration{ { Key: "os", @@ -694,11 +704,15 @@ func (e *csiSnapshotExposer) createBackupPod( } } - nodeSelector[kube.NodeOSLabel] = kube.NodeOSLinux podOS.Name = kube.NodeOSLinux + + affinity.NodeSelector.MatchExpressions = append(affinity.NodeSelector.MatchExpressions, metav1.LabelSelectorRequirement{ + Key: kube.NodeOSLabel, + Values: []string{kube.NodeOSWindows}, + Operator: metav1.LabelSelectorOpNotIn, + }) } - var podAffinity *corev1api.Affinity if len(intoleratableNodes) > 0 { if affinity == nil { affinity = &kube.LoadAffinity{} @@ -711,9 +725,7 @@ func (e *csiSnapshotExposer) createBackupPod( }) } - if affinity != nil { - podAffinity = kube.ToSystemAffinity(affinity, volumeTopology) - } + podAffinity := kube.ToSystemAffinity(affinity, volumeTopology) pod := &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/exposer/csi_snapshot_test.go b/pkg/exposer/csi_snapshot_test.go index 04cf2b8b6..e1a9860eb 100644 --- a/pkg/exposer/csi_snapshot_test.go +++ b/pkg/exposer/csi_snapshot_test.go @@ -467,6 +467,23 @@ func TestExpose(t *testing.T) { daemonSet, scObj, }, + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, }, { name: "success-with-labels", @@ -488,6 +505,23 @@ func TestExpose(t *testing.T) { daemonSet, scObj, }, + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, }, { name: "restore size from exposeParam", @@ -511,6 +545,23 @@ func TestExpose(t *testing.T) { scObj, }, expectedVolumeSize: resource.NewQuantity(567890, ""), + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, }, { name: "backupPod mounts read only backupPVC", @@ -539,6 +590,23 @@ func TestExpose(t *testing.T) { scObj, }, expectedReadOnlyPVC: true, + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, }, { name: "backupPod mounts read only backupPVC and storageClass specified in backupPVC config", @@ -568,6 +636,23 @@ func TestExpose(t *testing.T) { }, expectedReadOnlyPVC: true, expectedBackupPVCStorageClass: "fake-sc-read-only", + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, }, { name: "backupPod mounts backupPVC with storageClass specified in backupPVC config", @@ -595,6 +680,23 @@ func TestExpose(t *testing.T) { scObj, }, expectedBackupPVCStorageClass: "fake-sc-read-only", + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, }, { name: "Affinity per StorageClass", @@ -641,6 +743,11 @@ func TestExpose(t *testing.T) { Operator: corev1api.NodeSelectorOpIn, Values: []string{"Linux"}, }, + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, }, }, }, @@ -699,6 +806,11 @@ func TestExpose(t *testing.T) { Operator: corev1api.NodeSelectorOpIn, Values: []string{"amd64"}, }, + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, }, }, }, @@ -733,7 +845,23 @@ func TestExpose(t *testing.T) { scObj, }, expectedBackupPVCStorageClass: "fake-sc-read-only", - expectedAffinity: nil, + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, }, { name: "IntolerateSourceNode, get source node fail", @@ -770,7 +898,23 @@ func TestExpose(t *testing.T) { }, }, }, - expectedAffinity: nil, + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, expectedPVCAnnotation: nil, }, { @@ -799,7 +943,23 @@ func TestExpose(t *testing.T) { daemonSet, scObj, }, - expectedAffinity: nil, + expectedAffinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, expectedPVCAnnotation: map[string]string{util.VSphereCNSFastCloneAnno: "true"}, }, { @@ -836,6 +996,11 @@ func TestExpose(t *testing.T) { NodeSelectorTerms: []corev1api.NodeSelectorTerm{ { MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1api.NodeSelectorOpNotIn, + Values: []string{"windows"}, + }, { Key: "kubernetes.io/hostname", Operator: corev1api.NodeSelectorOpNotIn, @@ -929,6 +1094,8 @@ func TestExpose(t *testing.T) { if test.expectedAffinity != nil { assert.Equal(t, test.expectedAffinity, backupPod.Spec.Affinity) + } else { + assert.Nil(t, backupPod.Spec.Affinity) } if test.expectedPVCAnnotation != nil { diff --git a/pkg/exposer/generic_restore.go b/pkg/exposer/generic_restore.go index f7cf24d8d..186815d77 100644 --- a/pkg/exposer/generic_restore.go +++ b/pkg/exposer/generic_restore.go @@ -493,13 +493,13 @@ func (e *genericRestoreExposer) createRestorePod( containerName := string(ownerObject.UID) volumeName := string(ownerObject.UID) - var podAffinity *corev1api.Affinity - if selectedNode == "" { - e.log.Infof("No selected node for restore pod. Try to get affinity from the node-agent config.") + if selectedNode != "" { + affinity = nil + e.log.Infof("Selected node for restore pod. Ignore affinity from the node-agent config.") + } - if affinity != nil { - podAffinity = kube.ToSystemAffinity(affinity, nil) - } + if affinity == nil { + affinity = &kube.LoadAffinity{} } podInfo, err := getInheritedPodInfo(ctx, e.kubeClient, ownerObject.Namespace, nodeOS) @@ -576,9 +576,14 @@ func (e *genericRestoreExposer) createRestorePod( }, } - nodeSelector[kube.NodeOSLabel] = kube.NodeOSWindows podOS.Name = kube.NodeOSWindows + affinity.NodeSelector.MatchExpressions = append(affinity.NodeSelector.MatchExpressions, metav1.LabelSelectorRequirement{ + Key: kube.NodeOSLabel, + Values: []string{kube.NodeOSWindows}, + Operator: metav1.LabelSelectorOpIn, + }) + toleration = append(toleration, []corev1api.Toleration{ { Key: "os", @@ -599,10 +604,17 @@ func (e *genericRestoreExposer) createRestorePod( RunAsUser: &userID, } - nodeSelector[kube.NodeOSLabel] = kube.NodeOSLinux podOS.Name = kube.NodeOSLinux + + affinity.NodeSelector.MatchExpressions = append(affinity.NodeSelector.MatchExpressions, metav1.LabelSelectorRequirement{ + Key: kube.NodeOSLabel, + Values: []string{kube.NodeOSWindows}, + Operator: metav1.LabelSelectorOpNotIn, + }) } + podAffinity := kube.ToSystemAffinity(affinity, nil) + pod := &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: restorePodName, diff --git a/pkg/exposer/pod_volume.go b/pkg/exposer/pod_volume.go index 246d04e28..aeb6f1903 100644 --- a/pkg/exposer/pod_volume.go +++ b/pkg/exposer/pod_volume.go @@ -434,6 +434,8 @@ func (e *podVolumeExposer) createHostingPod( args = append(args, podInfo.logFormatArgs...) args = append(args, podInfo.logLevelArgs...) + affinity := &kube.LoadAffinity{} + var securityCtx *corev1api.PodSecurityContext var containerSecurityCtx *corev1api.SecurityContext nodeSelector := map[string]string{} @@ -446,9 +448,14 @@ func (e *podVolumeExposer) createHostingPod( }, } - nodeSelector[kube.NodeOSLabel] = kube.NodeOSWindows podOS.Name = kube.NodeOSWindows + affinity.NodeSelector.MatchExpressions = append(affinity.NodeSelector.MatchExpressions, metav1.LabelSelectorRequirement{ + Key: kube.NodeOSLabel, + Values: []string{kube.NodeOSWindows}, + Operator: metav1.LabelSelectorOpIn, + }) + toleration = append(toleration, []corev1api.Toleration{ { Key: "os", @@ -472,10 +479,17 @@ func (e *podVolumeExposer) createHostingPod( Privileged: &privileged, } - nodeSelector[kube.NodeOSLabel] = kube.NodeOSLinux podOS.Name = kube.NodeOSLinux + + affinity.NodeSelector.MatchExpressions = append(affinity.NodeSelector.MatchExpressions, metav1.LabelSelectorRequirement{ + Key: kube.NodeOSLabel, + Values: []string{kube.NodeOSWindows}, + Operator: metav1.LabelSelectorOpNotIn, + }) } + podAffinity := kube.ToSystemAffinity(affinity, nil) + pod := &corev1api.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: hostingPodName, @@ -495,6 +509,7 @@ func (e *podVolumeExposer) createHostingPod( Spec: corev1api.PodSpec{ NodeSelector: nodeSelector, OS: &podOS, + Affinity: podAffinity, Containers: []corev1api.Container{ { Name: containerName, diff --git a/pkg/install/daemonset.go b/pkg/install/daemonset.go index ee63f3736..771114e82 100644 --- a/pkg/install/daemonset.go +++ b/pkg/install/daemonset.go @@ -235,12 +235,28 @@ func DaemonSet(namespace string, opts ...podTemplateOption) *appsv1api.DaemonSet if c.forWindows { daemonSet.Spec.Template.Spec.SecurityContext = nil daemonSet.Spec.Template.Spec.Containers[0].SecurityContext = nil - daemonSet.Spec.Template.Spec.NodeSelector = map[string]string{ - "kubernetes.io/os": "windows", - } daemonSet.Spec.Template.Spec.OS = &corev1api.PodOS{ Name: "windows", } + + daemonSet.Spec.Template.Spec.Affinity = &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Values: []string{"windows"}, + Operator: corev1api.NodeSelectorOpIn, + }, + }, + }, + }, + }, + }, + } + daemonSet.Spec.Template.Spec.Tolerations = []corev1api.Toleration{ { Key: "os", @@ -256,11 +272,22 @@ func DaemonSet(namespace string, opts ...podTemplateOption) *appsv1api.DaemonSet }, } } else { - daemonSet.Spec.Template.Spec.NodeSelector = map[string]string{ - "kubernetes.io/os": "linux", - } - daemonSet.Spec.Template.Spec.OS = &corev1api.PodOS{ - Name: "linux", + daemonSet.Spec.Template.Spec.Affinity = &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Values: []string{"windows"}, + Operator: corev1api.NodeSelectorOpNotIn, + }, + }, + }, + }, + }, + }, } } diff --git a/pkg/install/daemonset_test.go b/pkg/install/daemonset_test.go index 139d3dcd0..0f4de11bd 100644 --- a/pkg/install/daemonset_test.go +++ b/pkg/install/daemonset_test.go @@ -34,8 +34,23 @@ func TestDaemonSet(t *testing.T) { assert.Equal(t, "velero", ds.ObjectMeta.Namespace) assert.Equal(t, "node-agent", ds.Spec.Template.ObjectMeta.Labels["name"]) assert.Equal(t, "node-agent", ds.Spec.Template.ObjectMeta.Labels["role"]) - assert.Equal(t, "linux", ds.Spec.Template.Spec.NodeSelector["kubernetes.io/os"]) - assert.Equal(t, "linux", string(ds.Spec.Template.Spec.OS.Name)) + assert.Equal(t, &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Values: []string{"windows"}, + Operator: corev1api.NodeSelectorOpNotIn, + }, + }, + }, + }, + }, + }, + }, ds.Spec.Template.Spec.Affinity) assert.Equal(t, corev1api.PodSecurityContext{RunAsUser: &userID}, *ds.Spec.Template.Spec.SecurityContext) assert.Equal(t, corev1api.SecurityContext{Privileged: &boolFalse}, *ds.Spec.Template.Spec.Containers[0].SecurityContext) assert.Len(t, ds.Spec.Template.Spec.Volumes, 3) @@ -80,8 +95,24 @@ func TestDaemonSet(t *testing.T) { assert.Equal(t, "velero", ds.ObjectMeta.Namespace) assert.Equal(t, "node-agent-windows", ds.Spec.Template.ObjectMeta.Labels["name"]) assert.Equal(t, "node-agent", ds.Spec.Template.ObjectMeta.Labels["role"]) - assert.Equal(t, "windows", ds.Spec.Template.Spec.NodeSelector["kubernetes.io/os"]) assert.Equal(t, "windows", string(ds.Spec.Template.Spec.OS.Name)) + assert.Equal(t, &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Values: []string{"windows"}, + Operator: corev1api.NodeSelectorOpIn, + }, + }, + }, + }, + }, + }, + }, ds.Spec.Template.Spec.Affinity) assert.Equal(t, (*corev1api.PodSecurityContext)(nil), ds.Spec.Template.Spec.SecurityContext) assert.Equal(t, (*corev1api.SecurityContext)(nil), ds.Spec.Template.Spec.Containers[0].SecurityContext) } diff --git a/pkg/install/deployment.go b/pkg/install/deployment.go index d1010d294..04ea40e04 100644 --- a/pkg/install/deployment.go +++ b/pkg/install/deployment.go @@ -364,12 +364,26 @@ func Deployment(namespace string, opts ...podTemplateOption) *appsv1api.Deployme Spec: corev1api.PodSpec{ RestartPolicy: corev1api.RestartPolicyAlways, ServiceAccountName: c.serviceAccountName, - NodeSelector: map[string]string{ - "kubernetes.io/os": "linux", - }, OS: &corev1api.PodOS{ Name: "linux", }, + Affinity: &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Values: []string{"windows"}, + Operator: corev1api.NodeSelectorOpNotIn, + }, + }, + }, + }, + }, + }, + }, Containers: []corev1api.Container{ { Name: "velero", diff --git a/pkg/install/deployment_test.go b/pkg/install/deployment_test.go index b8aeaa9dd..53b696f72 100644 --- a/pkg/install/deployment_test.go +++ b/pkg/install/deployment_test.go @@ -100,8 +100,23 @@ func TestDeployment(t *testing.T) { assert.Len(t, deploy.Spec.Template.Spec.Containers[0].Args, 2) assert.Equal(t, "--repo-maintenance-job-configmap=test-repo-maintenance-config", deploy.Spec.Template.Spec.Containers[0].Args[1]) - assert.Equal(t, "linux", deploy.Spec.Template.Spec.NodeSelector["kubernetes.io/os"]) - assert.Equal(t, "linux", string(deploy.Spec.Template.Spec.OS.Name)) + assert.Equal(t, &corev1api.Affinity{ + NodeAffinity: &corev1api.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1api.NodeSelector{ + NodeSelectorTerms: []corev1api.NodeSelectorTerm{ + { + MatchExpressions: []corev1api.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Values: []string{"windows"}, + Operator: corev1api.NodeSelectorOpNotIn, + }, + }, + }, + }, + }, + }, + }, deploy.Spec.Template.Spec.Affinity) } func TestDeploymentWithPriorityClassName(t *testing.T) { diff --git a/pkg/util/kube/node.go b/pkg/util/kube/node.go index da68183a5..ba6853624 100644 --- a/pkg/util/kube/node.go +++ b/pkg/util/kube/node.go @@ -17,7 +17,6 @@ package kube import ( "context" - "fmt" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -34,6 +33,11 @@ const ( NodeOSLabel = "kubernetes.io/os" ) +var realNodeOSMap = map[string]string{ + "linux": NodeOSLinux, + "windows": NodeOSWindows, +} + func IsLinuxNode(ctx context.Context, nodeName string, client client.Client) error { node := &corev1api.Node{} if err := client.Get(ctx, types.NamespacedName{Name: nodeName}, node); err != nil { @@ -41,12 +45,11 @@ func IsLinuxNode(ctx context.Context, nodeName string, client client.Client) err } os, found := node.Labels[NodeOSLabel] - if !found { return errors.Errorf("no os type label for node %s", nodeName) } - if os != NodeOSLinux { + if getRealOS(os) != NodeOSLinux { return errors.Errorf("os type %s for node %s is not linux", os, nodeName) } @@ -72,7 +75,7 @@ func withOSNode(ctx context.Context, client client.Client, osType string, log lo for _, node := range nodeList.Items { os, found := node.Labels[NodeOSLabel] - if os == osType { + if getRealOS(os) == osType { return true } @@ -98,7 +101,7 @@ func GetNodeOS(ctx context.Context, nodeName string, nodeClient corev1client.Cor return "", nil } - return node.Labels[NodeOSLabel], nil + return getRealOS(node.Labels[NodeOSLabel]), nil } func HasNodeWithOS(ctx context.Context, os string, nodeClient corev1client.CoreV1Interface) error { @@ -106,14 +109,29 @@ func HasNodeWithOS(ctx context.Context, os string, nodeClient corev1client.CoreV return errors.New("invalid node OS") } - nodes, err := nodeClient.Nodes().List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", NodeOSLabel, os)}) + nodes, err := nodeClient.Nodes().List(ctx, metav1.ListOptions{}) if err != nil { return errors.Wrapf(err, "error listing nodes with OS %s", os) } - if len(nodes.Items) == 0 { - return errors.Errorf("node with OS %s doesn't exist", os) + for _, node := range nodes.Items { + osLabel, found := node.Labels[NodeOSLabel] + if !found { + continue + } + + if getRealOS(osLabel) == os { + return nil + } } - return nil + return errors.Errorf("node with OS %s doesn't exist", os) +} + +func getRealOS(osLabel string) string { + if os, found := realNodeOSMap[osLabel]; !found { + return NodeOSLinux + } else { + return os + } } diff --git a/site/content/docs/main/upgrade-to-1.17.md b/site/content/docs/main/upgrade-to-1.18.md similarity index 70% rename from site/content/docs/main/upgrade-to-1.17.md rename to site/content/docs/main/upgrade-to-1.18.md index f6738d55c..0bf839fe3 100644 --- a/site/content/docs/main/upgrade-to-1.17.md +++ b/site/content/docs/main/upgrade-to-1.18.md @@ -1,13 +1,13 @@ --- -title: "Upgrading to Velero 1.17" +title: "Upgrading to Velero 1.18" layout: docs --- ## Prerequisites -- Velero [v1.16.x][9] installed. +- Velero [v1.17.x][9] installed. -If you're not yet running at least Velero v1.16, see the following: +If you're not yet running at least Velero v1.17, see the following: - [Upgrading to v1.8][1] - [Upgrading to v1.9][2] @@ -18,13 +18,14 @@ If you're not yet running at least Velero v1.16, see the following: - [Upgrading to v1.14][7] - [Upgrading to v1.15][8] - [Upgrading to v1.16][9] +- [Upgrading to v1.17][10] Before upgrading, check the [Velero compatibility matrix](https://github.com/vmware-tanzu/velero#velero-compatibility-matrix) to make sure your version of Kubernetes is supported by the new version of Velero. ## Instructions -### Upgrade from v1.16 -1. Install the Velero v1.17 command-line interface (CLI) by following the [instructions here][0]. +### Upgrade from v1.17 +1. Install the Velero v1.18 command-line interface (CLI) by following the [instructions here][0]. Verify that you've properly installed it by running: @@ -36,7 +37,7 @@ Before upgrading, check the [Velero compatibility matrix](https://github.com/vmw ```bash Client: - Version: v1.17.0 + Version: v1.18.0 Git commit: ``` @@ -46,28 +47,21 @@ Before upgrading, check the [Velero compatibility matrix](https://github.com/vmw velero install --crds-only --dry-run -o yaml | kubectl apply -f - ``` -3. (optional) Update the `uploader-type` to `kopia` if you are using `restic`: - ```bash - kubectl get deploy -n velero -ojson \ - | sed "s/\"--uploader-type=restic\"/\"--uploader-type=kopia\"/g" \ - | kubectl apply -f - - ``` - -4. Update the container image used by the Velero deployment, plugin and (optionally) the node agent daemon set: +3. Update the container image used by the Velero deployment, plugin and (optionally) the node agent daemon set: ```bash # set the container and image of the init container for plugin accordingly, # if you are using other plugin kubectl set image deployment/velero \ - velero=velero/velero:v1.17.0 \ - velero-plugin-for-aws=velero/velero-plugin-for-aws:v1.13.0 \ + velero=velero/velero:v1.18.0 \ + velero-plugin-for-aws=velero/velero-plugin-for-aws:v1.14.0 \ --namespace velero # optional, if using the node agent daemonset kubectl set image daemonset/node-agent \ - node-agent=velero/velero:v1.17.0 \ + node-agent=velero/velero:v1.18.0 \ --namespace velero ``` -5. Confirm that the deployment is up and running with the correct version by running: +4. Confirm that the deployment is up and running with the correct version by running: ```bash velero version @@ -77,11 +71,11 @@ Before upgrading, check the [Velero compatibility matrix](https://github.com/vmw ```bash Client: - Version: v1.17.0 + Version: v1.18.0 Git commit: Server: - Version: v1.17.0 + Version: v1.18.0 ``` [0]: basic-install.md#install-the-cli @@ -93,4 +87,5 @@ Before upgrading, check the [Velero compatibility matrix](https://github.com/vmw [6]: https://velero.io/docs/v1.13/upgrade-to-1.13 [7]: https://velero.io/docs/v1.14/upgrade-to-1.14 [8]: https://velero.io/docs/v1.15/upgrade-to-1.15 -[9]: https://velero.io/docs/v1.16/upgrade-to-1.16 \ No newline at end of file +[9]: https://velero.io/docs/v1.16/upgrade-to-1.16 +[10]: https://velero.io/docs/v1.17/upgrade-to-1.17 \ No newline at end of file diff --git a/site/data/docs/main-toc.yml b/site/data/docs/main-toc.yml index dacec0651..271705a1b 100644 --- a/site/data/docs/main-toc.yml +++ b/site/data/docs/main-toc.yml @@ -13,8 +13,8 @@ toc: url: /basic-install - page: Customize Installation url: /customize-installation - - page: Upgrade to 1.17 - url: /upgrade-to-1.17 + - page: Upgrade to 1.18 + url: /upgrade-to-1.18 - page: Supported providers url: /supported-providers - page: Evaluation install diff --git a/site/data/docs/v1-18-toc.yml b/site/data/docs/v1-18-toc.yml index dacec0651..271705a1b 100644 --- a/site/data/docs/v1-18-toc.yml +++ b/site/data/docs/v1-18-toc.yml @@ -13,8 +13,8 @@ toc: url: /basic-install - page: Customize Installation url: /customize-installation - - page: Upgrade to 1.17 - url: /upgrade-to-1.17 + - page: Upgrade to 1.18 + url: /upgrade-to-1.18 - page: Supported providers url: /supported-providers - page: Evaluation install