Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm?rev=1798487&r1=1798486&r2=1798487&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm Mon Jun 
12 16:33:35 2017
@@ -1,1417 +1,1417 @@
-#!/usr/bin/perl -w
-###############################################################################
-# $Id: openstack.pm 
-###############################################################################
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-###############################################################################
-
-=head1 NAME
-
-VCL::Provisioning::openstack - VCL module to support the Openstack 
provisioning engine with REST APIs v2
-
-=head1 SYNOPSIS
-
- Needs to be written
-
-=head1 DESCRIPTION
-
-This module provides VCL support for Openstack
-
-=cut
-
-###############################################################################
-package VCL::Module::Provisioning::openstack;
-
-# Include File Copying for Perl
-use File::Copy;
-
-# Specify the lib path using FindBin
-use FindBin;
-use lib "$FindBin::Bin/../../..";
-
-# Configure inheritance
-use base qw(VCL::Module::Provisioning);
-
-# Specify the version of this module
-our $VERSION = '2.4.2';
-
-# Specify the version of Perl to use
-use 5.008000;
-
-use strict;
-use warnings;
-use diagnostics;
-use English qw(-no_match_vars);
-use IO::File;
-use Fcntl qw(:DEFAULT :flock);
-use File::Temp qw(tempfile);
-use List::Util qw(max);
-use VCL::utils;
-use JSON qw(from_json to_json);
-use LWP::UserAgent;
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 initialize
-
- Parameters  :
- Returns     :
- Description :
-
-=cut
-
-sub initialize {
-       my $self = shift;
-       notify($ERRORS{'DEBUG'}, 0, "OpenStack module initialized");
-       
-       if ($self->_set_os_auth_conf()) {
-               notify($ERRORS{'OK'}, 0, "successfully set openStack auth 
configuration");
-       }
-       else {
-               notify($ERRORS{'WARNING'}, 0, "failed to set openstack auth 
configuration");
-               return 0;
-       }
-       
-       return 1;
-} ## end sub initialize
-
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 unload
-
- Parameters  : hash
- Returns     : 1(success) or 0(failure)
- Description : loads virtual machine with requested image
-
-=cut
-
-sub unload {
-       my $self = shift;
-       if (ref($self) !~ /openstack/i) {
-               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
-               return;
-       }
-
-       my $computer_name = $self->data->get_computer_short_name() || return;
-       my $vmhost_name = $self->data->get_vmhost_short_name() || return;
-       my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address();
-
-       # Remove existing VMs which were created for the reservation computer
-       if (_pingnode($computer_private_ip_address)) {
-               if (!$self->_terminate_os_instance()) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to delete VM 
$computer_name on VM host $vmhost_name");
-                       return 0;
-               }
-       }
-       # Remove existing openstack id for computer mapping in database 
-       # Althought the instance is not pingable (delete it accidently), it 
should delete the instance from database
-       if (!$self->_delete_os_computer_mapping()) {
-               notify($ERRORS{'WARNING'}, 0, "failed to delete the openstack 
instance id from openstackcomputermap");
-               return 0;
-       }
-
-       return 1;
-
-}
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 provision
-
- Parameters  : hash
- Returns     : 1(success) or 0(failure)
- Description : loads virtual machine with requested image
-
-=cut
-
-sub load {
-       my $self = shift;
-       if (ref($self) !~ /openstack/i) {
-               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
-               return;
-       }
-
-       my $reservation_id = $self->data->get_reservation_id() || return;
-       my $computer_id = $self->data->get_computer_id() || return;
-       my $computer_name = $self->data->get_computer_short_name() || return;
-       my $image_name = $self->data->get_image_name() || return;
-       my $vmhost_name = $self->data->get_vmhost_short_name() || return;
-       my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address() || return;
-
-       insertloadlog($reservation_id, $computer_id, "startload", 
"$computer_name $image_name");
-       notify($ERRORS{'DEBUG'}, 0, "computer_private_ip_address = 
[$computer_private_ip_address]");
-
-       # Remove existing VMs which were created for the reservation computer
-       if (_pingnode($computer_private_ip_address)) {
-               if (!$self->_terminate_os_instance()) {
-                       notify($ERRORS{'CRITICAL'}, 0, "failed to delete VM 
$computer_name on VM host $vmhost_name");
-               }
-       }
-       # Remove existing openstack id for computer mapping in database 
-       # Althought the instance is not pingable (delete it accidently), it 
should delete the instance from database
-       if (!$self->_delete_os_computer_mapping()) {
-               notify($ERRORS{'WARNING'}, 0, "failed to delete the openstack 
instance id from openstackcomputermap");
-               return;
-       }
-
-       # Create new instance 
-       my $os_instance_id = $self->_post_os_create_instance();
-       if (!defined($os_instance_id)) {
-               notify($ERRORS{'CRITICAL'}, 0, "failed to create an instance 
for computer $computer_name on VM host: $vmhost_name");
-               return;
-       }
-
-       # Update the private ip of the instance in database
-       if (!$self->_update_private_ip($os_instance_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to update private ip of 
the instance in database");
-               return;
-       }
-
-       # Call post_load 
-       if ($self->os->can("post_load")) {
-               notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->os) . 
"->post_load()");
-               if ($self->os->post_load()) {
-                       notify($ERRORS{'DEBUG'}, 0, "successfully ran OS 
post_load subroutine");
-               }
-               else {
-                       notify($ERRORS{'WARNING'}, 0, "failed to run OS 
post_load subroutine");
-                       return;
-               }
-       }
-       else {
-               notify($ERRORS{'WARNING'}, 0, ref($self->os) . "::post_load() 
has not been implemented");
-               return;
-       }
-
-       return 1;
-
-} ## end sub load
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 capture
-
- Parameters  : None
- Returns     : 1 if sucessful, 0 if failed
- Description : capturing a new OpenStack image.
-
-=cut
-
-sub capture {
-       my $self = shift;
-
-       if (ref($self) !~ /openstack/i) {
-               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
-               return;
-       }
-
-       my $reservation_id = $self->data->get_reservation_id() || return;
-       my $current_imagerevision_id = 
$self->os->get_current_imagerevision_id();
-       my $computer_id = $self->data->get_computer_id() || return;
-       my $image_name = $self->data->get_image_name() || return;
-       my $computer_name = $self->data->get_computer_short_name() || return;
-       my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address() || return;
-
-       insertloadlog($reservation_id, $computer_id, "startcapture", 
"$computer_name $image_name");
-       notify($ERRORS{'DEBUG'}, 0, "computer_private_ip_address = 
[$computer_private_ip_address]");
-       
-       # Remove existing VMs which were created for the reservation computer
-       if (!_pingnode($computer_private_ip_address)) {
-               notify($ERRORS{'WARNING'}, 0, "unable to ping to 
$computer_name");
-               return;
-       }
-
-       my $os_instance_id = $self->_get_os_instance_id();
-       if (!defined($os_instance_id)) {
-               notify($ERRORS{'WARNING'}, 0, "unable to get instance id for 
$computer_name");
-               return;
-       }
-       notify($ERRORS{'DEBUG'}, 0, "os_instance_id: $os_instance_id");
-
-       my $os_flavor_id = _get_os_flavor_id($current_imagerevision_id);
-       notify($ERRORS{'DEBUG'}, 0, "current imagerevision id is 
$current_imagerevision_id, flavor_id: $os_flavor_id");
-       if (!defined($os_flavor_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get current openstack 
flavor id");
-               return;
-       }
-               
-       if (!$self->_prepare_capture()) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute 
prepare_capture");
-               return;
-       }
-       
-       my $os_image_id = $self->_post_os_create_image($os_instance_id);
-       if (!defined($os_image_id)) {
-               notify($ERRORS{'CRITICAL'}, 0, "failed to create image for 
$computer_name");
-               return;
-       }
-       notify($ERRORS{'DEBUG'}, 0, "os_image_id: $os_image_id");
-
-       if (!$self->_wait_for_copying_image($os_image_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute 
_wait_for_copying_image for $os_image_id");
-               return;
-       }
-
-       # insert image details and flavor details, check status is ACTIVE 
before insert
-       if (!$self->_insert_os_image_id($os_image_id, $os_flavor_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to insert openstack image 
id");
-               return;
-       }
-       notify($ERRORS{'DEBUG'}, 0, "capturing $os_instance_id into 
$os_image_id is done");
-
-       return 1;
-} ## end sub capture
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 does_image_exist
-
- Parameters  : 
- Returns     : 1 or 0
- Description : Checks the existence of an image.
-
-=cut
-
-sub does_image_exist {
-       my $self = shift;
-       if (ref($self) !~ /openstack/i) {
-               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
-               return 0;
-       }
-
-       my $imagerevision_id = $self->data->get_imagerevision_id() || return 0;
-       my $image_name = $self->data->get_image_name() || return 0;
-       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
-       my $os_project_id = $ENV{'OS_PROJECT_ID'};
-       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
info");
-               return 0;
-       }
-
-       # Get the openstack image id for the corresponding VCL image revision id
-       my $os_image_id = _get_os_image_id($imagerevision_id);
-       if (!defined($os_image_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to acquire the openstack 
image id : $os_image_id");
-               return 0;
-       }
-
-       my $ua = LWP::UserAgent->new();
-       my $resp = $ua->get(
-               $os_compute_url . "/images/" . $os_image_id,
-               x_auth_token => $os_token,
-               x_auth_project_id => $os_project_id,
-       );
-
-       if (!$resp->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute post token: " 
. join("\n", $resp->content));
-               return 0;
-       }
-
-       my $output = from_json($resp->content);
-       if (!defined($output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to parse json ouput: 
$output");
-               return 0;
-       }
-
-       my $image_status = $output->{image}{status};
-       if (defined($image_status) && $image_status eq 'ACTIVE') {
-               notify($ERRORS{'OK'}, 0, "The openstack image for $image_name 
exists");
-               return 1;
-       }
-       else {
-               notify($ERRORS{'WARNING'}, 0, "The openstack image for 
$image_name does NOT exists");
-               return 0;
-       }
-
-} ## end sub does_image_exist
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2  get_image_size
-
- Parameters  : imagename
- Returns     : 0 failure or size of image
- Description : in size of Megabytes
-
-=cut
-
-sub get_image_size {
-       my $self = shift;
-       if (ref($self) !~ /openstack/i) {
-               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
-               return;
-       }
- 
-       # Attempt to get the image name argument
-       my $image_name = shift;
-       my $imagerevision_id = $self->data->get_imagerevision_id() || return;
-       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
-       my $os_project_id = $ENV{'OS_PROJECT_ID'};
-       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
info");
-               return;
-       }
-       my $os_image_id = _get_os_image_id($imagerevision_id);
-       if (!defined($os_image_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to acquire the openstack 
image id : $os_image_id for $image_name");
-               return;
-       }
-
-       my $ua = LWP::UserAgent->new();
-       my $resp = $ua->get(
-               $os_compute_url . "/images/" . $os_image_id,
-               x_auth_token => $os_token,
-               x_auth_project_id => $os_project_id,
-       );
-
-       if (!$resp->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute post token: " 
. join("\n", $resp->content));
-               return;
-       }
-
-       my $output = from_json($resp->content);
-       if (!defined($output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to parse json ouput: 
$output");
-               return;
-       }
-
-       my $os_image_size_bytes = $output->{'image'}{'OS-EXT-IMG-SIZE:size'};
-       if (!defined($os_image_size_bytes)) {
-               notify($ERRORS{'WARNING'}, 0, "The openstack image size for 
$image_name does NOT exists");
-               return;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "os_image_size_bytes: $os_image_size_bytes 
for $image_name");
-       return round($os_image_size_bytes / 1024 / 1024);
-} ## end sub get_image_size
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 node_status
-
- Parameters  : $computer_id or $hash->{computer}{id} (optional)
- Returns     : string -- 'READY', 'POST_LOAD', or 'RELOAD'
- Description : Checks the status of a VM. 'READY' is returned if the VM is
-              accessible via SSH, and the OS module's post-load tasks have
-              run. 'POST_LOAD' is returned if the VM only needs to have
-              the OS module's post-load tasks run before it is ready.
-              'RELOAD' is returned otherwise.
-
-=cut
-
-sub node_status {
-       my $self;
-
-       # Get the argument
-       my $argument = shift;
-
-       # Check if this subroutine was called an an object method or an 
argument was passed
-       if (ref($argument) =~ /VCL::Module/i) {
-               $self = $argument;
-       }
-       elsif (!ref($argument) || ref($argument) eq 'HASH') {
-               # An argument was passed, check its type and determine the 
computer ID
-               my $computer_id;
-               if (ref($argument)) {
-                       # Hash reference was passed
-                       $computer_id = $argument->{id};
-               }
-               elsif ($argument =~ /^\d+$/) {
-                       # Computer ID was passed
-                       $computer_id = $argument;
-               }
-               else {
-                       # Computer name was passed
-                       ($computer_id) = get_computer_ids($argument);
-               }
-
-               if ($computer_id) {
-                       notify($ERRORS{'DEBUG'}, 0, "computer ID: 
$computer_id");
-               }
-
-               else {
-                       notify($ERRORS{'WARNING'}, 0, "unable to determine 
computer ID from argument:\n" . format_data($argument));
-                       return;
-               }
-
-               # Create a DataStructure object containing data for the 
computer specified as the argument
-               my $data;
-               eval {
-                       $data= new VCL::DataStructure({computer_identifier => 
$computer_id});
-               };
-               if ($EVAL_ERROR) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to create 
DataStructure object for computer ID: $computer_id, error: $EVAL_ERROR");
-                       return;
-               }
-               elsif (!$data) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to create 
DataStructure object for computer ID: $computer_id, DataStructure object is not 
defined");
-                       return;
-               }
-               else {
-                       notify($ERRORS{'DEBUG'}, 0, "created DataStructure 
object  for computer ID: $computer_id");
-               }
-
-               # Create a VMware object
-               my $object_type = 'VCL::Module::Provisioning::openstack';
-               if ($self = ($object_type)->new({data_structure => $data})) {
-                       notify($ERRORS{'DEBUG'}, 0, "created $object_type 
object to check the status of computer ID: $computer_id");
-               }
-               else {
-                       notify($ERRORS{'WARNING'}, 0, "failed to create 
$object_type object to check the status of computer ID: $computer_id");
-                       return;
-               }
-
-               # Create an OS object for the VMware object to access
-               if (!$self->create_os_object()) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to create OS 
object");
-                       return;
-               }
-       }
-
-       my $reservation_id = $self->data->get_reservation_id();
-       my $computer_name = $self->data->get_computer_node_name();
-       my $image_name = $self->data->get_image_name();
-       my $request_forimaging = $self->data->get_request_forimaging();
-       my $imagerevision_id = $self->data->get_imagerevision_id();
-       my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address();
-
-
-       notify($ERRORS{'DEBUG'}, 0, "attempting to check the status of computer 
$computer_name, image: $image_name");
-
-       # Create a hash reference and populate it with the default values
-       my $status;
-       $status->{currentimage} = '';
-       $status->{ssh} = 0;
-       $status->{image_match} = 0;
-       $status->{status} = 'RELOAD';
-
-       # Check if node is pingable and retrieve the power status if the 
reservation ID is 0
-       # The reservation ID will be 0 is this subroutine was not called as an 
object method, but with a computer ID argument
-       # The reservation ID will be 0 when called from healthcheck.pm
-       # The reservation ID will be > 0 if called from a normal VCL reservation
-       # Skip the ping and power status checks for a normal reservation to 
speed things up
-       if (!$reservation_id) {
-               if (_pingnode($computer_private_ip_address)) {
-                       notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is 
pingable");
-                       $status->{ping} = 1;
-               }
-               else {
-                       notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is not 
pingable");
-                       $status->{ping} = 0;
-               }
-
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "Trying to ssh...");
-       # Check if SSH is available
-       if ($self->os->is_ssh_responding()) {
-               notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is responding to 
SSH");
-               $status->{ssh} = 1;
-       }
-       else {
-               notify($ERRORS{'OK'}, 0, "VM $computer_name is not responding 
to SSH, returning 'RELOAD'");
-               $status->{status} = 'RELOAD';
-               $status->{ssh} = 0;
-
-               # Skip remaining checks if SSH isn't available
-               return $status;
-       }
-
-       my $current_image_revision_id = 
$self->os->get_current_imagerevision_id();
-       $status->{currentimagerevision_id} = $current_image_revision_id;
-
-       $status->{currentimage} = $self->data->get_computer_currentimage_name();
-       my $current_image_name = $status->{currentimage};
-       my $vcld_post_load_status = $self->os->get_post_load_status();
-
-       if (!$current_image_revision_id) {
-               notify($ERRORS{'OK'}, 0, "unable to retrieve image name from 
currentimage.txt on VM $computer_name, returning 'RELOAD'");
-               return $status;
-       }
-       elsif ($current_image_revision_id eq $imagerevision_id) {
-               notify($ERRORS{'OK'}, 0, "currentimage.txt image 
$current_image_revision_id ($current_image_name) matches requested 
imagerevision_id $imagerevision_id  on VM $computer_name");
-               $status->{image_match} = 1;
-       }
-       else {
-               notify($ERRORS{'OK'}, 0, "currentimage.txt imagerevision_id 
$current_image_revision_id ($current_image_name) does not match requested 
imagerevision_id $imagerevision_id on VM $computer_name, returning 'RELOAD'");
-               return $status;
-       }
-
-
-       # Determine the overall machine status based on the individual status 
results
-       if ($status->{ssh} && $status->{image_match}) {
-               $status->{status} = 'READY';
-       }
-       else {
-               $status->{status} = 'RELOAD';
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "status set to $status->{status}");
-
-
-       if ($request_forimaging) {
-               $status->{status} = 'RELOAD';
-               notify($ERRORS{'OK'}, 0, "request_forimaging set, setting 
status to RELOAD");
-       }
-
-       if ($vcld_post_load_status) {
-               notify($ERRORS{'DEBUG'}, 0, "OS module post_load tasks have 
been completed on VM $computer_name");
-               $status->{status} = 'READY';
-       }
-       else {
-               notify($ERRORS{'OK'}, 0, "OS module post_load tasks have not 
been completed on VM $computer_name, returning 'POST_LOAD'");
-               $status->{status} = 'POST_LOAD';
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "returning node status hash reference 
(\$node_status->{status}=$status->{status})");
-       return $status;
-
-} ## end sub node_status
-
-                                                                               
               
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _delete_os_computer_mapping
-
- Parameters  : computer id
- Returns     : 1 or 0
- Description : delete match VCL computer id with OpenStack instance id
-
-=cut
-
-sub _delete_os_computer_mapping {
-       my $self = shift;
-       my $computer_id = $self->data->get_computer_id();
-       if (!defined($computer_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get computer id");
-               return 0;
-       }
-
-       my $sql_statement = <<EOF;
-SELECT
-computerid
-FROM
-openstackcomputermap
-WHERE
-computerid = '$computer_id'
-EOF
-
-       #notify($ERRORS{'DEBUG'}, 0, "delete_os_computer_mapping: 
$sql_statement");
-       my @selected_rows = database_select($sql_statement);
-       if (scalar @selected_rows == 0) {
-               notify($ERRORS{'OK'}, 0, "no instance for $computer_id");
-               return 1;
-       }
-
-       $sql_statement = <<EOF;
-DELETE FROM
-openstackcomputermap
-WHERE
-computerid = '$computer_id'
-EOF
-       #notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
-       my $result = database_execute($sql_statement);
-
-       if (!defined($result)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to delete computer 
mapping");
-               return 0;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "successfully deleted computer mapping");
-       sleep 5;
-       return 1;
-} ## end sub _delete_os_computer_mapping
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_os_flavor_id
-
- Parameters  : image revision id 
- Returns     : OpenStack image id or 0
- Description : match VCL image revision id with OpenStack image id 
-
-=cut
-
-sub _get_os_flavor_id {
-       my $imagerevision_id = shift;
-       if (!defined($imagerevision_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get image revision 
id");
-               return;
-       }
-
-       my $sql_statement = <<EOF;
-SELECT
-flavordetails as flavor
-FROM
-openstackimagerevision 
-WHERE
-imagerevisionid = '$imagerevision_id'
-EOF
-
-       #notify($ERRORS{'DEBUG'}, 0, "get_os_flavor_id: $sql_statement");
-       my @selected_rows = database_select($sql_statement);
-       if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
-               notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " 
rows were returned from database select");
-               return;
-       }
-       my $os_flavor_detail  = from_json($selected_rows[0]{flavor});
-       if (!defined($os_flavor_detail)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor 
detail");
-               return;
-       }
-       my $os_flavor_id = $os_flavor_detail->{flavor}{id};
-       if (!defined($os_flavor_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor 
id");
-               return;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "os_flavor_id: $os_flavor_id");
-       return $os_flavor_id;
-} ## end sub _get_os_flavor_id
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_os_image_id
-
- Parameters  : image revision id 
- Returns     : OpenStack image id or 0
- Description : Get the OpenStack image id corresponding to the VCL image 
revision id  
-
-=cut
-
-sub _get_os_image_id {
-       my $imagerevision_id = shift;
-       if (!defined($imagerevision_id)) {
-               notify($ERRORS{'DEBUG'}, 0, "failed to get image revision id");
-               return 0;
-       }
-
-       my $sql_statement = <<EOF;
-SELECT
-imagedetails as image
-FROM
-openstackimagerevision 
-WHERE
-imagerevisionid = '$imagerevision_id'
-EOF
-
-       notify($ERRORS{'DEBUG'}, 0, "get_os_image_id: $sql_statement");
-       my @selected_rows = database_select($sql_statement);
-       if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
-               notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " 
rows were returned from database select");
-               return 0;
-       }
-       my $os_image_detail = from_json($selected_rows[0]{image});
-       if (!defined($os_image_detail)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack image 
detail");
-               return 0;
-       }
-
-       my $os_image_id = $os_image_detail->{image}{id};
-       if (!defined($os_image_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack image 
id");
-               return 0;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "openstack image_id: $os_image_id");
-
-       return $os_image_id;
-} ## end sub _get_os_image_id
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_os_instance_id
-
- Parameters  : None
- Returns     : OpenStack instance id or 0
- Description : Checks the existence of an OpenStack instance.
-
-=cut
-sub _get_os_instance_id {
-       my $self = shift;
-       my $computer_id = $self->data->get_computer_id();
-       if (!defined($computer_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get computer id");
-               return;
-       }
-
-       my $sql_statement = <<EOF;
-SELECT
-instanceid as id
-FROM
-openstackcomputermap
-WHERE
-computerid = '$computer_id'
-EOF
-
-       #notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
-       my @selected_rows = database_select($sql_statement);
-       if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
-               notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " 
rows were returned from database select");
-               return;
-       }
-
-       my $os_instance_id = $selected_rows[0]{id};
-       if (!defined($os_instance_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack instance 
id");
-               return;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "Openstack instance id for $computer_id is 
$os_instance_id");
-       return $os_instance_id;
-}
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_os_token_computer_url
-
- Parameters  : None 
- Returns     : Openstack auth (token, compute url) or 0
- Description : Get the OpenStack auth token and compute url   
-
-=cut
-
-sub _get_os_token_compute_url {
-       my $self = shift;
-
-       my $os_auth_url = $ENV{'OS_AUTH_URL'};
-       my $os_tenant_name = $ENV{'OS_TENANT_NAME'};
-       my $os_user_name = $ENV{'OS_USERNAME'};
-       my $os_user_password = $ENV{'OS_PASSWORD'};
-       my $os_service_name = $ENV{'OS_SERVICE_NAME'};
-       if (!defined($os_auth_url) || !defined($os_tenant_name) 
-               || !defined($os_user_name) || !defined($os_user_password) || 
!defined($os_service_name)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
information from environment");
-               return 0;
-       }
-
-       my $os_auth_data = {
-               auth =>  {
-                       tenantName => $os_tenant_name,
-                       passwordCredentials => {
-                               username => $os_user_name,
-                               password => $os_user_password,
-                       }
-               }
-       };
-
-       my $ua = LWP::UserAgent->new();
-       my $resp =  $ua->post(
-               $os_auth_url . "/tokens",
-               content_type => 'application/json', 
-               content => to_json($os_auth_data)
-       );
-       if (!$resp->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack token: " 
. join("\n", $resp->content));
-               return 0;
-       }
-       
-       my $output = from_json($resp->content);
-       if (!defined($output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
-               return 0;
-       }
-
-       my $os_token = $output->{access}{token}{id};
-       if (!defined($os_token)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get token");
-               return 0;
-       }
-
-       my @serviceCatalog = @{ $output->{access}{serviceCatalog} };
-       @serviceCatalog = grep { $_->{type} eq 'compute' } @serviceCatalog;
-       if (!@serviceCatalog) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get compute service 
catalog");
-               return 0;
-       }
-
-       @serviceCatalog = grep { $_->{name} eq $os_service_name } 
@serviceCatalog;
-       my $serviceCatalog = $serviceCatalog[0];
-       if (!defined($serviceCatalog)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get service name: 
$os_service_name");
-               return 0;
-       }
-
-       my $os_compute_url = $serviceCatalog->{endpoints}[0]{publicURL};
-       if (!defined($os_compute_url)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get compute server 
url");
-               return 0;
-       }
-
-       #notify($ERRORS{'DEBUG'}, 0, "token: $os_token, compute_url: 
$os_compute_url");
-       return ($os_token, $os_compute_url);
-} ## end sub get_os_token_compute_url
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _insert_os_image_id
-
- Parameters  : OpenStack image id
- Returns     : 1 or 0
- Description : insert OpenStack image id and corresponding imagerevision id    
 
-
-=cut
-
-sub _insert_os_image_id {
-       my $self = shift;
-       my ($os_image_id, $os_flavor_id) = @_;
-       notify($ERRORS{'DEBUG'}, 0, "the openstack id: $os_image_id,  flavor 
id: $os_flavor_id");
-       if (!defined($os_image_id) || !defined($os_flavor_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack id: 
$os_image_id or flavor id: $os_flavor_id");
-               return 0;
-       }
-       my $imagerevision_id = $self->data->get_imagerevision_id();
-       if (!defined($imagerevision_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the imagerevision 
id");
-               return 0;
-       }
-       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
-       my $os_project_id = $ENV{'OS_PROJECT_ID'};
-       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth 
info");
-               return 0;
-       }
-
-       my $ua = LWP::UserAgent->new();
-       my $res = $ua->get(
-               $os_compute_url . "/images/" . $os_image_id,
-               x_auth_token => $os_token,
-               x_auth_project_id => $os_project_id,
-       );
-       if (!$res->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack image 
info: " . join("\n", $res->content));
-               return 0;
-       }
-       my $os_image_details = $res->content;
-       if (!defined($os_image_details)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
-               return 0;
-       }
-
-       my $resp = $ua->get(
-               $os_compute_url . "/flavors/". $os_flavor_id,
-               x_auth_token => $os_token,
-               x_auth_project_id => $os_project_id,
-       );
-       if (!$resp->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor 
info: " . join("\n", $resp->content));
-               return 0;
-       }
-       my $os_flavor_details = $resp->content;
-       if (!defined($os_flavor_details)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
-               return 0;
-       }
-
-       my $sql_statement = <<EOF;
-INSERT INTO
-openstackimagerevision (
-imagerevisionid, 
-imagedetails,
-flavordetails) 
-VALUES ( 
-       '$imagerevision_id',
-       '$os_image_details',
-       '$os_flavor_details')
-EOF
-
-       #notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
-       my $result = database_execute($sql_statement);
-
-       if (!defined($result)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to insert openstack image 
id");
-               return 0;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "successfully insert openstack image id");
-       sleep 5;
-       return 1;
-} ## end sub _insert_os_image_id
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _insert_os_instance_id
-
- Parameters  : OpenStack instance id
- Returns     : 1 or 0
- Description : insert OpenStack instance id and corresponding computer id
-
-=cut
-
-sub _insert_os_instance_id {
-       my $self = shift;
-       my $os_instance_id = shift;
-       my $computer_id = $self->data->get_computer_id();
-       if (!defined($os_instance_id) || !defined($computer_id)) {
-               notify($ERRORS{'DEBUG'}, 0, "failed to get the openstack 
instance id: $os_instance_id or computer id: $computer_id");
-               return 0;
-       }
-
-       my $sql_statement = <<EOF;
-INSERT INTO
-openstackcomputermap (
-instanceid,
-computerid)
-VALUES
-('$os_instance_id', '$computer_id')
-EOF
-
-       #notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
-       my $result = database_execute($sql_statement);
-       if (!defined($result)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to insert openstack 
instance id");
-               return 0;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "successfully insert openstack instance id 
and comptuer id");
-       sleep 5;
-       return 1;
-} ## end sub_insert_os_instance_id
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _post_os_create_image
-
- Parameters  : OpenStack instance id
- Returns     : 1 or 0
- Description : capture OpenStack instance    
-
-=cut
-
-sub _post_os_create_image{
-       my $self = shift;
-       my $os_instance_id = shift;
-       if (!defined($os_instance_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack 
instance id");
-               return;
-       }
-       notify($ERRORS{'DEBUG'}, 0, "os_instance_id: $os_instance_id in sub 
_post_os_create_image");
-       my $image_name = $self->data->get_image_name();
-       if (!defined($image_name)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
information from environment");
-               return;
-       }
-       notify($ERRORS{'DEBUG'}, 0, "os_image_name: $image_name in sub 
_post_os_create_image");
-       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
-       my $os_project_id = $ENV{'OS_PROJECT_ID'};
-       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
information from environment");
-               return;
-       }
-
-       my $ua = LWP::UserAgent->new();
-       my $server_data = {
-               createImage =>  {
-                       name => $image_name,
-               }
-       };
-
-       my $res =  $ua->post(
-               $os_compute_url . "/servers/" . $os_instance_id . "/action",
-               content_type => 'application/json',
-               x_auth_token => $os_token,
-               content => to_json($server_data)
-       );
-
-       if (!$res->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute capture image: 
" . join("\n", $res->content));
-               return;
-       }
-
-       my $resp =  $ua->get(
-               $os_compute_url . "/images/detail", 
-               server => $os_instance_id,
-               content_type => 'application/json',
-               x_auth_project_id => $os_project_id,
-               x_auth_token => $os_token
-       );
-
-       if (!$resp->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get image info: " . 
join("\n", $resp->content));
-               return;
-       }
-
-       my $output = from_json($resp->content);
-       if (!defined($output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
-               return;
-       }
-       my $os_image_id = $output->{images}[0]{id};
-       if (!defined($os_image_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to capture instance of 
$os_instance_id");
-               return;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "openstack image id for caputed instance of 
$os_instance_id is $os_image_id");
-       return $os_image_id;
-} ## end sub _post_os_create_image
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _post_os_create_instance
-
- Parameters  : None
- Returns     : 1 or 0
- Description : create an OpenStack instance    
-
-=cut
-
-sub _post_os_create_instance {
-       my $self = shift;
-       
-       my $imagerevision_id = $self->data->get_imagerevision_id() || return;
-       my $computer_name  = $self->data->get_computer_short_name() || return;
-       my $image_os_type  = $self->data->get_image_os_type() || return;
-       my $os_project_id = $ENV{'OS_PROJECT_ID'};
-       my $os_key_name = $ENV{'VCL_LINUX_KEY'};        
-       if (!defined($os_project_id) || !defined($os_key_name)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack 
project id or key name");
-               return;
-       }
-       if ($image_os_type eq 'linux') {
-               $os_key_name =  $ENV{'VCL_LINUX_KEY'};  
-               notify($ERRORS{'OK'}, 0, "The $os_key_name is the key for Linux 
(default)");
-       } 
-       elsif ($image_os_type eq 'windows') {
-               $os_key_name =  $ENV{'VCL_WINDOWS_KEY'};        
-               notify($ERRORS{'OK'}, 0, "The $os_key_name is the key for 
Windows");
-       }
-
-       my $os_image_id = _get_os_image_id($imagerevision_id);
-       if (!defined($os_image_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack 
image id");
-               return;
-       }
-
-       my $os_flavor_id = _get_os_flavor_id($imagerevision_id);
-       if (!$os_flavor_id) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack 
flavor id");
-               return;
-       }
-
-       my $ua = LWP::UserAgent->new();
-       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
-       my $server_data = {
-               server =>  {
-                       name => $computer_name,
-                       imageRef => $os_image_id,
-                       key_name => $os_key_name,
-                       flavorRef => $os_flavor_id
-               }
-       };
-
-       my $resp =  $ua->post(
-               $os_compute_url . "/servers",
-               content_type => 'application/json',
-               x_auth_token => $os_token,
-               x_auth_project_id => $os_project_id,
-               content => to_json($server_data)
-       );
-
-       if (!$resp->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute run instance: 
" . join("\n", $resp->content));
-               return;
-       }
-
-       my $output = from_json($resp->content);
-       notify($ERRORS{'DEBUG'}, 0, "create_instance output: $output");
-       if (!defined($output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
-               return;
-       }
-       my $os_instance_id = $output->{'server'}{'id'};
-       if (!defined($os_instance_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute command to get 
the instance id on $computer_name");
-               return;
-       }
-
-       if (!$self->_insert_os_instance_id($os_instance_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to insert the instance id 
: $os_instance_id");
-               return; 
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "The create_instance: $os_instance_id\n");
-       return $os_instance_id;
-} ## end sub _post_os_create_instance
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _prepare_capture
-
- Parameters  : None
- Returns     : 1 or 0
- Description : prepare capturing instance     
-
-=cut
-
-sub _prepare_capture {
-       my $self = shift;
-       
-       my ($package, $filename, $line, $sub) = caller(0);
-       my $request_data = $self->data->get_request_data();
-       if (!$request_data) {
-               notify($ERRORS{'WARNING'}, 0, "unable to retrieve request data 
hash");
-               return 0;
-       }
-       my $computer_name = $self->data->get_computer_short_name();
-       if (!defined($computer_name)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get computer name");
-               return 0;
-       }
-
-       if (!$self->data->set_imagemeta_sysprep(0)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to set the imagemeta 
Sysprep value to 0");
-               return 0;
-       }
-
-       if ($self->os->can("pre_capture")) {
-               notify($ERRORS{'OK'}, 0, "calling OS module's pre_capture() 
subroutine");
-
-               if (!$self->os->pre_capture({end_state => 'on'})) {
-                       notify($ERRORS{'WARNING'}, 0, "OS module pre_capture() 
failed");
-                       return 0;
-               }
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "pre_capture() is done");
-       return 1;
-} ## end sub _prepare_capture
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _set_os_auth_conf 
-
- Parameters  : None 
- Returns     : 1(success) or 0(failure)
- Description : load openstack environment profile and set global environemnt 
variables 
-
-example: openstack.conf
-"os_tenant_name" => "admin",
-"os_username" => "admin",
-"os_password" => "adminpassword",
-"os_auth_url" => "http://openstack_nova_url:5000/v2.0";,
-"os_service_name" => "nova",
-"vcl_windows_key" => "vcl_windows_key",
-"vcl_linux_key" => "vcl_linux_key",
-
-=cut
-
-sub _set_os_auth_conf {
-       my $self = shift;
-       # User's environment file
-       my $user_config_file = '/etc/vcl/openstack/openstack.conf';
-       my %config = do($user_config_file);
-       if (!%config) {
-               notify($ERRORS{'WARNING'},0, "failure to process 
$user_config_file");
-               return;
-       }
-       $self->{config} = \%config;
-       my $os_auth_url = $self->{config}->{os_auth_url};
-       my $os_service_name = $self->{config}->{os_service_name};
-       my $os_project_id = $self->{config}->{os_project_id};
-       my $os_tenant_name = $self->{config}->{os_tenant_name};
-       my $os_username = $self->{config}->{os_username};
-       my $os_password = $self->{config}->{os_password};
-       my $vcl_windows_key = $self->{config}->{vcl_windows_key};
-       my $vcl_linux_key = $self->{config}->{vcl_linux_key};
-
-       # Set Environment File
-       $ENV{'OS_AUTH_URL'} = $os_auth_url;
-       $ENV{'OS_SERVICE_NAME'} = $os_service_name;
-       $ENV{'OS_PROJECT_ID'} = $os_project_id;
-       $ENV{'OS_TENANT_NAME'} = $os_tenant_name;
-       $ENV{'OS_USERNAME'} = $os_username;
-       $ENV{'OS_PASSWORD'} = $os_password;
-       $ENV{'VCL_WINDOWS_KEY'} = $vcl_windows_key;
-       $ENV{'VCL_LINUX_KEY'} = $vcl_linux_key;
-
-       return 1;
-}# end sub _set_os_auth_conf
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _terminate_os_instance
-
- Parameters  : None
- Returns     : 1 or 0
- Description : terminate an OpenStack instance    
-
-=cut
-
-sub _terminate_os_instance {
-       my $self = shift;
-
-       my $computer_name = $self->data->get_computer_short_name() || return 0;
-               
-       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
-       my $os_project_id = $ENV{'OS_PROJECT_ID'};
-       my $os_instance_id = $self->_get_os_instance_id();
-       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id) || !defined($os_instance_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth 
info");
-               return 0;
-       }
-
-       my $ua = LWP::UserAgent->new();
-       my $resp =  $ua->delete(
-               $os_compute_url . "/servers/" . $os_instance_id,
-               x_auth_token => $os_token
-       );
-       if (!$resp->is_success) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute terminate 
instance: " . join("\n", $resp->content));
-               return 0;
-       }
-
-       sleep 30;
-       return 1;
-} ## end sub _terminate_os_instance
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _update_os_instance
-
- Parameters  : OpenStack instance id
- Returns     : 1 or 0
- Description : update the private ip address of the OpenStack instance in 
database 
-
-=cut
-
-sub _update_private_ip {
-       my $self = shift;
-       
-       my $os_instance_id = shift;
-       my $computer_id = $self->data->get_computer_id() || return 0;
-       my $computer_name  = $self->data->get_computer_short_name() || return 0;
-       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
-       if (!defined($os_instance_id) || !defined($os_token) || 
!defined($os_compute_url)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth 
info");
-               return 0;
-       }
-       my $ua = LWP::UserAgent->new();
-       my ($private_ip, $output, $resp);
-       my $main_loop = 60;
-
-       # Find the correct instance among running instances using the private IP
-       while ($main_loop > 0) {
-               notify($ERRORS{'DEBUG'}, 0, "try to fetch the private IP 
address for $computer_name, loop of $main_loop");      
-               $resp =  $ua->get(
-                       $os_compute_url . "/servers/" . $os_instance_id,
-                       x_auth_token => $os_token
-               );
-               if (!$resp->is_success) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to execute 
instance detail: " . join("\n", $resp->content));
-                       return 0;
-               }
-
-               $output = from_json($resp->content);
-               if (!defined($output)) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to parse json 
output");
-                       return 0;
-               }
-               $private_ip = 
$output->{'server'}{'addresses'}{'private'}[0]->{'addr'};
-
-               if (defined($private_ip)) {
-                       my $result = 
update_computer_private_ip_address($computer_id, $private_ip);
-                       if (!defined($result)) {
-                               notify($ERRORS{'WARNING'}, 0, "The $private_ip 
on Computer $computer_name is NOT updated");
-                               return 0;
-                       }
-                       notify($ERRORS{'DEBUG'}, 0, "private IP address is 
$private_ip for $computer_name");
-                       sleep 10;
-                       return 1;
-               }
-               else {
-                       notify($ERRORS{'DEBUG'}, 0, "waiting for assinging 
private IP address to $computer_name");
-               }
-               
-               sleep 20;
-               $main_loop--;
-       }
-
-       notify($ERRORS{'DEBUG'}, 0, "private IP address for $computer_name is 
not determined");
-       return 0;
-} ## end sub _update_private_ip
-
-#//////////////////////////////////////////////////////////////////////////////
-
-=head2 _wait_for_copying_image
-
- Parameters  : OpenStack image id
- Returns     : 1 or 0
- Description : wait for copying the OpenStack image to repository
-
-=cut
-
-sub _wait_for_copying_image {
-       my $self = shift;
-       
-       my $os_image_id = shift;
-       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
-       my $os_project_id = $ENV{'OS_PROJECT_ID'};
-       if (!defined($os_image_id) || !defined($os_token) || 
!defined($os_compute_url) || !defined($os_project_id)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
info or image id: $os_image_id");
-               return 0;
-       }
-       my $ua = LWP::UserAgent->new();
-       my ($resp, $output, $image_status);
-
-       my $main_loop = 100;
-       while ($main_loop > 0) {
-               $resp =  $ua->get(
-                       $os_compute_url . "/images/" . $os_image_id,
-                       content_type => 'application/json',
-                       x_auth_project_id => $os_project_id,
-                       x_auth_token => $os_token
-               );
-
-               if (!$resp->is_success) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to get image 
info: " . join("\n", $resp->content));
-                       return 0;
-               }
-
-               $output = from_json($resp->content);
-               $image_status = $output->{'image'}{'status'};
-               if (defined($image_status)) {
-                       notify($ERRORS{'DEBUG'}, 0, "image status: 
$image_status for loop #$main_loop");
-                       if ($image_status eq 'ACTIVE') {
-                               notify($ERRORS{'OK'}, 0, "$os_image_id is 
available now");
-                               return 1;
-                       }
-                       elsif ($image_status eq 'SAVING') {
-                               notify($ERRORS{'DEBUG'}, 0, "wait 25 seconds 
for capturing instance");
-                               sleep 25;
-                       }
-                       else {
-                               notify($ERRORS{'DEBUG'}, 0, "failed to capture 
image for $os_image_id");
-                               return 0;
-                       }
-               }
-               sleep 10;
-               $main_loop--;
-       }
-
-       return 0;
-} ## end sub _wait_for_copying_image
-
-sub power_reset {
-
-       return 1;
-
-}
-
-#//////////////////////////////////////////////////////////////////////////////
-1;
-__END__
+#!/usr/bin/perl -w
+###############################################################################
+# $Id: openstack.pm 
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+###############################################################################
+
+=head1 NAME
+
+VCL::Provisioning::openstack - VCL module to support the Openstack 
provisioning engine with REST APIs v2
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+This module provides VCL support for Openstack
+
+=cut
+
+###############################################################################
+package VCL::Module::Provisioning::openstack;
+
+# Include File Copying for Perl
+use File::Copy;
+
+# Specify the lib path using FindBin
+use FindBin;
+use lib "$FindBin::Bin/../../..";
+
+# Configure inheritance
+use base qw(VCL::Module::Provisioning);
+
+# Specify the version of this module
+our $VERSION = '2.4.2';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+use English qw(-no_match_vars);
+use IO::File;
+use Fcntl qw(:DEFAULT :flock);
+use File::Temp qw(tempfile);
+use List::Util qw(max);
+use VCL::utils;
+use JSON qw(from_json to_json);
+use LWP::UserAgent;
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 initialize
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub initialize {
+       my $self = shift;
+       notify($ERRORS{'DEBUG'}, 0, "OpenStack module initialized");
+       
+       if ($self->_set_os_auth_conf()) {
+               notify($ERRORS{'OK'}, 0, "successfully set openStack auth 
configuration");
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to set openstack auth 
configuration");
+               return 0;
+       }
+       
+       return 1;
+} ## end sub initialize
+
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 unload
+
+ Parameters  : hash
+ Returns     : 1(success) or 0(failure)
+ Description : loads virtual machine with requested image
+
+=cut
+
+sub unload {
+       my $self = shift;
+       if (ref($self) !~ /openstack/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+
+       my $computer_name = $self->data->get_computer_short_name() || return;
+       my $vmhost_name = $self->data->get_vmhost_short_name() || return;
+       my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address();
+
+       # Remove existing VMs which were created for the reservation computer
+       if (_pingnode($computer_private_ip_address)) {
+               if (!$self->_terminate_os_instance()) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to delete VM 
$computer_name on VM host $vmhost_name");
+                       return 0;
+               }
+       }
+       # Remove existing openstack id for computer mapping in database 
+       # Althought the instance is not pingable (delete it accidently), it 
should delete the instance from database
+       if (!$self->_delete_os_computer_mapping()) {
+               notify($ERRORS{'WARNING'}, 0, "failed to delete the openstack 
instance id from openstackcomputermap");
+               return 0;
+       }
+
+       return 1;
+
+}
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 provision
+
+ Parameters  : hash
+ Returns     : 1(success) or 0(failure)
+ Description : loads virtual machine with requested image
+
+=cut
+
+sub load {
+       my $self = shift;
+       if (ref($self) !~ /openstack/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+
+       my $reservation_id = $self->data->get_reservation_id() || return;
+       my $computer_id = $self->data->get_computer_id() || return;
+       my $computer_name = $self->data->get_computer_short_name() || return;
+       my $image_name = $self->data->get_image_name() || return;
+       my $vmhost_name = $self->data->get_vmhost_short_name() || return;
+       my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address() || return;
+
+       insertloadlog($reservation_id, $computer_id, "startload", 
"$computer_name $image_name");
+       notify($ERRORS{'DEBUG'}, 0, "computer_private_ip_address = 
[$computer_private_ip_address]");
+
+       # Remove existing VMs which were created for the reservation computer
+       if (_pingnode($computer_private_ip_address)) {
+               if (!$self->_terminate_os_instance()) {
+                       notify($ERRORS{'CRITICAL'}, 0, "failed to delete VM 
$computer_name on VM host $vmhost_name");
+               }
+       }
+       # Remove existing openstack id for computer mapping in database 
+       # Althought the instance is not pingable (delete it accidently), it 
should delete the instance from database
+       if (!$self->_delete_os_computer_mapping()) {
+               notify($ERRORS{'WARNING'}, 0, "failed to delete the openstack 
instance id from openstackcomputermap");
+               return;
+       }
+
+       # Create new instance 
+       my $os_instance_id = $self->_post_os_create_instance();
+       if (!defined($os_instance_id)) {
+               notify($ERRORS{'CRITICAL'}, 0, "failed to create an instance 
for computer $computer_name on VM host: $vmhost_name");
+               return;
+       }
+
+       # Update the private ip of the instance in database
+       if (!$self->_update_private_ip($os_instance_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to update private ip of 
the instance in database");
+               return;
+       }
+
+       # Call post_load 
+       if ($self->os->can("post_load")) {
+               notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->os) . 
"->post_load()");
+               if ($self->os->post_load()) {
+                       notify($ERRORS{'DEBUG'}, 0, "successfully ran OS 
post_load subroutine");
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "failed to run OS 
post_load subroutine");
+                       return;
+               }
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, ref($self->os) . "::post_load() 
has not been implemented");
+               return;
+       }
+
+       return 1;
+
+} ## end sub load
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 capture
+
+ Parameters  : None
+ Returns     : 1 if sucessful, 0 if failed
+ Description : capturing a new OpenStack image.
+
+=cut
+
+sub capture {
+       my $self = shift;
+
+       if (ref($self) !~ /openstack/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+
+       my $reservation_id = $self->data->get_reservation_id() || return;
+       my $current_imagerevision_id = 
$self->os->get_current_imagerevision_id();
+       my $computer_id = $self->data->get_computer_id() || return;
+       my $image_name = $self->data->get_image_name() || return;
+       my $computer_name = $self->data->get_computer_short_name() || return;
+       my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address() || return;
+
+       insertloadlog($reservation_id, $computer_id, "startcapture", 
"$computer_name $image_name");
+       notify($ERRORS{'DEBUG'}, 0, "computer_private_ip_address = 
[$computer_private_ip_address]");
+       
+       # Remove existing VMs which were created for the reservation computer
+       if (!_pingnode($computer_private_ip_address)) {
+               notify($ERRORS{'WARNING'}, 0, "unable to ping to 
$computer_name");
+               return;
+       }
+
+       my $os_instance_id = $self->_get_os_instance_id();
+       if (!defined($os_instance_id)) {
+               notify($ERRORS{'WARNING'}, 0, "unable to get instance id for 
$computer_name");
+               return;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "os_instance_id: $os_instance_id");
+
+       my $os_flavor_id = _get_os_flavor_id($current_imagerevision_id);
+       notify($ERRORS{'DEBUG'}, 0, "current imagerevision id is 
$current_imagerevision_id, flavor_id: $os_flavor_id");
+       if (!defined($os_flavor_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get current openstack 
flavor id");
+               return;
+       }
+               
+       if (!$self->_prepare_capture()) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute 
prepare_capture");
+               return;
+       }
+       
+       my $os_image_id = $self->_post_os_create_image($os_instance_id);
+       if (!defined($os_image_id)) {
+               notify($ERRORS{'CRITICAL'}, 0, "failed to create image for 
$computer_name");
+               return;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "os_image_id: $os_image_id");
+
+       if (!$self->_wait_for_copying_image($os_image_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute 
_wait_for_copying_image for $os_image_id");
+               return;
+       }
+
+       # insert image details and flavor details, check status is ACTIVE 
before insert
+       if (!$self->_insert_os_image_id($os_image_id, $os_flavor_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to insert openstack image 
id");
+               return;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "capturing $os_instance_id into 
$os_image_id is done");
+
+       return 1;
+} ## end sub capture
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 does_image_exist
+
+ Parameters  : 
+ Returns     : 1 or 0
+ Description : Checks the existence of an image.
+
+=cut
+
+sub does_image_exist {
+       my $self = shift;
+       if (ref($self) !~ /openstack/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+
+       my $imagerevision_id = $self->data->get_imagerevision_id() || return 0;
+       my $image_name = $self->data->get_image_name() || return 0;
+       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
+       my $os_project_id = $ENV{'OS_PROJECT_ID'};
+       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
info");
+               return 0;
+       }
+
+       # Get the openstack image id for the corresponding VCL image revision id
+       my $os_image_id = _get_os_image_id($imagerevision_id);
+       if (!defined($os_image_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to acquire the openstack 
image id : $os_image_id");
+               return 0;
+       }
+
+       my $ua = LWP::UserAgent->new();
+       my $resp = $ua->get(
+               $os_compute_url . "/images/" . $os_image_id,
+               x_auth_token => $os_token,
+               x_auth_project_id => $os_project_id,
+       );
+
+       if (!$resp->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute post token: " 
. join("\n", $resp->content));
+               return 0;
+       }
+
+       my $output = from_json($resp->content);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to parse json ouput: 
$output");
+               return 0;
+       }
+
+       my $image_status = $output->{image}{status};
+       if (defined($image_status) && $image_status eq 'ACTIVE') {
+               notify($ERRORS{'OK'}, 0, "The openstack image for $image_name 
exists");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "The openstack image for 
$image_name does NOT exists");
+               return 0;
+       }
+
+} ## end sub does_image_exist
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2  get_image_size
+
+ Parameters  : imagename
+ Returns     : 0 failure or size of image
+ Description : in size of Megabytes
+
+=cut
+
+sub get_image_size {
+       my $self = shift;
+       if (ref($self) !~ /openstack/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+ 
+       # Attempt to get the image name argument
+       my $image_name = shift;
+       my $imagerevision_id = $self->data->get_imagerevision_id() || return;
+       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
+       my $os_project_id = $ENV{'OS_PROJECT_ID'};
+       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
info");
+               return;
+       }
+       my $os_image_id = _get_os_image_id($imagerevision_id);
+       if (!defined($os_image_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to acquire the openstack 
image id : $os_image_id for $image_name");
+               return;
+       }
+
+       my $ua = LWP::UserAgent->new();
+       my $resp = $ua->get(
+               $os_compute_url . "/images/" . $os_image_id,
+               x_auth_token => $os_token,
+               x_auth_project_id => $os_project_id,
+       );
+
+       if (!$resp->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute post token: " 
. join("\n", $resp->content));
+               return;
+       }
+
+       my $output = from_json($resp->content);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to parse json ouput: 
$output");
+               return;
+       }
+
+       my $os_image_size_bytes = $output->{'image'}{'OS-EXT-IMG-SIZE:size'};
+       if (!defined($os_image_size_bytes)) {
+               notify($ERRORS{'WARNING'}, 0, "The openstack image size for 
$image_name does NOT exists");
+               return;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "os_image_size_bytes: $os_image_size_bytes 
for $image_name");
+       return round($os_image_size_bytes / 1024 / 1024);
+} ## end sub get_image_size
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 node_status
+
+ Parameters  : $computer_id or $hash->{computer}{id} (optional)
+ Returns     : string -- 'READY', 'POST_LOAD', or 'RELOAD'
+ Description : Checks the status of a VM. 'READY' is returned if the VM is
+              accessible via SSH, and the OS module's post-load tasks have
+              run. 'POST_LOAD' is returned if the VM only needs to have
+              the OS module's post-load tasks run before it is ready.
+              'RELOAD' is returned otherwise.
+
+=cut
+
+sub node_status {
+       my $self;
+
+       # Get the argument
+       my $argument = shift;
+
+       # Check if this subroutine was called an an object method or an 
argument was passed
+       if (ref($argument) =~ /VCL::Module/i) {
+               $self = $argument;
+       }
+       elsif (!ref($argument) || ref($argument) eq 'HASH') {
+               # An argument was passed, check its type and determine the 
computer ID
+               my $computer_id;
+               if (ref($argument)) {
+                       # Hash reference was passed
+                       $computer_id = $argument->{id};
+               }
+               elsif ($argument =~ /^\d+$/) {
+                       # Computer ID was passed
+                       $computer_id = $argument;
+               }
+               else {
+                       # Computer name was passed
+                       ($computer_id) = get_computer_ids($argument);
+               }
+
+               if ($computer_id) {
+                       notify($ERRORS{'DEBUG'}, 0, "computer ID: 
$computer_id");
+               }
+
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "unable to determine 
computer ID from argument:\n" . format_data($argument));
+                       return;
+               }
+
+               # Create a DataStructure object containing data for the 
computer specified as the argument
+               my $data;
+               eval {
+                       $data= new VCL::DataStructure({computer_identifier => 
$computer_id});
+               };
+               if ($EVAL_ERROR) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to create 
DataStructure object for computer ID: $computer_id, error: $EVAL_ERROR");
+                       return;
+               }
+               elsif (!$data) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to create 
DataStructure object for computer ID: $computer_id, DataStructure object is not 
defined");
+                       return;
+               }
+               else {
+                       notify($ERRORS{'DEBUG'}, 0, "created DataStructure 
object  for computer ID: $computer_id");
+               }
+
+               # Create a VMware object
+               my $object_type = 'VCL::Module::Provisioning::openstack';
+               if ($self = ($object_type)->new({data_structure => $data})) {
+                       notify($ERRORS{'DEBUG'}, 0, "created $object_type 
object to check the status of computer ID: $computer_id");
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "failed to create 
$object_type object to check the status of computer ID: $computer_id");
+                       return;
+               }
+
+               # Create an OS object for the VMware object to access
+               if (!$self->create_os_object()) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to create OS 
object");
+                       return;
+               }
+       }
+
+       my $reservation_id = $self->data->get_reservation_id();
+       my $computer_name = $self->data->get_computer_node_name();
+       my $image_name = $self->data->get_image_name();
+       my $request_forimaging = $self->data->get_request_forimaging();
+       my $imagerevision_id = $self->data->get_imagerevision_id();
+       my $computer_private_ip_address = 
$self->data->get_computer_private_ip_address();
+
+
+       notify($ERRORS{'DEBUG'}, 0, "attempting to check the status of computer 
$computer_name, image: $image_name");
+
+       # Create a hash reference and populate it with the default values
+       my $status;
+       $status->{currentimage} = '';
+       $status->{ssh} = 0;
+       $status->{image_match} = 0;
+       $status->{status} = 'RELOAD';
+
+       # Check if node is pingable and retrieve the power status if the 
reservation ID is 0
+       # The reservation ID will be 0 is this subroutine was not called as an 
object method, but with a computer ID argument
+       # The reservation ID will be 0 when called from healthcheck.pm
+       # The reservation ID will be > 0 if called from a normal VCL reservation
+       # Skip the ping and power status checks for a normal reservation to 
speed things up
+       if (!$reservation_id) {
+               if (_pingnode($computer_private_ip_address)) {
+                       notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is 
pingable");
+                       $status->{ping} = 1;
+               }
+               else {
+                       notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is not 
pingable");
+                       $status->{ping} = 0;
+               }
+
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "Trying to ssh...");
+       # Check if SSH is available
+       if ($self->os->is_ssh_responding()) {
+               notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is responding to 
SSH");
+               $status->{ssh} = 1;
+       }
+       else {
+               notify($ERRORS{'OK'}, 0, "VM $computer_name is not responding 
to SSH, returning 'RELOAD'");
+               $status->{status} = 'RELOAD';
+               $status->{ssh} = 0;
+
+               # Skip remaining checks if SSH isn't available
+               return $status;
+       }
+
+       my $current_image_revision_id = 
$self->os->get_current_imagerevision_id();
+       $status->{currentimagerevision_id} = $current_image_revision_id;
+
+       $status->{currentimage} = $self->data->get_computer_currentimage_name();
+       my $current_image_name = $status->{currentimage};
+       my $vcld_post_load_status = $self->os->get_post_load_status();
+
+       if (!$current_image_revision_id) {
+               notify($ERRORS{'OK'}, 0, "unable to retrieve image name from 
currentimage.txt on VM $computer_name, returning 'RELOAD'");
+               return $status;
+       }
+       elsif ($current_image_revision_id eq $imagerevision_id) {
+               notify($ERRORS{'OK'}, 0, "currentimage.txt image 
$current_image_revision_id ($current_image_name) matches requested 
imagerevision_id $imagerevision_id  on VM $computer_name");
+               $status->{image_match} = 1;
+       }
+       else {
+               notify($ERRORS{'OK'}, 0, "currentimage.txt imagerevision_id 
$current_image_revision_id ($current_image_name) does not match requested 
imagerevision_id $imagerevision_id on VM $computer_name, returning 'RELOAD'");
+               return $status;
+       }
+
+
+       # Determine the overall machine status based on the individual status 
results
+       if ($status->{ssh} && $status->{image_match}) {
+               $status->{status} = 'READY';
+       }
+       else {
+               $status->{status} = 'RELOAD';
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "status set to $status->{status}");
+
+
+       if ($request_forimaging) {
+               $status->{status} = 'RELOAD';
+               notify($ERRORS{'OK'}, 0, "request_forimaging set, setting 
status to RELOAD");
+       }
+
+       if ($vcld_post_load_status) {
+               notify($ERRORS{'DEBUG'}, 0, "OS module post_load tasks have 
been completed on VM $computer_name");
+               $status->{status} = 'READY';
+       }
+       else {
+               notify($ERRORS{'OK'}, 0, "OS module post_load tasks have not 
been completed on VM $computer_name, returning 'POST_LOAD'");
+               $status->{status} = 'POST_LOAD';
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "returning node status hash reference 
(\$node_status->{status}=$status->{status})");
+       return $status;
+
+} ## end sub node_status
+
+                                                                               
               
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _delete_os_computer_mapping
+
+ Parameters  : computer id
+ Returns     : 1 or 0
+ Description : delete match VCL computer id with OpenStack instance id
+
+=cut
+
+sub _delete_os_computer_mapping {
+       my $self = shift;
+       my $computer_id = $self->data->get_computer_id();
+       if (!defined($computer_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get computer id");
+               return 0;
+       }
+
+       my $sql_statement = <<EOF;
+SELECT
+computerid
+FROM
+openstackcomputermap
+WHERE
+computerid = '$computer_id'
+EOF
+
+       #notify($ERRORS{'DEBUG'}, 0, "delete_os_computer_mapping: 
$sql_statement");
+       my @selected_rows = database_select($sql_statement);
+       if (scalar @selected_rows == 0) {
+               notify($ERRORS{'OK'}, 0, "no instance for $computer_id");
+               return 1;
+       }
+
+       $sql_statement = <<EOF;
+DELETE FROM
+openstackcomputermap
+WHERE
+computerid = '$computer_id'
+EOF
+       #notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
+       my $result = database_execute($sql_statement);
+
+       if (!defined($result)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to delete computer 
mapping");
+               return 0;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "successfully deleted computer mapping");
+       sleep 5;
+       return 1;
+} ## end sub _delete_os_computer_mapping
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_os_flavor_id
+
+ Parameters  : image revision id 
+ Returns     : OpenStack image id or 0
+ Description : match VCL image revision id with OpenStack image id 
+
+=cut
+
+sub _get_os_flavor_id {
+       my $imagerevision_id = shift;
+       if (!defined($imagerevision_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get image revision 
id");
+               return;
+       }
+
+       my $sql_statement = <<EOF;
+SELECT
+flavordetails as flavor
+FROM
+openstackimagerevision 
+WHERE
+imagerevisionid = '$imagerevision_id'
+EOF
+
+       #notify($ERRORS{'DEBUG'}, 0, "get_os_flavor_id: $sql_statement");
+       my @selected_rows = database_select($sql_statement);
+       if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
+               notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " 
rows were returned from database select");
+               return;
+       }
+       my $os_flavor_detail  = from_json($selected_rows[0]{flavor});
+       if (!defined($os_flavor_detail)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor 
detail");
+               return;
+       }
+       my $os_flavor_id = $os_flavor_detail->{flavor}{id};
+       if (!defined($os_flavor_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor 
id");
+               return;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "os_flavor_id: $os_flavor_id");
+       return $os_flavor_id;
+} ## end sub _get_os_flavor_id
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_os_image_id
+
+ Parameters  : image revision id 
+ Returns     : OpenStack image id or 0
+ Description : Get the OpenStack image id corresponding to the VCL image 
revision id  
+
+=cut
+
+sub _get_os_image_id {
+       my $imagerevision_id = shift;
+       if (!defined($imagerevision_id)) {
+               notify($ERRORS{'DEBUG'}, 0, "failed to get image revision id");
+               return 0;
+       }
+
+       my $sql_statement = <<EOF;
+SELECT
+imagedetails as image
+FROM
+openstackimagerevision 
+WHERE
+imagerevisionid = '$imagerevision_id'
+EOF
+
+       notify($ERRORS{'DEBUG'}, 0, "get_os_image_id: $sql_statement");
+       my @selected_rows = database_select($sql_statement);
+       if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
+               notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " 
rows were returned from database select");
+               return 0;
+       }
+       my $os_image_detail = from_json($selected_rows[0]{image});
+       if (!defined($os_image_detail)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack image 
detail");
+               return 0;
+       }
+
+       my $os_image_id = $os_image_detail->{image}{id};
+       if (!defined($os_image_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack image 
id");
+               return 0;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "openstack image_id: $os_image_id");
+
+       return $os_image_id;
+} ## end sub _get_os_image_id
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_os_instance_id
+
+ Parameters  : None
+ Returns     : OpenStack instance id or 0
+ Description : Checks the existence of an OpenStack instance.
+
+=cut
+sub _get_os_instance_id {
+       my $self = shift;
+       my $computer_id = $self->data->get_computer_id();
+       if (!defined($computer_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get computer id");
+               return;
+       }
+
+       my $sql_statement = <<EOF;
+SELECT
+instanceid as id
+FROM
+openstackcomputermap
+WHERE
+computerid = '$computer_id'
+EOF
+
+       #notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
+       my @selected_rows = database_select($sql_statement);
+       if (scalar @selected_rows == 0 || scalar @selected_rows > 1) {
+               notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " 
rows were returned from database select");
+               return;
+       }
+
+       my $os_instance_id = $selected_rows[0]{id};
+       if (!defined($os_instance_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack instance 
id");
+               return;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "Openstack instance id for $computer_id is 
$os_instance_id");
+       return $os_instance_id;
+}
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_os_token_computer_url
+
+ Parameters  : None 
+ Returns     : Openstack auth (token, compute url) or 0
+ Description : Get the OpenStack auth token and compute url   
+
+=cut
+
+sub _get_os_token_compute_url {
+       my $self = shift;
+
+       my $os_auth_url = $ENV{'OS_AUTH_URL'};
+       my $os_tenant_name = $ENV{'OS_TENANT_NAME'};
+       my $os_user_name = $ENV{'OS_USERNAME'};
+       my $os_user_password = $ENV{'OS_PASSWORD'};
+       my $os_service_name = $ENV{'OS_SERVICE_NAME'};
+       if (!defined($os_auth_url) || !defined($os_tenant_name) 
+               || !defined($os_user_name) || !defined($os_user_password) || 
!defined($os_service_name)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
information from environment");
+               return 0;
+       }
+
+       my $os_auth_data = {
+               auth =>  {
+                       tenantName => $os_tenant_name,
+                       passwordCredentials => {
+                               username => $os_user_name,
+                               password => $os_user_password,
+                       }
+               }
+       };
+
+       my $ua = LWP::UserAgent->new();
+       my $resp =  $ua->post(
+               $os_auth_url . "/tokens",
+               content_type => 'application/json', 
+               content => to_json($os_auth_data)
+       );
+       if (!$resp->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack token: " 
. join("\n", $resp->content));
+               return 0;
+       }
+       
+       my $output = from_json($resp->content);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
+               return 0;
+       }
+
+       my $os_token = $output->{access}{token}{id};
+       if (!defined($os_token)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get token");
+               return 0;
+       }
+
+       my @serviceCatalog = @{ $output->{access}{serviceCatalog} };
+       @serviceCatalog = grep { $_->{type} eq 'compute' } @serviceCatalog;
+       if (!@serviceCatalog) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get compute service 
catalog");
+               return 0;
+       }
+
+       @serviceCatalog = grep { $_->{name} eq $os_service_name } 
@serviceCatalog;
+       my $serviceCatalog = $serviceCatalog[0];
+       if (!defined($serviceCatalog)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get service name: 
$os_service_name");
+               return 0;
+       }
+
+       my $os_compute_url = $serviceCatalog->{endpoints}[0]{publicURL};
+       if (!defined($os_compute_url)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get compute server 
url");
+               return 0;
+       }
+
+       #notify($ERRORS{'DEBUG'}, 0, "token: $os_token, compute_url: 
$os_compute_url");
+       return ($os_token, $os_compute_url);
+} ## end sub get_os_token_compute_url
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _insert_os_image_id
+
+ Parameters  : OpenStack image id
+ Returns     : 1 or 0
+ Description : insert OpenStack image id and corresponding imagerevision id    
 
+
+=cut
+
+sub _insert_os_image_id {
+       my $self = shift;
+       my ($os_image_id, $os_flavor_id) = @_;
+       notify($ERRORS{'DEBUG'}, 0, "the openstack id: $os_image_id,  flavor 
id: $os_flavor_id");
+       if (!defined($os_image_id) || !defined($os_flavor_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack id: 
$os_image_id or flavor id: $os_flavor_id");
+               return 0;
+       }
+       my $imagerevision_id = $self->data->get_imagerevision_id();
+       if (!defined($imagerevision_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the imagerevision 
id");
+               return 0;
+       }
+       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
+       my $os_project_id = $ENV{'OS_PROJECT_ID'};
+       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth 
info");
+               return 0;
+       }
+
+       my $ua = LWP::UserAgent->new();
+       my $res = $ua->get(
+               $os_compute_url . "/images/" . $os_image_id,
+               x_auth_token => $os_token,
+               x_auth_project_id => $os_project_id,
+       );
+       if (!$res->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack image 
info: " . join("\n", $res->content));
+               return 0;
+       }
+       my $os_image_details = $res->content;
+       if (!defined($os_image_details)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
+               return 0;
+       }
+
+       my $resp = $ua->get(
+               $os_compute_url . "/flavors/". $os_flavor_id,
+               x_auth_token => $os_token,
+               x_auth_project_id => $os_project_id,
+       );
+       if (!$resp->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack flavor 
info: " . join("\n", $resp->content));
+               return 0;
+       }
+       my $os_flavor_details = $resp->content;
+       if (!defined($os_flavor_details)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
+               return 0;
+       }
+
+       my $sql_statement = <<EOF;
+INSERT INTO
+openstackimagerevision (
+imagerevisionid, 
+imagedetails,
+flavordetails) 
+VALUES ( 
+       '$imagerevision_id',
+       '$os_image_details',
+       '$os_flavor_details')
+EOF
+
+       #notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
+       my $result = database_execute($sql_statement);
+
+       if (!defined($result)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to insert openstack image 
id");
+               return 0;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "successfully insert openstack image id");
+       sleep 5;
+       return 1;
+} ## end sub _insert_os_image_id
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _insert_os_instance_id
+
+ Parameters  : OpenStack instance id
+ Returns     : 1 or 0
+ Description : insert OpenStack instance id and corresponding computer id
+
+=cut
+
+sub _insert_os_instance_id {
+       my $self = shift;
+       my $os_instance_id = shift;
+       my $computer_id = $self->data->get_computer_id();
+       if (!defined($os_instance_id) || !defined($computer_id)) {
+               notify($ERRORS{'DEBUG'}, 0, "failed to get the openstack 
instance id: $os_instance_id or computer id: $computer_id");
+               return 0;
+       }
+
+       my $sql_statement = <<EOF;
+INSERT INTO
+openstackcomputermap (
+instanceid,
+computerid)
+VALUES
+('$os_instance_id', '$computer_id')
+EOF
+
+       #notify($ERRORS{'DEBUG'}, 0, "$sql_statement");
+       my $result = database_execute($sql_statement);
+       if (!defined($result)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to insert openstack 
instance id");
+               return 0;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "successfully insert openstack instance id 
and comptuer id");
+       sleep 5;
+       return 1;
+} ## end sub_insert_os_instance_id
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _post_os_create_image
+
+ Parameters  : OpenStack instance id
+ Returns     : 1 or 0
+ Description : capture OpenStack instance    
+
+=cut
+
+sub _post_os_create_image{
+       my $self = shift;
+       my $os_instance_id = shift;
+       if (!defined($os_instance_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack 
instance id");
+               return;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "os_instance_id: $os_instance_id in sub 
_post_os_create_image");
+       my $image_name = $self->data->get_image_name();
+       if (!defined($image_name)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
information from environment");
+               return;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "os_image_name: $image_name in sub 
_post_os_create_image");
+       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
+       my $os_project_id = $ENV{'OS_PROJECT_ID'};
+       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
information from environment");
+               return;
+       }
+
+       my $ua = LWP::UserAgent->new();
+       my $server_data = {
+               createImage =>  {
+                       name => $image_name,
+               }
+       };
+
+       my $res =  $ua->post(
+               $os_compute_url . "/servers/" . $os_instance_id . "/action",
+               content_type => 'application/json',
+               x_auth_token => $os_token,
+               content => to_json($server_data)
+       );
+
+       if (!$res->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute capture image: 
" . join("\n", $res->content));
+               return;
+       }
+
+       my $resp =  $ua->get(
+               $os_compute_url . "/images/detail", 
+               server => $os_instance_id,
+               content_type => 'application/json',
+               x_auth_project_id => $os_project_id,
+               x_auth_token => $os_token
+       );
+
+       if (!$resp->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get image info: " . 
join("\n", $resp->content));
+               return;
+       }
+
+       my $output = from_json($resp->content);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
+               return;
+       }
+       my $os_image_id = $output->{images}[0]{id};
+       if (!defined($os_image_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to capture instance of 
$os_instance_id");
+               return;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "openstack image id for caputed instance of 
$os_instance_id is $os_image_id");
+       return $os_image_id;
+} ## end sub _post_os_create_image
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _post_os_create_instance
+
+ Parameters  : None
+ Returns     : 1 or 0
+ Description : create an OpenStack instance    
+
+=cut
+
+sub _post_os_create_instance {
+       my $self = shift;
+       
+       my $imagerevision_id = $self->data->get_imagerevision_id() || return;
+       my $computer_name  = $self->data->get_computer_short_name() || return;
+       my $image_os_type  = $self->data->get_image_os_type() || return;
+       my $os_project_id = $ENV{'OS_PROJECT_ID'};
+       my $os_key_name = $ENV{'VCL_LINUX_KEY'};        
+       if (!defined($os_project_id) || !defined($os_key_name)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack 
project id or key name");
+               return;
+       }
+       if ($image_os_type eq 'linux') {
+               $os_key_name =  $ENV{'VCL_LINUX_KEY'};  
+               notify($ERRORS{'OK'}, 0, "The $os_key_name is the key for Linux 
(default)");
+       } 
+       elsif ($image_os_type eq 'windows') {
+               $os_key_name =  $ENV{'VCL_WINDOWS_KEY'};        
+               notify($ERRORS{'OK'}, 0, "The $os_key_name is the key for 
Windows");
+       }
+
+       my $os_image_id = _get_os_image_id($imagerevision_id);
+       if (!defined($os_image_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack 
image id");
+               return;
+       }
+
+       my $os_flavor_id = _get_os_flavor_id($imagerevision_id);
+       if (!$os_flavor_id) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack 
flavor id");
+               return;
+       }
+
+       my $ua = LWP::UserAgent->new();
+       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
+       my $server_data = {
+               server =>  {
+                       name => $computer_name,
+                       imageRef => $os_image_id,
+                       key_name => $os_key_name,
+                       flavorRef => $os_flavor_id
+               }
+       };
+
+       my $resp =  $ua->post(
+               $os_compute_url . "/servers",
+               content_type => 'application/json',
+               x_auth_token => $os_token,
+               x_auth_project_id => $os_project_id,
+               content => to_json($server_data)
+       );
+
+       if (!$resp->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute run instance: 
" . join("\n", $resp->content));
+               return;
+       }
+
+       my $output = from_json($resp->content);
+       notify($ERRORS{'DEBUG'}, 0, "create_instance output: $output");
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to parse json output");
+               return;
+       }
+       my $os_instance_id = $output->{'server'}{'id'};
+       if (!defined($os_instance_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command to get 
the instance id on $computer_name");
+               return;
+       }
+
+       if (!$self->_insert_os_instance_id($os_instance_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to insert the instance id 
: $os_instance_id");
+               return; 
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "The create_instance: $os_instance_id\n");
+       return $os_instance_id;
+} ## end sub _post_os_create_instance
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _prepare_capture
+
+ Parameters  : None
+ Returns     : 1 or 0
+ Description : prepare capturing instance     
+
+=cut
+
+sub _prepare_capture {
+       my $self = shift;
+       
+       my ($package, $filename, $line, $sub) = caller(0);
+       my $request_data = $self->data->get_request_data();
+       if (!$request_data) {
+               notify($ERRORS{'WARNING'}, 0, "unable to retrieve request data 
hash");
+               return 0;
+       }
+       my $computer_name = $self->data->get_computer_short_name();
+       if (!defined($computer_name)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get computer name");
+               return 0;
+       }
+
+       if (!$self->data->set_imagemeta_sysprep(0)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to set the imagemeta 
Sysprep value to 0");
+               return 0;
+       }
+
+       if ($self->os->can("pre_capture")) {
+               notify($ERRORS{'OK'}, 0, "calling OS module's pre_capture() 
subroutine");
+
+               if (!$self->os->pre_capture({end_state => 'on'})) {
+                       notify($ERRORS{'WARNING'}, 0, "OS module pre_capture() 
failed");
+                       return 0;
+               }
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "pre_capture() is done");
+       return 1;
+} ## end sub _prepare_capture
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _set_os_auth_conf 
+
+ Parameters  : None 
+ Returns     : 1(success) or 0(failure)
+ Description : load openstack environment profile and set global environemnt 
variables 
+
+example: openstack.conf
+"os_tenant_name" => "admin",
+"os_username" => "admin",
+"os_password" => "adminpassword",
+"os_auth_url" => "http://openstack_nova_url:5000/v2.0";,
+"os_service_name" => "nova",
+"vcl_windows_key" => "vcl_windows_key",
+"vcl_linux_key" => "vcl_linux_key",
+
+=cut
+
+sub _set_os_auth_conf {
+       my $self = shift;
+       # User's environment file
+       my $user_config_file = '/etc/vcl/openstack/openstack.conf';
+       my %config = do($user_config_file);
+       if (!%config) {
+               notify($ERRORS{'WARNING'},0, "failure to process 
$user_config_file");
+               return;
+       }
+       $self->{config} = \%config;
+       my $os_auth_url = $self->{config}->{os_auth_url};
+       my $os_service_name = $self->{config}->{os_service_name};
+       my $os_project_id = $self->{config}->{os_project_id};
+       my $os_tenant_name = $self->{config}->{os_tenant_name};
+       my $os_username = $self->{config}->{os_username};
+       my $os_password = $self->{config}->{os_password};
+       my $vcl_windows_key = $self->{config}->{vcl_windows_key};
+       my $vcl_linux_key = $self->{config}->{vcl_linux_key};
+
+       # Set Environment File
+       $ENV{'OS_AUTH_URL'} = $os_auth_url;
+       $ENV{'OS_SERVICE_NAME'} = $os_service_name;
+       $ENV{'OS_PROJECT_ID'} = $os_project_id;
+       $ENV{'OS_TENANT_NAME'} = $os_tenant_name;
+       $ENV{'OS_USERNAME'} = $os_username;
+       $ENV{'OS_PASSWORD'} = $os_password;
+       $ENV{'VCL_WINDOWS_KEY'} = $vcl_windows_key;
+       $ENV{'VCL_LINUX_KEY'} = $vcl_linux_key;
+
+       return 1;
+}# end sub _set_os_auth_conf
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _terminate_os_instance
+
+ Parameters  : None
+ Returns     : 1 or 0
+ Description : terminate an OpenStack instance    
+
+=cut
+
+sub _terminate_os_instance {
+       my $self = shift;
+
+       my $computer_name = $self->data->get_computer_short_name() || return 0;
+               
+       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
+       my $os_project_id = $ENV{'OS_PROJECT_ID'};
+       my $os_instance_id = $self->_get_os_instance_id();
+       if (!defined($os_token) || !defined($os_compute_url) || 
!defined($os_project_id) || !defined($os_instance_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth 
info");
+               return 0;
+       }
+
+       my $ua = LWP::UserAgent->new();
+       my $resp =  $ua->delete(
+               $os_compute_url . "/servers/" . $os_instance_id,
+               x_auth_token => $os_token
+       );
+       if (!$resp->is_success) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute terminate 
instance: " . join("\n", $resp->content));
+               return 0;
+       }
+
+       sleep 30;
+       return 1;
+} ## end sub _terminate_os_instance
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _update_os_instance
+
+ Parameters  : OpenStack instance id
+ Returns     : 1 or 0
+ Description : update the private ip address of the OpenStack instance in 
database 
+
+=cut
+
+sub _update_private_ip {
+       my $self = shift;
+       
+       my $os_instance_id = shift;
+       my $computer_id = $self->data->get_computer_id() || return 0;
+       my $computer_name  = $self->data->get_computer_short_name() || return 0;
+       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
+       if (!defined($os_instance_id) || !defined($os_token) || 
!defined($os_compute_url)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get the openstack auth 
info");
+               return 0;
+       }
+       my $ua = LWP::UserAgent->new();
+       my ($private_ip, $output, $resp);
+       my $main_loop = 60;
+
+       # Find the correct instance among running instances using the private IP
+       while ($main_loop > 0) {
+               notify($ERRORS{'DEBUG'}, 0, "try to fetch the private IP 
address for $computer_name, loop of $main_loop");      
+               $resp =  $ua->get(
+                       $os_compute_url . "/servers/" . $os_instance_id,
+                       x_auth_token => $os_token
+               );
+               if (!$resp->is_success) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to execute 
instance detail: " . join("\n", $resp->content));
+                       return 0;
+               }
+
+               $output = from_json($resp->content);
+               if (!defined($output)) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to parse json 
output");
+                       return 0;
+               }
+               $private_ip = 
$output->{'server'}{'addresses'}{'private'}[0]->{'addr'};
+
+               if (defined($private_ip)) {
+                       my $result = 
update_computer_private_ip_address($computer_id, $private_ip);
+                       if (!defined($result)) {
+                               notify($ERRORS{'WARNING'}, 0, "The $private_ip 
on Computer $computer_name is NOT updated");
+                               return 0;
+                       }
+                       notify($ERRORS{'DEBUG'}, 0, "private IP address is 
$private_ip for $computer_name");
+                       sleep 10;
+                       return 1;
+               }
+               else {
+                       notify($ERRORS{'DEBUG'}, 0, "waiting for assinging 
private IP address to $computer_name");
+               }
+               
+               sleep 20;
+               $main_loop--;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "private IP address for $computer_name is 
not determined");
+       return 0;
+} ## end sub _update_private_ip
+
+#//////////////////////////////////////////////////////////////////////////////
+
+=head2 _wait_for_copying_image
+
+ Parameters  : OpenStack image id
+ Returns     : 1 or 0
+ Description : wait for copying the OpenStack image to repository
+
+=cut
+
+sub _wait_for_copying_image {
+       my $self = shift;
+       
+       my $os_image_id = shift;
+       my ($os_token, $os_compute_url) = $self->_get_os_token_compute_url();
+       my $os_project_id = $ENV{'OS_PROJECT_ID'};
+       if (!defined($os_image_id) || !defined($os_token) || 
!defined($os_compute_url) || !defined($os_project_id)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to get openstack auth 
info or image id: $os_image_id");
+               return 0;
+       }
+       my $ua = LWP::UserAgent->new();

[... 50 lines stripped ...]

Reply via email to