* Fixed a bug where Tools.pm->_anvil_version() and Get->host_uuid() were storing values in the wrong $anvil hash.

* Fixed a bug where Get->host_uuid() wasn't reading from the host.uuid file.
* Updated Remote->call() to record a target's fingerprint when needed.
* The ocf:alteeve:server resource agent now properly stopps a server and the corresponding DRBD resource.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 6 years ago
parent b56fbf923c
commit 7e4a170382
  1. 22
      Anvil/Tools.pm
  2. 68
      Anvil/Tools/Get.pm
  3. 18
      Anvil/Tools/Remote.pm
  4. 55
      ocf/alteeve/server
  5. 6
      share/words.xml

@ -178,14 +178,18 @@ sub new
if (ref($parameter) eq "HASH")
{
# Local parameters...
if ($parameter->{debug})
if ($parameter->{log_level})
{
$debug = $parameter->{debug};
$anvil->Log->level({set => $parameter->{log_level}});
}
if ($parameter->{log_secure})
{
$anvil->Log->secure({set => $parameter->{log_secure}});
}
if ($parameter->{debug})
{
$debug = $parameter->{debug};
}
}
elsif ($parameter)
{
@ -194,12 +198,6 @@ sub new
exit(1);
}
# If the user passed a custom log level, sit it now.
if ($parameter->{log_level})
{
$anvil->Log->level({set => $parameter->{log_level}});
}
# This will help clean up if we catch a signal.
$SIG{INT} = sub { $anvil->catch_sig({signal => "INT"}); };
$SIG{TERM} = sub { $anvil->catch_sig({signal => "TERM"}); };
@ -612,14 +610,14 @@ sub _anvil_version
my $self = shift;
my $anvil = $self;
$anvil->data->{HOST}{ANVIL_VERSION} = "" if not defined $anvil->data->{HOST}{ANVIL_VERSION};
if ($anvil->data->{HOST}{ANVIL_VERSION} eq "")
$anvil->{HOST}{ANVIL_VERSION} = "" if not defined $anvil->{HOST}{ANVIL_VERSION};
if ($anvil->{HOST}{ANVIL_VERSION} eq "")
{
# Try to read the local Anvil! version.
$anvil->data->{HOST}{ANVIL_VERSION} = $anvil->Get->anvil_version();
$anvil->{HOST}{ANVIL_VERSION} = $anvil->Get->anvil_version();
}
return($anvil->data->{HOST}{ANVIL_VERSION});
return($anvil->{HOST}{ANVIL_VERSION});
}
=head2 _hostname

@ -524,44 +524,52 @@ sub host_uuid
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
my $set = defined $parameter->{set} ? $parameter->{set} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { set => $set }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
set => $set,
'HOST::UUID' => $anvil->{HOST}{UUID},
}});
if ($set)
{
$anvil->data->{HOST}{UUID} = $set;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "HOST::UUID" => $anvil->data->{HOST}{UUID} }});
$anvil->{HOST}{UUID} = $set;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "HOST::UUID" => $anvil->{HOST}{UUID} }});
}
elsif (not $anvil->data->{HOST}{UUID})
elsif (not $anvil->{HOST}{UUID})
{
# Read dmidecode if I am root, otherwise, read the cache.
# Read /etc/anvil/host.uuid if it exists. If not, and if we're root, we'll create that file
# using the UUID from dmidecode.
my $uuid = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { '$<' => $<, '$>' => $> }});
if (($< == 0) or ($> == 0))
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
'$<' => $<,
'$>' => $>,
'path::data::host_uuid' => $anvil->data->{path}{data}{host_uuid},
}});
if (-e $anvil->data->{path}{data}{host_uuid})
{
# Read the UUID in
$uuid = $anvil->Storage->read_file({debug => $debug, file => $anvil->data->{path}{data}{host_uuid}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid }});
}
elsif (($< == 0) or ($> == 0))
{
# Create the UUID file.
($uuid, my $return_code) = lc($anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{dmidecode}." --string system-uuid"}));
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid, return_code => $return_code }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid,
return_code => $return_code,
}});
}
else
{
# Not running as root, so I have to rely on the cache file, or die if it doesn't
# exist.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'path::data::host_uuid' => $anvil->data->{path}{data}{host_uuid} }});
if (not -e $anvil->data->{path}{data}{host_uuid})
{
# We're done.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0187"});
return("#!error!#");
}
else
{
$uuid = $anvil->Storage->read_file({debug => $debug, file => $anvil->data->{path}{data}{host_uuid}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid }});
}
# Host UUID file doesn't exist and I'm Not running as root, I'm done.
# We're done.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0187"});
return("#!error!#");
}
if ($anvil->Validate->is_uuid({uuid => $uuid}))
{
$anvil->data->{HOST}{UUID} = $uuid;
$anvil->{HOST}{UUID} = $uuid;
if (not -e $anvil->data->{path}{data}{host_uuid})
{
### TODO: This will need to set the proper SELinux context.
@ -582,21 +590,23 @@ sub host_uuid
else
{
# Bad UUID.
$anvil->{HOST}{UUID} = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "HOST::UUID" => $anvil->{HOST}{UUID} }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0134", variables => { uuid => $uuid }});
$anvil->data->{HOST}{UUID} = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "HOST::UUID" => $anvil->data->{HOST}{UUID} }});
return("#!error!#");
}
}
# We'll also store the host UUID in a variable.
if ((not $anvil->data->{sys}{host_uuid}) && ($anvil->data->{HOST}{UUID}))
if ((not $anvil->data->{sys}{host_uuid}) && ($anvil->{HOST}{UUID}))
{
$anvil->data->{sys}{host_uuid} = $anvil->data->{HOST}{UUID};
$anvil->data->{sys}{host_uuid} = $anvil->{HOST}{UUID};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::host_uuid" => $anvil->data->{sys}{host_uuid} }});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "HOST::UUID" => $anvil->data->{HOST}{UUID} }});
return($anvil->data->{HOST}{UUID});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "HOST::UUID" => $anvil->{HOST}{UUID} }});
return($anvil->{HOST}{UUID});
}
=head2 md5sum

