Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion internal/controllers/compute/machine_scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,17 @@ func (s *MachineScheduler) matchesLabels(_ context.Context, pool *scheduler.Cont
return machinePoolSelector.Matches(nodeLabels)
}

func (s *MachineScheduler) poolReady(_ context.Context, pool *scheduler.ContainerInfo) bool {
cond := computev1alpha1.FindMachinePoolCondition(pool.Node().Status.Conditions, computev1alpha1.MachinePoolReady)

return cond != nil && cond.Status == corev1.ConditionTrue
}

func (s *MachineScheduler) tolerateTaints(_ context.Context, pool *scheduler.ContainerInfo, machine *computev1alpha1.Machine) bool {
return v1alpha1.TolerateTaints(machine.Spec.Tolerations, pool.Node().Spec.Taints)
}

func (s *MachineScheduler) fitsPool(_ context.Context, pool *scheduler.ContainerInfo, machine *computev1alpha1.Machine) bool {

return pool.MaxAllocatable(machine.Spec.MachineClassRef.Name) > 0
}

Expand All @@ -102,6 +107,10 @@ func (s *MachineScheduler) reconcileExists(ctx context.Context, log logr.Logger,

var filteredNodes []*scheduler.ContainerInfo
for _, node := range nodes {
if !s.poolReady(ctx, node) {
log.Info("node filtered", "reason", "pool not ready")
continue
}
if !s.tolerateTaints(ctx, node, machine) {
log.Info("node filtered", "reason", "taints do not match")
continue
Expand Down
71 changes: 71 additions & 0 deletions internal/controllers/compute/machine_scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ import (
corev1alpha1 "github.com/ironcore-dev/ironcore/api/core/v1alpha1"
)

func markMachinePoolReady(machinePool *computev1alpha1.MachinePool) {
machinePool.Status.Conditions = computev1alpha1.SetMachinePoolCondition(machinePool.Status.Conditions,
computev1alpha1.MachinePoolCondition{
Type: computev1alpha1.MachinePoolReady,
Status: corev1.ConditionTrue,
})
}

var _ = Describe("MachineScheduler", func() {
ns := SetupNamespace(&k8sClient)
machineClass := SetupMachineClass()
Expand All @@ -40,6 +48,7 @@ var _ = Describe("MachineScheduler", func() {
machinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("10"),
}
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("creating a machine w/ the requested machine class")
Expand Down Expand Up @@ -94,6 +103,7 @@ var _ = Describe("MachineScheduler", func() {
machinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("10"),
}
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("waiting for the machine to be scheduled onto the machine pool")
Expand All @@ -118,6 +128,7 @@ var _ = Describe("MachineScheduler", func() {
machinePoolNoMatchingLabels.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("10"),
}
markMachinePoolReady(machinePoolNoMatchingLabels)
})).Should(Succeed())

By("creating a machine pool w/ matching labels")
Expand All @@ -137,6 +148,7 @@ var _ = Describe("MachineScheduler", func() {
machinePoolMatchingLabels.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("10"),
}
markMachinePoolReady(machinePoolMatchingLabels)
})).Should(Succeed())

By("creating a machine w/ the requested machine class")
Expand Down Expand Up @@ -191,6 +203,7 @@ var _ = Describe("MachineScheduler", func() {
taintedMachinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("10"),
}
markMachinePoolReady(taintedMachinePool)
})).Should(Succeed())

By("creating a machine")
Expand Down Expand Up @@ -236,6 +249,11 @@ var _ = Describe("MachineScheduler", func() {
})
Expect(k8sClient.Patch(ctx, machine, client.MergeFrom(machineBase))).To(Succeed(), "failed to patch the machine's spec")

By("re-asserting the machine pool is ready")
Eventually(UpdateStatus(taintedMachinePool, func() {
markMachinePoolReady(taintedMachinePool)
})).Should(Succeed())

By("observing the machine is scheduled onto the machine pool")
Eventually(Object(machine)).Should(SatisfyAll(
HaveField("Spec.MachinePoolRef", Equal(&corev1.LocalObjectReference{Name: taintedMachinePool.Name})),
Expand All @@ -257,6 +275,7 @@ var _ = Describe("MachineScheduler", func() {
machinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("10"),
}
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("creating a second machine pool")
Expand Down Expand Up @@ -289,6 +308,7 @@ var _ = Describe("MachineScheduler", func() {
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("5"),
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, secondMachineClass.Name): resource.MustParse("100"),
}
markMachinePoolReady(secondMachinePool)
})).Should(Succeed())

By("creating a machine")
Expand Down Expand Up @@ -326,6 +346,7 @@ var _ = Describe("MachineScheduler", func() {
machinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("50"),
}
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("creating a second machine pool")
Expand All @@ -344,6 +365,7 @@ var _ = Describe("MachineScheduler", func() {
secondMachinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("50"),
}
markMachinePoolReady(secondMachinePool)
})).Should(Succeed())

