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

let patch use --local flag like kubectl set image #26722

Merged
merged 1 commit into from Jun 25, 2016

Conversation

deads2k
Copy link
Contributor

@deads2k deads2k commented Jun 2, 2016

Adds the concept of a --local flag to kubectl patch. This flag is similar to kubectl set image -f --local because it will use the content of the file as the input to the patch operation instead of using the file content to file resource/name tuples.

This pull lets you run something like kubectl create deployment --dry-run -o yaml | kubectl set volume --local -f - -o yaml | kubectl patch --local -f - --patch {} | kubectl create -f -

As proof that it works, you can run against a local file just to mess around with it, but --local -f - is the most likely case.

$kubectl patch --local -f pkg/api/validation/testdata/v1/validPod.yaml --patch='{"spec": {"restartPolicy":"Never"}}'
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    name: redis-master
  name: name
spec:
  containers:
  - args:
    - this
    - is
    - an
    - ok
    - command
    image: gcr.io/fake_project/fake_image:fake_tag
    name: master
    resources: {}
  restartPolicy: Never
status: {}

This is useful for setting rarely used, but immutable fields from kubectl create or kubectl convert without dropping to an interactive editor.

Some discussion here: #21648 (comment)

@smarterclayton @kubernetes/kubectl
@eparis @soltysh @stevekuznetsov we've talked about this separately

@k8s-github-robot k8s-github-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. release-note-label-needed labels Jun 2, 2016
@fabianofranz
Copy link
Contributor

So this is mutually exclusive with -f and kind/name arg, right? Needs to reflect that in the command usage.

@fabianofranz
Copy link
Contributor

I'd like to somehow make it more clear that if you specify that flag, you are applying the patch to the local file, a different behavior in comparison to --filename which is read-only to apply the patch on the server. I'd suggest the flag name to be like --to-local-file=, --patch-in= or something similar. We also probably need to add a reference in the long desc.

@smarterclayton
Copy link
Contributor

Why would we patch the local file? We shouldn't write our inputs ever.

On Thu, Jun 2, 2016 at 2:42 PM, Kubernetes Bot notifications@github.com
wrote:

GCE e2e build/test passed for commit 3e1f6dc
3e1f6dc
.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#26722 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ABG_p1_azqlvu9dat-2xuUbA3zEK3xyDks5qHyQIgaJpZM4Is0Qz
.

@@ -175,3 +228,24 @@ func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
}
return nil
}

func getPatchedJS(patchType api.PatchType, originalJS, patchJS []byte, obj runtime.Object) ([]byte, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not getting a patched JavaScript so I feel like the method could be two letters longer

@deads2k
Copy link
Contributor Author

deads2k commented Jun 2, 2016

Why would we patch the local file? We shouldn't write our inputs ever.

@smarterclayton That was an example to prove that it works. The actual use-case runs more like kubectl create deployment --dry-run -o yaml | kubectl set volume --localfile - -o yaml | kubectl patch --local-file - --patch {} | kubectl create -f -

@deads2k
Copy link
Contributor Author

deads2k commented Jun 2, 2016

I'd like to somehow make it more clear that if you specify that flag, you are applying the patch to the local file, a different behavior in comparison to --filename which is read-only to apply the patch on the server. I'd suggest the flag name to be like --to-local-file=, --patch-in= or something similar. We also probably need to add a reference in the long desc.

This is still read-only to the file. It's using it for input and outputing to stdout. I don't think we'd support something like sed -i, since this is more interesting in chained cases from kubectl create <subcommand> -o yaml | kubectl patch --local-file -. Files on disk were my example to prove that it worked.

@fabianofranz
Copy link
Contributor

Oh, I got the purpose now, sorry.

I have mixed feelings then. Both the input and the output are different than the default behavior.

Input: instead of using it to identify the resources (with either tuples in -f or kind/name) you use it to provide the entire object content.

Output: instead of performing a patch you just print it, like --dry-run in a number of other commands.

Let me think a bit, but why couldn't you still use -f and do something like

$kubectl patch -f path/to/validPod.yaml --from-local-file --dry-run --patch='{"spec": {"restartPolicy":"Never"}}'

And you could combine it with --output to choose how to print it (json or yaml).

@deads2k
Copy link
Contributor Author

deads2k commented Jun 2, 2016

Updated the description to make it more clear that the primary case is for chaining from other commands, not messing around with files on disk.

@fabianofranz
Copy link
Contributor

Which is pretty much what you are saying, but use --dry-run to decide about just printing instead of performing the patch, and --output to decide about how to print it.

@bgrant0607
Copy link
Member

@deads2k Why "local-file"? That's very unintuitive to me.

@bgrant0607
Copy link
Member

@deads2k I highly value precedent and convention. They help users build a mental model of how the system works and to speculate and remember how to use numerous features -- remember the patterns, not just the specifics.

What is similar? Template files.
https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/resource_printer.go#L85

I'd say a --patch-file option should replace --patch entirely.

What other commands need something like this?

@bgrant0607 bgrant0607 assigned janetkuo and unassigned bgrant0607 Jun 3, 2016
@bgrant0607
Copy link
Member

cc @caesarxuchao, since he's worked on patch

@deads2k
Copy link
Contributor Author

deads2k commented Jun 3, 2016

What other commands need something like this?

label, annotate, scale, set <subcommand> are the high value ones that I can think of. Allowing those commands to pipe cleanly will enable natural flows. The first time a user works with it, they'll probably do a kubectl create something, then later a kubectl set volume or some such. After a few tries, they'll then try to build a piped flow to create it in one shot: kubectl create something -o yaml | kubectl set volume --local-file - | kubectl create -f -.

Allowing pipes like this will make it easy to make something (minimal flags on create), easy to modify it (our existing mutation commands), and easy to transition to a compositional flow (--local-file). Using composition will keep each individual command relatively small.

@lavalamp
Copy link
Member

lavalamp commented Jun 3, 2016

We've spent a fair amount of effort moving things out of kubectl so they'll be available to all clients, so I'm only on board with this if it's a specific interface that only makes sense for users of kubectl.

I agree that --local-file is clumsy. -f means "input file" for most of our commands so, how about an --output or -o flag instead-- default "" would mean to server, but passing '-' would mean write to stdout.

@lavalamp
Copy link
Member

lavalamp commented Jun 3, 2016

I also agree that a templating system has significant benefits. Templates can be versioned & upgraded, and I expect them to be much more readable and maintainable than imperative chains of kubectl calls. Basically the | chain looks like a big anti pattern to me, I'd be very unhappy to inherit an application deployment that was created that way.

@deads2k
Copy link
Contributor Author

deads2k commented Jun 3, 2016

Basically the | chain looks like a big anti pattern to me, I'd be very unhappy to inherit an application deployment that was created that way.

I'm not envisioning this as a way to build a script. I'm seeing it as a way to progress from "I know a few bits of this system" to "I speak runtime.Object json" without having to take a big leap.

I think the most obvious usage is probably kubect create <resource> -o yaml | kubectl set <specific thing with tailored flags> --local-file - | kubectl create -f -. -f in our normal pattern doesn't work for this, since -f means "pull resource/name tuples and get resources from the server", not "read this file and use it for input". kubectl patch just happened to be the one I wanted yesterday.

@caesarxuchao
Copy link
Member

If this pipe line syntax is not intended to build a script, then I guess editing the config in an interactive editor doesn't seem to be any worse than typing such a long command.

@eparis
Copy link
Contributor

eparis commented Jun 3, 2016

I kinda feel like
kubectl set -f - --local
fits the systems better than
kubectl set --local-file -

@eparis
Copy link
Contributor

eparis commented Jun 6, 2016

I should say I do like -o or --output or --out-file or something...

@smarterclayton
Copy link
Contributor

I don't think we should override -o because you may want JSON or YAML
output in this behavior. I agree with --local in that it's a natural step
for the use case the user will use.

On Mon, Jun 6, 2016 at 9:00 AM, Eric Paris notifications@github.com wrote:

I should say I do like -o or --output or --out-file or something...


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#26722 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ABG_p8b9LpL4O5Q9LhCKPeQ1dWskSlA2ks5qJBnzgaJpZM4Is0Qz
.

@smarterclayton
Copy link
Contributor

It may look like an anti pattern, but the alternative is sed, which I think
is a worse anti pattern. We see this coming up fairly often in real use
cases from ops teams (they want to create something, but mutate it), and
they want to use the generator pattern to handle simple cases. Forcing
them into a full templated API object is a big step, and defeats the
purpose of generators (which is to form small APIs for common use cases).

On Fri, Jun 3, 2016 at 3:11 PM, Daniel Smith notifications@github.com
wrote:

I also agree that a templating system has significant benefits. Templates
can be versioned & upgraded, and I expect them to be much more readable and
maintainable than imperative chains of kubectl calls. Basically the | chain
looks like a big anti pattern to me, I'd be very unhappy to inherit an
application deployment that was created that way.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#26722 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ABG_p4Z_xvXACxjHSwtYnRvynu_lHGVJks5qIHxegaJpZM4Is0Qz
.

@janetkuo
Copy link
Member

janetkuo commented Jun 8, 2016

I kinda feel like
kubectl set -f - --local
fits the systems better than
kubectl set --local-file -

FWIW we already have kubectl set image -f --local in the system

@deads2k
Copy link
Contributor Author

deads2k commented Jun 9, 2016

FWIW we already have kubectl set image -f --local in the system

Great, I'll update to that when I'm back on Monday.

@deads2k deads2k changed the title [POC] let patch use local file content to mutate let patch use --local flag like kubectl set image Jun 14, 2016
@deads2k
Copy link
Contributor Author

deads2k commented Jun 14, 2016

Updated to --local to match kubectl set image and test added. Also updated the output flags to allow encoding choices.

@0xmichalis
Copy link
Contributor

LGTM

@0xmichalis 0xmichalis added lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. and removed release-note-label-needed labels Jun 15, 2016
@k8s-bot
Copy link

k8s-bot commented Jun 21, 2016

GCE e2e build/test passed for commit ac64404.

@janetkuo janetkuo added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-none Denotes a PR that doesn't merit a release note. labels Jun 24, 2016
@janetkuo
Copy link
Member

this deserves a release note

@k8s-bot
Copy link

k8s-bot commented Jun 25, 2016

GCE e2e build/test passed for commit ac64404.

@k8s-github-robot
Copy link

@k8s-bot test this [submit-queue is verifying that this PR is safe to merge]

@k8s-bot
Copy link

k8s-bot commented Jun 25, 2016

GCE e2e build/test passed for commit ac64404.

@k8s-github-robot
Copy link

Automatic merge from submit-queue

@k8s-github-robot k8s-github-robot merged commit 951b591 into kubernetes:master Jun 25, 2016
@deads2k deads2k deleted the local-patch branch September 6, 2016 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet