diff --git a/contrib/completions/bash/kubectl b/contrib/completions/bash/kubectl index f6d0f25b51b..011542a285e 100644 --- a/contrib/completions/bash/kubectl +++ b/contrib/completions/bash/kubectl @@ -1164,6 +1164,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 fb5555e7ae7..bea0069e3b1 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 ca244d573b7..f9ae2831e11 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 429abef0945..b6f9ae90216 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 f795a35fcdd..27a6d208056 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() {