diff --git a/Anvil/Tools/Job.pm b/Anvil/Tools/Job.pm
index f53129be..eedda4e3 100755
--- a/Anvil/Tools/Job.pm
+++ b/Anvil/Tools/Job.pm
@@ -210,6 +210,10 @@ This is the UUID of the job to update. If it isn't set, but C<< jobs::job_uuid >
If set, this message will be appended to C<< job_status >>. If set to 'C<< clear >>', previous records will be removed.
+=head3 picked_up_by (optional, default '$$' (caller's PID))
+
+If set, this is used for the C<< job_picked_up_by >> column. If it isn't set, the process ID of the caller is used.
+
=head3 progress (required)
This is a number to set the current progress to.
@@ -222,15 +226,22 @@ sub update_progress
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
- my $job_uuid = defined $parameter->{job_uuid} ? $parameter->{job_uuid} : "";
- my $message = defined $parameter->{message} ? $parameter->{message} : "";
- my $progress = defined $parameter->{progress} ? $parameter->{progress} : "";
+ my $job_uuid = defined $parameter->{job_uuid} ? $parameter->{job_uuid} : "";
+ my $message = defined $parameter->{message} ? $parameter->{message} : "";
+ 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},
}});
+ if ($picked_up_by eq "")
+ {
+ $picked_up_by = $$;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { picked_up_by => $picked_up_by }});
+ }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { job_uuid => $job_uuid }});
if ((not $job_uuid) && ($anvil->data->{jobs}{job_uuid}))
@@ -269,14 +280,13 @@ sub update_progress
}
# Get the current job_status and append this new one.
- my $job_picked_up_by = $$;
my $job_picked_up_at = 0;
my $job_status = "";
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { message => $message, job_picked_up_by => $job_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")
{
- $job_picked_up_by = 0;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { job_picked_up_by => $job_picked_up_by }});
+ $picked_up_by = 0;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { picked_up_by => $picked_up_by }});
}
else
{
@@ -363,7 +373,7 @@ WHERE
debug => $debug,
update_progress_only => 1,
job_uuid => $job_uuid,
- job_picked_up_by => $job_picked_up_by,
+ job_picked_up_by => $picked_up_by,
job_picked_up_at => $job_picked_up_at,
job_progress => $progress,
job_status => $job_status,
diff --git a/Anvil/Tools/System.pm b/Anvil/Tools/System.pm
index 4cc9dd56..e1470e1f 100755
--- a/Anvil/Tools/System.pm
+++ b/Anvil/Tools/System.pm
@@ -882,6 +882,36 @@ sub get_ips
return(0);
}
+=head2 get_uptime
+
+This returns, in seconds, how long the host has been up and running for.
+
+This method takes no parameters.
+
+=cut
+sub get_uptime
+{
+ 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 => "System->_is_local()" }});
+
+ my $uptime = $anvil->Storage->read_file({
+ force_read => 1,
+ cache => 0,
+ file => $anvil->data->{path}{proc}{uptime},
+ });
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uptime => $uptime }});
+
+ # Clean it up. We'll have gotten two numbers, the uptime in seconds (to two decimal places) and the
+ # total idle time. We only care about the int number.
+ $uptime =~ s/^(\d+)\..*$/$1/;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uptime => $uptime }});
+
+ return($uptime);
+}
+
=head2 hostname
Get or set the local hostname. The current (or new) "static" (traditional) host name and the "pretty" (descriptive) host names are returned.
diff --git a/share/words.xml b/share/words.xml
index c131d398..25f4ec43 100644
--- a/share/words.xml
+++ b/share/words.xml
@@ -372,6 +372,10 @@ The database connection error was:
Writing: [#!variable!to_write!#] record(s) to resync the database on: [#!variable!host_name!#].
The connection to the database on: [#!variable!host!#] isn't established, trying again...
The connection to the database on: [#!variable!host!#] has been successfully established.
+ The system has only been running for: [#!variable!uptime!#] seconds. To minimize the impact of a bug causing a rapid reboot cycle, the request to: [#!variable!task!#] will be paused until the system has been running for at least ten minutes. We will proceed in: [#!variable!difference!#] seconds (at #!variable!say_time!#).
+ power off
+ reboot
+ Delay complete, proceeding with the #!variable!task!# operation now.
Test
diff --git a/tools/anvil-daemon b/tools/anvil-daemon
index 66d33723..79e54b6e 100755
--- a/tools/anvil-daemon
+++ b/tools/anvil-daemon
@@ -207,19 +207,10 @@ sub boot_time_tasks
my ($anvil) = @_;
# If the uptime is less than ten minutes, clear the reboot flag.
- my $uptime = $anvil->Storage->read_file({
- force_read => 1,
- cache => 0,
- file => $anvil->data->{path}{proc}{uptime},
- });
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { uptime => $uptime }});
-
- # Clean it up. We'll have gotten two numbers, the uptime in seconds (to two decimal places) and the
- # total idle time. We only care about the int number.
- $uptime =~ s/^(\d+)\..*$/$1/;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { uptime => $uptime }});
+ my $uptime = $anvil->System->get_uptime;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uptime => $uptime }});
- # Now find out if a reboot is needed and when it was last changed.
+ # Now find out if a reboot is listed as needed and when it was last changed.
my $reboot_needed = 0;
my $changed_seconds_ago = 0;
my $query = "
@@ -235,9 +226,10 @@ AND
AND
variable_name = 'reboot::needed'
;";
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { 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 => 3, list => {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
@@ -246,7 +238,7 @@ AND
$reboot_needed = $results->[0]->[0];
$changed_seconds_ago = $results->[0]->[1];
$changed_seconds_ago =~ s/^(\d+)\..*$/$1/;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
reboot_needed => $reboot_needed,
changed_seconds_ago => $changed_seconds_ago,
}});
@@ -255,34 +247,36 @@ AND
# If a reboot is needed, see if the uptime is less than the time since the reboot needed flag was
# set. If the uptime is less, then the system rebooted since it was requested so clear it. h/t to
# Lisa Seelye (@thedoh) for this idea!
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
- reboot_needed => $reboot_needed,
- changed_seconds_ago => $changed_seconds_ago,
- uptime => $uptime,
+ my $difference = ($changed_seconds_ago - $uptime);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:reboot_needed" => $reboot_needed,
+ "s2:changed_seconds_ago" => $changed_seconds_ago,
+ "s3:uptime" => $uptime,
+ "s4:difference" => $difference,
}});
if (($reboot_needed) && ($uptime < $changed_seconds_ago))
{
# Clear the reboot request.
- $reboot_needed = $anvil->System->reboot_needed({set => 0});
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { reboot_needed => $reboot_needed }});
+ $reboot_needed = $anvil->System->reboot_needed({debug => 2, set => 0});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reboot_needed => $reboot_needed }});
# Check to see if there was a reboot job in progress. If so, finish it off.
- my $job_uuid = $anvil->Job->get_job_uuid({program => "anvil-manage-power"});
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { job_uuid => $job_uuid }});
+ my $job_uuid = $anvil->Job->get_job_uuid({debug => 2, program => "anvil-manage-power"});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
if ($job_uuid)
{
# Update the percentage to '100' and then clear the old PID.
my $date_time = $anvil->Get->date_and_time();
- if ($anvil->data->{jobs}{job_uuid})
- {
- $anvil->Job->update_progress({
- progress => 100,
- message => "message_0064,!!date_and_time!".$date_time."!!",
- job_uuid => $job_uuid
- });
- }
- $anvil->Job->clear({job_uuid => $job_uuid});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { date_time => $date_time }});
+
+ $anvil->Job->update_progress({
+ debug => 2,
+ progress => 100,
+ message => "message_0064,!!date_and_time!".$date_time."!!",
+ job_uuid => $job_uuid,
+ picked_up_by => 0,
+ });
}
}
diff --git a/tools/anvil-manage-power b/tools/anvil-manage-power
index eb27cf6c..08f5413b 100755
--- a/tools/anvil-manage-power
+++ b/tools/anvil-manage-power
@@ -34,7 +34,7 @@ if (($running_directory =~ /^\./) && ($ENV{PWD}))
my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 1});
-$anvil->Storage->read_config({file => "/etc/anvil/anvil.conf"});
+$anvil->Storage->read_config({file => $anvil->data->{path}{configs}{'anvil.conf'}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
# Read switches
@@ -45,6 +45,7 @@ $anvil->data->{switches}{'y'} = "";
$anvil->data->{switches}{'yes'} = "";
$anvil->data->{switches}{'reboot-needed'} = "";
$anvil->data->{switches}{'job-uuid'} = "";
+$anvil->data->{switches}{'no-delay'} = "";
$anvil->Get->switches;
if ($anvil->data->{switches}{'power-off'})
@@ -58,7 +59,7 @@ if ($anvil->data->{switches}{'yes'})
# Connect to DBs.
$anvil->Database->connect;
-$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"});
+$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
# No databases, exit.
@@ -128,7 +129,7 @@ if ($anvil->data->{switches}{'reboot-needed'} eq "1")
# Enable
if (not $reboot_needed)
{
- $reboot_needed = $anvil->System->reboot_needed({set => 1});
+ $reboot_needed = $anvil->System->reboot_needed({debug => 2, set => 1});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reboot_needed => $reboot_needed }});
print $anvil->Words->string({key => "message_0048"})."\n";
}
@@ -143,7 +144,7 @@ elsif ($anvil->data->{switches}{'reboot-needed'} eq "0")
# Disabled
if ($reboot_needed)
{
- $reboot_needed = $anvil->System->reboot_needed({set => 0});
+ $reboot_needed = $anvil->System->reboot_needed({debug => 2, set => 0});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reboot_needed => $reboot_needed }});
print $anvil->Words->string({key => "message_0050"})."\n";
}
@@ -162,7 +163,7 @@ elsif ($anvil->data->{switches}{'reboot-needed'})
# Get the current state
if ($reboot_needed)
{
- # Report that we're in mainteance mode
+ # Report that we need to reboot
print $anvil->Words->string({key => "message_0053"})."\n";
}
else
@@ -185,9 +186,36 @@ sub do_poweroff
my ($anvil, $task) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { task => $task }});
+ # We'll wait until the system has at least 10 minutes of uptime, unless '--no-wait' was given.
+ my $uptime = $anvil->data->{switches}{'no-wait'} ? 0 : $anvil->System->get_uptime;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "switches::no-wait" => $anvil->data->{switches}{'no-delay'},
+ uptime => $uptime,
+ }});
+
my $say_task = $task eq "poweroff" ? "message_0062" : "message_0063";
my $percent = $task eq "poweroff" ? 100 : 50;
print $anvil->Words->string({key => $say_task})."\n";
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => $say_task});
+
+ # To minimize the trouble of a problem where the reboot needed flag isn't cleared, and so the system
+ # wants to repeatedly reboot, we need to add a delay to not let anvil-daemon ask us to
+ # reboot/power-off until the system uptime is more than ten minutes.
+ if (($uptime) && ($uptime < 600))
+ {
+ # We'll wait until the system has been running for ten minutes.
+ my $difference = 600 - $uptime;
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0224", variables => {
+ task => $task eq "poweroff" ? "#!string!log_0225!#" : "#!string!log_0226!#",
+ difference => $difference,
+ uptime => $uptime,
+ say_time => $anvil->Get->date_and_time({offset => $difference, time_only => 1}),
+ }});
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => $say_task});
+
+ sleep $difference;
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0227", variables => { task => $task eq "poweroff" ? "#!string!log_0225!#" : "#!string!log_0226!#" }});
+ }
# If I don't have a job_uuid, try to find one.
my $job_uuid = "";