2017-05-06 14:37:24 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"syscall"
|
2017-05-07 03:37:30 +02:00
|
|
|
"time"
|
2017-05-06 14:37:24 +02:00
|
|
|
|
|
|
|
"github.com/NYTimes/gziphandler"
|
2018-06-30 01:45:51 +02:00
|
|
|
"github.com/genofire/golang-lib/file"
|
2017-05-29 22:55:38 +02:00
|
|
|
httpLib "github.com/genofire/golang-lib/http"
|
|
|
|
"github.com/genofire/golang-lib/worker"
|
2018-06-30 01:45:51 +02:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
|
|
|
|
respondYanic "github.com/FreifunkBremen/yanic/respond"
|
|
|
|
runtimeYanic "github.com/FreifunkBremen/yanic/runtime"
|
2017-05-06 14:37:24 +02:00
|
|
|
|
2017-05-06 19:44:37 +02:00
|
|
|
"github.com/FreifunkBremen/freifunkmanager/runtime"
|
2017-05-06 14:37:24 +02:00
|
|
|
"github.com/FreifunkBremen/freifunkmanager/ssh"
|
2017-05-08 19:13:29 +02:00
|
|
|
"github.com/FreifunkBremen/freifunkmanager/websocket"
|
2017-05-06 14:37:24 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2018-06-30 01:45:51 +02:00
|
|
|
configFile string
|
|
|
|
config = &runtime.Config{}
|
|
|
|
nodes *runtime.Nodes
|
|
|
|
collector *respondYanic.Collector
|
|
|
|
verbose bool
|
2017-05-06 14:37:24 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
flag.StringVar(&configFile, "config", "config.conf", "path of configuration file (default:config.conf)")
|
2018-06-30 01:45:51 +02:00
|
|
|
flag.BoolVar(&verbose, "v", false, "verbose logging")
|
2017-05-06 14:37:24 +02:00
|
|
|
flag.Parse()
|
2018-06-30 01:45:51 +02:00
|
|
|
if verbose {
|
|
|
|
log.SetLevel(log.DebugLevel)
|
|
|
|
}
|
2017-05-06 14:37:24 +02:00
|
|
|
|
2018-06-30 01:45:51 +02:00
|
|
|
if err := file.ReadTOML(configFile, config); err != nil {
|
|
|
|
log.Panicf("Error during read config: %s", err)
|
|
|
|
}
|
2017-05-06 14:37:24 +02:00
|
|
|
|
2018-06-30 01:45:51 +02:00
|
|
|
log.Info("starting...")
|
2017-05-06 14:37:24 +02:00
|
|
|
|
2018-07-24 15:07:11 +02:00
|
|
|
sshmanager := ssh.NewManager(config.SSHPrivateKey, config.SSHTimeout.Duration)
|
2017-05-30 16:39:14 +02:00
|
|
|
nodes = runtime.NewNodes(config.StatePath, config.SSHInterface, sshmanager)
|
2017-05-08 19:13:29 +02:00
|
|
|
nodesSaveWorker := worker.NewWorker(time.Duration(3)*time.Second, nodes.Saver)
|
2018-06-30 01:45:51 +02:00
|
|
|
nodesUpdateWorker := worker.NewWorker(time.Duration(3)*time.Minute, nodes.Updater)
|
|
|
|
nodesYanic := runtimeYanic.NewNodes(&runtimeYanic.NodesConfig{})
|
2017-05-07 03:37:30 +02:00
|
|
|
|
2018-07-24 15:07:11 +02:00
|
|
|
db := runtime.NewYanicDB(nodes, config.SSHIPAddressSuffix)
|
2017-05-08 19:13:29 +02:00
|
|
|
go nodesSaveWorker.Start()
|
2018-06-30 01:45:51 +02:00
|
|
|
go nodesUpdateWorker.Start()
|
2017-05-06 19:44:37 +02:00
|
|
|
|
2018-06-30 16:20:54 +02:00
|
|
|
ws := websocket.NewWebsocketServer(config.Secret, nodes)
|
|
|
|
nodes.AddNotifyStats(ws.SendStats)
|
|
|
|
nodes.AddNotifyNode(ws.SendNode)
|
2017-05-15 21:59:48 +02:00
|
|
|
|
2018-07-17 23:11:47 +02:00
|
|
|
if config.YanicEnable {
|
|
|
|
if duration := config.YanicSynchronize.Duration; duration > 0 {
|
|
|
|
now := time.Now()
|
|
|
|
delay := duration - now.Sub(now.Truncate(duration))
|
|
|
|
log.Printf("delaying %0.1f seconds", delay.Seconds())
|
|
|
|
time.Sleep(delay)
|
|
|
|
}
|
|
|
|
collector = respondYanic.NewCollector(db, nodesYanic, make(map[string][]string), []respondYanic.InterfaceConfig{config.Yanic})
|
|
|
|
if duration := config.YanicCollectInterval.Duration; duration > 0 {
|
|
|
|
collector.Start(config.YanicCollectInterval.Duration)
|
|
|
|
}
|
2018-06-30 01:45:51 +02:00
|
|
|
defer collector.Close()
|
2018-07-17 23:11:47 +02:00
|
|
|
log.Info("started Yanic collector")
|
2017-05-06 19:44:37 +02:00
|
|
|
}
|
2017-05-06 14:37:24 +02:00
|
|
|
|
2017-05-08 19:13:29 +02:00
|
|
|
// Startwebserver
|
|
|
|
http.HandleFunc("/nodes", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
httpLib.Write(w, nodes)
|
|
|
|
})
|
2017-05-15 21:59:48 +02:00
|
|
|
http.HandleFunc("/stats", func(w http.ResponseWriter, r *http.Request) {
|
2018-06-30 16:20:54 +02:00
|
|
|
httpLib.Write(w, nodes.Statistics)
|
2017-05-15 21:59:48 +02:00
|
|
|
})
|
2017-05-08 19:13:29 +02:00
|
|
|
http.Handle("/", gziphandler.GzipHandler(http.FileServer(http.Dir(config.Webroot))))
|
2017-05-06 14:37:24 +02:00
|
|
|
|
|
|
|
srv := &http.Server{
|
2017-05-08 19:13:29 +02:00
|
|
|
Addr: config.WebserverBind,
|
2017-05-06 14:37:24 +02:00
|
|
|
}
|
2017-05-08 19:13:29 +02:00
|
|
|
|
2017-05-06 14:37:24 +02:00
|
|
|
go func() {
|
2018-06-30 16:20:54 +02:00
|
|
|
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
2018-06-30 01:45:51 +02:00
|
|
|
log.Panic(err)
|
2017-05-06 14:37:24 +02:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2018-06-30 01:45:51 +02:00
|
|
|
log.Info("started")
|
2017-05-06 14:37:24 +02:00
|
|
|
|
|
|
|
// Wait for system signal
|
|
|
|
sigs := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
sig := <-sigs
|
|
|
|
|
2018-06-30 16:20:54 +02:00
|
|
|
ws.Close()
|
2018-06-30 01:45:51 +02:00
|
|
|
|
|
|
|
// Stop services
|
2017-05-06 14:37:24 +02:00
|
|
|
srv.Close()
|
2017-05-07 03:37:30 +02:00
|
|
|
nodesSaveWorker.Close()
|
2018-06-30 01:45:51 +02:00
|
|
|
nodesUpdateWorker.Close()
|
2017-05-06 14:37:24 +02:00
|
|
|
|
2018-06-30 01:45:51 +02:00
|
|
|
log.Info("stop recieve:", sig)
|
2017-05-06 14:37:24 +02:00
|
|
|
}
|