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 => {
<keyname="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) -->
# 1 = Startup failure (not running as root, no DB, bad file read, etc)
# 1 = Startup failure (not running as root, no DB, bad file read, etc)
# 2 = libvirtd is not running.
# 2 = libvirtd is not running.
#
#
# BUG:
# - Check that an update on disk is not overwritten by the old config still being in memory for a still-
# running VM (specifically, RAM updates)
#
# TODO:
# TODO:
# - Move location constraints to the host node if the server is not on the preferred host (this happens after
# - Move location constraints to the host node if the server is not on the preferred host (this happens after
# recovering from a node loss).
# recovering from a node loss).
@ -132,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+)$/)
@ -282,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 => {
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",
@ -909,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,
@ -1039,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,
@ -1062,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.
<keyname="error_0359">There are no databases available, exiting.</key>
<keyname="error_0359">There are no databases available, exiting.</key>
<keyname="error_0360">Unable to find the Anvil! information for the Anvil! UUID: [#!variable!anvil_uuid!#].</key>
<keyname="error_0360">Unable to find the Anvil! information for the Anvil! UUID: [#!variable!anvil_uuid!#].</key>
<keyname="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>
<keyname="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>
<keyname="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:
<keyname="log_0697">All clients using our database are gone, ready to stop the postgresql daemon.</key>
<keyname="log_0697">All clients using our database are gone, ready to stop the postgresql daemon.</key>
<keyname="log_0698">[ Note ] - Marking our database as active.</key>
<keyname="log_0698">[ Note ] - Marking our database as active.</key>
<keyname="log_0699">[ Note ] - The Striker database host: [#!variable!host!#] is inactive, skipping it.</key>
<keyname="log_0699">[ Note ] - The Striker database host: [#!variable!host!#] is inactive, skipping it.</key>
<keyname="log_0700">[ Note ] - Deleting the contents of the hash: [#!variable!hash!#].</key>
<keyname="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. -->
<keyname="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>
<keyname="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>
print "Missing '--name <server_name>'\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
if (not $anvil->data->{switches}{os})
{
print "Missing '--os <os_variant>', valid options match 'virt-install --os-variant' (run: 'osinfo-query os' and reference the 'Short ID' column).\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
else
{
# Make sure it's valid.
my $os_key = "os_list_".$anvil->data->{switches}{os};
my $os_name = $anvil->Words->string({key => $os_key});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
os_key => $os_key,
os_name => $os_name,
}});
if ($os_name =~ /#!not_found/)
{
print "The OS: [".$anvil->data->{switches}{os}."] was not found. If you're sure the OS is valid, please run 'striker-parse-os-list --xml --new' and add the output to 'words.xml'.\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
}
if (not $anvil->data->{switches}{cpu})
{
print "Missing '--cpu <1 ~ ".$anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads}.">'\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
elsif (($anvil->data->{switches}{cpu} =~ /\D/) or ($anvil->data->{switches}{cpu} > $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads}) or ($anvil->data->{switches}{cpu} < 1))
{
print "The number of CPU cores: [".$anvil->data->{switches}{cpu}."] is invalid. Must be between 1 and ".$anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads}.".\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
my $max_ram = $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{available};
my $say_max_ram = $anvil->Convert->bytes_to_human_readable({"bytes" => $max_ram});
my $requested_ram = $anvil->Convert->human_readable_to_bytes({
base2 => 1,
size => $anvil->data->{switches}{ram},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
max_ram => $max_ram,
say_max_ram => $say_max_ram,
requested_ram => $requested_ram,
}});
if (not $anvil->data->{switches}{ram})
{
print "Missing '--ram <bytes or human readable, min is 64KiB, max is ".$say_max_ram.">'\n" if not $anvil->data->{switches}{options};
print "The requested RAM: [".$anvil->data->{switches}{ram}."] is not valid. Must be between: [64KiB] and: [".$say_max_ram."]\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
my $max_storage_group_size = 0;
my $storage_group_uuid = "";
if (not $anvil->data->{switches}{'storage-group'})
{
print "Missing '--storage-group <name or uuid>. Valid options are:'\n" if not $anvil->data->{switches}{options};
foreach my $storage_group_name (sort {$a cmp $b} keys %{$anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}})
{
print "- Name: [".$storage_group_name."], UUID: [".$anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid}."]\n" if not $anvil->data->{switches}{options};
}
$problem = 1;
}
else
{
# Make sure it's valid.
my $storage_group = $anvil->data->{switches}{'storage-group'};
if (exists $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}{$storage_group})
print "- The requested storage group: [".$storage_group."] does not appear to be valid. Valid options are;\n" if not $anvil->data->{switches}{options};
foreach my $storage_group_name (sort {$a cmp $b} keys %{$anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}})
{
print "- Name: [".$storage_group_name."], UUID: [".$anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid}."]\n" if not $anvil->data->{switches}{options};
}
$problem = 1;
}
}
my $say_max_storage_group_size = $max_storage_group_size ? $anvil->Convert->bytes_to_human_readable({"bytes" => $max_storage_group_size}) : "";
if (not $anvil->data->{switches}{'storage-size'})
{
if ($max_storage_group_size)
{
print "Missing '--storage-size <bytes or human readable. max is ".$say_max_storage_group_size.">'\n" if not $anvil->data->{switches}{options};
}
else
{
print "Missing '--storage-size <bytes or human readable>. Max will depend on selected --storage-group.'\n" if not $anvil->data->{switches}{options};
}
$problem = 1;
}
else
{
my $requested_disk = $anvil->Convert->human_readable_to_bytes({
base2 => 1,
size => $anvil->data->{switches}{'storage-size'},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { requested_disk => $requested_disk }});
if (($requested_disk eq "!!error!!") or
($requested_disk < (10*(2**20))) or
($requested_disk > $max_storage_group_size))
{
# Invalid
print "The requested disk size: [".$anvil->data->{switches}{'storage-size'}."] is not valid. Must be between: [10MiB] and: [".$say_max_storage_group_size."]\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
}
if ($anvil->Validate->uuid({uuid => $anvil->data->{switches}{uuid}}))
print "The install file: [".$anvil->data->{switches}{'install-media'}."] is not an ISO, so it can't be used to install.\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
}
last if $found;
}
if (not $found)
{
print "The install file: [".$anvil->data->{switches}{'install-media'}."] was not found on this Anvil!.\n" if not $anvil->data->{switches}{options};
print "Is it in '/mnt/shared/files/' and are the daemons running?\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
}
if ($anvil->data->{switches}{'driver-disc'})
{
# Make sure it exists
my $found = 0;
foreach my $file_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_name}})
{
my $file_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_name}{$file_name}{file_uuid};
my $file_type = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_type};
my $file_directory = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{file_uuid}{$file_uuid}{file_directory};
if ($file_name eq $anvil->data->{switches}{'driver-disc'})
print "The driver file: [".$anvil->data->{switches}{'driver-disc'}."] is not an ISO, so it can't be used as an optical disc.\n" if not $anvil->data->{switches}{options};
$problem = 1;
}
}
last if $found;
}
if (not $found)
{
print "The driver file: [".$anvil->data->{switches}{'driver-disc'}."] was not found on this Anvil!.\n" if not $anvil->data->{switches}{options};
print "Is it in '/mnt/shared/files/' and are the daemons running?\n" if not $anvil->data->{switches}{options};