diff --git a/Anvil/Tools/DRBD.pm b/Anvil/Tools/DRBD.pm
index 3fd91272..7c2e892c 100644
--- a/Anvil/Tools/DRBD.pm
+++ b/Anvil/Tools/DRBD.pm
@@ -1045,6 +1045,10 @@ This finds all of the configured '/dev/drbdX' devices and maps them to their res
Parameters;
+=head3 anvil_uuid (optional)
+
+If set, the C<< drbdadm dump-xml >> is not called, instead the most recent version as recorded in C<< scan_drbd -> scan_drbd_common_xml >> is loaded from one of the hosts.
+
=head3 password (optional)
This is the password to use when connecting to a remote machine. If not set, but C<< target >> is, an attempt to connect without a password will be made.
@@ -1070,48 +1074,102 @@ sub get_devices
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "DRBD->get_devices()" }});
+ my $anvil_uuid = defined $parameter->{anvil_uuid} ? $parameter->{anvil_uuid} : "";
my $password = defined $parameter->{password} ? $parameter->{password} : "";
my $port = defined $parameter->{port} ? $parameter->{port} : "";
my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root";
my $target = defined $parameter->{target} ? $parameter->{target} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ anvil_uuid => $anvil_uuid,
password => $anvil->Log->is_secure($password),
port => $port,
remote_user => $remote_user,
target => $target,
}});
- # Is this a local call or a remote call?
- my $host = $anvil->Get->short_host_name;
- my $shell_call = $anvil->data->{path}{exe}{drbdadm}." dump-xml";
- my $output = "";
- if ($anvil->Network->is_local({host => $target}))
+ # If we've got an anvil_uuid, search for the drbd common XML from the database.
+ my $host = $anvil->Get->short_host_name;
+ my $output = "";
+ if ($anvil_uuid)
{
- # Local.
- ($output, $anvil->data->{drbd}{'drbdadm-xml'}{return_code}) = $anvil->System->call({shell_call => $shell_call});
+ if (not exists $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid})
+ {
+ $anvil->Database->get_anvils({debug => $debug});
+ if (not exists $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid})
+ {
+ # Failed to find the Anvil! data.
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0360", variables => { anvil_uuid => $anvil_uuid }});
+ return("!!error!!");
+ }
+ }
+ my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
+ my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ node1_host_uuid => $node1_host_uuid,
+ node2_host_uuid => $node2_host_uuid,
+ }});
+
+ my $query = "
+SELECT
+ scan_drbd_common_xml
+FROM
+ scan_drbd
+WHERE
+ scan_drbd_host_uuid = '618e8007-3a0b-4bbf-a616-a64fd7d2dc30'
+OR
+ scan_drbd_host_uuid = '75070e21-a0e3-4ba5-b4f7-476bf5d08107'
+ORDER BY modified_date DESC
+LIMIT 1
+;";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
+
+ my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
+ my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
- output => $output,
- "drbd::drbdadm-xml::return_code" => $anvil->data->{drbd}{'drbdadm-xml'}{return_code},
+ results => $results,
+ count => $count,
}});
+ if (not $count)
+ {
+ # Nothing found
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0361", variables => { anvil_uuid => $anvil_uuid }});
+ return("!!error!!");
+ }
+ $output = $results->[0]->[0];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { output => $output }});
}
else
{
- # Remote call.
- ($output, my $error, $anvil->data->{drbd}{'drbdadm-xml'}{return_code}) = $anvil->Remote->call({
- debug => $debug,
- shell_call => $shell_call,
- target => $target,
- port => $port,
- password => $password,
- remote_user => $remote_user,
- });
- $host = $target;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
- host => $host,
- error => $error,
- output => $output,
- "drbd::drbdadm-xml::return_code" => $anvil->data->{drbd}{'drbdadm-xml'}{return_code},
- }});
+ # Is this a local call or a remote call?
+ my $shell_call = $anvil->data->{path}{exe}{drbdadm}." dump-xml";
+ if ($anvil->Network->is_local({host => $target}))
+ {
+ # Local.
+ ($output, $anvil->data->{drbd}{'drbdadm-xml'}{return_code}) = $anvil->System->call({shell_call => $shell_call});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ output => $output,
+ "drbd::drbdadm-xml::return_code" => $anvil->data->{drbd}{'drbdadm-xml'}{return_code},
+ }});
+ }
+ else
+ {
+ # Remote call.
+ ($output, my $error, $anvil->data->{drbd}{'drbdadm-xml'}{return_code}) = $anvil->Remote->call({
+ debug => $debug,
+ shell_call => $shell_call,
+ target => $target,
+ port => $port,
+ password => $password,
+ remote_user => $remote_user,
+ });
+ $host = $target;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ host => $host,
+ error => $error,
+ output => $output,
+ "drbd::drbdadm-xml::return_code" => $anvil->data->{drbd}{'drbdadm-xml'}{return_code},
+ }});
+ }
}
# Clear the hash where we'll store the data.
@@ -1225,6 +1283,9 @@ sub get_devices
my $by_res = "/dev/drbd/by-res/".$this_resource."/".$volume;
my $minor = $volume_href->{device}->[0]->{minor};
$anvil->data->{drbd}{config}{$host}{resource}{$this_resource}{volume}{$volume}{drbd_path} = "/dev/drbd".$minor;
+ ### TODO: Anything using these are broken as the values get rewritten and
+ ### only store the last DRBD node's data. Switch to using the
+ ### 'this_host' stored values below
$anvil->data->{drbd}{config}{$host}{resource}{$this_resource}{volume}{$volume}{drbd_path_by_res} = $by_res;
$anvil->data->{drbd}{config}{$host}{resource}{$this_resource}{volume}{$volume}{drbd_minor} = $minor;
$anvil->data->{drbd}{config}{$host}{resource}{$this_resource}{volume}{$volume}{'meta-disk'} = $volume_href->{'meta-disk'}->[0];
@@ -1236,12 +1297,13 @@ sub get_devices
"drbd::config::${host}::resource::${this_resource}::volume::${volume}::meta-disk" => $anvil->data->{drbd}{config}{$host}{resource}{$this_resource}{volume}{$volume}{'meta-disk'},
"drbd::config::${host}::resource::${this_resource}::volume::${volume}::backing_lv" => $anvil->data->{drbd}{config}{$host}{resource}{$this_resource}{volume}{$volume}{backing_lv},
}});
+
if (($anvil->data->{drbd}{config}{$host}{host}) && ($anvil->data->{drbd}{config}{$host}{host} eq $this_host))
{
$anvil->data->{drbd}{config}{$host}{drbd_path}{$drbd_path}{on} = $lv_path;
$anvil->data->{drbd}{config}{$host}{drbd_path}{$drbd_path}{resource} = $this_resource;
$anvil->data->{drbd}{config}{$host}{lv_path}{$lv_path}{under} = $drbd_path;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"drbd::config::${host}::drbd_path::${drbd_path}::on" => $anvil->data->{drbd}{config}{$host}{drbd_path}{$drbd_path}{on},
"drbd::config::${host}::drbd_path::${drbd_path}::resource" => $anvil->data->{drbd}{config}{$host}{drbd_path}{$drbd_path}{resource},
"drbd::config::${host}::lv_path::${lv_path}::under" => $anvil->data->{drbd}{config}{$host}{lv_path}{$lv_path}{under},
@@ -1259,6 +1321,20 @@ sub get_devices
"drbd::config::${host}::by-res::${by_res}::backing_lv" => $anvil->data->{drbd}{config}{$host}{'by-res'}{$by_res}{backing_lv},
}});
}
+
+ # This records the backing LV data for all hosts in this resource.
+ $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{drbd_path} = "/dev/drbd".$minor;
+ $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{drbd_path_by_res} = $by_res;
+ $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{drbd_minor} = $minor;
+ $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{'meta-disk'} = $volume_href->{'meta-disk'}->[0];
+ $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{backing_lv} = $lv_path;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ "drbd::drbd_node::${this_host}::config::resource::${this_resource}::volume::${volume}::drbd_path" => $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{drbd_path},
+ "drbd::drbd_node::${this_host}::config::resource::${this_resource}::volume::${volume}::drbd_path_by_res" => $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{drbd_path_by_res},
+ "drbd::drbd_node::${this_host}::config::resource::${this_resource}::volume::${volume}::drbd_minor" => $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{drbd_minor},
+ "drbd::drbd_node::${this_host}::config::resource::${this_resource}::volume::${volume}::meta-disk" => $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{'meta-disk'},
+ "drbd::drbd_node::${this_host}::config::resource::${this_resource}::volume::${volume}::backing_lv" => $anvil->data->{drbd}{drbd_node}{$this_host}{config}{resource}{$this_resource}{volume}{$volume}{backing_lv},
+ }});
}
}
diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm
index 98a23f23..efbe20bf 100644
--- a/Anvil/Tools/Database.pm
+++ b/Anvil/Tools/Database.pm
@@ -1696,7 +1696,7 @@ sub connect
uuid => $uuid,
variable_name => "database::".$uuid."::active",
});
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { active_value => $active_value }});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { active_value => $active_value }});
if (not $active_value)
{
# If we're "retry", we just started up.
@@ -16053,11 +16053,12 @@ sub resync_databases
$query =~ s/, $/ /;
$query .= "FROM ".$schema.".".$table;
- # Restrict to this host if a host column was found.
- if ($host_column)
- {
- $query .= " WHERE ".$host_column." = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid});
- }
+ ### NOTE: No longer restricting to the host, given only the strikers can do resyncs now.
+# # Restrict to this host if a host column was found.
+# if ($host_column)
+# {
+# $query .= " WHERE ".$host_column." = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid});
+# }
$query .= " ORDER BY utc_modified_date DESC;";
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0074", variables => { uuid => $uuid, query => $query }});
@@ -17633,7 +17634,7 @@ sub _find_column
This returns the most up to date database ID, the time it was last updated and an array or DB IDs that are behind.
-If there is a problem, C<< !!error!! >> is returned.
+If there is a problem, C<< !!error!! >> is returned. If this is called by a host that isn't a Striker, C<< 0 >> is returned and no actions are take.
Parameters;
@@ -17661,6 +17662,14 @@ sub _find_behind_databases
tables => $tables,
}});
+ # If we're not a striker, return.
+ my $host_type = $anvil->Get->host_type();
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_type => $host_type }});
+ if ($host_type ne "striker")
+ {
+ return(0);
+ }
+
# This should always be set, but just in case...
if (not $source)
{
@@ -17774,18 +17783,19 @@ sub _find_behind_databases
"database::${uuid}::password" => $anvil->Log->is_secure($anvil->data->{database}{$uuid}{password}),
}});
+ ### Only Strikers resync, so limiting to the host_uuid doesn't make sense anymore.
my $schema = $has_history ? "history" : "public";
$query = "
SELECT DISTINCT
round(extract(epoch from modified_date)) AS unix_modified_date
FROM
".$schema.".".$table." ";
- if ($host_column)
- {
- $query .= "
-WHERE
- ".$host_column." = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid}) ;
- }
+# if ($host_column)
+# {
+# $query .= "
+# WHERE
+# ".$host_column." = ".$anvil->Database->quote($anvil->data->{sys}{host_uuid}) ;
+# }
$query .= "
ORDER BY
unix_modified_date DESC
diff --git a/Anvil/Tools/Network.pm b/Anvil/Tools/Network.pm
index 9620ee97..32d6b10d 100644
--- a/Anvil/Tools/Network.pm
+++ b/Anvil/Tools/Network.pm
@@ -21,6 +21,7 @@ my $THIS_FILE = "Network.pm";
# find_target_ip
# get_company_from_mac
# get_ips
+# get_ip_from_mac
# get_network
# is_local
# is_our_interface
@@ -1943,6 +1944,50 @@ sub get_company_from_mac
return($company);
}
+
+=head2 get_ip_from_mac
+
+This takes a MAC address and tries to convert it to an IP address. If no IP is found, an empty string is returned.
+
+Parameters;
+
+=head3 mac (required)
+
+This is the MAC address we're looking for an IP to match to. The format must be C<< aa:bb:cc:dd:ee:ff >>.
+
+=cut
+sub get_ip_from_mac
+{
+ 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 => "Network->get_ip_from_mac()" }});
+
+ my $ip = "";
+ my $mac = defined $parameter->{mac} ? $parameter->{mac} : "";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ mac => $mac,
+ }});
+
+ my $query = "SELECT mac_to_ip_ip_address FROM mac_to_ip WHERE mac_to_ip_mac_address = ".$anvil->Database->quote(lc($mac)).";";
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0124", variables => { query => $query }});
+ my $results = $anvil->Database->query({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 ($count)
+ {
+ $ip = $results->[0]->[0];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip => $ip }});
+ }
+
+ return($ip);
+}
+
+
=head2 get_ips
This method checks the local system for interfaces and stores them in:
diff --git a/Anvil/Tools/Server.pm b/Anvil/Tools/Server.pm
index 7ca03ec1..c5ed6079 100644
--- a/Anvil/Tools/Server.pm
+++ b/Anvil/Tools/Server.pm
@@ -1259,6 +1259,10 @@ B<< Note >>: This method currently parses out data needed for specific tasks, an
Parameters;
+=head3 anvil_uuid (optional)
+
+If passed, the C<< anvil_uuid >> will be passed on to C<< DRBD->get_devices >>.
+
=head3 server (required)
This is the name of the server whose XML is being parsed.
@@ -1297,12 +1301,14 @@ sub parse_definition
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Server->parse_definition()" }});
# Source is required.
+ my $anvil_uuid = defined $parameter->{anvil_uuid} ? $parameter->{anvil_uuid} : "";
my $server = defined $parameter->{server} ? $parameter->{server} : "";
my $source = defined $parameter->{source} ? $parameter->{source} : "";
my $definition = defined $parameter->{definition} ? $parameter->{definition} : "";
my $host = defined $parameter->{host} ? $parameter->{host} : $anvil->Get->short_host_name;
my $target = $anvil->Get->short_host_name();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ anvil_uuid => $anvil_uuid,
server => $server,
source => $source,
definition => $definition,
@@ -1344,7 +1350,10 @@ sub parse_definition
$anvil->data->{server}{$target}{$server}{$source}{parsed} = $server_xml;
# Get the DRBD data that this server will almost certainly be using.
- $anvil->DRBD->get_devices({debug => $debug});
+ $anvil->DRBD->get_devices({
+ debug => $debug,
+ anvil_uuid => $anvil_uuid,
+ });
# Pull out some basic server info.
$anvil->data->{server}{$target}{$server}{$source}{info}{uuid} = $server_xml->{uuid}->[0];
diff --git a/Anvil/Tools/System.pm b/Anvil/Tools/System.pm
index 07ec0fb0..fe8d6aec 100644
--- a/Anvil/Tools/System.pm
+++ b/Anvil/Tools/System.pm
@@ -5407,16 +5407,18 @@ sub _check_anvil_conf
admin_uid => $admin_uid,
admin_gid => $admin_gid,
}});
- if (not $admin_gid)
+ if ((not $admin_uid) && (not $admin_gid))
{
- # Create the admin group
- my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{groupadd}." --system admin"});
+ # Create the admin user and group
+ my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{useradd}." --create-home --comment \"Anvil! user account\" admin"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
output => $output,
return_code => $return_code,
}});
+ $admin_uid = getpwnam('admin');
$admin_gid = getgrnam('admin');
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "warning_0119", variables => { uid => $admin_uid }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "warning_0118", variables => { gid => $admin_gid }});
}
if (not $admin_uid)
@@ -5428,8 +5430,20 @@ sub _check_anvil_conf
return_code => $return_code,
}});
- my $admin_uid = getpwnam('admin');
- $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "warning_0119", variables => { uid => $admin_gid }});
+ $admin_uid = getpwnam('admin');
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "warning_0119", variables => { uid => $admin_uid }});
+ }
+ if (not $admin_gid)
+ {
+ # Create the admin group
+ my ($output, $return_code) = $anvil->System->call({debug => $debug, shell_call => $anvil->data->{path}{exe}{groupadd}." admin"});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
+ output => $output,
+ return_code => $return_code,
+ }});
+
+ $admin_gid = getgrnam('admin');
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "warning_0118", variables => { gid => $admin_gid }});
}
# Does the file exist?
diff --git a/ocf/alteeve/server b/ocf/alteeve/server
index 01c7f9b0..1a28d7d3 100755
--- a/ocf/alteeve/server
+++ b/ocf/alteeve/server
@@ -937,13 +937,14 @@ sub start_drbd_resource
}
}
+ ### NOTE: We always check the peer now, in case it's resource is down and ours happens to be up.
# Do we need to start the resource on our peers?
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_startup_needed => $peer_startup_needed }});
- if (not $peer_startup_needed)
- {
- $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0431"});
- return(0);
- }
+ #$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { peer_startup_needed => $peer_startup_needed }});
+ #if (not $peer_startup_needed)
+ #{
+ # $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0431"});
+ # return(0);
+ #}
# Start DRBD on the peer(s).
foreach my $resource (sort {$a cmp $b} keys %{$anvil->data->{server}{$local_host}{$server}{resource}})
@@ -1244,17 +1245,18 @@ sub server_status
}
else
{
+ # On EL8 and above, libvirtd starts on demand, so this error isn't
if (not $warning_shown)
{
- $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0522", variables => { wait_time => ($wait_until - time) }});
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0522", variables => { wait_time => ($wait_until - time) }});
$warning_shown = 1;
}
sleep 1;
if (time > $wait_until)
{
# Libvirtd isn't running, try to find the PID of the server (in case it's
- # running a libvirtd isn't)
- $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "warning_0057"});
+ # running and libvirtd isn't)
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, priority => "alert", key => "warning_0057"});
$look_for_pid = 1;
$libvirtd_wait = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
diff --git a/scancore-agents/scan-network/scan-network b/scancore-agents/scan-network/scan-network
index 249db986..baace99b 100755
--- a/scancore-agents/scan-network/scan-network
+++ b/scancore-agents/scan-network/scan-network
@@ -85,6 +85,9 @@ process_health($anvil);
# This clears the TX and RX variable data for interfaces older than 'scancore::database::age_out'.
clear_old_variables($anvil);
+# This removes network interfaces that have been marked as DELETED for a while now.
+clear_old_interfaces($anvil);
+
# Shut down.
$anvil->ScanCore->agent_shutdown({agent => $THIS_FILE});
@@ -93,6 +96,81 @@ $anvil->ScanCore->agent_shutdown({agent => $THIS_FILE});
# Functions #
#############################################################################################################
+# This removes network interfaces that have been marked as DELETED for a while now.
+sub clear_old_interfaces
+{
+ my ($anvil) = @_;
+
+ # Read in all interfaces and for each, delete historical records over the age-out time.
+ my $age = $anvil->data->{scancore}{database}{age_out};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { age => $age }});
+
+ if ($age =~ /\D/)
+ {
+ # Age is not valid, set it to defaults.
+ $age = 24;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { age => $age }});
+ }
+
+ my $query = "SELECT now() - '".$age."h'::interval;";
+ my $old_timestamp = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
+ query => $query,
+ old_timestamp => $old_timestamp,
+ }});
+
+ $query = "
+SELECT
+ network_interface_uuid,
+ network_interface_mac_address,
+ network_interface_name
+FROM
+ network_interfaces
+WHERE
+ network_interface_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)."
+AND
+ network_interface_operational = 'DELETED'
+AND
+ modified_date < '".$old_timestamp."'
+ORDER BY
+ network_interface_name ASC;
+;";
+ my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
+ my $count = @{$results};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ results => $results,
+ count => $count,
+ }});
+ foreach my $row (@{$results})
+ {
+ my $network_interface_uuid = $row->[0];
+ my $network_interface_mac_address = $row->[1];
+ my $network_interface_name = $row->[2];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:network_interface_uuid' => $network_interface_uuid,
+ 's2:network_interface_mac_address' => $network_interface_mac_address,
+ 's3:network_interface_name' => $network_interface_name,
+ }});
+
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "scan_network_log_0002", variables => {
+ age => $age,
+ mac => $network_interface_mac_address,
+ name => $network_interface_name,
+ }});
+
+ my $queries = [];
+ push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_uuid = '".$network_interface_uuid."';";
+ push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_uuid = '".$network_interface_uuid."';";
+ foreach my $query (@{$queries})
+ {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
+ }
+ $anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__});
+ }
+
+ return(0);
+}
+
# This clears the TX and RX variable data for interfaces older than 'scancore::database::age_out'.
sub clear_old_variables
{
@@ -310,13 +388,15 @@ sub collect_data
{
# Pull out the data I want. Note that some of these don't exist with virtio-net interfaces.
my $interface = $file;
- my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
- my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
- my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
- my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
+ my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
+ my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
+ my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
+ my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
+ my $modalias = -e $full_path."/device/modalias" ? $anvil->Storage->read_file({file => $full_path."/device/modalias"}) : "unknown";
my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed"}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link
my $media = "unknown";
my $type = "interface";
+ my $driver = "";
my $tx_bytes = 0; # How many bytes transmitted
my $rx_bytes = 0; # How many bytes received
@@ -326,6 +406,7 @@ sub collect_data
$duplex =~ s/\n$//;
$operational =~ s/\n$//;
$speed =~ s/\n$//;
+ $modalias =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
link_state => $link_state,
@@ -333,8 +414,17 @@ sub collect_data
duplex => $duplex,
operational => $operational,
speed => $speed,
+ modalias => $modalias,
}});
+ ### NOTE: This only parses virtio so far.
+ # Pick out our driver.
+ if ($modalias =~ /^virtio:/)
+ {
+ $driver = "virtio";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { driver => $driver }});
+ }
+
# The MAC address can faked by a number of ways, so we make an explicit call to 'ethtool' to get the permanent mac address.
my $mac_address = "";
my $shell_call = $anvil->data->{path}{exe}{ethtool}." -P ".$interface;
@@ -412,12 +502,18 @@ sub collect_data
# If this is a virtual interface, set some fake values that don't actually exist on
# the system for the sake of a cleaner display.
- if ($mac_address =~ /^52:54:00/)
+ if (($mac_address =~ /^52:54:00/) or ($driver eq "virtio"))
{
### Set some fake values.
# Speed is "as fast as possible", so we'll record 100 Gbps, but that is really kind of arbitrary.
- $speed = 1000 if ((not $speed) or ($speed eq "-1"));
- $duplex = "full" if not $duplex;
+ if ((not $speed) or ($speed eq "-1"))
+ {
+ $speed = 10000;
+ }
+ if ((not $duplex) or ($duplex eq "unknown"))
+ {
+ $duplex = "full";
+ }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
speed => $speed,
duplex => $duplex,
@@ -885,9 +981,31 @@ ORDER BY
uuid => $bridge_uuid,
}});
+ # If there's a bond connected to this bridge, get it's bond_uuid so
+ # we can remove any interfaces linked to it.
+ my $bond_uuid = "";
+ my $query = "SELECT bond_uuid FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
+ my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
+ my $count = @{$results};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ results => $results,
+ count => $count,
+ }});
+ if ($count)
+ {
+ $bond_uuid = $results->[0]->[0];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }});
+ }
+
my $queries = [];
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
+ if ($bond_uuid)
+ {
+ push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
+ push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
+ }
push @{$queries}, "DELETE FROM history.bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
push @{$queries}, "DELETE FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
push @{$queries}, "DELETE FROM history.bridges WHERE bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
@@ -917,9 +1035,31 @@ ORDER BY
uuid => $bridge_uuid,
}});
+ # If there's a bond connected to this bridge, get it's bond_uuid so
+ # we can remove any interfaces linked to it.
+ my $bond_uuid = "";
+ my $query = "SELECT bond_uuid FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0124", variables => { query => $query }});
+ my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
+ my $count = @{$results};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ results => $results,
+ count => $count,
+ }});
+ if ($count)
+ {
+ $bond_uuid = $results->[0]->[0];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }});
+ }
+
my $queries = [];
push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
+ if ($bond_uuid)
+ {
+ push @{$queries}, "DELETE FROM history.network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
+ push @{$queries}, "DELETE FROM network_interfaces WHERE network_interface_bond_uuid = ".$anvil->Database->quote($bond_uuid).";";
+ }
push @{$queries}, "DELETE FROM history.bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
push @{$queries}, "DELETE FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
push @{$queries}, "DELETE FROM history.bridges WHERE bridge_uuid = ".$anvil->Database->quote($bridge_uuid).";";
diff --git a/scancore-agents/scan-network/scan-network.xml b/scancore-agents/scan-network/scan-network.xml
index 84081118..459a172a 100644
--- a/scancore-agents/scan-network/scan-network.xml
+++ b/scancore-agents/scan-network/scan-network.xml
@@ -215,5 +215,6 @@ This mode is NOT supported by the Anvil! Intelligent Availability™ platform!
Aging out RX and TX data under: [#!variable!records!#] interfaces. These have 1 or more historical records older than: [#!variable!age!#] hours old from the database host: [#!variable!host!#].
+ The old network interface: [#!variable!name!#] with the MAC address: [#!variable!mac!#] was marked as deleted more than: [#!variable!age!#] hours ago. Purging it from the database.
diff --git a/share/words.xml b/share/words.xml
index bf3e9147..586d4a6b 100644
--- a/share/words.xml
+++ b/share/words.xml
@@ -504,6 +504,9 @@ The output, if any, was;
Failed to read the kernel release on the host: [#!variable!target!#]. The return code was: [#!variable!return_code!#] (expected '0') and the release output, if any, was: [#!variable!output!#].
The program: [#!variable!program!#] is using: [#!variable!ram_used!#] (#!variable!ram_used_bytes!# Bytes). This is probably caused by a memory leak, so we will now exit so that systemctl can restart us. If this is happening repeatedly, please contact support.
This is not a Striker host.
+ There are no databases available, exiting.
+ Unable to find the Anvil! information for the Anvil! UUID: [#!variable!anvil_uuid!#].
+ 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?
@@ -845,6 +848,23 @@ resource #!variable!server!# {
Table
public
history
+ Server
+ CPU
+ RAM
+ Disk
+ Size
+ Storage Group
+ Bridge
+ Model
+ Last Known IP
+ Description
+ RAM Used
+ RAM Free
+ Bridges
+ Storage Group
+ Used
+ Free
+ Anvil! Node Pair
Configure Network
@@ -2509,6 +2529,10 @@ Available options;
I was asked to resync. Calling the resync now.
Aging out data to thin down the database(s).
Prior to resync, we will check to see if any scan agent schemas need to be loaded.
+ #!variable!total_cores!#c (#!variable!sockets!#s)
+ #!variable!total_cores!#c (#!variable!sockets!#s, #!variable!cores!#c, #!variable!threads!#t), #!variable!model!#, #!variable!mode!#
+ #!variable!cores!#c (#!variable!threads!#t)
+ -=] Server Usage and Anvil! Node Resource Availability
Saved the mail server information successfully!
@@ -3188,15 +3212,19 @@ We will sleep a bit and try again.
+
+
+
+
+
+
+
-
-
-
-
+
@@ -3204,6 +3232,8 @@ We will sleep a bit and try again.
+
+
@@ -3230,6 +3260,7 @@ We will sleep a bit and try again.
+
@@ -3255,6 +3286,12 @@ We will sleep a bit and try again.
+
+
+
+
+
+
@@ -3262,11 +3299,15 @@ We will sleep a bit and try again.
+
+
+
+
@@ -3347,6 +3388,7 @@ We will sleep a bit and try again.
+
@@ -3355,7 +3397,10 @@ We will sleep a bit and try again.
-
+
+
+
+
@@ -3385,15 +3430,14 @@ We will sleep a bit and try again.
+
+
-
-
-
@@ -3408,6 +3452,8 @@ We will sleep a bit and try again.
+
+
@@ -3453,6 +3499,7 @@ We will sleep a bit and try again.
+
@@ -3460,12 +3507,18 @@ We will sleep a bit and try again.
+
+
+
+
+
+
@@ -3484,6 +3537,7 @@ We will sleep a bit and try again.
+
@@ -3516,6 +3570,7 @@ We will sleep a bit and try again.
+
@@ -3547,6 +3602,7 @@ We will sleep a bit and try again.
+
@@ -3587,9 +3643,13 @@ We will sleep a bit and try again.
+
+
+
+
@@ -3614,6 +3674,8 @@ We will sleep a bit and try again.
+
+
@@ -3632,6 +3694,7 @@ We will sleep a bit and try again.
+
@@ -3719,6 +3782,7 @@ We will sleep a bit and try again.
+
@@ -3741,6 +3805,13 @@ We will sleep a bit and try again.
+
+
+
+
+
+
+
@@ -3772,14 +3843,16 @@ We will sleep a bit and try again.
+
+
-
-
+
+
@@ -3787,6 +3860,7 @@ We will sleep a bit and try again.
+
@@ -3805,6 +3879,7 @@ We will sleep a bit and try again.
+
@@ -3826,6 +3901,7 @@ We will sleep a bit and try again.
+
@@ -3846,8 +3922,10 @@ We will sleep a bit and try again.
-
+
+
+
@@ -3859,6 +3937,7 @@ We will sleep a bit and try again.
+
@@ -3869,6 +3948,7 @@ We will sleep a bit and try again.
+
@@ -3886,7 +3966,6 @@ We will sleep a bit and try again.
-
diff --git a/tools/anvil-daemon b/tools/anvil-daemon
index 6fdf464e..c9411601 100755
--- a/tools/anvil-daemon
+++ b/tools/anvil-daemon
@@ -404,21 +404,21 @@ sub set_delay
{
my ($anvil) = @_;
- my $delay = 7200;
- my $type = $anvil->Get->host_type();
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { type => $type }});
- if ($type eq "striker")
+ my $delay = 7200;
+ my $host_type = $anvil->Get->host_type();
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
+ if ($host_type eq "striker")
{
- foreach my $uuid (keys %{$anvil->data->{database}})
+ foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{database}})
{
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sys::host_uuid" => $anvil->data->{sys}{host_uuid},
uuid => $uuid,
}});
if ($uuid eq $anvil->data->{sys}{host_uuid})
{
$delay = 0;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { delay => $delay }});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { delay => $delay }});
}
last;
}
@@ -516,14 +516,14 @@ sub handle_periodic_tasks
{
my ($anvil) = @_;
- my $now_time = time;
- my $type = $anvil->Get->host_type();
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
+ my $now_time = time;
+ my $host_type = $anvil->Get->host_type();
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:now_time" => $now_time,
"s2:timing::next_minute_check" => $anvil->data->{timing}{next_minute_check},
"s3:timing::next_ten_minute_check" => $anvil->data->{timing}{next_ten_minute_check},
"s4:timing::next_daily_check" => $anvil->data->{timing}{next_daily_check},
- "s5:type" => $type,
+ "s5:host_type" => $host_type,
}});
# Time to run once per minute tasks.
@@ -625,74 +625,6 @@ sub handle_periodic_tasks
# down our database.
if ($host_type eq "striker")
{
- ### NOTE: Database shutdown logic is disabled. Too flaky.
-=cut
- if ($anvil->data->{sys}{database}{connections} > 1)
- {
- # Make sure that all active databases are in the host's table. If they're
- # not, we're still early in setup. To do this, we create an array of hosts
- # and then query both/all DBs to ensure they all have all hosts.
- my $all_in_hosts = 1;
- my $db_hosts = [];
- foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
- {
- push @{$db_hosts}, $uuid;
- }
- foreach my $db_uuid (@{$db_hosts})
- {
- my $query = "SELECT COUNT(*) FROM hosts WHERE host_uuid = ".$anvil->Database->quote($db_uuid).";";
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
- 's1:db_uuid' => $db_uuid,
- 's2:query' => $query,
- }});
- foreach my $host_uuid (@{$db_hosts})
- {
- my $count = $anvil->Database->query({debug => 2, uuid => $db_uuid, query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
- 's1:host_uuid' => $host_uuid,
- 's2:db_uuid' => $db_uuid,
- 's2:count' => $count,
- }});
- if (not $count)
- {
- $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "warning_0143", variables => {
- db_uuid => $db_uuid,
- host_uuid => $host_uuid,
- }});
-
- $all_in_hosts = 0;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { all_in_hosts => $all_in_hosts }});
- }
- }
- }
-
- # Sort by UUID, skip the first, and see if we're one of the others.
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { all_in_hosts => $all_in_hosts }});
- if ($all_in_hosts)
- {
- my $first_uuid = "";
- foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}})
- {
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { uuid => $uuid }});
- if (not $first_uuid)
- {
- $first_uuid = $uuid;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { first_uuid => $first_uuid }});
-
- # Skip the first UUID so it doesn't evaluate for
- # shutdown.
- next;
- }
- elsif ($uuid eq $host_uuid)
- {
- # This won't return until we're down.
- $anvil->Database->shutdown({debug => 2});
- }
- }
- }
- }
-=cut
-
# If we're the active database, dump our database out and rsync it to our peers.
my $peers = keys %{$anvil->data->{database}};
my $connections = $anvil->data->{sys}{database}{connections};
@@ -763,7 +695,7 @@ sub handle_periodic_tasks
### NOTE: We call it once/day, but this will also trigger on restart of anvil-daemon. As such, we
### don't use '--force' and let striker-manage-install-target skip the repo update if it happened
### recently enough.
- if ($type eq "striker")
+ if ($host_type eq "striker")
{
# Age out old data. This takes up to a minute.
$anvil->Database->_age_out_data();
@@ -817,7 +749,7 @@ sub handle_periodic_tasks
# Update the next check time.
$anvil->data->{timing}{next_daily_check} = $now_time + $anvil->data->{timing}{daily_checks};
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"s1:timing::daily_checks" => $anvil->data->{timing}{daily_checks},
"s2:timing::next_daily_check" => $anvil->data->{timing}{next_daily_check},
}});
@@ -1378,7 +1310,7 @@ AND
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
if ($host_type eq "striker")
{
- $anvil->Striker->check_httpd_conf({debug => 2});
+ $anvil->Striker->check_httpd_conf({debug => 3});
}
return(0);
diff --git a/tools/anvil-report-usage b/tools/anvil-report-usage
new file mode 100755
index 00000000..8db8f287
--- /dev/null
+++ b/tools/anvil-report-usage
@@ -0,0 +1,1005 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Anvil::Tools;
+use Data::Dumper;
+use Text::Diff;
+
+$| = 1;
+
+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();
+
+$anvil->data->{switches}{detailed} = 0;
+$anvil->Get->switches();
+$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "switches::detailed" => $anvil->data->{switches}{detailed},
+}});
+
+$anvil->Database->connect();
+$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0132"});
+if (not $anvil->data->{sys}{database}{connections})
+{
+ # No databases, exit.
+ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, priority => "err", key => "error_0359"});
+ $anvil->nice_exit({exit_code => 1});
+}
+
+$anvil->data->{display}{lines} = [];
+collect_server_data($anvil);
+collect_anvil_data($anvil);
+show_servers($anvil);
+show_anvils($anvil);
+
+# Show the results
+foreach my $line (@{$anvil->data->{display}{lines}})
+{
+ print $line."\n";
+}
+
+$anvil->nice_exit({exit_code => 0});
+
+
+#############################################################################################################
+# Functions #
+#############################################################################################################
+
+sub collect_anvil_data
+{
+ $anvil->data->{longest}{anvil_name} = 0;
+ $anvil->data->{longest}{description} = 0;
+ $anvil->data->{longest}{host_cpu_string} = 0;
+ $anvil->data->{longest}{ram_used} = 0;
+ $anvil->data->{longest}{ram_free} = 0;
+ $anvil->data->{longest}{bridge_string} = 0;
+ $anvil->data->{longest}{storage_group} = 0;
+ $anvil->data->{longest}{sg_used} = 0;
+ $anvil->data->{longest}{sg_free} = 0;
+ foreach my $anvil_name (sort {$a cmp $b} keys %{$anvil->data->{anvils}{anvil_name}})
+ {
+ my $anvil_uuid = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_uuid};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:anvil_name" => $anvil_name,
+ "s2:anvil_uuid" => $anvil_uuid,
+ }});
+
+ $anvil->data->{anvil_data}{$anvil_name}{description} = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_description};
+ $anvil->data->{anvil_data}{$anvil_name}{node1_host_uuid} = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_node1_host_uuid};
+ $anvil->data->{anvil_data}{$anvil_name}{node2_host_uuid} = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_node2_host_uuid};
+ $anvil->data->{anvil_data}{$anvil_name}{dr1_host_uuid} = $anvil->data->{anvils}{anvil_name}{$anvil_name}{anvil_dr1_host_uuid};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:anvil_data::${anvil_name}::anvil_description" => $anvil->data->{anvil_data}{$anvil_name}{description},
+ "s2:anvil_data::${anvil_name}::node1_host_uuid" => $anvil->data->{anvil_data}{$anvil_name}{node1_host_uuid},
+ "s3:anvil_data::${anvil_name}::node2_host_uuid" => $anvil->data->{anvil_data}{$anvil_name}{node2_host_uuid},
+ "s4:anvil_data::${anvil_name}::dr1_host_uuid" => $anvil->data->{anvil_data}{$anvil_name}{dr1_host_uuid},
+ }});
+
+ if (length($anvil_name) > $anvil->data->{longest}{anvil_name})
+ {
+ $anvil->data->{longest}{anvil_name} = length($anvil_name);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::anvil_name' => $anvil->data->{longest}{anvil_name},
+ }});
+ }
+
+ if (length($anvil->data->{anvil_data}{$anvil_name}{description}) > $anvil->data->{longest}{description})
+ {
+ $anvil->data->{longest}{description} = length($anvil->data->{anvil_data}{$anvil_name}{description});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::description' => $anvil->data->{longest}{description},
+ }});
+ }
+
+ my $node1_host_uuid = $anvil->data->{anvil_data}{$anvil_name}{node1_host_uuid};
+ my $node2_host_uuid = $anvil->data->{anvil_data}{$anvil_name}{node2_host_uuid};
+ my $dr1_host_uuid = $anvil->data->{anvil_data}{$anvil_name}{dr1_host_uuid};
+ if ($anvil->data->{switches}{detailed})
+ {
+ $anvil->data->{anvil_data}{$anvil_name}{node1_host_name} = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{host_name};
+ $anvil->data->{anvil_data}{$anvil_name}{node2_host_name} = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{host_name};
+ $anvil->data->{anvil_data}{$anvil_name}{dr1_host_name} = "";
+ if ($dr1_host_uuid)
+ {
+ $anvil->data->{anvil_data}{$anvil_name}{dr1_host_name} = $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{host_name};
+ }
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:anvil_data::${anvil_name}::node1_host_name" => $anvil->data->{anvil_data}{$anvil_name}{node1_host_name},
+ "s2:anvil_data::${anvil_name}::node2_host_name" => $anvil->data->{anvil_data}{$anvil_name}{node2_host_name},
+ "s3:anvil_data::${anvil_name}::dr1_host_name" => $anvil->data->{anvil_data}{$anvil_name}{dr1_host_name},
+ }});
+ }
+ else
+ {
+ $anvil->data->{anvil_data}{$anvil_name}{node1_host_name} = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{short_host_name};
+ $anvil->data->{anvil_data}{$anvil_name}{node2_host_name} = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{short_host_name};
+ if ($dr1_host_uuid)
+ {
+ $anvil->data->{anvil_data}{$anvil_name}{dr1_host_name} = $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{short_host_name};
+ }
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:anvil_data::${anvil_name}::node1_host_name" => $anvil->data->{anvil_data}{$anvil_name}{node1_host_name},
+ "s2:anvil_data::${anvil_name}::node2_host_name" => $anvil->data->{anvil_data}{$anvil_name}{node2_host_name},
+ "s3:anvil_data::${anvil_name}::dr1_host_name" => $anvil->data->{anvil_data}{$anvil_name}{dr1_host_name},
+ }});
+ }
+
+ $anvil->Get->available_resources({anvil_uuid => $anvil_uuid});
+ my $cpu_cores = $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{cores};
+ my $cpu_threads = $anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads};
+ my $say_cpu = $anvil->Words->string({key => "message_0289", variables => {
+ cores => $cpu_cores,
+ threads => $cpu_threads,
+ }});
+ my $ram_available = $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{available};
+ my $say_ram_available = $anvil->Convert->bytes_to_human_readable({'bytes' => $ram_available});
+ my $ram_used = $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{allocated};
+ my $say_ram_used = $anvil->Convert->bytes_to_human_readable({'bytes' => $ram_used});
+ my $ram_hardware = $anvil->data->{anvil_resources}{$anvil_uuid}{ram}{hardware};
+ my $say_ram_hardware = $anvil->Convert->bytes_to_human_readable({'bytes' => $ram_hardware});
+
+ my $bridges = "";
+ foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{anvil_resources}{$anvil_uuid}{bridges}})
+ {
+ $bridges .= $bridge_name.", ";
+ }
+ $bridges =~ s/, $//;
+
+ # Store
+ $anvil->data->{anvil_data}{$anvil_name}{cpu_string} = $say_cpu;
+ $anvil->data->{anvil_data}{$anvil_name}{ram_used_string} = $say_ram_hardware;
+ $anvil->data->{anvil_data}{$anvil_name}{ram_free_string} = $say_ram_available;
+ $anvil->data->{anvil_data}{$anvil_name}{bridge_string} = $bridges;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:anvil_data::${anvil_name}::cpu_string" => $anvil->data->{anvil_data}{$anvil_name}{cpu_string},
+ "s2:anvil_data::${anvil_name}::ram_used_string" => $anvil->data->{anvil_data}{$anvil_name}{ram_used_string},
+ "s3:anvil_data::${anvil_name}::ram_free_string" => $anvil->data->{anvil_data}{$anvil_name}{ram_free_string},
+ "s4:anvil_data::${anvil_name}::bridge_string" => $anvil->data->{anvil_data}{$anvil_name}{bridge_string},
+ }});
+
+ if (length($anvil->data->{anvil_data}{$anvil_name}{cpu_string}) > $anvil->data->{longest}{host_cpu_string})
+ {
+ $anvil->data->{longest}{host_cpu_string} = length($anvil->data->{anvil_data}{$anvil_name}{cpu_string});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::host_cpu_string' => $anvil->data->{longest}{host_cpu_string},
+ }});
+ }
+
+ if (length($anvil->data->{anvil_data}{$anvil_name}{ram_used_string}) > $anvil->data->{longest}{ram_used})
+ {
+ $anvil->data->{longest}{ram_used} = length($anvil->data->{anvil_data}{$anvil_name}{ram_used_string});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::ram_used' => $anvil->data->{longest}{ram_used},
+ }});
+ }
+
+ if (length($anvil->data->{anvil_data}{$anvil_name}{ram_free_string}) > $anvil->data->{longest}{ram_free})
+ {
+ $anvil->data->{longest}{ram_free} = length($anvil->data->{anvil_data}{$anvil_name}{ram_free_string});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::ram_free' => $anvil->data->{longest}{ram_free},
+ }});
+ }
+
+ if (length($anvil->data->{anvil_data}{$anvil_name}{bridge_string}) > $anvil->data->{longest}{bridge_string})
+ {
+ $anvil->data->{longest}{bridge_string} = length($anvil->data->{anvil_data}{$anvil_name}{bridge_string});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::bridge_string' => $anvil->data->{longest}{bridge_string},
+ }});
+ }
+
+ my $storage_groups = [];
+ foreach my $storage_group_name (sort {$a cmp $b} keys %{$anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}})
+ {
+ my $storage_group_uuid = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group_name}{$storage_group_name}{storage_group_uuid};
+ my $vg_size = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{vg_size};
+ my $free_size = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{free_size};
+ my $sg_used = $vg_size - $free_size;
+ my $vg_size_on_dr = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{vg_size_on_dr};
+ my $free_size_on_dr = $anvil->data->{anvil_resources}{$anvil_uuid}{storage_group}{$storage_group_uuid}{available_on_dr};
+ my $sg_used_on_dr = $vg_size_on_dr - $free_size_on_dr;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:storage_group_name' => $storage_group_name,
+ 's2:storage_group_uuid' => $storage_group_uuid,
+ 's3:vg_size' => $anvil->Convert->add_commas({number => $vg_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $vg_size}).")",
+ 's4:free_size' => $anvil->Convert->add_commas({number => $free_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free_size}).")",
+ 's5:sg_used' => $anvil->Convert->add_commas({number => $sg_used})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $sg_used}).")",
+ 's6:vg_size_on_dr' => $anvil->Convert->add_commas({number => $vg_size_on_dr})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $vg_size_on_dr}).")",
+ 's7:free_size_on_dr' => $anvil->Convert->add_commas({number => $free_size_on_dr})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $free_size_on_dr}).")",
+ 's8:sg_used_on_dr' => $anvil->Convert->add_commas({number => $sg_used_on_dr})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $sg_used_on_dr}).")",
+ }});
+
+ $anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_used_size} = $anvil->Convert->bytes_to_human_readable({'bytes' => $sg_used});
+ $anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_free_size} = $anvil->Convert->bytes_to_human_readable({'bytes' => $free_size});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:anvil_data::${anvil_name}::storage_group::${storage_group_name}::say_used_size" => $anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_used_size},
+ "s2:anvil_data::${anvil_name}::storage_group::${storage_group_name}::say_free_size" => $anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_free_size},
+ }});
+
+ if (length($storage_group_name) > $anvil->data->{longest}{storage_group})
+ {
+ $anvil->data->{longest}{storage_group} = length($storage_group_name);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::storage_group' => $anvil->data->{longest}{storage_group},
+ }});
+ }
+
+ if (length($anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_used_size}) > $anvil->data->{longest}{sg_used})
+ {
+ $anvil->data->{longest}{sg_used} = length($anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_used_size});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::sg_used' => $anvil->data->{longest}{sg_used},
+ }});
+ }
+
+ if (length($anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_free_size}) > $anvil->data->{longest}{sg_free})
+ {
+ $anvil->data->{longest}{sg_free} = length($anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_free_size});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'longest::sg_used' => $anvil->data->{longest}{sg_used},
+ }});
+ }
+ }
+ }
+}
+
+sub show_anvils
+{
+ my ($anvil) = @_;
+
+ my $anvil_header = $anvil->Words->string({key => "header_0081"});
+ my $longest_anvil_name = length($anvil_header) > $anvil->data->{longest}{anvil_name} ? length($anvil_header) : $anvil->data->{longest}{anvil_name};
+ my $description_header = $anvil->Words->string({key => "header_0074"});
+ my $longest_description = length($description_header) > $anvil->data->{longest}{description} ? length($description_header) : $anvil->data->{longest}{description};
+ my $cpu_header = $anvil->Words->string({key => "header_0066"});
+ my $longest_cpu_string = length($cpu_header) > $anvil->data->{longest}{host_cpu_string} ? length($cpu_header) : $anvil->data->{longest}{host_cpu_string};
+ my $ram_used_header = $anvil->Words->string({key => "header_0075"});
+ my $longest_ram_used = length($ram_used_header) > $anvil->data->{longest}{ram_used} ? length($ram_used_header) : $anvil->data->{longest}{ram_used};
+ my $ram_free_header = $anvil->Words->string({key => "header_0076"});
+ my $longest_ram_free = length($ram_free_header) > $anvil->data->{longest}{ram_free} ? length($ram_free_header) : $anvil->data->{longest}{ram_free};
+ my $bridge_header = $anvil->Words->string({key => "header_0077"});
+ my $longest_bridge_string = length($bridge_header) > $anvil->data->{longest}{bridge_string} ? length($bridge_header) : $anvil->data->{longest}{bridge_string};
+ my $storage_group_header = $anvil->Words->string({key => "header_0078"});
+ my $longest_storage_group = length($storage_group_header) > $anvil->data->{longest}{storage_group} ? length($storage_group_header) : $anvil->data->{longest}{storage_group};
+ my $sg_used_header = $anvil->Words->string({key => "header_0079"});
+ my $longest_sg_used = length($sg_used_header) > $anvil->data->{longest}{sg_used} ? length($sg_used_header) : $anvil->data->{longest}{sg_used};
+ my $sg_free_header = $anvil->Words->string({key => "header_0080"});
+ my $longest_sg_free = length($sg_free_header) > $anvil->data->{longest}{sg_free} ? length($sg_free_header) : $anvil->data->{longest}{sg_free};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:longest_anvil_name' => $longest_anvil_name,
+ 's2:longest_description' => $longest_description,
+ 's3:longest_cpu_string' => $longest_cpu_string,
+ 's4:longest_ram_used' => $longest_ram_used,
+ 's5:longest_ram_free' => $longest_ram_free,
+ 's6:longest_bridge_string' => $longest_bridge_string,
+ 's7:longest_storage_group' => $longest_storage_group,
+ 's8:longest_sg_used' => $longest_sg_used,
+ 's9:longest_sg_free' => $longest_sg_free,
+ }});
+
+ # Anvil!
+ my $break_line = "+-".sprintf("%0${longest_anvil_name}d", 0);
+ my $header_line = "| ".sprintf("%-${longest_anvil_name}s", $anvil_header)." ";
+ my $blank_lead = "| ".sprintf("%-${longest_anvil_name}s", $anvil_header)." ";
+ if ($anvil->data->{switches}{detailed})
+ {
+ # Description
+ $break_line .= "-+-".sprintf("%0${longest_description}d", 0);
+ $header_line .= "| ".sprintf("%-${longest_description}s", $description_header)." ";
+ $blank_lead .= " ".sprintf("%-${longest_description}s", $description_header)." ";
+
+ }
+ # CPU String
+ $break_line .= "-+-".sprintf("%0${longest_cpu_string}d", 0);
+ $header_line .= "| ".sprintf("%-${longest_cpu_string}s", $cpu_header)." ";
+ $blank_lead .= " ".sprintf("%-${longest_cpu_string}s", $cpu_header)." ";
+
+ if ($anvil->data->{switches}{detailed})
+ {
+ # RAM used
+ $break_line .= "-+-".sprintf("%0${longest_ram_used}d", 0);
+ $header_line .= "| ".sprintf("%-${longest_ram_used}s", $ram_used_header)." ";
+ $blank_lead .= " ".sprintf("%-${longest_ram_used}s", $ram_used_header)." ";
+ }
+
+ # RAM Free
+ $break_line .= "-+-".sprintf("%0${longest_ram_free}d", 0);
+ $header_line .= "| ".sprintf("%-${longest_ram_free}s", $ram_free_header)." ";
+ $blank_lead .= " ".sprintf("%-${longest_ram_free}s", $ram_free_header)." ";
+
+ # Bridges
+ $break_line .= "-+-".sprintf("%0${longest_bridge_string}d", 0);
+ $header_line .= "| ".sprintf("%-${longest_bridge_string}s", $bridge_header)." ";
+ $blank_lead .= " ".sprintf("%-${longest_bridge_string}s", $bridge_header)." ";
+
+ # Storage Group
+ $break_line .= "-+-".sprintf("%0${longest_storage_group}d", 0);
+ $header_line .= "| ".sprintf("%-${longest_storage_group}s", $storage_group_header)." ";
+
+ if ($anvil->data->{switches}{detailed})
+ {
+ # Storage Group Used
+ $break_line .= "-+-".sprintf("%0${longest_sg_used}d", 0);
+ $header_line .= "| ".sprintf("%-${longest_sg_used}s", $sg_used_header)." ";
+ }
+
+ # Storage Group Free Space
+ $break_line .= "-+-".sprintf("%0${longest_sg_free}d", 0)."-+";
+ $header_line .= "| ".sprintf("%-${longest_sg_free}s", $sg_free_header)." |";
+
+ $break_line =~ s/0/-/g;
+
+ push @{$anvil->data->{display}{lines}}, "";
+ push @{$anvil->data->{display}{lines}}, $break_line;
+ push @{$anvil->data->{display}{lines}}, $header_line;
+ push @{$anvil->data->{display}{lines}}, $break_line;
+ foreach my $anvil_name (sort {$a cmp $b} keys %{$anvil->data->{anvil_data}})
+ {
+ my $anvil_description = $anvil->data->{anvil_data}{$anvil_name}{description};
+ my $cpu_string = $anvil->data->{anvil_data}{$anvil_name}{cpu_string};
+ my $ram_used_string = $anvil->data->{anvil_data}{$anvil_name}{ram_used_string};
+ my $ram_free_string = $anvil->data->{anvil_data}{$anvil_name}{ram_free_string};
+ my $bridge_string = $anvil->data->{anvil_data}{$anvil_name}{bridge_string};
+
+ my $first_line = "| ".sprintf("%-${longest_anvil_name}s", $anvil_name);
+ if ($anvil->data->{switches}{detailed})
+ {
+ $first_line .= " | ".sprintf("%-${longest_description}s", $anvil_description);
+ }
+ $first_line .= " | ".sprintf("%-${longest_cpu_string}s", $cpu_string);
+ if ($anvil->data->{switches}{detailed})
+ {
+ $first_line .= " | ".sprintf("%-${longest_ram_used}s", $ram_used_string);
+ }
+ $first_line .= " | ".sprintf("%-${longest_ram_free}s", $ram_used_string);
+ $first_line .= " | ".sprintf("%-${longest_bridge_string}s", $bridge_string);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { first_line => $first_line }});
+
+ my $storage_groups = [];
+ foreach my $storage_group_name (sort {$a cmp $b} keys %{$anvil->data->{anvil_data}{$anvil_name}{storage_group}})
+ {
+ my $say_used_size = $anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_used_size};
+ my $say_free_size = $anvil->data->{anvil_data}{$anvil_name}{storage_group}{$storage_group_name}{say_free_size};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:storage_group_name' => $storage_group_name,
+ 's2:say_used_size' => $say_used_size,
+ 's3:say_free_size' => $say_free_size,
+ }});
+
+ my $storage_line = " | ".sprintf("%-${longest_storage_group}s", $storage_group_name);
+ if ($anvil->data->{switches}{detailed})
+ {
+ $storage_line .= " | ".sprintf("%-${longest_sg_used}s", $say_used_size);
+ }
+ $storage_line .= " | ".sprintf("%-${longest_sg_free}s", $say_free_size)." |";
+
+ push @{$storage_groups}, $storage_line;
+ }
+
+ my $line_count = @{$storage_groups};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line_count => $line_count }});
+ foreach (my $i = 0; $i < $line_count; $i++)
+ {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { i => $i }});
+ if ($i == 0)
+ {
+ push @{$anvil->data->{display}{lines}}, $first_line.$storage_groups->[$i];
+ }
+ else
+ {
+ push @{$anvil->data->{display}{lines}}, $blank_lead.$storage_groups->[$i];
+ }
+ }
+
+ }
+ push @{$anvil->data->{display}{lines}}, $break_line;
+
+ return(0);
+}
+
+sub show_servers
+{
+ my ($anvil) = @_;
+
+ my $server_header = $anvil->Words->string({key => "header_0065"});
+ my $longest_server_name = length($server_header) > $anvil->data->{longest}{server_name} ? length($server_header) : $anvil->data->{longest}{server_name};
+ my $anvil_header = $anvil->Words->string({key => "brand_0002"});
+ my $longest_anvil_name = length($anvil_header) > $anvil->data->{longest}{anvil_name} ? length($anvil_header) : $anvil->data->{longest}{anvil_name};
+ my $cpu_header = $anvil->Words->string({key => "header_0066"});
+ my $longest_cpu_string = length($cpu_header) > $anvil->data->{longest}{cpu_string} ? length($cpu_header) : $anvil->data->{longest}{cpu_string};
+ my $ram_header = $anvil->Words->string({key => "header_0067"});
+ my $longest_ram_string = length($ram_header) > $anvil->data->{longest}{ram_string} ? length($ram_header) : $anvil->data->{longest}{ram_string};
+ my $resource_header = $anvil->Words->string({key => "header_0068"});
+ my $longest_resource_name = length($resource_header) > $anvil->data->{longest}{resource_name} ? length($resource_header) : $anvil->data->{longest}{resource_name};
+ my $disk_header = $anvil->Words->string({key => "header_0069"});
+ my $longest_disk_size = length($disk_header) > $anvil->data->{longest}{disk_size} ? length($disk_header) : $anvil->data->{longest}{disk_size};
+ my $storage_group_header = $anvil->Words->string({key => "header_0070"});
+ my $longest_storage_group = length($storage_group_header) > $anvil->data->{longest}{storage_group} ? length($storage_group_header) : $anvil->data->{longest}{storage_group};
+ my $bridge_header = $anvil->Words->string({key => "header_0071"});
+ my $longest_bridge_name = length($bridge_header) > $anvil->data->{longest}{bridge_name} ? length($bridge_header) : $anvil->data->{longest}{bridge_name};
+ my $net_model_header = $anvil->Words->string({key => "header_0072"});
+ my $longest_net_model_name = length($net_model_header) > $anvil->data->{longest}{net_model_name} ? length($net_model_header) : $anvil->data->{longest}{net_model_name};
+ my $mac_address_header = $anvil->Words->string({key => "header_0002"});
+ my $longest_mac_address = length($mac_address_header) > $anvil->data->{longest}{mac_address} ? length($mac_address_header) : $anvil->data->{longest}{mac_address};
+ my $ip_address_header = $anvil->Words->string({key => "header_0073"});
+ my $longest_ip_address = length($ip_address_header) > $anvil->data->{longest}{ip_address} ? length($ip_address_header) : $anvil->data->{longest}{ip_address};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's01:longest_server_name' => $longest_server_name,
+ 's02:longest_anvil_name' => $longest_anvil_name,
+ 's03:longest_cpu_string' => $longest_cpu_string,
+ 's04:longest_ram_string' => $longest_ram_string,
+ 's05:longest_resource_name' => $longest_resource_name,
+ 's06:longest_disk_size' => $longest_disk_size,
+ 's07:longest_storage_group' => $longest_storage_group,
+ 's08:longest_bridge_name' => $longest_bridge_name,
+ 's09:longest_net_model_name' => $longest_net_model_name,
+ 's10:longest_mac_address' => $longest_mac_address,
+ 's11:longest_ip_address' => $longest_ip_address,
+ }});
+
+ my $break_line = "+-".sprintf("%0${longest_server_name}d", 0);
+ $break_line .= "-+-".sprintf("%0${longest_anvil_name}d", 0);
+ $break_line .= "-+-".sprintf("%0${longest_cpu_string}d", 0);
+ $break_line .= "-+-".sprintf("%0${longest_ram_string}d", 0);
+ $break_line .= "-+-".sprintf("%0${longest_resource_name}d", 0);
+ $break_line .= "-+-".sprintf("%0${longest_disk_size}d", 0);
+ if ($anvil->data->{switches}{detailed})
+ {
+ $break_line .= "-+-".sprintf("%0${longest_storage_group}d", 0);
+ }
+ $break_line .= "-+-".sprintf("%0${longest_bridge_name}d", 0);
+ if ($anvil->data->{switches}{detailed})
+ {
+ $break_line .= "-+-".sprintf("%0${longest_net_model_name}d", 0);
+ $break_line .= "-+-".sprintf("%0${longest_mac_address}d", 0);
+ }
+ $break_line .= "-+-".sprintf("%0${longest_ip_address}d", 0)."-+";
+ $break_line =~ s/0/-/g;
+
+ my $header_line = "| ".sprintf("%-${longest_server_name}s", $server_header)." ";
+ $header_line .= "| ".sprintf("%-${longest_anvil_name}s", $anvil_header)." ";
+ $header_line .= "| ".sprintf("%-${longest_cpu_string}s", $cpu_header)." ";
+ $header_line .= "| ".sprintf("%-${longest_ram_string}s", $ram_header)." ";
+ $header_line .= "| ".sprintf("%-${longest_resource_name}s", $resource_header)." ";
+ $header_line .= "| ".sprintf("%-${longest_disk_size}s", $disk_header)." ";
+ if ($anvil->data->{switches}{detailed})
+ {
+ $header_line .= "| ".sprintf("%-${longest_storage_group}s", $storage_group_header)." ";
+ }
+ $header_line .= "| ".sprintf("%-${longest_bridge_name}s", $bridge_header)." ";
+ if ($anvil->data->{switches}{detailed})
+ {
+ $header_line .= "| ".sprintf("%-${longest_net_model_name}s", $net_model_header)." ";
+ $header_line .= "| ".sprintf("%-${longest_mac_address}s", $mac_address_header)." ";
+ }
+ $header_line .= "| ".sprintf("%-${longest_ip_address}s", $ip_address_header)." |";
+
+ my $blank_lead = "| ".sprintf("%-${longest_server_name}s", " ")." ";
+ $blank_lead .= " ".sprintf("%-${longest_anvil_name}s", " ")." ";
+ $blank_lead .= " ".sprintf("%-${longest_cpu_string}s", " ")." ";
+ $blank_lead .= " ".sprintf("%-${longest_ram_string}s", " ")." ";
+ my $blank_drbd = "";
+ my $blank_net = "";
+
+ push @{$anvil->data->{display}{lines}}, $anvil->Words->string({key => "message_0290"});
+ push @{$anvil->data->{display}{lines}}, $break_line;
+ push @{$anvil->data->{display}{lines}}, $header_line;
+ push @{$anvil->data->{display}{lines}}, $break_line;
+ #push @{$anvil->data->{display}{lines}}, $blank_lead;
+ foreach my $server_name (sort {$a cmp $b} keys %{$anvil->data->{server_data}})
+ {
+ # There should only ever be one UUID for a given name, but it's not impossible for there to be two.
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_name => $server_name }});
+ foreach my $server_uuid (sort {$a cmp $b} keys %{$anvil->data->{server_data}{$server_name}{server_uuid}})
+ {
+ my $anvil_name = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{anvil_name};
+ my $anvil_uuid = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{anvil_uuid};
+ my $say_cpu = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{say_cpu};
+ my $ram_used = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{ram_used};
+ my $say_ram_used = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{say_ram_used};
+ my $first_line = "| ".sprintf("%-${longest_server_name}s", $server_name);
+ $first_line .= " | ".sprintf("%-${longest_anvil_name}s", $anvil_name);
+ $first_line .= " | ".sprintf("%-${longest_cpu_string}s", $say_cpu);
+ $first_line .= " | ".sprintf("%-${longest_ram_string}s", $say_ram_used)." | ";
+
+ my $drbd_lines = [];
+ foreach my $resource (sort {$a cmp $b} keys %{$anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}})
+ {
+ foreach my $volume (sort {$a cmp $b} keys %{$anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}})
+ {
+ my $say_size = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{say_size};
+ my $storage_group = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{storage_group};
+ my $say_resource = $resource."/".$volume;
+ my $storage_line = sprintf("%-${longest_resource_name}s", $say_resource)." | ";
+ $storage_line .= sprintf("%-${longest_disk_size}s", $say_size)." | ";
+ if ($anvil->data->{switches}{detailed})
+ {
+ $storage_line .= sprintf("%-${longest_storage_group}s", $storage_group)." | ";
+ }
+
+ push @{$drbd_lines}, $storage_line;
+ foreach my $drbd_node (sort {$a cmp $b} keys %{$anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}})
+ {
+ my $drbd_path = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_path};
+ my $drbd_path_by_res = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_path_by_res};
+ my $drbd_minor = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_minor};
+ my $meta_disk = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{'meta-disk'};
+ my $backing_lv = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{backing_lv};
+ my $node_host_uuid = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{host_uuid};
+ }
+
+ if (not length($blank_drbd))
+ {
+ $blank_drbd = sprintf("%-${longest_resource_name}s", " ")." ";
+ if ($anvil->data->{switches}{detailed})
+ {
+ $blank_drbd .= sprintf("%-${longest_disk_size}s", " ")." ";
+ $blank_drbd .= sprintf("%-${longest_storage_group}s", " ")." | ";
+ }
+ else
+ {
+ $blank_drbd .= sprintf("%-${longest_disk_size}s", " ")." |";
+ }
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { blank_drbd => $blank_drbd }});
+ }
+ }
+ }
+
+ my $net_lines = [];
+ foreach my $bridge (sort {$a cmp $b} keys %{$anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}})
+ {
+ foreach my $alias (sort {$a cmp $b} keys %{$anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}})
+ {
+ foreach my $mac (sort {$a cmp $b} keys %{$anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}})
+ {
+ my $model = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{model};
+ my $ip = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{ip};
+ if (not $ip)
+ {
+ $ip = "--";
+ }
+ my $net_line = sprintf("%-${longest_bridge_name}s", $bridge)." | ";
+ if ($anvil->data->{switches}{detailed})
+ {
+ $net_line .= sprintf("%-${longest_net_model_name}s", $model)." | ";
+ $net_line .= sprintf("%-${longest_mac_address}s", $mac)." | ";
+ }
+ $net_line .= sprintf("%-${longest_ip_address}s", $ip)." |";
+
+ push @{$net_lines}, $net_line;
+
+ if (not length($blank_net))
+ {
+ $blank_net = sprintf("%-${longest_bridge_name}s", " ")." ";
+ if ($anvil->data->{switches}{detailed})
+ {
+ $blank_net .= sprintf("%-${longest_net_model_name}s", " ")." ";
+ $blank_net .= sprintf("%-${longest_mac_address}s", " ")." ";
+ }
+ $blank_net .= sprintf("%-${longest_ip_address}s", " ")." |";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { blank_net => $blank_net }});
+ }
+ }
+ }
+ }
+
+ my $drbd_count = @{$drbd_lines};
+ my $net_count = @{$net_lines};
+ my $line_count = $drbd_count > $net_count ? $drbd_count : $net_count;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:drbd_count' => $drbd_count,
+ 's2:net_count' => $net_count,
+ 's3:line_count' => $line_count,
+ }});
+ foreach (my $i = 0; $i < $line_count; $i++)
+ {
+ my $drbd_line = $drbd_lines->[$i] ? $drbd_lines->[$i] : $blank_drbd;
+ my $net_line = $net_lines->[$i] ? $net_lines->[$i] : "-- | -- | -- ";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:i' => $i,
+ 's2:drbd_line' => $drbd_line,
+ 's3:drbd_line' => $net_line,
+ }});
+ if ($i == 0)
+ {
+ push @{$anvil->data->{display}{lines}}, $first_line.$drbd_line.$net_line;
+ }
+ else
+ {
+ push @{$anvil->data->{display}{lines}}, $blank_lead.$drbd_line.$net_line;
+ }
+ }
+ }
+ }
+ push @{$anvil->data->{display}{lines}}, $break_line;
+
+ return(0);
+}
+
+sub collect_server_data
+{
+ my ($anvil) = @_;
+
+ $anvil->Database->get_anvils();
+ $anvil->Database->get_servers();
+ $anvil->Database->get_server_definitions();
+
+ $anvil->data->{longest}{server_name} = 0;
+ $anvil->data->{longest}{anvil_name} = 0;
+ $anvil->data->{longest}{cpu_string} = 0;
+ $anvil->data->{longest}{ram_string} = 0;
+ $anvil->data->{longest}{resource_name} = 0;
+ $anvil->data->{longest}{disk_size} = 0;
+ $anvil->data->{longest}{storage_group} = 0;
+ $anvil->data->{longest}{bridge_name} = 0;
+ $anvil->data->{longest}{net_model_name} = 0;
+ $anvil->data->{longest}{mac_address} = 0;
+ $anvil->data->{longest}{ip_address} = 0;
+ foreach my $server_uuid (sort {$a cmp $b} keys %{$anvil->data->{servers}{server_uuid}})
+ {
+ my $server_name = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_name};
+ my $anvil_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_anvil_uuid};
+ my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
+ my $server_definition = $anvil->data->{server_definitions}{server_definition_server_uuid}{$server_uuid}{server_definition_xml};
+ my $server_ram = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_ram_in_use};
+ if ($anvil->data->{servers}{server_uuid}{$server_uuid}{server_configured_ram} > $server_ram)
+ {
+ $server_ram = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_configured_ram};
+ }
+ my $say_server_ram = $anvil->Convert->bytes_to_human_readable({'bytes' => $server_ram});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:server_name' => $server_name,
+ 's2:anvil_name' => $anvil_name,
+ 's3:server_ram' => $anvil->Convert->add_commas({number => $server_ram})." (".$say_server_ram.")",
+ }});
+
+ my $target = $anvil->Get->short_host_name;
+ my $source = "from_db";
+ $anvil->Server->parse_definition({
+ debug => 2,
+ source => $source,
+ server => $server_name,
+ definition => $server_definition,
+ anvil_uuid => $anvil_uuid,
+ });
+
+ # CPU info
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{anvil_name} = $anvil_name;
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{anvil_uuid} = $anvil_uuid;
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{ram_used} = $server_ram;
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{say_ram_used} = $say_server_ram;
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{total_cores} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{total_cores};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{sockets} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{sockets};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{cores} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{cores};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{threads} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{threads};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{model_name} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{model_name};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{model_fallback} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{model_fallback};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{match} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{match};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{vendor} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{vendor};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{mode} = $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{mode};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{say_cpu} = $anvil->Words->string({key => "message_0287", variables => {
+ total_cores => $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{total_cores},
+ sockets => $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{sockets},
+ }});
+ if ($anvil->data->{switches}{detailed})
+ {
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{say_cpu} = $anvil->Words->string({key => "message_0288", variables => {
+ total_cores => $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{total_cores},
+ sockets => $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{sockets},
+ cores => $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{cores},
+ threads => $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{threads},
+ model => $anvil->data->{server}{$target}{$server_name}{$source}{cpu}{model_name},
+ mode => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{mode},
+ }});
+ }
+
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:server_data::${server_name}::server_uuid::${server_uuid}::anvil_name" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{anvil_name},
+ "s2:server_data::${server_name}::server_uuid::${server_uuid}::anvil_uuid" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{anvil_uuid},
+ "s3:server_data::${server_name}::server_uuid::${server_uuid}::ram_used" => $anvil->Convert->add_commas({number => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{ram_used}})." (".$anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{say_ram_used}.")", ,
+ "s4:server_data::${server_name}::server_uuid::${server_uuid}::cpu::total_cores" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{total_cores},
+ "s5:server_data::${server_name}::server_uuid::${server_uuid}::cpu::sockets" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{sockets},
+ "s5:server_data::${server_name}::server_uuid::${server_uuid}::cpu::cores" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{cores},
+ "s6:server_data::${server_name}::server_uuid::${server_uuid}::cpu::threads" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{threads},
+ "s7:server_data::${server_name}::server_uuid::${server_uuid}::cpu::model_name" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{model_name},
+ "s8:server_data::${server_name}::server_uuid::${server_uuid}::cpu::model_fallback" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{model_fallback},
+ "s9:server_data::${server_name}::server_uuid::${server_uuid}::cpu::match" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{match},
+ "s10:server_data::${server_name}::server_uuid::${server_uuid}::cpu::vendor" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{vendor},
+ "s11:server_data::${server_name}::server_uuid::${server_uuid}::cpu::mode" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{mode},
+ "s12:server_data::${server_name}::server_uuid::${server_uuid}::cpu::say_cpu" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{say_cpu},
+ }});
+
+ if (length($server_name) > $anvil->data->{longest}{server_name})
+ {
+ $anvil->data->{longest}{server_name} = length($server_name);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::server_name' => $anvil->data->{longest}{server_name} }});
+ }
+ if (length($anvil_name) > $anvil->data->{longest}{anvil_name})
+ {
+ $anvil->data->{longest}{anvil_name} = length($anvil_name);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::anvil_name' => $anvil->data->{longest}{anvil_name} }});
+ }
+ if (length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{say_cpu}) > $anvil->data->{longest}{cpu_string})
+ {
+ $anvil->data->{longest}{cpu_string} = length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{cpu}{say_cpu});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::cpu_string' => $anvil->data->{longest}{cpu_string} }});
+ }
+ if (length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{say_ram_used}) > $anvil->data->{longest}{ram_string})
+ {
+ $anvil->data->{longest}{ram_string} = length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{say_ram_used});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::ram_string' => $anvil->data->{longest}{ram_string} }});
+ }
+
+ # I need to know what nodes are in this cluster, so I don't look at another node that may
+ # have a matching node name.
+ my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
+ my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
+ my $dr1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_dr1_host_uuid};
+
+ # Get names.
+ my $node1_host_name = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{host_name};
+ my $node1_short_host_name = $anvil->data->{hosts}{host_uuid}{$node1_host_uuid}{short_host_name};
+ my $node2_host_name = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{host_name};
+ my $node2_short_host_name = $anvil->data->{hosts}{host_uuid}{$node2_host_uuid}{short_host_name};
+ my $dr1_host_name = "";
+ my $dr1_short_host_name = "";
+ if (($dr1_host_uuid) && (exists $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}))
+ {
+ $dr1_host_name = $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{host_name};
+ $dr1_short_host_name = $anvil->data->{hosts}{host_uuid}{$dr1_host_uuid}{short_host_name};
+ }
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:node1_host_name' => $node1_host_name,
+ 's2:node1_short_host_name' => $node1_short_host_name,
+ 's3:node2_host_name' => $node2_host_name,
+ 's4:node2_short_host_name' => $node2_short_host_name,
+ 's5:dr1_host_name' => $dr1_host_name,
+ 's6:dr1_short_host_name' => $dr1_short_host_name,
+ }});
+
+ # Storage info.
+ foreach my $device_target (sort {$a cmp $b} keys %{$anvil->data->{server}{$target}{$server_name}{$source}{device}{disk}{target}})
+ {
+ my $address_domain = $anvil->data->{server}{$target}{$server_name}{$source}{device}{disk}{target}{$device_target}{address}{domain};
+ my $address_slot = $anvil->data->{server}{$target}{$server_name}{$source}{device}{disk}{target}{$device_target}{address}{slot};
+ my $address_function = $anvil->data->{server}{$target}{$server_name}{$source}{device}{disk}{target}{$device_target}{address}{function};
+ my $device_path = $anvil->data->{server}{$target}{$server_name}{$source}{device}{disk}{target}{$device_target}{path};
+ my $driver_io = $anvil->data->{server}{$target}{$server_name}{$source}{device}{disk}{target}{$device_target}{driver}{io};
+ my $driver_cache = $anvil->data->{server}{$target}{$server_name}{$source}{device}{disk}{target}{$device_target}{driver}{cache};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:device_target' => $device_target,
+ 's2:address_domain' => $address_domain,
+ 's3:address_slot' => $address_slot,
+ 's4:address_function' => $address_function,
+ 's5:device_path' => $device_path,
+ 's6:driver_io' => $driver_io,
+ 's7:driver_cache' => $driver_cache,
+ }});
+
+ # What is the DRBD resource name?
+ my ($resource, $volume) = ($device_path =~ /\/dev\/drbd\/by-res\/(.*?)\/(\d+)$/);
+ my $say_resource = $resource."/".$volume;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 's1:resource' => $resource,
+ 's2:volume' => $volume,
+ 's3:say_resource' => $say_resource,
+ }});
+ if (length($say_resource) > $anvil->data->{longest}{resource_name})
+ {
+ $anvil->data->{longest}{resource_name} = length($say_resource);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::resource_name' => $anvil->data->{longest}{resource_name} }});
+ }
+
+ # This will store the largest size LV becking the volume
+ my $disk_size = 0;
+ my $storage_group_name = "";
+ foreach my $drbd_node (sort {$a cmp $b} keys %{$anvil->data->{drbd}{drbd_node}})
+ {
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { drbd_node => $drbd_node }});
+ if (($drbd_node eq $node1_host_name) or
+ ($drbd_node eq $node1_short_host_name) or
+ ($drbd_node eq $node2_host_name) or
+ ($drbd_node eq $node2_short_host_name) or
+ (($dr1_host_name) && ($drbd_node eq $dr1_host_name)) or
+ (($dr1_short_host_name) && ($drbd_node eq $dr1_short_host_name)))
+ {
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_path} = $anvil->data->{drbd}{drbd_node}{$drbd_node}{config}{resource}{$resource}{volume}{$volume}{drbd_path};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_path_by_res} = $anvil->data->{drbd}{drbd_node}{$drbd_node}{config}{resource}{$resource}{volume}{$volume}{drbd_path_by_res};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_minor} = $anvil->data->{drbd}{drbd_node}{$drbd_node}{config}{resource}{$resource}{volume}{$volume}{drbd_minor};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{'meta-disk'} = $anvil->data->{drbd}{drbd_node}{$drbd_node}{config}{resource}{$resource}{volume}{$volume}{'meta-disk'};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{backing_lv} = $anvil->data->{drbd}{drbd_node}{$drbd_node}{config}{resource}{$resource}{volume}{$volume}{backing_lv};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:server_data::${server_name}::server_uuid::${server_uuid}::disk::${resource}::${volume}::node::${drbd_node}::drbd_path" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_path},
+ "s2:server_data::${server_name}::server_uuid::${server_uuid}::disk::${resource}::${volume}::node::${drbd_node}::drbd_path_by_res" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_path_by_res},
+ "s3:server_data::${server_name}::server_uuid::${server_uuid}::disk::${resource}::${volume}::node::${drbd_node}::drbd_minor" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{drbd_minor},
+ "s4:server_data::${server_name}::server_uuid::${server_uuid}::disk::${resource}::${volume}::node::${drbd_node}::meta_disk" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{'meta-disk'},
+ "s5:server_data::${server_name}::server_uuid::${server_uuid}::disk::${resource}::${volume}::node::${drbd_node}::backing_lv" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{backing_lv},
+ }});
+
+ # What this node's host uuid?
+ my $node_host_uuid = "";
+ if (($drbd_node eq $node1_host_name) or ($drbd_node eq $node1_short_host_name))
+ {
+ $node_host_uuid = $node1_host_uuid;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node_host_uuid => $node_host_uuid }});
+ }
+ elsif (($drbd_node eq $node2_host_name) or ($drbd_node eq $node2_short_host_name))
+ {
+ $node_host_uuid = $node2_host_uuid;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node_host_uuid => $node_host_uuid }});
+ }
+ elsif (($drbd_node eq $dr1_host_name) or ($drbd_node eq $dr1_short_host_name))
+ {
+ $node_host_uuid = $dr1_host_uuid;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { node_host_uuid => $node_host_uuid }});
+ }
+
+ # How big is this LV?
+ my $backing_lv = $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{backing_lv};
+ my $query = "
+SELECT
+ a.scan_lvm_lv_size,
+ d.storage_group_name
+FROM
+ scan_lvm_lvs a,
+ scan_lvm_vgs b,
+ storage_group_members c,
+ storage_groups d
+WHERE
+ a.scan_lvm_lv_path = ".$anvil->Database->quote($backing_lv);
+ if ($node_host_uuid)
+ {
+ $query .= "
+AND
+ a.scan_lvm_lv_host_uuid = ".$anvil->Database->quote($node_host_uuid);
+ }
+ $query .= "
+AND
+ a.scan_lvm_lv_on_vg = b.scan_lvm_vg_name";
+ if ($node_host_uuid)
+ {
+ $query .= "
+AND
+ b.scan_lvm_vg_host_uuid = ".$anvil->Database->quote($node_host_uuid);
+ }
+ $query .= "
+AND
+ b.scan_lvm_vg_internal_uuid = c.storage_group_member_vg_uuid";
+ if ($node_host_uuid)
+ {
+ $query .= "
+AND
+ c.storage_group_member_host_uuid = ".$anvil->Database->quote($node_host_uuid);
+ }
+ $query .= "
+AND
+ c.storage_group_member_storage_group_uuid = d.storage_group_uuid
+;";
+ if ($node_host_uuid)
+ {
+ # Store the host_uuid as well.
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{host_uuid} = $node_host_uuid;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:server_data::${server_name}::server_uuid::${server_uuid}::disk::${resource}::${volume}::node::${drbd_node}::host_uuid" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{node}{$drbd_node}{host_uuid},
+ }});
+ }
+ $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 $count = @{$results};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ results => $results,
+ count => $count,
+ }});
+
+ if ($count)
+ {
+ my $size = $results->[0]->[0];
+ my $in_storage_group = $results->[0]->[1];
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ size => $anvil->Convert->add_commas({number => $size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $size}).")",
+ in_storage_group => $in_storage_group,
+ }});
+ if ($size > $disk_size)
+ {
+ $disk_size = $size;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ disk_size => $anvil->Convert->add_commas({number => $disk_size})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $disk_size}).")",
+ }});
+ }
+
+ if ((not $storage_group_name) && ($in_storage_group))
+ {
+ $storage_group_name = $in_storage_group;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_name => $storage_group_name }});
+ }
+ }
+ }
+ }
+
+ # Store the disk size.
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{size} = $disk_size;
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{say_size} = $anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{size}});
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{storage_group} = $storage_group_name;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:server_data::${server_name}::server_uuid::${server_uuid}::disk::${resource}::${volume}::size" => $anvil->Convert->add_commas({number => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{size}})." (".$anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{say_size}.")",
+ "s2:server_data::${server_name}::server_uuid::${server_uuid}::disk::${resource}::${volume}::storage_group" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{storage_group},
+ }});
+
+ if (length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{say_size}) > $anvil->data->{longest}{disk_size})
+ {
+ $anvil->data->{longest}{disk_size} = length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{say_size});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::disk_size' => $anvil->data->{longest}{disk_size} }});
+ }
+
+ if (length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{storage_group}) > $anvil->data->{longest}{storage_group})
+ {
+ $anvil->data->{longest}{storage_group} = length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{disk}{$resource}{$volume}{storage_group});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::storage_group' => $anvil->data->{longest}{storage_group} }});
+ }
+ }
+
+ # Find networks
+ foreach my $mac (sort {$a cmp $b} keys %{$anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}})
+ {
+ my $bridge = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{bridge};
+ my $alias = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{alias};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:mac" => $mac,
+ "s2:bridge" => $bridge,
+ "s3:alias" => $alias,
+ }});
+
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{target} = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{target};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{model} = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{model};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{bus} = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{address}{bus};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{domain} = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{address}{domain};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{type} = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{address}{type};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{slot} = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{address}{slot};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{function} = $anvil->data->{server}{$target}{$server_name}{$source}{device}{interface}{$mac}{address}{function};
+ $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{ip} = $anvil->Network->get_ip_from_mac({debug => 2, mac => $mac});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ "s1:server_data::${server_name}::server_uuid::${server_uuid}::net::${bridge}::${alias}::${mac}::target" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{target},
+ "s2:server_data::${server_name}::server_uuid::${server_uuid}::net::${bridge}::${alias}::${mac}::model" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{model},
+ "s3:server_data::${server_name}::server_uuid::${server_uuid}::net::${bridge}::${alias}::${mac}::bus" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{bus},
+ "s4:server_data::${server_name}::server_uuid::${server_uuid}::net::${bridge}::${alias}::${mac}::domain" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{domain},
+ "s5:server_data::${server_name}::server_uuid::${server_uuid}::net::${bridge}::${alias}::${mac}::type" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{type},
+ "s6:server_data::${server_name}::server_uuid::${server_uuid}::net::${bridge}::${alias}::${mac}::slot" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{slot},
+ "s7:server_data::${server_name}::server_uuid::${server_uuid}::net::${bridge}::${alias}::${mac}::function" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{function},
+ "s8:server_data::${server_name}::server_uuid::${server_uuid}::net::${bridge}::${alias}::${mac}::ip" => $anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{ip},
+ }});
+
+ if (length($bridge) > $anvil->data->{longest}{bridge_name})
+ {
+ $anvil->data->{longest}{bridge_name} = length($bridge);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::bridge_name' => $anvil->data->{longest}{bridge_name} }});
+ }
+
+ if (length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{model}) > $anvil->data->{longest}{net_model_name})
+ {
+ $anvil->data->{longest}{net_model_name} = length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{model});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::net_model_name' => $anvil->data->{longest}{net_model_name} }});
+ }
+
+ if (length($mac) > $anvil->data->{longest}{mac_address})
+ {
+ $anvil->data->{longest}{mac_address} = length($mac);
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::mac_address' => $anvil->data->{longest}{mac_address} }});
+ }
+
+ if (length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{ip}) > $anvil->data->{longest}{ip_address})
+ {
+ $anvil->data->{longest}{ip_address} = length($anvil->data->{server_data}{$server_name}{server_uuid}{$server_uuid}{net}{$bridge}{$alias}{$mac}{ip});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'longest::ip_address' => $anvil->data->{longest}{ip_address} }});
+ }
+ }
+ }
+
+ return(0);
+}
diff --git a/tools/anvil-update-states b/tools/anvil-update-states
index 759a891d..7c9365f8 100755
--- a/tools/anvil-update-states
+++ b/tools/anvil-update-states
@@ -202,13 +202,15 @@ sub update_network
{
# Pull out the data I want. Note that some of these don't exist with virtio-net interfaces.
my $interface = $file;
- my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
- my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
- my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
- my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
+ my $link_state = -e $full_path."/carrier" ? $anvil->Storage->read_file({file => $full_path."/carrier"}) : 0;
+ my $mtu = -e $full_path."/mtu" ? $anvil->Storage->read_file({file => $full_path."/mtu"}) : 0;
+ my $duplex = -e $full_path."/duplex" ? $anvil->Storage->read_file({file => $full_path."/duplex"}) : "unknown"; # full or half?
+ my $operational = -e $full_path."/operstate" ? $anvil->Storage->read_file({file => $full_path."/operstate"}) : "unknown"; # up or down
+ my $modalias = -e $full_path."/device/modalias" ? $anvil->Storage->read_file({file => $full_path."/device/modalias"}) : "unknown";
my $speed = $link_state ? $anvil->Storage->read_file({file => $full_path."/speed"}) : 0; # Mbps (ie: 1000 = Gbps), gives a very high number for unplugged link
my $media = "unknown";
my $type = "interface";
+ my $driver = "";
# Clean up some newlines.
$link_state =~ s/\n$//;
@@ -216,15 +218,25 @@ sub update_network
$duplex =~ s/\n$//;
$operational =~ s/\n$//;
$speed =~ s/\n$//;
+ $modalias =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
link_state => $link_state,
- mtu => $mtu,
+ mtu => $mtu,
duplex => $duplex,
- operational => $operational,
+ operational => $operational,
speed => $speed,
+ modalias => $modalias,
}});
+ ### NOTE: This only parses virtio so far.
+ # Pick out our driver.
+ if ($modalias =~ /^virtio:/)
+ {
+ $driver = "virtio";
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { driver => $driver }});
+ }
+
# The MAC address can faked by a number of ways, so we make an explicit call to 'ethtool' to get the permanent mac address.
my $mac_address = "";
my $shell_call = $anvil->data->{path}{exe}{ethtool}." -P ".$interface;
@@ -298,13 +310,19 @@ sub update_network
# If this is a virtual interface, set some fake values that don't actually exist on
# the system for the sake of a cleaner display.
- if ($mac_address =~ /^52:54:00/)
+ if (($mac_address =~ /^52:54:00/) or ($driver eq "virtio"))
{
### Set some fake values.
# Speed is "as fast as possible", so we'll record 100 Gbps, but that is really kind of arbitrary.
- $speed = 1000 if ((not $speed) or ($speed eq "-1"));
- $duplex = "full" if not $duplex;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
+ if ((not $speed) or ($speed eq "-1"))
+ {
+ $speed = 10000;
+ }
+ if ((not $duplex) or ($duplex eq "unknown"))
+ {
+ $duplex = "full";
+ }
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
speed => $speed,
duplex => $duplex,
}});
@@ -313,7 +331,7 @@ sub update_network
if (not $link_state)
{
$speed = 0;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { speed => $speed }});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { speed => $speed }});
}
# Is this a bond interface?
diff --git a/tools/striker-parse-os-list b/tools/striker-parse-os-list
index de75b973..8c09a1ed 100755
--- a/tools/striker-parse-os-list
+++ b/tools/striker-parse-os-list
@@ -22,8 +22,14 @@ $| = 1;
my $anvil = Anvil::Tools->new();
# Read switches (target ([user@]host[:port]) and the file with the target's password.
+$anvil->data->{switches}{new} = 0;
+$anvil->data->{switches}{xml} = 0;
$anvil->Get->switches;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }});
+$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ 'switches::new' => $anvil->data->{switches}{new},
+ 'switches::xml' => $anvil->data->{switches}{xml},
+}});
my $words_file = $anvil->data->{path}{words}{'words.xml'};
my $language = $anvil->Words->language;
@@ -50,10 +56,26 @@ foreach my $line (split/\n/, $output)
}});
my $os_key = "os_list_".$os_code;
- if ((not exists $anvil->data->{words}{$words_file}{language}{$language}{key}{$os_key}) or (not $anvil->data->{words}{$words_file}{language}{$language}{key}{$os_key}{content}))
+ if ($anvil->data->{switches}{new})
+ {
+ # --xml only makes sense with '--new'. Without --new, we're comparing against the
+ if ((not exists $anvil->data->{words}{$words_file}{language}{$language}{key}{$os_key}) or (not $anvil->data->{words}{$words_file}{language}{$language}{key}{$os_key}{content}))
+ {
+ # Print already known.
+ print "\t\t\n";
+ }
+ }
+ else
{
- # Print already known.
- print "\t\t\n";
+ # Which format?
+ if ($anvil->data->{switches}{xml})
+ {
+ print "\t\t\n";
+ }
+ else
+ {
+ print "key=".$os_code.",name=\"".$os_name."\"\n";
+ }
}
}
diff --git a/tools/striker-scan-network b/tools/striker-scan-network
index 9daff95b..39583a1f 100755
--- a/tools/striker-scan-network
+++ b/tools/striker-scan-network
@@ -270,33 +270,42 @@ sub scan
$anvil->Network->get_ips();
my $target = "local";
my $to_scan = [];
- foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{$target}{interface}})
+ foreach my $target (sort {$a cmp $b} keys %{$anvil->data->{network}})
{
- my $ip = $anvil->data->{network}{$target}{interface}{$interface}{ip};
- my $subnet_mask = $anvil->data->{network}{$target}{interface}{$interface}{subnet_mask};
+ my $is_local = $anvil->Network->is_local({host => $target});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
- ip => $ip,
- subnet_mask => $subnet_mask,
+ target => $target,
+ is_local => $is_local,
}});
- if (($ip) && ($subnet_mask))
+ next if not $is_local;
+ foreach my $interface (sort {$a cmp $b} keys %{$anvil->data->{network}{$target}{interface}})
{
- my $network = $anvil->Network->get_network({ip => $ip, subnet_mask => $subnet_mask});
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network => $network }});
-
- if ($network)
+ my $ip = $anvil->data->{network}{$target}{interface}{$interface}{ip};
+ my $subnet_mask = $anvil->data->{network}{$target}{interface}{$interface}{subnet_mask};
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
+ ip => $ip,
+ subnet_mask => $subnet_mask,
+ }});
+ if (($ip) && ($subnet_mask))
{
- # Scan it.
- my $address = $network."/".$subnet_mask;
- $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { address => $address }});
- push @{$to_scan}, $address;
+ my $network = $anvil->Network->get_network({ip => $ip, subnet_mask => $subnet_mask});
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network => $network }});
+
+ if ($network)
+ {
+ # Scan it.
+ my $address = $network."/".$subnet_mask;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { address => $address }});
+ push @{$to_scan}, $address;
+ }
}
}
- }
-
- # Scan what we found
- foreach my $address (sort {$a cmp $b} @{$to_scan})
- {
- call_nmap($anvil, $address);
+
+ # Scan what we found
+ foreach my $address (sort {$a cmp $b} @{$to_scan})
+ {
+ call_nmap($anvil, $address);
+ }
}
}
@@ -350,7 +359,8 @@ sub call_nmap
my $this_ip = "";
my $this_mac = "";
my $section = "";
- my $shell_call = $anvil->data->{path}{exe}{nmap}." -sP -T4 --min-parallelism 100 --max-parallelism 256 ".$address;
+ my $shell_call = $anvil->data->{path}{exe}{nmap}." -sP -T4 -n --min-parallelism 100 --max-parallelism 256 ".$address;
+ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
open (my $file_handle, $shell_call." 2>&1 |") or $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, secure => 0, priority => "err", key => "log_0014", variables => { shell_call => $shell_call, error => $! }});
while(<$file_handle>)
{