Browse Source

feat: 容器镜像列表增加是否使用标签 (#2364)

Refs #2300 

![image](https://github.com/1Panel-dev/1Panel/assets/73214554/a808d4f8-18fa-4010-8860-0a3788fa7eb0)
pull/2370/head
ssongliu 1 year ago committed by GitHub
parent
commit
12d6c2c3df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      backend/app/dto/image.go
  2. 11
      backend/app/service/image.go
  3. 6
      frontend/src/lang/modules/en.ts
  4. 6
      frontend/src/lang/modules/tw.ts
  5. 6
      frontend/src/lang/modules/zh.ts
  6. 12
      frontend/src/views/container/image/index.vue
  7. 26
      frontend/src/views/container/image/prune/index.vue

1
backend/app/dto/image.go

@ -5,6 +5,7 @@ import "time"
type ImageInfo struct {
ID string `json:"id"`
CreatedAt time.Time `json:"createdAt"`
IsUsed bool `json:"isUsed"`
Tags []string `json:"tags"`
Size string `json:"size"`
}

11
backend/app/service/image.go

@ -53,6 +53,7 @@ func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error)
if err != nil {
return 0, nil, err
}
containers, _ := client.ContainerList(context.Background(), types.ContainerListOptions{All: true})
if len(req.Info) != 0 {
length, count := len(list), 0
for count < length {
@ -77,6 +78,7 @@ func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error)
records = append(records, dto.ImageInfo{
ID: image.ID,
Tags: image.RepoTags,
IsUsed: checkUsed(image.ID, containers),
CreatedAt: time.Unix(image.Created, 0),
Size: size,
})
@ -415,3 +417,12 @@ func formatFileSize(fileSize int64) (size string) {
return fmt.Sprintf("%.2fEB", float64(fileSize)/float64(1024*1024*1024*1024*1024))
}
}
func checkUsed(imageID string, containers []types.Container) bool {
for _, container := range containers {
if container.ImageID == imageID {
return true
}
}
return false
}

6
frontend/src/lang/modules/en.ts

@ -224,6 +224,8 @@ const message = {
rebuilding: 'ReBuilding',
deny: 'Denied',
accept: 'Accepted',
used: 'Used',
unUsed: 'Unused',
},
units: {
second: 'Second',
@ -493,9 +495,9 @@ const message = {
containerPruneHelper3: 'This operation cannot be rolled back. Do you want to continue?',
imagePrune: 'Image prune',
imagePruneSome: 'Clean unlabeled',
imagePruneSomeHelper: 'Remove all unused and unlabeled container images',
imagePruneSomeHelper: 'Clean the images with the tag "none" that are not used by any containers.',
imagePruneAll: 'Clean unused',
imagePruneAllHelper: 'Remove all unused images, not just unlabeled',
imagePruneAllHelper: 'Clean the images that are not used by any containers.',
networkPrune: 'Network prune',
networkPruneHelper: 'Remove all unused networks. Do you want to continue?',
volumePrune: 'Volume prune',

6
frontend/src/lang/modules/tw.ts

@ -222,6 +222,8 @@ const message = {
rebuilding: '重建中',
deny: '已屏蔽',
accept: '已放行',
used: '已使用',
unUsed: '未使用',
},
units: {
second: '秒',
@ -481,9 +483,9 @@ const message = {
containerPruneHelper3: '該操作無法回滾是否繼續',
imagePrune: '清理鏡像',
imagePruneSome: '未標簽鏡像',
imagePruneSomeHelper: '清理標簽為 none 且未被任何容器使用的鏡像',
imagePruneSomeHelper: '清理下列標簽為 none 且未被任何容器使用的鏡像',
imagePruneAll: '未使用鏡像',
imagePruneAllHelper: '清理所有未被任何容器使用的鏡像',
imagePruneAllHelper: '清理下列未被任何容器使用的鏡像',
networkPrune: '清理網絡',
networkPruneHelper: '清理網絡 將刪除所有未被使用的網絡該操作無法回滾是否繼續',
volumePrune: '清理存儲卷',

6
frontend/src/lang/modules/zh.ts

@ -222,6 +222,8 @@ const message = {
rebuilding: '重建中',
deny: '已屏蔽',
accept: '已放行',
used: '已使用',
unUsed: '未使用',
},
units: {
second: '秒',
@ -481,9 +483,9 @@ const message = {
containerPruneHelper3: '该操作无法回滚是否继续',
imagePrune: '清理镜像',
imagePruneSome: '未标签镜像',
imagePruneSomeHelper: '清理标签为 none 且未被任何容器使用的镜像',
imagePruneSomeHelper: '清理下列标签为 none 且未被任何容器使用的镜像',
imagePruneAll: '未使用镜像',
imagePruneAllHelper: '清理所有未被任何容器使用的镜像',
imagePruneAllHelper: '清理下列未被任何容器使用的镜像',
networkPrune: '清理网络',
networkPruneHelper: '清理网络 将删除所有未被使用的网络该操作无法回滚是否继续',
volumePrune: '清理存储卷',

12
frontend/src/views/container/image/index.vue

@ -46,6 +46,16 @@
<span>{{ row.id.replaceAll('sha256:', '').substring(0, 12) }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="isUsed" width="100">
<template #default="{ row }">
<el-tag icon="Select" v-if="row.isUsed" type="success">
{{ $t('commons.status.used') }}
</el-tag>
<el-tag v-else type="info">
{{ $t('commons.status.unUsed') }}
</el-tag>
</template>
</el-table-column>
<el-table-column
:label="$t('container.tag')"
prop="tags"
@ -186,7 +196,7 @@ const onOpenBuild = () => {
};
const onOpenPrune = () => {
dialogPruneRef.value!.acceptParams();
dialogPruneRef.value!.acceptParams({ list: data.value });
};
const onOpenload = () => {

26
frontend/src/views/container/image/prune/index.vue

@ -11,10 +11,22 @@
<el-radio :label="false">{{ $t('container.imagePruneSome') }}</el-radio>
<el-radio :label="true">{{ $t('container.imagePruneAll') }}</el-radio>
</el-radio-group>
<span class="input-help">
{{ withTagAll ? $t('container.imagePruneAllHelper') : $t('container.imagePruneSomeHelper') }}
</span>
</el-form-item>
<span>
{{ withTagAll ? $t('container.imagePruneAllHelper') : $t('container.imagePruneSomeHelper') }}
</span>
<div v-if="!withTagAll">
<ul v-for="(item, index) in imageList" :key="index">
<li v-if="item.tags.length === 1 && item.tags[0].indexOf(':<none>') !== -1">
{{ item.tags[0] }}
</li>
</ul>
</div>
<div v-else>
<ul v-for="(item, index) in imageList" :key="index">
<li v-if="!item.isUsed">{{ item.tags.join(', ') }}</li>
</ul>
</div>
</el-form>
<template #footer>
<span class="dialog-footer">
@ -30,6 +42,7 @@
</template>
<script lang="ts" setup>
import { Container } from '@/api/interface/container';
import { containerPrune } from '@/api/modules/container';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
@ -39,8 +52,13 @@ import { ref } from 'vue';
const dialogVisiable = ref(false);
const withTagAll = ref(false);
const loading = ref();
const imageList = ref();
const acceptParams = (): void => {
interface DialogProps {
list: Array<Container.ImageInfo>;
}
const acceptParams = (params: DialogProps): void => {
imageList.value = params.list;
dialogVisiable.value = true;
withTagAll.value = false;
};

Loading…
Cancel
Save