-
Notifications
You must be signed in to change notification settings - Fork 339
Gracefully handle missing shipped ConfigMaps at startup #3308
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?
Gracefully handle missing shipped ConfigMaps at startup #3308
Conversation
|
Hi @anjalii-28. Thanks for your PR. I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: anjalii-28 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3308 +/- ##
==========================================
- Coverage 74.63% 74.61% -0.02%
==========================================
Files 188 188
Lines 8195 8210 +15
==========================================
+ Hits 6116 6126 +10
- Misses 1840 1843 +3
- Partials 239 241 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
/ok-to-test |
| } | ||
| // ConfigMap doesn't exist and is not defaulted. Log a warning but don't fail. | ||
| // The watcher will pick up the ConfigMap if it's created later. | ||
| log.Printf("WARNING: ConfigMap %q in namespace %q not found, using defaults and watching for creation", k, i.Namespace) |
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.
shouldn't use log package. we use a zap logger we'll probably want a new constructor that accepts a logger if we want these errors
| if _, err := kubeclient.Get(ctx).CoreV1().ConfigMaps(system.Namespace()).Get(ctx, cmName, | ||
| metav1.GetOptions{}); err == nil { | ||
| cmw.Watch(logging.ConfigMapName(), logging.UpdateLevelFromConfigMap(logger, atomicLevel, component)) | ||
| } else if !apierrors.IsNotFound(err) { | ||
| logger.Fatalw("Error reading ConfigMap "+logging.ConfigMapName(), zap.Error(err)) | ||
| cmw.Watch(cmName, logging.UpdateLevelFromConfigMap(logger, atomicLevel, component)) | ||
| } else if apierrors.IsNotFound(err) { | ||
| // ConfigMap doesn't exist, but we still register a watcher so updates are picked up if it's created later. | ||
| logger.Warnw("ConfigMap "+cmName+" not found, using defaults and watching for creation", zap.String("configmap", cmName)) | ||
| cmw.Watch(cmName, logging.UpdateLevelFromConfigMap(logger, atomicLevel, component)) | ||
| } else { | ||
| logger.Fatalw("Error reading ConfigMap "+cmName, zap.Error(err)) | ||
| } |
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.
Seems like we can simply call Watch now? and not have these if clauses here
| } else if apierrors.IsNotFound(err) { | ||
| // ConfigMap doesn't exist, but we still register a watcher so updates are picked up if it's created later. | ||
| logger.Warnw("ConfigMap "+cmName+" not found, using defaults and watching for creation", zap.String("configmap", cmName)) | ||
| cmw.Watch(cmName, observers...) | ||
| } else { |
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.
Likewise we can simplify this and just call Watch and not worry about fetching the config maps?
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.
Also one thing we could do for the observability config map is maybe kill the main context thus triggering a shutdown of the component. Then Kubernetes would restart the pod.
|
|
||
| // Check which ConfigMaps exist and mark missing ones (without defaults) as done in the synced callback | ||
| // so we don't wait for them indefinitely | ||
| i.markMissingConfigMapsAsDone(s) |
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.
This behaviour should probably be opt-in for now using an option. Someone might be relying checkObservedResourcesExist to return the error and we don't want to break that.
| // so we don't wait for it. The watcher will pick it up if it's created later. | ||
| s.MarkKeyAsDone(k) | ||
| } | ||
| } |
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.
should probably return an error if Get returns something besides IsNotFound no?
| case err.Error() != tc.expectErr: | ||
| t.Fatal("Unexpected error =", err) | ||
| // Missing ConfigMaps should not cause Start to fail | ||
| if err != nil { |
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.
revert this - we shouldn't change the default behaviour
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.
We should add a separate test for the new behaviour
| cmw := cminformer.NewInformedWatcher(kc, system.Namespace()) | ||
|
|
||
| // Track if the update handler was invoked | ||
| var handlerInvoked sync.WaitGroup |
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.
It would be simpler to just have a channel that returns ConfigMaps
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.
Then you could drop handlerMutex as well
| } | ||
|
|
||
| // Give the watcher time to fully start and sync | ||
| time.Sleep(500 * time.Millisecond) |
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.
We should probably use the config map watchers Wait method here
| // Handler was invoked, verify the ConfigMap | ||
| handlerMutex.Lock() | ||
| defer handlerMutex.Unlock() | ||
| if receivedConfigMap == nil { |
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.
We use cmp.Diff to make this simpler - see other examples in the codebase
This change updates sharedmain to handle missing shipped ConfigMaps more gracefully
at startup.
Behavior:
-> Missing shipped ConfigMaps are treated as empty (defaults used) instead of panicking
Fixes #3195
Testing: