diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index c0b9beb9d..d358eba2b 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -4614,7 +4614,6 @@ AND $query = " SELECT ip_address_uuid, - ip_address_host_uuid, ip_address_on_type, ip_address_on_uuid, ip_address_address, @@ -4639,14 +4638,12 @@ ORDER BY foreach my $row (@{$results}) { my $ip_address_uuid = $row->[0]; - my $ip_address_host_uuid = $row->[1]; - my $ip_address_on_type = $row->[2]; - my $ip_address_on_uuid = $row->[3]; - my $ip_address_address = $row->[4]; - my $ip_address_subnet_mask = $row->[5]; + my $ip_address_on_type = $row->[1]; + my $ip_address_on_uuid = $row->[2]; + my $ip_address_address = $row->[3]; + my $ip_address_subnet_mask = $row->[4]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip_address_uuid => $ip_address_uuid, - ip_address_host_uuid => $ip_address_host_uuid, ip_address_on_type => $ip_address_on_type, ip_address_on_uuid => $ip_address_on_uuid, ip_address_address => $ip_address_address, @@ -4661,7 +4658,6 @@ ORDER BY # Duplicate, delete it. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, priority => "alert", key => "warning_0001", variables => { ip_address_uuid => $ip_address_uuid, - host_uuid => $ip_address_host_uuid, on_type => $ip_address_on_type, on_uuid => $ip_address_on_uuid, ip_address => $ip_address_address, @@ -4697,7 +4693,7 @@ ORDER BY } # We want to be able to map IPs to hosts. - $anvil->data->{ip_addresses}{$ip_address_address}{host_uuid} = $ip_address_host_uuid; + $anvil->data->{ip_addresses}{$ip_address_address}{host_uuid} = $host_uuid; $anvil->data->{ip_addresses}{$ip_address_address}{ip_address_uuid} = $ip_address_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "ip_addresses::${ip_address_address}::host_uuid" => $anvil->data->{ip_addresses}{$ip_address_address}{host_uuid}, diff --git a/Anvil/Tools/Network.pm b/Anvil/Tools/Network.pm index 852372eb5..3d47187e2 100644 --- a/Anvil/Tools/Network.pm +++ b/Anvil/Tools/Network.pm @@ -3327,6 +3327,7 @@ sub load_ips if (not $host_uuid) { + # The host UUID should be based on the host. $host_uuid = $anvil->Get->host_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid }}); } @@ -3399,34 +3400,69 @@ AND $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { network_interface_uuid => $network_interface_uuid }}); } else - { - my $query = ""; + { + my $query = ""; + my $active_interface = ""; if ($ip_address_on_type eq "bridge") { - # What's the bridge UUID? - $query = "SELECT bond_name, bond_active_interface FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($ip_address_on_uuid).";"; + # is this on a bond? If so, what's the bond UUID? + my $query = "SELECT bond_name, bond_active_interface FROM bonds WHERE bond_bridge_uuid = ".$anvil->Database->quote($ip_address_on_uuid).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); - # Get the bridge name, also. - if (1) + my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + if ($count) { + # This is on a bridge + $bond_name = $results->[0]->[0]; + $active_interface = $results->[0]->[1]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + bond_name => $bond_name, + active_interface => $active_interface, + }}); + + # Get the bridge name, also. my $query = "SELECT bridge_name FROM bridges WHERE bridge_uuid = ".$anvil->Database->quote($ip_address_on_uuid).";"; $bridge_name = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0]; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { bridge_name => $bridge_name }}); } + else + { + # It must be on an interface then. + my $query = "SELECT network_interface_uuid, network_interface_name, network_interface_device FROM network_interfaces WHERE network_interface_bridge_uuid = ".$anvil->Database->quote($ip_address_on_uuid).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + + my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + $network_interface_uuid = $results->[0]->[0]; + $interface_name = $results->[0]->[1]; + $interface_device = $results->[0]->[2]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + network_interface_uuid => $network_interface_uuid, + interface_name => $interface_name, + interface_device => $interface_device, + }}); + } } else { + # This is a bond $query = "SELECT bond_name, bond_active_interface FROM bonds WHERE bond_uuid = ".$anvil->Database->quote($ip_address_on_uuid).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + $bond_name = $results->[0]->[0]; + $active_interface = $results->[0]->[1]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + bond_name => $bond_name, + active_interface => $active_interface, + }}); } - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); - my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); - $bond_name = $results->[0]->[0]; - my $active_interface = $results->[0]->[1]; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - bond_name => $bond_name, - active_interface => $active_interface, - }}); + # If this is a bond, or it is a bridge that is on a bond, find the + # network_interface_uuid. if ($active_interface) { my $query = " diff --git a/man/anvil-configure-host.8 b/man/anvil-configure-host.8 index dc05871d8..d99b8bed1 100644 --- a/man/anvil-configure-host.8 +++ b/man/anvil-configure-host.8 @@ -20,6 +20,67 @@ When logging, record sensitive data, like passwords. Set the log level to 1, 2 or 3 respectively. Be aware that level 3 generates a significant amount of log data. .IP .SS "Commands:" +\fB\-\-file\fR +This provides an alternative to using the Striker UI's network configuration tool. To use this, create a file with the format; +.TP +.B Strikers +.EX +organization = +prefix = +sequence = 1+ +domain = +striker_password = +host_name = +gateway_interface = +gateway = +dns = +# If you have only one BCN but it's BCN 2 (or 3, 4...), set the BCN count to +# the number of the real BCN and the previous BCNs will be ignored. +ifn_count = 1 +ifn1_ip = +ifn1_subnet_mask = +ifn1_link1_mac_to_set = +ifn1_link2_mac_to_set = +bcn_count = 1 +bcn1_ip = +bcn1_subnet_mask = +bcn1_link1_mac_to_set = +bcn1_link2_mac_to_set = +.EE +.TP +.B Nodes and DR hosts +.EX +### Nodes/DRHosts +# If you have only one BCN but it's BCN 2 (or 3, 4...), set the BCN count to +# the number of the real BCN and the previous BCNs will be ignored. +host_name = +gateway_interface = +gateway = +dns = +bcn_count = 1 +bcn1_ip = +bcn1_subnet_mask = +bcn1_create_bridge = [0.1] +bcn1_link1_mac_to_set = +bcn1_link2_mac_to_set = +ifn_count = 1 +ifn1_ip = +ifn1_subnet_mask = +ifn1_create_bridge = [0,1] +ifn1_link1_mac_to_set = +ifn1_link2_mac_to_set = +sn_count = 0+ +sn1_ip = 10.101.x.y +sn1_subnet_mask = +sn1_link1_mac_to_set = +sn1_link2_mac_to_set = +mn_count = 0+ +mn1_ip = 10.199.x.y +mn1_subnet_mask = +mn1_link1_mac_to_set = +mn1_link2_mac_to_set = +.EE +.TP \fB\-\-job\-uuid\fR The program is normally run as a job, with data on how to configure the host defined in the job. This switch allows the running of a specific job. If this is not set, the program will search for a job that has not yet been picked up by another process. If found, that job UUID is used automatically. .IP diff --git a/share/words.xml b/share/words.xml index 7652c4746..b117fe750 100644 --- a/share/words.xml +++ b/share/words.xml @@ -43,9 +43,9 @@ If you need any assistance, please feel free to contact #!string!brand_0001!# (h [ Error ] - Failed to find the SSH key that should have been in file: [#!variable!file!#] at line: [#!variable!line!#]! - #!free!# + [ Error ] - The config file: [#!variable!file!#] was not found. None of the databases are accessible, unable to proceed. Please be sure that 'anvil-daemon' is enabled and running on the database machine(s). - #!free!# + Failed to find any interface to connect the bridge: [#!variable!bridge_name!#] to. This is likely a program error. This program must run with 'root' level privileges. No password was given, exiting. The passwords don't match, exiting. @@ -1919,7 +1919,7 @@ The database connection error was: round()' was passed the number: [#!variable!number!#] which contains an illegal value. Only digits and one decimal place are allowed.]]> [#!variable!timestamp!#] - The server: [#!variable!server_name!#] state is: [#!variable!server_state!#], not "shut off". [ Note ] - Continuing to wait for it to shut off before proceeding with growing storage. - #!free!# + The network: [#!variable!network!#] on the host: [#!variable!host_name!#] doesn't exist, not waiting for it in '/etc/hosts'. About to write the query: [#!variable!query!#]. About to query: [#!variable!query!#] Entering method: [#!variable!method!#] @@ -2854,7 +2854,7 @@ NOTE: Please be patient! #!variable!timestamp!#; Updating Anvil! RPMs on: [#!variable!host_name!#]. #!variable!timestamp!#; The node's Anvil! RPMs are updated, now proceeding with main OS update. Expired 'dnf' cache. - #!free!# + There is no bond interface, we will connect the bridge to the device: [#!variable!on_device!#] with the UUID: [#!variable!on_device_uuid!#]. #!free!# #!free!# #!free!# diff --git a/tools/anvil-configure-host b/tools/anvil-configure-host index 357b8eee2..c192b1004 100755 --- a/tools/anvil-configure-host +++ b/tools/anvil-configure-host @@ -38,6 +38,7 @@ my $anvil = Anvil::Tools->new(); # Read switches $anvil->Get->switches({list => [ + "file", "job-uuid", "debug", ], man => $THIS_FILE}); @@ -782,8 +783,8 @@ sub reconfigure_bridges # This is the old type of network config foreach my $i (1..$count) { - ### TODO: This is almost always going to be on the bond, but we need to handle - ### bridges on interfaces on DR hosts. + # This is almost always going to be on the bond, but bridges can be on interfaces on + # MicroAnvil! nodes and DR hosts. my $bridge_name = $network_type.$i."_bridge1"; my $on_device = $network_type.$i."_bond1"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { @@ -791,6 +792,101 @@ sub reconfigure_bridges on_device => $on_device, }}); + # If there's no bond, we'll using link1 if it's available, otherwise link2. If none + # are available, we're done. + my $on_device_uuid = ""; + if ($anvil->data->{nmcli}{device}{$on_device}{uuid}) + { + $on_device_uuid = $anvil->data->{nmcli}{device}{$on_device}{uuid}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { on_device_uuid => $on_device_uuid }}); + } + else + { + # If there a link1 or link2 device? + my $link1_key = $network_type.$i."_link1"; + my $link1_uuid = ""; + my $link2_key = $network_type.$i."_link2"; + my $link2_uuid = ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + link1_key => $link1_key, + link2_key => $link2_key, + }}); + foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{nmcli}{uuid}}) + { + my $match = $anvil->data->{nmcli}{uuid}{$uuid}{'match.interface-name'} // ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { match => $match }}); + next if not $match; + foreach my $interface (split/,/, $match) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { interface => $interface }}); + if ($interface eq $link1_key) + { + $link1_uuid = $uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link1_uuid => $link1_uuid }}); + last; + } + elsif ($interface eq $link2_key) + { + $link2_uuid = $uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { link2_uuid => $link2_uuid }}); + last; + } + } + } + + if ($link1_uuid) + { + # Use this interface + $on_device = $link1_key; + $on_device_uuid = $link1_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + on_device => $on_device, + on_device_uuid => $on_device_uuid, + }}); + } + elsif ($link2_uuid) + { + # Use this interface + $on_device = $link2_key; + $on_device_uuid = $link2_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + on_device => $on_device, + on_device_uuid => $on_device_uuid, + }}); + } + else + { + # No interfaces found for this interface, we can't proceed. + $anvil->Job->update_progress({ + progress => 100, + message => "error_0004", + log_level => 1, + 'print' => 1, + job_uuid => $anvil->data->{job}{uuid}, + job_status => "failed", + variables => { + bridge_name => $bridge_name, + }, + }); + $anvil->nice_exit({exit_code => 1}); + } + + # Mention that we're using link1 + $anvil->Job->update_progress({ + progress => $anvil->Job->bump_progress({steps => 1}), + message => "message_0107", + log_level => 1, + 'print' => 1, + job_uuid => $anvil->data->{job}{uuid}, + file => $THIS_FILE, + line => __LINE__, + variables => { + on_device => $on_device, + on_device_uuid => $on_device_uuid, + }, + }); + } + # Checking if the bridge exists and that it is on the requested device $anvil->Job->update_progress({ progress => $anvil->Job->bump_progress({steps => 1}), @@ -940,12 +1036,10 @@ sub reconfigure_bridges variables => { on_device => $on_device }, }); my $bridge_uuid = $anvil->data->{nmcli}{bridge}{$bridge_name}{uuid}; - my $on_device_uuid = $anvil->data->{nmcli}{device}{$on_device}{uuid} // ""; my $on_device_parent = $anvil->data->{nmcli}{uuid}{$on_device_uuid}{'connection.master'} // ""; my $on_device_child_type = $anvil->data->{nmcli}{uuid}{$on_device_uuid}{'connection.slave-type'} // ""; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { bridge_uuid => $bridge_uuid, - on_device_uuid => $on_device_uuid, on_device_parent => $on_device_parent, on_device_child_type => $on_device_child_type, }}); @@ -1120,6 +1214,7 @@ sub reconfigure_bonds 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 }}); + next if not $count; # This is the old type of network config foreach my $i (1..$count) @@ -1943,6 +2038,8 @@ sub reconfigure_interfaces { ### TODO: Any devices that are down, set: ### nmcli connection modify ipv4.method manual ipv4.addresses 169.0.0.x/8' (x == Wired connection x) + ### For now, we do nothing here + next; my $connection_id = $anvil->data->{nmcli}{uuid}{$uuid}{'connection.id'} // ""; my $general_ip_iface = $anvil->data->{nmcli}{uuid}{$uuid}{'GENERAL.IP-IFACE'} // ""; $general_ip_iface = "" if $general_ip_iface eq "--"; @@ -1959,42 +2056,6 @@ sub reconfigure_interfaces 's6:connection_autoconnect' => $connection_autoconnect, 's7:active' => $active, }}); - - ### NOTE: I don't think this is needed, but here's the code in case we change our mind. - if (0) - { - # Try activating it. - if ((not $general_ip_iface) && (not $active)) - { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 1, key => "log_0842", variables => { - id => $connection_id, - uuid => $uuid, - }}); - - my $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 }}); - 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, - }}); - # NM seems to have a race issue, so we sleep a second after nmcli calls. - sleep 2; - - # Rescan. - $anvil->Job->update_progress({ - progress => $anvil->Job->bump_progress({steps => 1}), - message => "message_0394", - log_level => 1, - 'print' => 1, - job_uuid => $anvil->data->{job}{uuid}, - file => $THIS_FILE, - line => __LINE__, - variables => { }, - }); - $anvil->Network->collect_data({debug => 2}); - } - } } my $local_host = $anvil->Get->short_host_name(); @@ -2022,6 +2083,7 @@ sub reconfigure_interfaces 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 }}); + next if not $count; # This is the old type of network config foreach my $i (1..$count) @@ -2200,7 +2262,8 @@ sub reconfigure_interfaces } } - # There is no way (that we've found) to get the network interface ames to be updated without a reboot. + # There is no way (that we've found) to get the network interface names to be updated without a + # reboot. if ($anvil->data->{sys}{reboot_needed}) { do_reboot($anvil); @@ -2530,6 +2593,90 @@ sub pickup_job_details { my ($anvil) = @_; + # If we're in a cluster, abort. + if (-e $anvil->data->{path}{exe}{pcs}) + { + # To make logs more sensible, we'll call 'problem' as 'out_of_cluster'. + $anvil->data->{cib}{parsed}{'local'}{ready} = "" if not defined $anvil->data->{cib}{parsed}{'local'}{ready}; + my ($out_of_cluster) = $anvil->Cluster->parse_cib(); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + out_of_cluster => $out_of_cluster, + "cib::parsed::local::ready" => defined $anvil->data->{cib}{parsed}{'local'}{ready} ? $anvil->data->{cib}{parsed}{'local'}{ready} : "", + }}); + if ((not $out_of_cluster) && ($anvil->data->{cib}{parsed}{'local'}{ready})) + { + # We're in a cluster, abort. + $anvil->Job->update_progress({ + progress => 100, + message => "error_0250", + job_uuid => $anvil->data->{job}{uuid}, + job_status => "failed", + 'print' => 1, + log_level => 1, + file => $THIS_FILE, + line => __LINE__, + }); + $anvil->nice_exit({exit_code => 7}); + } + } + + ### These are the new variables + $anvil->data->{config}{striker_password} = ""; + $anvil->data->{config}{prefix} = ""; + $anvil->data->{config}{sequence} = ""; + $anvil->data->{config}{domain} = ""; + $anvil->data->{config}{host_name} = ""; + $anvil->data->{config}{organization} = ""; + $anvil->data->{config}{bcn_count} = 1; + $anvil->data->{config}{ifn_count} = 1; + $anvil->data->{config}{sn_count} = 0; + $anvil->data->{config}{mn_count} = 0; + $anvil->data->{config}{dns} = ""; + $anvil->data->{config}{gateway} = ""; + $anvil->data->{config}{gateway_interface} = ""; + + ### TODO: Remove this later + # This will store the variables from the database + $anvil->data->{variables} = {}; + + # If we were passed a file, read it. + if ($anvil->data->{switches}{file}) + { + # If the file valid? + if (not -f $anvil->data->{switches}{file}) + { + # Needs to be a full path. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, 'print' => 0, priority => "err", key => "error_0002", variables => { file => $anvil->data->{switches}{file} }});; + $anvil->nice_exit({exit_code => 1}); + } + + my $config_file = $anvil->Storage->read_file({file => $anvil->data->{switches}{file}}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { config_file => $config_file }}); + + foreach my $line (split/\n/, $config_file) + { + $line = $anvil->Words->clean_spaces({string => $line}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { line => $line }}); + next if $line =~ /^#/; + if ($line =~ /^(\w+)\s*=\s*(.*)$/) + { + my $variable = $1; + my $value = $2; + my $secure = $variable =~ /passw/ ? 1 : 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, secure => $secure, list => { + variable => $variable, + value => $value, + }}); + + $anvil->data->{config}{$variable} = $value; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "config::${variable}" => $anvil->data->{config}{$variable}, + }}); + } + } + return(0); + } + # If this returns '1', the job-uuid was bad. If it returns '2', another process is running. my $return = $anvil->Job->get_job_details({ check => 1, @@ -2565,25 +2712,6 @@ sub pickup_job_details }}); } - ### These are the new variables - $anvil->data->{config}{striker_password} = ""; - $anvil->data->{config}{prefix} = ""; - $anvil->data->{config}{sequence} = ""; - $anvil->data->{config}{domain} = ""; - $anvil->data->{config}{host_name} = ""; - $anvil->data->{config}{organization} = ""; - $anvil->data->{config}{bcn_count} = 1; - $anvil->data->{config}{ifn_count} = 1; - $anvil->data->{config}{sn_count} = 0; - $anvil->data->{config}{mn_count} = 0; - $anvil->data->{config}{dns} = ""; - $anvil->data->{config}{gateway} = ""; - $anvil->data->{config}{gateway_interface} = ""; - - ### TODO: Remove this later - # This will store the variables from the database - $anvil->data->{variables} = {}; - ### TODO: Remove this, it shouldn't be needed once we confirm everything is in the job_data. # If we're still alive, pick up the details. my $query = " @@ -2685,33 +2813,6 @@ AND line => __LINE__, }); - # If we're in a cluster, abort. - if (-e $anvil->data->{path}{exe}{pcs}) - { - # To make logs more sensible, we'll call 'problem' as 'out_of_cluster'. - $anvil->data->{cib}{parsed}{'local'}{ready} = "" if not defined $anvil->data->{cib}{parsed}{'local'}{ready}; - my ($out_of_cluster) = $anvil->Cluster->parse_cib(); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - out_of_cluster => $out_of_cluster, - "cib::parsed::local::ready" => defined $anvil->data->{cib}{parsed}{'local'}{ready} ? $anvil->data->{cib}{parsed}{'local'}{ready} : "", - }}); - if ((not $out_of_cluster) && ($anvil->data->{cib}{parsed}{'local'}{ready})) - { - # We're in a cluster, abort. - $anvil->Job->update_progress({ - progress => 100, - message => "error_0250", - job_uuid => $anvil->data->{job}{uuid}, - job_status => "failed", - 'print' => 1, - log_level => 1, - file => $THIS_FILE, - line => __LINE__, - }); - $anvil->nice_exit({exit_code => 7}); - } - } - return(0); } diff --git a/tools/anvil-join-anvil b/tools/anvil-join-anvil index a29a460c3..d9bf6d25b 100755 --- a/tools/anvil-join-anvil +++ b/tools/anvil-join-anvil @@ -1320,7 +1320,11 @@ sub wait_for_etc_hosts my $this_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{"anvil_".$machine."_host_uuid"}; my $this_short_host_name = $anvil->data->{hosts}{host_uuid}{$this_host_uuid}{short_host_name}; my $bcn_name = ""; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { machine => $machine }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + 's1:machine' => $machine, + 's2:this_host_uuid' => $this_host_uuid, + 's3:this_short_host_name' => $this_short_host_name, + }}); foreach my $network_name (sort {$a cmp $b} keys %{$anvil->data->{manifests}{manifest_uuid}{$manifest_uuid}{parsed}{machine}{$machine}{network}}) { my $host_name = $this_short_host_name.".".$network_name; @@ -1427,6 +1431,40 @@ sub wait_for_etc_hosts last if $found; } + # Is the network missing? + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { found => $found }}); + if (not $found) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_name => $host_name }}); + if ($host_name =~ /^(.*)\.(.*?)$/) + { + my $short_host_name = $1; + my $network = $2; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "s1:short_host_name" => $short_host_name, + "s2:network" => $network, + }}); + + $anvil->data->{unused_network}{$network} = 0 if not defined $anvil->data->{unused_network}{$network}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "unused_network::${network}" => $anvil->data->{unused_network}{$network}, + }}); + + if ($anvil->data->{unused_network}{$network}) + { + # This network doesn't exist, don't wait for it. + $found = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { found => $found }}); + + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0122", variables => { + host_name => $host_name, + network => $network, + }}); + } + } + } + + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { found => $found }}); if (not $found) { $ready = 0; @@ -3415,7 +3453,7 @@ sub check_local_network my $wanted_dns_hash = {}; foreach my $this_dns (sort {$a cmp $b} @dns_array) { - $this_dns = $anvil->Words->clean_spaces({ string => $this_dns }); + $this_dns = $anvil->Words->clean_spaces({string => $this_dns}); $wanted_dns_hash->{$this_dns} = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "wanted_dns_hash->${this_dns}" => $wanted_dns_hash->{$this_dns}, @@ -3446,6 +3484,14 @@ sub check_local_network 's4:cidr' => $cidr, 's5:gateway' => $gateway, }}); + + # If a network in the manifest isn't found locally, note it so we don't wait for it in + # /etc/hosts. This gets set to '0' if found. + $anvil->data->{unused_network}{$network} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "unused_network::${network}" => $anvil->data->{unused_network}{$network}, + }}); + foreach my $in_iface (sort {$a cmp $b} keys %{$anvil->data->{network}{$local_host}{interface}}) { # Only one interface will start with the network name and have an IP address. @@ -3466,6 +3512,12 @@ sub check_local_network 's7:current_mtu' => $current_mtu, }}); + # Mark that there's an interface for this network so we wait for it in /etc/hosts + $anvil->data->{unused_network}{$network} = 0; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "unused_network::${network}" => $anvil->data->{unused_network}{$network}, + }}); + update_progress($anvil, ($anvil->data->{job}{progress} += 2), "job_0081,!!name!".$in_iface."!!"); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0081", variables => { name => $in_iface }}); @@ -3502,8 +3554,6 @@ sub check_local_network if (($current_ip ne $ip) or ($current_subnet ne $subnet)) { # IP / subnet changed. - #print __LINE__.": IP: .... [".$current_ip."] -> [".$ip."]\n"; - #print __LINE__.": Subnet: [".$current_subnet."] -> [".$subnet."]\n"; $change = 1; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { change => $change }}); } @@ -3661,7 +3711,7 @@ sub check_local_network # Restart $anvil->System->stop_daemon({debug => 2, daemon => "NetowkrManager.service"}); sleep 5; - $anvil->System->stop_daemon({debug => 2, daemon => "NetowkrManager.service"}); + $anvil->System->start_daemon({debug => 2, daemon => "NetowkrManager.service"}); # Wait for a DB connection. We'll wait up to 130 seconds (updelay is 120 seconds, plus a small buffer). my $wait_until = time + 130; diff --git a/tools/anvil-provision-server b/tools/anvil-provision-server index 441cae179..35846ae58 100755 --- a/tools/anvil-provision-server +++ b/tools/anvil-provision-server @@ -1311,7 +1311,7 @@ sub get_sn_details target => $peer_short_name, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { matches => $matches }}); - foreach my $preferred_network ("sn") + foreach my $preferred_network ("sn", "mn", "bcn", "ifn") { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { preferred_network => $preferred_network }}); foreach my $network_name (sort {$a cmp $b} keys %{$anvil->data->{network_access}})