mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #8628 from jlowdermilk/delete-not-found
Delete fails on notfound errors.
This commit is contained in:
commit
eab1ceccd4
@ -364,6 +364,7 @@ _kubectl_delete()
|
|||||||
flags+=("--grace-period=")
|
flags+=("--grace-period=")
|
||||||
flags+=("--help")
|
flags+=("--help")
|
||||||
flags+=("-h")
|
flags+=("-h")
|
||||||
|
flags+=("--ignore-not-found")
|
||||||
flags+=("--selector=")
|
flags+=("--selector=")
|
||||||
two_word_flags+=("-l")
|
two_word_flags+=("-l")
|
||||||
|
|
||||||
@ -587,6 +588,7 @@ _kubectl_stop()
|
|||||||
flags+=("--grace-period=")
|
flags+=("--grace-period=")
|
||||||
flags+=("--help")
|
flags+=("--help")
|
||||||
flags+=("-h")
|
flags+=("-h")
|
||||||
|
flags+=("--ignore-not-found")
|
||||||
flags+=("--selector=")
|
flags+=("--selector=")
|
||||||
two_word_flags+=("-l")
|
two_word_flags+=("-l")
|
||||||
|
|
||||||
|
@ -42,12 +42,13 @@ $ kubectl delete pods --all
|
|||||||
### Options
|
### 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.
|
--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.
|
--grace-period=-1: Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.
|
||||||
-h, --help=false: help for delete
|
-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
|
### Options inherited from parent commands
|
||||||
@ -82,6 +83,6 @@ $ kubectl delete pods --all
|
|||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
* [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
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
--all=false: [-all] to select all the specified resources
|
--all=false: [-all] to select all the specified resources.
|
||||||
-f, --filename=[]: Filename, directory, or URL to file of resource(s) to be stopped
|
-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.
|
--grace-period=-1: Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.
|
||||||
-h, --help=false: help for stop
|
-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
|
### Options inherited from parent commands
|
||||||
@ -72,6 +73,6 @@ $ kubectl stop -f path/to/resources
|
|||||||
### SEE ALSO
|
### SEE ALSO
|
||||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
* [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
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-all\fP=false
|
\fB\-\-all\fP=false
|
||||||
[\-all] to select all the specified resources
|
[\-all] to select all the specified resources.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-cascade\fP=true
|
\fB\-\-cascade\fP=true
|
||||||
@ -39,7 +39,7 @@ will be lost along with the rest of the resource.
|
|||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-f\fP, \fB\-\-filename\fP=[]
|
\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
|
.PP
|
||||||
\fB\-\-grace\-period\fP=\-1
|
\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
|
\fB\-h\fP, \fB\-\-help\fP=false
|
||||||
help for delete
|
help for delete
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-ignore\-not\-found\fP=false
|
||||||
|
Treat "resource not found" as a successful delete.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-l\fP, \fB\-\-selector\fP=""
|
\fB\-l\fP, \fB\-\-selector\fP=""
|
||||||
Selector (label query) to filter on
|
Selector (label query) to filter on.
|
||||||
|
|
||||||
|
|
||||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
.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
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-all\fP=false
|
\fB\-\-all\fP=false
|
||||||
[\-all] to select all the specified resources
|
[\-all] to select all the specified resources.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-f\fP, \fB\-\-filename\fP=[]
|
\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
|
.PP
|
||||||
\fB\-\-grace\-period\fP=\-1
|
\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
|
\fB\-h\fP, \fB\-\-help\fP=false
|
||||||
help for stop
|
help for stop
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-ignore\-not\-found\fP=false
|
||||||
|
Treat "resource not found" as a successful stop.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-l\fP, \fB\-\-selector\fP=""
|
\fB\-l\fP, \fB\-\-selector\fP=""
|
||||||
Selector (label query) to filter on
|
Selector (label query) to filter on.
|
||||||
|
|
||||||
|
|
||||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||||
|
@ -92,7 +92,7 @@ if ! hack/verify-gendocs.sh > /dev/null; then
|
|||||||
echo "${red}ERROR!"
|
echo "${red}ERROR!"
|
||||||
echo "Some docs are out of sync between CLI and markdown."
|
echo "Some docs are out of sync between CLI and markdown."
|
||||||
echo "To regenerate docs, run:"
|
echo "To regenerate docs, run:"
|
||||||
echo " hack/run-gendocs.sh > docs/kubectl.md"
|
echo " hack/run-gendocs.sh"
|
||||||
exit_code=1
|
exit_code=1
|
||||||
else
|
else
|
||||||
echo "${green}OK"
|
echo "${green}OK"
|
||||||
|
@ -69,10 +69,11 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
cmdutil.CheckErr(err)
|
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)
|
kubectl.AddJsonFilenameFlag(cmd, &filenames, usage)
|
||||||
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
|
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("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().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.")
|
cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
|
||||||
return cmd
|
return cmd
|
||||||
@ -98,20 +99,24 @@ func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ignoreNotFound := cmdutil.GetFlagBool(cmd, "ignore-not-found")
|
||||||
// By default use a reaper to delete all related resources.
|
// By default use a reaper to delete all related resources.
|
||||||
if cmdutil.GetFlagBool(cmd, "cascade") {
|
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
|
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++
|
found++
|
||||||
reaper, err := f.Reaper(info.Mapping)
|
reaper, err := f.Reaper(info.Mapping)
|
||||||
if err != nil {
|
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 {
|
if kubectl.IsNoSuchReaperError(err) && isDefaultDelete {
|
||||||
return deleteResource(info, out)
|
return deleteResource(info, out)
|
||||||
}
|
}
|
||||||
@ -136,9 +141,12 @@ func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefault
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteResult(r *resource.Result, out io.Writer) error {
|
func DeleteResult(r *resource.Result, out io.Writer, ignoreNotFound bool) error {
|
||||||
found := 0
|
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++
|
found++
|
||||||
return deleteResource(info, out)
|
return deleteResource(info, out)
|
||||||
})
|
})
|
||||||
|
@ -18,13 +18,16 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"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/api/testapi"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDeleteObjectByTuple(t *testing.T) {
|
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) {
|
func TestDeleteObjectIgnoreNotFound(t *testing.T) {
|
||||||
f, tf, codec := NewAPIFactory()
|
f, tf, codec := NewAPIFactory()
|
||||||
tf.Printer = &testPrinter{}
|
tf.Printer = &testPrinter{}
|
||||||
@ -141,6 +172,7 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) {
|
|||||||
cmd := NewCmdDelete(f, buf)
|
cmd := NewCmdDelete(f, buf)
|
||||||
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
|
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.json")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
|
cmd.Flags().Set("ignore-not-found", "true")
|
||||||
cmd.Run(cmd, []string{})
|
cmd.Run(cmd, []string{})
|
||||||
|
|
||||||
if buf.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()
|
_, svc, _ := testData()
|
||||||
|
|
||||||
f, tf, codec := NewAPIFactory()
|
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/redis-master-controller.json")
|
||||||
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json")
|
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.json")
|
||||||
cmd.Flags().Set("cascade", "false")
|
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" {
|
if buf.String() != "services/frontend\n" {
|
||||||
t.Errorf("unexpected output: %s", buf.String())
|
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))
|
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)
|
kubectl.AddJsonFilenameFlag(cmd, &flags.Filenames, usage)
|
||||||
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on")
|
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("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.")
|
cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@ -83,5 +84,5 @@ func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames ut
|
|||||||
if r.Err() != nil {
|
if r.Err() != nil {
|
||||||
return r.Err()
|
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"))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user