mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-14 01:34:47 +08:00
feat: 网站应用创建可以选择存量数据库,删除应用增加删除数据库选项
This commit is contained in:
parent
a1c3fa644c
commit
e1518e842f
@ -45,6 +45,7 @@ type AppInstalledOperate struct {
|
|||||||
Operate constant.AppOperate `json:"operate" validate:"required"`
|
Operate constant.AppOperate `json:"operate" validate:"required"`
|
||||||
ForceDelete bool `json:"forceDelete"`
|
ForceDelete bool `json:"forceDelete"`
|
||||||
DeleteBackup bool `json:"deleteBackup"`
|
DeleteBackup bool `json:"deleteBackup"`
|
||||||
|
DeleteDB bool `json:"deleteDB"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PortUpdate struct {
|
type PortUpdate struct {
|
||||||
|
@ -33,7 +33,6 @@ type IAppService interface {
|
|||||||
GetApp(key string) (*response.AppDTO, error)
|
GetApp(key string) (*response.AppDTO, error)
|
||||||
GetAppDetail(appId uint, version string) (response.AppDetailDTO, error)
|
GetAppDetail(appId uint, version string) (response.AppDetailDTO, error)
|
||||||
Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error)
|
Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error)
|
||||||
//SyncInstalled(installId uint) error
|
|
||||||
SyncAppList() error
|
SyncAppList() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ func (a AppInstallService) Operate(req request.AppInstalledOperate) error {
|
|||||||
install.Status = constant.Running
|
install.Status = constant.Running
|
||||||
case constant.Delete:
|
case constant.Delete:
|
||||||
tx, ctx := getTxAndContext()
|
tx, ctx := getTxAndContext()
|
||||||
if err := deleteAppInstall(ctx, install, req.DeleteBackup, req.ForceDelete); err != nil && !req.ForceDelete {
|
if err := deleteAppInstall(ctx, install, req.DeleteBackup, req.ForceDelete, req.DeleteDB); err != nil && !req.ForceDelete {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -88,18 +89,29 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var createMysql dto.MysqlDBCreate
|
iMysqlRepo := repo.NewIMysqlRepo()
|
||||||
createMysql.Name = dbConfig.DbName
|
oldMysqlDb, _ := iMysqlRepo.Get(commonRepo.WithByName(dbConfig.DbName))
|
||||||
createMysql.Username = dbConfig.DbUser
|
resourceId := oldMysqlDb.ID
|
||||||
createMysql.Format = "utf8mb4"
|
if oldMysqlDb.ID > 0 {
|
||||||
createMysql.Permission = "%"
|
if oldMysqlDb.Username != dbConfig.DbUser || oldMysqlDb.Password != dbConfig.Password {
|
||||||
createMysql.Password = dbConfig.Password
|
return buserr.New(constant.ErrDbUserNotValid)
|
||||||
mysqldb, err := NewIMysqlService().Create(ctx, createMysql)
|
}
|
||||||
if err != nil {
|
} else {
|
||||||
return err
|
var createMysql dto.MysqlDBCreate
|
||||||
|
createMysql.Name = dbConfig.DbName
|
||||||
|
createMysql.Username = dbConfig.DbUser
|
||||||
|
createMysql.Format = "utf8mb4"
|
||||||
|
createMysql.Permission = "%"
|
||||||
|
createMysql.Password = dbConfig.Password
|
||||||
|
mysqldb, err := NewIMysqlService().Create(ctx, createMysql)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resourceId = mysqldb.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
var installResource model.AppInstallResource
|
var installResource model.AppInstallResource
|
||||||
installResource.ResourceId = mysqldb.ID
|
installResource.ResourceId = resourceId
|
||||||
installResource.AppInstallId = appInstall.ID
|
installResource.AppInstallId = appInstall.ID
|
||||||
installResource.LinkId = dbInstall.ID
|
installResource.LinkId = dbInstall.ID
|
||||||
installResource.Key = dbInstall.App.Key
|
installResource.Key = dbInstall.App.Key
|
||||||
@ -110,7 +122,7 @@ func createLink(ctx context.Context, app model.App, appInstall *model.AppInstall
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBackup bool, forceDelete bool) error {
|
func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBackup bool, forceDelete bool, deleteDB bool) error {
|
||||||
op := files.NewFileOp()
|
op := files.NewFileOp()
|
||||||
appDir := install.GetPath()
|
appDir := install.GetPath()
|
||||||
dir, _ := os.Stat(appDir)
|
dir, _ := os.Stat(appDir)
|
||||||
@ -126,7 +138,7 @@ func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBacku
|
|||||||
if err := appInstallRepo.Delete(ctx, install); err != nil && !forceDelete {
|
if err := appInstallRepo.Delete(ctx, install); err != nil && !forceDelete {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := deleteLink(ctx, &install); err != nil && !forceDelete {
|
if err := deleteLink(ctx, &install, deleteDB); err != nil && !forceDelete {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
uploadDir := fmt.Sprintf("%s/1panel/uploads/app/%s/%s", global.CONF.System.BaseDir, install.App.Key, install.Name)
|
uploadDir := fmt.Sprintf("%s/1panel/uploads/app/%s/%s", global.CONF.System.BaseDir, install.App.Key, install.Name)
|
||||||
@ -149,14 +161,14 @@ func deleteAppInstall(ctx context.Context, install model.AppInstall, deleteBacku
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteLink(ctx context.Context, install *model.AppInstall) error {
|
func deleteLink(ctx context.Context, install *model.AppInstall, deleteDB bool) error {
|
||||||
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
|
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||||
if len(resources) == 0 {
|
if len(resources) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, re := range resources {
|
for _, re := range resources {
|
||||||
mysqlService := NewIMysqlService()
|
mysqlService := NewIMysqlService()
|
||||||
if re.Key == "mysql" {
|
if re.Key == "mysql" && deleteDB {
|
||||||
database, _ := mysqlRepo.Get(commonRepo.WithByID(re.ResourceId))
|
database, _ := mysqlRepo.Get(commonRepo.WithByID(re.ResourceId))
|
||||||
if reflect.DeepEqual(database, model.DatabaseMysql{}) {
|
if reflect.DeepEqual(database, model.DatabaseMysql{}) {
|
||||||
continue
|
continue
|
||||||
|
@ -253,7 +253,7 @@ func (w WebsiteService) DeleteWebsite(ctx context.Context, req request.WebsiteDe
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(model.AppInstall{}, appInstall) {
|
if !reflect.DeepEqual(model.AppInstall{}, appInstall) {
|
||||||
if err := deleteAppInstall(ctx, appInstall, true, req.ForceDelete); err != nil && !req.ForceDelete {
|
if err := deleteAppInstall(ctx, appInstall, true, req.ForceDelete, true); err != nil && !req.ForceDelete {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ var (
|
|||||||
ErrFileToLarge = "ErrFileToLarge"
|
ErrFileToLarge = "ErrFileToLarge"
|
||||||
ErrNotInstall = "ErrNotInstall"
|
ErrNotInstall = "ErrNotInstall"
|
||||||
ErrPortInOtherApp = "ErrPortInOtherApp"
|
ErrPortInOtherApp = "ErrPortInOtherApp"
|
||||||
|
ErrDbUserNotValid = "ErrDbUserNotValid"
|
||||||
)
|
)
|
||||||
|
|
||||||
//website
|
//website
|
||||||
|
@ -23,6 +23,7 @@ ErrAppLimit: "App exceeds install limit"
|
|||||||
ErrAppRequired: "{{ .detail }} app is required"
|
ErrAppRequired: "{{ .detail }} app is required"
|
||||||
ErrNotInstall: "App not installed"
|
ErrNotInstall: "App not installed"
|
||||||
ErrPortInOtherApp: "{{ .port }} port already in use by {{ .apps }}"
|
ErrPortInOtherApp: "{{ .port }} port already in use by {{ .apps }}"
|
||||||
|
ErrDbUserNotValid: "Stock database, username and password do not match!"
|
||||||
|
|
||||||
#file
|
#file
|
||||||
ErrFileCanNotRead: "File can not read"
|
ErrFileCanNotRead: "File can not read"
|
||||||
|
@ -23,6 +23,7 @@ ErrAppLimit: "应用超出安装数量限制"
|
|||||||
ErrAppRequired: "请先安装 {{ .detail }} 应用"
|
ErrAppRequired: "请先安装 {{ .detail }} 应用"
|
||||||
ErrNotInstall: "应用未安装"
|
ErrNotInstall: "应用未安装"
|
||||||
ErrPortInOtherApp: "{{ .port }} 端口已被 {{ .apps }}占用!"
|
ErrPortInOtherApp: "{{ .port }} 端口已被 {{ .apps }}占用!"
|
||||||
|
ErrDbUserNotValid: "存量数据库,用户名密码不匹配!"
|
||||||
|
|
||||||
#file
|
#file
|
||||||
ErrFileCanNotRead: "此文件不支持预览"
|
ErrFileCanNotRead: "此文件不支持预览"
|
||||||
|
@ -863,6 +863,7 @@ export default {
|
|||||||
all: 'All',
|
all: 'All',
|
||||||
version: 'Version',
|
version: 'Version',
|
||||||
detail: 'Details',
|
detail: 'Details',
|
||||||
|
params: 'Param',
|
||||||
install: 'Install',
|
install: 'Install',
|
||||||
author: 'Author',
|
author: 'Author',
|
||||||
source: 'Source',
|
source: 'Source',
|
||||||
@ -905,7 +906,9 @@ export default {
|
|||||||
forceDeleteHelper:
|
forceDeleteHelper:
|
||||||
'Forced deletion will ignore errors generated during the deletion process and eventually delete metadata',
|
'Forced deletion will ignore errors generated during the deletion process and eventually delete metadata',
|
||||||
deleteBackup: 'Delete backup',
|
deleteBackup: 'Delete backup',
|
||||||
deleteBackupHelper: 'Delete application backup at the same time',
|
deleteBackupHelper: 'Also delete the application backup',
|
||||||
|
deleteDB: 'Delete Database',
|
||||||
|
deleteDBHelper: 'Also delete the database',
|
||||||
noService: 'No {0}',
|
noService: 'No {0}',
|
||||||
toInstall: 'to install',
|
toInstall: 'to install',
|
||||||
param: 'parameter configuration',
|
param: 'parameter configuration',
|
||||||
|
@ -866,7 +866,8 @@ export default {
|
|||||||
installed: '已安装',
|
installed: '已安装',
|
||||||
all: '全部',
|
all: '全部',
|
||||||
version: '版本',
|
version: '版本',
|
||||||
detail: '参数',
|
detail: '详情',
|
||||||
|
params: '参数',
|
||||||
install: '安装',
|
install: '安装',
|
||||||
author: '作者',
|
author: '作者',
|
||||||
source: '来源',
|
source: '来源',
|
||||||
@ -907,6 +908,8 @@ export default {
|
|||||||
forceDeleteHelper: '强制删除,会忽略删除过程中产生的错误并最终删除元数据',
|
forceDeleteHelper: '强制删除,会忽略删除过程中产生的错误并最终删除元数据',
|
||||||
deleteBackup: '删除备份',
|
deleteBackup: '删除备份',
|
||||||
deleteBackupHelper: '同时删除应用备份',
|
deleteBackupHelper: '同时删除应用备份',
|
||||||
|
deleteDB: '删除数据库',
|
||||||
|
deleteDBHelper: '同时删除与应用关联的数据库',
|
||||||
noService: '无{0}',
|
noService: '无{0}',
|
||||||
toInstall: '去安装',
|
toInstall: '去安装',
|
||||||
param: '参数配置',
|
param: '参数配置',
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="open"
|
v-model="open"
|
||||||
:title="$t('commons.button.delete') + ' - ' + appInstallName"
|
:title="$t('commons.button.delete') + ' - ' + appInstallName"
|
||||||
width="30%"
|
width="40%"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
:before-close="handleClose"
|
:before-close="handleClose"
|
||||||
>
|
>
|
||||||
@ -19,6 +19,12 @@
|
|||||||
{{ $t('app.deleteBackupHelper') }}
|
{{ $t('app.deleteBackupHelper') }}
|
||||||
</span>
|
</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item v-if="appType === 'website'">
|
||||||
|
<el-checkbox v-model="deleteReq.deleteDB" :label="$t('app.deleteDB')" />
|
||||||
|
<span class="input-help">
|
||||||
|
{{ $t('app.deleteDBHelper') }}
|
||||||
|
</span>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<span v-html="deleteHelper"></span>
|
<span v-html="deleteHelper"></span>
|
||||||
<el-input v-model="deleteInfo" :placeholder="appInstallName" />
|
<el-input v-model="deleteInfo" :placeholder="appInstallName" />
|
||||||
@ -50,12 +56,14 @@ let deleteReq = ref({
|
|||||||
installId: 0,
|
installId: 0,
|
||||||
deleteBackup: false,
|
deleteBackup: false,
|
||||||
forceDelete: false,
|
forceDelete: false,
|
||||||
|
deleteDB: true,
|
||||||
});
|
});
|
||||||
let open = ref(false);
|
let open = ref(false);
|
||||||
let loading = ref(false);
|
let loading = ref(false);
|
||||||
let deleteHelper = ref('');
|
let deleteHelper = ref('');
|
||||||
let deleteInfo = ref('');
|
let deleteInfo = ref('');
|
||||||
let appInstallName = ref('');
|
let appInstallName = ref('');
|
||||||
|
let appType = ref('');
|
||||||
|
|
||||||
const deleteForm = ref<FormInstance>();
|
const deleteForm = ref<FormInstance>();
|
||||||
const em = defineEmits(['close']);
|
const em = defineEmits(['close']);
|
||||||
@ -71,9 +79,11 @@ const acceptParams = async (app: App.AppInstalled) => {
|
|||||||
installId: 0,
|
installId: 0,
|
||||||
deleteBackup: false,
|
deleteBackup: false,
|
||||||
forceDelete: false,
|
forceDelete: false,
|
||||||
|
deleteDB: true,
|
||||||
};
|
};
|
||||||
deleteInfo.value = '';
|
deleteInfo.value = '';
|
||||||
deleteReq.value.installId = app.id;
|
deleteReq.value.installId = app.id;
|
||||||
|
appType.value = app.app.type;
|
||||||
deleteHelper.value = i18n.global.t('website.deleteConfirmHelper', [app.name]);
|
deleteHelper.value = i18n.global.t('website.deleteConfirmHelper', [app.name]);
|
||||||
appInstallName.value = app.name;
|
appInstallName.value = app.name;
|
||||||
open.value = true;
|
open.value = true;
|
||||||
|
@ -348,7 +348,7 @@ const buttons = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: i18n.global.t('app.detail'),
|
label: i18n.global.t('app.params'),
|
||||||
click: (row: any) => {
|
click: (row: any) => {
|
||||||
openParam(row.id);
|
openParam(row.id);
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user