Check in cluster shutdown module

This commit is contained in:
Jamie Cameron
2014-07-06 08:32:25 -07:00
parent 893d48a02a
commit 1470699f53
13 changed files with 282 additions and 0 deletions

32
cluster-shutdown/check.pl Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/local/bin/perl
# Send email when a system is down
$no_acl_check++;
require './cluster-shutdown-lib.pl';
&foreign_require("mailboxes", "mailboxes-lib.pl");
@servers = grep { $_->{'user'} } &servers::list_servers();
%up = &get_all_statuses(\@servers);
$last_status_file = "$module_config_directory/last";
&read_file($last_status_file, \%oldstatus);
foreach $s (@servers) {
if (!$up{$s} && $oldstatus{$s->{'id'}}) {
# Just went down .. send email
local $mail =
{ 'headers' => [ [ 'From', 'webmin@'.&get_system_hostname() ],
[ 'To', $config{'email'} ],
[ 'Subject', "System $s->{'host'} is down" ],
],
'attach' =>
[ { 'headers' => [ [ 'Content-type', 'text/plain' ] ],
'data' => "The system $s->{'host'} has gone down!" } ]
};
&mailboxes::send_mail($mail, undef, undef, 0, $config{'smtp'});
}
$oldstatus{$s->{'id'}} = $up{$s};
}
&write_file($last_status_file, \%oldstatus);

View File

@@ -0,0 +1,55 @@
do '../web-lib.pl';
&init_config();
do '../ui-lib.pl';
&foreign_require("servers", "servers-lib.pl");
%access = &get_module_acl();
$cron_cmd = "$module_config_directory/check.pl";
sub find_cron_job
{
&foreign_require("cron", "cron-lib.pl");
local ($job) = grep { $_->{'command'} eq $cron_cmd } &cron::list_cron_jobs();
return $job;
}
# get_all_statuses(&servers)
# Returns a hash mapping servers to their statuses. The possible values are:
# 0 = down
# 1 = up
# 2 = up but login is not possible
# 3 = up but login failed
sub get_all_statuses
{
# Check which ones are up, in parallel
my ($servers) = @_;
my %pid;
foreach my $s (@$servers) {
my $pid;
if (!($pid = fork())) {
my $out = `ping -c 1 -w 1 $s->{'host'} 2>&1`;
if ($config{'login'} && !$?) {
# Attempt a Webmin login too
if (!$s->{'user'}) {
exit(101);
}
local $err = &servers::test_server($s->{'host'});
exit($err ? 102 : 0);
}
exit($? ? 1 : 0);
}
$pid{$s} = $pid;
}
my %up;
foreach my $s (@$servers) {
my $pid = waitpid($pid{$s}, 0);
$up{$s} = $? == 0 ? 1 :
$?/256 == 101 ? 2 :
$?/256 == 102 ? 3 : 0;
}
return %up;
}
1;

1
cluster-shutdown/config Normal file
View File

@@ -0,0 +1 @@
login=0

View File

@@ -0,0 +1 @@
login=Attempt Webmin login when testing servers?,1,1-Yes,0-No

View File

@@ -0,0 +1,2 @@
reboot=1
shut=1

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

67
cluster-shutdown/index.cgi Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/local/bin/perl
# Show a list of cluster servers that can be shut down
require './cluster-shutdown-lib.pl';
&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
@servers = grep { $_->{'user'} } &servers::list_servers();
%up = &get_all_statuses(\@servers);
if (@servers) {
print &ui_form_start("shutdown.cgi", "post");
@links = ( &select_all_link("id"),
&select_invert_link("id") );
print &ui_links_row(\@links);
print &ui_columns_start([ "",
$text{'index_host'},
$text{'index_desc'},
$text{'index_os'},
$text{'index_up'} ]);
foreach $s (@servers) {
($st) = grep { $_->[0] eq $s->{'type'} } @servers::server_types;
print &ui_checked_columns_row(
[ $s->{'host'},
$s->{'desc'},
$st->[1],
$up{$s} == 1 ?
"<font color=#00aa00>$text{'yes'}</font>" :
$up{$s} == 2 ?
"<font color=#000000>$text{'index_nu'}</font>" :
$up{$s} == 3 ?
"<font color=#ffaa00>$text{'index_nl'}</font>" :
"<font color=#ff0000>$text{'no'}</font>" ],
undef, "id", $s->{'id'});
}
print &ui_columns_end();
print &ui_links_row(\@links);
push(@buts, [ "shut", $text{'index_shut'} ]) if ($access{'shut'});
push(@buts, [ "reboot", $text{'index_reboot'} ]) if ($access{'reboot'});
print &ui_form_end(\@buts);
}
else {
print "<b>",&text('index_none', "../servers/"),"</b><p>\n";
}
if (@servers) {
# Show email notification form
print "<hr>\n";
print &ui_form_start("save_sched.cgi", "post");
print &ui_table_start($text{'index_header'}, undef, 2);
$job = &find_cron_job();
print &ui_table_row($text{'index_sched'},
&ui_yesno_radio("sched", $job ? 1 : 0));
print &ui_table_row($text{'index_email'},
&ui_textbox("email", $config{'email'}, 40));
print &ui_table_row($text{'index_smtp'},
&ui_opt_textbox("smtp", $config{'smtp'}, 30,
$text{'index_this'}));
print &ui_table_end();
print &ui_form_end([ [ "save", $text{'save'} ] ]);
}
&ui_print_footer("/", $text{'index'});

