Created a specific check that there's a hosts entry for each DB

* This is meant to deal with a case where, when a DB is added to
  anvil.conf but that new entry is not yet in hosts, the program crashes
  because of a duplicate key when calling insert_or_update_hosts for all
  DBs.

Signed-off-by: digimer <mkelly@alteeve.ca>
main
digimer 7 months ago
parent 3d50f45984
commit ab33c716cb
  1. 117
      Anvil/Tools/Database.pm
  2. 2
      ocf/alteeve/server
  3. 2
      tools/anvil-daemon

@ -19,6 +19,7 @@ my $THIS_FILE = "Database.pm";
# archive_database
# backup_database
# check_file_locations
# check_hosts
# check_lock_age
# check_for_schema
# configure_pgsql
@ -439,6 +440,115 @@ sub check_file_locations
return(0);
}
=head2 check_hosts
This checks to see if there's an entry in the C<< hosts >> table on each database. This is meant to avoid an INSERT on a table with a record already, wich can happen when programs start before initial sync.
This method takes no parameters.
=cut
sub check_hosts
{
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 => "Database->check_hosts()" }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::database::connections" => $anvil->data->{sys}{database}{connections},
}});
if ($anvil->data->{sys}{database}{connections} < 1)
{
# Nothing to do.
return(0);
}
# If we're starting with a new database, which is not yet in the hosts table, we can hit a case where
# this tries to insert into both DBs when it's only missing from one. So to habdle that, we'll
# manually check each DB to see if all hosts are there and, if not, INSERT only into the needed DB.
foreach my $db_uuid (sort {$a cmp $b} keys %{$anvil->data->{database}})
{
# Are we connected?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"db_status::${db_uuid}::access" => $anvil->data->{db_status}{$db_uuid}{access},
}});
next if not $anvil->data->{db_status}{$db_uuid}{access};
# Get the host information from the host.
my $query = "
SELECT
host_ipmi,
host_name,
host_type,
host_key,
host_status
FROM
hosts
WHERE
host_uuid = ".$anvil->Database->quote($db_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({uuid => $db_uuid, 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,
}});
next if not $count;
my $db_host_ipmi = $results->[0]->[0];
my $db_host_name = $results->[0]->[1];
my $db_host_type = $results->[0]->[2];
my $db_host_key = $results->[0]->[3];
my $db_host_status = $results->[0]->[4];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
db_host_ipmi => $db_host_ipmi =~ /passw/ ? $anvil->Log->is_secure($db_host_ipmi) : $db_host_ipmi,
db_host_name => $db_host_name,
db_host_type => $db_host_type,
db_host_key => $db_host_key,
db_host_status => $db_host_status,
}});
# Is this host in all DBs?
foreach my $check_uuid (sort {$a cmp $b} keys %{$anvil->data->{database}})
{
# Are we connected?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"db_status::${check_uuid}::access" => $anvil->data->{db_status}{$check_uuid}{access},
}});
next if not $anvil->data->{db_status}{$check_uuid}{access};
my $query = "SELECT COUNT(*) FROM hosts WHERE host_uuid = ".$anvil->Database->quote($check_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
my $results = $anvil->Database->query({uuid => $check_uuid, 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)
{
# INSERT it!
$anvil->Database->insert_or_update_hosts({
debug => 2,
uuid => $check_uuid,
host_ipmi => $db_host_ipmi,
host_key => $db_host_key,
host_name => $db_host_name,
host_type => $db_host_type,
host_uuid => $db_uuid,
host_status => $db_host_status,
});
}
}
}
return(0);
}
=head2 check_lock_age
@ -2143,6 +2253,12 @@ sub connect
$anvil->Database->disconnect({debug => $debug});
}
if ($local_host_type eq "striker")
{
# More sure any configured databases are in the hosts file.
$anvil->Database->check_hosts({debug => $debug});
}
# If this is a time sensitive call, end here.
if ($sensitive)
{
@ -19150,6 +19266,7 @@ sub write
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:test' => $test,
's2:$@' => $@,
's3:query' => $query,
}});
if (not $test)

@ -2007,7 +2007,7 @@ sub validate_ram
name => $server,
ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_bytes}),
ram_bytes => $anvil->Convert->add_commas({number => $server_ram_bytes}),
available_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram_bytes}),
available_ram => $anvil->Convert->bytes_to_human_readable({'bytes' => $available}),
available_ram_bytes => $anvil->Convert->add_commas({number => $available}),
}});
$anvil->nice_exit({exit_code => 1});

@ -1381,6 +1381,8 @@ AND
$anvil->Database->get_hosts({debug => 2});
my $host_uuid = $anvil->Get->host_uuid({debug => 2});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { host_uuid => $host_uuid }});
# Now update that we're online.
$anvil->Database->insert_or_update_hosts({
debug => 2,
host_ipmi => $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_ipmi},

Loading…
Cancel
Save