nginx.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package nginx
  2. import (
  3. "os"
  4. "strconv"
  5. "strings"
  6. "sync"
  7. "syscall"
  8. "time"
  9. "github.com/0xJacky/Nginx-UI/internal/docker"
  10. "github.com/0xJacky/Nginx-UI/settings"
  11. )
  12. var (
  13. mutex sync.Mutex
  14. lastStdOut string
  15. lastStdErr error
  16. )
  17. // TestConfig tests the nginx config
  18. func TestConfig() (stdOut string, stdErr error) {
  19. mutex.Lock()
  20. defer mutex.Unlock()
  21. if settings.NginxSettings.TestConfigCmd != "" {
  22. return execShell(settings.NginxSettings.TestConfigCmd)
  23. }
  24. return execCommand("nginx", "-t")
  25. }
  26. // Reload reloads the nginx
  27. func Reload() (stdOut string, stdErr error) {
  28. mutex.Lock()
  29. defer mutex.Unlock()
  30. // Clear the modules cache when reloading Nginx
  31. clearModulesCache()
  32. if !IsRunning() {
  33. restart()
  34. return
  35. }
  36. if settings.NginxSettings.ReloadCmd != "" {
  37. return execShell(settings.NginxSettings.ReloadCmd)
  38. }
  39. return execCommand("nginx", "-s", "reload")
  40. }
  41. func restart() {
  42. // fix(docker): nginx restart always output network error
  43. time.Sleep(500 * time.Millisecond)
  44. if settings.NginxSettings.RestartCmd != "" {
  45. lastStdOut, lastStdErr = execShell(settings.NginxSettings.RestartCmd)
  46. return
  47. }
  48. pidPath := GetPIDPath()
  49. daemon := GetSbinPath()
  50. // Check if nginx is running before attempting to stop it
  51. if IsRunning() {
  52. lastStdOut, lastStdErr = execCommand("start-stop-daemon", "--stop", "--quiet", "--oknodo", "--retry=TERM/30/KILL/5", "--pidfile", pidPath)
  53. if lastStdErr != nil {
  54. return
  55. }
  56. }
  57. if daemon == "" {
  58. lastStdOut, lastStdErr = execCommand("nginx")
  59. return
  60. }
  61. lastStdOut, lastStdErr = execCommand("start-stop-daemon", "--start", "--quiet", "--pidfile", pidPath, "--exec", daemon)
  62. }
  63. // Restart restarts the nginx
  64. func Restart() {
  65. mutex.Lock()
  66. defer mutex.Unlock()
  67. // Clear the modules cache when restarting Nginx
  68. clearModulesCache()
  69. restart()
  70. }
  71. // GetLastOutput returns the last output of the nginx command
  72. func GetLastResult() *ControlResult {
  73. mutex.Lock()
  74. defer mutex.Unlock()
  75. return &ControlResult{
  76. stdOut: lastStdOut,
  77. stdErr: lastStdErr,
  78. }
  79. }
  80. func IsRunning() bool {
  81. pidPath := GetPIDPath()
  82. switch settings.NginxSettings.RunningInAnotherContainer() {
  83. case true:
  84. return docker.StatPath(pidPath)
  85. case false:
  86. return isProcessRunning(pidPath)
  87. }
  88. return false
  89. }
  90. // isProcessRunning checks if the process with the PID from pidPath is actually running
  91. func isProcessRunning(pidPath string) bool {
  92. // Check if PID file exists
  93. if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 {
  94. return false
  95. }
  96. // Read PID from file
  97. pidBytes, err := os.ReadFile(pidPath)
  98. if err != nil {
  99. return false
  100. }
  101. pidStr := strings.TrimSpace(string(pidBytes))
  102. pid, err := strconv.Atoi(pidStr)
  103. if err != nil {
  104. return false
  105. }
  106. // Cross-platform process existence check
  107. process, err := os.FindProcess(pid)
  108. if err != nil {
  109. return false
  110. }
  111. // On Unix systems, FindProcess always succeeds and returns a Process for the given pid,
  112. // regardless of whether the process exists. To test whether the process actually exists,
  113. // see whether p.Signal(syscall.Signal(0)) reports an error.
  114. err = process.Signal(syscall.Signal(0))
  115. if err == nil {
  116. // Process exists and we can signal it
  117. return true
  118. }
  119. return false
  120. }