diff --git a/daemon.go b/daemon.go index 582bd69..c7026f0 100644 --- a/daemon.go +++ b/daemon.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "io" "net/http" "os" "os/signal" @@ -48,6 +49,8 @@ func StartDaemon(cfg *AppConfig, configPath string) error { mux.HandleFunc("/instances/logs", ds.handleGetLogs) mux.HandleFunc("/instances/delete", ds.handleDelete) mux.HandleFunc("/instances/modify", ds.handleModify) + mux.HandleFunc("/instances/getConfig", ds.handleGetConfig) + mux.HandleFunc("/instances/setConfig", ds.handleSetConfig) corsWrappedHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") @@ -549,3 +552,86 @@ func (ds *DaemonServer) handleModify(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Successfully modified instance %s", name) } + +func (ds *DaemonServer) handleGetConfig(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + name := r.URL.Query().Get("name") + if name == "" { + http.Error(w, "Missing name parameter", http.StatusBadRequest) + return + } + + exists := func() bool { + ds.RLock() + defer ds.RUnlock() + _, ok := ds.cfg.Instances[name] + return ok + }() + if !exists { + http.Error(w, fmt.Sprintf("Cannot modify instance config for: '%s'; Does not exist.", name), http.StatusBadRequest) + return + } + + confPath := filepath.Join(ds.cfg.Storage.InstancesDir, name, "serverconfig.json") + data, err := os.ReadFile(confPath) + if err != nil { + http.Error(w, fmt.Sprintf("Failed to get instance config: %v", err), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.Write(data) +} + +func (ds *DaemonServer) handleSetConfig(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + name := r.URL.Query().Get("name") + if name == "" { + http.Error(w, "Missing name parameter", http.StatusBadRequest) + return + } + + exists := func() bool { + ds.RLock() + defer ds.RUnlock() + _, ok := ds.cfg.Instances[name] + return ok + }() + if !exists { + http.Error(w, fmt.Sprintf("Cannot modify instance config for: '%s'; Does not exist.", name), http.StatusBadRequest) + return + } + + running := func() bool { + ds.procManager.RLock() + defer ds.procManager.RUnlock() + _, ok := ds.procManager.ActiveInstances[name] + return ok + }() + if running { + http.Error(w, fmt.Sprintf("Cannot modify instance config for: '%s'; It is currently running.", name), http.StatusBadRequest) + return + } + + data, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, fmt.Sprintf("Failed to set instance config: %v", err), http.StatusInternalServerError) + return + } + + confPath := filepath.Join(ds.cfg.Storage.InstancesDir, name, "serverconfig.json") + if err = os.WriteFile(confPath, data, 0644); err != nil { + http.Error(w, fmt.Sprintf("Failed to get instance config: %v", err), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) +} diff --git a/instance_config.go b/instance_config.go index 126015b..16929b9 100644 --- a/instance_config.go +++ b/instance_config.go @@ -62,7 +62,15 @@ func SyncInstanceConfig(templateVersion string, instanceConfigPath string, meta } for key, value := range meta.Config { - rawConfig[key] = value + if sub, ok := value.(map[string]interface{}); ok { + if existing, ok := rawConfig[key].(map[string]interface{}); ok { + for k, v := range sub { + existing[k] = v + } + } + } else { + rawConfig[key] = value + } } rawConfig["ServerName"] = meta.ServerName