Fixed a bug in which host runs an anvil-delete-server job.

* Updated anvil-delete-server to use the new Server->locate method. This
  was done as the old Server->locate() was failing to find the server
running on the peer when anvil-delete-server was running on the backup
subnode.
* Updated Server->locate() to search hosts for XML definition and DRBD
  configs so that it can record where the server is recorded to run,
even if the server isn't running or defined at the time the locate ran.

Signed-off-by: digimer <mkelly@alteeve.ca>
main
digimer 1 year ago
parent 68521cdab7
commit 7545df1e55
  1. 94
      Anvil/Tools/Server.pm
  2. 80
      tools/anvil-delete-server

@ -1241,6 +1241,8 @@ If a specific requested server is found, or is being asked to search for all ser
* server_location::host::<short_host_name>::server::<server_name>::active_definition = <XML>
* server_location::host::<short_host_name>::server::<server_name>::inactive_definition = <XML>
* server_location::host::<short_host_name>::server::<server_name>::definition_diff = <diff>
* server_location::host::<short_host_name>::server::<server_name>::file_definition = <file_body>
* server_location::host::<short_host_name>::server::<server_name>::drbd_config = <file_body>
If the target was not accessible, C<< access >> is set to C<< 0 >>. This is meant to allow telling the difference between "we know there's no servers on that host" versus "we don't know what's there because we couldn't access it".
@ -1259,6 +1261,8 @@ The C<< status >> can be:
If there is a problem, C<< !!error!! >> is returned. If the server is found on at least one host, C<< 0 >> is returned. If the server is not located anywhere, C<< 1 >> is returned.
If the server has a replicated storage (DRBD) config and/or a definition file, whether the server is found running or not, will be recorded. This can be used to see if the server has been configured to run there or not.
The connection to the host and to the server(s) is cached, for your use;
* server_location::host::<short_host_name>::connection = <Sys::Virt object>
@ -1319,26 +1323,28 @@ sub locate
# This will switch to '1' if we connect to libvirtd.
$anvil->data->{server_location}{host}{$short_host_name}{access} = 0;
# What IP to use?
# What IP to use? Don't test access, it's too slow if there's several down hosts.
my $target_ip = $anvil->Network->find_target_ip({
debug => $debug,
host_uuid => $host_uuid,
networks => "bcn,ifn", # Reduced list to not slow things down with test_access
test_access => 1,
networks => "bcn,mn,sn,ifn",
test_access => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { target_ip => $target_ip }});
if ($target_ip)
{
# Try to connect to libvirtd.
my $problem = $anvil->Server->connect_to_libvirt({
$anvil->Server->connect_to_libvirt({
debug => $debug,
target => $short_host_name,
target_ip => $target_ip,
server_name => $server_name,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { problem => $problem }});
if (not $problem)
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"libvirtd::${short_host_name}::connection" => $anvil->data->{libvirtd}{$short_host_name}{connection},
}});
if (ref($anvil->data->{libvirtd}{$short_host_name}{connection}) eq "Sys::Virt")
{
# We're connected! Collect the data on the requested server(s), if applicable.
$anvil->data->{server_location}{host}{$short_host_name}{access} = 1;
@ -1352,6 +1358,7 @@ sub locate
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { connection_handle => $connection_handle }});
foreach my $this_server_name (sort {$a cmp $b} keys %{$anvil->data->{libvirtd}{$short_host_name}{server}})
{
next if (ref($anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection}) ne "Sys::Virt::Domain");
if (($server_name eq "all") or ($server_name eq $this_server_name))
{
my $server_handle = $anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection};
@ -1394,6 +1401,12 @@ sub locate
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { definition_diff => $definition_diff }});
}
if ($server_state eq "running")
{
$server_host = $short_host_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { server_host => $server_host }});
}
# If it's running, record the host.
$anvil->data->{server_location}{host}{$short_host_name}{server}{$server_name}{status} = $server_state;
$anvil->data->{server_location}{host}{$short_host_name}{server}{$server_name}{active_definition} = $active_definition;
@ -1407,6 +1420,75 @@ sub locate
}});
}
}
# If we've connected to the host, see if the XML definition file
# and/or DRBD config file exist.
my $servers = [];
if ($server_name eq "all")
{
# Search for any server we can find.
$anvil->Database->get_servers();
foreach my $server_uuid (sort {$a cmp $b} keys %{$anvil->data->{servers}{server_uuid}})
{
next if $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state} eq "DELETED";
my $this_server_name = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
server_uuid => $server_uuid,
this_server_name => $this_server_name,
}});
push @{$servers}, $this_server_name;
}
}
else
{
push @{$servers}, $server_name;
}
foreach my $this_server_name (sort {$a cmp $b} @{$servers})
{
# Look for the files for the specified server.
$anvil->data->{server_location}{host}{$short_host_name}{server}{$this_server_name}{file_definition} = "";
$anvil->data->{server_location}{host}{$short_host_name}{server}{$this_server_name}{drbd_config} = "";
# See if there's a definition file and/or a DRBD
# config file on this host.
my $definition_file = $anvil->data->{path}{directories}{shared}{definitions}."/".$this_server_name.".xml";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { definition_file => $definition_file }});
# Can I read the definition file?
my $definition_body = $anvil->Storage->read_file({
debug => $debug,
file => $definition_file,
target => $target_ip,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { definition_body => $definition_body }});
if (($definition_body) && ($definition_body ne "!!error!!"))
{
$anvil->data->{server_location}{host}{$short_host_name}{server}{$this_server_name}{file_definition} = $definition_body;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"server_location::host::${short_host_name}::server::${this_server_name}::file_definition" => $anvil->data->{server_location}{host}{$short_host_name}{server}{$this_server_name}{file_definition},
}});
}
my $drbd_config_file = $anvil->data->{path}{directories}{drbd_resources}."/".$this_server_name.".res";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { drbd_config_file => $drbd_config_file }});
my $drbd_body = $anvil->Storage->read_file({
debug => $debug,
file => $drbd_config_file,
target => $target_ip,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { drbd_body => $drbd_body }});
if (($drbd_body) && ($drbd_body ne "!!error!!"))
{
$anvil->data->{server_location}{host}{$short_host_name}{server}{$this_server_name}{drbd_config} = $drbd_body;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"server_location::host::${short_host_name}::server::${this_server_name}::drbd_config" => $anvil->data->{server_location}{host}{$short_host_name}{server}{$this_server_name}{drbd_config},
}});
}
}
}
}
}

