fix(utils): now it can be successfully restarted when deployed as systemd service
- Add `getSystemdServiceName` function to get systemd service name. - When detected as systemd sevice, use `systemctl restart` to restart the program then exit.
This commit is contained in:
@@ -70,10 +70,12 @@ For detailed API documentation, please see [docs/api.md](docs/api.md)
|
|||||||
- [ ] Add per-proxy status display
|
- [ ] Add per-proxy status display
|
||||||
- [ ] Add proxy edit submit action
|
- [ ] Add proxy edit submit action
|
||||||
- [ ] Add per-proxy status control
|
- [ ] Add per-proxy status control
|
||||||
- [ ] Fix reboot failed when deployed as systemd service
|
- [x] Fix reboot failed when deployed as systemd service
|
||||||
- [x] Enhance speed of listing instances
|
- [x] Enhance speed of listing instances
|
||||||
- [x] Increase speed of fetching instance logs
|
- [x] Increase speed of fetching instance logs
|
||||||
- [x] Refactor systemd service log output method to local file
|
- [x] Refactor systemd service log output method to local file
|
||||||
|
- [ ] Fix no log output in instanceDetail view
|
||||||
|
- [ ] Add update frp binary function
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
+18
@@ -671,3 +671,21 @@ func RestartInitDService(instanceName string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSystemdServiceName() (string, error) {
|
||||||
|
data, err := os.ReadFile("/proc/self/cgroup")
|
||||||
|
if err == nil {
|
||||||
|
for _, line := range strings.Split(string(data), "\n") {
|
||||||
|
if !strings.Contains(line, ".service") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, part := range strings.Split(line, "/") {
|
||||||
|
part = strings.TrimSpace(part)
|
||||||
|
if strings.HasSuffix(part, ".service") {
|
||||||
|
return part, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("could not determine systemd service name from cgroup")
|
||||||
|
}
|
||||||
+23
-1
@@ -170,6 +170,8 @@ func IsFileExist(filePath string) bool {
|
|||||||
return !os.IsNotExist(err)
|
return !os.IsNotExist(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pendingSystemdRestart string
|
||||||
|
|
||||||
func RestartHandler(w http.ResponseWriter, r *http.Request) {
|
func RestartHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
userID, err := Auth(w, r, http.MethodGet, "superuser", "admin")
|
userID, err := Auth(w, r, http.MethodGet, "superuser", "admin")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -185,14 +187,34 @@ func RestartHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
SendSuccessResponse(w, "Restarting server...", nil)
|
SendSuccessResponse(w, "Restarting server...", nil)
|
||||||
postLog.Info(fmt.Sprintf("[RestartHandler] [%d] Restarting server", userID))
|
postLog.Info(fmt.Sprintf("[RestartHandler] [%d] Restarting server", userID))
|
||||||
|
|
||||||
|
if pendingSystemdRestart != "" {
|
||||||
|
serviceName := pendingSystemdRestart
|
||||||
|
go func() {
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
cmd := exec.Command("systemctl", "restart", serviceName)
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
postLog.Error(fmt.Sprintf("[RestartHandler] [%d] failed to restart systemd service %s: %v", userID, serviceName, err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RestartProcess() error {
|
func RestartProcess() error {
|
||||||
|
if getInitSystem() == "systemd" {
|
||||||
|
serviceName, err := getSystemdServiceName()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get systemd service name: %w", err)
|
||||||
|
}
|
||||||
|
pendingSystemdRestart = serviceName
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
executable, err := os.Executable()
|
executable, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get executable path: %w", err)
|
return fmt.Errorf("failed to get executable path: %w", err)
|
||||||
}
|
}
|
||||||
cmd := exec.Command(executable)
|
cmd := exec.Command(executable, os.Args[1:]...)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getSystemdServiceName() (string, error) {
|
||||||
|
data, err := os.ReadFile("/proc/self/cgroup")
|
||||||
|
if err == nil {
|
||||||
|
for _, line := range strings.Split(string(data), "\n") {
|
||||||
|
if !strings.Contains(line, ".service") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, part := range strings.Split(line, "/") {
|
||||||
|
part = strings.TrimSpace(part)
|
||||||
|
if strings.HasSuffix(part, ".service") {
|
||||||
|
return part, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("could not determine systemd service name from cgroup")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInitSystem() string {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return "windows"
|
||||||
|
}
|
||||||
|
if runtime.GOOS == "linux" {
|
||||||
|
if _, err := os.Stat("/run/systemd/system"); err == nil {
|
||||||
|
return "systemd"
|
||||||
|
}
|
||||||
|
if _, err := os.Stat("/etc/init.d"); err == nil {
|
||||||
|
return "init.d"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user