-
Notifications
You must be signed in to change notification settings - Fork 47
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
New Reconciler Option: SkipPrimaryGVKSchemeRegistration #147
New Reconciler Option: SkipPrimaryGVKSchemeRegistration #147
Conversation
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.
Hi @mtesseract, this seems straightforward enough, but could you include a use case and maybe a code example of what the custom setup would look like if this option is enabled?
Is there a case where an operator author wouldn't need to add unstructured.Unstructed{}
to the scheme for the primary objects?
Pull Request Test Coverage Report for Build 1945818205
💛 - Coveralls |
Hi @joelanford, Our use case is that we are developing a hybrid operator and we want to use custom types for configuring our custom resource instead of using the unstructured type for modelling underlying Helm chart's values. Code for adding custom types to scheme: var (
SchemeGroupVersion = schema.GroupVersion{Group: ..., Version: ...}
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&MyCustomType{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
} Then we set up new scheme and create a new manager for it: var (
scheme = runtime.NewScheme()
)
// [...]
AddToScheme(scheme)
// [...]
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
// [...]
}) Set up new reconciler for this scheme: func SetupReconcilerWithManager(mgr ctrl.Manager, gvk schema.GroupVersionKind) error {
// [...]
reconcilerOpts := []reconciler.Option{
reconciler.WithChart(*chart),
reconciler.SkipSchemeSetup(true),
// [...]
}
// [...]
r, err = reconciler.New(reconcilerOpts...)
// [...]
err = r.SetupWithManager(mgr)
// [...] Is this sufficient? Thanks! |
@mtesseract Does the operator work if Semi-related question: Is it possible to register two different objects to the same GVK? If you add the concrete type to the scheme while still allowing the reconciler to add the unstructured type to the scheme for the same GVK, does that result in an error? Lastly, could you add some tests in the reconciler, so we can verify the expected behavior now and avoid regressions in the future? |
Lastly, it looks like this PR needs to rebased. go-apidiff is reporting an API being removed that seems unrelated to this PR. |
Hi. Please excuse the late reply -- the pandemic forced me to take a care work leave for a few weeks. Let me answer this here right away:
I hope I'm understanding your question correctly. So, my answer is: This is not possible, with the current implementation of the reconciler. It throws this:
The relevant piece of code is this: func (s *Scheme) AddKnownTypeWithName(gvk schema.GroupVersionKind, obj Object) {
[...]
t := reflect.TypeOf(obj)
[...]
if oldT, found := s.gvkToType[gvk]; found && oldT != t {
panic(fmt.Sprintf("Double registration of different types for %v: old=%v.%v, new=%v.%v in scheme %q", gvk, oldT.PkgPath(), oldT.Name(), t.PkgPath(), t.Name(), s.schemeName))
}
[...]
} |
361be6a
to
41c90f5
Compare
Yes, the underlying object -- even if a custom type -- continues to be accessible as an |
@SimonBaeumer and I chatted about this in the community helm-operator meeting, and he successfully convinced me this is a necessary change. There are a few things I think still need to be done. Improvement: can we augment the reconciler tests with a scenario that runs the reconciler with this option enabled to show that registering the GVK with a concrete API type doesn't break the reconciler's use of Nits:
|
@joelanford , regarding the naming, going with something longer but more descriptive is of course fine for me. |
@joelanford, looking forward to your feedback. |
@mtesseract There's another case that comes to mind. Scenario:
What would we expect to happen here? I can think of two approaches.
I'm fairly sure option 1 is the existing (perhaps unintended) implementation. We currently make no attempt to setup the scheme for a anything other than the primary object being reconciled. However I think option 2 is possible if we wanted to go that route (i.e. similar to how we dynamically register watches for release object types, we could also check and update the scheme, always using unstructured for anything not already registered). ^ Does that all make sense and seem like a reasonable use case? If so, does that impact the name we choose for this? If we go with On the otherhand, If we think we need to distinguish, I think WDYT? |
I have updated the PR to use the name you have suggested ( Also, regarding your example, I think you are right in that it would be user's responsibility to register any types in the scheme that are to be used, e.g. in hooks. |
/ok-to-test |
/cc @jmrodri |
…an be used by users who prefer their custom scheme setup over the generic scheme setup currently being done by the reconciler. Signed-off-by: Moritz Clasmeier <moritz@stackrox.com>
9608c54
to
44597c1
Compare
Co-authored-by: Joe Lanford <joe.lanford@gmail.com>
/lgtm |
Add a new Reconciler option
SkipGenericGVKSchemeRegistration
, which can be used by users who prefer theircustom scheme setup over the generic scheme setup currently being done by the reconciler.
Signed-off-by: Moritz Clasmeier moritz@stackrox.com