feat(frpAct): add Windows/Systemd/Init.d service boot control. BUT WINDOWS STILL HAS BUGS AND LINUX HAS NOT BEEN TESTED.
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"super-frpc/postLog"
|
||||
"time"
|
||||
@@ -307,15 +308,15 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
instanceName := getStringFromMap(reqMap, "instanceName")
|
||||
if instanceName == "" {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "instanceName is required")
|
||||
instanceIDStr := getStringFromMap(reqMap, "instanceID")
|
||||
if instanceIDStr == "" {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceID := getStringFromMap(reqMap, "instanceID")
|
||||
if instanceID == "" {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
||||
instanceID, err := strconv.Atoi(instanceIDStr)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -349,16 +350,9 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := GetUserByID(userID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
instance, err := DBQueryFrpcInstance(userID, instanceName)
|
||||
instance, err := DBQueryFrpcInstanceByID(instanceID)
|
||||
if err == sql.ErrNoRows {
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] User %d tried to modify a not existed instance: %s", userID, instanceName))
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] User %d tried to modify a not existed instance: %d", userID, instanceID))
|
||||
SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
||||
return
|
||||
}
|
||||
@@ -368,8 +362,16 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if fmt.Sprintf("%d", instance.ID) != instanceID {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "instanceID does not match instanceName")
|
||||
if instance.UserID != userID {
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] User %d does not have permission to modify instance %d", userID, instanceID))
|
||||
SendErrorResponse(w, http.StatusForbidden, "Permission denied")
|
||||
return
|
||||
}
|
||||
|
||||
user, err := GetUserByID(instance.UserID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -449,7 +451,6 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance F
|
||||
newName := instance.Name
|
||||
newRunUser := instance.RunUser
|
||||
newBootAtStart := instance.BootAtStart
|
||||
oldBootAtStart := instance.BootAtStart
|
||||
var bootServiceError string
|
||||
|
||||
if v, ok := modifiedData["name"].(string); ok && v != "" {
|
||||
@@ -489,10 +490,10 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance F
|
||||
newConfigPath = oldConfigPath
|
||||
}
|
||||
|
||||
instance.Name = newName
|
||||
instance.RunUser = newRunUser
|
||||
instance.BootAtStart = newBootAtStart
|
||||
instance.ConfigPath = newConfigPath
|
||||
// Update instance new name will be processed in boot service creation or removal
|
||||
|
||||
if err := DBUpdateFrpcInstance(instance); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to update instance in database: %v", err))
|
||||
@@ -500,29 +501,27 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance F
|
||||
return
|
||||
}
|
||||
|
||||
if oldBootAtStart && !newBootAtStart {
|
||||
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)
|
||||
}
|
||||
} else if !oldBootAtStart && newBootAtStart {
|
||||
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))
|
||||
bootServiceError = fmt.Sprintf("Failed to create boot service: %v", err)
|
||||
}
|
||||
} else if oldBootAtStart && newBootAtStart && (instance.Name != newName || instance.RunUser != newRunUser) {
|
||||
if err := removeBootService(user.Username, instance.Name); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to remove old boot service: %v", err))
|
||||
bootServiceError = fmt.Sprintf("Failed to remove old boot service: %v", err)
|
||||
}
|
||||
if err := createBootService(user.Username, newName, newConfigPath, newRunUser); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to create new boot service: %v", err))
|
||||
if bootServiceError != "" {
|
||||
bootServiceError += "; "
|
||||
}
|
||||
bootServiceError += fmt.Sprintf("Failed to create new boot service: %v", err)
|
||||
bootServiceError += fmt.Sprintf("Failed to create boot service: %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)
|
||||
}
|
||||
instance.Name = newName
|
||||
}
|
||||
instance.Name = newName
|
||||
|
||||
data := map[string]interface{}{
|
||||
"instanceName": newName,
|
||||
@@ -644,3 +643,421 @@ func ListInstancesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
SendSuccessResponse(w, "Instances retrieved successfully", instanceList)
|
||||
postLog.Info(fmt.Sprintf("[ListInstancesHandler] Retrieved %d instances for user %d (type: %s)", len(instances), userID, userType))
|
||||
}
|
||||
|
||||
func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
|
||||
postLog.Debug(fmt.Sprintf("[StartInstanceHandler] Invalid request method: %s", r.Method))
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to read request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
var reqMap map[string]interface{}
|
||||
if err := json.Unmarshal(body, &reqMap); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to unmarshal request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
||||
return
|
||||
}
|
||||
|
||||
instanceIDStr := getStringFromMap(reqMap, "instanceID")
|
||||
if instanceIDStr == "" {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceID, err := strconv.Atoi(instanceIDStr)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
|
||||
return
|
||||
}
|
||||
|
||||
userID, _, err := ValidateRequestWithHeader(w, r)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to validate request header: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request header")
|
||||
return
|
||||
}
|
||||
|
||||
userType, err := GetUserType(userID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to get user type: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user type")
|
||||
return
|
||||
}
|
||||
if userType != "admin" && userType != "superuser" {
|
||||
SendErrorResponse(w, http.StatusForbidden, "Permission Denied")
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Permission Denied for user %d (type: %s)", userID, userType))
|
||||
return
|
||||
}
|
||||
|
||||
instance, err := DBQueryFrpcInstanceByID(instanceID)
|
||||
if err == sql.ErrNoRows {
|
||||
SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] User %d tried to start a not existed instance: %d", userID, instanceID))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to query instance: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
||||
return
|
||||
}
|
||||
|
||||
if instance.UserID != userID {
|
||||
SendErrorResponse(w, http.StatusForbidden, "Instance not found")
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] User %d tried to start instance %d that does not belong to them", userID, instanceID))
|
||||
return
|
||||
}
|
||||
|
||||
user, err := GetUserByID(instance.UserID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
initType := GetInitSystem()
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", user.Username, instance.Name)
|
||||
|
||||
switch initType {
|
||||
case "windows":
|
||||
if err := StartWindowsService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to start Windows service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start Windows service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[StartInstanceHandler] Windows service %s started successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance started successfully", nil)
|
||||
|
||||
case "systemd":
|
||||
if err := StartSystemdService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to start systemd service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start systemd service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[StartInstanceHandler] Systemd service %s started successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance started successfully", nil)
|
||||
|
||||
case "init.d":
|
||||
if err := StartInitDService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Failed to start init.d service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to start init.d service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[StartInstanceHandler] Init.d service %s started successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance started successfully", nil)
|
||||
|
||||
default:
|
||||
postLog.Error(fmt.Sprintf("[StartInstanceHandler] Unsupported init system: %s", initType))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
|
||||
postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Invalid request method: %s", r.Method))
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to read request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
var reqMap map[string]interface{}
|
||||
if err := json.Unmarshal(body, &reqMap); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to unmarshal request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
||||
return
|
||||
}
|
||||
|
||||
instanceIDStr := getStringFromMap(reqMap, "instanceID")
|
||||
if instanceIDStr == "" {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceID, err := strconv.Atoi(instanceIDStr)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
|
||||
return
|
||||
}
|
||||
|
||||
userID, _, err := ValidateRequestWithHeader(w, r)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to validate request header: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request header")
|
||||
return
|
||||
}
|
||||
|
||||
userType, err := GetUserType(userID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to get user type: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user type")
|
||||
return
|
||||
}
|
||||
if userType != "admin" && userType != "superuser" {
|
||||
SendErrorResponse(w, http.StatusForbidden, "Permission Denied")
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Permission Denied for user %d (type: %s)", userID, userType))
|
||||
return
|
||||
}
|
||||
|
||||
instance, err := DBQueryFrpcInstanceByID(instanceID)
|
||||
if err == sql.ErrNoRows {
|
||||
SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] User %d tried to stop a not existed instance: %d", userID, instanceID))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to query instance: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
||||
return
|
||||
}
|
||||
|
||||
if instance.UserID != userID {
|
||||
SendErrorResponse(w, http.StatusForbidden, "Instance not found")
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] User %d tried to stop instance %d that does not belong to them", userID, instanceID))
|
||||
return
|
||||
}
|
||||
|
||||
user, err := GetUserByID(instance.UserID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
initType := GetInitSystem()
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", user.Username, instance.Name)
|
||||
|
||||
switch initType {
|
||||
case "windows":
|
||||
if err := StopWindowsService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop Windows service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop Windows service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Windows service %s stopped successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance stopped successfully", nil)
|
||||
|
||||
case "systemd":
|
||||
if err := StopSystemdService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop systemd service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop systemd service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Systemd service %s stopped successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance stopped successfully", nil)
|
||||
|
||||
case "init.d":
|
||||
if err := StopInitDService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop init.d service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop init.d service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Init.d service %s stopped successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance stopped successfully", nil)
|
||||
|
||||
default:
|
||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Unsupported init system: %s", initType))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
|
||||
postLog.Debug(fmt.Sprintf("[RestartInstanceHandler] Invalid request method: %s", r.Method))
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to read request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
var reqMap map[string]interface{}
|
||||
if err := json.Unmarshal(body, &reqMap); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to unmarshal request body: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
||||
return
|
||||
}
|
||||
|
||||
instanceIDStr := getStringFromMap(reqMap, "instanceID")
|
||||
if instanceIDStr == "" {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceID, err := strconv.Atoi(instanceIDStr)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
|
||||
return
|
||||
}
|
||||
|
||||
userID, _, err := ValidateRequestWithHeader(w, r)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to validate request header: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request header")
|
||||
return
|
||||
}
|
||||
|
||||
userType, err := GetUserType(userID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to get user type: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user type")
|
||||
return
|
||||
}
|
||||
if userType != "admin" && userType != "superuser" {
|
||||
SendErrorResponse(w, http.StatusForbidden, "Permission Denied")
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Permission Denied for user %d (type: %s)", userID, userType))
|
||||
return
|
||||
}
|
||||
|
||||
instance, err := DBQueryFrpcInstanceByID(instanceID)
|
||||
if err == sql.ErrNoRows {
|
||||
SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] User %d tried to restart a not existed instance: %d", userID, instanceID))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to query instance: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
||||
return
|
||||
}
|
||||
|
||||
if instance.UserID != userID {
|
||||
SendErrorResponse(w, http.StatusForbidden, "Instance not found")
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] User %d tried to restart instance %d that does not belong to them", userID, instanceID))
|
||||
return
|
||||
}
|
||||
|
||||
user, err := GetUserByID(instance.UserID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
initType := GetInitSystem()
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", user.Username, instance.Name)
|
||||
|
||||
switch initType {
|
||||
case "windows":
|
||||
if err := RestartWindowsService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to restart Windows service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart Windows service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[RestartInstanceHandler] Windows service %s restarted successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance restarted successfully", nil)
|
||||
|
||||
case "systemd":
|
||||
if err := RestartSystemdService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to restart systemd service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart systemd service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[RestartInstanceHandler] Systemd service %s restarted successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance restarted successfully", nil)
|
||||
|
||||
case "init.d":
|
||||
if err := RestartInitDService(serviceName); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Failed to restart init.d service %s: %v", serviceName, err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to restart init.d service: %v", err))
|
||||
return
|
||||
}
|
||||
postLog.Info(fmt.Sprintf("[RestartInstanceHandler] Init.d service %s restarted successfully", serviceName))
|
||||
SendSuccessResponse(w, "Instance restarted successfully", nil)
|
||||
|
||||
default:
|
||||
postLog.Error(fmt.Sprintf("[RestartInstanceHandler] Unsupported init system: %s", initType))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func GetInstanceStatusHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
|
||||
postLog.Debug(fmt.Sprintf("[GetInstanceStatusHandler] Invalid request method: %s", r.Method))
|
||||
return
|
||||
}
|
||||
|
||||
queryParams := r.URL.Query()
|
||||
instanceIDStr := queryParams.Get("instanceID")
|
||||
if instanceIDStr == "" {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
||||
return
|
||||
}
|
||||
|
||||
instanceID, err := strconv.Atoi(instanceIDStr)
|
||||
if err != nil {
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid instanceID format")
|
||||
return
|
||||
}
|
||||
|
||||
userID, _, err := ValidateRequestWithHeader(w, r)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetInstanceStatusHandler] Failed to validate request header: %v", err))
|
||||
SendErrorResponse(w, http.StatusBadRequest, "Invalid request header")
|
||||
return
|
||||
}
|
||||
|
||||
instance, err := DBQueryFrpcInstanceByID(instanceID)
|
||||
if err == sql.ErrNoRows {
|
||||
SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
||||
postLog.Error(fmt.Sprintf("[GetInstanceStatusHandler] User %d tried to get status of a not existed instance: %d", userID, instanceID))
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetInstanceStatusHandler] Failed to query instance: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
||||
return
|
||||
}
|
||||
|
||||
if instance.UserID != userID {
|
||||
SendErrorResponse(w, http.StatusForbidden, "Instance not found")
|
||||
postLog.Error(fmt.Sprintf("[GetInstanceStatusHandler] User %d tried to get status of instance %d that does not belong to them", userID, instanceID))
|
||||
return
|
||||
}
|
||||
|
||||
user, err := GetUserByID(instance.UserID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetInstanceStatusHandler] Failed to get user info: %v", err))
|
||||
SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info")
|
||||
return
|
||||
}
|
||||
|
||||
initType := GetInitSystem()
|
||||
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", user.Username, instance.Name)
|
||||
|
||||
responseData := map[string]interface{}{
|
||||
"name": instance.Name,
|
||||
"initSystem": initType,
|
||||
"serviceName": serviceName,
|
||||
"isRunning": false,
|
||||
}
|
||||
|
||||
isRunning := IsInstanceRunning(instance.Name)
|
||||
responseData["isRunning"] = isRunning
|
||||
|
||||
SendSuccessResponse(w, "Instance status retrieved successfully", responseData)
|
||||
postLog.Info(fmt.Sprintf("[GetInstanceStatusHandler] Retrieved status for instance %d (name: %s), isRunning: %v", instanceID, instance.Name, isRunning))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user