diff --git a/docs/man/man1/kubectl-run.1 b/docs/man/man1/kubectl-run.1 index e0abc9e2a17..afb58809058 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'. + 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=Alwyas, 'run\-pod/v1' for others. .PP \fB\-\-hostport\fP=\-1 diff --git a/docs/user-guide/kubectl/kubectl_run.md b/docs/user-guide/kubectl/kubectl_run.md index 84906ebcea3..7f2366a110c 100644 --- a/docs/user-guide/kubectl/kubectl_run.md +++ b/docs/user-guide/kubectl/kubectl_run.md @@ -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'. + --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=Alwyas, '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. -l, --labels="": Labels to apply to the pod(s). @@ -147,7 +147,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 29-Feb-2016 +###### Auto generated by spf13/cobra on 11-Mar-2016 [![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 1c28821e721..d060ceddcad 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -25,6 +25,9 @@ import ( "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" + batchv1 "k8s.io/kubernetes/pkg/apis/batch/v1" + "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/kubectl" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -88,7 +91,7 @@ func NewCmdRun(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *c } func addRunFlags(cmd *cobra.Command) { - 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'.") + 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=Alwyas, '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.") @@ -146,10 +149,29 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob generatorName := cmdutil.GetFlagString(cmd, "generator") if len(generatorName) == 0 { + client, err := f.Client() + if err != nil { + return err + } + resourcesList, err := client.Discovery().ServerResources() + if err != nil { + // this cover the cases where old servers do not expose discovery + resourcesList = nil + } if restartPolicy == api.RestartPolicyAlways { - generatorName = "deployment/v1beta1" + if contains(resourcesList, v1beta1.SchemeGroupVersion.WithResource("deployments")) { + generatorName = "deployment/v1beta1" + } else { + generatorName = "run/v1" + } } else { - generatorName = "job/v1" + 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" + } } } generators := f.Generators("run") @@ -254,6 +276,23 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob return nil } +// TODO turn this into reusable method checking available resources +func contains(resourcesList map[string]*unversioned.APIResourceList, resource unversioned.GroupVersionResource) bool { + if resourcesList == nil { + return false + } + resourcesGroup, ok := resourcesList[resource.GroupVersion().String()] + if !ok { + return false + } + for _, item := range resourcesGroup.APIResources { + if resource.Resource == item.Name { + return true + } + } + return false +} + func waitForPodRunning(c *client.Client, pod *api.Pod, out io.Writer) (status api.PodPhase, err error) { for { pod, err := c.Pods(pod.Namespace).Get(pod.Name)