* Made a fair bit more progress on tools/striker-manage-install-target. It now registers a system with Red Hat and attaches appropriate subscriptions, updates the OS and (tries) to install anvil-{node,dr}.

* Fixed a bug in Remote->call where a shell call that ended in a newline would work, but throw an error and not get the return code.
* Created Database->get_job_details() which takes a job_uuid and returns the job details, if found.
* Fixed a bug in Jobs->update_progress() where 'clear' wasn't removing the old job_progress data.
* Added the parameters 'no_files' to skip stat'ing/recording non-directories, and 'search_for' which will set the parent directory in 'scan::searched' and stop scanning if found. This allows this method to act as a directory tree scanner and as a search engine.
* Created Striker->get_local_repo() that builds a repo file body suitable for adding to peers, nodes and DR hosts.
* Fixed bugs in the Striker WebUI related to initializing a target node / DR host.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent badaa39b7a
commit a54e0d4e22
  1. 2
      Anvil/Tools.pm
  2. 144
      Anvil/Tools/Database.pm
  3. 18
      Anvil/Tools/Job.pm
  4. 12
      Anvil/Tools/Remote.pm
  5. 48
      Anvil/Tools/Storage.pm
  6. 114
      Anvil/Tools/Striker.pm
  7. 17
      cgi-bin/striker
  8. 22
      html/skins/alteeve/anvil.html
  9. 17
      notes
  10. 33
      share/words.xml
  11. 515
      tools/striker-initialize-host
  12. 4
      tools/striker-manage-install-target

