* Updated Network->find_matches() to try to populate the first and second parameters if they're not passed in.

* Updated Network->load_ips() to load extra information about the interfaces.
* Updated ocf:alteeve:server to not check libvirtd daemon state on server start.
* Updated scan-hardware to check for duplicate entries and purge if found.
* Updated scan-network to check for the 'default' virbr0 interface by checking if the config file exists instead of calling virsh.
* Updated scan-server to have better logging.
* Created the new (and incomplete) anvil-test-alerts tool
* Updated scancore to support --purge to pass to all agents and then exit.
* Updated ScanCore->call_scan_agents() to no longer use 'timeout' as it was causing issues with virsh calls.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 3 years ago
parent 572167d034
commit 1b70b49cf8
  1. 103
      Anvil/Tools/Network.pm
  2. 19
      Anvil/Tools/ScanCore.pm
  3. 14
      Anvil/Tools/System.pm
  4. 9
      notes
  5. 148
      ocf/alteeve/server
  6. 19
      scancore-agents/scan-hardware/scan-hardware
  7. 1
      scancore-agents/scan-hardware/scan-hardware.xml
  8. 34
      scancore-agents/scan-network/scan-network
  9. 79
      scancore-agents/scan-server/scan-server
  10. 3
      share/words.xml
  11. 2
      tools/anvil-daemon
  12. 73
      tools/anvil-test-alerts
  13. 11
      tools/scancore

