From 9ab06cfa623307e79436e0df7278514767adc1af Mon Sep 17 00:00:00 2001 From: feihujiang Date: Thu, 10 Dec 2015 10:36:25 +0800 Subject: [PATCH] Support remove flag for kubectl run command --- contrib/completions/bash/kubectl | 1 + docs/man/man1/kubectl-run.1 | 4 +++ docs/user-guide/kubectl/kubectl_run.md | 3 ++- pkg/kubectl/cmd/run.go | 34 ++++++++++++++++++++++++-- test/e2e/kubectl.go | 19 ++++++++++++++ 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/contrib/completions/bash/kubectl b/contrib/completions/bash/kubectl index 433960d95b..cf9ac92b5a 100644 --- a/contrib/completions/bash/kubectl +++ b/contrib/completions/bash/kubectl @@ -1163,6 +1163,7 @@ _kubectl_run() two_word_flags+=("-r") flags+=("--requests=") flags+=("--restart=") + flags+=("--rm") flags+=("--save-config") flags+=("--service-generator=") flags+=("--service-overrides=") diff --git a/docs/man/man1/kubectl-run.1 b/docs/man/man1/kubectl-run.1 index fb5555e7ae..bea0069e3b 100644 --- a/docs/man/man1/kubectl-run.1 +++ b/docs/man/man1/kubectl-run.1 @@ -96,6 +96,10 @@ Creates a replication controller or job to manage the created container(s). \fB\-\-restart\fP="Always" The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a replication controller is created for this pod, if set to OnFailure or Never, a job is created for this pod and \-\-replicas must be 1. Default 'Always' +.PP +\fB\-\-rm\fP=false + If true, delete resources created in this command for attached containers. + .PP \fB\-\-save\-config\fP=false If true, the configuration of current object will be saved in its annotation. This is useful when you want to perform kubectl apply on this object in the future. diff --git a/docs/user-guide/kubectl/kubectl_run.md b/docs/user-guide/kubectl/kubectl_run.md index ca244d573b..f9ae2831e1 100644 --- a/docs/user-guide/kubectl/kubectl_run.md +++ b/docs/user-guide/kubectl/kubectl_run.md @@ -101,6 +101,7 @@ $ kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'pri -r, --replicas=1: Number of replicas to create for this container. Default is 1. --requests="": The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi' --restart="Always": The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a replication controller is created for this pod, if set to OnFailure or Never, a job is created for this pod and --replicas must be 1. Default 'Always' + --rm[=false]: If true, delete resources created in this command for attached containers. --save-config[=false]: If true, the configuration of current object will be saved in its annotation. This is useful when you want to perform kubectl apply on this object in the future. --service-generator="service/v2": The name of the generator to use for creating a service. Only used if --expose is true --service-overrides="": An inline JSON override for the generated service object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field. Only used if --expose is true. @@ -143,7 +144,7 @@ $ kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'pri * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra on 24-Nov-2015 +###### Auto generated by spf13/cobra on 14-Dec-2015 [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_run.md?pixel)]() diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index 429abef094..b6f9ae9021 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -92,6 +92,7 @@ func addRunFlags(cmd *cobra.Command) { cmd.Flags().String("image", "", "The image for the container to run.") cmd.MarkFlagRequired("image") cmd.Flags().IntP("replicas", "r", 1, "Number of replicas to create for this container. Default is 1.") + cmd.Flags().Bool("rm", false, "If true, delete resources created in this command for attached containers.") cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.") cmd.Flags().String("overrides", "", "An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field.") cmd.Flags().StringSlice("env", []string{}, "Environment variables to set in the container") @@ -135,7 +136,6 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob if err != nil { return err } - restartPolicy, err := getRestartPolicy(cmd, interactive) if err != nil { return err @@ -180,6 +180,7 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob if err != nil { return err } + attachFlag := cmd.Flags().Lookup("attach") attach := cmdutil.GetFlagBool(cmd, "attach") @@ -187,6 +188,11 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob attach = true } + remove := cmdutil.GetFlagBool(cmd, "rm") + if !attach && remove { + return cmdutil.UsageError(cmd, "--rm should only be used for attached containers") + } + if attach { opts := &AttachOptions{ In: cmdIn, @@ -213,7 +219,31 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob if err != nil { return err } - return handleAttachPod(f, client, attachablePod, opts) + err = handleAttachPod(f, client, attachablePod, opts) + if err != nil { + return err + } + + if remove { + namespace, err = mapping.MetadataAccessor.Namespace(obj) + if err != nil { + return err + } + var name string + name, err = mapping.MetadataAccessor.Name(obj) + if err != nil { + return err + } + _, typer := f.Object() + r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). + ContinueOnError(). + NamespaceParam(namespace).DefaultNamespace(). + ResourceNames(mapping.Resource, name). + Flatten(). + Do() + return ReapResult(r, f, cmdOut, true, true, 0, -1, false, mapper) + } + return nil } outputFormat := cmdutil.GetFlagString(cmd, "output") diff --git a/test/e2e/kubectl.go b/test/e2e/kubectl.go index 5a612450f4..e966d7ad3d 100644 --- a/test/e2e/kubectl.go +++ b/test/e2e/kubectl.go @@ -861,6 +861,25 @@ var _ = Describe("Kubectl client", func() { }) + Describe("Kubectl run --rm job", func() { + nsFlag := fmt.Sprintf("--namespace=%v", ns) + jobName := "e2e-test-rm-busybox-job" + + It("should create a job from an image, then delete the job [Conformance]", func() { + By("executing a command with run --rm and attach with stdin") + runOutput := newKubectlCommand(nsFlag, "run", jobName, "--image=busybox", "--rm=true", "--restart=Never", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). + withStdinData("abcd1234"). + execOrDie() + Expect(runOutput).To(ContainSubstring("abcd1234")) + Expect(runOutput).To(ContainSubstring("stdin closed")) + + By("verifying the job " + jobName + " was deleted") + _, err := c.Extensions().Jobs(ns).Get(jobName) + Expect(err).To(HaveOccurred()) + Expect(apierrs.IsNotFound(err)).To(BeTrue()) + }) + }) + Describe("Proxy server", func() { // TODO: test proxy options (static, prefix, etc) It("should support proxy with --port 0 [Conformance]", func() {