Let kubectl run follow rules for --

This commit is contained in:
feihujiang 2015-09-14 20:18:42 +08:00
parent 0ed6432ff7
commit 4d2333b7d8
3 changed files with 71 additions and 6 deletions

View File

@ -42,7 +42,7 @@ Create and run a particular image, possibly replicated.
Creates a replication controller to manage the created container(s).
```
kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json]
kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]
```
### Examples
@ -140,7 +140,7 @@ $ kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
###### Auto generated by spf13/cobra on 6-Nov-2015
###### Auto generated by spf13/cobra on 10-Nov-2015
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_run.md?pixel)]()

View File

@ -65,14 +65,15 @@ $ kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>`
func NewCmdRun(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "run NAME --image=image [--env=\"key=value\"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json]",
Use: "run NAME --image=image [--env=\"key=value\"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]",
// run-container is deprecated
Aliases: []string{"run-container"},
Short: "Run a particular image on the cluster.",
Long: run_long,
Example: run_example,
Run: func(cmd *cobra.Command, args []string) {
err := Run(f, cmdIn, cmdOut, cmdErr, cmd, args)
argsLenAtDash := cmd.ArgsLenAtDash()
err := Run(f, cmdIn, cmdOut, cmdErr, cmd, args, argsLenAtDash)
cmdutil.CheckErr(err)
},
}
@ -106,12 +107,13 @@ func addRunFlags(cmd *cobra.Command) {
cmd.Flags().String("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.")
}
func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cobra.Command, args []string) error {
func Run(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cobra.Command, args []string, argsLenAtDash int) error {
if len(os.Args) > 1 && os.Args[1] == "run-container" {
printDeprecationWarning("run", "run-container")
}
if len(args) == 0 {
// Let kubectl run follow rules for `--`, see #13004 issue
if len(args) == 0 || argsLenAtDash == 0 {
return cmdutil.UsageError(cmd, "NAME is required for run")
}

View File

@ -21,6 +21,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"os"
"reflect"
"testing"
@ -106,6 +107,68 @@ func TestGetEnv(t *testing.T) {
}
}
func TestRunArgsFollowDashRules(t *testing.T) {
_, _, rc := testData()
tests := []struct {
args []string
argsLenAtDash int
expectError bool
name string
}{
{
args: []string{},
argsLenAtDash: -1,
expectError: true,
name: "empty",
},
{
args: []string{"foo"},
argsLenAtDash: -1,
expectError: false,
name: "no cmd",
},
{
args: []string{"foo", "sleep"},
argsLenAtDash: -1,
expectError: false,
name: "cmd no dash",
},
{
args: []string{"foo", "sleep"},
argsLenAtDash: 1,
expectError: false,
name: "cmd has dash",
},
{
args: []string{"foo", "sleep"},
argsLenAtDash: 0,
expectError: true,
name: "no name",
},
}
for _, test := range tests {
f, tf, codec := NewAPIFactory()
tf.Client = &fake.RESTClient{
Codec: codec,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{StatusCode: 201, Body: objBody(codec, &rc.Items[0])}, nil
}),
}
tf.Namespace = "test"
tf.ClientConfig = &client.Config{}
cmd := NewCmdRun(f, os.Stdin, os.Stdout, os.Stderr)
cmd.Flags().Set("image", "nginx")
err := Run(f, os.Stdin, os.Stdout, os.Stderr, cmd, test.args, test.argsLenAtDash)
if test.expectError && err == nil {
t.Errorf("unexpected non-error (%s)", test.name)
}
if !test.expectError && err != nil {
t.Errorf("unexpected error: %v (%s)", err, test.name)
}
}
}
func TestGenerateService(t *testing.T) {
tests := []struct {