diff --git a/plugins/network/olsrd b/plugins/network/olsrd index 97daadf2..e74568d0 100755 --- a/plugins/network/olsrd +++ b/plugins/network/olsrd @@ -1,62 +1,88 @@ #!/bin/sh # weird shebang? See below: "interpreter selection" -# -# Collect basic information about the neighbours of an OLSR node: -# * link quality -# * neighbour link quality -# * number of nodes reachable behind each neighbour -# * ping times of direct neighbours -# -# This plugin works with the following python interpreters: -# * Python 2 -# * Python 3 -# * micropython -# -# Environment variables: -# * OLSRD_HOST: name or IP of the host running the txtinfo plugin (default: localhost) -# * OLSRD_TXTINFO_PORT: the port that the txtinfo plugin is listening to (default: 2006) -# * OLSRD_BIN_PATH: name of the olsrd binary (only used for 'autoconf', defaults to /usr/sbin/olsrd) -# * MICROPYTHON_HEAP: adjust this parameter for micropython if your olsr network contains -# more than a few thousand nodes (default: 512k) -# -# -# Copyright (C) 2015 Lars Kruse -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# Magic markers -#%# capabilities=autoconf -#%# family=auto """true" +: <<=cut + +=head1 NAME + +olsrd - Monitor the state of an OLSR-based routing network + + +=head1 APPLICABLE SYSTEMS + +Information is parsed from the output of "txtinfo" plugin for olsrd. + + +=head1 CONFIGURATION + +Environment variables: + + * OLSRD_HOST: name or IP of the host running the txtinfo plugin (default: localhost) + * OLSRD_TXTINFO_PORT: the port that the txtinfo plugin is listening to (default: 2006) + * OLSRD_BIN_PATH: name of the olsrd binary (only used for 'autoconf', default: /usr/sbin/olsrd) + * MICROPYTHON_HEAP: adjust this parameter for micropython if your olsr network contains + more than a few thousand nodes (default: 512k) + +=head1 USAGE + +Collect basic information about the neighbours of an OLSR node: + + * link quality + * neighbour link quality + * number of nodes reachable behind each neighbour + * ping times of direct neighbours + +This plugin works with the following python interpreters: + + * Python 2 + * Python 3 + * micropython (e.g. OpenWrt) + + +=head1 VERSION + + 0.4 + + +=head1 AUTHOR + +Lars Kruse + + +=head1 LICENSE + +GPLv3 or above + + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf + +=cut + + # ****************** Interpreter Selection *************** # This unbelievable dirty hack allows to find a suitable python interpreter. # This is specifically useful for OpenWRT where typically only micropython is available. # # Additionally we need to run micropython with additional startup options. -# This is necessary due to our demand for more than 128k heap (this default is sufficient for only 400 olsr nodes). +# This is necessary due to our demand for more than 128k heap (this default is sufficient for only +# 400 olsr nodes). # # This "execution hack" works as follows: # * the script is executed by busybox ash or another shell -# * the above line (three quotes before and one quote after 'true') evaluates differently for shell and python: -# * shell: run "true" (i.e. nothing happens) -# * python: ignore everything up to the next three consecutive quotes +# * the above line (three quotes before and one quote after 'true') evaluates differently for +# shell and python: +# * shell: run "true" (i.e. nothing happens) +# * python: ignore everything up to the next three consecutive quotes # Thus we may place shell code here that will take care for selecting an interpreter. # prefer micropython if it is available - otherwise fall back to any python (2 or 3) -if which micropython >/dev/null; then - /usr/bin/micropython -X "heapsize=${MICROPYTHON_HEAP:-512k}" "$0" "$@" +MICROPYTHON_BIN=$(which micropython || true) +if [ -n "$MICROPYTHON_BIN" ]; then + "$MICROPYTHON_BIN" -X "heapsize=${MICROPYTHON_HEAP:-512k}" "$0" "$@" else python "$0" "$@" fi @@ -68,19 +94,20 @@ true <{tempfile}' + .format(hosts=" ".join(hosts), tempfile=tempfile)) + # micropython supports only "os.system" (as of 2015) - thus we need to stick with it for + # OpenWrt. returncode = os.system(command) if returncode != 0: return {} @@ -248,71 +287,48 @@ def get_ping_times(hosts): return result -if __name__ == "__main__": - # parse arguments - if len(sys.argv) > 1: - if sys.argv[1]=="config": - links = list(get_olsr_links()) +def do_config(): + links = list(get_olsr_links()) - # link quality with regard to neighbours - print("multigraph olsr_link_quality") - print(LQ_GRAPH_CONFIG.format(title="OLSR Link Quality")) - is_first = True - for link in links: - print(LQ_VALUES_CONFIG.format(label=link["remote"], - suffix="_{host}".format(host=get_clean_fieldname(link["remote"])), - draw_type=("AREA" if is_first else "STACK"))) - is_first = False - is_first = True - for link in links: - print("multigraph olsr_link_quality.host_{remote}".format(remote=get_clean_fieldname(link["remote"]))) - print(LQ_GRAPH_CONFIG.format(title="Link Quality towards {host}".format(host=link["remote"]))) - print(LQ_VALUES_CONFIG.format(label="Link Quality", suffix="", draw_type="AREA")) - is_first = False + # link quality with regard to neighbours + print("multigraph olsr_link_quality") + print(LQ_GRAPH_CONFIG.format(title="OLSR Link Quality")) + for link in links: + print(LQ_VALUES_CONFIG.format( + label=link["remote"], + suffix="_{host}".format(host=get_clean_fieldname(link["remote"])), + draw_type="AREASTACK")) + for link in links: + print("multigraph olsr_link_quality.host_{remote}" + .format(remote=get_clean_fieldname(link["remote"]))) + title = "Link Quality towards {host}".format(host=link["remote"]) + print(LQ_GRAPH_CONFIG.format(title=title)) + print(LQ_VALUES_CONFIG.format(label="Link Quality", suffix="", draw_type="AREA")) - # link count ("number of nodes behind each neighbour") - print("multigraph olsr_neighbour_link_count") - print(NEIGHBOUR_COUNT_CONFIG) - is_first = True - for link in links: - print(NEIGHBOUR_COUNT_VALUE - .format(host=link["remote"], - host_fieldname=get_clean_fieldname(link["remote"]), - draw_type=("AREA" if is_first else "STACK"))) - is_first = False + # link count ("number of nodes behind each neighbour") + print("multigraph olsr_neighbour_link_count") + print(NEIGHBOUR_COUNT_CONFIG) + for link in links: + print(NEIGHBOUR_COUNT_VALUE + .format(host=link["remote"], host_fieldname=get_clean_fieldname(link["remote"]), + draw_type="AREASTACK")) - # neighbour ping - print("multigraph olsr_neighbour_ping") - print(NEIGHBOUR_PING_CONFIG.format(title="Ping time of neighbours")) - for link in links: - print(NEIGHBOUR_PING_VALUE - .format(host=link["remote"], - host_fieldname=get_clean_fieldname(link["remote"]))) - # neighbour pings - single subgraphs - for link in links: - remote = get_clean_fieldname(link["remote"]) - print("multigraph olsr_neighbour_ping.host_{remote}".format(remote=remote)) - print(NEIGHBOUR_PING_CONFIG.format(title="Ping time of {remote}".format(remote=remote))) - print(NEIGHBOUR_PING_VALUE.format(host=link["remote"], host_fieldname=remote)) + # neighbour ping + print("multigraph olsr_neighbour_ping") + print(NEIGHBOUR_PING_CONFIG.format(title="Ping time of neighbours")) + for link in links: + print(NEIGHBOUR_PING_VALUE + .format(host=link["remote"], host_fieldname=get_clean_fieldname(link["remote"]))) + # neighbour pings - single subgraphs + for link in links: + remote = get_clean_fieldname(link["remote"]) + print("multigraph olsr_neighbour_ping.host_{remote}".format(remote=remote)) + title = "Ping time of {remote}".format(remote=remote) + print(NEIGHBOUR_PING_CONFIG.format(title=title)) + print(NEIGHBOUR_PING_VALUE.format(host=link["remote"], host_fieldname=remote)) - sys.exit(0) - elif sys.argv[1] == "autoconf": - if os.path.exists(os.getenv('OLSRD_BIN_PATH', '/usr/sbin/olsrd')): - print('yes') - else: - print('no') - sys.exit(0) - elif sys.argv[1] == "version": - print('olsrd Munin plugin, version %s' % plugin_version) - sys.exit(0) - elif sys.argv[1] == "": - # ignore - pass - else: - # unknown argument - sys.stderr.write("Unknown argument{eol}".format(eol=LINESEP)) - sys.exit(1) +def do_fetch(): # output values links = list(get_olsr_links()) @@ -353,6 +369,34 @@ if __name__ == "__main__": print("multigraph olsr_neighbour_ping.host_{remote}".format(remote=remote)) print("neighbour_{remote}.value {value}".format(remote=remote, value=value)) + +if __name__ == "__main__": + # parse arguments + if len(sys.argv) > 1: + if sys.argv[1] == "config": + do_config() + if os.getenv("MUNIN_CAP_DIRTYCONFIG") == "1": + do_fetch() + sys.exit(0) + elif sys.argv[1] == "autoconf": + if os.path.exists(os.getenv('OLSRD_BIN_PATH', '/usr/sbin/olsrd')): + print('yes') + else: + print('no') + sys.exit(0) + elif sys.argv[1] == "version": + print('olsrd Munin plugin, version %s' % plugin_version) + sys.exit(0) + elif sys.argv[1] == "": + # ignore + pass + else: + # unknown argument + sys.stderr.write("Unknown argument{eol}".format(eol=LINESEP)) + sys.exit(1) + + do_fetch() + # final marker for shell / python hybrid script (see "Interpreter Selection") EOF = True EOF