* Updated Storage->backup to append a short UUID to the timestamp to prevent issues if the same file is backed up twice in the same clock second. Also fixed a bug with remote_user parameter not having a default.

* Finished the detection of and handling of initialization of a host when the host has no Internet access.
* Disabled (for now) anvil-daemon's check_ssh_keys function.
* Fixed a couple small bugs elsewhere.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent 65a27ba2f8
commit 183d2d9cce
  1. 9
      Anvil/Tools/Storage.pm
  2. 19
      Anvil/Tools/Striker.pm
  3. 24
      cgi-bin/striker
  4. 2
      html/skins/alteeve/anvil.html
  5. 6
      share/words.xml
  6. 21
      tools/anvil-daemon
  7. 3
      tools/striker-initialize-host
  8. 4
      tools/striker-manage-install-target

@ -144,7 +144,7 @@ sub backup
my $fatal = defined $parameter->{fatal} ? $parameter->{fatal} : 1; my $fatal = defined $parameter->{fatal} ? $parameter->{fatal} : 1;
my $port = defined $parameter->{port} ? $parameter->{port} : ""; my $port = defined $parameter->{port} ? $parameter->{port} : "";
my $password = defined $parameter->{password} ? $parameter->{password} : ""; my $password = defined $parameter->{password} ? $parameter->{password} : "";
my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : ""; my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root";
my $target = defined $parameter->{target} ? $parameter->{target} : ""; my $target = defined $parameter->{target} ? $parameter->{target} : "";
my $source_file = defined $parameter->{file} ? $parameter->{file} : ""; my $source_file = defined $parameter->{file} ? $parameter->{file} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
@ -240,7 +240,10 @@ fi";
target => $target, target => $target,
source_file => $source_file, source_file => $source_file,
}}); }});
if ($fatal) { $anvil->nice_exit({code => 1}); } if ($fatal)
{
$anvil->nice_exit({code => 1});
}
} }
} }
else else
@ -277,7 +280,7 @@ fi";
my ($directory, $file) = ($source_file =~ /^(\/.*)\/(.*)$/); my ($directory, $file) = ($source_file =~ /^(\/.*)\/(.*)$/);
my $timestamp = $anvil->Get->date_and_time({file_name => 1}); my $timestamp = $anvil->Get->date_and_time({file_name => 1});
my $backup_directory = $anvil->data->{path}{directories}{backups}.$directory; my $backup_directory = $anvil->data->{path}{directories}{backups}.$directory;
my $backup_target = $file.".".$timestamp; my $backup_target = $file.".".$timestamp.".".$anvil->Get->uuid({short => 1});
$target_file = $backup_directory."/".$backup_target; $target_file = $backup_directory."/".$backup_target;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
directory => $directory, directory => $directory,