@ -1077,12 +1077,20 @@ sub find_matches
} }
elsif (ref($anvil->data->{network}{$first}) ne "HASH") elsif (ref($anvil->data->{network}{$first}) ne "HASH")
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0106", variables => { $anvil->Network->load_ips({
key => "first -> network::".$first, debug => $debug,
source => $source, host => $first,
line => $line, });
}}); if (ref($anvil->data->{network}{$first}) ne "HASH")
return(""); {
# Well, we tried.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0106", variables => {
key => "first -> network::".$first,
source => $source,
line => $line,
}});
return("");
}
} }
if (not $second) if (not $second)
{ {
@ -1091,12 +1099,21 @@ sub find_matches
} }
elsif (ref($anvil->data->{network}{$second}) ne "HASH") elsif (ref($anvil->data->{network}{$second}) ne "HASH")
{ {
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0106", variables => { $anvil->Network->load_ips({
key => "second -> network::".$second, debug => $debug,
source => $source, host => $second,
line => $line, });
}}); if (ref($anvil->data->{network}{$second}) ne "HASH")
return(""); {
# Well, we tried.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0106", variables => {
key => "second -> network::".$second,
source => $source,
line => $line,
}});
die;
return("");
}
} }
# Loop through the first, and on each interface with an IP/subnet mask, look for a match in the second. # Loop through the first, and on each interface with an IP/subnet mask, look for a match in the second.
@ -1683,6 +1700,7 @@ sub load_ips
if (($clear) && (exists $anvil->data->{network}{$host})) if (($clear) && (exists $anvil->data->{network}{$host}))
{ {
delete $anvil->data->{network}{$host}; delete $anvil->data->{network}{$host};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0700", variables => { hash => "network::${host}" }});
} }
# Read in all IPs, so that we know which to remove. # Read in all IPs, so that we know which to remove.
@ -1734,8 +1752,17 @@ AND
{ {
my $query = " my $query = "
SELECT SELECT
network_interface_uuid,
network_interface_name, network_interface_name,
network_interface_mac_address network_interface_mac_address,
network_interface_speed,
network_interface_mtu,
network_interface_link_state,
network_interface_operational,
network_interface_duplex,
network_interface_medium,
network_interface_bond_uuid,
network_interface_bridge_uuid
FROM FROM
network_interfaces network_interfaces
WHERE WHERE
@ -1752,28 +1779,46 @@ AND
}}); }});
next if not $count; next if not $count;
$interface_name = $results->[0]->[0]; $interface_name = $results->[0]->[1];
$interface_mac = $results->[0]->[1]; $interface_mac = $results->[0]->[2];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
interface_name => $interface_name, interface_name => $interface_name,
interface_mac => $interface_mac, interface_mac => $interface_mac,
}}); }});
$anvil->data->{network}{$host}{interface}{$interface_name}{mac_address} = $interface_mac; $anvil->data->{network}{$host}{interface}{$interface_name}{network_interface_uuid} = $results->[0]->[0];
$anvil->data->{network}{$host}{interface}{$interface_name}{ip} = $ip_address_address; $anvil->data->{network}{$host}{interface}{$interface_name}{mac_address} = $interface_mac;
$anvil->data->{network}{$host}{interface}{$interface_name}{subnet_mask} = $ip_address_subnet_mask; $anvil->data->{network}{$host}{interface}{$interface_name}{ip} = $ip_address_address;
$anvil->data->{network}{$host}{interface}{$interface_name}{default_gateway} = $ip_address_default_gateway; $anvil->data->{network}{$host}{interface}{$interface_name}{subnet_mask} = $ip_address_subnet_mask;
$anvil->data->{network}{$host}{interface}{$interface_name}{gateway} = $ip_address_gateway; $anvil->data->{network}{$host}{interface}{$interface_name}{default_gateway} = $ip_address_default_gateway;
$anvil->data->{network}{$host}{interface}{$interface_name}{dns} = $ip_address_dns; $anvil->data->{network}{$host}{interface}{$interface_name}{gateway} = $ip_address_gateway;
$anvil->data->{network}{$host}{interface}{$interface_name}{type} = $ip_address_on_type; $anvil->data->{network}{$host}{interface}{$interface_name}{dns} = $ip_address_dns;
$anvil->data->{network}{$host}{interface}{$interface_name}{type} = $ip_address_on_type;
$anvil->data->{network}{$host}{interface}{$interface_name}{speed} = $results->[0]->[3];
$anvil->data->{network}{$host}{interface}{$interface_name}{mtu} = $results->[0]->[4];
$anvil->data->{network}{$host}{interface}{$interface_name}{link_state} = $results->[0]->[5];
$anvil->data->{network}{$host}{interface}{$interface_name}{operational} = $results->[0]->[6];
$anvil->data->{network}{$host}{interface}{$interface_name}{duplex} = $results->[0]->[7];
$anvil->data->{network}{$host}{interface}{$interface_name}{medium} = $results->[0]->[8];
$anvil->data->{network}{$host}{interface}{$interface_name}{bond_uuid} = $results->[0]->[9];
$anvil->data->{network}{$host}{interface}{$interface_name}{bridge_uuid} = $results->[0]->[10];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${host}::interface::${interface_name}::mac_address" => $anvil->data->{network}{$host}{interface}{$interface_name}{mac_address}, "network::${host}::interface::${interface_name}::network_interface_uuid" => $anvil->data->{network}{$host}{interface}{$interface_name}{network_interface_uuid},
"network::${host}::interface::${interface_name}::ip" => $anvil->data->{network}{$host}{interface}{$interface_name}{ip}, "network::${host}::interface::${interface_name}::mac_address" => $anvil->data->{network}{$host}{interface}{$interface_name}{mac_address},
"network::${host}::interface::${interface_name}::subnet_mask" => $anvil->data->{network}{$host}{interface}{$interface_name}{subnet_mask}, "network::${host}::interface::${interface_name}::ip" => $anvil->data->{network}{$host}{interface}{$interface_name}{ip},
"network::${host}::interface::${interface_name}::default_gateway" => $anvil->data->{network}{$host}{interface}{$interface_name}{default_gateway}, "network::${host}::interface::${interface_name}::subnet_mask" => $anvil->data->{network}{$host}{interface}{$interface_name}{subnet_mask},
"network::${host}::interface::${interface_name}::gateway" => $anvil->data->{network}{$host}{interface}{$interface_name}{gateway}, "network::${host}::interface::${interface_name}::default_gateway" => $anvil->data->{network}{$host}{interface}{$interface_name}{default_gateway},
"network::${host}::interface::${interface_name}::dns" => $anvil->data->{network}{$host}{interface}{$interface_name}{dns}, "network::${host}::interface::${interface_name}::gateway" => $anvil->data->{network}{$host}{interface}{$interface_name}{gateway},
"network::${host}::interface::${interface_name}::type" => $anvil->data->{network}{$host}{interface}{$interface_name}{type}, "network::${host}::interface::${interface_name}::dns" => $anvil->data->{network}{$host}{interface}{$interface_name}{dns},
"network::${host}::interface::${interface_name}::type" => $anvil->data->{network}{$host}{interface}{$interface_name}{type},
"network::${host}::interface::${interface_name}::speed" => $anvil->data->{network}{$host}{interface}{$interface_name}{speed},
"network::${host}::interface::${interface_name}::mtu" => $anvil->data->{network}{$host}{interface}{$interface_name}{mtu},
"network::${host}::interface::${interface_name}::link_state" => $anvil->data->{network}{$host}{interface}{$interface_name}{link_state},
"network::${host}::interface::${interface_name}::operational" => $anvil->data->{network}{$host}{interface}{$interface_name}{operational},
"network::${host}::interface::${interface_name}::duplex" => $anvil->data->{network}{$host}{interface}{$interface_name}{duplex},
"network::${host}::interface::${interface_name}::medium" => $anvil->data->{network}{$host}{interface}{$interface_name}{medium},
"network::${host}::interface::${interface_name}::bond_uuid" => $anvil->data->{network}{$host}{interface}{$interface_name}{bond_uuid},
"network::${host}::interface::${interface_name}::bridge_uuid" => $anvil->data->{network}{$host}{interface}{$interface_name}{bridge_uuid},
}}); }});
} }
elsif ($ip_address_on_type eq "bond") elsif ($ip_address_on_type eq "bond")