38
cluster-shutdown/lang/en Normal file
View File

@@ -0,0 +1,38 @@
index_title=Cluster Shutdown
index_host=Hostname
index_desc=Description
index_os=Operating System
index_up=Alive?
index_shut=Shut Down Servers
index_reboot=Reboot Servers
index_none=No servers have been defined in the <a href='$1'>Webmin Servers Index</a> module.
index_return=module index
index_header=Automatic system check
index_sched=Enable automatic system check?
index_email=Send email on system failures to
index_smtp=Send via SMTP server
index_this=This server
index_nu=No user set
index_nl=Login failed
shut_title=Shut Down Servers
shut_rusure=Are you sure you want to immediately shut down the $1 selected servers?
shut_ok=Yes, Do It
shut_doing=Shutting down $1 ..
shut_failed=.. failed! $1
shut_done=.. done.
shut_sel=The selected servers are :
shut_ecannot=You are not allowed to shut down servers
reboot_title=Reboot Servers
reboot_rusure=Are you sure you want to immediately reboot the $1 selected servers?
reboot_doing=Rebooting $1 ..
reboot_ecannot=You are not allowed to reboot servers
sched_err=Failed to setup automatic server checking
sched_eemail=Missing email address
sched_esmtp=Missing or invalid SMTP server
sched_title=Automatic Server Check
sched_enabled=Automatic checking of all servers every five minutes is now enabled.
sched_disabled=Automatic checking of all servers is now disabled.
__norefs=1

View File

@@ -0,0 +1,4 @@
desc=Cluster Shutdown
category=cluster
depends=servers
version=1.0

67
cluster-shutdown/shutdown.cgi Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/local/bin/perl
# Shut down the servers, after asking for confirmation
require './cluster-shutdown-lib.pl';
&ReadParse();
$pfx = $in{'shut'} ? 'shut' : 'reboot';
$access{$pfx} || &error($text{$pfx.'_ecannot'});
@ids = split(/\0/, $in{'id'});
@ids || &error($text{$pfx.'_enone'});
@servers = &servers::list_servers();
# Setup error handler for down hosts
sub inst_error
{
$inst_error_msg = join("", @_);
}
&remote_error_setup(\&inst_error);
if ($in{'confirm'}) {
# Do it!
&ui_print_unbuffered_header(undef, $text{$pfx.'_title'}, "");
foreach $id (@ids) {
($server) = grep { $_->{'id'} eq $id } @servers;
next if (!$server);
print &text($pfx.'_doing', $server->{'host'}),"<br>\n";
$inst_error_msg = undef;
$iconfig = &remote_foreign_config($server->{'host'}, "init");
if ($inst_error_msg) {
print &text('shut_failed', $inst_error_msg),"<p>\n";
next;
}
&remote_foreign_require($server->{'host'}, "init",
"init-lib.pl");
$cmd = $pfx eq 'shut' ? $iconfig->{'shutdown_command'}
: $iconfig->{'reboot_command'};
$out = &remote_eval($server->{'host'}, "init",
"system('$cmd')");
print &text('shut_done'),"<p>\n";
}
&ui_print_footer("", $text{'index_return'});
}
else {
# Ask first
&ui_print_header(undef, $text{$pfx.'_title'}, "");
print &ui_form_start("shutdown.cgi", "post");
foreach $id (@ids) {
print &ui_hidden("id", $id);
($server) = grep { $_->{'id'} eq $id } @servers;
push(@names, $server->{'host'});
}
print &ui_hidden($pfx, 1);
print "<center>\n";
print "<b>",&text($pfx.'_rusure', scalar(@ids)),"</b> <p>\n";
print &ui_submit($text{'shut_ok'}, "confirm"),"<p>\n";
print "<b>",$text{'shut_sel'},"\n",
join(" ", map { "<tt>$_</tt>" } @names),"</b><p>\n";
print "</center>\n";
print &ui_form_end();
&ui_print_footer("", $text{'index_return'});
}

View File

@@ -0,0 +1,15 @@
# uninstall.pl
# Called when webmin is uninstalled
require 'cluster-shutdown-lib.pl';
sub module_uninstall
{
local $job = &find_cron_job();
if ($job) {
&cron::delete_cron_job($j);
}
}
1;