From a54e0d4e221b31cbd4aa2861370361cc81875a3c Mon Sep 17 00:00:00 2001 From: Digimer Date: Wed, 18 Sep 2019 18:48:09 -0400 Subject: [PATCH] * 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 --- Anvil/Tools.pm | 2 + Anvil/Tools/Database.pm | 144 +++++++- Anvil/Tools/Job.pm | 18 +- Anvil/Tools/Remote.pm | 12 +- Anvil/Tools/Storage.pm | 48 ++- Anvil/Tools/Striker.pm | 114 +++++- cgi-bin/striker | 17 +- html/skins/alteeve/anvil.html | 22 +- notes | 17 +- share/words.xml | 33 ++ tools/striker-initialize-host | 515 +++++++++++++++++++++++++++- tools/striker-manage-install-target | 4 +- 12 files changed, 878 insertions(+), 68 deletions(-) diff --git a/Anvil/Tools.pm b/Anvil/Tools.pm index b1f9f20a..85accc2c 100644 --- a/Anvil/Tools.pm +++ b/Anvil/Tools.pm @@ -983,6 +983,7 @@ sub _set_paths }, data => { group => "/etc/group", + httpd_conf => "/etc/httpd/conf/httpd.conf", host_ssh_key => "/etc/ssh/ssh_host_ecdsa_key.pub", '.htpasswd' => "/etc/httpd/.htpasswd", host_uuid => "/etc/anvil/host.uuid", @@ -1088,6 +1089,7 @@ sub _set_paths stonith_admin => "/usr/sbin/stonith_admin", strings => "/usr/bin/strings", '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-peers' => "/usr/sbin/striker-manage-peers", 'striker-prep-database' => "/usr/sbin/striker-prep-database", diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 17577ba8..f230589e 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -22,6 +22,7 @@ my $THIS_FILE = "Database.pm"; # disconnect # get_alert_recipients # get_hosts +# get_job_details # get_jobs # get_local_uuid # initialize @@ -1374,6 +1375,123 @@ FROM 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 This gets the list of running jobs. @@ -1491,6 +1609,28 @@ WHERE my $return_count = @{$return}; $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); } @@ -3458,6 +3598,7 @@ sub insert_or_update_jobs my $job_description = defined $parameter->{job_description} ? $parameter->{job_description} : ""; 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 $clear_status = defined $parameter->{clear_status} ? $parameter->{clear_status} : 0; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid, file => $file, @@ -3475,6 +3616,7 @@ sub insert_or_update_jobs job_description => $job_description, job_status => $job_status, 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. @@ -3721,7 +3863,7 @@ SET "; 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; $query .= " diff --git a/Anvil/Tools/Job.pm b/Anvil/Tools/Job.pm index 021ba427..411f78fc 100644 --- a/Anvil/Tools/Job.pm +++ b/Anvil/Tools/Job.pm @@ -504,12 +504,12 @@ sub update_progress my $picked_up_by = defined $parameter->{picked_up_by} ? $parameter->{picked_up_by} : ""; my $progress = defined $parameter->{progress} ? $parameter->{progress} : ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - picked_up_by => $picked_up_by, - progress => $progress, - message => $message, - job_uuid => $job_uuid, - "jobs::job_uuid" => $anvil->data->{jobs}{job_uuid}, + picked_up_by => $picked_up_by, + progress => $progress, + message => $message, + job_uuid => $job_uuid, }}); + if ($picked_up_by eq "") { $picked_up_by = $$; @@ -556,11 +556,16 @@ sub update_progress # Get the current job_status and append this new one. my $job_picked_up_at = 0; 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 }}); if ($message eq "clear") { $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 { @@ -669,6 +674,7 @@ WHERE line => __LINE__, debug => $debug, update_progress_only => 1, + clear_status => $clear_status, job_uuid => $job_uuid, job_picked_up_by => $picked_up_by, job_picked_up_at => $job_picked_up_at, diff --git a/Anvil/Tools/Remote.pm b/Anvil/Tools/Remote.pm index acd3f0ec..f172e68c 100644 --- a/Anvil/Tools/Remote.pm +++ b/Anvil/Tools/Remote.pm @@ -260,7 +260,7 @@ B: If the C<< target >> is presented in the format C<< target:port >>, the =head3 timeout (optional, default '10') -B: This is the timeout for the command to return. This is NOT the connection timeout! +B: 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. @@ -563,13 +563,19 @@ sub call $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { ssh_fh => $ssh_fh }}); 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. $output = ""; $error = ""; if ($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; $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; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, secure => $secure, list => { 'ssh_fh->error' => $ssh_fh->error }}); } + # Was there a problem? if ($ssh_fh->error) { @@ -589,6 +596,7 @@ sub call connection => $ssh_fh_key, 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. diff --git a/Anvil/Tools/Storage.pm b/Anvil/Tools/Storage.pm index ff8d8d97..f292dee6 100644 --- a/Anvil/Tools/Storage.pm +++ b/Anvil/Tools/Storage.pm @@ -2043,12 +2043,20 @@ Parameters; 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') 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. +=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 ### TODO: Make this work on remote systems sub scan_directory @@ -2059,13 +2067,20 @@ sub scan_directory my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; # Set a default if nothing was passed. - my $directory = defined $parameter->{directory} ? $parameter->{directory} : ""; - my $recursive = defined $parameter->{recursive} ? $parameter->{recursive} : 0; + my $directory = defined $parameter->{directory} ? $parameter->{directory} : ""; + 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 => { - directory => $directory, - recursive => $recursive, + directory => $directory, + 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? if (not $directory) { @@ -2099,6 +2114,16 @@ sub scan_directory "scan::directories::${full_path}::name" => $anvil->data->{scan}{directories}{$full_path}{name}, 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) { # 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}::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 $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}, }}); } - elsif (-f $full_path) + elsif ((-f $full_path) && (not $no_files)) { # Normal file. my @details = stat($full_path); @@ -2150,7 +2181,6 @@ sub scan_directory } closedir(DIRECTORY); - return(0); } diff --git a/Anvil/Tools/Striker.pm b/Anvil/Tools/Striker.pm index 334f8ab0..77e14784 100644 --- a/Anvil/Tools/Striker.pm +++ b/Anvil/Tools/Striker.pm @@ -12,7 +12,8 @@ our $VERSION = "3.0.0"; my $THIS_FILE = "Striker.pm"; ### Methods; -# +# get_local_repo +# get_peer_data =pod @@ -74,6 +75,98 @@ sub parent # 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 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 }); $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, 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, - error => $error, return_code => $return_code, }}); # Pull out the details 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=(.*)$/) { # We collect this, but apparently not for any real reason... $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=(.*)$/) { # We collect this, but apparently not for any real reason... $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=(.*)$/) { $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=(.*)$/) { $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=(.*)$/) { $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, 'data->{host_name}' => $data->{host_name}, 'data->{host_uuid}' => $data->{host_uuid}, diff --git a/cgi-bin/striker b/cgi-bin/striker index 7603b1f7..6adb8b00 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -570,14 +570,19 @@ sub process_prep_host_page if (($connect) && ($confirm)) { # 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 => { job_command => $job_command, password => $anvil->Log->is_secure($host_password), }}); # 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 }}); # Store the job @@ -587,9 +592,9 @@ sub process_prep_host_page line => __LINE__, job_command => $job_command, job_data => $job_data, - job_name => "striker-peer::add", - job_title => "job_0011", - job_description => "job_0012", + job_name => "initialize::".$type."::".$host_ip_address, + job_title => $type eq "dr" ? "job_0021" : "job_0020", + job_description => "job_0022", job_progress => 0, }); $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 => { title_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!#", description => "#!string!striker_0129!#", }}); diff --git a/html/skins/alteeve/anvil.html b/html/skins/alteeve/anvil.html index c4288c17..ab8f59c1 100644 --- a/html/skins/alteeve/anvil.html +++ b/html/skins/alteeve/anvil.html @@ -190,7 +190,7 @@ - + @@ -201,14 +201,19 @@ + + + #!string!message_0148!# + + + + +   + + - - - - - -
- #!string!message_0148!# -
@@ -220,11 +225,6 @@
-   -
diff --git a/notes b/notes index 205a43a6..986e8d64 100644 --- a/notes +++ b/notes @@ -454,16 +454,7 @@ How to rebuild all of the packages in the Alteeve RHEL 8 repo; # Register if RHEL proper; subscription-manager register --username --password --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 rhel-8-for-x86_64-supplementary-source-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-appstream-rpms +repos => { + 'rhel-8-for-x86_64-highavailability-rpms' => 0, + 'codeready-builder-for-rhel-8-x86_64-rpms' => 0, +} + + * Packages to install; * Network; diff --git a/share/words.xml b/share/words.xml index ff2e7b92..e3796521 100644 --- a/share/words.xml +++ b/share/words.xml @@ -760,6 +760,7 @@ Failed to promote the DRBD resource: [#!variable!resource!#] primary. Expected a Program: [#!variable!program!#] running as the real user: [#!variable!real_user!# (#!variable!real_uid!#)] and effective user: [#!variable!effective_user!# (#!variable!effective_uid!#)]. The setuid c-wrapper: [#!variable!wrapper!#] already exists, no need to create it. The anvil version cache file: [#!variable!file!#] for: [#!variable!target!#] needs to be created/updated. + Test @@ -963,6 +964,36 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st Update the 'Install Target' source files and refresh RPM repository. Download a file The referenced file will be downloaded by the target host. + Initialize a new Anvil! Node + Initialize a new DR Host + 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. + Connecting to the target: [#!variable!target!#]... + Connected! + Unable to connect to: [#!variable!target!#]. Will keep trying for another: [#!variable!timeout!#] seconds... + Unable to connect, the job has failed. + 'Initialize host' job: [#!data!switches::job-uuid!#] picked up. + Adding repositories. + Added the repository for this dashboard. + Red Hat subscription information provides, attempting to register now. + This machine is already registered with Red Hat. Skipping it. + Unable to reach the Red Hat subscription service. Is the Internet working on this host? + Please be patient, subscription can take a while to complete. + Success! + +Failure! The return code: [#!variable!return_code!#] was received ('0' was expected). Possibly helpful information: +* Output: [#!variable!output!#] +* Error: [#!variable!error!#] + + Adding the repo: [#!variable!repo!#] + Verifying the the needed repos are enabled now. + [ Warning ] - The repo: [#!variable!repo!#] is not subcribed to this system! Initialization will continue, but it might fail. + Updating the target's operating system prior to package install. + [ Note ] - This step can take a while to finish, and there will be no input here until it completes. + Removing conflicting packages. + Will now install: [#!variable!package!#]. + Verifying installation. + [ Failed ] - There may be more information in #!data!path::configs::anvil.conf!#. + Success! The IP address will change. You will need to reconnect after applying these changes. @@ -1066,6 +1097,8 @@ Failed to generate an RSA public key for the user: [#!variable!user!#]. The outp Something went wrong trying to write: [#!variable!file!#], unable to proceed. Something went wrong trying to compile the C-program: [#!variable!file!#], unable to proceed. + The job UUID was not passed via '--job-uuid' and no unclaimed job was found in the database. + The initialization target: [#!variable!target!#] is not accessible. Will keep trying... Yes diff --git a/tools/striker-initialize-host b/tools/striker-initialize-host index 8c55edf6..896182d7 100755 --- a/tools/striker-initialize-host +++ b/tools/striker-initialize-host @@ -6,15 +6,16 @@ # Exit codes; # 0 = Normal exit. # 1 = No database connection. -# 2 = Password not found in the database. -# 3 = Peer not accessible -# 4 = Unable to find the peer's host UUID -# 5 = +# 2 = Job UUID not passed and no unclaimed jobs found +# 3 = Job detauls not found in the database. +# 4 = Unable to connect to the target. +# 5 = Failed to install the anvil package. # use strict; use warnings; use Anvil::Tools; +use Data::Dumper; my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; @@ -29,19 +30,29 @@ $| = 1; my $anvil = Anvil::Tools->new(); $anvil->Log->level({set => 2}); $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. -$anvil->data->{switches}{target} = ""; -$anvil->data->{switches}{'state-uuid'} = ""; +$anvil->data->{switches}{'job-uuid'} = ""; $anvil->Get->switches; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 'switches::target' => $anvil->data->{switches}{target}, - 'switches::state-uuid' => $anvil->data->{switches}{'state-uuid'}, + 'switches::job-uuid' => $anvil->data->{switches}{'job-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}); @@ -49,3 +60,487 @@ $anvil->nice_exit({code => 0}); ############################################################################################################# # 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); +} diff --git a/tools/striker-manage-install-target b/tools/striker-manage-install-target index df4dfcd6..df0745c5 100755 --- a/tools/striker-manage-install-target +++ b/tools/striker-manage-install-target @@ -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->nice_exit({exit_code => 8}); } -update_progress($anvil, 1, "clear"); -update_progress($anvil, 2, "log_0239"); +update_progress($anvil, 0, "clear"); +update_progress($anvil, 1, "log_0239"); # If we're being asked to disable, just do so and exit. if ($anvil->data->{switches}{disable})