refactor(frpc): restructure instance management and config handling
- Move instance-related structs and functions to config.go - Remove serverAddr, serverPort, and authMethod from database schema - Implement new config parsing and encoding with nested key support - Update service management to use instanceID instead of username/name - Add GetServiceNameByInstanceID helper function - Update API documentation for auth.method field change
This commit is contained in:
@@ -44,28 +44,47 @@ func GetInitSystem() string {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
func createBootService(username, instanceName, configPath, runUser string) error {
|
||||
func createBootService(instanceID int) error {
|
||||
instance, err := DBQueryFrpcInstanceByID(instanceID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query frpc instance: %w", err)
|
||||
}
|
||||
|
||||
initType := GetInitSystem()
|
||||
|
||||
switch initType {
|
||||
case "systemd":
|
||||
return createSystemdService(username, instanceName, configPath, runUser)
|
||||
return createSystemdService(instanceID, instance.ConfigPath, instance.RunUser)
|
||||
case "init.d":
|
||||
return createInitDService(username, instanceName, configPath, runUser)
|
||||
return createInitDService(instanceID, instance.ConfigPath, instance.RunUser)
|
||||
case "windows":
|
||||
return createWindowsBootService(username, instanceName, configPath)
|
||||
return createWindowsBootService(instanceID, instance.ConfigPath)
|
||||
default:
|
||||
return fmt.Errorf("unsupported init system: %s", initType)
|
||||
}
|
||||
}
|
||||
|
||||
func createSystemdService(username, instanceName, configPath, runUser string) error {
|
||||
func createSystemdService(instanceID int, configPath, runUser string) error {
|
||||
frpcPath, err := GetFrpcPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName)
|
||||
serviceName, err := GetServiceNameByInstanceID(instanceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
serviceContent := fmt.Sprintf(`[Unit]
|
||||
Description=superfrpc_%s_%s
|
||||
After=network.target
|
||||
@@ -79,7 +98,7 @@ RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
`, username, instanceName, frpcPath, configPath, runUser)
|
||||
`, user.Username, instance.Name, frpcPath, configPath, runUser)
|
||||
|
||||
servicePath := filepath.Join("/etc/systemd/system", serviceName+".service")
|
||||
if err := os.WriteFile(servicePath, []byte(serviceContent), 0644); err != nil {
|
||||
@@ -100,13 +119,26 @@ WantedBy=multi-user.target
|
||||
return nil
|
||||
}
|
||||
|
||||
func createInitDService(username, instanceName, configPath, runUser string) error {
|
||||
func createInitDService(instanceID int, configPath, runUser string) error {
|
||||
frpcPath, err := GetFrpcPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName)
|
||||
serviceName, err := GetServiceNameByInstanceID(instanceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
var serviceContent string
|
||||
runUserArg := ""
|
||||
@@ -162,7 +194,7 @@ case "$1" in
|
||||
esac
|
||||
|
||||
exit 0
|
||||
`, serviceName, username, instanceName, serviceName, frpcPath, configPath, runUserArg)
|
||||
`, serviceName, user.Username, instance.Name, serviceName, frpcPath, configPath, runUserArg)
|
||||
} else {
|
||||
serviceContent = fmt.Sprintf(`#!/bin/sh
|
||||
|
||||
@@ -213,7 +245,7 @@ case "$1" in
|
||||
esac
|
||||
|
||||
exit 0
|
||||
`, serviceName, username, instanceName, serviceName, frpcPath, configPath)
|
||||
`, serviceName, user.Username, instance.Name, serviceName, frpcPath, configPath)
|
||||
}
|
||||
|
||||
servicePath := filepath.Join("/etc/init.d", serviceName)
|
||||
@@ -230,13 +262,17 @@ exit 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func createWindowsBootService(username, instanceName, configPath string) error {
|
||||
func createWindowsBootService(instanceID int, configPath string) error {
|
||||
frpcPath, err := GetFrpcPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName)
|
||||
serviceName, err := GetServiceNameByInstanceID(instanceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
command := fmt.Sprintf("\"%s\" -c \"%s\"", frpcPath, configPath)
|
||||
|
||||
cmd := exec.Command("sc", "create", serviceName, "binPath=", command, "start=", "auto")
|
||||
@@ -249,9 +285,12 @@ func createWindowsBootService(username, instanceName, configPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setBootAtStart(username, instanceName string) error {
|
||||
func setBootAtStart(instanceID int) error {
|
||||
initType := GetInitSystem()
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName)
|
||||
serviceName, err := GetServiceNameByInstanceID(instanceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch initType {
|
||||
case "windows":
|
||||
@@ -280,11 +319,14 @@ func setBootAtStart(username, instanceName string) error {
|
||||
}
|
||||
}
|
||||
|
||||
func removeBootAtStart(username, instanceName string) error {
|
||||
func removeBootAtStart(instanceID int) error {
|
||||
initType := GetInitSystem()
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName)
|
||||
serviceName, err := GetServiceNameByInstanceID(instanceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch initType{
|
||||
switch initType {
|
||||
case "windows":
|
||||
cmd := exec.Command("sc", "config", serviceName, "start=", "disabled")
|
||||
output, err := cmd.CombinedOutput()
|
||||
@@ -311,10 +353,12 @@ func removeBootAtStart(username, instanceName string) error {
|
||||
}
|
||||
}
|
||||
|
||||
func removeBootService(username, instanceName string) error {
|
||||
func removeBootService(instanceID int) error {
|
||||
initType := GetInitSystem()
|
||||
|
||||
serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName)
|
||||
serviceName, err := GetServiceNameByInstanceID(instanceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch initType {
|
||||
case "systemd":
|
||||
@@ -347,11 +391,23 @@ func removeBootService(username, instanceName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsInstanceRunning(instanceName string) bool {
|
||||
func IsInstanceRunning(instanceID int) bool {
|
||||
initType := GetInitSystem()
|
||||
serviceName, err := GetServiceNameByInstanceID(instanceID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[IsInstanceRunning] Failed to get service name: %v", err))
|
||||
return false
|
||||
}
|
||||
|
||||
instance, err := DBQueryFrpcInstanceByID(instanceID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[IsInstanceRunning] Failed to query instance: %v", err))
|
||||
return false
|
||||
}
|
||||
|
||||
switch initType {
|
||||
case "windows":
|
||||
cmd := exec.Command("sc", "query", instanceName)
|
||||
cmd := exec.Command("sc", "query", serviceName)
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
postLog.Debug(fmt.Sprintf("[IsInstanceRunning] Sc query output: %s", output))
|
||||
@@ -362,15 +418,15 @@ func IsInstanceRunning(instanceName string) bool {
|
||||
|
||||
outputStr := string(output)
|
||||
if strings.Contains(outputStr, "RUNNING") {
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is running", instanceName))
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is running", instance.Name))
|
||||
return true
|
||||
} else {
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is stopped", instanceName))
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is stopped", instance.Name))
|
||||
return false
|
||||
}
|
||||
|
||||
case "systemd":
|
||||
cmd := exec.Command("systemctl", "is-active", instanceName)
|
||||
cmd := exec.Command("systemctl", "is-active", serviceName)
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
@@ -380,17 +436,17 @@ func IsInstanceRunning(instanceName string) bool {
|
||||
|
||||
status := strings.TrimSpace(string(output))
|
||||
if status == "active" {
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Systemd service %s is running", instanceName))
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Systemd service %s is running", serviceName))
|
||||
return true
|
||||
} else {
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Systemd service %s is stopped", instanceName))
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Systemd service %s is stopped", serviceName))
|
||||
return false
|
||||
}
|
||||
|
||||
case "init.d":
|
||||
servicePath := fmt.Sprintf("/etc/init.d/%s", instanceName)
|
||||
servicePath := fmt.Sprintf("/etc/init.d/%s", serviceName)
|
||||
if _, err := os.Stat(servicePath); err != nil {
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Init.d service %s not found", instanceName))
|
||||
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Init.d service %s not found", serviceName))
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -415,11 +471,17 @@ func IsInstanceRunning(instanceName string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func GetInstancePid(instanceName string) int {
|
||||
func GetInstancePid(instanceID int) int {
|
||||
initType := GetInitSystem()
|
||||
serviceName, err := GetServiceNameByInstanceID(instanceID)
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetInstancePid] Failed to get service name: %v", err))
|
||||
return 0
|
||||
}
|
||||
|
||||
switch initType {
|
||||
case "windows":
|
||||
cmd := exec.Command("sc", "query", instanceName, "info")
|
||||
cmd := exec.Command("sc", "query", serviceName, "info")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetInstancePid] Failed to get Windows service info: %s, output: %s", err, output))
|
||||
@@ -441,7 +503,7 @@ func GetInstancePid(instanceName string) int {
|
||||
}
|
||||
return 0
|
||||
case "systemd":
|
||||
cmd := exec.Command("systemctl", "show", instanceName, "--property", "MainPID")
|
||||
cmd := exec.Command("systemctl", "show", serviceName, "--property", "MainPID")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetInstancePid] Failed to get PID from systemd: %s, output: %s", err, output))
|
||||
@@ -460,9 +522,9 @@ func GetInstancePid(instanceName string) int {
|
||||
}
|
||||
return 0
|
||||
case "init.d":
|
||||
servicePath := fmt.Sprintf("/etc/init.d/%s", instanceName)
|
||||
servicePath := fmt.Sprintf("/etc/init.d/%s", serviceName)
|
||||
if _, err := os.Stat(servicePath); err != nil {
|
||||
postLog.Error(fmt.Sprintf("[GetInstancePid] Init.d service %s not found", instanceName))
|
||||
postLog.Error(fmt.Sprintf("[GetInstancePid] Init.d service %s not found", serviceName))
|
||||
return 0
|
||||
}
|
||||
cmd := exec.Command(servicePath, "status")
|
||||
@@ -483,7 +545,7 @@ func GetInstancePid(instanceName string) int {
|
||||
}
|
||||
}
|
||||
}
|
||||
pidFile := fmt.Sprintf("/var/run/%s.pid", instanceName)
|
||||
pidFile := fmt.Sprintf("/var/run/%s.pid", serviceName)
|
||||
if content, err := os.ReadFile(pidFile); err == nil {
|
||||
pidStr := strings.TrimSpace(string(content))
|
||||
pid, err := strconv.Atoi(pidStr)
|
||||
|
||||
Reference in New Issue
Block a user