You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2008/12/12 19:20:18 UTC

svn commit: r726079 [9/32] - in /incubator/vcl/tags/import: ./ managementnode/ managementnode/bin/ managementnode/etc/ managementnode/etc/vcl/ managementnode/legacy_vcl_vbs_scripts/ managementnode/lib/ managementnode/lib/VCL/ managementnode/lib/VCL/Mod...

Added: incubator/vcl/tags/import/managementnode/lib/VCL/Module/State.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/Module/State.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/Module/State.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/Module/State.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,511 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+##############################################################################
+# $Id: State.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Core::State - VCL state base module
+
+=head1 SYNOPSIS
+
+ use base qw(VCL::Module::State);
+
+=head1 DESCRIPTION
+
+ Needs to be written.
+
+=cut
+
+##############################################################################
+package VCL::Module::State;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../..";
+
+# Configure inheritance
+use base qw(VCL::Module);
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+use English '-no_match_vars';
+
+use VCL::utils;
+use VCL::DataStructure;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 initialize
+
+ Parameters  : Reference to current inuse object is automatically passed when
+               invoked as a class method.
+ Returns     : 1 if successful, 0 otherwise
+ Description : Prepares the delete object to process a reservation. Renames the
+               process.
+
+=cut
+
+sub initialize {
+	my $self = shift;
+	my ($package, $filename, $line, $sub) = caller(0);
+
+	# Initialize the database handle count
+	$ENV{dbh_count} = 0;
+
+	# Attempt to get a database handle
+	if ($ENV{dbh} = getnewdbh()) {
+		notify($ERRORS{'OK'}, 0, "obtained a database handle for this state process, stored as \$ENV{dbh}");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to obtain a database handle for this state process");
+	}
+
+	# Check the image OS before creating OS object
+	if (!$self->check_image_os()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to check if image OS is correct");
+		$self->reservation_failed();
+	}
+
+	# Store some hash variables into local variables
+	my $request_id                = $self->data->get_request_id();
+	my $reservation_id            = $self->data->get_reservation_id();
+	my $provisioning_perl_package = $self->data->get_computer_provisioning_module_perl_package();
+	my $os_perl_package           = $self->data->get_image_os_module_perl_package();
+	my $predictive_perl_package   = $self->data->get_management_node_predictive_module_perl_package();
+
+	# Store the name of this class in an environment variable
+	$ENV{class_name} = ref($self);
+
+	# Rename this process to include some request info
+	rename_vcld_process($self->data);
+
+	# Set the PARENTIMAGE and SUBIMAGE keys in the request data hash
+	# These are deprecated, DataStructure's is_parent_reservation function should be used
+	$self->data->get_request_data->{PARENTIMAGE} = ($self->data->is_parent_reservation() + 0);
+	$self->data->get_request_data->{SUBIMAGE}    = (!$self->data->is_parent_reservation() + 0);
+
+	# Set the parent PID and this process's PID in the hash
+	set_hash_process_id($self->data->get_request_data);
+
+	# Attempt to load the computer provisioning module
+	if ($provisioning_perl_package) {
+		notify($ERRORS{'OK'}, 0, "attempting to load provisioning module: $provisioning_perl_package");
+		eval "use $provisioning_perl_package";
+		if ($EVAL_ERROR) {
+			notify($ERRORS{'WARNING'}, 0, "$provisioning_perl_package module could not be loaded");
+			notify($ERRORS{'OK'},      0, "returning 0");
+			return 0;
+		}
+		notify($ERRORS{'OK'}, 0, "$provisioning_perl_package module successfully loaded");
+
+		# Create provisioner object
+		if (my $provisioner = ($provisioning_perl_package)->new({data_structure => $self->data})) {
+			notify($ERRORS{'OK'}, 0, ref($provisioner) . " provisioner object successfully created");
+			$self->{provisioner} = $provisioner;
+		}
+		else {
+			notify($ERRORS{'OK'}, 0, "provisioning object could not be created, returning 0");
+			return 0;
+		}
+	} ## end if ($provisioning_perl_package)
+	else {
+		notify($ERRORS{'OK'}, 0, "provisioning module not loaded, Perl package is not defined");
+	}
+
+	# Attempt to load the OS module
+	if ($os_perl_package) {
+		notify($ERRORS{'OK'}, 0, "attempting to load OS module: $os_perl_package");
+		eval "use $os_perl_package";
+		if ($EVAL_ERROR) {
+			notify($ERRORS{'WARNING'}, 0, "$os_perl_package module could not be loaded");
+			notify($ERRORS{'OK'},      0, "returning 0");
+			return 0;
+		}
+		if (my $os = ($os_perl_package)->new({data_structure => $self->data})) {
+			notify($ERRORS{'OK'}, 0, ref($os) . " OS object successfully created");
+			$self->{os} = $os;
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "OS object could not be created, returning 0");
+			return 0;
+		}
+	} ## end if ($os_perl_package)
+	else {
+		notify($ERRORS{'OK'}, 0, "OS module not loaded, Perl package is not defined");
+	}
+
+	# Attempt to load the predictive loading module
+	if ($predictive_perl_package) {
+		notify($ERRORS{'OK'}, 0, "attempting to load predictive loading module: $predictive_perl_package");
+		eval "use $predictive_perl_package";
+		if ($EVAL_ERROR) {
+			notify($ERRORS{'WARNING'}, 0, "$predictive_perl_package module could not be loaded");
+			notify($ERRORS{'OK'},      0, "returning 0");
+			return 0;
+		}
+		if (my $predictor = ($predictive_perl_package)->new({data_structure => $self->data})) {
+			notify($ERRORS{'OK'}, 0, ref($predictor) . " predictive loading object successfully created");
+			$self->{predictor} = $predictor;
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "predictive loading object could not be created, returning 0");
+			return 0;
+		}
+	} ## end if ($predictive_perl_package)
+	else {
+		notify($ERRORS{'OK'}, 0, "predictive loading module not loaded, Perl package is not defined");
+	}
+
+	notify($ERRORS{'OK'}, 0, "returning 1");
+	return 1;
+
+} ## end sub initialize
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 provisioner
+
+ Parameters  : None
+ Returns     : Object's provisioner object
+ Description : Returns this objects provisioner object, which is stored in
+               $self->{provisioner}.  This method allows it to accessed using
+					$self->provisioner.
+
+=cut
+
+sub provisioner {
+	my $self = shift;
+	return $self->{provisioner};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 os
+
+ Parameters  : None
+ Returns     : Object's OS object
+ Description : Returns this objects OS object, which is stored in
+               $self->{os}.  This method allows it to accessed using
+					$self->os.
+
+=cut
+
+sub os {
+	my $self = shift;
+	return $self->{os};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 predictor
+
+ Parameters  : None
+ Returns     : Object's predictive loading object
+ Description : Returns this objects predictive loading object, which is stored
+               in $self->{predictor}.  This method allows it to accessed using
+					$self->predictor.
+
+=cut
+
+sub predictor {
+	my $self = shift;
+	return $self->{predictor};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 reservation_failed
+
+ Parameters  : Message string
+ Returns     : Nothing, process exits
+ Description : Performs the steps required when a reservation fails:
+					-if request was deleted
+					   -sets computer state to available
+						-exits with status 0
+					
+					-inserts 'failed' computerloadlog table entry
+					-updates ending field in the log table to 'failed'
+					-updates the computer state to 'failed'
+					-updates the request state to 'failed', laststate to request's previous state
+					-removes computer from blockcomputers table if this is a block request
+               -exits with status 1
+
+=cut
+
+sub reservation_failed {
+	my $self = shift;
+	if (ref($self) !~ /VCL::/) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method, reservation failure tasks not attempted, process exiting");
+		exit 1;
+	}
+
+	# Check if a message was passed as an argument
+	my $message = shift;
+	if (!$message) {
+		$message = 'reservation failed';
+	}
+
+	# Get the required data
+	my $request_id             = $self->data->get_request_id();
+	my $request_logid          = $self->data->get_request_log_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 $request_state_name     = $self->data->get_request_state_name();
+	my $request_laststate_name = $self->data->get_request_laststate_name();
+
+	# Check if the request has been deleted
+	if (is_request_deleted($request_id)) {
+		notify($ERRORS{'OK'}, 0, "request has been deleted, setting computer state to available and exiting");
+
+		# Update the computer state to available
+		if (update_computer_state($computer_id, "available")) {
+			notify($ERRORS{'OK'}, 0, "$computer_short_name ($computer_id) state set to 'available'");
+		}
+		else {
+			notify($ERRORS{'OK'}, 0, "failed to set $computer_short_name ($computer_id) state to 'available'");
+		}
+
+		notify($ERRORS{'OK'}, 0, "exiting 0");
+		exit 0;
+	} ## end if (is_request_deleted($request_id))
+
+	# Display the message
+	notify($ERRORS{'CRITICAL'}, 0, "reservation failed on $computer_short_name: $message");
+
+	# Insert a row into the computerloadlog table
+	if (insertloadlog($reservation_id, $computer_id, "failed", $message)) {
+		notify($ERRORS{'OK'}, 0, "inserted computerloadlog entry");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to insert computerloadlog entry");
+	}
+
+	# Update log table ending column to failed for this request
+	if (update_log_ending($request_logid, "failed")) {
+		notify($ERRORS{'OK'}, 0, "updated log ending value to 'failed', logid=$request_logid");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to update log ending value to 'failed', logid=$request_logid");
+	}
+
+	# Update the computer state to failed
+	if (update_computer_state($computer_id, "failed")) {
+		notify($ERRORS{'OK'}, 0, "computer $computer_short_name ($computer_id) state set to failed");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to set computer $computer_short_name ($computer_id) state to failed");
+	}
+
+	# Update the request state to failed
+	if (update_request_state($request_id, "failed", $request_laststate_name)) {
+		notify($ERRORS{'OK'}, 0, "set request state to 'failed'/'$request_laststate_name'");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to set request to 'failed'/'$request_laststate_name'");
+	}
+
+	# Check if computer is part of a blockrequest, if so pull out of blockcomputers table
+	if (is_inblockrequest($computer_id)) {
+		notify($ERRORS{'OK'}, 0, "$computer_short_name in blockcomputers table");
+		if (clearfromblockrequest($computer_id)) {
+			notify($ERRORS{'OK'}, 0, "removed $computer_short_name from blockcomputers table");
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to remove $computer_short_name from blockcomputers table");
+		}
+	}
+	else {
+		notify($ERRORS{'OK'}, 0, "$computer_short_name is NOT in blockcomputers table");
+	}
+
+	notify($ERRORS{'OK'}, 0, "exiting 1");
+	exit 1;
+} ## end sub reservation_failed
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 check_image_os
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+
+sub check_image_os {
+	my $self               = shift;
+	my $request_state_name = $self->data->get_request_state_name();
+	my $image_id           = $self->data->get_image_id();
+	my $image_name         = $self->data->get_image_name();
+	my $image_os_name      = $self->data->get_image_os_name();
+	my $imagerevision_id   = $self->data->get_imagerevision_id();
+
+	# Only make corrections if state is image
+	if ($request_state_name ne 'image') {
+		notify($ERRORS{'OK'}, 0, "no corrections need to be made, not an imaging request, returning 1");
+		return 1;
+	}
+
+	my $image_os_name_new;
+	if ($image_os_name =~ /^(rh)el([0-9])/ || $image_os_name =~ /^rh(fc)([0-9])/) {
+		# Change rhelX --> rhXimage, rhfcX --> fcXimage
+		$image_os_name_new = "$1$2image";
+	}
+	else {
+		notify($ERRORS{'OK'}, 0, "no corrections need to be made to image OS: $image_os_name");
+		return 1;
+	}
+
+	# Change the image name
+	$image_name =~ /^[^-]+-(.*)/;
+	my $image_name_new = "$image_os_name_new-$1";
+
+	notify($ERRORS{'OK'}, 0, "Kickstart image OS needs to be changed: $image_os_name -> $image_os_name_new, image name: $image_name -> $image_name_new");
+
+	# Update the image table, change the OS for this image
+	my $sql_statement = "
+	UPDATE
+	OS,
+	image,
+	imagerevision
+	SET
+	image.OSid = OS.id,
+	image.name = \'$image_name_new\',
+	imagerevision.imagename = \'$image_name_new\'
+	WHERE
+	image.id = $image_id
+	AND imagerevision.id = $imagerevision_id
+	AND OS.name = \'$image_os_name_new\'
+	";
+
+	# Update the image and imagerevision tables
+	if (database_execute($sql_statement)) {
+		notify($ERRORS{'OK'}, 0, "image and imagerevision tables updated: $image_name -> $image_name_new");
+	}
+	else {
+		notify($ERRORS{'OK'}, 0, "failed to update image and imagerevision tables: $image_name -> $image_name_new, returning 0");
+		return 0;
+	}
+
+	if ($self->data->refresh()) {
+		notify($ERRORS{'OK'}, 0, "DataStructure refreshed after correcting image OS");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to update DataStructure updated correcting image OS, returning 0");
+		return 0;
+	}
+
+	notify($ERRORS{'OK'}, 0, "returning 1");
+	return 1;
+} ## end sub check_image_os
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 DESTROY
+
+ Parameters  : None
+ Returns     : Nothing
+ Description : Performs module cleanup actions:
+               -closes the database connection
+
+					If child classes of VCL::Module need to implement their own
+					DESTROY method, they should call this method	from their own
+					DESTROY method using:
+					$self->SUPER::DESTROY if $self->can("SUPER::DESTROY");
+
+=cut
+
+sub DESTROY {
+	my $self = shift;
+	my $reservation_id = $self->data->get_reservation_id();
+	
+	notify($ERRORS{'DEBUG'}, 0, "destructor called, ref(\$self)=" . ref($self));
+	
+	# Delete all computerloadlog rows with loadstatename = 'begin' for thie reservation
+	if (delete_computerloadlog_reservation($reservation_id, 'begin')) {
+		notify($ERRORS{'OK'}, 0, "removed computerloadlog rows with loadstate=begin for reservation");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to remove computerloadlog rows with loadstate=begin for reservation");
+	}
+
+	# 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}");
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "state process created unknown number of database handles, \$ENV{dbh_count} is undefined");
+	}
+
+	# Close the database handle
+	if (defined $ENV{dbh}) {
+		notify($ERRORS{'DEBUG'}, 0, "process has a database handle stored in \$ENV{dbh}, attempting disconnect");
+
+		if ($ENV{dbh}->disconnect) {
+			notify($ERRORS{'OK'}, 0, "\$ENV{dbh}: database disconnect successful");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "\$ENV{dbh}: database disconnect failed, " . DBI::errstr());
+		}
+	} ## end if (defined $ENV{dbh})
+	else {
+		notify($ERRORS{'OK'}, 0, "process does not have a database handle stored in \$ENV{dbh}");
+	}
+
+	# Check for an overridden destructor
+	$self->SUPER::DESTROY if $self->can("SUPER::DESTROY");
+} ## end sub DESTROY
+
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 BUGS and LIMITATIONS
+
+ There are no known bugs in this module.
+ Please report problems to the VCL team (vcl_help@ncsu.edu).
+
+=head1 AUTHOR
+
+ Aaron Peeler, aaron_peeler@ncsu.edu
+ Andy Kurth, andy_kurth@ncsu.edu
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+
+=cut