@ -983,6 +983,7 @@ sub _set_paths
}, },
data => { data => {
group => "/etc/group", group => "/etc/group",
httpd_conf => "/etc/httpd/conf/httpd.conf",
host_ssh_key => "/etc/ssh/ssh_host_ecdsa_key.pub", host_ssh_key => "/etc/ssh/ssh_host_ecdsa_key.pub",
'.htpasswd' => "/etc/httpd/.htpasswd", '.htpasswd' => "/etc/httpd/.htpasswd",
host_uuid => "/etc/anvil/host.uuid", host_uuid => "/etc/anvil/host.uuid",
@ -1088,6 +1089,7 @@ sub _set_paths
stonith_admin => "/usr/sbin/stonith_admin", stonith_admin => "/usr/sbin/stonith_admin",
strings => "/usr/bin/strings", strings => "/usr/bin/strings",
'striker-get-peer-data' => "/usr/sbin/striker-get-peer-data", 'striker-get-peer-data' => "/usr/sbin/striker-get-peer-data",
'striker-initialize-host' => "/usr/sbin/striker-initialize-host",
'striker-manage-install-target' => "/usr/sbin/striker-manage-install-target", 'striker-manage-install-target' => "/usr/sbin/striker-manage-install-target",
'striker-manage-peers' => "/usr/sbin/striker-manage-peers", 'striker-manage-peers' => "/usr/sbin/striker-manage-peers",
'striker-prep-database' => "/usr/sbin/striker-prep-database", 'striker-prep-database' => "/usr/sbin/striker-prep-database",

@ -22,6 +22,7 @@ my $THIS_FILE = "Database.pm";
# disconnect # disconnect
# get_alert_recipients # get_alert_recipients
# get_hosts # get_hosts
# get_job_details
# get_jobs # get_jobs
# get_local_uuid # get_local_uuid
# initialize # initialize
@ -1374,6 +1375,123 @@ FROM
return($return); return($return);
} }
=head2 get_job_details
This gets the details for a given job. If the job is found, a hash reference is returned containing the tables that were read in.
Parameters;
=head3 job_uuid (default switches::job-uuid)
This is the C<< job_uuid >> of the job being retrieved.
=cut
sub get_job_details
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
my $return = "";
my $job_uuid = defined $parameter->{job_uuid} ? $parameter->{job_uuid} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
job_uuid => $job_uuid,
}});
# If we didn't get a job_uuid, see if 'swtiches::job-uuid' is set.
if ((not $job_uuid) && ($anvil->data->{switches}{'job-uuid'}))
{
$job_uuid = $anvil->data->{switches}{'job-uuid'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { job_uuid => $job_uuid }});
}
if (not $job_uuid)
{
# Throw an error and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->get_job_details()", parameter => "get_jobs" }});
return($return);
}
my $query = "
SELECT
job_host_uuid,
job_command,
job_data,
job_picked_up_by,
job_picked_up_at,
job_updated,
job_name,
job_progress,
job_title,
job_description,
job_status,
modified_date
FROM
jobs
WHERE
job_uuid = ".$anvil->Database->quote($job_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
results => $results,
count => $count,
}});
if (not $count)
{
# Job wasn't found.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0438", variables => { job_uuid => $job_uuid }});
return($return);
}
my $job_host_uuid = $results->[0]->[0];
my $job_command = $results->[0]->[1];
my $job_data = defined $results->[0]->[2] ? $results->[0]->[2] : "";
my $job_picked_up_by = $results->[0]->[3];
my $job_picked_up_at = $results->[0]->[4];
my $job_updated = $results->[0]->[5];
my $job_name = $results->[0]->[6];
my $job_progress = $results->[0]->[7];
my $job_title = $results->[0]->[8];
my $job_description = $results->[0]->[9];
my $job_status = $results->[0]->[10];
my $modified_date = $results->[0]->[11];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
job_host_uuid => $job_host_uuid,
job_command => $job_command,
job_data => $job_data,
job_picked_up_by => $job_picked_up_by,
job_picked_up_at => $job_picked_up_at,
job_updated => $job_updated,
job_name => $job_name,
job_progress => $job_progress,
job_title => $job_title,
job_description => $job_description,
job_status => $job_status,
modified_date => $modified_date,
}});
$return = {
job_host_uuid => $job_host_uuid,
job_command => $job_command,
job_data => $job_data,
job_picked_up_by => $job_picked_up_by,
job_picked_up_at => $job_picked_up_at,
job_updated => $job_updated,
job_name => $job_name,
job_progress => $job_progress,
job_title => $job_title,
job_description => $job_description,
job_status => $job_status,
modified_date => $modified_date,
};
return($return);
}
=head2 get_jobs =head2 get_jobs
This gets the list of running jobs. This gets the list of running jobs.
@ -1491,6 +1609,28 @@ WHERE
my $return_count = @{$return}; my $return_count = @{$return};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { return_count => $return_count }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { return_count => $return_count }});
if ($return_count)
{
foreach my $hash_ref (@{$return})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
job_uuid => $hash_ref->{job_uuid},
job_command => $hash_ref->{job_command},
job_data => $hash_ref->{job_data},
job_picked_up_by => $hash_ref->{job_picked_up_by},
job_picked_up_at => $hash_ref->{job_picked_up_at},
job_updated => $hash_ref->{job_updated},
job_name => $hash_ref->{job_name},
job_progress => $hash_ref->{job_progress},
job_title => $hash_ref->{job_title},
job_description => $hash_ref->{job_description},
job_status => $hash_ref->{job_status},
modified_date => $hash_ref->{modified_date},
}});
}
}
return($return); return($return);
} }
@ -3458,6 +3598,7 @@ sub insert_or_update_jobs
my $job_description = defined $parameter->{job_description} ? $parameter->{job_description} : ""; my $job_description = defined $parameter->{job_description} ? $parameter->{job_description} : "";
my $job_status = defined $parameter->{job_status} ? $parameter->{job_status} : ""; my $job_status = defined $parameter->{job_status} ? $parameter->{job_status} : "";
my $update_progress_only = defined $parameter->{update_progress_only} ? $parameter->{update_progress_only} : 0; my $update_progress_only = defined $parameter->{update_progress_only} ? $parameter->{update_progress_only} : 0;
my $clear_status = defined $parameter->{clear_status} ? $parameter->{clear_status} : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
uuid => $uuid, uuid => $uuid,
file => $file, file => $file,
@ -3475,6 +3616,7 @@ sub insert_or_update_jobs
job_description => $job_description, job_description => $job_description,
job_status => $job_status, job_status => $job_status,
update_progress_only => $update_progress_only, update_progress_only => $update_progress_only,
clear_status => $clear_status,
}}); }});
# If I have a job_uuid and update_progress_only is true, I only need the progress. # If I have a job_uuid and update_progress_only is true, I only need the progress.
@ -3721,7 +3863,7 @@ SET ";
query => $query, query => $query,
}}); }});
} }
if (($job_status ne "") && ($old_job_status ne $job_status)) if (($clear_status) or (($job_status ne "") && ($old_job_status ne $job_status)))
{ {
$update = 1; $update = 1;
$query .= " $query .= "

@ -504,12 +504,12 @@ sub update_progress
my $picked_up_by = defined $parameter->{picked_up_by} ? $parameter->{picked_up_by} : ""; my $picked_up_by = defined $parameter->{picked_up_by} ? $parameter->{picked_up_by} : "";
my $progress = defined $parameter->{progress} ? $parameter->{progress} : ""; my $progress = defined $parameter->{progress} ? $parameter->{progress} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
picked_up_by => $picked_up_by, picked_up_by => $picked_up_by,
progress => $progress, progress => $progress,
message => $message, message => $message,
job_uuid => $job_uuid, job_uuid => $job_uuid,
"jobs::job_uuid" => $anvil->data->{jobs}{job_uuid},
}}); }});
if ($picked_up_by eq "") if ($picked_up_by eq "")
{ {
$picked_up_by = $$; $picked_up_by = $$;
@ -556,11 +556,16 @@ sub update_progress
# Get the current job_status and append this new one. # Get the current job_status and append this new one.
my $job_picked_up_at = 0; my $job_picked_up_at = 0;
my $job_status = ""; my $job_status = "";
my $clear_status = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { message => $message, picked_up_by => $picked_up_by }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { message => $message, picked_up_by => $picked_up_by }});
if ($message eq "clear") if ($message eq "clear")
{ {
$picked_up_by = 0; $picked_up_by = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { picked_up_by => $picked_up_by }}); $clear_status = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
picked_up_by => $picked_up_by,
clear_status => $clear_status,
}});
} }
else else
{ {
@ -669,6 +674,7 @@ WHERE
line => __LINE__, line => __LINE__,
debug => $debug, debug => $debug,
update_progress_only => 1, update_progress_only => 1,
clear_status => $clear_status,
job_uuid => $job_uuid, job_uuid => $job_uuid,
job_picked_up_by => $picked_up_by, job_picked_up_by => $picked_up_by,
job_picked_up_at => $job_picked_up_at, job_picked_up_at => $job_picked_up_at,

@ -260,7 +260,7 @@ B<NOTE>: If the C<< target >> is presented in the format C<< target:port >>, the
=head3 timeout (optional, default '10') =head3 timeout (optional, default '10')
B<NOTE>: This is the timeout for the command to return. This is NOT the connection timeout! B<NOTE>: This is the timeout for the command to return, in seconds. This is NOT the connection timeout!
If this is set to a numeric whole number, then the called shell command will have the set number of seconds to complete. If this is set to C<< 0 >>, then no timeout will be used. If this is set to a numeric whole number, then the called shell command will have the set number of seconds to complete. If this is set to C<< 0 >>, then no timeout will be used.
@ -563,13 +563,19 @@ sub call
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { ssh_fh => $ssh_fh }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { ssh_fh => $ssh_fh }});
if ($ssh_fh =~ /^Net::OpenSSH/) if ($ssh_fh =~ /^Net::OpenSSH/)
{ {
# The shell_call can't end is a newline. Conveniently, we want the return code. By adding
# this, we ensure it doesn't end in a new-line (and we can't blindly strip off the last
# new-line because of 'EOF' type cat's).
$shell_call .= "\n".$anvil->data->{path}{exe}{echo}." return_code:\$?";
# Make sure the output variables are clean and then make the call. # Make sure the output variables are clean and then make the call.
$output = ""; $output = "";
$error = ""; $error = "";
if ($timeout) if ($timeout)
{ {
# Call with a timeout # Call with a timeout
($output, $error) = $ssh_fh->capture2({timeout => $timeout}, $shell_call."; ".$anvil->data->{path}{exe}{echo}." return_code:\$?"); #($output, $error) = $ssh_fh->capture2({timeout => $timeout}, $shell_call."; ".$anvil->data->{path}{exe}{echo}." return_code:\$?");
($output, $error) = $ssh_fh->capture2({timeout => $timeout}, $shell_call);
$output = "" if not defined $output; $output = "" if not defined $output;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { 'ssh_fh->error' => $ssh_fh->error }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { 'ssh_fh->error' => $ssh_fh->error }});
} }
@ -580,6 +586,7 @@ sub call
$output = "" if not defined $output; $output = "" if not defined $output;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { 'ssh_fh->error' => $ssh_fh->error }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { 'ssh_fh->error' => $ssh_fh->error }});
} }
# Was there a problem? # Was there a problem?
if ($ssh_fh->error) if ($ssh_fh->error)
{ {
@ -589,6 +596,7 @@ sub call
connection => $ssh_fh_key, connection => $ssh_fh_key,
error => $ssh_fh->error, error => $ssh_fh->error,
}}); }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { error => $error }});
} }
# Take the last new line off. # Take the last new line off.

