Got anvil-monitor-network assembling bonds properly (I think)

Signed-off-by: digimer <mkelly@alteeve.ca>
main
digimer 1 year ago
parent a038a1c553
commit ac2f9999ae
  1. 663
      tools/anvil-monitor-network

@ -29,36 +29,56 @@ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure =
#print "DBs: [".$anvil->data->{sys}{database}{connections}."]\n";
$anvil->data->{network_manager}{want}{ifn1_link1}{mac_address} = "52:54:00:d3:19:cc";
$anvil->data->{network_manager}{want}{ifn1_link1}{device} = "enp1s0";
$anvil->data->{network_manager}{want}{ifn1_link1}{found} = 0;
$anvil->data->{network_manager}{want}{ifn1_link2}{mac_address} = "52:54:00:fc:82:b0";
$anvil->data->{network_manager}{want}{ifn1_link2}{device} = "enp7s0";
$anvil->data->{network_manager}{want}{ifn1_link2}{found} = 0;
$anvil->data->{network_manager}{want}{interface}{ifn1_link1}{mac_address} = "52:54:00:d3:19:cc";
$anvil->data->{network_manager}{want}{interface}{ifn1_link1}{device} = "enp1s0";
$anvil->data->{network_manager}{want}{interface}{ifn1_link2}{mac_address} = "52:54:00:fc:82:b0";
$anvil->data->{network_manager}{want}{interface}{ifn1_link2}{device} = "enp7s0";
$anvil->data->{network_manager}{want}{bcn1_link1}{mac_address} = "52:54:00:86:f5:1d";
$anvil->data->{network_manager}{want}{bcn1_link1}{device} = "enp8s0";
$anvil->data->{network_manager}{want}{bcn1_link1}{found} = 0;
$anvil->data->{network_manager}{want}{bcn1_link2}{mac_address} = "52:54:00:16:c5:33";
$anvil->data->{network_manager}{want}{bcn1_link2}{device} = "enp9s0";
$anvil->data->{network_manager}{want}{bcn1_link2}{found} = 0;
$anvil->data->{network_manager}{want}{interface}{bcn1_link1}{mac_address} = "52:54:00:86:f5:1d";
$anvil->data->{network_manager}{want}{interface}{bcn1_link1}{device} = "enp8s0";
$anvil->data->{network_manager}{want}{interface}{bcn1_link2}{mac_address} = "52:54:00:16:c5:33";
$anvil->data->{network_manager}{want}{interface}{bcn1_link2}{device} = "enp9s0";
$anvil->data->{network_manager}{want}{sn1_link1}{mac_address} = "52:54:00:37:6f:22";
$anvil->data->{network_manager}{want}{sn1_link1}{device} = "enp10s0";
$anvil->data->{network_manager}{want}{sn1_link1}{found} = 0;
$anvil->data->{network_manager}{want}{sn1_link2}{mac_address} = "52:54:00:2f:02:1b";
$anvil->data->{network_manager}{want}{sn1_link2}{device} = "enp11s0";
$anvil->data->{network_manager}{want}{sn1_link2}{found} = 0;
$anvil->data->{network_manager}{want}{interface}{sn1_link1}{mac_address} = "52:54:00:37:6f:22";
$anvil->data->{network_manager}{want}{interface}{sn1_link1}{device} = "enp10s0";
$anvil->data->{network_manager}{want}{interface}{sn1_link2}{mac_address} = "52:54:00:2f:02:1b";
$anvil->data->{network_manager}{want}{interface}{sn1_link2}{device} = "enp11s0";
# Bonds
#$anvil->data->{network_manager}{want}{bond}{ifn1_bond1}{interfaces} = ["ifn1_link1", "ifn1_link2"]; # First interface is primary
$anvil->data->{network_manager}{want}{bond}{bcn1_bond1}{interfaces} = ["bcn1_link1", "bcn1_link2"];
$anvil->data->{network_manager}{want}{bond}{sn1_bond1}{interfaces} = ["sn1_link1", "sn1_link2"];
# Bridges
#$anvil->data->{network_manager}{want}{bridge}{ifn1_bridge1}{on} = "ifn1_bond1";
$anvil->data->{network_manager}{want}{bridge}{bcn1_bridge1}{on} = "bcn1_bond1";
# IP addresses.
#$anvil->data->{network_manager}{want}{ip_on}{ifn1_bridge1}{ip_address} = "192.168.6.42";
#$anvil->data->{network_manager}{want}{ip_on}{ifn1_bridge1}{subnet_mask} = "255.255.0.0";
#$anvil->data->{network_manager}{want}{ip_on}{ifn1_bridge1}{gateway} = "192.168.255.254";
#$anvil->data->{network_manager}{want}{ip_on}{ifn1_bridge1}{dns} = "8.8.8.8,8.8.4.4";
$anvil->data->{network_manager}{want}{ip_on}{sn1_bond1}{ip_address} = "10.101.4.42";
$anvil->data->{network_manager}{want}{ip_on}{sn1_bond1}{subnet_mask} = "255.255.0.0";
$anvil->data->{network_manager}{want}{ip_on}{sn1_bond1}{gateway} = "";
$anvil->data->{network_manager}{want}{ip_on}{sn1_bond1}{dns} = "";
$anvil->data->{network_manager}{want}{ip_on}{bcn1_bridge1}{ip_address} = "10.201.4.42";
$anvil->data->{network_manager}{want}{ip_on}{bcn1_bridge1}{subnet_mask} = "255.255.0.0";
$anvil->data->{network_manager}{want}{ip_on}{bcn1_bridge1}{gateway} = "";
$anvil->data->{network_manager}{want}{ip_on}{bcn1_bridge1}{dns} = "";
$anvil->data->{sys}{reboot_needed} = 0;
$anvil->data->{sys}{make_changes} = 1;
scan($anvil);
collect_data($anvil);
reconfigure($anvil);
$anvil->nice_exit({exit_code => 0});
#############################################################################################################
# Functions #
#############################################################################################################
@ -67,195 +87,163 @@ sub reconfigure
{
my ($anvil) = @_;
my $reconfigure_count = keys %{$anvil->data->{network_manager}{reconfigure}};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reconfigure_count => $reconfigure_count }});
if (not $reconfigure_count)
{
return(0);
}
reconfigure_interfaces($anvil);
reconfigure_bonds($anvil);
reconfigure_bridges($anvil);
reconfigure_ip_addresses($anvil);
foreach my $wanted_interface (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{reconfigure}})
return(0);
}
sub reconfigure_bonds
{
my ($anvil) = @_;
# $anvil->data->{network_manager}{want}{bond}{ifn1_bond1}{interfaces} = ["ifn1_link1", "ifn1_link2"]; # First interface is primary
# $anvil->data->{network_manager}{want}{bond}{ifn1_bond1}{ipv4_method} = "disabled";
foreach my $bond_name (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{want}{bond}})
{
my $uuid = $anvil->data->{network_manager}{reconfigure}{$wanted_interface}{from_uuid};
my $old_device = $anvil->data->{interface}{uuid}{$uuid}{device};
my $name = $anvil->data->{interface}{uuid}{$uuid}{'connection.id'};
my $mac_address = $anvil->data->{interface}{uuid}{$uuid}{mac_address};
my $type = $anvil->data->{interface}{uuid}{$uuid}{type};
print "Renaming old device/name: [".$old_device."/".$name."] with MAC: [".$mac_address."] to: [".$wanted_interface."] using UUID: [".$uuid."]\n";
# Read persistent-net and see if it needs to be updated.
my $new_persistent_net = "";
my $old_persistent_net = "";
if (-e $anvil->data->{path}{configs}{'persistent-net'})
print "Checking if the bond: [".$bond_name."] exists or not.\n";
if (exists $anvil->data->{interface}{bond}{$bond_name})
{
$old_persistent_net = $anvil->Storage->read_file({debug => 2, file => $anvil->data->{path}{configs}{'persistent-net'}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_persistent_net => $old_persistent_net }});
}
foreach my $line (split/\n/, $old_persistent_net)
{
# If this MAC or device name exists already, delete the line.
if (($line =~ /"$mac_address"/) or ($line =~ /"$wanted_interface"/))
{
next;
}
$new_persistent_net .= $line."\n";
print "- It does, its UUID is: [".$anvil->data->{interface}{bond}{$bond_name}{uuid}."]\n";
}
$new_persistent_net .= "SUBSYSTEM==\"net\",ACTION==\"add\",ATTR{address}==\"".$mac_address."\",ATTR{type}==\"".$type."\",NAME=\"".$wanted_interface."\"\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_persistent_net => $new_persistent_net }});
my $difference = diff \$old_persistent_net, \$new_persistent_net, { STYLE => 'Unified' };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { difference => $difference }});
# Write the new file.
if ($difference)
else
{
print "- Updating the udev file: [".$anvil->data->{path}{configs}{'persistent-net'}."]\n";
my $problem = $anvil->Storage->write_file({
file => $anvil->data->{path}{configs}{'persistent-net'},
body => $new_persistent_net,
overwrite => 1,
user => "admin",
group => "admin",
mode => "0644",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem)
my $primary_interface = $anvil->data->{network_manager}{want}{bond}{$bond_name}{interfaces}->[0];
if (not $primary_interface)
{
print "[ Error ] - Failed to write the new: [".$anvil->data->{path}{configs}{'persistent-net'}."] file, aborting!\n";
print "[ Error ] - There appears to be no primary interface specified for this bond!\n";
$anvil->nice_exit({exit_code => 1});
}
}
# Update the connection.interface-name
my $connection_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} ? $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { connection_interface_name => $connection_interface_name }});
if ($connection_interface_name)
{
print "- Removing the old 'connection.interface-name': [".$connection_interface_name."]\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." connection.interface-name \"\"";
print "- It does not, creating it with the primary interface: [".$primary_interface."] now.\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection add type bond con-name ".$bond_name." ifname ".$bond_name." bond.options \"mode=active-backup,miimon=100,downdelay=0,updelay=120000,primary=".$primary_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,
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values connection.interface-name connection show ".$uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
if ($output)
if ($return_code)
{
# This should have been blank
print "[ Error ] - Failed to delete the 'connection.interface-name', got: [".$output."] and it should bhave been blank, aborting!\n";
print "[ Error ] - The attempt to add the bond failed! The return code was: [".$return_code."]. The output, if any, was:\n";
print "========\n";
print $output."\n";
print "========\n";
$anvil->nice_exit({exit_code => 1});
}
my $bond_uuid = ($output =~ /\((.*?)\) successfully added/)[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_uuid => $bond_uuid }});
if ($bond_uuid)
{
print " - Disabling DHCP on the new bond device: [".$bond_uuid."].\n";
my ($output, $return_code) = modify_connection($anvil, $bond_uuid, "ipv4.method", "disabled");
($output, $return_code) = modify_connection($anvil, $bond_uuid, "ipv6.method", "disabled");
}
# Rescan.
print " - Done! Rescanning the network config.\n";
collect_data($anvil);
}
# We'll log what it was, and change it anyway
my $match_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'match.interface-name'} ? $anvil->data->{interface}{uuid}{$uuid}{'match.interface-name'} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_interface_name => $match_interface_name }});
if (1)
# Now add the interfaces, disabling their ipv4.method first.
foreach my $interface_name (@{$anvil->data->{network_manager}{want}{bond}{$bond_name}{interfaces}})
{
print "- Matching the new interface name: [".$wanted_interface."] to the bios device name: [".$old_device."]\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." match.interface-name \"".$wanted_interface." ".$old_device."\"";
$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});
# What is the interface UUID?
my $interface_uuid = $anvil->data->{interface}{device}{$interface_name}{uuid};
my $parent_bond_name = $anvil->data->{interface}{uuid}{$interface_uuid}{'connection.master'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
interface_name => $interface_name,
interface_uuid => $interface_uuid,
parent_bond_name => $parent_bond_name,
}});
if ($parent_bond_name eq "--")
{
$parent_bond_name = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { parent_bond_name => $parent_bond_name }});
}
# Read it back
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values match.interface-name connection show ".$uuid;
if ($parent_bond_name)
{
if ($parent_bond_name eq $bond_name)
{
print "- The interface: [".$interface_name."] (".$interface_uuid.") is already a member of the bond.\n";
next;
}
else
{
print "- The interface: [".$interface_name."] (".$interface_uuid.") is a member of the bond: [".$parent_bond_name."], switching it to this bond.\n";
}
}
else
{
print "- The interface: [".$interface_name."] (".$interface_uuid.") needs to be connected to the bond.\n";
}
print " - Disabling DHCP on the interface\n";
my ($output, $return_code) = modify_connection($anvil, $interface_uuid, "ipv4.method", "disabled");
($output, $return_code) = modify_connection($anvil, $interface_uuid, "ipv6.method", "disabled");
print " - Connecting the interface to the bond.\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$interface_uuid." connection.master ".$bond_name." connection.slave-type bond";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
output => $output,
return_code => $return_code,
}});
if (($output ne $wanted_interface.",".$old_device) && ($output ne $old_device.",".$wanted_interface))
if ($return_code)
{
# This should have been blank
print "[ Error ] - Failed to create the 'match.interface-name' value. Expected: [".$wanted_interface.",".$old_device."], got: [".$output."], aborting!\n";
print "[ Error ] - The attempt to add the bond failed! The return code was: [".$return_code."]. The output, if any, was:\n";
print "========\n";
print $output."\n";
print "========\n";
$anvil->nice_exit({exit_code => 1});
}
# Set the connection.id to the old name.
print "- Setting the connection.id to the bios device name: [".$old_device."]\n";
$shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." connection.id \"".$old_device."\"";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
# Rescan.
print " - Done! Rescanning the network config.\n";
($output, $return_code) = reset_connection($anvil, $interface_uuid);
# Read it back
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values connection.id connection show ".$uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
# Rescan.
collect_data($anvil);
}
# Set the reboot flag.
$anvil->data->{sys}{reboot_needed} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::reboot_needed" => $anvil->data->{sys}{reboot_needed} }});
}
if ($anvil->data->{sys}{reboot_needed})
return(0);
}
sub reconfigure_bridges
{
my ($anvil) = @_;
foreach my $bridge_name (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{want}{bridge}})
{
print "Reboot needed.\n";
print "- Regenerating dracute initrd image, this can take a moment...\n";
my $shell_call = $anvil->data->{path}{exe}{dracut}." --force";
$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});
my $on_device = $anvil->data->{network_manager}{want}{bridge}{$bridge_name}{on};
print "Checking if the bridge: [".$bridge_name."] exists and that it is on: [".$on_device."]\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
bridge_name => $bridge_name,
on_device => $on_device,
}});
print "- New initrd image created, rebooting in 60 seconds (press 'ctrl + c' to abort).\n";
my $timeout = 60;
while($timeout)
{
if ($timeout % 10)
{
print "."
}
else
{
print $timeout;
}
sleep 1;
$timeout--;
}
print "0\n";
}
return(0);
}
sub scan
sub reconfigure_ip_addresses
{
my ($anvil) = @_;
# Get a list of interfaces.
get_interfaces($anvil);
return(0);
}
sub get_interfaces
sub collect_data
{
my ($anvil) = @_;
@ -310,11 +298,16 @@ sub get_interfaces
}});
foreach my $line (split/\n/, $output)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }});
if ($line =~ /^(.*?):\s+(.*)$/)
{
my $variable = $1;
my $value = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:variable' => $variable,
's2:value' => $value,
}});
$anvil->data->{interface}{uuid}{$uuid}{$variable} = $value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::uuid::${uuid}::${variable}" => $anvil->data->{interface}{uuid}{$uuid}{$variable},
@ -439,13 +432,14 @@ sub get_interfaces
{
my $connection_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} // "";
my $general_devices = $anvil->data->{interface}{uuid}{$uuid}{'GENERAL.DEVICES'} // "";
my $device_type = $anvil->data->{interface}{uuid}{$uuid}{'connection.type'} // "";
my $device = $connection_interface_name ne "--" ? $connection_interface_name : $general_devices;
my $name =
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:uuid' => $uuid,
's2:connection_interface_name' => $connection_interface_name,
's3:general_devices' => $general_devices,
's4:device' => $device,
's4:device_type' => $device_type,
's5:device' => $device,
}});
if ($device)
@ -468,52 +462,67 @@ sub get_interfaces
"interface::uuid::${uuid}::connected" => $anvil->data->{interface}{uuid}{$uuid}{connected},
}});
# MAC address
my $mac_address_file = "/sys/class/net/".$device."/address";
my $type_file = "/sys/class/net/".$device."/type";
my $mtu_file = "/sys/class/net/".$device."/mtu";
if (-e $mac_address_file)
if ($device_type eq "bond")
{
my $mac_address = $anvil->Storage->read_file({file => $mac_address_file});
$mac_address =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
if (($mac_address) && ($mac_address ne "!!error!!"))
{
$anvil->data->{interface}{uuid}{$uuid}{mac_address} = $mac_address;
$anvil->data->{interface}{mac_address}{$mac_address}{uuid} = $uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::uuid::${uuid}::mac_address" => $anvil->data->{interface}{uuid}{$uuid}{mac_address},
"interface::mac_address::${mac_address}::uuid" => $anvil->data->{interface}{mac_address}{$mac_address}{uuid},
}});
}
$anvil->data->{interface}{bond}{$device}{uuid} = $uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::bond::${device}::uuid" => $anvil->data->{interface}{bond}{$device}{uuid},
}});
}
if (-e $type_file)
elsif ($device_type eq "802-3-ethernet")
{
my $type = $anvil->Storage->read_file({file => $type_file});
$type =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }});
$anvil->data->{interface}{phy}{$device}{uuid} = $uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::phy::${device}::uuid" => $anvil->data->{interface}{phy}{$device}{uuid},
}});
if (($type) && ($type ne "!!error!!"))
# MAC address
my $mac_address_file = "/sys/class/net/".$device."/address";
my $type_file = "/sys/class/net/".$device."/type";
my $mtu_file = "/sys/class/net/".$device."/mtu";
if (-e $mac_address_file)
{
$anvil->data->{interface}{uuid}{$uuid}{type} = $type;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::uuid::${uuid}::type" => $anvil->data->{interface}{uuid}{$uuid}{type},
}});
my $mac_address = $anvil->Storage->read_file({file => $mac_address_file});
$mac_address =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mac_address => $mac_address }});
if (($mac_address) && ($mac_address ne "!!error!!"))
{
$anvil->data->{interface}{uuid}{$uuid}{mac_address} = $mac_address;
$anvil->data->{interface}{mac_address}{$mac_address}{uuid} = $uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::uuid::${uuid}::mac_address" => $anvil->data->{interface}{uuid}{$uuid}{mac_address},
"interface::mac_address::${mac_address}::uuid" => $anvil->data->{interface}{mac_address}{$mac_address}{uuid},
}});
}
}
}
if (-e $mtu_file)
{
my $mtu = $anvil->Storage->read_file({file => $mtu_file});
$mtu =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mtu => $mtu }});
if (($mtu) && ($mtu ne "!!error!!"))
if (-e $type_file)
{
$anvil->data->{interface}{uuid}{$uuid}{mtu} = $mtu;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::uuid::${uuid}::mtu" => $anvil->data->{interface}{uuid}{$uuid}{mtu},
}});
my $type = $anvil->Storage->read_file({file => $type_file});
$type =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }});
if (($type) && ($type ne "!!error!!"))
{
$anvil->data->{interface}{uuid}{$uuid}{type} = $type;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::uuid::${uuid}::type" => $anvil->data->{interface}{uuid}{$uuid}{type},
}});
}
}
if (-e $mtu_file)
{
my $mtu = $anvil->Storage->read_file({file => $mtu_file});
$mtu =~ s/\n$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mtu => $mtu }});
if (($mtu) && ($mtu ne "!!error!!"))
{
$anvil->data->{interface}{uuid}{$uuid}{mtu} = $mtu;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"interface::uuid::${uuid}::mtu" => $anvil->data->{interface}{uuid}{$uuid}{mtu},
}});
}
}
}
}
@ -551,14 +560,10 @@ sub get_interfaces
"s13:route_count" => $route_count,
}});
#print "- Device: [".$device."], Name: [".$name."], MAC: [".$mac_address."], UUID: [".$uuid."]\n";
# $anvil->data->{network_manager}{want}{ifn1_link1}{mac_address} = "52:54:00:d3:19:cc";
# $anvil->data->{network_manager}{want}{ifn1_link1}{device} = "enp1s0";
# $anvil->data->{network_manager}{want}{ifn1_link1}{found} = 0;
if (exists $anvil->data->{network_manager}{want}{$device})
if (exists $anvil->data->{network_manager}{want}{interface}{$device})
{
# We know this device. Does it match the expected MAC address?
my $wanted_mac_address = $anvil->data->{network_manager}{want}{ifn1_link1}{mac_address};
my $wanted_mac_address = $anvil->data->{network_manager}{want}{interface}{ifn1_link1}{mac_address};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { wanted_mac_address => $wanted_mac_address }});
if (lc($wanted_mac_address) eq lc($mac_address))
{
@ -573,10 +578,10 @@ sub get_interfaces
{
#print " - This interface isn't one of the matched ones. Check if this should be reconfigured.\n";
my $reconfigure_to = "";
foreach my $wanted_interface (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{want}})
foreach my $wanted_interface (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{want}{interface}})
{
my $wanted_device = $anvil->data->{network_manager}{want}{$wanted_interface}{device};
my $wanted_mac_address = $anvil->data->{network_manager}{want}{$wanted_interface}{mac_address};
my $wanted_device = $anvil->data->{network_manager}{want}{interface}{$wanted_interface}{device};
my $wanted_mac_address = $anvil->data->{network_manager}{want}{interface}{$wanted_interface}{mac_address};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
wanted_interface => $wanted_interface,
wanted_device => $wanted_device,
@ -647,3 +652,245 @@ sub get_interfaces
return(0);
}
sub reconfigure_interfaces
{
my ($anvil) = @_;
my $reconfigure_count = keys %{$anvil->data->{network_manager}{reconfigure}};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { reconfigure_count => $reconfigure_count }});
if (not $reconfigure_count)
{
return(0);
}
foreach my $wanted_interface (sort {$a cmp $b} keys %{$anvil->data->{network_manager}{reconfigure}})
{
my $uuid = $anvil->data->{network_manager}{reconfigure}{$wanted_interface}{from_uuid};
my $old_device = $anvil->data->{interface}{uuid}{$uuid}{device};
my $name = $anvil->data->{interface}{uuid}{$uuid}{'connection.id'};
my $mac_address = $anvil->data->{interface}{uuid}{$uuid}{mac_address};
my $type = $anvil->data->{interface}{uuid}{$uuid}{type};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:wanted_interface' => $wanted_interface,
's2:uuid' => $uuid,
's3:old_device' => $old_device,
's4:name' => $name,
's5:mac_address' => $mac_address,
's6:type' => $type,
}});
print "Renaming old device/name: [".$old_device."/".$name."] with MAC: [".$mac_address."] to: [".$wanted_interface."] using UUID: [".$uuid."]\n";
# Read persistent-net and see if it needs to be updated.
my $new_persistent_net = "";
my $old_persistent_net = "";
if (-e $anvil->data->{path}{configs}{'persistent-net'})
{
$old_persistent_net = $anvil->Storage->read_file({debug => 2, file => $anvil->data->{path}{configs}{'persistent-net'}});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { old_persistent_net => $old_persistent_net }});
}
foreach my $line (split/\n/, $old_persistent_net)
{
# If this MAC or device name exists already, delete the line.
if (($line =~ /"$mac_address"/) or ($line =~ /"$wanted_interface"/))
{
next;
}
$new_persistent_net .= $line."\n";
}
$new_persistent_net .= "SUBSYSTEM==\"net\",ACTION==\"add\",ATTR{address}==\"".$mac_address."\",ATTR{type}==\"".$type."\",NAME=\"".$wanted_interface."\"\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { new_persistent_net => $new_persistent_net }});
my $difference = diff \$old_persistent_net, \$new_persistent_net, { STYLE => 'Unified' };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { difference => $difference }});
# Write the new file.
if ($difference)
{
print "- Updating the udev file: [".$anvil->data->{path}{configs}{'persistent-net'}."]\n";
my $problem = $anvil->Storage->write_file({
file => $anvil->data->{path}{configs}{'persistent-net'},
body => $new_persistent_net,
overwrite => 1,
user => "admin",
group => "admin",
mode => "0644",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem)
{
print "[ Error ] - Failed to write the new: [".$anvil->data->{path}{configs}{'persistent-net'}."] file, aborting!\n";
$anvil->nice_exit({exit_code => 1});
}
}
# Update the connection.interface-name
my $connection_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} ? $anvil->data->{interface}{uuid}{$uuid}{'connection.interface-name'} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { connection_interface_name => $connection_interface_name }});
if ($connection_interface_name)
{
print "- Removing the old 'connection.interface-name': [".$connection_interface_name."]\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." connection.interface-name \"\"";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values connection.interface-name connection show ".$uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
if ($output)
{
# This should have been blank
print "[ Error ] - Failed to delete the 'connection.interface-name', got: [".$output."] and it should bhave been blank, aborting!\n";
$anvil->nice_exit({exit_code => 1});
}
}
# We'll log what it was, and change it anyway
my $match_interface_name = $anvil->data->{interface}{uuid}{$uuid}{'match.interface-name'} ? $anvil->data->{interface}{uuid}{$uuid}{'match.interface-name'} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_interface_name => $match_interface_name }});
if (1)
{
print "- Matching the new interface name: [".$wanted_interface."] to the bios device name: [".$old_device."]\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." match.interface-name \"".$wanted_interface." ".$old_device."\"";
$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,
}});
# Read it back
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values match.interface-name connection show ".$uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
if (($output ne $wanted_interface.",".$old_device) && ($output ne $old_device.",".$wanted_interface))
{
# This should have been blank
print "[ Error ] - Failed to create the 'match.interface-name' value. Expected: [".$wanted_interface.",".$old_device."], got: [".$output."], aborting!\n";
$anvil->nice_exit({exit_code => 1});
}
# Set the connection.id to the old name.
print "- Setting the connection.id to the bios device name: [".$old_device."]\n";
$shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." connection.id \"".$old_device."\"";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
# Read it back
$shell_call = $anvil->data->{path}{exe}{nmcli}." --get-values connection.id connection show ".$uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
}
# Set the reboot flag.
$anvil->data->{sys}{reboot_needed} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::reboot_needed" => $anvil->data->{sys}{reboot_needed} }});
}
if ($anvil->data->{sys}{reboot_needed})
{
print "Reboot needed.\n";
print "- Regenerating dracute initrd image, this can take a moment...\n";
my $shell_call = $anvil->data->{path}{exe}{dracut}." --force";
$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,
}});
print "- New initrd image created.\n";
print "[ Note ] - Reboot needed. Re-run this after the reboot to complete setup.\n";
print "- Rebooting in 60 seconds (press 'ctrl + c' to abort).\n";
my $timeout = 60;
while($timeout)
{
if ($timeout % 10)
{
print "."
}
else
{
print $timeout;
}
sleep 1;
$timeout--;
}
print "0\n";
print "Rebooting NOW!\n";
$shell_call = $anvil->data->{path}{exe}{systemctl}." reboot";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output, return_code => $return_code }});
}
return(0);
}
sub modify_connection
{
my ($anvil, $uuid, $variable, $value) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
uuid => $uuid,
variable => $variable,
value => $value,
}});
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$uuid." ".$variable." ".$value;
$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,
}});
return($output, $return_code);
}
sub reset_connection
{
my ($anvil, $uuid) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }});
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection down ".$uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
$shell_call = $anvil->data->{path}{exe}{nmcli}." connection up ".$uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
($output, $return_code) = $anvil->System->call({shell_call => $shell_call});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
output => $output,
return_code => $return_code,
}});
return($output, $return_code);
}

Loading…
Cancel
Save