Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 工具箱的缓存清理添加容器垃圾清理功能 #5024

Merged
merged 1 commit into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/app/dto/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ type CleanData struct {
UploadClean []CleanTree `json:"uploadClean"`
DownloadClean []CleanTree `json:"downloadClean"`
SystemLogClean []CleanTree `json:"systemLogClean"`
ContainerClean []CleanTree `json:"containerClean"`
}

type CleanTree struct {
Expand Down
4 changes: 3 additions & 1 deletion backend/app/service/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@ func (u *ContainerService) Prune(req dto.ContainerPrune) (dto.ContainerPruneRepo
report.DeletedNumber = len(rep.VolumesDeleted)
report.SpaceReclaimed = int(rep.SpaceReclaimed)
case "buildcache":
rep, err := client.BuildCachePrune(context.Background(), types.BuildCachePruneOptions{})
opts := types.BuildCachePruneOptions{}
opts.All = true
rep, err := client.BuildCachePrune(context.Background(), opts)
if err != nil {
return report, err
}
Expand Down
148 changes: 148 additions & 0 deletions backend/app/service/device_clean.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package service

import (
"context"
"fmt"
"github.com/1Panel-dev/1Panel/backend/utils/docker"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"os"
"path"
"sort"
Expand Down Expand Up @@ -130,6 +134,9 @@ func (u *DeviceService) Scan() dto.CleanData {
logTree := loadLogTree(fileOp)
SystemClean.SystemLogClean = append(SystemClean.SystemLogClean, logTree...)

containerTree := loadContainerTree()
SystemClean.ContainerClean = append(SystemClean.ContainerClean, containerTree...)

return SystemClean
}

Expand Down Expand Up @@ -259,6 +266,14 @@ func (u *DeviceService) Clean(req []dto.Clean) {
} else {
_ = cronjobRepo.DeleteRecord(cronjobRepo.WithByRecordFile(pathItem))
}
case "images":
dropImages()
case "containers":
dropContainers()
case "volumes":
dropVolumes()
case "build_cache":
dropBuildCache()
}
}

Expand Down Expand Up @@ -496,6 +511,82 @@ func loadLogTree(fileOp fileUtils.FileOp) []dto.CleanTree {
return treeData
}

func loadContainerTree() []dto.CleanTree {
var treeData []dto.CleanTree
client, err := docker.NewDockerClient()
diskUsage, err := client.DiskUsage(context.Background(), types.DiskUsageOptions{})
if err != nil {
return treeData
}
var listImage []dto.CleanTree
imageSize := uint64(0)
for _, file := range diskUsage.Images {
if file.Containers == 0 {
name := "none"
if file.RepoTags != nil {
name = file.RepoTags[0]
}
item := dto.CleanTree{
ID: file.ID,
Label: name,
Type: "images",
Size: uint64(file.Size),
Name: name,
IsCheck: false,
IsRecommend: true,
}
imageSize += item.Size
listImage = append(listImage, item)
}
}
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "container_images", Size: imageSize, Children: listImage, Type: "images", IsRecommend: true})

var listContainer []dto.CleanTree
containerSize := uint64(0)
for _, file := range diskUsage.Containers {
if file.State != "running" {
item := dto.CleanTree{
ID: file.ID,
Label: file.Names[0],
Type: "containers",
Size: uint64(file.SizeRw),
Name: file.Names[0],
IsCheck: false,
IsRecommend: true,
}
containerSize += item.Size
listContainer = append(listContainer, item)
}
}
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "container_containers", Size: containerSize, Children: listContainer, Type: "containers", IsRecommend: true})

var listVolume []dto.CleanTree
volumeSize := uint64(0)
for _, file := range diskUsage.Volumes {
if file.UsageData.RefCount <= 0 {
item := dto.CleanTree{
ID: uuid.NewString(),
Label: file.Name,
Type: "volumes",
Size: uint64(file.UsageData.Size),
Name: file.Name,
IsCheck: false,
IsRecommend: true,
}
volumeSize += item.Size
listVolume = append(listVolume, item)
}
}
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "container_volumes", Size: volumeSize, Children: listVolume, Type: "volumes", IsRecommend: true})

var buildCacheTotalSize int64
for _, cache := range diskUsage.BuildCache {
buildCacheTotalSize += cache.Size
}
treeData = append(treeData, dto.CleanTree{ID: uuid.NewString(), Label: "build_cache", Size: uint64(buildCacheTotalSize), Type: "build_cache", IsRecommend: true})
return treeData
}

func loadTreeWithDir(isCheck bool, treeType, pathItem string, fileOp fileUtils.FileOp) []dto.CleanTree {
var lists []dto.CleanTree
files, err := os.ReadDir(pathItem)
Expand Down Expand Up @@ -586,6 +677,63 @@ func dropFileOrDir(itemPath string) {
}
}

