fix: Add custom timeout support for remote database (#9830)

This commit is contained in:
ssongliu 2025-08-04 13:40:35 +08:00 committed by GitHub
parent 00f103c66a
commit 8542323c0b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 37 additions and 15 deletions

View file

@ -295,6 +295,7 @@ type DatabaseCreate struct {
ClientCert string `json:"clientCert"` ClientCert string `json:"clientCert"`
SkipVerify bool `json:"skipVerify"` SkipVerify bool `json:"skipVerify"`
Timeout uint `json:"timeout"`
Description string `json:"description"` Description string `json:"description"`
} }
@ -313,6 +314,7 @@ type DatabaseUpdate struct {
ClientCert string `json:"clientCert"` ClientCert string `json:"clientCert"`
SkipVerify bool `json:"skipVerify"` SkipVerify bool `json:"skipVerify"`
Timeout uint `json:"timeout"`
Description string `json:"description"` Description string `json:"description"`
} }

View file

@ -119,7 +119,7 @@ func handlePostgresqlBackup(db DatabaseHelper, parentTask *task.Task, targetDir,
} }
itemHandler := func() error { return doPostgresqlgBackup(db, targetDir, fileName) } itemHandler := func() error { return doPostgresqlgBackup(db, targetDir, fileName) }
backupTask.AddSubTask(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeWebsite), func(task *task.Task) error { return itemHandler() }, nil) backupTask.AddSubTask(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeDatabase), func(task *task.Task) error { return itemHandler() }, nil)
if parentTask != nil { if parentTask != nil {
return itemHandler() return itemHandler()
} }
@ -137,7 +137,7 @@ func handlePostgresqlRecover(req dto.CommonRecover, parentTask *task.Task, isRol
} }
itemTask = parentTask itemTask = parentTask
if parentTask == nil { if parentTask == nil {
itemTask, err = task.NewTaskWithOps("Redis", task.TaskRecover, task.TaskScopeDatabase, req.TaskID, dbInfo.ID) itemTask, err = task.NewTaskWithOps(req.Name, task.TaskRecover, task.TaskScopeDatabase, req.TaskID, dbInfo.ID)
if err != nil { if err != nil {
return err return err
} }

View file

@ -6,19 +6,17 @@ import (
"os" "os"
"path" "path"
"github.com/1Panel-dev/1Panel/agent/app/repo"
"github.com/1Panel-dev/1Panel/agent/utils/postgresql"
pgclient "github.com/1Panel-dev/1Panel/agent/utils/postgresql/client"
redisclient "github.com/1Panel-dev/1Panel/agent/utils/redis"
"github.com/1Panel-dev/1Panel/agent/app/dto" "github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/repo"
"github.com/1Panel-dev/1Panel/agent/buserr" "github.com/1Panel-dev/1Panel/agent/buserr"
"github.com/1Panel-dev/1Panel/agent/constant" "github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global" "github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/encrypt" "github.com/1Panel-dev/1Panel/agent/utils/encrypt"
"github.com/1Panel-dev/1Panel/agent/utils/mysql" "github.com/1Panel-dev/1Panel/agent/utils/mysql"
"github.com/1Panel-dev/1Panel/agent/utils/mysql/client" "github.com/1Panel-dev/1Panel/agent/utils/mysql/client"
"github.com/1Panel-dev/1Panel/agent/utils/postgresql"
pgclient "github.com/1Panel-dev/1Panel/agent/utils/postgresql/client"
redisclient "github.com/1Panel-dev/1Panel/agent/utils/redis"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -118,6 +116,9 @@ func (u *DatabaseService) LoadItems(dbType string) ([]dto.DatabaseItem, error) {
} }
func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool { func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
if req.Timeout == 0 {
req.Timeout = 30
}
switch req.Type { switch req.Type {
case constant.AppPostgresql: case constant.AppPostgresql:
_, err := postgresql.NewPostgresqlClient(pgclient.DBInfo{ _, err := postgresql.NewPostgresqlClient(pgclient.DBInfo{
@ -126,7 +127,7 @@ func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
Port: req.Port, Port: req.Port,
Username: req.Username, Username: req.Username,
Password: req.Password, Password: req.Password,
Timeout: 6, Timeout: req.Timeout,
}) })
return err == nil return err == nil
case constant.AppRedis: case constant.AppRedis:
@ -149,7 +150,7 @@ func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
ClientKey: req.ClientKey, ClientKey: req.ClientKey,
ClientCert: req.ClientCert, ClientCert: req.ClientCert,
SkipVerify: req.SkipVerify, SkipVerify: req.SkipVerify,
Timeout: 6, Timeout: req.Timeout,
}) })
return err == nil return err == nil
} }
@ -158,6 +159,9 @@ func (u *DatabaseService) CheckDatabase(req dto.DatabaseCreate) bool {
} }
func (u *DatabaseService) Create(req dto.DatabaseCreate) error { func (u *DatabaseService) Create(req dto.DatabaseCreate) error {
if req.Timeout == 0 {
req.Timeout = 30
}
db, _ := databaseRepo.Get(repo.WithByName(req.Name)) db, _ := databaseRepo.Get(repo.WithByName(req.Name))
if db.ID != 0 { if db.ID != 0 {
if db.From == "local" { if db.From == "local" {
@ -173,7 +177,7 @@ func (u *DatabaseService) Create(req dto.DatabaseCreate) error {
Port: req.Port, Port: req.Port,
Username: req.Username, Username: req.Username,
Password: req.Password, Password: req.Password,
Timeout: 6, Timeout: req.Timeout,
}); err != nil { }); err != nil {
return err return err
} }
@ -198,7 +202,7 @@ func (u *DatabaseService) Create(req dto.DatabaseCreate) error {
ClientKey: req.ClientKey, ClientKey: req.ClientKey,
ClientCert: req.ClientCert, ClientCert: req.ClientCert,
SkipVerify: req.SkipVerify, SkipVerify: req.SkipVerify,
Timeout: 6, Timeout: req.Timeout,
}); err != nil { }); err != nil {
return err return err
} }
@ -273,7 +277,7 @@ func (u *DatabaseService) Update(req dto.DatabaseUpdate) error {
Port: req.Port, Port: req.Port,
Username: req.Username, Username: req.Username,
Password: req.Password, Password: req.Password,
Timeout: 300, Timeout: req.Timeout,
}); err != nil { }); err != nil {
return err return err
} }
@ -298,7 +302,7 @@ func (u *DatabaseService) Update(req dto.DatabaseUpdate) error {
ClientKey: req.ClientKey, ClientKey: req.ClientKey,
ClientCert: req.ClientCert, ClientCert: req.ClientCert,
SkipVerify: req.SkipVerify, SkipVerify: req.SkipVerify,
Timeout: 300, Timeout: req.Timeout,
}); err != nil { }); err != nil {
return err return err
} }

