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