* Renamed striker-parse-fence-agents to anvil-parse-fence-agents and changed anvil-daemon to run it on all machines.

* Cleaned up a lot of logging.
* Updated Cluster->parse_cib() to track if a stonith device has 'delay' set.
* Got a lot more work done on anvil-join-anvil's stonith processing, but it still isn't complete. Updated it to change shell user passwords as well.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 4 years ago
parent 61f4dcc41f
commit c27cc7507f
  1. 2
      Anvil/Tools.pm
  2. 25
      Anvil/Tools/Cluster.pm
  3. 2
      Anvil/Tools/Striker.pm
  4. 17
      Anvil/Tools/System.pm
  5. 11
      share/words.xml
  6. 10
      tools/anvil-daemon
  7. 769
      tools/anvil-join-anvil
  8. 6
      tools/anvil-parse-fence-agents
  9. 11
      tools/fence_pacemaker

@ -1139,6 +1139,7 @@ sub _set_paths
'anvil-manage-firewall' => "/usr/sbin/anvil-manage-firewall", 'anvil-manage-firewall' => "/usr/sbin/anvil-manage-firewall",
'anvil-manage-keys' => "/usr/sbin/anvil-manage-keys", 'anvil-manage-keys' => "/usr/sbin/anvil-manage-keys",
'anvil-manage-power' => "/usr/sbin/anvil-manage-power", 'anvil-manage-power' => "/usr/sbin/anvil-manage-power",
'anvil-parse-fence-agents' => "/usr/sbin/anvil-parse-fence-agents",
'anvil-report-memory' => "/usr/sbin/anvil-report-memory", 'anvil-report-memory' => "/usr/sbin/anvil-report-memory",
'anvil-update-files' => "/usr/sbin/anvil-update-files", 'anvil-update-files' => "/usr/sbin/anvil-update-files",
'anvil-update-states' => "/usr/sbin/anvil-update-states", 'anvil-update-states' => "/usr/sbin/anvil-update-states",
@ -1214,7 +1215,6 @@ sub _set_paths
'striker-initialize-host' => "/usr/sbin/striker-initialize-host", 'striker-initialize-host' => "/usr/sbin/striker-initialize-host",
'striker-manage-install-target' => "/usr/sbin/striker-manage-install-target", 'striker-manage-install-target' => "/usr/sbin/striker-manage-install-target",
'striker-manage-peers' => "/usr/sbin/striker-manage-peers", 'striker-manage-peers' => "/usr/sbin/striker-manage-peers",
'striker-parse-fence-agents' => "/usr/sbin/striker-parse-fence-agents",
'striker-parse-oui' => "/usr/sbin/striker-parse-oui", 'striker-parse-oui' => "/usr/sbin/striker-parse-oui",
'striker-prep-database' => "/usr/sbin/striker-prep-database", 'striker-prep-database' => "/usr/sbin/striker-prep-database",
'striker-scan-network' => "/usr/sbin/striker-scan-network", 'striker-scan-network' => "/usr/sbin/striker-scan-network",

