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:
@@ -3,7 +3,6 @@ package builder
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -12,30 +11,6 @@ import (
|
|||||||
"github.com/dokku/dokku/plugins/common"
|
"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) {
|
func listImagesByImageRepo(imageRepo string) ([]string, error) {
|
||||||
command := []string{
|
command := []string{
|
||||||
common.DockerBin(),
|
common.DockerBin(),
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ func main() {
|
|||||||
case "post-delete":
|
case "post-delete":
|
||||||
appName := flag.Arg(0)
|
appName := flag.Arg(0)
|
||||||
err = builder.TriggerPostDelete(appName)
|
err = builder.TriggerPostDelete(appName)
|
||||||
|
case "post-release-builder":
|
||||||
|
builderType := flag.Arg(0)
|
||||||
|
appName := flag.Arg(1)
|
||||||
|
err = builder.TriggerPostReleaseBuilder(builderType, appName)
|
||||||
case "report":
|
case "report":
|
||||||
appName := flag.Arg(0)
|
appName := flag.Arg(0)
|
||||||
err = builder.ReportSingleApp(appName, "", "")
|
err = builder.ReportSingleApp(appName, "", "")
|
||||||
|
|||||||
@@ -133,7 +133,9 @@ func TriggerPostDelete(appName string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
imagesByAppLabel, err := listImagesByAppLabel(appName)
|
imagesByAppLabel, err := common.DockerFilterImages([]string{
|
||||||
|
fmt.Sprintf("label=com.dokku.app-name=%s", appName),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.LogWarn(err.Error())
|
common.LogWarn(err.Error())
|
||||||
}
|
}
|
||||||
@@ -149,3 +151,17 @@ func TriggerPostDelete(appName string) error {
|
|||||||
|
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -300,17 +300,58 @@ func IsImageHerokuishBased(image string, appName string) bool {
|
|||||||
|
|
||||||
// ListDanglingImages lists all dangling image ids for a given app
|
// ListDanglingImages lists all dangling image ids for a given app
|
||||||
func ListDanglingImages(appName string) ([]string, error) {
|
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{
|
command := []string{
|
||||||
DockerBin(),
|
DockerBin(),
|
||||||
"image",
|
"image",
|
||||||
"ls",
|
"rm",
|
||||||
"--quiet",
|
|
||||||
"--filter",
|
|
||||||
"dangling=true",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if appName != "" {
|
command = append(command, imageIDs...)
|
||||||
command = append(command, []string{"--filter", fmt.Sprintf("label=com.dokku.app-name=%v", appName)}...)
|
|
||||||
|
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
|
var stderr bytes.Buffer
|
||||||
@@ -327,39 +368,11 @@ func ListDanglingImages(appName string) ([]string, error) {
|
|||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveImages removes images by ID
|
// DockerFilterImages returns a slice of image IDs based on the passed in filters
|
||||||
func RemoveImages(imageIDs []string) {
|
func DockerFilterImages(filters []string) ([]string, error) {
|
||||||
if len(imageIDs) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
command := []string{
|
command := []string{
|
||||||
DockerBin(),
|
DockerBin(),
|
||||||
"image",
|
"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",
|
"ls",
|
||||||
"--quiet",
|
"--quiet",
|
||||||
"--all",
|
"--all",
|
||||||
|
|||||||
Reference in New Issue
Block a user