|
@@ -2,7 +2,10 @@ package nginx
|
|
|
|
|
|
import (
|
|
|
"os"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
"sync"
|
|
|
+ "syscall"
|
|
|
"time"
|
|
|
|
|
|
"github.com/0xJacky/Nginx-UI/internal/docker"
|
|
@@ -33,20 +36,18 @@ func Reload() (stdOut string, stdErr error) {
|
|
|
// Clear the modules cache when reloading Nginx
|
|
|
clearModulesCache()
|
|
|
|
|
|
+ if !IsRunning() {
|
|
|
+ restart()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
if settings.NginxSettings.ReloadCmd != "" {
|
|
|
return execShell(settings.NginxSettings.ReloadCmd)
|
|
|
}
|
|
|
return execCommand("nginx", "-s", "reload")
|
|
|
}
|
|
|
|
|
|
-// Restart restarts the nginx
|
|
|
-func Restart() {
|
|
|
- mutex.Lock()
|
|
|
- defer mutex.Unlock()
|
|
|
-
|
|
|
- // Clear the modules cache when restarting Nginx
|
|
|
- clearModulesCache()
|
|
|
-
|
|
|
+func restart() {
|
|
|
// fix(docker): nginx restart always output network error
|
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
|
|
@@ -58,9 +59,12 @@ func Restart() {
|
|
|
pidPath := GetPIDPath()
|
|
|
daemon := GetSbinPath()
|
|
|
|
|
|
- lastStdOut, lastStdErr = execCommand("start-stop-daemon", "--stop", "--quiet", "--oknodo", "--retry=TERM/30/KILL/5", "--pidfile", pidPath)
|
|
|
- if lastStdErr != nil {
|
|
|
- return
|
|
|
+ // Check if nginx is running before attempting to stop it
|
|
|
+ if IsRunning() {
|
|
|
+ lastStdOut, lastStdErr = execCommand("start-stop-daemon", "--stop", "--quiet", "--oknodo", "--retry=TERM/30/KILL/5", "--pidfile", pidPath)
|
|
|
+ if lastStdErr != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if daemon == "" {
|
|
@@ -71,6 +75,17 @@ func Restart() {
|
|
|
lastStdOut, lastStdErr = execCommand("start-stop-daemon", "--start", "--quiet", "--pidfile", pidPath, "--exec", daemon)
|
|
|
}
|
|
|
|
|
|
+// Restart restarts the nginx
|
|
|
+func Restart() {
|
|
|
+ mutex.Lock()
|
|
|
+ defer mutex.Unlock()
|
|
|
+
|
|
|
+ // Clear the modules cache when restarting Nginx
|
|
|
+ clearModulesCache()
|
|
|
+
|
|
|
+ restart()
|
|
|
+}
|
|
|
+
|
|
|
// GetLastOutput returns the last output of the nginx command
|
|
|
func GetLastResult() *ControlResult {
|
|
|
mutex.Lock()
|
|
@@ -87,9 +102,42 @@ func IsRunning() bool {
|
|
|
case true:
|
|
|
return docker.StatPath(pidPath)
|
|
|
case false:
|
|
|
- if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 {
|
|
|
- return false
|
|
|
- }
|
|
|
+ return isProcessRunning(pidPath)
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+// isProcessRunning checks if the process with the PID from pidPath is actually running
|
|
|
+func isProcessRunning(pidPath string) bool {
|
|
|
+ // Check if PID file exists
|
|
|
+ if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ // Read PID from file
|
|
|
+ pidBytes, err := os.ReadFile(pidPath)
|
|
|
+ if err != nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ pidStr := strings.TrimSpace(string(pidBytes))
|
|
|
+ pid, err := strconv.Atoi(pidStr)
|
|
|
+ if err != nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ // Cross-platform process existence check
|
|
|
+ process, err := os.FindProcess(pid)
|
|
|
+ if err != nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ // On Unix systems, FindProcess always succeeds and returns a Process for the given pid,
|
|
|
+ // regardless of whether the process exists. To test whether the process actually exists,
|
|
|
+ // see whether p.Signal(syscall.Signal(0)) reports an error.
|
|
|
+ err = process.Signal(syscall.Signal(0))
|
|
|
+ if err == nil {
|
|
|
+ // Process exists and we can signal it
|
|
|
return true
|
|
|
}
|
|
|
return false
|