Author: arkurth
Date: Thu Aug 30 16:01:18 2012
New Revision: 1378998

URL: http://svn.apache.org/viewvc?rev=1378998&view=rev
Log:
Merged revision(s) 1378995 from vcl/trunk:
VCL-623
Added Windows.pm::get_public_interface_name. This calls 
OS.pm::get_public_interface_name and adds a loop if the interface name can't be 
determined. This should solve the problem where the code attempts to determine 
the public interface name before the interface driver is installed and 
initialized.

Changed OS.pm::get_public_interface_name so that it never returns the private 
interface name if that interface is only assigned the private IP address. It 
may return the private interface name if that interface is assigned other 
addresses. This is done for future enhancements when a single interface is 
supported.

Commented out section in get_network_configuration which was looping in order 
to attempt to determine if devices were being installed. This functionality 
should be replaced by the new code in this commit.

Updated Module.pm::code_loop_timeout to return the value returned by the code 
reference instead of a simple boolean value. Also added an additional argument 
to be specified controlling how often log messages are displayed.

Modified:
    vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module.pm
    vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS.pm
    vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS/Windows.pm   
(contents, props changed)

Modified: vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module.pm
URL: 
http://svn.apache.org/viewvc/vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module.pm?rev=1378998&r1=1378997&r2=1378998&view=diff
==============================================================================
--- vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module.pm (original)
+++ vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module.pm Thu Aug 30 
16:01:18 2012
@@ -803,8 +803,9 @@ sub get_package_hierarchy {
                2: array reference containing arguments to pass to code 
reference
                3: message to display when attempting to execute code reference
                4: timeout seconds, maximum number of seconds to attempt to 
execute code until it returns true
-               5: seconds to wait in between code execution attempts
- Returns     : If code returns true: 1
+               5: seconds to wait in between code execution attempts (optional)
+               6: message interval seconds (optional)
+ Returns     : If code returns true: returns result returned by code reference
                If code never returns true: 0
  Description : Executes the code contained in the code reference argument until
                it returns true or until the timeout is reached.
@@ -824,17 +825,9 @@ sub code_loop_timeout {
                return;
        }
        
-       # Get the start time
-       my $start_time = time();
-       
        my $computer_node_name = $self->data->get_computer_node_name();
        
-       # Check the argument count and get the arguments
-       if (scalar(@_) != 5) {
-               notify($ERRORS{'WARNING'}, 0, scalar(@_) . " arguments were 
passed, argument count must be 5");
-               return;
-       }
-       my ($code_ref, $args_array_ref, $message, $total_wait_seconds, 
$attempt_delay_seconds) = @_;
+       my ($code_ref, $args_array_ref, $message, $total_wait_seconds, 
$attempt_delay_seconds, $message_interval_seconds) = @_;
        
        # Make sure the code reference argument was passed correctly
        if (!defined($code_ref)) {
@@ -868,37 +861,60 @@ sub code_loop_timeout {
                return;
        }
        
-       if (!defined($attempt_delay_seconds) || $attempt_delay_seconds !~ 
/^\d+$/) {
+       if (!$attempt_delay_seconds) {
+               $attempt_delay_seconds = 15;
+       }
+       elsif (defined($attempt_delay_seconds) && $attempt_delay_seconds !~ 
/^\d+$/) {
                notify($ERRORS{'WARNING'}, 0, "5th argument (attempt delay) was 
not passed correctly");
                return;
        }
        
+       if ($message_interval_seconds) {
+               if ($message_interval_seconds !~ /^\d+$/) {
+                       notify($ERRORS{'WARNING'}, 0, "6th argument (message 
interval) was not passed correctly");
+                       return;
+               }
+       
+               # Message interval is pointless if it's set to a value less 
than $attempt_delay_seconds
+               if ($message_interval_seconds < $attempt_delay_seconds) {
+                       $message_interval_seconds = 0;
+               }
+       }
+       else {
+               $message_interval_seconds = 0;
+       }
+       
+       notify($ERRORS{'DEBUG'}, 0, "$message, maximum of $total_wait_seconds 
seconds");
        
-       # Calculate total seconds to wait and end time
-       my $end_time = $start_time + $total_wait_seconds;
-       notify($ERRORS{'OK'}, 0, "$message, maximum of $total_wait_seconds 
seconds");
+       my $start_time = time();
+       my $current_time = $start_time;
+       my $end_time = ($start_time + $total_wait_seconds);
        
        # Loop until code returns true
-       # Loop once if the wait time is 0
-       my $attempt_count = 0;
-       my $current_time;
-       while (($current_time = time()) < $end_time || ($total_wait_seconds == 
0 && $attempt_count == 0)) {
-               $attempt_count++;
-               
-               if ($attempt_count > 1) {
-                       my $seconds_elapsed = $current_time - $start_time;
-                       my $seconds_remaining = $end_time - $current_time;
-                       
-                       notify($ERRORS{'OK'}, 0, "attempt " . 
($attempt_count-1) . ": $message ($seconds_elapsed/$seconds_remaining seconds) 
sleeping for $attempt_delay_seconds seconds");
-                       sleep $attempt_delay_seconds;
+       my $attempt = 0;
+       while (($current_time = time) <= $end_time) {
+               $attempt++;
+               
+               # Execute the code reference
+               if (my $result = &$code_ref(@{$args_array_ref})) {
+                       notify($ERRORS{'OK'}, 0, "$message, code returned 
true");
+                       return $result;
                }
                
-               #notify($ERRORS{'OK'}, 0, "attempt $attempt_count: $message");
+               $current_time = time;
+               my $seconds_elapsed = ($current_time - $start_time);
+               my $seconds_remaining = ($end_time > $current_time) ? 
($end_time - $current_time) : 0;
+               my $sleep_seconds = ($seconds_remaining < 
$attempt_delay_seconds) ? $seconds_remaining : $attempt_delay_seconds;
                
-               if (&$code_ref(@{$args_array_ref})) {
-                       notify($ERRORS{'OK'}, 0, "$message, code returned 
true");
-                       return 1;
+               if (!$message_interval_seconds || ($attempt == 1 || 
($seconds_remaining <= $attempt_delay_seconds) || ($seconds_elapsed % 
$message_interval_seconds) < $attempt_delay_seconds)) {
+                       notify($ERRORS{'DEBUG'}, 0, "attempt $attempt: $message 
($seconds_elapsed/$seconds_remaining elapsed/remaining seconds), sleeping for 
$sleep_seconds seconds");
                }
+               
+               if (!$sleep_seconds) {
+                       last;
+       }
+
+               sleep $sleep_seconds;
        }
 
        notify($ERRORS{'OK'}, 0, "$message, code did not return true after 
waiting $total_wait_seconds seconds");

Modified: vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS.pm?rev=1378998&r1=1378997&r2=1378998&view=diff
==============================================================================
--- vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS.pm Thu Aug 
30 16:01:18 2012
@@ -1093,10 +1093,15 @@ sub get_public_interface_name {
                return;
        }
        
-       return $self->{public_interface_name} if defined 
$self->{public_interface_name};
+       my $no_cache = shift;
+       
+       if (defined $self->{public_interface_name} && !$no_cache) {
+               notify($ERRORS{'DEBUG'}, 0, "returning public interface name 
previously retrieved: $self->{public_interface_name}");
+               return $self->{public_interface_name};
+       }
        
        # Get the network configuration hash reference
-       my $network_configuration = $self->get_network_configuration();
+       my $network_configuration = $self->get_network_configuration($no_cache);
        if (!$network_configuration) {
                notify($ERRORS{'WARNING'}, 0, "unable to determine public 
interface name, failed to retrieve network configuration");
                return;
@@ -1132,7 +1137,39 @@ sub get_public_interface_name {
                
                # If $public_interface_name hasn't been set yet, set it and 
continue checking the next interface
                if (!$public_interface_name) {
+                       my @check_ip_addresses = keys 
%{$network_configuration->{$check_interface_name}{ip_address}};
+                       my $matches_private = (grep { $_ eq 
$computer_private_ip_address } @check_ip_addresses) ? 1 : 0;
+                       
+                       if ($matches_private) {
+                               if (scalar(@check_ip_addresses) == 1) {
+                                       notify($ERRORS{'DEBUG'}, 0, 
"'$check_interface_name' could not be the public interface, it is only assigned 
the private IP address");
+                                       next INTERFACE;
+                               }
+                               
+                               notify($ERRORS{'DEBUG'}, 0, 
"'$check_interface_name' is assigned private IP address, checking if other 
assigned IP addresses could potentially be public");
+                               CHECK_IP_ADDRESS: for my $check_ip_address 
(@check_ip_addresses) {
+                                       
+                                       if ($check_ip_address eq 
$computer_private_ip_address) {
+                                               notify($ERRORS{'DEBUG'}, 0, 
"ignoring private IP address ($check_ip_address) assigned to interface 
'$check_interface_name'");
+                                               next CHECK_IP_ADDRESS;
+                                       }
+                                       elsif ($check_ip_address =~ 
/^(169\.254|0\.0\.0\.0)/) {
+                                               notify($ERRORS{'DEBUG'}, 0, 
"ignoring invalid IP address ($check_ip_address) assigned to interface 
'$check_interface_name'");
+                                               next CHECK_IP_ADDRESS;
+                                       }
+                                       else {
+                                               notify($ERRORS{'DEBUG'}, 0, 
"'$check_interface_name' could potententially be public interface, assigned IP 
address: $check_ip_address");
                        $public_interface_name = $check_interface_name;
+                                               last CHECK_IP_ADDRESS;
+                                       }
+                               }
+                       }
+                       else {
+                               # Does not match private IP address
+                               notify($ERRORS{'DEBUG'}, 0, 
"'$check_interface_name' could potententially be public interface, not assigned 
private IP address");
+                               $public_interface_name = $check_interface_name;
+                       }
+                       
                        next INTERFACE;
                }
                
@@ -1443,11 +1480,6 @@ sub get_ip_address {
                notify($ERRORS{'WARNING'}, 0, "unable to determine 
$network_type IP address, 'ip_address' value is not set in the network 
configuration info: \n" . format_data($network_configuration));
                return;
        }
-       elsif (scalar(@ip_addresses) == 1) {
-               $ip_address = $ip_addresses[0];
-               notify($ERRORS{'DEBUG'}, 0, "$network_type interface assigned a 
single IP address, returning $ip_address");
-               return $ip_address;
-       }
        
        # Interface has multiple IP addresses, try to find a valid one
        for $ip_address (@ip_addresses) {
@@ -1460,10 +1492,8 @@ sub get_ip_address {
                }
        }
        
-       # Multiple invalid IP addresses, return the first one
-       $ip_address = $ip_addresses[0];
-       notify($ERRORS{'WARNING'}, 0, "$network_type interface assigned a 
multiple invalid IP addresses (" . join(", ", @ip_addresses) . "), returning 
$ip_address");
-       return $ip_address;
+       notify($ERRORS{'WARNING'}, 0, "$network_type interface not assigned a 
valid IP address: " . join(", ", @ip_addresses));
+       return;
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -2133,7 +2163,6 @@ sub execute_new {
                };
                
                if ($EVAL_ERROR) {
-                       
                        if ($ignore_error) {
                                notify($ERRORS{'DEBUG'}, 0, "executed command 
on $computer_name: '$command', ignoring error, returning null") if 
($display_output);
                                return;
@@ -2507,7 +2536,6 @@ sub process_connect_methods {
                                        notify($ERRORS{'WARNING'}, 0, 
"'$service_name' service for '$name' connect method does NOT exist on 
$computer_node_name, connect method install script is not defined");
                                }
                        }
-                       
                        # Run the startup script if the service is not started
                        if (!$service_started && defined($startup_script)) {
                                notify($ERRORS{'DEBUG'}, 0, "attempting to run 
startup script '$startup_script' for '$name' connect method on 
$computer_node_name");

Modified: 
vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS/Windows.pm
URL: 
http://svn.apache.org/viewvc/vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1378998&r1=1378997&r2=1378998&view=diff
==============================================================================
--- vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS/Windows.pm 
(original)
+++ vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS/Windows.pm 
Thu Aug 30 16:01:18 2012
@@ -690,7 +690,7 @@ sub post_load {
 
    if (!$self->update_public_ip_address()) {
                notify($ERRORS{'WARNING'}, 0, "failed to update IP address for 
$computer_node_name");
-      return 0;
+               return 0;
    }
 
 =item *
@@ -5607,7 +5607,7 @@ sub firewall_disable_rdp {
 
 =head2 get_network_configuration
 
- Parameters  : 
+ Parameters  : $no_cache (optional)
  Returns     :
  Description : Retrieves the network configuration from the computer. Returns
                a hash. The hash keys are the interface names:
@@ -5631,13 +5631,19 @@ sub get_network_configuration {
                return;
        }
        
+       my $no_cache = shift;
+       
        # 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 && $self->{network_configuration}) {
+               notify($ERRORS{'DEBUG'}, 0, "returning network configuration 
previously retrieved");
+               return $self->{network_configuration};
+       }
        
        my $system32_path = $self->get_system32_path();
-       my $management_node_keys = $self->data->get_management_node_keys();
        my $computer_node_name   = $self->data->get_computer_node_name();
        
+       notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve network 
configuration from $computer_node_name");
+       
        # Get the computer private IP address
        my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address();
        if (!$computer_private_ip_address) {
@@ -5645,32 +5651,32 @@ sub get_network_configuration {
                return;
        }
        
-       # Check if OS may still be initializing before attempting to retrieve 
network information
-       # Windows may respond to SSH before all network interface drivers are 
installed and interfaces brought up
-       # This causes many problems
-       # Get the list of running tasks, check if drvinst.exe is running
-       my $initialization_check = 0;
-       my $initialization_check_limit = 12;
-       my $initialization_check_delay = 10;
-       while (++$initialization_check) {
-               # Get the list of running tasks (this returns an array 
reference of the raw tasklist.exe output)
-               notify($ERRORS{'DEBUG'}, 0, "attempt 
$initialization_check/$initialization_check_limit: checking if devices still 
appear to be initializing before retrieving network configuration");
-               my $task_info = $self->get_task_info('drvinst');
-               if (!defined($task_info)) {
-                       notify($ERRORS{'WARNING'}, 0, "attempt 
$initialization_check/$initialization_check_limit: unable to determine if 
devices are still being initialized, task information could not be retrieved, 
sleeping for $initialization_check_delay seconds");
-                       sleep $initialization_check_delay;
-                       next;
-               }
-               elsif (!keys(%$task_info)) {
-                       #notify($ERRORS{'DEBUG'}, 0, "no devices appear to 
still be initializing");
-                       notify($ERRORS{'DEBUG'}, 0, "no devices appear to still 
be initializing, tasks:\n" . format_data($task_info));
-                       last;
-               }
-               else {
-                       notify($ERRORS{'DEBUG'}, 0, "attempt 
$initialization_check/$initialization_check_limit: devices still appear to be 
initializing, sleeping for $initialization_check_delay seconds, matching 
tasks:\n" . format_data($task_info));
-                       sleep $initialization_check_delay;
-               }
-       }
+       ## Check if OS may still be initializing before attempting to retrieve 
network information
+       ## Windows may respond to SSH before all network interface drivers are 
installed and interfaces brought up
+       ## This causes many problems
+       ## Get the list of running tasks, check if drvinst.exe is running
+       #my $initialization_check = 0;
+       #my $initialization_check_limit = 12;
+       #my $initialization_check_delay = 10;
+       #while (++$initialization_check) {
+       #       # Get the list of running tasks (this returns an array 
reference of the raw tasklist.exe output)
+       #       notify($ERRORS{'DEBUG'}, 0, "attempt 
$initialization_check/$initialization_check_limit: checking if devices still 
appear to be initializing before retrieving network configuration");
+       #       my $task_info = $self->get_task_info('drvinst');
+       #       if (!defined($task_info)) {
+       #               notify($ERRORS{'WARNING'}, 0, "attempt 
$initialization_check/$initialization_check_limit: unable to determine if 
devices are still being initialized, task information could not be retrieved, 
sleeping for $initialization_check_delay seconds");
+       #               sleep $initialization_check_delay;
+       #               next;
+       #       }
+       #       elsif (!keys(%$task_info)) {
+       #               #notify($ERRORS{'DEBUG'}, 0, "no devices appear to 
still be initializing");
+       #               notify($ERRORS{'DEBUG'}, 0, "no devices appear to still 
be initializing, tasks:\n" . format_data($task_info));
+       #               last;
+       #       }
+       #       else {
+       #               notify($ERRORS{'DEBUG'}, 0, "attempt 
$initialization_check/$initialization_check_limit: devices still appear to be 
initializing, sleeping for $initialization_check_delay seconds, matching 
tasks:\n" . format_data($task_info));
+       #               sleep $initialization_check_delay;
+       #       }
+       #}
        
        my $network_configuration;
        notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve network 
configuration information from $computer_node_name");
@@ -5678,11 +5684,15 @@ sub get_network_configuration {
        # Run ipconfig /all, try twice in case it fails the first time
        my $ipconfig_attempt = 0;
        my $ipconfig_attempt_limit = 2;
+       my $ipconfig_attempt_delay = 5;
        
        my $ipconfig_command = $system32_path . '/ipconfig.exe /all';
        my ($ipconfig_exit_status, $ipconfig_output);
-       while (++$ipconfig_attempt) {
-               ($ipconfig_exit_status, $ipconfig_output) = 
$self->execute($ipconfig_command);
+       
+       IPCONFIG_ATTEMPT: while (++$ipconfig_attempt) {
+               
+               
+               ($ipconfig_exit_status, $ipconfig_output) = 
$self->execute($ipconfig_command, 0);
                if (!defined($ipconfig_output)) {
                        notify($ERRORS{'WARNING'}, 0, "attempt 
$ipconfig_attempt: failed to run the SSH command to run ipconfig");
                }
@@ -5701,7 +5711,7 @@ sub get_network_configuration {
                        return;
                }
                
-               sleep 2;
+               sleep $ipconfig_attempt_delay;
        }
 
        my $interface_name;
@@ -5725,11 +5735,6 @@ sub get_network_configuration {
                # Skip line if interface hasn't been found yet
                next if !$interface_name;
                
-               ## Check if the interface should be ignored based on the name 
or description
-               #if ($interface_name =~ 
/loopback|vmnet|afs|tunnel|6to4|isatap|teredo/i) {
-               #       next;
-               #}
-               
                # Take apart the line finding the setting name and value with a 
hideous regex
                my ($line_setting, $value) = $line =~ /^[ ]{1,8}(\w[^\.]*\w)?[ 
\.:]+([^\r\n]*)/i;
                
@@ -5783,16 +5788,49 @@ 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
-               management node is configured to use DHCP for public IP
-               addresses, the IP address is checked to make sure it is valid. 
If
-               the computer has an invalid public IP address (169.254.*.*,
-               0.0.0.0), an attempt is made to run 'ipconfig /renew' and
-               retrieve the network configuration again.
+ 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
 
@@ -5806,25 +5844,45 @@ sub get_public_ip_address {
        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;
+       }
        
-       # Check to make sure the address is valid if DHCP is used
-       if ($public_ip_configuration =~ /dhcp/i) {
-               if (!$public_ip_address || $public_ip_address =~ 
/^(169\.254|0\.0\.0\.0)/) {
-                       notify($ERRORS{'WARNING'}, 0, "$computer_node_name is 
assigned an invalid public IP address: $public_ip_address, attempting to run 
ipconfig /renew");
-                       delete $self->{network_configuration};
-                       $self->ipconfig_renew('public');
+       # 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;
+       }
                        
-                       $public_ip_address = $self->get_ip_address('public');
-                       if (!$public_ip_address || $public_ip_address =~ 
/^(169\.254|0\.0\.0\.0)/) {
-                               notify($ERRORS{'CRITICAL'}, 0, 
"$computer_node_name failed to obtain a valid public IP address: 
$public_ip_address");
+       # 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;
                        }
-               }
-       }
        
-       notify($ERRORS{'DEBUG'}, 0, "retrieved public IP address of 
$computer_node_name: $public_ip_address");
-       return $public_ip_address;
+       # 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
+       );
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -5954,6 +6012,11 @@ sub ipconfig_renew {
        my $computer_node_name   = $self->data->get_computer_node_name();
        my $system32_path        = $self->get_system32_path() || return;
        
+       # Delete cached network configuration information
+       delete $self->{network_configuration};
+       delete $self->{public_interface_name};
+       delete $self->{private_interface_name};
+       
        my $interface_name = shift;
        if (!$interface_name) {
                notify($ERRORS{'WARNING'}, 0, "interface name argument was not 
supplied");
@@ -5966,6 +6029,11 @@ sub ipconfig_renew {
                $interface_name = $self->get_private_interface_name() || return;
        }
        
+       # Delete cached network configuration information again
+       delete $self->{network_configuration};
+       delete $self->{public_interface_name};
+       delete $self->{private_interface_name};
+       
        my $release_first = shift;
        
        # Assemble the ipconfig command, include the interface name if argument 
was specified
@@ -5975,27 +6043,19 @@ sub ipconfig_renew {
        }
        $ipconfig_command .= "$system32_path/ipconfig.exe /renew 
\"$interface_name\"";
        
-       # Delete cached network configuration information so it is retrieved 
next time it is needed
-       delete $self->{network_configuration};
-       
-       my $attempt_limit = 3;
-       my $attempt = 0;
-       
-       while ($attempt < $attempt_limit) {
-               $attempt++;
-               
                # Run ipconfig
                my ($ipconfig_status, $ipconfig_output) = 
$self->execute({command => $ipconfig_command, timeout => 65, ignore_error => 
1});
-               
                if (!defined($ipconfig_output)) {
-                       notify($ERRORS{'WARNING'}, 0, "attempt 
$attempt/$attempt_limit: failed to execute command to renew IP configuration 
for interface '$interface_name'");
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command to 
renew IP configuration for interface '$interface_name'");
+               return;
                }
                elsif (grep(/error occurred/i, @$ipconfig_output)) {
-                       notify($ERRORS{'WARNING'}, 0, "attempt 
$attempt/$attempt_limit: failed to renew IP configuration for interface 
'$interface_name', exit status: $ipconfig_status, output:\n" . join("\n", 
@$ipconfig_output));
+               notify($ERRORS{'WARNING'}, 0, "failed to renew IP configuration 
for interface '$interface_name', exit status: $ipconfig_status, output:\n" . 
join("\n", @$ipconfig_output));
                        return;
                }
                elsif ($ipconfig_status ne '0' || grep(/error occurred/i, 
@$ipconfig_output)) {
-                       notify($ERRORS{'WARNING'}, 0, "attempt 
$attempt/$attempt_limit: failed to renew IP configuration for interface 
'$interface_name', exit status: $ipconfig_status, command: '$ipconfig_command', 
output:\n" . join("\n", @$ipconfig_output));
+               notify($ERRORS{'WARNING'}, 0, "failed to renew IP configuration 
for interface '$interface_name', exit status: $ipconfig_status, command: 
'$ipconfig_command', output:\n" . join("\n", @$ipconfig_output));
+               return;
                }
                else {
                        notify($ERRORS{'OK'}, 0, "renewed IP configuration for 
interface '$interface_name', output:\n" . join("\n", @$ipconfig_output));
@@ -6003,9 +6063,6 @@ sub ipconfig_renew {
                }
        }
        
-       return;
-} 
-
 #/////////////////////////////////////////////////////////////////////////////
 
 =head2 delete_capture_configuration_files

Propchange: 
vcl/branches/vcl-2.3-bugfixes/managementnode/lib/VCL/Module/OS/Windows.pm
------------------------------------------------------------------------------
  Merged /vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm:r1378995


Reply via email to