Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --keep to delete --all, to keep the last N pipelineruns #720

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/cmd/tkn_pipelinerun_delete.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ or
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-f, --force Whether to force deletion (default: false)
-h, --help help for delete
--keep int Keep n least recent number of pipelineruns when deleting alls
-o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
-p, --pipeline string The name of a pipeline whose pipelineruns should be deleted (does not delete the pipeline)
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
Expand Down
1 change: 1 addition & 0 deletions docs/cmd/tkn_taskrun_delete.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ or
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
-f, --force Whether to force deletion (default: false)
-h, --help help for delete
--keep int Keep n least recent number of pipelineruns when deleting alls
-o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
-t, --task string The name of a task whose taskruns should be deleted (does not delete the task)
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
Expand Down
4 changes: 4 additions & 0 deletions docs/man/man1/tkn-pipelinerun-delete.1
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ Delete pipelineruns in a namespace
\fB\-h\fP, \fB\-\-help\fP[=false]
help for delete

.PP
\fB\-\-keep\fP=0
Keep n least recent number of pipelineruns when deleting alls

.PP
\fB\-o\fP, \fB\-\-output\fP=""
Output format. One of: json|yaml|name|go\-template|go\-template\-file|template|templatefile|jsonpath|jsonpath\-file.
Expand Down
4 changes: 4 additions & 0 deletions docs/man/man1/tkn-taskrun-delete.1
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ Delete taskruns in a namespace
\fB\-h\fP, \fB\-\-help\fP[=false]
help for delete

.PP
\fB\-\-keep\fP=0
Keep n least recent number of pipelineruns when deleting alls

.PP
\fB\-o\fP, \fB\-\-output\fP=""
Output format. One of: json|yaml|name|go\-template|go\-template\-file|template|templatefile|jsonpath|jsonpath\-file.
Expand Down
19 changes: 15 additions & 4 deletions pkg/cmd/pipelinerun/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/tektoncd/cli/pkg/cli"
"github.com/tektoncd/cli/pkg/helper/deleter"
"github.com/tektoncd/cli/pkg/helper/options"
prhsort "github.com/tektoncd/cli/pkg/helper/pipelinerun/sort"
validate "github.com/tektoncd/cli/pkg/helper/validate"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
cliopts "k8s.io/cli-runtime/pkg/genericclioptions"
Expand Down Expand Up @@ -70,6 +71,7 @@ or
f.AddFlags(c)
c.Flags().BoolVarP(&opts.ForceDelete, "force", "f", false, "Whether to force deletion (default: false)")
c.Flags().StringVarP(&opts.ParentResourceName, "pipeline", "p", "", "The name of a pipeline whose pipelineruns should be deleted (does not delete the pipeline)")
c.Flags().IntVarP(&opts.Keep, "keep", "", 0, "Keep n least recent number of pipelineruns when deleting alls")
c.Flags().BoolVarP(&opts.DeleteAllNs, "all", "", false, "Delete all pipelineruns in a namespace (default: false)")
_ = c.MarkZshCompPositionalArgumentCustom(1, "__tkn_get_pipelinerun")
return c
Expand All @@ -86,7 +88,7 @@ func deletePipelineRuns(s *cli.Stream, p cli.Params, prNames []string, opts *opt
d = deleter.New("PipelineRun", func(pipelineRunName string) error {
return cs.Tekton.TektonV1alpha1().PipelineRuns(p.Namespace()).Delete(pipelineRunName, &metav1.DeleteOptions{})
})
prs, err := allPipelineRunNames(p, cs)
prs, err := allPipelineRunNames(p, cs, opts.Keep)
if err != nil {
return err
}
Expand All @@ -109,7 +111,11 @@ func deletePipelineRuns(s *cli.Stream, p cli.Params, prNames []string, opts *opt
d.PrintSuccesses(s)
} else if opts.DeleteAllNs {
if d.Errors() == nil {
fmt.Fprintf(s.Out, "All PipelineRuns deleted in namespace %q\n", p.Namespace())
if opts.Keep > 0 {
fmt.Fprintf(s.Out, "All but %d PipelineRuns deleted in namespace %q\n", opts.Keep, p.Namespace())
} else {
fmt.Fprintf(s.Out, "All PipelineRuns deleted in namespace %q\n", p.Namespace())
}
}
}
return d.Errors()
Expand All @@ -132,13 +138,18 @@ func pipelineRunLister(p cli.Params, cs *cli.Clients) func(string) ([]string, er
}
}

