1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 16:29:17 +08:00

feat: 运行环境及容器菜单增加清理构建缓存功能 (#4978)

Co-authored-by: zhoujunhong <1298308460@qq.com>
This commit is contained in:
John Bro 2024-05-11 17:50:24 +08:00 committed by GitHub
parent df53193f3f
commit d43df6941b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 111 additions and 2 deletions

View File

@ -123,7 +123,7 @@ type ContainerRename struct {
} }
type ContainerPrune struct { type ContainerPrune struct {
PruneType string `json:"pruneType" validate:"required,oneof=container image volume network"` PruneType string `json:"pruneType" validate:"required,oneof=container image volume network buildcache"`
WithTagAll bool `json:"withTagAll"` WithTagAll bool `json:"withTagAll"`
} }

View File

@ -329,6 +329,13 @@ func (u *ContainerService) Prune(req dto.ContainerPrune) (dto.ContainerPruneRepo
} }
report.DeletedNumber = len(rep.VolumesDeleted) report.DeletedNumber = len(rep.VolumesDeleted)
report.SpaceReclaimed = int(rep.SpaceReclaimed) report.SpaceReclaimed = int(rep.SpaceReclaimed)
case "buildcache":
rep, err := client.BuildCachePrune(context.Background(), types.BuildCachePruneOptions{})
if err != nil {
return report, err
}
report.DeletedNumber = len(rep.CachesDeleted)
report.SpaceReclaimed = int(rep.SpaceReclaimed)
} }
return report, nil return report, nil
} }

View File

