Skip to content

Restart csv with exponential delay in checker #804

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions controllers/constant/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ const (
//HashedData is the key for checking the checksum of data section
HashedData string = "hashedData"

// SubscriptionRestartCount is the name use to count the restart times done by operator checker
SubscriptionRestartCount string = "operator.ibm.com/operator-checker-restart-count"

//DefaultRequestTimeout is the default timeout for kube request
DefaultRequestTimeout = 5 * time.Second

Expand Down
65 changes: 33 additions & 32 deletions controllers/operatorchecker/operatorchecker_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package operatorchecker

import (
"context"
"math"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -48,6 +50,20 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
return ctrl.Result{RequeueAfter: constant.DefaultRequeueDuration}, nil
}

if subscriptionInstance.Spec.InstallPlanApproval == olmv1alpha1.ApprovalManual {
return ctrl.Result{RequeueAfter: constant.DefaultRequeueDuration}, nil
}

restartCount := 0
forceRestart := false
if subscriptionInstance.GetAnnotations() == nil {
subscriptionInstance.SetAnnotations(make(map[string]string))
}
existingAnnotations := subscriptionInstance.GetAnnotations()
if existingRestartCount, ok := existingAnnotations[constant.SubscriptionRestartCount]; ok {
restartCount, _ = strconv.Atoi(existingRestartCount)
}

if subscriptionInstance.Status.CurrentCSV == "" && subscriptionInstance.Status.State == "" {
// cover fresh install case
csvList, err := r.getCSVBySubscription(ctx, subscriptionInstance)
Expand All @@ -67,45 +83,30 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
return ctrl.Result{}, client.IgnoreNotFound(err)
}
if subscriptionInstance.Status.CurrentCSV == "" && subscriptionInstance.Status.State == "" {
if restartCount > 5 {
if err = r.Delete(ctx, subscriptionInstance); err != nil {
return ctrl.Result{}, err
}
forceRestart = true
} else {
restartCount = restartCount + 1
existingAnnotations[constant.SubscriptionRestartCount] = strconv.Itoa(restartCount)
subscriptionInstance.SetAnnotations(existingAnnotations)
if err = r.Update(ctx, subscriptionInstance); err != nil {
return ctrl.Result{}, err
}
}
if err = r.deleteCSV(ctx, csv.Name, csv.Namespace); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
}
}

if subscriptionInstance.Status.State == "UpgradePending" && subscriptionInstance.Status.CurrentCSV != "" && subscriptionInstance.Status.InstalledCSV != "" {
// cover upgrade case
csvList, err := r.getCSVBySubscription(ctx, subscriptionInstance)
if err != nil {
klog.Error(err)
return ctrl.Result{RequeueAfter: constant.DefaultRequeueDuration}, nil
}
if len(csvList) != 1 {
klog.Warning("Not found matched CSV, CSVList length: ", len(csvList))
return ctrl.Result{RequeueAfter: constant.DefaultRequeueDuration}, nil
}
csv := csvList[0]

currentCSVVersion := ""
if len(strings.SplitN(subscriptionInstance.Status.CurrentCSV, ".", 2)) == 2 {
currentCSVVersion = strings.SplitN(subscriptionInstance.Status.CurrentCSV, ".", 2)[1]
}

if currentCSVVersion != csv.Spec.Version.String() {
time.Sleep(constant.DefaultCSVWaitPeriod)
subscriptionInstance, err := r.getSubscription(ctx, req)
if err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
if subscriptionInstance.Status.State == "UpgradePending" && subscriptionInstance.Status.CurrentCSV != "" && subscriptionInstance.Status.InstalledCSV != "" {
if err = r.deleteCSV(ctx, csv.Name, csv.Namespace); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
}
}
if forceRestart {
return ctrl.Result{RequeueAfter: constant.DefaultRequeueDuration}, nil
}

return ctrl.Result{RequeueAfter: constant.DefaultRequeueDuration}, nil
requeueTime := constant.DefaultRequeueDuration * time.Duration(math.Pow(2, float64(restartCount)))
return ctrl.Result{RequeueAfter: requeueTime}, nil
}

func (r *Reconciler) getCSVBySubscription(ctx context.Context, subscriptionInstance *olmv1alpha1.Subscription) ([]olmv1alpha1.ClusterServiceVersion, error) {
Expand Down