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

Fixed a bug in Remote->call()
main
Digimer 1 year ago committed by GitHub
commit 5a7fb09ec8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      Anvil/Tools/Database.pm
  2. 19
      Anvil/Tools/Remote.pm
  3. 2
      Anvil/Tools/ScanCore.pm
  4. 211
      Anvil/Tools/Server.pm
  5. 15
      share/words.xml
  6. 13
      tools/anvil-configure-host
  7. 9
      tools/anvil-daemon
  8. 4
      tools/anvil-delete-server
  9. 5
      tools/anvil-manage-files
  10. 8
      tools/anvil-manage-host
  11. 111
      tools/anvil-manage-server-system
  12. 7
      tools/anvil-provision-server

@ -2392,6 +2392,7 @@ sub get_anvil_uuid_from_string
}
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0466", variables => { string => $anvil }});
return("");
}
@ -19208,6 +19209,9 @@ sub _age_out_data
$to_clean->{table}{bonds}{child_table}{bonds}{uuid_column} = "bond_uuid";
$to_clean->{table}{ip_addresses}{child_table}{ip_addresses}{uuid_column} = "ip_address_uuid";
# Misc stuff
$to_clean->{table}{sessions}{child_table}{sessions}{uuid_column} = "session_uuid";
my $vacuum = 0;
foreach my $table (sort {$a cmp $b} keys %{$to_clean->{table}})
{
@ -19699,7 +19703,7 @@ ORDER BY
my $variable_source_uuid = $row->[4] ? $row->[4] : "none";
my $variable_value = $row->[5];
my $modified_date = $row->[6];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
variable_uuid => $variable_uuid,
variable_section => $variable_section,
variable_name => $variable_name,
@ -19712,12 +19716,12 @@ ORDER BY
if (not $variable_source_table)
{
$variable_source_table = "none";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { variable_source_table => $variable_source_table }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable_source_table => $variable_source_table }});
}
if (not $variable_source_uuid)
{
$variable_source_uuid = "none";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { variable_source_uuid => $variable_source_uuid }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable_source_uuid => $variable_source_uuid }});
}
if ((not exists $anvil->data->{duplicate_variables}{$variable_section}{$variable_name}{$variable_source_table}{$variable_source_uuid}) &&
@ -19726,7 +19730,7 @@ ORDER BY
# Save it.
$anvil->data->{duplicate_variables}{$variable_section}{$variable_name}{$variable_source_table}{$variable_source_uuid}{variable_value} = $variable_value;
$anvil->data->{duplicate_variables}{$variable_section}{$variable_name}{$variable_source_table}{$variable_source_uuid}{variable_uuid} = $variable_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"duplicate_variables::${variable_section}::${variable_name}::${variable_source_table}::${variable_source_uuid}::variable_value" => $anvil->data->{duplicate_variables}{$variable_section}{$variable_name}{$variable_source_table}{$variable_source_uuid}{variable_value},
"duplicate_variables::${variable_section}::${variable_name}::${variable_source_table}::${variable_source_uuid}::variable_uuid" => $anvil->data->{duplicate_variables}{$variable_section}{$variable_name}{$variable_source_table}{$variable_source_uuid}{variable_uuid},
}});
@ -19734,7 +19738,7 @@ ORDER BY
else
{
# Duplicate! This is older, so delete it.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"duplicate_variables::${variable_section}::${variable_name}::${variable_source_table}::${variable_source_uuid}::variable_value" => $anvil->data->{duplicate_variables}{$variable_section}{$variable_name}{$variable_source_table}{$variable_source_uuid}{variable_value},
"duplicate_variables::${variable_section}::${variable_name}::${variable_source_table}::${variable_source_uuid}::variable_uuid" => $anvil->data->{duplicate_variables}{$variable_section}{$variable_name}{$variable_source_table}{$variable_source_uuid}{variable_uuid},
}});
@ -19752,7 +19756,7 @@ ORDER BY
push @{$queries}, "DELETE FROM variables WHERE variable_uuid = ".$anvil->Database->quote($variable_uuid).";";
foreach my $query (@{$queries})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { query => $query }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
}
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
}
@ -20014,6 +20018,9 @@ ORDER BY
next if $table eq "alert_sent";
next if $table eq "states";
next if $table eq "update";
### TODO: Delete 'sessions' when issue #520 is solved
### - https://github.com/ClusterLabs/anvil/issues/520
next if $table eq "sessions";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::database::table::${table}::last_updated" => $anvil->data->{sys}{database}{table}{$table}{last_updated},

