Aktualisierung auf Python 3 und einige kleine Verbesserungen
parent
88cfca048f
commit
1844652e4d
2
README
2
README
|
@ -1,6 +1,6 @@
|
|||
Achtung, Verwendung aller Programme auf eigene Gefahr!
|
||||
|
||||
Vor Inbetriebnahme ist jedes Script daraufhin zu überprüfen,
|
||||
ob noch Konfigurationseinstellungen vorgenommen werder müssen.
|
||||
ob noch Konfigurationseinstellungen vorgenommen werden müssen.
|
||||
Z.B. muß bei ffgate-check die IP-Aresse des anzupingenden Hosts
|
||||
eingetragen werden.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -39,6 +39,8 @@ Version Datum Änderung(en) von
|
|||
0.2 2016-08-30 Automatisierung Land des Exit-VPNs tho
|
||||
0.3 2016-12-04 DHCPD-Leases integrieren zur Anzeige der Clientanz. tho
|
||||
0.4 2017-02-10 Communityunabhängig durch sitecode als Einstellung tho
|
||||
0.5 2022-10-05 Umbau auf python3 für Einsatz unter Debian 11 tho
|
||||
0.6 2023-01-02 -m bei batctl deprecated: durch meshif ersetzt tho
|
||||
|
||||
"""
|
||||
|
||||
|
@ -49,7 +51,8 @@ import platform
|
|||
import getopt
|
||||
import signal
|
||||
import daemon
|
||||
from collections import defaultdict, Mapping
|
||||
from collections import defaultdict
|
||||
from collections.abc import Mapping
|
||||
import json
|
||||
import subprocess
|
||||
import socket
|
||||
|
@ -58,6 +61,13 @@ import time
|
|||
import logging
|
||||
import re
|
||||
import datetime
|
||||
import functools
|
||||
|
||||
__author__ = "Thomas Hooge"
|
||||
__copyright__ = "Public Domain"
|
||||
__version__ = "0.6"
|
||||
__email__ = "thomas@hoogi.de"
|
||||
__status__ = "Development"
|
||||
|
||||
cfg = {
|
||||
'logfile': '/var/log/alfred-announced.log',
|
||||
|
@ -107,7 +117,7 @@ def fn_node_net_mesh_ifaces():
|
|||
# Die Stelle mit "bat0" müßte dynamisch aufgrund der Interfaces
|
||||
# zusammengebaut werden
|
||||
return [open('/sys/class/net/' + iface + '/address').read().strip()
|
||||
for iface in map(lambda line: line.split(':')[0], call(['batctl', '-m', cfg['interface'], 'if']))]
|
||||
for iface in map(lambda line: line.split(':')[0], call(['batctl', 'meshif', cfg['interface'], 'if']))]
|
||||
|
||||
def fn_exitvpn_provider():
|
||||
"""
|
||||
|
@ -151,7 +161,8 @@ def fn_fastd_enabled():
|
|||
- prüfe, ob das Script tatsächlich existiert
|
||||
"""
|
||||
runlevel = int(call(['runlevel'])[0].split(' ')[1])
|
||||
fname = glob.glob("/etc/rc%d.d/S??fastd" % runlevel)
|
||||
#fname = glob.glob("/etc/rc%d.d/S??fastd" % runlevel)
|
||||
fname = glob.glob("/etc/rc{:02d}.d/S??fastd".format(runlevel))
|
||||
if not fname:
|
||||
return False
|
||||
return os.path.isfile(fname[0])
|
||||
|
@ -168,6 +179,9 @@ def fn_firmware_base():
|
|||
return call(['lsb_release','-is'])[0]
|
||||
|
||||
def fn_firmware_release():
|
||||
if fn_firmware_base() == 'Debian':
|
||||
return call(['cat','/etc/debian_version'])[0]
|
||||
else:
|
||||
return call(['lsb_release','-rs'])[0]
|
||||
|
||||
def fn_idletime():
|
||||
|
@ -227,12 +241,14 @@ def fn_fastd_peers():
|
|||
data = json.loads(client.makefile('r').read())
|
||||
client.close()
|
||||
# 2. Gateways ermitteln (MACs)
|
||||
with open('/sys/kernel/debug/batman_adv/{0}/gateways'.format(cfg['interface'])) as f:
|
||||
lines = f.readlines()
|
||||
# deprecated
|
||||
#with open('/sys/kernel/debug/batman_adv/{0}/gateways'.format(cfg['interface'])) as f:
|
||||
# lines = f.readlines()
|
||||
lines = call(['batctl', 'meshif', cfg['interface'], 'gwl'])
|
||||
gw_macs = set([gw[3:20] for gw in lines[1:]])
|
||||
# 3. Ergebnis ermitteln
|
||||
npeers = 0
|
||||
for peer in data['peers'].itervalues():
|
||||
for peer in data['peers'].values():
|
||||
if peer['connection']:
|
||||
if not set(peer['connection']['mac_addresses']) & gw_macs:
|
||||
npeers += 1
|
||||
|
@ -285,21 +301,21 @@ item = {
|
|||
#items_by_interval = defaultdict(list)
|
||||
#for k, v in item.iteritems():
|
||||
# items_by_interval[v['interval']].append(k)
|
||||
#print items_by_interval
|
||||
#print(items_by_interval)
|
||||
|
||||
#for i in items_by_interval:
|
||||
# print i
|
||||
# print(i)
|
||||
|
||||
# Datenstruktur zum Übertragen an Alfred.
|
||||
# Wir nehmen die optimale Variante, ggf. ist das *nicht*
|
||||
# JSON
|
||||
def dot_to_json(a):
|
||||
output = {}
|
||||
for key, value in a.iteritems():
|
||||
for key, value in a.items():
|
||||
path = key.split('.')
|
||||
if path[0] == 'json':
|
||||
path = path[1:]
|
||||
target = reduce(lambda d, k: d.setdefault(k, {}), path[:-1], output)
|
||||
target = functools.reduce(lambda d, k: d.setdefault(k, {}), path[:-1], output)
|
||||
target[path[-1]] = value
|
||||
return output
|
||||
|
||||
|
@ -327,12 +343,12 @@ def set_loglevel(nr):
|
|||
return level
|
||||
|
||||
def usage():
|
||||
print "Alfred Announce Daemon for Gateways"
|
||||
print "Version %s" % __version__
|
||||
print
|
||||
print "Optionen"
|
||||
print " -d Programm als Daemon laufen lassen"
|
||||
print
|
||||
print("Alfred Announce Daemon for Gateways")
|
||||
print("Version {}".format(__version__))
|
||||
print()
|
||||
print("Optionen")
|
||||
print(" -d Programm als Daemon laufen lassen")
|
||||
print()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
|
@ -342,8 +358,8 @@ if __name__ == "__main__":
|
|||
# Kommandozeilenoptionen verarbeiten
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], "dh", ["daemon", "help"])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err)
|
||||
except getopt.GetoptError as err:
|
||||
print(str(err))
|
||||
sys.exit(2)
|
||||
for opt, arg in opts:
|
||||
if opt in ("-h", "--help"):
|
||||
|
@ -363,13 +379,13 @@ if __name__ == "__main__":
|
|||
loglevel = set_loglevel(cfg['loglevel'])
|
||||
if loglevel:
|
||||
log.setLevel(loglevel)
|
||||
log.info("%s started on %s" % (sys.argv[0], socket.gethostname()))
|
||||
log.info("{} started on {}".format(sys.argv[0], socket.gethostname()))
|
||||
else:
|
||||
log.disabled = True
|
||||
|
||||
# Zugeordnete Funktionen je Item ausführen
|
||||
result = {}
|
||||
for k, v in item.iteritems():
|
||||
for k, v in item.items():
|
||||
result[k] = v['exec']()
|
||||
|
||||
# Daten für Alfred aufbereiten, wir verwenden gzip
|
||||
|
@ -383,28 +399,28 @@ if __name__ == "__main__":
|
|||
statics = {}
|
||||
except ValueError:
|
||||
statics = {}
|
||||
print "Syntax error in statics file, import failed"
|
||||
print("Syntax error in statics file, import failed")
|
||||
merge_dict(data, statics)
|
||||
|
||||
# Aufteilen in die jew. Datentypen
|
||||
nodeinfo = data['node']
|
||||
statistics = data['statistics']
|
||||
|
||||
cnodeinfo = zlib.compress(json.dumps(nodeinfo))
|
||||
cstatistics = zlib.compress(json.dumps(statistics))
|
||||
cnodeinfo = zlib.compress(bytes(json.dumps(nodeinfo), 'UTF-8'))
|
||||
cstatistics = zlib.compress(bytes(json.dumps(statistics), 'UTF-8'))
|
||||
|
||||
# Knoteninfos übertragen
|
||||
alfred = subprocess.Popen(['alfred', '-s', '158'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
streamdata = alfred.communicate(cnodeinfo)[0]
|
||||
if alfred.returncode != 0:
|
||||
print "Communication error with alfred: %s" % streamdata
|
||||
print("Communication error with alfred: {}".format(streamdata))
|
||||
|
||||
# Statistik übertragen
|
||||
alfred = subprocess.Popen(['alfred', '-s', '159'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
streamdata = alfred.communicate(cstatistics)[0]
|
||||
if alfred.returncode != 0:
|
||||
print "Communication error with alfred: %s" % streamdata
|
||||
print("Communication error with alfred: {}".format(streamdata))
|
||||
|
||||
# Zeitmessung beenden
|
||||
tn = time.time()
|
||||
log.info(u"Benötigte Zeit: %.2f Minuten" % ((tn-t0)/60))
|
||||
log.info("Benötigte Zeit: {:.2f} Minuten" .format((tn-t0)/60))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -6,29 +6,55 @@ Informationen aus dem fastd-Socket anzeigen.
|
|||
Voraussetzung ist natürlich, daß dieser über die fastd-Konfiguration
|
||||
eingeschaltet ist.
|
||||
Programm von Freifunk Pinneberg / Havelock
|
||||
|
||||
TODO Mehr automatisieren
|
||||
- pidof fastd liefert Liste mit laufenden Prozessen (Trennung mit Leerzeichen)
|
||||
- /proc/<pid>/cmdline liefert Kommando mit Konfigurationsdatei
|
||||
- dann Konfigurationsdatei auswerten
|
||||
|
||||
Änderungsprotokoll
|
||||
==================
|
||||
|
||||
Version Datum Änderung(en) von
|
||||
-------- ----------- ------------------------------------------------------ ----
|
||||
0.1 2015-09-27 Änderungsprotokoll eingebaut tho
|
||||
0.2 2023-01-08 Umstellung auf Python 3 tho
|
||||
0.3 2023-12-06 Zugriff auf debugfs für GW-Interfaces entfernt tho
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import socket
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
__author__ = "Thomas Hooge"
|
||||
__copyright__ = "Public Domain"
|
||||
__version__ = "0.3"
|
||||
__email__ = "thomas@hoogi.de"
|
||||
__status__ = "Development"
|
||||
|
||||
def call(cmdnargs):
|
||||
output = subprocess.check_output(cmdnargs)
|
||||
lines = [line.decode("utf-8") for line in output.splitlines()]
|
||||
return lines
|
||||
|
||||
def get_fastd_data(sockfile):
|
||||
# fastd-Socket auslesen, liefert ein JSON-Objekt
|
||||
client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
try:
|
||||
client.connect(sockfile)
|
||||
except socket.error, msg:
|
||||
print >>sys.stderr, msg
|
||||
except socket.error as msg:
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
data = json.loads(client.makefile('r').read())
|
||||
client.close()
|
||||
return data
|
||||
|
||||
def get_gate_macs():
|
||||
# Ermitteln der (sichtbaten) Gateways
|
||||
with open('/sys/kernel/debug/batman_adv/bat0/gateways') as f:
|
||||
lines = f.readlines()
|
||||
# Ermitteln der (sichtbaren) Gateways
|
||||
lines = call(['batctl', 'meshif', 'bat0', 'gwl'])
|
||||
return set([gw[3:20] for gw in lines[1:]])
|
||||
|
||||
def main():
|
||||
|
@ -36,15 +62,19 @@ def main():
|
|||
gw_macs = get_gate_macs()
|
||||
npeers = 0
|
||||
ngates = 0
|
||||
for key, peer in data['peers'].iteritems():
|
||||
for key, peer in data['peers'].items():
|
||||
if peer['connection']:
|
||||
if set(peer['connection']['mac_addresses']) & gw_macs:
|
||||
print "Gate %s (%s) connected as %s..." % (peer['name'], peer['connection']['mac_addresses'][0], key[:16])
|
||||
print("Gate %s (%s) connected as %s..." % (peer['name'], peer['connection']['mac_addresses'][0], key[:16]))
|
||||
ngates += 1
|
||||
else:
|
||||
print "Peer %s (%s) connected as %s..." % (peer['name'], peer['connection']['mac_addresses'][0], key[:16])
|
||||
try:
|
||||
peer_mac = peer['connection']['mac_addresses'][0]
|
||||
except:
|
||||
peer_mac = '*no mac*'
|
||||
print("Peer %s (%s) connected as %s..." % (peer['name'], peer_mac, key[:16]))
|
||||
npeers += 1
|
||||
print "%d peers total, %d gateways and %d peers currently connected" % (len(data['peers']), ngates, npeers)
|
||||
print("%d peers total, %d gateways and %d peers currently connected" % (len(data['peers']), ngates, npeers))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
Loading…
Reference in New Issue