Skip to content

Commit

Permalink
[TASK] add respond(d) daemon - WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
genofire committed Jan 25, 2019
1 parent bd13b99 commit 76a4410
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ _testmain.go
*.prof
webroot
/config.toml
/config-respondd.toml
/vendor
31 changes: 4 additions & 27 deletions cmd/config.go
Original file line number Diff line number Diff line change
@@ -1,54 +1,31 @@
package cmd

import (
"fmt"
"io/ioutil"
"os"

"github.com/naoina/toml"

"github.com/FreifunkBremen/yanic/database"
"github.com/FreifunkBremen/yanic/respond"
"github.com/FreifunkBremen/yanic/runtime"
"github.com/FreifunkBremen/yanic/webserver"
)

// Config represents the whole configuration
type Config struct {
Respondd respond.Config
Webserver webserver.Config
Nodes runtime.NodesConfig
Database database.Config
}

var (
configPath string
collector *respond.Collector
nodes *runtime.Nodes
)

func loadConfig() *Config {
config, err := ReadConfigFile(configPath)
if err != nil {
fmt.Fprintln(os.Stderr, "unable to load config file:", err)
os.Exit(2)
}
return config
}

// ReadConfigFile reads a config model from path of a yml file
func ReadConfigFile(path string) (config *Config, err error) {
config = &Config{}

func ReadConfigFile(path string, config interface{}) error {
file, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
return err
}

err = toml.Unmarshal(file, config)
if err != nil {
return nil, err
return err
}

return
return nil
}
8 changes: 5 additions & 3 deletions cmd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
func TestReadConfig(t *testing.T) {
assert := assert.New(t)

config, err := ReadConfigFile("../config_example.toml")
config := &ServeConfig{}
err := ReadConfigFile("../config_example.toml", config)

assert.NoError(err)
assert.NotNil(config)

Expand Down Expand Up @@ -40,11 +42,11 @@ func TestReadConfig(t *testing.T) {
},
}, meshviewer)

_, err = ReadConfigFile("testdata/config_invalid.toml")
err = ReadConfigFile("testdata/config_invalid.toml", config)
assert.Error(err, "not unmarshalable")
assert.Contains(err.Error(), "invalid TOML syntax")

