Author: bmbouter
Date: Fri Jan 30 18:42:13 2009
New Revision: 739371

URL: http://svn.apache.org/viewvc?rev=739371&view=rev
Log:
VCL-29

An working alpha version of the esx provsioning module.  Includes instructions 
in the esx.README file


Added:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.README
    incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.pm

Added: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.README
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.README?rev=739371&view=auto
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.README 
(added)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.README 
Fri Jan 30 18:42:13 2009
@@ -0,0 +1,86 @@
+Pre-Installation:
+
+You need to install the VMware VI Perl toolkit installed on the VCL server
+
+Each vmware esx hypervisor requires a mounted NFS datastore named 'VCL'
+
+This same datastore needs to be mounted on the VCL server at /mnt/vcl/
+
+This NFS export needs to be exported (from the NFS server) at /mnt/export/
+
+This same datastore requires the following structure.
+
+[VCL]
+       /inuse  (required)
+       /golden  (required)
+               /imagename
+                       imagename.vmdk
+                       imagename-flat.vmdk
+               ...
+
+Image requirements:
+       All images used by this module must have names that begin with 
esx3-<anything you want>
+       ssh must be set to start on boot
+       ssh keys must be setup so that VCL can ssh into it
+       The image needs two NICs (eth0 is private, eth1 is public)
+       The IP addressing of the private (eth1) interface must be set to DHCP 
on boot
+
+
+VCL expects the blades to have a consistant private IP address.  Go configure 
dhcpd.conf and in /etc/hosts manually
+
+
+Customize the module:
+
+This module expects the following three variables to be hard-coded at the top 
of the esx.pm file.  Remember to character escape any special characters.
+
+$vmhost_username, $vmhost_password, $datastore_ip
+
+A note about datastore_ip.  Because the module ssh's to the storage system 
directly instead of doing a cp over nfs, you need to set the IP of the 
datastore here.  The datastore machine should be setup with SSH keys from the 
VCL ssh keys set as IDENTITY_blade_linux in the VCL conf file.
+
+Install the module:
+
+Do these once:
+1)  Insert a row into the module table with `perlpackage` equal to 
'VCL::Module::Provisioning::esx'
+2)  Insert a row into the provisioning table with `moduleid` equal to the id 
of the entry from step 1 in the module table
+3)  Insert a record into the 'vmprofile' table with the following guidelines
+       profilename: VMware ESX SAN
+       vmtypeid: link to anything valid ID from the vmtype table.
+       imageid: link to the "No Image" id in the image table
+       virtualswitch0: <name of your private virtual machine port group> 
+       virtualswitch1: <name of your public virtual machine port group>
+
+Make VCL aware of your ESX hosts:
+1)  For each esx hypervisor, which VCL should provisong virtual machine to, 
create an entry for that hypervisor by going to Manage Computers -> Edit 
Computer Information -> Add
+       Hostname <your ESX's hostname>
+       IP <your ESX's IP>
+       Type "blade"
+       Provisioning Engine:  This doesn't matter
+       Computer Groups:  Don't add the hypervisors to any computer groups
+
+2)  For each esx hypervisor manually create an entry in the 'vmhost' database 
table with the following guidelines:
+       computerid: the id of the computer created in step 1
+       vmlimit: the max number of vms to have on this hypervisor
+       vmprofileid: the id of the vmprofile entry created in the "Do these 
once" secion step 3
+
+Create a virtual machine placeholder for each VM you would like to 
concurrently run.  Do so by going to Manage Computers -> Edit Computer 
Information -> Add
+       Hostname: <the hostname of the vm when it is provisioned and turned on>
+       IP: <the public IP of the vm when it is provisioned and turned on>
+       Type: virtualmachine
+       Provisioning Engine: VMware ESX
+       Computer Groups:  allComputers
+
+For each virtual machine, manually update the private IP, eth0macaddress 
(private), and eth1macaddress (public) for the placeholder virtual machine 
entries created in in the computers table during step (4)
+
+Add static entries in dhcpd.conf for the eth0macaddresses (private) for all 
computer placeholder entries
+
+Add similar entries for each compter placeholder to the /etc/hosts file to 
provide VCL with name resolution on these vms
+
+Finally, once all virtual machines placeholders have been created, 'assign' 
them to hypervisors by using the 'Virtual Hosts' area of your web interface.
+
+Now your hypervisors and virtual machines are setup, time to add an image:
+
+1)  Create an entry in the image table.
+       name:  esx3-<what you want>-v0
+       OSid:  link to the fc9 entry on the OS table
+2)  Create an image revision table with the imageid fromt the entry created in 
(1) and the imagename used in (1)
+3)  Add the image revision to the allImages and allVMimages groups
\ No newline at end of file

