Merge pull request #6273 from dokku/6272-force-clean-intermediate-images

Clean up local build images immediately after an image is released
This commit is contained in:
Jose Diaz-Gonzalez
2023-10-14 23:32:49 -04:00
committed by GitHub
4 changed files with 70 additions and 62 deletions

View File

@@ -3,7 +3,6 @@ package builder
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
@@ -12,30 +11,6 @@ import (
"github.com/dokku/dokku/plugins/common"
)
func listImagesByAppLabel(appName string) ([]string, error) {
command := []string{
common.DockerBin(),
"image",
"ls",
"--quiet",
"--filter",
fmt.Sprintf("label=com.dokku.app-name=%v", appName),
}
var stderr bytes.Buffer
listCmd := common.NewShellCmd(strings.Join(command, " "))
listCmd.ShowOutput = false
listCmd.Command.Stderr = &stderr
b, err := listCmd.Output()
if err != nil {
return []string{}, errors.New(strings.TrimSpace(stderr.String()))
}
output := strings.Split(strings.TrimSpace(string(b[:])), "\n")
return output, nil
}
func listImagesByImageRepo(imageRepo string) ([]string, error) {
command := []string{
common.DockerBin(),

View File

@@ -50,6 +50,10 @@ func main() {
case "post-delete":
appName := flag.Arg(0)
err = builder.TriggerPostDelete(appName)
case "post-release-builder":
builderType := flag.Arg(0)
appName := flag.Arg(1)
err = builder.TriggerPostReleaseBuilder(builderType, appName)
case "report":
appName := flag.Arg(0)
err = builder.ReportSingleApp(appName, "", "")

View File

@@ -133,7 +133,9 @@ func TriggerPostDelete(appName string) error {
return err
}
imagesByAppLabel, err := listImagesByAppLabel(appName)
imagesByAppLabel, err := common.DockerFilterImages([]string{
fmt.Sprintf("label=com.dokku.app-name=%s", appName),
})
if err != nil {
common.LogWarn(err.Error())
}
@@ -149,3 +151,17 @@ func TriggerPostDelete(appName string) error {
return nil
}
// TriggerPostReleaseBuilder deletes unused build images
func TriggerPostReleaseBuilder(builderType string, appName string) error {
images, _ := common.DockerFilterImages([]string{
"label=com.dokku.image-stage=build",
fmt.Sprintf("label=com.dokku.app-name=%s", appName),
})
if err := common.RemoveImages(images); err != nil {
common.LogWarn(err.Error())
}
return nil
}

View File

@@ -300,17 +300,58 @@ func IsImageHerokuishBased(image string, appName string) bool {
// ListDanglingImages lists all dangling image ids for a given app
func ListDanglingImages(appName string) ([]string, error) {
filters := []string{"dangling=true"}
if appName != "" {
filters = append(filters, []string{fmt.Sprintf("label=com.dokku.app-name=%v", appName)}...)
}
return DockerFilterImages(filters)
}
// RemoveImages removes images by ID
func RemoveImages(imageIDs []string) error {
if len(imageIDs) == 0 {
return nil
}
command := []string{
DockerBin(),
"image",
"ls",
"--quiet",
"--filter",
"dangling=true",
"rm",
}
if appName != "" {
command = append(command, []string{"--filter", fmt.Sprintf("label=com.dokku.app-name=%v", appName)}...)
command = append(command, imageIDs...)
var stderr bytes.Buffer
rmCmd := NewShellCmd(strings.Join(command, " "))
rmCmd.ShowOutput = false
rmCmd.Command.Stderr = &stderr
rmCmd.Execute()
if _, err := rmCmd.Output(); err != nil {
return errors.New(strings.TrimSpace(stderr.String()))
}
return nil
}
// VerifyImage returns true if docker image exists in local repo
func VerifyImage(image string) bool {
imageCmd := NewShellCmd(strings.Join([]string{DockerBin(), "image", "inspect", image}, " "))
imageCmd.ShowOutput = false
return imageCmd.Execute()
}
// DockerFilterContainers returns a slice of container IDs based on the passed in filters
func DockerFilterContainers(filters []string) ([]string, error) {
command := []string{
DockerBin(),
"container",
"ls",
"--quiet",
"--all",
}
for _, filter := range filters {
command = append(command, "--filter", filter)
}
var stderr bytes.Buffer
@@ -327,39 +368,11 @@ func ListDanglingImages(appName string) ([]string, error) {
return output, nil
}
// RemoveImages removes images by ID
func RemoveImages(imageIDs []string) {
if len(imageIDs) == 0 {
return
}
// DockerFilterImages returns a slice of image IDs based on the passed in filters
func DockerFilterImages(filters []string) ([]string, error) {
command := []string{
DockerBin(),
"image",
"rm",
}
command = append(command, imageIDs...)
var stderr bytes.Buffer
rmCmd := NewShellCmd(strings.Join(command, " "))
rmCmd.ShowOutput = false
rmCmd.Command.Stderr = &stderr
rmCmd.Execute()
}
// VerifyImage returns true if docker image exists in local repo
func VerifyImage(image string) bool {
imageCmd := NewShellCmd(strings.Join([]string{DockerBin(), "image", "inspect", image}, " "))
imageCmd.ShowOutput = false
return imageCmd.Execute()
}
// DockerFilterContainers returns a slice of container IDs based on the passed in filters
func DockerFilterContainers(filters []string) ([]string, error) {
command := []string{
DockerBin(),
"container",
"ls",
"--quiet",
"--all",