1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
package main
import ( "log" "os" "path/filepath" "syscall"
"github.com/fsnotify/fsnotify" proc "github.com/shirou/gopsutil/process" )
const ( nginxProcessName = "nginx" defaultNginxConfPath = "/etc/nginx" watchPathEnvVarName = "WATCH_NGINX_CONF_PATH" )
var stderrLogger = log.New(os.Stderr, "error: ", log.Lshortfile) var stdoutLogger = log.New(os.Stdout, "", log.Lshortfile)
func getMasterNginxPid() (int, error) { processes, processesErr := proc.Processes() if processesErr != nil { return 0, processesErr }
nginxProcesses := map[int32]int32{}
for _, process := range processes { processName, processNameErr := process.Name() if processNameErr != nil { return 0, processNameErr }
if processName == nginxProcessName { ppid, ppidErr := process.Ppid()
if ppidErr != nil { return 0, ppidErr }
nginxProcesses[process.Pid] = ppid } }
var masterNginxPid int32
for pid, ppid := range nginxProcesses { if ppid == 0 { masterNginxPid = pid
break } }
stdoutLogger.Println("found master nginx pid:", masterNginxPid)
return int(masterNginxPid), nil }
func signalNginxReload(pid int) error { stdoutLogger.Printf("signaling master nginx process (pid: %d) -> SIGHUP\n", pid) nginxProcess, nginxProcessErr := os.FindProcess(pid)
if nginxProcessErr != nil { return nginxProcessErr }
return nginxProcess.Signal(syscall.SIGHUP) }
func main() { watcher, watcherErr := fsnotify.NewWatcher() if watcherErr != nil { stderrLogger.Fatal(watcherErr) } defer watcher.Close()
done := make(chan bool) go func() { for { select { case event, ok := <-watcher.Events: if !ok { return }
if event.Op&fsnotify.Create == fsnotify.Create { if filepath.Base(event.Name) == "..data" { stdoutLogger.Println("config map updated")
nginxPid, nginxPidErr := getMasterNginxPid() if nginxPidErr != nil { stderrLogger.Printf("getting master nginx pid failed: %s", nginxPidErr.Error())
continue }
if err := signalNginxReload(nginxPid); err != nil { stderrLogger.Printf("signaling master nginx process failed: %s", err) } } } case err, ok := <-watcher.Errors: if !ok { return } stderrLogger.Printf("received watcher.Error: %s", err) } } }()
pathToWatch, ok := os.LookupEnv(watchPathEnvVarName) if !ok { pathToWatch = defaultNginxConfPath }
stdoutLogger.Printf("adding path: `%s` to watch\n", pathToWatch)
if err := watcher.Add(pathToWatch); err != nil { stderrLogger.Fatal(err) } <-done }
|