diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go b/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go index 7531f581af1..800fa736bd6 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go @@ -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 diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/apply/patcher.go b/staging/src/k8s.io/kubectl/pkg/cmd/apply/patcher.go index e7522273aaf..f14fdd06632 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/apply/patcher.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/apply/patcher.go @@ -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" @@ -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 @@ -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 } diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/apply/prune.go b/staging/src/k8s.io/kubectl/pkg/cmd/apply/prune.go index 6856fcea6dc..724fe9d14db 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/apply/prune.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/apply/prune.go @@ -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) @@ -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, @@ -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 } diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete.go b/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete.go index 088d85aa655..1ba0ceae848 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete.go @@ -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 @@ -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)) @@ -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") diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_flags.go b/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_flags.go index 20447ff0bf9..863ca1cbc1e 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_flags.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_flags.go @@ -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 @@ -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, @@ -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 @@ -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) { @@ -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).") @@ -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 @@ -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, @@ -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 @@ -203,8 +216,8 @@ 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, @@ -212,3 +225,27 @@ func NewDeleteFlags(usage string) *DeleteFlags { 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 +} diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_test.go b/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_test.go index f4faf6289f5..f5e36e3bbee 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_test.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete_test.go @@ -112,8 +112,8 @@ func hasExpectedPropagationPolicy(body io.ReadCloser, policy *metav1.DeletionPro return *policy == *parsedBody.PropagationPolicy } -// Tests that DeleteOptions.OrphanDependents is appropriately set while deleting objects. -func TestOrphanDependentsInDeleteObject(t *testing.T) { +// TestCascadingStrategy tests that DeleteOptions.DeletionPropagation is appropriately set while deleting objects. +func TestCascadingStrategy(t *testing.T) { cmdtesting.InitTestErrorHandler(t) _, _, rc := cmdtesting.TestData() @@ -137,7 +137,7 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) { }), } - // DeleteOptions.PropagationPolicy should be Background, when cascade is true (default). + // DeleteOptions.PropagationPolicy should be Background, when cascading strategy is empty (default). backgroundPolicy := metav1.DeletePropagationBackground policy = &backgroundPolicy streams, _, buf, _ := genericclioptions.NewTestIOStreams() @@ -149,13 +149,26 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) { t.Errorf("unexpected output: %s", buf.String()) } - // Test that delete options should be set to orphan when cascade is false. + // DeleteOptions.PropagationPolicy should be Foreground, when cascading strategy is foreground. + foregroundPolicy := metav1.DeletePropagationForeground + policy = &foregroundPolicy + streams, _, buf, _ = genericclioptions.NewTestIOStreams() + cmd = NewCmdDelete(tf, streams) + cmd.Flags().Set("namespace", "test") + cmd.Flags().Set("cascade", "foreground") + cmd.Flags().Set("output", "name") + cmd.Run(cmd, []string{"secrets/mysecret"}) + if buf.String() != "secret/mysecret\n" { + t.Errorf("unexpected output: %s", buf.String()) + } + + // Test that delete options should be set to orphan when cascading strategy is orphan. orphanPolicy := metav1.DeletePropagationOrphan policy = &orphanPolicy streams, _, buf, _ = genericclioptions.NewTestIOStreams() cmd = NewCmdDelete(tf, streams) cmd.Flags().Set("namespace", "test") - cmd.Flags().Set("cascade", "false") + cmd.Flags().Set("cascade", "orphan") cmd.Flags().Set("output", "name") cmd.Run(cmd, []string{"secrets/mysecret"}) if buf.String() != "secret/mysecret\n" { @@ -427,10 +440,10 @@ func TestDeleteObjectNotFound(t *testing.T) { FilenameOptions: resource.FilenameOptions{ Filenames: []string{"../../../testdata/redis-master-controller.yaml"}, }, - GracePeriod: -1, - Cascade: false, - Output: "name", - IOStreams: genericclioptions.NewTestIOStreamsDiscard(), + GracePeriod: -1, + CascadingStrategy: metav1.DeletePropagationOrphan, + Output: "name", + IOStreams: genericclioptions.NewTestIOStreamsDiscard(), } err := options.Complete(tf, []string{}, fakecmd()) if err != nil { @@ -504,13 +517,13 @@ func TestDeleteAllNotFound(t *testing.T) { // Make sure we can explicitly choose to fail on NotFound errors, even with --all options := &DeleteOptions{ - FilenameOptions: resource.FilenameOptions{}, - GracePeriod: -1, - Cascade: false, - DeleteAll: true, - IgnoreNotFound: false, - Output: "name", - IOStreams: genericclioptions.NewTestIOStreamsDiscard(), + FilenameOptions: resource.FilenameOptions{}, + GracePeriod: -1, + CascadingStrategy: metav1.DeletePropagationOrphan, + DeleteAll: true, + IgnoreNotFound: false, + Output: "name", + IOStreams: genericclioptions.NewTestIOStreamsDiscard(), } err := options.Complete(tf, []string{"services"}, fakecmd()) if err != nil { @@ -630,10 +643,10 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) { FilenameOptions: resource.FilenameOptions{ Filenames: []string{"../../../testdata/redis-master-controller.yaml", "../../../testdata/frontend-service.yaml"}, }, - GracePeriod: -1, - Cascade: false, - Output: "name", - IOStreams: streams, + GracePeriod: -1, + CascadingStrategy: metav1.DeletePropagationOrphan, + Output: "name", + IOStreams: streams, } err := options.Complete(tf, []string{}, fakecmd()) if err != nil { @@ -801,11 +814,11 @@ func TestResourceErrors(t *testing.T) { streams, _, buf, _ := genericclioptions.NewTestIOStreams() options := &DeleteOptions{ - FilenameOptions: resource.FilenameOptions{}, - GracePeriod: -1, - Cascade: false, - Output: "name", - IOStreams: streams, + FilenameOptions: resource.FilenameOptions{}, + GracePeriod: -1, + CascadingStrategy: metav1.DeletePropagationOrphan, + Output: "name", + IOStreams: streams, } err := options.Complete(tf, testCase.args, fakecmd()) if !testCase.errFn(err) { diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/replace/replace.go b/staging/src/k8s.io/kubectl/pkg/cmd/replace/replace.go index 03b809c8d64..ff4a9be31ed 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/replace/replace.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/replace/replace.go @@ -171,7 +171,10 @@ func (o *ReplaceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [] return printer.PrintObj(obj, o.Out) } - deleteOpts := o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams) + deleteOpts, err := o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams) + if err != nil { + return err + } //Replace will create a resource if it doesn't exist already, so ignore not found error deleteOpts.IgnoreNotFound = true diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/run/run.go b/staging/src/k8s.io/kubectl/pkg/cmd/run/run.go index 524f0093c4a..6910caf6b85 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/run/run.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/run/run.go @@ -245,7 +245,11 @@ func (o *RunOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { return printer.PrintObj(obj, o.Out) } - deleteOpts := o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams) + deleteOpts, err := o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams) + if err != nil { + return err + } + deleteOpts.IgnoreNotFound = true deleteOpts.WaitForDeletion = false deleteOpts.GracePeriod = -1 diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/run/run_test.go b/staging/src/k8s.io/kubectl/pkg/cmd/run/run_test.go index 0fb7686fd1a..d2a264fb6c5 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/run/run_test.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/run/run_test.go @@ -199,9 +199,14 @@ func TestRunArgsFollowDashRules(t *testing.T) { } deleteFlags := delete.NewDeleteFlags("to use to replace the resource.") + deleteOptions, err := deleteFlags.ToOptions(nil, genericclioptions.NewTestIOStreamsDiscard()) + if err != nil { + t.Errorf("unexpected error: %v", err) + return + } opts := &RunOptions{ PrintFlags: printFlags, - DeleteOptions: deleteFlags.ToOptions(nil, genericclioptions.NewTestIOStreamsDiscard()), + DeleteOptions: deleteOptions, IOStreams: genericclioptions.NewTestIOStreamsDiscard(), @@ -371,9 +376,14 @@ func TestGenerateService(t *testing.T) { ioStreams, _, buff, _ := genericclioptions.NewTestIOStreams() deleteFlags := delete.NewDeleteFlags("to use to replace the resource.") + deleteOptions, err := deleteFlags.ToOptions(nil, genericclioptions.NewTestIOStreamsDiscard()) + if err != nil { + t.Errorf("unexpected error: %v", err) + return + } opts := &RunOptions{ PrintFlags: printFlags, - DeleteOptions: deleteFlags.ToOptions(nil, genericclioptions.NewTestIOStreamsDiscard()), + DeleteOptions: deleteOptions, IOStreams: ioStreams, diff --git a/test/cmd/apps.sh b/test/cmd/apps.sh index c119a9b8b35..dca1b696b9a 100755 --- a/test/cmd/apps.sh +++ b/test/cmd/apps.sh @@ -137,7 +137,7 @@ run_kubectl_apply_deployments_tests() { # cleanup # need to explicitly remove replicasets and pods because we changed the deployment selector and orphaned things - kubectl delete deployments,rs,pods --all --cascade=false --grace-period=0 + kubectl delete deployments,rs,pods --all --cascade=orphan --grace-period=0 # Post-Condition: no Deployments, ReplicaSets, Pods exist kube::test::wait_object_assert deployments "{{range.items}}{{${id_field:?}}}:{{end}}" '' kube::test::wait_object_assert replicasets "{{range.items}}{{${id_field:?}}}:{{end}}" '' @@ -246,10 +246,11 @@ run_deployment_tests() { # Wait for rs to come up. kube::test::wait_object_assert rs "{{range.items}}{{${rs_replicas_field:?}}}{{end}}" '3' # Deleting the deployment should delete the rs. - kubectl delete deployment nginx-deployment "${kube_flags[@]:?}" + # using empty value in cascade flag to make sure the backward compatibility. + kubectl delete deployment nginx-deployment "${kube_flags[@]:?}" --cascade kube::test::wait_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" '' - ## Test that rs is not deleted when deployment is deleted with cascade set to false. + ## Test that rs is not deleted when deployment is deleted with cascading strategy set to orphan. # Pre-condition: no deployment and rs exist kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" '' kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" '' @@ -257,8 +258,8 @@ run_deployment_tests() { kubectl create deployment nginx-deployment --image=k8s.gcr.io/nginx:test-cmd # Wait for rs to come up. kube::test::wait_object_assert rs "{{range.items}}{{${rs_replicas_field:?}}}{{end}}" '1' - # Delete the deployment with cascade set to false. - kubectl delete deployment nginx-deployment "${kube_flags[@]:?}" --cascade=false + # Delete the deployment with cascading strategy set to orphan. + kubectl delete deployment nginx-deployment "${kube_flags[@]:?}" --cascade=orphan # Wait for the deployment to be deleted and then verify that rs is not # deleted. kube::test::wait_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" '' @@ -545,7 +546,7 @@ run_rs_tests() { # Post-condition: no pods from frontend replica set kube::test::wait_object_assert 'pods -l "tier=frontend"' "{{range.items}}{{${id_field:?}}}:{{end}}" '' - ### Create and then delete a replica set with cascade=false, make sure it doesn't delete pods. + ### Create and then delete a replica set with cascading strategy set to orphan, make sure it doesn't delete pods. # Pre-condition: no replica set exists kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" '' # Command @@ -553,7 +554,7 @@ run_rs_tests() { # wait for all 3 pods to be set up kube::test::wait_object_assert 'pods -l "tier=frontend"' "{{range.items}}{{${pod_container_name_field:?}}}:{{end}}" 'php-redis:php-redis:php-redis:' kube::log::status "Deleting rs" - kubectl delete rs frontend "${kube_flags[@]:?}" --cascade=false + kubectl delete rs frontend "${kube_flags[@]:?}" --cascade=orphan # Wait for the rs to be deleted. kube::test::wait_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" '' # Post-condition: All 3 pods still remain from frontend replica set diff --git a/test/cmd/crd.sh b/test/cmd/crd.sh index 0549337cdd8..52e72293e3b 100755 --- a/test/cmd/crd.sh +++ b/test/cmd/crd.sh @@ -194,8 +194,8 @@ run_non_native_resource_tests() { output_message=$(kubectl "${kube_flags[@]}" get kind.mygroup.example.com/myobj -o name) kube::test::if_has_string "${output_message}" 'kind.mygroup.example.com/myobj' - # Delete the resource with cascade. - kubectl "${kube_flags[@]}" delete resources myobj --cascade=true + # Delete the resource with cascading strategy background. + kubectl "${kube_flags[@]}" delete resources myobj --cascade=background # Make sure it's gone kube::test::wait_object_assert resources "{{range.items}}{{$id_field}}:{{end}}" '' @@ -275,8 +275,8 @@ run_non_native_resource_tests() { kubectl "${kube_flags[@]}" describe foos | grep listlabel=true kubectl "${kube_flags[@]}" describe foos | grep itemlabel=true - # Delete the resource with cascade. - kubectl "${kube_flags[@]}" delete foos test --cascade=true + # Delete the resource with cascading strategy background. + kubectl "${kube_flags[@]}" delete foos test --cascade=background # Make sure it's gone kube::test::wait_object_assert foos "{{range.items}}{{$id_field}}:{{end}}" '' @@ -313,8 +313,8 @@ run_non_native_resource_tests() { kill -9 "${patch_pid}" kube::test::if_has_string "${watch_output}" 'bar.company.com/test' - # Delete the resource without cascade. - kubectl "${kube_flags[@]}" delete bars test --cascade=false + # Delete the resource with cascading strategy orphan. + kubectl "${kube_flags[@]}" delete bars test --cascade=orphan # Make sure it's gone kube::test::wait_object_assert bars "{{range.items}}{{$id_field}}:{{end}}" '' diff --git a/test/cmd/generic-resources.sh b/test/cmd/generic-resources.sh index c3bb11fa5e0..17f111580b2 100755 --- a/test/cmd/generic-resources.sh +++ b/test/cmd/generic-resources.sh @@ -90,7 +90,7 @@ run_multi_resources_tests() { fi kubectl describe -f "${file}" "${kube_flags[@]}" # Command - kubectl replace -f "${replace_file}" --force --cascade "${kube_flags[@]}" + kubectl replace -f "${replace_file}" --force --cascade=background "${kube_flags[@]}" # Post-condition: mock service (and mock2) and mock rc (and mock2) are replaced if [ "$has_svc" = true ]; then kube::test::get_object_assert 'services mock' "{{${labels_field:?}.status}}" 'replaced'