Merge branch 'main' into patch-screenshot-icons

main
Digimer 1 year ago committed by GitHub
commit 852f341a99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 170
      Anvil/Tools/Database.pm
  2. 72
      Anvil/Tools/Storage.pm
  3. 7
      share/words.xml
  4. 38
      tools/anvil-configure-host
  5. 10
      tools/anvil-daemon
  6. 110
      tools/anvil-join-anvil
  7. 7
      tools/anvil-manage-files
  8. 43
      tools/anvil-manage-power
  9. 40
      tools/anvil-provision-server
  10. 5
      tools/anvil-sync-shared
  11. 31
      tools/striker-collect-debug

@ -404,8 +404,6 @@ sub check_file_locations
# Get all the Anvil! systems we know of.
$anvil->Database->get_hosts({debug => $debug});
#$anvil->Database->get_files({debug => $debug});
#$anvil->Database->get_file_locations({debug => $debug});
foreach my $host_name (sort {$a cmp $b} keys %{$anvil->data->{hosts}{host_name}})
{
@ -3705,23 +3703,26 @@ WHERE
}});
foreach my $row (@{$results})
{
my $file_uuid = $row->[0];
my $file_name = $row->[1];
my $file_directory = $row->[2];
my $file_size = $row->[3];
my $file_md5sum = $row->[4];
my $file_type = $row->[5];
my $file_mtime = $row->[6];
my $modified_date = $row->[7];
my $file_uuid = $row->[0];
my $file_name = $row->[1];
my $file_directory = $row->[2];
my $file_size = $row->[3];
my $file_md5sum = $row->[4];
my $file_type = $row->[5];
my $file_mtime = $row->[6];
my $modified_date = $row->[7];
my $full_path = $file_directory."/".$file_name;
$full_path =~ s/\/\//\//g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
file_uuid => $file_uuid,
file_name => $file_name,
file_directory => $file_directory,
file_size => $file_size,
file_size => $file_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $file_size}).")",
file_md5sum => $file_md5sum,
file_type => $file_type,
file_mtime => $file_mtime,
modified_date => $modified_date,
full_path => $full_path,
}});
# Record the data in the hash, too.
@ -3735,13 +3736,156 @@ WHERE
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"files::file_uuid::${file_uuid}::file_name" => $anvil->data->{files}{file_uuid}{$file_uuid}{file_name},
"files::file_uuid::${file_uuid}::file_directory" => $anvil->data->{files}{file_uuid}{$file_uuid}{file_directory},
"files::file_uuid::${file_uuid}::file_size" => $anvil->data->{files}{file_uuid}{$file_uuid}{file_size},
"files::file_uuid::${file_uuid}::file_size" => $anvil->data->{files}{file_uuid}{$file_uuid}{file_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{files}{file_uuid}{$file_uuid}{file_size}}).")",
"files::file_uuid::${file_uuid}::file_md5sum" => $anvil->data->{files}{file_uuid}{$file_uuid}{file_md5sum},
"files::file_uuid::${file_uuid}::file_type" => $anvil->data->{files}{file_uuid}{$file_uuid}{file_type},
"files::file_uuid::${file_uuid}::file_mtime" => $anvil->data->{files}{file_uuid}{$file_uuid}{file_mtime},
"files::file_uuid::${file_uuid}::modified_date" => $anvil->data->{files}{file_uuid}{$file_uuid}{modified_date},
}});
# Is this a duplicate?
if (exists $anvil->data->{files}{full_path}{$full_path})
{
# Duplicate! How many file_locations are linked to the duplicates?
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0812", variables => { full_path => $full_path }});
$anvil->Database->get_file_locations({debug => $debug});
my $other_file_uuid = $anvil->data->{files}{full_path}{$full_path}{file_uuid};
my $other_file_size = $anvil->data->{files}{file_uuid}{$other_file_uuid}{file_size};
my $other_file_md5sum = $anvil->data->{files}{file_uuid}{$file_uuid}{file_md5sum};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
other_file_uuid => $other_file_uuid,
other_file_size => $other_file_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $other_file_size}).")",
other_file_md5sum => $other_file_md5sum,
}});
my $delete_file_uuid = "";
# How many linked file_locations are there?
my $query = "SELECT COUNT(*) FROM file_locations WHERE file_location_file_uuid = ".$anvil->Database->quote($file_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $file_location_count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { file_location_count => $file_location_count }});
$query = "SELECT COUNT(*) FROM file_locations WHERE file_location_file_uuid = ".$anvil->Database->quote($other_file_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $other_file_location_count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { other_file_location_count => $other_file_location_count }});
# This could happen just after peering a striker, so both could have no
# file_locations yet. If so, delete this one.
if (not $file_location_count)
{
$delete_file_uuid = $file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { delete_file_uuid => $delete_file_uuid }});
}
elsif (not $other_file_location_count)
{
# Choose the other
$delete_file_uuid = $other_file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { delete_file_uuid => $delete_file_uuid }});
}
else
{
# Pick the one with the largest file, if there's a difference.
if ($file_size != $other_file_size)
{
if ($file_size > $other_file_size)
{
# This one is bigger, delete the other
$delete_file_uuid = $other_file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { delete_file_uuid => $delete_file_uuid }});
}
else
{
# The other is bigger, delete this one.
$delete_file_uuid = $file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { delete_file_uuid => $delete_file_uuid }});
}
}
else
{
# Sizes are the same. Does one have more file_location references?
if ($file_location_count != $other_file_location_count)
{
if ($file_location_count > $other_file_location_count)
{
# This one has more references
$delete_file_uuid = $other_file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { delete_file_uuid => $delete_file_uuid }});
}
else
{
# The other one has more references.
$delete_file_uuid = $file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { delete_file_uuid => $delete_file_uuid }});
}
}
else
{
# No difference, delete this one.
$delete_file_uuid = $file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { delete_file_uuid => $delete_file_uuid }});
}
}
}
if ($delete_file_uuid)
{
# Log which we're deleting
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0813", variables => { file_uuid => $delete_file_uuid }});
# As we delete file_locations, we need to make sure that there are
# file_location_file_uuid entries for the other file.
my $keep_file_uuid = $file_uuid eq $delete_file_uuid ? $other_file_uuid : $file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { keep_file_uuid => $keep_file_uuid }});
my $query = "DELETE FROM history.file_locations WHERE file_location_file_uuid = ".$anvil->Database->quote($delete_file_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({debug => $debug, query => $query, source => $THIS_FILE, line => __LINE__});
$query = "DELETE FROM file_locations WHERE file_location_file_uuid = ".$anvil->Database->quote($delete_file_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({debug => $debug, query => $query, source => $THIS_FILE, line => __LINE__});
$query = "DELETE FROM history.files WHERE file_uuid = ".$anvil->Database->quote($delete_file_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({debug => $debug, query => $query, source => $THIS_FILE, line => __LINE__});
$query = "DELETE FROM files WHERE file_uuid = ".$anvil->Database->quote($delete_file_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Database->write({debug => $debug, query => $query, source => $THIS_FILE, line => __LINE__});
delete $anvil->data->{files}{file_uuid}{$delete_file_uuid};
next;
}
}
else
{
$anvil->data->{files}{full_path}{$full_path}{file_uuid} = $file_uuid;
$anvil->data->{files}{full_path}{$full_path}{file_name} = $file_name;
$anvil->data->{files}{full_path}{$full_path}{file_directory} = $file_directory;
$anvil->data->{files}{full_path}{$full_path}{file_size} = $file_size;
$anvil->data->{files}{full_path}{$full_path}{file_md5sum} = $file_md5sum;
$anvil->data->{files}{full_path}{$full_path}{file_type} = $file_type;
$anvil->data->{files}{full_path}{$full_path}{file_mtime} = $file_mtime;
$anvil->data->{files}{full_path}{$full_path}{modified_date} = $modified_date;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"files::full_path::${full_path}::file_uuid" => $anvil->data->{files}{full_path}{$full_path}{file_uuid},
"files::full_path::${full_path}::file_name" => $anvil->data->{files}{full_path}{$full_path}{file_name},
"files::full_path::${full_path}::file_directory" => $anvil->data->{files}{full_path}{$full_path}{file_directory},
"files::full_path::${full_path}::file_size" => $anvil->data->{files}{full_path}{$full_path}{file_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{files}{full_path}{$full_path}{file_size}}).")",
"files::full_path::${full_path}::file_md5sum" => $anvil->data->{files}{full_path}{$full_path}{file_md5sum},
"files::full_path::${full_path}::file_type" => $anvil->data->{files}{full_path}{$full_path}{file_type},
"files::full_path::${full_path}::file_mtime" => $anvil->data->{files}{full_path}{$full_path}{file_mtime},
"files::full_path::${full_path}::modified_date" => $anvil->data->{files}{full_path}{$full_path}{modified_date},
}});
}
### NOTE: This is the old way, which didn't allow two files with the same name in different
### directories. This needs to be retired.
$anvil->data->{files}{file_name}{$file_name}{file_uuid} = $file_uuid;
$anvil->data->{files}{file_name}{$file_name}{file_directory} = $file_directory;
$anvil->data->{files}{file_name}{$file_name}{file_size} = $file_size;
@ -3752,7 +3896,7 @@ WHERE
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"files::file_name::${file_name}::file_uuid" => $anvil->data->{files}{file_name}{$file_name}{file_uuid},
"files::file_name::${file_name}::file_directory" => $anvil->data->{files}{file_name}{$file_name}{file_directory},
"files::file_name::${file_name}::file_size" => $anvil->data->{files}{file_name}{$file_name}{file_size},
"files::file_name::${file_name}::file_size" => $anvil->data->{files}{file_name}{$file_name}{file_size}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{files}{file_name}{$file_name}{file_size}}).")",
"files::file_name::${file_name}::file_md5sum" => $anvil->data->{files}{file_name}{$file_name}{file_md5sum},
"files::file_name::${file_name}::file_type" => $anvil->data->{files}{file_name}{$file_name}{file_type},
"files::file_name::${file_name}::file_mtime" => $anvil->data->{files}{file_name}{$file_name}{file_mtime},

