chore: change service && filename rule to "superfrpc_instanceID"

This commit is contained in:
2026-05-07 22:46:28 +08:00
parent 6e705ce2f3
commit 00319d790d
5 changed files with 69 additions and 147 deletions
+1 -13
View File
@@ -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
}
+13 -13
View File
@@ -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_<username>_<instanceName>.toml
superfrpc_<instanceID>.toml
```
Example: `superfrpc_admin_my_frpc.toml`
Example: `superfrpc_1.toml`
---
+1 -11
View File
@@ -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
}
+48 -84
View File
@@ -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,
})
}
}
+6 -26
View File
@@ -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)