diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm
index b381e8a9..1fad5432 100755
--- a/Anvil/Tools/Database.pm
+++ b/Anvil/Tools/Database.pm
@@ -687,6 +687,9 @@ sub connect
my $successful_connections = [];
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{database}})
{
+ # Periodically, autovivication causes and empty key to appear.
+ next if ((not $uuid) or (not $anvil->Validate->is_uuid({uuid => $uuid})));
+
if (($db_uuid) && ($db_uuid ne $uuid))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0191", variables => { db_uuid => $db_uuid, uuid => $uuid }});
@@ -1198,6 +1201,9 @@ sub disconnect
delete $anvil->data->{sys}{database}{use_handle};
delete $anvil->data->{sys}{database}{read_uuid};
+ # Delete any database information (reconnects should re-read anvil.conf anyway).
+ delete $anvil->data->{database};
+
# Set the connection count to 0.
$anvil->data->{sys}{database}{connections} = 0;
@@ -4095,13 +4101,13 @@ sub locking
}});
# Make sure we have a sane lock age
- if ((not defined $anvil->data->{database}{locking}{reap_age}) or
- (not $anvil->data->{database}{locking}{reap_age}) or
- ($anvil->data->{database}{locking}{reap_age} =~ /\D/)
+ if ((not defined $anvil->data->{sys}{database}{locking}{reap_age}) or
+ (not $anvil->data->{sys}{database}{locking}{reap_age}) or
+ ($anvil->data->{sys}{database}{locking}{reap_age} =~ /\D/)
)
{
- $anvil->data->{database}{locking}{reap_age} = $anvil->data->{defaults}{database}{locking}{reap_age};
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "database::locking::reap_age" => $anvil->data->{database}{locking}{reap_age} }});
+ $anvil->data->{sys}{database}{locking}{reap_age} = $anvil->data->{defaults}{database}{locking}{reap_age};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::locking::reap_age" => $anvil->data->{sys}{database}{locking}{reap_age} }});
}
# If I have been asked to check, we will return the variable_uuid if a lock is set.
@@ -4180,7 +4186,7 @@ sub locking
}
# We always check for, and then wait for, locks. Read in the locks, if any. If any are set and they are
- # younger than database::locking::reap_age, we'll hold.
+ # younger than sys::database::locking::reap_age, we'll hold.
my $waiting = 1;
while ($waiting)
{
@@ -4201,7 +4207,7 @@ sub locking
my $lock_source_uuid = $2;
my $lock_time = $3;
my $current_time = time;
- my $timeout_time = $lock_time + $anvil->data->{database}{locking}{reap_age};
+ my $timeout_time = $lock_time + $anvil->data->{sys}{database}{locking}{reap_age};
my $lock_age = $current_time - $lock_time;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
lock_source_name => $lock_source_name,
diff --git a/Anvil/Tools/System.pm b/Anvil/Tools/System.pm
index 2c101499..2cfb9703 100755
--- a/Anvil/Tools/System.pm
+++ b/Anvil/Tools/System.pm
@@ -233,15 +233,15 @@ sub call
# Setup output files
if (($stderr_file) && ($stdout_file))
{
- $process->($stdout_file, $stderr_file);
+ $process->redirect_output($stdout_file, $stderr_file);
}
elsif ($stdout_file)
{
- $process->($stdout_file, undef);
+ $process->redirect_output($stdout_file, undef);
}
elsif ($stderr_file)
{
- $process->(undef, $stderr_file);
+ $process->redirect_output(undef, $stderr_file);
}
my $status = $process->start($shell_call);
diff --git a/share/words.xml b/share/words.xml
index 06e3ffa4..6c6d18c8 100644
--- a/share/words.xml
+++ b/share/words.xml
@@ -88,6 +88,7 @@ Report if a reboot is needed: #!variable!program!#
This system needs to be rebooted.
This system does NOT need to be rebooted.
+ Exiting to '--run-once' switch.
Starting: [#!variable!program!#].
@@ -166,7 +167,7 @@ Connecting to Database with configuration ID: [#!variable!uuid!#]
Database user: [#!variable!user!#] already exists with ID: [#!variable!uuid!#].
users_home() was asked to find the home directory for the user: [#!variable!user!#], but was unable to do so.]]>
SSH session opened without a password to: [#!variable!target!#].
- The database: [#!variable!host!# -> #!variable!name!#] with the ID: [#!variable!uuid!#] did not respond to pings and 'database::#!variable!uuid!#::ping' is not set to '0' in '#!data!path::configs::anvil.conf!#', skipping it.
+ The database: [#!variable!host!# -> #!variable!name!#] with the UUID: [#!variable!uuid!#] did not respond to pings and 'database::#!variable!uuid!#::ping' is not set to '0' in '#!data!path::configs::anvil.conf!#', skipping it.
[ Warning ] - The database: [#!variable!name!#] on host: [#!variable!host!#] with ID: [#!variable!uuid!#] can not be used, skipping it.
The database connection error was:
@@ -323,6 +324,9 @@ The database connection error was:
The user: [#!variable!user!#] logged out successfully.
A system reboot is required, setting the database flag.
A system reboot is required, setting the database flag.
+ Unable to connect to any database. Will try to initialize the local system and then try again.
+ Failed to connect to any databases. Skipping the loop of the daemon.
+ Disconnected from all databases. Will reconnect when entering the main loop.
Test
@@ -514,6 +518,7 @@ The update appears to have not completed successfully. The output was:
#!variable!output!#
====
+
Yes
diff --git a/tools/anvil-daemon b/tools/anvil-daemon
index 605a38d1..db85009d 100755
--- a/tools/anvil-daemon
+++ b/tools/anvil-daemon
@@ -6,8 +6,10 @@
# Exit codes;
# 0 = Normal exit
# 1 = md5sum of this program changed. Exited to reload.
+# 2 = Unable to connect to any database, even after trying to initialize the local system.
#
# TODO:
+# - Need to check what kind of machine this is and not prep the database unless its a dashboard.
#
use strict;
@@ -32,21 +34,58 @@ my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 1});
$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
+# If I have no databases, sleep for a second and then exit (systemd will restart us).
+if (not $anvil->data->{sys}{database}{connections})
+{
+ # Try to configure the local database, and then try to connect again.
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, secure => 0, key => "log_0201"});
+ prep_database($anvil);
+ sleep 1;
+
+ # Try connecting again
+ $anvil->Database->connect();
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
+ if (not $anvil->data->{sys}{database}{connections})
+ {
+ # Still nothing, sleep and exit.
+ print $anvil->Words->string({key => "error_0003"})."\n";
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, secure => 0, key => "error_0003"});
+ $anvil->nice_exit({exit_code => 2});
+ }
+}
+
+# Read switches
+$anvil->data->{switches}{'run-once'} = "";
+$anvil->data->{switches}{'no-run-once'} = "";
+$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);
+run_once($anvil) if not $anvil->data->{switches}{'no-run-once'};
# Calculate my sum so that we can exit if it changes later.
$anvil->Storage->record_md5sums;
# Disconnect. We'll reconnect inside the loop
$anvil->Database->disconnect;
-$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
+$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0203"});
# These are the things we always want running.
while(1)
{
- # Loop and sleep for 2s.
- keep_running($anvil);
+ # Connect to the database(s)
+ $anvil->Storage->read_config({file => "/etc/anvil/anvil.conf"});
+ $anvil->Database->connect;
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
+
+ if ($anvil->data->{sys}{database}{connections})
+ {
+ # Loop and sleep for 2s.
+ keep_running($anvil);
+ }
+ else
+ {
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, secure => 0, key => "log_0202"});
+ }
# Exit if called with '--run-once'
if ($anvil->data->{switches}{'run-once'})
@@ -61,6 +100,13 @@ while(1)
$anvil->nice_exit({code => 1});
}
+ # Exit if 'run-once' selected.
+ if ($anvil->data->{switches}{'run-once'})
+ {
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "warn", key => "message_0055"});
+ $anvil->nice_exit({code => 0});
+ }
+
# Sleep now.
sleep 2;
}
@@ -78,13 +124,7 @@ sub run_once
my ($anvil) = @_;
# Check that the database is ready.
- my $shell_call = $anvil->data->{path}{exe}{'anvil-prep-database'};
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
- my $database_output = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
- if ($database_output)
- {
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { database_output => $database_output }});
- }
+ prep_database($anvil);
# If the uptime is less than ten minutes, clear the reboot flag.
my $uptime = $anvil->Storage->read_file({
@@ -115,6 +155,22 @@ sub run_once
return(0);
}
+# Configure the local database, if needed.
+sub prep_database
+{
+ my ($anvil) = @_;
+
+ my $shell_call = $anvil->data->{path}{exe}{'anvil-prep-database'};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
+ my $database_output = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
+ if ($database_output)
+ {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { database_output => $database_output }});
+ }
+
+ return(0);
+}
+
# These are tools that need to keep running.
sub keep_running
{
@@ -193,9 +249,7 @@ SELECT
job_data,
job_picked_up_by,
job_picked_up_at,
- extract(epoch from job_picked_up_at),
job_updated,
- extract(epoch from modified_date)
job_progress
FROM
jobs
@@ -212,44 +266,43 @@ WHERE
}});
foreach my $row (@{$results})
{
- my $job_uuid = $row->[0];
- my $job_command = $row->[1];
- my $job_data = defined $row->[2] ? $row->[2] : "";
- my $job_picked_up_by = $row->[3];
- my $job_picked_up_at = $row->[4];
- my $unix_picked_up = $row->[3];
- my $job_updated = $row->[5];
- my $unix_updated = $row->[6];
- my $job_progress = $row->[7];
- my $started_seconds_ago = time - $unix_picked_up;
- my $updated_seconds_ago = time - $unix_updated;
+ my $job_uuid = $row->[0];
+ my $job_command = $row->[1];
+ my $job_data = defined $row->[2] ? $row->[2] : "";
+ my $job_picked_up_by = $row->[3];
+ my $job_picked_up_at = $row->[4];
+ my $job_updated = $row->[5];
+ my $job_progress = $row->[6];
+ my $started_seconds_ago = $job_picked_up_at ? (time - $job_picked_up_at) : 0;
+ my $updated_seconds_ago = $job_updated ? (time - $job_updated) : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
job_uuid => $job_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,
- unix_picked_up => $unix_picked_up,
job_updated => $job_updated,
- unix_updated => $unix_updated,
job_progress => $job_progress,
started_seconds_ago => $started_seconds_ago,
updated_seconds_ago => $updated_seconds_ago,
}});
+ # This will be appended to the json file
+ my $json_string = "{ \"job_uuid\":\"".$job_uuid."\", \"job_command\":\"".$job_command."\", \"job_data\":\"".$job_data."\", \"job_picked_up_at\":\"".$job_picked_up_at."\", \"job_updated\":\"".$job_updated."\", \"job_progress\":\"".$job_progress."\", \"job_progress\":\"".$job_progress."\", \"started_seconds_ago\":\"".$started_seconds_ago."\", \"updated_seconds_ago\":\"".$updated_seconds_ago."\" }, \n";
+
# If the job is done, see if it was recently enough to record in the jobs.json file.
if ($job_progress eq "100")
{
# Record in JSON if it wass last updated less than 5 minutes ago.
if ($updated_seconds_ago < 300)
{
- $jobs_file .= "{ \"job_uuid\":\"".$job_uuid."\", \"job_command\":\"".$job_command."\", \"job_data\":\"".$job_data."\", \"job_picked_up_at\":\"".$job_picked_up_at."\", \"job_updated\":\"".$job_updated."\", \"job_progress\":\"".$job_progress."\", \"job_progress\":\"".$job_progress."\", \"started_seconds_ago\":\"".$started_seconds_ago."\", \"updated_seconds_ago\":\"".$updated_seconds_ago."\" }, \n";
+ $jobs_file .= $json_string;
}
next;
}
# If we're here, the job isn't done. So first, record it.
- $jobs_file .= "{ \"job_uuid\":\"".$job_uuid."\", \"job_command\":\"".$job_command."\", \"job_data\":\"".$job_data."\", \"job_picked_up_at\":\"".$job_picked_up_at."\", \"job_updated\":\"".$job_updated."\", \"job_progress\":\"".$job_progress."\", \"job_progress\":\"".$job_progress."\", \"started_seconds_ago\":\"".$started_seconds_ago."\", \"updated_seconds_ago\":\"".$updated_seconds_ago."\" }, \n";
+ $jobs_file .= $json_string;
# See if the job was picked up by another running instance.
if ($job_picked_up_by)
@@ -300,6 +353,19 @@ WHERE
# Close the jobs file.
$jobs_file .= "]}\n";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { jobs_file => $jobs_file }});
+
+ # Write the JSON file
+ my $output_json = $anvil->data->{path}{directories}{html}."/status/jobs.json";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output_xml => $output_json }});
+ $anvil->Storage->write_file({
+ file => $output_json,
+ body => $jobs_file,
+ overwrite => 1,
+ mode => "0644",
+ user => "apache",
+ group => "apache"
+ });
return(0);
}
diff --git a/tools/anvil-update-system b/tools/anvil-update-system
index 901b1d10..7e21fd00 100755
--- a/tools/anvil-update-system
+++ b/tools/anvil-update-system
@@ -35,7 +35,6 @@ my $anvil = Anvil::Tools->new({log_level => 2, log_secure => 1});
$anvil->Storage->read_config({file => "/etc/anvil/anvil.conf"});
# Read switches
-$anvil->data->{switches}{'no-reboot'} = 0;
$anvil->data->{switches}{'job-uuid'} = "";
$anvil->Get->switches;
@@ -110,8 +109,11 @@ WHERE
# Mark that we're starting
update_progress($anvil, 1, "message_0033");
-my ($reboot) = run_os_update($anvil);
-$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reboot => $reboot }});
+print $THIS_FILE." running with PID: [".$$."]\n"
+sleep 60;
+exit;
+
+run_os_update($anvil);
# We're done updating
my $reboot_needed = $anvil->System->reboot_needed({debug => 2, set => 1});