Freifunk-Gateway aufsetzen/Alfred

= Alfred Master =
== Funktion ==
Die Nodewatcher Daten aus dem Alfred werden nicht mehr von einer zentralen VM (früher die Netmon VM) ans Monitoring geschickt. Das übernehmen jetzt die Gateways. Daher muss auf den Gateways Alfred installiert werden und die Daten ans Monitoring übertragen werden
== Installation ==
Das Gateway muss die Daten zuerst als sogenannter Alfred-Master sammeln. Dazu muss "alfred" installiert werden. (Entweder aus den Distributionsquellen oder selbst kompilieren, funktioniert analog zum batman-adv https://wiki.freifunk-franken.de/w/Freifunk-Gateway_aufsetzen/Batman-adv
== Konfiguration ==
Dann muss pro bedienter Hood (also für jedes batX Interface) ein Alfred master gestartet werden (beispielsweise mit in die Interfacekonfiguration oder wie unten als systemd-Service ...):
~# cat /etc/systemd/system/alfred-bayreuth.service 
[Unit]
Description=Alfred Master
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/sbin/alfred -m -i bat-bayreuth -b none -u /var/run/alfred-bayreuth.sock
WorkingDirectory=/tmp
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
bitte den Parameter -i und -u entsprechend anpassen
 -i, --interface specify the interface (or comma separated list of interfaces) to listen on
Anschliesend den neuen Service registrieren und starten:
systemctl enable alfred-bayreuth.service
systemctl start alfred-bayreuth.service 
=== Testen der Konfigration ===
Wenn bereits ein Router in der Hood ist, kann mit 
alfred -r 64 -u /var/run/xx.sock 
der Datensatz des Routers angezeigt werden. Auch kann ein eigener Datensatz ins Batman gesteckt werden z.b. 
echo "asdf" | alfred -s 66 -u /var/run/xx.sock
diese können dann mit 
alfred -r 66 -u /var/run/xx.sock
wieder ausgelesen werden
Bitte den Data-type 64 für das Monitoring frei halten und dort keine eigenen Daten hinein stecken.
== Alfred Monitoring Proxy ==
Die gesammelten Daten müssen nun noch periodisch an das Monitoring gesendet werden.
=== alfred-json ===
Dazu kann alfred-json (https://github.com/FreifunkFranken/alfred-json) in Kombination mit einem passenden curl-Skript verwenden werden. Zunächst muss alfred-json kompiliert werden (siehe README).
Auf einem Debian werden einige zusätzlche Pakete benötigt:
apt install cmake pkg-config libjansson-dev zlib1g-dev
=== Alfred-Monitoring-Proxy (via /api/alfred2) ===
Diese Implementierung vom Nov. 2018 verzichtet auf das einschließende {"64":"<data>"} und sollte daher einfacher sein. Die bisherige Lösung folgt unten.
Danach noch das curl-Script anlegen (auf eigenes Zeug anpassen! Pfade der inneren for-loop über die Sockets prüfen!):
~# cat /usr/local/sbin/alfred-monitoring-proxy
#!/bin/bash
api_url="https://monitoring.freifunk-franken.de/api/alfred2"
fetchid=64
alfredjson=/usr/local/bin/alfred-json
header="Content-type: application/json; charset=UTF-8"
gziphead="Content-Encoding: gzip"
verbose=-v
for socket in /var/run/alfred-*.sock
do
	sleep 1
	if [ "$zip" = "1" ]; then
		$alfredjson -r "$fetchid" -s "$socket" | gzip | curl $verbose -H "$header" -H "$gziphead" --compressed --data-binary @- "$api_url"
	else
		$alfredjson -r "$fetchid" -s "$socket" | curl $verbose -H "$header" --data-binary @- "$api_url"
	fi
done
==== Multi-Target ====
Für den seltenen Fall, dass man selbst ein Monitoring unterhält oder die Daten aus einem anderen Grund an mehrere Adressen versendet werden sollen, kann man folgende Variante verwenden:
~# cat /usr/local/sbin/alfred-monitoring-proxy
#!/bin/bash
api_urls=(
 "https://monitoring.freifunk-franken.de/api/alfred2"
 "https://stats.freifunk-schweinfurt.de/api/alfred2"
)
fetchid=64
alfredjson=/usr/local/bin/alfred-json
header="Content-type: application/json; charset=UTF-8"
gziphead="Content-Encoding: gzip"
verbose=-i
for socket in /var/run/alfred-*.sock
do
 sleep 1
 if [ "$zip" = "1" ]; then
 $alfredjson -r "$fetchid" -s "$socket" | gzip | curl $verbose -H "$header" -H "$gziphead" --compressed --data-binary @- "${api_urls[@]}"
 else
 $alfredjson -r "$fetchid" -s "$socket" | curl $verbose -H "$header" --data-binary @- "${api_urls[@]}"
 fi
done
=== Alfred-Monitoring-Proxy (via /api/alfred, veraltet) ===
Diese Implementierung benötigt ein einschließendes {"64":"<data>"} für die Daten und wird daher von der oben beschriebenen Variante abgelöst. Beide Varianten können jedoch ohne Ablaufdatum verwendet werden.
Danach noch das curl-Script anlegen (auf eigenes Zeug anpassen! Pfade der inneren for-loop über die Sockets prüfen!):
~# cat /usr/local/sbin/alfred-monitoring-proxy
#!/bin/bash
api_url="https://monitoring.freifunk-franken.de/api/alfred"
fetch_ids="64"
for fetch_id in $fetch_ids
do
	for socket in /var/run/alfred-*.sock
	do
		tmp=$(mktemp)
		echo "{\"$fetch_id\": " > $tmp
		/usr/local/bin/alfred-json -r "$fetch_id" -s "$socket" >> $tmp
		echo "}" >> $tmp
		if [ "$zip" = "1" ]; then
			gzip $tmp
			tmp="$tmp.gz"
			HEADER='-H "Content-Encoding: gzip" --compressed'
		fi
		curl -v -H "Content-type: application/json; charset=UTF-8" $HEADER --data-binary @$tmp $api_url
		rm "$tmp"
	done
done
=== Cron-Job ===
Und einen passenden Cronjob dafür anlegen:
1-59/5 * * * * sleep 9; /usr/local/sbin/alfred-monitoring-proxy
WICHTIG: Bitte im nächsten Abschnitt den optimalen Zeitpunkt für das senden bestimmen!
=== Wahl des korrekten Delays (sleep) ===
Das Zusammenspiel zwischen nodewatcher, Alfred und Monitoring ist komplex. Entsprechend gibt es mehr und weniger sinnvolle Zeiten, wann der Alfred Master seine Daten an das Monitoring sendet. Die folgende Tabelle soll bei der Wahl eines geeigneten Delays behilflich sein.
Anstatt eines fixen Delays ist auch eine Variante mit random möglich. Die Grenzen sollten dabei die angegebenen Bereiche nicht verlassen!
WICHTIG: Sind mehrere Alfred Master in einer Hood sollten diese ihre Daten nie gleichzeitig schicken! (Empfohlener Abstand min. 5 sec.)
	Wartezeit nach Erreichen von */5	Kommentar
	0 - 50 sec. 	Reservierter Zeitslot (nodewatcher)
* In dieser Zeit generiert der nodewatcher die Daten und verschickt diese per Alfred.
* Findet die Anfrage in diesem Zeitraum statt, werden die Daten von 5 Minuten zuvor verwendet.
	50 - 85 sec. 	Empfohlener Zeitslot
* Optimal zwischen 65 und 80 sec.
	85 - 120 sec. 	Reservierter Zeitslot (Netmon-VM)
* Bei einer anderen Anfrage sollten keine Fehler auftreten, aber die Last wird unnötig erhöht
	120 - 175 sec. 	Möglicher Zeitslot
* Die Daten werden noch rechtzeitig für die Statistiken geliefert
* Die Routerdaten selbst sind weniger aktuell im Vergleich zum empfohlenen Slot
	175 - 185 sec. 	Reservierter Zeitslot (Erstellung der Statistiken)
* Findet hier eine Anfrage statt kann es gelegentlich zu Fehlern kommen
	185 - 300 sec. 	Freier Zeitslot
* Die Daten werden NACH Erstellung der Statistiken geliefert und müssen entsprechend lange warten
*Optimal ist dieser Zeitslot für den zweiten Alfred Master einer Hood, sodass der Abstand zwischen den Anfragen etwa gleich ist (=> effektives Update alle 2.5 Minuten)
* Ein Setzen auf nahe 300 Sekunden sollte vermieden werden
Tipps:
Handelt es sich um mehr als eine Minute Delay, kann die Cron Syntax ausgenutzt werden:
1-59/5 * * * * Befehl
Das löst dann 00:01, 00:06, 00:11 usw. aus, also im beginnend bei 1 bis 59 in 5-er Schritten
2-59/5 * * * * Befehl
Das löst dann 00:02, 00:07, 00:12 usw. aus, also im beginnend bei 2 bis 59 in 5-er Schritten.
In Kombination mit sleep gibt es also für 130 Sekunden folgende Lösungen:
*/5 * * * * sleep 130; Befehl
oder besser:
2-59/5 * * * * sleep 10; Befehl
Zwei Minuten plus 10 Sekunden sind 130 Sekunden, aber man vermeidet den langen Sleep.