@ -358,7 +358,7 @@ sub call
else
{
# In case the user is using ports in /etc/ssh/ssh_config, we'll want to check for an entry.
$anvil->System->read_ssh_config();
$anvil->System->read_ssh_config({deubg => $debug});
$anvil->data->{hosts}{$target}{port} = "" if not defined $anvil->data->{hosts}{$target}{port};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "hosts::${target}::port" => $anvil->data->{hosts}{$target}{port} }});
@ -389,7 +389,7 @@ sub call
# If the target is a host name, convert it to an IP.
if (not $anvil->Validate->is_ipv4({ip => $target}))
{
my $new_target = $anvil->Convert->hostname_to_ip({host_name => $target});
my $new_target = $anvil->Convert->hostname_to_ip({hostname => $target});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { new_target => $new_target }});
if ($new_target)
{
@ -465,6 +465,20 @@ sub call
$message_key = "message_0003";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { i => $i, message_key => $message_key }});
}
elsif ($connect_output =~ /Host key verification failed/i)
{
# Need to accept the fingerprint
$message_key = "message_0135";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { i => $i, message_key => $message_key }});
# Make sure we know the fingerprint of the remote machine
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, key => "log_0158", variables => { target => $target, user => $< }});
$anvil->Remote->add_target_to_known_hosts({
debug => $debug,
target => $target,
user => $<,
});
}
elsif ($connect_output =~ /Connection refused/i)
{
$i = $last_loop;

@ -422,7 +422,8 @@ sub stop_server
{
my ($anvil) = @_;
# Stopping the server is simply a question of "is the server running?" and, if so, stop it.
# Stopping the server is simply a question of "is the server running?" and, if so, stop it. Once
# stopped, we stop the DRBD resource on both nodes.
my $server = $anvil->data->{environment}{OCF_RESKEY_name};
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list"});
if ($return_code)
@ -609,8 +610,9 @@ sub stop_server
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0329", variables => { server => $server }});
# Stop DRBD resources now.
stop_storage($anvil);
# Stop DRBD resources now. We don't worry if it actually stops or not (let ScanCore
# handle that). We only care that the server has stopped.
manage_drbd_resource($anvil, "down");
$anvil->nice_exit({exit_code => 0});
}
@ -1219,8 +1221,8 @@ sub validate_storage_drbd
{
my $protocol = $connection_ref->{section}->{net}->{option}->{protocol}->{value};
my $fencing = $connection_ref->{section}->{net}->{option}->{fencing}->{value};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
protocol => $resource,
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
protocol => $protocol,
fencing => $fencing,
}});
@ -1345,6 +1347,12 @@ sub validate_storage_drbd
}
}
# If we're in a stop operation, we're done.
if ($anvil->data->{switches}{stop})
{
return(0);
}
# Now read in the status of the drbd devices
$return_code = undef;
(my $status_json, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{drbdsetup}." status --json"});
@ -1783,12 +1791,43 @@ sub validate_ram
}
# This stops (drbdadm down <server>) the storage for a given server on both nodes.
sub stop_storage
sub manage_drbd_resource
{
my ($anvil) = @_;
my ($anvil, $task) = @_;
read_server_definition($anvil);
validate_storage($anvil);
validate_storage_drbd($anvil);
# Stop the resource on the peer, then stop it here.
my $server = $anvil->data->{environment}{OCF_RESKEY_name};
my $peer_hostname = $anvil->data->{server}{drbd}{peer}{hostname};
my $peer_address = $anvil->data->{server}{drbd}{peer}{address};
my $shell_call = $anvil->data->{path}{exe}{drbdadm}." ".$task." ".$server;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
server => $server,
peer_hostname => $peer_hostname,
peer_address => $peer_address,
shell_call => $shell_call,
}});
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 2,
shell_call => $shell_call,
target => $peer_hostname,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
# Now call it locally
$output = undef;
$return_code = undef;
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
return(0);
}

