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();