2014-10-06 01:24:19 +00:00
/ *
2015-05-01 16:19:44 +00:00
Copyright 2014 The Kubernetes Authors All rights reserved .
2014-10-06 01:24:19 +00:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package cmd
import (
2014-10-27 02:21:31 +00:00
"fmt"
2014-10-06 01:24:19 +00:00
"io"
2015-05-29 23:16:30 +00:00
"time"
2014-10-06 01:24:19 +00:00
"github.com/spf13/cobra"
2014-12-15 17:32:46 +00:00
2015-08-05 22:03:47 +00:00
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
2014-10-06 01:24:19 +00:00
)
2015-08-14 18:46:43 +00:00
// DeleteOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
// referencing the cmd.Flags()
type DeleteOptions struct {
Filenames [ ] string
}
2015-02-20 21:28:43 +00:00
const (
2015-07-16 06:19:47 +00:00
delete_long = ` Delete resources by filenames , stdin , resources and names , or by resources and label selector .
2014-10-06 01:24:19 +00:00
JSON and YAML formats are accepted .
2015-07-16 06:19:47 +00:00
Only one type of the arguments may be specified : filenames , resources and names , or resources and label selector
2014-10-06 01:24:19 +00:00
Note that the delete command does NOT do resource version checks , so if someone
submits an update to a resource right when you submit a delete , their update
2015-02-20 21:28:43 +00:00
will be lost along with the rest of the resource . `
2015-08-12 16:50:09 +00:00
delete_example = ` # Delete a pod using the type and name specified in pod . json .
2015-07-16 00:20:39 +00:00
$ kubectl delete - f . / pod . json
2014-10-06 01:24:19 +00:00
2015-08-12 16:50:09 +00:00
# Delete a pod based on the type and name in the JSON passed into stdin .
2015-02-20 21:28:43 +00:00
$ cat pod . json | kubectl delete - f -
2014-12-15 17:32:46 +00:00
2015-08-19 08:33:02 +00:00
# Delete pods and services with same names "baz" and "foo"
$ kubectl delete pod , service baz foo
2015-08-12 16:50:09 +00:00
# Delete pods and services with label name = myLabel .
2015-02-20 21:28:43 +00:00
$ kubectl delete pods , services - l name = myLabel
2015-02-03 17:59:21 +00:00
2015-08-12 16:50:09 +00:00
# Delete a pod with UID 1234 - 56 - 7890 - 234234 - 456456.
2015-02-20 21:28:43 +00:00
$ kubectl delete pod 1234 - 56 - 7890 - 234234 - 456456
2015-02-12 14:59:58 +00:00
2015-08-12 16:50:09 +00:00
# Delete all pods
2015-02-20 21:28:43 +00:00
$ kubectl delete pods -- all `
)
2015-02-12 14:59:58 +00:00
2015-04-07 18:21:25 +00:00
func NewCmdDelete ( f * cmdutil . Factory , out io . Writer ) * cobra . Command {
2015-07-31 23:42:34 +00:00
p := kubectl . NewHumanReadablePrinter ( false , false , false , false , [ ] string { } )
2015-05-23 20:56:16 +00:00
validArgs := p . HandledResources ( )
2015-08-14 18:46:43 +00:00
options := & DeleteOptions { }
2015-02-20 21:28:43 +00:00
cmd := & cobra . Command {
2015-07-06 11:31:27 +00:00
Use : "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])" ,
2015-07-16 06:19:47 +00:00
Short : "Delete resources by filenames, stdin, resources and names, or by resources and label selector." ,
2015-02-20 21:28:43 +00:00
Long : delete_long ,
Example : delete_example ,
2014-10-06 01:24:19 +00:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2015-07-01 22:47:43 +00:00
cmdutil . CheckErr ( cmdutil . ValidateOutputArgs ( cmd ) )
2015-08-14 18:46:43 +00:00
err := RunDelete ( f , out , cmd , args , options )
2015-03-04 00:24:29 +00:00
cmdutil . CheckErr ( err )
2014-10-06 01:24:19 +00:00
} ,
2015-05-23 20:56:16 +00:00
ValidArgs : validArgs ,
2014-10-06 01:24:19 +00:00
}
2015-05-21 17:01:34 +00:00
usage := "Filename, directory, or URL to a file containing the resource to delete."
2015-08-14 18:46:43 +00:00
kubectl . AddJsonFilenameFlag ( cmd , & options . Filenames , usage )
2015-05-21 17:01:34 +00:00
cmd . Flags ( ) . StringP ( "selector" , "l" , "" , "Selector (label query) to filter on." )
cmd . Flags ( ) . Bool ( "all" , false , "[-all] to select all the specified resources." )
2015-07-07 17:32:05 +00:00
cmd . Flags ( ) . Bool ( "ignore-not-found" , false , "Treat \"resource not found\" as a successful delete. Defaults to \"true\" when --all is specified." )
2015-06-25 00:33:46 +00:00
cmd . Flags ( ) . Bool ( "cascade" , true , "If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true." )
2015-04-28 12:21:57 +00:00
cmd . Flags ( ) . Int ( "grace-period" , - 1 , "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative." )
2015-05-29 23:16:30 +00:00
cmd . Flags ( ) . Duration ( "timeout" , 0 , "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object" )
2015-07-01 22:47:43 +00:00
cmdutil . AddOutputFlagsForMutation ( cmd )
2014-10-06 01:24:19 +00:00
return cmd
}
2015-03-09 22:08:16 +00:00
2015-08-14 18:46:43 +00:00
func RunDelete ( f * cmdutil . Factory , out io . Writer , cmd * cobra . Command , args [ ] string , options * DeleteOptions ) error {
2015-06-26 20:49:34 +00:00
cmdNamespace , enforceNamespace , err := f . DefaultNamespace ( )
2015-03-09 22:08:16 +00:00
if err != nil {
return err
}
2015-07-07 17:32:05 +00:00
deleteAll := cmdutil . GetFlagBool ( cmd , "all" )
2015-03-14 10:45:18 +00:00
mapper , typer := f . Object ( )
2015-03-27 13:46:17 +00:00
r := resource . NewBuilder ( mapper , typer , f . ClientMapperForCommand ( ) ) .
2015-03-09 22:08:16 +00:00
ContinueOnError ( ) .
NamespaceParam ( cmdNamespace ) . DefaultNamespace ( ) .
2015-08-14 18:46:43 +00:00
FilenameParam ( enforceNamespace , options . Filenames ... ) .
2015-03-09 22:08:16 +00:00
SelectorParam ( cmdutil . GetFlagString ( cmd , "selector" ) ) .
2015-07-07 17:32:05 +00:00
SelectAllParam ( deleteAll ) .
2015-04-20 19:00:52 +00:00
ResourceTypeOrNameArgs ( false , args ... ) . RequireObject ( false ) .
2015-03-09 22:08:16 +00:00
Flatten ( ) .
Do ( )
err = r . Err ( )
if err != nil {
return err
}
2015-05-21 17:01:34 +00:00
ignoreNotFound := cmdutil . GetFlagBool ( cmd , "ignore-not-found" )
2015-07-07 17:32:05 +00:00
if deleteAll {
f := cmd . Flags ( ) . Lookup ( "ignore-not-found" )
// The flag should never be missing
if f == nil {
return fmt . Errorf ( "missing --ignore-not-found flag" )
}
// If the user didn't explicitly set the option, default to ignoring NotFound errors when used with --all
if ! f . Changed {
ignoreNotFound = true
}
}
2015-08-05 14:21:47 +00:00
shortOutput := cmdutil . GetFlagString ( cmd , "output" ) == "name"
2015-04-23 04:15:15 +00:00
// By default use a reaper to delete all related resources.
if cmdutil . GetFlagBool ( cmd , "cascade" ) {
2015-07-01 22:47:43 +00:00
return ReapResult ( r , f , out , cmdutil . GetFlagBool ( cmd , "cascade" ) , ignoreNotFound , cmdutil . GetFlagDuration ( cmd , "timeout" ) , cmdutil . GetFlagInt ( cmd , "grace-period" ) , shortOutput , mapper )
2015-04-23 04:15:15 +00:00
}
2015-07-01 22:47:43 +00:00
return DeleteResult ( r , out , ignoreNotFound , shortOutput , mapper )
2015-04-23 04:15:15 +00:00
}
2015-07-01 22:47:43 +00:00
func ReapResult ( r * resource . Result , f * cmdutil . Factory , out io . Writer , isDefaultDelete , ignoreNotFound bool , timeout time . Duration , gracePeriod int , shortOutput bool , mapper meta . RESTMapper ) error {
2015-03-09 22:08:16 +00:00
found := 0
2015-05-21 17:01:34 +00:00
if ignoreNotFound {
r = r . IgnoreErrors ( errors . IsNotFound )
}
2015-06-15 02:48:56 +00:00
err := r . Visit ( func ( info * resource . Info , err error ) error {
if err != nil {
return err
}
2015-03-09 22:08:16 +00:00
found ++
2015-04-23 04:15:15 +00:00
reaper , err := f . Reaper ( info . Mapping )
if err != nil {
2015-05-21 17:01:34 +00:00
// If there is no reaper for this resources and the user didn't explicitly ask for stop.
2015-04-23 04:15:15 +00:00
if kubectl . IsNoSuchReaperError ( err ) && isDefaultDelete {
2015-07-01 22:47:43 +00:00
return deleteResource ( info , out , shortOutput , mapper )
2015-04-23 04:15:15 +00:00
}
2015-06-23 12:26:27 +00:00
return cmdutil . AddSourceToErr ( "reaping" , info . Source , err )
2015-03-09 22:08:16 +00:00
}
2015-04-28 12:21:57 +00:00
var options * api . DeleteOptions
if gracePeriod >= 0 {
options = api . NewDeleteOptions ( int64 ( gracePeriod ) )
}
2015-05-29 23:16:30 +00:00
if _ , err := reaper . Stop ( info . Namespace , info . Name , timeout , options ) ; err != nil {
2015-06-23 12:26:27 +00:00
return cmdutil . AddSourceToErr ( "stopping" , info . Source , err )
2015-04-23 04:15:15 +00:00
}
2015-07-01 22:47:43 +00:00
cmdutil . PrintSuccess ( mapper , shortOutput , out , info . Mapping . Resource , info . Name , "deleted" )
2015-03-09 22:08:16 +00:00
return nil
} )
if err != nil {
return err
}
if found == 0 {
2015-04-23 04:15:15 +00:00
fmt . Fprintf ( out , "No resources found\n" )
}
return nil
}
2015-07-01 22:47:43 +00:00
func DeleteResult ( r * resource . Result , out io . Writer , ignoreNotFound bool , shortOutput bool , mapper meta . RESTMapper ) error {
2015-04-23 04:15:15 +00:00
found := 0
2015-05-21 17:01:34 +00:00
if ignoreNotFound {
r = r . IgnoreErrors ( errors . IsNotFound )
}
2015-06-15 02:48:56 +00:00
err := r . Visit ( func ( info * resource . Info , err error ) error {
if err != nil {
return err
}
2015-04-23 04:15:15 +00:00
found ++
2015-07-01 22:47:43 +00:00
return deleteResource ( info , out , shortOutput , mapper )
2015-04-23 04:15:15 +00:00
} )
if err != nil {
return err
}
if found == 0 {
fmt . Fprintf ( out , "No resources found\n" )
}
return nil
}
2015-07-01 22:47:43 +00:00
func deleteResource ( info * resource . Info , out io . Writer , shortOutput bool , mapper meta . RESTMapper ) error {
2015-04-23 04:15:15 +00:00
if err := resource . NewHelper ( info . Client , info . Mapping ) . Delete ( info . Namespace , info . Name ) ; err != nil {
2015-06-23 12:26:27 +00:00
return cmdutil . AddSourceToErr ( "deleting" , info . Source , err )
2015-03-09 22:08:16 +00:00
}
2015-07-01 22:47:43 +00:00
cmdutil . PrintSuccess ( mapper , shortOutput , out , info . Mapping . Resource , info . Name , "deleted" )
2015-03-09 22:08:16 +00:00
return nil
}