diff --git a/frpAct.go b/frpAct.go index ccf1e08..7b370f4 100644 --- a/frpAct.go +++ b/frpAct.go @@ -180,14 +180,20 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) { return } - if req.BootAtStart { - if err := createBootService(user.Username, req.InstanceInfo.Name, configPath, runUser); err != nil { + if err := createBootService(user.Username, req.InstanceInfo.Name, configPath, runUser); err != nil { frpcDB.Exec("DELETE FROM frpcInstances WHERE userID = ? AND name = ?", userID, req.InstanceInfo.Name) os.Remove(configPath) postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to create boot service for instance %s: %v", req.InstanceInfo.Name, err)) SendErrorResponse(w, http.StatusInternalServerError, "Failed to create boot service") return } + + if req.BootAtStart { + if err := setBootAtStart(user.Username, req.InstanceInfo.Name); err != nil { + postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to set boot at start for instance %s: %v", req.InstanceInfo.Name, err)) + SendErrorResponse(w, http.StatusInternalServerError, "Failed to set boot at start") + return + } } SendSuccessResponse(w, "Instance created successfully", map[string]interface{}{ @@ -264,12 +270,10 @@ func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) { return } - if instance.BootAtStart { - if err := removeBootService(user.Username, instance.Name); err != nil { - postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to remove boot service for instance %s: %v", instance.Name, err)) - SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove boot service") - return - } + if err := removeBootService(user.Username, instance.Name); err != nil { + postLog.Error(fmt.Sprintf("[DeleteInstanceHandler] Failed to remove boot service for instance %s: %v", instance.Name, err)) + SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove boot service") + return } if _, err := os.Stat(instance.ConfigPath); err == nil { @@ -508,22 +512,22 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance F } if newBootAtStart { - if err := removeBootService(user.Username, instance.Name); err != nil { - postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove boot service: %v", err)) - bootServiceError = fmt.Sprintf("Failed to remove boot service: %v", err) + if err := removeBootAtStart(user.Username, instance.Name); err != nil { + postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove boot at start: %v", err)) + bootServiceError = fmt.Sprintf("Failed to remove boot at start: %v", err) } instance.Name = newName - if err := createBootService(user.Username, newName, newConfigPath, newRunUser); err != nil { - postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to create boot service: %v", err)) + if err := setBootAtStart(user.Username, newName); err != nil { + postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to set boot at start: %v", err)) if bootServiceError != "" { bootServiceError += "; " } - bootServiceError += fmt.Sprintf("Failed to create boot service: %v", err) + bootServiceError += fmt.Sprintf("Failed to set boot at start: %v", err) } } else { - if err := removeBootService(user.Username, instance.Name); err != nil { - postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove boot service: %v", err)) - bootServiceError = fmt.Sprintf("Failed to remove boot service: %v", err) + if err := removeBootAtStart(user.Username, instance.Name); err != nil { + postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove boot at start: %v", err)) + bootServiceError = fmt.Sprintf("Failed to remove boot at start: %v", err) } instance.Name = newName } diff --git a/os.go b/os.go index adaf8de..4bff9de 100644 --- a/os.go +++ b/os.go @@ -249,6 +249,68 @@ func createWindowsBootService(username, instanceName, configPath string) error { return nil } +func setBootAtStart(username, instanceName string) error { + initType := GetInitSystem() + serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName) + + switch initType { + case "windows": + cmd := exec.Command("sc", "config", serviceName, "start=", "auto") + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to set Windows service %s to auto-start: %s, output: %s", serviceName, err, output) + } + return nil + case "systemd": + cmd := exec.Command("systemctl", "enable", serviceName) + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to enable systemd service %s: %s, output: %s", serviceName, err, output) + } + return nil + case "init.d": + cmd := exec.Command("update-rc.d", serviceName, "enable") + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to enable init.d service %s: %s, output: %s", serviceName, err, output) + } + return nil + default: + return fmt.Errorf("unsupported init system: %s", initType) + } +} + +func removeBootAtStart(username, instanceName string) error { + initType := GetInitSystem() + serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName) + + switch initType{ + case "windows": + cmd := exec.Command("sc", "config", serviceName, "start=", "disabled") + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to set Windows service %s to disabled-start: %s, output: %s", serviceName, err, output) + } + return nil + case "systemd": + cmd := exec.Command("systemctl", "disable", serviceName) + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to disable systemd service %s: %s, output: %s", serviceName, err, output) + } + return nil + case "init.d": + cmd := exec.Command("update-rc.d", serviceName, "disable") + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("failed to disable init.d service %s: %s, output: %s", serviceName, err, output) + } + return nil + default: + return fmt.Errorf("unsupported init system: %s", initType) + } +} + func removeBootService(username, instanceName string) error { initType := GetInitSystem()