You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by fa...@apache.org on 2014/09/23 21:09:54 UTC

svn commit: r1627119 - in /vcl/trunk/managementnode/lib/VCL: ./ Module/Predictive/ Module/Provisioning/ Module/Provisioning/VMware/

Author: fapeeler
Date: Tue Sep 23 19:09:53 2014
New Revision: 1627119

URL: http://svn.apache.org/r1627119
Log:
VCL-170

Created Level_2 module
added unload routine to all active provisioning modules
updated new.pm to not always set the nextimageid, not sure why it was setting it
extended predictive reload modules return array to contain an action (reload/unload).
moved predictive reload info from management node to each individual computer
Updated Datastructure to pull predictive module info from computer section.


Added:
    vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_2.pm
Modified:
    vcl/trunk/managementnode/lib/VCL/DataStructure.pm
    vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_0.pm
    vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_1.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm
    vcl/trunk/managementnode/lib/VCL/new.pm
    vcl/trunk/managementnode/lib/VCL/reclaim.pm
    vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/DataStructure.pm Tue Sep 23 19:09:53 2014
@@ -236,6 +236,16 @@ $SUBROUTINE_MAPPINGS{computer_provisioni
 $SUBROUTINE_MAPPINGS{computer_provisioning_module_description} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{module}{description}';
 $SUBROUTINE_MAPPINGS{computer_provisioning_module_perl_package} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{module}{perlpackage}';
 
+$SUBROUTINE_MAPPINGS{computer_predictive_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictiveid}';
+$SUBROUTINE_MAPPINGS{computer_predictive_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{name}';
+$SUBROUTINE_MAPPINGS{computer_predictive_pretty_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{prettyname}';
+$SUBROUTINE_MAPPINGS{computer_predictive_module_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{id}';
+
+$SUBROUTINE_MAPPINGS{computer_predictive_module_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{name}';
+$SUBROUTINE_MAPPINGS{computer_predictive_module_pretty_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{prettyname}';
+$SUBROUTINE_MAPPINGS{computer_predictive_module_description} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{description}';
+$SUBROUTINE_MAPPINGS{computer_predictive_module_perl_package} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{perlpackage}';
+
 $SUBROUTINE_MAPPINGS{vmhost_computer_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computerid}';
 $SUBROUTINE_MAPPINGS{vmhost_hostname} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{hostname}';
 $SUBROUTINE_MAPPINGS{vmhost_short_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{SHORTNAME}';
@@ -1270,29 +1280,33 @@ sub get_next_image_dataStructure {
 	# This will be returned if the predictive method fails
 	my @current_image;
 	if ($image_name && $image_id && $imagerevision_id) {
-		@current_image = ($image_name, $image_id, $imagerevision_id);
+		@current_image = ("reload", $image_name, $image_id, $imagerevision_id);
 	}
 	else {
 		notify($ERRORS{'WARNING'}, 0, "unable to obtain current image information");
       @current_image = ();
 	}
+	
+	my $computer_predictive_module_id = $self->get_computer_predictive_module_id();
 
 	#collect predictive reload information from database.
 	my $management_predictive_info = get_management_predictive_info();
-	if (!$management_predictive_info->{predictivemoduleid}){
+	if (!$computer_predictive_module_id){
 		notify($ERRORS{'CRITICAL'}, 0, "unable to obtain management node info for this node, returning current reservation image information");
       return @current_image;
 	}
 
 	#update ENV in case other modules need to know
 	my $management_node_info = get_management_node_info();
-	$management_node_info->{predictivemoduleid} = $management_predictive_info->{predictivemoduleid};
-	$management_node_info->{predictive_name} = $management_predictive_info->{predictive_name};
-	$management_node_info->{predictive_prettyname} = $management_predictive_info->{predictive_prettyname};
-	$management_node_info->{predictive_description} = $management_predictive_info->{predictive_description};
-	$management_node_info->{predictive_perlpackage} = $management_predictive_info->{predictive_perlpackage};
+	
+	$management_node_info->{predictivemoduleid} = $self->get_computer_predictive_module_id();
+	$management_node_info->{predictive_name} = $self->get_computer_predictive_module_name();
+	$management_node_info->{predictive_prettyname} = $self->get_computer_predictive_pretty_name();
+	$management_node_info->{predictive_description} = $self->get_computer_predictive_module_description();
+	$management_node_info->{predictive_perlpackage} = $self->get_computer_predictive_module_perl_package();
+
+	my $predictive_perl_package = $self->get_computer_predictive_module_perl_package();
 
-	my $predictive_perl_package = $management_predictive_info->{predictive_perlpackage};
 	my @nextimage;
 
 	if ($predictive_perl_package) {
@@ -1306,10 +1320,10 @@ sub get_next_image_dataStructure {
 			return @current_image;
 		}
 		if (my $predictor = ($predictive_perl_package)->new({data_structure => $self})) {
-			notify($ERRORS{'OK'}, 0, ref($predictor) . " predictive loading object successfully created");
 			@nextimage = $predictor->get_next_image();
-			if (scalar(@nextimage) == 3) {
+			notify($ERRORS{'OK'}, 0, ref($predictor) . " predictive loading object successfully created");
 				notify($ERRORS{'OK'}, 0, "predictive loading module retreived image information: @nextimage");
+			if (scalar(@nextimage) >= 3) {
 				return @nextimage;
 			}
 			else {

Modified: vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_0.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_0.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_0.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_0.pm Tue Sep 23 19:09:53 2014
@@ -84,6 +84,9 @@ sub get_next_image {
 	my $reservation_id      = $self->data->get_reservation_id();
 	my $computer_id         = $self->data->get_computer_id();
 	my $computer_short_name = $self->data->get_computer_short_name();
+	my $current_image_id    = $self->data->get_image_id();
+	my $current_image_name  = $self->data->get_image_name();
+	my $current_imagerevision_id = $self->data->get_imagerevision_id();
 	
 	my $notify_prefix = "predictive_reload_Level_0: ";
 	
@@ -169,6 +172,7 @@ sub get_next_image {
 		AND imagerevision.production = 1
 		AND computer.nextimageid = image.id
 		AND computer.id = $computer_id
+		AND image.name NOT LIKE 'noimage'
 	";
 	
 	
@@ -178,15 +182,15 @@ sub get_next_image {
 	
 	# Check to make sure at least 1 row were returned
 	if (scalar @next_selected_rows == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch next image for computerid $computer_id");
-		return 0;
+		notify($ERRORS{'OK'}, 0, "$notify_prefix next image for computerid $computer_id is not set");
+		return;
 	}
 	elsif (scalar @next_selected_rows > 1) {
-		notify($ERRORS{'WARNING'}, 0, "" . scalar @next_selected_rows . " rows were returned from database select");
-		return 0;
+		notify($ERRORS{'OK'}, 0, "" . scalar @next_selected_rows . " rows were returned from database select");
+		return;
 	}
 	notify($ERRORS{'OK'}, 0, "$notify_prefix returning nextimage image=$next_selected_rows[0]{imagename} imageid=$next_selected_rows[0]{imageid}");
-	push (@ret_array, $next_selected_rows[0]{imagename}, $next_selected_rows[0]{imageid}, $next_selected_rows[0]{imagerevisionid});
+	push (@ret_array, "reload", $next_selected_rows[0]{imagename}, $next_selected_rows[0]{imageid}, $next_selected_rows[0]{imagerevisionid});
 	#Clear next_imageid
 	if(!clear_next_image_id($computer_id)){
 		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to clear next_image_id for computerid $computer_id");

Modified: vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_1.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_1.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_1.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_1.pm Tue Sep 23 19:09:53 2014
@@ -119,13 +119,14 @@ sub get_next_image {
 			AND imagerevision.production = 1
 			AND computer.nextimageid = image.id
 			AND computer.id = $computer_id
+			AND image.name NOT LIKE 'noimage'
 		";
 		
 		
 		my @next_selected_rows = database_select($select_nextimage);
 		# Check to make sure at least 1 row were returned
 		if (scalar @next_selected_rows == 0) {
-			notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch next image for computerid $computer_id");
+			notify($ERRORS{'OK'}, 0, "$notify_prefix next image not set for computerid $computer_id");
 		}   
 		elsif (scalar @next_selected_rows > 1) {
 			notify($ERRORS{'WARNING'}, 0, "" . scalar @next_selected_rows . " rows were returned from database select");
@@ -185,7 +186,7 @@ sub get_next_image {
 			notify($ERRORS{'OK'}, 0, "$notify_prefix diff= $diff image= $reservation_row{imagename} imageid=$reservation_row{imageid}");
 			if ($diff < (50 * 60)) {
 				notify($ERRORS{'OK'}, 0, "$notify_prefix future reservation detected diff= $diff image= $reservation_row{imagename} imageid=$reservation_row{imageid}");
-				push(@ret_array, $reservation_row{imagename}, $reservation_row{imageid}, $reservation_row{imagerevisionid});
+				push(@ret_array, "reload", $reservation_row{imagename}, $reservation_row{imageid}, $reservation_row{imagerevisionid});
 				return @ret_array;
 			}
 		} ## end for (@selected_rows)
@@ -207,7 +208,7 @@ sub get_next_image {
 	
 	my @data = database_select($select_type);
 	if (scalar @data == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch provisioningid for computer_id $computer_id");
 		return 0;
 	}
 	my $type = $data[0]{type};
@@ -226,7 +227,7 @@ sub get_next_image {
 	
 	@data = database_select($select_online);
 	if (scalar @data == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to run query for computer_id $computer_id\n $select_online");
 		return 0;
 	}
 	my $online = $data[0]{cnt};
@@ -244,7 +245,7 @@ sub get_next_image {
 	
 	@data = database_select($select_available);
 	if (scalar @data == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to run query for computer_id $computer_id\n $select_available");
 		return 0;
 	}
 	
@@ -297,7 +298,7 @@ sub get_next_image {
 	";
 	@data = database_select($select_mapped_images);
 	if (scalar @data == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to run query for computer_id $computer_id\n $select_mapped_images");
 		return 0;
 	}
 	my $resourceid = $data[0]{id};
@@ -313,7 +314,7 @@ sub get_next_image {
 	@data = database_select($select_compgrps1);
 	
 	if (scalar @data == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to run query for computer_id $computer_id\n $select_compgrps1");
 		return 0;
 	}
 	my @compgroups;
@@ -357,7 +358,7 @@ sub get_next_image {
 		push(@imggroups, $row{resourcegroupid1});
 	}
 	if (scalar @imggroups == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to run query for computer_id $computer_id\n $select_imggrps2");
 		return 0;
 	}
 	
@@ -386,7 +387,7 @@ sub get_next_image {
 	my @imgids;
 	@data = database_select($select_imageids);
 	if (scalar @data == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to run query for computer_id $computer_id\n $select_imageids");
 		return 0;
 	}
 	foreach (@data) {
@@ -448,7 +449,7 @@ sub get_next_image {
 	";
 	@data = database_select($select_imageid);
 	if (scalar @data == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to run query for computer_id $computer_id\n $select_imageid");
 		return 0;
 	}
 	my $imageid = $data[0]{imageid};
@@ -470,12 +471,12 @@ sub get_next_image {
 	";
 	@data = database_select($select_extra);
 	if (scalar @data == 0) {
-		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to fetch preferred image for computer_id $computer_id");
+		notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to run query for computer_id $computer_id\n $select_extra");
 		return 0;
 	}
 	
 	notify($ERRORS{'OK'}, 0, "$notify_prefix $computer_id $data[0]{name}, $imageid, $data[0]{id}");
-	push(@ret_array, $data[0]{name}, $imageid, $data[0]{id});
+	push(@ret_array, "reload", $data[0]{name}, $imageid, $data[0]{id});
 	return @ret_array;
 } ## end sub get_next_image_revision
 

Added: vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_2.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_2.pm?rev=1627119&view=auto
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_2.pm (added)
+++ vcl/trunk/managementnode/lib/VCL/Module/Predictive/Level_2.pm Tue Sep 23 19:09:53 2014
@@ -0,0 +1,225 @@
+#!/usr/bin/perl -w
+###############################################################################
+# $Id: Level_2.pm 1610496 2014-07-14 19:37:51Z fapeeler $
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                  
+# See the License for the specific language governing permissions and
+# limitations under the License.
+###############################################################################
+
+=head1 NAME
+
+VCL::Module::Predictive::Level_2 - VCL predictive loading module for "Level 1" algorithm
+
+=head1 SYNOPSIS
+
+ use base qw(VCL::Module::Predictive::Level_2);
+
+=head1 DESCRIPTION
+
+ Needs to be written.
+
+=cut
+
+##############################################################################
+package VCL::Module::Predictive::Level_2;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::Predictive);
+
+# Specify the version of this module
+our $VERSION = '2.3';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+use English '-no_match_vars';
+
+use VCL::utils;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_next_image
+
+ Parameters  : None. Must be called as an object method.
+ Returns     :
+ Description :
+
+=cut
+
+sub get_next_image {
+	my $self = shift;
+	if (ref($self) !~ /Level_2/) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method, process exiting");
+		exit 1;
+	}
+	#notify($ERRORS{'WARNING'}, 0, "get_next_image_revision works!");
+
+	# Retrieve variables from the DataStructure
+	my $request_id          = $self->data->get_request_id();
+	my $reservation_id      = $self->data->get_reservation_id();
+	my $computer_id         = $self->data->get_computer_id();
+	my $computer_short_name = $self->data->get_computer_short_name();
+	my $computer_nextimage_id = $self->data->get_computer_nextimage_id();
+
+	my @ret_array;
+	my $notify_prefix = "predictive_reload_Level_2 :";
+
+	notify($ERRORS{'OK'}, 0, "$notify_prefix starting predictive_reload_level_2 for $computer_id");
+
+	#check if node is part of block reservation 
+	if(is_inblockrequest($computer_id)){
+		notify($ERRORS{'DEBUG'}, 0, "computer id $computer_id is in blockComputers table");
+		my @block_ret_array = get_block_request_image_info($computer_id);
+
+		push(@ret_array, "reload", @block_ret_array);	
+
+		if(defined($block_ret_array[0]) && $block_ret_array[0]){
+			return @block_ret_array;
+		}
+		else{
+			notify($ERRORS{'WARNING'}, 0, "computer $computer_id is part of blockComputers, failed to return image info"); 
+		}
+	}
+
+	#If nextimageid set, set to default 0 and return the imageid
+	if(defined($computer_nextimage_id) && $computer_nextimage_id) {
+		#Get computer_nextimage_id info
+		my $select_nextimage = " 
+		SELECT DISTINCT
+		imagerevision.imagename AS imagename,
+		imagerevision.id AS imagerevisionid,
+		image.id AS imageid
+		FROM
+		image,
+		computer,
+		imagerevision
+		WHERE
+		imagerevision.imageid = computer.nextimageid
+		AND imagerevision.production = 1
+		AND computer.nextimageid = image.id
+		AND computer.id = $computer_id
+		AND image.name NOT LIKE 'noimage'
+		";
+		
+
+		# Call the database select subroutine
+		# This will return an array of one or more rows based on the select statement
+		my @next_selected_rows = database_select($select_nextimage);
+		# Check to make sure at least 1 row were returned
+		if (scalar @next_selected_rows == 0) {
+			notify($ERRORS{'OK'}, 0, "$notify_prefix next image is not set for for computerid $computer_id");
+		}   
+		elsif (scalar @next_selected_rows > 1) {      notify($ERRORS{'WARNING'}, 0, "" . scalar @next_selected_rows . " rows were returned from database select");
+		}
+		else {
+			notify($ERRORS{'OK'}, 0, "$notify_prefix returning nextimage image=$next_selected_rows[0]{imagename} imageid=$next_selected_rows[0]{imageid}");
+			my @next_image_ret_array;
+			push(@next_image_ret_array, "reload", $next_selected_rows[0]{imagename}, $next_selected_rows[0]{imageid}, $next_selected_rows[0]{imagerevisionid});
+			
+			#Clear next_imageid
+			if(!clear_next_image_id($computer_id)){
+				notify($ERRORS{'WARNING'}, 0, "$notify_prefix failed to clear next_image_id for computerid $computer_id");
+			}
+			return @next_image_ret_array;
+		}
+
+	}
+
+	#Look for any upcoming reservations
+
+	my $select_statement = "
+		  SELECT DISTINCT
+		  req.start AS starttime,
+		  ir.imagename AS imagename,
+        res.imagerevisionid AS imagerevisionid,
+        res.imageid AS imageid
+        FROM
+        reservation res,
+        request req,
+        image i,
+        state s,
+        imagerevision ir
+   WHERE
+        res.requestid = req.id
+        AND req.stateid = s.id
+        AND i.id = res.imageid
+        AND ir.id = res.imagerevisionid
+        AND res.computerid = $computer_id
+        AND (s.name = \'new\' OR s.name = \'reload\' OR s.name = \'imageprep\')
+   ";
+
+	# Call the database select subroutine
+	# This will return an array of one or more rows based on the select statement
+	my @selected_rows = database_select($select_statement);
+	
+
+	# Check to make sure 1 or more rows were returned
+	if (scalar @selected_rows > 0) {
+		# Loop through list of upcoming reservations
+		# Based on the start time load the next one
+
+		my $now = time();
+
+		# It contains a hash
+		for (@selected_rows) {
+			my %reservation_row = %{$_};
+			# $reservation_row{starttime}
+			# $reservation_row{imagename}
+			# $reservation_row{imagerevisionid}
+			# $reservation_row{imageid}
+			my $epoch_start = convert_to_epoch_seconds($reservation_row{starttime});
+			my $diff        = $epoch_start - $now;
+			# If start time is less than 50 minutes from now return this image
+			notify($ERRORS{'OK'}, 0, "$notify_prefix diff= $diff image= $reservation_row{imagename} imageid=$reservation_row{imageid}");
+			if ($diff < (50 * 60)) {
+				notify($ERRORS{'OK'}, 0, "$notify_prefix future reservation detected diff= $diff image= $reservation_row{imagename} imageid=$reservation_row{imageid}");
+				push(@ret_array, "reload", $reservation_row{imagename}, $reservation_row{imageid}, $reservation_row{imagerevisionid});
+				return @ret_array;
+			}
+		} ## end for (@selected_rows)
+	} ## end if (scalar @selected_rows > 0)
+
+	# No upcoming reservations - power off
+	
+	push(@ret_array, "unload","NA","NA","NA");
+
+	return @ret_array;
+
+
+} ## end sub get_next_image_revision
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 SEE ALSO
+
+L<http://cwiki.apache.org/VCL/>
+
+=cut

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/Lab.pm Tue Sep 23 19:09:53 2014
@@ -61,6 +61,21 @@ use VCL::utils;
 
 =cut
 
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 unload
+
+ Parameters  :
+ Returns     : 0 can't unload this resource type
+ Description :
+
+=cut
+
+sub unload {
+	return 0;
+}
+
 #/////////////////////////////////////////////////////////////////////////////
 
 =head2 load

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm Tue Sep 23 19:09:53 2014
@@ -468,6 +468,36 @@ sub initialize {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 unload
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Unloads a VM with the requested image.
+
+=cut
+
+sub unload {
+	my $self = shift;
+	if (ref($self) !~ /vmware/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $computer_name = $self->data->get_computer_short_name() || return;
+	my $vmhost_name = $self->data->get_vmhost_short_name() || return;
+
+	# Remove existing VMs which were created for the reservation computer
+	if (!$self->remove_existing_vms()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to remove existing VMs created for computer $computer_name on VM host: $vmhost_name");
+		return;
+	}
+
+	return 1;
+
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 load
 
  Parameters  : none

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm Tue Sep 23 19:09:53 2014
@@ -140,6 +140,34 @@ sub initialize {
 	return 1;
 }
 
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 unload
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Unloads the image on the domain:
+
+=over 3
+
+=cut
+
+sub unload {
+	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;
+	}
+
+	if(!$self->delete_existing_domains()) {
+		return;
+	}
+
+	return 1;
+
+}
+
 #/////////////////////////////////////////////////////////////////////////////
 
 =head2 load

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/one.pm Tue Sep 23 19:09:53 2014
@@ -102,6 +102,35 @@ sub initialize {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 unload
+
+ Parameters  : hash
+ Returns     : 1(success) or 0(failure)
+ Description : loads node with provided image
+
+=cut
+
+sub unload {
+	my $self = shift;
+	if (ref($self) !~ /one/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return 0;
+	}
+
+	my $computer_name = $self->data->get_computer_hostname();
+
+	my $one_computer_id = $self->_one_get_object_id("computer",$computer_name);
+	if ($one_computer_id) {
+		if(!$self->_one_delete_vm($one_computer_id)) {
+			return 0;
+		}
+	}
+
+		return 1;
+}
+	
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 provision
 
  Parameters  : hash

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm Tue Sep 23 19:09:53 2014
@@ -88,6 +88,45 @@ sub initialize {
 	return 1;
 } ## end sub initialize
 
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 unload
+
+ Parameters  : hash
+ Returns     : 1(success) or 0(failure)
+ Description : loads virtual machine with requested image
+
+=cut
+
+sub unload {
+	my $self = shift;
+	if (ref($self) !~ /openstack/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $computer_name = $self->data->get_computer_short_name() || return;
+	my $vmhost_name = $self->data->get_vmhost_short_name() || return;
+
+	# Remove existing VMs which were created for the reservation computer
+	if (_pingnode($computer_name)) {
+		if (!$self->_terminate_os_instance()) {
+			notify($ERRORS{'WARNING'}, 0, "failed to delete VM $computer_name on VM host $vmhost_name");
+			return 0;
+		}
+	}
+	# Remove existing openstack id for computer mapping in database 
+	# Althought the instance is not pingable (delete it accidently), it should delete the instance from database
+	if (!$self->_delete_os_computer_mapping()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to delete the openstack instance id from openstackComputerMap");
+		return 0;
+	}
+
+	return 1;
+
+}
+
 #/////////////////////////////////////////////////////////////////////////////
 
 =head2 provision

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT.pm Tue Sep 23 19:09:53 2014
@@ -144,6 +144,31 @@ sub initialize {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 unload
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Powers-off computer with the image defined in the reservation data.
+
+=cut
+
+sub unload {
+	my $self = shift;
+	if (ref($self) !~ /xCAT/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	if (!$self->power_off()) {
+		return 0;
+	}
+
+	return 1;
+
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 load
 
  Parameters  : none

Modified: vcl/trunk/managementnode/lib/VCL/new.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/new.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/new.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/new.pm Tue Sep 23 19:09:53 2014
@@ -159,20 +159,6 @@ sub process {
 		# Computer is not available, not a new request (most likely a simple reload)
 		notify($ERRORS{'WARNING'}, 0, "request state=$request_state_name, $computer_short_name is NOT available");
 		
-		# Set the computer next image so it gets loaded if/when other reservations are complete
-		if (!defined($computer_next_image_name) || $image_name ne $computer_next_image_name) {
-			notify($ERRORS{'OK'}, 0, "$computer_short_name is not available, setting computer next image to $image_name");
-			if (setnextimage($computer_id, $image_id)) {
-				notify($ERRORS{'OK'}, 0, "$computer_short_name next image set to $image_name");
-			}
-			else {
-				notify($ERRORS{'WARNING'}, 0, "failed to set $computer_short_name next image to $image_name");
-			}
-		}
-		else {
-			notify($ERRORS{'OK'}, 0, "$computer_short_name is not available, computer next image is already set to $image_name");
-		}
-		
 		# Update request state to complete
 		if (update_request_state($request_id, "complete", $request_state_name)) {
 			notify($ERRORS{'OK'}, 0, "request state updated to 'complete'/'$request_state_name'");
@@ -373,18 +359,6 @@ sub process {
 	# These steps are not done for simple reloads
 	notify($ERRORS{'OK'}, 0, "request_state_name= $request_state_name");
 	if ($request_state_name =~ /^(new|reinstall)/) {
-		# Set the computer next image to the one for this reservation
-		if (!defined($computer_next_image_name) || $image_name ne $computer_next_image_name) {
-			if (setnextimage($computer_id, $image_id)) {
-				notify($ERRORS{'OK'}, 0, "$computer_short_name next image set to $image_name");
-			}
-			else {
-				notify($ERRORS{'WARNING'}, 0, "failed to set $computer_short_name next image to $image_name");
-			}
-		}
-		else {
-			notify($ERRORS{'OK'}, 0, "$computer_short_name next image is already set to $image_name");
-		}
 		
 		if ($request_preload_only) {
 			# Return back to original states

Modified: vcl/trunk/managementnode/lib/VCL/reclaim.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/reclaim.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/reclaim.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/reclaim.pm Tue Sep 23 19:09:53 2014
@@ -232,34 +232,50 @@ sub insert_reload_and_exit {
 	}
 	
 	# Retrieve next image
-	my ($next_image_name, $next_image_id, $next_imagerevision_id) = $self->data->get_next_image_dataStructure();
-	if (!$next_image_name || !$next_image_id || !$next_imagerevision_id) {
-		notify($ERRORS{'WARNING'}, 0, "predictor module did not return required information, calling get_next_image_default from utils");
-		($next_image_name, $next_image_id, $next_imagerevision_id) = get_next_image_default($computer_id);
-	}
-
-	# Update the DataStructure object with the next image values
-	# These will be used by insert_reload_request()
-	$self->data->set_image_name($next_image_name);
-	$self->data->set_image_id($next_image_id);
-	$self->data->set_imagerevision_id($next_imagerevision_id);
-
-	notify($ERRORS{'OK'}, 0, "next image: $next_image_name, image id=$next_image_id, imagerevision id=$next_imagerevision_id");
-	
-	# Insert reload request data into the database
-	if (insert_reload_request($request_data)) {
-		notify($ERRORS{'OK'}, 0, "inserted reload request into database for computer id=$computer_id, image=$next_image_name");
+	my ($action, $next_image_name, $next_image_id, $next_imagerevision_id) = $self->data->get_next_image_dataStructure();
+
+	if($action =~ /unload/i) {
+		if($self->provisioner->can("unload")){
+			if($self->provisioner->unload()) {
+				if (update_computer_imagename($computer_id, 'noimage')) {
+					notify($ERRORS{'DEBUG'}, 0, "set computer $computer_shortname current image to 'noimage'");
+				}
+				
+				switch_state($request_data, 'complete', 'available', '', '1');
+			}
+		}
 
-		# Switch the request state to complete, the computer state to reload
-		switch_state($request_data, 'complete', 'reload', '', '1');
 	}
 	else {
-		notify($ERRORS{'CRITICAL'}, 0, "failed to insert reload request into database for computer id=$computer_id image=$next_image_name");
-
-		# Switch the request and computer states to failed
-		switch_state($request_data, 'failed', 'failed', '', '1');
+	#elsif( $action =~ /reload/i ){ 
+		if (!$next_image_name || !$next_image_id || !$next_imagerevision_id) {
+			notify($ERRORS{'WARNING'}, 0, "predictor module did not return required information, calling get_next_image_default from utils");
+			($next_image_name, $next_image_id, $next_imagerevision_id) = get_next_image_default($computer_id);
+		}
+
+		# Update the DataStructure object with the next image values
+		# These will be used by insert_reload_request()
+		$self->data->set_image_name($next_image_name);
+		$self->data->set_image_id($next_image_id);
+		$self->data->set_imagerevision_id($next_imagerevision_id);
+
+		notify($ERRORS{'OK'}, 0, "next image: $next_image_name, image id=$next_image_id, imagerevision id=$next_imagerevision_id");
+	
+		# Insert reload request data into the database
+		if (insert_reload_request($request_data)) {
+			notify($ERRORS{'OK'}, 0, "inserted reload request into database for computer id=$computer_id, image=$next_image_name");
+
+			# Switch the request state to complete, the computer state to reload
+			switch_state($request_data, 'complete', 'reload', '', '1');
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to insert reload request into database for computer id=$computer_id image=$next_image_name");
+
+			# Switch the request and computer states to failed
+			switch_state($request_data, 'failed', 'failed', '', '1');
+		}
 	}
-	
+
 	notify($ERRORS{'DEBUG'}, 0, "exiting");
 	exit;
 }

Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1627119&r1=1627118&r2=1627119&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Tue Sep 23 19:09:53 2014
@@ -4779,6 +4779,7 @@ sub update_currentimage {
 	 ";
 
 	if (defined($nextimagid) && ($nextimagid)) {
+		notify($ERRORS{'WARNING'}, 0, "*******NEXTIMAGE updating computer $computerid: image=$imageid, imagerevision=$imagerevisionid nextimageid = $imageid");
 		$update_statement = "
 			UPDATE
 			computer c, image i
@@ -6864,6 +6865,12 @@ sub get_computer_info {
 			$select_statement .= "$table.$column AS '$table-$column',\n";
 		}
 	}
+
+	# Add the column for predictive module info
+   my @columns = @{$database_table_columns->{module}};
+   for my $column (@columns) {
+         $select_statement .= "predictivemodule.$column AS 'predictivemodule-$column',\n";
+   }
 	
 	# Remove the comma after the last column line
 	$select_statement =~ s/,$//;
@@ -6884,6 +6891,7 @@ ON (
 	AND module.id = provisioning.moduleid
 )
 LEFT JOIN (schedule) ON (schedule.id = computer.scheduleid)
+LEFT JOIN (module AS predictivemodule) ON (predictivemodule.id = computer.predictivemoduleid)
 
 WHERE
 computer.deleted != '1'
@@ -6933,6 +6941,9 @@ EOF
 		elsif ($table eq 'module') {
 			$computer_info->{provisioning}{$table}{$column} = $value;
 		}
+		elsif ($table eq 'predictivemodule' ) {
+		   $computer_info->{predictive}{module}{$column} = $value;
+		}
 		else {
 			$computer_info->{$table}{$column} = $value;
 		}