Skip to content

Commit fc4f55e

Browse files
authored
Merge pull request #1358 from tahsinrahman/track-old-ms
🐛 track MS with old labels after updating MD labels
2 parents 1202244 + bfd65df commit fc4f55e

File tree

3 files changed

+135
-18
lines changed

3 files changed

+135
-18
lines changed

controllers/machinedeployment_controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ func (r *MachineDeploymentReconciler) getMachineSetsForDeployment(d *clusterv1.M
205205
continue
206206
}
207207

208-
if !selector.Matches(labels.Set(ms.Labels)) {
208+
// Skip this MachineSet unless either selector matches or it has a controller ref pointing to this MachineDeployment
209+
if !selector.Matches(labels.Set(ms.Labels)) && !metav1.IsControlledBy(ms, d) {
209210
klog.V(4).Infof("Skipping MachineSet %v, label mismatch", ms.Name)
210211
continue
211212
}

controllers/machinedeployment_controller_test.go

Lines changed: 119 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,67 @@ var _ = Describe("MachineDeployment Reconciler", func() {
235235
return len(machineSets.Items)
236236
}, timeout*3).Should(BeEquivalentTo(1))
237237

238+
//
239+
// Update a MachineDeployment spec.Selector.Matchlabels spec.Template.Labels
240+
// expect Reconcile to be called and a new MachineSet to appear
241+
// expect old MachineSets with old labels to be deleted
242+
//
243+
oldLabels := deployment.Spec.Selector.MatchLabels
244+
newLabels := map[string]string{
245+
"new-key": "new-value",
246+
}
247+
248+
By("Updating MachineDeployment label")
249+
err = updateMachineDeployment(k8sClient, deployment, func(d *clusterv1.MachineDeployment) {
250+
d.Spec.Selector.MatchLabels = newLabels
251+
d.Spec.Template.Labels = newLabels
252+
})
253+
Expect(err).ToNot(HaveOccurred())
254+
255+
By("Verifying if a new MachineSet with updated labels are created")
256+
Eventually(func() int {
257+
listOpts := client.MatchingLabels(newLabels)
258+
if err := k8sClient.List(ctx, machineSets, listOpts); err != nil {
259+
return -1
260+
}
261+
return len(machineSets.Items)
262+
}, timeout).Should(BeEquivalentTo(1))
263+
newms := machineSets.Items[0]
264+
265+
By("Verifying new MachineSet has desired number of replicas")
266+
Eventually(func() bool {
267+
// Set the all non-deleted machines as ready with a NodeRef, so the MachineSet controller can proceed
268+
// to properly set AvailableReplicas.
269+
machines := &clusterv1.MachineList{}
270+
Expect(k8sClient.List(ctx, machines, client.InNamespace(namespace.Name))).NotTo(HaveOccurred())
271+
for _, m := range machines.Items {
272+
if !m.DeletionTimestamp.IsZero() {
273+
continue
274+
}
275+
// Skip over Machines controlled by other (previous) MachineSets
276+
if !metav1.IsControlledBy(&m, &newms) {
277+
continue
278+
}
279+
fakeInfrastructureRefReady(m.Spec.InfrastructureRef, infraResource)
280+
fakeMachineNodeRef(&m)
281+
}
282+
283+
listOpts := client.MatchingLabels(newLabels)
284+
if err := k8sClient.List(ctx, machineSets, listOpts); err != nil {
285+
return false
286+
}
287+
return machineSets.Items[0].Status.Replicas == *deployment.Spec.Replicas
288+
}, timeout*5).Should(BeTrue())
289+
290+
By("Verifying MachineSets with old labels are deleted")
291+
Eventually(func() int {
292+
listOpts := client.MatchingLabels(oldLabels)
293+
if err := k8sClient.List(ctx, machineSets, listOpts); err != nil {
294+
return -1
295+
}
296+
297+
return len(machineSets.Items)
298+
}, timeout*5).Should(BeEquivalentTo(0))
238299
})
239300
})
240301

@@ -454,6 +515,20 @@ func TestGetMachineSetsForDeployment(t *testing.T) {
454515
},
455516
},
456517
}
518+
machineDeployment3 := clusterv1.MachineDeployment{
519+
ObjectMeta: metav1.ObjectMeta{
520+
Name: "withMatchingOwnerRefAndNoMatchingLabels",
521+
Namespace: "test",
522+
UID: "UID3",
523+
},
524+
Spec: clusterv1.MachineDeploymentSpec{
525+
Selector: metav1.LabelSelector{
526+
MatchLabels: map[string]string{
527+
"foo": "bar",
528+
},
529+
},
530+
},
531+
}
457532

