Skip to content

Commit

Permalink
Merge pull request #93384 from zhouya0/support_kubectl_delete_foreground
Browse files Browse the repository at this point in the history
Support kubectl delete orphan/foreground/background options
  • Loading branch information
k8s-ci-robot committed Sep 24, 2020
2 parents 63d4a03 + 383b5f6 commit d9b576d
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 104 deletions.
6 changes: 5 additions & 1 deletion staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,11 @@ func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
return err
}

o.DeleteOptions = o.DeleteFlags.ToOptions(o.DynamicClient, o.IOStreams)
o.DeleteOptions, err = o.DeleteFlags.ToOptions(o.DynamicClient, o.IOStreams)
if err != nil {
return err
}

err = o.DeleteOptions.FilenameOptions.RequireFilenameOrKustomize()
if err != nil {
return err
Expand Down
31 changes: 16 additions & 15 deletions staging/src/k8s.io/kubectl/pkg/cmd/apply/patcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/jonboulle/clockwork"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -57,10 +58,10 @@ type Patcher struct {
Overwrite bool
BackOff clockwork.Clock

Force bool
Cascade bool
Timeout time.Duration
GracePeriod int
Force bool
CascadingStrategy metav1.DeletionPropagation
Timeout time.Duration
GracePeriod int

// If set, forces the patch against a specific resourceVersion
ResourceVersion *string
Expand All @@ -78,21 +79,21 @@ func newPatcher(o *ApplyOptions, info *resource.Info, helper *resource.Helper) (
}

return &Patcher{
Mapping: info.Mapping,
Helper: helper,
Overwrite: o.Overwrite,
BackOff: clockwork.NewRealClock(),
Force: o.DeleteOptions.ForceDeletion,
Cascade: o.DeleteOptions.Cascade,
Timeout: o.DeleteOptions.Timeout,
GracePeriod: o.DeleteOptions.GracePeriod,
OpenapiSchema: openapiSchema,
Retries: maxPatchRetry,
Mapping: info.Mapping,
Helper: helper,
Overwrite: o.Overwrite,
BackOff: clockwork.NewRealClock(),
Force: o.DeleteOptions.ForceDeletion,
CascadingStrategy: o.DeleteOptions.CascadingStrategy,
Timeout: o.DeleteOptions.Timeout,
GracePeriod: o.DeleteOptions.GracePeriod,
OpenapiSchema: openapiSchema,
Retries: maxPatchRetry,
}, nil
}