View file

@ -283,6 +283,7 @@ export namespace Database {
clientCert: string; clientCert: string;
skipVerify: boolean; skipVerify: boolean;
timeout: number;
description: string; description: string;
} }
export interface SearchDatabasePage { export interface SearchDatabasePage {
@ -322,6 +323,7 @@ export namespace Database {
clientCert: string; clientCert: string;
skipVerify: boolean; skipVerify: boolean;
timeout: number;
description: string; description: string;
} }
export interface DatabaseUpdate { export interface DatabaseUpdate {
@ -338,6 +340,7 @@ export namespace Database {
clientCert: string; clientCert: string;
skipVerify: boolean; skipVerify: boolean;
timeout: number;
description: string; description: string;
} }
export interface DatabaseDelete { export interface DatabaseDelete {

View file

@ -126,6 +126,7 @@ const onOpenDialog = async (
port: 3306, port: 3306,
username: 'root', username: 'root',
password: '', password: '',
timeout: 30,
description: '', description: '',
}, },
) => { ) => {
@ -133,6 +134,7 @@ const onOpenDialog = async (
title, title,
rowData: { ...rowData }, rowData: { ...rowData },
}; };
params.rowData.timeout = 30;
dialogRef.value!.acceptParams(params); dialogRef.value!.acceptParams(params);
}; };

View file

@ -87,6 +87,16 @@
<el-input type="textarea" @change="isOK = false" clearable v-model="dialogData.rowData!.rootCert" /> <el-input type="textarea" @change="isOK = false" clearable v-model="dialogData.rowData!.rootCert" />
</el-form-item> </el-form-item>
</div> </div>
<el-form-item :label="$t('database.timeout')" prop="timeout">
<el-input-number
class="p-w-200"
:min="1"
:precision="0"
step-strictly
:step="1"
v-model.number="dialogData.rowData!.timeout"
/>
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description"> <el-form-item :label="$t('commons.table.description')" prop="description">
<el-input clearable v-model.trim="dialogData.rowData!.description" /> <el-input clearable v-model.trim="dialogData.rowData!.description" />
</el-form-item> </el-form-item>
@ -111,7 +121,7 @@ import i18n from '@/lang';
import { ElForm } from 'element-plus'; import { ElForm } from 'element-plus';
import { Database } from '@/api/interface/database'; import { Database } from '@/api/interface/database';
import { MsgError, MsgSuccess } from '@/utils/message'; import { MsgError, MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules'; import { checkNumberRange, Rules } from '@/global/form-rules';
import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database'; import { addDatabase, checkDatabase, editDatabase } from '@/api/modules/database';
interface DialogProps { interface DialogProps {
@ -159,6 +169,7 @@ const rules = reactive({
port: [Rules.port], port: [Rules.port],
username: [Rules.requiredInput], username: [Rules.requiredInput],
password: [Rules.requiredInput], password: [Rules.requiredInput],
timeout: [Rules.number, checkNumberRange(1, 600)],
}); });
type FormInstance = InstanceType<typeof ElForm>; type FormInstance = InstanceType<typeof ElForm>;