Merge pull request #242 from ClusterLabs/anvil-tools-dev

* Updated Cluster->parse_crm_mon() to record the role of stonith reso…
main
Digimer 2 years ago committed by GitHub
commit 83e577d057
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      Anvil/Tools/Cluster.pm
  2. 2
      Anvil/Tools/Log.pm
  3. 34
      Anvil/Tools/Server.pm
  4. 97
      Anvil/Tools/System.pm
  5. 4
      share/words.xml
  6. 94
      tools/anvil-safe-stop

@ -2976,7 +2976,7 @@ sub parse_cib
if ($anvil->Network->is_local({host => $target}))
{
# Local call
($cib_data, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
($cib_data, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
cib_data => $cib_data,
return_code => $return_code,
@ -3151,6 +3151,7 @@ sub parse_cib
foreach my $node_state ($dom->findnodes('/cib/status/node_state'))
{
my $id = $node_state->{id};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { id => $id }});
foreach my $variable (sort {$a cmp $b} keys %{$node_state})
{
next if $variable eq "id";
@ -3162,6 +3163,7 @@ sub parse_cib
foreach my $lrm ($node_state->findnodes('./lrm'))
{
my $lrm_id = $lrm->{id};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { lrm_id => $lrm_id }});
foreach my $lrm_resource ($lrm->findnodes('./lrm_resources/lrm_resource'))
{
my $lrm_resource_id = $lrm_resource->{id};
@ -3643,6 +3645,8 @@ sub parse_cib
}});
}
return($problem);
}
@ -3717,7 +3721,7 @@ sub parse_crm_mon
if ($anvil->Network->is_local({host => $target}))
{
# Local call
($crm_mon_data, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
($crm_mon_data, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
crm_mon_data => $crm_mon_data,
return_code => $return_code,
@ -3764,7 +3768,8 @@ sub parse_crm_mon
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { problem => $problem }});
foreach my $resource ($dom->findnodes('/pacemaker-result/resources/resource'))
{
next if $resource->{resource_agent} ne "ocf::alteeve:server";
if ($resource->{resource_agent} eq "ocf::alteeve:server")
{
my $id = $resource->{id};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { id => $id }});
foreach my $variable (sort {$a cmp $b} keys %{$resource})
@ -3788,6 +3793,36 @@ sub parse_crm_mon
}});
}
}
if ($resource->{resource_agent} =~ /stonith:(.*)$/)
{
my $fence_agent = $1;
my $id = $resource->{id};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:fence_agent' => $fence_agent,
's2:id' => $id,
}});
foreach my $variable (sort {$a cmp $b} keys %{$resource})
{
next if $variable eq "id";
$anvil->data->{crm_mon}{parsed}{'pacemaker-result'}{resources}{stonith}{$id}{variables}{$variable} = $resource->{$variable};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"crm_mon::parsed::pacemaker-result::resources::stonith::${id}::variables::${variable}" => $anvil->data->{crm_mon}{parsed}{'pacemaker-result'}{resources}{stonith}{$id}{variables}{$variable},
}});
}
foreach my $node ($resource->findnodes('./node'))
{
my $node_id = $node->{id};
my $node_name = $node->{name};
my $cached = $node->{cached};
$anvil->data->{crm_mon}{parsed}{'pacemaker-result'}{resources}{stonith}{$id}{host}{node_name} = $node->{name};
$anvil->data->{crm_mon}{parsed}{'pacemaker-result'}{resources}{stonith}{$id}{host}{node_id} = $node->{id};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"crm_mon::parsed::pacemaker-result::resources::stonith::${id}::host::node_name" => $anvil->data->{crm_mon}{parsed}{'pacemaker-result'}{resources}{stonith}{$id}{host}{node_name},
"crm_mon::parsed::pacemaker-result::resources::stonith::${id}::host::node_id" => $anvil->data->{crm_mon}{parsed}{'pacemaker-result'}{resources}{stonith}{$id}{host}{node_id},
}});
}
}
}
}
}