@ -222,6 +222,8 @@ Any output from the call will be stored in C<< $output >>. STDERR and STDOUT are
B<NOTE>: By default, a connection to a target will be held open and cached to increase performance for future connections.
B<NOTE>: If the C<< target >> is actually the local system, C<< System->call >> is called instead, and the C<< error >> variable will be set to C<< local >>.
Parameters;
=head3 close (optional, default '0')
@ -337,12 +339,21 @@ sub call
}});
}
# In case 'target' is our short host name, change it to ''.
if ($target eq $anvil->Get->short_host_name())
### NOTE: This caused problems that are currently unsolved.
=cut
# If the call is to ourselves, switch to a local system call.
if ($anvil->Network->is_local({host => $target}))
{
$target = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { target => $target }});
# Use a local system call.
my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
return($output, "local", $return_code);
}
=cut
if (not $shell_call)
{

@ -2716,7 +2716,7 @@ LIMIT 1;";
# * 0 = No UPSes found for the host
# * 1 = One or more UPSes found and at least one has input power from mains.
# * 2 = One or more UPSes found, all are running on battery.
if (($temp_health eq "1") && ($power_health eq "1"))
if (($temp_health ne "2") && ($power_health ne "2"))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0673", variables => { host_name => $host_name }});

@ -383,11 +383,26 @@ sub connect_to_libvirt
# If we don't have a connection, try to establish one now.
if (not $anvil->data->{libvirtd}{$target}{connection})
{
my $uri = "qemu+ssh://".$target_ip."/system";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uri => $uri }});
# Make sure the target is known.
my $problem = $anvil->Remote->add_target_to_known_hosts({
debug => $debug,
target => $target_ip,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => 0, list => { problem => $problem }});
### NOTE: For some reason, the below 'alarm'/SIGALRM' hook doesn't work if the ssh target's
### fingerprint isn't known, hence the call above. Whatever is causing this though
### could bite us in other ways.
# Test connect
eval { $anvil->data->{libvirtd}{$target}{connection} = Sys::Virt->new(uri => $uri); };
my $uri = "qemu+ssh://".$target_ip."/system";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uri => $uri }});
eval
{
local $SIG{ALRM} = sub { die "Connection to: [".$uri."] timed out!\n" }; # NB: \n required
alarm 10;
$anvil->data->{libvirtd}{$target}{connection} = Sys::Virt->new(uri => $uri);
alarm 0;
};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"libvirtd::${target}::connection" => $anvil->data->{libvirtd}{$target}{connection},
}});
@ -1272,6 +1287,10 @@ C<< Note >>: By design, servers are set to 'undefined' on subnodes, so when the
Parameters;
=head3 anvil (optional, name or uuid)
If set, it restricts the search for a server to a specific Anvil! (and DR hosts, if protected). This will improve search performance on systems with nodes or DR hosts that are offline.
=head3 server_name (required)
This is the name of the server being located. It can be set to C<< all >>, in which case all servers on all hosts are located.
@ -1285,8 +1304,10 @@ sub locate
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Server->locate()" }});
my $anvil_string = defined $parameter->{anvil} ? $parameter->{anvil} : "";
my $server_name = defined $parameter->{server_name} ? $parameter->{server_name} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
anvil_string => $anvil_string,
server_name => $server_name,
}});
@ -1296,6 +1317,24 @@ sub locate
return('!!error!!');
}
my $anvil_uuid = "";
my $anvil_name = "";
if ($anvil_string)
{
$anvil_uuid = $anvil->Database->get_anvil_uuid_from_string({
debug => $debug,
string => $anvil_string,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { anvil_uuid => $anvil_uuid }});
if (not $anvil_uuid)
{
# Anvil! not found. Will be logged in Database->get_anvil_uuid_from_string().
return('!!error!!');
}
$anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { anvil_name => $anvil_name }});
}
if (exists $anvil->data->{server_location}{host})
{
delete $anvil->data->{server_location}{host};
@ -1307,6 +1346,38 @@ sub locate
# Connect to all hosts.
$anvil->Database->get_hosts({debug => $debug});
if ($anvil_uuid)
{
my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
$anvil->data->{host_search}{$node1_host_uuid}{short_host_name} = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{short_host_name};
$anvil->data->{host_search}{$node2_host_uuid}{short_host_name} = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{short_host_name};
# Add DR hosts, if any.
if (exists $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{dr_host})
{
foreach my $host_uuid (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{dr_host}})
{
$anvil->data->{host_search}{$host_uuid}{short_host_name} = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
}
}
# Log the hosts we'll search (alphabetically).
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{sys}{hosts}{by_name}})
{
my $host_uuid = $anvil->data->{sys}{hosts}{by_name}{$host_name};
if (exists $anvil->data->{host_search}{$host_uuid})
{
# Searching this
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:host_name' => $host_name,
's2:host_uuid' => $host_uuid,
}});
}
}
}
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{sys}{hosts}{by_name}})
{
my $host_uuid = $anvil->data->{sys}{hosts}{by_name}{$host_name};
@ -1320,6 +1391,15 @@ sub locate
}});
next if $host_type eq "striker";
if ($anvil_uuid)
{
# Skip if this isn't a host we're searching.
if (not exists $anvil->data->{host_search}{$host_uuid})
{
next;
}
}
# This will switch to '1' if we connect to libvirtd.
$anvil->data->{server_location}{host}{$short_host_name}{access} = 0;
@ -1934,6 +2014,7 @@ sub parse_definition
source => $source,
definition => $definition,
host => $host,
target => $target,
}});
if (not $target)
@ -1983,6 +2064,9 @@ sub parse_definition
}
$anvil->data->{server}{$target}{$server}{$source}{parsed} = $server_xml;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"server::${target}::${server}::${source}::parsed" => $anvil->data->{server}{$target}{$server}{$source}{parsed},
}});
# Get the DRBD data that this server will almost certainly be using.
$anvil->DRBD->get_devices({
@ -2851,6 +2935,15 @@ sub update_definition
return('!!error!!');
}
# Find where the server exists.
my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
$anvil->Server->locate({
debug => $debug,
server_name => $server_name,
anvil => $anvil_uuid,
});
# Validate the new XML
my $short_host_name = $anvil->Get->short_host_name();
my $problem = $anvil->Server->parse_definition({
@ -2885,7 +2978,6 @@ sub update_definition
}
# Prep our variables.
my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid};
my $definition_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_uuid};
my $db_definition_xml = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml};
my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
@ -2893,7 +2985,6 @@ sub update_definition
my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
my $node2_host_name = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
anvil_uuid => $anvil_uuid,
definition_uuid => $definition_uuid,
db_definition_xml => $db_definition_xml,
node1_host_uuid => $node1_host_uuid,
@ -2937,29 +3028,29 @@ sub update_definition
foreach my $host_uuid (@{$hosts})
{
# Find a target_ip (local will be detected as local in the file read/write)
my $short_host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{short_host_name};
my $target_ip = $anvil->Network->find_target_ip({
debug => 2,
host_uuid => $host_uuid,
test_access => 1,
networks => "bcn,mn,sn,ifn,any",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target_ip => $target_ip }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
target_ip => $target_ip,
short_host_name => $short_host_name,
}});
if ($target_ip)
{
# Read the old definition.
my $old_definition_xml = $anvil->Storage->read_file({
debug => $debug,
file => $definition_file,
target => $target_ip,
});
# The definition was read by Server->locate, so we can use it.
my $old_definition_xml = defined $anvil->data->{server_location}{host}{$short_host_name}{server}{$server_name}{file_definition} ? $anvil->data->{server_location}{host}{$short_host_name}{server}{$server_name}{file_definition} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_definition_xml => $old_definition_xml }});
### TODO: Handle when the definition file simply doesn't exist.
if ((not $old_definition_xml) or ($old_definition_xml eq "!!error!!") or ($old_definition_xml !~ /<domain/ms))
{
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "warning_0163", variables => {
server_name => $server_name,
host_name => $host_name,
host_name => $short_host_name,
file => $definition_file,
}});
}
@ -2993,10 +3084,100 @@ sub update_definition
}});
}
}
# If the server is defined, update that also.
if ((exists $anvil->data->{server_location}{host}{$short_host_name}{server}{$server_name}{inactive_definition}) &&
($anvil->data->{server_location}{host}{$short_host_name}{server}{$server_name}{inactive_definition}))
{
# This will always differ, so just update.
my $problem = $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 => 2, 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},
}});
# Define the server
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0818", variables => { server_name => $server_name }});
eval { $anvil->data->{libvirtd}{$short_host_name}{connection}->define_domain($new_definition_xml); };
if ($@)
{
# Throw an error, then clear the URI so that we just update the DB/on-disk definitions.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "warning_0166", variables => {
host_name => $short_host_name,
server_name => $server_name,
error => $@,
}});
}
else
{
if (not ref($anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection}) eq "Sys::Virt::Domain")
{
# Connect to the server.
my @domains = $anvil->data->{libvirtd}{$short_host_name}{connection}->list_all_domains();
foreach my $domain_handle (@domains)
{
my $this_server_name = $domain_handle->get_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
domain_handle => $domain_handle,
this_server_name => $this_server_name,
}});
if ($this_server_name eq $server_name)
{
$anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection} = $domain_handle;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"libvirtd::${short_host_name}::server::${server_name}::connection" => $anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection},
}});
last;
}
}
}
# If the server running or defined here?
# If this connection still valid?
if (ref($anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection}) eq "Sys::Virt::Domain")
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0819", variables => { server_name => $server_name }});
my $uuid = "";
eval { $uuid = $anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection}->get_uuid_string(); };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "uuid" => $uuid }});
if ((not $@) && ($uuid))
{
# Connection is good.
my $updated = $anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection}->is_updated();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "updated" => $updated }});
if ($updated)
{
eval { $anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection}->undefine; };
if ($@)
{
# Throw an error, then clear the URI so that we just update the DB/on-disk definitions.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "warning_0167", variables => {
host_name => $short_host_name,
server_name => $server_name,
error => $@,
}});
}
else
{
my $updated = $anvil->data->{libvirtd}{$short_host_name}{server}{$server_name}{connection}->is_updated();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "updated" => $updated }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0817", variables => { server_name => $server_name }});
}
}
}
}
}
}
}
}
}
}