Added: incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/Logging.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/Logging.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/Logging.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/Logging.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,136 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+##############################################################################
+# $Id: Logging.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Module::Utils::Logging
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides...
+
+=cut
+
+##############################################################################
+package VCL::Module::Utils::Logging;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../..";
+
+# Configure inheritance
+use base qw();
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+require Exporter;
+our @ISA    = qw(Exporter);
+our @EXPORT = qw(
+  &log_info
+  &log_verbose
+  &log_warning
+  &log_critical
+);
+
+use VCL::utils qw(
+  %ERRORS
+  &notify
+);
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2  log_info
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub log_info {
+	my ($message, $data) = @_;
+	notify($ERRORS{'OK'}, 0, $message, $data);
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2  log_verbose
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub log_verbose {
+	my ($message, $data) = @_;
+	notify($ERRORS{'DEBUG'}, 0, $message, $data);
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2  log_warning
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub log_warning {
+	my ($message, $data) = @_;
+	notify($ERRORS{'WARNING'}, 0, $message, $data);
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2  log_critical
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub log_critical {
+	my ($message, $data) = @_;
+	notify($ERRORS{'CRITICAL'}, 0, $message, $data);
+}
+
+1;

Added: incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/SCP.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/SCP.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/SCP.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/SCP.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,222 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+##############################################################################
+# $Id: SCP.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Module::Utils::SCP
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides...
+
+=cut
+
+##############################################################################
+package VCL::Module::Utils::SCP;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../..";
+
+# Configure inheritance
+use base qw();
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+require Exporter;
+our @ISA    = qw(Exporter);
+our @EXPORT = qw(
+  &scp
+);
+
+use File::Basename;
+use VCL::Module::Utils::Logging;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 scp
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+
+sub scp {
+	my $options_hashref = shift;
+
+	my $options       = $options_hashref->{options};
+	my $cipher        = $options_hashref->{cipter};
+	my $ssh_config    = $options_hashref->{ssh_config};
+	my $identity_file = $options_hashref->{identity_file};
+	my $limit         = $options_hashref->{limit};
+	my $ssh_option    = $options_hashref->{ssh_option};
+	my $port          = $options_hashref->{port};
+	my $program       = $options_hashref->{program};
+
+	my $source_user = $options_hashref->{source_user};
+	my $source_host = $options_hashref->{source_host};
+	my $source_path = $options_hashref->{source_path};
+
+	my $destination_user = $options_hashref->{destination_user};
+	my $destination_host = $options_hashref->{destination_host};
+	my $destination_path = $options_hashref->{destination_path};
+
+	if (!$source_path || !$destination_host || !$destination_path) {
+		log_warning("missing at least 1 of the required parameters: source_path, destination_host, destination_path");
+		return 0;
+	}
+
+	# TODO: Add ssh path to config file and set global variable
+	# Locate the path to the scp binary
+	my @possible_scp_paths = ('scp.exe', 'scp', 'C:/cygwin/bin/scp.exe', 'D:/cygwin/bin/scp.exe', '/usr/bin/scp',);
+
+	my $scp_path;
+	for my $possible_scp_path (@possible_scp_paths) {
+		if (-x $possible_scp_path) {
+			$scp_path = $possible_scp_path;
+			last;
+		}
+	}
+	if (!$scp_path) {
+		log_warning("unable to locate the SCP executable");
+		return 0;
+	}
+
+	# Fix the options
+	$options = '' if !$options;
+
+	# -B, Selects batch mode (prevents asking for passwords or passphrases).
+	$options .= 'B' if ($options !~ /B/);
+
+	# -p, Preserves modification times, access times, and modes from the original file.
+	$options .= 'p' if ($options !~ /p/);
+
+	# -r, Recursively copy entire directories.
+	$options .= 'r' if ($options !~ /r/);
+
+	# Don't use -q, Disables the progress meter. Error messages are more descriptive without it
+	$options =~ s/q//g if ($options =~ /q/);
+
+	# Remove all dashes and spaces from the options string
+	$options =~ s/[-\s]//g;
+
+	# Replace 'x' with ' -x'
+	$options =~ s/(\w)/ -$1/gx;
+
+	# Remove leading space
+	$options =~ s/^\s//;
+
+	# Fix some things if pscp.exe is being used
+
+
+	# Set the default destination user
+	$destination_user = 'root' if !$destination_user;
+
+	# Set the default port
+	$port = '22' if !$port;
+
+	# Create a variable to store the entire SCP command
+	my $scp_command;
+
+	# Check if source path contains a colon (likely a Windows machine)
+	# SCP can't handle Windows-style paths like C:\...
+	# cd to the directory then run SCP on the local file name
+	if ($source_path =~ /:/) {
+		# Take the source path apart
+		my ($source_filename, $source_directory) = fileparse($source_path);
+
+		# Add the cd command to the beginning of the SCP command
+		# Use the /D switch to change drives if necessary
+		$scp_command .= "cd /D \"$source_directory\" && ";
+
+		# Change the source file path to the file name
+		$source_path = $source_filename;
+	} ## end if ($source_path =~ /:/)
+
+	# Assemble the SCP command
+	$scp_command .= "\"$scp_path\" ";
+	$scp_command .= "$options ";
+	$scp_command .= "-c $cipher " if $cipher;
+	$scp_command .= "-F \"$ssh_config\" " if $ssh_config;
+	$scp_command .= "-i \"$identity_file\" " if $identity_file;
+	$scp_command .= "-l $limit " if $limit;
+	$scp_command .= "-o $ssh_option " if $ssh_option;
+	$scp_command .= "-P $port ";
+	$scp_command .= "-S \"$program\" " if $program;
+	$scp_command .= "$source_user@" if $source_user;
+	$scp_command .= "$source_host:" if $source_host;
+	$scp_command .= "\"$source_path\" ";
+	$scp_command .= "$destination_user@";
+	$scp_command .= "$destination_host:";
+	$scp_command .= "\"$destination_path\" ";
+
+	# Redirect standard output and error output so all messages are captured
+	$scp_command .= ' 2>&1';
+
+	# Print the configuration if $VERBOSE
+	log_verbose("SCP command: $scp_command");
+
+	# Execute the command
+	my $scp_output = `$scp_command` || 'scp did not produce any output';
+
+	# Save the exit status
+	my $scp_exit_status = $?;
+
+	# Strip out the key warning message
+	$scp_output =~ s/\@{10,}.*man-in-the-middle attacks\.//igs;
+	chomp $scp_output;
+
+	# Check the exit status
+	# scp exits with 0 on success or >0 if an error occurred
+	if ($scp_exit_status <= 0) {
+		# Success
+		log_verbose("scp exit status: $scp_exit_status (success), output: $scp_output");
+		log_info("successfully copied files using scp");
+		return 1;
+	}
+	else {
+		# Failure
+		log_verbose("failed to copy files using scp, exit status: $scp_exit_status, output: $scp_output");
+		return 0;
+	}
+} ## end sub scp
+
+1;

Added: incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/SSH.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/SSH.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/SSH.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/Module/Utils/SSH.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,168 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+##############################################################################
+# $Id: SSH.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Module::Utils::SSH
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides...
+
+=cut
+
+##############################################################################
+package VCL::Module::Utils::SSH;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../..";
+
+# Configure inheritance
+use base qw();
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+require Exporter;
+our @ISA    = qw(Exporter);
+our @EXPORT = qw(
+  &ssh
+);
+
+use VCL::Module::Utils::Logging;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 ssh
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+
+sub ssh {
+	my ($node, $identity_path, $command, $user, $port) = @_;
+	my ($package, $filename, $line, $sub) = caller(0);
+
+	# Check the arguments
+	if (!defined($node) || !$node) {
+		log_warning("computer node was not specified");
+		return 0;
+	}
+	if (!defined($identity_path) || !$identity_path) {
+		log_warning("identity file path was not specified");
+		return 0;
+	}
+	if (!defined($command) || !$command) {
+		log_warning("command was not specified");
+		return 0;
+	}
+
+	# Set default values if not passed as an argument
+	$user = "root" if (!defined($user));
+	$port = 22     if (!defined($port));
+
+
+	# TODO: Add ssh path to config file and set global variable
+	# Locate the path to the ssh binary
+	my @possible_ssh_paths = ('ssh.exe', 'ssh', 'C:/cygwin/bin/ssh.exe', 'D:/cygwin/bin/ssh.exe', '/usr/bin/ssh',);
+
+	my $ssh_path;
+	for my $possible_ssh_path (@possible_ssh_paths) {
+		if (-x $possible_ssh_path) {
+			$ssh_path = $possible_ssh_path;
+			last;
+		}
+	}
+	if (!$ssh_path) {
+		log_warning("unable to locate the SSH executable");
+		return 0;
+	}
+
+	# Print the configuration if $VERBOSE
+	log_verbose("node: $node, identity file path: $identity_path, user: $user, port: $port caller info $package, $filename, $line, $sub");
+	log_verbose("command: $command");
+
+	# Assemble the SSH command
+	# -i <identity_file>, Selects the file from which the identity (private key) for RSA authentication is read.
+	# -l <login_name>, Specifies the user to log in as on the remote machine.
+	# -p <port>, Port to connect to on the remote host.
+	# -x, Disables X11 forwarding.
+	# Dont use: -q, Quiet mode.  Causes all warning and diagnostic messages to be suppressed.
+	my $ssh_command = "$ssh_path -i '$identity_path' -l $user -p $port -x $node \"$command\"";
+
+	# Redirect standard output and error output so all messages are captured
+	$ssh_command .= ' 2>&1';
+
+	# Print the command if $VERBOSE
+	log_verbose("ssh command: $ssh_command");
+
+	# Execute the command
+	my $ssh_output = `$ssh_command` || 'ssh did not produce any output';
+
+	# Save the exit status
+	# For some reason the ssh exit status is right-padded with 8 0's
+	# Shift right 8 bits to get the real value
+	my $ssh_exit_status = $? >> 8;
+
+	# Print the exit status and output if $VERBOSE
+	log_verbose("ssh exit status: $ssh_exit_status, output:\n$ssh_output");
+
+	# Check the exit status
+	# ssh exits with the exit status of the remote command or with 255 if an error occurred.
+	if ($ssh_exit_status == 255) {
+		log_warning("failed to execute ssh command, exit status: $ssh_exit_status, ssh exits with the exit status of the remote command or with 255 if an error occurred, output:\n$ssh_output");
+		return ();
+	}
+	elsif ($ssh_exit_status > 0) {
+		log_warning("most likely failed to execute ssh command, exit status: $ssh_exit_status, output:\n$ssh_output");
+		return ();
+	}
+
+	# Split the output up into an array of lines
+	my @output_lines = split(/\n/, $ssh_output);
+
+	# Return the exit status and output
+	return ($ssh_exit_status, \@output_lines);
+
+} ## end sub ssh
+
+1;

Added: incubator/vcl/tags/import/managementnode/lib/VCL/blockrequest.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/managementnode/lib/VCL/blockrequest.pm?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/managementnode/lib/VCL/blockrequest.pm (added)
+++ incubator/vcl/tags/import/managementnode/lib/VCL/blockrequest.pm Fri Dec 12 10:20:10 2008
@@ -0,0 +1,815 @@
+#!/usr/bin/perl -w
+
+# 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.
+
+##############################################################################
+# $Id: blockrequest.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::blockrequest
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides VCL support for...
+
+=cut
+
+##############################################################################
+package VCL::blockrequest;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/..";
+
+# Configure inheritance
+use base qw(VCL::Module::State);
+
+# Specify the version of this module
+our $VERSION = '2.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+use English '-no_match_vars';
+
+use VCL::utils;
+use DBI;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 initialize
+
+ Parameters  : Reference to current inuse object is automatically passed when
+               invoked as a class method.
+ Returns     : 1 if successful, 0 otherwise
+ Description : Prepares the delete object to process a reservation. Renames the
+               process.
+
+=cut
+
+sub initialize {
+	my $self                    = shift;
+
+	# Initialize the database handle count
+	$ENV{dbh_count} = 0;
+
+	# Attempt to get a database handle
+	if ($ENV{dbh} = getnewdbh()) {
+		notify($ERRORS{'OK'}, 0, "obtained a database handle for this state process, stored as \$ENV{dbh}");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to obtain a database handle for this state process");
+	}
+
+
+	# Store the name of this class in an environment variable
+	$ENV{class_name} = ref($self);
+
+	# Rename this process to include some request info
+	rename_vcld_process($self->data);
+
+	# Call the old _initialize subroutine
+	if (!$self->_initialize()) {
+		return 0;
+	}
+
+	notify($ERRORS{'OK'}, 0, "returning 1");
+	return 1;
+
+} ## end sub initialize
+
+=pod
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn function _initialize
+///
+/// \param hash data structure of the referenced object
+///
+/// \return
+///
+/// \brief  collects data based this modules goals, sets up data structure
+///
+////////////////////////////////////////////////////////////////////////////////
+=cut
+
+sub _initialize {
+	my $self    = shift;
+	my $request = $self->data->get_blockrequest_data();
+	my ($package, $filename, $line) = caller;
+
+	# Create a new database handler
+	my $dbh = getnewdbh();
+
+	# Retrieve data from the data structure
+	my $blockrequest_id              = $self->data->get_blockrequest_id();
+	my $blockrequest_mode            = $self->data->get_blockrequest_mode();
+	my $blockrequest_image_id        = $self->data->get_blockrequest_image_id();
+	my $blockrequest_number_machines = $self->data->get_blockrequest_number_machines();
+	my $blockrequest_expire          = $self->data->get_blockrequest_expire();
+	my $blocktime_id                 = $self->data->get_blocktime_id();
+	my $blocktime_processed          = $self->data->get_blocktime_processed();
+	my $blocktime_start              = $self->data->get_blocktime_start();
+	my $blocktime_end                = $self->data->get_blocktime_end();
+
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest id: $blockrequest_id");
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest mode: $blockrequest_mode");
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest image id: $blockrequest_image_id");
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest number machines: $blockrequest_number_machines");
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest expire: $blockrequest_expire");
+	notify($ERRORS{'DEBUG'}, 0, "blocktime id: $blocktime_id");
+	notify($ERRORS{'DEBUG'}, 0, "blocktime processed: $blocktime_processed");
+	notify($ERRORS{'DEBUG'}, 0, "blocktime start: $blocktime_start");
+	notify($ERRORS{'DEBUG'}, 0, "blocktime end: $blocktime_end");
+
+	sleep 2;
+
+	#record my process start time
+	$request->{"myprocessStart"} = convert_to_epoch_seconds();
+
+
+	# active db handle ?
+	if (!($dbh->ping)) {
+		notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+		$dbh = getnewdbh();
+		notify($ERRORS{'OK'},      0, "database handle re-est")     if ($dbh->ping);
+		notify($ERRORS{'WARNING'}, 0, "database handle NOT re-set") if (!($dbh->ping));
+	}
+
+	#get the production imagerevision
+	my $imageselh = $dbh->prepare(
+		"SELECT ir.imagename,ir.id
+                                              FROM imagerevision ir
+                                              WHERE ir.production = 1 AND ir.imageid = ?") or notify($ERRORS{'WARNING'}, 0, "block request Could not prepare selecting production image from imagerevision" . $dbh->errstr());
+
+	$imageselh->execute($blockrequest_image_id) or notify($ERRORS{'WARNING'}, 0, "block request Could not execute selecting production image from imagerevision " . $dbh->errstr());
+	my $imagerows = $imageselh->rows;
+	my @imagerow;
+	if ($imagerows != 0) {
+		@imagerow                     = $imageselh->fetchrow_array;
+		$request->{"imagename"}       = $imagerow[0];
+		$request->{"imagerevisionid"} = $imagerow[1];
+		notify($ERRORS{'OK'}, 0, "collected production imagename imagerevisionid @imagerow $blockrequest_image_id");
+	}
+	else {
+		#warning no data for imageid
+		notify($ERRORS{'CRITICAL'}, 0, "no data from imagerevision table $blockrequest_image_id");
+		#preform more steps to prevent looping
+		return 0;
+	}
+
+	if ($blockrequest_mode eq "start") {
+		# find all nodes that can load/run requested image including those under other management nodes
+		# collect resourceid for this imageid
+		my $selh = $dbh->prepare(
+			"SELECT r.id
+                                            FROM resource r, resourcetype rt
+                                            WHERE r.resourcetypeid = rt.id AND rt.name = ? AND r.subid = ?") or notify($ERRORS{'WARNING'}, 0, "block request Could not prepare select imageid resourceid" . $dbh->errstr());
+		$selh->execute("image", $blockrequest_image_id) or notify($ERRORS{'WARNING'}, 0, "block request Could not execute select imageid resourceid" . $dbh->errstr());
+		my $rows = $selh->rows;
+		my @row;
+		if ($rows != 0) {
+			@row = $selh->fetchrow_array;
+			$request->{"imageresourceid"} = $row[0];
+			notify($ERRORS{'OK'}, 0, "collected resourceid $row[0] for imageid $blockrequest_image_id");
+		}
+		else {
+			#warning no data for imageid
+			notify($ERRORS{'CRITICAL'}, 0, "no resource id associated with imageid $blockrequest_image_id");
+			#preform more steps to prevent looping
+			return 0;
+		}
+		# collect resource groups this image is a member of
+		$selh = $dbh->prepare(
+			"SELECT resourcegroupid
+                                          FROM resourcegroupmembers
+                                         WHERE resourceid = ?")                                           or notify($ERRORS{'WARNING'}, 0, "Could not prepare select resource group membership resourceid" . $dbh->errstr());
+		$selh->execute($request->{imageresourceid}) or notify($ERRORS{'WARNING'}, 0, "Could not execute select resource group membership resourceid" . $dbh->errstr());
+		$rows = $selh->rows;
+		if ($rows != 0) {
+			while (@row = $selh->fetchrow_array) {
+				push(@{$request->{resourcegroups}}, $row[0]);
+				notify($ERRORS{'OK'}, 0, "pushing image resource group $row[0] on list");
+			}
+			notify($ERRORS{'OK'}, 0, "complete list of image resource groups @{ $request->{resourcegroups} }");
+		}
+		else {
+			#warning no data for imageid
+			notify($ERRORS{'CRITICAL'}, 0, "image resource id $request->{imageresourceid} is not in any groups");
+			#preform more steps to prevent looping
+			return 0;
+		}
+
+		# active db handle ?
+		if (!($dbh->ping)) {
+			notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+			$dbh = getnewdbh();
+			notify($ERRORS{'OK'},      0, "database handle re-est")     if ($dbh->ping);
+			notify($ERRORS{'WARNING'}, 0, "database handle NOT re-set") if (!($dbh->ping));
+		}
+
+		#find mapping between image resource groups and computer groups
+		$selh = $dbh->prepare(
+			"SELECT r.resourcegroupid2,r.resourcetypeid2
+                                             FROM resourcemap r, resourcetype rt
+                                             WHERE r.resourcetypeid1 = rt.id AND rt.name = ? AND r.resourcegroupid1 = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare resource to computer group mapping" . $dbh->errstr());
+		foreach my $rgroupid (@{$request->{resourcegroups}}) {
+			notify($ERRORS{'OK'}, 0, "fetching list of groups mapped to image resource group $rgroupid");
+			$selh->execute("image", $rgroupid) or notify($ERRORS{'WARNING'}, 0, "Could not execute select resource group membership resourceid" . $dbh->errstr());
+			$rows = $selh->rows;
+			if ($rows != 0) {
+				while (@row = $selh->fetchrow_array) {
+					$request->{"computergroups"}->{$row[0]}->{"resourceid"}     = $row[0];
+					$request->{"computergroups"}->{$row[0]}->{"resourcetypeid"} = $row[1];
+					notify($ERRORS{'OK'}, 0, "computer group= $row[0] can run image grpid= $rgroupid");
+				}
+			}
+			else {
+				#warning no data for mapped resources on resourcegroupid
+				notify($ERRORS{'WARNING'}, 0, "no computer groups found for image resource groupid $rgroupid");
+				#preform more steps to prevent looping
+				#check next one
+
+			}
+		} ## end foreach my $rgroupid (@{$request->{resourcegroups...
+		    # active db handle ?
+		if (!($dbh->ping)) {
+			notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+			$dbh = getnewdbh();
+			notify($ERRORS{'OK'},      0, "database handle re-est")     if ($dbh->ping);
+			notify($ERRORS{'WARNING'}, 0, "database handle NOT re-set") if (!($dbh->ping));
+		}
+		#who(Management Node) can control these computer group(s)
+		$selh = $dbh->prepare(
+			"SELECT rg.resourceid
+                                          FROM resourcemap rm, resourcegroupmembers rg, resourcetype rt
+                                          WHERE rg.resourcegroupid = rm.resourcegroupid1 AND rm.resourcetypeid1 = rt.id AND rt.name = ? AND rm.resourcegroupid2 = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare managment node owner of computer group" . $dbh->errstr());
+		#seperating statement about management node information
+		my $selhmn = $dbh->prepare(
+			"SELECT r.subid,m.IPaddress,m.hostname,m.ownerid,s.name,m.lastcheckin
+                                                FROM resource r,managementnode m,resourcetype rt,state s
+                                              WHERE m.id = r.subid AND r.resourcetypeid = rt.id AND s.id = m.stateid AND rt.name = ? AND r.id = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare managment node info statement" . $dbh->errstr());
+
+		foreach my $computergrpid (keys %{$request->{computergroups}}) {
+			$selh->execute("managementnode", $computergrpid) or notify($ERRORS{'WARNING'}, 0, "Could not execute select resource group membership resourceid" . $dbh->errstr());
+			$rows = $selh->rows;
+			if ($rows != 0) {
+				while (@row = $selh->fetchrow_array) {
+					$request->{"computergroups"}->{$computergrpid}->{"controllingmnids"}->{$row[0]}->{"resourceid"} = $row[0];
+					notify($ERRORS{'OK'}, 0, "management node resourceid @row can control this computer grp $computergrpid");
+					$selhmn->execute("managementnode", $row[0]) or notify($ERRORS{'WARNING'}, 0, "Could not execute select management node info" . $dbh->errstr());
+					my $mrows = $selhmn->rows;
+					if ($mrows != 0) {
+						while (my @mrow = $selhmn->fetchrow_array) {
+							$request->{"computergroups"}->{$computergrpid}->{"controllingmnids"}->{$mrow[0]}->{"IPaddress"}        = $mrow[1];
+							$request->{"computergroups"}->{$computergrpid}->{"controllingmnids"}->{$mrow[0]}->{"hostname"}         = $mrow[2];
+							$request->{"computergroups"}->{$computergrpid}->{"controllingmnids"}->{$mrow[0]}->{"ownerid"}          = $mrow[3];
+							$request->{"computergroups"}->{$computergrpid}->{"controllingmnids"}->{$mrow[0]}->{"state"}            = $mrow[4];
+							$request->{"computergroups"}->{$computergrpid}->{"controllingmnids"}->{$mrow[0]}->{"lastcheckin"}      = $mrow[5];
+							$request->{"computergroups"}->{$computergrpid}->{"controllingmnids"}->{$mrow[0]}->{"managementnodeid"} = $mrow[0];
+							notify($ERRORS{'OK'}, 0, "management node $mrow[2] can control computergroup $computergrpid");
+						}
+					} ## end if ($mrows != 0)
+					else {
+						#warning no data for mapped resources on resourcegroupid
+						notify($ERRORS{'CRITICAL'}, 0, "no management nodes listed controlling computer groupid $row[0] skipping this group");
+						#preform more steps to prevent looping
+					}
+				} ## end while (@row = $selh->fetchrow_array)
+			} ## end if ($rows != 0)
+			else {
+				#warning no data for mapped resources on resourcegroupid
+				notify($ERRORS{'CRITICAL'}, 0, "no management nodes listed to control computer group id $computergrpid, attempting to remove from our local hash");
+				#preform more steps to prevent looping
+				#delete computergroupid from hash
+				delete($request->{computergroups}->{$computergrpid});
+				if (!(exists($request->{computergroups}->{$computergrpid}))) {
+					notify($ERRORS{'OK'}, 0, "SUCCESSFULLY removed problem computer groupid from list");
+				}
+			} ## end else [ if ($rows != 0)
+		} ## end foreach my $computergrpid (keys %{$request->{computergroups...
+		    # active db handle ?
+		if (!($dbh->ping)) {
+			notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+			$dbh = getnewdbh();
+			notify($ERRORS{'OK'},      0, "database handle re-est")     if ($dbh->ping);
+			notify($ERRORS{'WARNING'}, 0, "database handle NOT re-set") if (!($dbh->ping));
+		}
+		#collect computer members of associated computer groups
+		$selh = $dbh->prepare(
+			"SELECT c.id,c.hostname,c.IPaddress,s.name,c.currentimageid,c.type
+                                          FROM resourcetype rt, resource r,resourcegroupmembers rg,computer c,state s
+                                         WHERE s.id = c.stateid AND rg.resourceid = r.id AND r.subid = c.id AND r.resourcetypeid = rt.id AND rt.name = ? AND rg.resourcegroupid = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare statement collect members of related computer groups" . $dbh->errstr());
+
+		#collect list of computers already in the blockcomputers table for this start time
+		my $bcselh = $dbh->prepare(
+			"SELECT bc.computerid FROM blockComputers bc, blockTimes bt
+                                          WHERE bc.blockTimeid = bt.id AND bt.id != ? AND bt.start < ? AND bt.end > ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare statement collect members of related computer groups" . $dbh->errstr());
+		$bcselh->execute($blocktime_id, $blocktime_end, $blocktime_start) or notify($ERRORS{'WARNING'}, 0, "Could not execute blockcomputer lookup " . $dbh->errstr());
+		my $bcrows = $bcselh->rows;
+		if ($bcrows != 0) {
+			my @bclist;
+			while (@bclist = $bcselh->fetchrow_array) {
+				$request->{"blockcomputerslist"}->{$bclist[0]} = 1;
+			}
+		}
+
+		#collect OSname for image id
+		my $selhOS = $dbh->prepare(
+			"SELECT o.name FROM OS o,image i
+                                              WHERE i.id = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare statement for OS " . $dbh->errstr());
+		#sort through list of computers
+		foreach my $grpid (keys %{$request->{computergroups}}) {
+			$selh->execute("computer", $grpid) or notify($ERRORS{'WARNING'}, 0, "Could not execute select computer members of group ids" . $dbh->errstr());
+			$rows = $selh->rows;
+			if ($rows != 0) {
+				while (@row = $selh->fetchrow_array) {
+					$request->{"computergroups"}->{computercount}++;
+					$request->{"computergroups"}->{$grpid}->{"members"}->{$row[0]}->{"id"}        = $row[0];
+					$request->{"computergroups"}->{$grpid}->{"members"}->{$row[0]}->{"hostname"}  = $row[1];
+					$request->{"computergroups"}->{$grpid}->{"members"}->{$row[0]}->{"IPaddress"} = $row[2];
+					$request->{"computergroups"}->{$grpid}->{"members"}->{$row[0]}->{"state"}     = $row[3];
+					if (exists($request->{"blockcomputerslist"}->{$row[0]})) {
+						notify($ERRORS{'OK'}, 0, "computer id $row[0] hostname $row[1] is in another block reservation");
+						$row[3] = "inuse";
+						$request->{"computergroups"}->{$grpid}->{"members"}->{$row[0]}->{"state"} = $row[3];
+					}
+					if ($row[3] eq "available") {
+						notify($ERRORS{'OK'}, 0, "available machineid $row[0] hostname $row[1]");
+						$request->{"availablemachines"}->{$row[0]}->{"id"}             = $row[0];
+						$request->{"availablemachines"}->{$row[0]}->{"hostname"}       = $row[1];
+						$request->{"availablemachines"}->{$row[0]}->{"IPaddress"}      = $row[2];
+						$request->{"availablemachines"}->{$row[0]}->{"state"}          = $row[3];
+						$request->{"availablemachines"}->{$row[0]}->{"currentimageid"} = $row[4];
+						$request->{"availablemachines"}->{$row[0]}->{"type"}           = $row[5];
+						$request->{"availablemachines"}->{$row[0]}->{"shortname"}      = $1 if ($row[1] =~ /([-_a-zA-Z0-9]*)\./);
+						#which management node should handle this -- in case there are more than one
+						my $mncount = 0;
+						foreach my $mnid (keys %{$request->{computergroups}->{$grpid}->{controllingmnids}}) {
+							if ($request->{computergroups}->{$grpid}->{controllingmnids}->{$mnid}->{managementnodeid}) {
+								$mncount++;
+								notify($ERRORS{'OK'}, 0, "setting MN to $request->{computergroups}->{$grpid}->{controllingmnids}->{$mnid}->{managementnodeid} for computerid $row[0]");
+								$request->{"availablemachines"}->{$row[0]}->{"managementnodeid"} = $request->{computergroups}->{$grpid}->{controllingmnids}->{$mnid}->{managementnodeid};
+
+								if ($mncount > 1) {
+									#need to figure out which one has less load
+								}
+							}
+						} ## end foreach my $mnid (keys %{$request->{computergroups...
+
+						if ($row[4] eq $blockrequest_image_id) {
+							push(@{$request->{preloadedlist}}, $row[0]);
+							$request->{"availablemachines"}->{$row[0]}->{"preloaded"} = 1;
+						}
+						else {
+							$request->{"availablemachines"}->{$row[0]}->{"preloaded"} = 0;
+						}
+						if ($row[5] =~ /lab/) {
+							$selhOS->execute($row[4]) or notify($ERRORS{'WARNING'}, 0, "Could not execute statement to collect OS info" . $dbh->errstr());
+							my $OS;
+							my $dbretval = $selhOS->bind_columns(\($OS));
+							if ($selhOS->fetch) {
+								$request->{"availablemachines"}->{$row[0]}->{"OS"} = $OS;
+							}
+						}
+					} ## end if ($row[3] eq "available")
+				} ## end while (@row = $selh->fetchrow_array)
+			} ## end if ($rows != 0)
+			else {
+				notify($ERRORS{'WARNING'}, 0, "possible empty group for groupid $grpid");
+			}
+		} ## end foreach my $grpid (keys %{$request->{computergroups...
+		    #collect id for reload state and vclreload user
+		$selh = $dbh->prepare("SELECT s.id,u.id FROM state s,user u WHERE s.name= ? AND u.unityid=?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare statement to find reload state" . $dbh->errstr());
+		$selh->execute("reload", "vclreload") or notify($ERRORS{'WARNING'}, 0, "Could not execute reload stateid fetch" . $dbh->errstr());
+		$rows = $selh->rows;
+		if ($rows != 0) {
+			if (@row = $selh->fetchrow_array) {
+				$request->{"reloadstateid"} = $row[0];
+				$request->{"vclreloaduid"}  = $row[1];
+			}
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "reload state id or vclreload user id not found");
+		}
+	} ## end if ($blockrequest_mode eq "start")
+	elsif ($blockrequest_mode eq "end") {
+		#collect machines assigned for this blockRequest
+		my $selhandle = $dbh->prepare("SELECT computerid FROM blockComputers WHERE blockTimeid = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare statement to collect computerids under blockTimesid" . $dbh->errstr());
+		$selhandle->execute($blocktime_id);
+		if (!$dbh->err) {
+			notify($ERRORS{'OK'}, 0, "collected computer ids for block time $blocktime_id");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "could not execute statement collect computerid under blockTimesid" . $dbh->errstr());
+		}
+
+		my $rows = $selhandle->rows;
+		if (!$rows == 0) {
+			while (my @row = $selhandle->fetchrow_array) {
+				$request->{"blockComputers"}->{$row[0]}->{"id"} = $row[0];
+			}
+		}
+		else {
+			#strange -- no machines
+			notify($ERRORS{'WARNING'}, 0, "mode= $blockrequest_mode no machines found for blockRequest $blockrequest_id blockTimesid $blocktime_id in blockTimes table");
+		}
+	} ## end elsif ($blockrequest_mode eq "end")  [ if ($blockrequest_mode eq "start")
+	elsif ($blockrequest_mode eq "expire") {
+		#just remove request entry from table
+
+	}
+	else {
+		#mode not set or mode
+		notify($ERRORS{'CRITICAL'}, 0, "mode not determined mode= $blockrequest_mode");
+	}
+
+	return 1;
+} ## end sub _initialize
+
+=pod
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn sub process
+///
+/// \param  hash
+///
+/// \return  1, 0
+///
+/// \brief start mode:
+///         sorts through list of computers, pull out machines that are not
+///         available or are inuse or already scheduled to be used
+///         based on the number of machines needed put machines into blockcomputers
+///         table and insert reload requests
+///        end mode:
+///         remove machines from blockComputers table for block request id X
+///         reload ?
+///        expire mode:
+///         delete entries related to blockRequest
+///
+////////////////////////////////////////////////////////////////////////////////
+=cut
+
+sub process {
+	my $self    = shift;
+	my $request = $self->data->get_blockrequest_data();
+	my ($package, $filename, $line) = caller;
+
+	# Create a new database handler
+	my $dbh = getnewdbh();
+
+	# Retrieve data from the data structure
+	my $blockrequest_id              = $self->data->get_blockrequest_id();
+	my $blockrequest_mode            = $self->data->get_blockrequest_mode();
+	my $blockrequest_image_id        = $self->data->get_blockrequest_image_id();
+	my $blockrequest_number_machines = $self->data->get_blockrequest_number_machines();
+	my $blockrequest_expire          = $self->data->get_blockrequest_expire();
+	my $blocktime_id                 = $self->data->get_blocktime_id();
+	my $blocktime_processed          = $self->data->get_blocktime_processed();
+	my $blocktime_start              = $self->data->get_blocktime_start();
+	my $blocktime_end                = $self->data->get_blocktime_end();
+
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest id: $blockrequest_id");
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest mode: $blockrequest_mode");
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest image id: $blockrequest_image_id");
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest number machines: $blockrequest_number_machines");
+	notify($ERRORS{'DEBUG'}, 0, "blockrequest expire: $blockrequest_expire");
+	notify($ERRORS{'DEBUG'}, 0, "blocktime id: $blocktime_id");
+	notify($ERRORS{'DEBUG'}, 0, "blocktime processed: $blocktime_processed");
+	notify($ERRORS{'DEBUG'}, 0, "blocktime start: $blocktime_start");
+	notify($ERRORS{'DEBUG'}, 0, "blocktime end: $blocktime_end");
+
+	if ($blockrequest_mode eq "start") {
+		#confirm preloaded list
+		if ($blocktime_processed) {
+
+			notify($ERRORS{'WARNING'}, 0, "id $blockrequest_id has already been processed, pausing 60 seconds before reseting the processing flag");
+			##remove processing flag
+			sleep 60;
+			my $updatehdle = $dbh->prepare("UPDATE blockRequest SET processing = ? WHERE id = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare update processing statement for end mode" . $dbh->errstr());
+			$updatehdle->execute(0, $blockrequest_id) or notify($ERRORS{'WARNING'}, 0, "Could not execute update processing statement for end mode" . $dbh->errstr());
+			notify($ERRORS{'OK'}, 0, "removed processing flag from blockrequest id $blockrequest_id");
+			return 1;
+		} ## end if ($blocktime_processed)
+		$request->{"availmachinecount"} = 0;
+		# active db handle ?
+		if (!($dbh->ping)) {
+			notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+			$dbh = getnewdbh();
+			notify($ERRORS{'OK'},      0, "database handle re-est")     if ($dbh->ping);
+			notify($ERRORS{'WARNING'}, 0, "database handle NOT re-set") if (!($dbh->ping));
+		}
+
+		my $selh = $dbh->prepare(
+			"SELECT r.id,r.start,r.end,s.name
+                                            FROM request r, reservation rs, state s
+                                            WHERE r.stateid = s.id AND rs.computerid = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare statement for furture reservations checks of computer id " . $dbh->errstr());
+		#sort hash based on preloaded flag
+		foreach my $computerid (sort {$request->{availablemachines}->{$b}->{preloaded} eq '1'} keys %{$request->{availablemachines}}) {
+			#confirm status of available machines
+			notify($ERRORS{'OK'}, 0, "$computerid preload flag= $request->{availablemachines}->{$computerid}->{preloaded}");
+
+			#can only check the machines under this MN control
+			$request->{availablemachines}->{$computerid}->{"ok"} = 0;
+			my @status;
+			if ($request->{availablemachines}->{$computerid}->{type} =~ /blade/) {
+				$request->{availablemachines}->{$computerid}->{"on"} = 1;
+			}
+			elsif ($request->{availablemachines}->{$computerid}->{type} =~ /lab/) {
+				@status = virtual_status_unix($request->{availablemachines}->{$computerid}->{hostname}, $request->{availablemachines}->{$computerid}->{OS}, "linux", $request->{availablemachines}->{$computerid}->{IPaddress});
+				if ($status[2]) {
+					$request->{availablemachines}->{$computerid}->{"on"} = 1;
+				}
+			}
+			elsif ($request->{availablemachines}->{$computerid}->{type} =~ /virtualmachine/) {
+				$request->{availablemachines}->{$computerid}->{"on"} = 1;
+			}
+			notify($ERRORS{'OK'}, 0, "checking for future reservations for computerid $computerid");
+			#check for future reservations
+			$selh->execute($computerid) or notify($ERRORS{'WARNING'}, 0, "Could not execute statement for furture reservations checks of computer id $computerid" . $dbh->errstr());
+			my $rows = $selh->rows;
+			if (!$rows == 0) {
+				my @row = $selh->fetchrow_array;
+				#does blockrequest end time end before this reservations start time
+				if ($row[3] =~ /new/) {
+					my $furture_start = convert_to_epoch_seconds($row[1]);
+					my $BRend         = convert_to_epoch_seconds($blocktime_end);
+					#is start greater than end by at least 35 minutes -- to be safe?
+					if ((($furture_start - (35 * 60)) > $BRend)) {
+						#this one is ok
+						$request->{availablemachines}->{$computerid}->{"ok"} = 1;
+						notify($ERRORS{'OK'}, 0, "setting ok flag for computerid $computerid");
+					}
+					else {
+						notify($ERRORS{'OK'}, 0, "$computerid not ok to use deleting from hash");
+						my $d = ($furture_start - (35 * 60));
+						notify($ERRORS{'OK'}, 0, "furture_start $furture_start : BRend $BRend : delta $d");
+						#skip and remove from our list
+						#my $a = delete($request->{availablemachines}->{$computerid});
+						#next;
+						$request->{availablemachines}->{$computerid}->{"ok"} = 0;
+					}
+				} ## end if ($row[3] =~ /new/)
+				else {
+					$request->{availablemachines}->{$computerid}->{"ok"} = 0;
+					notify($ERRORS{'OK'}, 0, "NOT setting ok flag for computerid $computerid : listed in request $row[0] with state $row[3]");
+				}
+			} ## end if (!$rows == 0)
+			else {
+				#nothing scheduled for this computer id
+				$request->{availablemachines}->{$computerid}->{"ok"} = 1;
+				notify($ERRORS{'OK'}, 0, " setting ok flag for computerid $computerid");
+			}
+
+			if ($request->{availablemachines}->{$computerid}->{on} && $request->{availablemachines}->{$computerid}->{ok}) {
+				# add to our master list
+				$request->{"masterlist"}->{$computerid}->{"id"}              = $computerid;
+				$request->{"masterlist"}->{$computerid}->{"controllingMNid"} = $request->{availablemachines}->{$computerid}->{managementnodeid};
+				#increment our count
+				$request->{availmachinecount}++;
+			}
+
+			if ($request->{availmachinecount} > $blockrequest_number_machines) {
+				#should end up with one extra machine
+				last;
+			}
+
+		} ## end foreach my $computerid (sort {$request->{availablemachines...
+
+		#insert machines into Block computers
+		# insert reload request for machine
+		#one sanity check
+		if (!$request->{availmachinecount}) {
+			#nothing  -- not good, complain
+			notify($ERRORS{'CRITICAL'}, 0, "no machines where found or allocated for block request $blockrequest_id");
+
+		}
+		if ($request->{availmachinecount} >= $blockrequest_number_machines) {
+			#good they can get what they requested
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "Could not allocate number of requested machines for block request id $blockrequest_id . Only $request->{availmachinecount} are available, will give them those.");
+		}
+		# active db handle ?
+		if (!($dbh->ping)) {
+			notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+			$dbh = getnewdbh();
+			notify($ERRORS{'OK'},      0, "database handle re-est")     if ($dbh->ping);
+			notify($ERRORS{'WARNING'}, 0, "database handle NOT re-set") if (!($dbh->ping));
+		}
+		my $insertBC = $dbh->prepare("INSERT INTO blockComputers (blockTimeid,computerid) VALUES(?,?)") or notify($ERRORS{'WARNING'}, 0, "Could not prepare INSERT of blockcomputer table for start mode" . $dbh->errstr());
+
+		my $insertlog = $dbh->prepare("INSERT INTO log (userid,start,initialend,wasavailable,computerid,imageid) VALUES(?,?,?,?,?,?)") or notify($ERRORS{'WARNING'}, 0, "Could not prepare INSERT log entry " . $dbh->errstr());
+		my $lastinsertid;
+		my $insertsublog = $dbh->prepare("INSERT INTO sublog (logid,imageid,computerid) VALUES(?,?,?)") or notify($ERRORS{'WARNING'}, 0, "Could not prepare INSERT of sublog for reload mode" . $dbh->errstr());
+
+		my $insertrequest     = $dbh->prepare("INSERT INTO request (stateid,userid,laststateid,logid,start,end,daterequested) VALUES(?,?,?,?,?,?,?)")       or notify($ERRORS{'WARNING'}, 0, "Could not prepare INSERT of request for reload mode" . $dbh->errstr());
+		my $insertreservation = $dbh->prepare("INSERT INTO reservation (requestid,computerid,imageid,imagerevisionid,managementnodeid) VALUES (?,?,?,?,?)") or notify($ERRORS{'WARNING'}, 0, "Could not prepare INSERT of reservation for reload mode" . $dbh->errstr());
+
+
+		# $request->masterlist should contain a list of machines we can allocate
+		notify($ERRORS{'OK'}, 0, "number of available machines= $request->{availmachinecount}");
+
+		#do this in two or more loops
+		foreach my $computerid (keys %{$request->{masterlist}}) {
+			$insertBC->execute($blocktime_id, $request->{masterlist}->{$computerid}->{id}) or notify($ERRORS{'WARNING'}, 0, "Could not execute blockcomputers INSERT statement for computerid $computerid under blockrequest id $blockrequest_id" . $dbh->errstr());
+			notify($ERRORS{'OK'}, 0, "Inserted computerid $computerid blockTimesid $blocktime_id into blockcomputers table for block request $blockrequest_id");
+		}
+
+		foreach my $compid (keys %{$request->{masterlist}}) {
+			# set start to be 35 minutes prior to start time
+			# convert to epoch time
+			my $starttimeepoch = convert_to_epoch_seconds($blocktime_start);
+			#subtract 35 minutes from start time
+			$starttimeepoch = ($starttimeepoch - (35 * 60));
+			#convert back to datetime
+			my $starttime = convert_to_datetime($starttimeepoch);
+			#set to nearest 15 minute mark
+			my $start = timefloor15interval($starttime);
+			#set end time
+			my $Eend = ($starttimeepoch + (15 * 60));
+			my $end = convert_to_datetime($Eend);
+			notify($ERRORS{'OK'}, 0, "blockstart= $blocktime_start reloadstart= $start reloadend= $end");
+			#insert into log and sublog
+			$insertlog->execute($request->{vclreloaduid}, $start, $end, 1, $compid, $blockrequest_image_id) or notify($ERRORS{'WARNING'}, 0, "Could not execute log entry" . $dbh->errstr());
+			#get last insertid
+			$lastinsertid = $dbh->{'mysql_insertid'};
+			notify($ERRORS{'OK'}, 0, "lastinsertid for log entry is $lastinsertid");
+			$request->{masterlist}->{$compid}->{"logid"} = $lastinsertid;
+			#insert sublog entry
+			$insertsublog->execute($lastinsertid, $blockrequest_image_id, $request->{masterlist}->{$compid}->{id}) or notify($ERRORS{'WARNING'}, 0, "Could not execute sublog entry" . $dbh->errstr());
+			$lastinsertid = 0;
+			#insert reload request
+			$insertrequest->execute($request->{reloadstateid}, $request->{vclreloaduid}, $request->{reloadstateid}, $request->{masterlist}->{$compid}->{logid}, $start, $end, $start) or notify($ERRORS{'WARNING'}, 0, "Could not prepare INSERT of request for reload mode" . $dbh->errstr());
+			#fetch request insert id
+			$lastinsertid = $dbh->{'mysql_insertid'};
+			notify($ERRORS{'OK'}, 0, "lastinsertid for request entry is $lastinsertid");
+			$request->{masterlist}->{$compid}->{"requestid"} = $lastinsertid;
+			#insert reservation
+			$insertreservation->execute($lastinsertid, $request->{masterlist}->{$compid}->{id}, $blockrequest_image_id, $request->{imagerevisionid}, $request->{masterlist}->{$compid}->{controllingMNid}) or notify($ERRORS{'WARNING'}, 0, "Could not execute reservation entry" . $dbh->errstr());
+		} ## end foreach my $compid (keys %{$request->{masterlist...
+
+		#update processed flag for request
+		my $updatetimes = $dbh->prepare("UPDATE blockTimes SET processed=? WHERE id =?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare INSERT of blockcomputer table for start mode " . $dbh->errstr());
+		$updatetimes->execute(1, $blocktime_id) or notify($ERRORS{'WARNING'}, 0, "could not execute update processing flag on blockRequest id $blockrequest_id " . $dbh->errstr());
+
+
+		#pause
+		if (pauseprocessing($request->{myprocessStart})) {
+			notify($ERRORS{'OK'}, 0, "past check window for this request, -- ok to proceed");
+		}
+		# active db handle ?
+		if (!($dbh->ping)) {
+			notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+			$dbh = getnewdbh();
+			notify($ERRORS{'OK'},      0, "database handle re-est")     if ($dbh->ping);
+			notify($ERRORS{'WARNING'}, 0, "database handle NOT re-set") if (!($dbh->ping));
+		}
+
+		#remove processing flag
+		my $update = $dbh->prepare("UPDATE blockRequest SET processing = ? WHERE id = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare INSERT of blockcomputer table for start mode " . $dbh->errstr());
+		$update->execute(0, $blockrequest_id);
+		if (!$dbh->errstr()) {
+			notify($ERRORS{'OK'}, 0, "updated processing flag on blockRequest $blockrequest_id to 0");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to update processing flag on blockRequest $blockrequest_id to 0: " . $dbh->errstr());
+		}
+
+	} ## end if ($blockrequest_mode eq "start")
+	elsif ($blockrequest_mode eq "end") {
+		# active db handle ?
+		if (!($dbh->ping)) {
+			notify($ERRORS{'WARNING'}, 0, "database handle died, trying to create another one");
+			$dbh = getnewdbh();
+			notify($ERRORS{'OK'},      0, "database handle re-est")     if ($dbh->ping);
+			notify($ERRORS{'WARNING'}, 0, "database handle NOT re-set") if (!($dbh->ping));
+		}
+
+		# remove blockTime entry for this request
+		#
+		my $delhandle = $dbh->prepare("DELETE blockTimes FROM blockTimes WHERE id = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare DELETE blockTimes under id $blockrequest_id" . $dbh->errstr());
+		$delhandle->execute($blocktime_id) or notify($ERRORS{'WARNING'}, 0, "Could not prepare DELETE blockcomputers under id $blockrequest_id" . $dbh->errstr());
+		notify($ERRORS{'OK'}, 0, "removed blockTimes id $blocktime_id from blockTimes table");
+
+		$delhandle = $dbh->prepare("DELETE blockComputers FROM blockComputers WHERE blockTimeid = ? AND computerid = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare DELETE blockcomputers under id $blockrequest_id" . $dbh->errstr());
+		# remove each computer in order to reload blades
+		foreach my $computerid (keys %{$request->{"blockComputers"}}) {
+			#remove machines from blockComputers table for block request id X
+			$delhandle->execute($blocktime_id, $request->{blockComputers}->{$computerid}->{id}) or notify($ERRORS{'WARNING'}, 0, "Could not prepare DELETE blockcomputers under id $blockrequest_id" . $dbh->errstr());
+			notify($ERRORS{'OK'}, 0, "removed block computerid $computerid from blockComputers table for blockTimeid $blocktime_id");
+
+			#reload blades
+			#call get next image -- placeholder
+
+		}
+		#check expire time also, if this was the last blockTimes entry then this is likely the expiration time as well
+		my $status = check_blockrequest_time($blocktime_start, $blocktime_end, $blockrequest_expire);
+		if ($status eq "expire") {
+			#fork start processing
+			notify($ERRORS{'OK'}, 0, "this is expire time also");
+			#just remove blockRequest entry from BlockRequest table
+			my $delhandle = $dbh->prepare("DELETE blockRequest FROM blockRequest WHERE id = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare DELETE blockRequest id $blockrequest_id " . $dbh->errstr());
+			$delhandle->execute($blockrequest_id) or notify($ERRORS{'WARNING'}, 0, "Could not execute DELETE blcokRequest id $blockrequest_id " . $dbh->errstr());
+			notify($ERRORS{'OK'}, 0, "blockRequest id $blockrequest_id has expired and was removed from the database");
+			return 1;
+		}
+
+		##remove processing flag
+		my $updatehdle = $dbh->prepare("UPDATE blockRequest SET processing = ? WHERE id = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare update processing statement for end mode" . $dbh->errstr());
+		$updatehdle->execute(0, $blockrequest_id) or notify($ERRORS{'WARNING'}, 0, "Could not execute update processing statement for end mode" . $dbh->errstr());
+		notify($ERRORS{'OK'}, 0, "removed processing flag from blockrequest id $blockrequest_id");
+
+	} ## end elsif ($blockrequest_mode eq "end")  [ if ($blockrequest_mode eq "start")
+	elsif ($blockrequest_mode eq "expire") {
+		#there should not be any blockTimes entries for this request
+		#just remove blockRequest entry from BlockRequest table
+		my $delhandle = $dbh->prepare("DELETE blockRequest FROM blockRequest WHERE id = ?") or notify($ERRORS{'WARNING'}, 0, "Could not prepare DELETE blockRequest id $blockrequest_id " . $dbh->errstr());
+		$delhandle->execute($blockrequest_id) or notify($ERRORS{'WARNING'}, 0, "Could not execute DELETE blcokRequest id $blockrequest_id " . $dbh->errstr());
+		notify($ERRORS{'OK'}, 0, "blockRequest id $blockrequest_id has expired and was removed from the database");
+		return 1;
+	}
+	else {
+		#should not of hit this
+		notify($ERRORS{'CRITICAL'}, 0, "mode not determined mode= $blockrequest_mode");
+	}
+	return 1;
+
+} ## end sub process
+
+=pod
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn sub pauseprocessing
+///
+/// \param  process start time
+///
+/// \return  1, 0
+///
+/// \brief rest until our window for checking request has closed
+///
+////////////////////////////////////////////////////////////////////////////////
+=cut
+
+sub pauseprocessing {
+	my $myStartTime = shift;
+	# set timer to 8 minutes
+	my $wait_minutes = (8 * 60);
+	my $delta        = (convert_to_epoch_seconds() - $myStartTime);
+	while ($delta < $wait_minutes) {
+		#continue to loop
+		notify($ERRORS{'OK'}, 0, "going to sleep for 30 seconds, delta=$delta (until delta >= $wait_minutes)");
+		sleep 30;
+		$delta = (convert_to_epoch_seconds() - $myStartTime);
+	}
+	return 1;
+} ## end sub pauseprocessing
+#/////////////////////////////////////////////////////////////////////////////
+
+1;
+__END__
+
+=head1 BUGS and LIMITATIONS
+
+ There are no known bugs in this module.
+ Please report problems to the VCL team (vcl_help@ncsu.edu).
+
+=head1 AUTHOR
+
+ Aaron Peeler, aaron_peeler@ncsu.edu
+ Andy Kurth, andy_kurth@ncsu.edu
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+=cut
+
+