diff --git a/Anvil/Tools/Server.pm b/Anvil/Tools/Server.pm
index 39866588..78b2c895 100644
--- a/Anvil/Tools/Server.pm
+++ b/Anvil/Tools/Server.pm
@@ -2145,8 +2145,11 @@ sub shutdown_virsh
elsif ($status eq "pmsuspended")
{
# 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 }});
- 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)
{
# Looks like virsh isn't running.
diff --git a/man/anvil-shutdown-server.8 b/man/anvil-shutdown-server.8
index e822676e..0294303d 100644
--- a/man/anvil-shutdown-server.8
+++ b/man/anvil-shutdown-server.8
@@ -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.
.SS "Commands:"
.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
.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.
@@ -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
.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.
+.TP
+Note: When \fB\-\-immediate\fR is used, \fB\-\-wait\fR is ignored.
.IP
.SH AUTHOR
Written by Madison Kelly, Alteeve staff and the Anvil! project contributors.
diff --git a/share/words.xml b/share/words.xml
index 03f8adaa..59880fce 100644
--- a/share/words.xml
+++ b/share/words.xml
@@ -725,6 +725,7 @@ The creation of the new replicatedd disk is incomplete, manual intervention is r
#!variable!error!#
====================
The creation of the new replicated disk is incomplete, manual intervention is required!]]>
+
@@ -1684,6 +1685,7 @@ Note: This is a permanent action! If you protect this server again later, a full
Exiting.
Server Storage Management
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.
+ The server: [#!variable!server!#] will now be forced off!
Starting: [#!variable!program!#].
diff --git a/tools/anvil-shutdown-server b/tools/anvil-shutdown-server
index 0fcce6ea..8623d68f 100755
--- a/tools/anvil-shutdown-server
+++ b/tools/anvil-shutdown-server
@@ -29,6 +29,7 @@ my $anvil = Anvil::Tools->new();
# Read switches (target ([user@]host[:port]) and the file with the target's password.
$anvil->Get->switches({list => [
+ "immediate",
"no-db",
"no-wait",
"server",
@@ -142,6 +143,15 @@ if (not $anvil->data->{switches}{'server'})
$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?
$anvil->data->{sys}{host_type} = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
@@ -252,6 +262,12 @@ sub shutdown_server
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?
if (not exists $anvil->data->{cib}{parsed}{data}{server}{$server})
{
@@ -271,20 +287,34 @@ sub shutdown_server
return(0);
}
- # Now shut down.
- $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'};
+ # Now shut down. Forcibly?
+ if ($anvil->data->{switches}{immediate})
+ {
+ # 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;
if ($anvil->Get->host_type eq "dr")
{
# Shut down using virsh. Invert the return.
+ my $force = $anvil->data->{switches}{immediate} ? 1 : 0;
my $success = $anvil->Server->shutdown_virsh({
debug => 2,
+ server => $server,
+ force => $force,
wait_time => $wait ? 0 : 1,
});
$problem = $success ? 0 : 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ force => $force,
success => $success,
problem => $problem,
}});
@@ -297,7 +327,24 @@ sub shutdown_server
'wait' => $wait,
});
$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)
{
# Failed, abort.