forked from pivotal-cf/cf-redis-broker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
125 lines (105 loc) · 3.32 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
package main
import (
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"code.cloudfoundry.org/lager"
"github.com/pivotal-cf/cf-redis-broker/availability"
"github.com/pivotal-cf/cf-redis-broker/brokerconfig"
"github.com/pivotal-cf/cf-redis-broker/process"
"github.com/pivotal-cf/cf-redis-broker/redis"
)
func main() {
logger := lager.NewLogger("process-monitor")
logger.RegisterSink(lager.NewWriterSink(os.Stdout, lager.DEBUG))
logger.RegisterSink(lager.NewWriterSink(os.Stderr, lager.ERROR))
sigChannel := make(chan os.Signal, 1)
signal.Notify(sigChannel, syscall.SIGUSR1)
skipProcessCheck := false
go func() {
<-sigChannel
logger.Info("Trapped USR1, disabling process monitor")
skipProcessCheck = true
}()
config, err := brokerconfig.ParseConfig(configPath())
if err != nil {
logger.Fatal("could not parse config file", err, lager.Data{
"config-path": configPath(),
})
}
logger.Info("Starting process monitor")
repo := redis.NewLocalRepository(config.RedisConfiguration, logger)
setPidDir(repo)
processController := redis.NewOSProcessController(
logger,
repo,
new(process.ProcessChecker),
new(process.ProcessKiller),
redis.PingServer,
availability.Check,
"",
)
checkInterval := config.RedisConfiguration.ProcessCheckIntervalSeconds
instances, _ := repo.AllInstancesVerbose()
for _, instance := range instances {
copyConfigFile(instance, repo, logger)
}
for {
if skipProcessCheck {
logger.Info("Skipping instance check")
} else {
instances, _ := repo.AllInstances()
for _, instance := range instances {
ensureRunningIfNotLocked(instance, repo, processController, logger)
}
}
time.Sleep(time.Second * time.Duration(checkInterval))
}
}
func ensureRunningIfNotLocked(instance *redis.Instance, repo *redis.LocalRepository, processController *redis.OSProcessController, logger lager.Logger) {
_, err := os.Stat(filepath.Join(repo.InstanceBaseDir(instance.ID), "lock"))
if err != nil {
ensureRunning(instance, repo, processController, logger)
}
}
func copyConfigFile(instance *redis.Instance, repo *redis.LocalRepository, logger lager.Logger) {
err := repo.EnsureDirectoriesExist(instance)
if err != nil {
logger.Fatal("Error creating instance directories", err, lager.Data{
"instance": instance.ID,
})
}
err = repo.WriteConfigFile(instance)
if err != nil {
logger.Fatal("Error writing redis config", err, lager.Data{
"instance": instance.ID,
})
}
}
func ensureRunning(instance *redis.Instance, repo *redis.LocalRepository, processController *redis.OSProcessController, logger lager.Logger) {
configPath := repo.InstanceConfigPath(instance.ID)
instanceDataDir := repo.InstanceDataDir(instance.ID)
pidfilePath := repo.InstancePidFilePath(instance.ID)
logfilePath := repo.InstanceLogFilePath(instance.ID)
err := processController.EnsureRunning(instance, configPath, instanceDataDir, pidfilePath, logfilePath)
if err != nil {
logger.Fatal("Error starting instance", err, lager.Data{
"instance": instance.ID,
})
}
}
func configPath() string {
brokerConfigYamlPath := os.Getenv("BROKER_CONFIG_PATH")
if brokerConfigYamlPath == "" {
panic("BROKER_CONFIG_PATH not set")
}
return brokerConfigYamlPath
}
func setPidDir(localRepo *redis.LocalRepository) {
pidDir := os.Getenv("SHARED_PID_DIR")
if pidDir != "" {
localRepo.RedisConf.PidfileDirectory = pidDir
}
}