Skip to content
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

feat: Implement config pod status #3544

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

abhipatnala
Copy link
Contributor

What this PR does / why we need it:

Which issue(s) this PR fixes (optional, using fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when the PR gets merged):
Fixes #2918

Special notes for your reviewer:

@abhipatnala abhipatnala requested a review from a team as a code owner September 14, 2024 03:35
@codecov-commenter
Copy link

codecov-commenter commented Sep 14, 2024

Codecov Report

Attention: Patch coverage is 49.54545% with 111 lines in your changes missing coverage. Please review.

Project coverage is 48.15%. Comparing base (3350319) to head (7bf092d).
Report is 150 commits behind head on master.

Files with missing lines Patch % Lines
apis/status/v1beta1/zz_generated.deepcopy.go 0.00% 62 Missing ⚠️
...controller/configstatus/configstatus_controller.go 67.12% 15 Missing and 9 partials ⚠️
pkg/controller/config/config_controller.go 63.15% 13 Missing and 8 partials ⚠️
apis/status/v1beta1/configpodstatus_types.go 80.00% 2 Missing and 2 partials ⚠️

❗ There is a different number of reports uploaded between BASE (3350319) and HEAD (7bf092d). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (3350319) HEAD (7bf092d)
unittests 2 1
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3544      +/-   ##
==========================================
- Coverage   54.49%   48.15%   -6.35%     
==========================================
  Files         134      221      +87     
  Lines       12329    15348    +3019     
==========================================
+ Hits         6719     7391     +672     
- Misses       5116     7121    +2005     
- Partials      494      836     +342     
Flag Coverage Δ
unittests 48.15% <49.54%> (-6.35%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

type: object
type: array
id:
description: 'Important: Run "make" to regenerate code after modifying
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably don't want this in the API docs...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

@abhipatnala abhipatnala force-pushed the add_status_to_config branch 2 times, most recently from 0721779 to a240878 Compare September 19, 2024 18:18
@@ -89,6 +89,17 @@ type Tracker struct {
trackListerPredicateOverride retryPredicate
}

type WrapFakeClientWithMutex struct {
Copy link
Contributor

@maxsmythe maxsmythe Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pure test code, it should live in the test file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. moved code to test file

@@ -167,7 +180,11 @@ func (r *ReconcileConfig) Reconcile(ctx context.Context, request reconcile.Reque
// If the config is being deleted the user is saying they don't want to
// sync anything
gvksToSync := []schema.GroupVersionKind{}
if exists && instance.GetDeletionTimestamp().IsZero() {

// deleted is true if the instance doesn't exist or has a deletion timestamp.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment is redundant as-worded. Potentially could be adding extra context, or could be citing the code as-written.

"K8s API conventions consider an object to be deleted when either the object no longer exists or when a deletion timestamp has been set"

would be a more useful comment -- it highlights that the reason this line of code exists is to align with an API convention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the comment.

@@ -195,5 +212,72 @@ func (r *ReconcileConfig) Reconcile(ctx context.Context, request reconcile.Reque
}

r.tracker.For(configGVK).Observe(instance)
return reconcile.Result{}, nil

if deleted {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should "config-controller: error establishing watches for new syncOnly:" be written to the status object? Maybe with a more user-friendly error string?

return err
}

// Watch for changes to ExpansionTemplateStatus
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stale comment, also comment is not helpful, as it describes obvious code function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted stale comment.


// add adds a new Controller to mgr with r as the reconcile.Reconciler.
func add(mgr manager.Manager, r reconcile.Reconciler) error {
// Create a new controller
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unhelpful comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated with more useful comment

return err
}

// Watch for changes to ExpansionTemplate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stale comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted


// PodStatusToConfigMapper correlates a ConfigPodStatus with its corresponding Config.
// `selfOnly` tells the mapper to only map statuses corresponding to the current pod.
func PodStatusToConfigMapper(selfOnly bool) handler.TypedMapFunc[*v1beta1.ConfigPodStatus] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like selfOnly is not being used. This code was copied from expansion templates, which also did not use selfOnly. This is a bug. Here is an example of proper use of selfOnly in the constraint controller:

err = c.Watch(
source.Kind(mgr.GetCache(), &constraintstatusv1beta1.ConstraintPodStatus{}, handler.TypedEnqueueRequestsFromMapFunc(constraintstatus.PodStatusToConstraintMapper(true, util.EventPackerMapFunc()))))
if err != nil {
return err
}

Here is the basic reasoning:

  • status controllers want to watch all podStatus objects and the primary object because they want to make sure they respond to any changes (i.e. writing status changes, overwriting inappropriate deletes of the status field, etc.)

  • primary controllers want to watch podStatus for the corresponding pod -- if someone deletes a podStatus resource the main object should be re-reconciled to avoid missing state.

As it stands, if a user were to delete the podStatus object, there is a risk that there would be no reconcile.

We should add the appropriate watches to the config and expansion controllers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

// created is true if at least one Pod hasn't reported any errors

for i := range statusObjs {
// Don't report status if it's not for the correct object. This can happen
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an example of a good comment -- the why of this code is not obvious and depends on external considerations

sort.Sort(statusObjs)

var s []v1beta1.ConfigPodStatusStatus
// created is true if at least one Pod hasn't reported any errors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stale comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted.


// Add creates a new config Status Controller and adds it to the Manager. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func (a *Adder) Add(mgr manager.Manager) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like we're gating status controller on whether the status operation is enabled -- this is bad because it means this controller will not run as a singleton, which invites write conflicts particularly as the # of pods scales.

Example of the status gate:

if operations.IsAssigned(operations.Status) {
// statusEvents will be used to receive events from dynamic watches registered
// via the registrar below.
statusEvents := make(chan event.GenericEvent, 1024)
csAdder := constraintstatus.Adder{
CFClient: cfClient,
WatchManager: wm,
ControllerSwitch: cs,
Events: statusEvents,
IfWatching: statusW.IfWatching,
}
if err := csAdder.Add(mgr); err != nil {
return nil, err
}
ctsAdder := constrainttemplatestatus.Adder{
CfClient: cfClient,
WatchManager: wm,
ControllerSwitch: cs,
}
if err := ctsAdder.Add(mgr); err != nil {
return nil, err
}
}

Though a more appropriate code shape for this PR is probably the mutator status gate:

if !operations.IsAssigned(operations.MutationStatus) {
return nil
}

(however we should depend on Status, not MutatorStatus)

We should also fix this for the expansion template status controller (worth verifying it has a similar oversight first).

Long-term a more uniform design pattern for adding status controllers may help avoid similar oversights in the future, but that's beyond the scope of this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the logic to use status gate

Avinash Patnala added 16 commits September 20, 2024 23:20
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Avinash Patnala added 3 commits September 20, 2024 23:32
Signed-off-by: Avinash Patnala <[email protected]>
Signed-off-by: Avinash Patnala <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add status to config
3 participants