#!/usr/bin/perl -w
###############################################################################
#
# Webmin Sysstats Module
# Copyright (C) 2003 by Eric Gerbier
# Bug reports to: gerbier@users.sourceforge.net
# $Id: hplog-lib.pl 4175 2011-06-24 10:45:11Z gerbier $
#
# 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 2 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.
#
###############################################################################
use strict;
use warnings;
use English qw(-no_match_vars);
unset_warnings();
require RRDs;
set_warnings();
# from web-lib.pl
## no critic (ProhibitPackageVars)
use vars qw(%config %text %in $in $cb $tb %access );
## use critic
my $module_name = 'hplog';
my $fscript = $module_name . '.pl';
my $pre = 'vol';
my $data_name = 'total';
my $module_cmd = 'hplog';
my $EMPTY = EMPTY();
###############################################################################
sub install_module($$) {
my ( $minfo, $defaults ) = ( $_[0], $_[1] );
debug_sub_begin();
my @colors = generate_colors();
my %my_config = init_module_config( $module_name, 1 );
$my_config{'pre'} = $pre;
my $db_uid = 1;
# search for command
$my_config{$module_cmd} = guess_hplog_client();
$my_config{'runstop'} = test_command( $my_config{$module_cmd} );
if ( $my_config{'runstop'} ) {
warning( "disable $module_name : " . get_error() );
}
else {
my @vol = tab_vol( \%my_config );
foreach my $vol (@vol) {
create_base( $minfo, \%my_config, $db_uid );
my $type = param2type($vol);
$my_config{ $pre . $db_uid } =
pack_config( $db_uid, $vol, $type,
$colors[ ( $db_uid - 1 ) % ( scalar @colors ) ],
0, 0 );
$db_uid++;
}
}
if ( $db_uid > 1 ) {
# run
$my_config{'runstop'} = 0;
}
else {
# no parameters : stop
$my_config{'runstop'} = 1;
}
$my_config{'db_uid'} = $db_uid;
write_config( $minfo, \%my_config );
install_script( $minfo, $fscript );
debug_sub_end();
return 1;
}
###############################################################################
sub graph_data($$) {
my ( $minfo, $my_config ) = ( $_[0], $_[1] );
debug_sub_begin();
my $cf = $my_config->{'cf'};
# take care of cgi parameters
my ( $graph_type, $c_display ) = get_cgi_graph($my_config);
my @rrd_detals;
gprint_title( $module_name, 'param', \@rrd_detals );
my $vol_num = 1;
my $first_graph = 1;
VOL: while ( defined $my_config->{ $pre . $vol_num } ) {
my $vol_nb = $pre . $vol_num;
my ( $vol_id, $vol_name, $vol_type, $vol_config, $runstop, $display ) =
unpack_config( $my_config->{$vol_nb} );
if ($runstop) {
$vol_num++;
next VOL;
}
if ( $display == $c_display ) {
add_def( \@rrd_detals, $vol_nb, $minfo->{'dbtables'} . $vol_id,
$data_name, $cf );
if ( $graph_type == 0 ) {
# histograms
my $type;
if ($first_graph) {
$first_graph = 0;
$type = 'AREA';
}
else {
$type = 'STACK';
}
gprint_param( \@rrd_detals, $vol_nb, $vol_name, $vol_config,
$type );
}
else {
# lines
gprint_param( \@rrd_detals, $vol_nb, $vol_name, $vol_config );
}
}
$vol_num++;
}
graph_common( $minfo, $my_config, @rrd_detals );
debug_sub_end();
return;
}
###############################################################################
sub mod_config($$$) {
my ( $minfo, $my_config, $defaults ) = ( $_[0], $_[1], $_[2] );
debug_sub_begin();
mod_config_opt( $minfo, $my_config, $pre );
begin_html_config(1);
# general
change_database( $minfo, $my_config );
change_local_params($my_config);
change_display($my_config);
# local
change_module_config($my_config);
change_scale( $minfo, $my_config );
change_default( $my_config->{'graph_type'},
$text{'word_line'}, $text{'word_bar'} );
my @columns = (
'module_subtitle_vol_name', 'word_subtitle_disp_colour',
'word_subtitle_controls',
);
end_html_config(@columns);
my $vol_num = 1;
while ( defined $my_config->{ $pre . $vol_num } ) {
my ( $vol_id, $vol_name, $vol_type, $vol_config, $runstop, $display ) =
unpack_config( $my_config->{ $pre . $vol_num } );
my ( $vol_colour, $vol_line ) = get_line_config($vol_config);
begin_row($cb); # row 1
# name
print
"<td><strong><a href=\"edit_module.cgi?idx=$in{'idx'}&opt=edit&vol_num=$vol_num\">$vol_name</a></strong></td>";
# color
print "<td><font color=\"#$vol_colour\"><strong>";
print $text{ 'colour_' . $vol_colour }
? $text{ 'colour_' . $vol_colour }
: "<pre>#$vol_colour </pre>";
print "</strong></font></td>\n";
# controls
print '<td align=right>';
display_parameter_line( $vol_num, $runstop, $display, $my_config,
$pre );
print "</td>\n";
end_row(); # row 1
$vol_num++;
}
end_table();
if ( ( exists $in{'opt'} ) and ( $in{'opt'} eq 'edit' ) ) {
my ( $vol_id, $vol_name, $vol_type, $vol_config, $runstop, $display ) =
unpack_config( $my_config->{ $pre . $in{'vol_num'} } );
begin_table( 'edition', 'border' ); # table 1
begin_row($tb); # row 1
title_row( $text{'module_vol'} );
end_row(); # row 1
begin_row($cb); # row 2
print '<td>';
print '<form action="save_config.cgi">';
print '<table ' . w100() . ">\n"; # table 2
begin_row(); # row 3
title_row( $text{'module_word_vol'}, w15() );
title_row( $vol_name, 'nowrap ' . width(5) );
end_row(); # row 3
modify_colour( $vol_config, $display, $runstop, $my_config, $pre );
print_button( $pre, $in{'idx'}, 'update_vol', $in{'vol_num'},
$text{'word_update'} );
print "</table>\n"; # table 2
print "</form>\n";
print "</td>\n";
end_row(); # row 2
end_table(); # table 1
}
else {
# new ones
my @vol_list = filter_known( $my_config, tab_vol($my_config) );
begin_table( 'new_config', 'border' ); # table 1
begin_row($tb); # row 1
title_row( $text{'module_new_vol'} );
end_row(); # row 1
begin_row($cb); # row 2
print '<td>';
print '<form action="save_config.cgi">';
print '<table ' . w100() . ">\n"; # table 2
begin_row(); # row 3
title_row( $text{'module_word_vol'}, w15() );
my $i = 0;
print '<td nowrap><strong>';
print "<select name=\"new_vol_def\">\n";
print '<option value="' . $i++ . "\">$text{'word_select'}\n";
foreach my $vlist (@vol_list) {
print '<option value="' . $i++ . "\">$vlist\n";
}
print '</select>';
print '</strong></td>';
end_row(); # row 3
modify_colour( '00ff00', 0, 0, $my_config, $pre );
print_button( $pre, $in{'idx'}, 'new_vol', $vol_num,
$text{'word_addnew'} );
print "</table>\n"; # table 2
print "</form>\n";
print "</td>\n";
end_row(); # row 2
end_table(); # table 1
}
end_table();
print "</table>\n";
debug_sub_end();
return;
}
###############################################################################
sub mod_config_save($$$) {
my ( $minfo, $my_config, $defaults ) = ( $_[0], $_[1], $_[2] );
debug_sub_begin();
if ( $in{'opt'} eq 'new_vol' ) {
if (
( $in{'new_vol_def'} eq $EMPTY )
or ( ( $in{'vol_colour1_def'} eq 'nocolour' )
and ( $in{'vol_colour2_def'} eq $EMPTY ) )
)
{
error( $text{'save_einvaled_selection'} );
}
create_base( $minfo, $my_config, $my_config->{'db_uid'} );
my @vol_list = filter_known( $my_config, tab_vol($my_config) );
my $new_vol = $vol_list[ $in{'new_vol_def'} - 1 ];
$my_config->{ $pre . $in{$pre} } = pack_config(
$my_config->{'db_uid'}++,
$new_vol,
param2type($new_vol),
set_line_config(
get_colourselect( 'vol_colour', $EMPTY ),
get_lineselect('vol_line')
),
0,
$in{'display_def'}
);
write_config( $minfo, $my_config );
myredirect("edit_module.cgi?idx=$in{'idx'}");
}
elsif ( $in{'opt'} eq 'update_vol' ) {
if ( ( $in{'vol_colour1_def'} eq 'nocolour' )
and ( $in{'vol_colour2_def'} eq $EMPTY ) )
{
error( $text{'save_einvaled_selection'} );
}
my ( $vol_id, $vol_name, $vol_type, $vol_config, $runstop, $display ) =
unpack_config( $my_config->{ $pre . $in{$pre} } );
$my_config->{ $pre . $in{$pre} } = pack_config(
$vol_id,
$vol_name,
$vol_type,
set_line_config(
get_colourselect( 'vol_colour', $EMPTY ),
get_lineselect('vol_line')
),
$in{'runstop_def'},
$in{'display_def'}
);
# test for display : force to create an dummy label
test_for_new_display($my_config);
write_config( $minfo, $my_config );
myredirect("edit_module.cgi?idx=$in{'idx'}");
}
elsif ( $in{'opt'} eq 'general' ) {
test_database_change( $minfo, $my_config );
test_local_params($my_config);
test_display_change($my_config);
test_scale_change( $minfo, $my_config );
test_default_change($my_config);
# configuration
test_module_config($my_config);
write_config( $minfo, $my_config );
}
else {
error($in);
}
debug_sub_end();
return;
}
###############################################################################
sub param2type($) {
my $param = shift @_;
my ( $type, $location ) = decode_param($param);
return $type;
}
###############################################################################
# get data from hplog-client
#ID TYPE LOCATION STATUS REDUNDANT FAN SPEED
# 1 Basic Fan Processor Zone Nominal N/A -------
# 2 Basic Fan Pwr. Supply Bay Nominal N/A -------
#ID TYPE LOCATION STATUS CURRENT THRESHOLD
# 1 ADM1022 Processor Zone Nominal 86F/ 30C 156F/ 69C
# 2 ADM1022 I/O Zone Nominal 96F/ 36C 167F/ 75C
# 3 ADM1022 CPU (1) Nominal 87F/ 31C 161F/ 72C
# 4 ADM1022 CPU (2) Nominal 87F/ 31C 161F/ 72C
#
sub tab_vol($) {
my $my_config = shift @_;
debug_sub_begin();
my @tab;
my $cmd = $my_config->{$module_cmd};
if ($cmd) {
# first temperatures
my $r_tab = read_pipe("$cmd -t");
my $first_line = 1;
foreach my $line ( @{$r_tab} ) {
chomp $line;
next if ( $line eq q{} );
if ($first_line) {
$first_line = 0;
next;
}
my $location = substr $line, 17, 13;
$location =~ s/\s*$//;
#print "$location : $value\n";
my $name = encode_param( 'temp', $location );
push @tab, $name;
}
# then fan
$cmd = $my_config->{$module_cmd} . ' -f';
$r_tab = read_pipe($cmd);
$first_line = 1;
foreach my $line ( @{$r_tab} ) {
chomp $line;
next if ( $line eq q{} );
if ($first_line) {
$first_line = 0;
next;
}
my $location = substr $line, 17, 13;
$location =~ s/\s*$//;
#print "$location : $value\n";
my $name = encode_param( 'fan', $location );
push @tab, $name;
}
}
else {
debug("tab_vol : unconfigured $module_cmd");
}
debug_sub_end();
return @tab;
}
###############################################################################
sub create_base($$$) {
my ( $minfo, $my_config, $db_uid ) = ( $_[0], $_[1], $_[2] );
debug_sub_begin();
my $cf = $my_config->{'cf'};
my $heartbeat = compute_heartbeat( $my_config->{'sample_rate'} );
my $base = $minfo->{'dbtables'} . $db_uid . '.rrd';
create_rrd( $base, "DS:$data_name:GAUGE:$heartbeat:0:U", $cf );
debug_sub_end();
return;
}
###############################################################################
sub write_config($$) {
my ( $minfo, $my_config ) = ( $_[0], $_[1] );
debug_sub_begin();
common_write_config( $minfo, $my_config );
debug_sub_end();
return;
}
###############################################################################
sub postupgrade($$$) {
my ( $minfo, $my_config, $defaults ) = ( $_[0], $_[1], $_[2] );
debug_sub_begin();
debug_sub_end();
return;
}
###############################################################################
# get/set_display/runstop must be defined to allow mod_config_opt to work
sub toggle_display($) {
my $line = shift @_;
my ( $vol_id, $vol_name, $vol_type, $vol_config, $runstop, $display ) =
unpack_config($line);
$display = toggle_param_display($display);
$line = pack_config( $vol_id, $vol_name, $vol_type, $vol_config, $runstop,
$display );
return $line;
}
###############################################################################
sub toggle_runstop($) {
my $line = shift @_;
my ( $vol_id, $vol_name, $vol_type, $vol_config, $runstop, $display ) =
unpack_config($line);
$runstop = toggle_param_runstop($runstop);
$line = pack_config( $vol_id, $vol_name, $vol_type, $vol_config, $runstop,
$display );
return $line;
}
###############################################################################
# local config
###############################################################################
sub change_module_config($) {
my $my_config = $_[0];
debug_sub_begin();
titre_table('files');
begin_table('files'); # general
# hplog path
print_input( $module_cmd, $module_cmd, $my_config->{$module_cmd}, 1, 1, 1 );
end_table(); # general
separator();
debug_sub_end();
return;
}
###############################################################################
sub test_module_config($) {
my $my_config = $_[0];
debug_sub_begin();
if ( $in{'guess'} ) {
$my_config->{$module_cmd} = search_command($module_cmd);
}
else {
$my_config->{$module_cmd} = $in{$module_cmd};
}
# if bad path, disable module
$my_config->{'runstop'} = test_command( $my_config->{$module_cmd} );
if ( $my_config->{'runstop'} ) {
warning( "disable $module_name : " . get_error() );
}
debug_sub_end();
return;
}
###############################################################################
sub guess_hplog_client() {
my $client = search_command($module_cmd);
return $client;
}
###############################################################################
sub list_params($) {
my $my_config = $_[0];
return list_used_param($my_config);
}
###############################################################################
1;