feat: edit server config online (#980)

* feat: edit server config online

* clean

* refactor

* generate template

* fix deadlocks

* fix
This commit is contained in:
UUBulb
2025-01-31 13:33:53 +08:00
committed by GitHub
parent 82d40d49fd
commit 7e8985a599
10 changed files with 227 additions and 86 deletions

View File

@@ -110,6 +110,8 @@ func routers(r *gin.Engine, frontendDist fs.FS) {
auth.GET("/server", listHandler(listServer))
auth.PATCH("/server/:id", commonHandler(updateServer))
auth.GET("/server/:id/config", commonHandler(getServerConfig))
auth.POST("/server/:id/config", commonHandler(setServerConfig))
auth.POST("/batch-delete/server", commonHandler(batchDeleteServer))
auth.POST("/force-update/server", commonHandler(forceUpdateServer))

View File

@@ -2,6 +2,7 @@ package controller
import (
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/jinzhu/copier"
@@ -213,3 +214,99 @@ func forceUpdateServer(c *gin.Context) (*model.ForceUpdateResponse, error) {
return forceUpdateResp, nil
}
// Get server config
// @Summary Get server config
// @Security BearerAuth
// @Schemes
// @Description Get server config
// @Tags auth required
// @Produce json
// @Success 200 {object} model.CommonResponse[string]
// @Router /server/{id}/config [get]
func getServerConfig(c *gin.Context) (string, error) {
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 64)
if err != nil {
return "", err
}
singleton.ServerLock.RLock()
s, ok := singleton.ServerList[id]
if !ok || s.TaskStream == nil {
singleton.ServerLock.RUnlock()
return "", nil
}
singleton.ServerLock.RUnlock()
if !s.HasPermission(c) {
return "", singleton.Localizer.ErrorT("permission denied")
}
if err := s.TaskStream.Send(&pb.Task{
Type: model.TaskTypeReportConfig,
}); err != nil {
return "", err
}
timeout := time.NewTimer(time.Second * 10)
select {
case <-timeout.C:
return "", singleton.Localizer.ErrorT("operation timeout")
case data := <-s.ConfigCache:
timeout.Stop()
switch data := data.(type) {
case string:
return data, nil
case error:
return "", singleton.Localizer.ErrorT("get server config failed: %v", data)
}
}
return "", singleton.Localizer.ErrorT("get server config failed")
}
// Set server config
// @Summary Set server config
// @Security BearerAuth
// @Schemes
// @Description Set server config
// @Tags auth required
// @Accept json
// @param request body string true "config"
// @Produce json
// @Success 200 {object} model.CommonResponse[any]
// @Router /server/{id}/config [post]
func setServerConfig(c *gin.Context) (any, error) {
idStr := c.Param("id")
id, err := strconv.ParseUint(idStr, 10, 64)
if err != nil {
return "", err
}
var configRaw string
if err := c.ShouldBindJSON(&configRaw); err != nil {
return nil, err
}
singleton.ServerLock.RLock()
s, ok := singleton.ServerList[id]
if !ok || s.TaskStream == nil {
singleton.ServerLock.RUnlock()
return "", nil
}
singleton.ServerLock.RUnlock()
if !s.HasPermission(c) {
return "", singleton.Localizer.ErrorT("permission denied")
}
if err := s.TaskStream.Send(&pb.Task{
Type: model.TaskTypeApplyConfig,
Data: configRaw,
}); err != nil {
return "", err
}
return nil, nil
}