Author: arkurth Date: Tue Dec 13 20:46:23 2011 New Revision: 1213919 URL: http://svn.apache.org/viewvc?rev=1213919&view=rev Log: VCL-545 Added code to create a VM host OS object to State.pm::initialize if computer.vmhostid is set. This allows provisioning modules to access the VM host OS via $self->vmhost_os.
VCL-546 Updated OS.pm::_get_public_interface_name_helper. Reordered logic so that the private interface isn't returned if another interface is found which isn't assigned a public address. Other Updated OS.pm::create_text_file to attempt to create the parent directory first. It was failing if the directory didn't exist beforehand. Commented out some unnecessary debugging statements in State.pm::DESTROY. Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module.pm?rev=1213919&r1=1213918&r2=1213919&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module.pm Tue Dec 13 20:46:23 2011 @@ -390,6 +390,89 @@ sub create_mn_os_object { #///////////////////////////////////////////////////////////////////////////// +=head2 create_vmhost_os_object + + Parameters : None + Returns : boolean + Description : Creates an OS object for the VM host. + +=cut + +sub create_vmhost_os_object { + my $self = shift; + unless (ref($self) && $self->isa('VCL::Module')) { + notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); + return; + } + + # Check if an OS object has already been stored in the calling object + if ($ENV{vmhost_os}) { + return 1; + } + + # Make sure calling object isn't an OS module to avoid an infinite loop + if ($self->isa('VCL::Module::OS')) { + notify($ERRORS{'WARNING'}, 0, "this subroutine cannot be called from an existing OS module: " . ref($self)); + return; + } + + my $request_data = $self->data->get_request_data(); + my $reservation_id = $self->data->get_reservation_id(); + my $vmhost_computer_id = $self->data->get_vmhost_computer_id(); + my $vmhost_profile_image_id = $self->data->get_vmhost_profile_image_id(); + + # Create a DataStructure object containing computer data for the VM host + my $vmhost_data; + eval { + $vmhost_data = new VCL::DataStructure({ + request_data => $request_data, + reservation_id => $reservation_id, + computer_id => $vmhost_computer_id, + image_id => $vmhost_profile_image_id + } + ); + }; + + if ($EVAL_ERROR) { + notify($ERRORS{'WARNING'}, 0, "unable to create DataStructure object for VM host, error: $EVAL_ERROR"); + return; + } + elsif (!$vmhost_data) { + notify($ERRORS{'WARNING'}, 0, "unable to create DataStructure object for VM host, DataStructure object is not defined"); + return; + } + + # Get the VM host OS module Perl package name + my $vmhost_os_perl_package = $vmhost_data->get_image_os_module_perl_package(); + if (!$vmhost_os_perl_package) { + notify($ERRORS{'WARNING'}, 0, "unable to create DataStructure or OS object for VM host, failed to retrieve VM host image OS module Perl package name"); + return; + } + + # Load the VM host OS module + notify($ERRORS{'DEBUG'}, 0, "attempting to load VM host OS module: $vmhost_os_perl_package"); + eval "use $vmhost_os_perl_package"; + if ($EVAL_ERROR) { + notify($ERRORS{'WARNING'}, 0, "VM host OS module could NOT be loaded: $vmhost_os_perl_package, error: $EVAL_ERROR"); + return; + } + notify($ERRORS{'DEBUG'}, 0, "VM host OS module loaded: $vmhost_os_perl_package"); + + # Attempt to create the object + if (my $vmhost_os = ($vmhost_os_perl_package)->new({data_structure => $vmhost_data})) { + my $address = sprintf('%x', $vmhost_os); + notify($ERRORS{'OK'}, 0, "$vmhost_os_perl_package OS object created, address: $address"); + $self->set_vmhost_os($vmhost_os); + return 1; + } + else { + notify($ERRORS{'WARNING'}, 0, "failed to create VM host OS object"); + return; + } +} + +#///////////////////////////////////////////////////////////////////////////// + =head2 create_provisioning_object Parameters : None @@ -435,7 +518,7 @@ sub create_provisioning_object { notify($ERRORS{'DEBUG'}, 0, "$provisioning_perl_package module loaded"); # Create provisioner object - if (my $provisioner = ($provisioning_perl_package)->new({data_structure => $self->data})) { + if (my $provisioner = ($provisioning_perl_package)->new({data_structure => $self->data, os => $self->{os}})) { my $provisioner_address = sprintf('%x', $provisioner); my $provisioner_computer_name = $provisioner->data->get_computer_short_name(); notify($ERRORS{'OK'}, 0, "$provisioning_perl_package provisioner object created for $provisioner_computer_name, address: $provisioner_address"); @@ -494,6 +577,28 @@ sub mn_os { #///////////////////////////////////////////////////////////////////////////// +=head2 vmhost_os + + Parameters : None + Returns : VM hosts's OS object + Description : Allows modules to access the VM host's OS object. + +=cut + +sub vmhost_os { + my $self = shift; + + if (!$ENV{vmhost_os}) { + notify($ERRORS{'WARNING'}, 0, "unable to return VM host OS object, \$self->{vmhost_os} is not set"); + return; + } + else { + return $ENV{vmhost_os}; + } +} + +#///////////////////////////////////////////////////////////////////////////// + =head2 provisioner Parameters : None @@ -549,6 +654,22 @@ sub set_mn_os { #///////////////////////////////////////////////////////////////////////////// +=head2 set_vmhost_os + + Parameters : None + Returns : + Description : Sets the VM host OS object for the module to access. + +=cut + +sub set_vmhost_os { + my $self = shift; + my $vmhost_os = shift; + $ENV{vmhost_os} = $vmhost_os; +} + +#///////////////////////////////////////////////////////////////////////////// + =head2 set_provisioner Parameters : None Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1213919&r1=1213918&r2=1213919&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Tue Dec 13 20:46:23 2011 @@ -155,9 +155,9 @@ sub get_currentimage_txt_contents { # Attempt to retrieve the contents of currentimage.txt my $cat_command = "cat ~/currentimage.txt"; - my ($cat_exit_status, $cat_output) = run_ssh_command($computer_node_name, $management_node_keys, $cat_command, '', '', 0); + my ($cat_exit_status, $cat_output) = run_ssh_command($computer_node_name, $management_node_keys, $cat_command); if (defined($cat_exit_status) && $cat_exit_status == 0) { - notify($ERRORS{'DEBUG'}, 0, "retrieved currentimage.txt contents from $computer_node_name"); + notify($ERRORS{'DEBUG'}, 0, "retrieved currentimage.txt contents from $computer_node_name:\n" . join("\n", @$cat_output)); } elsif (defined($cat_exit_status)) { notify($ERRORS{'WARNING'}, 0, "failed to retrieve currentimage.txt from $computer_node_name, exit status: $cat_exit_status, output:\n@{$cat_output}"); @@ -1038,7 +1038,31 @@ sub _get_public_interface_name_helper { my @ip_addresses_1 = keys %{$network_configuration->{$interface_name_1}{ip_address}}; my @ip_addresses_2 = keys %{$network_configuration->{$interface_name_2}{ip_address}}; - if (!$condition || $condition eq 'assigned_public') { + if (!$condition || $condition eq 'matches_private') { + # Get the computer private IP address + my $computer_private_ip_address = $self->data->get_computer_private_ip_address(); + if (!$computer_private_ip_address) { + notify($ERRORS{'DEBUG'}, 0, "unable to retrieve computer private IP address from reservation data"); + return; + } + + my $matches_private_1 = (grep { $_ eq $computer_private_ip_address } @ip_addresses_1) ? 1 : 0; + my $matches_private_2 = (grep { $_ eq $computer_private_ip_address } @ip_addresses_2) ? 1 : 0; + + if ($matches_private_1 eq $matches_private_2) { + notify($ERRORS{'DEBUG'}, 0, "tie: both interfaces are/are not assigned the private IP address: $computer_private_ip_address, proceeding to check if either interface is assigned a public IP address"); + return $self->_get_public_interface_name_helper($interface_name_1, $interface_name_2, 'assigned_public'); + } + elsif ($matches_private_1) { + notify($ERRORS{'DEBUG'}, 0, "'$interface_name_2' is more likely the public interface, it is NOT assigned the private IP address: $computer_private_ip_address"); + return $interface_name_2; + } + else { + notify($ERRORS{'DEBUG'}, 0, "'$interface_name_1' is more likely the public interface, it is NOT assigned the private IP address: $computer_private_ip_address"); + return $interface_name_1; + } + } + elsif ($condition eq 'assigned_public') { my $assigned_public_1 = (grep { is_public_ip_address($_) } @ip_addresses_1) ? 1 : 0; my $assigned_public_2 = (grep { is_public_ip_address($_) } @ip_addresses_2) ? 1 : 0; @@ -1060,8 +1084,8 @@ sub _get_public_interface_name_helper { my $assigned_default_gateway_2 = defined($network_configuration->{$interface_name_2}{default_gateway}) ? 1 : 0; if ($assigned_default_gateway_1 eq $assigned_default_gateway_2) { - notify($ERRORS{'DEBUG'}, 0, "tie: both interfaces are/are not assigned a default gateway, proceeding to check if either is assigned the private IP address"); - return $self->_get_public_interface_name_helper($interface_name_1, $interface_name_2, 'matches_private'); + notify($ERRORS{'DEBUG'}, 0, "tie: both interfaces are/are not assigned a default gateway, returning '$interface_name_2'"); + return $interface_name_2; } elsif ($assigned_default_gateway_1) { notify($ERRORS{'DEBUG'}, 0, "'$interface_name_1' is more likely the public interface, it is assigned a default gateway, '$interface_name_2' is not"); @@ -1072,30 +1096,6 @@ sub _get_public_interface_name_helper { return $interface_name_2; } } - elsif ($condition eq 'matches_private') { - # Get the computer private IP address - my $computer_private_ip_address = $self->data->get_computer_private_ip_address(); - if (!$computer_private_ip_address) { - notify($ERRORS{'DEBUG'}, 0, "unable to retrieve computer private IP address from reservation data"); - return; - } - - my $matches_private_1 = (grep { $_ eq $computer_private_ip_address } @ip_addresses_1) ? 1 : 0; - my $matches_private_2 = (grep { $_ eq $computer_private_ip_address } @ip_addresses_2) ? 1 : 0; - - if ($matches_private_1 eq $matches_private_2) { - notify($ERRORS{'DEBUG'}, 0, "tie: both interfaces are/are not assigned the private IP address: $computer_private_ip_address, returning '$interface_name_1'"); - return $interface_name_1; - } - elsif ($matches_private_1) { - notify($ERRORS{'DEBUG'}, 0, "'$interface_name_2' is more likely the public interface, it is NOT assigned the private IP address: $computer_private_ip_address"); - return $interface_name_2; - } - else { - notify($ERRORS{'DEBUG'}, 0, "'$interface_name_1' is more likely the public interface, it is NOT assigned the private IP address: $computer_private_ip_address"); - return $interface_name_1; - } - } else { notify($ERRORS{'WARNING'}, 0, "unable to determine which interface is more likely the public interface, invalid \$condition argument: '$condition'"); return; @@ -1529,6 +1529,12 @@ sub create_text_file { my $computer_node_name = $self->data->get_computer_node_name(); my $image_os_type = $self->data->get_image_os_type(); + # Attempt to create the parent directory if it does not exist + if ($self->can('create_directory')) { + my $parent_directory_path = parent_directory_path($file_path); + $self->create_directory($parent_directory_path); + } + # Remove Windows-style carriage returns if the image OS isn't Windows if ($image_os_type =~ /windows/) { $file_contents_string =~ s/\r*\n/\r\n/g; @@ -1767,6 +1773,7 @@ sub execute_new { # If true, sets the timeout to "inactivity timeout" # If false sets it to "absolute timeout" #$ssh->restart_timeout_upon_receive(1); + $ssh->read_all(); }; if ($EVAL_ERROR) { if ($EVAL_ERROR =~ /^(\w+) at \//) { Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm?rev=1213919&r1=1213918&r2=1213919&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm Tue Dec 13 20:46:23 2011 @@ -62,45 +62,6 @@ use VCL::utils; #///////////////////////////////////////////////////////////////////////////// -=head2 set_vmhost_os - - Parameters : None - Returns : Process's VM host OS object - Description : Sets the VM host OS object for the provisioner module to access. - -=cut - -sub set_vmhost_os { - my $self = shift; - my $vmhost_os = shift; - $self->{vmhost_os} = $vmhost_os; -} - -#///////////////////////////////////////////////////////////////////////////// - -=head2 vmhost_os - - Parameters : None - Returns : Process's VM host OS object - Description : Allows provisioning modules to access the reservation's VM host OS - object. - -=cut - -sub vmhost_os { - my $self = shift; - - if (!$self->{vmhost_os}) { - notify($ERRORS{'WARNING'}, 0, "unable to return VM host OS object, \$self->{vmhost_os} is not set"); - return; - } - else { - return $self->{vmhost_os}; - } -} - -#///////////////////////////////////////////////////////////////////////////// - =head2 retrieve_image Parameters : none Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm?rev=1213919&r1=1213918&r2=1213919&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm Tue Dec 13 20:46:23 2011 @@ -119,6 +119,12 @@ sub initialize { return; } + # Create a VM host OS object if vmhostid is set for the computer + if ($self->data->get_computer_vmhost_id() && !$self->create_vmhost_os_object()) { + notify($ERRORS{'WARNING'}, 0, "failed to create VM host OS object"); + return; + } + # Create a provisioning object if (!$self->create_provisioning_object()) { notify($ERRORS{'WARNING'}, 0, "failed to create provisioning object"); @@ -126,8 +132,9 @@ sub initialize { } # Allow the provisioning object to access the OS object and vice-versa - $self->{provisioner}->set_os($self->{os}); - $self->{os}->set_provisioner($self->{provisioner}); + $self->provisioner->set_os($self->os()); + $self->provisioner->set_vmhost_os($self->vmhost_os()); + $self->os->set_provisioner($self->provisioner()); notify($ERRORS{'DEBUG'}, 0, "returning 1"); return 1; @@ -838,7 +845,7 @@ sub DESTROY { my $self = shift; my $address = sprintf('%x', $self); - notify($ERRORS{'DEBUG'}, 0, ref($self) . " destructor called, address: $address"); + #notify($ERRORS{'DEBUG'}, 0, ref($self) . " destructor called, address: $address"); # If not a blockrequest, delete computerloadlog entry if ($self && $self->data && !$self->data->is_blockrequest()) { @@ -858,14 +865,14 @@ sub DESTROY { # Print the number of database handles this process created for testing/development if (defined $ENV{dbh_count}) { - notify($ERRORS{'DEBUG'}, 0, "number of database handles state process created: $ENV{dbh_count}"); + #notify($ERRORS{'DEBUG'}, 0, "number of database handles state process created: $ENV{dbh_count}"); } else { notify($ERRORS{'DEBUG'}, 0, "state process created unknown number of database handles, \$ENV{dbh_count} is undefined"); } if (defined $ENV{database_select_count}) { - notify($ERRORS{'DEBUG'}, 0, "database select queries: $ENV{database_select_count}"); + #notify($ERRORS{'DEBUG'}, 0, "database select queries: $ENV{database_select_count}"); } if (defined $ENV{database_select_calls}) { @@ -876,11 +883,11 @@ sub DESTROY { $database_select_calls_string .= "$ENV{database_select_calls}{$key}: $key\n"; } - notify($ERRORS{'DEBUG'}, 0, "database select called from:\n$database_select_calls_string"); + #notify($ERRORS{'DEBUG'}, 0, "database select called from:\n$database_select_calls_string"); } if (defined $ENV{database_execute_count}) { - notify($ERRORS{'DEBUG'}, 0, "database execute queries: $ENV{database_execute_count}"); + #notify($ERRORS{'DEBUG'}, 0, "database execute queries: $ENV{database_execute_count}"); } # Close the database handle