From 00319d790d4919ebb533bcb99273d651a3ca1df5 Mon Sep 17 00:00:00 2001 From: NanamiAdmin Date: Thu, 7 May 2026 22:46:28 +0800 Subject: [PATCH] chore: change service && filename rule to "superfrpc_instanceID" --- database/database.go | 14 +---- docs/api.md | 26 ++++---- frpLogger/frpLogger.go | 12 +--- handlers/instance.go | 132 +++++++++++++++-------------------------- sys/core.go | 32 ++-------- 5 files changed, 69 insertions(+), 147 deletions(-) diff --git a/database/database.go b/database/database.go index 14ce774..68930cd 100644 --- a/database/database.go +++ b/database/database.go @@ -467,19 +467,7 @@ func DBQueryUserInstances(userID int) (*sql.Rows, error) { } func GetServiceNameByInstanceID(instanceID int) (string, error) { - instance, err := DBQueryFrpcInstanceByID(instanceID) - if err != nil { - return "", fmt.Errorf("failed to query frpc instance: %w", err) - } - - user, err := GetUserByID(instance.UserID) - if err != nil { - postLog.Warning(fmt.Sprintf("[GetServiceNameByInstanceID] User %d not found, using fallback", instance.UserID)) - serviceName := fmt.Sprintf("superfrpc_unknown_%s", instance.Name) - return serviceName, nil - } - - serviceName := fmt.Sprintf("superfrpc_%s_%s", user.Username, instance.Name) + serviceName := fmt.Sprintf("superfrpc_%d", instanceID) postLog.Debug(fmt.Sprintf("[GetServiceNameByInstanceID] instanceID: %d, serviceName: %s", instanceID, serviceName)) return serviceName, nil } diff --git a/docs/api.md b/docs/api.md index 50b4efd..285e3c9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -571,7 +571,7 @@ X-Timestamp: 1704067200000 "message": "instance created successfully", "data": { "name": "my_frpc", - "configPath": "./configs/superfrpc_user_my_frpc.toml", + "configPath": "./configs/superfrpc_1.toml", "bootAtStart": true } } @@ -675,7 +675,7 @@ Modify fields in the `[common]` section of the frpc configuration file. Only `[c "message": "Config file modified successfully", "data": { "instanceID": 1, - "configPath": "./configs/superfrpc_user_my_frpc.toml" + "configPath": "./configs/superfrpc_1.toml" } } ``` @@ -712,7 +712,7 @@ Modify system-level settings such as instance name, boot-at-start configuration, "message": "System config modified successfully", "data": { "instanceID": 1, - "configPath": "./configs/superfrpc_user_new_frpc_name.toml", + "configPath": "./configs/superfrpc_1.toml", "bootAtStart": true, "runUser": "www-data" } @@ -727,7 +727,7 @@ Modify system-level settings such as instance name, boot-at-start configuration, "data": { "instanceName": "new_frpc_name", "instanceID": 1, - "configPath": "./configs/superfrpc_user_new_frpc_name.toml", + "configPath": "./configs/superfrpc_1.toml", "bootAtStart": true, "runUser": "www-data", "bootServiceError": "Failed to create boot service: unsupported init system" @@ -1048,7 +1048,7 @@ X-Timestamp: 1704067200000 "message": "Proxy created successfully", "data": { "instanceID": 1, - "configPath": "./configs/superfrpc_user_my_frpc.toml", + "configPath": "./configs/superfrpc_1.toml", "proxyName": "ssh_proxy" } } @@ -1134,7 +1134,7 @@ X-Timestamp: 1704067200000 "message": "Proxy modified successfully", "data": { "instanceID": 1, - "configPath": "./configs/superfrpc_user_my_frpc.toml", + "configPath": "./configs/superfrpc_1.toml", "proxyName": "ssh_proxy123" } } @@ -1209,7 +1209,7 @@ X-Timestamp: 1704067200000 "message": "Proxy deleted successfully", "data": { "instanceID": 1, - "configPath": "./configs/superfrpc_user_my_frpc.toml", + "configPath": "./configs/superfrpc_1.toml", "proxyName": "ssh_proxy" } } @@ -1392,7 +1392,7 @@ instanceID=1 "message": "Instance info retrieved successfully", "data": { "name": "my_frpc", - "serviceName": "superfrpc_admin_my_frpc", + "serviceName": "superfrpc_1", "createdAt": "2024-01-01T00:00:00Z", "createdBy": "admin", "isRunning": true, @@ -1401,7 +1401,7 @@ instanceID=1 "auth_method": "token", "bootAtStart": true, "runUser": "root", - "configPath": "./configs/superfrpc_admin_my_frpc.toml" + "configPath": "./configs/superfrpc_1.toml" } } ``` @@ -1413,14 +1413,14 @@ instanceID=1 "message": "Instance info retrieved successfully", "data": { "name": "my_frpc", - "serviceName": "superfrpc_admin_my_frpc", + "serviceName": "superfrpc_1", "createdAt": "2024-01-01T00:00:00Z", "createdBy": "admin", "isRunning": true, "auth_method": "token", "bootAtStart": true, "runUser": "root", - "configPath": "./configs/superfrpc_admin_my_frpc.toml" + "configPath": "./configs/superfrpc_1.toml" } } ``` @@ -1781,10 +1781,10 @@ Tokens are valid for 1 hour. After expiration, users need to re-login to get a n Instance configuration files are saved in the specified `instancePath` with the naming convention: ``` -superfrpc__.toml +superfrpc_.toml ``` -Example: `superfrpc_admin_my_frpc.toml` +Example: `superfrpc_1.toml` --- diff --git a/frpLogger/frpLogger.go b/frpLogger/frpLogger.go index d4a2e58..a8a2991 100644 --- a/frpLogger/frpLogger.go +++ b/frpLogger/frpLogger.go @@ -195,17 +195,7 @@ func GetUserByID(userID int) (*User, error) { } func GetServiceNameByInstanceID(instanceID int) (string, error) { - instance, err := DBQueryFrpcInstanceByID(instanceID) - if err != nil { - return "", fmt.Errorf("failed to query frpc instance: %w", err) - } - - user, err := GetUserByID(instance.UserID) - if err != nil { - return "", fmt.Errorf("failed to get user info: %w", err) - } - - serviceName := fmt.Sprintf("superfrpc_%s_%s", user.Username, instance.Name) + serviceName := fmt.Sprintf("superfrpc_%d", instanceID) return serviceName, nil } diff --git a/handlers/instance.go b/handlers/instance.go index edb8fd0..a351159 100644 --- a/handlers/instance.go +++ b/handlers/instance.go @@ -91,13 +91,6 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) { runUser = "root" } - user, err := database.GetUserByID(userID) - if err != nil { - postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to get user info: %v", err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info") - return - } - configDir, err := sys.GetConfigDir() if err != nil { postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to get config directory: %v", err)) @@ -105,30 +98,16 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) { return } - configFileName := fmt.Sprintf("superfrpc_%s_%s.toml", user.Username, req.InstanceInfo.Name) - configPath := filepath.Join(configDir, configFileName) - - setKeyTextWrapper := func(configPath, key, section, value string) error { - return config.SetKeyText(configPath, key, section, value, os.ReadFile, os.WriteFile) - } - - if err := config.HandleConfigFileCreate(configPath, req.InstanceInfo, setKeyTextWrapper); err != nil { - postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to create config file %s: %v", configPath, err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to create config file") - return - } - instance := database.FrpcInstance{ UserID: userID, Name: req.InstanceInfo.Name, BootAtStart: req.BootAtStart, RunUser: runUser, - ConfigPath: configPath, + ConfigPath: "", Watchdog: 0, } if err := database.DBAddFrpcInstance(instance); err != nil { - os.Remove(configPath) postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to save instance %s to database: %v", req.InstanceInfo.Name, err)) utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to save instance to database") return @@ -136,12 +115,34 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) { createdInstance, err := database.DBQueryFrpcInstance(userID, req.InstanceInfo.Name) if err != nil { - os.Remove(configPath) postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to query created instance: %v", err)) utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query created instance") return } + configFileName := fmt.Sprintf("superfrpc_%d.toml", createdInstance.ID) + configPath := filepath.Join(configDir, configFileName) + + setKeyTextWrapper := func(configPath, key, section, value string) error { + return config.SetKeyText(configPath, key, section, value, os.ReadFile, os.WriteFile) + } + + if err := config.HandleConfigFileCreate(configPath, req.InstanceInfo, setKeyTextWrapper); err != nil { + database.DBRemoveFrpcInstanceByID(createdInstance.ID) + postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to create config file %s: %v", configPath, err)) + utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to create config file") + return + } + + createdInstance.ConfigPath = configPath + if err := database.DBUpdateFrpcInstance(createdInstance); err != nil { + os.Remove(configPath) + database.DBRemoveFrpcInstanceByID(createdInstance.ID) + postLog.Error(fmt.Sprintf("[CreateInstanceHandler] Failed to update instance config path: %v", err)) + utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to update instance config path") + return + } + if err := sys.CreateBootService(createdInstance.ID); err != nil { database.DBRemoveFrpcInstanceByID(createdInstance.ID) os.Remove(configPath) @@ -309,17 +310,10 @@ func ModifyInstanceHandler(w http.ResponseWriter, r *http.Request) { return } - user, err := database.GetUserByID(instance.UserID) - if err != nil { - postLog.Error(fmt.Sprintf("[ModifyInstanceHandler] Failed to get user info: %v", err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get user info") - return - } - if modifyType == "configFile" { handleConfigFileModify(w, instance, modifiedData) } else { - handleSystemConfigModify(w, r, instance, modifiedData, user) + handleSystemConfigModify(w, r, instance, modifiedData) } } @@ -370,7 +364,7 @@ func handleConfigFileModify(w http.ResponseWriter, instance database.FrpcInstanc postLog.Info(fmt.Sprintf("[handleConfigFileModify] Config file for instance %s modified successfully", instance.Name)) } -func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance database.FrpcInstance, modifiedData map[string]interface{}, user *database.User) { +func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance database.FrpcInstance, modifiedData map[string]interface{}) { newName := instance.Name newRunUser := instance.RunUser newBootAtStart := instance.BootAtStart @@ -386,36 +380,9 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance d newBootAtStart = v } - oldConfigPath := instance.ConfigPath - var newConfigPath string - - if newName != instance.Name || newRunUser != instance.RunUser { - configDir, err := sys.GetConfigDir() - if err != nil { - postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to get config directory: %v", err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get config directory") - return - } - - newConfigFileName := fmt.Sprintf("superfrpc_%s_%s.toml", user.Username, newName) - newConfigPath = filepath.Join(configDir, newConfigFileName) - - if oldConfigPath != newConfigPath { - if _, err := os.Stat(oldConfigPath); err == nil { - if err := os.Rename(oldConfigPath, newConfigPath); err != nil { - postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to rename config file %s to %s: %v", oldConfigPath, newConfigPath, err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to rename config file") - return - } - } - } - } else { - newConfigPath = oldConfigPath - } - instance.RunUser = newRunUser instance.BootAtStart = newBootAtStart - instance.ConfigPath = newConfigPath + instance.Name = newName if err := database.DBUpdateFrpcInstance(instance); err != nil { postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to update instance in database: %v", err)) @@ -428,7 +395,6 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance d 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 := sys.SetBootAtStart(instance.ID); err != nil { postLog.Error(fmt.Sprintf("[handleSystemConfigModify] Failed to set boot at start: %v", err)) if bootServiceError != "" { @@ -441,14 +407,12 @@ func handleSystemConfigModify(w http.ResponseWriter, r *http.Request, instance d 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 } - instance.Name = newName data := map[string]interface{}{ "instanceName": newName, "instanceID": instance.ID, - "configPath": newConfigPath, + "configPath": instance.ConfigPath, "bootAtStart": newBootAtStart, "runUser": newRunUser, } @@ -720,44 +684,44 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) { } initType := sys.GetInitSystem() - sysName, err := database.GetServiceNameByInstanceID(instanceID) + serviceName, err := database.GetServiceNameByInstanceID(instanceID) if err != nil { - postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to get sys name: %v", err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get sys name") + postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to get service name: %v", err)) + utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get service name") return } switch initType { case "windows": - if err := sys.StopWindowsService(sysName); err != nil { - postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop Windows sys %s: %v", sysName, err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop Windows sys: %v", err)) + if err := sys.StopWindowsService(serviceName); err != nil { + postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop Windows service %s: %v", serviceName, err)) + utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop Windows service: %v", err)) return } time.Sleep(time.Millisecond * 200) if err := sys.IsInstanceRunning(instanceID); err == nil { - postLog.Error(fmt.Sprintf("[StopInstanceHandler] Windows sys %s failed to stop: %v", sysName, err)) + postLog.Error(fmt.Sprintf("[StopInstanceHandler] Windows service %s failed to stop: %v", serviceName, err)) utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop Windows sys: %v", err)) return } - postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Windows sys %s stopped successfully", sysName)) + postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Windows service %s stopped successfully", serviceName)) case "systemd": - if err := sys.StopSystemdService(sysName); err != nil { - postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop systemd sys %s: %v", sysName, err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop systemd sys: %v", err)) + if err := sys.StopSystemdService(serviceName); err != nil { + postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop systemd service %s: %v", serviceName, err)) + utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop systemd service: %v", err)) return } - postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Systemd sys %s stopped successfully", sysName)) + postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Systemd service %s stopped successfully", serviceName)) case "init.d": - if err := sys.StopInitDService(sysName); err != nil { + if err := sys.StopInitDService(serviceName); err != nil { time.Sleep(time.Millisecond * 200) - postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop init.d sys %s: %v", sysName, err)) - utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop init.d sys: %v", err)) + postLog.Error(fmt.Sprintf("[StopInstanceHandler] Failed to stop init.d service %s: %v", serviceName, err)) + utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Failed to stop init.d service: %v", err)) return } - postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Init.d sys %s stopped successfully", sysName)) + postLog.Debug(fmt.Sprintf("[StopInstanceHandler] Init.d service %s stopped successfully", serviceName)) default: utils.SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType)) @@ -765,16 +729,16 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) { } if global.Is.WatchdogConnected { - if !watchdog.RemoveInstance(sysName) { - postLog.Warning(fmt.Sprintf("[StopInstanceHandler] Failed to remove watchdog instance %s", sysName)) + if !watchdog.RemoveInstance(serviceName) { + postLog.Warning(fmt.Sprintf("[StopInstanceHandler] Failed to remove watchdog instance %s", serviceName)) utils.SendSuccessResponse(w, "Instance stopped successfully but watchdog instance remove failed", map[string]interface{}{ "instanceID": instanceID, - "sysName": sysName, + "serviceName": serviceName, }) } else { utils.SendSuccessResponse(w, "Instance stopped successfully", map[string]interface{}{ "instanceID": instanceID, - "sysName": sysName, + "serviceName": serviceName, }) } } diff --git a/sys/core.go b/sys/core.go index d49ff91..8589103 100644 --- a/sys/core.go +++ b/sys/core.go @@ -68,18 +68,8 @@ func createSystemdService(instanceID int, configPath, runUser string) error { return err } - instance, err := database.DBQueryFrpcInstanceByID(instanceID) - if err != nil { - return fmt.Errorf("failed to query frpc instance: %w", err) - } - - user, err := database.GetUserByID(instance.UserID) - if err != nil { - return fmt.Errorf("failed to get user info: %w", err) - } - serviceContent := fmt.Sprintf(`[Unit] -Description=superfrpc_%s_%s +Description=superfrpc_%d After=network.target [Service] @@ -91,7 +81,7 @@ RestartSec=5 [Install] WantedBy=multi-user.target -`, user.Username, instance.Name, frpcPath, configPath, runUser) +`, instanceID, frpcPath, configPath, runUser) servicePath := filepath.Join("/etc/systemd/system", serviceName+".service") if err := os.WriteFile(servicePath, []byte(serviceContent), 0644); err != nil { @@ -123,16 +113,6 @@ func createInitDService(instanceID int, configPath, runUser string) error { return err } - instance, err := database.DBQueryFrpcInstanceByID(instanceID) - if err != nil { - return fmt.Errorf("failed to query frpc instance: %w", err) - } - - user, err := database.GetUserByID(instance.UserID) - if err != nil { - return fmt.Errorf("failed to get user info: %w", err) - } - var serviceContent string runUserArg := "" if runUser != "" && runUser != "root" { @@ -145,7 +125,7 @@ func createInitDService(instanceID int, configPath, runUser string) error { # Required-Stop: $network $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 -# Description: superfrpc %s %s +# Description: superfrpc %d ### END INIT INFO NAME="%s" @@ -187,7 +167,7 @@ case "$1" in esac exit 0 -`, serviceName, user.Username, instance.Name, serviceName, frpcPath, configPath, runUserArg) +`, serviceName, instanceID, serviceName, frpcPath, configPath, runUserArg) } else { serviceContent = fmt.Sprintf(`#!/bin/sh @@ -197,7 +177,7 @@ exit 0 # Required-Stop: $network $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 -# Description: superfrpc %s %s +# Description: superfrpc %d ### END INIT INFO NAME="%s" @@ -238,7 +218,7 @@ case "$1" in esac exit 0 -`, serviceName, user.Username, instance.Name, serviceName, frpcPath, configPath) +`, serviceName, instanceID, serviceName, frpcPath, configPath) } servicePath := filepath.Join("/etc/init.d", serviceName)