1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-31 22:18:07 +08:00

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"` State string `json:"state"`
RunTime string `json:"runTime"` RunTime string `json:"runTime"`
IsFromApp bool `json:"isFromApp"`
IsFromCompose bool `json:"isFromCompose"` 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 { if _, ok := container.Labels[composeProjectLabel]; ok {
IsFromCompose = true IsFromCompose = true
} }
IsFromApp := false
if created, ok := container.Labels[composeCreatedBy]; ok && created == "Apps" {
IsFromApp = true
}
backDatas = append(backDatas, dto.ContainerInfo{ backDatas = append(backDatas, dto.ContainerInfo{
ContainerID: container.ID, ContainerID: container.ID,
CreateTime: time.Unix(container.Created, 0).Format("2006-01-02 15:04:05"), 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, ImageName: container.Image,
State: container.State, State: container.State,
RunTime: container.Status, RunTime: container.Status,
IsFromApp: IsFromApp,
IsFromCompose: IsFromCompose, IsFromCompose: IsFromCompose,
}) })
} }

View File

@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/1Panel-dev/1Panel/backend/app/dto" "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/constant"
"github.com/1Panel-dev/1Panel/backend/utils/docker" "github.com/1Panel-dev/1Panel/backend/utils/docker"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -95,6 +96,9 @@ func (u *ContainerService) DeleteVolume(req dto.BatchDelete) error {
} }
for _, id := range req.Names { for _, id := range req.Names {
if err := client.VolumeRemove(context.TODO(), id, true); err != nil { 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 return err
} }
} }

View File

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

View File

@ -53,3 +53,6 @@ ErrDatabaseIsExist: "The current database already exists. Please enter a new dat
#redis #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

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

View File

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

View File

@ -407,6 +407,8 @@ export default {
createContainer: 'Create container', createContainer: 'Create container',
containerList: 'Container list', containerList: 'Container list',
operatorHelper: '{0} will be performed on the selected container. Do you want to continue?', 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', start: 'Start',
stop: 'Stop', stop: 'Stop',
restart: 'Restart', restart: 'Restart',

View File

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

View File

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

View File

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

View File

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