@ -169,9 +169,15 @@ skip_if_unavailable=1";
=head2 get_peer_data =head2 get_peer_data
This calls the C<< call_striker-get-peer-data >> program to try to connect to the target (as C<< root >>). If successful, it will return the target's host UUID (either by reading C<< /etc/anvil/host.uuid >> if it exists, or using C<< dmidecode >> if not). This calls the C<< call_striker-get-peer-data >> program to try to connect to the target (as C<< root >>). This method returns a string variable and a hash reference. The string variable will be C<< 1 >> if we connected successfully, C<< 0 >> if not. The hash reference will contain parsed details about the peer, assuming it connected. If the connection failed, the hash reference will exist but the values will be empty.
This method will return a string variable with C<< 1 >> if the peer was reached, or C<< 0 >> if it was not. It will also return a hash reference containing the collected data. Keys in the hash;
* C<< host_uuid >> - The host's UUID.
* C<< host_name >> - The host's current (static) host name.
* C<< host_os >> - This is the host's operating system and version. The OS is returned as C<< rhel >> or C<< centos >>. The version is returned as C<< 8.x >>.
* C<< internet >> - This indicates if the target was found to have a a working Internet connection.
* C<< os_registered >> - This indicates if the OS is registered with Red Hat (if the OS is C<< rhel >>). It will be C<< yes >>, C<< no >> or C<< unknown >>.
my ($connected, $data) = $anvil->Striker->get_peer_data({target => 10.255.1.218, password => "Initial1"}); my ($connected, $data) = $anvil->Striker->get_peer_data({target => 10.255.1.218, password => "Initial1"});
if ($connected) if ($connected)
@ -217,6 +223,7 @@ sub get_peer_data
host_uuid => "", host_uuid => "",
host_name => "", host_name => "",
host_os => "", host_os => "",
internet => 0,
os_registered => "", os_registered => "",
}; };
@ -227,6 +234,7 @@ sub get_peer_data
return($connected, $data); return($connected, $data);
} }
# Record the password in the database so that we don't pass it over the command line.
my $state_uuid = $anvil->Database->insert_or_update_states({ my $state_uuid = $anvil->Database->insert_or_update_states({
debug => $debug, debug => $debug,
file => $THIS_FILE, file => $THIS_FILE,
@ -276,12 +284,18 @@ sub get_peer_data
$data->{os_registered} = $1; $data->{os_registered} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'data->{os_registered}' => $data->{os_registered} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'data->{os_registered}' => $data->{os_registered} }});
} }
if ($line =~ /internet=(.*)$/)
{
$data->{internet} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'data->{internet}' => $data->{internet} }});
}
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
connected => $connected, connected => $connected,
'data->{host_name}' => $data->{host_name}, 'data->{host_name}' => $data->{host_name},
'data->{host_uuid}' => $data->{host_uuid}, 'data->{host_uuid}' => $data->{host_uuid},
'data->{host_os}' => $data->{host_os}, 'data->{host_os}' => $data->{host_os},
'data->{internet}' => $data->{internet},
'data->{os_registered}' => $data->{os_registered}, 'data->{os_registered}' => $data->{os_registered},
}}); }});
@ -289,6 +303,7 @@ sub get_peer_data
my $query = "DELETE FROM states WHERE state_name = ".$anvil->Database->quote("peer::".$target."::password").";"; my $query = "DELETE FROM states WHERE state_name = ".$anvil->Database->quote("peer::".$target."::password").";";
$anvil->Database->write({uuid => $anvil->data->{sys}{host_uuid}, debug => 3, query => $query, source => $THIS_FILE, line => __LINE__}); $anvil->Database->write({uuid => $anvil->data->{sys}{host_uuid}, debug => 3, query => $query, source => $THIS_FILE, line => __LINE__});
# Verify that the host UUID is actually valid.
if (not $anvil->Validate->is_uuid({uuid => $data->{host_uuid}})) if (not $anvil->Validate->is_uuid({uuid => $data->{host_uuid}}))
{ {
$data->{host_uuid} = ""; $data->{host_uuid} = "";

@ -820,8 +820,9 @@ sub process_prep_host_page
# Can we connect? # Can we connect?
my $target_host_name = ""; my $target_host_name = "";
my $target_host_uuid = ""; my $target_host_uuid = "";
my $has_internet = 0;
my ($connected, $data) = $anvil->Striker->get_peer_data({ my ($connected, $data) = $anvil->Striker->get_peer_data({
debug => 3, debug => 2,
target => $host_ip_address, target => $host_ip_address,
password => $host_password, password => $host_password,
port => $ssh_port, port => $ssh_port,
@ -841,6 +842,11 @@ sub process_prep_host_page
$target_host_uuid = $data->{host_uuid}; $target_host_uuid = $data->{host_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target_host_uuid => $target_host_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { target_host_uuid => $target_host_uuid }});
} }
if ($data->{internet})
{
$has_internet = $data->{internet};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { has_internet => $has_internet }});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
target_host_name => $target_host_name, target_host_name => $target_host_name,
target_host_uuid => $target_host_uuid, target_host_uuid => $target_host_uuid,
@ -851,7 +857,10 @@ sub process_prep_host_page
my $redhat_form = ""; my $redhat_form = "";
if (($data->{host_os} =~ /^rhel/) && ($data->{os_registered} ne "yes")) if (($data->{host_os} =~ /^rhel/) && ($data->{os_registered} ne "yes"))
{ {
$redhat_message = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-message"}); # If we don't have internet access, tell the user they can register later.
if ($has_internet)
{
$redhat_message = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-message", variables => { message => "#!string!message_0148!#" }});
$redhat_form = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-form", variables => { $redhat_form = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-form", variables => {
rh_user => $rh_user, rh_user => $rh_user,
rh_password => $rh_password, rh_password => $rh_password,
@ -861,6 +870,17 @@ sub process_prep_host_page
redhat_message => $redhat_message, redhat_message => $redhat_message,
}}); }});
} }
else
{
$redhat_message = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-message", variables => { message => "#!string!message_0151!#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { redhat_message => $redhat_message }});
}
}
elsif (not $has_internet)
{
$redhat_message = $anvil->Template->get({file => "anvil.html", name => "host-setup-redhat-message", variables => { message => "#!string!message_01512#" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { redhat_message => $redhat_message }});
}
# Did we connect? # Did we connect?
if (not $connected) if (not $connected)

@ -230,7 +230,7 @@
<!-- start host-setup-redhat-message --> <!-- start host-setup-redhat-message -->
<tr> <tr>
<td class="menu_details"> <td class="menu_details">
#!string!message_0148!# #!variable!message!#
</td> </td>
</tr> </tr>
<tr> <tr>

@ -255,6 +255,8 @@ About to try to download aproximately: [#!variable!packages!#] packages needed t
<key name="message_0148"><![CDATA[This is a RHEL host and has not yet been subscribed. You can enter your Red Hat subscription credentials below. If the host has internet access, the host will be subscribed during setup.]]></key> <key name="message_0148"><![CDATA[This is a RHEL host and has not yet been subscribed. You can enter your Red Hat subscription credentials below. If the host has internet access, the host will be subscribed during setup.]]></key>
<key name="message_0149">The target's host key has changed. If the target has been rebuilt, or the target IP reused, the old key will need to be removed. If this is the case, remove line: [#!variable!line!#] from: [#!variable!file!#].</key> <key name="message_0149">The target's host key has changed. If the target has been rebuilt, or the target IP reused, the old key will need to be removed. If this is the case, remove line: [#!variable!line!#] from: [#!variable!file!#].</key>
<key name="message_0150">Set the new host name.</key> <key name="message_0150">Set the new host name.</key>
<key name="message_0151">This is a RHEL host and has not yet been subscribed, but there is no internet access detected. OS Updates likely won't work, nor will subscribing the system. These tasks will be deferred until later in the setup process.</key>
<key name="message_0152">There is no internet access detected. OS Updates likely won't work and will be deferred until later in the setup process.</key>
<!-- Log entries --> <!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key> <key name="log_0001">Starting: [#!variable!program!#].</key>
@ -533,8 +535,8 @@ The body of the file: [#!variable!file!#] does not match the new body. The file
<key name="log_0236">Skipping the RPM repository refresh. The next scheduled refresh will be done in: [#!variable!next_refresh!#] second(s). Override with '--force'.</key> <key name="log_0236">Skipping the RPM repository refresh. The next scheduled refresh will be done in: [#!variable!next_refresh!#] second(s). Override with '--force'.</key>
<key name="log_0237">RPM repository refresh required, [#!data!path::directories::packages!#] doesn't exist (likely this is the first run or the directory was deleted).</key> <key name="log_0237">RPM repository refresh required, [#!data!path::directories::packages!#] doesn't exist (likely this is the first run or the directory was deleted).</key>
<key name="log_0238">RPM repository refresh required, it has been more than: [#!variable!seconds!#] seconds since the last refresh (or no previous refresh was logged).</key> <key name="log_0238">RPM repository refresh required, it has been more than: [#!variable!seconds!#] seconds since the last refresh (or no previous refresh was logged).</key>
<key name="log_0239">'Install Target' job: [#!data!switches::job-uuid!#] picked up.</key> <key name="log_0239">'Install Target' job: [#!variable!job-uuid!#] picked up.</key>
<key name="log_0240">'Install Target' job: [#!data!switches::job-uuid!#] aborted, system not yet configured.</key> <key name="log_0240">'Install Target' job: [#!variable!job-uuid!#] aborted, system not yet configured.</key>
<key name="log_0241">Package list loaded.</key> <key name="log_0241">Package list loaded.</key>
<key name="log_0242">It looks like a user tried to upload a file without actually doing so.</key> <key name="log_0242">It looks like a user tried to upload a file without actually doing so.</key>
<key name="log_0243">[ Error ] - Failed to delete the file: [#!variable!file!#].</key> <key name="log_0243">[ Error ] - Failed to delete the file: [#!variable!file!#].</key>

@ -321,6 +321,10 @@ sub check_ssh_keys
{ {
my ($anvil) = @_; my ($anvil) = @_;
### TODO: When a node is rebuilt, this causes the old keys to be reloaded between when we delete the entries. We need to delete the keys for the target IP from the 'ip_addresses' table.
return(0);
# Get a list of machine host keys and user public keys from other machines. # Get a list of machine host keys and user public keys from other machines.
get_other_keys($anvil); get_other_keys($anvil);
@ -345,6 +349,7 @@ sub check_ssh_keys
# Create it. # Create it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0272", variables => { user => $user, directory => $ssh_directory }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0272", variables => { user => $user, directory => $ssh_directory }});
$anvil->Storage->make_directory({ $anvil->Storage->make_directory({
debug => 2,
directory => $ssh_directory, directory => $ssh_directory,
user => $user, user => $user,
group => $user, group => $user,
@ -383,7 +388,10 @@ sub check_ssh_keys
} }
# Now read in the key. # Now read in the key.
my $users_public_key = $anvil->Storage->read_file({file => $ssh_public_key_file}); my $users_public_key = $anvil->Storage->read_file({
debug => 2,
file => $ssh_public_key_file,
});
$users_public_key =~ s/\n$//; $users_public_key =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { users_public_key => $users_public_key }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { users_public_key => $users_public_key }});
@ -404,7 +412,10 @@ sub check_ssh_keys
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { known_hosts_file => $known_hosts_file }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { known_hosts_file => $known_hosts_file }});
if (-e $known_hosts_file) if (-e $known_hosts_file)
{ {
$known_hosts_file_body = $anvil->Storage->read_file({file => $known_hosts_file}); $known_hosts_file_body = $anvil->Storage->read_file({
debug => 2,
file => $known_hosts_file,
});
$known_hosts_old_body = $known_hosts_file_body; $known_hosts_old_body = $known_hosts_file_body;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { known_hosts_file_body => $known_hosts_file_body }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { known_hosts_file_body => $known_hosts_file_body }});
} }
@ -417,7 +428,10 @@ sub check_ssh_keys
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { authorized_keys_file => $authorized_keys_file }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { authorized_keys_file => $authorized_keys_file }});
if (-e $authorized_keys_file) if (-e $authorized_keys_file)
{ {
$authorized_keys_file_body = $anvil->Storage->read_file({file => $authorized_keys_file}); $authorized_keys_file_body = $anvil->Storage->read_file({
debug => 2,
file => $authorized_keys_file,
});
$authorized_keys_old_body = $authorized_keys_file_body; $authorized_keys_old_body = $authorized_keys_file_body;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { authorized_keys_file_body => $authorized_keys_file_body }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { authorized_keys_file_body => $authorized_keys_file_body }});
} }
@ -1296,6 +1310,7 @@ sub run_jobs
file => $output_json, file => $output_json,
body => $jobs_file, body => $jobs_file,
overwrite => 1, overwrite => 1,
backup => 0,
mode => "0644", mode => "0644",
user => "apache", user => "apache",
group => "apache" group => "apache"

@ -450,6 +450,9 @@ EOF
} }
} }
### NOTE: This seems dumb without internet, but it's worth calling anyway in case the repo on the
### Striker has newer packages. If we go right to installing packages and one of them is newer
### than an installed dependency, the install could fail. This prevents that.
# Call an OS update. # Call an OS update.
$anvil->data->{job}{progress} += 5; $anvil->data->{job}{progress} += 5;
update_progress($anvil, $anvil->data->{job}{progress}, "job_0039"); update_progress($anvil, $anvil->data->{job}{progress}, "job_0039");

@ -183,7 +183,7 @@ if (not $configured)
print $anvil->Words->string({key => "error_0046"})."\n"; print $anvil->Words->string({key => "error_0046"})."\n";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, secure => 0, key => "error_0046"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, secure => 0, key => "error_0046"});
update_progress($anvil, 100, "log_0240"); update_progress($anvil, 100, "log_0240,!!job-uuid!".$anvil->data->{switches}{'job-uuid'}."!!");
$anvil->nice_exit({exit_code => 9}); $anvil->nice_exit({exit_code => 9});
} }
@ -763,7 +763,7 @@ sub setup_boot_environment
# Something went wrong. # Something went wrong.
print $anvil->Words->string({key => "log_0233", variables => { file => $anvil->data->{path}{configs}{'dnf.conf'}, 'return' => $return }})."\n"; print $anvil->Words->string({key => "log_0233", variables => { file => $anvil->data->{path}{configs}{'dnf.conf'}, 'return' => $return }})."\n";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0233", variables => { file => $anvil->data->{path}{configs}{'dnf.conf'}, 'return' => $return }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0233", variables => { file => $anvil->data->{path}{configs}{'dnf.conf'}, 'return' => $return }});
update_progress($anvil, 100, "log_0023,!!file!".$anvil->data->{path}{configs}{'dnf.conf'}."!!,!!refresh!return!".$return."!!"); update_progress($anvil, 100, "log_0233,!!file!".$anvil->data->{path}{configs}{'dnf.conf'}."!!,!!return!".$return."!!");
$anvil->nice_exit({code => 3}); $anvil->nice_exit({code => 3});
} }
print $anvil->Words->string({key => "message_0097", variables => { file => $anvil->data->{path}{configs}{'dnf.conf'} }})."\n"; print $anvil->Words->string({key => "message_0097", variables => { file => $anvil->data->{path}{configs}{'dnf.conf'} }})."\n";

Loading…
Cancel
Save