Skip to content

Commit a371244

Browse files
Krisztian Horvathschfeca75
Krisztian Horvath
authored andcommitted
restart minions if we change the master list
1 parent 03139bf commit a371244

File tree

5 files changed

+102
-30
lines changed

5 files changed

+102
-30
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BINARY=salt-bootstrap
22

3-
VERSION=0.11.0
3+
VERSION=0.11.1
44
BUILD_TIME=$(shell date +%FT%T)
55
LDFLAGS=-ldflags "-X github.com/hortonworks/salt-bootstrap/saltboot.Version=${VERSION} -X github.com/hortonworks/salt-bootstrap/saltboot.BuildTime=${BUILD_TIME}"
66
GOFILES = $(shell find . -type f -name '*.go')

saltboot/initSystem.go

+22-9
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,37 @@ import (
88
type InitSystem struct {
99
Start string
1010
Stop string
11+
Restart string
1112
Enable string
1213
Disable string
1314
ActionBin string
1415
StateBin string
1516
CommandOrderASC bool
1617
}
1718

19+
const (
20+
START_ACTION = "start"
21+
STOP_ACTION = "stop"
22+
RESTART_ACTION = "restart"
23+
)
24+
1825
var (
19-
SYSYEM_D = InitSystem{ActionBin: "/bin/systemctl", StateBin: "/bin/systemctl", Start: "start", Stop: "stop", Enable: "enable", Disable: "disable", CommandOrderASC: true}
20-
SYS_V_INIT = InitSystem{ActionBin: "/sbin/service", StateBin: "/sbin/chkconfig", Start: "start", Stop: "stop", Enable: "on", Disable: "off", CommandOrderASC: false}
26+
SYSTEM_D = InitSystem{ActionBin: "/bin/systemctl", StateBin: "/bin/systemctl", Start: START_ACTION, Stop: STOP_ACTION, Restart: RESTART_ACTION, Enable: "enable", Disable: "disable", CommandOrderASC: true}
27+
SYS_V_INIT = InitSystem{ActionBin: "/sbin/service", StateBin: "/sbin/chkconfig", Start: START_ACTION, Stop: STOP_ACTION, Restart: RESTART_ACTION, Enable: "on", Disable: "off", CommandOrderASC: false}
2128
)
2229

23-
func (system InitSystem) ActionCommand(service string, run bool) []string {
24-
if run {
30+
func (system InitSystem) ActionCommand(service string, action string) []string {
31+
if action == START_ACTION || action == RESTART_ACTION {
32+
if action == START_ACTION {
33+
if system.CommandOrderASC {
34+
return []string{system.ActionBin, system.Start, service}
35+
}
36+
return []string{system.ActionBin, service, system.Start}
37+
}
2538
if system.CommandOrderASC {
26-
return []string{system.ActionBin, system.Start, service}
39+
return []string{system.ActionBin, system.Restart, service}
2740
}
28-
return []string{system.ActionBin, service, system.Start}
41+
return []string{system.ActionBin, service, system.Restart}
2942
}
3043
if system.CommandOrderASC {
3144
return []string{system.ActionBin, system.Stop, service}
@@ -52,9 +65,9 @@ func (system InitSystem) Error() string {
5265

5366
func GetInitSystem(stat func(name string) (os.FileInfo, error)) (system InitSystem) {
5467
if _, err := stat("/bin/systemctl"); err == nil {
55-
log.Printf("[GetInitSystem] /bin/systemctl found, assume systemd")
56-
return SYSYEM_D
68+
log.Println("[GetInitSystem] /bin/systemctl found, assume systemd")
69+
return SYSTEM_D
5770
}
58-
log.Printf("[GetInitSystem] /bin/systemctl not found, assume sysv init")
71+
log.Println("[GetInitSystem] /bin/systemctl not found, assume sysv init")
5972
return SYS_V_INIT
6073
}

saltboot/initSystem_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func TestActionCommandRunCommandOrderASC(t *testing.T) {
1414
CommandOrderASC: true,
1515
}
1616

17-
resp := s.ActionCommand("service", true)
17+
resp := s.ActionCommand("service", START_ACTION)
1818

1919
expected := []string{"bin", "start", "service"}
2020
if strings.Join(resp, "") != strings.Join(expected, "") {
@@ -29,7 +29,7 @@ func TestActionCommandRunCommandOrderDESC(t *testing.T) {
2929
CommandOrderASC: false,
3030
}
3131

32-
resp := s.ActionCommand("service", true)
32+
resp := s.ActionCommand("service", START_ACTION)
3333

3434
expected := []string{"bin", "service", "start"}
3535
if strings.Join(resp, "") != strings.Join(expected, "") {
@@ -44,7 +44,7 @@ func TestActionCommandCommandOrderASC(t *testing.T) {
4444
CommandOrderASC: true,
4545
}
4646

47-
resp := s.ActionCommand("service", false)
47+
resp := s.ActionCommand("service", STOP_ACTION)
4848

4949
expected := []string{"bin", "stop", "service"}
5050
if strings.Join(resp, "") != strings.Join(expected, "") {
@@ -59,7 +59,7 @@ func TestActionCommandCommandOrderDESC(t *testing.T) {
5959
CommandOrderASC: false,
6060
}
6161

62-
resp := s.ActionCommand("service", false)
62+
resp := s.ActionCommand("service", STOP_ACTION)
6363

6464
expected := []string{"bin", "service", "stop"}
6565
if strings.Join(resp, "") != strings.Join(expected, "") {
@@ -134,8 +134,8 @@ func TestGetInitSystemSystemD(t *testing.T) {
134134

135135
resp := GetInitSystem(stat)
136136

137-
if resp != SYSYEM_D {
138-
t.Errorf("wrong init system found %s == %s", SYSYEM_D, resp)
137+
if resp != SYSTEM_D {
138+
t.Errorf("wrong init system found %s == %s", SYSTEM_D, resp)
139139
}
140140
}
141141

saltboot/salt.go

+42-4
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,17 @@ func SaltMinionRunRequestHandler(w http.ResponseWriter, req *http.Request) {
155155

156156
var masterConf []byte
157157
servers := saltMinion.Servers
158+
restartNeeded := false
158159
if servers != nil && len(servers) > 0 {
159-
log.Printf("[SaltMinionRunRequestHandler] multiple salt masters: %s", servers)
160+
log.Printf("[SaltMinionRunRequestHandler] salt master list: %s", servers)
160161
masterConf, _ = yaml.Marshal(map[string][]string{"master": servers})
162+
restartNeeded = isSaltMinionRestartNeeded(servers)
161163
} else {
162-
log.Printf("[SaltMinionRunRequestHandler] single salt master: %s", saltMinion.Server)
164+
log.Printf("[SaltMinionRunRequestHandler] salt master (depricated): %s", saltMinion.Server)
163165
masterConf, _ = yaml.Marshal(map[string][]string{"master": []string{saltMinion.Server}})
166+
restartNeeded = isSaltMinionRestartNeeded([]string{saltMinion.Server})
164167
}
168+
165169
err = ioutil.WriteFile(baseDir+"/etc/salt/minion.d/master.conf", masterConf, 0644)
166170
if err != nil {
167171
resp = model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}
@@ -177,8 +181,13 @@ func SaltMinionRunRequestHandler(w http.ResponseWriter, req *http.Request) {
177181
}
178182

179183
log.Println("[SaltMinionRunRequestHandler] execute salt-minion run request")
180-
resp, _ = LaunchService("salt-minion")
181-
resp.WriteHttp(w)
184+
if restartNeeded {
185+
resp, _ = RestartService("salt-minion")
186+
resp.WriteHttp(w)
187+
} else {
188+
resp, _ = LaunchService("salt-minion")
189+
resp.WriteHttp(w)
190+
}
182191
}
183192

184193
func SaltMinionStopRequestHandler(w http.ResponseWriter, req *http.Request) {
@@ -371,3 +380,32 @@ func distributePillarImpl(distributeActionRequest func([]string, string, string,
371380
}
372381
return result
373382
}
383+
384+
func isSaltMinionRestartNeeded(servers []string) bool {
385+
log.Println("[isSaltMinionRestartNeeded] check whether salt-minion requires restart")
386+
masterConfFile := "/etc/salt/minion.d/master.conf"
387+
b, err := ioutil.ReadFile(masterConfFile)
388+
if err == nil && len(b) > 0 {
389+
var saltMasterIps map[string][]string = make(map[string][]string)
390+
if err := yaml.Unmarshal(b, saltMasterIps); err != nil {
391+
log.Printf("[isSaltMinionRestartNeeded] failed to unmarshal salt master config file: %s", err.Error())
392+
return false
393+
}
394+
ipList := saltMasterIps["master"]
395+
log.Printf("[isSaltMinionRestartNeeded] original master IP list: %s", ipList)
396+
for _, server := range servers {
397+
newMaster := true
398+
for _, ip := range ipList {
399+
if ip == server {
400+
newMaster = false
401+
}
402+
}
403+
if newMaster {
404+
log.Printf("[isSaltMinionRestartNeeded] found new salt-master: %s, restart needed", server)
405+
return true
406+
}
407+
}
408+
}
409+
log.Println("[isSaltMinionRestartNeeded] there is no new salt-master")
410+
return false
411+
}

saltboot/service.go

+31-10
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,20 @@ import (
99
"strings"
1010
)
1111

12-
func LaunchService(service string) (resp model.Response, err error) {
13-
log.Printf("[LaunchService] check if service: %s is running", service)
14-
psOutput, _ := ExecCmd("ps", "aux")
15-
alreadyRunning := strings.Contains(psOutput, service)
12+
func RestartService(service string) (model.Response, error) {
13+
alreadyRunning, psOutput := IsServiceRunning(service)
14+
15+
if alreadyRunning {
16+
log.Printf("[RestartService] %s is already running %s, restart", service, psOutput)
17+
return SetServiceState(service, RESTART_ACTION)
18+
} else {
19+
log.Printf("[RestartService] %s is not running (no need to stop first) and will be started", service)
20+
return LaunchService(service)
21+
}
22+
}
23+
24+
func LaunchService(service string) (model.Response, error) {
25+
alreadyRunning, psOutput := IsServiceRunning(service)
1626

1727
if alreadyRunning {
1828
log.Printf("[LaunchService] %s is already running %s", service, psOutput)
@@ -21,21 +31,32 @@ func LaunchService(service string) (resp model.Response, err error) {
2131
log.Printf("[LaunchService] %s is not running and will be started", service)
2232
}
2333

24-
return SetServiceState(service, true)
34+
return SetServiceState(service, START_ACTION)
35+
}
36+
37+
func StopService(service string) (model.Response, error) {
38+
return SetServiceState(service, STOP_ACTION)
2539
}
2640

27-
func StopService(service string) (resp model.Response, err error) {
28-
return SetServiceState(service, false)
41+
func IsServiceRunning(service string) (bool, string) {
42+
log.Printf("[IsServiceRunning] check if service: %s is running", service)
43+
psOutput, _ := ExecCmd("ps", "aux")
44+
return strings.Contains(psOutput, service), psOutput
2945
}
3046

31-
func SetServiceState(service string, up bool) (resp model.Response, err error) {
47+
func SetServiceState(service string, serviceAction string) (resp model.Response, err error) {
3248
initSystem := GetInitSystem(os.Stat)
33-
action := initSystem.ActionCommand(service, up)
49+
action := initSystem.ActionCommand(service, serviceAction)
3450
result, err := ExecCmd(action[0], action[1:len(action)]...)
3551
if err != nil {
3652
return model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}, err
3753
}
38-
state := initSystem.StateCommand(service, up)
54+
var state []string
55+
if serviceAction == STOP_ACTION {
56+
state = initSystem.StateCommand(service, false)
57+
} else {
58+
state = initSystem.StateCommand(service, true)
59+
}
3960
result, err = ExecCmd(state[0], state[1:len(state)]...)
4061
if err != nil {
4162
return model.Response{ErrorText: err.Error(), StatusCode: http.StatusInternalServerError}, err

0 commit comments

Comments
 (0)