Update the operand when image changes#32
Update the operand when image changes#32openshift-merge-robot merged 1 commit intoopenshift:masterfrom
Conversation
| if c.containerImagesNeedsUpdate(&existingDeployment.Spec.Template.Spec, &deploy.Spec.Template.Spec) { | ||
| forceRollout = true | ||
| } | ||
| } |
There was a problem hiding this comment.
Have you considered doing this in library-go's ApplyDeployment()? I think it'd be cleaner, as ApplyDeployment needs to Get the object anyway.
Updating the object when there's a new container image seems to be desired, so it shouldn't be a problem for other users of ApplyDeployment()?
There was a problem hiding this comment.
To clarify, perhaps even better would be to compare the Spec, something like:
diff --git a/pkg/operator/resource/resourceapply/apps.go b/pkg/operator/resource/resourceapply/apps.go
index 253b17ef..1a8ecb0a 100644
--- a/pkg/operator/resource/resourceapply/apps.go
+++ b/pkg/operator/resource/resourceapply/apps.go
if !*modified && existingCopy.ObjectMeta.Generation == expectedGeneration && !forceRollout {
- return existingCopy, false, nil
+ if equality.Semantic.DeepEqual(required.Spec, existingCopy.Spec) {
+ return existingCopy, false, nil
+ }
}There was a problem hiding this comment.
This has bothered me for awhile but none of the Apply* functions in library-go check for spec. Are you proposing that we patch it in library-go?
There was a problem hiding this comment.
IMO you can't check Spec, some fields gets defaulted by API server. That's IMO the reason why Generation was introduced.
And each team will have different opinion what should be checked - now we want conainer images, but someone will want also cmdline arguments (that's where the log level is) and whatnot.
It would be better to change resourceapply functions to accept existing object, if it is known.
There was a problem hiding this comment.
@deads2k, are we missing anything? This PR tries to re-deploy operand (DaemonSet + Deployment) when the operator is restarted with env. variables pointing to new images. Someone must have it solved already. How other operators detect this?
There was a problem hiding this comment.
library-go's ApplyDeployment uses generation, not spec to determine whether it needs to be applied. See the check here: https://github.com/openshift/library-go/blob/master/pkg/operator/resource/resourceapply/apps.go#L39-L42
The recommended .status for operators keep track of the last applied generation. You can see usage here: https://github.com/openshift/cluster-openshift-apiserver-operator/blob/1bc63aca70a3258876befa7db6aeb8e6e05cee87/pkg/operator/workload/workload_openshiftapiserver_v311_00_sync.go#L396
There was a problem hiding this comment.
@deads2k Is there a point to tracking the generation if ApplyDeployment sets the deployment spec as an annotation?
|
@jsafrane can we remove operand and operator image version checks then? |
|
namely - https://github.com/openshift/aws-ebs-csi-driver-operator/blob/master/pkg/operator/operator.go#L45 if we are not going to use them. We also need to update the CSV |
Maybe we can remove the operand check. I would keep the operator check in place - a new operator version may introduce changed assets in its bindata and we should apply them. |
|
Talked on Slack with @deads2k and @marun, some operators add "configuration" that was used to render the required Deployment to the Deployment.Annotations
|
|
@jsafrane if I understand this correctly, are we planning to store all the imagePullSpec or just of the operator based on the fact that if operand image changes, operator image changes too? |
|
I can get behind generating SHA of spec too, because that way we may not have to track each operand individually.. |
Sounds like an elegant solution to what we need. Even if some spec fields are changed/defaulted by the apiserver, the hash won't change and |
|
I have a PR up if you want to test with it: openshift/library-go#773 |
pkg/operator/sync.go
Outdated
| if daemonSet.Annotations == nil { | ||
| daemonSet.Annotations = map[string]string{} | ||
| } | ||
| daemonSet.Annotations[specHashAnnotation] = specHash |
There was a problem hiding this comment.
I'd suggest moving this to the getDaemonSet() function down below (`getDeployment() for the deployment). So far we've been "patching" the objects only in those functions.
There was a problem hiding this comment.
I expect the hashing to be done by ApplyDaemonSet soon, so I want to keep it close.
pkg/operator/sync.go
Outdated
| return deployment | ||
| } | ||
|
|
||
| func (c *csiDriverOperator) containerImagesNeedsUpdate(actual, required *corev1.PodSpec) bool { |
08260ab to
c88c792
Compare
|
Fixed unit tests with a bit of refactoring. |
c88c792 to
8bf45f3
Compare
|
Squashed and updated commit message. |
The operator may need to update the operands (Deployment, DaemonSet) when: - The images are changed by env. variables. - Log level changes in CR. - New operator starts and has updated bindata. It's nearly impossible to detect these changes, therefore hash whole Deployment / DaemonSet .Spec and make sure the new objects are applied when the hash gets different.
8bf45f3 to
94e62f1
Compare
| needApply := forceRollout | ||
| if existing.GetGeneration() != expectedGeneration { | ||
| needApply = true | ||
| } |
There was a problem hiding this comment.
Do we need to check the generation if we're checking the spec hash?
There was a problem hiding this comment.
Yes, we need both hash and generation. Spec hash checks for changes in the operator (new images, new bindata, ...). Generation checks for changes in the cluster (user changing the object).
|
Onde minor comment, otherwise LGTM. |
pkg/operator/credential_request.go
Outdated
| } | ||
|
|
||
| crClient := client.Resource(credentialsRequestResourceGVR).Namespace(required.GetNamespace()) | ||
| if err := addCredetialsRequestHash(required); err != nil { |
94e62f1 to
6a9a02a
Compare
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: gnufied, jsafrane The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
The operator may need to update the operands (Deployment, DaemonSet) when:
It's nearly impossible to detect these changes, therefore hash whole Deployment / DaemonSet .Spec and make sure the new objects are applied when the hash gets different.
cc @bertinatto @gnufied