@ -239,7 +239,7 @@ About to try to download aproximately: [#!variable!packages!#] packages needed t
<key name="message_0132">Storage Network ##!variable!number!# - Used for DRBD communication between nodes and DR hosts. Should be VLAN-isolated from the IFN and, thus, trusted.</key>
<key name="message_0133">Internet/Intranet-Facing Network ##!variable!number!# - Used for all client/user facing traffic. Likely connected to a semi-trusted network only.</key>
<key name="message_0134">Updating / configuring the firewall.</key>
<key name="message_0135">#!free!#</key>
<key name="message_0135">It appears like we need to accept the fingerprint. Will do so now and then try to conenct again.</key>
<key name="message_0136">The zone: [#!variable!zone!#] file: [#!variable!file!#] needs to be updated.</key>
<key name="message_0137">The zone: [#!variable!zone!#] file: [#!variable!file!#] doesn't exist, it will now be created.</key>
<key name="message_0138">The interface: [#!variable!interface!#] will be added to the zone: [#!variable!zone!#].</key>
@ -416,7 +416,7 @@ The database connection error was:
<key name="log_0131">Entering function: [#!variable!function!#]</key>
<key name="log_0132">Connected to: [#!data!sys::database::connections!#] database(s).</key>
<key name="log_0133">Failed to read the system UUID. Received a non-UUID string: [#!variable!uuid!#]. Is the user: [#!variable!user!#] in the 'kmem' group?</key>
<key name="log_0134">The read host UUID: [#!variable!uuid!#] does not appear to be a valid UUID.</key>
<key name="log_0134">The host UUID: [#!variable!uuid!#] does not appear to be a valid UUID. Please check the contents of: [#!data!path::data::host_uuid!#] or the output from: [dmidecode --string system-uuid]. Note that some mainboards will report their UUID as all-0. If this is the case, manually create the 'host.uuid' file with a UUID created by 'uuidgen'.</key>
<key name="log_0135">- #!variable!caller!# runtime was approximately: [#!variable!runtime!#] seconds.</key>
<key name="log_0136"><![CDATA[[ Error ] - The method: [#!variable!method!#] was called with either 'job_uuid': [#!variable!job_uuid!#] not being passed (or was not a valid UUID), or 'job_name': [#!variable!job_name!#] not being passed.]]></key>
<key name="log_0137"><![CDATA[[ Error ] - The method: [#!variable!method!#] was called with an invalid value for: [#!variable!variable_name!#]: -> [#!variable!variable_value!#]. See 'perldoc Anvil::Tools::#!variable!module!#' for valid options.]]></key>
@ -469,7 +469,7 @@ The database connection error was:
<key name="log_0184">Theew was a failed login attempt from: [#!variable!user_agent!#], trying to log in as: [#!variable!user!#]. log in rejected.</key>
<key name="log_0185"><![CDATA[<unknown>]]></key> <!-- Used in some cases when a variable isn't known -->
<key name="log_0186"><![CDATA[<suppressed>]]></key> <!-- Used in some cases when a variable isn't known -->
<key name="log_0187">UUID cache file: [#!data!path::data::host_uuid!#] doesn't exists and we're not running as root. Unable to proceed.</key>
<key name="log_0187">Host UUID cache file: [#!data!path::data::host_uuid!#] doesn't exists and we're not running as root so we can't read dmidecode. Unable to proceed.</key>
<key name="log_0188">Database archive check skipped, not running as root.</key>
<key name="log_0189">Database archiving is disabled, skipping archive checks.</key>
<key name="log_0190">Peer: [#!variable!peer!#], database: [#!variable!name!#], password: [#!variable!password!#], host UUID: [#!variable!uuid!#]</key>

Loading…
Cancel
Save