Closed thotz closed 3 years ago
@jeffvance @guymguym @copejon any thoughts on above issue?
shouldProvision
returns true when obc.bucketName is empty, meaning the OBC has not been bound to the OB. In the log we see that the OBC is already bound to the OB so no provisioning is performed. I don't see a connection between this and additionalConfig
@jeffvance the question is in the context bucket notification CRD. the plan is to referenced it from the OBC (via additionalconfig
).
we want to cover the case where bucket notification could be configured on a bucket after it was created.
for that we need to be triggered when OBC is modified (new additionlconfig
value is added). note that no bucket provisioning is required at this point, just triggering the notification provisioning hook.
I guess that all bucket provisioning related fields of the OBC are not supposed to change.
do you think it makes sense to add logic that would check if the additionalConfiig
map changed, and allow others (e.g bucket notification code in rook) to register to that event?
The code en-queues only the new obc. Maybe we can compare the obc retrieved from the GET call against the obc from the informer cache to determine which obc fields changed?
The code en-queues only the new obc. Maybe we can compare the obc retrieved from the GET call against the obc from the informer cache to determine which obc fields changed?
IMO values in AdditionalConfig
need to compared between new and old OBC. Better to keep other fields like storageclass
, bucketname
immutable and throws an error if user tries to change it. But I am not sure how(or is right to) values inside AdditionalConfig
can be compared since key-value pairs are opaque to lib-bucket-provisioner?
Better to keep other fields like
storageclass
,bucketname
immutable and throws an error if user tries to change it
this is a nice enhancement regardless of bucket notifications. currently we just silently ignore updates to immutable fields, would be better to error on that.
currently we just silently ignore updates to immutable fields, would be better to error on that.
True. We do the same with the OB too (no OB watch even).
values inside AdditionalConfig can be compared since key-value pairs are opaque to lib-bucket-provisione
It is tricky to compare maps because you cannot expect the keys to be retrieved in the same order. Go's "reflect" pkg should work, eg: reflect.DeepEqual(a, b)
currently we just silently ignore updates to immutable fields, would be better to error on that.
True. We do the same with the OB too (no OB watch even).
values inside AdditionalConfig can be compared since key-value pairs are opaque to lib-bucket-provisione
It is tricky to compare maps because you cannot expect the keys to be retrieved in the same order. Go's "reflect" pkg should work, eg:
reflect.DeepEqual(a, b)
@jeffvance Cool. How will we able to move forward here? Will you able to push a PR ?
Cool. How will we able to move forward here? Will you able to push a PR ?
Not likely. I do have some time to review lib PRs. Are you able to @thotz ?
Cool. How will we able to move forward here? Will you able to push a PR ?
Not likely. I do have some time to review lib PRs. Are you able to @thotz ?
Sure I will give a try then
@jeffvance : It looks a bit complex than I thought. If understand correctly in the library has Provisioner
which internally creates an obcController
. From Rook, a new provisioner is initialized and Started for handling OBC requests. Provisioner
works on a queue filled by the obcController
. This happens based on the events received in the controller and the following code handles it :+1:
obcInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: ctrl.enqueueOBC,
UpdateFunc: func(old, new interface{}) {
oldObc := old.(*v1alpha1.ObjectBucketClaim)
newObc := new.(*v1alpha1.ObjectBucketClaim)
if newObc.ResourceVersion == oldObc.ResourceVersion {
// periodic re-sync can be ignored
return
}
// if old and new both have deletionTimestamps we can also ignore the
// update since these events are occurring on an obc marked for deletion,
// eg. extra finalizers being added and deleted.
if newObc.ObjectMeta.DeletionTimestamp != nil && oldObc.ObjectMeta.DeletionTimestamp != nil {
return
}
// handle this update
ctrl.enqueueOBC(new)
},
DeleteFunc: func(obj interface{}) {
// Since a finalizer is added to the obc and thus the obc will remain
// visible, we do not need to handle delete events here. Instead, obc
// deletes are indicated by the deletionTimestamp being non-nil.
return
},
})
If I understand correctly UpdateFunc
needs to modify for fixing this issue. But I am not sure how the queue will be effective in the scenario. Do we need to change the current design for Provisioner.Start()
as well?
If I understand correctly UpdateFunc needs to modify for fixing this issue. But I am not sure how the queue will be effective in the scenario.
The code in your comment above added the "namespace/name" of the new object to the work queue for update events. But the syncHandler
methods needs to be enhanced to process update events. Today it only handles delete and add events.
I think an approach would be to keep the delete logic where it is with no changes. If the timestamp is nil then we have either add or update. The shouldProvision
func checks if the OBC is bound to the OB and if it returns false we know we have an update event. However, I think there are windows in this logic where the OBC is partially updated due to processing the new OBC and then an update event comes in. As an initial effort we can assume that if shouldProvision
returns false we need to handle update, otherwise we have an add event. You'll need to write a new handleUpdateClaim
method which will get the old OBC (not sure if better to use API Get
or retrieve from cache) and then compare additionalConfig
using reflect.DeepEqual
.
What do you think?
please see discussion here: https://github.com/rook/rook/pull/6425#discussion_r539844190 if we are going to use labels there, than there is not need for this enhancement anymore. unless there is another motivation, IMO we can close this issue.
I am not sure whether bug or current design limitation. In rook quota for OBC is supported with help of
additionalConfig
string Map. When I try to update the field it is not working viakubectl edit
orkubectl apply
the request is not handled properly.I can see following logs from rook-operator
If I understand correctly current code follow in
lib-bucket-provisioner
the request reachessyncHandler
.Firsts it check for whether request delete/revokes, if not checks whether provisioning is needed via
shouldProvision
. TheshouldProvision
checks whetherOB
name is present onOBC
CRD. If exists it returns true. In case of updatingOBC
field this always exist and skips further part of code. Is this intended behavior?CCing @yuvalif