@ -924,7 +924,7 @@ sub variables
# Strip a leading 'sX:' in case the user is sorting the output.
my $say_key = $key;
$say_key =~ s/^s(\d+)://;
$raw .= "$say_key: [".$list->{$key}."], ";
$raw .= $say_key.": [".$list->{$key}."], ";
print $THIS_FILE." ".__LINE__."; raw: [".$raw."]\n" if $test;
}
$raw =~ s/, $//;

@ -1959,21 +1959,22 @@ sub shutdown_virsh
}
elsif ($status eq "paused")
{
### TODO: No, don't do this! The server might be migrating
# The server is paused. Resume it, wait a few, then proceed with the shutdown.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0314", variables => { server => $server }});
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." resume $server"});
if ($return_code)
{
# Looks like virsh isn't running.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0315", variables => {
server => $server,
return_code => $return_code,
output => $output,
}});
$anvil->nice_exit({exit_code => 1});
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0316"});
sleep 3;
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0314", variables => { server => $server }});
# my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." resume $server"});
# if ($return_code)
# {
# # Looks like virsh isn't running.
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "log_0315", variables => {
# server => $server,
# return_code => $return_code,
# output => $output,
# }});
# $anvil->nice_exit({exit_code => 1});
# }
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0316"});
# sleep 3;
}
elsif ($status eq "pmsuspended")
{
@ -2147,9 +2148,10 @@ WHERE
{
# Give up waiting.
$waiting = 0;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0426", variables => { waiting => $waiting }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { waiting => $waiting }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0427", variables => {
my $key = $wait_time == 1 ? "log_0727" : "log_0427";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => $key, variables => {
server => $server,
'wait' => $wait_time,
}});

@ -3864,18 +3864,62 @@ sub parse_arguments
arguments => $arguments,
}});
# Convert escaped quotes, we'll convert them back at the end
my $secure = $arguments =~ /-passw/ ? 1 : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
">> arguments" => $secure ? $anvil->Log->is_secure($arguments) : $arguments,
}});
$arguments =~ s/\\\"/"/g;
$arguments =~ s/\\\'/'/g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"<< arguments" => $secure ? $anvil->Log->is_secure($arguments) : $arguments,
}});
my $hash = {};
my $quoted = "";
my $switch = "";
my $value = "";
foreach my $arg (split/ /, $arguments)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { arg => $arg }});
# We're likely processing a password, so we need to decide if we're logging securely or not
# right away.
my $secure = 0;
if (($switch) && ($switch =~ /passw/))
{
$secure = 1;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { secure => $secure }});
# Now we can start logging.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
arg => $secure ? $anvil->Log->is_secure($arg) : $arg,
}});
if (($arg =~ /^'/) or ($arg =~ /^"/))
{
# If the quoted value has no spaces, store it now.
if (($arg =~ /^'(.*?)'$/) or ($arg =~ /^"(.*?)"$/))
{
$hash->{$switch} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hash->{$switch}" => $secure ? $anvil->Log->is_secure($hash->{$switch}) : $hash->{$switch},
}});
}
elsif (($arg =~ /'$/) or ($arg =~ /"$/))
{
$hash->{$switch} = $quoted.$arg;
$quoted = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hash->{$switch}" => $secure ? $anvil->Log->is_secure($hash->{$switch}) : $hash->{$switch},
}});
}
else
{
# Store a quoted value.
$quoted .= $arg." ";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { quoted => $quoted }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
quoted => $secure ? $anvil->Log->is_secure($quoted) : $quoted,
}});
}
}
elsif ($quoted)
{
@ -3883,33 +3927,43 @@ sub parse_arguments
{
# Done
$quoted .= $arg;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { quoted => $quoted }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
quoted => $secure ? $anvil->Log->is_secure($quoted) : $quoted,
}});
if ($quoted =~ /^'(.*)'$/)
{
$value = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { value => $value }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
value => $secure ? $anvil->Log->is_secure($value) : $value,
}});
}
elsif ($quoted =~ /^"(.*)"$/)
{
$value = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { value => $value }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
value => $secure ? $anvil->Log->is_secure($value) : $value,
}});
}
$hash->{$switch} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "hash->{$switch}" => $hash->{$switch} }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hash->{$switch}" => $secure ? $anvil->Log->is_secure($hash->{$switch}) : $hash->{$switch},
}});
$quoted = "";
$switch = "";
$value = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
quoted => $quoted,
quoted => $secure ? $anvil->Log->is_secure($quoted) : $quoted,
switch => $switch,
value => $value,
value => $secure ? $anvil->Log->is_secure($value) : $value,
}});
}
else
{
$quoted .= $arg." ";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { quoted => $quoted }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
quoted => $secure ? $anvil->Log->is_secure($quoted) : $quoted,
}});
}
}
elsif ($arg =~ /^-/)
@ -3918,7 +3972,9 @@ sub parse_arguments
{
$value = "#!SET!#";
$hash->{$switch} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "hash->{$switch}" => $hash->{$switch} }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hash->{$switch}" => $secure ? $anvil->Log->is_secure($hash->{$switch}) : $hash->{$switch},
}});
$switch = "";
$value = "";
@ -3942,7 +3998,9 @@ sub parse_arguments
else
{
$hash->{$switch} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "hash->{$switch}" => $hash->{$switch} }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hash->{$switch}" => $secure ? $anvil->Log->is_secure($hash->{$switch}) : $hash->{$switch},
}});
$switch = "";
$value = "";
@ -3962,7 +4020,9 @@ sub parse_arguments
else
{
$hash->{$switch} = $arg;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "hash->{$switch}" => $hash->{$switch} }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"hash->{$switch}" => $secure ? $anvil->Log->is_secure($hash->{$switch}) : $hash->{$switch},
}});
$switch = "";
$value = "";
@ -3973,6 +4033,19 @@ sub parse_arguments
}
}
foreach my $switch (sort {$a cmp $b} keys %{$hash})
{
my $secure = $switch =~ /^passw/ ? 1 : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
">> hash->{$switch}" => $secure ? $anvil->Log->is_secure($hash->{$switch}) : $hash->{$switch},
}});
$hash->{$switch} =~ s/&quot;/\\"/g;
$hash->{$switch} =~ s/&apos;/\\'/g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"<< hash->{$switch}" => $secure ? $anvil->Log->is_secure($hash->{$switch}) : $hash->{$switch},
}});
}
return($hash);
}