func allPipelineRunNames(p cli.Params, cs *cli.Clients) ([]string, error) {
func allPipelineRunNames(p cli.Params, cs *cli.Clients, keep int) ([]string, error) {
pipelineRuns, err := cs.Tekton.TektonV1alpha1().PipelineRuns(p.Namespace()).List(metav1.ListOptions{})
if err != nil {
return nil, err
}
var names []string
for _, pr := range pipelineRuns.Items {
var counter = 0
for _, pr := range prhsort.SortPipelineRunsByStartTime(pipelineRuns.Items) {
if keep > 0 && counter != keep {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be some kind of error message if keep < 0? Currently, it will delete all pipelineruns.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in case If the user choose ?:

--last=-1

I guess that's quite a weird user case

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I mean it's totally unlikely, but we should prevent it by checking if keep < 0 similar to what is done for limit. So fail fast in RunE in this case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danielhelfand isn't the code above already checking that keep can't be < 0 ?

counter++
continue
}
names = append(names, pr.Name)
}
return names, nil
Expand Down
16 changes: 16 additions & 0 deletions pkg/cmd/pipelinerun/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,22 @@ func TestPipelineRunDelete(t *testing.T) {
wantError: false,
want: "All PipelineRuns deleted in namespace \"ns\"\n",
},
{
name: "Delete all keeping 2",
command: []string{"delete", "--all", "-f", "--keep", "2", "-n", "ns"},
input: seeds[4],
inputStream: nil,
wantError: false,
want: "All but 2 PipelineRuns deleted in namespace \"ns\"\n",
},
{
name: "Keep -1 is a no go",
command: []string{"delete", "--all", "-f", "--keep", "-1", "-n", "ns"},
input: seeds[4],
inputStream: nil,
wantError: true,
want: "keep option should not be lower than 0",
},
{
name: "Error from using pipelinerun name with --all",
command: []string{"delete", "pipelinerun", "--all", "-n", "ns"},
Expand Down
16 changes: 13 additions & 3 deletions pkg/cmd/taskrun/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ or
c.Flags().BoolVarP(&opts.ForceDelete, "force", "f", false, "Whether to force deletion (default: false)")
c.Flags().StringVarP(&opts.ParentResourceName, "task", "t", "", "The name of a task whose taskruns should be deleted (does not delete the task)")
c.Flags().BoolVarP(&opts.DeleteAllNs, "all", "", false, "Delete all taskruns in a namespace (default: false)")
c.Flags().IntVarP(&opts.Keep, "keep", "", 0, "Keep n least recent number of pipelineruns when deleting alls")
_ = c.MarkZshCompPositionalArgumentCustom(1, "__tkn_get_taskrun")
return c
}
Expand All @@ -86,7 +87,7 @@ func deleteTaskRuns(s *cli.Stream, p cli.Params, trNames []string, opts *options
d = deleter.New("TaskRun", func(taskRunName string) error {
return cs.Tekton.TektonV1alpha1().TaskRuns(p.Namespace()).Delete(taskRunName, &metav1.DeleteOptions{})
})
trs, err := allTaskRunNames(p, cs)
trs, err := allTaskRunNames(p, cs, opts.Keep)
if err != nil {
return err
}
Expand All @@ -109,7 +110,11 @@ func deleteTaskRuns(s *cli.Stream, p cli.Params, trNames []string, opts *options
d.PrintSuccesses(s)
} else if opts.DeleteAllNs {
if d.Errors() == nil {
fmt.Fprintf(s.Out, "All TaskRuns deleted in namespace %q\n", p.Namespace())
if opts.Keep > 0 {
fmt.Fprintf(s.Out, "All but %d TaskRuns deleted in namespace %q\n", opts.Keep, p.Namespace())
} else {
fmt.Fprintf(s.Out, "All TaskRuns deleted in namespace %q\n", p.Namespace())
}
}
}
return d.Errors()
Expand All @@ -132,13 +137,18 @@ func taskRunLister(p cli.Params, cs *cli.Clients) func(string) ([]string, error)
}
}

func allTaskRunNames(p cli.Params, cs *cli.Clients) ([]string, error) {
func allTaskRunNames(p cli.Params, cs *cli.Clients, keep int) ([]string, error) {
taskRuns, err := cs.Tekton.TektonV1alpha1().TaskRuns(p.Namespace()).List(metav1.ListOptions{})
if err != nil {
return nil, err
}
var names []string
var counter = 0
for _, tr := range taskRuns.Items {
if keep > 0 && counter != keep {
counter++
continue
}
names = append(names, tr.Name)
}
return names, nil
Expand Down
16 changes: 16 additions & 0 deletions pkg/cmd/taskrun/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,22 @@ func TestTaskRunDelete(t *testing.T) {
wantError: false,
want: "All TaskRuns deleted in namespace \"ns\"\n",
},
{
name: "Delete all keeping 2",
command: []string{"delete", "--all", "-f", "--keep", "2", "-n", "ns"},
input: seeds[4],
inputStream: nil,
wantError: false,
want: "All but 2 TaskRuns deleted in namespace \"ns\"\n",
},
{
name: "Keep -1 is a no go",
command: []string{"delete", "--all", "-f", "--keep", "-1", "-n", "ns"},
input: seeds[4],
inputStream: nil,
wantError: true,
want: "keep option should not be lower than 0",
},
{
name: "Error from using taskrun name with --all",
command: []string{"delete", "taskrun", "--all", "-n", "ns"},
Expand Down
16 changes: 14 additions & 2 deletions pkg/helper/options/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ type DeleteOptions struct {
DeleteRelated bool
DeleteAllNs bool
DeleteAll bool
Keep int
}

func (o *DeleteOptions) CheckOptions(s *cli.Stream, resourceNames []string, ns string) error {
if o.Keep > 0 && !(o.DeleteAllNs || o.DeleteAll) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promise this is the last thing. Could the error message be:

Suggested change
if o.Keep > 0 && !(o.DeleteAllNs || o.DeleteAll) {
return fmt.Errorf("must use --all flag with --keep")

return fmt.Errorf("must provide pipelineruns to delete or --pipeline flag")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promise this is the last thing. Could the error message be:

Suggested change
return fmt.Errorf("must provide pipelineruns to delete or --pipeline flag")
return fmt.Errorf("must use --all flag with --keep")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promise this is the last thing. Could the error message be:

Suggested change
return fmt.Errorf("must provide pipelineruns to delete or --pipeline flag")
return fmt.Errorf("must use --all flag with --keep")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Promise this is the last thing. Could the error message be:

Suggested change
return fmt.Errorf("must provide pipelineruns to delete or --pipeline flag")
return fmt.Errorf("must use --all flag with --keep")

}
// make sure no resource names are provided when using --all flag
if len(resourceNames) > 0 && (o.DeleteAllNs || o.DeleteAll) {
return fmt.Errorf("--all flag should not have any arguments or flags specified with it")
Expand All @@ -51,17 +55,25 @@ func (o *DeleteOptions) CheckOptions(s *cli.Stream, resourceNames []string, ns s
return fmt.Errorf("must provide %s name(s) or use --all flag with delete", o.Resource)
}

if o.Keep < 0 {
return fmt.Errorf("keep option should not be lower than 0")
}

if o.ForceDelete {
return nil
}

formattedNames := names.QuotedList(resourceNames)

keepStr := ""
if o.Keep > 0 {
keepStr = fmt.Sprintf(" keeping %d %ss", o.Keep, o.Resource)
}
switch {
case o.DeleteAllNs:
fmt.Fprintf(s.Out, "Are you sure you want to delete all %ss in namespace %q (y/n): ", o.Resource, ns)
fmt.Fprintf(s.Out, "Are you sure you want to delete all %ss in namespace %q%s (y/n): ", o.Resource, ns, keepStr)
case o.DeleteAll:
fmt.Fprintf(s.Out, "Are you sure you want to delete all %ss (y/n): ", o.Resource)
fmt.Fprintf(s.Out, "Are you sure you want to delete all %ss%s (y/n): ", o.Resource, keepStr)
case o.ParentResource != "" && o.ParentResourceName != "":
fmt.Fprintf(s.Out, "Are you sure you want to delete all %ss related to %s %q (y/n): ", o.Resource, o.ParentResource, o.ParentResourceName)
case o.DeleteRelated:
Expand Down