Skip to content

Commit

Permalink
Use --delete (instead of --force)
Browse files Browse the repository at this point in the history
Add short aliases for images command
  • Loading branch information
bittner committed Apr 27, 2020
1 parent edc457f commit 0649951
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 47 deletions.
17 changes: 7 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,21 @@ The ImageStream "application" is invalid: []: Internal error: ImageStream.image.
1. It can be used more aggressively by deleting dangling image tags, "orphans",
that happen to exist when the Git history is altered (e.g. by force-pushing).

1. It can identify `ConfigMap` resources by its `config` label that are sufficiently
old to be deleted.
1. It can identify `ConfigMap` resources by labels that are sufficiently old to be deleted.

1. It can identify `Secret` resources by its `secret` label that are sufficiently
old to be deleted.
1. It can identify `Secret` resources by labels that are sufficiently old to be deleted.

*Seiso* is opinionated, e.g. with respect to naming conventions of image tags,
either by relying on a long Git SHA-1 value (`namespace/app:a3d0df2c5060b87650df6a94a0a9600510303003`)
or a Git tag following semantic versioning (`namespace/app:v1.2.3`).

The cleanup **runs in dry-mode by default**. Only when the `--force` flag is specified,
it will actually delete the identified resources. This should prevent accidental
deletions during verifications or test runs.
The cleanup **runs in dry-mode by default**. Only when the `--delete` flag
is specified, it will actually delete the identified resources. This should
prevent accidental deletions during verifications or test runs.

## Caveats and known issues

* Currently only OpenShift image registries are supported. In future, more
resource types are planned to be supported for cleanup.
* Currently, only OpenShift image registries are supported.

* **Please watch out for shallow clones**, as the Git history might be missing,
it would in some cases also undesirably delete image tags.
Expand Down Expand Up @@ -214,7 +211,7 @@ oc -n "$OPENSHIFT_PROJECT" plugin cleanup "$APP_NAME" -p "$PWD" -f=y
```
becomes:
```console
seiso images history "$OPENSHIFT_PROJECT/$APP_NAME" --force
seiso images history "$OPENSHIFT_PROJECT/$APP_NAME" --delete
```

## Development
Expand Down
4 changes: 2 additions & 2 deletions cfg/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type (
Orphan OrphanConfig `mapstructure:",squash"`
Resource ResourceConfig `mapstructure:",squash"`
Log LogConfig
Force bool
Delete bool
}
// GitConfig configures git repository
GitConfig struct {
Expand Down Expand Up @@ -64,7 +64,7 @@ func NewDefaultConfig() *Configuration {
Labels: []string{},
OlderThan: "2mo",
},
Force: false,
Delete: false,
Log: LogConfig{
LogLevel: "info",
Batch: false,
Expand Down
41 changes: 18 additions & 23 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,48 +15,42 @@ import (
)

// DeleteImages deletes a list of image tags
func DeleteImages(imageTags []string, imageName string, namespace string, force bool) {
if !force {
log.Warn("Force mode not enabled, nothing will be deleted")
}
func DeleteImages(imageTags []string, imageName string, namespace string, delete bool) {
for _, inactiveTag := range imageTags {
logEvent := log.WithFields(log.Fields{
"namespace": namespace,
"image": imageName,
"imageTag": inactiveTag,
})
if force {
if err := openshift.DeleteImageStreamTag(namespace, openshift.BuildImageStreamTagName(imageName, inactiveTag)); err == nil {
logEvent.Info("Deleted image tag")
if delete {
if err := openshift.DeleteImageStreamTag(namespace, openshift.BuildImageStreamTagName(imageName, inactiveTag)); err != nil {
logEvent.WithError(err).Error("Failed to delete")
} else {
logEvent.WithError(err).Error("Could not delete image tag")
logEvent.Info("Deleted")
}
} else {
logEvent.Info("Would delete image tag")
logEvent.Info("Should be deleted")
}
}
}

// DeleteResources deletes a list of ConfigMaps or secrets
func DeleteResources(resources []cfg.KubernetesResource, force bool, resourceSelectorFunc cfg.ResourceNamespaceSelector) {
if !force {
log.Warn("Force mode not enabled, nothing will be deleted")
}
func DeleteResources(resources []cfg.KubernetesResource, delete bool, resourceSelectorFunc cfg.ResourceNamespaceSelector) {
for _, resource := range resources {
kind := resource.GetKind()
name := resource.GetName()
logEvent := log.WithFields(log.Fields{
"namespace": resource.GetNamespace(),
kind: name,
})
if force {
if err := openshift.DeleteResource(name, resourceSelectorFunc); err == nil {
logEvent.Info("Deleted resource")
if delete {
if err := openshift.DeleteResource(name, resourceSelectorFunc); err != nil {
logEvent.WithError(err).Error("Failed to delete")
} else {
logEvent.WithError(err).Error("Could not delete resource")
logEvent.Info("Deleted")
}
} else {
logEvent.Info("Would delete resource")
logEvent.Info("Should be deleted")
}
}
}
Expand Down Expand Up @@ -89,10 +83,11 @@ func PrintResources(resources []cfg.KubernetesResource) {
}
}

// addCommonFlagsForGit sets up the force flag, as well as the common git flags. Adding the flags to the root cmd would make those
// addCommonFlagsForGit sets up the delete flag, as well as the common git flags. Adding the flags to the root cmd would make those
// global, even for commands that do not need them, which might be overkill.
func addCommonFlagsForGit(cmd *cobra.Command, defaults *cfg.Configuration) {
cmd.PersistentFlags().BoolP("force", "f", defaults.Force, "Confirm deletion of image tags.")
cmd.PersistentFlags().BoolP("delete", "d", defaults.Delete, "Confirm deletion of image tags.")
cmd.PersistentFlags().BoolP("force", "f", defaults.Delete, "(deprecated) Confirm deletion. Alias for --delete")
cmd.PersistentFlags().IntP("commit-limit", "l", defaults.Git.CommitLimit,
"Only look at the first <l> commits to compare with tags. Use 0 (zero) for all commits. Limited effect if repo is a shallow clone.")
cmd.PersistentFlags().StringP("repo-path", "p", defaults.Git.RepoPath, "Path to Git repository")
Expand All @@ -116,9 +111,9 @@ func listImages() error {
imageNames = append(imageNames, image.Name)
}
log.WithFields(log.Fields{
"project": ns,
"images": imageNames,
}).Info("Please select an image. The following images are available")
"\n - project": ns,
"\n - 📺 images": imageNames,
}).Info("Please select an image. The following images are available:")
return nil
}

Expand Down
5 changes: 3 additions & 2 deletions cmd/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ func init() {
rootCmd.AddCommand(configMapCmd)
defaults := cfg.NewDefaultConfig()

configMapCmd.PersistentFlags().BoolP("force", "f", defaults.Force, "Confirm deletion of ConfigMaps.")
configMapCmd.PersistentFlags().BoolP("delete", "d", defaults.Delete, "Confirm deletion of ConfigMaps.")
configMapCmd.PersistentFlags().BoolP("force", "f", defaults.Delete, "(deprecated) Alias for --delete")
configMapCmd.PersistentFlags().StringSliceP("label", "l", defaults.Resource.Labels, "Identify the config map by these labels")
configMapCmd.PersistentFlags().IntP("keep", "k", defaults.History.Keep,
"Keep most current <k> ConfigMaps. Does not include currently used ConfigMaps (if detected).")
Expand Down Expand Up @@ -93,7 +94,7 @@ func executeConfigMapCleanupCommand(args []string) error {
PrintResources(filteredConfigMaps)
DeleteResources(
filteredConfigMaps,
config.Force,
config.Delete,
func(client *core.CoreV1Client) cfg.CoreObjectInterface {
return client.ConfigMaps(namespace)
})
Expand Down
6 changes: 3 additions & 3 deletions cmd/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ func ExecuteHistoryCleanupCommand(args []string) error {
inactiveTags = cleanup.LimitTags(&inactiveTags, c.Keep)
if len(inactiveTags) == 0 {
log.WithFields(log.Fields{
"namespace": namespace,
"imageName": image,
"\n - namespace": namespace,
"\n - imageName": image,
}).Info("No inactive image stream tags found")
return nil
}
PrintImageTags(inactiveTags)
DeleteImages(inactiveTags, image, namespace, config.Force)
DeleteImages(inactiveTags, image, namespace, config.Delete)
return nil
}
5 changes: 3 additions & 2 deletions cmd/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import (

// imagesCmd represents the images command
var imagesCmd = &cobra.Command{
Use: "images",
Short: "Cleans up your image registry from unused image tags",
Use: "images",
Short: "Cleans up your image registry from unused image tags",
Aliases: []string{"image", "img"},
}

func init() {
Expand Down
6 changes: 3 additions & 3 deletions cmd/orphans.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ func ExecuteOrphanCleanupCommand(args []string) error {
}
if len(imageTagList) == 0 {
log.WithFields(log.Fields{
"namespace": namespace,
"imageName": imageName,
"\n - namespace": namespace,
"\n - imageName": imageName,
}).Info("No orphaned image stream tags found")
return nil
}
PrintImageTags(imageTagList)
DeleteImages(imageTagList, imageName, namespace, config.Force)
DeleteImages(imageTagList, imageName, namespace, config.Delete)
return nil
}

Expand Down
5 changes: 3 additions & 2 deletions cmd/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ func init() {
rootCmd.AddCommand(secretCmd)
defaults := cfg.NewDefaultConfig()

secretCmd.PersistentFlags().BoolP("force", "f", defaults.Force, "Confirm deletion of secrets.")
secretCmd.PersistentFlags().BoolP("delete", "d", defaults.Delete, "Confirm deletion of secrets.")
secretCmd.PersistentFlags().BoolP("force", "f", defaults.Delete, "(deprecated) Alias for --delete")
secretCmd.PersistentFlags().StringSliceP("label", "l", defaults.Resource.Labels, "Identify the secret by these labels")
secretCmd.PersistentFlags().IntP("keep", "k", defaults.History.Keep,
"Keep most current <k> secrets. Does not include currently used secret (if detected).")
Expand Down Expand Up @@ -90,7 +91,7 @@ func executeSecretCleanupCommand(args []string) error {
PrintResources(filteredSecrets)
DeleteResources(
filteredSecrets,
config.Force,
config.Delete,
func(client *core.CoreV1Client) cfg.CoreObjectInterface {
return client.Secrets(namespace)
})
Expand Down

0 comments on commit 0649951

Please sign in to comment.