458533
ms1 := clusterv1.MachineSet{
459534
TypeMeta: metav1.TypeMeta{
@@ -506,6 +581,21 @@ func TestGetMachineSetsForDeployment(t *testing.T) {
506581
},
507582
},
508583
}
584+
ms5 := clusterv1.MachineSet{
585+
TypeMeta: metav1.TypeMeta{
586+
Kind: "MachineSet",
587+
},
588+
ObjectMeta: metav1.ObjectMeta{
589+
Name: "withOwnerRefAndNoMatchLabels",
590+
Namespace: "test",
591+
OwnerReferences: []metav1.OwnerReference{
592+
*metav1.NewControllerRef(&machineDeployment3, machineDeploymentKind),
593+
},
594+
Labels: map[string]string{
595+
"foo": "nomatch",
596+
},
597+
},
598+
}
509599
machineSetList := &clusterv1.MachineSetList{
510600
TypeMeta: metav1.TypeMeta{
511601
Kind: "MachineSetList",
@@ -515,43 +605,55 @@ func TestGetMachineSetsForDeployment(t *testing.T) {
515605
ms2,
516606
ms3,
517607
ms4,
608+
ms5,
518609
},
519610
}
520611

521612
testCases := []struct {
613+
name string
522614
machineDeployment clusterv1.MachineDeployment
523615
expected []*clusterv1.MachineSet
524616
}{
525617
{
618+
name: "matching ownerRef and labels",
526619
machineDeployment: machineDeployment1,
527620
expected: []*clusterv1.MachineSet{&ms2, &ms3},
528621
},
529622
{
623+
name: "no matching ownerRef, matching labels",
530624
machineDeployment: machineDeployment2,
531625
expected: []*clusterv1.MachineSet{&ms1},
532626
},
627+
{
628+
name: "matching ownerRef, mismatch labels",
629+
machineDeployment: machineDeployment3,
630+
expected: []*clusterv1.MachineSet{&ms3, &ms5},
631+
},
533632
}
534633

535-
clusterv1.AddToScheme(scheme.Scheme)
536-
r := &MachineDeploymentReconciler{
537-
Client: fake.NewFakeClient(machineSetList),
538-
Log: log.Log,
539-
recorder: record.NewFakeRecorder(32),
540-
}
541634
for _, tc := range testCases {
542-
got, err := r.getMachineSetsForDeployment(&tc.machineDeployment)
543-
if err != nil {
544-
t.Errorf("Failed running getMachineSetsForDeployment: %v", err)
545-
}
635+
t.Run(tc.name, func(t *testing.T) {
636+
clusterv1.AddToScheme(scheme.Scheme)
637+
r := &MachineDeploymentReconciler{
638+
Client: fake.NewFakeClient(machineSetList),
639+
Log: log.Log,
640+
recorder: record.NewFakeRecorder(32),
641+
}
546642

547-
if len(tc.expected) != len(got) {
548-
t.Errorf("Case %s. Expected to get %d MachineSets but got %d", tc.machineDeployment.Name, len(tc.expected), len(got))
549-
}
643+
got, err := r.getMachineSetsForDeployment(&tc.machineDeployment)
644+
if err != nil {
645+
t.Errorf("Failed running getMachineSetsForDeployment: %v", err)
646+
}
550647

551-
for idx, res := range got {
552-
if res.Name != tc.expected[idx].Name || res.Namespace != tc.expected[idx].Namespace {
553-
t.Errorf("Case %s. Expected %q found %q", tc.machineDeployment.Name, res.Name, tc.expected[idx].Name)
648+
if len(tc.expected) != len(got) {
649+
t.Errorf("Case %s. Expected to get %d MachineSets but got %d", tc.machineDeployment.Name, len(tc.expected), len(got))
554650
}
555-
}
651+
652+
for idx, res := range got {
653+
if res.Name != tc.expected[idx].Name || res.Namespace != tc.expected[idx].Namespace {
654+
t.Errorf("Case %s. Expected %q found %q", tc.machineDeployment.Name, res.Name, tc.expected[idx].Name)
655+
}
656+
}
657+
})
556658
}
557659
}

controllers/mdutil/util_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,13 @@ func TestFindOldMachineSets(t *testing.T) {
264264
oldMS.Status.FullyLabeledReplicas = *(oldMS.Spec.Replicas)
265265
oldMS.CreationTimestamp = before
266266

267+
oldDeployment = generateDeployment("nginx")
268+
oldDeployment.Spec.Selector.MatchLabels["old-label"] = "old-value"
269+
oldDeployment.Spec.Template.Labels["old-label"] = "old-value"
270+
oldMSwithOldLabel := generateMS(oldDeployment)
271+
oldMSwithOldLabel.Status.FullyLabeledReplicas = *(oldMSwithOldLabel.Spec.Replicas)
272+
oldMSwithOldLabel.CreationTimestamp = before
273+
267274
tests := []struct {
268275
Name string
269276
deployment clusterv1.MachineDeployment
@@ -300,6 +307,13 @@ func TestFindOldMachineSets(t *testing.T) {
300307
expected: []*clusterv1.MachineSet{},
301308
expectedRequire: nil,
302309
},
310+
{
311+
Name: "Get old MachineSets after label changed in MachineDeployments",
312+
deployment: deployment,
313+
msList: []*clusterv1.MachineSet{&newMS, &oldMSwithOldLabel},
314+
expected: []*clusterv1.MachineSet{&oldMSwithOldLabel},
315+
expectedRequire: nil,
316+
},
303317
}
304318

305319
for _, test := range tests {

0 commit comments

Comments
 (0)