* Updated anvil-shutdown-server to take the new '--immediate' switch which forces a server to shut down immediately (akin to pulling the power on a traditional machine). This is needed to allow a user to recover a crash or hung server.

Signed-off-by: digimer <mkelly@alteeve.ca>
main
digimer 1 year ago
parent 122816255d
commit 8925dabb9d
  1. 5
      Anvil/Tools/Server.pm
  2. 6
      man/anvil-shutdown-server.8
  3. 2
      share/words.xml
  4. 53
      tools/anvil-shutdown-server

@ -2145,8 +2145,11 @@ sub shutdown_virsh
elsif ($status eq "pmsuspended") elsif ($status eq "pmsuspended")
{ {
# The server is suspended. Resume it, wait a few, then proceed with the shutdown. # The server is suspended. Resume it, wait a few, then proceed with the shutdown.
my $shell_call = $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." dompmwakeup ".$server;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0317", variables => { server => $server }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0317", variables => { server => $server }});
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{setsid}." --wait ".$anvil->data->{path}{exe}{virsh}." dompmwakeup $server"}); my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
if ($return_code) if ($return_code)
{ {
# Looks like virsh isn't running. # Looks like virsh isn't running.

@ -19,6 +19,10 @@ When logging, record sensitive data, like passwords.
Set the log level to 1, 2 or 3 respectively. Be aware that level 3 generates a significant amount of log data. Set the log level to 1, 2 or 3 respectively. Be aware that level 3 generates a significant amount of log data.
.SS "Commands:" .SS "Commands:"
.TP .TP
\fB\-\-immediate\fR
.TP
This causes the server to be forced off, equivalent to pulling the power cord out of a traditional server. This doesn't work with '\fB\-\-server all\fR', a specific server must be specified.
.TP
\fB\-\-no\-db\fR \fB\-\-no\-db\fR
.TP .TP
This tells the program to run without connecting to any databases. This is used mainly when the host is being taken down as part of a cluster-wise upgrade. This tells the program to run without connecting to any databases. This is used mainly when the host is being taken down as part of a cluster-wise upgrade.
@ -38,6 +42,8 @@ This is the server UUID of the server to shut down. NOTE: This can not be used w
\fB\-\-wait\fR \fB\-\-wait\fR
.TP .TP
This tells the program to wait for the server(s) to stop before returning. By default, when '\fB\-\-server all\fR' is used,, the shutdown will NOT wait. This makes the shutdowns sequential. This tells the program to wait for the server(s) to stop before returning. By default, when '\fB\-\-server all\fR' is used,, the shutdown will NOT wait. This makes the shutdowns sequential.
.TP
Note: When \fB\-\-immediate\fR is used, \fB\-\-wait\fR is ignored.
.IP .IP
.SH AUTHOR .SH AUTHOR
Written by Madison Kelly, Alteeve staff and the Anvil! project contributors. Written by Madison Kelly, Alteeve staff and the Anvil! project contributors.

@ -725,6 +725,7 @@ The creation of the new replicatedd disk is incomplete, manual intervention is r
#!variable!error!# #!variable!error!#
==================== ====================
The creation of the new replicated disk is incomplete, manual intervention is required!]]></key> The creation of the new replicated disk is incomplete, manual intervention is required!]]></key>
<key name="error_0462"><![CDATA[The switch '--immediate' can not be used with '--server all'.]]></key>
<!-- Files templates --> <!-- Files templates -->
<!-- NOTE: Translating these files requires an understanding of which lines are translatable --> <!-- NOTE: Translating these files requires an understanding of which lines are translatable -->
@ -1684,6 +1685,7 @@ Note: This is a permanent action! If you protect this server again later, a full
<key name="job_0471">Exiting.</key> <key name="job_0471">Exiting.</key>
<key name="job_0472">Server Storage Management</key> <key name="job_0472">Server Storage Management</key>
<key name="job_0473">This job manages the storage on a given hosted server. It can grow an existing disk, add a new disk, insert an ISO into an optical disc, or eject a disc.</key> <key name="job_0473">This job manages the storage on a given hosted server. It can grow an existing disk, add a new disk, insert an ISO into an optical disc, or eject a disc.</key>
<key name="job_0474">The server: [#!variable!server!#] will now be forced off!</key>
<!-- Log entries --> <!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key> <key name="log_0001">Starting: [#!variable!program!#].</key>

@ -29,6 +29,7 @@ my $anvil = Anvil::Tools->new();
# Read switches (target ([user@]host[:port]) and the file with the target's password. # Read switches (target ([user@]host[:port]) and the file with the target's password.
$anvil->Get->switches({list => [ $anvil->Get->switches({list => [
"immediate",
"no-db", "no-db",
"no-wait", "no-wait",
"server", "server",
@ -142,6 +143,15 @@ if (not $anvil->data->{switches}{'server'})
$anvil->nice_exit({exit_code => 1}); $anvil->nice_exit({exit_code => 1});
} }
# If we're forcing off a server, make sure '--server' isn't 'all'.
if (($anvil->data->{switches}{'server'} =~ /all/i) && ($anvil->data->{switches}{immediate}))
{
# Unable to proceed.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0462"});
$anvil->Job->update_progress({progress => 100, message => "error_0462"});
$anvil->nice_exit({exit_code => 1});
}
# Are we a node or DR host? # Are we a node or DR host?
$anvil->data->{sys}{host_type} = $anvil->Get->host_type(); $anvil->data->{sys}{host_type} = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
@ -252,6 +262,12 @@ sub shutdown_server
progress => $progress, progress => $progress,
}}); }});
if (($wait) && ($anvil->data->{switches}{immediate}))
{
$wait = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'wait' => $wait }});
}
# Is the server in the cluster? # Is the server in the cluster?
if (not exists $anvil->data->{cib}{parsed}{data}{server}{$server}) if (not exists $anvil->data->{cib}{parsed}{data}{server}{$server})
{ {
@ -271,20 +287,34 @@ sub shutdown_server
return(0); return(0);
} }
# Now shut down. # Now shut down. Forcibly?
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0289", variables => { server => $server }}); if ($anvil->data->{switches}{immediate})
$anvil->Job->update_progress({progress => $progress, message => "job_0289,!!server!".$server."!!"}) if $anvil->data->{switches}{'job-uuid'}; {
# Kill it!
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0474", variables => { server => $server }});
$anvil->Job->update_progress({progress => $progress, message => "job_0474,!!server!".$server."!!"}) if $anvil->data->{switches}{'job-uuid'};
}
else
{
# Lets be gentle
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0289", variables => { server => $server }});
$anvil->Job->update_progress({progress => $progress, message => "job_0289,!!server!".$server."!!"}) if $anvil->data->{switches}{'job-uuid'};
}
my $problem = 0; my $problem = 0;
if ($anvil->Get->host_type eq "dr") if ($anvil->Get->host_type eq "dr")
{ {
# Shut down using virsh. Invert the return. # Shut down using virsh. Invert the return.
my $force = $anvil->data->{switches}{immediate} ? 1 : 0;
my $success = $anvil->Server->shutdown_virsh({ my $success = $anvil->Server->shutdown_virsh({
debug => 2, debug => 2,
server => $server,
force => $force,
wait_time => $wait ? 0 : 1, wait_time => $wait ? 0 : 1,
}); });
$problem = $success ? 0 : 1; $problem = $success ? 0 : 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
force => $force,
success => $success, success => $success,
problem => $problem, problem => $problem,
}}); }});
@ -297,7 +327,24 @@ sub shutdown_server
'wait' => $wait, 'wait' => $wait,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
# If we're being asked to force the server off, do it now regardless of what pacemaker returned.
if ($anvil->data->{switches}{immediate})
{
my $success = $anvil->Server->shutdown_virsh({
debug => 2,
server => $server,
force => 1,
wait_time => 0,
});
$problem = $success ? 0 : 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
success => $success,
problem => $problem,
}});
}
} }
if ($problem) if ($problem)
{ {
# Failed, abort. # Failed, abort.

Loading…
Cancel
Save