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
First pass at last_operation description proposal #537
First pass at last_operation description proposal #537
Conversation
|
@rthallisey As per discussion on the issue, I have made an attempt at a proposal here to implement last operation description. Any feedback welcome when you get a chance |
|
|
||
|
|
||
| ## Proposed Implementation | ||
| Create an append only log file in a specified location ```/var/log/last_operation```, which is collected periodically and also a final time after |
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.
terms:
final operation - the operation that indicates the apb is 100% complete
last_operation - the most recent operation an apb performed
One thing I like about waiting to collect the final operation is that we know the apb is complete. That might come in handy with dependencies. On the other hand, does the broker really need the final operation if it's only a description? How do you view the importance of the final operation?
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.
Thank you for this proposal. I really like this idea. I think it would be better implemented by manipulating the Pod's annotations rather than relying on log files and exec'ing into containers.
| ## Proposed Implementation | ||
| Create an append only log file in a specified location ```/var/log/last_operation```, which is collected periodically and also a final time after | ||
| the apb has completed but before the pod is deleted. | ||
| In the bind workflow, we already do something similar by execing into the container in order to collect |
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.
I'm wondering if all of this is possible without using a file inside the APB container. Kubernetes already has a downward API for exposing things like Pod Name and Pod Namespace combined with Kubernetes annotations means that we could simply have an annotation(s) for last_operation and final_operation available through API calls w/o needing to exec.
$ kubectl annotate pods asb-1-h597s last_operation='Last operation added'
pod "asb-1-h597s" annotated
$ kubectl get pods asb-1-h597s -o go-template='{{ .metadata.annotations.last_operation }}'
Last operation added%
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.
@djzager Interesting that you mention the annotations approach. This was something I also thought about. I shied away from it as the file approach seemed more fitting given the pod was already being exec'd into. I agree though this could be a simpler approach, particularly taking into account using the downward API to inform the apb.
Curious on your thoughts about using a watch while the pod was executing, would this be a reasonable way to pick up updates to the annotations in the broker?
I will rework the proposal to make use of the downward API and pod annotations.
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.
So, the APB pod that is running would add annotations on itself?
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.
Yes that is my understanding. I believe the apb module could make this transparent to the apb developer
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.
I like the idea of using watch, unfortunately this is where I get a little fuzzy with how the broker handles the provision/deprovision jobs, their associated channels, and writing state information to etcd. My immediate impression is that we may need to make some changes to the broker in order to support additional status changes if we are going to write the last_operation to etcd.
You may be able to get by with handling the in progress state with an associated request for the last_operation annotation on the pod when the service catalog is asking for the last operation.
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.
I am wondering if using the labels instead of the annotation might make more sense. I don't fully understand the difference but just starting the discussion.
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.
I am a bit hazy on the difference also. However I know labels are used as selectors etc and for querying via the client. Whereas I have often seen annotations used for specific meta data for example https://github.com/openshift/origin/blob/master/examples/quickstarts/cakephp-mysql-persistent.json#L11
So I think that in this case annotations would make more sense.
Although, perhaps just keys in the metadata as this one is https://github.com/openshift/origin/blob/master/examples/quickstarts/cakephp-mysql-persistent.json#L18
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.
A question on this approach: If we go with the watch on the pod, I am wondering would it at some point also make sense to do the same thing for the credentials from a bind. Rather than execing into the pod, have the pod create a secret in the pods namespace and have the broker watch for secrets in that namespace.
Obviously this is separate from this work but it could be a good paradigm to use for these kind of interactions? I can create a separate issue for this to discuss further.
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.
I don't know the security impact, if at all, of the apb creating a secret and populating it. But, I think it's a good idea. The broker could also create it and the apb populate it. There are a few avenues we could take here. We'll have to explore this separately.
So I think that in this case annotations would make more sense.
+1 for annotations. I think labels are meant for kubernetes services identifying other kubernetes services.
Curious on your thoughts about using a watch while the pod was executing, would this be a
reasonable way to pick up updates to the annotations in the broker?
If the broker watches the resource, it should allow us to always get the final operation because the logic will exist in the broker. We can grab the final operation right before the namespace is cleaned up. +1
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.
I agree with the comments about looking into a better approach than adding another exec.
|
@djzager we may need an experiment with the annotations to see if that is something we can definitely do. |
|
I'm assuming this is what we're talking about: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ |
|
@jmrodri yes that is what we're talking about |
|
It would be nice if I could thread conversations. I'm working on an experiment for you @jmrodri by creating a broker that passes the |
|
I thought there was some way to pull this data from the pod, I know namespace is possible, but pod name might be a little harder |
|
You may have heard me celebrating @shawn-hurley that this worked. |
|
I'm actually genuinely surprised that it was this easy and it worked on the first And then I created a custom hello-world-apb whose last step was to annotate itself: Then I ran the apb, keeping the namespace after completion: 🕺 |
|
@djzager so would an apb be annotating itself regularly? Like if I'm giving status of my installation, will I have to call that annotation multiple times? What are the restrictions for the status or annotation fields? With the logfile approach, we can put ANYTHING in there. So I'd want to be able to get as much information as possible. Also, will annotations overwrite themselves? Say the apb writes 50%, then 60%, then 70%, then 80%. We only see the 50 and 80 because we didn't catch the 60 and 70 in time. Could this happen? I like the changes, just want to see what the gotchas will be if any. |
|
@shawn-hurley you mentioned "pull this data". Are you wondering if there is a need to have the apb annotate itself for the name, etc? |
|
@jmrodri I was referring to being able to use the known location of |
An apb could be annotating itself as often as it wants, my guess is that we would want to support annotations like
Annotations are unstructured key:value pairs so we could put whatever we want in there but I think simpler the better.
Everytime we update the annotation field (ie. |
I only ask in order to set expectations. I can see bugs being written against this when the progress goes from 0 to 100% because we missed the 2 operations in between. The workflow would be service-catalog is polling the broker's My original concern might not be a problem there are enough latency in this whole work flow from the polling of the last_operation endpoint to the watching interval down to time it takes for apb to update status. I think it will be okay if we miss a few. Also, getting some status is better than what we have today, NO STATUS! |
I think going the asb module route also makes a lot of sense. That module could then handle retrieving the values of those annotations and then updating the value by appending to the existing one. Ensuring an append only log. One thing I think we should discuss is error scenarios. Is there a common or best way to "trap" an error during the apb execution to allow the developer to add some context and update the log before the apb exits? |
We could when going the I say this because it seems appropriate for us to be reporting the |
|
@djzager Yeah I see where you are coming from, and strictly speaking I think you are correct, it should be the last operation only. The concern I would have then is around consistency, as mentioned in previous comment, you could potentially get very different feedback depending on the the timings of the polling. |
|
I will wait to update the proposal until we iron out these different pieces |
I think it's going to be hard to expect consistency from last_operation because the description field can be anything. It's plain text so we're not requiring a percentage or anything, but it gives the user a way to demonstrate progress that is meaningful to them. So to me, it doesn't matter if we're missing any messages because the description isn't guaranteed to be a definition of state. Here are a summary of my expectations:
|
|
Ok this sounds like a good definition. Based on the thumbs up looks like there is agreement, so I think I can proceed with an update to the proposal based on the conversations here.
I am away next week so it may be after next week before I complete it |
e4e54cc
to
603e07d
Compare
|
Updated proposal based on discussions here |
|
Changes Unknown when pulling 603e07d on maleck13:proposal-last-operation-description into ** on openshift:master**. |
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.
Looking pretty good to me. A bunch of nitpicks and a few meaningful requests for you.
| - The last_operation demonstrates APB progress. | ||
| - No restrictions or requirements for user to demonstrate APB progress. | ||
| - No guarantee that last_operation shows every operation. | ||
| - The final_operation is the last_operation gathered before the APB is deleted. |
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.
deleted completes
|
|
||
| **Last Operation:** the most recent operation an apb performed | ||
|
|
||
| **Final operation:** the operation that indicates the apb is 100% complete |
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.
oOperation
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.
I'd also recommend lining this up with the expectations, `Final Operation: the last operation before APB completed.
|
|
||
| ## Terms | ||
|
|
||
| **Last Operation:** the most recent operation an apb performed |
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.
nit: strings.ToUpper("apb"), I see this elsewhere
|
|
||
| ```go | ||
|
|
||
| wi, err := k8client.CoreV1().Pods(ns).Watch(meta_v1.ListOptions{}) |
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 wasn't immediately obvious to me how to accomplish this, nice.
| - Modify the existing provision and deprovision subscribers along with the corresponding work messages. | ||
| A namespace field would be added to these messages as the pod name is already present. | ||
| Inside the subscriber, the go routine to watch the pod and update the JobStatus would start when a new work msg was recieved. | ||
| This routine would stop once the a deleted change was received in the watch. |
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.
nit: This routine would stop once the a deleted change was received in the watch.
|
|
||
| - Modify last operation handler to pull the description out of the Job state and send it back as part of the response. | ||
|
|
||
| ### APB changes |
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.
Actually don't think that you are targeting the APB specifically here, more the underlying ansible-asb-modules. I don't think that you would be putting the last operation on disk, you should just modify the running pod's annotation directly with the new asb_last_operation_description.
| Something like the following may make sense: | ||
|
|
||
| ``` | ||
| asb_last_operation_description: |
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 applies to both new ansible-asb-module actions, _description from the name.
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.
👍
|
|
||
| In order to collect this information we would use a watch via the Kubernetes client on the pod resource within the temporary namespace [Pod Rest API](https://docs.openshift.com/container-platform/3.5/rest_api/kubernetes_v1.html#list-or-watch-objects-of-kind-pod). | ||
| This would allow us to react to changes made (i.e to the annotations) on Pod Object. Whenever a change occurred, an update to the JobStatus would happen. If the ```apb_final_operation``` annotation is present this would take precedence over the last_operation annotation. | ||
| Once the pod was deleted we would stop the watch on the pod and update the JobStatus ```final_operation``` annotation value. |
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.
Do we need two annotations? If the pod completes, the final_operation = last_operation. Since we're watching the pod anyway, we'll know when it's complete. That will allow us to get both data points with a single annotation.
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.
Right that's actually a good point, and simplifies things further. I will update based on this
603e07d
to
8e4dc8f
Compare
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.
LGTM, one nit
| description:"10%: creating deployment and routes" | ||
| ``` | ||
|
|
||
| ***Note not very familiar with how the ansible apb modules wors under the hood so would need some guidance here*** |
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.
nit: worsworks
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.
ansibleplaybookbundle/ansible-asb-modules#8 actually has an example for you of using the kubernetes API to create a secret. If you need any more guidance, I think I can help you out.
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.
Nice job Craig
|
Changes Unknown when pulling 8e4dc8f on maleck13:proposal-last-operation-description into ** on openshift:master**. |
8e4dc8f
to
55ded73
Compare
|
Fixed the typo. Thanks for the help guys. I am hoping to start looking at implementation next week. However we have a lot going at the moment with the mobile next project as we have finished our PoC and are planning for tech preview, so I will have to see how things pan out. |
|
Changes Unknown when pulling 55ded73 on maleck13:proposal-last-operation-description into ** on openshift:master**. |
|
@jmrodri @rthallisey After spending sometime looking at the implementation of this, I have a question about the subscribers and the role they play, in particular the setting of the JobState. Does it make sense for these subscribers to set the JobState or would it make sense to change the jobs to have access to the DAO and set the JobState directly? |
|
One of the reasons behind subscribers was async, where the work and the state handling are two separate threads. A second thing about subscribers is that it makes a general API for an $action that handles all its logging and its DAO connection. This may come in handy later with the recent discussion in the community about making the broker a more general API. I think for now we should keep it as is. We can always change it down the road. |
Describe what this PR does and why we need it:
Proposal to allow APBs to write a last operation description and have the broker collect and return it as part of the last_operation API
Which issue this PR fixes (This will close that issue when PR gets merged)
#475
Note
While I am becoming more familiar with the broker code, I am still very new to the code base so would appreciate an feedback on the approach outlined here.
On the APB side I would need to investigate the code in order to better understand how we could add a module to allow writing to the log file.