func (p *Patcher) delete(namespace, name string) error {
options := asDeleteOptions(p.Cascade, p.GracePeriod)
options := asDeleteOptions(p.CascadingStrategy, p.GracePeriod)
_, err := p.Helper.DeleteWithOptions(namespace, name, &options)
return err
}
Expand Down
26 changes: 11 additions & 15 deletions staging/src/k8s.io/kubectl/pkg/cmd/apply/prune.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ type pruner struct {
labelSelector string
fieldSelector string

cascade bool
dryRunStrategy cmdutil.DryRunStrategy
gracePeriod int
cascadingStrategy metav1.DeletionPropagation
dryRunStrategy cmdutil.DryRunStrategy
gracePeriod int

toPrinter func(string) (printers.ResourcePrinter, error)

Expand All @@ -59,9 +59,9 @@ func newPruner(o *ApplyOptions) pruner {
visitedUids: o.VisitedUids,
visitedNamespaces: o.VisitedNamespaces,

cascade: o.DeleteOptions.Cascade,
dryRunStrategy: o.DryRunStrategy,
gracePeriod: o.DeleteOptions.GracePeriod,
cascadingStrategy: o.DeleteOptions.CascadingStrategy,
dryRunStrategy: o.DryRunStrategy,
gracePeriod: o.DeleteOptions.GracePeriod,

toPrinter: o.ToPrinter,

Expand Down Expand Up @@ -139,27 +139,23 @@ func (p *pruner) prune(namespace string, mapping *meta.RESTMapping) error {
}

func (p *pruner) delete(namespace, name string, mapping *meta.RESTMapping) error {
return runDelete(namespace, name, mapping, p.dynamicClient, p.cascade, p.gracePeriod, p.dryRunStrategy == cmdutil.DryRunServer)
return runDelete(namespace, name, mapping, p.dynamicClient, p.cascadingStrategy, p.gracePeriod, p.dryRunStrategy == cmdutil.DryRunServer)
}

func runDelete(namespace, name string, mapping *meta.RESTMapping, c dynamic.Interface, cascade bool, gracePeriod int, serverDryRun bool) error {
options := asDeleteOptions(cascade, gracePeriod)
func runDelete(namespace, name string, mapping *meta.RESTMapping, c dynamic.Interface, cascadingStrategy metav1.DeletionPropagation, gracePeriod int, serverDryRun bool) error {
options := asDeleteOptions(cascadingStrategy, gracePeriod)
if serverDryRun {
options.DryRun = []string{metav1.DryRunAll}
}
return c.Resource(mapping.Resource).Namespace(namespace).Delete(context.TODO(), name, options)
}

func asDeleteOptions(cascade bool, gracePeriod int) metav1.DeleteOptions {
func asDeleteOptions(cascadingStrategy metav1.DeletionPropagation, gracePeriod int) metav1.DeleteOptions {
options := metav1.DeleteOptions{}
if gracePeriod >= 0 {
options = *metav1.NewDeleteOptions(int64(gracePeriod))
}
policy := metav1.DeletePropagationForeground
if !cascade {
policy = metav1.DeletePropagationOrphan
}
options.PropagationPolicy = &policy
options.PropagationPolicy = &cascadingStrategy
return options
}

Expand Down
11 changes: 4 additions & 7 deletions staging/src/k8s.io/kubectl/pkg/cmd/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ type DeleteOptions struct {
FieldSelector string
DeleteAll bool
DeleteAllNamespaces bool
CascadingStrategy metav1.DeletionPropagation
IgnoreNotFound bool
Cascade bool
DeleteNow bool
ForceDeletion bool
WaitForDeletion bool
Expand Down Expand Up @@ -136,7 +136,8 @@ func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
o := deleteFlags.ToOptions(nil, streams)
o, err := deleteFlags.ToOptions(nil, streams)
cmdutil.CheckErr(err)
cmdutil.CheckErr(o.Complete(f, args, cmd))
cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(o.RunDelete(f))
Expand Down Expand Up @@ -301,11 +302,7 @@ func (o *DeleteOptions) DeleteResult(r *resource.Result) error {
if o.GracePeriod >= 0 {
options = metav1.NewDeleteOptions(int64(o.GracePeriod))
}
policy := metav1.DeletePropagationBackground
if !o.Cascade {
policy = metav1.DeletePropagationOrphan
}
options.PropagationPolicy = &policy
options.PropagationPolicy = &o.CascadingStrategy

if warnClusterScope && info.Mapping.Scope.Name() == meta.RESTScopeNameRoot {
fmt.Fprintf(o.ErrOut, "warning: deleting cluster-scoped resources, not scoped to the provided namespace\n")
Expand Down
83 changes: 60 additions & 23 deletions staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ limitations under the License.
package delete

import (
"fmt"
"strconv"
"time"

"github.com/spf13/cobra"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/client-go/dynamic"
"k8s.io/klog/v2"
)

// DeleteFlags composes common printer flag structs
Expand All @@ -32,20 +36,20 @@ type DeleteFlags struct {
LabelSelector *string
FieldSelector *string

All *bool
AllNamespaces *bool
Cascade *bool
Force *bool
GracePeriod *int
IgnoreNotFound *bool
Now *bool
Timeout *time.Duration
Wait *bool
Output *string
Raw *string
All *bool
AllNamespaces *bool
CascadingStrategy *string
Force *bool
GracePeriod *int
IgnoreNotFound *bool
Now *bool
Timeout *time.Duration
Wait *bool
Output *string
Raw *string
}

func (f *DeleteFlags) ToOptions(dynamicClient dynamic.Interface, streams genericclioptions.IOStreams) *DeleteOptions {
func (f *DeleteFlags) ToOptions(dynamicClient dynamic.Interface, streams genericclioptions.IOStreams) (*DeleteOptions, error) {
options := &DeleteOptions{
DynamicClient: dynamicClient,
IOStreams: streams,
Expand Down Expand Up @@ -73,8 +77,12 @@ func (f *DeleteFlags) ToOptions(dynamicClient dynamic.Interface, streams generic
if f.AllNamespaces != nil {
options.DeleteAllNamespaces = *f.AllNamespaces
}
if f.Cascade != nil {
options.Cascade = *f.Cascade
if f.CascadingStrategy != nil {
var err error
options.CascadingStrategy, err = getCascadingStrategy(*f.CascadingStrategy)
if err != nil {
return nil, err
}
}
if f.Force != nil {
options.ForceDeletion = *f.Force
Expand All @@ -98,7 +106,7 @@ func (f *DeleteFlags) ToOptions(dynamicClient dynamic.Interface, streams generic
options.Raw = *f.Raw
}

return options
return options, nil
}

func (f *DeleteFlags) AddFlags(cmd *cobra.Command) {
Expand All @@ -118,8 +126,13 @@ func (f *DeleteFlags) AddFlags(cmd *cobra.Command) {
if f.Force != nil {
cmd.Flags().BoolVar(f.Force, "force", *f.Force, "If true, immediately remove resources from API and bypass graceful deletion. Note that immediate deletion of some resources may result in inconsistency or data loss and requires confirmation.")
}
if f.Cascade != nil {
cmd.Flags().BoolVar(f.Cascade, "cascade", *f.Cascade, "If true, run background cascade deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.")
if f.CascadingStrategy != nil {
cmd.Flags().StringVar(
f.CascadingStrategy,
"cascade",
*f.CascadingStrategy,
`Must be "background", "orphan", or "foreground". Selects the deletion cascading strategy for the dependents (e.g. Pods created by a ReplicationController). Defaults to background.`)
cmd.Flags().Lookup("cascade").NoOptDefVal = "background"
}
if f.Now != nil {
cmd.Flags().BoolVar(f.Now, "now", *f.Now, "If true, resources are signaled for immediate shutdown (same as --grace-period=1).")
Expand All @@ -146,7 +159,7 @@ func (f *DeleteFlags) AddFlags(cmd *cobra.Command) {

// NewDeleteCommandFlags provides default flags and values for use with the "delete" command
func NewDeleteCommandFlags(usage string) *DeleteFlags {
cascade := true
cascadingStrategy := "background"
gracePeriod := -1

// setup command defaults
Expand All @@ -172,8 +185,8 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags {
LabelSelector: &labelSelector,
FieldSelector: &fieldSelector,

Cascade: &cascade,
GracePeriod: &gracePeriod,
CascadingStrategy: &cascadingStrategy,
GracePeriod: &gracePeriod,

All: &all,
AllNamespaces: &allNamespaces,
Expand All @@ -189,7 +202,7 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags {

// NewDeleteFlags provides default flags and values for use in commands outside of "delete"
func NewDeleteFlags(usage string) *DeleteFlags {
cascade := true
cascadingStrategy := "background"
gracePeriod := -1

force := false
Expand All @@ -203,12 +216,36 @@ func NewDeleteFlags(usage string) *DeleteFlags {
return &DeleteFlags{
FileNameFlags: &genericclioptions.FileNameFlags{Usage: usage, Filenames: &filenames, Kustomize: &kustomize, Recursive: &recursive},

Cascade: &cascade,
GracePeriod: &gracePeriod,
CascadingStrategy: &cascadingStrategy,
GracePeriod: &gracePeriod,

// add non-defaults
Force: &force,
Timeout: &timeout,
Wait: &wait,
}
}

func getCascadingStrategy(cascadingFlag string) (metav1.DeletionPropagation, error) {
b, err := strconv.ParseBool(cascadingFlag)
// The flag is not a boolean
if err != nil {
switch cascadingFlag {
case "orphan":
return metav1.DeletePropagationOrphan, nil
case "foreground":
return metav1.DeletePropagationForeground, nil
case "background":
return metav1.DeletePropagationBackground, nil
default:
return metav1.DeletePropagationBackground, fmt.Errorf(`Invalid cascade value (%v). Must be "background", "foreground", or "orphan".`, cascadingFlag)
}
}
// The flag was a boolean
if b {
klog.Warningf(`--cascade=%v is deprecated (boolean value) and can be replaced with --cascade=%s.`, cascadingFlag, "background")
return metav1.DeletePropagationBackground, nil
}
klog.Warningf(`--cascade=%v is deprecated (boolean value) and can be replaced with --cascade=%s.`, cascadingFlag, "orphan")
return metav1.DeletePropagationOrphan, nil
}

0 comments on commit d9b576d

Please sign in to comment.