@ -607,6 +607,78 @@ sub check_files
my $host_uuid = $anvil->Get->host_uuid({debug => $debug});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }});
# Make sure all entries in 'files' has a corresponding 'file_locations' entry for this host.
my $host_type = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
# Look for files on this computer not yet on the system
if ($host_type ne "striker")
{
my $reload = 0;
foreach my $file_name (sort {$a cmp $b} keys %{$anvil->data->{files}{file_name}})
{
my $file_uuid = $anvil->data->{files}{file_name}{$file_name}{file_uuid};
my $file_directory = $anvil->data->{files}{file_name}{$file_name}{file_directory};
my $file_size = $anvil->data->{files}{file_name}{$file_name}{file_size};
my $file_md5sum = $anvil->data->{files}{file_name}{$file_name}{file_md5sum};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:file_name' => $file_name,
's2:file_uuid' => $file_uuid,
's3:file_directory' => $file_directory,
's4:file_size' => $file_size." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $file_size}).")",
's5:file_md5sum' => $file_md5sum,
}});
# Is there an entry or this host?
if (not exists $anvil->data->{file_locations}{host_uuid}{$host_uuid}{file_uuid}{$file_uuid})
{
# Nope, add it.
$reload = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { reload => $reload }});
my $file_ready = 0;
my $full_path = $file_directory."/".$file_name;
$full_path =~ s/\/\//\//g;
if (-f $full_path)
{
# Calculate the md5sum.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0265", variables => { file => $full_path }});
if ($file_size > (128 * (2 ** 20)))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0266", variables => {
size => $anvil->Convert->bytes_to_human_readable({'bytes' => $file_size}),
}});
}
# Update (or get) the md5sum.
my $local_md5sum = $anvil->Get->md5sum({debug => 2, file => $full_path});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { local_md5sum => $local_md5sum }});
if ($local_md5sum eq $file_md5sum)
{
$file_ready = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_ready => $file_ready }});
}
}
my $file_location_uuid = $anvil->Database->insert_or_update_file_locations({
debug => $debug,
file_location_file_uuid => $file_uuid,
file_location_host_uuid => $host_uuid,
file_location_active => 1,
file_location_ready => $file_ready,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_location_uuid => $file_location_uuid }});
}
}
if ($reload)
{
$anvil->Database->get_files({debug => $debug});
$anvil->Database->get_file_locations({debug => $debug});
}
}
# Sorting isn't useful really, but it ensures consistent listing run over run).
foreach my $file_location_file_uuid (sort {$a cmp $b} keys %{$anvil->data->{file_locations}{host_uuid}{$host_uuid}{file_uuid}})
{

@ -1686,6 +1686,9 @@ Note: This is a permanent action! If you protect this server again later, a full
<key name="job_0472">Server Storage Management</key>
<key name="job_0473">This job manages the storage on a given hosted server. It can grow an existing disk, add a new disk, insert an ISO into an optical disc, or eject a disc.</key>
<key name="job_0474">The server: [#!variable!server!#] will now be forced off!</key>
<key name="job_0475">The subnode: [#!variable!subnode!#] is not ready. Configured: [#!variable!configured!#], maintenance mode: [#!variable!maintenance_mode!#], job_running: [#!variable!job_running!#].</key>
<key name="job_0476">Waiting for a bit, then will check again.</key>
<key name="job_0477">Waiting for both subnodes to be configured and out of maintenance mode.</key>
<!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key>
@ -2608,6 +2611,8 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0809">- Deleting the server: [#!variable!server_name!#]'s screenshot: [#!variable!file!#].</key>
<key name="log_0810">- No access to: [#!variable!host_name!#] found.</key>
<key name="log_0811">- The host: [#!variable!host_name!#] is not configured, skipping it.</key>
<key name="log_0812">The file: [#!variable!full_path!#] is in the database multiple times. This could be an artifact from peering Strikers. Selecting an entry to remove...</key>
<key name="log_0813">Deleting the 'files' database entry for the file uuid: [#!variable!file_uuid!#].</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>
@ -3154,6 +3159,8 @@ Proceed? [y/N]</key>
<key name="message_0348">Available Storage Groups;</key>
<key name="message_0349">- #!variable!storage_group_name!#, free space: #!variable!free_space!#, UUID: #!variable!storage_group_uuid!#</key>
<key name="message_0350">Preparing to managing storage for a server.</key>
<key name="message_0351">Running checks before processing power request...</key>
<key name="message_0352">The job to: [#!variable!task!#] this host has been picked up.</key>
<!-- Translate names (protocols, etc) -->
<key name="name_0001">Normal Password</key> <!-- none in mail-server -->

@ -64,7 +64,7 @@ pickup_job_details($anvil);
overwrite_variables_with_switches($anvil);
# Set maintenance mode
$anvil->System->maintenance_mode({set => 1});
$anvil->System->maintenance_mode({set => 1, debug => 2});
reconfigure_network($anvil);
@ -88,7 +88,7 @@ $anvil->Job->update_progress({
});
# Clear maintenance mode.
$anvil->System->maintenance_mode({set => 0});
$anvil->System->maintenance_mode({set => 0, debug => 2});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "log_0467"});
### TODO: As of now, the network doesn't come up reliably, so reboot. We add a 60 second delay to make it
@ -110,20 +110,21 @@ $anvil->nice_exit({exit_code => 0});
sub do_reboot
{
my ($anvil) = @_;
# Mark that a reboot is needed, in case something kills us before we actually reboot.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0687", variables => { reason => "#!string!log_0693!#" }});
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
file => $THIS_FILE,
line => __LINE__,
job_command => $anvil->data->{path}{exe}{'anvil-manage-power'}." --reboot -y".$anvil->Log->switches,
job_data => "",
job_name => "reboot::system",
job_title => "job_0009",
job_description => "job_0006",
job_progress => 0,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
### TODO: Nothing should be killing us, anything that could should be updated to hold while we run.
# # Mark that a reboot is needed, in case something kills us before we actually reboot.
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0687", variables => { reason => "#!string!log_0693!#" }});
# my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
# file => $THIS_FILE,
# line => __LINE__,
# job_command => $anvil->data->{path}{exe}{'anvil-manage-power'}." --reboot -y".$anvil->Log->switches,
# job_data => "",
# job_name => "reboot::system",
# job_title => "job_0009",
# job_description => "job_0006",
# job_progress => 0,
# });
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
my $time_left = 60;
while ($time_left)
@ -435,7 +436,7 @@ ORDER BY
}});
# An undefined interface will have the MAC address value set to '1', ignore those.
next if $variable_value == 1;
next if $variable_value eq "1";
if ($variable_name =~ /form::config_step2::(.*?)_mac_to_set::value/)
{
@ -1686,7 +1687,8 @@ AND
if (-e $anvil->data->{path}{exe}{pcs})
{
# To make logs more sensible, we'll call 'problem' as 'out_of_cluster'.
my ($out_of_cluster) = $anvil->Cluster->parse_cib();
$anvil->data->{cib}{parsed}{'local'}{ready} = "" if not defined $anvil->data->{cib}{parsed}{'local'}{ready};
my ($out_of_cluster) = $anvil->Cluster->parse_cib();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
out_of_cluster => $out_of_cluster,
"cib::parsed::local::ready" => $anvil->data->{cib}{parsed}{'local'}{ready},

@ -577,19 +577,19 @@ sub handle_periodic_tasks
check_db_in_use_states($anvil);
# Do Striker-specific minute tasks
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { host_type => $host_type }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
if ($host_type eq "striker")
{
# This can take a while, but it's been optimized to minimize how long it takes to
# run. To be safe, we'll still background it.
my $shell_call = $anvil->data->{path}{exe}{'striker-get-screenshots'}.$anvil->Log->switches;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { shell_call => $shell_call }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({
background => 1,
shell_call => $shell_call,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
@ -952,7 +952,7 @@ sub check_incoming
{
my ($anvil) = @_;
my $shell_call = $anvil->data->{path}{exe}{'anvil-manage-files'}." --check";
my $shell_call = $anvil->data->{path}{exe}{'anvil-manage-files'}." --check".$anvil->Log->switches;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({
shell_call => $shell_call,
@ -1452,7 +1452,7 @@ sub prep_database
{
$anvil->Database->configure_pgsql({debug => 2})
# ### NOTE: This failed once, in case / until it happens again, we'll force log level 2 and secure logging.
# my $shell_call = $anvil->data->{path}{exe}{'striker-prep-database'}." -vv --log-secure";
# my $shell_call = $anvil->data->{path}{exe}{'striker-prep-database'}$anvil->Log->switches;
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
# my ($database_output, $return_code) = $anvil->System->call({debug => 2, shell_call => $shell_call, source => $THIS_FILE, line => __LINE__ });
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {

@ -54,6 +54,9 @@ if (not $anvil->data->{sys}{database}{connections})
# Get the job details
load_job($anvil);
# Hold until both subnodes are marked as configured and not in maintenance mode.
wait_for_subnodes($anvil);
# Update the user passwords
update_passwords($anvil);
@ -182,10 +185,10 @@ sub configure_pacemaker
my $anvil_uuid = $anvil->data->{sys}{anvil_uuid};
my $host_name = $anvil->Get->host_name;
my $new_password = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_password};
my $node1_host_uuid = $anvil->data->{sys}{node1_host_uuid} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node1_host_name = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{host_name};
$node1_host_name =~ s/\..*$//;
my $node2_host_uuid = $anvil->data->{sys}{node2_host_uuid} = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
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};
$node2_host_name =~ s/\..*$//;
my $peer_host_name = $anvil->Get->host_uuid() eq $node1_host_uuid ? $node2_host_name : $node1_host_name;
@ -1558,6 +1561,17 @@ sub check_local_network
ntp => $ntp,
}});
if (not $dns)
{
$dns = "8.8.8.8,8.8.4.4";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { dns => $dns }});
}
if (not $mtu)
{
$mtu = "1500";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mtu => $mtu }});
}
### TODO: sorting the array seems inconsistent, so sorting in a hash
# The DNS are comma-separated lists, that may or may not have spaces and may or may not be in
# alphabetical order. To properly compare, we'll rebuild the CSV string of the current and desired
@ -2385,3 +2399,95 @@ sub update_progress
return(0);
}
sub wait_for_subnodes
{
my ($anvil) = @_;
my $anvil_uuid = $anvil->data->{sys}{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->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
anvil_uuid => $anvil_uuid,
node1_host_uuid => $node1_host_uuid,
node2_host_uuid => $node2_host_uuid,
}});
my $waiting = 1;
update_progress($anvil, $anvil->data->{job}{progress}, "job_0477");
while($waiting)
{
my $ready = 1;
foreach my $host_uuid ($node1_host_uuid, $node2_host_uuid)
{
my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
host_uuid => $host_uuid,
host_name => $host_name,
}});
my ($maintenance_mode, $variable_uuid, $modified_date) = $anvil->Database->read_variable({
variable_name => "maintenance_mode",
variable_source_table => "hosts",
variable_source_uuid => $host_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { maintenance_mode => $maintenance_mode }});
(my $configured, $variable_uuid, $modified_date) = $anvil->Database->read_variable({
variable_name => "system::configured",
variable_source_uuid => $host_uuid,
variable_source_table => "hosts",
});
$maintenance_mode = 1 if not defined $maintenance_mode;
$configured = 0 if not defined $configured;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { configured => $configured }});
# Is anvil-configure-host running?
my $job_running = 0;
$anvil->Database->get_jobs({job_host_uuid => $host_uuid});
foreach my $job_uuid (sort {$a cmp $b} keys %{$anvil->data->{jobs}{running}})
{
my $job_command = $anvil->data->{jobs}{running}{$job_uuid}{job_command};
my $job_data = $anvil->data->{jobs}{running}{$job_uuid}{job_data};
my $job_progress = $anvil->data->{jobs}{running}{$job_uuid}{job_progress};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:job_uuid' => $job_uuid,
's2:job_command' => $job_command,
's3:job_data' => $job_data,
's4:job_progress' => $job_progress,
}});
next if $job_progress == 100;
if ($job_command =~ /anvil-configure-host/)
{
$job_running = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_running => $job_running }});
}
}
if (($maintenance_mode) or ($job_running) or (not $configured))
{
$ready = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ready => $ready }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0475", variables => {
subnode => $host_name,
configured => $configured,
maintenance_mode => $maintenance_mode,
job_running => $job_running,
}});
}
}
if ($ready)
{
$waiting = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0476"});
sleep 5;
}
}
return(0);
}

