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 ([email protected]).
+
+=head1 AUTHOR
+
+ Andrew Brown <[email protected]>
+ Brian Bouterse <[email protected]>
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+=cut