@ -397,13 +397,22 @@ sub call_scan_agents
$shell_call .= " ".$anvil->data->{sys}{'log'}{level}; $shell_call .= " ".$anvil->data->{sys}{'log'}{level};
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
if ($anvil->data->{switches}{purge})
{
$shell_call .= " --purge";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }});
# Tell the user this agent is about to run... # Tell the user this agent is about to run...
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => $debug, key => "log_0252", variables => { # $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => $debug, key => "log_0252", variables => {
agent_name => $agent_name, # agent_name => $agent_name,
timeout => $timeout, # timeout => $timeout,
}}); # }});
my ($output, $return_code) = $anvil->System->call({timeout => $timeout, shell_call => $shell_call}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => $debug, key => "log_0701", variables => { agent_name => $agent_name }});
### TODO: Timeout, when called / set here, was hanging virsh calls. Unknown why yet, but temp
### fix is to just not use timeouts for calls.
#my ($output, $return_code) = $anvil->System->call({timeout => $timeout, shell_call => $shell_call});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output, return_code => $return_code }});
foreach my $line (split/\n/, $output) foreach my $line (split/\n/, $output)
{ {

@ -2865,15 +2865,15 @@ sub generate_state_json
} }
else else
{ {
my $speed = $anvil->data->{network}{$host}{interface}{$interface}{speed}; my $speed = $anvil->data->{network}{$host}{interface}{$interface}{speed} ? $anvil->data->{network}{$host}{interface}{$interface}{speed} : 0;
my $say_speed = $anvil->Convert->add_commas({number => $anvil->data->{network}{$host}{interface}{$interface}{speed}})." ".$anvil->Words->string({key => "suffix_0050"}); my $say_speed = $anvil->Convert->add_commas({number => $anvil->data->{network}{$host}{interface}{$interface}{speed}})." ".$anvil->Words->string({key => "suffix_0050"});
my $link_state = $anvil->data->{network}{$host}{interface}{$interface}{link_state}; my $link_state = $anvil->data->{network}{$host}{interface}{$interface}{link_state} ? $anvil->data->{network}{$host}{interface}{$interface}{link_state} : "";
my $operational = $anvil->data->{network}{$host}{interface}{$interface}{operational}; my $operational = $anvil->data->{network}{$host}{interface}{$interface}{operational} ? $anvil->data->{network}{$host}{interface}{$interface}{operational} : "";
my $duplex = $anvil->data->{network}{$host}{interface}{$interface}{duplex}; my $duplex = $anvil->data->{network}{$host}{interface}{$interface}{duplex} ? $anvil->data->{network}{$host}{interface}{$interface}{duplex} : "unknown";
my $medium = $anvil->data->{network}{$host}{interface}{$interface}{medium}; my $medium = $anvil->data->{network}{$host}{interface}{$interface}{medium} ? $anvil->data->{network}{$host}{interface}{$interface}{medium} : "unknown";
my $bond_uuid = $anvil->data->{network}{$host}{interface}{$interface}{bond_uuid}; my $bond_uuid = $anvil->data->{network}{$host}{interface}{$interface}{bond_uuid} ? $anvil->data->{network}{$host}{interface}{$interface}{bond_uuid} : "";
my $bond_name = $anvil->data->{network}{$host}{interface}{$interface}{bond_name} ? $anvil->data->{network}{$host}{interface}{$interface}{bond_name} : $anvil->Words->string({key => "unit_0005"}); my $bond_name = $anvil->data->{network}{$host}{interface}{$interface}{bond_name} ? $anvil->data->{network}{$host}{interface}{$interface}{bond_name} : $anvil->Words->string({key => "unit_0005"});
my $bridge_uuid = $anvil->data->{network}{$host}{interface}{$interface}{bridge_uuid}; my $bridge_uuid = $anvil->data->{network}{$host}{interface}{$interface}{bridge_uuid} ? $anvil->data->{network}{$host}{interface}{$interface}{bridge_uuid} : "";
my $bridge_name = $anvil->data->{network}{$host}{interface}{$interface}{bridge_name} ? $anvil->data->{network}{$host}{interface}{$interface}{bridge_name} : $anvil->Words->string({key => "unit_0005"}); my $bridge_name = $anvil->data->{network}{$host}{interface}{$interface}{bridge_name} ? $anvil->data->{network}{$host}{interface}{$interface}{bridge_name} : $anvil->Words->string({key => "unit_0005"});
my $changed_order = $anvil->data->{network}{$host}{interface}{$interface}{changed_order}; my $changed_order = $anvil->data->{network}{$host}{interface}{$interface}{changed_order};
my $say_link_state = $link_state; my $say_link_state = $link_state;

@ -1,3 +1,12 @@
When pairing Striker, make sure new config goes to all known nodes!
Immediately set drbdadm to 'secondary' after 'primary --force'
dnf -y update && dnf -y install https://www.alteeve.com/an-repo/m3/anvil-release-latest.noarch.rpm && alteeve-repo-setup -y && dnf -y install anvil-striker --allowerasing
dnf -y update && dnf -y install https://www.alteeve.com/an-repo/m3/anvil-release-latest.noarch.rpm && alteeve-repo-setup -y && dnf -y install anvil-node --allowerasing
dnf -y update && dnf -y install https://www.alteeve.com/an-repo/m3/anvil-release-latest.noarch.rpm && alteeve-repo-setup -y && dnf -y install anvil-dr --allowerasing
# Configure APC PDUs and UPSes # Configure APC PDUs and UPSes
tcpip -i 10.201.2.3 -s 255.255.0.0 -g 10.201.255.254 tcpip -i 10.201.2.3 -s 255.255.0.0 -g 10.201.255.254
web -h enable web -h enable

@ -357,8 +357,9 @@ sub check_daemons
if ($task eq "start") if ($task eq "start")
{ {
### It doesn't look like we need to start drbd. Up'ing the first resource works without it. ### It doesn't look like we need to start drbd. Up'ing the first resource works without it.
#foreach my $daemon ("libvirtd.service", "drbd.service") ### libvirtd also starts on-demand.
foreach my $daemon ("libvirtd.service") =cut
foreach my $daemon ("libvirtd.service", "drbd.service")
{ {
my $running_local = 0; my $running_local = 0;
my $running_peer = 0; my $running_peer = 0;
@ -503,149 +504,8 @@ sub check_daemons
} }
} }
} }
}
=cut # It's simpler (and thus safer) to not stop daemons.
if ($task eq "stop")
{
print "Stopping daemons\n";
my $stop = 0;
# Check both nodes if a server is running on either node.
my $local_vm_count = 0;
my $remote_vm_count = 0;
# Call virsh list --all
my ($local_output, $local_return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list --all"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
local_output => $local_output,
local_return_code => $local_return_code,
}});
if (not $local_return_code)
{
# Parse output
foreach my $line (split/\n/, $local_output)
{
$line = $anvil->Words->clean_spaces({ string => $line });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /(\d+)\s+(.*?)\s+running/)
{
$local_vm_count++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { local_vm_count => $local_vm_count }});
}
}
}
my ($remote_output, $remote_error, $remote_return_code) = $anvil->Remote->call({
target => $peer_name,
shell_call => $anvil->data->{path}{exe}{virsh}." list --all",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
remote_output => $remote_output,
remote_error => $remote_error,
remote_return_code => $remote_return_code,
}});
if (not $remote_return_code)
{
# Parse output
foreach my $line (split/\n/, $remote_output)
{
$line = $anvil->Words->clean_spaces({ string => $line });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /(\d+)\s+(.*?)\s+running/)
{
$remote_vm_count++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { remote_vm_count => $remote_vm_count }});
}
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
local_vm_count => $local_vm_count,
remote_vm_count => $remote_vm_count,
}});
if ((not $local_vm_count) && (not $remote_vm_count))
{
if ($peer_ready)
{
# No servers running on either node.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0490"});
}
else
{
# No servers running here and the peer is not in the cluster.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0491"});
}
foreach my $daemon ("libvirtd.service", "drbd.service")
{
my $running_local = 0;
my $running_peer = 0;
my ($local_output, $local_return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{systemctl}." status ".$daemon});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
local_output => $local_output,
local_return_code => $local_return_code,
}});
if ($local_return_code eq "3")
{
# Already stopped.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0492", variables => { daemon => $daemon }});
}
elsif ($local_return_code eq "0")
{
# Running, stop it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0493", variables => { daemon => $daemon }});
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{systemctl}." stop ".$daemon});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
}
my ($remote_output, $remote_error, $remote_return_code) = $anvil->Remote->call({
target => $peer_name,
shell_call => $anvil->data->{path}{exe}{systemctl}." status ".$daemon,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
remote_output => $remote_output,
remote_error => $remote_error,
remote_return_code => $remote_return_code,
}});
if ($remote_return_code eq "3")
{
# Already stopped.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0494", variables => {
daemon => $daemon,
host => $peer_name,
}});
}
elsif ($remote_return_code eq "0")
{
# Running, stop it.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0495", variables => {
daemon => $daemon,
host => $peer_name,
}});
my ($output, $error, $return_code) = $anvil->Remote->call({
target => $peer_name,
shell_call => $anvil->data->{path}{exe}{systemctl}." stop ".$daemon,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
error => $error,
return_code => $return_code,
}});
}
}
}
else
{
# Servers are still running, don't stop the daemons.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0496"});
}
}
=cut =cut
}
return(0); return(0);
} }

