#!/bin/sh

: << =cut

=head1 NAME

lxc_net - Munin plugin to graph traffic of active LXC containers.

=head1 APPLICABLE SYSTEMS

LXC container with "lxc.network.type=veth" and "lxc.network.veth.pair" settings.

=head1 CONFIGURATION

env.lxcpath - Set the path where LXC containers are stored, default: /var/lib/lxc
env.exclude - Removing containers from graphs, default: empty

  [lxc_net]
    env.lxcpath /var/lib/lxc
    env.exclude container1 container2

=head1 INTERPRETATION

This plugin reads a "lxc.network.veth.pair" setting from "config" file of each container,
because lxc-start command creates a random named veth device without the setting.

If your xen config (/var/lib/lxc/GUEST_NAME/config does not contain this parameter, 
then you have to fill it, because if every guest restart generate new device name, then the graph will be useless
( example config : lxc.network.veth.pair = vethsamba )

=head1 AUTHOR

mitty   mitty@mitty.jp

=head1 LICENSE

2-clause BSD License

=head1 MAGIC MARKERS

 #%# familiy=auto
 #%# capabilities=autoconf

=cut

. $MUNIN_LIBDIR/plugins/plugin.sh

lxcpath=${lxcpath:-/var/lib/lxc}

if [ "$1" = "autoconf" ]; then
    if [ ! -r /proc/net/dev ]; then
        echo "no (/proc/net/dev cannot be read)"
        exit 0
    fi
    if [ ! -e "$lxcpath" ]; then
        echo "no ($lxcdir is not present)"
        exit 0
    fi
    
    echo yes
fi

actives=""
for guest in `ls $lxcpath`; do
    if [ `echo $exclude | grep -c "\b$guest\b"` -eq 1 ]; then
        continue;
    fi
    if [ -f "$lxcpath/$guest/config" ]; then
        devices=`grep '^lxc\.network\.veth\.pair[ \t]*=[ \t]*' $lxcpath/$guest/config | \
            awk '{ split($0, a, /=/); gsub(/[ \t]/, "", a[2]); print a[2]; }'`
        if [ -n "$devices" ]; then
            for device in $devices; do
                device_re=`echo $device | sed -e 's/\./\\\\./g'`
                if [ `grep -c "^ *$device_re:" /proc/net/dev` -eq 1 ]; then
                    actives="$actives $guest"
                    eval "dev_$(clean_fieldname $guest)=$device"
                fi
            done
        fi
    fi
done

if [ "$1" = "config" ]; then
    echo "graph_title Network traffic"
    echo "graph_args --base 1000"
    echo "graph_vlabel bits in (-) / out (+) per ${graph_period}"
    echo "graph_category lxc"
    echo "graph_info This graph shows the traffic of active LXC containers."
    
    for guestname in $actives; do
        guest=$(clean_fieldname $guestname)
        device=$(eval 'echo $dev_'$guest)
        bps="U"
        if [ -r /sys/class/net/$device/speed ]; then
            bps=$(cat /sys/class/net/$device/speed)
            bps=$(($bps * 1000 * 1000))
        fi
        
        echo "${guest}_down.label $guestname"
        echo "${guest}_down.type DERIVE"
        echo "${guest}_down.graph no"
        echo "${guest}_down.cdef ${guest}_down,8,*"
        echo "${guest}_down.min 0"
        echo "${guest}_down.max $bps"
        echo "${guest}_up.label $guestname"
        echo "${guest}_up.type DERIVE"
        echo "${guest}_up.negative ${guest}_down"
        echo "${guest}_up.cdef ${guest}_up,8,*"
        echo "${guest}_up.min 0"
        echo "${guest}_up.max $bps"
   done
   exit 0
fi


for guest in $actives; do
    guest=$(clean_fieldname $guest)
    device=$(eval 'echo $dev_'$guest)
    device_re=`echo $device | sed -e 's/\./\\\\./g'`
    line=`grep "^ *$device_re:" /proc/net/dev`
    echo -n "${guest}_down.value "
    echo $line | awk '{
            split($0, a, /: */); 
            print  $2;
    }'
    echo -n "${guest}_up.value "
    echo $line | awk '{
            split($0, a, /: */); 
            print  $10; 
        }'
done
