From 47c832bc0e17ab18a3e2a014bac886d9842866a7 Mon Sep 17 00:00:00 2001 From: Digimer Date: Thu, 7 Oct 2021 17:10:25 -0400 Subject: [PATCH] * 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 ' 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 --- Anvil/Tools/Network.pm | 13 ++++- Anvil/Tools/Storage.pm | 47 ++++++++++++++----- notes | 4 +- .../scan-filesystems/scan-filesystems | 14 +++++- scancore-agents/scan-hardware/scan-hardware | 4 +- scancore-agents/scan-network/scan-network | 41 ++++++++++++---- tools/anvil-provision-server | 2 +- 7 files changed, 95 insertions(+), 30 deletions(-) diff --git a/Anvil/Tools/Network.pm b/Anvil/Tools/Network.pm index 254d98f2..13633844 100644 --- a/Anvil/Tools/Network.pm +++ b/Anvil/Tools/Network.pm @@ -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}, }}); diff --git a/Anvil/Tools/Storage.pm b/Anvil/Tools/Storage.pm index db81542b..d29a7fca 100644 --- a/Anvil/Tools/Storage.pm +++ b/Anvil/Tools/Storage.pm @@ -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= >> and C<< destination= >> 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= >>. + =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(""); } diff --git a/notes b/notes index 5af42d87..43fac7aa 100644 --- a/notes +++ b/notes @@ -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 diff --git a/scancore-agents/scan-filesystems/scan-filesystems b/scancore-agents/scan-filesystems/scan-filesystems index bbf0f2ff..513ecc4f 100755 --- a/scancore-agents/scan-filesystems/scan-filesystems +++ b/scancore-agents/scan-filesystems/scan-filesystems @@ -486,6 +486,11 @@ INSERT INTO if ($changed) { # First time we've fallen under 5% + my $alert_level = "warning"; + if ($new_mount_point eq "") + { + $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 "") + { + $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, diff --git a/scancore-agents/scan-hardware/scan-hardware b/scancore-agents/scan-hardware/scan-hardware index a2caebb2..aaf3734c 100755 --- a/scancore-agents/scan-hardware/scan-hardware +++ b/scancore-agents/scan-hardware/scan-hardware @@ -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 }); } } } diff --git a/scancore-agents/scan-network/scan-network b/scancore-agents/scan-network/scan-network index a99255e7..c66fc286 100755 --- a/scancore-agents/scan-network/scan-network +++ b/scancore-agents/scan-network/scan-network @@ -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 }}); diff --git a/tools/anvil-provision-server b/tools/anvil-provision-server index bb453791..54c79d1e 100755 --- a/tools/anvil-provision-server +++ b/tools/anvil-provision-server @@ -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";