diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..9a9c5778 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,5 @@ +## Contributing is welcome + +Pull requests are welcome without the need of opening an issue. If you're unsure +about your feature or your implementation open an issue and discuss your +suggested changes. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..4009262a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,16 @@ + + +## Description + + +## Motivation and Context + + + +## Checklist: + + +- [ ] My code follows the code style of this project. +- [ ] I have added also tests for my new code. +- [ ] My change requires a change to the documentation. +- [ ] I have updated the documentation accordingly. diff --git a/.test-coverage b/.test-coverage index c6bd28b1..daf9b8d9 100755 --- a/.test-coverage +++ b/.test-coverage @@ -30,4 +30,22 @@ if [ "$FAIL" -eq 0 ]; then bash <(curl -s https://codecov.io/bash) -t $CODECOV_TOKEN -f profile.cov fi +# Test if every package has testfiles +for dir in $(find . -name "*.go" -printf '%h\0'| sort -zu | sed -z 's/$/\n/'); +do + if [ "$(ls $dir/*_test.go 2> /dev/null | wc -l)" -eq "0" ]; then + echo -n "no test files for $dir"; + case $dir in + '.' | './cmd' | './database/graphite') + echo " - but ignored"; + continue + ;; + *) + echo ""; + FAIL=1; + ;; + esac + fi +done + exit $FAIL diff --git a/INSTALL.md b/INSTALL.md index d877bb31..8d890e11 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,12 +1,13 @@ # Howto install Yanic ## go + ### Install ```sh cd /usr/local/ -wget https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz -tar xvf go1.8.linux-amd64.tar.gz -rm go1.8.linux-amd64.tar.gz +wget https://storage.googleapis.com/golang/go1.9.1.linux-amd64.tar.gz -O go-release-linux-amd64.tar.gz +tar xvf go-release-linux-amd64.tar.gz +rm go-release-linux-amd64.tar.gz ``` ### Configure go @@ -16,12 +17,6 @@ export GOPATH=/opt/go export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin ``` -and these in the shell startup file of a normal user: -```sh -export GOPATH=~/go -export PATH=$PATH:$GOPATH/bin -``` - ## Yanic ### Compile @@ -65,7 +60,7 @@ the same directory as the `dataPath`. Change the path in the section ### Service ```sh -cp /opt/go/src/github.com/FreifunkBremen/yanic/contrib/init/linux-systemd/yanic.service /lib/systemd/system/ +cp /opt/go/src/github.com/FreifunkBremen/yanic/contrib/init/linux-systemd/yanic.service /lib/systemd/system/yanic.service systemctl daemon-reload systemctl start yanic systemctl enable yanic diff --git a/README.md b/README.md index dd1b3a61..a1f26d31 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,9 @@ Yet another node info collector In the first step Yanic sends a multicast message to the group `ff02:0:0:0:0:0:2:1001` and port `1001`. Recently seen nodes that does not reply are requested via a unicast message. -## [Documentation](https://www.gitbook.com/book/freifunkbremen/yanic/details) -* [Webview](https://freifunkbremen.gitbooks.io/yanic/content/) -* [PDF](https://www.gitbook.com/download/pdf/book/freifunkbremen/yanic) -* [Mobi](https://www.gitbook.com/download/mobi/book/freifunkbremen/yanic) -* [ePUB](https://www.gitbook.com/download/epub/book/freifunkbremen/yanic) +## Documentation +Take a look at the [git](https://github.com/FreifunkBremen/yanic/blob/master/SUMMARY.md) or [Gitbook](https://freifunkbremen.gitbooks.io/yanic/content/) + ## Configuration Read comments in [config_example.toml](config_example.toml) for more information. diff --git a/SUMMARY.md b/SUMMARY.md new file mode 100644 index 00000000..54722733 --- /dev/null +++ b/SUMMARY.md @@ -0,0 +1,15 @@ +# Summary + +* [Home](/docs/index.md) +* [About](/docs/home_about.md) +* [Running](/docs/home_running.md) + +* Documentation + * [Build and Install](/docs/docs_install.md) + * [Usage](/docs/docs_usage.md) + * [Quick Configuration](/docs/docs_quick_conf.md) + * [Configuration](/docs/docs_configuration.md) + +* Developing + * [Add new database type](/docs/dev_database.md) + * [Add new output type](/docs/dev_output.md) diff --git a/book.json b/book.json new file mode 100644 index 00000000..df9cbdde --- /dev/null +++ b/book.json @@ -0,0 +1,22 @@ +{ + "plugins": [ + "theme-api", + "anchors", + "sitemap" + ], + "pluginsConfig": { + "theme-api": { + "split": true, + "languages": [ + { + "lang": "toml", + "name": "TOML", + "default": true + } + ] + }, + "sitemap": { + "hostname": "https://freifunkbremen.gitbooks.io/yanic/" + } + } +} diff --git a/config_example.toml b/config_example.toml index b681c4fe..58ebc070 100644 --- a/config_example.toml +++ b/config_example.toml @@ -1,6 +1,6 @@ # This is the config file for Yanic written in "Tom's Obvious, Minimal Language." # syntax: https://github.com/toml-lang/toml -# (if you need somethink multiple times, checkout out the [[table]] section) +# (if you need somethink multiple times, checkout out the [[array of table]] section) # Send respondd request to update information [respondd] @@ -27,7 +27,6 @@ webroot = "/var/www/html/meshviewer" [nodes] -enable = true # Cache file # a json file to cache all data collected directly from respondd state_path = "/var/lib/yanic/state.json" @@ -138,17 +137,12 @@ password = "" # Tagging of the data (optional) [database.connection.influxdb.tags] # Tags used by Yanic would override the tags from this config -# nodeid, hostname, owner, model and firmware are tags which are already used +# nodeid, hostname, owner, model, firmware_base, firmware_release,frequency11g and frequency11a are tags which are already used #tagname1 = "tagvalue 1" # some usefull e.g.: #system = "productive" #site = "ffhb" -# Logging -[[database.connection.logging]] -enable = false -path = "/var/log/yanic.log" - # Graphite settings [[database.connection.graphite]] enable = false @@ -160,3 +154,8 @@ address = "localhost:2003" # then the prefix can be set to anything (including the empty string) since you # probably wont care much about "polluting" the namespace. prefix = "freifunk" + +# Logging +[[database.connection.logging]] +enable = false +path = "/var/log/yanic.log" diff --git a/docs/dev_database.md b/docs/dev_database.md new file mode 100644 index 00000000..113b5c07 --- /dev/null +++ b/docs/dev_database.md @@ -0,0 +1,49 @@ +# Add new database type + +Write a new package to implement the interface [database.Connection:](https://github.com/FreifunkBremen/yanic/blob/master/database/database.go) + +```go +type Connection interface { + InsertNode(node *runtime.Node) + + InsertLink(*runtime.Link, time.Time) + + InsertGlobals(*runtime.GlobalStats, time.Time, string) + + PruneNodes(deleteAfter time.Duration) + + Close() +} +``` + +**InsertNode** is stores statistics per node + +**InsertLink** is stores statistics per link + +**InsertGlobals** is stores global statistics (by `site_code`, and "global" like in `runtime.GLOBAL_SITE` overall sites). + +**PruneNodes** is prunes historical per-node data + +**Close** is called during shutdown of Yanic. + + + +For startup, you need to bind your database type by calling `database.RegisterAdapter("typeofdatabase",ConnectFunction)` + +it should be in the `func init() {}` of your package. + + + +The _typeofdatabase_ is used as mapping in the configuration `[[database.connection.typeofdatabase]]` the `map[string]interface{}` of the content are parsed to the _ConnectFunction_ and on of your implemented `Connection` or a `error` is needed as result. + + + +Short: the function signature of _ConnectFunction_ should be `func Connect(configuration interface{}) (Connection, error)` + + + +At last add you import string to compile the your database as well in this [all](https://github.com/FreifunkBremen/yanic/blob/master/database/all/main.go) package. + + + +TIP: take a look in the easy database type [logging](https://github.com/FreifunkBremen/yanic/blob/master/database/logging/file.go). diff --git a/docs/dev_output.md b/docs/dev_output.md new file mode 100644 index 00000000..439b3c88 --- /dev/null +++ b/docs/dev_output.md @@ -0,0 +1,30 @@ +# Add new output type + +Write a new package to implement the interface [output.Output:](https://github.com/FreifunkBremen/yanic/blob/master/output/output.go) + +```go +type Output interface { + Save(nodes *runtime.Nodes) +} +``` + +**Save** a pre-filtered state of the Nodes + + + +For startup, you need to bind your output type by calling + `output.RegisterAdapter("typeofoutput",Register)` + +it should be in the `func init() {}` of your package. + + + +The _typeofoutput_ is used as mapping in the configuration `[[nodes.output.typeofoutput]]` the `map[string]interface{}` of the content are parsed to the _Register_ and on of your implemented `Output` or a `error` is needed as result. + + + +Short: the function signature of _Register_ should be `func Register(configuration map[string]interface{}) (Output, error)` + + + +At last add you import string to compile the your database as well in this [all](https://github.com/FreifunkBremen/yanic/blob/master/output/all/main.go) package. diff --git a/docs/docs_configuration.md b/docs/docs_configuration.md new file mode 100644 index 00000000..d8d84fe8 --- /dev/null +++ b/docs/docs_configuration.md @@ -0,0 +1,585 @@ +# Configuration + +Here you would find a long description, maybe the description in [example file](https://github.com/FreifunkBremen/yanic/blob/master/config_example.toml) are enough for you. + +The config file for Yanic written in "Tom's Obvious, Minimal Language." [syntax](https://github.com/toml-lang/toml). +(if you need somethink multiple times, checkout out the [[array of table]] section) + +## [respondd] +{% method %} +Group for configuration of respondd request. +{% sample lang="toml" %} +```toml +[respondd] +enable = true +# synchronize = "1m" +collect_interval = "1m" +interfaces = ["br-ffhb"] +sites = ["ffhb"] +#port = 10001 +``` +{% endmethod %} + + +### enable +{% method %} +Enable request and collection of data per respondd requests +{% sample lang="toml" %} +```toml +enable = true +``` +{% endmethod %} + + +### synchronize +{% method %} +Delay startup until a multiple of the period since zero time +{% sample lang="toml" %} +```toml +synchronize = "1m" +``` +{% endmethod %} + + +### collect_interval +{% method %} +How often send request per respondd. + +It will send UDP packets with multicast group `ff02::2:1001` and port `1001`. +If a node does not answer after the half time, it will request with the last know address under the port `1001`. +{% sample lang="toml" %} +```toml +collect_interval = "1m" +``` +{% endmethod %} + + +### interfaces +{% method %} +Interface that has an IP in your mesh network +{% sample lang="toml" %} +```toml +interfaces = ["br-ffhb"] +``` +{% endmethod %} + + +### sites +{% method %} +List of sites to save stats for (empty for global only) +{% sample lang="toml" %} +```toml +sites = ["ffhb"] +``` +{% endmethod %} + + +### port +{% method %} +Define a port to listen and send the respondd packages. +If not set or set to 0 the kernel will use a random free port at its own. +{% sample lang="toml" %} +```toml +port = 10001 +``` +{% endmethod %} + + + +## [webserver] +{% method %} +Yanic has a little build-in webserver, which statically serves a directory. +This is useful for testing purposes or for a little standalone installation. +{% sample lang="toml" %} +```toml +[webserver] +enable = false +bind = "127.0.0.1:8080" +webroot = "/var/www/html/meshviewer" +``` +{% endmethod %} + + +### enable +{% method %} +Enable to start the built-in webserver of Yanic +{% sample lang="toml" %} +```toml +enable = false +``` +{% endmethod %} + + +### bind +{% method %} +On which ip address and port listen the webserver +{% sample lang="toml" %} +```toml +bind = "127.0.0.1:8080" +``` +{% endmethod %} + + +### webroot +{% method %} +The path to a folder, which files are published on this webserver. +{% sample lang="toml" %} +```toml +webroot = "/var/www/html/meshviewer" +``` +{% endmethod %} + + + +## [nodes] +{% method %} +{% sample lang="toml" %} +```toml +[nodes] +state_path = "/var/lib/yanic/state.json" +prune_after = "7d" +save_interval = "5s" +offline_after = "10m" +``` +{% endmethod %} + + +### state_path +{% method %} +A json file to cache all data collected directly from respondd. +{% sample lang="toml" %} +```toml +state_path = "/var/lib/yanic/state.json" +``` +{% endmethod %} + + +### prune_after +{% method %} +Prune data in RAM, cache-file and output json files (i.e. nodes.json) that were inactive for longer than. +{% sample lang="toml" %} +```toml +prune_after = "7d" +``` +{% endmethod %} + + +### save_interval +{% method %} +Export nodes and graph periodically. +{% sample lang="toml" %} +```toml +save_interval = "5s" +``` +{% endmethod %} + + +### offline_after +{% method %} +Set node to offline if not seen within this period. +{% sample lang="toml" %} +```toml +offline_after = "10m" +``` +{% endmethod %} + + +## [[nodes.output.example]] +{% method %} +This example block shows all option which is useable for every following output type. +Every output type has his own configuration under `nodes.output`. +It is possible to have multiple output for one type of output, just add this group again with new parameters (see toml [[array of table]]). +{% sample lang="toml" %} +```toml +[[nodes.output.example]] +enable = true +[nodes.output.example.filter] +no_owner = true +blacklist = ["00112233445566", "1337f0badead"] +has_location = true +[nodes.output.example.filter.in_area] +latitude_min = 34.30 +latitude_max = 71.85 +longitude_min = -24.96 +longitude_max = 39.72 +``` +{% endmethod %} + +### enable +{% method %} +Each output format has its own config block and needs to be enabled by adding: +{% sample lang="toml" %} +```toml +enable = true +``` +{% endmethod %} + +### [nodes.output.example.filter] +{% method %} +For each output format there can be set different filters +{% sample lang="toml" %} +```toml +[nodes.output.example.filter] +no_owner = true +blacklist = ["00112233445566", "1337f0badead"] +has_location = true +[nodes.output.example.filter.in_area] +latitude_min = 34.30 +latitude_max = 71.85 +longitude_min = -24.96 +longitude_max = 39.72 +``` +{% endmethod %} + + +### no_owner +{% method %} +Set to false, if you want the json files to contain the owner information +{% sample lang="toml" %} +```toml +no_owner = true +``` +{% endmethod %} + + +### blacklist +{% method %} +List of nodeids of nodes that should be filtered out, so they won't appear in output +{% sample lang="toml" %} +```toml +blacklist = ["00112233445566", "1337f0badead"] +``` +{% endmethod %} + + +### has_location +{% method %} +set has_location to true if you want to include only nodes that have geo-coordinates set +(setting this to false has no sensible effect, unless you'd want to hide nodes that have coordinates) +{% sample lang="toml" %} +```toml +has_location = true +``` +{% endmethod %} + + +### [nodes.output.example.filter.in_area] +{% method %} +nodes outside this area are not shown on the map but are still listed as a node without coordinates +{% sample lang="toml" %} +```toml +latitude_min = 34.30 +latitude_max = 71.85 +longitude_min = -24.96 +longitude_max = 39.72 +``` +{% endmethod %} + + + +## [[nodes.output.meshviewer-ffrgb]] +{% method %} +The new json file format for the [meshviewer](https://github.com/ffrgb/meshviewer) developed in Regensburg. + +{% sample lang="toml" %} +```toml +[[nodes.output.meshviewer-ffrgb]] +enable = true +path = "/var/www/html/meshviewer/data/meshviewer.json" +#[nodes.output.meshviewer-ffrgb.filter] +#no_owner = false +#blacklist = ["00112233445566", "1337f0badead"] +#has_location = true + +#[nodes.output.meshviewer-ffrgb.filter.in_area] +#latitude_min = 34.30 +#latitude_max = 71.85 +#longitude_min = -24.96 +#longitude_max = 39.72 +``` +{% endmethod %} + + +### path +{% method %} +The path, where to store meshviewer.json +{% sample lang="toml" %} +```toml +path = "/var/www/html/meshviewer/data/meshviewer.json" +``` +{% endmethod %} + + + +## [[nodes.output.meshviewer]] +{% method %} +{% sample lang="toml" %} +```toml +[[nodes.output.meshviewer]] +enable = false +version = 2 +nodes_path = "/var/www/html/meshviewer/data/nodes.json" +graph_path = "/var/www/html/meshviewer/data/graph.json" +``` +{% endmethod %} + + +### version +{% method %} +The structure version of the output which should be generated (i.e. nodes.json) +* version 1 is accepted by the legacy meshviewer (which is the master branch) +* https://github.com/ffnord/meshviewer/tree/master +* version 2 is accepted by the new version of meshviewer (which are in legacy develop branch or newer) +* https://github.com/ffnord/meshviewer/tree/dev +* https://github.com/ffrgb/meshviewer/tree/develop + +{% sample lang="toml" %} +```toml +version = 2 +``` +{% endmethod %} + + +### nodes_path +{% method %} +The path, where to store nodes.json (supports version 1 and two, see `nodes_version`) +{% sample lang="toml" %} +```toml +nodes_path = "/var/www/html/meshviewer/data/nodes.json" +``` +{% endmethod %} + + +### graph_path +{% method %} +The path, where to store graph.json (only version 1) +{% sample lang="toml" %} +```toml +graph_path = "/var/www/html/meshviewer/data/graph.json" +``` +{% endmethod %} + + + +## [[nodes.output.nodelist]] +{% method %} +The nodelist output is a minimal output with current state of collected data. +Should be prefered to use it on the [ffapi](https://freifunk.net/api-generator/) for the [freifunk-karte.de](https://freifunk-karte.de) +{% sample lang="toml" %} +```toml +[[nodes.output.nodelist]] +enable = false +path = "/var/www/html/meshviewer/data/nodelist.json" +#[nodes.output.nodelist.filter] +#no_owner = false +``` +{% endmethod %} + + +### path +{% method %} +The path, where to store nodelist.json +{% sample lang="toml" %} +```toml +path = "/var/www/html/meshviewer/data/nodelist.json" +``` +{% endmethod %} + + + +## [database] +{% method %} +The database organize all database types. +For all database types the is a internal job, which reset data for nodes (global statistics are still stored). +_(We have for privacy policy to store node data for maximum seven days.)_ +{% sample lang="toml" %} +```toml +delete_after = "7d" +delete_interval = "1h" +``` +{% endmethod %} + + +### delete_after +{% method %} +This will send delete commands to the database to prune data which is older than: +{% sample lang="toml" %} +```toml +delete_after = "7d" +``` +{% endmethod %} + + +### delete_interval +{% method %} +How often run the delete commands. +{% sample lang="toml" %} +```toml +delete_interval = "1h" +``` +{% endmethod %} + + +## [[database.connection.example]] +{% method %} +This example block shows all option which is useable for every following database type. +Every database type has his own configuration under `database.connection`. +It is possible to have multiple connections for one type of database, just add this group again with new parameters (see toml [[array of table]]). +{% sample lang="toml" %} +```toml +[[database.connection.example]] +enable = true +``` +{% endmethod %} + + +### enable +{% method %} +Each database-connection has its own config block and needs to be enabled by adding: +{% sample lang="toml" %} +```toml +enable = true +``` +{% endmethod %} + + + +## [[database.connection.influxdb]] +{% method %} +Save collected data to InfluxDB. +There are would be the following measurements: +- node: store node specific data i.e. clients memory, airtime +- global: store global data, i.e. count of clients and nodes +- firmware: store the count of nodes tagged with firmware +- model: store the count of nodes tagged with hardware model +{% sample lang="toml" %} +```toml +enable = false +address = "http://localhost:8086" +database = "ffhb" +username = "" +password = "" +[database.connection.influxdb.tags] +tagname1 = "tagvalue 1" +system = "productive" +site = "ffhb" +``` +{% endmethod %} + + +### address +{% method %} +Address to connect on InfluxDB server. +{% sample lang="toml" %} +```toml +address = "http://localhost:8086" +``` +{% endmethod %} + + +### database +{% method %} +Database on which the measurement should be stored. +{% sample lang="toml" %} +```toml +database = "ffhb" +``` +{% endmethod %} + + +### username +{% method %} +Username to authenticate on InfluxDB +{% sample lang="toml" %} +```toml +username = "" +``` +{% endmethod %} + + +### password +{% method %} +Password to authenticate on InfluxDB. +{% sample lang="toml" %} +```toml +password = "" +``` +{% endmethod %} + + +### [database.connection.influxdb.tags] +{% method %} +You could set manuelle tags with inserting into a influxdb. +Usefull if you want to identify the yanic instance when you use multiple own on the same influxdb (e.g. multisites). + +Warning: +Tags used by Yanic would override the tags from this config (e.g. `nodeid`, `hostname`, `owner`, `model`, `firmware_base`, `firmware_release`, `frequency11g`, `frequency11a`). +{% sample lang="toml" %} +```toml +tagname1 = "tagvalue 1s" +# some usefull e.g.: +system = "productive" +site = "ffhb" +``` +{% endmethod %} + + + +## [[database.connection.graphite]] +{% method %} +Save collected data to a graphite database. +{% sample lang="toml" %} +```toml +enable = false +address = "localhost:2003" +prefix = "freifunk" +``` +{% endmethod %} + + +### address +{% method %} +Address to connect on graphite server. +{% sample lang="toml" %} +```toml +address = "localhost:2003" +``` +{% endmethod %} + + +### prefix +{% method %} +Graphite is replacing every "." in the metric name with a slash "/" and uses +that for the file system hierarchy it generates. it is recommended to at least +move the metrics out of the root namespace (that would be the empty prefix). +If you only intend to run one community and only freifunk on your graphite node +then the prefix can be set to anything (including the empty string) since you +probably wont care much about "polluting" the namespace. +{% sample lang="toml" %} +```toml +prefix = "freifunk" +``` +{% endmethod %} + + + +## [[database.connection.logging]] +{% method %} +This database type is just for, debugging without a real database connection. +A example for other developers for new database types. +{% sample lang="toml" %} +```toml +enable = false +path = "/var/log/yanic.log" +``` +{% endmethod %} + + +### path +{% method %} +Path to file where to store some examples with every line. +{% sample lang="toml" %} +```toml +path = "/var/log/yanic.log" +``` +{% endmethod %} diff --git a/docs/docs_install.md b/docs/docs_install.md new file mode 100644 index 00000000..b7fc3c3b --- /dev/null +++ b/docs/docs_install.md @@ -0,0 +1,57 @@ +# Build and Installation + +## go + +### Install +```sh +cd /usr/local/ +wget https://storage.googleapis.com/golang/go1.9.1.linux-amd64.tar.gz -O go-release-linux-amd64.tar.gz +tar xvf go-release-linux-amd64.tar.gz +rm go-release-linux-amd64.tar.gz +``` + +### Configure go +Add these lines in your root shell startup file (e.g. `/root/.bashrc`): + +```sh +export GOPATH=/opt/go +export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin +``` + +## Yanic + +### Compile +As root: +```sh +go get -v -u github.com/FreifunkBremen/yanic +``` + +### Install + +```sh +cp /opt/go/src/github.com/FreifunkBremen/yanic/contrib/init/linux-systemd/yanic.service /lib/systemd/system/yanic.service +systemctl daemon-reload +``` + +Before start, you should configurate yanic by the file `/etc/yanic.conf`: + +``` +systemctl start yanic +``` + +Enable to start on boot: + +``` +systemctl enable yanic +``` + +### Update +For an update just stop yanic and then call the same `go` command again (again as root): +```sh +systemctl stop yanic +go get -v -u github.com/FreifunkBremen/yanic +``` +Then update the config file, for example look at the diff with the new example: +```sh +diff /opt/go/src/github.com/FreifunkBremen/yanic/config_example.toml /etc/yanic.conf +``` diff --git a/docs/docs_quick_conf.md b/docs/docs_quick_conf.md new file mode 100644 index 00000000..4fbb45bf --- /dev/null +++ b/docs/docs_quick_conf.md @@ -0,0 +1,31 @@ +# Quick Configuration + +```sh +cp /opt/go/src/github.com/FreifunkBremen/yanic/config_example.toml /etc/yanic.conf +``` + +# Quick configuration +For an easy startup you only need to edit the `interfaces` in section +`[respondd]` in file `/etc/yanic.conf`. + +Then create the following files and folders: +```sh +adduser --system yanic --home /var/lib/yanic +mkdir -p /var/lib/yanic +mkdir -p /var/www/html/meshviewer/data +touch /var/log/yanic.log +chown yanic /var/log/yanic.log /var/lib/yanic /var/www/html/meshviewer/data +``` + +#### Standalone +If you like to run a standalone meshviewer, just set `enable` in section +`[webserver]` to `true`. + +##### Configure the [meshviewer](https://github.com/ffrgb/meshviewer): +set `dataPath` in `config.json` to `/data/` and make the `build` directory +accessible under `/var/www/html/meshviewer`. + +#### With webserver (Apache, nginx) +The meshviewer needs the output files like `nodes_path` and `graph_path` inside +the same directory as the `dataPath`. Change the path in the section +`[meshviewer]` accordingly. diff --git a/docs/docs_usage.md b/docs/docs_usage.md new file mode 100644 index 00000000..33f864b6 --- /dev/null +++ b/docs/docs_usage.md @@ -0,0 +1,75 @@ +# Usage + +Yanic provides several commands: + +* `import` +* `query` +* `serve` + +## Import + +### RRD-File +Warning, just tested with olddata.rrd from Freifunk Bremen generated by detailed-rrds branch of [ffmap-backend](https://github.com/ffnord/ffmap-backend/tree/detailed-rrds) + +``` +Usage: + yanic import [flags] + +Examples: + yanic import --config /etc/yanic.toml olddata.rrd + +Flags: + -c, --config string Path to configuration file (default "config.toml") + -h, --help help for import +``` + +### Firstseen +To import firstseen values there is a little script in contrib: + +``` +/opt/go/src/github.com/FreifunkBremen/yanic/contrib/yanic-import-timestamp -n path/to/nodes_old.json -s state.json /var/lib/yanic/state.json +``` + +On a productive system @ once: + +``` +systemctl stop yanic; cp /var/lib/yanic/state.json /var/lib/yanic/state.bak; /opt/go/src/github.com/FreifunkBremen/yanic/contrib/yanic-import-timestamp -n path/to/nodes_old.json -s /var/lib/yanic/state.json; systemctl start yanic; +``` + +## Serve +runs yanic in collector-modus to genereate files (e.g. for meshviewer) and save values in databases + +from shell + +``` +Usage: + yanic serve [flags] + +Examples: + yanic serve --config /etc/yanic.toml + +Flags: + -c, --config string Path to configuration file (default "config.toml") + -h, --help help for serve +``` + +or run as [daemon]({{site.baseurl}}/docs/install.html) + + +## Query + +Send a single request and show response like `gluon-neighbour-info` on gluon. + +e.g. to check the right interface + +``` +Usage: + yanic query [flags] + +Examples: + yanic query wlan0 "fe80::eade:27ff:dead:beef" + +Flags: + -h, --help help for query + --wait int Seconds to wait for a response (default 1) +``` diff --git a/docs/home_about.md b/docs/home_about.md new file mode 100644 index 00000000..6ed79711 --- /dev/null +++ b/docs/home_about.md @@ -0,0 +1,45 @@ +# About + +A little overview of yanic in connection with other software: +![Overview](overview.svg) + +## How respondd works + +It sends the `gluon-neighbour-info` request and collects the answers. + +It will send UDP packets with multicast group `ff02:0:0:0:0:0:2:1001` and port `1001`. + +If a node does not answer, it will request with the last know address under the port `1001`. + +## Related projects + +#### yanic collecting data +VPNs (respondd for servers): + +* [mesh-announce](https://github.com/ffnord/mesh-announce) from FreiFunkNord +* [respondd](https://github.com/Sunz3r/ext-respondd) from Sunz3r + +Nodes (respondd for nodes): [gluon](https://github.com/freifunk-gluon/gluon/) + +#### Alternative collectors of respondd data: + +* [Node informant](https://github.com/ffdo/node-informant) written in Go +* [HopGlass Server](https://github.com/plumpudding/hopglass-server) written in Node.js + +#### yanic published data + +**Databases:** + +* [InfluxDB](https://influxdata.com/) SQL-like timeserial database +* [Graphite](https://graphiteapp.org/) RRD file Based + + Visualization from Databases: [Grafana](https://grafana.com/) + +**Output:** +* meshviewer-ffrgb: + * [meshviewer](https://github.com/ffrgb/meshviewer) +* nodelist: + * [ffapi](https://freifunk.net/api-generator/) + * [freifunk-karte.de](https://freifunk-karte.de) +* meshviewer (others): + * unmaintained [origin meshviewer](https://github.com/ffnord/meshviewer) branch: master (v1) and dev (v2) diff --git a/docs/home_running.md b/docs/home_running.md new file mode 100644 index 00000000..ea31c056 --- /dev/null +++ b/docs/home_running.md @@ -0,0 +1,24 @@ +# Running Yanic + +| Community | Meshviewer | Database Visualisation \(Grafana\) | +| :--- | :--- | :--- | +| Freifunk Bremen | [meshviewer](https://map.bremen.freifunk.net) from Freifunk Regensburgwith a patch to show state.json | [grafana](https://grafana.bremen.freifunk.net) - with influxdb | +| Freifunk Regensburg | [meshviewer ](https://regensburg.freifunk.net/meshviewer/)from Freifunk Regensburg | [grafana](https://grafana.regensburg.freifunk.net/) - without yanic | +| Freifunk Frankfurt am Main | [meshviewer ](https://map.ffm.freifunk.net)from Freifunk Regensburg | - | +| Freifunk Hannover | [meshviewer ](https://hannover.freifunk.net/karte/)from Freifunk Regensburg | [grafana ](https://stats.ffh.zone)with influxdb | +| Freifunk Hochstift | [meshviewer ](https://map.hochstift.freifunk.net)from Freifunk Regensburg | - | +| Freifunk in Mainz , Wiesbaden & Umgebung | [meshviewer ](https://mapng.freifunk-mwu.de/)from Freifunk Regensburg | [grafana](https://stats.freifunk-mwu.de) with influxdb | +| Freifunk Ulzen | [meshviewer ](http://map.ffue.eu)from Freifunk Regensburg | - | +| Freifunk Gera Greiz | [meshviewer](https://www.freifunk-gera-greiz.de/meshviewer/) from Freifunk Regensburg | [grafana](https://www.freifunk-gera-greiz.de/grafana/dashboard/db/meshviewer-graphen) - with influxdb | +| Freifunk Westpfalz | [meshviewer ](https://map.freifunk-westpfalz.de/)from Freifunk Regensburg | [grafana](https://stats.freifunk-westpfalz.de/)- with influxdb | + + +### meshviewer-collector +A little project starts, to collect meshviewer-ffrgb data from multiple communities. + + +List of communities: +[https://github.com/genofire/meshviewer-collector](https://github.com/genofire/meshviewer-collector/blob/master/config.toml) + +Meshviewer with colleced data: +[https://web.fireorbit.de/meshviewer](https://web.fireorbit.de/meshviewer). diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..92e3cb37 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,24 @@ +# Home + + + __ __ _ + \ \ / /_ _ _ __ (_) ___ + \ V / _` | '_ \| |/ __| + | | (_| | | | | | (__ + |_|\__,_|_| |_|_|\___| + Yet another node info collector + +(previously [respond-collector](https://github.com/FreifunkBremen/respond-collector)) + +[![Build Status](https://travis-ci.org/FreifunkBremen/yanic.svg?branch=master)](https://travis-ci.org/FreifunkBremen/yanic) +[![Coverage Status](https://coveralls.io/repos/github/FreifunkBremen/yanic/badge.svg?branch=master)](https://coveralls.io/github/FreifunkBremen/yanic?branch=master) +[![codecov](https://codecov.io/gh/FreifunkBremen/yanic/branch/master/graph/badge.svg)](https://codecov.io/gh/FreifunkBremen/yanic) +[![Go Report Card](https://goreportcard.com/badge/github.com/FreifunkBremen/yanic)](https://goreportcard.com/report/github.com/FreifunkBremen/yanic) + +`yanic` is a respondd client that fetches, stores and publishes information about a Freifunk network. + +## The goals: + +* Generating JSON for [Meshviewer](https://github.com/ffrgb/meshviewer) +* Storing statistics in [InfluxDB](https://influxdata.com/) or [Graphite](https://graphiteapp.org/) to be analyzed by [Grafana](http://grafana.org/) +* Provide a little webserver for a standalone installation with a meshviewer diff --git a/docs/overview.svg b/docs/overview.svg new file mode 100644 index 00000000..2b2f0020 --- /dev/null +++ b/docs/overview.svg @@ -0,0 +1,2 @@ + +
Nodes
(gluon)
[Not supported by viewer]
[Not supported by viewer]
Database
Database
[Not supported by viewer][Not supported by viewer]
image
image
Grafana
(Visualisition)
[Not supported by viewer]
[Not supported by viewer]
meshviewer-ffrgb
(meshviewer.json)
meshviewer-ffrgb<br>(meshviewer.json)
ffapi
ffapi
nodelist.json
nodelist.json
meshviewer (v1 & v2)
nodes.json + graph.json
meshviewer (v1 &amp; v2)<br>nodes.json + graph.json
[Not supported by viewer]
respondd
respondd
output
output
others
others
\ No newline at end of file diff --git a/docs/overview.xml b/docs/overview.xml new file mode 100644 index 00000000..98da03dd --- /dev/null +++ b/docs/overview.xml @@ -0,0 +1 @@ +5Vptc6M2EP41nsl9sAchwM7HOG/tTO96M2nvmo+yEaAEI1eI2L5fXwkk8yLsOrHB7jUfYlgtQuw+z+5qYQBvF+tHhpbRZ+rjeGBb/noA7wa2DSxnIn6kZFNIPGgVgpARXymVgifyA+srlTQjPk5ripzSmJNlXTinSYLnvCZDjNFVXS2gcf2uSxRiQ/A0R7Ep/U58HhXSiWuV8l8wCSN9Z2CpkRmav4aMZom638CGQf5XDC+QnkvppxHy6aoigvcDeMso5cXRYn2LY2lbbbbiuocdo9t1M5zwQy6AUK2Db/SzY1+YQp1SxiMa0gTF96V0mj8fljNY4izii1gcAnGI14T/JcUjV509q5EXzPlG+RllnApROfdvlC6VXrEauYSdD6REKc3YXGnZW8sJRGK6wJxthArDMeLkrT4VUtAIt3rbS79SIm5iWwrGUKNRgdj2rPoUHLEQc3VVaWRxUFlGKcpN3+4Gu5j4DcWZWu0XKglge7F46umMiaNQHl1pERLqEcNBru39nUnACFdwSZAbuRT7ISQ8ymajOV2Ik4BhEmTJ6zCMM5rIUfVbXq3voUaK+wgNpAc+GVhZRYTjpyXKHbESsaCOB5QuC3YGZC3xotz7hhnH6/0ONr2pvTKue0VzclXyFGhHRVWONr1XBUDNdfv8BAwTdEIXYQu2qQzJ02c1QbdUUvGggLay8JHsOtS40CDBt69fTsqBIKHMl8vAaTRESSIcI567jQMNjQvlwjbtnIMLOjpW/HWHOJqhFHdDErvfpOKaTPB6YoLdUVYeX06cabEuGPdlXud/ad5JT+Z1rJ7Me6gJ97nhdOa97qYIdesh3gGT+hTFsowi1Jho3KhmnQmsT7Sjmr1hDG0qakupkL5jwe7kfeuq64uDYgUHltZ/ppj9PnuRqda2YjTD8UBtxD5WMzyounnK8ALLenmDEjI3C4ZnJTYKheLhNDeqtZSizXlLCBvu2OR0UUOI04p/dpQVPe1IzxebPTN49JX5vN0lm0R/s9IeDmT74GDi+HSejkgSxNnaF9MqBinBrLXO/nU72MacI9cTyuaUYNSIYSTAjIv10daFfI+IYJe408Ojumo3mc+8AW7G8T6LfqeTDTCocLOg4/tTe43D+RwfY+e4JbUfuwP+UCLdslU5euw1Wnn/qg+OSaSm680mFVnIPmoTEALavO5nhlPyA81yBeko9ehC250O3DtJlJiEiRDMhWsEC+FUUoTMUXyjBhbE93Mw5Tl9um2z3tKYsvy+utG6h2SqXaxWMth2YauQcPazzxoBYKkS7KOlnVahQZDiY1uHY8Mr74uQAUp0pDaj4mMxflh0vvpG0kw4MiWc0OQiGiSNWOlNQI+xErhHuabeuWLhTDWu3gheyUTV9NXn6thFZi7bhWd0hw6P/+1XHaCL/HQwos1gUyJyqEBqhIVSZfSSXkhgsMeTehV17ZpQBG1QBCeAIuwJiufb4+guRRWmlRecHb9IMGEaBGhJfrJKBe5oR5eVCmygHFxQ3aIRUnFSIr8jICnPw8QlRAnHc88ZJeyfPkpcm1EC7nDJ6ZPZ9Z5kJuRXb6BoN6CFhFrxX+rbn8wkJ6GbKtyKa6Re3n24GCh7TgPKkxYowzYow1PUXua7wneUwttvF16RsMDIx2bx26ZykTWw4zS3JL1+v2AGXZHxljTx/QOSY8oZfcU6jyU0kQEnIHHcEB2eItscUI9gJzC5fd1ocQPT5E6Lxe1TGNwMMjTjy4yfphYRETktgjOo2D3GAW+xOpfRepoKa5Mk/CMP3UPnRKi26zs7B04ME7sdmRgC08Q8wiw9mu4+SqMciOBEMdhoR3T7rqX8jLCoz8pvNeH9Pw== \ No newline at end of file diff --git a/output/internal_test.go b/output/internal_test.go index 72c7a11b..2ab095aa 100644 --- a/output/internal_test.go +++ b/output/internal_test.go @@ -32,7 +32,6 @@ func TestStart(t *testing.T) { conn := &testConn{} config := &runtime.Config{ Nodes: struct { - Enable bool `toml:"enable"` StatePath string `toml:"state_path"` SaveInterval runtime.Duration `toml:"save_interval"` OfflineAfter runtime.Duration `toml:"offline_after"` diff --git a/runtime/config.go b/runtime/config.go index d4578a24..ec3c0d11 100644 --- a/runtime/config.go +++ b/runtime/config.go @@ -22,7 +22,6 @@ type Config struct { Webroot string `toml:"webroot"` } Nodes struct { - Enable bool `toml:"enable"` StatePath string `toml:"state_path"` SaveInterval Duration `toml:"save_interval"` // Save nodes periodically OfflineAfter Duration `toml:"offline_after"` // Set node to offline if not seen within this period