Merge pull request #22849 from soltysh/issue22836

Added api discovery to kubectl run, based on which we decide which generators to use
This commit is contained in:
Brian Grant 2016-03-11 09:04:12 -08:00
commit 1c50f1831c
3 changed files with 45 additions and 6 deletions

View File

@ -40,7 +40,7 @@ Creates a deployment or job to manage the created container(s).
.PP .PP
\fB\-\-generator\fP="" \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 .PP
\fB\-\-hostport\fP=\-1 \fB\-\-hostport\fP=\-1

View File

@ -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. --dry-run[=false]: If true, only print the object that would be sent, without sending it.
--env=[]: Environment variables to set in the container --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 --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. --hostport=-1: The host port mapping for the container port. To demonstrate a single-machine container.
--image="": The image for the container to run. --image="": The image for the container to run.
-l, --labels="": Labels to apply to the pod(s). -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 * [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
<!-- BEGIN MUNGE: GENERATED_ANALYTICS --> <!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_run.md?pixel)]() [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_run.md?pixel)]()

View File

@ -25,6 +25,9 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "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" client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" 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) { 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.Flags().String("image", "", "The image for the container to run.")
cmd.MarkFlagRequired("image") cmd.MarkFlagRequired("image")
cmd.Flags().IntP("replicas", "r", 1, "Number of replicas to create for this container. Default is 1.") 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") generatorName := cmdutil.GetFlagString(cmd, "generator")
if len(generatorName) == 0 { 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 { if restartPolicy == api.RestartPolicyAlways {
generatorName = "deployment/v1beta1" if contains(resourcesList, v1beta1.SchemeGroupVersion.WithResource("deployments")) {
generatorName = "deployment/v1beta1"
} else {
generatorName = "run/v1"
}
} else { } 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") generators := f.Generators("run")
@ -254,6 +276,23 @@ func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cob
return nil 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) { func waitForPodRunning(c *client.Client, pod *api.Pod, out io.Writer) (status api.PodPhase, err error) {
for { for {
pod, err := c.Pods(pod.Namespace).Get(pod.Name) pod, err := c.Pods(pod.Namespace).Get(pod.Name)