Skip to content

Commit

Permalink
Merge pull request #7 from appuio/feature/git-sha-cleanup
Browse files Browse the repository at this point in the history
Add image cleanup command and restructure folders
  • Loading branch information
Simon Rüegg authored Dec 19, 2019
2 parents cef2b04 + 9cecc2b commit 21dfb07
Show file tree
Hide file tree
Showing 27 changed files with 782 additions and 297 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/dist
/.idea
/.vscode
/vendor
66 changes: 66 additions & 0 deletions cmd/cmd.go
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)
}
}
32 changes: 32 additions & 0 deletions cmd/docker.go
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)
}
97 changes: 97 additions & 0 deletions cmd/imagestream.go
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.")
}
}
39 changes: 0 additions & 39 deletions commands/git.go

This file was deleted.

23 changes: 0 additions & 23 deletions commands/git_test.go

This file was deleted.

62 changes: 0 additions & 62 deletions commands/imagestream.go

This file was deleted.

23 changes: 0 additions & 23 deletions commands/imagestream_test.go

This file was deleted.

28 changes: 0 additions & 28 deletions commands/root.go

This file was deleted.

Loading

0 comments on commit 21dfb07

Please sign in to comment.