@ -2043,12 +2043,20 @@ Parameters;
This is the full path to the directory to scan. This is the full path to the directory to scan.
=head4 no_files (optional, default 0)
If set to C<< 1 >>, this scans directories only, ignoring files and symlinks.
=head3 recursive (optional, default '0') =head3 recursive (optional, default '0')
If set to C<< 1 >>, any directories found will be scanned as well. If set to C<< 1 >>, any directories found will be scanned as well.
B<< NOTE >>: Symlinks that point to directories will B<< NOT >> be scanned. B<< NOTE >>: Symlinks that point to directories will B<< NOT >> be scanned.
=head3 search_for (optional)
If set, the string will be searched for. If it is found, the B<< directory it is in >> will be stored in C<< scan::searched >>. The scan will end at this point, even if C<< recursive >> is set.
=cut =cut
### TODO: Make this work on remote systems ### TODO: Make this work on remote systems
sub scan_directory sub scan_directory
@ -2059,13 +2067,20 @@ sub scan_directory
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
# Set a default if nothing was passed. # Set a default if nothing was passed.
my $directory = defined $parameter->{directory} ? $parameter->{directory} : ""; my $directory = defined $parameter->{directory} ? $parameter->{directory} : "";
my $recursive = defined $parameter->{recursive} ? $parameter->{recursive} : 0; my $no_files = defined $parameter->{no_files} ? $parameter->{no_files} : 0;
my $recursive = defined $parameter->{recursive} ? $parameter->{recursive} : 0;
my $search_for = defined $parameter->{search_for} ? $parameter->{search_for} : "";
$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,
recursive => $recursive, no_files => $no_files,
recursive => $recursive,
search_for => $search_for,
}}); }});
# Setup the search variable, if needed.
$anvil->data->{scan}{searched} = "" if not exists $anvil->data->{scan}{searched};
# Does this directory exist? # Does this directory exist?
if (not $directory) if (not $directory)
{ {
@ -2099,6 +2114,16 @@ sub scan_directory
"scan::directories::${full_path}::name" => $anvil->data->{scan}{directories}{$full_path}{name}, "scan::directories::${full_path}::name" => $anvil->data->{scan}{directories}{$full_path}{name},
full_path => $full_path, full_path => $full_path,
}}); }});
if (($search_for) && ($file eq $search_for))
{
# Found what we're looking for, we're done.
$anvil->data->{scan}{searched} = $directory;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"scan::searched" => $anvil->data->{scan}{searched},
}});
return(0);
}
if (-d $full_path) if (-d $full_path)
{ {
# This is a directory, dive into it is asked. # This is a directory, dive into it is asked.
@ -2109,12 +2134,18 @@ sub scan_directory
"scan::directories::${full_path}::type" => $anvil->data->{scan}{directories}{$full_path}{type}, "scan::directories::${full_path}::type" => $anvil->data->{scan}{directories}{$full_path}{type},
"scan::directories::${full_path}::mode" => $anvil->data->{scan}{directories}{$full_path}{mode}, "scan::directories::${full_path}::mode" => $anvil->data->{scan}{directories}{$full_path}{mode},
}}); }});
if ($recursive) if (($recursive) && (not $anvil->data->{scan}{searched}))
{ {
$anvil->Storage->scan_directory({debug => $debug, directory => $full_path, recursive => $recursive}); $anvil->Storage->scan_directory({
debug => $debug,
directory => $full_path,
recursive => $recursive,
no_files => $no_files,
search_for => $search_for,
});
} }
} }
elsif (-l $full_path) elsif ((-l $full_path) && (not $no_files))
{ {
# Symlink # Symlink
$anvil->data->{scan}{directories}{$full_path}{type} = "symlink"; $anvil->data->{scan}{directories}{$full_path}{type} = "symlink";
@ -2124,7 +2155,7 @@ sub scan_directory
"scan::directories::${full_path}::taarget" => $anvil->data->{scan}{directories}{$full_path}{taarget}, "scan::directories::${full_path}::taarget" => $anvil->data->{scan}{directories}{$full_path}{taarget},
}}); }});
} }
elsif (-f $full_path) elsif ((-f $full_path) && (not $no_files))
{ {
# Normal file. # Normal file.
my @details = stat($full_path); my @details = stat($full_path);
@ -2150,7 +2181,6 @@ sub scan_directory
} }
closedir(DIRECTORY); closedir(DIRECTORY);
return(0); return(0);
} }

