From 1470699f53b235e1c936d6caa5abf22bc62f70f6 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Sun, 6 Jul 2014 08:32:25 -0700 Subject: [PATCH] Check in cluster shutdown module --- cluster-shutdown/check.pl | 32 +++++++++++ cluster-shutdown/cluster-shutdown-lib.pl | 55 +++++++++++++++++++ cluster-shutdown/config | 1 + cluster-shutdown/config.info | 1 + cluster-shutdown/defaultacl | 2 + cluster-shutdown/images/.xvpics/icon.gif | Bin 0 -> 2369 bytes cluster-shutdown/images/icon.gif | Bin 0 -> 457 bytes cluster-shutdown/images/smallicon.gif | Bin 0 -> 339 bytes cluster-shutdown/index.cgi | 67 +++++++++++++++++++++++ cluster-shutdown/lang/en | 38 +++++++++++++ cluster-shutdown/module.info | 4 ++ cluster-shutdown/shutdown.cgi | 67 +++++++++++++++++++++++ cluster-shutdown/uninstall.pl | 15 +++++ 13 files changed, 282 insertions(+) create mode 100755 cluster-shutdown/check.pl create mode 100644 cluster-shutdown/cluster-shutdown-lib.pl create mode 100644 cluster-shutdown/config create mode 100644 cluster-shutdown/config.info create mode 100644 cluster-shutdown/defaultacl create mode 100644 cluster-shutdown/images/.xvpics/icon.gif create mode 100644 cluster-shutdown/images/icon.gif create mode 100644 cluster-shutdown/images/smallicon.gif create mode 100755 cluster-shutdown/index.cgi create mode 100644 cluster-shutdown/lang/en create mode 100644 cluster-shutdown/module.info create mode 100755 cluster-shutdown/shutdown.cgi create mode 100644 cluster-shutdown/uninstall.pl diff --git a/cluster-shutdown/check.pl b/cluster-shutdown/check.pl new file mode 100755 index 000000000..941d284e6 --- /dev/null +++ b/cluster-shutdown/check.pl @@ -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); + diff --git a/cluster-shutdown/cluster-shutdown-lib.pl b/cluster-shutdown/cluster-shutdown-lib.pl new file mode 100644 index 000000000..ba718c9a1 --- /dev/null +++ b/cluster-shutdown/cluster-shutdown-lib.pl @@ -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; + diff --git a/cluster-shutdown/config b/cluster-shutdown/config new file mode 100644 index 000000000..c844ad194 --- /dev/null +++ b/cluster-shutdown/config @@ -0,0 +1 @@ +login=0 diff --git a/cluster-shutdown/config.info b/cluster-shutdown/config.info new file mode 100644 index 000000000..fc6af65d8 --- /dev/null +++ b/cluster-shutdown/config.info @@ -0,0 +1 @@ +login=Attempt Webmin login when testing servers?,1,1-Yes,0-No diff --git a/cluster-shutdown/defaultacl b/cluster-shutdown/defaultacl new file mode 100644 index 000000000..95efc1ec9 --- /dev/null +++ b/cluster-shutdown/defaultacl @@ -0,0 +1,2 @@ +reboot=1 +shut=1 diff --git a/cluster-shutdown/images/.xvpics/icon.gif b/cluster-shutdown/images/.xvpics/icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..20ef9810c2ba1c528a2e9bd5733444625c28db9b GIT binary patch literal 2369 zcmb_e!D`z;5Y5?NVTc9RHA-;kF_jW6)JdreIR*+nq@Y|{X!{F26e_6u1wF{niwmKg5AshN&9AZCCiSJx}~<*jq#h=H*aR2^L#RlqNBl~m|lp>^Q$Mvryq__hc7P9 zhU4Rt$?(<3cdy@ugTv%9zPUQTd3rUSCYLW~17PqRotz9bDNS0@#zLfmG!XcXf>dLZ z0J&u!{6Y6ZR_Z?ZKX8~-G!h~}M(kRx5&s9j&MgE8xcr7s*`0qE-WU$p8*dKyy+8hd z(c5@#18dS>puc3K$CrIQAHpkcm8t4d*VQIIx}IIn@U(BGp?_T|Jix2!9)9(ySQI}N z#bRP(7@wq-YRblN6xCb#@8OA>5@$4((Nfr%veno{t7w(a^DoPM{(bU3!n-NCUsi&S ze}6us72x@Do)@kJP2hkgq12B5ZoH&9{Upd&%ThI!27g{lf#$bIO7NNI;Dh|Y%OzC` z^@GNd>&_;aQdD+1+h61v~@wAQcHZOMww%O^ua{xiBFmZC~jY z$=_rMk*cARnsG7~tj|b&sx)sn`>`4`S?V^qNDJ9V`-ra}#M zX?y1DeGCuUsFh@j0O-lJqhAl_|0BNha1n5ANGp)v@$K?&XtJ)Qi}n8B-N*j@^;|JM zsnwnJ_l{r~r!m_9hUaiy)^ePr0z)a&Fy{W^e(lW9aNuK$!S@6yvF&_|w0Ha%V*?iYpwNca2&p4;dm*@cN`(A|%~?(i%8 zU(g;8zJQRsf9z%KeePcS-QL|a_{9b#-Cb|9gB+%Y&)~V_Jnnm2;Cit?2JPa#0G^!)81-fjp-UI13_1@kh literal 0 HcmV?d00001 diff --git a/cluster-shutdown/images/icon.gif b/cluster-shutdown/images/icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..8c16688bda7d7732e4d0b852d834e14d7ef5a949 GIT binary patch literal 457 zcmZ?wbhEHbG+;1bc+9|X=FAxe28RC(3?7UBZ}P1=bLRidnKRdII-Hi4_8%Ki{K>+| z#lX*?1JngH!GM8*<)6R_&+J-@?A+b|uc)O3CCt-kU6-TKn|yQDt2_HXsGZ-s_mQPg zf~tpajZVUcjocjbmdj0Ii{SD5)Zh&TmQx~nniAYio^Qb@0nxR z?@eT8V`*$^s)!S*sd7%KZ|-dkm1dp9G)bn*riX3TY&MpDr}iAVhB>q6l{>JCb}SNE zvUD!{rp*pQlO}IpHDQ|A`lT$Jx9nD8^4__Z4~E?No;Uqd*J{VPcLd9x*G#l~^E0R;DEQf?<90ZT z0e*jUb_@&>MJ5F&ZB14Y85t`Ki580{Vh5TB3tAM0hKMMa7HkBk1WqLuId38Su<3!9n_xVpQhs014c7s4qlExSD{QWZ-|&M7YjGCmUq1{ek3;NciaOg<0P l&SN6X($!Eb3tc3+&hjJ3ZGLgpY=Uung8ozkC}=?l06Y86m9qc< literal 0 HcmV?d00001 diff --git a/cluster-shutdown/index.cgi b/cluster-shutdown/index.cgi new file mode 100755 index 000000000..c1fbe4c92 --- /dev/null +++ b/cluster-shutdown/index.cgi @@ -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 ? + "$text{'yes'}" : + $up{$s} == 2 ? + "$text{'index_nu'}" : + $up{$s} == 3 ? + "$text{'index_nl'}" : + "$text{'no'}" ], + 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 "",&text('index_none', "../servers/"),"

\n"; + } + +if (@servers) { + # Show email notification form + print "


\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'}); + diff --git a/cluster-shutdown/lang/en b/cluster-shutdown/lang/en new file mode 100644 index 000000000..2edb54bbe --- /dev/null +++ b/cluster-shutdown/lang/en @@ -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 Webmin Servers Index 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 diff --git a/cluster-shutdown/module.info b/cluster-shutdown/module.info new file mode 100644 index 000000000..cb02c9a6d --- /dev/null +++ b/cluster-shutdown/module.info @@ -0,0 +1,4 @@ +desc=Cluster Shutdown +category=cluster +depends=servers +version=1.0 diff --git a/cluster-shutdown/shutdown.cgi b/cluster-shutdown/shutdown.cgi new file mode 100755 index 000000000..cd8cd2615 --- /dev/null +++ b/cluster-shutdown/shutdown.cgi @@ -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'}),"
\n"; + $inst_error_msg = undef; + $iconfig = &remote_foreign_config($server->{'host'}, "init"); + if ($inst_error_msg) { + print &text('shut_failed', $inst_error_msg),"

\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'),"

\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 "

\n"; + print "",&text($pfx.'_rusure', scalar(@ids)),"

\n"; + print &ui_submit($text{'shut_ok'}, "confirm"),"

\n"; + print "",$text{'shut_sel'},"\n", + join(" ", map { "$_" } @names),"

\n"; + print "

\n"; + print &ui_form_end(); + + &ui_print_footer("", $text{'index_return'}); + } + + diff --git a/cluster-shutdown/uninstall.pl b/cluster-shutdown/uninstall.pl new file mode 100644 index 000000000..2bc1406a1 --- /dev/null +++ b/cluster-shutdown/uninstall.pl @@ -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; +