@ -1433,7 +1433,7 @@ FROM
WHERE WHERE
scan_hardware_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." scan_hardware_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
;"; ;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results}; my $count = @{$results};
@ -1441,6 +1441,21 @@ WHERE
results => $results, results => $results,
count => $count, count => $count,
}}); }});
# If there are 2, then we've hit a bug where, somehow, we got listed twice.
if ($count > 1)
{
# Delete all and exit.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "scan_hardware_log_0002", variables => { count => $count }});
my $queries = [];
push @{$queries}, "DELETE FROM history.scan_hardware_ram_modules WHERE scan_hardware_ram_module_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).";";
push @{$queries}, "DELETE FROM scan_hardware_ram_modules WHERE scan_hardware_ram_module_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).";";
push @{$queries}, "DELETE FROM history.scan_hardware WHERE scan_hardware_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).";";
push @{$queries}, "DELETE FROM scan_hardware WHERE scan_hardware_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { query => $query }});
$anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
}
foreach my $row (@{$results}) foreach my $row (@{$results})
{ {
# We've got an entry in the 'scan_hardware' table, so now we'll look for data in the node and # We've got an entry in the 'scan_hardware' table, so now we'll look for data in the node and
@ -1460,7 +1475,7 @@ WHERE
my $scan_hardware_led_css = $row->[12]; my $scan_hardware_led_css = $row->[12];
my $scan_hardware_led_error = $row->[13]; my $scan_hardware_led_error = $row->[13];
my $scan_hardware_modified_date = $row->[14]; my $scan_hardware_modified_date = $row->[14];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"scan_hardware_uuid" => $scan_hardware_uuid, "scan_hardware_uuid" => $scan_hardware_uuid,
"scan_hardware_cpu_model" => $scan_hardware_cpu_model, "scan_hardware_cpu_model" => $scan_hardware_cpu_model,
"scan_hardware_cpu_cores" => $scan_hardware_cpu_cores, "scan_hardware_cpu_cores" => $scan_hardware_cpu_cores,

@ -157,6 +157,7 @@ If the RAM is being updated, this alert will clear once this node has been upgra
<!-- Log entries --> <!-- Log entries -->
<key name="scan_hardware_log_0001">Starting: [#!variable!program!#].</key> <key name="scan_hardware_log_0001">Starting: [#!variable!program!#].</key>
<key name="scan_hardware_log_0002">[ Note ] - There were: [#!variable!count!#] entries for this host. This should not happen! Deleting all entries and then exiting. Entries will be recreated on the next run.</key>
<!-- Message entries (usually meant to be alerts) --> <!-- Message entries (usually meant to be alerts) -->
<key name="scan_hardware_message_0001">Unknown</key> <key name="scan_hardware_message_0001">Unknown</key>

@ -321,9 +321,42 @@ sub collect_data
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
if (($host_type eq "node") or ($host_type eq "dr")) if (($host_type eq "node") or ($host_type eq "dr"))
{ {
my $default_network = "/etc/libvirt/qemu/networks/default.xml";
if (-e $default_network)
{
my $shell_call = $anvil->data->{path}{exe}{virsh}." net-destroy default";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{virsh}." net-undefine default";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
# Register an alert
my $variables = {
bridge => "default",
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_network_alert_0001", variables => $variables});
$anvil->Alert->register({
alert_level => "notice",
message => "scan_network_alert_0001",
variables => $variables,
set_by => $THIS_FILE,
});
}
=cut
my $shell_call = $anvil->data->{path}{exe}{virsh}." net-list --all --name"; my $shell_call = $anvil->data->{path}{exe}{virsh}." net-list --all --name";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
# This often hangs.
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call}); my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output, output => $output,
@ -371,6 +404,7 @@ sub collect_data
}); });
} }
} }
=cut
} }
# Walk through the sysfs files. # Walk through the sysfs files.

