Skip to content

Commit 951fd2e

Browse files
committed
Don't ignore earlier completed deployments
This sometimes breaks update workflow as we set the containerImages from the completed deployments and if the nodeset misses a reconciliation after `ovn-update` deployment, containerImage for ovn-controller won't be changed as it would pick only the last `update` deployment, which does not have the changed ovn-controller image and it would not match with the openstackversion images. Signed-off-by: rabi <[email protected]>
1 parent b608ce3 commit 951fd2e

File tree

2 files changed

+51
-47
lines changed

2 files changed

+51
-47
lines changed

controllers/dataplane/openstackdataplanenodeset_controller.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,9 @@ func (r *OpenStackDataPlaneNodeSetReconciler) Reconcile(ctx context.Context, req
476476
}
477477

478478
func checkDeployment(ctx context.Context, helper *helper.Helper,
479-
instance *dataplanev1.OpenStackDataPlaneNodeSet) (isDeploymentReady bool, isDeploymentRunning bool, isDeploymentFailed bool, failedDeploymentName string, err error) {
479+
instance *dataplanev1.OpenStackDataPlaneNodeSet) (
480+
isNodeSetDeploymentReady bool, isNodeSetDeploymentRunning bool,
481+
isNodeSetDeploymentFailed bool, failedDeploymentName string, err error) {
480482

481483
// Get all completed deployments
482484
deployments := &dataplanev1.OpenStackDataPlaneDeploymentList{}
@@ -486,7 +488,7 @@ func checkDeployment(ctx context.Context, helper *helper.Helper,
486488
err = helper.GetClient().List(ctx, deployments, opts...)
487489
if err != nil {
488490
helper.GetLogger().Error(err, "Unable to retrieve OpenStackDataPlaneDeployment CRs %v")
489-
return isDeploymentReady, isDeploymentRunning, isDeploymentFailed, failedDeploymentName, err
491+
return isNodeSetDeploymentReady, isNodeSetDeploymentRunning, isNodeSetDeploymentFailed, failedDeploymentName, err
490492
}
491493

492494
// Collect deployments that target this nodeset (excluding deleted ones)
@@ -528,33 +530,41 @@ func checkDeployment(ctx context.Context, helper *helper.Helper,
528530
// Apply filtering for overall nodeset deployment state logic
529531
isLatestDeployment := latestRelevantDeployment != nil && deployment.Name == latestRelevantDeployment.Name
530532
deploymentCondition := deploymentConditions.Get(dataplanev1.NodeSetDeploymentReadyCondition)
531-
isRunningDeployment := deploymentConditions.IsFalse(dataplanev1.NodeSetDeploymentReadyCondition) && !condition.IsError(deploymentCondition)
532533

533-
// Skip processing for overall nodeset state if not running AND not latest
534-
// (This handles both completed and failed deployments that aren't the latest)
535-
if !isRunningDeployment && !isLatestDeployment {
534+
// Skip failed/error deployments that aren't the latest
535+
// All running and completed deployments are processed
536+
isCurrentDeploymentFailed := condition.IsError(deploymentCondition)
537+
if isCurrentDeploymentFailed && !isLatestDeployment {
536538
continue
537539
}
538540

541+
isCurrentDeploymentRunning := deploymentConditions.IsFalse(dataplanev1.NodeSetDeploymentReadyCondition) && !isCurrentDeploymentFailed
542+
isCurrentDeploymentReady := deploymentConditions.IsTrue(dataplanev1.NodeSetDeploymentReadyCondition)
543+
539544
// Reset the vars for every deployment that affects overall state
540-
isDeploymentReady = false
541-
isDeploymentRunning = false
542-
if condition.IsError(deploymentCondition) {
545+
isNodeSetDeploymentReady = false
546+
isNodeSetDeploymentRunning = false
547+
isNodeSetDeploymentFailed = false
548+
549+
if isCurrentDeploymentFailed {
543550
err = fmt.Errorf("%s", deploymentCondition.Message)
544-
isDeploymentFailed = true
545551
failedDeploymentName = deployment.Name
552+
isNodeSetDeploymentFailed = true
546553
break
547-
} else if deploymentConditions.IsFalse(dataplanev1.NodeSetDeploymentReadyCondition) {
548-
isDeploymentRunning = true
549-
} else if deploymentConditions.IsTrue(dataplanev1.NodeSetDeploymentReadyCondition) {
554+
}
555+
if isCurrentDeploymentRunning {
556+
isNodeSetDeploymentRunning = true
557+
}
558+
559+
if isCurrentDeploymentReady {
550560
// If the nodeset configHash does not match with what's in the deployment or
551561
// deployedBmhHash is different from current bmhRefHash.
552562
if (deployment.Status.NodeSetHashes[instance.Name] != instance.Status.ConfigHash) ||
553563
(!instance.Spec.PreProvisioned &&
554564
deployment.Status.BmhRefHashes[instance.Name] != instance.Status.BmhRefHash) {
555565
continue
556566
}
557-
isDeploymentReady = true
567+
isNodeSetDeploymentReady = true
558568
for k, v := range deployment.Status.ConfigMapHashes {
559569
instance.Status.ConfigMapHashes[k] = v
560570
}
@@ -587,7 +597,7 @@ func checkDeployment(ctx context.Context, helper *helper.Helper,
587597
err := helper.GetClient().Get(ctx, name, service)
588598
if err != nil {
589599
helper.GetLogger().Error(err, "Unable to retrieve OpenStackDataPlaneService %v")
590-
return isDeploymentReady, isDeploymentRunning, isDeploymentFailed, failedDeploymentName, err
600+
return isNodeSetDeploymentReady, isNodeSetDeploymentRunning, isNodeSetDeploymentFailed, failedDeploymentName, err
591601
}
592602

593603
if service.Spec.EDPMServiceType != "update" && service.Spec.EDPMServiceType != "update-services" {
@@ -602,7 +612,7 @@ func checkDeployment(ctx context.Context, helper *helper.Helper,
602612
}
603613
}
604614

605-
return isDeploymentReady, isDeploymentRunning, isDeploymentFailed, failedDeploymentName, err
615+
return isNodeSetDeploymentReady, isNodeSetDeploymentRunning, isNodeSetDeploymentFailed, failedDeploymentName, err
606616
}
607617

608618
// SetupWithManager sets up the controller with the Manager.

tests/functional/dataplane/openstackdataplanenodeset_controller_test.go

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,17 +1494,12 @@ var _ = Describe("Dataplane NodeSet Test", func() {
14941494

14951495
When("Testing deployment filtering logic", func() {
14961496
var secondDeploymentName types.NamespacedName
1497-
var thirdDeploymentName types.NamespacedName
14981497

14991498
BeforeEach(func() {
15001499
secondDeploymentName = types.NamespacedName{
15011500
Name: "edpm-deployment-2",
15021501
Namespace: namespace,
15031502
}
1504-
thirdDeploymentName = types.NamespacedName{
1505-
Name: "edpm-deployment-3",
1506-
Namespace: namespace,
1507-
}
15081503
})
15091504

15101505
When("Multiple deployments exist with ServicesOverride", func() {
@@ -1546,7 +1541,7 @@ var _ = Describe("Dataplane NodeSet Test", func() {
15461541
}, th.Timeout, th.Interval).Should(Succeed())
15471542

15481543
// Both deployments should be in status (for visibility)
1549-
// But only latest deployment affects overall nodeset state
1544+
// All completed deployments are processed, with latest deployment determining final state
15501545
Eventually(func(g Gomega) {
15511546
instance := GetDataplaneNodeSet(dataplaneNodeSetName)
15521547
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(dataplaneDeploymentName.Name))
@@ -1581,7 +1576,7 @@ var _ = Describe("Dataplane NodeSet Test", func() {
15811576
SimulateDNSDataComplete(dataplaneNodeSetName)
15821577
})
15831578

1584-
It("Should show all deployments in status but only latest affects overall state", func() {
1579+
It("Should show all deployments in status and process all completed deployments", func() {
15851580
// Complete the first deployment
15861581
Eventually(func(g Gomega) {
15871582
ansibleeeName := types.NamespacedName{
@@ -1594,7 +1589,7 @@ var _ = Describe("Dataplane NodeSet Test", func() {
15941589
}, th.Timeout, th.Interval).Should(Succeed())
15951590

15961591
// Both deployments should be included (for visibility)
1597-
// But only latest deployment affects overall nodeset state
1592+
// All completed deployments are processed, with latest determining final state
15981593
Eventually(func(g Gomega) {
15991594
instance := GetDataplaneNodeSet(dataplaneNodeSetName)
16001595
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(dataplaneDeploymentName.Name))
@@ -1642,10 +1637,10 @@ var _ = Describe("Dataplane NodeSet Test", func() {
16421637

16431638
// Leave second deployment running (don't complete it)
16441639
// Both deployments should be in status (for visibility)
1645-
// Second deployment affects overall state (running and latest)
1640+
// First deployment is processed (completed), second affects final state (running and latest)
16461641
Eventually(func(g Gomega) {
16471642
instance := GetDataplaneNodeSet(dataplaneNodeSetName)
1648-
// Should have first deployment (for visibility)
1643+
// Should have first deployment (completed, processed)
16491644
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(dataplaneDeploymentName.Name))
16501645
// Should have second deployment (running and latest)
16511646
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(secondDeploymentName.Name))
@@ -1702,10 +1697,10 @@ var _ = Describe("Dataplane NodeSet Test", func() {
17021697
}, th.Timeout, th.Interval).Should(Succeed())
17031698

17041699
// Both error deployments should be in status (for visibility)
1705-
// But only latest error affects overall nodeset state
1700+
// First failed deployment is skipped (not latest), second error affects final state (latest)
17061701
Eventually(func(g Gomega) {
17071702
instance := GetDataplaneNodeSet(dataplaneNodeSetName)
1708-
// Should have first deployment (for visibility)
1703+
// Should have first deployment (for visibility only)
17091704
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(dataplaneDeploymentName.Name))
17101705
// Should have second deployment (latest - affects overall state)
17111706
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(secondDeploymentName.Name))
@@ -1721,7 +1716,7 @@ var _ = Describe("Dataplane NodeSet Test", func() {
17211716
})
17221717
})
17231718

1724-
When("Mixed deployment states exist", func() {
1719+
When("Failed deployment followed by completed deployment", func() {
17251720
BeforeEach(func() {
17261721
nodeSetSpec := DefaultDataPlaneNodeSetSpec("edpm-compute")
17271722
nodeSetSpec["preProvisioned"] = true
@@ -1731,18 +1726,13 @@ var _ = Describe("Dataplane NodeSet Test", func() {
17311726
DeferCleanup(th.DeleteInstance, CreateDNSMasq(dnsMasqName, DefaultDNSMasqSpec()))
17321727
DeferCleanup(th.DeleteInstance, CreateDataplaneNodeSet(dataplaneNodeSetName, nodeSetSpec))
17331728

1734-
// Create first deployment (will have error - should be ignored)
1729+
// Create first deployment (will fail)
17351730
firstDeploymentSpec := DefaultDataPlaneDeploymentSpec()
17361731
DeferCleanup(th.DeleteInstance, CreateDataplaneDeployment(dataplaneDeploymentName, firstDeploymentSpec))
17371732

1738-
// Create second deployment with ServicesOverride (should be ignored)
1739-
overrideDeploymentSpec := DefaultDataPlaneDeploymentSpec()
1740-
overrideDeploymentSpec["servicesOverride"] = []string{"bootstrap"}
1741-
DeferCleanup(th.DeleteInstance, CreateDataplaneDeployment(secondDeploymentName, overrideDeploymentSpec))
1742-
1743-
// Create third deployment (will succeed - should be processed)
1744-
thirdDeploymentSpec := DefaultDataPlaneDeploymentSpec()
1745-
DeferCleanup(th.DeleteInstance, CreateDataplaneDeployment(thirdDeploymentName, thirdDeploymentSpec))
1733+
// Create second deployment (will complete successfully)
1734+
secondDeploymentSpec := DefaultDataPlaneDeploymentSpec()
1735+
DeferCleanup(th.DeleteInstance, CreateDataplaneDeployment(secondDeploymentName, secondDeploymentSpec))
17461736

17471737
CreateSSHSecret(dataplaneSSHSecretName)
17481738
CreateCABundleSecret(caBundleSecretName)
@@ -1751,7 +1741,7 @@ var _ = Describe("Dataplane NodeSet Test", func() {
17511741
SimulateDNSDataComplete(dataplaneNodeSetName)
17521742
})
17531743

1754-
It("Should show all deployments in status but only latest affects overall state", func() {
1744+
It("Should show all deployments in status and process completed deployment", func() {
17551745
// Fail the first deployment
17561746
Eventually(func(g Gomega) {
17571747
ansibleeeName := types.NamespacedName{
@@ -1763,27 +1753,31 @@ var _ = Describe("Dataplane NodeSet Test", func() {
17631753
g.Expect(th.K8sClient.Status().Update(th.Ctx, ansibleEE)).To(Succeed())
17641754
}, th.Timeout, th.Interval).Should(Succeed())
17651755

1766-
// Complete the third deployment
1756+
// Complete the second deployment
17671757
Eventually(func(g Gomega) {
17681758
ansibleeeName := types.NamespacedName{
1769-
Name: "bootstrap-" + thirdDeploymentName.Name + "-" + dataplaneNodeSetName.Name,
1759+
Name: "bootstrap-" + secondDeploymentName.Name + "-" + dataplaneNodeSetName.Name,
17701760
Namespace: namespace,
17711761
}
17721762
ansibleEE := GetAnsibleee(ansibleeeName)
17731763
ansibleEE.Status.Succeeded = 1
17741764
g.Expect(th.K8sClient.Status().Update(th.Ctx, ansibleEE)).To(Succeed())
17751765
}, th.Timeout, th.Interval).Should(Succeed())
17761766

1777-
// All deployments should be in status (for visibility)
1778-
// But only latest deployment affects overall nodeset state
1767+
// Wait for deployment controller to populate hashes
1768+
Eventually(func(g Gomega) {
1769+
deployment := GetDataplaneDeployment(secondDeploymentName)
1770+
g.Expect(deployment.Status.NodeSetHashes).Should(HaveKey(dataplaneNodeSetName.Name))
1771+
}, th.Timeout, th.Interval).Should(Succeed())
1772+
1773+
// Both deployments should be in status (for visibility)
1774+
// First failed deployment is skipped (not latest), second completed deployment is processed and determines final state
17791775
Eventually(func(g Gomega) {
17801776
instance := GetDataplaneNodeSet(dataplaneNodeSetName)
1781-
// Should have first deployment (for visibility)
1777+
// Should have first deployment (for visibility only)
17821778
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(dataplaneDeploymentName.Name))
1783-
// Should have second deployment (for visibility)
1779+
// Should have second deployment (completed and latest - affects overall state)
17841780
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(secondDeploymentName.Name))
1785-
// Should have third deployment (latest - affects overall state)
1786-
g.Expect(instance.Status.DeploymentStatuses).Should(HaveKey(thirdDeploymentName.Name))
17871781
}, th.Timeout, th.Interval).Should(Succeed())
17881782

17891783
// The overall deployment condition should be true from the successful deployment

0 commit comments

Comments
 (0)