#!/usr/bin/perl -w
###############################################################################
# Webmin Sysstats - load-lib.pl
#
# Webmin Sysstats Module
# Copyright (C) 2004 by Eric Gerbier
# Bug reports to: gerbier@users.sourceforge.net
# $Id$
#
# 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 %access $cb $tb );
## use critic
my $fscript = 'load.pl';
my $pre = 'load';
my $EMPTY = EMPTY();
###############################################################################
sub install_module($$) {
my ( $minfo, $defaults ) = ( $_[0], $_[1] );
debug_sub_begin();
my @colors = generate_colors();
my %my_config = init_module_config( 'load', 1 );
$my_config{'cf'} = 'MAX';
$my_config{'pre'} = $pre;
my @load_list = tab_load();
my $db_uid = 1;
foreach my $load (@load_list) {
create_base( $minfo, \%my_config, $db_uid );
# create config file
my ( $load_number, $load_name ) = split /:/, $load;
if ( !$load_name ) {
$load_name = $load_number;
}
else {
# is there any "," training ?
$load_name =~ s/,//;
$load_name =~ s/ //;
}
$my_config{ $pre . $db_uid } =
pack_config( $db_uid, $load_number, $load_name,
$colors[ ( $db_uid - 1 ) % ( scalar @colors ) ],
0, 0 );
$db_uid++;
}
$my_config{'db_uid'} = $db_uid;
$my_config{'graph_type'} = 1;
$my_config{'nb_graph'} = 2;
$my_config{'keep'} = 0; # dynamique
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( 'load', 'load', \@rrd_detals );
# and a step at 1
push @rrd_detals, 'HRULE:1#FF0000';
my $load_num = 1;
my $first_graph = 1;
VOL: while ( defined $my_config->{ $pre . $load_num } ) {
my $load_nb = $pre . $load_num;
my (
$load_id, $load_number, $load_name,
$load_config, $runstop, $display
) = unpack_config( $my_config->{$load_nb} );
if ($runstop) {
$load_num++;
next VOL;
}
if ( $display == $c_display ) {
add_def( \@rrd_detals, $load_nb, $minfo->{'dbtables'} . $load_id,
'load', $cf );
if ( $graph_type == 1 ) {
# lines
gprint_param( \@rrd_detals, $load_nb, $load_name,
$load_config );
}
else {
# histogram
my $type;
if ($first_graph) {
$first_graph = 0;
$type = 'AREA';
}
else {
$type = 'STACK';
}
gprint_param( \@rrd_detals, $load_nb, $load_name, $load_config,
$type );
}
}
$load_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();
my (
$load_id, $load_number, $load_name, $load_config,
$runstop, $display, $load_colour, $load_line,
);
#debug_hash( '%in', %in );
mod_config_opt( $minfo, $my_config, $pre );
begin_html_config(1);
# title general
change_database( $minfo, $my_config );
change_local_params($my_config);
change_display($my_config);
change_scale( $minfo, $my_config );
change_default( $my_config->{'graph_type'},
$text{'word_line'}, $text{'word_bar'} );
my @columns = (
'module_subtitle_load_name', 'module_display_name',
'word_subtitle_disp_colour', 'word_subtitle_controls',
);
end_html_config(@columns);
my @load_list = tab_load();
my $load_num = 1;
my $load_sname;
while ( defined $my_config->{ $pre . $load_num } ) {
( $load_id, $load_number, $load_name, $load_config, $runstop, $display )
= unpack_config( $my_config->{ $pre . $load_num } );
( $load_colour, $load_line ) = get_line_config($load_config);
#for ( my $i = 0 ; $i < scalar(@load_list) ; $i++ ) {
foreach my $l (@load_list) {
#my ( $n, $name ) = split /:/, $load_list[$i] ;
my ( $n, $name ) = split /:/, $l;
if ( $n eq $load_number ) {
$load_sname = $name;
last;
}
}
if ( !$load_sname ) {
$load_sname = $load_name;
}
print "<tr $cb>\n";
print
"<td><strong><a href=\"edit_module.cgi?idx=$in{'idx'}&opt=edit&load_num=$load_num\">$load_sname</a></strong></td>\n";
print "<td>$load_name</td>\n";
print "<td><font color=\"#$load_colour\"><strong>";
print $text{ 'colour_' . $load_colour }
? $text{ 'colour_' . $load_colour }
: "<pre>#$load_colour </pre>";
print "</strong></font></td>\n";
print '<td align=right>';
display_parameter_line( $load_num, $runstop, $display, $my_config,
$pre );
print "</td>\n";
$load_num++;
}
print "</tr>\n";
end_table();
if ( ( exists $in{'opt'} ) and ( $in{'opt'} eq 'edit' ) ) {
( $load_id, $load_number, $load_name, $load_config, $runstop, $display )
= unpack_config( $my_config->{ $pre . $in{'load_num'} } );
( $load_colour, $load_line ) = get_line_config($load_config);
begin_table( 'edition', 'border' );
print "<tr $tb><td><strong>"
. $text{'module_load'}
. "</strong></td></tr>\n";
print "<tr $cb>";
print '<td>';
print '<form action="save_config.cgi">';
print '<table ' . w100() . ">\n";
print "<tr>\n";
title_row( $text{'module_word_load'}, w15() );
title_row( $load_name, 'nowrap' );
print "</tr>\n";
modify_colour( $load_config, $display, $runstop, $my_config, $pre );
print '<tr>';
title_row( $text{'module_display_name'} );
print
"<td><input type=text name=\"load_name_def\" size=9 maxlength=18 value=\"$load_name\">";
print "</td></tr>\n";
print '<tr>';
print '<td align=left>';
print '<input type=hidden name=idx value="' . $in{'idx'} . '">';
print '<input type=hidden name=opt value="update_load">';
print '<input type=hidden name=load value="' . $in{'load_num'} . '">';
print "<input type=submit value=\"$text{'word_update'}\">";
print "</td>\n";
print "</tr>\n";
print "</table>\n";
print "</form>\n";
print "</td>\n";
print "</tr>\n";
end_table();
}
else {
my $i = 0;
begin_table( 'new_config', 'border' );
print "<tr $tb><td><strong>"
. $text{'module_new_load'}
. "</strong></td></tr>\n";
print "<tr $cb>";
print '<td>';
print '<form action="save_config.cgi">';
print '<table ' . w100() . ">\n";
print "<tr>\n";
title_row( $text{'module_word_load'}, w15() );
print '<td nowrap><strong>';
print "<select name=\"new_load_def\">\n";
print '<option value="' . $i++ . "\">$text{'word_select'}\n";
my @load_unknown = filter_known( $my_config, @load_list );
foreach my $vlist (@load_unknown) {
print '<option value="' . $i++ . "\">$vlist\n";
}
print '</select>';
print "</strong></td>\n";
print "</tr>\n";
modify_colour( '00ff00', 0, 0, $my_config, $pre );
print '<tr>';
title_row( $text{'module_display_name'} );
print
'<td><input type=text name="new_load_name_def" size=9 maxlength=18 value="">';
print "</td>\n";
print '<tr>';
print '<td align=left>';
print '<input type=hidden name=idx value="' . $in{'idx'} . '">';
print '<input type=hidden name=opt value="new_load">';
print '<input type=hidden name=load value="' . $load_num . '">';
print "<input type=submit value=\"$text{'word_addnew'}\">";
print "</td>\n";
print "</tr>\n";
print "</table>\n";
print "</form>\n";
print "</td>\n";
print "</tr>\n";
end_table();
}
end_table();
print "</table>\n";
debug_sub_end();
return;
}
###############################################################################
sub mod_config_save($$$) {
my ( $minfo, $my_config, $defaults ) = ( $_[0], $_[1], $_[2] );
debug_sub_begin();
#debug_hash( '%in', %in );
if ( $in{'opt'} eq 'new_load' ) {
if (
( $in{'new_load_def'} eq '0' )
or ( $in{'new_load_name_def'} eq $EMPTY )
or ( ( $in{'load_colour1_def'} eq 'nocolour' )
and ( $in{'load_colour2_def'} eq $EMPTY ) )
)
{
error( $text{'save_einvaled_selection'} );
}
create_base( $minfo, $my_config, $my_config->{'db_uid'} );
#my @load_list = tab_load();
my @load_list = filter_known( $my_config, tab_load() );
my $load_number = @load_list[ $in{'new_load_def'} - 1 ];
$load_number =~ s/://;
$my_config->{ $pre . $in{$pre} } = pack_config(
$my_config->{'db_uid'}++,
$load_number,
$in{'new_load_name_def'},
set_line_config(
get_colourselect( 'load_colour', $EMPTY ),
get_lineselect('user_line')
),
0,
$in{'display_def'}
);
write_config( $minfo, $my_config );
myredirect("edit_module.cgi?idx=$in{'idx'}");
}
elsif ( $in{'opt'} eq 'update_load' ) {
my $load_num = $in{$pre};
if ( ( $in{'load_colour1_def'} eq 'nocolour' )
and ( $in{'load_colour2_def'} eq $EMPTY ) )
{
error( $text{'save_einvaled_selection'} );
}
my (
$load_id, $load_number, $load_name,
$load_colour, $runstop, $display
) = unpack_config( $my_config->{ $pre . $in{$pre} } );
$my_config->{ $pre . $in{$pre} } = pack_config(
$load_id,
$load_number,
$in{'load_name_def'},
set_line_config(
get_colourselect( 'load_colour', $EMPTY ),
get_lineselect('load_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);
write_config( $minfo, $my_config );
}
else {
error($in);
}
debug_sub_end();
return;
}
###############################################################################
sub tab_load () {
my $flag = shift @_;
debug_sub_begin();
my @tab = ( 'load1', 'load5', 'load15' );
debug_sub_end();
return @tab;
}
###############################################################################
sub create_base($$$) {
debug_sub_begin();
my $minfo = shift @_;
my $my_config = shift @_;
my $db_uid = shift @_;
my $cf = $my_config->{'cf'};
my $heartbeat = compute_heartbeat( $my_config->{'sample_rate'} );
my $base = $minfo->{'dbtables'} . $db_uid . '.rrd';
create_rrd( $base, "DS:load: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();
# copy and rename old database
my $oldbase = 'load.rrd';
if ( -f $minfo->{'dbtables'} . $oldbase ) {
update_base( $minfo, $oldbase, '1.rrd' );
mod_cf( 'AVERAGE', 'MAX', ( $minfo->{'dbtables'} . '/1.rrd' ) );
}
common_write_config( $minfo, $my_config );
debug_sub_end();
return;
}
###############################################################################
# toggle_display/runstop must be defined to allow mod_config_opt to work
sub toggle_display($) {
my $line = shift @_;
my ( $load_id, $load_number, $load_name, $load_config, $runstop, $display )
= unpack_config($line);
$display = toggle_param_display($display);
$line = pack_config(
$load_id, $load_number, $load_name,
$load_config, $runstop, $display
);
return $line;
}
###############################################################################
sub toggle_runstop($) {
my $line = shift @_;
my ( $load_id, $load_number, $load_name, $load_config, $runstop, $display )
= unpack_config($line);
$runstop = toggle_param_runstop($runstop);
$line = pack_config(
$load_id, $load_number, $load_name,
$load_config, $runstop, $display
);
return $line;
}
###############################################################################
1;