diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm
index 5f473fb6..7e84ee06 100644
--- a/Anvil/Tools/Database.pm
+++ b/Anvil/Tools/Database.pm
@@ -1332,7 +1332,7 @@ sub connect
# This method just returns if nothing is needed.
if (($local_host_type eq "striker") && ($check_if_configured) && ($< == 0) && ($> == 0))
{
- $anvil->Database->configure_pgsql({debug => 2, uuid => $local_host_uuid});
+ $anvil->Database->configure_pgsql({debug => $debug, uuid => $local_host_uuid});
}
# Now setup or however-many connections
diff --git a/scancore-agents/scan-network/scan-network b/scancore-agents/scan-network/scan-network
index 9793af6d..333765b6 100755
--- a/scancore-agents/scan-network/scan-network
+++ b/scancore-agents/scan-network/scan-network
@@ -785,7 +785,7 @@ sub read_last_scan
### NOTE: There is a bug somewhere where interfaces are periodically being added twice per host. This
### checks for / cleans those up. Remove this when the core issue is resolved.
- clear_duplicate_nics($anvil);
+ clear_duplicates($anvil);
# Read in the old bridge data.
load_bridge_data($anvil);
@@ -796,9 +796,9 @@ sub read_last_scan
return(0);
}
-# There is a bug somewhere where interfaces are periodically being added twice per host. This checks
-# for / cleans those up. Remove this when the core issue is resolved.
-sub clear_duplicate_nics
+# There is a bug somewhere where interfaces and ip addresses are periodically being added twice per host.
+# This checks for / cleans those up. Remove this when the core issue is resolved.
+sub clear_duplicates
{
my ($anvil) = @_;
@@ -911,6 +911,107 @@ ORDER BY
delete $anvil->data->{duplicate_nics};
+ $query = "
+SELECT
+ ip_address_uuid,
+ ip_address_address,
+ ip_address_note
+FROM
+ ip_addresses
+WHERE
+ ip_address_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
+ORDER BY
+ ip_address_address ASC
+;";
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
+ $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
+ $count = @{$results};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ results => $results,
+ count => $count,
+ }});
+ foreach my $row (@{$results})
+ {
+ my $ip_address_uuid = $row->[0];
+ my $ip_address_address = $row->[1];
+ my $ip_address_note = $row->[2];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ ip_address_uuid => $ip_address_uuid,
+ ip_address_address => $ip_address_address,
+ ip_address_note => $ip_address_note,
+ }});
+
+ if (not exists $anvil->data->{duplicate_ips}{seen}{$ip_address_address})
+ {
+ $anvil->data->{duplicate_ips}{seen}{$ip_address_address} = [];
+ }
+ push @{$anvil->data->{duplicate_ips}{seen}{$ip_address_address}}, $ip_address_uuid;
+
+ $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_address} = $ip_address_address;
+ $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_note} = $ip_address_note;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "duplicate_ips::ip_address_uuid::${ip_address_uuid}::ip_address_address" => $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_address},
+ "duplicate_ips::ip_address_uuid::${ip_address_uuid}::ip_address_note" => $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_note},
+ }});
+ }
+ foreach my $ip_address_address (sort {$a cmp $b} keys %{$anvil->data->{duplicate_ips}{seen}})
+ {
+ my $count = @{$anvil->data->{duplicate_ips}{seen}{$ip_address_address}};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:ip_address_address' => $ip_address_address,
+ 's2:count' => $count,
+ }});
+
+ if ($count > 1)
+ {
+ # Duplicate! Is one of them marked as DELETED?
+ foreach my $ip_address_uuid (@{$anvil->data->{duplicate_ips}{seen}{$ip_address_address}})
+ {
+ # Is this one deleted?
+ my $ip_address_note = $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_note};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ ip_address_uuid => $ip_address_uuid,
+ ip_address_note => $anvil->data->{duplicate_ips}{ip_address_uuid}{$ip_address_uuid}{ip_address_note},
+ }});
+ if ($ip_address_note eq "DELETED")
+ {
+ # Take this one out.
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0664", variables => {
+ ip => $ip_address_address,
+ uuid => $ip_address_uuid,
+ }});
+
+ my $query = "DELETE FROM ip_addresses WHERE ip_address_uuid = ".$anvil->Database->quote($ip_address_uuid).";";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
+ $anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
+
+ $count--;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
+ }
+ last if $count == 1;
+ }
+
+ # If count is still > 1, we need to arbitrarily delete an interface.
+ if ($count > 1)
+ {
+ foreach my $ip_address_uuid (@{$anvil->data->{duplicate_ips}{seen}{$ip_address_address}})
+ {
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0664", variables => {
+ ip => $ip_address_address,
+ uuid => $ip_address_uuid,
+ }});
+
+ my $query = "DELETE FROM ip_addresses WHERE ip_address_uuid = ".$anvil->Database->quote($ip_address_uuid).";";
+ $anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
+
+ $count--;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
+ }
+ last if $count == 1;
+ }
+ }
+ }
+
return(0);
}
diff --git a/share/words.xml b/share/words.xml
index 4ec2d18d..8b6c8946 100644
--- a/share/words.xml
+++ b/share/words.xml
@@ -2054,6 +2054,8 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
Our most recent database dump is newer than any from our peers. As such, we'll just start the database without a load.
Retrying to connect to the database.
The target can be reached on the dedicated migration network: [#!variable!target!#] via the IP address: [#!variable!ip!#], switching to use that for the RAM copy.
+ [ Note ] - The IP address: [#!variable!ip!#] with 'ip_address_uuid': [#!variable!uuid!#] is a duplicate, removing it from the database(s).
+ The database dump file: [#!variable!file!#] exists, skipping database setup.
The host name: [#!variable!target!#] does not resolve to an IP address.
diff --git a/tools/anvil-daemon b/tools/anvil-daemon
index e6c0f4da..3f23c09f 100755
--- a/tools/anvil-daemon
+++ b/tools/anvil-daemon
@@ -1156,14 +1156,19 @@ sub prep_database
my ($anvil) = @_;
# If there's a backup file, we're configured and possibly just off.
- my $dump_file = $anvil->data->{path}{directories}{pgsql}."/".$anvil->data->{sys}{database}{name}."_db_dump.".$anvil->Get->host_uuid().".out";
- $dump_file =~ s/\/\//\//g;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { dump_file => $dump_file }});
- if (-e $dump_file)
+ foreach my $uuid (keys %{$anvil->data->{database}})
{
- # No need to prepare.
- return(0);
+ my $dump_file = $anvil->data->{path}{directories}{pgsql}."/".$anvil->data->{sys}{database}{name}."_db_dump.".$uuid.".sql";
+ $dump_file =~ s/\/\//\//g;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { dump_file => $dump_file }});
+ if (-e $dump_file)
+ {
+ # No need to prepare.
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0665", variables => { file => $dump_file }});
+ return(0);
+ }
}
+ die;
# Only run this if we're a dashboard.
my $host_type = $anvil->Get->host_type();