-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Observe command #4196
Observe command #4196
Conversation
Why not make
or even
You'll never have enough builtin matchers and processors to keep people happy, just punt the whole thing to UNIX tools. |
Because sync is fundamentally different than regular update - I think there So sync should probably be a batch operation (or at least have begin and However, I did intend to have the formatting to STDOUT so that someone On Mon, Aug 17, 2015 at 12:56 PM, Tim Hockin [email protected]
Clayton Coleman | Lead Engineer, OpenShift |
I don't follow. You're writing a CLI tool so people can do controller-like things outside of the core code. Whether they choose to script in bash, python, perl, or whatever - a universal interface is "here is a piece of text structured in a way we agree on". Having the I am not sure what you mean by "should probably be a batch operation". Is there atomicity that matters? The beauty of a watch stream is that it is sequential - you start with a state dump and you process discrete mutations to that state, in series. What value does a begin/end marker offer other than information? why not make a new meta-field for update-transaction-number and prefix every output line?
|
Actually, how is this different than |
There's a difference between "trivial to implement for Tim Hockin" and As an example, consider the "for every PVC that comes in, dynamically The naive implementation is "for every PVC that is unbound, there should be So I'm approaching this from the perspective of yes, you could go do On Mon, Aug 17, 2015 at 4:07 PM, Tim Hockin [email protected]
Clayton Coleman | Lead Engineer, OpenShift |
I'm also not saying that I want to take away the simple thing - but even On Mon, Aug 17, 2015 at 4:51 PM, Clayton Coleman [email protected]
Clayton Coleman | Lead Engineer, OpenShift |
So this is |
So this command is intended to solve "allow someone to build a controller Are you saying you think the approach of providing an interface (commands My goal is: I think if you need to write a bash script with looping, extensive timeout On Aug 17, 2015, at 5:18 PM, Tim Hockin [email protected] wrote: So this is get -w with more specific semantics for control-loops? Fine. I — |
Also I want to be able to avoid deep conditional logic in the bash code as much as possible by offering helpers that can do hard stuff |
No, I just want to make sure that the plumbing is sufficient to handle Can you sketch a script (pseudocode is fine) using this feature that On Mon, Aug 17, 2015 at 2:56 PM, Clayton Coleman [email protected]
|
|
||
// add additional arguments / info to the server | ||
cmd.Flags().StringVar(&options.templateType, "use", options.templateType, "Format for template arguments. jsonpath and gotemplate are supported.") | ||
cmd.Flags().BoolVar(&options.strictTemplates, "strict-templates", false, "If true return an error on any field or map key that is not missing in a template.") |
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 still don't think that I want to have a "make it fail" option. An env var indicating the failure ought to be sufficient.
cmd.Flags().StringVar(&options.objectEnvVar, "object-env-var", "", "The name of an env var to serialize the object to when calling --each, optional.") | ||
|
||
// control retries of individual commands | ||
cmd.Flags().IntVar(&options.maximumErrors, "maximum-errors", options.maximumErrors, "Exit after this many errors have been detected with. May be set to -1 for no maximum.") |
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 think so. I think you're in a pod, and if you hit enough errors
you restart. There is no sliding window that will work for all users. We
could do % for sync but it wouldn't have any meaning after sync. In
practice, your scripts should never error. If you're erroring, you want to
restart.
10 errors out of 20 attempts is a lot different than 10 errors out of 20,000 attempts. Having one value is silly.
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.
The point of this is to get you to fix your bugs. The worst outcome to me
is you have a lot of uncovered edge cases and you never discover it because
you don't look at your logs. The best outcome is by default you get a nice
error "hey, you hit too many errors, maybe you should think about fixing
your stuff". I am worried about hitting the limit on sync and not getting
through the whole list (so maybe we can defer the exit until after the
first sync is complete). OTOH if you have > 50 items and you fail the first
twenty I don't see much point to continuing.
I think of this as gamifying error handling - you are a new user, we will
gently nudge you to do things that handle errors, without trying to
surprise you.
On Tue, Aug 30, 2016 at 3:52 PM, David Eads [email protected]
wrote:
In pkg/cmd/cli/cmd/observe/observe.go
#4196 (comment):
- // the commands to execute on changes
- cmd.Flags().VarP(&options.eachCommand, "each", "e", "A command to run for each change. Specify mulitple times to add arguments.")
- // to perform deletion synchronization
- cmd.Flags().VarP(&options.deleteCommand, "delete", "d", "A command to run when resources are deleted. Specify mulitple times to add arguments.")
- cmd.Flags().Var(&options.nameSyncCommand, "names", "A command that will list all of the currently known names, optional. Specify multiple times to add arguments. Use to get notifications when objects are deleted.")
- // add additional arguments / info to the server
- cmd.Flags().StringVar(&options.templateType, "use", options.templateType, "Format for template arguments. jsonpath and gotemplate are supported.")
- cmd.Flags().BoolVar(&options.strictTemplates, "strict-templates", false, "If true return an error on any field or map key that is not missing in a template.")
- cmd.Flags().VarP(&options.templates, "argument", "a", "Template for the arguments to be passed to each command in the format defined by --use.")
- cmd.Flags().StringVar(&options.typeEnvVar, "type-env-var", "", "The name of an env var to set with the type of event received ('Sync', 'Updated', 'Deleted', 'Added') as the first argument to the --each command.")
- cmd.Flags().StringVar(&options.objectEnvVar, "object-env-var", "", "The name of an env var to serialize the object to when calling --each, optional.")
- // control retries of individual commands
- cmd.Flags().IntVar(&options.maximumErrors, "maximum-errors", options.maximumErrors, "Exit after this many errors have been detected with. May be set to -1 for no maximum.")
I don't think so. I think you're in a pod, and if you hit enough errors
you restart. There is no sliding window that will work for all users. We
could do % for sync but it wouldn't have any meaning after sync. In
practice, your scripts should never error. If you're erroring, you want to
restart.10 errors out of 20 attempts is a lot different than 10 errors out of
20,000 attempts. Having one value is silly.—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/openshift/origin/pull/4196/files/d21d6896f2faeac799f81a73286a7821db37b0d4#r76866832,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABG_p_sCJ3E5qT64tInJ1Fmp0aecYoRuks5qlIoAgaJpZM4Fsaph
.
About the env vars. I don't see us ending up in a place where this command still make sense, but a watch on a resource doesn't have:
Why would I make a user explicitly opt-in (maybe even have to describe it using templates) and end up with scripts that each use slightly different values? Seems like that's just making it hard to work with. |
41aa0ff
to
b4d4f52
Compare
For those things you mentioned each of them is in the JSON. I think JSON as env var is best (any advanced case do what you want in your script). The only other field you can't get at is type, so that's an env var as well. |
Changed --use to --output, but made -a behave like --template. It's really No other changes outstanding. On Wed, Aug 31, 2016 at 4:57 PM, OpenShift Bot [email protected]
|
[test] On Wed, Aug 31, 2016 at 8:02 PM, OpenShift Bot [email protected]
|
[test] On Thu, Sep 1, 2016 at 12:27 AM, OpenShift Bot [email protected]
|
[test] |
The 'observe' command tracks changes to objects and invokes a named script each time the object is updated. The command can also assist users in building external integrations by assisting in reconciling differences between data recorded in one resource and data recorded in an external system. See the help documentation for more.
Makes it easier to try on Kubernetes.
Evaluated for origin test up to 185e992 |
continuous-integration/openshift-jenkins/test SUCCESS (https://ci.openshift.redhat.com/jenkins/job/test_pr_origin/8648/) |
[merge] for great justice |
continuous-integration/openshift-jenkins/merge SUCCESS (https://ci.openshift.redhat.com/jenkins/job/test_pr_origin/8648/) (Image: devenv-rhel7_4972) |
Evaluated for origin merge up to 185e992 |
Based in part on kubernetes/kubernetes#5164
It should be easy for a third party to build a "controller" - a loop that iterates over all Kubernetes or OpenShift resources and invokes a script to maintain an invariant. It should also be easy for a third party to understand the implications of building a controller - there are many hard edge cases that users should be exposed to gradually.
This PR adds the
observe
command tooc
. It takes a resource type and a flag to apply to the current namespace or all namespaces and then creates a DeltaFIFO that watches those resources. By default, the user gets only updates and adds, and cannot sync on deletes. The user can provide a--names
command to handle external synchronization and handle deletes via a--delete
command.The
--each
command is invoked once for each resource. By default it takes namespace and name as the first two arguments, and a user can specify additional arguments with-a
in JSONPath or Go template format. An admin can get the specific type via an env var by specifying--type-env-var
. The admin can also use the--object-env-var
flag to specify an env var that will contain the full serialized JSON of the object.Two examples are described in the help - future examples will be created that demonstrate more complex scenarios.
The process exposes a health check, readiness check, and metrics for exec duration. By default the loop terminates with a non-zero exit code after 20 errors are encountered, which forces admins to handle poorly performing loops and surfaces them up in their intended use (as controllers in pods).
Todo:
examples/observer