@ -12,7 +12,8 @@ our $VERSION = "3.0.0";
my $THIS_FILE = "Striker.pm"; my $THIS_FILE = "Striker.pm";
### Methods; ### Methods;
# # get_local_repo
# get_peer_data
=pod =pod
@ -74,6 +75,98 @@ sub parent
# Public methods # # Public methods #
############################################################################################################# #############################################################################################################
=head2 get_local_repo
This builds the body of an RPM repo for the local machine. If, for some reason, this machine can't be used as a repo, an empty string will be returned.
The method takes no paramters.
=cut
sub get_local_repo
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Striker->get_peer_data()" }});
# What is the repo directory?
my $document_root = "";
my $httpd_conf = $anvil->Storage->read_file({file => $anvil->data->{path}{data}{httpd_conf} });
foreach my $line (split/\n/, $httpd_conf)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /^DocumentRoot\s+"(\/.*?)"/)
{
$document_root = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { document_root => $document_root }});
last;
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { document_root => $document_root }});
if (not $document_root)
{
# Problem with apache.
return("");
}
$anvil->Storage->scan_directory({
debug => $debug,
directory => $document_root,
recursive => 1,
no_files => 1,
search_for => "repodata",
});
my $directory = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "scan::searched" => $anvil->data->{scan}{searched} }});
if ($anvil->data->{scan}{searched})
{
$directory = $anvil->data->{scan}{searched};
$directory =~ s/^$document_root//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { directory => $directory }});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { directory => $directory }});
if (not $directory)
{
# No repo found.
return("");
}
# What are my IPs?
$anvil->System->get_ips();
my $base_url = "";
foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{sys}{network}{interface}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { interface => $interface }});
if ($anvil->data->{sys}{network}{interface}{$interface}{ip})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::network::interface::${interface}::ip" => $anvil->data->{sys}{network}{interface}{$interface}{ip} }});
if (not $base_url)
{
$base_url = "baseurl=http://".$anvil->data->{sys}{network}{interface}{$interface}{ip}.$directory;
}
else
{
$base_url .= "\n http://".$anvil->data->{sys}{network}{interface}{$interface}{ip}.$directory;
}
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { base_url => $base_url }});
# Create the local repo file body
my $repo = "[".$anvil->_short_hostname."-repo]
name=Repo on ".$anvil->_hostname."
".$base_url."
enabled=1
gpgcheck=0
timeout=5
skip_if_unavailable=1";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { repo => $repo }});
return($repo);
}
=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 >>). 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).
@ -143,49 +236,48 @@ sub get_peer_data
uuid => $anvil->data->{sys}{host_uuid}, # Only write to our DB, no reason to store elsewhere uuid => $anvil->data->{sys}{host_uuid}, # Only write to our DB, no reason to store elsewhere
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { state_uuid => $state_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { state_uuid => $state_uuid }});
my ($output, $error, $return_code) = $anvil->System->call({ my ($output, $return_code) = $anvil->System->call({
debug => $debug, debug => $debug,
shell_call => $anvil->data->{path}{exe}{'call_striker-get-peer-data'}." --target root\@".$target.":".$port." --state-uuid ".$state_uuid, shell_call => $anvil->data->{path}{exe}{'call_striker-get-peer-data'}." --target root\@".$target.":".$port." --state-uuid ".$state_uuid,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output, output => $output,
error => $error,
return_code => $return_code, return_code => $return_code,
}}); }});
# Pull out the details # Pull out the details
foreach my $line (split/\n/, $output) foreach my $line (split/\n/, $output)
{ {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /connected=(.*)$/) if ($line =~ /connected=(.*)$/)
{ {
# We collect this, but apparently not for any real reason... # We collect this, but apparently not for any real reason...
$connected = $1; $connected = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { connected => $connected }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { connected => $connected }});
} }
if ($line =~ /host_name=(.*)$/) if ($line =~ /host_name=(.*)$/)
{ {
# We collect this, but apparently not for any real reason... # We collect this, but apparently not for any real reason...
$data->{host_name} = $1; $data->{host_name} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'data->{host_name}' => $data->{host_name} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'data->{host_name}' => $data->{host_name} }});
} }
if ($line =~ /host_uuid=(.*)$/) if ($line =~ /host_uuid=(.*)$/)
{ {
$data->{host_uuid} = $1; $data->{host_uuid} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'data->{host_uuid}' => $data->{host_uuid} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'data->{host_uuid}' => $data->{host_uuid} }});
} }
if ($line =~ /host_os=(.*)$/) if ($line =~ /host_os=(.*)$/)
{ {
$data->{host_os} = $1; $data->{host_os} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'data->{host_os}' => $data->{host_os} }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'data->{host_os}' => $data->{host_os} }});
} }
if ($line =~ /os_registered=(.*)$/) if ($line =~ /os_registered=(.*)$/)
{ {
$data->{os_registered} = $1; $data->{os_registered} = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'data->{os_registered}' => $data->{os_registered} }}); $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 => 2, 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},

