func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args []string) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } // Set up client based support. mapper, typer, err := f.UnstructuredObject() if err != nil { return err } o.Mapper = mapper r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). SelectorParam(o.Selector). SelectAllParam(o.DeleteAll). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } o.Result = r o.f = f // Set up writer o.Out = out o.ErrOut = errOut return nil }
func RunDelete(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } deleteAll := cmdutil.GetFlagBool(cmd, "all") mapper, typer, err := f.UnstructuredObject() if err != nil { return err } r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(deleteAll). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } ignoreNotFound := cmdutil.GetFlagBool(cmd, "ignore-not-found") 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 } } gracePeriod := cmdutil.GetFlagInt(cmd, "grace-period") if cmdutil.GetFlagBool(cmd, "now") { if gracePeriod != -1 { return fmt.Errorf("--now and --grace-period cannot be specified together") } gracePeriod = 1 } if gracePeriod == 0 && !cmdutil.GetFlagBool(cmd, "force") { return fmt.Errorf("Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely. You must pass --force to delete with grace period 0.") } shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" // By default use a reaper to delete all related resources. if cmdutil.GetFlagBool(cmd, "cascade") { return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), gracePeriod, shortOutput, mapper, false) } return DeleteResult(r, out, ignoreNotFound, shortOutput, mapper) }
func getMapperAndResult(f cmdutil.Factory, args []string, options *resource.FilenameOptions, editMode EditMode) (meta.RESTMapper, *resource.Mapper, *resource.Result, string, error) { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return nil, nil, nil, "", err } var mapper meta.RESTMapper var typer runtime.ObjectTyper switch editMode { case NormalEditMode: mapper, typer = f.Object() case EditBeforeCreateMode: mapper, typer, err = f.UnstructuredObject() default: return nil, nil, nil, "", fmt.Errorf("Not supported edit mode %q", editMode) } if err != nil { return nil, nil, nil, "", err } resourceMapper := &resource.Mapper{ ObjectTyper: typer, RESTMapper: mapper, ClientMapper: resource.ClientMapperFunc(f.ClientForMapping), // NB: we use `f.Decoder(false)` to get a plain deserializer for // the resourceMapper, since it's used to read in edits and // we don't want to convert into the internal version when // reading in edits (this would cause us to potentially try to // compare two different GroupVersions). Decoder: f.Decoder(false), } var b *resource.Builder switch editMode { case NormalEditMode: b = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)). ResourceTypeOrNameArgs(true, args...). Latest() case EditBeforeCreateMode: b = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme) default: return nil, nil, nil, "", fmt.Errorf("Not supported edit mode %q", editMode) } r := b.NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). ContinueOnError(). Flatten(). Do() err = r.Err() if err != nil { return nil, nil, nil, "", err } return mapper, resourceMapper, r, cmdNamespace, err }
func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool, options *resource.FilenameOptions) error { schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } for i, filename := range options.Filenames { if filename == "-" { tempDir, err := ioutil.TempDir("", "kubectl_replace_") if err != nil { return err } defer os.RemoveAll(tempDir) tempFilename := filepath.Join(tempDir, "resource.stdin") err = cmdutil.DumpReaderToFile(os.Stdin, tempFilename) if err != nil { return err } options.Filenames[i] = tempFilename } } mapper, typer, err := f.UnstructuredObject() if err != nil { return err } r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } //Replace will create a resource if it doesn't exist already, so ignore not found error ignoreNotFound := true timeout := cmdutil.GetFlagDuration(cmd, "timeout") // By default use a reaper to delete all related resources. if cmdutil.GetFlagBool(cmd, "cascade") { glog.Warningf("\"cascade\" is set, kubectl will delete and re-create all resources managed by this resource (e.g. Pods created by a ReplicationController). Consider using \"kubectl rolling-update\" if you want to update a ReplicationController together with its Pods.") err = ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, timeout, cmdutil.GetFlagInt(cmd, "grace-period"), shortOutput, mapper, false) } else { err = DeleteResult(r, out, ignoreNotFound, shortOutput, mapper) } if err != nil { return err } if timeout == 0 { timeout = kubectl.Timeout } r.Visit(func(info *resource.Info, err error) error { if err != nil { return err } return wait.PollImmediate(kubectl.Interval, timeout, func() (bool, error) { if err := info.Get(); !errors.IsNotFound(err) { return false, err } return true, nil }) }) r = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). Flatten(). Do() err = r.Err() if err != nil { return err } count := 0 err = r.Visit(func(info *resource.Info, err error) error { if err != nil { return err } if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, f.JSONEncoder()); err != nil { return err } if cmdutil.ShouldRecord(cmd, info) { if err := cmdutil.RecordChangeCause(info.Object, f.Command()); err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } } obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object) if err != nil { return err } count++ info.Refresh(obj, true) f.PrintObjectSpecificMessage(obj, out) cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, false, "replaced") return nil }) if err != nil { return err } if count == 0 { return fmt.Errorf("no objects passed to replace") } return nil }
func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, options *resource.FilenameOptions) error { if cmdutil.GetFlagBool(cmd, "edit") { return RunEditOnCreate(f, out, errOut, cmd, options) } schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } mapper, typer, err := f.UnstructuredObject() if err != nil { return err } r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). Flatten(). Do() err = r.Err() if err != nil { return err } dryRun := cmdutil.GetFlagBool(cmd, "dry-run") count := 0 err = r.Visit(func(info *resource.Info, err error) error { if err != nil { return err } if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, f.JSONEncoder()); err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } if cmdutil.ShouldRecord(cmd, info) { if err := cmdutil.RecordChangeCause(info.Object, f.Command()); err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } } if !dryRun { if err := createAndRefresh(info); err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } } count++ shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" if !shortOutput { f.PrintObjectSpecificMessage(info.Object, out) } cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, dryRun, "created") return nil }) if err != nil { return err } if count == 0 { return fmt.Errorf("no objects passed to create") } return nil }
// RunGet implements the generic Get command // TODO: convert all direct flag accessors to a struct and pass that instead of cmd func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args []string, options *GetOptions) error { if len(options.Raw) > 0 { restClient, err := f.RESTClient() if err != nil { return err } stream, err := restClient.Get().RequestURI(options.Raw).Stream() if err != nil { return err } defer stream.Close() _, err = io.Copy(out, stream) if err != nil && err != io.EOF { return err } return nil } selector := cmdutil.GetFlagString(cmd, "selector") allNamespaces := cmdutil.GetFlagBool(cmd, "all-namespaces") showKind := cmdutil.GetFlagBool(cmd, "show-kind") mapper, typer, err := f.UnstructuredObject() if err != nil { return err } filterFuncs := f.DefaultResourceFilterFunc() filterOpts := f.DefaultResourceFilterOptions(cmd, allNamespaces) cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } if allNamespaces { enforceNamespace = false } if len(args) == 0 && cmdutil.IsFilenameEmpty(options.Filenames) { fmt.Fprint(errOut, "You must specify the type of resource to get. ", valid_resources) fullCmdName := cmd.Parent().CommandPath() usageString := "Required resource not specified." if len(fullCmdName) > 0 && cmdutil.IsSiblingCommandExists(cmd, "explain") { usageString = fmt.Sprintf("%s\nUse \"%s explain <resource>\" for a detailed description of that resource (e.g. %[2]s explain pods).", usageString, fullCmdName) } return cmdutil.UsageError(cmd, usageString) } // always show resources when getting by name or filename argsHasNames, err := resource.HasNames(args) if err != nil { return err } if len(options.Filenames) > 0 || argsHasNames { cmd.Flag("show-all").Value.Set("true") } export := cmdutil.GetFlagBool(cmd, "export") // handle watch separately since we cannot watch multiple resource types isWatch, isWatchOnly := cmdutil.GetFlagBool(cmd, "watch"), cmdutil.GetFlagBool(cmd, "watch-only") if isWatch || isWatchOnly { r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). ExportParam(export). ResourceTypeOrNameArgs(true, args...). SingleResourceType(). Latest(). Do() err := r.Err() if err != nil { return err } infos, err := r.Infos() if err != nil { return err } if len(infos) != 1 { return fmt.Errorf("watch is only supported on individual resources and resource collections - %d resources were found", len(infos)) } info := infos[0] mapping := info.ResourceMapping() printer, err := f.PrinterForMapping(cmd, mapping, allNamespaces) if err != nil { return err } obj, err := r.Object() if err != nil { return err } // watching from resourceVersion 0, starts the watch at ~now and // will return an initial watch event. Starting form ~now, rather // the rv of the object will insure that we start the watch from // inside the watch window, which the rv of the object might not be. rv := "0" isList := meta.IsListType(obj) if isList { // the resourceVersion of list objects is ~now but won't return // an initial watch event rv, err = mapping.MetadataAccessor.ResourceVersion(obj) if err != nil { return err } } // print the current object filteredResourceCount := 0 if !isWatchOnly { if err := printer.PrintObj(obj, out); err != nil { return fmt.Errorf("unable to output the provided object: %v", err) } filteredResourceCount++ cmdutil.PrintFilterCount(filteredResourceCount, mapping.Resource, filterOpts) } // print watched changes w, err := r.Watch(rv) if err != nil { return err } first := true filteredResourceCount = 0 intr := interrupt.New(nil, w.Stop) intr.Run(func() error { _, err := watch.Until(0, w, func(e watch.Event) (bool, error) { if !isList && first { // drop the initial watch event in the single resource case first = false return false, nil } err := printer.PrintObj(e.Object, out) if err != nil { return false, err } filteredResourceCount++ cmdutil.PrintFilterCount(filteredResourceCount, mapping.Resource, filterOpts) return false, nil }) return err }) return nil } r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). ExportParam(export). ResourceTypeOrNameArgs(true, args...). ContinueOnError(). Latest(). Flatten(). Do() err = r.Err() if err != nil { return err } printer, generic, err := cmdutil.PrinterForCommand(cmd) if err != nil { return err } if generic { // we flattened the data from the builder, so we have individual items, but now we'd like to either: // 1. if there is more than one item, combine them all into a single list // 2. if there is a single item and that item is a list, leave it as its specific list // 3. if there is a single item and it is not a a list, leave it as a single item var errs []error singular := false infos, err := r.IntoSingular(&singular).Infos() if err != nil { if singular { return err } errs = append(errs, err) } if len(infos) == 0 && len(errs) == 0 { outputEmptyListWarning(errOut) } res := "" if len(infos) > 0 { res = infos[0].ResourceMapping().Resource } var obj runtime.Object if singular { obj = infos[0].Object } else { // we have more than one item, so coerce all items into a list list := &runtime.UnstructuredList{ Object: map[string]interface{}{ "kind": "List", "apiVersion": "v1", "metadata": map[string]interface{}{}, }, } for _, info := range infos { list.Items = append(list.Items, info.Object.(*runtime.Unstructured)) } obj = list } isList := meta.IsListType(obj) if isList { filteredResourceCount, items, err := cmdutil.FilterResourceList(obj, filterFuncs, filterOpts) if err != nil { return err } // take the filtered items and create a new list for display list := &runtime.UnstructuredList{ Object: map[string]interface{}{ "kind": "List", "apiVersion": "v1", "metadata": map[string]interface{}{}, }, } if listMeta, err := meta.ListAccessor(obj); err == nil { list.Object["selfLink"] = listMeta.GetSelfLink() list.Object["resourceVersion"] = listMeta.GetResourceVersion() } for _, item := range items { list.Items = append(list.Items, item.(*runtime.Unstructured)) } if err := printer.PrintObj(list, out); err != nil { errs = append(errs, err) } cmdutil.PrintFilterCount(filteredResourceCount, res, filterOpts) return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs))) } filteredResourceCount := 0 if isFiltered, err := filterFuncs.Filter(obj, filterOpts); !isFiltered { if err != nil { glog.V(2).Infof("Unable to filter resource: %v", err) } else if err := printer.PrintObj(obj, out); err != nil { errs = append(errs, err) } } else if isFiltered { filteredResourceCount++ } cmdutil.PrintFilterCount(filteredResourceCount, res, filterOpts) return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs))) } allErrs := []error{} errs := sets.NewString() infos, err := r.Infos() if err != nil { allErrs = append(allErrs, err) } if len(infos) == 0 && len(allErrs) == 0 { outputEmptyListWarning(errOut) } objs := make([]runtime.Object, len(infos)) for ix := range infos { objs[ix] = infos[ix].Object } sorting, err := cmd.Flags().GetString("sort-by") if err != nil { return err } var sorter *kubectl.RuntimeSort if len(sorting) > 0 && len(objs) > 1 { // TODO: questionable if sorter, err = kubectl.SortObjects(f.Decoder(true), objs, sorting); err != nil { return err } } // use the default printer for each object printer = nil var lastMapping *meta.RESTMapping w := kubectl.GetNewTabWriter(out) filteredResourceCount := 0 if resource.MultipleTypesRequested(args) || cmdutil.MustPrintWithKinds(objs, infos, sorter) { showKind = true } for ix := range objs { var mapping *meta.RESTMapping var original runtime.Object if sorter != nil { mapping = infos[sorter.OriginalPosition(ix)].Mapping original = infos[sorter.OriginalPosition(ix)].Object } else { mapping = infos[ix].Mapping original = infos[ix].Object } if printer == nil || lastMapping == nil || mapping == nil || mapping.Resource != lastMapping.Resource { if printer != nil { w.Flush() cmdutil.PrintFilterCount(filteredResourceCount, lastMapping.Resource, filterOpts) } printer, err = f.PrinterForMapping(cmd, mapping, allNamespaces) if err != nil { if !errs.Has(err.Error()) { errs.Insert(err.Error()) allErrs = append(allErrs, err) } continue } // add linebreak between resource groups (if there is more than one) // skip linebreak above first resource group noHeaders := cmdutil.GetFlagBool(cmd, "no-headers") if lastMapping != nil && !noHeaders { fmt.Fprintf(errOut, "%s\n", "") } lastMapping = mapping } // filter objects if filter has been defined for current object if isFiltered, err := filterFuncs.Filter(original, filterOpts); isFiltered { if err == nil { filteredResourceCount++ continue } if !errs.Has(err.Error()) { errs.Insert(err.Error()) allErrs = append(allErrs, err) } } if resourcePrinter, found := printer.(*kubectl.HumanReadablePrinter); found { resourceName := resourcePrinter.GetResourceKind() if mapping != nil { if resourceName == "" { resourceName = mapping.Resource } if alias, ok := kubectl.ResourceShortFormFor(mapping.Resource); ok { resourceName = alias } else if resourceName == "" { resourceName = "none" } } else { resourceName = "none" } if showKind { resourcePrinter.EnsurePrintWithKind(resourceName) } if err := printer.PrintObj(original, w); err != nil { if !errs.Has(err.Error()) { errs.Insert(err.Error()) allErrs = append(allErrs, err) } } continue } if err := printer.PrintObj(original, w); err != nil { if !errs.Has(err.Error()) { errs.Insert(err.Error()) allErrs = append(allErrs, err) } continue } } w.Flush() if printer != nil && lastMapping != nil { cmdutil.PrintFilterCount(filteredResourceCount, lastMapping.Resource, filterOpts) } return utilerrors.NewAggregate(allErrs) }
func RunReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions) error { if len(os.Args) > 1 && os.Args[1] == "update" { printDeprecationWarning("replace", "update") } schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) if err != nil { return err } cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } force := cmdutil.GetFlagBool(cmd, "force") if cmdutil.IsFilenameEmpty(options.Filenames) { return cmdutil.UsageError(cmd, "Must specify --filename to replace") } shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" if force { return forceReplace(f, out, cmd, args, shortOutput, options) } if cmdutil.GetFlagInt(cmd, "grace-period") >= 0 { return fmt.Errorf("--grace-period must have --force specified") } if cmdutil.GetFlagDuration(cmd, "timeout") != 0 { return fmt.Errorf("--timeout must have --force specified") } mapper, typer, err := f.UnstructuredObject() if err != nil { return err } r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). Flatten(). Do() err = r.Err() if err != nil { return err } return r.Visit(func(info *resource.Info, err error) error { if err != nil { return err } if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, f.JSONEncoder()); err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } if cmdutil.ShouldRecord(cmd, info) { if err := cmdutil.RecordChangeCause(info.Object, f.Command()); err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } } // Serialize the object with the annotation applied. obj, err := resource.NewHelper(info.Client, info.Mapping).Replace(info.Namespace, info.Name, true, info.Object) if err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } info.Refresh(obj, true) f.PrintObjectSpecificMessage(obj, out) cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, false, "replaced") return nil }) }
func RunDelete(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions) error { cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } deleteAll := cmdutil.GetFlagBool(cmd, "all") mapper, typer, err := f.UnstructuredObject() if err != nil { return err } r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). SelectorParam(cmdutil.GetFlagString(cmd, "selector")). SelectAllParam(deleteAll). ResourceTypeOrNameArgs(false, args...).RequireObject(false). Flatten(). Do() err = r.Err() if err != nil { return err } ignoreNotFound := cmdutil.GetFlagBool(cmd, "ignore-not-found") 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 } } gracePeriod := cmdutil.GetFlagInt(cmd, "grace-period") force := cmdutil.GetFlagBool(cmd, "force") if cmdutil.GetFlagBool(cmd, "now") { if gracePeriod != -1 { return fmt.Errorf("--now and --grace-period cannot be specified together") } gracePeriod = 1 } wait := false if gracePeriod == 0 { if force { fmt.Fprintf(errOut, "warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.\n") } else { // To preserve backwards compatibility, but prevent accidental data loss, we convert --grace-period=0 // into --grace-period=1 and wait until the object is successfully deleted. Users may provide --force // to bypass this wait. wait = true gracePeriod = 1 } } shortOutput := cmdutil.GetFlagString(cmd, "output") == "name" // By default use a reaper to delete all related resources. if cmdutil.GetFlagBool(cmd, "cascade") { return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), gracePeriod, wait, shortOutput, mapper, false) } return DeleteResult(r, out, ignoreNotFound, shortOutput, mapper) }