Author: arkurth
Date: Mon Jun 20 19:24:54 2016
New Revision: 1749392

URL: http://svn.apache.org/viewvc?rev=1749392&view=rev
Log:
VCL-940
Added OS.pm::wait_for_public_ip_address. This gets called from 
OS.pm::update_public_ip_address.

Added $no_cache and $ignore_error arguments to several get_* networking 
subroutines to allow fresh data to be retrieves and to suppress warning 
messages.

Removed Windows.pm::get_public_interface_name and get_public_ip_address. These 
were already looping until the public IP was obtained. Having everything use 
the code in OS.pm is simpler.

Modified:
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1749392&r1=1749391&r2=1749392&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Mon Jun 20 19:24:54 2016
@@ -1279,14 +1279,16 @@ sub update_public_ip_address {
        if ($public_ip_configuration =~ /dhcp/i) {
                notify($ERRORS{'DEBUG'}, 0, "IP configuration is set to 
$public_ip_configuration, attempting to retrieve dynamic public IP address from 
$computer_node_name");
                
-               my $retrieved_public_ip_address;
-               
-               # Try to retrieve the public IP address from the OS module
-               if (!$self->can("get_public_ip_address")) {
-                       notify($ERRORS{'WARNING'}, 0, "unable to retrieve 
public IP address from $computer_node_name, OS module " . ref($self) . " does 
not implement a 'get_public_ip_address' subroutine");
+               # Wait for the computer to be assigned a public IP address
+               # There is sometimes a delay
+               if (!$self->wait_for_public_ip_address()) {
+                       notify($ERRORS{'WARNING'}, 0, "unable to update public 
IP address, $computer_node_name did not receive a public IP address via DHCP");
                        return;
                }
-               elsif ($retrieved_public_ip_address = 
$self->get_public_ip_address()) {
+               
+               # Retrieve the public IP address from the OS module
+               my $retrieved_public_ip_address = 
$self->get_public_ip_address();
+               if ($retrieved_public_ip_address) {
                        notify($ERRORS{'DEBUG'}, 0, "retrieved public IP 
address from $computer_node_name using the OS module: 
$retrieved_public_ip_address");
                }
                else {
@@ -1442,7 +1444,7 @@ sub get_private_interface_name {
 
 =head2 get_public_interface_name
 
- Parameters  : none
+ Parameters  : $no_cache (optional), $ignore_error (optional)
  Returns     : string
  Description : Determines the public interface name based on the information in
                the network configuration hash returned by
@@ -1457,9 +1459,15 @@ sub get_public_interface_name {
                return;
        }
        
-       my $no_cache = shift;
+       my $no_cache = shift || 0;
+       my $ignore_error = shift || 0;
+       
+       notify($ERRORS{'DEBUG'}, 0, "attempting to determine public interface 
name, no cache: $no_cache, ignore error: $ignore_error");
        
-       if (defined $self->{public_interface_name} && !$no_cache) {
+       if ($no_cache) {
+               delete $self->{public_interface_name};
+       }
+       elsif ($self->{public_interface_name}) {
                #notify($ERRORS{'DEBUG'}, 0, "returning public interface name 
previously retrieved: $self->{public_interface_name}");
                return $self->{public_interface_name};
        }
@@ -1552,7 +1560,7 @@ sub get_public_interface_name {
                return $self->{public_interface_name};
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "failed to determine the public 
interface name:\n" . format_data($network_configuration));
+               notify($ERRORS{'WARNING'}, 0, "failed to determine the public 
interface name:\n" . format_data($network_configuration)) unless $ignore_error;
                return;
        }
 }
@@ -1658,7 +1666,70 @@ sub _get_public_interface_name_helper {
                notify($ERRORS{'WARNING'}, 0, "unable to determine which 
interface is more likely the public interface, invalid \$condition argument: 
'$condition'");
                return;
        }
+}
+
+#///////////////////////////////////////////////////////////////////////////////
+
+=head2 wait_for_public_ip_address
+
+ Parameters  : $total_wait_seconds (optional), $attempt_delay_seconds 
(optional)
+ Returns     : boolean
+ Description : Loops until the computer's public interface name can be 
retrieved
+               or the timeout is reached. The public interface name can only be
+               retrieved if an IP address is assigned to it. The default 
maximum
+               wait time is 60 seconds.
+
+=cut
+
+sub wait_for_public_ip_address {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       # Attempt to get the total number of seconds to wait from the arguments
+       my $total_wait_seconds = shift;
+       if (!defined($total_wait_seconds) || $total_wait_seconds !~ /^\d+$/) {
+               $total_wait_seconds = 60;
+       }
+       
+       # Seconds to wait in between loop attempts
+       my $attempt_delay_seconds = shift;
+       if (!defined($attempt_delay_seconds) || $attempt_delay_seconds !~ 
/^\d+$/) {
+               $attempt_delay_seconds = 2;
+       }
+       
+       my $computer_node_name = $self->data->get_computer_node_name();
+       
+       # Check if the public IP address was already retrieved
+       # Use cached data if available (0), ignore errors (1)
+       my $public_ip_address = $self->get_public_ip_address(0, 1);
+       if ($public_ip_address) {
+               notify($ERRORS{'DEBUG'}, 0, "$computer_node_name is already 
assigned a public IP address: $public_ip_address");
+               return 1;
+       }
+       
+       my $sub_ref = $self->can("get_public_ip_address");
+       notify($ERRORS{'DEBUG'}, 0, "");
+       my $message = "waiting for $computer_node_name to get public IP 
address";
        
+       return $self->code_loop_timeout(
+               sub {
+                       my $public_ip_address = $self->get_public_ip_address(1, 
1);
+                       if (!defined($public_ip_address)) {
+                               return;
+                       }
+                       else {
+                               notify($ERRORS{'DEBUG'}, 0, 
"$computer_node_name was assigned a public IP address: $public_ip_address");
+                               return 1;
+                       }
+               },
+               [$self, 1],
+               $message,
+               $total_wait_seconds,
+               $attempt_delay_seconds
+       );
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -1691,8 +1762,8 @@ sub get_private_network_configuration {
 
 =head2 get_public_network_configuration
 
- Parameters  : none
- Returns     : 
+ Parameters  : $no_cache (optional), $ignore_error (optional)
+ Returns     : hash reference
  Description : 
 
 =cut
@@ -1704,9 +1775,14 @@ sub get_public_network_configuration {
                return;
        }
        
-       my $public_interface_name = $self->get_public_interface_name();
+       my $no_cache = shift || 0;
+       my $ignore_error = shift || 0;
+       
+       notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve public network 
configuration, no cache: $no_cache, ignore error: $ignore_error");
+       
+       my $public_interface_name = $self->get_public_interface_name($no_cache, 
$ignore_error);
        if (!$public_interface_name) {
-               notify($ERRORS{'WARNING'}, 0, "unable to retrieve public 
network configuration, public interface name could not be determined");
+               notify($ERRORS{'WARNING'}, 0, "unable to retrieve public 
network configuration, public interface name could not be determined") unless 
$ignore_error;
                return;
        }
        
@@ -1802,7 +1878,7 @@ sub get_public_mac_address {
 
 =head2 get_ip_address
 
- Parameters  : $network_type (optional), $ignore_error (optional)
+ Parameters  : $network_type (optional), $no_cache (optional), $ignore_error 
(optional)
  Returns     : string
  Description : Returns the IP address of the computer. The $network_type
                argument may either be 'public' or 'private'. If not supplied,
@@ -1825,19 +1901,22 @@ sub get_ip_address {
                return;
        }
        
-       my $ignore_error = shift;
+       my $no_cache = shift || 0;
+       my $ignore_error = shift || 0;
+       
+       notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve IP address, type: 
$network_type, no cache: $no_cache, ignore error: $ignore_error");
        
        # Get the public or private network configuration
        # Use 'eval' to construct the appropriate subroutine name
-       my $network_configuration = eval 
"\$self->get_$network_type\_network_configuration()";
+       my $network_configuration = eval 
"\$self->get_$network_type\_network_configuration($no_cache, $ignore_error)";
        if ($EVAL_ERROR || !$network_configuration) {
-               notify($ERRORS{'WARNING'}, 0, "unable to retrieve $network_type 
network configuration");
+               notify($ERRORS{'WARNING'}, 0, "unable to retrieve $network_type 
network configuration") unless $ignore_error;
                return;
        }
        
        my $ip_address_info = $network_configuration->{ip_address};
        if (!defined($ip_address_info)) {
-               notify($ERRORS{'WARNING'}, 0, "$network_type network 
configuration info does not contain an 'ip_address' key");
+               notify($ERRORS{'WARNING'}, 0, "$network_type network 
configuration info does not contain an 'ip_address' key") unless $ignore_error;
                return;
        }
        
@@ -1908,7 +1987,7 @@ sub get_ip_addresses {
 
 =head2 get_private_ip_address
 
- Parameters  : $ignore_error (optional)
+ Parameters  : $no_cache (optional), $ignore_error (optional)
  Returns     : string
  Description : Returns the computer's private IP address.
 
@@ -1921,15 +2000,17 @@ sub get_private_ip_address {
                return;
        }
        
+       my $no_cache = shift;
        my $ignore_error = shift;
-       return $self->get_ip_address('private', $ignore_error);
+       
+       return $self->get_ip_address('private', $no_cache, $ignore_error);
 }
 
 #/////////////////////////////////////////////////////////////////////////////
 
 =head2 get_public_ip_address
 
- Parameters  : $ignore_error (optional)
+ Parameters  : $no_cache (optional), $ignore_error (optional)
  Returns     : string
  Description : Returns the computer's public IP address.
 
@@ -1941,11 +2022,14 @@ sub get_public_ip_address {
                notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
                return;
        }
-       my $ignore_error = shift;
-       return $self->get_ip_address('public', $ignore_error);
+       my $no_cache = shift || 0;
+       my $ignore_error = shift || 0;
+       
+       notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve public IP address, 
no cache: $no_cache, ignore error: $ignore_error");
+       return $self->get_ip_address('public', $no_cache, $ignore_error);
 }
 
-#/////////////////////////////////////////////////////////////////////////////
+#///////////////////////////////////////////////////////////////////////////////
 
 =head2 get_subnet_mask
 

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1749392&r1=1749391&r2=1749392&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Mon Jun 20 19:24:54 2016
@@ -831,8 +831,8 @@ public DNS server(s): @dns_servers
 EOF
        
        # Get the current public IP address being used by the computer
-       # Pass the $ignore_error flag to prevent warnings if not defined
-       my $current_public_ip_address = $self->get_public_ip_address(1);
+       # Use cached data if available (0), ignore errors (1)
+       my $current_public_ip_address = $self->get_public_ip_address(0, 1);
        if ($current_public_ip_address && $current_public_ip_address eq 
$computer_public_ip_address) {
                notify($ERRORS{'DEBUG'}, 0, "static public IP address does not 
need to be set, $computer_name is already configured to use 
$current_public_ip_address");
        }
@@ -2349,13 +2349,16 @@ sub get_network_configuration {
                return;
        }
        
-       my $no_cache = shift;
+       my $no_cache = shift || 0;
+       notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve network 
configuration, no cache: $no_cache");
        
        # Delete previously retrieved data if $no_cache was specified
-       delete $self->{network_configuration} if $no_cache;
-       
-       # Check if the network configuration has already been retrieved and 
saved in this object
-       return $self->{network_configuration} if 
($self->{network_configuration});
+       if ($no_cache) {
+               delete $self->{network_configuration};
+       }
+       elsif ($self->{network_configuration}) {
+               return $self->{network_configuration}
+       }
        
        # Run ipconfig
        my $ifconfig_command = "/sbin/ifconfig -a";

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm?rev=1749392&r1=1749391&r2=1749392&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/Ubuntu.pm Mon Jun 20 
19:24:54 2016
@@ -310,7 +310,7 @@ sub set_password {
 
 =head2 get_network_configuration
 
- Parameters  : 
+ Parameters  : $no_cache (optional)
  Returns     : hash reference
  Description : Retrieves the network configuration on the Linux computer and
                constructs a hash. The hash reference returned is formatted as
@@ -331,6 +331,11 @@ sub get_network_configuration {
                return;
        }
        
+       my $no_cache = shift;
+       
+       # Delete previously retrieved data if $no_cache was specified
+       delete $self->{network_configuration} if $no_cache;
+       
        # Check if the network configuration has already been retrieved and 
saved in this object
        return $self->{network_configuration} if 
($self->{network_configuration});
        

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1749392&r1=1749391&r2=1749392&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Mon Jun 20 19:24:54 
2016
@@ -5557,8 +5557,10 @@ sub get_network_configuration {
        
        my $no_cache = shift;
        
-       # Check if the network configuration has already been retrieved and 
saved in this object
-       if (!$no_cache && $self->{network_configuration}) {
+       if ($no_cache) {
+               delete $self->{network_configuration};
+       }
+       elsif ($self->{network_configuration}) {
                notify($ERRORS{'DEBUG'}, 0, "returning network configuration 
previously retrieved");
                return $self->{network_configuration};
        }
@@ -5686,105 +5688,6 @@ sub get_network_configuration {
 }
 
 #/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_public_interface_name
-
- Parameters  : none
- Returns     : string
- Description : Retrieves the public interface name on the computer. This may 
not
-               be determined when the computer is first booting because the
-               interfaces are being initialized. This subroutine will loop for
-               up to 3 minutes.
-
-=cut
-
-sub get_public_interface_name {
-       my $self = shift;
-       if (ref($self) !~ /VCL::Module/i) {
-               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
-               return;
-       }
-       
-       my $computer_node_name   = $self->data->get_computer_node_name();
-       
-       # Try to determine the public interface name
-       my $public_interface_name = $self->SUPER::get_public_interface_name();
-       return $public_interface_name if ($public_interface_name);
-       
-       # Network interfaces may still be initializing
-       return $self->code_loop_timeout(
-               sub {
-                       return $self->SUPER::get_public_interface_name(1);
-               },
-               [], "waiting for public interface to initialize on 
$computer_node_name", 180, 3
-       );
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 get_public_ip_address
-
- Parameters  : none
- Returns     : string
- Description : Retrieves the public IP address from the computer. If the 
address
-               can't be determined and DHCP is used on the management node, an
-               attempt is made to run 'ipconfig /renew' and retrieve the 
network
-               configuration again. This will loop for up to 2 minutes.
-
-=cut
-
-sub get_public_ip_address {
-       my $self = shift;
-       if (ref($self) !~ /VCL::Module/i) {
-               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
-               return;
-       }
-       
-       my $computer_node_name   = $self->data->get_computer_node_name();
-       my $public_ip_configuration = 
$self->data->get_management_node_public_ip_configuration();
-       
-       # Make sure public interface name can be determined
-       my $public_interface_name = $self->get_public_interface_name();
-       if (!$public_interface_name) {
-               notify($ERRORS{'WARNING'}, 0, "unable to determine public IP 
address assigned to $computer_node_name, public interface name could not be 
determined");
-               return;
-       }
-       
-       # Call OS.pm::get_ip_address
-       # OS.pm will check for invalid addresses, assume the address is good if 
a value was returned
-       my $public_ip_address = $self->get_ip_address('public');
-       if ($public_ip_address) {
-               return $public_ip_address;
-       }
-       
-       # If unable to determine public IP on 1st try and DHCP isn't being 
used, return null
-       if ($public_ip_configuration !~ /dhcp/i) {
-               # Return null if MN is not configured to use DHCP and address 
could not be determined
-               notify($ERRORS{'WARNING'}, 0, "unable to determine public IP 
address assigned to $computer_node_name, static public IP address may not have 
been set yet, management node public IP configuration: 
$public_ip_configuration");
-               return;
-       }
-                       
-       # Management node is configured to use DHCP, failed to determine public 
IP address on 1st try
-       # Check if DHCP is enabled on what was determined to be the public 
interface
-       # DHCP should always be enabled or something is wrong
-       # If not enabled, don't enter the loop below
-       # Don't forcefully enable DHCP
-       if (!$self->is_dhcp_enabled($public_interface_name)) {
-               notify($ERRORS{'WARNING'}, 0, "unable to determine public IP 
address assigned to $computer_node_name, DHCP is not enabled on public 
interface: '$public_interface_name', management node public IP configuration: 
$public_ip_configuration");
-                               return;
-                       }
-       
-       # Network interfaces may still be initializing
-       return $self->code_loop_timeout(
-               sub {
-                       $self->ipconfig_renew('public');
-                       return $self->get_ip_address('public')
-               },
-               [], "waiting for $computer_node_name to receive public IP 
address via DHCP", 120, 5
-       );
-}
-
-#/////////////////////////////////////////////////////////////////////////////
 
 =head2 enable_dhcp
 


Reply via email to