diff --git a/docs/man/man1/kubectl-run.1 b/docs/man/man1/kubectl-run.1 index 1a9fc941ab4..9f1df35de1b 100644 --- a/docs/man/man1/kubectl-run.1 +++ b/docs/man/man1/kubectl-run.1 @@ -40,7 +40,7 @@ Creates a deployment or job to manage the created container(s). .PP \fB\-\-generator\fP="" - The name of the API generator to use. Default is 'deployment/v1beta1' if \-\-restart=Always, otherwise the default is 'job/v1'. This will happen only for cluster version at least 1.2, for olders we will fallback to 'run/v1' for \-\-restart=Always, 'run\-pod/v1' for others. + The name of the API generator to use. Default is 'deployment/v1beta1' if \-\-restart=Always, 'job/v1' for OnFailure and 'run\-pod/v1' for Never. This will happen only for cluster version at least 1.3, for 1.2 we will fallback to 'deployment/v1beta1' for \-\-restart=Always, 'job/v1' for others, for olders we will fallback to 'run/v1' for \-\-restart=Always, 'run\-pod/v1' for others. .PP \fB\-\-hostport\fP=\-1 @@ -102,7 +102,7 @@ Creates a deployment or job to manage the created container(s). .PP \fB\-\-restart\fP="Always" - The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment 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' + The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment is created for this pod, if set to 'OnFailure', a job is created for this pod, if set to 'Never', a regular pod is created. For the latter two \-\-replicas must be 1. Default 'Always' .PP \fB\-\-rm\fP=false @@ -267,7 +267,7 @@ kubectl run nginx \-\-image=nginx \-\-dry\-run # Start a single instance of nginx, but overload the spec of the deployment with a partial set of values parsed from JSON. kubectl run nginx \-\-image=nginx \-\-overrides='{ "apiVersion": "v1", "spec": { ... } }' -# Start a single instance of busybox and keep it in the foreground, don't restart it if it exits. +# Start a pod of busybox and keep it in the foreground, don't restart it if it exits. kubectl run \-i \-t busybox \-\-image=busybox \-\-restart=Never # Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command. diff --git a/docs/user-guide/kubectl/kubectl_run.md b/docs/user-guide/kubectl/kubectl_run.md index 34ec997ea68..c34a68ff6a3 100644 --- a/docs/user-guide/kubectl/kubectl_run.md +++ b/docs/user-guide/kubectl/kubectl_run.md @@ -67,7 +67,7 @@ kubectl run nginx --image=nginx --dry-run # Start a single instance of nginx, but overload the spec of the deployment with a partial set of values parsed from JSON. kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }' -# Start a single instance of busybox and keep it in the foreground, don't restart it if it exits. +# Start a pod of busybox and keep it in the foreground, don't restart it if it exits. kubectl run -i -t busybox --image=busybox --restart=Never # Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command. @@ -88,7 +88,7 @@ kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print --dry-run[=false]: If true, only print the object that would be sent, without sending it. --env=[]: Environment variables to set in the container --expose[=false]: If true, a public, external service is created for the container(s) which are run - --generator="": The name of the API generator to use. Default is 'deployment/v1beta1' if --restart=Always, otherwise the default is 'job/v1'. This will happen only for cluster version at least 1.2, for olders we will fallback to 'run/v1' for --restart=Always, 'run-pod/v1' for others. + --generator="": The name of the API generator to use. Default is 'deployment/v1beta1' if --restart=Always, 'job/v1' for OnFailure and 'run-pod/v1' for Never. This will happen only for cluster version at least 1.3, for 1.2 we will fallback to 'deployment/v1beta1' for --restart=Always, 'job/v1' for others, for olders we will fallback to 'run/v1' for --restart=Always, 'run-pod/v1' for others. --hostport=-1: The host port mapping for the container port. To demonstrate a single-machine container. --image="": The image for the container to run. --include-extended-apis[=true]: If true, include definitions of new APIs via calls to the API server. [default true] @@ -103,7 +103,7 @@ kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print --record[=false]: Record current kubectl command in the resource annotation. -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'. Note that server side components may assign requests depending on the server configuration, such as limit ranges. - --restart="Always": The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment 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' + --restart="Always": The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment is created for this pod, if set to 'OnFailure', a job is created for this pod, if set to 'Never', a regular pod is created. For the latter two --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 @@ -148,7 +148,7 @@ kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra on 22-Apr-2016 +###### Auto generated by spf13/cobra on 28-May-2016 [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_run.md?pixel)]() diff --git a/docs/yaml/kubectl/kubectl_run.yaml b/docs/yaml/kubectl/kubectl_run.yaml index 85ae53e45ac..806f7548970 100644 --- a/docs/yaml/kubectl/kubectl_run.yaml +++ b/docs/yaml/kubectl/kubectl_run.yaml @@ -25,7 +25,7 @@ options: If true, a public, external service is created for the container(s) which are run - name: generator usage: | - The name of the API generator to use. Default is 'deployment/v1beta1' if --restart=Always, otherwise the default is 'job/v1'. This will happen only for cluster version at least 1.2, for olders we will fallback to 'run/v1' for --restart=Always, 'run-pod/v1' for others. + The name of the API generator to use. Default is 'deployment/v1beta1' if --restart=Always, 'job/v1' for OnFailure and 'run-pod/v1' for Never. This will happen only for cluster version at least 1.3, for 1.2 we will fallback to 'deployment/v1beta1' for --restart=Always, 'job/v1' for others, for olders we will fallback to 'run/v1' for --restart=Always, 'run-pod/v1' for others. - name: hostport default_value: "-1" usage: | @@ -77,7 +77,7 @@ options: - name: restart default_value: Always usage: | - The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment 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' + The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment is created for this pod, if set to 'OnFailure', a job is created for this pod, if set to 'Never', a regular pod is created. For the latter two --replicas must be 1. Default 'Always' - name: rm default_value: "false" usage: | @@ -197,7 +197,7 @@ example: |- # Start a single instance of nginx, but overload the spec of the deployment with a partial set of values parsed from JSON. kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }' - # Start a single instance of busybox and keep it in the foreground, don't restart it if it exits. + # Start a pod of busybox and keep it in the foreground, don't restart it if it exits. kubectl run -i -t busybox --image=busybox --restart=Never # Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command. diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index 236e758dce7..ce87971f298 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -56,7 +56,7 @@ kubectl run nginx --image=nginx --dry-run # Start a single instance of nginx, but overload the spec of the deployment with a partial set of values parsed from JSON. kubectl run nginx --image=nginx --overrides='{ "apiVersion": "v1", "spec": { ... } }' -# Start a single instance of busybox and keep it in the foreground, don't restart it if it exits. +# Start a pod of busybox and keep it in the foreground, don't restart it if it exits. kubectl run -i -t busybox --image=busybox --restart=Never # Start the nginx container using the default command, but use custom arguments (arg1 .. argN) for that command. @@ -93,7 +93,7 @@ func NewCmdRun(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *c func addRunFlags(cmd *cobra.Command) { cmdutil.AddDryRunFlag(cmd) - cmd.Flags().String("generator", "", "The name of the API generator to use. Default is 'deployment/v1beta1' if --restart=Always, otherwise the default is 'job/v1'. This will happen only for cluster version at least 1.2, for olders we will fallback to 'run/v1' for --restart=Always, 'run-pod/v1' for others.") + cmd.Flags().String("generator", "", "The name of the API generator to use. Default is 'deployment/v1beta1' if --restart=Always, 'job/v1' for OnFailure and 'run-pod/v1' for Never. This will happen only for cluster version at least 1.3, for 1.2 we will fallback to 'deployment/v1beta1' for --restart=Always, 'job/v1' for others, for olders we will fallback to 'run/v1' for --restart=Always, 'run-pod/v1' for others.") 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.") @@ -107,7 +107,7 @@ func addRunFlags(cmd *cobra.Command) { cmd.Flags().BoolP("tty", "t", false, "Allocated a TTY for each container in the pod.") cmd.Flags().Bool("attach", false, "If true, wait for the Pod to start running, and then attach to the Pod as if 'kubectl attach ...' were called. Default false, unless '-i/--interactive' is set, in which case the default is true.") cmd.Flags().Bool("leave-stdin-open", false, "If the pod is started in interactive mode or with stdin, leave stdin open after the first attach completes. By default, stdin will be closed after the first attach completes.") - cmd.Flags().String("restart", "Always", "The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment 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'") + cmd.Flags().String("restart", "Always", "The restart policy for this Pod. Legal values [Always, OnFailure, Never]. If set to 'Always' a deployment is created for this pod, if set to 'OnFailure', a job is created for this pod, if set to 'Never', a regular pod is created. For the latter two --replicas must be 1. Default 'Always'") cmd.Flags().Bool("command", false, "If true and extra arguments are present, use them as the 'command' field in the container, rather than the 'args' field which is the default.") cmd.Flags().String("requests", "", "The resource requirement requests for this container. For example, 'cpu=100m,memory=256Mi'. Note that server side components may assign requests depending on the server configuration, such as limit ranges.") cmd.Flags().String("limits", "", "The resource requirement limits for this container. For example, 'cpu=200m,memory=512Mi'. Note that server side components may assign limits depending on the server configuration, such as limit ranges.") @@ -159,13 +159,14 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob // this cover the cases where old servers do not expose discovery resourcesList = nil } - if restartPolicy == api.RestartPolicyAlways { + switch restartPolicy { + case api.RestartPolicyAlways: if contains(resourcesList, v1beta1.SchemeGroupVersion.WithResource("deployments")) { generatorName = "deployment/v1beta1" } else { generatorName = "run/v1" } - } else { + case api.RestartPolicyOnFailure: if contains(resourcesList, batchv1.SchemeGroupVersion.WithResource("jobs")) { generatorName = "job/v1" } else if contains(resourcesList, v1beta1.SchemeGroupVersion.WithResource("jobs")) { @@ -173,6 +174,8 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob } else { generatorName = "run-pod/v1" } + case api.RestartPolicyNever: + generatorName = "run-pod/v1" } } generators := f.Generators("run") diff --git a/test/e2e/kubectl.go b/test/e2e/kubectl.go index 15eb532d936..cee0e2ff1db 100644 --- a/test/e2e/kubectl.go +++ b/test/e2e/kubectl.go @@ -354,7 +354,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { nsFlag := fmt.Sprintf("--namespace=%v", ns) By("executing a command with run and attach with stdin") - runOutput := framework.NewKubectlCommand(nsFlag, "run", "run-test", "--image="+busyboxImage, "--restart=Never", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput := framework.NewKubectlCommand(nsFlag, "run", "run-test", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234"). ExecOrDie() Expect(runOutput).To(ContainSubstring("abcd1234")) @@ -362,7 +362,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { Expect(c.Extensions().Jobs(ns).Delete("run-test", nil)).To(BeNil()) By("executing a command with run and attach without stdin") - runOutput = framework.NewKubectlCommand(fmt.Sprintf("--namespace=%v", ns), "run", "run-test-2", "--image="+busyboxImage, "--restart=Never", "--attach=true", "--leave-stdin-open=true", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput = framework.NewKubectlCommand(fmt.Sprintf("--namespace=%v", ns), "run", "run-test-2", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234"). ExecOrDie() Expect(runOutput).ToNot(ContainSubstring("abcd1234")) @@ -370,7 +370,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { Expect(c.Extensions().Jobs(ns).Delete("run-test-2", nil)).To(BeNil()) By("executing a command with run and attach with stdin with open stdin should remain running") - runOutput = framework.NewKubectlCommand(nsFlag, "run", "run-test-3", "--image="+busyboxImage, "--restart=Never", "--attach=true", "--leave-stdin-open=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput = framework.NewKubectlCommand(nsFlag, "run", "run-test-3", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234\n"). ExecOrDie() Expect(runOutput).ToNot(ContainSubstring("stdin closed")) @@ -992,7 +992,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { framework.SkipUnlessServerVersionGTE(jobsVersion, c) By("running the image " + nginxImage) - framework.RunKubectlOrDie("run", jobName, "--restart=OnFailure", "--image="+nginxImage, nsFlag) + framework.RunKubectlOrDie("run", jobName, "--restart=OnFailure", "--generator=job/v1", "--image="+nginxImage, nsFlag) By("verifying the job " + jobName + " was created") job, err := c.Extensions().Jobs(ns).Get(jobName) if err != nil { @@ -1006,23 +1006,37 @@ var _ = framework.KubeDescribe("Kubectl client", func() { framework.Failf("Failed creating a job with correct restart policy for --restart=OnFailure") } }) + }) - It("should create a job from an image when restart is Never [Conformance]", func() { + framework.KubeDescribe("Kubectl run pod", func() { + var nsFlag string + var podName string + + BeforeEach(func() { + nsFlag = fmt.Sprintf("--namespace=%v", ns) + podName = "e2e-test-nginx-pod" + }) + + AfterEach(func() { + framework.RunKubectlOrDie("delete", "pods", podName, nsFlag) + }) + + It("should create a pod from an image when restart is Never [Conformance]", func() { framework.SkipUnlessServerVersionGTE(jobsVersion, c) By("running the image " + nginxImage) - framework.RunKubectlOrDie("run", jobName, "--restart=Never", "--image="+nginxImage, nsFlag) - By("verifying the job " + jobName + " was created") - job, err := c.Extensions().Jobs(ns).Get(jobName) + framework.RunKubectlOrDie("run", podName, "--restart=Never", "--generator=run-pod/v1", "--image="+nginxImage, nsFlag) + By("verifying the pod " + podName + " was created") + pod, err := c.Pods(ns).Get(podName) if err != nil { - framework.Failf("Failed getting job %s: %v", jobName, err) + framework.Failf("Failed getting pod %s: %v", podName, err) } - containers := job.Spec.Template.Spec.Containers + containers := pod.Spec.Containers if containers == nil || len(containers) != 1 || containers[0].Image != nginxImage { - framework.Failf("Failed creating job %s for 1 pod with expected image %s", jobName, nginxImage) + framework.Failf("Failed creating pod %s with expected image %s", podName, nginxImage) } - if job.Spec.Template.Spec.RestartPolicy != api.RestartPolicyNever { - framework.Failf("Failed creating a job with correct restart policy for --restart=OnFailure") + if pod.Spec.RestartPolicy != api.RestartPolicyNever { + framework.Failf("Failed creating a pod with correct restart policy for --restart=Never") } }) }) @@ -1037,7 +1051,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { By("executing a command with run --rm and attach with stdin") t := time.NewTimer(runJobTimeout) defer t.Stop() - runOutput := framework.NewKubectlCommand(nsFlag, "run", jobName, "--image="+busyboxImage, "--rm=true", "--restart=Never", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput := framework.NewKubectlCommand(nsFlag, "run", jobName, "--image="+busyboxImage, "--rm=true", "--generator=job/v1", "--restart=OnFailure", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234"). WithTimeout(t.C). ExecOrDie()