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

kubectl run --restart=Never creates pods #25253

Merged
merged 1 commit into from
May 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/man/man1/kubectl-run.1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
8 changes: 4 additions & 4 deletions docs/user-guide/kubectl/kubectl_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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]
Expand All @@ -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
Expand Down Expand Up @@ -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

<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_run.md?pixel)]()
Expand Down
6 changes: 3 additions & 3 deletions docs/yaml/kubectl/kubectl_run.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down Expand Up @@ -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: |
Expand Down Expand Up @@ -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.
Expand Down
13 changes: 8 additions & 5 deletions pkg/kubectl/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.")
Expand All @@ -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.")
Expand Down Expand Up @@ -159,20 +159,23 @@ 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")) {
generatorName = "job/v1beta1"
} else {
generatorName = "run-pod/v1"
}
case api.RestartPolicyNever:
generatorName = "run-pod/v1"
}
}
generators := f.Generators("run")
Expand Down
42 changes: 28 additions & 14 deletions test/e2e/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,23 +354,23 @@ 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"))
Expect(runOutput).To(ContainSubstring("stdin closed"))
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"))
Expect(runOutput).To(ContainSubstring("stdin closed"))
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"))
Expand Down Expand Up @@ -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 {
Expand All @@ -1006,23 +1006,37 @@ var _ = framework.KubeDescribe("Kubectl client", func() {
framework.Failf("Failed creating a job with correct restart policy for --restart=OnFailure")
}
})
})

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 job from an image when restart is Never [Conformance]", func() {
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")
}
})
})
Expand All @@ -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()
Expand Down