@ -53,8 +53,12 @@ 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
@ -1127,6 +1131,7 @@ AND
{
# Yup.
($file_uuid) = $anvil->Database->insert_or_update_files({
debug => 2,
file_uuid => $file_uuid,
file_name => $file_name,
file_directory => $file_directory,

@ -40,7 +40,9 @@ $anvil->Get->switches({list => [
"power-off",
"poweroff",
"reboot",
"reboot-needed"], man => $THIS_FILE});
"reboot-needed",
"y",
"yes"], man => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => $anvil->data->{switches}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
@ -65,7 +67,19 @@ if (not $anvil->data->{sys}{database}{connections})
}
# Clear the job in case a previous call failed.
$anvil->Job->clear({debug => 2, job_uuid => $anvil->data->{switches}{'job-uuid'}}) if $anvil->data->{switches}{'job-uuid'};
if ($anvil->data->{switches}{'job-uuid'})
{
$anvil->Job->clear({debug => 2, job_uuid => $anvil->data->{switches}{'job-uuid'}});
my $task = $anvil->data->{switches}{'reboot'} ? "log_0226" : "log_0225";
$anvil->Job->update_progress({
debug => 2,
progress => 1,
message => "message_0352",
job_uuid => $anvil->data->{switches}{'job-uuid'},
log_level => 1,
variables => { task => $task },
});
}
# Are we being asked to reboot or power off?
if ($anvil->data->{switches}{'reboot'})
@ -186,6 +200,17 @@ sub do_poweroff
my ($anvil, $task) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { task => $task }});
if ($anvil->data->{switches}{'job-uuid'})
{
$anvil->Job->update_progress({
debug => 2,
progress => 10,
message => "message_0351",
log_level => 1,
job_uuid => $anvil->data->{switches}{'job-uuid'},
});
}
# In case we're being called by another job, we'll sleep for a few second to let those close out.
sleep 3;
@ -202,10 +227,11 @@ sub do_poweroff
# To minimize the trouble of a problem where the reboot needed flag isn't cleared, and so the system
# wants to repeatedly reboot, we need to add a delay to not let anvil-daemon ask us to
# reboot/power-off until the system uptime is more than ten minutes.
# reboot/power-off until the system uptime is more than five minutes.
if (($uptime) && ($uptime < 300))
{
# We'll wait until the system has been running for ten minutes.
# We'll wait until the system has been running for five minutes.
my $difference = 300 - $uptime;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0224", variables => {
task => $task eq "poweroff" ? "#!string!log_0225!#" : "#!string!log_0226!#",
@ -285,10 +311,11 @@ sub do_poweroff
if ($job_uuid)
{
$anvil->Job->update_progress({
debug => 2,
progress => 100,
message => $say_task,
job_uuid => $job_uuid,
debug => 2,
progress => 100,
message => $say_task,
log_level => 1,
job_uuid => $job_uuid,
});
}

@ -587,7 +587,6 @@ sub provision_server
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
### TODO: Left off here
# Wait until file(s) are ready.
my $waiting = 1;
my $host_uuid = $anvil->Get->host_uuid();
@ -598,9 +597,8 @@ sub provision_server
}
while ($waiting)
{
# This loads files and file locations.
$anvil->Storage->check_files({debug => 2});
$anvil->Database->get_files({debug => 2});
$anvil->Database->get_file_locations({debug => 2});
$waiting = 0;
foreach my $file_path (sort {$a cmp $b} @files)
{
@ -609,14 +607,16 @@ sub provision_server
$anvil->data->{file_uuid}{$file_path} = "" if not exists $anvil->data->{uuid}{$file_path}{file_uuid};
# What's this file's file_uuid?
my $file_uuid = $anvil->data->{file_uuid}{$file_path};
my $file_uuid = $anvil->data->{file_uuid}{$file_path};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_uuid => $file_uuid }});
my $file_location_uuid = "";
if (not $file_uuid)
{
foreach my $this_file_uuid (sort {$a cmp $b} keys %{$anvil->data->{files}{file_uuid}})
{
my $this_file_path = $anvil->data->{files}{file_uuid}{$this_file_uuid}{file_directory}."/".$anvil->data->{files}{file_uuid}{$this_file_uuid}{file_name};
$this_file_path =~ s/\/\//\//g;
$this_file_path =~ s/\/\//\//g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
this_file_uuid => $this_file_uuid,
this_file_path => $this_file_path,
@ -626,6 +626,7 @@ sub provision_server
# Found it.
$file_uuid = $this_file_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_uuid => $file_uuid }});
last;
}
}
}
@ -644,6 +645,9 @@ sub provision_server
}
# Yes, now do we have the file_location_uuid?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"file_locations::host_uuid::${host_uuid}::file_uuid::${file_uuid}" => exists $anvil->data->{file_locations}{host_uuid}{$host_uuid}{file_uuid}{$file_uuid} ? 1 : 0,
}});
if (not exists $anvil->data->{file_locations}{host_uuid}{$host_uuid}{file_uuid}{$file_uuid})
{
# Nope
@ -653,6 +657,32 @@ sub provision_server
file_path => $file_path,
server_name => $server,
}});
# This is being hit improperly somehow. Added logging to help diagnose.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:Get->host_uuid' => $anvil->Get->host_uuid,
's2:host_uuid' => $host_uuid,
's3:file_uuid' => $file_uuid,
}});
foreach my $this_host_uuid (sort {$a cmp $b} keys %{$anvil->data->{file_locations}{host_uuid}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:this_host_uuid' => $this_host_uuid,
's2:this_host_name' => $anvil->Get->host_name_from_uuid({host_uuid => $this_host_uuid}),
}});
foreach my $this_file_uuid (sort {$a cmp $b} keys %{$anvil->data->{file_locations}{host_uuid}{$this_host_uuid}{file_uuid}})
{
my $this_file_location_uuid = $anvil->data->{file_locations}{host_uuid}{$this_host_uuid}{file_uuid}{$this_file_uuid}{file_location_uuid};
my $this_anvil_uuid = $anvil->data->{file_locations}{file_location_uuid}{$this_file_location_uuid}{file_location_anvil_uuid};
my $this_file_name = $anvil->data->{anvils}{anvil_uuid}{$this_anvil_uuid}{file_uuid}{$this_file_uuid}{file_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:this_file_uuid' => $this_file_uuid,
's2:this_file_location_uuid' => $this_file_location_uuid,
's3:this_anvil_uuid' => $this_anvil_uuid,
's4:this_file_name' => $this_file_name,
}});
}
}
next;
}