Added: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.pm?rev=739371&view=auto
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.pm 
(added)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/esx.pm Fri 
Jan 30 18:42:13 2009
@@ -0,0 +1,592 @@
+#!/usr/bin/perl -w
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+##############################################################################
+# $Id: vmware.pm 1953 2008-12-12 14:23:17Z arkurth $
+##############################################################################
+
+=head1 NAME
+
+VCL::Provisioning::esx - VCL module to support the vmware esx provisioning 
engine
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides VCL support for vmware server
+ http://www.vmware.com
+
+=cut
+
+##############################################################################
+package VCL::Module::Provisioning::esx;
+
+# 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 = '1.00';
+
+# Specify the version of Perl to use
+use 5.008000;
+
+use strict;
+use warnings;
+use diagnostics;
+
+use VCL::utils;
+use Fcntl qw(:DEFAULT :flock);
+
+##############################################################################
+
+=head1 CLASS ATTRIBUTES
+
+=cut
+
+=head2 %VMWARE_CONFIG
+
+ Data type   : hash
+ Description : %VMWARE_CONFIG is a hash containing the general VMWARE 
configuration
+               for the management node this code is running on. Since the data 
is
+                                       the same for every instance of the 
VMWARE class, a class attribute
+                                       is used and the hash is shared among 
all instances. This also
+                                       means that the data only needs to be 
retrieved from the database
+                                       once.
+
+=cut
+
+#my %VMWARE_CONFIG;
+
+# Class attributes to store VMWWARE configuration details
+# This data also resides in the %VMWARE_CONFIG hash
+# Extract hash data to scalars for ease of use
+my $IMAGE_LIB_ENABLE  = $IMAGELIBENABLE;
+my $IMAGE_LIB_USER    = $IMAGELIBUSER;
+my $IMAGE_LIB_KEY     = $IMAGELIBKEY;
+my $IMAGE_LIB_SERVERS = $IMAGESERVERS;
+
+##############################################################################
+
+=head1 OBJECT METHODS
+
+=cut
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 initialize
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub initialize {
+       notify($ERRORS{'DEBUG'}, 0, "vmware ESX module initialized");
+       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;
+
+       #check to make sure this call is for the esx module
+       if (ref($self) !~ /esx/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+
+       my $request_data = shift;
+       my ($package, $filename, $line, $sub) = caller(0);
+       notify($ERRORS{'DEBUG'}, 0, 
"****************************************************");
+
+       # get various useful vars from the database
+       my $request_id     = $self->data->get_request_id;
+       my $reservation_id = $self->data->get_reservation_id;
+       my $vmhost_hostname           = $self->data->get_vmhost_hostname;
+       my $image_name     = $self->data->get_image_name;
+       my $computer_shortname  = $self->data->get_computer_short_name;
+       my $vmclient_computerid = $self->data->get_computer_id;
+       my $vmclient_imageminram      = $self->data->get_image_minram;
+       my $image_os_name  = $self->data->get_image_os_name;
+       my $image_identity = $self->data->get_image_identity;
+
+       my $virtualswitch0    = $self->data->get_vmhost_profile_virtualswitch0;
+       my $virtualswitch1    = $self->data->get_vmhost_profile_virtualswitch1;
+       my $vmclient_eth0MAC          = 
$self->data->get_computer_eth0_mac_address;
+       my $vmclient_eth1MAC          = 
$self->data->get_computer_eth1_mac_address;
+       my $vmclient_OSname           = $self->data->get_image_os_name;
+
+       #eventually get these from a config file or database
+       my $vmhost_username = "";
+       my $vmhost_password = "";
+       my $datastore_ip = "";
+
+       notify($ERRORS{'OK'}, 0, "Entered ESX module, loading $image_name on 
$computer_shortname (on $vmhost_hostname) for reservation $reservation_id");
+
+       my $datastorepath4vmx = "/mnt/vcl/inuse/$computer_shortname";
+
+       # query the host to see if the vm currently exists
+       my $vminfo_command = "/usr/lib/vmware-viperl/apps/vm/vminfo.pl";
+       $vminfo_command .= " --server '$vmhost_hostname'";
+       $vminfo_command .= " --vmname $computer_shortname";
+       $vminfo_command .= " --username $vmhost_username";
+       $vminfo_command .= " --password '$vmhost_password'";
+       notify($ERRORS{'DEBUG'},0,"VM info command: $vminfo_command");
+       my $vminfo_output;
+       $vminfo_output = `$vminfo_command`;
+       notify($ERRORS{'DEBUG'},0,"VM info output: $vminfo_output");
+
+       # parse the results from the host and determine if we need to remove an 
old vm
+       if ($vminfo_output =~ /^Information of Virtual Machine 
$computer_shortname/m) {
+               # Turn new vm on
+               my $poweroff_command = 
"/usr/lib/vmware-viperl/apps/vm/vmcontrol.pl";
+               $poweroff_command .= " --server '$vmhost_hostname'";
+               $poweroff_command .= " --vmname $computer_shortname";
+               $poweroff_command .= " --operation poweroff";
+               $poweroff_command .= " --username $vmhost_username";
+               $poweroff_command .= " --password '$vmhost_password'";
+               notify($ERRORS{'DEBUG'},0,"Power off command: 
$poweroff_command");
+               my $poweroff_output;
+               $poweroff_output = `$poweroff_command`;
+               notify($ERRORS{'DEBUG'},0,"Powered off: $poweroff_output");
+
+               # unregister old vm from host
+               my $unregister_command = 
"/usr/lib/vmware-viperl/apps/vm/vmregister.pl";
+               $unregister_command .= " --server '$vmhost_hostname'";
+               $unregister_command .= " --username $vmhost_username";
+               $unregister_command .= " --password '$vmhost_password'";
+               $unregister_command .= " --vmxpath 
'[VCL]/inuse/$computer_shortname/$image_name.vmx'";
+               $unregister_command .= " --operation unregister";
+               $unregister_command .= " --vmname $computer_shortname";
+               $unregister_command .= " --pool Resources";
+               $unregister_command .= " --hostname '$vmhost_hostname'";
+               $unregister_command .= " --datacenter 'ha-datacenter'";
+               my $unregister_output;
+               $unregister_output = `$unregister_command`;
+               notify($ERRORS{'DEBUG'}, 0, "Un-Registered: 
$unregister_output");
+
+               my $remove_vm_output = `rm -rf $datastorepath4vmx`;
+               notify($ERRORS{'DEBUG'}, 0, "Output from remove command is: 
$remove_vm_output");
+       }
+
+       # copy appropriate vmdk file
+       my $newdir = $datastorepath4vmx;
+       if (!mkdir($newdir)) {
+               notify($ERRORS{'CRITICAL'}, 0, "Could not create new directory: 
$!");
+               return 0;
+       }
+       my $from = "/mnt/vcl/golden/$image_name/$image_name.vmdk";
+       my $to = "$datastorepath4vmx/$image_name.vmdk";
+       if (!copy($from, $to)) {
+               notify($ERRORS{'CRITICAL'}, 0, "Could not copy VMDK file! $!");
+               # insert load log here perhaps
+               return 0;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "COPIED VMDK SUCCESSFULLY");
+
+
+       # Copy the (large) -flat.vmdk file
+       # This uses ssh to do the copy locally on the nfs server.
+       $from = "/mnt/export/golden/$image_name/$image_name-flat.vmdk";
+       $to = "/mnt/export/inuse/$computer_shortname/$image_name-flat.vmdk";
+       my @copy_command = ("ssh", $datastore_ip, "-i", $image_identity, "-o", 
"BatchMode yes", "cp $from $to");
+       notify($ERRORS{'OK'}, 0, "SSHing to copy vmdk-flat file");
+       if (system(@copy_command) >> 8) {
+               notify($ERRORS{'CRITICAL'}, 0, "Could not copy VMDK-flat file! 
$!");
+               # insert load log here perhaps
+               return 0;
+       }
+
+       # Author new VMX file
+       my @vmxfile;
+       my $vmxpath = "$datastorepath4vmx/$image_name.vmx";
+
+       my $guestOS = "other";
+       $guestOS = "linux"   if ($image_os_name =~ /(fc|centos)/i);
+       # FIXME Should add some more entries here
+
+       # determine adapter type by looking at vmdk file
+       my $adapter = "lsilogic"; # default
+       if (open(RE, "grep adapterType $datastorepath4vmx/$image_name.vmdk 2>&1 
|")) {
+               my @LIST = <RE>;
+               close(RE);
+               foreach my $a (@LIST) {
+                       if ($a =~ /(ide|buslogic|lsilogic)/) {
+                               $adapter = $1;
+                               notify($ERRORS{'OK'}, 0, "adapter= $1 ");
+                       }
+               }
+       } ## end if (open(RE, "grep adapterType 
$VMWAREREPOSITORY/$image_name/$image_name.vmdk 2>&1 |"...
+
+       push(@vmxfile, "#!/usr/bin/vmware\n");
+       push(@vmxfile, "config.version = \"8\"\n");
+       push(@vmxfile, "virtualHW.version = \"4\"\n");
+       push(@vmxfile, "memsize = \"$vmclient_imageminram\"\n");
+       push(@vmxfile, "displayName = \"$computer_shortname\"\n");
+       push(@vmxfile, "guestOS = \"$guestOS\"\n");
+       push(@vmxfile, "uuid.action = \"create\"\n");
+       push(@vmxfile, "Ethernet0.present = \"TRUE\"\n");
+       push(@vmxfile, "Ethernet1.present = \"TRUE\"\n");
+
+       push(@vmxfile, "Ethernet0.networkName = \"$virtualswitch0\"\n");
+       push(@vmxfile, "Ethernet1.networkName = \"$virtualswitch1\"\n");
+       push(@vmxfile, "ethernet0.wakeOnPcktRcv = \"false\"\n");
+       push(@vmxfile, "ethernet1.wakeOnPcktRcv = \"false\"\n");
+
+       push(@vmxfile, "ethernet0.address = \"$vmclient_eth0MAC\"\n");
+       push(@vmxfile, "ethernet1.address = \"$vmclient_eth1MAC\"\n");
+       push(@vmxfile, "ethernet0.addressType = \"static\"\n");
+       push(@vmxfile, "ethernet1.addressType = \"generated\"\n");
+       push(@vmxfile, "gui.exitOnCLIHLT = \"FALSE\"\n");
+       push(@vmxfile, "snapshot.disabled = \"TRUE\"\n");
+       push(@vmxfile, "floppy0.present = \"FALSE\"\n");
+       push(@vmxfile, "priority.grabbed = \"normal\"\n");
+       push(@vmxfile, "priority.ungrabbed = \"normal\"\n");
+       push(@vmxfile, "checkpoint.vmState = \"\"\n");
+
+       push(@vmxfile, "scsi0.present = \"TRUE\"\n");
+       push(@vmxfile, "scsi0.sharedBus = \"none\"\n");
+       push(@vmxfile, "scsi0.virtualDev = \"$adapter\"\n");
+       push(@vmxfile, "scsi0:0.present = \"TRUE\"\n");
+       push(@vmxfile, "scsi0:0.deviceType = \"scsi-hardDisk\"\n");
+       push(@vmxfile, "scsi0:0.fileName =\"$image_name.vmdk\"\n");
+
+       #write to tmpfile
+       if (open(TMP, ">$vmxpath")) {
+               print TMP @vmxfile;
+               close(TMP);
+               notify($ERRORS{'OK'}, 0, "wrote vmxarray to $vmxpath");
+       }
+       else {
+               notify($ERRORS{'CRITICAL'}, 0, "could not write vmxarray to 
$vmxpath");
+               insertloadlog($reservation_id, $vmclient_computerid, "failed", 
"could not write vmx file to local tmp file");
+               return 0;
+       }
+
+       # Register new vm on host
+       my $register_command = "/usr/lib/vmware-viperl/apps/vm/vmregister.pl";
+       $register_command .= " --server '$vmhost_hostname'";
+       $register_command .= " --username $vmhost_username";
+       $register_command .= " --password '$vmhost_password'";
+       $register_command .= " --vmxpath 
'[VCL]/inuse/$computer_shortname/$image_name.vmx'";
+       $register_command .= " --operation register";
+       $register_command .= " --vmname $computer_shortname";
+       $register_command .= " --pool Resources";
+       $register_command .= " --hostname '$vmhost_hostname'";
+       $register_command .= " --datacenter 'ha-datacenter'";
+       my $register_output;
+       $register_output = `$register_command`;
+       notify($ERRORS{'DEBUG'}, 0, "Registered: $register_output");
+
+       # Turn new vm on
+       my $poweron_command = "/usr/lib/vmware-viperl/apps/vm/vmcontrol.pl";
+       $poweron_command .= " --server '$vmhost_hostname'";
+       $poweron_command .= " --vmname $computer_shortname";
+       $poweron_command .= " --operation poweron";
+       $poweron_command .= " --username $vmhost_username";
+       $poweron_command .= " --password '$vmhost_password'";
+       notify($ERRORS{'DEBUG'},0,"Power on command: $poweron_command");
+       my $poweron_output;
+       $poweron_output = `$poweron_command`;
+       notify($ERRORS{'DEBUG'},0,"Powered on: $poweron_output");
+
+
+       # Start waiting for SSH to come up
+       
+
+       my $sshdstatus = 0;
+       my $wait_loops = 0;
+       my $sshd_status = "off";
+       notify($ERRORS{'DEBUG'}, 0, "Waiting for ssh to come up on 
$computer_shortname");
+       while (!$sshdstatus) {
+               my $sshd_status = _sshd_status($computer_shortname, 
$image_name);
+               if ($sshd_status eq "on") {
+                       $sshdstatus = 1;
+                       notify($ERRORS{'OK'}, 0, "$computer_shortname now has 
active sshd running");
+               }
+               else {
+                       #either sshd is off or N/A, we wait
+                       if ($wait_loops > 24) {
+                                       notify($ERRORS{'CRITICAL'}, 0, "waited 
acceptable amount of time for sshd to become active, please check 
$computer_shortname on $vmhost_hostname");
+                                       #need to check power, maybe reboot it. 
for now fail it
+                                       return 0;
+                       }
+                       else {
+                               $wait_loops++;
+                               # to give post config a chance
+                               notify($ERRORS{'OK'}, 0, "going to sleep 5 
seconds, waiting for post config to finish. Try $wait_loops");
+                               sleep 5;
+                       }
+               }    # else
+       }    #while
+
+       # Set IP info
+       if ($IPCONFIGURATION ne "manualDHCP") {
+               #not default setting
+               if ($IPCONFIGURATION eq "dynamicDHCP") {
+                       insertloadlog($reservation_id, $vmclient_computerid, 
"dynamicDHCPaddress", "collecting dynamic IP address for node");
+                       notify($ERRORS{'DEBUG'}, 0, "Attempting to query 
vmclient for its public IP...");
+                       my $assignedIPaddress = 
getdynamicaddress($computer_shortname, $vmclient_OSname);
+                       if ($assignedIPaddress) {
+                               #update computer table
+                               notify($ERRORS{'DEBUG'}, 0, " Got dynamic 
address from vmclient, attempting to update database");
+                               if 
(update_computer_address($vmclient_computerid, $assignedIPaddress)) {
+                                       notify($ERRORS{'DEBUG'}, 0, " 
succesfully updated IPaddress of node $computer_shortname");
+                               }
+                               else {
+                                       notify($ERRORS{'CRITICAL'}, 0, "could 
not update dynamic address $assignedIPaddress for $computer_shortname 
$image_name");
+                                       return 0;
+                               }
+                       } ## end if ($assignedIPaddress)
+                       else {
+                               notify($ERRORS{'CRITICAL'}, 0, "could not fetch 
dynamic address from $computer_shortname $image_name");
+                               insertloadlog($reservation_id, 
$vmclient_computerid, "failed", "could not collect dynamic IP address for 
node");
+                               return 0;
+                       }
+               } ## end if ($IPCONFIGURATION eq "dynamicDHCP")
+               elsif ($IPCONFIGURATION eq "static") {
+                       notify($ERRORS{'CRITICAL'}, 0, "STATIC ASSIGNMENT NOT 
SUPPORTED. See vcld.conf");
+                       return 0;
+                       #insertloadlog($reservation_id, $vmclient_computerid, 
"staticIPaddress", "setting static IP address for node");
+                       #if (setstaticaddress($computer_shortname, 
$vmclient_OSname, $vmclient_publicIPaddress)) {
+                       #       # good set static address
+                       #}
+               }
+       } ## end if ($IPCONFIGURATION ne "manualDHCP")
+       return 1;
+
+} ## end sub load
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 capture
+
+ Parameters  : $request_data_hash_reference
+ Returns     : 1 if sucessful, 0 if failed
+ Description : Creates a new vmware image.
+
+=cut
+
+sub capture {
+       notify($ERRORS{'OK'}, 0, "Hello world, I am capturing an image now");
+       return 1;
+} ## end sub capture
+
+
+#/////////////////////////////////////////////////////////////////////////
+=head2 node_status
+
+ Parameters  : $nodename, $log
+ Returns     : array of related status checks
+ Description : checks on sshd, currentimage
+
+=cut
+
+sub node_status {
+       my $self = shift;
+
+       # Check if subroutine was called as a class method
+       if (ref($self) !~ /esx/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+
+       #my ($vmhash) = shift;
+
+       my ($package, $filename, $line, $sub) = caller(0);
+
+       # try to contact vm
+       # $self->data->get_request_data;
+       # get state of vm
+       my $vmpath             = $self->data->get_vmhost_profile_vmpath;
+       my $datastorepath      = $self->data->get_vmhost_profile_datastore_path;
+       my $requestedimagename = $self->data->get_image_name;
+       my $vmhost_type        = $self->data->get_vmhost_type;
+       my $vmhost_hostname    = $self->data->get_vmhost_hostname;
+       my $vmhost_imagename   = $self->data->get_vmhost_image_name;
+       my $vmclient_shortname = $self->data->get_computer_short_name;
+       my $request_forimaging              = 
$self->data->get_request_forimaging();
+
+       notify($ERRORS{'OK'}, 0, "Entering node_status, checking status of 
$vmclient_shortname");
+       notify($ERRORS{'DEBUG'}, 0, "request_for_imaging: $request_forimaging");
+       notify($ERRORS{'DEBUG'}, 0, "requeseted image name: 
$requestedimagename");
+
+       my ($hostnode, $identity);
+
+       # Create a hash to store status components
+       my %status;
+
+       # Initialize all hash keys here to make sure they're defined
+       $status{status}       = 0;
+       $status{currentimage} = 0;
+       $status{ping}         = 0;
+       $status{ssh}          = 0;
+       $status{vmstate}      = 0;    #on or off
+       $status{image_match}  = 0;
+
+       if ($vmhost_type eq "blade") {
+               $hostnode = $1 if ($vmhost_hostname =~ /([-_a-zA-Z0-9]*)(\.?)/);
+               $identity = $IDENTITY_bladerhel;    #if($vm{vmhost}{imagename} 
=~ /^(rhel|rh3image|rh4image|fc|rhfc)/);
+       }
+       else {
+               #using FQHN
+               $hostnode = $vmhost_hostname;
+               $identity = $IDENTITY_linux_lab if ($vmhost_imagename =~ 
/^(realmrhel)/);
+       }
+
+       if (!$identity) {
+               notify($ERRORS{'CRITICAL'}, 0, "could not set ssh identity 
variable for image $vmhost_imagename type= $vmhost_type host= 
$vmhost_hostname");
+       }
+
+       # Check if node is pingable
+       notify($ERRORS{'DEBUG'}, 0, "checking if $vmclient_shortname is 
pingable");
+       if (_pingnode($vmclient_shortname)) {
+               $status{ping} = 1;
+               notify($ERRORS{'OK'}, 0, "$vmclient_shortname is pingable 
($status{ping})");
+       }
+       else {
+               notify($ERRORS{'OK'}, 0, "$vmclient_shortname is not pingable 
($status{ping})");
+               $status{status} = 'RELOAD';
+               return $status{status};
+       }
+
+       #
+       #my $vmx_directory = "$requestedimagename$vmclient_shortname";
+       #my $myvmx         = 
"$vmpath/$requestedimagename$vmclient_shortname/$requestedimagename$vmclient_shortname.vmx";
+       #my $mybasedirname = $requestedimagename;
+       #my $myimagename   = $requestedimagename;
+
+       notify($ERRORS{'DEBUG'}, 0, "Trying to ssh...");
+
+       #can I ssh into it
+       my $sshd = _sshd_status($vmclient_shortname, $requestedimagename);
+
+
+       #is it running the requested image
+       if ($sshd eq "on") {
+
+               notify($ERRORS{'DEBUG'}, 0, "SSH good, trying to query image 
name");
+
+               $status{ssh}          = 1;
+               my $identity = $IDENTITY_bladerhel;
+               my @sshcmd = run_ssh_command($vmclient_shortname, $identity, 
"cat currentimage.txt");
+               $status{currentimage} = $sshcmd[1][0];
+
+               notify($ERRORS{'DEBUG'}, 0, "Image name: 
$status{currentimage}");
+
+               if ($status{currentimage}) {
+                       chomp($status{currentimage});
+                       if ($status{currentimage} =~ /$requestedimagename/) {
+                               $status{image_match} = 1;
+                               notify($ERRORS{'OK'}, 0, "$vmclient_shortname 
is loaded with requestedimagename $requestedimagename");
+                       }
+                       else {
+                               notify($ERRORS{'OK'}, 0, "$vmclient_shortname 
reports current image is currentimage= $status{currentimage} 
requestedimagename= $requestedimagename");
+                       }
+               } ## end if ($status{currentimage})
+       } ## end if ($sshd eq "on")
+
+       # 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");
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "returning node status hash reference 
(\$node_status->{status}=$status{status})");
+       return \%status;
+
+} ## end sub node_status
+
+sub does_image_exist {
+       my $self = shift;
+       if (ref($self) !~ /esx/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+
+       my $image_name = $self->data->get_image_name();
+       if (!$image_name) {
+               notify($ERRORS{'CRITICAL'}, 0, "unable to determine if image 
exists, unable to determine image name");
+               return 0;
+       }
+
+       my $IMAGEREPOSITORY = "/mnt/vcl/golden";
+
+       if (open(IMAGES, "/bin/ls -1 $IMAGEREPOSITORY 2>&1 |")) {
+               my @images = <IMAGES>;
+               close(IMAGES);
+               foreach my $i (@images) {
+                       if ($i =~ /$image_name/) {
+                               notify($ERRORS{'OK'}, 0, "image $image_name 
exists");
+                               return 1;
+                       }
+               }
+       } ## end if (open(IMAGES, "/bin/ls -1 $IMAGEREPOSITORY 2>&1 |"...
+
+       notify($ERRORS{'WARNING'}, 0, "image $IMAGEREPOSITORY/$image_name does 
NOT exists");
+       return 0;
+
+} ## end sub does_image_exist
+
+initialize();
+1;
+__END__
+
+=head1 BUGS and LIMITATIONS
+
+ There are no known bugs in this module.
+ Please report problems to the VCL team (vcl_h...@ncsu.edu).
+
+=head1 AUTHOR
+
+ Andrew Brown <ambro...@ncsu.edu>
+ Brian Bouterse <bmbou...@ncsu.edu>
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+=cut


Reply via email to