@ -570,14 +570,19 @@ sub process_prep_host_page
if (($connect) && ($confirm)) if (($connect) && ($confirm))
{ {
# Save the job # Save the job
my $job_command = $anvil->data->{path}{exe}{'striker-initialize-host'}." --target root\@".$host_ip_address.":".$ssh_port." --type".$type; my $job_command = $anvil->data->{path}{exe}{'striker-initialize-host'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
job_command => $job_command, job_command => $job_command,
password => $anvil->Log->is_secure($host_password), password => $anvil->Log->is_secure($host_password),
}}); }});
# Store the peer's password as the job data # Store the peer's password as the job data
my $job_data = "password=".$host_password; my $job_data = "password=".$host_password."\n";
$job_data .= "rh_password=".$rh_password."\n";
$job_data .= "rh_user=".$rh_user."\n";
$job_data .= "host_ip_address=".$host_ip_address."\n";
$job_data .= "ssh_port=".$ssh_port."\n";
$job_data .= "type=".$type."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { job_data => $job_data }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 1, list => { job_data => $job_data }});
# Store the job # Store the job
@ -587,9 +592,9 @@ sub process_prep_host_page
line => __LINE__, line => __LINE__,
job_command => $job_command, job_command => $job_command,
job_data => $job_data, job_data => $job_data,
job_name => "striker-peer::add", job_name => "initialize::".$type."::".$host_ip_address,
job_title => "job_0011", job_title => $type eq "dr" ? "job_0021" : "job_0020",
job_description => "job_0012", job_description => "job_0022",
job_progress => 0, job_progress => 0,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
@ -599,7 +604,7 @@ sub process_prep_host_page
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => { $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => {
title_id => "", title_id => "",
message_id => "", message_id => "",
reload_url => "/cgi-bin/".$THIS_FILE."?anvil=true&task=prep-host", reload_url => "/cgi-bin/".$THIS_FILE."?anvil=true&",
title => "#!string!striker_0044!#", title => "#!string!striker_0044!#",
description => "#!string!striker_0129!#", description => "#!string!striker_0129!#",
}}); }});

@ -190,7 +190,7 @@
<input type="hidden" name="connect" id="connect" value="#!data!cgi::connect::value!#"> <input type="hidden" name="connect" id="connect" value="#!data!cgi::connect::value!#">
<input type="hidden" name="host_ip_address" id="host_ip_address" value="#!data!cgi::host_ip_address::value!#"> <input type="hidden" name="host_ip_address" id="host_ip_address" value="#!data!cgi::host_ip_address::value!#">
<input type="hidden" name="host_password" id="host_password" value="#!data!cgi::host_password::value!#"> <input type="hidden" name="host_password" id="host_password" value="#!data!cgi::host_password::value!#">
<input type="hidden" name="type" id="type" value="#!data!cgi::striker::value!#"> <input type="hidden" name="type" id="type" value="#!data!cgi::type::value!#">
<input type="hidden" name="task" id="task" value="#!data!cgi::task::value!#"> <input type="hidden" name="task" id="task" value="#!data!cgi::task::value!#">
</div> </div>
</table> </table>
@ -201,14 +201,19 @@
<!-- end confirm-initialize-host --> <!-- end confirm-initialize-host -->
<!-- start host-setup-redhat --> <!-- start host-setup-redhat -->
<tr>
<td class="menu_details">
#!string!message_0148!#
</td>
</tr>
<tr>
<td>
&nbsp;
</td>
</tr>
<tr> <tr>
<td> <td>
<table align="center" width="90%"> <table align="center" width="90%">
<tr>
<td colspan="3">
#!string!message_0148!#
</td>
</tr>
<tr> <tr>
<td> <td>
<input type="text" name="rh_user" id="rh_user" value="#!variable!rh_user!#" placeholder="#!string!message_0144!#" /> <input type="text" name="rh_user" id="rh_user" value="#!variable!rh_user!#" placeholder="#!string!message_0144!#" />
@ -220,11 +225,6 @@
<input type="text" name="rh_password" id="rh_password" value="#!variable!rh_password!#" style="text-security:disc; -webkit-text-security:disc;" autocomplete="off" placeholder="#!string!message_0145!#" /> <input type="text" name="rh_password" id="rh_password" value="#!variable!rh_password!#" style="text-security:disc; -webkit-text-security:disc;" autocomplete="off" placeholder="#!string!message_0145!#" />
</td> </td>
</tr> </tr>
<tr>
<td colspan="3">
&nbsp;
</td>
</tr>
</table> </table>
</td> </td>
</tr> </tr>

17
notes

@ -454,16 +454,7 @@ How to rebuild all of the packages in the Alteeve RHEL 8 repo;
# Register if RHEL proper; # Register if RHEL proper;
subscription-manager register --username <user> --password <secret> --auto-attach --force subscription-manager register --username <user> --password <secret> --auto-attach --force
subscription-manager repos --enable rhel-8-for-x86_64-appstream-rpms
subscription-manager repos --enable rhel-8-for-x86_64-appstream-source-rpms
subscription-manager repos --enable rhel-8-for-x86_64-baseos-rpms
subscription-manager repos --enable rhel-8-for-x86_64-baseos-source-rpms
subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms
subscription-manager repos --enable rhel-8-for-x86_64-highavailability-source-rpms
subscription-manager repos --enable rhel-8-for-x86_64-supplementary-rpms
subscription-manager repos --enable rhel-8-for-x86_64-supplementary-source-rpms
subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-rpms
subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-source-rpms
subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-source-rpms subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-source-rpms
subscription-manager repos --enable rhel-8-for-x86_64-supplementary-source-rpms subscription-manager repos --enable rhel-8-for-x86_64-supplementary-source-rpms
subscription-manager repos --enable rhel-8-for-x86_64-baseos-rpms subscription-manager repos --enable rhel-8-for-x86_64-baseos-rpms
@ -475,6 +466,12 @@ subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-rpms
subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms subscription-manager repos --enable rhel-8-for-x86_64-highavailability-rpms
subscription-manager repos --enable rhel-8-for-x86_64-appstream-rpms subscription-manager repos --enable rhel-8-for-x86_64-appstream-rpms
repos => {
'rhel-8-for-x86_64-highavailability-rpms' => 0,
'codeready-builder-for-rhel-8-x86_64-rpms' => 0,
}
* Packages to install; * Packages to install;
* Network; * Network;

