mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-08-16 04:06:06 +00:00
Merge pull request #9606 from Lyndon-Li/release-1.18
Run the E2E test on kind / get-go-version (push) Failing after 1m19s
Run the E2E test on kind / build (push) Has been skipped
Run the E2E test on kind / setup-test-matrix (push) Successful in 2s
Run the E2E test on kind / run-e2e-test (push) Has been skipped
Main CI / get-go-version (push) Failing after 15s
Main CI / Build (push) Has been skipped
Run the E2E test on kind / get-go-version (push) Failing after 1m19s
Run the E2E test on kind / build (push) Has been skipped
Run the E2E test on kind / setup-test-matrix (push) Successful in 2s
Run the E2E test on kind / run-e2e-test (push) Has been skipped
Main CI / get-go-version (push) Failing after 15s
Main CI / Build (push) Has been skipped
[1.18] Issue 9496: support customized host os
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Fix issue #9496, support customized host os
|
||||
@@ -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{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+27
-9
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user