From e18fb0317f74e82aa33154c48b03506be235d9e6 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 6 Mar 2020 11:01:33 +0100 Subject: [PATCH] Consolidate common git options --- cmd/common.go | 30 ++++++++++++++++++++++++ cmd/history.go | 63 +++++++++++++++----------------------------------- cmd/orphan.go | 47 ++++++++++--------------------------- 3 files changed, 61 insertions(+), 79 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index 9d6696e..324f912 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "github.com/appuio/image-cleanup/pkg/git" "github.com/appuio/image-cleanup/pkg/openshift" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -11,6 +12,15 @@ const ( imageRepositoryCliFlag = "image-repository" ) +type ( + GitOptions struct { + CommitLimit int + RepoPath string + Tag bool + SortCriteria string + } +) + func DeleteImages(imageTags []string, imageName string, namespace string) { for _, inactiveTag := range imageTags { err := openshift.DeleteImageStreamTag(namespace, openshift.BuildImageStreamTagName(imageName, inactiveTag)) @@ -35,3 +45,23 @@ func PrintImageTags(cmd *cobra.Command, imageTags []string) { } } } + +func getGitCandidateList(o *GitOptions) []string { + logEvent := log.WithFields(log.Fields{ + "GitRepoPath": o.RepoPath, + "CommitLimit": o.CommitLimit, + }) + if o.Tag { + candidates, err := git.GetTags(o.RepoPath, o.CommitLimit, git.SortOption(o.SortCriteria)) + if err != nil { + logEvent.WithError(err).Fatal("Retrieving commit tags failed.") + } + return candidates + } else { + candidates, err := git.GetCommitHashes(o.RepoPath, o.CommitLimit) + if err != nil { + logEvent.WithError(err).Fatal("Retrieving commit hashes failed.") + } + return candidates + } +} diff --git a/cmd/history.go b/cmd/history.go index 8c81826..c86eb8e 100644 --- a/cmd/history.go +++ b/cmd/history.go @@ -12,65 +12,39 @@ import ( // HistoryCleanupOptions is a struct to support the cleanup command type HistoryCleanupOptions struct { Force bool - CommitLimit int - RepoPath string Keep int ImageRepository string Namespace string - Tag bool - SortCriteria string } // NewHistoryCleanupCommand creates a cobra command to clean up images by comparing the git commit history. func NewHistoryCleanupCommand() *cobra.Command { - o := HistoryCleanupOptions{} + historyCleanupOptions := HistoryCleanupOptions{} + gitOptions := GitOptions{} cmd := &cobra.Command{ Use: "history", Aliases: []string{"hist"}, Short: "Clean up excessive image tags", Long: `Clean up excessive image tags matching the commit hashes (prefix) of the git repository`, Run: func(cmd *cobra.Command, args []string) { - validateFlagCombinationInput(&o) - ExecuteHistoryCleanupCommand(cmd, &o, args) + validateFlagCombinationInput(&gitOptions) + ExecuteHistoryCleanupCommand(cmd, &historyCleanupOptions, &gitOptions, args) }, } - cmd.Flags().BoolVarP(&o.Force, "force", "f", false, "Confirm deletion of image tags.") - cmd.Flags().IntVarP(&o.CommitLimit, "git-commit-limit", "l", 0, + cmd.Flags().BoolVarP(&historyCleanupOptions.Force, "force", "f", false, "Confirm deletion of image tags.") + cmd.Flags().IntVarP(&gitOptions.CommitLimit, "git-commit-limit", "l", 0, "Only look at the first commits to compare with image tags. Use 0 (zero) for all commits. Limited effect if repo is a shallow clone.") - cmd.Flags().StringVarP(&o.RepoPath, "git-repo-path", "p", ".", "Path to Git repository.") - cmd.Flags().StringVarP(&o.ImageRepository, imageRepositoryCliFlag, "i", "", "Image repository in form of .") - cmd.Flags().IntVarP(&o.Keep, "keep", "k", 10, "Keep most current images.") - cmd.Flags().BoolVarP(&o.Tag, "tags", "t", false, "Compare with Git tags instead of commit hashes.") - cmd.Flags().StringVar(&o.SortCriteria, "sort", string(git.SortOptionVersion), + cmd.Flags().StringVarP(&gitOptions.RepoPath, "git-repo-path", "p", ".", "Path to Git repository.") + cmd.Flags().StringVarP(&historyCleanupOptions.ImageRepository, imageRepositoryCliFlag, "i", "", "Image repository in form of .") + cmd.Flags().IntVarP(&historyCleanupOptions.Keep, "keep", "k", 10, "Keep most current images.") + cmd.Flags().BoolVarP(&gitOptions.Tag, "tags", "t", false, "Compare with Git tags instead of commit hashes.") + cmd.Flags().StringVar(&gitOptions.SortCriteria, "sort", string(git.SortOptionVersion), fmt.Sprintf("Sort git tags by criteria. Only effective with --tags. Allowed values: %s", []git.SortOption{git.SortOptionVersion, git.SortOptionAlphabetic})) cmd.MarkFlagRequired("image-repository") return cmd } -func ExecuteHistoryCleanupCommand(cmd *cobra.Command, o *HistoryCleanupOptions, args []string) { - - var matchValues []string - if o.Tag { - var err error - matchValues, err = git.GetTags(o.RepoPath, o.CommitLimit, git.SortOption(o.SortCriteria)) - if err != nil { - log.WithError(err). - WithFields(log.Fields{ - "RepoPath": o.RepoPath, - "CommitLimit": o.CommitLimit}). - Fatal("Retrieving commit tags failed.") - } - } else { - var err error - matchValues, err = git.GetCommitHashes(o.RepoPath, o.CommitLimit) - if err != nil { - log.WithError(err). - WithFields(log.Fields{ - "RepoPath": o.RepoPath, - "CommitLimit": o.CommitLimit}). - Fatal("Retrieving commit hashes failed.") - } - } +func ExecuteHistoryCleanupCommand(cmd *cobra.Command, o *HistoryCleanupOptions, gitOptions *GitOptions, args []string) { imageStreamObjectTags, err := openshift.GetImageStreamTags(o.Namespace, o.ImageRepository) if err != nil { @@ -87,11 +61,12 @@ func ExecuteHistoryCleanupCommand(cmd *cobra.Command, o *HistoryCleanupOptions, } var matchOption cleanup.MatchOption - if o.Tag { + if gitOptions.Tag { matchOption = cleanup.MatchOptionExact } - var matchingTags = cleanup.GetMatchingTags(&matchValues, &imageStreamTags, matchOption) + gitCandidates := getGitCandidateList(gitOptions) + var matchingTags = cleanup.GetMatchingTags(&gitCandidates, &imageStreamTags, matchOption) activeImageStreamTags, err := openshift.GetActiveImageStreamTags(o.Namespace, o.ImageRepository, imageStreamTags) if err != nil { @@ -107,7 +82,7 @@ func ExecuteHistoryCleanupCommand(cmd *cobra.Command, o *HistoryCleanupOptions, inactiveTags = cleanup.LimitTags(&inactiveTags, o.Keep) - log.WithField("inactiveTags", inactiveTags).Info("Compiled list of image tags to delete.") + PrintImageTags(cmd, inactiveTags) if o.Force { DeleteImages(inactiveTags, o.ImageRepository, o.Namespace) @@ -116,10 +91,10 @@ func ExecuteHistoryCleanupCommand(cmd *cobra.Command, o *HistoryCleanupOptions, } } -func validateFlagCombinationInput(o *HistoryCleanupOptions) { +func validateFlagCombinationInput(gitOptions *GitOptions) { - if o.Tag && !git.IsValidSortValue(o.SortCriteria) { - log.WithField("sort_criteria", o.SortCriteria).Fatal("Invalid sort criteria.") + if gitOptions.Tag && !git.IsValidSortValue(gitOptions.SortCriteria) { + log.WithField("sort_criteria", gitOptions.SortCriteria).Fatal("Invalid sort criteria.") } } diff --git a/cmd/orphan.go b/cmd/orphan.go index 2415dd8..58cf6c8 100644 --- a/cmd/orphan.go +++ b/cmd/orphan.go @@ -17,11 +17,7 @@ import ( // OrphanCleanupOptions holds the user-defined settings type OrphanCleanupOptions struct { Force bool - CommitLimit int - GitRepoPath string ImageRepository string - Tag bool - SortCriteria string OlderThan string OrphanDeletionRegex string } @@ -37,24 +33,25 @@ This command deletes images that are not found in the git history.` // image tags that are not found in the git history by given criteria. func NewOrphanCleanupCommand() *cobra.Command { o := OrphanCleanupOptions{} + gitOptions := GitOptions{} cmd := &cobra.Command{ Use: "orphans", Aliases: []string{"orph"}, Short: "Clean up unknown image tags", Long: orphanCommandLongDescription, RunE: func(cmd *cobra.Command, args []string) error { - validateOrphanCommandInput(&o) + validateOrphanCommandInput(&o, &gitOptions) return ExecuteOrphanCleanupCommand(cmd, &o, args) }, } cmd.Flags().BoolVarP(&o.Force, "force", "f", false, "Confirm deletion of image tags.") - cmd.Flags().IntVarP(&o.CommitLimit, "git-commit-limit", "l", 0, + cmd.Flags().IntVarP(&gitOptions.CommitLimit, "git-commit-limit", "l", 0, "Only look at the first commits to compare with tags. Use 0 (zero) for all commits. Limited effect if repo is a shallow clone.") - cmd.Flags().StringVarP(&o.GitRepoPath, "git-repo-path", "p", ".", "Path to Git repository") + cmd.Flags().StringVarP(&gitOptions.RepoPath, "git-repo-path", "p", ".", "Path to Git repository") cmd.Flags().StringVarP(&o.ImageRepository, imageRepositoryCliFlag, "i", "", "Image repository (e.g. namespace/repo)") - cmd.Flags().BoolVarP(&o.Tag, "tags", "t", false, + cmd.Flags().BoolVarP(&gitOptions.Tag, "tags", "t", false, "Instead of comparing commit history, it will compare git tags with the existing image tags, removing any image tags that do not match") - cmd.Flags().StringVar(&o.SortCriteria, "sort", string(git.SortOptionVersion), + cmd.Flags().StringVar(&gitOptions.SortCriteria, "sort", string(git.SortOptionVersion), fmt.Sprintf("Sort git tags by criteria. Only effective with --tags. Allowed values: [%s, %s]", git.SortOptionVersion, git.SortOptionAlphabetic)) cmd.Flags().StringVar(&o.OlderThan, orphanOlderThanCliFlag, "2mo", "delete images that are older than the duration. Ex.: [1y2mo3w4d5h6m7s]") @@ -64,7 +61,7 @@ func NewOrphanCleanupCommand() *cobra.Command { return cmd } -func validateOrphanCommandInput(o *OrphanCleanupOptions) { +func validateOrphanCommandInput(o *OrphanCleanupOptions, gitOptions *GitOptions) { if _, _, err := splitNamespaceAndImagestream(o.ImageRepository); err != nil { log.WithError(err). @@ -84,18 +81,18 @@ func validateOrphanCommandInput(o *OrphanCleanupOptions) { Fatal("Could not parse cut off date.") } - if o.Tag && !git.IsValidSortValue(o.SortCriteria) { + if gitOptions.Tag && !git.IsValidSortValue(gitOptions.SortCriteria) { log.WithFields(log.Fields{ "error": "invalid sort criteria", - "sort": o.SortCriteria, + "sort": gitOptions.SortCriteria, }).Fatal("Could not parse sort criteria.") } } -func ExecuteOrphanCleanupCommand(cmd *cobra.Command, o *OrphanCleanupOptions, args []string) error { +func ExecuteOrphanCleanupCommand(cmd *cobra.Command, o *OrphanCleanupOptions, gitOptions *GitOptions, args []string) error { - gitCandidates := getGitCandidateList(o) + gitCandidates := getGitCandidateList(gitOptions) namespace, imageName, err := splitNamespaceAndImagestream(o.ImageRepository) @@ -112,7 +109,7 @@ func ExecuteOrphanCleanupCommand(cmd *cobra.Command, o *OrphanCleanupOptions, ar imageStreamTags := cleanup.FilterImageTagsByTime(&imageStreamObjectTags, cutOffDateTime) var matchOption cleanup.MatchOption - if o.Tag { + if gitOptions.Tag { matchOption = cleanup.MatchOptionExact } @@ -144,26 +141,6 @@ func ExecuteOrphanCleanupCommand(cmd *cobra.Command, o *OrphanCleanupOptions, ar return nil } -func getGitCandidateList(o *OrphanCleanupOptions) []string { - logEvent := log.WithFields(log.Fields{ - "GitRepoPath": o.GitRepoPath, - "CommitLimit": o.CommitLimit, - }) - if o.Tag { - candidates, err := git.GetTags(o.GitRepoPath, o.CommitLimit, git.SortOption(o.SortCriteria)) - if err != nil { - logEvent.WithError(err).Fatal("Retrieving commit tags failed.") - } - return candidates - } else { - candidates, err := git.GetCommitHashes(o.GitRepoPath, o.CommitLimit) - if err != nil { - logEvent.WithError(err).Fatal("Retrieving commit hashes failed.") - } - return candidates - } -} - func parseOrphanDeletionRegex(orphanIncludeRegex string) (*regexp.Regexp, error) { r, err := regexp.Compile(orphanIncludeRegex) if err != nil {