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
+ ¬ify
+);
+
+##############################################################################
+
+=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
+
+