diff --git a/Anvil/Tools/Words.pm b/Anvil/Tools/Words.pm index 0627e2a7..457c1f93 100755 --- a/Anvil/Tools/Words.pm +++ b/Anvil/Tools/Words.pm @@ -20,6 +20,7 @@ my $THIS_FILE = "Words.pm"; # clean_spaces # key # language +# parse_banged_string # read # string # _wrap_string @@ -244,6 +245,111 @@ sub language return($self->{WORDS}{LANGUAGE}); } +=head2 parse_banged_string + +This takes a string (usually from a DB record) in the format C<< [,!!var1!value1!!,!!var2!value2!!,...,!!varN!valueN!! >> and converts it into an actual string. + +Parameters; + +=head3 key_string (required) + +This is the double-banged string to process. It can take and process multiple lines at once, so long as each line is in the above format, broken by a simple new line (C<< \n >>). + +=head3 json_escape (optional, default '0') + +If set to C<< 1 >>, and double-quote (C<< " >>) characters will be escaped (ie: for use in JSON files). + +=cut +sub parse_banged_string +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + + # Setup default values + my $out_string = ""; + my $key_string = defined $parameter->{key_string} ? $parameter->{key_string} : 0; + my $json_escape = defined $parameter->{json_escape} ? $parameter->{json_escape} : 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + json_escape => $json_escape, + key_string => $key_string, + }}); + + # There might be multiple keys, split by newlines. + foreach my $message (split/\n/, $key_string) + { + # If we've looped, there will be data in 'out_string" already so append a newline to separate + # this key from the previous one. + if ($out_string) + { + # Already processed a line, so prepend a newline. + $out_string .= "\n"; + } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { message => $message }}); + if ($message =~ /^(.*?),(.*)$/) + { + # This key has insertion variables. + my $key = $1; + my $variable_string = $2; + my $variables = {}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + key => $key, + variable_string => $variable_string, + }}); + foreach my $pair (split/,/, $variable_string) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { pair => $pair }}); + my $name = ""; + my $value = ""; + if ($pair =~ /^!!(.*?)!(.*)!!$/) + { + $name = $1; + $value = $2; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + name => $name, + value => $value, + }}); + } + elsif ($pair =~ /^!!(.*?)!!!$/) + { + $name = $1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { name => $name }}); + } + else + { + # what?! + } + $variables->{$name} = $value; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "variables->$name" => $variables->{$name} }}); + } + + # Parse the line now. + $out_string .= $anvil->Words->string({key => $key, variables => $variables}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { out_string => $out_string }}); + } + else + { + # This key is just a key, no variables. + $out_string .= $anvil->Words->string({key => $message}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { out_string => $out_string }}); + } + } + + if ($json_escape) + { + # Escape characters needed for use in json. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { ">> out_string" => $out_string }}); + $out_string =~ s/\"/\\\"/msg; + $out_string =~ s/\n/
/msg; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "<< out_string" => $out_string }}); + } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { out_string => $out_string }}); + return($out_string); +} + =head2 read This reads in a words file containing translated strings used to generated output for the user. diff --git a/share/words.xml b/share/words.xml index 8faf7059..5dc6bea7 100644 --- a/share/words.xml +++ b/share/words.xml @@ -470,7 +470,11 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st Configure Network The network configuration will be updated based on the variables stored in the database. Reconnecting to the machine using the new IP address may be required. Update Striker - This system is now scheduled to be updated. + +This "system" is now scheduled to be updated. +Here's a "multi" quoted "multi" line. +OK, go! + The IP address will change. You will need to reconnect after applying these changes. diff --git a/tools/anvil-daemon b/tools/anvil-daemon index 9e4d5e65..5fefb8e1 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -54,13 +54,17 @@ if (not $anvil->data->{sys}{database}{connections}) } } +my $say_description = $anvil->Words->parse_banged_string({json_escape => 1, key_string => "job_0004"}); +print "say_description: [".$say_description."]\n"; +die; + # Read switches -$anvil->data->{switches}{'run-once'} = ""; -$anvil->data->{switches}{'no-run-once'} = ""; +$anvil->data->{switches}{'run-once'} = ""; +$anvil->data->{switches}{'main-loop-only'} = ""; $anvil->Get->switches; # There are some things we only want to run on (re)start and don't need to always run. -run_once($anvil) if not $anvil->data->{switches}{'no-run-once'}; +run_once($anvil) if not $anvil->data->{switches}{'main-loop-only'}; # Calculate my sum so that we can exit if it changes later. $anvil->Storage->record_md5sums; @@ -244,8 +248,6 @@ sub run_jobs # Get a list of pending or incomplete jobs. my $return = $anvil->Database->get_jobs({debug => 2, ended_within => 300}); my $count = @{$return}; - - my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'return' => $return, count => $count, @@ -272,59 +274,22 @@ sub run_jobs 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, started_seconds_ago => $started_seconds_ago, updated_seconds_ago => $updated_seconds_ago, }}); - # TODO: Make this a Words->decypher_string() method - my $say_progress = ""; - if ($job_progress) - { - foreach my $message (split/\n/, $job_progress) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { message => $message }}); - if ($message =~ /^(.*?),(.*)$/) - { - my $key = $1; - my $variable_string = $2; - my $variables = {}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - key => $key, - variable_string => $variable_string, - }}); - foreach my $pair (split/,/, $variable_string) - { - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { pair => $pair }}); - my $name = ""; - my $value = ""; - if ($pair =~ /^!!(.*?)!(.*)!!$/) - { - $name = $1; - $value = $2; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - name => $name, - value => $value, - }}); - } - elsif ($pair =~ /^!!(.*?)!!!$/) - { - $name = $1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { name => $name }}); - } - else - { - # what?! - } - $variables->{$name} = $value; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "variables->$name" => $variables->{$name} }}); - } - - $say_progress = $anvil->Words->string({key => $key, variables => $variables}), - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "say_progress" => $say_progress }}); - } - } - } + # Convert the double-banged strings into a proper message. + my $say_title = $job_title ? $anvil->Words->parse_banged_string({debug => 2, json_escape => 1, key_string => $job_title}) : ""; + my $say_description = $job_description ? $anvil->Words->parse_banged_string({debug => 2, json_escape => 1, key_string => $job_description}) : ""; + my $say_status = $job_progress ? $anvil->Words->parse_banged_string({debug => 2, json_escape => 1, key_string => $job_status}) : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + job_title => $job_title, + say_description => $say_description, + say_status => $say_status, + }}); # Add this to the jobs.json file $jobs_file .= "{ \"job_uuid\":\"".$job_uuid."\", @@ -332,10 +297,17 @@ sub run_jobs \"job_data\":\"".$job_data."\", \"job_picked_up_at\":\"".$job_picked_up_at."\", \"job_updated\":\"".$job_updated."\", + \"job_name\":\"".$job_name."\", \"job_progress\":\"".$job_progress."\", + \"job_title\":\"".$say_title."\", + \"job_description\":\"".$say_description."\", + \"job_status\":\"".$say_status."\", \"started_seconds_ago\":\"".$started_seconds_ago."\", \"updated_seconds_ago\":\"".$updated_seconds_ago."\" }, \n"; + # If the job is done, move on. + next if $job_progress eq "100"; + # See if the job was picked up by another running instance. if ($job_picked_up_by) { diff --git a/tools/anvil-prep-database b/tools/anvil-prep-database index 338f3c3b..2f19b29a 100755 --- a/tools/anvil-prep-database +++ b/tools/anvil-prep-database @@ -26,7 +26,7 @@ if (($running_directory =~ /^\./) && ($ENV{PWD})) # Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete. $| = 1; -my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 0}); +my $anvil = Anvil::Tools->new({log_level => 3, log_secure => 0}); # Read switches $anvil->Get->switches; diff --git a/tools/anvil-update-system b/tools/anvil-update-system index e49cded5..e6600aa6 100755 --- a/tools/anvil-update-system +++ b/tools/anvil-update-system @@ -53,8 +53,37 @@ if (not $anvil->data->{sys}{database}{connections}) $anvil->nice_exit({exit_code => 1}); } -# Did we get called with a job UUID? +# Did we get called with a job UUID? If not, try to find a pending job and take it. $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }}); +if (not $anvil->data->{switches}{'job-uuid'}) +{ + # See if a job is waiting to run. + my $query = " +SELECT + job_uuid +FROM + jobs +WHERE + job_command LIKE '".$THIS_FILE."%' +AND + job_progress != '100' +AND + job_host_uuid = ".$anvil->data->{sys}{database}{use_handle}->quote($anvil->Get->host_uuid)." +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, 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 => 2, list => { + results => $results, + count => $count, + }}); + if ($count == 1) + { + # Found it + $anvil->data->{jobs}{job_uuid} = defined $results->[0]->[0] ? $results->[0]->[0] : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }}); + } +} if ($anvil->data->{switches}{'job-uuid'}) { # Is it set and valid? @@ -119,7 +148,8 @@ print $THIS_FILE."; time: [".time."], running with PID: [".$$."]\n"; update_progress($anvil, 1, "message_0033"); sleep 10; print $THIS_FILE."; time: [".time."], exiting\n"; -update_progress($anvil, 2, "message_0034"); +update_progress($anvil, 2, "message_0035,!!size!42M!!"); +update_progress($anvil, 3, "message_0017,!!hostname!neutron!!,!!bad_hostname!mermaid!!"); exit; run_os_update($anvil);