_, err = ReadConfigFile("testdata/adsa.toml")
err = ReadConfigFile("testdata/adsa.toml", config)
assert.Error(err, "not found able")
assert.Contains(err.Error(), "no such file or directory")
}
5 changes: 4 additions & 1 deletion cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ var importCmd = &cobra.Command{
path := args[0]
site := args[1]
domain := args[2]
config := loadConfig()
config := &ServeConfig{}
if err := ReadConfigFile(configPath, config); err != nil {
log.Panicf("unable to load config file: %s", err)
}

err := allDatabase.Start(config.Database)
if err != nil {
Expand Down
40 changes: 40 additions & 0 deletions cmd/respondd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cmd

import (
"os"
"os/signal"
"syscall"

"github.com/bdlm/log"
"github.com/spf13/cobra"

"github.com/FreifunkBremen/yanic/respond/daemon"
)

// serveCmd represents the serve command
var responddCMD = &cobra.Command{
Use: "respondd",
Short: "Runs a respond daemon",
Example: "yanic respondd --config /etc/respondd.toml",
Run: func(cmd *cobra.Command, args []string) {
daemon := &respondd.Daemon{}
if err := ReadConfigFile(configPath, daemon); err != nil {
log.Panicf("unable to load config file: %s", err)
}

go daemon.Start()

log.Info("respondd daemon started")
// Wait for INT/TERM
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
sig := <-sigs
log.Infof("received %s", sig)

},
}

func init() {
RootCmd.AddCommand(responddCMD)
responddCMD.Flags().StringVarP(&configPath, "config", "c", "config-respondd.toml", "Path to configuration file")
}
20 changes: 15 additions & 5 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,42 @@ import (
"github.com/bdlm/log"
"github.com/spf13/cobra"

"github.com/FreifunkBremen/yanic/database"
allDatabase "github.com/FreifunkBremen/yanic/database/all"
allOutput "github.com/FreifunkBremen/yanic/output/all"
"github.com/FreifunkBremen/yanic/respond"
"github.com/FreifunkBremen/yanic/runtime"
"github.com/FreifunkBremen/yanic/webserver"
)

// Config represents the whole configuration
type ServeConfig struct {
Respondd respond.Config
Webserver webserver.Config
Nodes runtime.NodesConfig
Database database.Config
}

// serveCmd represents the serve command
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Runs the yanic server",
Example: "yanic serve --config /etc/yanic.toml",
Run: func(cmd *cobra.Command, args []string) {
config := loadConfig()
config := &ServeConfig{}
if err := ReadConfigFile(configPath, config); err != nil {
log.Panicf("unable to load config file: %s", err)
}

err := allDatabase.Start(config.Database)
if err != nil {
if err := allDatabase.Start(config.Database); err != nil {
log.Panicf("could not connect to database: %s", err)
}
defer allDatabase.Close()

nodes = runtime.NewNodes(&config.Nodes)
nodes.Start()

err = allOutput.Start(nodes, config.Nodes)
if err != nil {
if err := allOutput.Start(nodes, config.Nodes); err != nil {
log.Panicf("error on init outputs: %s", err)
}
defer allOutput.Close()
Expand Down
15 changes: 15 additions & 0 deletions config-respondd_example.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# how ofter the cache respond of a respondd request is calculated
data_interval = "3m"

# if set true, respond will contain data from batman interface
multi_instance = false

[[listen]]
address = "ff02::2:1001"
interface = ""
port = 1001

# manuelle data for respond
[data.nodeinfo.location]
latitude = 53.112446246
longitude = 8.734087944
13 changes: 13 additions & 0 deletions contrib/init/linux-systemd/respondd.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=yanic

[Service]
Type=simple
User=yanic
ExecStart=/opt/go/bin/yanic respondd --config /etc/respondd.conf
Restart=always
RestartSec=5s
Environment=PATH=/usr/bin:/usr/local/bin

[Install]
WantedBy=multi-user.target
6 changes: 3 additions & 3 deletions data/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package data

// ResponseData struct
type ResponseData struct {
Neighbours *Neighbours `json:"neighbours"`
Nodeinfo *Nodeinfo `json:"nodeinfo"`
Statistics *Statistics `json:"statistics"`
Nodeinfo *Nodeinfo `json:"nodeinfo" toml:"nodeinfo"`
Statistics *Statistics `json:"statistics" toml:"statistics"`
Neighbours *Neighbours `json:"neighbours" toml:"neighbours"`
}
19 changes: 2 additions & 17 deletions respond/collector.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package respond

import (
"bytes"
"compress/flate"
"encoding/json"
"fmt"
"net"
"time"
Expand Down Expand Up @@ -86,7 +83,7 @@ func (coll *Collector) listenUDP(iface InterfaceConfig) {
if err != nil {
log.Panic(err)
}
conn.SetReadBuffer(maxDataGramSize)
conn.SetReadBuffer(MaxDataGramSize)

coll.connections = append(coll.connections, multicastConn{
Conn: conn,
Expand Down Expand Up @@ -245,18 +242,6 @@ func (coll *Collector) parser() {
}
}

func (res *Response) parse() (*data.ResponseData, error) {
// Deflate
deflater := flate.NewReader(bytes.NewReader(res.Raw))
defer deflater.Close()

// Unmarshal
rdata := &data.ResponseData{}
err := json.NewDecoder(deflater).Decode(rdata)

return rdata, err
}

func (coll *Collector) saveResponse(addr *net.UDPAddr, res *data.ResponseData) {
// Search for NodeID
var nodeID string
Expand Down Expand Up @@ -308,7 +293,7 @@ func (coll *Collector) saveResponse(addr *net.UDPAddr, res *data.ResponseData) {
}

func (coll *Collector) receiver(conn *net.UDPConn) {
buf := make([]byte, maxDataGramSize)
buf := make([]byte, MaxDataGramSize)
for {
n, src, err := conn.ReadFromUDP(buf)

Expand Down
65 changes: 65 additions & 0 deletions respond/daemon/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package respondd

import (
"io/ioutil"
"os"
"strings"

"github.com/FreifunkBremen/yanic/data"
)

func trim(s string) string {
return strings.TrimSpace(strings.Trim(s, "\n"))
}

func (d *Daemon) updateData() {
nodeID := ""
// Nodeinfo
if d.Data.Nodeinfo == nil {
d.Data.Nodeinfo = &data.Nodeinfo{}
} else {
nodeID = d.Data.Nodeinfo.NodeID
}
if d.Data.Nodeinfo.Hostname == "" {
d.Data.Nodeinfo.Hostname, _ = os.Hostname()
}

// Statistics
if d.Data.Statistics == nil {
d.Data.Statistics = &data.Statistics{}
} else if nodeID == "" {
nodeID = d.Data.Statistics.NodeID
}

// Neighbours
if d.Data.Neighbours == nil {
d.Data.Neighbours = &data.Neighbours{}
} else if nodeID == "" {
nodeID = d.Data.Neighbours.NodeID
}

if nodeID == "" && !d.MultiInstance {
if v, err := ioutil.ReadFile("/etc/machine-id"); err == nil {
nodeID = trim(string(v))[:12]
}
}
d.Data.Nodeinfo.NodeID = nodeID
d.Data.Statistics.NodeID = nodeID
d.Data.Neighbours.NodeID = nodeID

for _, data := range d.dataByInterface {
data.Nodeinfo = d.Data.Nodeinfo
}
}

func (d *Daemon) getData(iface string) *data.ResponseData {
if !d.MultiInstance {
return d.Data
}
if data, ok := d.dataByInterface[iface]; ok {
return data
}
d.dataByInterface[iface] = &data.ResponseData{}
d.updateData()
return d.dataByInterface[iface]
}
Loading

0 comments on commit 76a4410

Please sign in to comment.