-
Notifications
You must be signed in to change notification settings - Fork 52
🐛 addon fix for Install namespace potential race condition with addondeploymentconfig - For issue: https://github.com/open-cluster-management-io/ocm/issues/1465 #381
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ import ( | |
| "context" | ||
| "fmt" | ||
|
|
||
| "k8s.io/apimachinery/pkg/api/meta" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||
| "k8s.io/apimachinery/pkg/runtime" | ||
|
|
@@ -47,11 +48,6 @@ func AgentInstallNamespaceFromDeploymentConfigFunc( | |
| return "", fmt.Errorf("failed to get deployment config for addon %s: %v", addon.Name, err) | ||
| } | ||
|
|
||
| // For now, we have no way of knowing if the addon depleoyment config is not configured, or | ||
| // is configured but not yet been added to the managedclusteraddon status config references, | ||
| // we expect no error will be returned when the addon deployment config is not configured | ||
| // so we can use the default namespace. | ||
| // TODO: Find a way to distinguish between the above two cases | ||
| if config == nil { | ||
| klog.V(4).InfoS("Addon deployment config is nil, return an empty string for agent install namespace", | ||
| "addonNamespace", addon.Namespace, "addonName", addon.Name) | ||
|
|
@@ -71,6 +67,14 @@ func GetDesiredAddOnDeploymentConfig( | |
| ok, configRef := GetAddOnConfigRef(addon.Status.ConfigReferences, | ||
| AddOnDeploymentConfigGVR.Group, AddOnDeploymentConfigGVR.Resource) | ||
| if !ok { | ||
| // If the addon declares support for addondeploymentconfigs but the Configured condition | ||
| // is not yet True, the addonconfiguration controller either hasn't processed this MCA | ||
| // or hasn't finished rolling out configs. In either case configReferences may be | ||
| // incomplete. Return an error so callers retry rather than proceeding with no config. | ||
| if addonSupportsDeploymentConfig(addon) && !addonConfiguredTrue(addon) { | ||
| return nil, fmt.Errorf("addon %s supports addondeploymentconfigs but Configured condition is not True yet, need to retry", | ||
| addon.Name) | ||
| } | ||
| return nil, nil | ||
| } | ||
|
|
||
|
|
@@ -134,3 +138,17 @@ func GetAddOnConfigRef( | |
|
|
||
| return false, addonapiv1beta1.ConfigReference{} | ||
| } | ||
|
|
||
| func addonSupportsDeploymentConfig(addon *addonapiv1beta1.ManagedClusterAddOn) bool { | ||
| for _, sc := range addon.Status.SupportedConfigs { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addon.Status.SupportedConfigs is for addon users to know to supported config type. In code level, https://github.com/open-cluster-management-io/addon-framework/blob/main/pkg/addonmanager/controllers/addonconfig/controller.go#L177 , should check the configGVRs.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for this @haoqing0110 - I guess I was having trouble seeing why the configGVRs would get loaded in this code - but using Status.SupportedConfigs has a similar timing issue as it's something else that's setting that status. I think in the end, are you ok if we use However, there is the one caveat that where a ClusterManagementAddOn may have this annotation: Do you think this is a concern? I think with v1beta1 this is less of a concern since there is no such idea of "supportedConfigs" anymore - and if the annotation is set by a user, do we not expect them to call
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tesshuflower I think it's good to check the condition |
||
| if sc.Group == AddOnDeploymentConfigGVR.Group && sc.Resource == AddOnDeploymentConfigGVR.Resource { | ||
| return true | ||
| } | ||
| } | ||
| return false | ||
| } | ||
|
|
||
| func addonConfiguredTrue(addon *addonapiv1beta1.ManagedClusterAddOn) bool { | ||
| cond := meta.FindStatusCondition(addon.Status.Conditions, addonapiv1beta1.ManagedClusterAddOnConditionConfigured) | ||
| return cond != nil && cond.Status == metav1.ConditionTrue | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have an integration test on this? Also if it returns err, the controller will backoff upon error. Instead of returning an error, should we return a state that "nothing is configured yet" so the caller will know nothing should be handled, and when addon status is updated, this func will be triggered again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is a concern I mentioned in my description as well - the issue is the function
AgentInstallNamespaceFromDeploymentConfigFunc()is essentially a helper function provided by the addon-framework that addons are already using to get the namespace from the deploymentconfig - Should I consider deprecating it and making a new function instead that can return the extra status?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@qiujian16 What do you think about my comment above? My main concern with changing the function signature is this is a function already called by users of the addon-framework - If I want to return another parameter to tell them to retry, this necessitates a change in the function or perhaps a new one. Do you have a preference here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I think it makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@qiujian16 @haoqing0110 I've come back to this one, and was going through changes required to add new functions to be able to get the namespace (with retries) - however there are a lot of cascading affected places.
For example addon framework interface functions would need updating too, example:
addon-framework/pkg/agent/interface.go
Line 73 in 929daf0
And then even from getValues functions like here:
addon-framework/pkg/addonfactory/helm_agentaddon.go
Line 170 in 929daf0
Essentially all of those don't currently have a strict retry mechanism and would need to change or get updated.
But then I found we actually have this
ConfigCheckEnabledsetting already:addon-framework/pkg/agent/interface.go
Line 112 in 929daf0
And this is used in a couple places before calling the agent Manifests() function.
Do you think perhaps I should pivot to a fix that simply uses ConfigCheckEnabled instead? Ultimately it's the same exact guard - it checks for configured=true in the status before proceeding. I feel like my current fix in this PR is maybe bypassing the `ConfigCheckEnabled as well as getting overly complicated.
Essentially a fix would be to make sure we do something similar to this:
https://github.com/open-cluster-management-io/addon-framework/blob/main/pkg/addonmanager/controllers/agentdeploy/controller.go#L409-L413
Anytime before the getAgentNamespace (of even agent Manifests()) is called. This would essentially give us the same protection, but would only be turned on when users set
ConfigCheckEnabled.Sorry the above is very long, I've made an alternative draft PR here to demonstrate the changes required with this approach: #382
The comments on the original function with the race condition attempt to explain it as well: https://github.com/open-cluster-management-io/addon-framework/pull/382/changes#diff-0268a17aba5249e6bd421172ca6ac3c9c0e93ef819030b1cba41afbe50d89743
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@qiujian16 and @haoqing0110 - sorry do you mind taking a look again at the above? Would you be ok with the alternative approach in #382 ?