diff --git a/contrib/completions/bash/kubectl b/contrib/completions/bash/kubectl index 4e7e2c958a0..0a07a3aab44 100644 --- a/contrib/completions/bash/kubectl +++ b/contrib/completions/bash/kubectl @@ -343,6 +343,7 @@ _kubectl_delete() flags_completion=() flags+=("--all") + flags+=("--cascade") flags+=("--filename=") flags_with_completion+=("--filename") flags_completion+=("_filedir '@(json|yaml|yml)'") diff --git a/docs/kubectl.md b/docs/kubectl.md index c027af7e09d..d6f2e8850a0 100644 --- a/docs/kubectl.md +++ b/docs/kubectl.md @@ -66,4 +66,4 @@ kubectl * [kubectl update](kubectl_update.md) - Update a resource by filename or stdin. * [kubectl version](kubectl_version.md) - Print the client and server version information. -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.529528989 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.18016485 +0000 UTC diff --git a/docs/kubectl_api-versions.md b/docs/kubectl_api-versions.md index 66650fa9701..19eff6d3d15 100644 --- a/docs/kubectl_api-versions.md +++ b/docs/kubectl_api-versions.md @@ -50,4 +50,4 @@ kubectl api-versions ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.529124749 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.179420324 +0000 UTC diff --git a/docs/kubectl_cluster-info.md b/docs/kubectl_cluster-info.md index cb6b41dbb28..fa6ec4201b9 100644 --- a/docs/kubectl_cluster-info.md +++ b/docs/kubectl_cluster-info.md @@ -50,4 +50,4 @@ kubectl cluster-info ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.528967691 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.179075262 +0000 UTC diff --git a/docs/kubectl_config.md b/docs/kubectl_config.md index 2aa5dd00a00..9f93f5d1778 100644 --- a/docs/kubectl_config.md +++ b/docs/kubectl_config.md @@ -63,4 +63,4 @@ kubectl config SUBCOMMAND * [kubectl config use-context](kubectl_config_use-context.md) - Sets the current-context in a kubeconfig file * [kubectl config view](kubectl_config_view.md) - displays Merged kubeconfig settings or a specified kubeconfig file. -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.528802509 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.178743093 +0000 UTC diff --git a/docs/kubectl_config_set-cluster.md b/docs/kubectl_config_set-cluster.md index ee112abf58e..8233db05dbf 100644 --- a/docs/kubectl_config_set-cluster.md +++ b/docs/kubectl_config_set-cluster.md @@ -65,4 +65,4 @@ $ kubectl config set-cluster e2e --insecure-skip-tls-verify=true ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.527769365 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.176632377 +0000 UTC diff --git a/docs/kubectl_config_set-context.md b/docs/kubectl_config_set-context.md index a0fa3891401..42122c02227 100644 --- a/docs/kubectl_config_set-context.md +++ b/docs/kubectl_config_set-context.md @@ -58,4 +58,4 @@ $ kubectl config set-context gce --user=cluster-admin ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.528131768 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.177351504 +0000 UTC diff --git a/docs/kubectl_config_set-credentials.md b/docs/kubectl_config_set-credentials.md index ee1aee4ee7c..3be48988ecd 100644 --- a/docs/kubectl_config_set-credentials.md +++ b/docs/kubectl_config_set-credentials.md @@ -78,4 +78,4 @@ $ kubectl set-credentials cluster-admin --client-certificate=~/.kube/admin.crt - ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.527942873 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.176997115 +0000 UTC diff --git a/docs/kubectl_config_set.md b/docs/kubectl_config_set.md index 037f53e87bf..d01f5990f86 100644 --- a/docs/kubectl_config_set.md +++ b/docs/kubectl_config_set.md @@ -52,4 +52,4 @@ kubectl config set PROPERTY_NAME PROPERTY_VALUE ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.528303344 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.177697607 +0000 UTC diff --git a/docs/kubectl_config_unset.md b/docs/kubectl_config_unset.md index c1c99fab75b..d19f2750cab 100644 --- a/docs/kubectl_config_unset.md +++ b/docs/kubectl_config_unset.md @@ -51,4 +51,4 @@ kubectl config unset PROPERTY_NAME ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.528464868 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.178014311 +0000 UTC diff --git a/docs/kubectl_config_use-context.md b/docs/kubectl_config_use-context.md index 2b8beacd2eb..2f699fc3d53 100644 --- a/docs/kubectl_config_use-context.md +++ b/docs/kubectl_config_use-context.md @@ -50,4 +50,4 @@ kubectl config use-context CONTEXT_NAME ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.528626589 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.178387488 +0000 UTC diff --git a/docs/kubectl_config_view.md b/docs/kubectl_config_view.md index e0dfd7c607b..4c5c551f3dc 100644 --- a/docs/kubectl_config_view.md +++ b/docs/kubectl_config_view.md @@ -73,4 +73,4 @@ $ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2 ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.527582988 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.176300117 +0000 UTC diff --git a/docs/kubectl_create.md b/docs/kubectl_create.md index e694758fa75..8f4a8e9c81f 100644 --- a/docs/kubectl_create.md +++ b/docs/kubectl_create.md @@ -63,4 +63,4 @@ $ cat pod.json | kubectl create -f - ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.52422236 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.169347287 +0000 UTC diff --git a/docs/kubectl_delete.md b/docs/kubectl_delete.md index d4087b5dcb8..e191d70c668 100644 --- a/docs/kubectl_delete.md +++ b/docs/kubectl_delete.md @@ -43,6 +43,7 @@ $ kubectl delete pods --all ``` --all=false: [-all] to select all the specified resources + --cascade=true: If true, cascade the delete resources managed by this resource (e.g. Pods created by a ReplicationController). Default true. -f, --filename=[]: Filename, directory, or URL to a file containing the resource to delete -h, --help=false: help for delete -l, --selector="": Selector (label query) to filter on @@ -81,4 +82,4 @@ $ kubectl delete pods --all ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.524590507 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.170113984 +0000 UTC diff --git a/docs/kubectl_describe.md b/docs/kubectl_describe.md index 29d123d8890..4e7fe4d6079 100644 --- a/docs/kubectl_describe.md +++ b/docs/kubectl_describe.md @@ -63,4 +63,4 @@ $ kubectl describe pods/nginx ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.524047164 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.168905946 +0000 UTC diff --git a/docs/kubectl_exec.md b/docs/kubectl_exec.md index 4de0ffc6518..30eb75a7e0b 100644 --- a/docs/kubectl_exec.md +++ b/docs/kubectl_exec.md @@ -64,4 +64,4 @@ $ kubectl exec -p 123456-7890 -c ruby-container -i -t -- bash -il ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.52551618 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.173193785 +0000 UTC diff --git a/docs/kubectl_expose.md b/docs/kubectl_expose.md index c604c6126a3..3dd54f3d8f8 100644 --- a/docs/kubectl_expose.md +++ b/docs/kubectl_expose.md @@ -82,4 +82,4 @@ $ kubectl expose streamer --port=4100 --protocol=udp --service-name=video-stream ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.527149074 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.175492324 +0000 UTC diff --git a/docs/kubectl_get.md b/docs/kubectl_get.md index 3f7446d355a..f6af6c5f2e9 100644 --- a/docs/kubectl_get.md +++ b/docs/kubectl_get.md @@ -85,4 +85,4 @@ $ kubectl get rc/web service/frontend pods/web-pod-13je7 ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.523839103 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.168465048 +0000 UTC diff --git a/docs/kubectl_label.md b/docs/kubectl_label.md index 5b4d2da4129..900d47bc664 100644 --- a/docs/kubectl_label.md +++ b/docs/kubectl_label.md @@ -81,4 +81,4 @@ $ kubectl label pods foo bar- ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.527386643 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.175924183 +0000 UTC diff --git a/docs/kubectl_log.md b/docs/kubectl_log.md index 027b8ef6a86..77ddbb5ef16 100644 --- a/docs/kubectl_log.md +++ b/docs/kubectl_log.md @@ -62,4 +62,4 @@ $ kubectl log -f 123456-7890 ruby-container ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.524938744 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.170843937 +0000 UTC diff --git a/docs/kubectl_namespace.md b/docs/kubectl_namespace.md index 6fd03526d70..4c88ea908a0 100644 --- a/docs/kubectl_namespace.md +++ b/docs/kubectl_namespace.md @@ -53,4 +53,4 @@ kubectl namespace [namespace] ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.524751287 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.170473143 +0000 UTC diff --git a/docs/kubectl_port-forward.md b/docs/kubectl_port-forward.md index 42e4d8473db..c55506242f1 100644 --- a/docs/kubectl_port-forward.md +++ b/docs/kubectl_port-forward.md @@ -68,4 +68,4 @@ $ kubectl port-forward -p mypod 0:5000 ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.525691097 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.173592919 +0000 UTC diff --git a/docs/kubectl_proxy.md b/docs/kubectl_proxy.md index 7f69bda3887..b1152ae451c 100644 --- a/docs/kubectl_proxy.md +++ b/docs/kubectl_proxy.md @@ -65,4 +65,4 @@ $ kubectl proxy --api-prefix=k8s-api ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.525864716 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.173961813 +0000 UTC diff --git a/docs/kubectl_resize.md b/docs/kubectl_resize.md index 2dd18891799..0f066936abd 100644 --- a/docs/kubectl_resize.md +++ b/docs/kubectl_resize.md @@ -68,4 +68,4 @@ $ kubectl resize --current-replicas=2 --replicas=3 replicationcontrollers foo ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.52532658 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.171613369 +0000 UTC diff --git a/docs/kubectl_rolling-update.md b/docs/kubectl_rolling-update.md index d9e850bfc09..6a09bf6e31c 100644 --- a/docs/kubectl_rolling-update.md +++ b/docs/kubectl_rolling-update.md @@ -83,4 +83,4 @@ $ kubectl rolling-update frontend --image=image:v2 ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:44:36.84341428 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 21:28:37.951011185 +0000 UTC diff --git a/docs/kubectl_run-container.md b/docs/kubectl_run-container.md index 83af9746a72..1f99745b4bd 100644 --- a/docs/kubectl_run-container.md +++ b/docs/kubectl_run-container.md @@ -78,4 +78,4 @@ $ kubectl run-container nginx --image=nginx --overrides='{ "apiVersion": "v1beta ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.526080215 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.174507457 +0000 UTC diff --git a/docs/kubectl_stop.md b/docs/kubectl_stop.md index ff16d718507..3b1fdd1a345 100644 --- a/docs/kubectl_stop.md +++ b/docs/kubectl_stop.md @@ -72,4 +72,4 @@ $ kubectl stop -f path/to/resources ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.526923863 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.174999749 +0000 UTC diff --git a/docs/kubectl_update.md b/docs/kubectl_update.md index 54961ea2b9d..d171c2585f0 100644 --- a/docs/kubectl_update.md +++ b/docs/kubectl_update.md @@ -67,4 +67,4 @@ $ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState": ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.52440746 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.16972972 +0000 UTC diff --git a/docs/kubectl_version.md b/docs/kubectl_version.md index 7c84feabd7f..9f01f8fb175 100644 --- a/docs/kubectl_version.md +++ b/docs/kubectl_version.md @@ -51,4 +51,4 @@ kubectl version ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-27 22:01:46.529297188 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.179736961 +0000 UTC diff --git a/docs/man/man1/kubectl-delete.1 b/docs/man/man1/kubectl-delete.1 index 5063ea7549d..3542f199d78 100644 --- a/docs/man/man1/kubectl-delete.1 +++ b/docs/man/man1/kubectl-delete.1 @@ -33,6 +33,10 @@ will be lost along with the rest of the resource. \fB\-\-all\fP=false [\-all] to select all the specified resources +.PP +\fB\-\-cascade\fP=true + If true, cascade the delete resources managed by this resource (e.g. Pods created by a ReplicationController). Default true. + .PP \fB\-f\fP, \fB\-\-filename\fP=[] Filename, directory, or URL to a file containing the resource to delete diff --git a/pkg/kubectl/cmd/delete.go b/pkg/kubectl/cmd/delete.go index 545f6c8f584..9205bfdc703 100644 --- a/pkg/kubectl/cmd/delete.go +++ b/pkg/kubectl/cmd/delete.go @@ -72,6 +72,7 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command { kubectl.AddJsonFilenameFlag(cmd, &filenames, usage) cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on") cmd.Flags().Bool("all", false, "[-all] to select all the specified resources") + cmd.Flags().Bool("cascade", true, "If true, cascade the delete resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.") return cmd } @@ -95,20 +96,59 @@ func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str return err } + // By default use a reaper to delete all related resources. + if cmdutil.GetFlagBool(cmd, "cascade") { + return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade")) + } + return DeleteResult(r, out) +} + +func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefaultDelete bool) error { found := 0 - err = r.IgnoreErrors(errors.IsNotFound).Visit(func(r *resource.Info) error { + err := r.IgnoreErrors(errors.IsNotFound).Visit(func(info *resource.Info) error { found++ - if err := resource.NewHelper(r.Client, r.Mapping).Delete(r.Namespace, r.Name); err != nil { + reaper, err := f.Reaper(info.Mapping) + if err != nil { + // If the error is "not found" and the user didn't explicitly ask for stop. + if kubectl.IsNoSuchReaperError(err) && isDefaultDelete { + return deleteResource(info, out) + } return err } - fmt.Fprintf(out, "%s/%s\n", r.Mapping.Resource, r.Name) + if _, err := reaper.Stop(info.Namespace, info.Name); err != nil { + return err + } + fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name) return nil }) if err != nil { return err } if found == 0 { - fmt.Fprintf(cmd.Out(), "No resources found\n") + fmt.Fprintf(out, "No resources found\n") } return nil } + +func DeleteResult(r *resource.Result, out io.Writer) error { + found := 0 + err := r.IgnoreErrors(errors.IsNotFound).Visit(func(info *resource.Info) error { + found++ + return deleteResource(info, out) + }) + if err != nil { + return err + } + if found == 0 { + fmt.Fprintf(out, "No resources found\n") + } + return nil +} + +func deleteResource(info *resource.Info, out io.Writer) error { + if err := resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name); err != nil { + return err + } + fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name) + return nil +} diff --git a/pkg/kubectl/cmd/delete_test.go b/pkg/kubectl/cmd/delete_test.go index 92f1ff6bcb3..45dade1ce7b 100644 --- a/pkg/kubectl/cmd/delete_test.go +++ b/pkg/kubectl/cmd/delete_test.go @@ -50,6 +50,7 @@ func TestDeleteObjectByTuple(t *testing.T) { cmd := NewCmdDelete(f, buf) cmd.Flags().Set("namespace", "test") + cmd.Flags().Set("cascade", "false") cmd.Run(cmd, []string{"replicationcontrollers/redis-master-controller"}) if buf.String() != "replicationControllers/redis-master-controller\n" { @@ -80,6 +81,7 @@ func TestDeleteNamedObject(t *testing.T) { cmd := NewCmdDelete(f, buf) cmd.Flags().Set("namespace", "test") + cmd.Flags().Set("cascade", "false") cmd.Run(cmd, []string{"replicationcontrollers", "redis-master-controller"}) if buf.String() != "replicationControllers/redis-master-controller\n" { @@ -109,6 +111,7 @@ func TestDeleteObject(t *testing.T) { cmd := NewCmdDelete(f, buf) cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json") + cmd.Flags().Set("cascade", "false") cmd.Run(cmd, []string{}) // uses the name from the file, not the response @@ -137,6 +140,7 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) { cmd := NewCmdDelete(f, buf) cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json") + cmd.Flags().Set("cascade", "false") cmd.Run(cmd, []string{}) if buf.String() != "" { @@ -169,6 +173,7 @@ func TestDeleteMultipleObject(t *testing.T) { cmd := NewCmdDelete(f, buf) cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json") cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json") + cmd.Flags().Set("cascade", "false") cmd.Run(cmd, []string{}) if buf.String() != "replicationcontrollers/redis-master\nservices/frontend\n" { @@ -201,6 +206,7 @@ func TestDeleteMultipleObjectIgnoreMissing(t *testing.T) { cmd := NewCmdDelete(f, buf) cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json") cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json") + cmd.Flags().Set("cascade", "false") cmd.Run(cmd, []string{}) if buf.String() != "services/frontend\n" { @@ -232,6 +238,7 @@ func TestDeleteDirectory(t *testing.T) { cmd := NewCmdDelete(f, buf) cmd.Flags().Set("filename", "../../../examples/guestbook") + cmd.Flags().Set("cascade", "false") cmd.Run(cmd, []string{}) if buf.String() != "replicationcontrollers/frontend\nservices/frontend\nreplicationcontrollers/redis-master\nservices/redis-master\nreplicationcontrollers/redis-slave\nservices/redis-slave\n" { @@ -273,6 +280,7 @@ func TestDeleteMultipleSelector(t *testing.T) { cmd := NewCmdDelete(f, buf) cmd.Flags().Set("selector", "a=b") + cmd.Flags().Set("cascade", "false") cmd.Run(cmd, []string{"pods,services"}) if buf.String() != "pods/foo\npods/bar\nservices/baz\n" { diff --git a/pkg/kubectl/cmd/stop.go b/pkg/kubectl/cmd/stop.go index f361b9ef8f2..41a25dc92c3 100644 --- a/pkg/kubectl/cmd/stop.go +++ b/pkg/kubectl/cmd/stop.go @@ -17,7 +17,6 @@ limitations under the License. package cmd import ( - "fmt" "io" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl" @@ -55,29 +54,7 @@ func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command { Long: stop_long, Example: stop_example, Run: func(cmd *cobra.Command, args []string) { - cmdNamespace, err := f.DefaultNamespace() - cmdutil.CheckErr(err) - mapper, typer := f.Object() - r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). - ContinueOnError(). - NamespaceParam(cmdNamespace).RequireNamespace(). - ResourceTypeOrNameArgs(false, args...). - FilenameParam(flags.Filenames...). - SelectorParam(cmdutil.GetFlagString(cmd, "selector")). - SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). - Flatten(). - Do() - cmdutil.CheckErr(r.Err()) - - r.Visit(func(info *resource.Info) error { - reaper, err := f.Reaper(info.Mapping) - cmdutil.CheckErr(err) - if _, err := reaper.Stop(info.Namespace, info.Name); err != nil { - return err - } - fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name) - return nil - }) + cmdutil.CheckErr(RunStop(f, cmd, args, flags.Filenames, out)) }, } usage := "Filename, directory, or URL to file of resource(s) to be stopped" @@ -86,3 +63,24 @@ func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command { cmd.Flags().Bool("all", false, "[-all] to select all the specified resources") return cmd } + +func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames util.StringList, out io.Writer) error { + cmdNamespace, err := f.DefaultNamespace() + if err != nil { + return err + } + mapper, typer := f.Object() + r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). + ContinueOnError(). + NamespaceParam(cmdNamespace).RequireNamespace(). + ResourceTypeOrNameArgs(false, args...). + FilenameParam(filenames...). + SelectorParam(cmdutil.GetFlagString(cmd, "selector")). + SelectAllParam(cmdutil.GetFlagBool(cmd, "all")). + Flatten(). + Do() + if r.Err() != nil { + return r.Err() + } + return ReapResult(r, f, out, false) +} diff --git a/pkg/kubectl/stop.go b/pkg/kubectl/stop.go index ba1d69d8442..ebdc95db64d 100644 --- a/pkg/kubectl/stop.go +++ b/pkg/kubectl/stop.go @@ -35,6 +35,19 @@ type Reaper interface { Stop(namespace, name string) (string, error) } +type NoSuchReaperError struct { + kind string +} + +func (n *NoSuchReaperError) Error() string { + return fmt.Sprintf("no reaper has been implemented for %q", n.kind) +} + +func IsNoSuchReaperError(err error) bool { + _, ok := err.(*NoSuchReaperError) + return ok +} + func ReaperFor(kind string, c client.Interface) (Reaper, error) { switch kind { case "ReplicationController": @@ -44,7 +57,7 @@ func ReaperFor(kind string, c client.Interface) (Reaper, error) { case "Service": return &ServiceReaper{c}, nil } - return nil, fmt.Errorf("no reaper has been implemented for %q", kind) + return nil, &NoSuchReaperError{kind} } type ReplicationControllerReaper struct {