* Updated Network->get_ips() to check for 'permaddr' when processing 'ip addr list' to ensure the partmanent MAC is used.

* Updated scan-filesystems to set swap usage alerts to notice level only.
* Updated scan-network to pull the permanent MAC address from an 'ethtool -P <iface>' call to deal with the fact that wireless interfaces don't have their real MAC in the sysfs address file.
* Updated anvil-provision-server to set the rtc_tickpolicy to catchup.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 3 years ago
parent 8e436ffec7
commit 47c832bc0e
  1. 13
      Anvil/Tools/Network.pm
  2. 47
      Anvil/Tools/Storage.pm
  3. 4
      notes
  4. 14
      scancore-agents/scan-filesystems/scan-filesystems
  5. 4
      scancore-agents/scan-hardware/scan-hardware
  6. 41
      scancore-agents/scan-network/scan-network
  7. 2
      tools/anvil-provision-server

@ -2151,8 +2151,17 @@ fi";
}
if ($line =~ /ether (.*?) /i)
{
my $mac_address = $1;
$anvil->data->{network}{$host}{interface}{$in_iface}{mac_address} = $mac_address;
my $mac_address = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { mac_address => $mac_address }});
# Wireless interfaces have a 'permaddr' that is stable. The MAC address shown by 'ether' changes constantly, for some odd reason.
if ($line =~ /permaddr (.*)$/)
{
$mac_address = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { mac_address => $mac_address }});
}
$anvil->data->{network}{$host}{interface}{$in_iface}{mac_address} = $mac_address;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"network::${host}::interface::${in_iface}::mac_address" => $anvil->data->{network}{$host}{interface}{$in_iface}{mac_address},
}});

@ -1272,6 +1272,8 @@ B<< Warning >>: This must be used carefully! Calling this backwards could destro
B<< Note >>: The caller is responsible for ensuring the data on the soure will not change during the copy. If the source is a server, make sure it's off. If the source is a file system, make sure it's unmounted.
B<< Note >>: If the C<< source >> or C<< destination >> is a remote host, passwordless SSH must be configured for this to work!
Parameters;
=head3 block_size (optional, default '4M')
@ -1298,6 +1300,10 @@ This is the full path to the source (copy from) file or device. If the source is
B<< Note >>: Only the source OR the destination can be remote, not both!
=head3 status_file (required)
This is the path to the status file used to record the progress of the copy. This will contain a parsed version of the C<< dd ... --status=progress >> output. When the copy is done, if C<< calculate_sums >> is set, then the C<< source=<sum> >> and C<< destination=<sum> >> will be recorded, marking the completion of the copy. If not set, those same variables will be written without a value, still marking the end of the copy. If there is a problem, the last line of the file be C<< failed=<reason> >>.
=cut
sub copy_device
{
@ -1305,21 +1311,40 @@ sub copy_device
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 => "Storage->delete_file()" }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Storage->copy_device()" }});
my $file = defined $parameter->{file} ? $parameter->{file} : "";
my $password = defined $parameter->{password} ? $parameter->{password} : "";
my $port = defined $parameter->{port} ? $parameter->{port} : 22;
my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root";
my $target = defined $parameter->{target} ? $parameter->{target} : "";
my $block_size = defined $parameter->{block_size} ? $parameter->{block_size} : "";
my $calculate_sums = defined $parameter->{calculate_sums} ? $parameter->{calculate_sums} : "";
my $destination = defined $parameter->{destination} ? $parameter->{destination} : "";
my $source = defined $parameter->{source} ? $parameter->{source} : "";
my $status_file = defined $parameter->{status_file} ? $parameter->{status_file} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
file => $file,
password => $anvil->Log->is_secure($password),
port => $port,
remote_user => $remote_user,
target => $target,
block_size => $block_size,
calculate_sums => $calculate_sums,
destination => $destination,
source => $source,
status_file => $status_file,
}});
if (not $source)
{
# No source passed.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Storage->copy_device()", parameter => "source" }});
return('!!error!!');
}
if (not $destination)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Storage->copy_device()", parameter => "destination" }});
return('!!error!!');
}
if (not $block_size)
{
$block_size = "4M";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { block_size => $block_size }});
}
# Verify that the source exists.
return("");
}

@ -934,7 +934,7 @@ OS10(conf-vlt-1)# discovery-interface ethernet 1/1/25-1/1/26
# Configure the same MAC address to the VLT on both switches:
OS10# configure terminal
OS10(config)# vlt-domain 1
OS10(conf-vlt-1)# vlt-mac 00:00:00:00:00:02
OS10(conf-vlt-1)# vlt-mac 00:00:00:00:00:02 # Set once per VLT domain, not per switch
OS10# show vlt 1 mismatch
(If no issues, VLT is OK)
@ -958,7 +958,7 @@ OS10(config)# write memory
OS10(config)# hostname zo-switch01
zo-switch01(config)# interface vlan 100
zo-switch01(conf-if-vl-100)# description BCN1
zo-switch01(conf-if-vl-100)# interface range ethernet 1/1/1-1/1/10
zo-switch01(conf-if-vl-100)# interface range ethernet 1/1/1-1/1/14
zo-switch01(conf-range-eth1/1/1-1/1/10)# switchport access vlan 100
zo-switch01(conf-range-eth1/1/1-1/1/10)# no shutdown
zo-switch01(conf-range-eth1/1/1-1/1/10)# exit

@ -486,6 +486,11 @@ INSERT INTO
if ($changed)
{
# First time we've fallen under 5%
my $alert_level = "warning";
if ($new_mount_point eq "<swap>")
{
$alert_level = "notice";
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0002", variables => $variables});
$anvil->Alert->register({
alert_level => "warning",
@ -537,10 +542,15 @@ INSERT INTO
}});
if (($very_low_changed) or ($low_changed))
{
# Clear the alert
# Clear the alert. If this is swap, make it a notice level alert.
my $alert_level = $very_low_changed ? "warning" : "notice";
if ($new_mount_point eq "<swap>")
{
$alert_level = "notice";
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "scan_filesystem_alert_0004", variables => $variables});
$anvil->Alert->register({
alert_level => $very_low_changed ? "warning" : "notice",
alert_level => $alert_level,
clear_alert => 1,
message => "scan_filesystem_alert_0004",
sort_position => 1,

@ -952,7 +952,7 @@ sub find_changes
swap_percent => $new_swap_percent_used,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "scan_hardware_alert_0020", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_hardware_alert_0020", variables => $variables, set_by => $THIS_FILE });
$anvil->Alert->register({alert_level => "notice", message => "scan_hardware_alert_0020", variables => $variables, set_by => $THIS_FILE });
}
}
elsif ($new_scan_hardware_swap_free < $anvil->data->{scancore}{'scan-hardware'}{swap}{clear_threshold})
@ -976,7 +976,7 @@ sub find_changes
swap_percent => $new_swap_percent_used,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "scan_hardware_alert_0021", variables => $variables});
$anvil->Alert->register({alert_level => "warning", message => "scan_hardware_alert_0021", variables => $variables, set_by => $THIS_FILE });
$anvil->Alert->register({alert_level => "notice", message => "scan_hardware_alert_0021", variables => $variables, set_by => $THIS_FILE });
}
}
}

@ -177,7 +177,6 @@ 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 $mac_address = -e $full_path."/address" ? $anvil->Storage->read_file({file => $full_path."/address"}) : "";
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?
@ -188,14 +187,7 @@ sub collect_data
my $tx_bytes = 0; # How many bytes transmitted
my $rx_bytes = 0; # How many bytes received
# If the NIC is a bond member, the MAC address could be virtual.
if (-e $full_path."/bonding_slave/perm_hwaddr")
{
$mac_address = $anvil->Storage->read_file({file => $full_path."/bonding_slave/perm_hwaddr"});
}
# Clean up some newlines.
$mac_address =~ s/\n$//;
$link_state =~ s/\n$//;
$mtu =~ s/\n$//;
$duplex =~ s/\n$//;
@ -203,7 +195,6 @@ sub collect_data
$speed =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
interface => $interface,
mac_address => $mac_address,
link_state => $link_state,
mtu => $mtu,
duplex => $duplex,
@ -211,6 +202,36 @@ sub collect_data
speed => $speed,
}});
# 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;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
if ($output =~ /(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)$/)
{
$mac_address = lc($1);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
}
else
{
# Get it by reading the address file.
if (-e $full_path."/bonding_slave/perm_hwaddr")
{
$mac_address = $anvil->Storage->read_file({file => $full_path."/bonding_slave/perm_hwaddr"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
}
elsif (-e $full_path."/address")
{
$mac_address = $anvil->Storage->read_file({file => $full_path."/address"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
}
}
# These are variables that will be needed if this is a bond interface.
my $ip_address = "";
my $subnet_mask = "";
@ -402,7 +423,7 @@ sub collect_data
}
# Find the media, if possible.
my ($ethtool, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ethtool}." $interface"});
(my $ethtool, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{ethtool}." $interface"});
foreach my $line (split/\n/, $ethtool)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});

@ -488,7 +488,7 @@ sub provision_server
$shell_call .= " --network bridge=ifn1_bridge1".$nic_model." \\\n";
$shell_call .= " --graphics vnc \\\n";
$shell_call .= " --sound ich9 \\\n";
$shell_call .= " --clock offset=".$clock_offset." \\\n"; # We may want to support ',rtc_tickpolicy=catchup'
$shell_call .= " --clock offset=".$clock_offset.",rtc_tickpolicy=catchup \\\n";
$shell_call .= " --boot menu=on \\\n";
$shell_call .= " --disk path=/dev/drbd/by-res/".$server."/0".$disk_bus.",driver.io=threads,cache=writeback,driver.discard=unmap,boot.order=1 \\\n";
$shell_call .= " --disk path=".$anvil->data->{job}{install_iso_path}.",device=cdrom,shareable=on,boot.order=2 \\\n";

Loading…
Cancel
Save