@ -136,7 +136,10 @@ sub check_vnc
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__}); my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
foreach my $line (split/\n/, $output) foreach my $line (split/\n/, $output)
{ {
if ($line =~ /\d.*?:(\d+)$/) if ($line =~ /\d.*?:(\d+)$/)
@ -286,8 +289,14 @@ sub collect_data
} }
} }
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." list --all", source => $THIS_FILE, line => __LINE__}); my $shell_call = $anvil->data->{path}{exe}{virsh}." list --all";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
foreach my $line (split/\n/, $output) foreach my $line (split/\n/, $output)
{ {
$line = $anvil->Words->clean_spaces({string => $line}); $line = $anvil->Words->clean_spaces({string => $line});
@ -449,16 +458,28 @@ DELETED - Marks a server as no longer existing
# The definition was likely changed by the user while it was running. We # The definition was likely changed by the user while it was running. We
# should have already picked up the changes, but just to be safe, check for # should have already picked up the changes, but just to be safe, check for
# differences. # differences.
my ($virsh_definition, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." dumpxml --inactive ".$server_name, source => $THIS_FILE, line => __LINE__}); my $shell_call = $anvil->data->{path}{exe}{virsh}." dumpxml --inactive ".$server_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $virsh_definition, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($virsh_definition, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $virsh_definition,
return_code => $return_code,
}});
# The definition may have certainly changed, so update it in case # The definition may have certainly changed, so update it in case
# needed. # needed.
update_definitions_from_virsh($anvil, $server_name, $server_uuid, $virsh_definition); update_definitions_from_virsh($anvil, $server_name, $server_uuid, $virsh_definition);
# Now undefine the server # Now undefine the server
(my $output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." undefine ".$server_name, source => $THIS_FILE, line => __LINE__}); $shell_call = $anvil->data->{path}{exe}{virsh}." undefine ".$server_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
(my $output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
} }
# Set the boot time back to zero. # Set the boot time back to zero.
@ -594,8 +615,11 @@ DELETED - Marks a server as no longer existing
$anvil->Alert->register({alert_level => "notice", message => "scan_server_alert_0003", variables => $variables, set_by => $THIS_FILE}); $anvil->Alert->register({alert_level => "notice", message => "scan_server_alert_0003", variables => $variables, set_by => $THIS_FILE});
} }
my ($virsh_live_definition, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." dumpxml ".$server_name, source => $THIS_FILE, line => __LINE__}); my $shell_call = $anvil->data->{path}{exe}{virsh}." dumpxml ".$server_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $virsh_definition, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($virsh_live_definition, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $virsh_definition, return_code => $return_code }});
$anvil->Server->parse_definition({ $anvil->Server->parse_definition({
server => $server_name, server => $server_name,
source => "from_live_virsh", source => "from_live_virsh",
@ -913,12 +937,15 @@ DELETED - Marks a server as no longer existing
if ($peer_access) if ($peer_access)
{ {
# Get a list of servers running on our peer. # Get a list of servers running on our peer.
my $shell_call = $anvil->data->{path}{exe}{virsh}." list --all";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $error, $return_code) = $anvil->Remote->call({ my ($output, $error, $return_code) = $anvil->Remote->call({
target => $peer_name, target => $peer_name,
password => $password, password => $password,
shell_call => $anvil->data->{path}{exe}{virsh}." list --all", shell_call => $shell_call,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
error => $error, error => $error,
output => $output, output => $output,
return_code => $return_code, return_code => $return_code,
@ -1043,8 +1070,14 @@ sub get_and_parse_virsh_definition
my ($anvil, $server_name) = @_; my ($anvil, $server_name) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { server_name => $server_name }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { server_name => $server_name }});
my ($virsh_definition, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." dumpxml --inactive ".$server_name, source => $THIS_FILE, line => __LINE__}); my $shell_call = $anvil->data->{path}{exe}{virsh}." dumpxml --inactive ".$server_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $virsh_definition, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($virsh_definition, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $virsh_definition,
return_code => $return_code,
}});
$anvil->Server->parse_definition({ $anvil->Server->parse_definition({
server => $server_name, server => $server_name,
@ -1066,12 +1099,24 @@ sub redefine_server_from_disk
# Push the new definition into virsh (it won't take effect until a reboot likely, but it will update # Push the new definition into virsh (it won't take effect until a reboot likely, but it will update
# the 'inactive' definition immediately. # the 'inactive' definition immediately.
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." defined ".$xml_file, source => $THIS_FILE, line => __LINE__}); my $shell_call = $anvil->data->{path}{exe}{virsh}." defined ".$xml_file;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
# Now undefine the server again so it disappears when stopped. # Now undefine the server again so it disappears when stopped.
($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{virsh}." undefine ".$server_name, source => $THIS_FILE, line => __LINE__}); $shell_call = $anvil->data->{path}{exe}{virsh}." undefine ".$server_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output, return_code => $return_code }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
return_code => $return_code,
}});
# Re-read and parse the new (inactive) definition # Re-read and parse the new (inactive) definition
my $virsh_definition = get_and_parse_virsh_definition($anvil, $server_name); my $virsh_definition = get_and_parse_virsh_definition($anvil, $server_name);

@ -507,6 +507,7 @@ The output, if any, was;
<key name="error_0359">There are no databases available, exiting.</key> <key name="error_0359">There are no databases available, exiting.</key>
<key name="error_0360">Unable to find the Anvil! information for the Anvil! UUID: [#!variable!anvil_uuid!#].</key> <key name="error_0360">Unable to find the Anvil! information for the Anvil! UUID: [#!variable!anvil_uuid!#].</key>
<key name="error_0361">Unable to find the DRBD config from either node in the Anvil! with the Anvil! UUID: [#!variable!anvil_uuid!#]. Has scan_drbd (as part of scancore) run on either nodes?</key> <key name="error_0361">Unable to find the DRBD config from either node in the Anvil! with the Anvil! UUID: [#!variable!anvil_uuid!#]. Has scan_drbd (as part of scancore) run on either nodes?</key>
<key name="error_0362"><![CDATA[The level: [#!variable!level!#] is invalid. Please use '--level <critical,warning,notice,info>' to specify the alert level of the test message.]]></key>
<!-- Files templates --> <!-- Files templates -->
<!-- NOTE: Translating these files requires an understanding of which lines are translatable --> <!-- NOTE: Translating these files requires an understanding of which lines are translatable -->
@ -2117,6 +2118,8 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0697">All clients using our database are gone, ready to stop the postgresql daemon.</key> <key name="log_0697">All clients using our database are gone, ready to stop the postgresql daemon.</key>
<key name="log_0698">[ Note ] - Marking our database as active.</key> <key name="log_0698">[ Note ] - Marking our database as active.</key>
<key name="log_0699">[ Note ] - The Striker database host: [#!variable!host!#] is inactive, skipping it.</key> <key name="log_0699">[ Note ] - The Striker database host: [#!variable!host!#] is inactive, skipping it.</key>
<key name="log_0700">[ Note ] - Deleting the contents of the hash: [#!variable!hash!#].</key>
<key name="log_0701">Running the scan agent: [#!variable!agent_name!#]...</key>
<!-- Messages for users (less technical than log entries), though sometimes used for logs, too. --> <!-- Messages for users (less technical than log entries), though sometimes used for logs, too. -->
<key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key> <key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>

@ -1455,7 +1455,7 @@ sub keep_running
# Write out state information for all known Anvil! systems and the information from # Write out state information for all known Anvil! systems and the information from
# unconfigured nods and DR hosts, using just database data (hence, fast enough to run # unconfigured nods and DR hosts, using just database data (hence, fast enough to run
# constantly). # constantly).
$anvil->System->generate_state_json({debug => 3}); $anvil->System->generate_state_json({debug => 2});
} }
else else
{ {

@ -0,0 +1,73 @@
#!/usr/bin/perl
#
use strict;
use warnings;
use Anvil::Tools;
use Data::Dumper;
# Disable buffering
$| = 1;
# Prevent a discrepency between UID/GID and EUID/EGID from throwing an error.
$< = $>;
$( = $);
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0];
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0];
if (($running_directory =~ /^\./) && ($ENV{PWD}))
{
$running_directory =~ s/^\./$ENV{PWD}/;
}
my $anvil = Anvil::Tools->new();
# Make sure we're running as 'root'
# $< == real UID, $> == effective UID
if (($< != 0) && ($> != 0))
{
# Not root
print $anvil->Words->string({key => "error_0005"})."\n";
$anvil->nice_exit({exit_code => 1});
}
$anvil->data->{switches}{level} = "";
$anvil->data->{switches}{message} = "";
$anvil->Get->switches;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
'switches::level' => $anvil->data->{switches}{level},
'switches::message' => $anvil->data->{switches}{message},
}});
my $level = "";
if (($anvil->data->{switches}{level} eq "1") or (lc($anvil->data->{switches}{level}) eq "critical"))
{
$level = "critical";
}
elsif (($anvil->data->{switches}{level} eq "2") or (lc($anvil->data->{switches}{level}) eq "warning"))
{
$level = "warning";
}
elsif (($anvil->data->{switches}{level} eq "3") or (lc($anvil->data->{switches}{level}) eq "notice"))
{
$level = "notice";
}
elsif (($anvil->data->{switches}{level} eq "4") or (lc($anvil->data->{switches}{level}) eq "info"))
{
$level = "info";
}
if ((not $anvil->data->{switches}{level}) or (not $level))
{
print $anvil->Words->string({key => "error_0362", variables => { level => $anvil->data->{switches}{level} }})."\n";
$anvil->nice_exit({exit_code => 1});
}
$anvil->nice_exit({exit_code => 0});
#############################################################################################################
# Functions #
#############################################################################################################

@ -68,10 +68,21 @@ $anvil->data->{scancore} = {
$anvil->Storage->read_config(); $anvil->Storage->read_config();
# Read switches # Read switches
$anvil->data->{switches}{purge} = "";
$anvil->data->{switches}{'run-once'} = ""; $anvil->data->{switches}{'run-once'} = "";
$anvil->Get->switches; $anvil->Get->switches;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0115", variables => { program => $THIS_FILE }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0115", variables => { program => $THIS_FILE }});
# If purging, also set 'run-once'.
if ($anvil->data->{switches}{purge})
{
$anvil->data->{switches}{'run-once'} = 1;
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"switches::purge" => $anvil->data->{switches}{purge},
"switches::run-once" => $anvil->data->{switches}{'run-once'},
}});
# Calculate my sum so that we can exit if it changes later. # Calculate my sum so that we can exit if it changes later.
$anvil->Storage->record_md5sums(); $anvil->Storage->record_md5sums();

Loading…
Cancel
Save