From 6bca354d87da939680367a95c3dfe231e060d913 Mon Sep 17 00:00:00 2001 From: Digimer Date: Fri, 27 Sep 2019 01:31:29 -0400 Subject: [PATCH] * More progress on managing/removing back keys. Updated it to have jobs list one or more state_uuid(s) to be removed, instead of bulk-removing all found back keys. Created the web interface to let the user select the keys to be deleted. Works partially now, but bugs need to be removed. Signed-off-by: Digimer --- cgi-bin/striker | 137 +++++++--- html/skins/alteeve/main.css | 9 + html/skins/alteeve/striker.html | 97 ++++++- share/words.xml | 23 +- tools/anvil-manage-keys | 444 ++++++++++++++++++++------------ 5 files changed, 510 insertions(+), 200 deletions(-) diff --git a/cgi-bin/striker b/cgi-bin/striker index b6e83549..579529d6 100755 --- a/cgi-bin/striker +++ b/cgi-bin/striker @@ -500,39 +500,60 @@ sub process_keys ### TODO: Left off here... Create a check-box list of state_uuid(s) the user selected, if any, and store them as a comma-separated list. ### NOTE: This doesn't update Striker (the Alteeve) stack yet, just the base OK. - $anvil->data->{cgi}{confirm}{value} = "" if not defined $anvil->data->{cgi}{confirm}{value}; - if ($anvil->data->{cgi}{confirm}{value}) + my $show_list = 1; + $anvil->data->{cgi}{'delete'}{value} = "" if not defined $anvil->data->{cgi}{'delete'}{value}; + if ($anvil->data->{cgi}{'delete'}{value}) { # Record the job! my $job_data = ""; + foreach my $key (sort {$a cmp $b} keys %{$anvil->data->{cgi}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { key => $key }}); + if ($key =~ /^state_uuid_(.*)$/) + { + my $state_uuid = $1; + $show_list = 0; + $job_data .= $state_uuid.","; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + state_uuid => $state_uuid, + show_list => $show_list, + job_data => $job_data, + }}); + } + } + $job_data =~ s/,$//; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_data => $job_data }}); - - die; - my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ - file => $THIS_FILE, - line => __LINE__, - job_command => $anvil->data->{path}{exe}{'anvil-manage-keys'}, - job_data => "", - job_name => "manage::keys", - job_title => "job_0056", - job_description => "job_0057", - job_progress => 0, - job_host_uuid => $anvil->data->{sys}{host_uuid}, - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }}); - - # We don't need to store anything as hidden variables, we'll read it back from the database - # later. - $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => { - title_id => "", - message_id => "", - reload_url => "/cgi-bin/".$THIS_FILE, - title => "#!string!job_0056!#", - description => "#!string!job_0057!#", - }}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); + if ($job_data) + { + my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ + file => $THIS_FILE, + line => __LINE__, + job_command => $anvil->data->{path}{exe}{'anvil-manage-keys'}, + job_data => $job_data, + job_name => "manage::broken_keys", + job_title => "job_0056", + job_description => "job_0057", + job_progress => 0, + job_host_uuid => $anvil->data->{sys}{host_uuid}, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }}); + + # We don't need to store anything as hidden variables, we'll read it back from the database + # later. + $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => { + title_id => "", + message_id => "", + reload_url => "/cgi-bin/".$THIS_FILE, + title => "#!string!job_0056!#", + description => "#!string!job_0057!#", + }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "form::body" => $anvil->data->{form}{body} }}); + } } - else + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { show_list => $show_list }}); + if ($show_list) { # Get a list of bad keys we know about and ask the user which they want to remove my $query = " @@ -543,7 +564,7 @@ SELECT state_note FROM states -AND +WHERE state_name LIKE 'host_key_changed::%' ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); @@ -575,16 +596,58 @@ AND state_name => $state_name, state_note => $state_note, }}); + + my $bad_file = ""; + my $bad_line = ""; + foreach my $pair (split/,/, $state_note) + { + my ($variable, $value) = ($pair =~ /^(.*?)=(.*)$/); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + pair => $pair, + variable => $variable, + value => $value, + }}); + if ($variable eq "file") + { + $bad_file = $value; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_file => $bad_file }}); + } + if ($variable eq "line") + { + $bad_line = $value; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_line => $bad_line }}); + } + } + my ($target, $user) = ($state_name =~ /host_key_changed::(.*)::(.*)$/); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + target => $target, + user => $user, + bad_file => $bad_file, + bad_line => $bad_line, + }}); + + + my $checkbox_key = "state_uuid_".$state_uuid; + my $checked = ""; + if ((exists $anvil->data->{cgi}{$checkbox_key}) && ($anvil->data->{cgi}{$checkbox_key}{value})) + { + $checked = "checked"; + } + $bad_key_list .= $anvil->Template->get({file => "striker.html", name => "broken-key-entry", variables => { + checkbox_name => $checkbox_key, + checkbox_checked => $checked, + target => $target, + user => $user, + file => $bad_file, + line => $bad_line, + }}); } + + #Show the screen the confirm the addition. + $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "broken-key-list", variables => { + bad_keys => $bad_key_list, + }}); } - - die; - #Show the screen the confirm the addition. - $anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "confirm-action", variables => { - title => "#!string!job_0056!#", - message => "#!string!!#", - hidden_fields => "", - }}); } return(0); diff --git a/html/skins/alteeve/main.css b/html/skins/alteeve/main.css index 811182fd..a56b3599 100644 --- a/html/skins/alteeve/main.css +++ b/html/skins/alteeve/main.css @@ -15,6 +15,9 @@ a { color: #f2f2f2; text-decoration: none; } +a.highlight { + color: #ff80ee; +} body { font-family: 'Dejavu Sans', Arial, Helvetica, Verdana, Sans-Serif; @@ -367,3 +370,9 @@ tr.data_row { text-align: left; font-size: 0.9em; } + +.warning { + color: #dc9012; + font-size: 1.1em; + font-weight: bold; +} diff --git a/html/skins/alteeve/striker.html b/html/skins/alteeve/striker.html index f192bbc9..fbe65501 100644 --- a/html/skins/alteeve/striker.html +++ b/html/skins/alteeve/striker.html @@ -1,3 +1,96 @@ + + + + + + + #!variable!user!# + + + #!variable!target!# + + + #!variable!file!# + + + #!variable!line!# + + + + + + + + + + + + + + + + + + + + + +
+   +
+ + + + + + + + + + + + + + + + + +#!variable!bad_keys!# + + + + + + + + + +
+   + + #!string!header_0013!# + + #!string!header_0012!# + + #!string!header_0014!# + + #!string!header_0015!# +
+   +
+   +
+ +
+
+   +
+ + @@ -446,12 +539,12 @@
diff --git a/share/words.xml b/share/words.xml index cc6d6626..7fa5c704 100644 --- a/share/words.xml +++ b/share/words.xml @@ -800,6 +800,10 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st Peer ConnectionsPingJobs + Target + User + File + LineWelcome! Lets setup your #!string!brand_0003!# dashboard... @@ -936,6 +940,15 @@ Here we will inject 't_0006', which injects 't_0001' which has a variable: [#!st There are one or more broken keys, blocking access to target machines. If a target has been rebuilt, you can clear the old keys here.Manage Changed KeysThere are no known bad keys at this time. + Add or remove Striker peers. + Peer dashboards are Striker machines whose databases this Striker will use to record data. If this machine ever needs to be replaced, or goes offline for a period of time, it will automatically pull the data back from any peers that it is missing. + +
+Warning: If you haven't rebuilt the target, then the "broken key" could actually be a "man in the middle" attack. Verify that the target has changed for a known reason before proceeding!
+
+If you are comfortable that the target has changed for a known reason, you can select the broken keys below to have them removed.
+ ]]>
#!variable!number!#/sec @@ -1011,7 +1024,10 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec [ Error ] - The line number: [#!variable!line!#] in: [#!variable!file!#] does not appear to be for the target: [#!variable!target!#]. Has the file already been updated? Skipping it. Rewriing: [#!variable!file!#]. Manage Keys - The bad keys will be removed from the specified files. + The selected bad key(s) will be removed from the specified files. + The state UUID: [#!variable!state_uuid!#] is for the machine with the host UUID: [#!variable!host_uuid!#], which is not us. This is probably a progrem error, skipping this. + [ Error ] - There was a problem writing the file: [#!variable!file!#]. Details will be found in the logs. + Success! The file: [#!variable!file!#] has been updated. The IP address will change. You will need to reconnect after applying these changes. @@ -1122,6 +1138,11 @@ Failed to generate an RSA public key for the user: [#!variable!user!#]. The outp There was a problem adding out database to the target's anvil.conf file. Unable to connect to the database, unable to read the details of the key to remove. Did not find any offending keys on this host, exiting. + Job data not found for job_uuid: [#!variable!job_uuid!#]. + No job UUID was passwed . + The job_uuid: [#!variable!job_uuid!#] appears valid, but there was no job_data. + The state UUID: [#!variable!state_uuid!#] does not appear to be a valid UUID. + No (good) state UUIDs found, unable to run this job. Yes diff --git a/tools/anvil-manage-keys b/tools/anvil-manage-keys index 46d7af6f..17881492 100755 --- a/tools/anvil-manage-keys +++ b/tools/anvil-manage-keys @@ -8,8 +8,8 @@ # Exit codes; # 0 = Normal exit. # 1 = No database connection. -# 2 = No offending keys found. -# 3 = +# 2 = Job not found. +# 3 = No offending keys found. # use strict; @@ -46,187 +46,315 @@ if (not $anvil->data->{sys}{database}{connections}) $anvil->nice_exit({exit_code => 1}); } -### TODO: Store the state_uuid(s) of the key(s) to remove. -# If we don't have a state_uuid, pick it up from the job_data +# Pick up the job details +$anvil->data->{switches}{'job-uuid'} = ""; +$anvil->Get->switches; +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'}, +}}); + +# Load data. +load_job_data($anvil); + +# Process the bad keys +process_keys($anvil); + +# Done. +update_progress($anvil, 100, "job_0051"); +$anvil->nice_exit({code => 0}); -# Read in the details and make sure the bad the bad key is on our system. -my $query = "SELECT - state_uuid, + +############################################################################################################# +# Functions # +############################################################################################################# + +sub process_keys +{ + my ($anvil) = @_; + + foreach my $state_uuid (@{$anvil->data->{state_uuids}}) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { state_uuid => $state_uuid }}); + my $query = " +SELECT + state_host_uuid, state_name, state_note FROM states WHERE - state_host_uuid = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid})." -AND - state_name LIKE 'host_key_changed::%' + state_uuid = ".$anvil->Database->quote($state_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 (not $count) -{ - # No bad keys found on this host. - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0078"}); - sleep 10; - $anvil->nice_exit({exit_code => 2}); -} -my $progress = 0; -update_progress($anvil, 0, "clear"); -$progress += 5; -update_progress($anvil, $progress, "job_0048"); -$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0048"}); -foreach my $row (@{$results}) -{ - - my $state_uuid = $row->[0]; - my $state_name = $row->[1]; - my $state_note = $row->[2]; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - state_uuid => $state_uuid, - state_name => $state_name, - state_note => $state_note, - }}); - - # Pull out the details. - my $bad_file = ""; - my $bad_line = ""; - foreach my $pair (split/,/, $state_note) - { - my ($variable, $value) = ($pair =~ /^(.*?)=(.*)$/); + $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 => { - pair => $pair, - variable => $variable, - value => $value, + results => $results, + count => $count, }}); - if ($variable eq "file") + if (not $count) { - $bad_file = $value; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_file => $bad_file }}); + # No bad keys found on this host. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0078"}); + sleep 10; + $anvil->nice_exit({exit_code => 2}); } - if ($variable eq "line") + foreach my $row (@{$results}) { - $bad_line = $value; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_line => $bad_line }}); + + my $state_host_uuid = $row->[0]; + my $state_name = $row->[1]; + my $state_note = $row->[2]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:sys::host_uuid' => $anvil->data->{sys}{host_uuid}, + 's2:state_host_uuid' => $state_host_uuid, + 's3:state_name' => $state_name, + 's4:state_note' => $state_note, + }}); + + # Is this meant for us? + if ($state_host_uuid ne $anvil->data->{sys}{host_uuid}) + { + # Um... + $anvil->data->{job}{progress} += 10; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0058,!!state_uuid!".$state_uuid."!!,!!host_uuid!".$state_host_uuid."!!"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0058", variables => { + state_uuid => $state_uuid, + host_uuid => $state_host_uuid, + }}); + next; + } + + # Pull out the details. + my $bad_file = ""; + my $bad_line = ""; + foreach my $pair (split/,/, $state_note) + { + my ($variable, $value) = ($pair =~ /^(.*?)=(.*)$/); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + pair => $pair, + variable => $variable, + value => $value, + }}); + if ($variable eq "file") + { + $bad_file = $value; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_file => $bad_file }}); + } + if ($variable eq "line") + { + $bad_line = $value; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bad_line => $bad_line }}); + } + } + my ($target, $user) = ($state_name =~ /host_key_changed::(.*)::(.*)$/); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + target => $target, + user => $user, + bad_file => $bad_file, + bad_line => $bad_line, + }}); + + $anvil->data->{job}{progress} += 5; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0049,!!line!:".$bad_line.",!!file!".$bad_file."!!,!!target!".$target."!!"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0049", variables => { + line => $bad_line, + file => $bad_file, + target => $target, + }}); + + # Read in the file, if it exists. + if (not -e $bad_file) + { + $anvil->data->{job}{progress} += 10; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0050,!!file!".$bad_file."!!"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0050", variables => { file => $bad_file }}); + + # Remove this job and go on to the next bad key (if any). + delete_state($anvil, $state_uuid); + next; + } + + # Read in the file + my ($old_body) = $anvil->Storage->read_file({file => $bad_file}); + if ($old_body eq "!!error!!") + { + # Failed to read the file + $anvil->data->{job}{progress} += 10; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0052,!!file!".$bad_file."!!"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0052", variables => { file => $bad_file }}); + + # Remove this job and go on to the next bad key (if any). + delete_state($anvil, $state_uuid); + next; + } + + # Find our key + my $line_number = 0; + my $new_body = ""; + my $update = 0; + foreach my $line (split/\n/, $old_body) + { + $line_number++; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:line_number' => $line_number, + 's2:bad_line' => $bad_line, + 's3:line' => $line, + }}); + if ($line_number eq $bad_line) + { + # Verify that this is, indeed, the right line. + if ($line =~ /^$target /) + { + # Found it! + $anvil->data->{job}{progress} += 5; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0053"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0053"}); + $update = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }}); + } + else + { + # Line found, but not for the target. + $anvil->data->{job}{progress} += 10; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0054,!!line!".$bad_line."!!,!!file!".$bad_file."!!,!!target!".$target."!!"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0054", variables => { + line => $bad_line, + file => $bad_file, + target => $target, + }}); + + # Remove this job and go on to the next bad key (if any). + delete_state($anvil, $state_uuid); + last; + } + } + else + { + $new_body .= $line."\n"; + } + } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:old_body' => $old_body, + 's2:new_body' => $new_body, + 's3:update' => $update, + }}); + if ($update) + { + # Write the file out. + $anvil->data->{job}{progress} += 5; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0055,!!file!".$bad_file."!!"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0055", variables => { file => $bad_file }}); + + my $error = $anvil->Storage->write_file({ + body => $new_body, + debug => 2, + file => $bad_file, + overwrite => 1, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, list => { error => $error }}); + if ($error) + { + $anvil->data->{job}{progress} += 5; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0059,!!file!".$bad_file."!!"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0059", variables => { file => $bad_file }}); + } + else + { + # Success! + delete_state($anvil, $state_uuid); + $anvil->data->{job}{progress} += 5; $anvil->data->{job}{progress} = 95 if $anvil->data->{job}{progress} > 95; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0060,!!file!".$bad_file."!!"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0060", variables => { file => $bad_file }}); + } + } + } } - my ($target, $user) = ($state_name =~ /host_key_changed::(.*)::(.*)$/); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - target => $target, - user => $user, - bad_file => $bad_file, - bad_line => $bad_line, - }}); - $progress += 5; $progress = 95 if $progress > 95; - update_progress($anvil, $progress, "job_0049,!!line!:".$bad_line.",!!file!".$bad_file."!!,!!target!".$target."!!"); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0049", variables => { - line => $bad_line, - file => $bad_file, - target => $target, - }}); + return(0); +} + +# Load the job data or exit +sub load_job_data +{ + my ($anvil) = @_; - # Read in the file, if it exists. - if (not -e $bad_file) + if (not $anvil->data->{switches}{'job-uuid'}) { - $progress += 10; $progress = 95 if $progress > 95; - update_progress($anvil, $progress, "job_0050,!!file!".$bad_file."!!"); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0050", variables => { file => $bad_file }}); - - # Remove this job and go on to the next bad key (if any). - delete_state($anvil, $state_uuid); - next; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0080"}); + $anvil->nice_exit({exit_code => 1}); } - # Read in the file - my ($old_body) = $anvil->Storage->read_file({file => $bad_file}); - if ($old_body eq "!!error!!") + my $query = "SELECT job_data FROM jobs WHERE job_uuid = ".$anvil->Database->quote($anvil->data->{switches}{'job-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 (not $count) { - # Failed to read the file - $progress += 10; $progress = 95 if $progress > 95; - update_progress($anvil, $progress, "job_0052,!!file!".$bad_file."!!"); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0052", variables => { file => $bad_file }}); - - # Remove this job and go on to the next bad key (if any). - delete_state($anvil, $state_uuid); - next; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0079", variables => { + job_uuid => $anvil->data->{switches}{'job-uuid'}, + }}); + $anvil->nice_exit({exit_code => 1}); } - # Find our key - my $line_number = 0; - my $new_body = ""; - my $update = 0; - foreach my $line (split/\n/, $old_body) + # Pick up the data. + my $job_data = $results->[0]->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_data => $job_data }}); + if (not $job_data) { - $line_number++; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 's1:line_number' => $line_number, - 's2:bad_line' => $bad_line, - 's3:line' => $line, + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0081", variables => { + job_uuid => $anvil->data->{switches}{'job-uuid'}, }}); - if ($line_number eq $bad_line) + $anvil->nice_exit({exit_code => 1}); + } + + # Pick up the job. + $anvil->data->{job}{progress} = 0; + update_progress($anvil, 0, "clear"); + + $anvil->data->{job}{progress} += 5; + update_progress($anvil, $anvil->data->{job}{progress}, "job_0048"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0048"}); + + # Break the job up. + $anvil->data->{state_uuids} = []; + foreach my $state_uuid (split/,/, $job_data) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { state_uuid => $state_uuid }}); + if ($anvil->Validate->is_uuid({uuid => $state_uuid})) { - # Verify that this is, indeed, the right line. - if ($line =~ /^$target /) - { - # Found it! - $progress += 5; $progress = 95 if $progress > 95; - update_progress($anvil, $progress, "job_0053"); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0053"}); - $update = 1; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { update => $update }}); - last; - } - else - { - # Line found, but not for the target. - $progress += 10; $progress = 95 if $progress > 95; - update_progress($anvil, $progress, "job_0054,!!line!".$bad_line."!!,!!file!".$bad_file."!!,!!target!".$target."!!"); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0054", variables => { - line => $bad_line, - file => $bad_file, - target => $target, - }}); - - # Remove this job and go on to the next bad key (if any). - delete_state($anvil, $state_uuid); - last; - } + push @{$anvil->data->{state_uuids}}, $state_uuid; } else { - $new_body .= $line."\n"; + # Invalid, skip it. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0082", variables => { + state_uuid => $state_uuid, + }}); } } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 's1:old_body' => $old_body', - 's2:new_body' => $new_body, - 's3:update' => $update, - }}); - if ($update) + my $uuid_count = @{$anvil->data->{state_uuids}}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid_count => $uuid_count }}); + + # Did I find any actual UUIDs? + if (not $uuid_count) { - # Write the file out. - $progress += 5; $progress = 95 if $progress > 95; - update_progress($anvil, $progress, "job_0055,!!file!".$bad_file."!!"); - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0055", variables => { file => $bad_file }}); + # Nope. + update_progress($anvil, 100, "error_0083"); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "error_0083"}); } + return(0); } -# Done. -update_progress($anvil, 100, "job_0051"); -$anvil->nice_exit({code => 0}); - - -############################################################################################################# -# Functions # -############################################################################################################# - # This deletes a state entry. sub delete_state { @@ -236,7 +364,7 @@ sub delete_state if ($state_uuid) { my $query = "DELETE FROM states WHERE state_uuid = ".$anvil->Database->quote($state_uuid).";"; - $anvil->Database->write({debug => 2, query => $merged, source => $THIS_FILE, line => __LINE__}); + $anvil->Database->write({debug => 2, query => $query, source => $THIS_FILE, line => __LINE__}); } return(0); @@ -249,20 +377,16 @@ sub update_progress # Log the progress percentage. $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - progress => $progress, - message => $message, - "jobs::job_uuid" => $anvil->data->{jobs}{job_uuid}, + progress => $progress, + message => $message, }}); - if ($anvil->data->{jobs}{job_uuid}) - { - $anvil->Job->update_progress({ - debug => 3, - progress => $progress, - message => $message, - job_uuid => $anvil->data->{jobs}{job_uuid}, - }); - } + $anvil->Job->update_progress({ + debug => 3, + progress => $progress, + message => $message, + job_uuid => $anvil->data->{switches}{'job-uuid'}, + }); return(0); }