@ -734,6 +734,7 @@ The XML that failed sanity check was:
========
]]></key>
<key name="error_0465"><![CDATA[The file: [#!variable!file!#] doesn't exist on the target: [#!variable!target!#].]]></key>
<key name="error_0466"><![CDATA[The Anvil! string (name or UUID): [#!variable!string!#] didn't match any known Anvil! in the database.]]></key>
<!-- Files templates -->
<!-- NOTE: Translating these files requires an understanding of which lines are translatable -->
@ -2628,6 +2629,10 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0814">There is an existing a functioning connection to: [#!variable!target!#], no need to reconnect.</key>
<key name="log_0815">There is an existing a functioning connection to the server: [#!variable!server_name!#], no need to reconnect.</key>
<key name="log_0816">Waiting for: [#!variable!delay!#] seconds.</key>
<key name="log_0817">The server: [#!variable!server_name!#] libvirt definition was updated, undefining static config.</key>
<key name="log_0818">The server: [#!variable!server_name!#] libvirt definition will now be updated.</key>
<key name="log_0819">Check to verify that the connection to the server: [#!variable!server_name!#] is valid.</key>
<key name="log_0820">The network mapping flag is NOT set.</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>
@ -3955,6 +3960,16 @@ We will try to proceed anyway.</key>
<key name="warning_0163"><![CDATA[Failed to read the definition file: [#!variable!file!#] for the server: [#!variable!server_name!#] on the host: [#!variable!host_name!#]. If the host is online, it should update the next time scan-server runs.]]></key>
<key name="warning_0164"><![CDATA[Failed to update the definition file: [#!variable!file!#] for the server: [#!variable!server_name!#] on the host: [#!variable!host_name!#]. If the host is online, it should update the next time scan-server runs.]]></key>
<key name="warning_0165"><![CDATA[A duplicate variable was found! Section: [#!variable!section!#], name: [#!variable!name!#], source table: [#!variable!source_table!#], source_uuid: [#!variable!source_uuid!#], value: [#!variable!value!#]. This is older, so it will be deleted.]]></key>
<key name="warning_0166">Failed to update the in-memory definition for the server: [#!variable!server_name!#] on the host: [#!variable!host_name!#]. The error, if any, was:
====
#!variable!error!#
====
</key>
<key name="warning_0167">Failed to undefine the running server: [#!variable!server_name!#] on the host: [#!variable!host_name!#]. The error, if any, was:
====
#!variable!error!#
====
</key>
</language>
<!-- 日本語 -->

@ -70,6 +70,7 @@ reconfigure_network($anvil);
# Record that we've configured this machine.
$anvil->Database->insert_or_update_variables({
debug => 2,
variable_name => "system::configured",
variable_value => 1,
variable_default => "",
@ -258,6 +259,18 @@ sub reconfigure_network
type => $type,
}});
# Clear the network mapping flag.
$anvil->Database->insert_or_update_variables({
debug => 2,
variable_name => "config::map_network",
variable_value => 0,
variable_default => "",
variable_description => "striker_0202",
variable_section => "config",
variable_source_uuid => $anvil->Get->host_uuid,
variable_source_table => "hosts",
});
# If we're configuring a dashboard and no host name was given, generate it.
if (($type eq "striker") && (not $new_host_name))
{

@ -1586,7 +1586,7 @@ sub keep_running
}
# Run any pending jobs by calling 'anvil-jobs' with the 'job_uuid' as a background process.
run_jobs($anvil, 0) if not $anvil->data->{sys}{mapping_network};
run_jobs($anvil, 0);
return(0);
}
@ -1622,13 +1622,14 @@ sub run_jobs
# If we're not configured, we won't hold on starting jobs
my $configured = $anvil->System->check_if_configured;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { configured => $configured }});
# We'll also update the jobs.json file.
my $jobs_file = "{\"jobs\":[\n";
# Get a list of pending or incomplete jobs.
my $ended_within = $startup ? 1 : 300;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { ended_within => $ended_within }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ended_within => $ended_within }});
$anvil->Database->get_jobs({
debug => 2,
@ -1675,8 +1676,12 @@ sub run_jobs
's12:job_status' => $job_status,
's13:started_seconds_ago' => $started_seconds_ago,
's14:updated_seconds_ago' => $updated_seconds_ago,
's15:sys::mapping_network' => $anvil->data->{sys}{mapping_network},
}});
# If we're mapping, we'll only run 'anvil-configure-host' jobs on this host.
next if (($anvil->data->{sys}{mapping_network}) && ($job_command !~ /anvil-configure-host/));
# To minimize the chance of race conditions, any given command will be called only
# once at a time. If two jobs of the same command exist, only one will be called.
if ($job_progress != 100)

@ -36,6 +36,10 @@ $anvil->Get->switches({list => [
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
### TODO: Remove this post testing
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})

@ -54,11 +54,6 @@ if (($running_directory =~ /^\./) && ($ENV{PWD}))
my $anvil = Anvil::Tools->new();
$anvil->Get->switches({list => ["add", "check", "delete", "download", "file", "is-script", "rename", "remove", "to"], man => $THIS_FILE});
### TODO: Remove this
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
# Connect or die

@ -247,7 +247,7 @@ sub update_network_mapping
's4:map_network_modified_date' => $map_network_modified_date,
's5:map_network_uuid' => $map_network_uuid,
}});
if ($anvil->data->{switches}{'check-configured'})
if ($anvil->data->{switches}{'check-network-mapping'})
{
# We'll run for a day (should be cancelled by the program when the user's done, so this
# shouldn't fire in practice).
@ -278,12 +278,16 @@ sub update_network_mapping
# Mark it so we only track the network.
my $say_age = $anvil->Convert->add_commas({number => $expire_age});
my $timeout = $anvil->Convert->add_commas({number => ($expire_age - $map_network_age)});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0471", variables => {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0471", variables => {
age => $say_age,
timeout => $timeout,
}});
}
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0820"});
}
return(0);
}

@ -110,7 +110,7 @@ elsif ($anvil->data->{switches}{ram})
}
elsif ($anvil->data->{switches}{boot})
{
#manage_boot($anvil);
manage_boot($anvil);
}
elsif ($anvil->data->{switches}{'boot-menu'})
{
@ -133,7 +133,7 @@ $anvil->nice_exit({exit_code => 0});
# Functions #
#############################################################################################################
sub connect_to_libvirt
sub manage_boot
{
my ($anvil) = @_;
@ -141,11 +141,14 @@ sub connect_to_libvirt
my $host_uuid = $anvil->Get->host_uuid;
my $server_name = $anvil->data->{switches}{server_name};
my $server_uuid = $anvil->data->{switches}{server_uuid};
my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid};
my $server_host_name = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:short_host_name' => $short_host_name,
's2:host_uuid' => $host_uuid,
's3:server_name' => $server_name,
's4:server_uuid' => $server_uuid,
's5:server_host_uuid' => $server_host_uuid,
}});
my $from_source = get_definition_source($anvil);
@ -154,71 +157,31 @@ sub connect_to_libvirt
from_source => $from_source,
server_state => $server_state,
}});
# We'll make changes to the DB and on-disk definitions if the server isn't running. If it is, we'll
# update the live system as well.
my $uri = "";
if ($server_state eq "running")
{
if ($server_uuid eq $anvil->Get->host_uuid)
{
### NOTE: Don't use 'localhost', Sys::Virt translates it to '::1' which Net::OpenSSH
### breaks on.
# Connect to the local libvirtd API, and handle problems if not.
$uri = "qemu+ssh://".$short_host_name."/system";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uri => $uri }});
}
else
{
my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid};
my $server_host_name = $anvil->Database->get_host_from_uuid({
$server_host_name = $anvil->Database->get_host_from_uuid({
short => 1,
host_uuid => $server_host_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_name => $server_host_name }});
my $target_ip = $anvil->Network->find_target_ip({
debug => 2,
host_uuid => $server_host_uuid,
test_access => 1,
networks => "bcn,mn,sn,ifn,any",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target_ip => $target_ip }});
if ($target_ip)
{
# Connect using this URI
$uri = "qemu+ssh://".$target_ip."/system";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uri => $uri }});
}
}
}
my $connection = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uri => $uri }});
eval { $connection = Sys::Virt->new(uri => $uri); };
if ($@)
if ($anvil->data->{switches}{boot} eq "#!SET!#")
{
# Throw an error, then clear the URI so that we just update the DB/on-disk definitions.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "warning_0162", variables => {
host_name => $short_host_name,
uri => $uri,
error => $@,
}});
return(1);
}
my $domain = "";
my @domains = $connection->list_all_domains();
foreach my $domain_handle (@domains)
print "Boot device order for: [".$server_name."]\n";
foreach my $boot_order (sort {$a cmp $b} keys %{$anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}})
{
my $this_server_name = $domain_handle->get_name;
next if $this_server_name ne $server_name;
$domain = $domain_handle;
last;
my $device_target = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$boot_order}{device_target};
my $device = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{boot_order}{$boot_order}{device_type};
my $path = $anvil->data->{server}{$short_host_name}{$server_name}{$from_source}{device}{$device}{target}{$device_target}{path};
print " ".$boot_order.") Target: [".$device_target."], Device: [".$device."], Path: [".$path."]\n";
}
print "To change the boot device, use '--boot <target>' or --boot <target1>,<target2>,...\n";
return(0);
}
print "Updating boot devices.\n";
return($domain);
return(0);
}
sub manage_boot_menu
@ -230,6 +193,7 @@ sub manage_boot_menu
my $server_name = $anvil->data->{switches}{server_name};
my $server_uuid = $anvil->data->{switches}{server_uuid};
my $server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid};
my $server_host_name = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:short_host_name' => $short_host_name,
's2:host_uuid' => $host_uuid,
@ -238,20 +202,19 @@ sub manage_boot_menu
's5:server_host_uuid' => $server_host_uuid,
}});
my $domain_handle = connect_to_libvirt($anvil);
my $from_source = get_definition_source($anvil);
my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
domain_handle => $domain_handle,
from_source => $from_source,
server_state => $server_state,
}});
if ($server_state eq "running")
{
my $server_host_name = $anvil->Database->get_host_from_uuid({
$server_host_name = $anvil->Database->get_host_from_uuid({
short => 1,
host_uuid => $server_host_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_host_name => $server_host_name }});
}
my $say_yes = $anvil->Words->string({key => 'unit_0001'});
@ -265,8 +228,12 @@ sub manage_boot_menu
new_boot_menu => $new_boot_menu,
}});
if (($anvil->data->{switches}{'boot-menu'} eq "yes") or ($anvil->data->{switches}{'boot-menu'} eq "no"))
if ((lc($anvil->data->{switches}{'boot-menu'}) eq "yes") or (lc($anvil->data->{switches}{'boot-menu'}) eq "no"))
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"servers::server_uuid::${server_uuid}::server_definition_xml" => $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml},
}});
# We need to rewrite the boot menu manually.
my $new_definition = "";
my $in_os = 0;
@ -314,11 +281,35 @@ sub manage_boot_menu
new_definition_xml => $new_definition,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
# Reload and parse from the DB to confirm things are updated.
delete $anvil->data->{servers}{server_uuid}{$server_uuid};
$anvil->Database->get_servers();
my $server_definition_xml = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_definition_xml};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_definition_xml => $server_definition_xml }});
undef $anvil->data->{server}{$short_host_name}{$server_name}{from_db};
$anvil->Server->parse_definition({
debug => 2,
host => $short_host_name,
server => $server_name,
source => "from_db",
definition => $server_definition_xml,
});
my $new_boot_menu = lc($anvil->data->{server}{$short_host_name}{$server_name}{from_db}{info}{boot_menu});
my $say_new_boot_menu = $new_boot_menu eq "yes" ? $say_yes : $say_no;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
new_boot_menu => $new_boot_menu,
say_new_boot_menu => $say_new_boot_menu,
}});
print "Boot Menu enabled now: [".$say_new_boot_menu."]\n";
print "- The boot menu has been updated.\n";
}
else
{
print "Boot Menu enabled: [".$say_old_boot_menu."]\n";
print "- You can change this using '--boot-menu off' or '--boot-menu on'.\n";
print "- You can change this using '--boot-menu yes' or '--boot-menu no'.\n";
}
return(0);

@ -407,8 +407,8 @@ sub write_definition
while (not -f $xml_file)
{
$anvil->Database->get_servers();
$anvil->Database->get_server_definitions();
$anvil->Database->get_servers({debug => 2});
$anvil->Database->get_server_definitions({debug => 2});
if (not exists $anvil->data->{servers}{anvil_uuid}{$anvil_uuid}{server_name}{$server_name}{server_uuid})
{
@ -423,14 +423,15 @@ sub write_definition
{
# Write it!
my $return = $anvil->Storage->write_file({
debug => 2,
body => $server_definition,
file => $xml_file,
overwrite => 1,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'return' => $return }});
if (-f $xml_file)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'return' => $return }});
$anvil->Job->update_progress({
progress => 80,
message => "job_0206,!!file!".$xml_file."!!",

Loading…
Cancel
Save