@ -774,58 +774,66 @@ sub save_job
my $server_name = $anvil->data->{switches}{server_name};
my $server_uuid = $anvil->data->{switches}{server_uuid};
my $delete_uuid = $server_uuid;
push @{$hosts}, $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
push @{$hosts}, $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
if ($anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid})
{
push @{$hosts}, $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid};
}
my $server_host = "";
foreach my $host_uuid (@{$hosts})
{
if ($host_uuid eq $anvil->Get->host_uuid)
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
anvil_uuid => $anvil_uuid,
server_name => $server_name,
server_uuid => $server_uuid,
delete_uuid => $delete_uuid,
}});
if ((not $server_name) && (exists $anvil->data->{servers}{server_uuid}{$server_uuid}) && ($anvil->data->{servers}{server_uuid}{$server_uuid}{server_name}))
{
# This is us.
$anvil->Server->find({refresh => 0});
$server_name = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_name => $server_name }});
}
else
{
# This is another machine.
my $target_ip = $anvil->Network->find_target_ip({host_uuid => $host_uuid});
$anvil->Server->find({
refresh => 0,
target => $target_ip,
password => $password,
# Find the server on hosts.
my $server_host_name = $anvil->Server->locate({
debug => 2,
server_name => $server_name,
});
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_name => $server_host_name }});
my $host_name = "";
my $host_uuid = "";
if (exists $anvil->data->{server}{location}{$server_name})
foreach my $short_host_name (sort {$a cmp $b} keys %{$anvil->data->{server_location}{host}})
{
my $status = $anvil->data->{server}{location}{$server_name}{status};
$host_name = $anvil->data->{server}{location}{$server_name}{host_name};
my $host_uuid = $anvil->Database->get_host_uuid_from_string({string => $short_host_name});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
status => $status,
host_name => $host_name,
short_host_name => $short_host_name,
host_uuid => $host_uuid,
}});
if ($status eq "running")
my $exists = 0;
if (($anvil->data->{server_location}{host}{$short_host_name}{server}{$server_name}{file_definition}) or ($anvil->data->{server_location}{host}{$short_host_name}{server}{$server_name}{drbd_config}))
{
$host_uuid = $anvil->Get->host_uuid_from_name({host_name => $host_name});
$exists = 1;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'exists' => $exists }});
if (($exists) or
($host_uuid eq $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid}) or
($host_uuid eq $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid}))
{
push @{$hosts}, $host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_uuid => $host_uuid }});
}
}
# If the server was found to be running, the host will be returned.
my $server_host_uuid = "";
if ($server_host_name)
{
$server_host_uuid = $anvil->Get->host_uuid_from_name({host_name => $server_host_name});
}
# Now, we'll do the delete, unless we see the server running elsewhere.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_uuid => $host_uuid }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_uuid => $server_host_uuid }});
my $job_host_uuid = "";
if ($host_uuid)
if ($server_host_uuid)
{
$job_host_uuid = $host_uuid;
$job_host_uuid = $server_host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_host_uuid => $job_host_uuid }});
if ($host_uuid eq $anvil->Get->host_uuid)
if ($server_host_uuid eq $anvil->Get->host_uuid)
{
# Running here
print $anvil->Words->string({key => "message_0216"})."\n";
@ -833,7 +841,7 @@ sub save_job
else
{
# Running on a peer.
print $anvil->Words->string({key => "message_0214", variables => { host_name => $host_name }})."\n";
print $anvil->Words->string({key => "message_0214", variables => { host_name => $server_host_name }})."\n";
}
}
else

Loading…
Cancel
Save