@ -691,6 +691,9 @@ const message = {
tag: 'Tag', tag: 'Tag',
tagHelper: 'one in a row, for example, \nkey1=value1\nkey2=value2', tagHelper: 'one in a row, for example, \nkey1=value1\nkey2=value2',
imageNameHelper: 'Image name and Tag, for example: nginx:latest', imageNameHelper: 'Image name and Tag, for example: nginx:latest',
cleanBuildCache: 'Clean Build Cache',
delBuildCacheHelper:
'Cleaning the build cache will delete all cached artifacts generated during builds. This action cannot be undone. Continue?',
network: 'Network', network: 'Network',
createNetwork: 'Create network', createNetwork: 'Create network',

View File

@ -672,6 +672,8 @@ const message = {
tag: '標簽', tag: '標簽',
tagHelper: '一行一個 \nkey1=value1\nkey2=value2', tagHelper: '一行一個 \nkey1=value1\nkey2=value2',
imageNameHelper: '鏡像名稱及 Tagnginx:latest', imageNameHelper: '鏡像名稱及 Tagnginx:latest',
cleanBuildCache: '清理建置快取',
delBuildCacheHelper: '清理建置快取將刪除所有建置所產生的快取此操作無法回復是否繼續',
network: '網絡', network: '網絡',
createNetwork: '創建網絡', createNetwork: '創建網絡',

View File

@ -673,6 +673,8 @@ const message = {
tag: '标签', tag: '标签',
tagHelper: '一行一个 \nkey1=value1\nkey2=value2', tagHelper: '一行一个 \nkey1=value1\nkey2=value2',
imageNameHelper: '镜像名称及 Tagnginx:latest', imageNameHelper: '镜像名称及 Tagnginx:latest',
cleanBuildCache: '清理构建缓存',
delBuildCacheHelper: '清理构建缓存 将删除所有构建产生的缓存该操作无法回滚是否继续',
network: '网络', network: '网络',
createNetwork: '创建网络', createNetwork: '创建网络',

View File

@ -19,6 +19,9 @@
<el-button type="primary" plain @click="onOpenBuild"> <el-button type="primary" plain @click="onOpenBuild">
{{ $t('container.imageBuild') }} {{ $t('container.imageBuild') }}
</el-button> </el-button>
<el-button type="primary" plain @click="onOpenBuildCache()">
{{ $t('container.cleanBuildCache') }}
</el-button>
<el-button type="primary" plain @click="onOpenPrune()"> <el-button type="primary" plain @click="onOpenPrune()">
{{ $t('container.imagePrune') }} {{ $t('container.imagePrune') }}
</el-button> </el-button>
@ -112,10 +115,19 @@ import Build from '@/views/container/image/build/index.vue';
import Delete from '@/views/container/image/delete/index.vue'; import Delete from '@/views/container/image/delete/index.vue';
import Prune from '@/views/container/image/prune/index.vue'; import Prune from '@/views/container/image/prune/index.vue';
import CodemirrorDialog from '@/components/codemirror-dialog/index.vue'; import CodemirrorDialog from '@/components/codemirror-dialog/index.vue';
import { searchImage, listImageRepo, loadDockerStatus, imageRemove, inspect } from '@/api/modules/container'; import {
searchImage,
listImageRepo,
loadDockerStatus,
imageRemove,
inspect,
containerPrune,
} from '@/api/modules/container';
import i18n from '@/lang'; import i18n from '@/lang';
import router from '@/routers'; import router from '@/routers';
import { GlobalStore } from '@/store'; import { GlobalStore } from '@/store';
import { ElMessageBox } from 'element-plus';
import { MsgSuccess } from '@/utils/message';
const globalStore = GlobalStore(); const globalStore = GlobalStore();
const mobile = computed(() => { const mobile = computed(() => {
@ -222,6 +234,29 @@ const onOpenPrune = () => {
dialogPruneRef.value!.acceptParams(); dialogPruneRef.value!.acceptParams();
}; };
const onOpenBuildCache = () => {
ElMessageBox.confirm(i18n.global.t('container.delBuildCacheHelper'), i18n.global.t('container.cleanBuildCache'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(async () => {
loading.value = true;
let params = {
pruneType: 'buildcache',
withTagAll: false,
};
await containerPrune(params)
.then((res) => {
loading.value = false;
MsgSuccess(i18n.global.t('container.cleanSuccess', [res.data.deletedNumber]));
search();
})
.catch(() => {
loading.value = false;
});
});
};
const onOpenload = () => { const onOpenload = () => {
dialogLoadRef.value!.acceptParams(); dialogLoadRef.value!.acceptParams();
}; };

View File

@ -13,6 +13,10 @@
<el-button type="primary" @click="openCreate"> <el-button type="primary" @click="openCreate">
{{ $t('runtime.create') }} {{ $t('runtime.create') }}
</el-button> </el-button>
<el-button type="primary" plain @click="onOpenBuildCache()">
{{ $t('container.cleanBuildCache') }}
</el-button>
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()"> <ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()">
@ -104,6 +108,9 @@ import ComposeLogs from '@/components/compose-log/index.vue';
import { Promotion } from '@element-plus/icons-vue'; import { Promotion } from '@element-plus/icons-vue';
import PortJumpDialog from '@/components/port-jump/index.vue'; import PortJumpDialog from '@/components/port-jump/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue'; import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus';
import { containerPrune } from '@/api/modules/container';
import { MsgSuccess } from '@/utils/message';
let timer: NodeJS.Timer | null = null; let timer: NodeJS.Timer | null = null;
const loading = ref(false); const loading = ref(false);
@ -222,6 +229,29 @@ const openDelete = async (row: Runtime.Runtime) => {
}); });
}; };
const onOpenBuildCache = () => {
ElMessageBox.confirm(i18n.global.t('container.delBuildCacheHelper'), i18n.global.t('container.cleanBuildCache'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(async () => {
loading.value = true;
let params = {
pruneType: 'buildcache',
withTagAll: false,
};
await containerPrune(params)
.then((res) => {
loading.value = false;
MsgSuccess(i18n.global.t('container.cleanSuccess', [res.data.deletedNumber]));
search();
})
.catch(() => {
loading.value = false;
});
});
};
const openLog = (row: any) => { const openLog = (row: any) => {
composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name }); composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name });
}; };

View File

@ -17,6 +17,10 @@
<el-button @click="openExtensions"> <el-button @click="openExtensions">
{{ $t('php.extensions') }} {{ $t('php.extensions') }}
</el-button> </el-button>
<el-button type="primary" plain @click="onOpenBuildCache()">
{{ $t('container.cleanBuildCache') }}
</el-button>
</template> </template>
<template #main> <template #main>
<ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()"> <ComplexTable :pagination-config="paginationConfig" :data="items" @search="search()">
@ -95,6 +99,9 @@ import RouterMenu from '../index.vue';
import Log from '@/components/log-dialog/index.vue'; import Log from '@/components/log-dialog/index.vue';
import Extensions from './extensions/index.vue'; import Extensions from './extensions/index.vue';
import AppResources from '@/views/website/runtime/php/check/index.vue'; import AppResources from '@/views/website/runtime/php/check/index.vue';
import { ElMessageBox } from 'element-plus';
import { containerPrune } from '@/api/modules/container';
import { MsgSuccess } from '@/utils/message';
const paginationConfig = reactive({ const paginationConfig = reactive({
cacheSizeKey: 'runtime-page-size', cacheSizeKey: 'runtime-page-size',
@ -190,6 +197,29 @@ const openDelete = async (row: Runtime.Runtime) => {
}); });
}; };
const onOpenBuildCache = () => {
ElMessageBox.confirm(i18n.global.t('container.delBuildCacheHelper'), i18n.global.t('container.cleanBuildCache'), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(async () => {
loading.value = true;
let params = {
pruneType: 'buildcache',
withTagAll: false,
};
await containerPrune(params)
.then((res) => {
loading.value = false;
MsgSuccess(i18n.global.t('container.cleanSuccess', [res.data.deletedNumber]));
search();
})
.catch(() => {
loading.value = false;
});
});
};
onMounted(() => { onMounted(() => {
search(); search();
timer = setInterval(() => { timer = setInterval(() => {