Skip to content

Commit 2d87a5d

Browse files
authored
Merge pull request #494 from tiraboschi/KubeVirtRelieveAndMigrate_without_KubeVirt
Explicit error for DevKubeVirtRelieveAndMigrate without KubeVirt
2 parents aa5461c + 8c8ec42 commit 2d87a5d

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

pkg/operator/target_config_reconciler.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,13 @@ func (c *TargetConfigReconciler) manageConfigMap(descheduler *deschedulerv1.Kube
12981298
case deschedulerv1.CompactAndScale:
12991299
profile, err = compactAndScaleProfile(descheduler.Spec.ProfileCustomizations, includedNamespaces, excludedNamespaces, ignorePVCPods, evictLocalStoragePods)
13001300
case deschedulerv1.RelieveAndMigrate:
1301+
kvDeployed, kverr := c.isKubeVirtDeployed()
1302+
if kverr != nil {
1303+
return nil, false, kverr
1304+
}
1305+
if !kvDeployed {
1306+
return nil, true, fmt.Errorf("profile %v can only be used when KubeVirt is properly deployed", deschedulerv1.RelieveAndMigrate)
1307+
}
13011308
kubeVirtShedulable := kubeVirtShedulableLabelSelector
13021309
policy.NodeSelector = &kubeVirtShedulable
13031310
profile, err = relieveAndMigrateProfile(descheduler.Spec.ProfileCustomizations, includedNamespaces, excludedNamespaces, c.protectedNamespaces)
@@ -1572,6 +1579,21 @@ func (c *TargetConfigReconciler) checkNamepsaceMonitoringLabel() error {
15721579
return nil
15731580
}
15741581

1582+
func (c *TargetConfigReconciler) isKubeVirtDeployed() (bool, error) {
1583+
ls, err := labels.Parse(kubeVirtShedulableLabelSelector)
1584+
if err != nil {
1585+
return false, err
1586+
}
1587+
nodes, err := c.nodeLister.List(ls)
1588+
if err != nil {
1589+
return false, err
1590+
}
1591+
if len(nodes) > 0 {
1592+
return true, nil
1593+
}
1594+
return false, nil
1595+
}
1596+
15751597
func (c *TargetConfigReconciler) isSoftTainterNeeded(descheduler *deschedulerv1.KubeDescheduler) (bool, error) {
15761598
if descheduler.Spec.ProfileCustomizations != nil && descheduler.Spec.ProfileCustomizations.DevEnableSoftTainter {
15771599
return true, nil

pkg/operator/target_config_reconciler_test.go

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func TestManageConfigMap(t *testing.T) {
6868
want *corev1.ConfigMap
6969
descheduler *deschedulerv1.KubeDescheduler
7070
routes []runtime.Object
71+
nodes []runtime.Object
7172
err error
7273
forceDeployment bool
7374
}{
@@ -226,6 +227,20 @@ func TestManageConfigMap(t *testing.T) {
226227
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
227228
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/relieveAndMigrateLowConfig.yaml"))},
228229
},
230+
nodes: []runtime.Object{
231+
&corev1.Node{
232+
ObjectMeta: metav1.ObjectMeta{
233+
Name: "node1",
234+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
235+
},
236+
},
237+
&corev1.Node{
238+
ObjectMeta: metav1.ObjectMeta{
239+
Name: "node2",
240+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
241+
},
242+
},
243+
},
229244
},
230245
{
231246
name: "RelieveAndMigrateMedium",
@@ -239,6 +254,20 @@ func TestManageConfigMap(t *testing.T) {
239254
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
240255
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/relieveAndMigrateMediumConfig.yaml"))},
241256
},
257+
nodes: []runtime.Object{
258+
&corev1.Node{
259+
ObjectMeta: metav1.ObjectMeta{
260+
Name: "node1",
261+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
262+
},
263+
},
264+
&corev1.Node{
265+
ObjectMeta: metav1.ObjectMeta{
266+
Name: "node2",
267+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
268+
},
269+
},
270+
},
242271
},
243272
{
244273
name: "RelieveAndMigrateDeviationLowWithCombinedMetrics",
@@ -269,6 +298,20 @@ func TestManageConfigMap(t *testing.T) {
269298
},
270299
},
271300
},
301+
nodes: []runtime.Object{
302+
&corev1.Node{
303+
ObjectMeta: metav1.ObjectMeta{
304+
Name: "node1",
305+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
306+
},
307+
},
308+
&corev1.Node{
309+
ObjectMeta: metav1.ObjectMeta{
310+
Name: "node2",
311+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
312+
},
313+
},
314+
},
272315
},
273316
{
274317
name: "RelieveAndMigrateHigh",
@@ -282,6 +325,20 @@ func TestManageConfigMap(t *testing.T) {
282325
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
283326
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/relieveAndMigrateHighConfig.yaml"))},
284327
},
328+
nodes: []runtime.Object{
329+
&corev1.Node{
330+
ObjectMeta: metav1.ObjectMeta{
331+
Name: "node1",
332+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
333+
},
334+
},
335+
&corev1.Node{
336+
ObjectMeta: metav1.ObjectMeta{
337+
Name: "node2",
338+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
339+
},
340+
},
341+
},
285342
},
286343
{
287344
name: "RelieveAndMigrateIncludedNamespace",
@@ -299,6 +356,20 @@ func TestManageConfigMap(t *testing.T) {
299356
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
300357
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/relieveAndMigrateIncludedNamespace.yaml"))},
301358
},
359+
nodes: []runtime.Object{
360+
&corev1.Node{
361+
ObjectMeta: metav1.ObjectMeta{
362+
Name: "node1",
363+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
364+
},
365+
},
366+
&corev1.Node{
367+
ObjectMeta: metav1.ObjectMeta{
368+
Name: "node2",
369+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
370+
},
371+
},
372+
},
302373
},
303374
{
304375
name: "RelieveAndMigrateDynamicThresholdsLow",
@@ -314,6 +385,20 @@ func TestManageConfigMap(t *testing.T) {
314385
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
315386
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/relieveAndMigrateDynamicThresholdsLow.yaml"))},
316387
},
388+
nodes: []runtime.Object{
389+
&corev1.Node{
390+
ObjectMeta: metav1.ObjectMeta{
391+
Name: "node1",
392+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
393+
},
394+
},
395+
&corev1.Node{
396+
ObjectMeta: metav1.ObjectMeta{
397+
Name: "node2",
398+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
399+
},
400+
},
401+
},
317402
},
318403
{
319404
name: "RelieveAndMigrateDynamicThresholdsMedium",
@@ -329,6 +414,20 @@ func TestManageConfigMap(t *testing.T) {
329414
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
330415
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/relieveAndMigrateDynamicThresholdsMedium.yaml"))},
331416
},
417+
nodes: []runtime.Object{
418+
&corev1.Node{
419+
ObjectMeta: metav1.ObjectMeta{
420+
Name: "node1",
421+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
422+
},
423+
},
424+
&corev1.Node{
425+
ObjectMeta: metav1.ObjectMeta{
426+
Name: "node2",
427+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
428+
},
429+
},
430+
},
332431
},
333432
{
334433
name: "RelieveAndMigrateDynamicThresholdsHigh",
@@ -344,6 +443,20 @@ func TestManageConfigMap(t *testing.T) {
344443
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "ConfigMap"},
345444
Data: map[string]string{"policy.yaml": string(bindata.MustAsset("assets/relieveAndMigrateDynamicThresholdsHigh.yaml"))},
346445
},
446+
nodes: []runtime.Object{
447+
&corev1.Node{
448+
ObjectMeta: metav1.ObjectMeta{
449+
Name: "node1",
450+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
451+
},
452+
},
453+
&corev1.Node{
454+
ObjectMeta: metav1.ObjectMeta{
455+
Name: "node2",
456+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
457+
},
458+
},
459+
},
347460
},
348461
{
349462
name: "RelieveAndMigrateDynamicAndStaticThresholds",
@@ -356,8 +469,48 @@ func TestManageConfigMap(t *testing.T) {
356469
},
357470
},
358471
},
472+
nodes: []runtime.Object{
473+
&corev1.Node{
474+
ObjectMeta: metav1.ObjectMeta{
475+
Name: "node1",
476+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
477+
},
478+
},
479+
&corev1.Node{
480+
ObjectMeta: metav1.ObjectMeta{
481+
Name: "node2",
482+
Labels: map[string]string{"kubevirt.io/schedulable": "true"},
483+
},
484+
},
485+
},
359486
err: fmt.Errorf("only one of DevLowNodeUtilizationThresholds and DevDeviationThresholds customizations can be configured simultaneously"),
360487
},
488+
{
489+
name: "RelieveAndMigrateWithoutKubeVirt",
490+
descheduler: &deschedulerv1.KubeDescheduler{
491+
Spec: deschedulerv1.KubeDeschedulerSpec{
492+
Profiles: []deschedulerv1.DeschedulerProfile{"DevKubeVirtRelieveAndMigrate"},
493+
ProfileCustomizations: &deschedulerv1.ProfileCustomizations{
494+
DevDeviationThresholds: &deschedulerv1.LowDeviationThreshold,
495+
DevLowNodeUtilizationThresholds: &deschedulerv1.LowThreshold,
496+
},
497+
},
498+
},
499+
nodes: []runtime.Object{
500+
&corev1.Node{
501+
ObjectMeta: metav1.ObjectMeta{
502+
Name: "node1",
503+
},
504+
},
505+
&corev1.Node{
506+
ObjectMeta: metav1.ObjectMeta{
507+
Name: "node2",
508+
},
509+
},
510+
},
511+
err: fmt.Errorf("profile DevKubeVirtRelieveAndMigrate can only be used when KubeVirt is properly deployed"),
512+
forceDeployment: true,
513+
},
361514
{
362515
name: "AffinityAndTaintsWithNamespaces",
363516
descheduler: &deschedulerv1.KubeDescheduler{
@@ -659,6 +812,7 @@ func TestManageConfigMap(t *testing.T) {
659812
},
660813
},
661814
}
815+
objects = append(objects, tt.nodes...)
662816

663817
ctx, cancelFunc := context.WithCancel(context.TODO())
664818
defer cancelFunc()

0 commit comments

Comments
 (0)