func dropBuildCache() {
client, err := docker.NewDockerClient()
if err != nil {
global.LOG.Errorf("do not get docker client")
}
opts := types.BuildCachePruneOptions{}
opts.All = true
_, err = client.BuildCachePrune(context.Background(), opts)
if err != nil {
global.LOG.Errorf("drop build cache failed, err %v", err)
}
}

func dropImages() {
client, err := docker.NewDockerClient()
if err != nil {
global.LOG.Errorf("do not get docker client")
}
pruneFilters := filters.NewArgs()
pruneFilters.Add("dangling", "false")
_, err = client.ImagesPrune(context.Background(), pruneFilters)
if err != nil {
global.LOG.Errorf("drop images failed, err %v", err)
}
}

func dropContainers() {
client, err := docker.NewDockerClient()
if err != nil {
global.LOG.Errorf("do not get docker client")
}
pruneFilters := filters.NewArgs()
_, err = client.ContainersPrune(context.Background(), pruneFilters)
if err != nil {
global.LOG.Errorf("drop containers failed, err %v", err)
}
}

func dropVolumes() {
client, err := docker.NewDockerClient()
if err != nil {
global.LOG.Errorf("do not get docker client")
}
pruneFilters := filters.NewArgs()
versions, err := client.ServerVersion(context.Background())
if err != nil {
global.LOG.Errorf("do not get docker api versions")
}
if common.ComparePanelVersion(versions.APIVersion, "1.42") {
pruneFilters.Add("all", "true")
}
_, err = client.VolumesPrune(context.Background(), pruneFilters)
if err != nil {
global.LOG.Errorf("drop volumes failed, err %v", err)
}
}

func dropFileOrDirWithLog(itemPath string, log *string, size *int64, count *int) {
itemSize := int64(0)
itemCount := 0
Expand Down
1 change: 1 addition & 0 deletions frontend/src/api/interface/toolbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export namespace Toolbox {
uploadClean: Array<CleanTree>;
downloadClean: Array<CleanTree>;
systemLogClean: Array<CleanTree>;
containerClean: Array<CleanTree>;
}
export interface CleanTree {
id: string;
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,11 @@ const message = {
sockPathErr: 'Please select or enter the correct Docker sock file path',
related: 'Related resources',
includeAppstore: 'Show app store container',

cleanDockerDiskZone: 'Clean up disk space used by Docker',
cleanImagesHelper: '( Clean up all images that are not used by any containers )',
cleanContainersHelper: '( Clean up all stopped containers )',
cleanVolumesHelper: '( Clean up all unused local volumes )',
},
cronjob: {
create: 'Create Cronjob',
Expand Down Expand Up @@ -1601,6 +1606,12 @@ const message = {
shell: 'Shell script scheduled tasks',
containerShell: 'Container internal Shell script scheduled tasks',
curl: 'CURL scheduled tasks',

containerTrash: 'Container Trash',
images: 'Images',
containers: 'Containers',
volumes: 'Volumes',
buildCache: 'Container Build Cache',
},
app: {
app: 'Application',
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/lang/modules/tw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,11 @@ const message = {
sockPathErr: '請選擇或輸入正確的 Docker sock 文件路徑',
related: '相關資源',
includeAppstore: '顯示應用程式商店容器',

cleanDockerDiskZone: '清理 Docker 使用的磁碟空間',
cleanImagesHelper: '( 清理所有未被任何容器使用的鏡像 )',
cleanContainersHelper: '( 清理所有處於停止狀態的容器 )',
cleanVolumesHelper: '( 清理所有未被使用的本地存儲卷 )',
},
cronjob: {
create: '創建計劃任務',
Expand Down Expand Up @@ -1493,6 +1498,12 @@ const message = {
shell: 'Shell 腳本計劃任務',
containerShell: '容器內執行 Shell 腳本計劃任務',
curl: 'CURL 計劃任務',

containerTrash: '容器垃圾',
images: '鏡像',
containers: '容器',
volumes: '存儲卷',
buildCache: '容器建置快取',
},
app: {
app: '應用',
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/lang/modules/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,11 @@ const message = {
sockPathErr: '请选择或输入正确的 Docker sock 文件路径',
related: '关联资源',
includeAppstore: '显示应用商店容器',

cleanDockerDiskZone: '清理 Docker 使用的磁盘空间',
cleanImagesHelper: '( 清理所有未被任何容器使用的镜像 )',
cleanContainersHelper: '( 清理所有处于停止状态的容器 )',
cleanVolumesHelper: '( 清理所有未被使用的本地存储卷 )',
},
cronjob: {
create: '创建计划任务',
Expand Down Expand Up @@ -1493,6 +1498,12 @@ const message = {
shell: 'Shell 脚本计划任务',
containerShell: '容器内执行 Shell 脚本计划任务',
curl: 'CURL 计划任务',

containerTrash: '容器垃圾',
images: '镜像',
containers: '容器',
volumes: '存储卷',
buildCache: '构建缓存',
},
app: {
app: '应用',
Expand Down
Loading
Loading