@ -1372,6 +1372,8 @@ Note: This is a permanent action! If you protect this server again later, a full
<key name="job_0416">Done! The server: [#!variable!server!#] is no longer being protected on DR!</key>
<key name="job_0417">The resource config file: [#!variable!config_file!#] doesn't exist locally, pulling a copy over from: [#!variable!source!#].</key>
<key name="job_0418">Re-parsing the replicated storage configuration.</key>
<key name="job_0419">The server: [#!variable!server!#] was found to be running outside the cluster. Asking it to shut down now.</key>
<key name="job_0428">The server: [#!variable!server!#] is still running two minutes after asking it to stop. It might have woken up on the first press and ignored the shutdown request (Hi Windows). Pressing the poewr button again.</key>
<!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key>
@ -2200,6 +2202,7 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0724">The file: [#!variable!file!#] needs to be added to the database, but since the last scan it's size grew from: [#!variable!old_size_bytes!# (#!variable!old_size_hr!#)] to: [#!variable!new_size_bytes!# (#!variable!new_size_hr!#)]. A difference of: [#!variable!difference_bytes!# (#!variable!difference_hr!#)]. It might still be being uploaded, so we'll keep checking periodocally until the size stops changing.</key>
<key name="log_0725">Found the missing file: [#!variable!file!#] in the directory: [#!variable!directory!#]. Updating the database now.</key>
<key name="log_0726">Deleting the hash key: [#!variable!hash_key!#].</key>
<key name="log_0727">[ Note ] - The server: [#!variable!server!#] is not yet off, but we've been told not to wait for it to stop.</key>
<!-- Messages for users (less technical than log entries), though sometimes used for logs, too. -->
<key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>
@ -3315,6 +3318,7 @@ The error was:
========
</key>
<key name="warning_0147">[ Warning ] - The interface: [#!variable!interface!#] is in a bond, but it is down. The system uptime is: [#!variable!uptime!#], so it might be a problem where the interface didn't start on boot as it should have. So we're going to bring the interface up.</key>
<key name="warning_0148">[ Warning ] - The IPMI stonith resource: [#!variable!resource!#] is in the role: [#!variable!role!#] (should be 'Started'). Will check the IPMI config now.</key>
<!-- The entries below here are not sequential, but use a key to find the entry. -->
<!-- Run 'striker-parse-os-list to find new entries. -->

@ -277,7 +277,20 @@ sub process_servers
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0321"});
$anvil->Job->update_progress({progress => 10, message => "job_0321"});
}
# Use virsh to check for servers, in case pacemaker lies to us.
$anvil->Server->find();
my $progress = 10;
my $waiting = 1;
my $first_try = 0;
my $second_try = 0;
my $try_again = 0;
my $server_count = keys %{$anvil->data->{server}{location}};
my $progress_steps = $server_count ? int(35 / $server_count) : 70;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:server_count' => $server_count,
's2:progress_steps' => $progress_steps,
}});
while ($waiting)
{
# Is the cluster up?
@ -286,7 +299,84 @@ sub process_servers
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem)
{
# Nope.
# Nope. Are we stopping servers?
if ($anvil->data->{switches}{'stop-servers'})
{
# Yes, are any servers running (check virsh)
foreach my $server_name (sort {$a cmp $b} keys %{$anvil->data->{server}{location}})
{
my $status = $anvil->data->{server}{location}{$server_name}{status};
my $host_name = $anvil->data->{server}{location}{$server_name}{host_name};
$progress += $progress_steps;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:server_name' => $server_name,
's2:status' => $status,
's3:host_name' => $host_name,
's4:progress' => $progress,
}});
if ($host_name eq $anvil->Get->host_name)
{
# Server is still running.
if (($status eq "running") && (not $first_try))
{
# It's running despite the cluster being own, stop it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "job_0419", variables => { server => $server_name }});
$anvil->Job->update_progress({progress => $progress, message => "job_0419,!!server!".$server_name."!!"});
$anvil->Server->shutdown_virsh({
debug => 2,
server => $server_name,
wait_time => 1,
});
$waiting = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
}
elsif (($status eq "in shutdown") && ($try_again))
{
# Hit the power button again.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "job_0420", variables => { server => $server_name }});
$anvil->Job->update_progress({progress => $progress, message => "job_0420,!!server!".$server_name."!!"});
$anvil->Server->shutdown_virsh({
debug => 2,
server => $server_name,
wait_time => 1,
});
$waiting = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
}
}
}
if ($waiting)
{
if (not $first_try)
{
$first_try = time;
$second_try = $first_try + 120;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
first_try => $first_try,
second_try => $second_try,
}});
}
elsif ($try_again)
{
$try_again = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { try_again => $try_again }});
}
elsif (($second_try) && (time > $second_try))
{
$try_again = 1;
$second_try = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
second_try => $second_try,
try_again => $try_again,
}});
}
}
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "job_0313"});
$anvil->Job->update_progress({progress => 80, message => "job_0313"});
}
@ -304,7 +394,7 @@ sub process_servers
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:server' => $server,
's2:status' => $status,
's2:host_name' => $host_name,
's3:host_name' => $host_name,
's4:role' => $role,
's5:active' => $active,
}});

Loading…
Cancel
Save