#!/usr/bin/perl # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos720 src/bos/usr/lpp/bosinst/samples/AE/AE/ActivateVM.pl 1.1 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2008,2009 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#)23 1.1 src/bos/usr/lpp/bosinst/samples/AE/AE/ActivateVM.pl, bosinst, bos720 3/29/09 15:19:55 #----------------------include--------------------# use XML::LibXML; use File::Basename; #----------------------include--------------------# # ## This script - ActiveVM is executed by AE service ## and reads parameters from ovf-env.xml or *.ap. ## This script is called with three command line ## arguments. The first is the AE path, the second ## is the resource name, and the third is the ## config name. For example, a valid call to this ## would be: ## perl ActivateVM /opt/IBM/AE SUSE_V10 ConfigNET # #-------------------main process------------------# # get parameters $AEPATH = $ARGV[0]; $RESOURCENAME = $ARGV[1]; $CONFNAME = $ARGV[2]; $LOCKFILE = "/var/lock/ActiveVM"; # AE's subdirectories $APPATH="${AEPATH}/AP"; $ALPATH="${AEPATH}/AL"; $ARPATH="${AEPATH}/AR"; $AL="${AEPATH}/AL/master.al"; my $NS_URI = 'http://schemas.dmtf.org/ovf/environment/1'; if ((! -e '/var/lock') && (-e '/var/locks')) { $LOCKFILE = "/var/locks/ActiveVM"; } while ( -e $LOCKFILE ) { sleep 1; } system("touch $LOCKFILE"); #Create a lockfile to prevent another process read and write the same file. my $APNAME; # find the ovf-env.xml or the *.ap file if( ($APNAME=findAPFile($APPATH )) ne "")# First find the AP file in the AP directory { print("found $APNAME in directory $APPATH \n"); } elsif(($APNAME=findAPFile("/media/floppy")) ne "")# If not found the AP file, try the floppy { print("found $APNAME on sencondary slave /media/floppy \n"); } elsif(($APNAME=findAPFile("/dev/hdd")) ne "")# If not found , try /dev/hdd { print("found $APNAME on sencondary slave /dev/hdd \n"); } elsif(($APNAME=findAPFile("/dev/hdc")) ne "")# If not found, try /dev/hdc { print("found $APNAME on second master /dev/hdc \n"); } elsif(($APNAME=findAPFile("/dev/hdb")) ne "")# If not found, try /dev/hdb { print("found $APNAME on primary slave /dev/hdb \n"); } elsif(($APNAME=findAPFile("/dev/hdb1")) ne "")# Check /dev/hdb1, if still no AP file found { print("found $APNAME on partition /dev/hdb1 \n"); } elsif(($APNAME=findAPFile("/dev/hda")) ne "")# Check /dev/hdb1, if still no AP file found { print("found $APNAME on partition /dev/hdb1 \n"); } elsif(($APNAME=findAPFile("/dev/cdrom")) ne "")# Check cdrom, if still no AP file found { print("found $APNAME in /dev/cdrom \n"); } elsif(($APNAME=findAPFileInScsiDevice()) ne "")# Check scsi devices for .ibm directory { print("found $APNAME scsi disk \n"); } my $AP="$APPATH" ."/" ."$APNAME"; unlink($LOCKFILE); # Remove the lockfile if ( ! -f "$AP") { # No ap file found, exit. die "AP file is not found. \n"; } # The following code processes the first AL file found #$AL=`find $ALPATH -name "*.al" -print`; #$AL=~s/\n$//; if ( ! -e "$AL" ) { die "AL file ($AL) is not found. \n"; } # Create AR file - this is the activation result log $vmInstance = &getVMInstance(); $AR=$ARPATH."/".$vmInstance.".ar"; if( ! -e "$AR") { &createARFile(); } %alParam = &getScriptFromAL(); $RESOURCE = $alParam{"resource"}; $CONFIG = $alParam{"config"}; $SCRIPT = $alParam{"script"}; if ( $RESOURCE eq "" or $CONFIG eq "" or $SCRIPT eq "" ) { die "cannot find resource \"$RESOURCE\" or config class \"$CONFIG\" or script \"$SCRIPT\" in $AL"; } # Read parameters from ovf-env.xml and if not found ofv-xnv.xml try the *.ap file if( $AP=~/ovf-env.xml/) { $apParam = &getParamFromOVFAP(); } else { $apParam = &getParamFromAP(); } $arStatus = &getStatusFromAR(); #get the status of *.ar file if ( $apParam ne "" and $arStatus eq "NO" ) { $logFile = &executeScript($SCRIPT, $apParam); if($CONFNAME eq "ConfigDisk" && $RESOURCENAME eq "VirtualDisk") { &createARFile(); } &updateARStatus($logFile); } else { print "$RESOURCENAME $CONFNAME: Skip Activation\n"; } ################################### #-------------------main process------------------# #--------------subfunction definition-------------# # If find ovf-env.xml,get vmInstance from the id attribute of the root Environment element # else get vmInstance from the name attribute sub getVMInstance { my $vmInstance = ""; if($AP=~/ovf-env.xml/) { my $envDoc = openXMLFile($AP); my $rootElement = $envDoc->getDocumentElement(); $vmInstance = $rootElement->getAttributeNode("id")->getValue(); } else { # my $tmpStr=`cat $AP|grep -P 'virtual-image\\s+name'`; # -P option not supported on AIX my $tmpStr=`cat $AP|grep 'virtual-image[ \t][ \t]*name'`; $tmpStr=~s|name=\"(.*?)\"||; $vmInstance=$1; } if(not defined($vmInstance)) { exit -1; } return $vmInstance; } # get AS file's scriptType sub getScriptType { my ($scriptpath) = @_; my $rc = ''; my @types = `grep '#!/' $scriptpath`; if ($#types >= 0) { if ($types[0] =~ m/\/perl/) { $rc = 'pl'; } elsif (($types[0] =~ m/\/sh/) || ($types[0] =~ m/\/ksh/)) { $rc = 'sh'; } } return $rc; } # get AS file's prefixName sub getPrefixName { my($scriptpath)=@_; my ($filename, $dirs, $suffix) = fileparse($scriptpath); return $filename; } sub createARFile { open(RAL, "<$AL") || die "cannot open $AL"; open(WAR, ">$AR") || die "cannot open $AR"; while ($line = ) { if ( $line =~ m/\n"; print WAR $tmp; } elsif ( $line =~ m//) { next; } else { print WAR $line; } } close(RAL); close(WAR); } sub openXMLFile { my($fpath)=@_; my $parser=new XML::LibXML(); my $ldoc; chomp($fpath); $ldoc=eval { $parser->parse_file($fpath); }; $ldoc || die "can not open the file ".$fpath."\n"; return $ldoc; } # get resource name, configuration name and script path from AL file sub getScriptFromAL { my $alDoc = openXMLFile($AL); my %alParam = (); my $resrcName = ""; my $confName = ""; my $scriptPath = ""; my @resourceNodes = $alDoc->getElementsByTagName("software-resource"); foreach my $resourceNode (@resourceNodes) { $resrcName = $resourceNode->getAttributeNode("name")->getValue(); if ( $resrcName eq $RESOURCENAME ) { my @configNodes = $resourceNode->childNodes(); foreach my $configNode (@configNodes) { if ($configNode->nodeName() ne "configuration") { next; } $confName = $configNode->getAttributeNode("name")->getValue(); if( $confName eq $CONFNAME ) { my @paramNodes = $configNode->childNodes(); foreach my $paramNode (@paramNodes) { my $name = $paramNode->nodeName(); if ($name eq 'script') { $scriptPath = $paramNode->getAttributeNode("file")->getValue(); } } %alParam = ("resource", "$resrcName", "config", "$confName", "script", "$scriptPath"); last; } } } } return %alParam; } # If exists ovf-env.xml file, get parameters using this method sub getParamFromOVFAP { my $apDoc = openXMLFile($AP); my $paramStr = ""; my $resrcName = ""; my $confName = ""; my $scriptPath = ""; my $rootElement = $apDoc->getDocumentElement(); $rootElement->setNamespace($NS_URI, 'default_ns', 1); $rootElement->setNamespace($NS_URI, 'ovfenv_ns', 1); # xpath = //PropertySection/Property[@ovfenv:key='ConfigWAS.password'][@ovfenv:value] my $xpath_expression = "//default_ns:PropertySection/default_ns:Property[\@ovfenv_ns:key][\@ovfenv_ns:value]"; my @nodes = $rootElement->findnodes($xpath_expression); # log_printf("\tchecking %d nodes\n", $#nodes + 1); foreach my $node (@nodes) { my $key_attr_node = $node->getAttributeNodeNS($NS_URI, 'key'); if ($key_attr_node) { my $key = $key_attr_node->getValue(); if($key =~ m/\.$CONFNAME\./) { $key = substr($key, rindex($key, ".") + 1); my $value_attr_node = $node->getAttributeNodeNS($NS_URI, 'value'); my $value = ''; if ($value_attr_node) { $value = $value_attr_node->getValue(); } print "Property Key is \" $key\". \n"; print "Property Value is \" $value\". \n"; $paramStr = "$paramStr -$key \"$value\""; } } } return $paramStr; } # If not found the ovf-env.xml, get parameters from *AP file using this method sub getParamFromAP { my $apDoc = openXMLFile($AP); my $paramStr = ""; my $resrcName = ""; my $confName = ""; my $scriptPath = ""; my @resourceNodes = $apDoc->getElementsByTagName("software-resource"); foreach my $resourceNode (@resourceNodes) { $resrcName = $resourceNode->getAttributeNode("name")->getValue(); if ( $resrcName eq $RESOURCENAME ) { my @configNodes = $resourceNode->childNodes(); foreach my $configNode (@configNodes) { if ($configNode->nodeName() ne "configuration") { next; } $confName = $configNode->getAttributeNode("name")->getValue(); if( $confName eq $CONFNAME ) { my @paramNodes = $configNode->childNodes(); foreach my $paramNode (@paramNodes) { my $name = $paramNode->nodeName(); if ($name ne "parameter") { next; } $paramName = $paramNode->getAttributeNode("name")->getValue(); $paramValue = $paramNode->getAttributeNode("value")->getValue(); $paramStr = "$paramStr -$paramName \"$paramValue\""; } last; } } } } return $paramStr; } # get scripts execution status. if scripts wasn't executed yet, status should be "NO" sub getStatusFromAR { my $arDoc = openXMLFile($AR); my $status = "NO"; my $nodeName = ""; my @resourceNodes = $arDoc->getElementsByTagName("software-resource"); foreach my $resourceNode (@resourceNodes) { $resrcName = $resourceNode->getAttributeNode("name")->getValue(); if ( $resrcName eq $RESOURCENAME ) { my @configNodes = $resourceNode->childNodes(); foreach my $configNode (@configNodes) { if ($configNode->nodeName() ne "configuration") { next; } $confName = $configNode->getAttributeNode("name")->getValue(); if( $confName eq $CONFNAME ) { my @paramNodes = $configNode->childNodes(); foreach my $paramNode (@paramNodes) { my $name = $paramNode->nodeName(); if ($name eq 'execution') { $status = $paramNode->getAttributeNode("status")->getValue(); } } last; } } } } return $status; } # execute script with parameters, stderr and stdout are being captured # and redirected into an activation results log file in the AR directory sub executeScript { my($script, $param) = @_; my $prefixName = getPrefixName($script); my $scriptType = &getScriptType($script); my $logFile = "${ARPATH}/${prefixName}.log"; my $fullScriptPath=""; chomp($prefixName); chomp($scriptType); chomp($script); # find whether $script stands for an absolute path or not if($script=~/^\s*(\/.*)$/) { $fullScriptPath=$1; } else { $fullScriptPath="$AEPATH/$script"; } #determine the kind of the executable script--shell or perl if ($scriptType eq "pl") { print "perl $fullScriptPath $param\n"; system "perl $fullScriptPath $param 1>${ARPATH}/${prefixName}.log 2>&1"; } elsif ($scriptType eq "sh") { print "sh $fullScriptPath $param\n"; system "sh $fullScriptPath $param 1>${ARPATH}/${prefixName}.log 2>&1"; } else { print "$scriptType is not supported. \n"; } return $logFile; } # update execution status in AR sub updateARStatus { my ($logFile)=@_; my $flag = 0; open(RAR, "<$AR") || die "cannot open $AR"; open(WTMP, ">${AR}.tmp") || die "cannot open ${AR}.tmp"; while ($line = ) { if ( $line =~ m/$SCRIPT/ ) { my $tmp_status = "\t\t\t\n"; #Change the status of the AR file. my $tmp_log = "\t\t\t\n"; print WTMP $line; print WTMP $tmp_status; print WTMP $tmp_log; $flag = 1; } elsif ( $line =~ m/