-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.go
129 lines (102 loc) · 3.21 KB
/
main.go
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
128
129
/*
2020年4月17日 14:19:02 by elvis
kubernetes nginx configmap reload
*/
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
}