#!/bin/bash
# -*- sh -*-

: << =cut

=head1 NAME

ipmi_ - Plugin to monitor temperature or fan speed using IPMI

=head1 CONFIGURATION

=head2 ENVIRONMENT VARIABLES

This plugin does not use environment variables

=head2 WILDCARD PLUGIN

This plugin should be linked as ipmi_temp or ipmi_fans, and will show
either temperatures or fan speeds based on its link name.

=head1 NOTE

WARNING: Munin has a 10 second default timeout on plugins.  On some
hosts ipmitool takes longer than that to probe all your hardware.  In
this case this plugin us unusable.

=head1 AUTHOR

Nicolai Langfeldt <janl@linpro.no>

=head1 LICENSE

Donated to the public domain by Nicolai Langfeldt (janl@linpro.no)

=head1 MAGIC MARKERS

 #%# family=auto
 #%# capabilities=autoconf suggest

=cut

#### Parse commandline to determine what the job is

CONFIG=no

case $1 in
    autoconf)
        ! test -x /usr/bin/ipmitool && 
	  echo 'no (no /usr/bin/ipmitool)' && exit 0
	! (/sbin/lsmod | grep -q ipmi) &&
	  echo 'no (impi module not loaded' && exit 0
	echo yes
        exit 0
	;;
    suggest) echo fans
             echo temp
	     exit 0;;
    config)  CONFIG=config;;
esac

case $0 in
    *_temp) MEASURE=temp;;
    *_fans) MEASURE=fans;;
    *) echo Please invoke as ipmi_temp or ipmi_fans >&2
       exit 1;;
esac

export CONFIG MEASURE

#### Work is done in this awk script

ipmitool sensor | gawk -F'|' '
BEGIN {
    FANS = "";
    TEMPS = "";
    CFANS = "graph_title Fan speeds based on IPMI\ngraph_vlabel RPM\ngraph_category Sensors\n";
    CTEMPS = "graph_title Machine temperature based on IPMI\ngraph_vlabel Degrees celcius\ngraph_category Sensors\n";
}

# Remove extraneous spaces to make output prettyer
{ gsub(/\t/," "); gsub(/ +/," "); gsub(/ +\|/,"|"); gsub(/\| +/,"|") }

# Skip lines with 0x0 in first column
/^[^|]+\|0x0\|/ { next; };

# Skip lines with na in first column
/^[^|]+\|na\|/ { next; };

# Parse temperatures
/degrees C/ {
	NAME=THING=$1;
	gsub(/[^A-Za-z0-9]/,"",NAME);
	TEMP=$2;

	# Find unique name
	while (NAMES[NAME] >= 1) {
	    NAME=sprintf("%si",NAME);
	}
	NAMES[NAME]=1;

	WARN=$8;
	CRIT=$9;

	TEMPS = sprintf("%s%s.value %s\n",TEMPS,NAME,TEMP);
	CTEMPS = sprintf("%s%s.label %s\n",CTEMPS,NAME,THING);

	if (CRIT !~ /na/) {
		CTEMPS = sprintf("%s%s.critical 0:%s\n",CTEMPS,NAME,CRIT);
	}

	if (WARN !~ /na/) {
		CTEMPS = sprintf("%s%s.warning 0:%s\n",CTEMPS,NAME,WARN);
	}
}

/RPM/ { 
        NAME=THING=$1;
	gsub(/[^A-Za-z0-9]/,"",NAME);
	SPEED=$2;

	# Find unique name
	while (NAMES[NAME] >= 1) {
	    NAME=sprintf("%si",NAME);
	}
	NAMES[NAME]=1;

	FANS = sprintf("%s%s.value %s\n",FANS,NAME,SPEED);
	CFANS = sprintf("%s%s.label %s\n",CFANS,NAME,THING);

	OK=$4;

	MIN=$6;
	if (MIN !~ /na/) {
		CFANS = sprintf("%s%s.warning %s:\n",CFANS,NAME,MIN);
	}
}

END {
    if (ENVIRON["MEASURE"] == "temp") {
	VALUE=TEMPS;
	CONFIG=CTEMPS;
    } else {
	VALUE=FANS;
	CONFIG=CFANS;
    }
    if (ENVIRON["CONFIG"] == "config")
	printf "%s",CONFIG;
    else
	printf "%s",VALUE;
}
'
