You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2009/04/06 19:54:20 UTC
svn commit: r762438 -
/incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
Author: arkurth
Date: Mon Apr 6 17:54:19 2009
New Revision: 762438
URL: http://svn.apache.org/viewvc?rev=762438&view=rev
Log:
VCL-122
Added functionality to DataStructure.pm allowing it to get/set data from the log table.
Added DataStructure.pm::update_log_ending_DataStructure(). This sub will replace utils.pm::update_log_ending(). The new sub has access to all of the DataStructure data and adds logic to set the log.ending value to "failedtest" instead of "failed" under any of these conditions:
-imagerevision.production = 0
-image is only assigned to a single group named newimages-*
-state = reload
-state = to* (tomaintenance...)
-state = makeproduction
-state = *hpc*
-state = image
Modified:
incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
Modified: incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=762438&r1=762437&r2=762438&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm Mon Apr 6 17:54:19 2009
@@ -141,6 +141,28 @@
$SUBROUTINE_MAPPINGS{request_state_name} = '$self->request_data->{state}{name}';
$SUBROUTINE_MAPPINGS{request_laststate_name} = '$self->request_data->{laststate}{name}';
+$SUBROUTINE_MAPPINGS{log_id} = '$self->request_data->{log}{id}';
+$SUBROUTINE_MAPPINGS{log_userid} = '$self->request_data->{log}{userid}';
+$SUBROUTINE_MAPPINGS{log_nowfuture} = '$self->request_data->{log}{nowfuture}';
+$SUBROUTINE_MAPPINGS{log_start} = '$self->request_data->{log}{start}';
+$SUBROUTINE_MAPPINGS{log_loaded} = '$self->request_data->{log}{loaded}';
+$SUBROUTINE_MAPPINGS{log_initialend} = '$self->request_data->{log}{initialend}';
+$SUBROUTINE_MAPPINGS{log_finalend} = '$self->request_data->{log}{finalend}';
+$SUBROUTINE_MAPPINGS{log_wasavailable} = '$self->request_data->{log}{wasavailable}';
+$SUBROUTINE_MAPPINGS{log_ending} = '$self->request_data->{log}{ending}';
+$SUBROUTINE_MAPPINGS{log_requestid} = '$self->request_data->{log}{requestid}';
+$SUBROUTINE_MAPPINGS{log_computerid} = '$self->request_data->{log}{computerid}';
+$SUBROUTINE_MAPPINGS{log_remoteIP} = '$self->request_data->{log}{remoteIP}';
+$SUBROUTINE_MAPPINGS{log_imageid} = '$self->request_data->{log}{imageid}';
+$SUBROUTINE_MAPPINGS{log_size} = '$self->request_data->{log}{size}';
+
+$SUBROUTINE_MAPPINGS{sublog_imageid} = '$self->request_data->{log}{imageid}';
+$SUBROUTINE_MAPPINGS{sublog_imagerevisionid} = '$self->request_data->{log}{imagerevisionid}';
+$SUBROUTINE_MAPPINGS{sublog_computerid} = '$self->request_data->{log}{computerid}';
+$SUBROUTINE_MAPPINGS{sublog_IPaddress} = '$self->request_data->{log}{IPaddress}';
+$SUBROUTINE_MAPPINGS{sublog_managementnodeid} = '$self->request_data->{log}{managementnodeid}';
+$SUBROUTINE_MAPPINGS{sublog_predictivemoduleid} = '$self->request_data->{log}{predictivemoduleid}';
+
#$SUBROUTINE_MAPPINGS{request_reservationid} = '$self->request_data->{RESERVATIONID}';
$SUBROUTINE_MAPPINGS{reservation_id} = '$self->request_data->{RESERVATIONID}';
@@ -606,7 +628,24 @@
# Get the data from the request_data hash
# eval is required in order to interpolate the hash path before retrieving the data
my $key_defined = eval "defined $hash_path";
- if (!$key_defined) {
+
+ # If log or sublog data was requested and not yet populated, attempt to retrieve it
+ if (!$key_defined && $data_identifier =~ /^(log_|sublog_)/) {
+ notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve log data, requested data has not been initialized ($data_identifier)");
+
+ if ($self->get_log_data()) {
+ # Log data was retrieved, check if requested data is now populated
+ if (!eval "defined $hash_path") {
+ notify($ERRORS{'WARNING'}, 0, "log data was retrieved but corresponding data has not been initialized for $method_name: $hash_path", $self->request_data);
+ return sub { };
+ }
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "log data could not be retrieved");
+ return sub { };
+ }
+ }
+ elsif (!$key_defined) {
notify($ERRORS{'WARNING'}, 0, "corresponding data has not been initialized for $method_name: $hash_path", $self->request_data);
return sub { };
}
@@ -1250,6 +1289,267 @@
#/////////////////////////////////////////////////////////////////////////////
+=head2 get_log_data
+
+ Parameters : log ID (optional)
+ Returns : hash reference
+ Description : Retrieves data from the log and sublog tables for the log ID
+ either specified via an argument or the log ID for the
+ reservation represented by the DataStructure object.
+
+=cut
+
+sub get_log_data {
+ my $self;
+ my $argument = shift;
+ my $request_log_id;
+
+ # Check if subroutine was called as an object method
+ if (ref($argument) =~ /DataStructure/) {
+ # Subroutine was called as an object method, get next argument
+ $self = $argument;
+ $argument = shift;
+
+ # If argument wasn't passed, attempt to get the log id from this DataStructure object
+ if (!$argument) {
+ # Get the log id and make sure it is set
+ $request_log_id = $self->get_request_log_id();
+ if (!$request_log_id) {
+ notify($ERRORS{'WARNING'}, 0, "log id was not passed as an argument and could not be retrieved from the existing DataStructure object");
+ return;
+ }
+ }
+ else {
+ $request_log_id = $argument;
+ }
+ }
+ else {
+ $request_log_id = $argument;
+
+ # Make sure log id was determined and is valid
+ if (!$request_log_id) {
+ notify($ERRORS{'WARNING'}, 0, "log id was not passed as an argument and subroutine was not called as an object method");
+ return;
+ }
+ }
+
+ # Make sure log id was determined and is valid
+ if (!$request_log_id) {
+ notify($ERRORS{'WARNING'}, 0, "log id could not be determined");
+ return;
+ }
+ elsif ($request_log_id !~ /^\d+$/) {
+ notify($ERRORS{'WARNING'}, 0, "log id is not valid: $request_log_id");
+ return;
+ }
+
+ # Construct a select statement
+ my $sql_select_statement = "
+ SELECT
+ *
+ FROM
+ log
+ LEFT JOIN sublog ON sublog.logid = log.id
+ WHERE
+ log.id = $request_log_id
+ ";
+
+ # Call database_select() to execute the select statement and make sure 1 row was returned
+ my @select_rows = VCL::utils::database_select($sql_select_statement);
+ if (!scalar @select_rows == 1) {
+ notify($ERRORS{'WARNING'}, 0, "select statement returned " . scalar @select_rows . " rows:\n" . join("\n", $sql_select_statement));
+ return;
+ }
+
+ # $select_rows[0] is a hash reference, the keys are the column names
+ # Loop through the column names and add the data to $self->request_data
+ my $row = $select_rows[0];
+
+ my %data_hash;
+ foreach my $column_name (sort keys(%{$row})) {
+ # Get the data value for the column
+ my $data_value = $row->{$column_name};
+ $self->request_data->{log}{$column_name} = $data_value if !defined($self->request_data->{log}{$column_name});
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, "retrieved log data for log id: $request_log_id");
+ return $self->request_data->{log};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 update_log_ending_DataStructure
+
+ Parameters : string containing the log ending value
+ Returns : true if successful, false if failed
+ Description : Updates the log.ending value in the database for the log ID
+ set for this reservation. Returns false if log ID is not
+ set. A string argument must be passed containing the new
+ log.ending value.
+
+=cut
+
+sub update_log_ending_DataStructure {
+ my $self = shift;
+ my $request_log_ending = shift;
+
+ # Check if subroutine was called as an object method
+ if (!ref($self) =~ /DataStructure/) {
+ notify($ERRORS{'WARNING'}, 0, "subroutine must be called as an object method");
+ return;
+ }
+
+ # Make sure log ending value was passed
+ if (!$request_log_ending) {
+ notify($ERRORS{'WARNING'}, 0, "log ending value argument was not passed");
+ return;
+ }
+
+ # Get the log id
+ my $request_log_id = $self->get_request_log_id();
+ if (!$request_log_id) {
+ notify($ERRORS{'WARNING'}, 0, "request log id could not be retrieved");
+ return;
+ }
+
+ # Get the request state name
+ my $request_state_name = $self->get_request_state_name();
+ if (!$request_state_name) {
+ notify($ERRORS{'WARNING'}, 0, "request state name could not be retrieved");
+ return;
+ }
+
+ # Get the image id
+ my $image_id = $self->get_image_id();
+ if (!$image_id) {
+ notify($ERRORS{'WARNING'}, 0, "image id could not be retrieved");
+ return;
+ }
+
+ # Get the image name
+ my $image_name = $self->get_image_name();
+ if (!$image_name) {
+ notify($ERRORS{'WARNING'}, 0, "image name could not be retrieved");
+ return;
+ }
+
+ # Get the imagerevision production flag
+ my $imagerevision_production = $self->get_imagerevision_production();
+ if ($imagerevision_production !~ /^(0|1)$/) {
+ notify($ERRORS{'WARNING'}, 0, "imagerevision production flag could not be retrieved");
+ return;
+ }
+
+ # Construct a select statement to retrieve the resource group names this image belongs to
+ my $select_image_groups_statement = "
+ SELECT DISTINCT
+ resourcegroup.name
+ FROM
+ image,
+ resource,
+ resourcetype,
+ resourcegroup,
+ resourcegroupmembers
+ WHERE
+ image.id = $image_id AND
+ resource.subid = image.id AND resource.resourcetypeid = 13 AND
+ resourcegroupmembers.resourceid = resource.id AND
+ resourcegroup.id = resourcegroupmembers.resourcegroupid
+ ";
+
+ # Call database_select() to execute the select statement
+ my @image_group_rows = VCL::utils::database_select($select_image_groups_statement);
+ if (!scalar @image_group_rows == 1) {
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve image group names for image $image_name");
+ return;
+ }
+
+ # Assemble an array from the select return array
+ my @image_group_names;
+ for my $image_group_row (@image_group_rows) {
+ my $image_group_name = $image_group_row->{name};
+ push @image_group_names, $image_group_name;
+ }
+ notify($ERRORS{'DEBUG'}, 0, "retrieved groups image $image_name belongs to:\n" . join("\n", @image_group_names));
+
+
+ # Make sure the requested log ending makes sense
+
+ # Don't set ending to 'failed' if image only belongs to newimages-* group
+ if ($request_log_ending eq 'failed' && scalar @image_group_names == 1 && $image_group_names[0] =~ /^newimages-.*/i) {
+ notify($ERRORS{'WARNING'}, 0, "log ending should not be set to '$request_log_ending' because image only belongs to $image_group_names[0] group, changing to 'failedtest'");
+ $request_log_ending = 'failedtest';
+ }
+
+ # Don't set ending to 'failed' if not a state the end user sees
+ if ($request_log_ending eq 'failed' && $request_state_name =~ /^(reload|to.*|makeproduction|.*hpc.*|image)$/) {
+ notify($ERRORS{'WARNING'}, 0, "log ending should not be set to '$request_log_ending' because request state is $request_state_name, changing to 'failedtest'");
+ $request_log_ending = 'failedtest';
+ }
+
+ # Don't set ending to 'failed' if imagerevision.production = 0
+ if ($request_log_ending eq 'failed' && !$imagerevision_production) {
+ notify($ERRORS{'WARNING'}, 0, "log ending should not be set to '$request_log_ending' because imagerevision.production = 0, changing to 'failedtest'");
+ $request_log_ending = 'failedtest';
+ }
+
+
+ # Construct the update statement
+ my $sql_update_statement = "
+ UPDATE
+ log
+ SET
+ log.ending = \'$request_log_ending\',
+ log.finalend = NOW()
+ WHERE
+ log.id = $request_log_id
+ ";
+
+ # Execute the update statement
+ if (database_execute($sql_update_statement)) {
+ notify($ERRORS{'OK'}, 0, "executed update statement to set log ending to $request_log_ending for log id: $request_log_id");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute update statement to set log ending to $request_log_ending for log id: $request_log_id");
+ return;
+ }
+
+ # Check the actual ending value in the database, SQL update returns 1 even if 0 rows were affected
+ # Construct a select statement
+ my $sql_select_statement = "
+ SELECT
+ log.ending,
+ log.finalend
+ FROM
+ log
+ WHERE
+ log.id = $request_log_id
+ ";
+
+ # Call database_select() to execute the select statement and make sure 1 row was returned
+ my @select_rows = VCL::utils::database_select($sql_select_statement);
+ if (!scalar @select_rows == 1) {
+ notify($ERRORS{'WARNING'}, 0, "unable to verify log ending value, select statement returned " . scalar @select_rows . " rows:\n" . join("\n", $sql_select_statement));
+ return;
+ }
+
+ # $select_rows[0] is a hash reference, the keys are the column names
+ my $log_ending = $select_rows[0]->{ending};
+
+ # Compare the ending value in the database to the argument
+ if ($log_ending && $log_ending eq $request_log_ending) {
+ notify($ERRORS{'DEBUG'}, 0, "verified log ending was set to '$request_log_ending' for log id: $request_log_id");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "log ending in database ('$log_ending') does not match requested value ('$request_log_ending') for log id: $request_log_id");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
1;
__END__