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

Informer creation behavior for custom resource with CRDContext in SharedInformerFactory #2746

Closed
LukaTchumburidze opened this issue Jan 22, 2021 · 5 comments · Fixed by #2882 or jenkinsci/kubernetes-client-api-plugin#83
Assignees
Milestone

Comments

@LukaTchumburidze
Copy link

The factory has a method sharedIndexInformerForCustomResource to create an informer with a CRDContext for CRs. It's is using sharedInformerFor to register the informer inside the factory object. This causes a problem when registering new informers using several different CRDContexts, but using same set of classes (extending CustomResource and CustomResourceList). Case will result in creation of several informers, but registering only the one which is has been created the latest (since factory's internal map uses only classname as key).
Example:

        SharedInformerFactory factory = defaultKubernetesClient.informers();

        CustomResourceDefinitionContext firstCrdContext = getFirstCrdContext();
        CustomResourceDefinitionContext secondCrdContext = getSecondCrdContext();

        SharedIndexInformer<MyCustomResourceClass> lostIndexInformer = factory.sharedIndexInformerForCustomResource(
                firstCrdContext,
                MyCustomResourceClass.class,
                MyCustomResourceClassList.class,
                0);

        SharedIndexInformer<MyCustomResourceClass> savedIndexInformer = factory.sharedIndexInformerForCustomResource(
                secondCrdContext,
                MyCustomResourceClass.class,
                MyCustomResourceClassList.class,
                0);

        factory.startAllRegisteredInformers();

As I have said lostIndexInformer will be rewritten by the time we reach to startAllRegisteredInformers. I don't think this is the right behavior, since idea of passing the different CRDContexts to factory methods means that several informers should be registered and that they should operate on different CRs which has been described in CRDContext.

@LukaTchumburidze LukaTchumburidze changed the title Informer creation behavior for custom resource with crdcontext in SharedInformerFactory Informer creation behavior for custom resource with CRDContext in SharedInformerFactory Jan 22, 2021
@rohanKanojia rohanKanojia self-assigned this Mar 4, 2021
@rohanKanojia
Copy link
Member

This issue also seems related to #2738

We're using type as the key for informer

private final Map<Type, SharedIndexInformer> informers = new HashMap<>();

@rohanKanojia
Copy link
Member

rohanKanojia commented Mar 5, 2021

@LukaTchumburidze: Hi, Would it be possible for you to share contents for firstCrdContext and secondCrdContext?

@rohanKanojia
Copy link
Member

rohanKanojia commented Mar 8, 2021

Bdw, these methods accepting CustomResourceDefinitionContext in SharedInformerFactory were removed in #2667 and are not part of API since v5.1.0

But I still see a way to provide different versions by providing an OperationContext .However this doesn't work due to apiversion always getting picked from annotation:

KubernetesDeserializer.registerCustomKind(HasMetadata.getApiVersion(apiTypeClass), apiTypeClass.getSimpleName(), apiTypeClass);

SharedIndexInformer<Bicycle> bicycleV1Informer = informerFactory.sharedIndexInformerForCustomResource(Bicycle.class, resyncPeriodMillis);
SharedIndexInformer<Bicycle> bicycleV1beta1Informer = informerFactory.sharedIndexInformerForCustomResource(Bicycle.class, new OperationContext().withApiGroupVersion("v1beta1"), resyncPeriodMillis);

bicycleV1beta1Informer.addEventHandler(new GenericResourceHandler<>("v1beta1-bicycle"));
bicycleV1Informer.addEventHandler(new GenericResourceHandler<>("v1-bicycle"));

Moreover having Type as the key doesn't only affect CustomResources. This informer lost behavior is also visible in standard Kubernetes resources:

SharedIndexInformer<Pod> podInDefaultNamespaceInformer = informerFactory.inNamespace("default")
  .sharedIndexInformerFor(Pod.class, resyncPeriodMillis);
SharedIndexInformer<Pod> podInKubePublicNamespaceInformer = informerFactory.inNamespace("kube-system")
  .sharedIndexInformerFor(Pod.class, resyncPeriodMillis); // Overwrites previous entry

I admit key should not be Type and should be a composite key depending upon resource's ApiGroup, ApiVersion, Namespace and Name

@LukaTchumburidze
Copy link
Author

LukaTchumburidze commented Mar 8, 2021

@rohanKanojia Since kubernetes-client's approach with CRDs has changed much during these months you're right that my example is obsolete.
However, you have also correctly remarked, that core issue still stays the same, hashmap's keys are being populated only according to Types.

I admit key should not be Type and should be a composite key depending upon resource's ApiGroup, ApiVersion, Namespace and Name

Currently factory does not support several OperatorContexts for one class as well. The key should contain OperationContext, since OperationContext might contain any queries needed for two informers to be distinguished from each other. I might be wrong on this one, but it can be checked.

rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Mar 8, 2021
… as key

SharedInformerFactory has `informers` and `startedInformers` Map fields
which use `Type` as key. This limits us to use only one
SharedIndexInformer corresponding to a particular type. Since
OperationContext is unique for all requests, it should be used as key
parameter instead.
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Mar 9, 2021
… as key

SharedInformerFactory has `informers` and `startedInformers` Map fields
which use `Type` as key. This limits us to use only one
SharedIndexInformer corresponding to a particular type. We should make a
key based on OperationContext's elements like apigroup, apiversion,
namespace, name, labels, fields etc.
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Mar 9, 2021
… as key

SharedInformerFactory has `informers` and `startedInformers` Map fields
which use `Type` as key. This limits us to use only one
SharedIndexInformer corresponding to a particular type. We should make a
key based on OperationContext's elements like apigroup, apiversion,
namespace, name, labels, fields etc.
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Mar 9, 2021
… as key

SharedInformerFactory has `informers` and `startedInformers` Map fields
which use `Type` as key. This limits us to use only one
SharedIndexInformer corresponding to a particular type. We should make a
key based on OperationContext's elements like apigroup, apiversion,
namespace, name, labels, fields etc.
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Mar 9, 2021
… as key

SharedInformerFactory has `informers` and `startedInformers` Map fields
which use `Type` as key. This limits us to use only one
SharedIndexInformer corresponding to a particular type. We should make a
key based on OperationContext's elements like apigroup, apiversion,
namespace, name, labels, fields etc.
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Mar 9, 2021
… as key

SharedInformerFactory has `informers` and `startedInformers` Map fields
which use `Type` as key. This limits us to use only one
SharedIndexInformer corresponding to a particular type. We should make a
key based on OperationContext's elements like apigroup, apiversion,
namespace, name, labels, fields etc.
manusa pushed a commit to rohanKanojia/kubernetes-client that referenced this issue Mar 11, 2021
… as key

SharedInformerFactory has `informers` and `startedInformers` Map fields
which use `Type` as key. This limits us to use only one
SharedIndexInformer corresponding to a particular type. We should make a
key based on OperationContext's elements like apigroup, apiversion,
namespace, name, labels, fields etc.
manusa pushed a commit that referenced this issue Mar 11, 2021
SharedInformerFactory has `informers` and `startedInformers` Map fields
which use `Type` as key. This limits us to use only one
SharedIndexInformer corresponding to a particular type. We should make a
key based on OperationContext's elements like apigroup, apiversion,
namespace, name, labels, fields etc.
@manusa manusa added this to the 5.2.0 milestone Mar 11, 2021
This was referenced Mar 15, 2021
@manusa
Copy link
Member

manusa commented Jun 23, 2021

Relates to: #2010

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment