mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #8628 from jlowdermilk/delete-not-found
Delete fails on notfound errors.
This commit is contained in:
		@@ -364,6 +364,7 @@ _kubectl_delete()
 | 
			
		||||
    flags+=("--grace-period=")
 | 
			
		||||
    flags+=("--help")
 | 
			
		||||
    flags+=("-h")
 | 
			
		||||
    flags+=("--ignore-not-found")
 | 
			
		||||
    flags+=("--selector=")
 | 
			
		||||
    two_word_flags+=("-l")
 | 
			
		||||
 | 
			
		||||
@@ -587,6 +588,7 @@ _kubectl_stop()
 | 
			
		||||
    flags+=("--grace-period=")
 | 
			
		||||
    flags+=("--help")
 | 
			
		||||
    flags+=("-h")
 | 
			
		||||
    flags+=("--ignore-not-found")
 | 
			
		||||
    flags+=("--selector=")
 | 
			
		||||
    two_word_flags+=("-l")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -42,12 +42,13 @@ $ kubectl delete pods --all
 | 
			
		||||
### Options
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
      --all=false: [-all] to select all the specified resources
 | 
			
		||||
      --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
 | 
			
		||||
  -f, --filename=[]: Filename, directory, or URL to a file containing the resource to delete.
 | 
			
		||||
      --grace-period=-1: Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.
 | 
			
		||||
  -h, --help=false: help for delete
 | 
			
		||||
  -l, --selector="": Selector (label query) to filter on
 | 
			
		||||
      --ignore-not-found=false: Treat "resource not found" as a successful delete.
 | 
			
		||||
  -l, --selector="": Selector (label query) to filter on.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Options inherited from parent commands
 | 
			
		||||
@@ -82,6 +83,6 @@ $ kubectl delete pods --all
 | 
			
		||||
### SEE ALSO
 | 
			
		||||
* [kubectl](kubectl.md)	 - kubectl controls the Kubernetes cluster manager
 | 
			
		||||
 | 
			
		||||
###### Auto generated by spf13/cobra at 2015-05-21 10:33:11.18056941 +0000 UTC
 | 
			
		||||
###### Auto generated by spf13/cobra at 2015-05-21 18:30:45.437003409 +0000 UTC
 | 
			
		||||
 | 
			
		||||
[]()
 | 
			
		||||
 
 | 
			
		||||
@@ -33,11 +33,12 @@ $ kubectl stop -f path/to/resources
 | 
			
		||||
### Options
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
      --all=false: [-all] to select all the specified resources
 | 
			
		||||
  -f, --filename=[]: Filename, directory, or URL to file of resource(s) to be stopped
 | 
			
		||||
      --all=false: [-all] to select all the specified resources.
 | 
			
		||||
  -f, --filename=[]: Filename, directory, or URL to file of resource(s) to be stopped.
 | 
			
		||||
      --grace-period=-1: Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.
 | 
			
		||||
  -h, --help=false: help for stop
 | 
			
		||||
  -l, --selector="": Selector (label query) to filter on
 | 
			
		||||
      --ignore-not-found=false: Treat "resource not found" as a successful stop.
 | 
			
		||||
  -l, --selector="": Selector (label query) to filter on.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Options inherited from parent commands
 | 
			
		||||
@@ -72,6 +73,6 @@ $ kubectl stop -f path/to/resources
 | 
			
		||||
### SEE ALSO
 | 
			
		||||
* [kubectl](kubectl.md)	 - kubectl controls the Kubernetes cluster manager
 | 
			
		||||
 | 
			
		||||
###### Auto generated by spf13/cobra at 2015-05-21 10:33:11.190996891 +0000 UTC
 | 
			
		||||
###### Auto generated by spf13/cobra at 2015-05-21 18:30:45.439945376 +0000 UTC
 | 
			
		||||
 | 
			
		||||
[]()
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ will be lost along with the rest of the resource.
 | 
			
		||||
.SH OPTIONS
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-all\fP=false
 | 
			
		||||
    [\-all] to select all the specified resources
 | 
			
		||||
    [\-all] to select all the specified resources.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-cascade\fP=true
 | 
			
		||||
@@ -39,7 +39,7 @@ will be lost along with the rest of the resource.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-f\fP, \fB\-\-filename\fP=[]
 | 
			
		||||
    Filename, directory, or URL to a file containing the resource to delete
 | 
			
		||||
    Filename, directory, or URL to a file containing the resource to delete.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-grace\-period\fP=\-1
 | 
			
		||||
@@ -49,9 +49,13 @@ will be lost along with the rest of the resource.
 | 
			
		||||
\fB\-h\fP, \fB\-\-help\fP=false
 | 
			
		||||
    help for delete
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-ignore\-not\-found\fP=false
 | 
			
		||||
    Treat "resource not found" as a successful delete.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-l\fP, \fB\-\-selector\fP=""
 | 
			
		||||
    Selector (label query) to filter on
 | 
			
		||||
    Selector (label query) to filter on.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
 | 
			
		||||
 
 | 
			
		||||
@@ -23,11 +23,11 @@ If the resource is scalable it will be scaled to 0 before deletion.
 | 
			
		||||
.SH OPTIONS
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-all\fP=false
 | 
			
		||||
    [\-all] to select all the specified resources
 | 
			
		||||
    [\-all] to select all the specified resources.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-f\fP, \fB\-\-filename\fP=[]
 | 
			
		||||
    Filename, directory, or URL to file of resource(s) to be stopped
 | 
			
		||||
    Filename, directory, or URL to file of resource(s) to be stopped.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-grace\-period\fP=\-1
 | 
			
		||||
@@ -37,9 +37,13 @@ If the resource is scalable it will be scaled to 0 before deletion.
 | 
			
		||||
\fB\-h\fP, \fB\-\-help\fP=false
 | 
			
		||||
    help for stop
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-\-ignore\-not\-found\fP=false
 | 
			
		||||
    Treat "resource not found" as a successful stop.
 | 
			
		||||
 | 
			
		||||
.PP
 | 
			
		||||
\fB\-l\fP, \fB\-\-selector\fP=""
 | 
			
		||||
    Selector (label query) to filter on
 | 
			
		||||
    Selector (label query) to filter on.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
 | 
			
		||||
 
 | 
			
		||||
@@ -92,7 +92,7 @@ if ! hack/verify-gendocs.sh > /dev/null; then
 | 
			
		||||
  echo "${red}ERROR!"
 | 
			
		||||
  echo "Some docs are out of sync between CLI and markdown."
 | 
			
		||||
  echo "To regenerate docs, run:"
 | 
			
		||||
  echo "  hack/run-gendocs.sh > docs/kubectl.md"
 | 
			
		||||
  echo "  hack/run-gendocs.sh"
 | 
			
		||||
  exit_code=1
 | 
			
		||||
else
 | 
			
		||||
  echo "${green}OK"
 | 
			
		||||
 
 | 
			
		||||
@@ -69,10 +69,11 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
			
		||||
			cmdutil.CheckErr(err)
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	usage := "Filename, directory, or URL to a file containing the resource to delete"
 | 
			
		||||
	usage := "Filename, directory, or URL to a file containing the resource to delete."
 | 
			
		||||
	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().StringP("selector", "l", "", "Selector (label query) to filter on.")
 | 
			
		||||
	cmd.Flags().Bool("all", false, "[-all] to select all the specified resources.")
 | 
			
		||||
	cmd.Flags().Bool("ignore-not-found", false, "Treat \"resource not found\" as a successful delete.")
 | 
			
		||||
	cmd.Flags().Bool("cascade", true, "If true, cascade the delete resources managed by this resource (e.g. Pods created by a ReplicationController).  Default true.")
 | 
			
		||||
	cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
 | 
			
		||||
	return cmd
 | 
			
		||||
@@ -98,20 +99,24 @@ func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ignoreNotFound := cmdutil.GetFlagBool(cmd, "ignore-not-found")
 | 
			
		||||
	// By default use a reaper to delete all related resources.
 | 
			
		||||
	if cmdutil.GetFlagBool(cmd, "cascade") {
 | 
			
		||||
		return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), cmdutil.GetFlagInt(cmd, "grace-period"))
 | 
			
		||||
		return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagInt(cmd, "grace-period"))
 | 
			
		||||
	}
 | 
			
		||||
	return DeleteResult(r, out)
 | 
			
		||||
	return DeleteResult(r, out, ignoreNotFound)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefaultDelete bool, gracePeriod int) error {
 | 
			
		||||
func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefaultDelete, ignoreNotFound bool, gracePeriod int) error {
 | 
			
		||||
	found := 0
 | 
			
		||||
	err := r.IgnoreErrors(errors.IsNotFound).Visit(func(info *resource.Info) error {
 | 
			
		||||
	if ignoreNotFound {
 | 
			
		||||
		r = r.IgnoreErrors(errors.IsNotFound)
 | 
			
		||||
	}
 | 
			
		||||
	err := r.Visit(func(info *resource.Info) error {
 | 
			
		||||
		found++
 | 
			
		||||
		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 there is no reaper for this resources and the user didn't explicitly ask for stop.
 | 
			
		||||
			if kubectl.IsNoSuchReaperError(err) && isDefaultDelete {
 | 
			
		||||
				return deleteResource(info, out)
 | 
			
		||||
			}
 | 
			
		||||
@@ -136,9 +141,12 @@ func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefault
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DeleteResult(r *resource.Result, out io.Writer) error {
 | 
			
		||||
func DeleteResult(r *resource.Result, out io.Writer, ignoreNotFound bool) error {
 | 
			
		||||
	found := 0
 | 
			
		||||
	err := r.IgnoreErrors(errors.IsNotFound).Visit(func(info *resource.Info) error {
 | 
			
		||||
	if ignoreNotFound {
 | 
			
		||||
		r = r.IgnoreErrors(errors.IsNotFound)
 | 
			
		||||
	}
 | 
			
		||||
	err := r.Visit(func(info *resource.Info) error {
 | 
			
		||||
		found++
 | 
			
		||||
		return deleteResource(info, out)
 | 
			
		||||
	})
 | 
			
		||||
 
 | 
			
		||||
@@ -18,13 +18,16 @@ package cmd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
			
		||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestDeleteObjectByTuple(t *testing.T) {
 | 
			
		||||
@@ -120,6 +123,34 @@ func TestDeleteObject(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDeleteObjectNotFound(t *testing.T) {
 | 
			
		||||
	f, tf, codec := NewAPIFactory()
 | 
			
		||||
	tf.Printer = &testPrinter{}
 | 
			
		||||
	tf.Client = &client.FakeRESTClient{
 | 
			
		||||
		Codec: codec,
 | 
			
		||||
		Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
 | 
			
		||||
			switch p, m := req.URL.Path, req.Method; {
 | 
			
		||||
			case p == "/namespaces/test/replicationcontrollers/redis-master" && m == "DELETE":
 | 
			
		||||
				return &http.Response{StatusCode: 404, Body: stringBody("")}, nil
 | 
			
		||||
			default:
 | 
			
		||||
				t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
 | 
			
		||||
				return nil, nil
 | 
			
		||||
			}
 | 
			
		||||
		}),
 | 
			
		||||
	}
 | 
			
		||||
	tf.Namespace = "test"
 | 
			
		||||
	buf := bytes.NewBuffer([]byte{})
 | 
			
		||||
 | 
			
		||||
	cmd := NewCmdDelete(f, buf)
 | 
			
		||||
	cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
 | 
			
		||||
	cmd.Flags().Set("cascade", "false")
 | 
			
		||||
	filenames := cmd.Flags().Lookup("filename").Value.(*util.StringList)
 | 
			
		||||
	err := RunDelete(f, buf, cmd, []string{}, *filenames)
 | 
			
		||||
	if err == nil || !errors.IsNotFound(err) {
 | 
			
		||||
		t.Errorf("unexpected error: expected NotFound, got %v", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDeleteObjectIgnoreNotFound(t *testing.T) {
 | 
			
		||||
	f, tf, codec := NewAPIFactory()
 | 
			
		||||
	tf.Printer = &testPrinter{}
 | 
			
		||||
@@ -141,6 +172,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.Flags().Set("ignore-not-found", "true")
 | 
			
		||||
	cmd.Run(cmd, []string{})
 | 
			
		||||
 | 
			
		||||
	if buf.String() != "" {
 | 
			
		||||
@@ -181,7 +213,7 @@ func TestDeleteMultipleObject(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDeleteMultipleObjectIgnoreMissing(t *testing.T) {
 | 
			
		||||
func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
 | 
			
		||||
	_, svc, _ := testData()
 | 
			
		||||
 | 
			
		||||
	f, tf, codec := NewAPIFactory()
 | 
			
		||||
@@ -207,7 +239,12 @@ func TestDeleteMultipleObjectIgnoreMissing(t *testing.T) {
 | 
			
		||||
	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{})
 | 
			
		||||
	filenames := cmd.Flags().Lookup("filename").Value.(*util.StringList)
 | 
			
		||||
	fmt.Printf("filenames: %v\n", filenames)
 | 
			
		||||
	err := RunDelete(f, buf, cmd, []string{}, *filenames)
 | 
			
		||||
	if err == nil || !errors.IsNotFound(err) {
 | 
			
		||||
		t.Errorf("unexpected error: expected NotFound, got %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if buf.String() != "services/frontend\n" {
 | 
			
		||||
		t.Errorf("unexpected output: %s", buf.String())
 | 
			
		||||
 
 | 
			
		||||
@@ -57,10 +57,11 @@ func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
			
		||||
			cmdutil.CheckErr(RunStop(f, cmd, args, flags.Filenames, out))
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	usage := "Filename, directory, or URL to file of resource(s) to be stopped"
 | 
			
		||||
	usage := "Filename, directory, or URL to file of resource(s) to be stopped."
 | 
			
		||||
	kubectl.AddJsonFilenameFlag(cmd, &flags.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().StringP("selector", "l", "", "Selector (label query) to filter on.")
 | 
			
		||||
	cmd.Flags().Bool("all", false, "[-all] to select all the specified resources.")
 | 
			
		||||
	cmd.Flags().Bool("ignore-not-found", false, "Treat \"resource not found\" as a successful stop.")
 | 
			
		||||
	cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
@@ -83,5 +84,5 @@ func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames ut
 | 
			
		||||
	if r.Err() != nil {
 | 
			
		||||
		return r.Err()
 | 
			
		||||
	}
 | 
			
		||||
	return ReapResult(r, f, out, false, cmdutil.GetFlagInt(cmd, "grace-period"))
 | 
			
		||||
	return ReapResult(r, f, out, false, cmdutil.GetFlagBool(cmd, "ignore-not-found"), cmdutil.GetFlagInt(cmd, "grace-period"))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user