-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from appuio/feature/git-sha-cleanup
Add image cleanup command and restructure folders
- Loading branch information
Showing
27 changed files
with
782 additions
and
297 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/dist | ||
/.idea | ||
/.vscode | ||
/vendor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package cmd | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
// Build contains build information for the cobra version flag | ||
type Build struct { | ||
Version string | ||
Commit string | ||
Date string | ||
} | ||
|
||
// Options is a struct holding the options of the root command | ||
type Options struct { | ||
LogLevel string | ||
} | ||
|
||
// NewCleanupCommand creates the `image-cleanup` command | ||
func NewCleanupCommand(build Build) *cobra.Command { | ||
o := Options{} | ||
cmds := &cobra.Command{ | ||
Use: "image-cleanup", | ||
Short: "image-cleanup cleans up docker images", | ||
Long: "image-cleanup cleans up docker images.", | ||
PersistentPreRun: o.init, | ||
Run: runHelp, | ||
Version: build.Version + "\ncommit = " + build.Commit + "\ndate = " + build.Date, | ||
} | ||
|
||
cmds.PersistentFlags().StringVarP(&o.LogLevel, "verbosity", "v", "info", "Log level to use") | ||
|
||
cmds.AddCommand(NewTagsCommand()) | ||
cmds.AddCommand(NewImageStreamCleanupCommand()) | ||
|
||
return cmds | ||
} | ||
|
||
func runHelp(cmd *cobra.Command, args []string) { | ||
cmd.Help() | ||
} | ||
|
||
func (o *Options) init(cmd *cobra.Command, args []string) { | ||
configureLogging(o.LogLevel) | ||
} | ||
|
||
func configureLogging(logLevel string) { | ||
|
||
log.SetFormatter(&log.TextFormatter{ | ||
FullTimestamp: true, | ||
}) | ||
|
||
log.SetOutput(os.Stderr) | ||
|
||
level, err := log.ParseLevel(logLevel) | ||
if err != nil { | ||
log.WithField("error", err).Warn("Using info level.") | ||
log.SetLevel(log.InfoLevel) | ||
} else { | ||
log.SetLevel(level) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/appuio/image-cleanup/pkg/docker" | ||
"github.com/spf13/cobra" | ||
|
||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
// NewTagsCommand creates a cobra command to print the tags of a docker image | ||
func NewTagsCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "tags", | ||
Short: "Print the available tags", | ||
Long: `Print the available tags for a Docker image`, | ||
Args: cobra.ExactValidArgs(1), | ||
Run: printImageTags, | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
func printImageTags(cmd *cobra.Command, args []string) { | ||
image := args[0] | ||
|
||
imageTags, err := docker.GetImageTags(image) | ||
if err != nil { | ||
log.WithError(err).WithField("image", image).Fatal("Retrieving image tags failed.") | ||
} | ||
|
||
log.Println(imageTags) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package cmd | ||
|
||
import ( | ||
log "github.com/sirupsen/logrus" | ||
|
||
"github.com/appuio/image-cleanup/pkg/cleanup" | ||
"github.com/appuio/image-cleanup/pkg/git" | ||
"github.com/appuio/image-cleanup/pkg/kubernetes" | ||
"github.com/appuio/image-cleanup/pkg/openshift" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// ImageStreamCleanupOptions is a struct to support the cleanup command | ||
type ImageStreamCleanupOptions struct { | ||
Force bool | ||
CommitLimit int | ||
RepoPath string | ||
Keep int | ||
ImageStream string | ||
Namespace string | ||
} | ||
|
||
// NewImageStreamCleanupCommand creates a cobra command to clean up an imagestream based on commits | ||
func NewImageStreamCleanupCommand() *cobra.Command { | ||
o := ImageStreamCleanupOptions{} | ||
cmd := &cobra.Command{ | ||
Use: "imagestream", | ||
Aliases: []string{"is"}, | ||
Short: "Clean up excessive image tags", | ||
Long: `Clean up excessive image tags matching the commit hashes (prefix) of the git repository`, | ||
Run: o.cleanupImageStreamTags, | ||
} | ||
cmd.Flags().BoolVarP(&o.Force, "force", "f", false, "delete image stream tags") | ||
cmd.Flags().IntVarP(&o.CommitLimit, "git-commit-limit", "l", 100, "only look at the first <n> commits to compare with tags or use -1 for all commits") | ||
cmd.Flags().StringVarP(&o.RepoPath, "git-repo-path", "p", ".", "absolute path to Git repository (for current dir use: $PWD)") | ||
cmd.Flags().StringVarP(&o.Namespace, "namespace", "n", "", "Kubernetes namespace") | ||
cmd.Flags().IntVarP(&o.Keep, "keep", "k", 10, "keep most current <n> images") | ||
return cmd | ||
} | ||
|
||
func (o *ImageStreamCleanupOptions) cleanupImageStreamTags(cmd *cobra.Command, args []string) { | ||
if len(args) > 0 { | ||
o.ImageStream = args[0] | ||
} | ||
|
||
if len(o.Namespace) == 0 { | ||
namespace, err := kubernetes.Namespace() | ||
if err != nil { | ||
log.WithError(err).Fatal("Could not retrieve default namespace from kubeconfig.") | ||
} | ||
|
||
o.Namespace = namespace | ||
} | ||
|
||
if len(o.ImageStream) == 0 { | ||
imageStreams, err := openshift.GetImageStreams(o.Namespace) | ||
if err != nil { | ||
log.WithError(err).WithField("namespace", o.Namespace).Fatal("Could not retrieve image streams.") | ||
} | ||
|
||
log.Printf("No image stream provided as argument. Available image streams for namespace %s: %s", o.Namespace, imageStreams) | ||
|
||
return | ||
} | ||
|
||
commitHashes, err := git.GetCommitHashes(o.RepoPath, o.CommitLimit) | ||
if err != nil { | ||
log.WithError(err).WithField("RepoPath", o.RepoPath).WithField("CommitLimit", o.CommitLimit).Fatal("Retrieving commit hashes failed.") | ||
} | ||
|
||
imageStreamTags, err := openshift.GetImageStreamTags(o.Namespace, o.ImageStream) | ||
if err != nil { | ||
log.WithError(err).WithField("Namespace", o.Namespace).WithField("ImageStream", o.ImageStream).Fatal("Could not retrieve image stream.") | ||
} | ||
|
||
matchingTags := cleanup.GetTagsMatchingPrefixes(&commitHashes, &imageStreamTags) | ||
|
||
activeImageStreamTags, err := openshift.GetActiveImageStreamTags(o.Namespace, o.ImageStream, imageStreamTags) | ||
if err != nil { | ||
log.WithError(err).WithField("Namespace", o.Namespace).WithField("ImageStream", o.ImageStream).WithField("imageStreamTags", imageStreamTags).Fatal("Could not retrieve active image stream tags.") | ||
} | ||
|
||
inactiveTags := cleanup.GetInactiveTags(&activeImageStreamTags, &matchingTags) | ||
|
||
inactiveTags = cleanup.LimitTags(&inactiveTags, o.Keep) | ||
|
||
log.Printf("Tags for deletion: %s", inactiveTags) | ||
|
||
if o.Force { | ||
for _, inactiveTag := range inactiveTags { | ||
openshift.DeleteImageStreamTag(o.Namespace, openshift.BuildImageStreamTagName(o.ImageStream, inactiveTag)) | ||
log.Printf("Deleted image stream tag: %s", inactiveTag) | ||
} | ||
} else { | ||
log.Println("--force was not specified. Nothing has been deleted.") | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.