By("creating machines")
Expand Down Expand Up @@ -394,6 +416,7 @@ var _ = Describe("MachineScheduler", func() {
By("patching the machine pool status to contain a machine class")
Eventually(UpdateStatus(machinePool, func() {
machinePool.Status.AvailableMachineClasses = []corev1.LocalObjectReference{{Name: machineClass.Name}}
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("creating a machine")
Expand All @@ -420,6 +443,7 @@ var _ = Describe("MachineScheduler", func() {
machinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("10"),
}
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("checking that the machine is scheduled onto the machine pool")
Expand All @@ -443,6 +467,7 @@ var _ = Describe("MachineScheduler", func() {
machinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("2"),
}
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("creating the first machine")
Expand Down Expand Up @@ -512,6 +537,7 @@ var _ = Describe("MachineScheduler", func() {
machinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("5"),
}
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("creating a second machine pool")
Expand Down Expand Up @@ -545,6 +571,7 @@ var _ = Describe("MachineScheduler", func() {
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("5"),
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, secondMachineClass.Name): resource.MustParse("5"),
}
markMachinePoolReady(secondMachinePool)
})).Should(Succeed())

By("creating a machine")
Expand All @@ -566,4 +593,48 @@ var _ = Describe("MachineScheduler", func() {
HaveField("Spec.MachinePoolRef.Name", Equal(secondMachinePool.Name)),
))
})

It("should not schedule machines onto a machine pool that is not ready", func(ctx SpecContext) {
Comment thread
gonzolino marked this conversation as resolved.
Outdated
By("creating a machine pool")
machinePool := &computev1alpha1.MachinePool{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "test-pool-",
},
}
Expect(k8sClient.Create(ctx, machinePool)).To(Succeed(), "failed to create machine pool")

By("patching the machine pool status to have capacity but no ready condition")
Eventually(UpdateStatus(machinePool, func() {
machinePool.Status.AvailableMachineClasses = []corev1.LocalObjectReference{{Name: machineClass.Name}}
machinePool.Status.Allocatable = corev1alpha1.ResourceList{
corev1alpha1.ClassCountFor(corev1alpha1.ClassTypeMachineClass, machineClass.Name): resource.MustParse("10"),
}
})).Should(Succeed())

By("creating a machine w/ the requested machine class")
machine := &computev1alpha1.Machine{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
GenerateName: "test-machine-",
},
Spec: computev1alpha1.MachineSpec{
MachineClassRef: corev1.LocalObjectReference{Name: machineClass.Name},
},
}
Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "failed to create machine")

By("observing the machine isn't scheduled onto the not-ready machine pool")
Consistently(Object(machine)).Should(HaveField("Spec.MachinePoolRef", BeNil()))

By("marking the machine pool ready")
Eventually(UpdateStatus(machinePool, func() {
markMachinePoolReady(machinePool)
})).Should(Succeed())

By("waiting for the machine to be scheduled once the pool is ready")
Eventually(Object(machine)).Should(SatisfyAll(
HaveField("Spec.MachinePoolRef", Equal(&corev1.LocalObjectReference{Name: machinePool.Name})),
HaveField("Status.State", Equal(computev1alpha1.MachineStatePending)),
))
})
})