Created Job->bump_progress() to make advancing job progress easier

* Updated Network->collect_data() to find the GENERAL.DEVICES and
  GENERAL.IP-IFACE from match.interface-name when the link is down.
* More work done on anvil-configure-host.

Signed-off-by: digimer <mkelly@alteeve.ca>
main
digimer 12 months ago
parent ef89a79162
commit 71735947dc
  1. 79
      Anvil/Tools/Job.pm
  2. 31
      Anvil/Tools/Network.pm
  3. 12
      share/words.xml
  4. 728
      tools/anvil-configure-host

@ -12,6 +12,7 @@ our $VERSION = "3.0.0";
my $THIS_FILE = "Job.pm";
### Methods;
# bump_progress
# clear
# get_job_details
# get_job_uuid
@ -80,6 +81,84 @@ sub parent
# Public methods #
#############################################################################################################
=head2 bump_progress
This method is meant to make it easier to bump the progress of a jump by some number of steps when a job doesn't run in a linear fashion.
It does this by storing the progress in the C<< sys::job_progress >> hash and incrementing it by the C<< steps >> parameter value (setting it to C<< 0 >> if it doesn't exist or exists with a non-digit value). If the progress goes over C<< 99 >>, it will return C<< 99 >>.
If you want to set the progress to C<< 0 >> or C<< 100 >>, use the C<< set >> parameter.
Parameters;
=head3 set (optional)
If you want to set the progress to a specific value, use this parameter.
B<< NOTE >>: If the set value is less than the current value, the current progress + 1 will be returns. This is meant to prevent progress bars from backing up.
=head3 steps (default '1')
This takes an integer and it will increase the job progress by that value. If this is not specified, or if it is set to a non-integer value, C<< 1 >> will be used.
=cut
sub bump_progress
{
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 => "Job->bump_progress()" }});
my $set = defined $parameter->{set} ? $parameter->{set} : "";
my $steps = defined $parameter->{steps} ? $parameter->{steps} : 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
set => $set,
steps => $steps,
}});
if ((not exists $anvil->data->{sys}{job_progress}) or ($anvil->data->{sys}{job_progress} !~ /^\d+$/))
{
$anvil->data->{sys}{job_progress} = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
}
if ($set =~ /^\d+$/)
{
if ($set > 100)
{
$anvil->data->{sys}{job_progress} = 100;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
}
elsif ($set > $anvil->data->{sys}{job_progress})
{
$anvil->data->{sys}{job_progress}++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
}
}
$anvil->data->{sys}{job_progress} += $steps;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
if ($anvil->data->{sys}{job_progress} > 99)
{
$anvil->data->{sys}{job_progress} = 99;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::job_progress" => $anvil->data->{sys}{job_progress},
}});
}
return($anvil->data->{sys}{job_progress});
}
=head2 clear
This clears the C<< job_picked_up_by >> value for the given job.

@ -1170,18 +1170,41 @@ sub collect_data
# Now loop through and look for the name that maps to what's shown in 'ip addr list'. This can be a bit tricky.
foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{nmcli}{uuid}})
{
my $connection_id = $anvil->data->{nmcli}{uuid}{$uuid}{'connection.id'} // "";
my $connection_interface_name = $anvil->data->{nmcli}{uuid}{$uuid}{'connection.interface-name'} // "";
my $general_devices = $anvil->data->{nmcli}{uuid}{$uuid}{'GENERAL.DEVICES'} // "";
my $general_ip_iface = $anvil->data->{nmcli}{uuid}{$uuid}{'GENERAL.IP-IFACE'} // "";
my $device_type = $anvil->data->{nmcli}{uuid}{$uuid}{'connection.type'} // "";
my $match_interface_name = $anvil->data->{nmcli}{uuid}{$uuid}{'match.interface-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:general_ip_iface' => $general_ip_iface,
's5:device_type' => $device_type,
's2:connection_id' => $connection_id,
's3:connection_interface_name' => $connection_interface_name,
's4:general_devices' => $general_devices,
's5:general_ip_iface' => $general_ip_iface,
's6:device_type' => $device_type,
's7:match_interface_name' => $match_interface_name,
}});
# If there isn't a GENERAL.DEVICES or GENERAL.IP-IFACE, the link is down. Use the match.interface-name.
if (((not $general_devices) or (not $general_ip_iface)) && ($match_interface_name))
{
foreach my $interface (split/,/, $match_interface_name)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { interface => $interface }});
next if $connection_id eq $interface;
if ($interface)
{
$general_devices = $interface if not $general_devices;
$general_ip_iface = $interface if not $general_ip_iface;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
general_devices => $general_devices,
general_ip_iface => $general_ip_iface,
}});
}
}
}
my $device = "";
if (($general_ip_iface) && ($general_ip_iface ne "--"))
{

@ -753,6 +753,8 @@ The XML that failed sanity check was:
<key name="error_0478">[ Error ] - This program must be run on a subnode.</key>
<key name="error_0479">[ Error ] - This subnode is not in the cluster (failed to parse the CIB). Exiting.</key>
<key name="error_0480">[ Error ] - The wanted interface: [#!variable!interface_name!#] which should have the MAC address: [#!variable!mac_address!#] was not found in Network Manager. Unable to proceed.</key>
<key name="error_0481">[ Error ] - Failed to delete the 'connection.interface-name', got: [#!variable!output!#] and it should bhave been blank, aborting!</key>
<key name="error_0482">[ Error ] - Failed to create the 'match.interface-name' value. Expected: [#!variable!new_name!#,#!variable!old_device!#], got: [#!variable!output!#], aborting!</key>
<!-- Files templates -->
<!-- NOTE: Translating these files requires an understanding of which lines are translatable -->
@ -3285,6 +3287,16 @@ proceeding.
- Threads per Core: [#!variable!old_threads!#] -> [#!variable!new_threads!#]
- Total Cores: .... [#!variable!old_total_cores!#] -> [#!variable!new_total_cores!#]]]></key>
<key name="message_0382"><![CDATA[-=] Updated: #!variable!date!# - Press '<ctrl> + <c>' to exit]]></key>
<key name="message_0383">Renaming old device/name: [#!variable!old_device!#/#!variable!old_name!#] with MAC: [#!variable!mac_address!#] to: [#!variable!new_name!#] using UUID: [#!variable!nm_uuid!#].</key>
<key name="message_0384">- Updating the udev file: [#!variable!file!#].</key>
<key name="message_0385">- Removing the old 'connection.interface-name': [#!variable!name!#].</key>
<key name="message_0386">- Matching the new interface name: [#!variable!new_name!#] to the bios device name: [#!variable!old_device!#].</key>
<key name="message_0387">- Setting the connection.id to the bios device name: [#!variable!old_device!#]</key>
<key name="message_0388">The new interface names need a reboot to take effect.</key>
<key name="message_0389">Rebooting NOW! The job will restart on reboot.</key>
<key name="message_0390">Checking if the bond: [#!variable!bond_name!#] exists or not.</key>
<key name="message_0391">- It does, its UUID is: [#!variable!nm_uuid!#].</key>
<key name="message_0392">- The bond: [#!variable!bond_name!#] doesn't exist. Will create it using the primary interface: [#!variable!link1_name!#] (MAC: [#!variable!link1_mac!#], NM UUID: [#!variable!link1_nm_uuid!#) and the backup interface: : [#!variable!link2_name!#] (MAC: [#!variable!link2_mac!#], NM UUID: [#!variable!link2_nm_uuid!#).</key>
<!-- Translate names (protocols, etc) -->
<key name="name_0001">Normal Password</key> <!-- none in mail-server -->

@ -83,10 +83,9 @@ $anvil->Database->insert_or_update_variables({
update_passwords($anvil);
$anvil->Job->update_progress({
debug => 3,
progress => 100,
message => "",
job_uuid => $anvil->data->{job}{uuid},
progress => 100,
message => "",
job_uuid => $anvil->data->{job}{uuid},
});
# Clear maintenance mode.
@ -113,28 +112,38 @@ sub do_reboot
{
my ($anvil) = @_;
### TODO: Nothing should be killing us, anything that could should be updated to hold while we run.
# # Mark that a reboot is needed, in case something kills us before we actually reboot.
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0687", variables => { reason => "#!string!log_0693!#" }});
# my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
# file => $THIS_FILE,
# line => __LINE__,
# job_command => $anvil->data->{path}{exe}{'anvil-manage-power'}." --reboot -y".$anvil->Log->switches,
# job_data => "",
# job_name => "reboot::system",
# job_title => "job_0009",
# job_description => "job_0006",
# job_progress => 0,
# });
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
# Tell the user why we're rebooting
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({set => 10}),
message => "message_0388",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
});
my $time_left = 60;
while ($time_left)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "log_0626", variables => { seconds => $time_left }});
# Give them the countdown.
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({set => 10}),
message => "log_0626",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
variables => { seconds => $time_left },
});
sleep 10;
$time_left -= 10;
}
# Last, log that we're going down now.
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({set => 10}),
message => "message_0389",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
});
my $shell_call = $anvil->data->{path}{exe}{systemctl}." reboot";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
@ -174,7 +183,15 @@ sub update_passwords
if ($error)
{
# Couldn't write the temp file.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "message_0030", variables => { file => $temp_file }});
$anvil->Job->update_progress({
progress => 100,
message => "message_0030",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
job_status => "failed",
variables => { file => $temp_file },
});
$anvil->nice_exit({exit_code => 5});
}
else
@ -237,18 +254,17 @@ sub reconfigure_network
{
my ($anvil) = @_;
my $reboot_needed = 0;
my $local_host = $anvil->Get->short_host_name();
my $prefix = $anvil->data->{config}{prefix};
my $sequence = $anvil->data->{config}{sequence};
my $domain = $anvil->data->{config}{domain};
my $new_host_name = $anvil->data->{config}{host_name};
my $organization = $anvil->data->{config}{organization};
my $bcn_count = $anvil->data->{config}{bcn_count};
my $ifn_count = $anvil->data->{config}{ifn_count};
my $sn_count = $anvil->data->{config}{sn_count};
my $mn_count = $anvil->data->{config}{mn_count};
my $type = $anvil->Get->host_type();
my $local_host = $anvil->Get->short_host_name();
my $prefix = $anvil->data->{config}{prefix};
my $sequence = $anvil->data->{config}{sequence};
my $domain = $anvil->data->{config}{domain};
my $new_host_name = $anvil->data->{config}{host_name};
my $organization = $anvil->data->{config}{organization};
my $bcn_count = $anvil->data->{config}{bcn_count};
my $ifn_count = $anvil->data->{config}{ifn_count};
my $sn_count = $anvil->data->{config}{sn_count};
my $mn_count = $anvil->data->{config}{mn_count};
my $type = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
prefix => $prefix,
sequence => $sequence,
@ -304,24 +320,29 @@ sub reconfigure_network
{
# Success
$anvil->Job->update_progress({
progress => 10,
message => "message_0016,!!host_name!$new_host_name!!",
job_uuid => $anvil->data->{job}{uuid},
progress => $anvil->Job->bump_progress({set => 10}),
message => "message_0016",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
variables => { host_name => $new_host_name },
});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, 'print' => 1, key => "message_0016", variables => { host_name => $new_host_name }});
}
else
{
# Failed
$anvil->Job->update_progress({
progress => 0,
message => "message_0017,!!host_name!$new_host_name!!,!!bad_host_name!$host_name!!",
job_uuid => $anvil->data->{job}{uuid},
progress => 100,
message => "message_0017",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
job_status => "failed",
variables => {
host_name => $new_host_name,
bad_host_name => $host_name,
},
});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "message_0017", variables => {
host_name => $new_host_name,
bad_host_name => $host_name,
}});
$anvil->nice_exit({exit_code => 4});
}
}
@ -458,17 +479,17 @@ ORDER BY
else
{
# Fail out!
my $variables = {
mac_address => $variable_value,
iface1 => $macs->{$variable_value},
iface2 => $device,
};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "error_0376", variables => $variables});
$anvil->Job->update_progress({
progress => 100,
message => "error_0376",
variables => $variables,
job_status => "failed",
'print' => 1,
log_level => 1,
variables => {
mac_address => $variable_value,
iface1 => $macs->{$variable_value},
iface2 => $device,
},
});
$anvil->nice_exit({exit_code => 8});
}
@ -500,9 +521,9 @@ ORDER BY
else
{
# Configure the network using Network Manager
reconfigure_bridges($anvil);
reconfigure_bonds($anvil);
reconfigure_interfaces($anvil);
reconfigure_bonds($anvil);
reconfigure_bridges($anvil);
reconfigure_ip_addresses($anvil);
}
die;
@ -571,7 +592,7 @@ ORDER BY
# We're half-way there.
$anvil->Job->update_progress({
progress => 50,
progress => $anvil->Job->bump_progress({set => 50}),
job_uuid => $anvil->data->{job}{uuid},
});
@ -654,7 +675,7 @@ ORDER BY
}
$anvil->Job->update_progress({
progress => 75,
progress => $anvil->Job->bump_progress({set => 75}),
job_uuid => $anvil->data->{job}{uuid},
});
@ -671,8 +692,278 @@ sub reconfigure_bridges
sub reconfigure_bonds
{
my ($anvil) = @_;
my ($anvil, $wanted_link_name, $nm_uuid) = @_;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
wanted_link_name => $wanted_link_name,
nm_uuid => $nm_uuid,
}});
my $local_host = $anvil->Get->short_host_name();
my $prefix = $anvil->data->{config}{prefix};
my $sequence = $anvil->data->{config}{sequence};
my $domain = $anvil->data->{config}{domain};
my $bcn_count = $anvil->data->{config}{bcn_count};
my $ifn_count = $anvil->data->{config}{ifn_count};
my $sn_count = $anvil->data->{config}{sn_count};
my $mn_count = $anvil->data->{config}{mn_count};
my $type = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
local_host => $local_host,
prefix => $prefix,
sequence => $sequence,
domain => $domain,
type => $type,
}});
foreach my $network_type ("bcn", "sn", "mn", "ifn")
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { network_type => $network_type }});
my $count = 0;
if ($network_type eq "bcn") { $count = $bcn_count; }
elsif ($network_type eq "sn") { $count = $sn_count; }
elsif ($network_type eq "ifn") { $count = $ifn_count; }
elsif ($network_type eq "mn") { $count = $mn_count; }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
# This is the old type of network config
foreach my $i (1..$count)
{
my $bond_name = $network_type.$i."_bond1";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bond_name => $bond_name }});
# Skip if this isn't marked to become a bond.
next if not exists $anvil->data->{config}{$bond_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"config::${bond_name}" => $anvil->data->{config}{$bond_name},
}});
# Check if the bond exists or not.
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({set => 10}),
message => "message_0390",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
variables => { bond_name => $bond_name },
});
if (exists $anvil->data->{nmcli}{bond}{$bond_name})
{
# It does.
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({set => 10}),
message => "message_0391",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
variables => { nm_uuid => $anvil->data->{nmcli}{bond}{$bond_name}{uuid} },
});
}
else
{
# It doesn't, create it.
my $link1_name = $network_type.$i."_link1";
my $link1_mac_key = $network_type.$i."_link1_mac_to_set";
my $link1_mac = $anvil->data->{config}{$link1_mac_key};
my $link1_nm_uuid = $anvil->data->{nmcli}{mac_address}{$link1_mac}{uuid};
my $link2_name = $network_type.$i."_link2";
my $link2_mac_key = $network_type.$i."_link2_mac_to_set";
my $link2_mac = $anvil->data->{config}{$link2_mac_key};
my $link2_nm_uuid = $anvil->data->{nmcli}{mac_address}{$link2_mac}{uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
link1_name => $link1_name,
link1_mac_key => $link1_mac_key,
link1_mac => $link1_mac,
link1_nm_uuid => $link1_nm_uuid,
link2_name => $link2_name,
link2_mac_key => $link2_mac_key,
link2_mac => $link2_mac,
link2_nm_uuid => $link2_nm_uuid,
}});
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({set => 10}),
message => "message_0392",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
variables => {
bond_name => $bond_name,
link1_name => $link1_name,
link1_mac => $link1_mac,
link1_nm_uuid => $link1_nm_uuid,
link2_name => $link2_name,
link2_mac => $link2_mac,
link2_nm_uuid => $link2_nm_uuid,
},
});
die;
# my $primary_interface = $anvil->data->{network_manager}{want}{bond}{$bond_name}{interfaces}->[0];
# if (not $primary_interface)
# {
# print "[ Error ] - There appears to be no primary interface specified for this bond!\n";
# $anvil->nice_exit({exit_code => 1});
# }
# 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,
# return_code => $return_code,
# }});
#
# if ($return_code)
# {
# 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");
#
# my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection up ".$bond_name;
# $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";
# collect_data($anvil);
}
# Now add the interfaces, disabling their ipv4.method first.
# foreach my $interface_name (@{$anvil->data->{network_manager}{want}{bond}{$bond_name}{interfaces}})
# {
# # 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 => {
# 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 }});
# }
#
# 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,
# return_code => $return_code,
# }});
#
# if ($return_code)
# {
# 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});
# }
#
# # Rescan.
# print " - Done! Rescanning the network config.\n";
# ($output, $return_code) = reset_connection($anvil, $interface_uuid);
#
# # Rescan.
# collect_data($anvil);
# }
}
}
=cut
* nmcli::uuid::<uuid>::device = 'connection.interface-name', or 'GENERAL.DEVICES'. See note below
* nmcli::uuid::<uuid>::type = interface, bond, bridge, etc
* nmcli::uuid::<uuid>::active = 1,0
* nmcli::uuid::<uuid>::state = activated,activating,etc
* nmcli::uuid::<uuid>::<variable> = all 'variable: value' pairs returned by 'nmcli connection show <uuid>'
* nmcli::uuid::<uuid>::mac_address = MAC address (in lower case)
* nmcli::uuid::<uuid>::connected = 0 is down, unix timestamp (seconds since epoch) of when it connected if up.
* nmcli::uuid::<uuid>::mtu = This is the MTU (maximum transimssion unit in bytes) of the interface.
To make it easier to map a device by name or MAC address to a UUID, this lookup hash is provided. Note that 'device' is 'connection.interface-name' when available, falling back to 'GENERAL.DEVICES' otherwise.
B<< NOTE >>: An inactive interface will not report the 'connection.interface-name', and the bios device name will be returned (which is what is stored in 'GENERAL.DEVICES'. If you're trying to find a device, and the expected name doesn't exist, look up the device by MAC address. If that's not found, then the old GENERAL.DEVICES name can help you identify a replaced interface.
* nmcli::device::<device>::uuid = interface name (or device name)
* nmcli::mac_address::<mac_address>::uuid = MAC address (lower case)
Given that a single interface can have multiple IP addresses and routes, the IPs on a given interface are stored using a sequence number <1, 2, 3 ... n>. To make it easier to find what device has an IP, the IPs are stored with a quick access hash.
* nmcli::ipv4::<ip_address>::on_uuid = interface UUID
* nmcli::ipv4::<ip_address>::sequence = sequence number
* nmcli::uuid::<uuid>::ipv{4,6}::ip::<sequence>::ip_address = IP address
* nmcli::uuid::<uuid>::ipv{4,6}::ip::<sequence>::subnet_mask = subnet mask (CIDR notation)
* nmcli::uuid::<uuid>::ipv{4,6}::dns = comma-separated list of DNS IP addresses
* nmcli::uuid::<uuid>::ipv{4,6}::gateway = comma-separated list of DNS IP addresses
* nmcli::uuid::<uuid>::ipv{4,6}::route::<sequence> = Route info (ie: 'dst = 0.0.0.0/0, nh = 192.168.255.254, mt = 428', or 'dst = 192.168.0.0/16, nh = 0.0.0.0, mt = 428'.)
Bond data is stored in these hashes;
* nmcli::bond::<bond_device>::uuid = The UUID on the bond
* nmcli::bond::<bond_device>::carrier = 1,0 - indicates if the bond has a connection or not.
* nmcli::bond::<bond_device>::operstate = 1,0 - indicates if the bond is operational or not.
* nmcli::bond::<bond_device>::up = 1,0 - indicates if the bond up up or not.
* nmcli::bond::<bond_device>::interface::<interface>::up = 1,0 - indicates if the child interface is up or not.
Bridge data is simple, but also made easy to find. The only real data is the hash references for the interfaces connected to the bridge.
* nmcli::bridge::<device>::uuid = The UUID of the bridge
* nmcli::bridge::<device>::interface::<interface>::status = This is the link data for the connected interface (ie: 'BROADCAST,MULTICAST,MASTER,UP,LOWER_UP').
To make it easier to find interfaces, the following look up hash is available.
* nmcli::interface::<device>::uuid = The UUID of the interface
* nmcli::mac_address::<mac_address>::uuid = $anvil->data->{nmcli}{mac_address}{$mac_address}{uuid},
=cut
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{config}})
{
print $variable.": [".$anvil->data->{config}{$variable}."]\n";
}
return(0);
}
@ -690,16 +981,15 @@ sub reconfigure_interfaces
{
my ($anvil) = @_;
my $reboot_needed = 0;
my $local_host = $anvil->Get->short_host_name();
my $prefix = $anvil->data->{config}{prefix};
my $sequence = $anvil->data->{config}{sequence};
my $domain = $anvil->data->{config}{domain};
my $bcn_count = $anvil->data->{config}{bcn_count};
my $ifn_count = $anvil->data->{config}{ifn_count};
my $sn_count = $anvil->data->{config}{sn_count};
my $mn_count = $anvil->data->{config}{mn_count};
my $type = $anvil->Get->host_type();
my $local_host = $anvil->Get->short_host_name();
my $prefix = $anvil->data->{config}{prefix};
my $sequence = $anvil->data->{config}{sequence};
my $domain = $anvil->data->{config}{domain};
my $bcn_count = $anvil->data->{config}{bcn_count};
my $ifn_count = $anvil->data->{config}{ifn_count};
my $sn_count = $anvil->data->{config}{sn_count};
my $mn_count = $anvil->data->{config}{mn_count};
my $type = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
local_host => $local_host,
prefix => $prefix,
@ -728,6 +1018,11 @@ sub reconfigure_interfaces
link2_mac_key => $link2_mac_key,
}});
# If the user had the option to create a network but didn't, there will be no link1
# mac to set.
next if not exists $anvil->data->{config}{$link1_mac_key};
next if not $anvil->data->{config}{$link1_mac_key};
my $wanted_link1_name = $network_type.$i."_link1";
my $wanted_link1_mac = $anvil->data->{config}{$link1_mac_key};
my $wanted_link2_name = $network_type.$i."_link2";
@ -747,12 +1042,13 @@ sub reconfigure_interfaces
if (not $link1_nm_uuid)
{
$anvil->Job->update_progress({
progress => 100,
message => "error_0480",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
variables => {
progress => 100,
message => "error_0480",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
job_status => "failed",
variables => {
mac_address => $wanted_link1_mac,
interface_name => $wanted_link1_name,
},
@ -769,91 +1065,35 @@ sub reconfigure_interfaces
if (not $link2_nm_uuid)
{
$anvil->Job->update_progress({
progress => 100,
message => "error_0480",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
variables => {
progress => 100,
message => "error_0480",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
job_status => "failed",
variables => {
mac_address => $wanted_link2_mac,
interface_name => $wanted_link2_name,
},
});
$anvil->nice_exit({exit_code => 1});
}
rename_interface($anvil, $wanted_link1_name, $link1_nm_uuid);
rename_interface($anvil, $wanted_link2_name, $link2_nm_uuid);
# There's a second interface, so create a bond.
my $bond_name = $network_type.$i."_bond1";
$anvil->data->{config}{$bond_name} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"config::${bond_name}" => $anvil->data->{config}{$bond_name},
}});
}
}
}
=cut
* nmcli::uuid::<uuid>::device = 'connection.interface-name', or 'GENERAL.DEVICES'. See note below
* nmcli::uuid::<uuid>::type = interface, bond, bridge, etc
* nmcli::uuid::<uuid>::active = 1,0
* nmcli::uuid::<uuid>::state = activated,activating,etc
* nmcli::uuid::<uuid>::<variable> = all 'variable: value' pairs returned by 'nmcli connection show <uuid>'
* nmcli::uuid::<uuid>::mac_address = MAC address (in lower case)
* nmcli::uuid::<uuid>::connected = 0 is down, unix timestamp (seconds since epoch) of when it connected if up.
* nmcli::uuid::<uuid>::mtu = This is the MTU (maximum transimssion unit in bytes) of the interface.
To make it easier to map a device by name or MAC address to a UUID, this lookup hash is provided. Note that 'device' is 'connection.interface-name' when available, falling back to 'GENERAL.DEVICES' otherwise.
B<< NOTE >>: An inactive interface will not report the 'connection.interface-name', and the bios device name will be returned (which is what is stored in 'GENERAL.DEVICES'. If you're trying to find a device, and the expected name doesn't exist, look up the device by MAC address. If that's not found, then the old GENERAL.DEVICES name can help you identify a replaced interface.
* nmcli::device::<device>::uuid = interface name (or device name)
* nmcli::mac_address::<mac_address>::uuid = MAC address (lower case)
Given that a single interface can have multiple IP addresses and routes, the IPs on a given interface are stored using a sequence number <1, 2, 3 ... n>. To make it easier to find what device has an IP, the IPs are stored with a quick access hash.
* nmcli::ipv4::<ip_address>::on_uuid = interface UUID
* nmcli::ipv4::<ip_address>::sequence = sequence number
* nmcli::uuid::<uuid>::ipv{4,6}::ip::<sequence>::ip_address = IP address
* nmcli::uuid::<uuid>::ipv{4,6}::ip::<sequence>::subnet_mask = subnet mask (CIDR notation)
* nmcli::uuid::<uuid>::ipv{4,6}::dns = comma-separated list of DNS IP addresses
* nmcli::uuid::<uuid>::ipv{4,6}::gateway = comma-separated list of DNS IP addresses
* nmcli::uuid::<uuid>::ipv{4,6}::route::<sequence> = Route info (ie: 'dst = 0.0.0.0/0, nh = 192.168.255.254, mt = 428', or 'dst = 192.168.0.0/16, nh = 0.0.0.0, mt = 428'.)
Bond data is stored in these hashes;
* nmcli::bond::<bond_device>::uuid = The UUID on the bond
* nmcli::bond::<bond_device>::carrier = 1,0 - indicates if the bond has a connection or not.
* nmcli::bond::<bond_device>::operstate = 1,0 - indicates if the bond is operational or not.
* nmcli::bond::<bond_device>::up = 1,0 - indicates if the bond up up or not.
* nmcli::bond::<bond_device>::interface::<interface>::up = 1,0 - indicates if the child interface is up or not.
Bridge data is simple, but also made easy to find. The only real data is the hash references for the interfaces connected to the bridge.
* nmcli::bridge::<device>::uuid = The UUID of the bridge
* nmcli::bridge::<device>::interface::<interface>::status = This is the link data for the connected interface (ie: 'BROADCAST,MULTICAST,MASTER,UP,LOWER_UP').
To make it easier to find interfaces, the following look up hash is available.
* nmcli::interface::<device>::uuid = The UUID of the interface
* nmcli::mac_address::<mac_address>::uuid = $anvil->data->{nmcli}{mac_address}{$mac_address}{uuid},
bcn1_ip: [10.201.4.1]
bcn1_link1_mac_to_set: [52:54:00:84:b3:2c]
bcn1_subnet_mask: [255.255.0.0]
bcn_count: [1]
dns: [8.8.8.8,8.8.4.4]
domain: [alteeve.com]
gateway: [192.168.255.254]
gateway_interface: [ifn1]
host_name: [an9-striker01.alteeve.com]
mn_count: [0]
organization: [Alteeve]
prefix: [an9]
sequence: [1]
sn_count: [0]
striker_password: [Initial1]
striker_user: [admin]
=cut
foreach my $variable (sort {$a cmp $b} keys %{$anvil->data->{config}})
# There is no way (that we've found) to get the network interface ames to be updated without a reboot.
if ($anvil->data->{sys}{reboot_needed})
{
print $variable.": [".$anvil->data->{config}{$variable}."]\n";
do_reboot($anvil);
}
return(0);
@ -880,8 +1120,21 @@ sub rename_interface
's6:type' => $type,
}});
print "Renaming old device/name: [".$old_device."/".$name."] with MAC: [".$mac_address."] to: [".$wanted_link_name."] using UUID: [".$nm_uuid."]\n";
die;
# Tell the user what we're about to rename
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({steps => 2}),
message => "message_0383",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
variables => {
mac_address => $mac_address,
old_device => $old_device,
old_name => $name,
new_name => $wanted_link_name,
nm_uuid => $nm_uuid,
},
});
# Read persistent-net and see if it needs to be updated.
my $new_persistent_net = "";
@ -909,7 +1162,15 @@ sub rename_interface
# Write the new file.
if ($difference)
{
print "- Updating the udev file: [".$anvil->data->{path}{configs}{'persistent-net'}."]\n";
# Updating the udev file
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({steps => 2}),
message => "message_0384",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
variables => { file => $anvil->data->{path}{configs}{'persistent-net'} },
});
my $problem = $anvil->Storage->write_file({
file => $anvil->data->{path}{configs}{'persistent-net'},
body => $new_persistent_net,
@ -922,7 +1183,16 @@ sub rename_interface
$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";
# Failed to write the udev file
$anvil->Job->update_progress({
progress => 100,
message => "error_0043",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
job_status => "failed",
variables => { file => $anvil->data->{path}{configs}{'persistent-net'} },
});
$anvil->nice_exit({exit_code => 1});
}
}
@ -932,7 +1202,15 @@ sub rename_interface
$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";
# Removing the old 'connection.interface-name'
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({steps => 2}),
message => "message_0385",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
variables => { name => $connection_interface_name },
});
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$nm_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});
@ -951,8 +1229,16 @@ sub rename_interface
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";
# Failed to delete the 'connection.interface-name', This should have been blank
$anvil->Job->update_progress({
progress => 100,
message => "error_0481",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
job_status => "failed",
variables => { output => $output },
});
$anvil->nice_exit({exit_code => 1});
}
}
@ -960,58 +1246,86 @@ sub rename_interface
# We'll log what it was, and change it anyway
my $match_interface_name = $anvil->data->{nmcli}{uuid}{$nm_uuid}{'match.interface-name'} ? $anvil->data->{nmcli}{uuid}{$nm_uuid}{'match.interface-name'} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match_interface_name => $match_interface_name }});
if (1)
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({steps => 2}),
message => "message_0386",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
variables => {
new_name => $wanted_link_name,
old_device => $old_device,
},
});
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$nm_uuid." match.interface-name \"".$wanted_link_name." ".$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 ".$nm_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_link_name.",".$old_device) && ($output ne $old_device.",".$wanted_link_name))
{
print "- Matching the new interface name: [".$wanted_link_name."] to the bios device name: [".$old_device."]\n";
my $shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$nm_uuid." match.interface-name \"".$wanted_link_name." ".$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 ".$nm_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_link_name.",".$old_device) && ($output ne $old_device.",".$wanted_link_name))
{
# This should have been blank
print "[ Error ] - Failed to create the 'match.interface-name' value. Expected: [".$wanted_link_name.",".$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 ".$nm_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 ".$nm_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,
}});
# This should have been blank
$anvil->Job->update_progress({
progress => 100,
message => "error_0482",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
job_status => "failed",
variables => {
new_name => $wanted_link_name,
old_device => $old_device,
output => $output,
},
});
$anvil->nice_exit({exit_code => 1});
}
# Set the connection.id to the old name.
$anvil->Job->update_progress({
progress => $anvil->Job->bump_progress({steps => 2}),
message => "message_0387",
log_leve => 1,
'print' => 1,
job_uuid => $anvil->data->{job}{uuid},
variables => { old_device => $old_device },
});
$shell_call = $anvil->data->{path}{exe}{nmcli}." connection modify ".$nm_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 ".$nm_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,
}});
# Re-read the updated data
$anvil->Network->collect_data({debug => 2});
# 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} }});
return(0);
}
@ -2120,9 +2434,11 @@ AND
# Record that we've picked up this job.
$anvil->Job->update_progress({
progress => 1,
message => "message_0015",
job_uuid => $anvil->data->{job}{uuid},
progress => $anvil->Job->bump_progress({steps => 1}),
message => "message_0015",
job_uuid => $anvil->data->{job}{uuid},
'print' => 1,
log_level => 1,
});
# If we're in a cluster, abort.
@ -2139,11 +2455,13 @@ AND
{
# We're in a cluster, abort.
$anvil->Job->update_progress({
progress => 100,
message => "error_0250",
job_uuid => $anvil->data->{job}{uuid},
progress => 100,
message => "error_0250",
job_uuid => $anvil->data->{job}{uuid},
job_status => "failed",
'print' => 1,
log_level => 1,
});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0250"});
$anvil->nice_exit({exit_code => 7});
}
}

Loading…
Cancel
Save