@ -577,14 +577,14 @@ sub parse_cib
if ($variable eq "stonith-max-attempts") if ($variable eq "stonith-max-attempts")
{ {
$anvil->data->{cib}{parsed}{data}{stonith}{'max-attempts'} = $value; $anvil->data->{cib}{parsed}{data}{stonith}{'max-attempts'} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::data::stonith::max-attempts" => $anvil->data->{cib}{parsed}{data}{stonith}{'max-attempts'}, "cib::parsed::data::stonith::max-attempts" => $anvil->data->{cib}{parsed}{data}{stonith}{'max-attempts'},
}}); }});
} }
if ($variable eq "stonith-enabled") if ($variable eq "stonith-enabled")
{ {
$anvil->data->{cib}{parsed}{data}{stonith}{enabled} = $value eq "true" ? 1 : 0; $anvil->data->{cib}{parsed}{data}{stonith}{enabled} = $value eq "true" ? 1 : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::data::stonith::enabled" => $anvil->data->{cib}{parsed}{data}{stonith}{enabled}, "cib::parsed::data::stonith::enabled" => $anvil->data->{cib}{parsed}{data}{stonith}{enabled},
}}); }});
} }
@ -598,6 +598,7 @@ sub parse_cib
} }
# Fencing devices and levels. # Fencing devices and levels.
my $delay_set = 0;
foreach my $primitive_id (sort {$a cmp $b} keys %{$anvil->data->{cib}{parsed}{cib}{resources}{primitive}}) foreach my $primitive_id (sort {$a cmp $b} keys %{$anvil->data->{cib}{parsed}{cib}{resources}{primitive}})
{ {
next if not $anvil->data->{cib}{parsed}{cib}{resources}{primitive}{$primitive_id}{class}; next if not $anvil->data->{cib}{parsed}{cib}{resources}{primitive}{$primitive_id}{class};
@ -631,10 +632,16 @@ sub parse_cib
foreach my $name (sort {$a cmp $b} keys %{$variables}) foreach my $name (sort {$a cmp $b} keys %{$variables})
{ {
$anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{device}{$primitive_id}{argument}{$name}{value} = $variables->{$name}; $anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{device}{$primitive_id}{argument}{$name}{value} = $variables->{$name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::data::node::${node_name}::fencing::device::${primitive_id}::argument::${name}::value" => $variables->{$name}, "cib::parsed::data::node::${node_name}::fencing::device::${primitive_id}::argument::${name}::value" => $variables->{$name},
}}); }});
if ($name eq "delay")
{
$delay_set = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { delay_set => $delay_set }});
}
my $value = $variables->{$name}; my $value = $variables->{$name};
$value =~ s/"/\\"/g; $value =~ s/"/\\"/g;
$argument_string .= $name."=\"".$value."\" "; $argument_string .= $name."=\"".$value."\" ";
@ -644,12 +651,17 @@ sub parse_cib
} }
$argument_string =~ s/ $//; $argument_string =~ s/ $//;
$anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{device}{$primitive_id}{arguments} = $argument_string; $anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{device}{$primitive_id}{arguments} = $argument_string;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::data::node::${node_name}::fencing::device::${primitive_id}::arguments" => $anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{device}{$primitive_id}{arguments}, "cib::parsed::data::node::${node_name}::fencing::device::${primitive_id}::arguments" => $anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{device}{$primitive_id}{arguments},
}}); }});
} }
} }
} }
$anvil->data->{cib}{parsed}{data}{stonith}{delay_set} = $delay_set;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::data::stonith::delay_set" => $anvil->data->{cib}{parsed}{data}{stonith}{delay_set},
}});
foreach my $id (sort {$a cmp $b} keys %{$anvil->data->{cib}{parsed}{configuration}{'fencing-topology'}{'fencing-level'}}) foreach my $id (sort {$a cmp $b} keys %{$anvil->data->{cib}{parsed}{configuration}{'fencing-topology'}{'fencing-level'}})
{ {
my $node_name = $anvil->data->{cib}{parsed}{configuration}{'fencing-topology'}{'fencing-level'}{$id}{target}; my $node_name = $anvil->data->{cib}{parsed}{configuration}{'fencing-topology'}{'fencing-level'}{$id}{target};
@ -662,11 +674,10 @@ sub parse_cib
}}); }});
$anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{order}{$index}{devices} = $devices; $anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{order}{$index}{devices} = $devices;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::data::node::${node_name}::fencing::order::${index}::devices" => $anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{order}{$index}{devices}, "cib::parsed::data::node::${node_name}::fencing::order::${index}::devices" => $anvil->data->{cib}{parsed}{data}{node}{$node_name}{fencing}{order}{$index}{devices},
}}); }});
} }
return($problem); return($problem);
} }
@ -688,7 +699,7 @@ sub start_cluster
my $parameter = shift; my $parameter = shift;
my $anvil = $self->parent; my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Cluster->parse_cib()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Cluster->start_cluster()" }});
my $all = defined $parameter->{all} ? $parameter->{all} : 0; my $all = defined $parameter->{all} ? $parameter->{all} : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {

@ -826,7 +826,7 @@ sub load_manifest
my $parameter = shift; my $parameter = shift;
my $anvil = $self->parent; my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Striker->get_ups_data()" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Striker->load_manifest()" }});
my $manifest_uuid = defined $parameter->{manifest_uuid} ? $parameter->{manifest_uuid} : ""; my $manifest_uuid = defined $parameter->{manifest_uuid} ? $parameter->{manifest_uuid} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {

@ -1291,10 +1291,7 @@ LIMIT 1
}}); }});
# Load the manifest. # Load the manifest.
my $problem = $anvil->Striker->load_manifest({ my $problem = $anvil->Striker->load_manifest({debug => $debug, manifest_uuid => $manifest_uuid});
debug => 2,
manifest_uuid => $manifest_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { problem => $problem }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { problem => $problem }});
if ($problem) if ($problem)
{ {
@ -1684,7 +1681,7 @@ LIMIT 1
} }
my $try_again = 1; my $try_again = 1;
$host_ipmi = $anvil->System->test_ipmi({ $host_ipmi = $anvil->System->test_ipmi({
debug => 2, debug => $debug,
ipmi_user => $user_name, ipmi_user => $user_name,
ipmi_password => $ipmi_password, ipmi_password => $ipmi_password,
ipmi_target => $ipmi_ip_address, ipmi_target => $ipmi_ip_address,
@ -1704,7 +1701,7 @@ LIMIT 1
# Try it again from the dashboard, we may just not be able to talk to our own BMC (can happen # Try it again from the dashboard, we may just not be able to talk to our own BMC (can happen
# on shared interfaces) # on shared interfaces)
$host_ipmi = $anvil->System->test_ipmi({ $host_ipmi = $anvil->System->test_ipmi({
debug => 2, debug => $debug,
ipmi_user => $user_name, ipmi_user => $user_name,
ipmi_password => $ipmi_password, ipmi_password => $ipmi_password,
ipmi_target => $ipmi_ip_address, ipmi_target => $ipmi_ip_address,
@ -1736,7 +1733,7 @@ LIMIT 1
{ {
# Try again with the 20-byte password. # Try again with the 20-byte password.
my $twenty_byte_ipmi_password = $anvil->Words->shorten_string({ my $twenty_byte_ipmi_password = $anvil->Words->shorten_string({
debug => 3, debug => $debug,
secure => 1, secure => 1,
string => $ipmi_password, string => $ipmi_password,
'length' => 20, 'length' => 20,
@ -1756,7 +1753,7 @@ LIMIT 1
{ {
# Try once more with the 16-byte password. # Try once more with the 16-byte password.
my $sixteen_byte_ipmi_password = $anvil->Words->shorten_string({ my $sixteen_byte_ipmi_password = $anvil->Words->shorten_string({
debug => 3, debug => $debug,
secure => 1, secure => 1,
string => $ipmi_password, string => $ipmi_password,
'length' => 16, 'length' => 16,
@ -1806,7 +1803,7 @@ LIMIT 1
if ($try_again) if ($try_again)
{ {
$host_ipmi = $anvil->System->test_ipmi({ $host_ipmi = $anvil->System->test_ipmi({
debug => 2, debug => $debug,
ipmi_user => $user_name, ipmi_user => $user_name,
ipmi_password => $ipmi_password, ipmi_password => $ipmi_password,
ipmi_target => $ipmi_ip_address, ipmi_target => $ipmi_ip_address,
@ -1823,7 +1820,7 @@ LIMIT 1
# Try it again from the dashboard, we may just not be able to talk to our own BMC ( # Try it again from the dashboard, we may just not be able to talk to our own BMC (
# can happen on shared interfaces) # can happen on shared interfaces)
my $host_ipmi = $anvil->System->test_ipmi({ my $host_ipmi = $anvil->System->test_ipmi({
debug => 2, debug => $debug,
ipmi_user => $user_name, ipmi_user => $user_name,
ipmi_password => $ipmi_password, ipmi_password => $ipmi_password,
ipmi_target => $ipmi_ip_address, ipmi_target => $ipmi_ip_address,

@ -359,6 +359,17 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec
<key name="job_0112">Updating the '/etc/hosts' file.</key> <key name="job_0112">Updating the '/etc/hosts' file.</key>
<key name="job_0113">Checking the SSH configuration.</key> <key name="job_0113">Checking the SSH configuration.</key>
<key name="job_0114">Configuring the IPMI BMC. Please be patient, this could take a minute.</key> <key name="job_0114">Configuring the IPMI BMC. Please be patient, this could take a minute.</key>
<key name="job_0115">Checking the fence configuration for the node: [#!variable!node!#].</key>
<key name="job_0116">IPMI exists on this node, but it is not yet setup as a fence device, adding it.</key>
<key name="job_0117">The IPMI information in the existing fence configuration is different from the details stored in the database. Will reconfigure.</key>
<key name="job_0118">There is an IPMI fence device configured, but there is no host IPMI information in the database. Removing it.</key>
<key name="job_0119">Deleting the old fence device: [#!variable!device!#].</key>
<key name="job_0120">Creating the new fence device: [#!variable!device!#].</key>
<key name="job_0121">The fence device: [#!variable!device!#] information in the existing fence configuration is different from the details stored in the database. Will reconfigure.</key>
<key name="job_0122">The fence device: [#!variable!device!#] does not exist as a fence device, adding it.</key>
<key name="job_0123">Adding a fence delay agent to provide time for the IPMI BMC to boot before trying it again.</key>
<key name="job_0124">Configuring the cluster to loop fence attempts indefinitely.</key>
<key name="job_0125">Enabling fencing!</key>
<!-- Log entries --> <!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key> <key name="log_0001">Starting: [#!variable!program!#].</key>

@ -384,13 +384,9 @@ sub handle_periodic_tasks
"s2:timing::next_minute_check" => $anvil->data->{timing}{next_minute_check}, "s2:timing::next_minute_check" => $anvil->data->{timing}{next_minute_check},
}}); }});
# If we're a dashboard, see if the fence information needs to be gathered. # Even when this runs, it should finish in under ten seconds so we don't need to background it.
if ($type eq "striker") my ($parse_output, $return_code) = $anvil->System->call({debug => 3, shell_call => $anvil->data->{path}{exe}{'anvil-parse-fence-agents'}, source => $THIS_FILE, line => __LINE__});
{ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { parse_output => $parse_output }});
# Even when this runs, it should finish in under ten seconds so we don't need to background it.
my ($parse_output, $return_code) = $anvil->System->call({debug => 3, shell_call => $anvil->data->{path}{exe}{'striker-parse-fence-agents'}, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { parse_output => $parse_output }});
}
# Scan the local network. # Scan the local network.
update_state_file($anvil); update_state_file($anvil);

File diff suppressed because it is too large Load Diff

@ -1,8 +1,11 @@
#!/usr/bin/perl #!/usr/bin/perl
# #
# This walks through all installed fence agents, parses their man page, and records their description and STDIN parameters. # This walks through all installed fence agents, parses their man page, and records their description and
# STDIN parameters.
# #
# TODO: # TODO:
# - Look at the mtime of the fence agents and record them as variables. Only process if an agenti is new or
# the mtime has changed.
# #
use strict; use strict;
@ -36,7 +39,6 @@ refresh_unified_metadata($anvil);
$anvil->nice_exit({exit_code => 0}); $anvil->nice_exit({exit_code => 0});
############################################################################################################# #############################################################################################################
# Functions # # Functions #
############################################################################################################# #############################################################################################################

@ -112,7 +112,7 @@ my $conf = {
find_executables($conf); find_executables($conf);
# Something for the logs # Something for the logs
to_log($conf, {message => "Attempting to fence the peer via pacemaker's stonith...", 'line' => __LINE__}); to_log($conf, {message => "DRBD pacemaker's stonith handler invoked.", 'line' => __LINE__});
# These are the full host names of the nodes given their IDs. # These are the full host names of the nodes given their IDs.
foreach my $i (0..31) foreach my $i (0..31)
@ -121,25 +121,28 @@ foreach my $i (0..31)
if ((exists $ENV{$key}) && (defined $ENV{$key})) if ((exists $ENV{$key}) && (defined $ENV{$key}))
{ {
$conf->{environment}{$key} = $ENV{$key}; $conf->{environment}{$key} = $ENV{$key};
to_log($conf, {message => "DRBD Environment variable: [$key] -> [".$conf->{environment}{$key}."]", 'line' => __LINE__, level => 2}); my $level = $conf->{environment}{$key} eq "" ? 3 : 2;
to_log($conf, {message => "DRBD Environment variable: [$key] -> [".$conf->{environment}{$key}."]", 'line' => __LINE__, level => $level});
} }
} }
# Record the environment variables # Record the environment variables
foreach my $key (sort {$a cmp $b} keys %{$conf->{environment}}) foreach my $key (sort {$a cmp $b} keys %{$conf->{environment}})
{ {
to_log($conf, {message => "DRBD Environment variable: [$key] -> [".$conf->{environment}{$key}."]", 'line' => __LINE__, level => 2}); my $level = $conf->{environment}{$key} eq "" ? 3 : 2;
to_log($conf, {message => "DRBD Environment variable: [$key] -> [".$conf->{environment}{$key}."]", 'line' => __LINE__, level => $level});
} }
foreach my $key (sort {$a cmp $b} keys %ENV) foreach my $key (sort {$a cmp $b} keys %ENV)
{ {
next if exists $conf->{environment}{$key}; next if exists $conf->{environment}{$key};
my $level = $ENV{$key} eq "" ? 3 : 2;
to_log($conf, {message => "System Environment variable: [$key] -> [".$ENV{$key}."]", 'line' => __LINE__, level => 3}); to_log($conf, {message => "System Environment variable: [$key] -> [".$ENV{$key}."]", 'line' => __LINE__, level => 3});
} }
# Make sure we at least have the target's IP. # Make sure we at least have the target's IP.
if (not $conf->{environment}{DRBD_PEER_ADDRESS}) if (not $conf->{environment}{DRBD_PEER_ADDRESS})
{ {
to_log($conf, {message => "Target's IP not set via the DRBD_PEER_ADDRESS environment variable. Unable to proceed.", 'line' => __LINE__, level => 0, priority => "err"}); to_log($conf, {message => "Called without target's IP. Nothing to do, exiting. Were we called by 'pcs stonith list'?", 'line' => __LINE__, level => 1, priority => "alert"});
exit(1); exit(1);
} }

Loading…
Cancel
Save