@ -760,6 +760,7 @@ Failed to promote the DRBD resource: [#!variable!resource!#] primary. Expected a
<key name="log_0435">Program: [#!variable!program!#] running as the real user: [#!variable!real_user!# (#!variable!real_uid!#)] and effective user: [#!variable!effective_user!# (#!variable!effective_uid!#)].</key> <key name="log_0435">Program: [#!variable!program!#] running as the real user: [#!variable!real_user!# (#!variable!real_uid!#)] and effective user: [#!variable!effective_user!# (#!variable!effective_uid!#)].</key>
<key name="log_0436">The setuid c-wrapper: [#!variable!wrapper!#] already exists, no need to create it.</key> <key name="log_0436">The setuid c-wrapper: [#!variable!wrapper!#] already exists, no need to create it.</key>
<key name="log_0437">The anvil version cache file: [#!variable!file!#] for: [#!variable!target!#] needs to be created/updated.</key> <key name="log_0437">The anvil version cache file: [#!variable!file!#] for: [#!variable!target!#] needs to be created/updated.</key>
<key name="log_0438"><![CDATA[[ Error ] - No job was found for the 'job_uuid': [#!variable!job_uuid!#].]]></key>
<!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. --> <!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. -->
<key name="t_0000">Test</key> <key name="t_0000">Test</key>
@ -963,6 +964,36 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st
<key name="job_0017">Update the 'Install Target' source files and refresh RPM repository.</key> <key name="job_0017">Update the 'Install Target' source files and refresh RPM repository.</key>
<key name="job_0018">Download a file</key> <key name="job_0018">Download a file</key>
<key name="job_0019">The referenced file will be downloaded by the target host.</key> <key name="job_0019">The referenced file will be downloaded by the target host.</key>
<key name="job_0020">Initialize a new Anvil! Node</key>
<key name="job_0021">Initialize a new DR Host</key>
<key name="job_0022">The target will be setup to talk to this and our peer dashboards. When initialization is complete, you will be able to map the target's network.</key>
<key name="job_0023">Connecting to the target: [#!variable!target!#]...</key>
<key name="job_0024">Connected!</key>
<key name="job_0025">Unable to connect to: [#!variable!target!#]. Will keep trying for another: [#!variable!timeout!#] seconds...</key>
<key name="job_0026">Unable to connect, the job has failed.</key>
<key name="job_0027">'Initialize host' job: [#!data!switches::job-uuid!#] picked up.</key>
<key name="job_0028">Adding repositories.</key>
<key name="job_0029">Added the repository for this dashboard.</key>
<key name="job_0030">Red Hat subscription information provides, attempting to register now.</key>
<key name="job_0031">This machine is already registered with Red Hat. Skipping it.</key>
<key name="job_0032">Unable to reach the Red Hat subscription service. Is the Internet working on this host?</key>
<key name="job_0033">Please be patient, subscription can take a while to complete.</key>
<key name="job_0034">Success!</key>
<key name="job_0035">
Failure! The return code: [#!variable!return_code!#] was received ('0' was expected). Possibly helpful information:
* Output: [#!variable!output!#]
* Error: [#!variable!error!#]
</key>
<key name="job_0036">Adding the repo: [#!variable!repo!#]</key>
<key name="job_0037">Verifying the the needed repos are enabled now.</key>
<key name="job_0038">[ Warning ] - The repo: [#!variable!repo!#] is not subcribed to this system! Initialization will continue, but it might fail.</key>
<key name="job_0039">Updating the target's operating system prior to package install.</key>
<key name="job_0040">[ Note ] - This step can take a while to finish, and there will be no input here until it completes.</key>
<key name="job_0041">Removing conflicting packages.</key>
<key name="job_0042">Will now install: [#!variable!package!#].</key>
<key name="job_0043">Verifying installation.</key>
<key name="job_0044">[ Failed ] - There may be more information in #!data!path::configs::anvil.conf!#.</key>
<key name="job_0045">Success!</key>
<!-- Warnings --> <!-- Warnings -->
<key name="striker_warning_0001">The IP address will change. You will need to reconnect after applying these changes.</key> <key name="striker_warning_0001">The IP address will change. You will need to reconnect after applying these changes.</key>
@ -1066,6 +1097,8 @@ Failed to generate an RSA public key for the user: [#!variable!user!#]. The outp
<key name="error_0070"><![CDATA[Unable to find the host UUID on the host: [#!variable!host!#].]]></key> <key name="error_0070"><![CDATA[Unable to find the host UUID on the host: [#!variable!host!#].]]></key>
<key name="error_0071">Something went wrong trying to write: [#!variable!file!#], unable to proceed.</key> <key name="error_0071">Something went wrong trying to write: [#!variable!file!#], unable to proceed.</key>
<key name="error_0072">Something went wrong trying to compile the C-program: [#!variable!file!#], unable to proceed.</key> <key name="error_0072">Something went wrong trying to compile the C-program: [#!variable!file!#], unable to proceed.</key>
<key name="error_0073">The job UUID was not passed via '--job-uuid' and no unclaimed job was found in the database.</key>
<key name="error_0074">The initialization target: [#!variable!target!#] is not accessible. Will keep trying...</key>
<!-- These are units, words and so on used when displaying information. --> <!-- These are units, words and so on used when displaying information. -->
<key name="unit_0001">Yes</key> <key name="unit_0001">Yes</key>

@ -6,15 +6,16 @@
# Exit codes; # Exit codes;
# 0 = Normal exit. # 0 = Normal exit.
# 1 = No database connection. # 1 = No database connection.
# 2 = Password not found in the database. # 2 = Job UUID not passed and no unclaimed jobs found
# 3 = Peer not accessible # 3 = Job detauls not found in the database.
# 4 = Unable to find the peer's host UUID # 4 = Unable to connect to the target.
# 5 = # 5 = Failed to install the anvil package.
# #
use strict; use strict;
use warnings; use warnings;
use Anvil::Tools; use Anvil::Tools;
use Data::Dumper;
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
@ -29,19 +30,29 @@ $| = 1;
my $anvil = Anvil::Tools->new(); my $anvil = Anvil::Tools->new();
$anvil->Log->level({set => 2}); $anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1}); $anvil->Log->secure({set => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
# Read switches (target ([user@]host[:port]) and the file with the target's password. # Read switches (target ([user@]host[:port]) and the file with the target's password.
$anvil->data->{switches}{target} = ""; $anvil->data->{switches}{'job-uuid'} = "";
$anvil->data->{switches}{'state-uuid'} = "";
$anvil->Get->switches; $anvil->Get->switches;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
'switches::target' => $anvil->data->{switches}{target}, 'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'},
'switches::state-uuid' => $anvil->data->{switches}{'state-uuid'},
}}); }});
# Connect to the database(s).
$anvil->Database->connect;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
# No databases, exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0003"});
$anvil->nice_exit({exit_code => 1});
}
get_job_details($anvil);
wait_for_access($anvil);
add_repos($anvil);
add_databases($anvil);
$anvil->nice_exit({code => 0}); $anvil->nice_exit({code => 0});
@ -49,3 +60,487 @@ $anvil->nice_exit({code => 0});
############################################################################################################# #############################################################################################################
# Functions # # Functions #
############################################################################################################# #############################################################################################################
# Add any databases we're using to the initialized host.
sub add_databases
{
my ($anvil) = @_;
return(0);
}
# This adds this machine's repo, and if the internet is up on the target, we'll add the Anvil! repo as well.
sub add_repos
{
my ($anvil) = @_;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0028"});
update_progress($anvil, 6, "job_0028");
# Add the local repo.
my $repo = $anvil->Striker->get_local_repo({debug => 3});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { repo => $repo }});
if ($repo)
{
# NOTE: We can't use Storage->write_file() because the target may not have 'rsync' installed
# yet.
my $shell_call = "
".$anvil->data->{path}{exe}{cat}." > /etc/yum.repos.d/".$anvil->_short_hostname.".repo << EOF
$repo
EOF
";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $shell_call,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
error => $error,
output => $output,
return_code => $return_code,
}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0029"});
update_progress($anvil, 7, "job_0029");
}
# If I have a Red Hat user and password, try to subscribe this syste,.
if (($anvil->data->{data}{rh_user}) && ($anvil->data->{data}{rh_password}))
{
# If there's no internet, this will fail. If the network is up, we can see if the
# registration is still needed.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0030"});
update_progress($anvil, 7, "job_0030");
# We'll attach subscriptions if this is set
my $subscribe = 1;
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." identity",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
if ($return_code eq "0")
{
# Already registered.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0031"});
update_progress($anvil, 10, "job_0031");
}
elsif ($return_code eq "1")
{
# Registration is needed. This can take a while, so we give it a generous timeout.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0033"});
update_progress($anvil, 8, "job_0033");
my $bash_password = $anvil->data->{data}{rh_password};
$bash_password =~ s/'/\\\'/g;
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." register --username ".$anvil->data->{data}{rh_user}." --password '".$bash_password."' --auto-attach --force",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
if ($return_code)
{
# Something went wrong
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0035", variables => {
output => $output,
error => $error,
return_code => $return_code,
}});
update_progress($anvil, 10, "job_0035,!!return_code!".$return_code."!!,!!output!".$output."!!,!!error!".$error."!!");
$subscribe = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { subscribe => $subscribe }});
}
else
{
# Success!
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0034"});
update_progress($anvil, 9, "job_0034");
}
}
elsif ($return_code eq "70")
{
# No Internet (or can't reach the subscriion servers)
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0032"});
update_progress($anvil, 10, "job_0032");
$subscribe = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { subscribe => $subscribe }});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { subscribe => $subscribe }});
if ($subscribe)
{
# We're going to need these repos when it's all said and done. The first two are
# enabled by default.
$anvil->data->{repos}{'rhel-8-for-x86_64-baseos-rpms'} = 0;
$anvil->data->{repos}{'rhel-8-for-x86_64-appstream-rpms'} = 0;
$anvil->data->{repos}{'codeready-builder-for-rhel-8-x86_64-rpms'} = 0;
# Both target types need 'codeready-builder-for-rhel-8-x86_64-rpms', but only nodes
# need 'rhel-8-for-x86_64-highavailability-rpms'
# We blindly subscribe, then we'll check that they're actually subscribed.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0036", variables => { repo => 'codeready-builder-for-rhel-8-x86_64-rpms' }});
update_progress($anvil, 10, "job_0036,!!repo!codeready-builder-for-rhel-8-x86_64-rpms!!");
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --enable codeready-builder-for-rhel-8-x86_64-rpms",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
# If this
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'data::type' => $anvil->data->{data}{type} }});
if ($anvil->data->{data}{type} eq "node")
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0036", variables => { repo => 'rhel-8-for-x86_64-highavailability-rpms' }});
update_progress($anvil, 11, "job_0036,!!repo!rhel-8-for-x86_64-highavailability-rpms!!");
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --enable rhel-8-for-x86_64-highavailability-rpms",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
# Add this to the needed list.
$anvil->data->{repos}{'rhel-8-for-x86_64-highavailability-rpms'} = 0;
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0037"});
update_progress($anvil, 12, "job_0037");
undef $output;
undef $error;
undef $return_code;
($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'subscription-manager'}." repos --list-enabled",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /Repo ID:\s+(.*)$/i)
{
my $repo = $1;
$anvil->data->{repos}{$repo} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "repos::${repo}" => $anvil->data->{repos}{$repo} }});
}
}
# Are any still missing?
foreach my $repo (sort {$a cmp $b} keys %{$anvil->data->{repos}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "repos::${repo}" => $anvil->data->{repos}{$repo} }});
if (not $anvil->data->{repos}{$repo})
{
# Well this is a problem...
update_progress($anvil, 11, "job_0038,!!repo!".$repo."!!");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0038", variables => { repo => $repo }});
}
}
}
}
# Call an OS update.
update_progress($anvil, 20, "job_0039");
update_progress($anvil, 25, "job_0040");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0039"});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0040"});
my ($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y update",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 3600,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
# Now remove biosdevname
update_progress($anvil, 50, "job_0041");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0041"});
undef $output;
undef $error;
undef $return_code;
($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y remove biosdevname",
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 300,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
# Install the anvil package now.
my $package = $anvil->data->{data}{type} eq "dr" ? "anvil-dr" : "anvil-node";
update_progress($anvil, 70, "job_0042,!!package!".$package."!!");
update_progress($anvil, 75, "job_0040");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0042", variables => { 'package' => $package }});
undef $output;
undef $error;
undef $return_code;
($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." -y install ".$package,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 3600,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
update_progress($anvil, 80, "job_0043");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0043"});
undef $output;
undef $error;
undef $return_code;
($output, $error, $return_code) = $anvil->Remote->call({
debug => 3,
shell_call => $anvil->data->{path}{exe}{'dnf'}." list installed ".$package,
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
timeout => 3600,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
# The return code of '0' means found, '1' means not found
if ($return_code)
{
# Failed...
update_progress($anvil, 100, "job_0044");
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0044"});
$anvil->nice_exit({code => 6});
}
else
{
# Found it!
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0045"});
update_progress($anvil, 90, "job_0045");
}
return(0);
}
# This goes into a loop until the target is accessible.
sub wait_for_access
{
my ($anvil) = @_;
# Test access
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0023", variables => { target => $anvil->data->{data}{say_target} }});
update_progress($anvil, 2, "job_0023,!!target!".$anvil->data->{data}{say_target}."!!");
my $waiting = 1;
my $access = 0;
my $timeout = time + 600;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { timeout => $timeout, 'time' => time }});
while ($waiting)
{
$access = $anvil->Remote->test_access({
password => $anvil->data->{data}{password},
port => $anvil->data->{data}{ssh_port},
target => $anvil->data->{data}{host_ip_address},
user => "root",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { access => $access }});
if ($access)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0024"});
update_progress($anvil, 5, "job_0024");
$waiting = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
}
else
{
my $time_left = $timeout - time;
if ($time_left < 0)
{
$waiting = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { waiting => $waiting }});
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0025", variables => {
target => $anvil->data->{data}{say_target},
time_left => $time_left,
}});
update_progress($anvil, 3, "job_0025,!!timeout!".$time_left."!!");
sleep 5;
}
}
}
if (not $access)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "job_0026"});
update_progress($anvil, 100, "job_0026");
$anvil->nice_exit({code => 3});
}
return(0);
}
# This picks up the details for the job, so we know who to connect to.
sub get_job_details
{
my ($anvil) = @_;
# If we don't have a job-uuid, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
my $return = $anvil->Database->get_jobs();
foreach my $hash_ref (@{$return})
{
my $job_command = $hash_ref->{job_command};
my $job_progress = $hash_ref->{job_progress};
my $job_uuid = $hash_ref->{job_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
job_command => $job_command,
job_progress => $job_progress,
job_uuid => $job_uuid,
}});
next if $job_command ne $anvil->data->{path}{exe}{$THIS_FILE};
next if $job_progress;
# Still alive? found it!
$anvil->data->{switches}{'job-uuid'} = $job_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'} }});
last;
}
}
if (not $anvil->data->{switches}{'job-uuid'})
{
# No job UUID.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0073"});
$anvil->nice_exit({code => 2});
}
my $return = $anvil->Database->get_job_details({debug => 3, job_uuid => $anvil->data->{switches}{'job-uuid'}});
if (not $return)
{
# No job details
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0034", variables => { job_uuid => $anvil->data->{switches}{'job-uuid'} }});
$anvil->nice_exit({code => 3});
}
$anvil->data->{jobs}{job_uuid} = $anvil->data->{switches}{'job-uuid'};
$anvil->data->{jobs}{job_command} = $return->{job_command};
$anvil->data->{jobs}{job_data} = $return->{job_data};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
'jobs::job_uuid' => $anvil->data->{jobs}{job_uuid},
'jobs::job_command' => $anvil->data->{jobs}{job_command},
'jobs::job_data' => $anvil->Log->is_secure($anvil->data->{jobs}{job_data}),
}});
foreach my $line (split/\n/, $anvil->data->{jobs}{job_data})
{
my $secure = $line =~ /passw/ ? 1 : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, secure => $secure, list => { line => $line }});
my ($variable, $value) = ($line =~ /^(.*?)=(.*)$/);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
variable => $variable,
value => $secure ? $anvil->Log->is_secure($value) : $value,
}});
$anvil->data->{data}{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"data::${variable}" => $secure ? $anvil->Log->is_secure($anvil->data->{data}{$variable}) : $anvil->data->{data}{$variable},
}});
}
$anvil->data->{data}{say_target} = "root\@".$anvil->data->{data}{host_ip_address}.":".$anvil->data->{data}{ssh_port};
# Update that we've picked the job up.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "job_0027"});
update_progress($anvil, 0, "clear");
update_progress($anvil, 1, "job_0027");
return(0);
}
# If this is being called as a job, this will allow the progress to be updated.
sub update_progress
{
my ($anvil, $progress, $message) = @_;
if (not $anvil->data->{switches}{'job-uuid'})
{
return(0);
}
$anvil->Job->update_progress({
debug => 3,
progress => $progress,
message => $message,
job_uuid => $anvil->data->{switches}{'job-uuid'},
});
return(0);
}

@ -132,8 +132,8 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0003"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0003"});
$anvil->nice_exit({exit_code => 8}); $anvil->nice_exit({exit_code => 8});
} }
update_progress($anvil, 1, "clear"); update_progress($anvil, 0, "clear");
update_progress($anvil, 2, "log_0239"); update_progress($anvil, 1, "log_0239");
# If we're being asked to disable, just do so and exit. # If we're being asked to disable, just do so and exit.
if ($anvil->data->{switches}{disable}) if ($anvil->data->{switches}{disable})

Loading…
Cancel
Save