mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-08-25 08:25:07 +03:00
Implement JSON configuration editor in WebUI with save and restart functionality. Enhance configuration handling by converting data to JSON format and adding validation features. Update styles for improved user experience.
This commit is contained in:
parent
4935fcf226
commit
0d0f524071
7 changed files with 650 additions and 352 deletions
|
@ -8,8 +8,10 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
||||
|
@ -384,23 +386,25 @@ func (w *WebUIServer) callAdminHandler(command string, args map[string]interface
|
|||
|
||||
// Configuration response structures
|
||||
type ConfigResponse struct {
|
||||
ConfigPath string `json:"config_path"`
|
||||
ConfigFormat string `json:"config_format"`
|
||||
ConfigData interface{} `json:"config_data"`
|
||||
IsWritable bool `json:"is_writable"`
|
||||
ConfigPath string `json:"config_path"`
|
||||
ConfigFormat string `json:"config_format"`
|
||||
ConfigJSON string `json:"config_json"`
|
||||
IsWritable bool `json:"is_writable"`
|
||||
}
|
||||
|
||||
type ConfigSetRequest struct {
|
||||
ConfigData interface{} `json:"config_data"`
|
||||
ConfigPath string `json:"config_path,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
ConfigJSON string `json:"config_json"`
|
||||
ConfigPath string `json:"config_path,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Restart bool `json:"restart,omitempty"`
|
||||
}
|
||||
|
||||
type ConfigSetResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
ConfigPath string `json:"config_path"`
|
||||
BackupPath string `json:"backup_path,omitempty"`
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
ConfigPath string `json:"config_path"`
|
||||
BackupPath string `json:"backup_path,omitempty"`
|
||||
RestartRequired bool `json:"restart_required"`
|
||||
}
|
||||
|
||||
// getConfigHandler handles configuration file reading
|
||||
|
@ -418,10 +422,18 @@ func (w *WebUIServer) getConfigHandler(rw http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
// Convert config data to formatted JSON string
|
||||
configBytes, err := json.MarshalIndent(configInfo.Data, "", " ")
|
||||
if err != nil {
|
||||
w.log.Errorf("Failed to marshal config to JSON: %v", err)
|
||||
http.Error(rw, "Failed to format configuration", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response := ConfigResponse{
|
||||
ConfigPath: configInfo.Path,
|
||||
ConfigFormat: configInfo.Format,
|
||||
ConfigData: configInfo.Data,
|
||||
ConfigJSON: string(configBytes),
|
||||
IsWritable: configInfo.Writable,
|
||||
}
|
||||
|
||||
|
@ -445,8 +457,19 @@ func (w *WebUIServer) setConfigHandler(rw http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
|
||||
// Parse JSON configuration
|
||||
var configData interface{}
|
||||
if err := json.Unmarshal([]byte(req.ConfigJSON), &configData); err != nil {
|
||||
response := ConfigSetResponse{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("Invalid JSON configuration: %v", err),
|
||||
}
|
||||
w.writeJSONResponse(rw, response)
|
||||
return
|
||||
}
|
||||
|
||||
// Use config package to save configuration
|
||||
err := config.SaveConfig(req.ConfigData, req.ConfigPath, req.Format)
|
||||
err := config.SaveConfig(configData, req.ConfigPath, req.Format)
|
||||
if err != nil {
|
||||
response := ConfigSetResponse{
|
||||
Success: false,
|
||||
|
@ -464,11 +487,19 @@ func (w *WebUIServer) setConfigHandler(rw http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
|
||||
response := ConfigSetResponse{
|
||||
Success: true,
|
||||
Message: "Configuration saved successfully",
|
||||
ConfigPath: configPath,
|
||||
BackupPath: configPath + ".backup",
|
||||
Success: true,
|
||||
Message: "Configuration saved successfully",
|
||||
ConfigPath: configPath,
|
||||
BackupPath: configPath + ".backup",
|
||||
RestartRequired: req.Restart,
|
||||
}
|
||||
|
||||
// If restart is requested, trigger server restart
|
||||
if req.Restart {
|
||||
w.log.Infof("Configuration saved with restart request")
|
||||
go w.restartServer()
|
||||
}
|
||||
|
||||
w.writeJSONResponse(rw, response)
|
||||
}
|
||||
|
||||
|
@ -556,3 +587,23 @@ func (w *WebUIServer) Stop() error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// restartServer triggers a graceful restart of the Yggdrasil process
|
||||
func (w *WebUIServer) restartServer() {
|
||||
w.log.Infof("Initiating server restart after configuration change")
|
||||
|
||||
// Give some time for the response to be sent
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// Send SIGUSR1 signal to trigger a graceful restart
|
||||
// This assumes the main process handles SIGUSR1 for restart
|
||||
proc, err := os.FindProcess(os.Getpid())
|
||||
if err != nil {
|
||||
w.log.Errorf("Failed to find current process: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := proc.Signal(syscall.SIGUSR1); err != nil {
|
||||
w.log.Errorf("Failed to send restart signal: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue