v0.2.5: Reloading a badly formated configuration wont crash, so the old configuration will keep running.
This commit is contained in:
parent
fe6ca819f4
commit
8958845f65
60
main.go
60
main.go
@ -34,7 +34,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
gVersion = "0.2.4"
|
gVersion = "0.2.5"
|
||||||
// Default datasource timeout is 10 seconds
|
// Default datasource timeout is 10 seconds
|
||||||
gDefaultDSTimeout = 10
|
gDefaultDSTimeout = 10
|
||||||
)
|
)
|
||||||
@ -329,7 +329,7 @@ func getGraph(name string) (Graph, error) {
|
|||||||
return Graph{}, fmt.Errorf("Graph not found: %s", name)
|
return Graph{}, fmt.Errorf("Graph not found: %s", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initRoutes(r *gin.Engine) {
|
func initRoutes(r *gin.Engine, confFile string) {
|
||||||
r.GET("/ping", func(c *gin.Context) {
|
r.GET("/ping", func(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"message": "pong",
|
"message": "pong",
|
||||||
@ -338,7 +338,10 @@ func initRoutes(r *gin.Engine) {
|
|||||||
|
|
||||||
// An endpoint to force read of configuration file
|
// An endpoint to force read of configuration file
|
||||||
r.POST("/reload", func(c *gin.Context) {
|
r.POST("/reload", func(c *gin.Context) {
|
||||||
reloadConfigFile()
|
if err := reloadConfigFile(confFile); err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"message": "configuration successfully reloaded",
|
"message": "configuration successfully reloaded",
|
||||||
})
|
})
|
||||||
@ -469,16 +472,32 @@ func newEdgeClone(src *Edge) *Edge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reloadConfigFile() {
|
// This function assume we already have a running configuration.
|
||||||
// First reread config file
|
func reloadConfigFile(confFile string) error {
|
||||||
if err := viper.ReadInConfig(); err != nil {
|
oldConfigRestored := false
|
||||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
// We need to keep this config, incase the new one is b0rken
|
||||||
log.Fatalf("config file not found")
|
fname := fmt.Sprintf("/tmp/nodegopher.%d.yaml", os.Getpid())
|
||||||
os.Exit(1)
|
if err := viper.WriteConfigAs(fname); err != nil {
|
||||||
} else {
|
log.Errorf("Unable to save current running config to %s, wont reload configuration.\n", fname)
|
||||||
log.Fatalf("unknown error looking for config file: %v", err)
|
return fmt.Errorf("Unable to save current configuration, configuration not reloaded. See logs.")
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
defer os.Remove(fname)
|
||||||
|
|
||||||
|
// Reread config file
|
||||||
|
if oldErr := viper.ReadInConfig(); oldErr != nil {
|
||||||
|
if _, ok := oldErr.(viper.ConfigFileNotFoundError); ok {
|
||||||
|
log.Errorf("config file not found")
|
||||||
|
} else {
|
||||||
|
log.Errorf("unknown error looking for config file: %v", oldErr)
|
||||||
|
}
|
||||||
|
// Restore old configuration and notify.
|
||||||
|
log.Debugf("Fallback on previous configuration.\n")
|
||||||
|
viper.SetConfigFile(fname)
|
||||||
|
if err := viper.ReadInConfig(); err != nil {
|
||||||
|
log.Fatalf("Unable to restore configuration, and new is invalid. fix it now.\n")
|
||||||
|
}
|
||||||
|
viper.SetConfigFile(confFile)
|
||||||
|
oldConfigRestored = true
|
||||||
}
|
}
|
||||||
|
|
||||||
switch viper.Get("language").(string) {
|
switch viper.Get("language").(string) {
|
||||||
@ -503,6 +522,7 @@ func reloadConfigFile() {
|
|||||||
gCfgMutex.Lock()
|
gCfgMutex.Lock()
|
||||||
defer gCfgMutex.Unlock()
|
defer gCfgMutex.Unlock()
|
||||||
|
|
||||||
|
// We need to keep this config, incase the new one is b0rken
|
||||||
for _, g := range gGraphs {
|
for _, g := range gGraphs {
|
||||||
g.Nodes = nil
|
g.Nodes = nil
|
||||||
g.Edges = nil
|
g.Edges = nil
|
||||||
@ -538,8 +558,8 @@ func reloadConfigFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if viper.Get("datasources") == nil {
|
if viper.Get("datasources") == nil {
|
||||||
log.Printf("no datasources found, data will be static")
|
log.Warningf("no datasources found, data will be static")
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
dss := viper.Get("datasources").([]interface{})
|
dss := viper.Get("datasources").([]interface{})
|
||||||
for _, d := range dss {
|
for _, d := range dss {
|
||||||
@ -552,6 +572,10 @@ func reloadConfigFile() {
|
|||||||
}
|
}
|
||||||
gDataSources = append(gDataSources, ds)
|
gDataSources = append(gDataSources, ds)
|
||||||
}
|
}
|
||||||
|
if oldConfigRestored {
|
||||||
|
return fmt.Errorf("Unable to load new configuration, keeping old one. See logs.")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -604,7 +628,7 @@ func main() {
|
|||||||
// FIXME: Watch config changes. Does not work on FreeBSD. TODO: Test with linux
|
// FIXME: Watch config changes. Does not work on FreeBSD. TODO: Test with linux
|
||||||
viper.OnConfigChange(func(e fsnotify.Event) {
|
viper.OnConfigChange(func(e fsnotify.Event) {
|
||||||
log.Printf("Config file changed, reloading data\n")
|
log.Printf("Config file changed, reloading data\n")
|
||||||
reloadConfigFile()
|
reloadConfigFile(confFile)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Lets reload config on SIGHUP
|
// Lets reload config on SIGHUP
|
||||||
@ -614,11 +638,11 @@ func main() {
|
|||||||
for {
|
for {
|
||||||
_ = <- sigs
|
_ = <- sigs
|
||||||
log.Infof("SIGHUP received, reloading configuration\n")
|
log.Infof("SIGHUP received, reloading configuration\n")
|
||||||
reloadConfigFile()
|
reloadConfigFile(confFile)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
reloadConfigFile()
|
reloadConfigFile(confFile)
|
||||||
|
|
||||||
// Capture variable name. There should be only one variable. Space is tolerated before and after name.
|
// Capture variable name. There should be only one variable. Space is tolerated before and after name.
|
||||||
gDSVarCompRegex = regexp.MustCompile(`^\{\{(?:\ )?([a-zA-Z0-9\-_]+)(?:\ )?\}\}$`)
|
gDSVarCompRegex = regexp.MustCompile(`^\{\{(?:\ )?([a-zA-Z0-9\-_]+)(?:\ )?\}\}$`)
|
||||||
@ -629,6 +653,6 @@ func main() {
|
|||||||
log.Printf("Starting NodeGopher v.%s\n", gVersion)
|
log.Printf("Starting NodeGopher v.%s\n", gVersion)
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
initRoutes(r)
|
initRoutes(r, confFile)
|
||||||
r.Run(listen)
|
r.Run(listen)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user