feat(service): add auto-start management for services
Implement setBootAtStart and removeBootAtStart functions to handle service auto-start configuration separately from service creation/removal. Update handlers to use these new functions for better control of boot behavior. The changes support Windows, systemd and init.d systems.
This commit is contained in:
@@ -180,7 +180,6 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
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)
|
frpcDB.Exec("DELETE FROM frpcInstances WHERE userID = ? AND name = ?", userID, req.InstanceInfo.Name)
|
||||||
os.Remove(configPath)
|
os.Remove(configPath)
|
||||||
@@ -188,6 +187,13 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to create boot service")
|
SendErrorResponse(w, http.StatusInternalServerError, "Failed to create boot service")
|
||||||
return
|
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{}{
|
SendSuccessResponse(w, "Instance created successfully", map[string]interface{}{
|
||||||
@@ -264,13 +270,11 @@ func DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if instance.BootAtStart {
|
|
||||||
if err := removeBootService(user.Username, instance.Name); err != nil {
|
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))
|
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")
|
SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove boot service")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stat(instance.ConfigPath); err == nil {
|
if _, err := os.Stat(instance.ConfigPath); err == nil {
|
||||||
if err := os.Remove(instance.ConfigPath); err != nil {
|
if err := os.Remove(instance.ConfigPath); err != nil {
|
||||||
@@ -508,22 +512,22 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance F
|
|||||||
}
|
}
|
||||||
|
|
||||||
if newBootAtStart {
|
if newBootAtStart {
|
||||||
if err := removeBootService(user.Username, instance.Name); err != nil {
|
if err := removeBootAtStart(user.Username, instance.Name); err != nil {
|
||||||
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove boot service: %v", err))
|
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove boot at start: %v", err))
|
||||||
bootServiceError = fmt.Sprintf("Failed to remove boot service: %v", err)
|
bootServiceError = fmt.Sprintf("Failed to remove boot at start: %v", err)
|
||||||
}
|
}
|
||||||
instance.Name = newName
|
instance.Name = newName
|
||||||
if err := createBootService(user.Username, newName, newConfigPath, newRunUser); err != nil {
|
if err := setBootAtStart(user.Username, newName); err != nil {
|
||||||
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to create boot service: %v", err))
|
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to set boot at start: %v", err))
|
||||||
if bootServiceError != "" {
|
if bootServiceError != "" {
|
||||||
bootServiceError += "; "
|
bootServiceError += "; "
|
||||||
}
|
}
|
||||||
bootServiceError += fmt.Sprintf("Failed to create boot service: %v", err)
|
bootServiceError += fmt.Sprintf("Failed to set boot at start: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := removeBootService(user.Username, instance.Name); err != nil {
|
if err := removeBootAtStart(user.Username, instance.Name); err != nil {
|
||||||
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove boot service: %v", err))
|
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove boot at start: %v", err))
|
||||||
bootServiceError = fmt.Sprintf("Failed to remove boot service: %v", err)
|
bootServiceError = fmt.Sprintf("Failed to remove boot at start: %v", err)
|
||||||
}
|
}
|
||||||
instance.Name = newName
|
instance.Name = newName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,6 +249,68 @@ func createWindowsBootService(username, instanceName, configPath string) error {
|
|||||||
return nil
|
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 {
|
func removeBootService(username, instanceName string) error {
|
||||||
initType := GetInitSystem()
|
initType := GetInitSystem()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user