Skip to content

Commit

Permalink
Allow PeriodicallyExecConfigPolicies to finish after uninstall
Browse files Browse the repository at this point in the history
Without this commit, as soon as a SIGINT signal was received, mgr.Start
would exit and cause the main function to finish before
PeriodicallyExecConfigPolicies could finish the removal of finalizers
when the config-policy-controller is being uninstalled.

Co-authored-by: Justin Kulikauskas <jkulikau@redhat.com>
Signed-off-by: mprahl <mprahl@users.noreply.github.com>
  • Loading branch information
2 people authored and openshift-merge-robot committed Feb 3, 2023
1 parent eb8f720 commit 82a7f86
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
3 changes: 3 additions & 0 deletions build/common/config/.golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ linters:
enable-all: true
disable:
- bodyclose
# Disable contextcheck since we don't want to pass the context passed to PeriodicallyExecConfigPolicies to functions
# called within it or else cleanup won't occur
- contextcheck
- cyclop
- depguard
- dupl
Expand Down
27 changes: 20 additions & 7 deletions controllers/configurationpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,32 @@ func (r *ConfigurationPolicyReconciler) Reconcile(ctx context.Context, request c

// PeriodicallyExecConfigPolicies loops through all configurationpolicies in the target namespace and triggers
// template handling for each one. This function drives all the work the configuration policy controller does.
func (r *ConfigurationPolicyReconciler) PeriodicallyExecConfigPolicies(freq uint, elected <-chan struct{}, test bool) {
func (r *ConfigurationPolicyReconciler) PeriodicallyExecConfigPolicies(
ctx context.Context, freq uint, elected <-chan struct{},
) {
log.Info("Waiting for leader election before periodically evaluating configuration policies")
<-elected

select {
case <-elected:
case <-ctx.Done():
return
}

const waiting = 10 * time.Minute
var exiting bool
// Loop twice after exit condition is received to account for race conditions and retries.
loopsAfterExit := 2

for {
for !exiting || (exiting && loopsAfterExit > 0) {
start := time.Now()

select {
case <-ctx.Done():
exiting = true
loopsAfterExit--
default:
}

policiesList := policyv1.ConfigurationPolicyList{}

var skipLoop bool
Expand Down Expand Up @@ -264,10 +281,6 @@ func (r *ConfigurationPolicyReconciler) PeriodicallyExecConfigPolicies(freq uint
log.V(2).Info("Sleeping before reprocessing the configuration policies", "seconds", sleepTime)
time.Sleep(sleepTime)
}

if test {
return
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,16 @@ func main() {
os.Exit(1)
}

terminatingCtx := ctrl.SetupSignalHandler()
managerCtx, managerCancel := context.WithCancel(context.Background())

// PeriodicallyExecConfigPolicies is the go-routine that periodically checks the policies
log.V(1).Info("Perodically processing Configuration Policies", "frequency", frequency)

go reconciler.PeriodicallyExecConfigPolicies(frequency, mgr.Elected(), false)
go func() {
reconciler.PeriodicallyExecConfigPolicies(terminatingCtx, frequency, mgr.Elected())
managerCancel()
}()

// This lease is not related to leader election. This is to report the status of the controller
// to the addon framework. This can be seen in the "status" section of the ManagedClusterAddOn
Expand Down Expand Up @@ -361,7 +367,7 @@ func main() {

log.Info("Starting manager")

if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
if err := mgr.Start(managerCtx); err != nil {
log.Error(err, "Problem running manager")
os.Exit(1)
}
Expand Down

0 comments on commit 82a7f86

Please sign in to comment.