Merge pull request #61713 from mountkin/fix-cli-run-panic

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

kubectl: fix a panic when createGeneratedObject failed

**What this PR does / why we need it**:
This PR fixed two bugs in the `kubectl run` command.
The first commit fixed a panic that can be reproduced with the following two commands:
```bash
kubectl run --image=alpine hello -- sleep 1d
kubectl run --image=alpine --stdin --tty --attach hello -- /bin/sh
```
When the panic happens, the stack trace is as the following: 
```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x12f92e6]

goroutine 1 [running]:
k8s.io/kubernetes/pkg/kubectl/cmd.RunRun(0x1890d20, 0xc4207f6210, 0x184e700, 0xc42000c010, 0x184e720, 0xc42000c018, 0x184e720, 0xc42000c020, 0xc42052ef00, 0xc42054f980, ...)
	/home/star/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/kubectl/cmd/run.go:328 +0x10b6
k8s.io/kubernetes/pkg/kubectl/cmd.NewCmdRun.func1(0xc42052ef00, 0xc42054f980, 0x2, 0x8)
	/home/star/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/kubectl/cmd/run.go:105 +0x144
...
```
The reason for the panic is that the original code didn't handle the error returned by `createGeneratedObject` correctly. See https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/run.go#L281
If the function `createGeneratedObject` fails, the returned `runObject` will be `nil`.  At https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/run.go#L328 a nil pointer dereference will happen.

The second problem this PR fixed is a resource leak if both `--rm` and `--expose` flags are provided. The original code used a map (https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/run.go#L280) to trace the created objects. But at https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/run.go#L296 the code will overwrite the previously created object with the same key. So at https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/run.go#L348 only the service will be deleted. The deployment will be left behind.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note
NONE
```
/kind bug
/sig cli
pull/8/head
Kubernetes Submit Queue 2018-03-30 13:19:31 -07:00 committed by GitHub
commit 8f7eb4e6ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 6 additions and 6 deletions

View File

@ -276,14 +276,14 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
params["env"] = cmdutil.GetFlagStringArray(cmd, "env")
allErrs := []error{}
var runObjectMap = map[string]*RunObject{}
var createdObjects = []*RunObject{}
runObject, err := createGeneratedObject(f, cmd, generator, names, params, cmdutil.GetFlagString(cmd, "overrides"), namespace)
if err != nil {
allErrs = append(allErrs, err)
return err
} else {
runObjectMap[generatorName] = runObject
createdObjects = append(createdObjects, runObject)
}
allErrs := []error{}
if cmdutil.GetFlagBool(cmd, "expose") {
serviceGenerator := cmdutil.GetFlagString(cmd, "service-generator")
if len(serviceGenerator) == 0 {
@ -293,7 +293,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
if err != nil {
allErrs = append(allErrs, err)
} else {
runObjectMap[generatorName] = serviceRunObject
createdObjects = append(createdObjects, serviceRunObject)
}
}
@ -345,7 +345,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
}
if remove {
for _, obj := range runObjectMap {
for _, obj := range createdObjects {
namespace, err = obj.Mapping.MetadataAccessor.Namespace(obj.Object)
if err != nil {
return err