diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 62625b41..1e49a47f 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -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}, diff --git a/Anvil/Tools/Remote.pm b/Anvil/Tools/Remote.pm index f228541d..48d19651 100644 --- a/Anvil/Tools/Remote.pm +++ b/Anvil/Tools/Remote.pm @@ -222,6 +222,8 @@ Any output from the call will be stored in C<< $output >>. STDERR and STDOUT are B: By default, a connection to a target will be held open and cached to increase performance for future connections. +B: 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') @@ -336,13 +338,22 @@ sub call password => $anvil->Log->is_secure($password), }}); } - - # 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) { diff --git a/Anvil/Tools/ScanCore.pm b/Anvil/Tools/ScanCore.pm index 8af2b18f..41e35bdf 100644 --- a/Anvil/Tools/ScanCore.pm +++ b/Anvil/Tools/ScanCore.pm @@ -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 }}); diff --git a/Anvil/Tools/Server.pm b/Anvil/Tools/Server.pm index 9d82781e..a4fa8413 100644 --- a/Anvil/Tools/Server.pm +++ b/Anvil/Tools/Server.pm @@ -346,7 +346,7 @@ sub connect_to_libvirt target_ip => $target_ip, }}); - if ((not $target)or ($target eq "localhost")) + if ((not $target) or ($target eq "localhost")) { # Change to the short host name. $target = $anvil->Get->short_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,9 +1304,11 @@ 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 $server_name = defined $parameter->{server_name} ? $parameter->{server_name} : ""; + 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 => { - server_name => $server_name, + anvil_string => $anvil_string, + server_name => $server_name, }}); if (not $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 $target_ip = $anvil->Network->find_target_ip({ + 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 !~ /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 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 }}); + } + } + } + } + } + } + } } - - # If the server running or defined here? - } } diff --git a/share/words.xml b/share/words.xml index 5600ecd1..e795a34d 100644 --- a/share/words.xml +++ b/share/words.xml @@ -734,6 +734,7 @@ The XML that failed sanity check was: ======== ]]> + @@ -2628,6 +2629,10 @@ The file: [#!variable!file!#] needs to be updated. The difference is: There is an existing a functioning connection to: [#!variable!target!#], no need to reconnect. There is an existing a functioning connection to the server: [#!variable!server_name!#], no need to reconnect. Waiting for: [#!variable!delay!#] seconds. + The server: [#!variable!server_name!#] libvirt definition was updated, undefining static config. + The server: [#!variable!server_name!#] libvirt definition will now be updated. + Check to verify that the connection to the server: [#!variable!server_name!#] is valid. + The network mapping flag is NOT set. The host name: [#!variable!target!#] does not resolve to an IP address. @@ -3955,6 +3960,16 @@ We will try to proceed anyway. + 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!# +==== + + Failed to undefine the running server: [#!variable!server_name!#] on the host: [#!variable!host_name!#]. The error, if any, was: +==== +#!variable!error!# +==== + diff --git a/tools/anvil-configure-host b/tools/anvil-configure-host index adc32550..4f02b3c7 100755 --- a/tools/anvil-configure-host +++ b/tools/anvil-configure-host @@ -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 => "", @@ -257,6 +258,18 @@ sub reconfigure_network new_host_name => $new_host_name, 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)) diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 70edb32f..eeea2e2e 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -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, @@ -1661,22 +1662,26 @@ sub run_jobs my $started_seconds_ago = $job_picked_up_at ? (time - $job_picked_up_at) : 0; my $updated_seconds_ago = $job_updated ? (time - $job_updated) : 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 's01:job_uuid' => $job_uuid, - 's02:job_command' => $job_command, - 's03:short_command' => $short_command, - 's04:job_data' => $job_data, - 's05:job_picked_up_by' => $job_picked_up_by, - 's06:job_picked_up_at' => $job_picked_up_at, - 's07:job_updated' => $job_updated, - 's08:job_name' => $job_name, - 's09:job_progress' => $job_progress, - 's10:job_title' => $job_title, - 's11:job_description' => $job_description, - 's12:job_status' => $job_status, - 's13:started_seconds_ago' => $started_seconds_ago, - 's14:updated_seconds_ago' => $updated_seconds_ago, + 's01:job_uuid' => $job_uuid, + 's02:job_command' => $job_command, + 's03:short_command' => $short_command, + 's04:job_data' => $job_data, + 's05:job_picked_up_by' => $job_picked_up_by, + 's06:job_picked_up_at' => $job_picked_up_at, + 's07:job_updated' => $job_updated, + 's08:job_name' => $job_name, + 's09:job_progress' => $job_progress, + 's10:job_title' => $job_title, + 's11:job_description' => $job_description, + '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) diff --git a/tools/anvil-delete-server b/tools/anvil-delete-server index 4b7bdc89..c7065796 100755 --- a/tools/anvil-delete-server +++ b/tools/anvil-delete-server @@ -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}) diff --git a/tools/anvil-manage-files b/tools/anvil-manage-files index 075ddb19..4c888396 100755 --- a/tools/anvil-manage-files +++ b/tools/anvil-manage-files @@ -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 diff --git a/tools/anvil-manage-host b/tools/anvil-manage-host index 5cd6634a..b793e332 100755 --- a/tools/anvil-manage-host +++ b/tools/anvil-manage-host @@ -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); } diff --git a/tools/anvil-manage-server-system b/tools/anvil-manage-server-system index d1502c4a..916830d6 100755 --- a/tools/anvil-manage-server-system +++ b/tools/anvil-manage-server-system @@ -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,92 +133,55 @@ $anvil->nice_exit({exit_code => 0}); # Functions # ############################################################################################################# -sub connect_to_libvirt +sub manage_boot { my ($anvil) = @_; - my $short_host_name = $anvil->Get->short_host_name; - my $host_uuid = $anvil->Get->host_uuid; - my $server_name = $anvil->data->{switches}{server_name}; - my $server_uuid = $anvil->data->{switches}{server_uuid}; + my $short_host_name = $anvil->Get->short_host_name; + 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, + '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); my $server_state = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_state}; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - from_source => $from_source, - server_state => $server_state, + 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({ - 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 ($@) - { - # 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); + $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 $domain = ""; - my @domains = $connection->list_all_domains(); - foreach my $domain_handle (@domains) + if ($anvil->data->{switches}{boot} eq "#!SET!#") { - my $this_server_name = $domain_handle->get_name; - next if $this_server_name ne $server_name; - - $domain = $domain_handle; - last; + 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 $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 ' or --boot ,,...\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}; + 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); diff --git a/tools/anvil-provision-server b/tools/anvil-provision-server index ca5d7578..e358456a 100755 --- a/tools/anvil-provision-server +++ b/tools/anvil-provision-server @@ -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."!!",