Skip to content

Commit 44434a6

Browse files
authored
Merge pull request #657 from gianlucam76/rollout
(feat) Rolling updates and paused cluster
2 parents a6f85d6 + a29b09a commit 44434a6

File tree

2 files changed

+88
-21
lines changed

2 files changed

+88
-21
lines changed

controllers/profile_utils.go

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,22 @@ func updateClusterSummaries(ctx context.Context, c client.Client, profileScope *
564564
continue
565565
}
566566

567+
if maxUpdate != 0 {
568+
// maxUpdate is set. Skip paused clusters (which would not be updated anyhow as set to paused)
569+
// and try to pcik any non paused cluster
570+
isClusterPaused, err := clusterproxy.IsClusterPaused(ctx, c, cluster.Namespace,
571+
cluster.Name, clusterproxy.GetClusterType(&cluster))
572+
if err != nil {
573+
logger.V(logs.LogDebug).Info(fmt.Sprintf("failed to verify if cluster is paused: %v", err))
574+
return err
575+
}
576+
if isClusterPaused {
577+
// No need to set skippedUpdated. Profile will react to a cluster switching from paused to unpaused
578+
logger.V(logs.LogDebug).Info("Cluster is paused and maxUpdate is set. Ignore this cluster.")
579+
continue
580+
}
581+
}
582+
567583
// if maxUpdate is set no more than maxUpdate clusters can be updated in parallel by ClusterProfile
568584
if maxUpdate != 0 && !updatingClusters.Has(&cluster) && int32(updatingClusters.Len()) >= maxUpdate {
569585
logger.V(logs.LogDebug).Info(fmt.Sprintf("Already %d being updating", updatingClusters.Len()))
@@ -575,27 +591,9 @@ func updateClusterSummaries(ctx context.Context, c client.Client, profileScope *
575591
// If a Cluster exists and it is a match, ClusterSummary is created (and ClusterSummary.Spec kept in sync if mode is
576592
// continuous).
577593
// ClusterSummary won't program cluster in paused state.
578-
_, err = getClusterSummary(ctx, c, profileScope.GetKind(), profileScope.Name(), cluster.Namespace,
579-
cluster.Name, clusterproxy.GetClusterType(&cluster))
594+
err = patchClusterSummary(ctx, c, profileScope, &cluster, logger)
580595
if err != nil {
581-
if apierrors.IsNotFound(err) {
582-
err = createClusterSummary(ctx, c, profileScope, &cluster)
583-
if err != nil {
584-
profileScope.Logger.Error(err, fmt.Sprintf("failed to create ClusterSummary for cluster %s/%s",
585-
cluster.Namespace, cluster.Name))
586-
}
587-
} else {
588-
profileScope.Logger.Error(err, "failed to get ClusterSummary for cluster %s/%s",
589-
cluster.Namespace, cluster.Name)
590-
return err
591-
}
592-
} else {
593-
err = updateClusterSummary(ctx, c, profileScope, &cluster)
594-
if err != nil {
595-
profileScope.Logger.Error(err, "failed to update ClusterSummary for cluster %s/%s",
596-
cluster.Namespace, cluster.Name)
597-
return err
598-
}
596+
return err
599597
}
600598

601599
if !updatingClusters.Has(&cluster) {
@@ -609,7 +607,7 @@ func updateClusterSummaries(ctx context.Context, c client.Client, profileScope *
609607
}
610608

611609
if skippedUpdate {
612-
return fmt.Errorf("Not all clusters updated yet. %d still being updated",
610+
return fmt.Errorf("not all clusters updated yet. %d still being updated",
613611
len(profileScope.GetStatus().UpdatingClusters.Clusters))
614612
}
615613

@@ -620,6 +618,36 @@ func updateClusterSummaries(ctx context.Context, c client.Client, profileScope *
620618
return nil
621619
}
622620

621+
func patchClusterSummary(ctx context.Context, c client.Client, profileScope *scope.ProfileScope,
622+
cluster *corev1.ObjectReference, logger logr.Logger) error {
623+
624+
// ClusterProfile does not look at whether Cluster is paused or not.
625+
// If a Cluster exists and it is a match, ClusterSummary is created (and ClusterSummary.Spec kept in sync if mode is
626+
// continuous).
627+
// ClusterSummary won't program cluster in paused state.
628+
_, err := getClusterSummary(ctx, c, profileScope.GetKind(), profileScope.Name(), cluster.Namespace,
629+
cluster.Name, clusterproxy.GetClusterType(cluster))
630+
if err != nil {
631+
if apierrors.IsNotFound(err) {
632+
err = createClusterSummary(ctx, c, profileScope, cluster)
633+
if err != nil {
634+
logger.Error(err, "failed to create ClusterSummary")
635+
}
636+
} else {
637+
logger.Error(err, "failed to get ClusterSummary")
638+
return err
639+
}
640+
} else {
641+
err = updateClusterSummary(ctx, c, profileScope, cluster)
642+
if err != nil {
643+
logger.Error(err, "failed to update ClusterSummary")
644+
return err
645+
}
646+
}
647+
648+
return nil
649+
}
650+
623651
// cleanClusterSummaries finds all ClusterSummary currently owned by ClusterProfile/Profile.
624652
// For each such ClusterSummary, if corresponding Sveltos/Cluster is not a match anymore, deletes ClusterSummary
625653
func cleanClusterSummaries(ctx context.Context, c client.Client, profileScope *scope.ProfileScope) error {

controllers/profile_utils_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,45 @@ var _ = Describe("Profile: Reconciler", func() {
624624
Expect(len(clusterSummaryList.Items)).To(Equal(0))
625625
})
626626

627+
It("updateClusterSummaries does not create ClusterSummary for matching Paused Cluster", func() {
628+
maxUpdate := int32(3)
629+
clusterProfile.Spec.MaxUpdate = &intstr.IntOrString{Type: intstr.Int, IntVal: maxUpdate}
630+
clusterProfile.Status.MatchingClusterRefs = []corev1.ObjectReference{
631+
{
632+
Namespace: matchingCluster.Namespace,
633+
Name: matchingCluster.Name,
634+
Kind: clusterKind,
635+
APIVersion: clusterv1.GroupVersion.String(),
636+
},
637+
}
638+
639+
matchingCluster.Status.ControlPlaneReady = true
640+
matchingCluster.Spec.Paused = true
641+
642+
initObjects := []client.Object{
643+
clusterProfile,
644+
nonMatchingCluster,
645+
matchingCluster,
646+
}
647+
648+
c := fake.NewClientBuilder().WithScheme(scheme).WithStatusSubresource(initObjects...).WithObjects(initObjects...).Build()
649+
650+
clusterProfileScope, err := scope.NewProfileScope(scope.ProfileScopeParams{
651+
Client: c,
652+
Logger: logger,
653+
Profile: clusterProfile,
654+
ControllerName: "clusterprofile",
655+
})
656+
Expect(err).To(BeNil())
657+
658+
err = controllers.UpdateClusterSummaries(context.TODO(), c, clusterProfileScope)
659+
Expect(err).To(BeNil())
660+
661+
clusterSummaryList := &configv1beta1.ClusterSummaryList{}
662+
Expect(c.List(context.TODO(), clusterSummaryList)).To(BeNil())
663+
Expect(len(clusterSummaryList.Items)).To(Equal(0))
664+
})
665+
627666
It("updateClusterSummaries creates ClusterSummary for each matching CAPI Cluster", func() {
628667
matchingCluster.Status.Conditions = []clusterv1.Condition{
629668
{

0 commit comments

Comments
 (0)