mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-06 13:27:43 +08:00
feat: Add installation support for Redis Cluster (#9561)
This commit is contained in:
parent
5d4ab23d95
commit
a74c6dd522
20 changed files with 60 additions and 19 deletions
|
@ -11,13 +11,13 @@ import (
|
|||
// @Tags Database Redis
|
||||
// @Summary Load redis status info
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithName true "request"
|
||||
// @Param request body dto.LoadRedisStatus true "request"
|
||||
// @Success 200 {object} dto.RedisStatus
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /databases/redis/status [post]
|
||||
func (b *BaseApi) LoadRedisStatus(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
var req dto.LoadRedisStatus
|
||||
if err := helper.CheckBind(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -89,8 +89,8 @@ func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
|
|||
var containerID string
|
||||
var initCmd []string
|
||||
switch source {
|
||||
case "redis":
|
||||
containerID, initCmd, err = loadRedisInitCmd(c)
|
||||
case "redis", "redis-cluster":
|
||||
containerID, initCmd, err = loadRedisInitCmd(c, source)
|
||||
case "ollama":
|
||||
containerID, initCmd, err = loadOllamaInitCmd(c)
|
||||
case "container":
|
||||
|
@ -127,7 +127,7 @@ func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
|
|||
_ = wsConn.WriteControl(websocket.CloseMessage, nil, dt)
|
||||
}
|
||||
|
||||
func loadRedisInitCmd(c *gin.Context) (string, []string, error) {
|
||||
func loadRedisInitCmd(c *gin.Context, redisType string) (string, []string, error) {
|
||||
name := c.Query("name")
|
||||
from := c.Query("from")
|
||||
commands := []string{"exec", "-it"}
|
||||
|
@ -136,7 +136,7 @@ func loadRedisInitCmd(c *gin.Context) (string, []string, error) {
|
|||
return "", nil, fmt.Errorf("no such database in db, err: %v", err)
|
||||
}
|
||||
if from == "local" {
|
||||
redisInfo, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Name: name, Type: "redis"})
|
||||
redisInfo, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Name: name, Type: redisType})
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("no such app in db, err: %v", err)
|
||||
}
|
||||
|
|
|
@ -319,3 +319,8 @@ type DatabaseDelete struct {
|
|||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
}
|
||||
|
||||
type LoadRedisStatus struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
}
|
||||
|
|
|
@ -482,6 +482,8 @@ func (a *AppInstallService) GetServices(key string) ([]response.AppService, erro
|
|||
types = []string{constant.AppMysql, constant.AppMysqlCluster}
|
||||
case constant.AppPostgresql:
|
||||
types = []string{constant.AppPostgresql, constant.AppPostgresqlCluster}
|
||||
case constant.AppRedis:
|
||||
types = []string{constant.AppRedis, constant.AppRedisCluster}
|
||||
}
|
||||
|
||||
dbs, _ := databaseRepo.GetList(repo.WithTypes(types))
|
||||
|
|
|
@ -125,6 +125,7 @@ var DatabaseKeys = map[string]uint{
|
|||
constant.AppMemcached: 11211,
|
||||
constant.AppMysqlCluster: 3306,
|
||||
constant.AppPostgresqlCluster: 5432,
|
||||
constant.AppRedisCluster: 6379,
|
||||
}
|
||||
|
||||
var ToolKeys = map[string]uint{
|
||||
|
|
|
@ -54,6 +54,8 @@ func (u *DBCommonService) LoadDatabaseFile(req dto.OperationWithNameAndType) (st
|
|||
filePath = path.Join(global.Dir.DataDir, fmt.Sprintf("apps/postgresql/%s/data/postgresql.conf", req.Name))
|
||||
case "redis-conf":
|
||||
filePath = path.Join(global.Dir.DataDir, fmt.Sprintf("apps/redis/%s/conf/redis.conf", req.Name))
|
||||
case "redis-cluster-conf":
|
||||
filePath = path.Join(global.Dir.DataDir, fmt.Sprintf("apps/redis-cluster/%s/conf/redis.conf", req.Name))
|
||||
}
|
||||
if _, err := os.Stat(filePath); err != nil {
|
||||
return "", buserr.New("ErrHttpReqNotFound")
|
||||
|
|
|
@ -28,7 +28,7 @@ type IRedisService interface {
|
|||
UpdatePersistenceConf(req dto.RedisConfPersistenceUpdate) error
|
||||
ChangePassword(info dto.ChangeRedisPass) error
|
||||
|
||||
LoadStatus(req dto.OperationWithName) (*dto.RedisStatus, error)
|
||||
LoadStatus(req dto.LoadRedisStatus) (*dto.RedisStatus, error)
|
||||
LoadConf(req dto.OperationWithName) (*dto.RedisConf, error)
|
||||
LoadPersistenceConf(req dto.OperationWithName) (*dto.RedisPersistence, error)
|
||||
|
||||
|
@ -129,8 +129,8 @@ func (u *RedisService) UpdatePersistenceConf(req dto.RedisConfPersistenceUpdate)
|
|||
return nil
|
||||
}
|
||||
|
||||
func (u *RedisService) LoadStatus(req dto.OperationWithName) (*dto.RedisStatus, error) {
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfo("redis", req.Name)
|
||||
func (u *RedisService) LoadStatus(req dto.LoadRedisStatus) (*dto.RedisStatus, error) {
|
||||
redisInfo, err := appInstallRepo.LoadBaseInfo(req.Type, req.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -108,8 +108,8 @@ export const loadRemoteAccess = (type: string, database: string) => {
|
|||
};
|
||||
|
||||
// redis
|
||||
export const loadRedisStatus = (database: string) => {
|
||||
return http.post<Database.RedisStatus>(`/databases/redis/status`, { name: database });
|
||||
export const loadRedisStatus = (type: string, database: string) => {
|
||||
return http.post<Database.RedisStatus>(`/databases/redis/status`, { type: type, name: database });
|
||||
};
|
||||
export const loadRedisConf = (database: string) => {
|
||||
return http.post<Database.RedisConf>(`/databases/redis/conf`, { name: database });
|
||||
|
|
|
@ -3657,6 +3657,8 @@ const message = {
|
|||
master: 'Master Node',
|
||||
slave: 'Slave Node',
|
||||
replicaStatus: 'Master-Slave Status',
|
||||
unhealthyDeleteError: 'The installation node status is abnormal, please check the node list and try again!',
|
||||
replicaStatusError: 'Status acquisition is abnormal, please check the master node.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3520,6 +3520,9 @@ const message = {
|
|||
master: 'マスターノード',
|
||||
slave: 'スレーブノード',
|
||||
replicaStatus: 'マスタースレーブステータス',
|
||||
unhealthyDeleteError:
|
||||
'インストールノードのステータスが異常です。ノードリストを確認してから再試行してください!',
|
||||
replicaStatusError: 'ステータスの取得が異常です。マスターノードを確認してください。',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3458,6 +3458,8 @@ const message = {
|
|||
master: '마스터 노드',
|
||||
slave: '슬레이브 노드',
|
||||
replicaStatus: '마스터-슬레이브 상태',
|
||||
unhealthyDeleteError: '설치 노드 상태가 비정상입니다. 노드 목록을 확인한 후 다시 시도하세요!',
|
||||
replicaStatusError: '상태 획득이 비정상입니다. 마스터 노드를 확인하세요.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3601,6 +3601,8 @@ const message = {
|
|||
master: 'Node Utama',
|
||||
slave: 'Node Hamba',
|
||||
replicaStatus: 'Utama-Hamba Status',
|
||||
unhealthyDeleteError: 'Status nod pemasangan tidak normal, sila periksa senarai nod dan cuba lagi!',
|
||||
replicaStatusError: 'Pengambilan status tidak normal, sila periksa nod utama.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3608,6 +3608,9 @@ const message = {
|
|||
master: 'Nó Mestre',
|
||||
slave: 'Nó Escravo',
|
||||
replicaStatus: 'Status Mestre-Escravo',
|
||||
unhealthyDeleteError:
|
||||
'O status do nó de instalação está anormal, verifique a lista de nós e tente novamente!',
|
||||
replicaStatusError: 'A aquisição do status está anormal, verifique o nó mestre.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3599,6 +3599,9 @@ const message = {
|
|||
master: 'Главный узел',
|
||||
slave: 'Подчиненный узел',
|
||||
replicaStatus: 'Состояние мастер-слейв',
|
||||
unhealthyDeleteError:
|
||||
'Состояние узла установки аномально, пожалуйста, проверьте список узлов и повторите попытку!',
|
||||
replicaStatusError: 'Получение статуса аномально, пожалуйста, проверьте главный узел.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3697,6 +3697,9 @@ const message = {
|
|||
master: 'Главный узел',
|
||||
slave: 'Подчиненный узел',
|
||||
replicaStatus: 'Ana-Çalışan Durumu',
|
||||
unhealthyDeleteError:
|
||||
'Yükleme düğümü durumu anormal, lütfen düğüm listesini kontrol edin ve tekrar deneyin!',
|
||||
replicaStatusError: 'Durum alımı anormal, lütfen ana düğümü kontrol edin.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3402,6 +3402,8 @@ const message = {
|
|||
master: '主節點',
|
||||
slave: '從節點',
|
||||
replicaStatus: '主從狀態',
|
||||
unhealthyDeleteError: '安裝節點狀態異常,請在節點列表檢查後重試!',
|
||||
replicaStatusError: '狀態獲取異常,請檢查主節點。',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3382,6 +3382,8 @@ const message = {
|
|||
master: '主节点',
|
||||
slave: '从节点',
|
||||
replicaStatus: '主从状态',
|
||||
unhealthyDeleteError: '安装节点状态异常,请在节点列表检查后重试!',
|
||||
replicaStatusError: '状态获取异常 请检查主节点',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -188,7 +188,7 @@ const onSetting = async () => {
|
|||
isOnSetting.value = true;
|
||||
terminalRef.value?.onClose(false);
|
||||
terminalShow.value = false;
|
||||
settingRef.value!.acceptParams({ status: redisStatus.value, database: currentDBName.value });
|
||||
settingRef.value!.acceptParams({ status: redisStatus.value, database: currentDBName.value, type: appKey.value });
|
||||
};
|
||||
|
||||
const loadHeight = () => {
|
||||
|
@ -244,7 +244,7 @@ const changeDatabase = async () => {
|
|||
|
||||
const loadDBOptions = async () => {
|
||||
try {
|
||||
const res = await listDatabases('redis');
|
||||
const res = await listDatabases('redis,redis-cluster');
|
||||
let datas = res.data || [];
|
||||
dbOptionsLocal.value = [];
|
||||
dbOptionsRemote.value = [];
|
||||
|
@ -318,8 +318,10 @@ const initTerminal = async () => {
|
|||
isRefresh.value = !isRefresh.value;
|
||||
return;
|
||||
}
|
||||
await checkAppInstalled('redis', currentDBName.value)
|
||||
console.log(currentDBName.value);
|
||||
await checkAppInstalled(currentDB.value.type, currentDBName.value)
|
||||
.then((res) => {
|
||||
console.log(res.data);
|
||||
redisIsExist.value = res.data.isExist;
|
||||
redisStatus.value = res.data.status;
|
||||
loading.value = false;
|
||||
|
@ -328,7 +330,7 @@ const initTerminal = async () => {
|
|||
terminalShow.value = true;
|
||||
terminalRef.value.acceptParams({
|
||||
endpoint: '/api/v2/containers/exec',
|
||||
args: `source=redis&name=${currentDBName.value}&from=${currentDB.value.from}`,
|
||||
args: `source=${currentDB.value.type}&name=${currentDBName.value}&from=${currentDB.value.from}`,
|
||||
error: '',
|
||||
initCmd: '',
|
||||
});
|
||||
|
|
|
@ -153,6 +153,7 @@ const useOld = ref(false);
|
|||
|
||||
const redisStatus = ref();
|
||||
const database = ref();
|
||||
const dbType = ref('redis');
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const redisConf = ref();
|
||||
|
@ -163,6 +164,7 @@ const settingShow = ref<boolean>(false);
|
|||
interface DialogProps {
|
||||
database: string;
|
||||
status: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
const changeTab = (val: string) => {
|
||||
|
@ -179,7 +181,7 @@ const changeTab = (val: string) => {
|
|||
loadForm();
|
||||
break;
|
||||
case 'status':
|
||||
statusRef.value!.acceptParams({ status: redisStatus.value, database: database.value });
|
||||
statusRef.value!.acceptParams({ status: redisStatus.value, database: database.value, type: dbType.value });
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -191,6 +193,7 @@ const changeLoading = (status: boolean) => {
|
|||
const acceptParams = (prop: DialogProps): void => {
|
||||
redisStatus.value = prop.status;
|
||||
database.value = prop.database;
|
||||
dbType.value = prop.type;
|
||||
settingShow.value = true;
|
||||
changeTab('status');
|
||||
};
|
||||
|
@ -274,7 +277,7 @@ const submitForm = async () => {
|
|||
|
||||
const getDefaultConfig = async () => {
|
||||
loading.value = true;
|
||||
await getAppDefaultConfig('redis', '')
|
||||
await getAppDefaultConfig(dbType.value, '')
|
||||
.then((res) => {
|
||||
redisConf.value = res.data;
|
||||
useOld.value = true;
|
||||
|
@ -323,7 +326,7 @@ const loadForm = async () => {
|
|||
const loadConfFile = async () => {
|
||||
useOld.value = false;
|
||||
loading.value = true;
|
||||
await loadDBFile('redis-conf', database.value)
|
||||
await loadDBFile(dbType.value + '-conf', database.value)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
redisConf.value = res.data;
|
||||
|
|
|
@ -163,21 +163,25 @@ const redisStatus = reactive({
|
|||
|
||||
const database = ref();
|
||||
const statusShow = ref(false);
|
||||
const dbType = ref('redis');
|
||||
|
||||
interface DialogProps {
|
||||
database: string;
|
||||
status: string;
|
||||
type: string;
|
||||
}
|
||||
const acceptParams = (prop: DialogProps): void => {
|
||||
statusShow.value = true;
|
||||
database.value = prop.database;
|
||||
dbType.value = prop.type;
|
||||
if (prop.status === 'Running') {
|
||||
loadStatus();
|
||||
}
|
||||
};
|
||||
|
||||
const loadStatus = async () => {
|
||||
const res = await loadRedisStatus(database.value);
|
||||
console.log('loadStatus', database.value);
|
||||
const res = await loadRedisStatus(dbType.value, database.value);
|
||||
let hit = (
|
||||
(Number(res.data.keyspace_hits) / (Number(res.data.keyspace_hits) + Number(res.data.keyspace_misses))) *
|
||||
100
|
||||
|
|
Loading…
Add table
Reference in a new issue