fix: 容器部分已知问题修改 (#224)

1. 删除存储卷增加使用中判断
2. 容器操作时增加来源判断
3. 解决删除镜像后页面没有自动刷新的问题
This commit is contained in:
ssongliu 2023-03-15 16:48:26 +08:00 committed by GitHub
parent 281d0cf880
commit 4f52580938
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 53 additions and 21 deletions

View File

@ -22,6 +22,7 @@ type ContainerInfo struct {
State string `json:"state"`
RunTime string `json:"runTime"`
IsFromApp bool `json:"isFromApp"`
IsFromCompose bool `json:"isFromCompose"`
}

View File

@ -98,6 +98,10 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
if _, ok := container.Labels[composeProjectLabel]; ok {
IsFromCompose = true
}
IsFromApp := false
if created, ok := container.Labels[composeCreatedBy]; ok && created == "Apps" {
IsFromApp = true
}
backDatas = append(backDatas, dto.ContainerInfo{
ContainerID: container.ID,
CreateTime: time.Unix(container.Created, 0).Format("2006-01-02 15:04:05"),
@ -106,6 +110,7 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
ImageName: container.Image,
State: container.State,
RunTime: container.Status,
IsFromApp: IsFromApp,
IsFromCompose: IsFromCompose,
})
}

View File

@ -7,6 +7,7 @@ import (
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/utils/docker"
"github.com/docker/docker/api/types"
@ -95,6 +96,9 @@ func (u *ContainerService) DeleteVolume(req dto.BatchDelete) error {
}
for _, id := range req.Names {
if err := client.VolumeRemove(context.TODO(), id, true); err != nil {
if strings.Contains(err.Error(), "volume is in use") {
return buserr.New(constant.ErrInUsed)
}
return err
}
}

View File

@ -95,3 +95,8 @@ var (
var (
ErrTypeOfRedis = "ErrTypeOfRedis"
)
//container
var (
ErrInUsed = "ErrInUsed"
)

View File

@ -52,4 +52,7 @@ ErrUserIsExist: "The current user already exists. Please enter a new user"
ErrDatabaseIsExist: "The current database already exists. Please enter a new database"
#redis
ErrTypeOfRedis: "The recovery file type does not match the current persistence mode. Modify the file type and try again"
ErrTypeOfRedis: "The recovery file type does not match the current persistence mode. Modify the file type and try again"
#container
ErrInUsed: "The deleted object is in use and cannot be deleted"

View File

@ -52,4 +52,7 @@ ErrUserIsExist: "当前用户已存在,请重新输入"
ErrDatabaseIsExist: "当前数据库已存在,请重新输入"
#redis
ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后重试"
ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后重试"
#container
ErrInUsed: "该删除对象正被使用,无法删除"

View File

@ -43,7 +43,8 @@ export namespace Container {
state: string;
runTime: string;
isFromCompose: string;
isFromApp: boolean;
isFromCompose: boolean;
}
export interface ContainerStats {
cpuPercent: number;

View File

@ -407,6 +407,8 @@ export default {
createContainer: 'Create container',
containerList: 'Container list',
operatorHelper: '{0} will be performed on the selected container. Do you want to continue?',
operatorAppHelper:
'There is a container from the App store. The {0} operation may affect the normal use of this service. Are you sure?',
start: 'Start',
stop: 'Stop',
restart: 'Restart',

View File

@ -419,6 +419,7 @@ export default {
createContainer: '创建容器',
containerList: '容器列表',
operatorHelper: '将对选中容器进行 {0} 操作是否继续',
operatorAppHelper: '存在来源于应用商店的容器{0} 操作可能会影响到该服务的正常使用是否确认',
start: '启动',
stop: '停止',
restart: '重启',

View File

@ -228,15 +228,18 @@ const checkStatus = (operation: string) => {
};
const onOperate = async (operation: string) => {
ElMessageBox.confirm(
i18n.global.t('container.operatorHelper', [i18n.global.t('container.' + operation)]),
i18n.global.t('container.' + operation),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
},
).then(() => {
let msg = i18n.global.t('container.operatorHelper', [i18n.global.t('container.' + operation)]);
for (const item of selects.value) {
if (item.isFromApp) {
msg = i18n.global.t('container.operatorAppHelper', [i18n.global.t('container.' + operation)]);
break;
}
}
ElMessageBox.confirm(msg, i18n.global.t('container.' + operation), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(() => {
let ps = [];
for (const item of selects.value) {
const param = {

View File

@ -252,15 +252,18 @@ const checkStatus = (operation: string) => {
}
};
const onOperate = async (operation: string) => {
ElMessageBox.confirm(
i18n.global.t('container.operatorHelper', [i18n.global.t('container.' + operation)]),
i18n.global.t('container.' + operation),
{
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
},
).then(() => {
let msg = i18n.global.t('container.operatorHelper', [i18n.global.t('container.' + operation)]);
for (const item of selects.value) {
if (item.isFromApp) {
msg = i18n.global.t('container.operatorAppHelper', [i18n.global.t('container.' + operation)]);
break;
}
}
ElMessageBox.confirm(msg, i18n.global.t('container.' + operation), {
confirmButtonText: i18n.global.t('commons.button.confirm'),
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(() => {
let ps = [];
for (const item of selects.value) {
const param = {

View File

@ -193,6 +193,7 @@ const buttons = [
click: async (row: Container.ImageInfo) => {
if (row.tags.length <= 1) {
await useDeleteData(imageRemove, { names: [row.id] }, 'commons.msg.delete');
search();
return;
}
let params = {