@ -34,6 +34,11 @@ my $anvil = Anvil::Tools->new();
# Read switches (target ([user@]host[:port]) and the file with the target's password.
$anvil->data->{switches}{'job-uuid'} = "";
$anvil->Get->switches;
### TODO: Remove this
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
# Connect to the database(s).

@ -104,7 +104,7 @@ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list
print "Done!\n";
print "\n[ Complete ] - The debug data is here: [".$tarball."]\n";
print "[ Warning ] - The collected logs likely include sensitive information! Share is carefully!\n";
print "[ Warning ] - The collected logs likely include sensitive information! Share it carefully!\n";
@ -662,6 +662,35 @@ sub collect_local_data
$anvil->nice_exit({exit_code => 1});
}
print "Done!\n";
# Grab screenshots.
print "- Collecting server screenshots... ";
if (-d $anvil->data->{path}{directories}{screenshots})
{
$shell_call = $anvil->data->{path}{exe}{tar}." -cvjf ".$target_directory."/server-screenshots.bz2 ".$anvil->data->{path}{directories}{screenshots};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($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,
}});
if ($return_code)
{
# Failed
print "Failed!\n";
print "Expected the return code '0', but got: [".$return_code."]. The error, if any, was:\n";
print "========\n";
print $output."\n";
print "========\n";
$anvil->nice_exit({exit_code => 1});
}
print "Done!\n";
}
else
{
print "Failed!\nScreenshot directory: [".$anvil->data->{path}{directories}{screenshots}."] doesn't exist, skipping.\n";
}
}
print "- Grabbing hosts file... ";

Loading…
Cancel
Save