Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > d236c5da97a239a1b6991cfba2865b66 > files > 92

cman-2.0.115-68.el5_6.1.src.rpm

From 0886ca800604fa1db013446af27ef715e7658952 Mon Sep 17 00:00:00 2001
From: Marek 'marx' Grac <mgrac@redhat.com>
Date: Sun, 20 Dec 2009 19:33:17 +0100
Subject: [PATCH] fencing: New fence agent for VMWare

Current version of vmware fence agent (techpreview) is not cluster aware. New
fence agent should support VMware ESX/ESXi/VC/Server 1/Server 2 and be cluster
aware. That will require that user must install VI Perl or VIX API to every
node which do fencing.

Resolve: rhbz#548577
---
 fence/agents/lib/fencing.py.py             |   51 ++--
 fence/agents/vmware/Makefile               |   17 +-
 fence/agents/vmware/fence_vmware.pl        |  337 ----------------------
 fence/agents/vmware/fence_vmware.py        |  426 ++++++++++++++++++++--------
 fence/agents/vmware/fence_vmware_helper.pl |  276 ++++++++++++++++++
 5 files changed, 619 insertions(+), 488 deletions(-)
 delete mode 100755 fence/agents/vmware/fence_vmware.pl
 mode change 100755 => 100644 fence/agents/vmware/fence_vmware.py
 create mode 100644 fence/agents/vmware/fence_vmware_helper.pl

diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 647011a..711e17d 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -224,22 +224,27 @@ all_opt = {
 		"help" : "",
 		"order" : 1,
 		"obsolete" : "use -o status instead" },
-	"vmipaddr" : {
-		"getopt" : "A:",
-		"help" : "-A <ip>        IP address or hostname of managed VMware ESX (default localhost)",
-		"order" : 2 },
-	"vmlogin" : {
-		"getopt" : "L:",
-		"help" : "-L <name>      VMware ESX management login name",
-		"order" : 2 },
-	"vmpasswd" : {
-		"getopt" : "P:",
-		"help" : "-P <password>  VMware ESX management login password",
-		"order" : 2 },
-	"vmpasswd_script" : {
-		"getopt" : "B:",
-		"help" : "-B <script>    Script to run to retrieve VMware ESX management password",
-		"order" : 2 },
+	"exec" : {
+		"getopt" : "e:",
+		"longopt" : "exec",
+		"help" : "-e, --exec=<command>           Command to execute",
+		"required" : "0",
+		"shortdesc" : "Command to execute",
+		"order" : 1 },
+	"vmware_type" : {
+		"getopt" : "d:",
+		"longopt" : "vmware_type",
+		"help" : "-d, --vmware_type=<type>       Type of VMware to connect",
+		"required" : "0",
+		"shortdesc" : "Type of VMware to connect",
+		"order" : 1 },
+	"vmware_datacenter" : {
+		"getopt" : "s:",
+		"longopt" : "vmware_datacenter",
+		"help" : "-s, --vmware_datacenter=<dc>   VMWare datacenter filter",
+		"required" : "0",
+		"shortdesc" : "Show only machines in specified datacenter",
+ 		"order" : 2 },
 	"snmp_version" : {
 		"getopt" : "d:",
 		"longopt" : "snmp-version",
@@ -656,20 +661,6 @@ def check_input(device_opt, opt):
 	if options.has_key("-R"):
 		options["-P"] = os.popen(options["-R"]).read().rstrip()
 
-	## VMware
-	#######
-	if options.has_key("-B"):
-		options["-P"] = os.popen(options["-B"]).read().rstrip()
-
-	if (device_opt.count("vmlogin") and (not options.has_key("-L"))):
-		fail_usage("Failed: You have to set login name for VMware ESX management console")
-
-	if (options.has_key("-L") and (not (options.has_key("-P") or options.has_key("-B")))):
-		fail_usage("Failed: You have to enter password or password script for VMware ESX management console")
-
-	if (["list", "monitor"].count(options["-o"])==0 and (options.has_key("-L") and (not (options.has_key("-n"))))):
-		fail_usage("Failed: You have to enter virtual machine name")
-
 	if options.has_key("-u") == False:
 		if options.has_key("-x"):
 			options["-u"] = 22
diff --git a/fence/agents/vmware/Makefile b/fence/agents/vmware/Makefile
index ea0a207..f0259b8 100644
--- a/fence/agents/vmware/Makefile
+++ b/fence/agents/vmware/Makefile
@@ -14,10 +14,13 @@
 SOURCE= fence_vmware.py
 TARGET= fence_vmware
 
+SOURCE2= fence_vmware_helper.pl
+TARGET2= fence_vmware_helper
+
 top_srcdir=../..
 include ${top_srcdir}/make/defines.mk
 
-all: $(TARGET)
+all: $(TARGET) $(TARGET2)
 
 $(TARGET): $(SOURCE)
 	: > $(TARGET)
@@ -28,12 +31,22 @@ $(TARGET): $(SOURCE)
 	awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET)
 	chmod +x $(TARGET)
 
+$(TARGET2): $(SOURCE2)
+	: > $(TARGET2)
+	awk "{print}(\$$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE2) >> $(TARGET2)
+	echo "FENCE_RELEASE_NAME=\"${RELEASE}\";" >> $(TARGET2)
+	${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET2)
+	echo "BUILD_DATE=\"(built `date`)\";" >> $(TARGET2)
+	awk -v p=0 "(\$$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE2) >> $(TARGET2)
+	chmod +x $(TARGET2)
+
 install: all
 	if [ ! -d ${sbindir} ]; then \
 		install -d ${sbindir}; \
 	fi
 	install -m755 ${TARGET} ${sbindir}
+	install -m755 ${TARGET2} ${sbindir}
 
 clean:
-	rm -f $(TARGET)
+	rm -f $(TARGET) $(TARGET2)
 
diff --git a/fence/agents/vmware/fence_vmware.pl b/fence/agents/vmware/fence_vmware.pl
deleted file mode 100755
index 3c08312..0000000
--- a/fence/agents/vmware/fence_vmware.pl
+++ /dev/null
@@ -1,337 +0,0 @@
-#!/usr/bin/perl
-
-###############################################################################
-###############################################################################
-##
-##  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-##  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
-##  
-##  This copyrighted material is made available to anyone wishing to use,
-##  modify, copy, or redistribute it subject to the terms and conditions
-##  of the GNU General Public License v.2.
-##
-##  VMWare ESX Server fencing support by Zach Lowry <zach@zachlowry.net>
-##
-###############################################################################
-###############################################################################
-
-use strict;
-use Getopt::Std;
-use VMware::VmPerl;
-use VMware::VmPerl::VM;
-use VMware::VmPerl::Server;
-use VMware::VmPerl::ConnectParams;
-use vars qw( $opt_L $opt_v $opt_V $opt_h $opt_T $opt_n $opt_o $opt_p $opt_P $opt_S $opt_l $opt_a $opt_q $vm_product $vm_platform $vm_build $vm_version_major $vm_version_minor $vm_version_revision );
-
-# Get the program name from $0 and strip directory names
-$_=$0;
-s/.*\///;
-my $pname = $_;
-
-# Change these if the text returned by your equipment is different.
-# Test by running script with options -t -v and checking /tmp/vmlog
-
-my $immediate = 'immediate'; # # Or 'delayed' - action string prefix on menu
-
-my $max_open_tries = 3;      # How many attempts to make.
-my $open_wait = 5;           # Seconds to wait between each attempt
-my $debuglog = '/tmp/apclog';# Location of debugging log when in verbose mode
-my $powerop_mode = VM_POWEROP_MODE_TRYSOFT;
-$opt_o = 'Reboot';           # Default fence action.  
-
-
-my $logged_in = 0;
-
-my $vm = VMware::VmPerl::VM::new();
-my $server = VMware::VmPerl::Server::new();
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-#END_VERSION_GENERATION
-
-sub usage 
-{
-	print "Usage:\n";
-	print "\n";
-	print "$pname [options]\n";
-	print "\n";
-	print "Options:\n";
-	print "  -a <ip>:<port>   IP address or hostname of VMware ESX Server\n";
-	print "  -h               usage\n";
-	print "  -l <name>        Login name\n";
-	print "  -p <string>      Login password\n";
-	print "  -S <path>        Script to run to retrieve login password\n";
-	print "  -n <name>        Name of VM to change \n";
-	print "  -o <string>      Action: Reboot (default), Off or On\n";
-	print "  -q               quiet mode\n";
-	print "  -T               Test mode (cancels action)\n";
-	print "  -V               version\n";
-	print "  -v               Log to file /tmp/vmlog\n";
-	print "  -L               List VMs on Server\n";
-	
-	exit 0;
-}
-
-sub fail
-{
-	my ($msg)=@_;
-	print $msg."\n" unless defined $opt_q;
-
-	if (defined $vm)
-	{
-		# make sure we don't get stuck in a loop due to errors
-
-		logout() if $logged_in;
-		undef $vm;
-	}
-	exit 1;
-}
-
-sub fail_usage
-{
-	my ($msg)=@_;
-	print STDERR $msg."\n" if $msg;
-	print STDERR "Please use '-h' for usage.\n";
-	exit 1;
-}
-
-sub version
-{
-	print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n";
-	print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-	exit 0;
-}
-
-
-sub login
-{
-	my $connect_params = VMware::VmPerl::ConnectParams::new($opt_a, $opt_P, $opt_l, $opt_p);
-	for (my $i=0; $i<$max_open_tries; $i++)
-	{
-		if (defined $opt_L) {
-			if (! $server->connect($connect_params)) {
-				my ($error_number, $error_string) = $server->get_last_error(); 
-				fail "$error_number, $error_string";
-			}
-			return;
-		} else {
-			if (! $vm->connect($connect_params, $opt_n)) {
-				my ($error_number, $error_string) = $vm->get_last_error(); 
-				fail "$error_number, $error_string";
-			}
-			return;
-		}
-	}
-	if (defined $opt_L) {
-		fail "failed: connect failed: ". $server->get_last_error() ."\n";
-	} else {
-		fail "failed: connect failed: ". $vm->get_last_error() ."\n";
-	}
-}
-
-# Determine if the switch is a working state.  Also check to make sure that 
-# the switch has been specified in the case that there are slave switches
-# present.  This assumes that we are at the main menu.
-sub identify_vmware
-{
-	if (! defined $opt_L) {
-		$vm_product = $vm->get_product_info(VM_PRODINFO_PRODUCT);
-		$vm_platform = $vm->get_product_info(VM_PRODINFO_PLATFORM);
-		$vm_build = $vm->get_product_info(VM_PRODINFO_BUILD);
-		$vm_version_major = $vm->get_product_info(VM_PRODINFO_VERSION_MAJOR);
-		$vm_version_minor = $vm->get_product_info(VM_PRODINFO_VERSION_MINOR);
-		$vm_version_revision = $vm->get_product_info(VM_PRODINFO_VERSION_REVISION);
-	}
-}
-
-
-sub logout 
-{
-	undef $vm, $server;
-}
-
-
-sub action
-{
-	if (defined $opt_L) {
-		foreach my  $name ($server->registered_vm_names()) {
-			print "$name\n";
-		}
-		logout(); 
-
-		exit 0;
-	}
-	if (defined $opt_T) {
-		print "success: test outlet $opt_n $opt_o\n" unless defined $opt_q; 
-		logout(); 
-
-		exit 0;
-	} elsif ( $vm->is_connected() ) {
-		my $cur_state = $vm->get_execution_state();
-		if ( $opt_o =~ /Reboot/i ) {
-			$vm->reset($powerop_mode);
-		} elsif ( $opt_o =~ /On/i ) {
-			$vm->start($powerop_mode);
-		} elsif ( $opt_o =~ /Off/i ) {
-			$vm->stop($powerop_mode);
-		}
-		if ($_) {
-			my ($error_number, $error_string) = $vm->get_last_error(); 
-			if ($error_number != 0) {
-				fail "$error_number, $error_string";
-			} else {
-				print "success: outlet $opt_n $opt_o\n" unless defined $opt_q; 
-			}
-			logout();
-
-			exit 0;
-		}
-	} 
-
-	fail "failed: unrecognised action response\n";
-}
-
-
-sub get_options_stdin
-{
-	my $opt;
-	my $line = 0;
-	my $in;
-	while( defined($in = <>) )
-	{
-		$_ = $in;
-		chomp;
-
-		# strip leading and trailing whitespace
-		s/^\s*//;
-		s/\s*$//;
-
-		# skip comments
-		next if /^#/;
-	
-		$line+=1;
-		$opt=$_;
-		next unless $opt;
-
-		my ($name,$val)=split /\s*=\s*/, $opt;
-
-		if ( $name eq "" )
-		{
-			print STDERR "parse error: illegal name in option $line\n";
-			exit 2;
-		} 
-		# DO NOTHING -- this field is used by fenced 
-		elsif ($name eq "agent" ) 
-		{
-		} 
-		elsif ($name eq "ipaddr" ) 
-		{
-			$opt_a = $val;
-		} 
-		elsif ($name eq "login" ) 
-		{
-			$opt_l = $val;
-		} 
-		elsif ($name eq "option" ) 
-		{
-			$opt_o = $val;
-		} 
-		elsif ($name eq "passwd" ) 
-		{
-			$opt_p = $val;
-		}
-		elsif ($name eq "passwd_script" )
-		{
-			$opt_S = $val;
-		}
-		elsif ($name eq "port" ) 
-		{
-			$opt_n = $val;
-		} 
-		elsif ($name eq "switch" ) 
-		{
-			$opt_P = $val;
-		} 
-		elsif ($name eq "test" ) 
-		{
-			$opt_T = $val;
-		} 
-		elsif ($name eq "verbose" ) 
-		{
-			$opt_v = $val;
-		} 
-		# Excess name/vals will fail
-		else 
-		{
-			fail "parse error: unknown option \"$opt\"";
-		}
-	}
-}
-		
-
-sub connect_error
-{
-	fail "failed: connect returned: ".$vm->get_last_error()."\n";
-}
-
-
-### MAIN #######################################################
-
-if (@ARGV > 0) {
-	getopts("a:hl:n:o:p:S:qTvVL") || fail_usage ;
-	
-	usage if defined $opt_h;
-	version if defined $opt_V;
-
-	fail_usage "Unkown parameter." if (@ARGV > 0);
-
-	fail_usage "No '-a' flag specified." unless defined $opt_a;
-	fail_usage "No '-n' flag specified." unless defined $opt_n or defined $opt_L;
-	fail_usage "No '-l' flag specified." unless defined $opt_l;
-
-	if (defined $opt_S) {
-		$pwd_script_out = `$opt_S`;
-		chomp($pwd_script_out);
-		if ($pwd_script_out) {
-			$opt_p = $pwd_script_out;
-		}
-	}
-
-	fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p;
-	fail_usage "Unrecognized action '$opt_o' for '-o' flag"
-		unless $opt_o =~ /^(Off|On|Reboot)$/i;
-
-	($opt_a, $opt_P) = split(/:/, $opt_a);
-	fail_usage "No port number specified." unless defined $opt_P;
-
-} else {
-	get_options_stdin();
-
-	fail "failed: no IP address" unless defined $opt_a;
-	fail "failed: no vm name" unless defined $opt_n;
-	fail "failed: no login name" unless defined $opt_l;
-
-	if (defined $opt_S) {
-		$pwd_script_out = `$opt_S`;
-		chomp($pwd_script_out);
-		if ($pwd_script_out) {
-			$opt_p = $pwd_script_out;
-		}
-	}
-
-	fail "failed: no password" unless defined $opt_p;
-	fail "failed: unrecognized action: $opt_o"
-		unless $opt_o =~ /^(Off|On|Reboot)$/i;
-} 
-
-&login;
-
-&identify_vmware;
-
-&action;
-
-exit 0;
-
-
diff --git a/fence/agents/vmware/fence_vmware.py b/fence/agents/vmware/fence_vmware.py
old mode 100755
new mode 100644
index a6ce9ef..75fd887
--- a/fence/agents/vmware/fence_vmware.py
+++ b/fence/agents/vmware/fence_vmware.py
@@ -1,153 +1,341 @@
 #!/usr/bin/python
 
-##
-## Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
-##
-## The Following Agent Has Been Tested On VMware ESX 3.5 and VMware Server 1.0.7
-## 
-#####
+#
+# The Following agent has been tested on:
+# vmrun 2.0.0 build-116503 (from VMware Server 2.0) against:
+#	VMware ESX 4.0.0
+#	VMware vCenter 4.0.0
+# 	VMware ESX 3.5
+# 	VMware Server 2.0.0
+#	VMware ESXi 3.5 update 2
+# 	VMware Server 1.0.7 (works but list/status show only running VMs)
+#
+# VI Perl API 1.6 against:
+# 	VMware ESX 4.0.0
+#	VMware vCenter 4.0.0
+# 	VMware ESX 3.5
+#	VMware ESXi 3.5 update 2
+# 	VMware Virtual Center 2.5
+#
+# VMware vSphere SDK for Perl 4.0.0 against:
+# 	VMware ESX 4.0.0
+#	VMware vCenter 4.0.0
+#
 
 import sys, re, pexpect, exceptions
-sys.path.append("/usr/lib/fence")
+sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
 
 #BEGIN_VERSION_GENERATION
-FENCE_RELEASE_NAME=""
+RELEASE_VERSION="VMware Agent using VI Perl API and/or VIX vmrun command"
 REDHAT_COPYRIGHT=""
 BUILD_DATE=""
 #END_VERSION_GENERATION
 
-VMWARE_COMMAND="/usr/bin/vmware-cmd"
-COMMAND_PROMPT_REG="\[PEXPECT\]\$ "
-COMMAND_PROMPT_NEW="[PEXPECT]\$ "
+### CONSTANTS ####
+# VMware type is ESX/ESXi/VC
+VMWARE_TYPE_ESX=0
+# VMware type is Server 1.x
+VMWARE_TYPE_SERVER1=1
+# VMware type is Server 2.x and/or ESX 3.5 up2, ESXi 3.5 up2, VC 2.5 up2
+VMWARE_TYPE_SERVER2=2
+
+# Minimum required version of vmrun command
+VMRUN_MINIMUM_REQUIRED_VERSION=2
+
+# Default path to vmhelper command
+VMHELPER_COMMAND="fence_vmware_helper"
+# Default path to vmrun command
+VMRUN_COMMAND="/usr/bin/vmrun"
+# Default type of vmware
+VMWARE_DEFAULT_TYPE="esx"
+
+#### GLOBAL VARIABLES ####
+# Internal type. One of VMWARE_TYPE_, set by #vmware_check_vmware_type
+vmware_internal_type=VMWARE_TYPE_ESX
+
+# If ESX is disconnected, say, that VM is off (don't return previous state)
+vmware_disconnected_hack=False
+
+### FUNCTIONS ####
+
+#Split string in simplified DSV format to array of items
+def dsv_split(dsv_str):
+	delimiter_c=':'
+	escape_c='\\'
+
+	res=[]
+	status=0
+	tmp_str=""
+
+	for x in dsv_str:
+		if (status==0):
+			if (x==delimiter_c):
+				res.append(tmp_str)
+				tmp_str=""
+			elif (x==escape_c):
+				status=1
+			else:
+				tmp_str+=x
+		elif (status==1):
+			if (x==delimiter_c):
+				tmp_str+=delimiter_c
+			elif (x==escape_c):
+				tmp_str+=escape_c
+			else:
+				tmp_str+=escape_c+x
+			status=0
+
+	if (tmp_str!=""):
+		res.append(tmp_str)
+
+	return res
+
+# Quote string for proper existence in quoted string used for pexpect.run function
+# Ex. test'this will return test'\''this. So pexpect run will really pass ' to argument
+def quote_for_run(str):
+	dstr=''
+
+	for c in str:
+		if c==r"'":
+			dstr+="'\\''"
+		else:
+			dstr+=c
+
+	return dstr
+
+# Return string with command and additional parameters (something like vmrun -h 'host'
+def vmware_prepare_command(options,add_login_params,additional_params):
+	res=options["-e"]
+
+	if (add_login_params):
+		if (vmware_internal_type==VMWARE_TYPE_ESX):
+			res+=" --server '%s' --username '%s' --password '%s' "%(quote_for_run(options["-a"]),
+										quote_for_run(options["-l"]),
+										quote_for_run(options["-p"]))
+		elif (vmware_internal_type==VMWARE_TYPE_SERVER2):
+			res+=" -h 'https://%s/sdk' -u '%s' -p '%s' -T server "%(quote_for_run(options["-a"]),
+										quote_for_run(options["-l"]),
+										quote_for_run(options["-p"]))
+		elif (vmware_internal_type==VMWARE_TYPE_SERVER1):
+			host_name_array=options["-a"].split(':')
+
+			res+=" -h '%s' -u '%s' -p '%s' -T server1 "%(quote_for_run(host_name_array[0]),
+								     quote_for_run(options["-l"]),
+								     quote_for_run(options["-p"]))
+			if (len(host_name_array)>1):
+				res+="-P '%s' "%(quote_for_run(host_name_array[1]))
+
+	if ((options.has_key("-s")) and (vmware_internal_type==VMWARE_TYPE_ESX)):
+		res+="--datacenter '%s' "%(quote_for_run(options["-s"]))
+
+	if (additional_params!=""):
+		res+=additional_params
+
+	return res
+
+# Log message if user set verbose option
+def vmware_log(options, message):
+	if options["log"] >= LOG_MODE_VERBOSE:
+		options["debug_fh"].write(message+"\n")
+
+# Run command with timeout and parameters. Internaly uses vmware_prepare_command. Returns string
+# with output from vmrun command. If something fails (command not found, exit code is not 0), fail_usage
+# function is called (and never return).
+def vmware_run_command(options,add_login_params,additional_params,additional_timeout):
+	command=vmware_prepare_command(options,add_login_params,additional_params)
 
-# Start comunicating after login. Prepare good environment.
-def start_communication(conn, options):
-	conn.sendline ("PS1='"+COMMAND_PROMPT_NEW+"'");
-	conn.log_expect(options,COMMAND_PROMPT_REG,SHELL_TIMEOUT)
-
-# Prepare command line for vmware-cmd with parameters.
-def prepare_cmdline(conn,options,add_vm_name):
-	cmd_line=VMWARE_COMMAND+" -H '"+options["-A"]+"' -U '"+options["-L"]+"' -P '"+options["-P"]+"'"
-	if (add_vm_name):
-		cmd_line+=" '"+options["-n"]+"'"
-
-        if options.has_key("-v"):
-    		cmd_line+=" -v"
-
-    	return cmd_line
-    	
-def get_power_status(conn, options):
-	result = ""
 	try:
-		start_communication(conn,options)
-
-		cmd_line=prepare_cmdline(conn,options,True)
-
-            	cmd_line+=" getstate"
+		vmware_log(options,command)
 
-		conn.sendline(cmd_line)
-
-		conn.log_expect(options,COMMAND_PROMPT_REG,SHELL_TIMEOUT)
-		status_err = re.search("vmcontrol\ error\ ([-+]?\d+)\:(.*)",conn.before.lower())
-		if (status_err!=None):
-			fail_usage("VMware error "+status_err.group(1)+": "+status_err.group(2))
-			
-		status = re.search("getstate\(\)\ =\ on",conn.before.lower())
-		
-		result=(status==None and "off" or "on")
-		
-	except pexpect.EOF:
-		fail(EC_CONNECTION_LOST)
-	except pexpect.TIMEOUT:
-		fail(EC_TIMED_OUT)
-
-	return result
-
-def get_outlet_list(conn,options):
-	result={}
-
-	try:
-		start_communication(conn,options)
+		(res_output,res_code)=pexpect.run(command,int(options["-Y"])+int(options["-y"])+additional_timeout,True)
 
-		cmd_line=prepare_cmdline(conn,options,False)
-		cmd_line+=" -l"
+		if (res_code==None):
+			fail(EC_TIMED_OUT)
+		if ((res_code!=0) and (add_login_params)):
+			vmware_log(options,res_output)
+			fail_usage("%s returned %s"%(options["-e"],res_output))
+		else:
+			vmware_log(options,res_output)
 
-		conn.sendline(cmd_line)
-
-		conn.log_expect(options,COMMAND_PROMPT_REG,SHELL_TIMEOUT)
-		status_err = re.search("vmcontrol\ error\ ([-+]?\d+)\:(.*)",conn.before.lower())
-		if (status_err!=None):
-			fail_usage("VMware error "+status_err.group(1)+": "+status_err.group(2))
-
-                lines=conn.before.splitlines()
+	except pexpect.ExceptionPexpect:
+		fail_usage("Cannot run command %s"%(options["-e"]))
 
-                for line in lines[(options.has_key("-v") and 3 or 1):-1]:
-			if (line!=""):
-			    result[line]=("","")
+	return res_output
 
-	except pexpect.EOF:
-		fail(EC_CONNECTION_LOST)
-	except pexpect.TIMEOUT:
-		fail(EC_TIMED_OUT)
+# Get outlet list with status as hash table. If you will use add_vm_name, only VM with vmname is
+# returned. This is used in get_status function
+def vmware_get_outlets_vi(conn, options, add_vm_name):
+	outlets={}
 
-	return result
+	if (add_vm_name):
+		all_machines=vmware_run_command(options,True,("--operation status --vmname '%s'"%(quote_for_run(options["-n"]))),0)
+	else:
+		all_machines=vmware_run_command(options,True,"--operation list",int(options["-g"]))
+
+	all_machines_array=all_machines.splitlines()
+
+	for machine in all_machines_array:
+		machine_array=dsv_split(machine)
+		if (len(machine_array)==4):
+			if (machine_array[0] in outlets):
+				fail_usage("Failed. More machines with same name %s found!"%(machine_array[0]))
+
+			if (vmware_disconnected_hack):
+				outlets[machine_array[0]]=("",(
+						((machine_array[2].lower() in ["poweredon"]) and
+						 (machine_array[3].lower()=="connected"))
+						and "on" or "off"))
+			else:
+				outlets[machine_array[0]]=("",((machine_array[2].lower() in ["poweredon"]) and "on" or "off"))
+	return outlets
+
+# Get outlet list with status as hash table.
+def vmware_get_outlets_vix(conn,options):
+	outlets={}
+
+	running_machines=vmware_run_command(options,True,"list",0)
+	running_machines_array=running_machines.splitlines()[1:]
+
+	if (vmware_internal_type==VMWARE_TYPE_SERVER2):
+		all_machines=vmware_run_command(options,True,"listRegisteredVM",0)
+		all_machines_array=all_machines.splitlines()[1:]
+	elif (vmware_internal_type==VMWARE_TYPE_SERVER1):
+		all_machines_array=running_machines_array
+
+	for machine in all_machines_array:
+		if (machine!=""):
+			outlets[machine]=("",((machine in running_machines_array) and "on" or "off"))
+
+	return outlets
+
+def get_outlets_status(conn, options):
+	if (vmware_internal_type==VMWARE_TYPE_ESX):
+		return vmware_get_outlets_vi(conn,options,False)
+	if ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)):
+		return vmware_get_outlets_vix(conn,options)
+
+def get_power_status(conn,options):
+	if (vmware_internal_type==VMWARE_TYPE_ESX):
+		outlets=vmware_get_outlets_vi(conn,options,True)
+	else:
+		outlets=get_outlets_status(conn,options)
+
+	if ((vmware_internal_type==VMWARE_TYPE_SERVER2) or (vmware_internal_type==VMWARE_TYPE_ESX)):
+		if (not (options["-n"] in outlets)):
+			fail_usage("Failed: You have to enter existing name of virtual machine!")
+		else:
+			return outlets[options["-n"]][1]
+	elif (vmware_internal_type==VMWARE_TYPE_SERVER1):
+		return ((options["-n"] in outlets) and "on" or "off")
 
 def set_power_status(conn, options):
-	try:
-		start_communication(conn,options)
+	if (vmware_internal_type==VMWARE_TYPE_ESX):
+		additional_params="--operation %s --vmname '%s'"%((options["-o"]=="on" and "on" or "off"),quote_for_run(options["-n"]))
+	elif ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)):
+		additional_params="%s '%s'"%((options["-o"]=="on" and "start" or "stop"),quote_for_run(options["-n"]))
+		if (options["-o"]=="off"):
+			additional_params+=" hard"
 
-		cmd_line=prepare_cmdline(conn,options,True)
+	vmware_run_command(options,True,additional_params,int(options["-g"]))
 
-            	cmd_line+=" "+(options["-o"]=="on" and "start" or "stop hard")
+# Returns True, if user uses supported vmrun version (currently >=2.0.0) otherwise False.
+def vmware_is_supported_vmrun_version(options):
+	vmware_help_str=vmware_run_command(options,False,"",0)
+	version_re=re.search("vmrun version (\d\.(\d[\.]*)*)",vmware_help_str.lower())
+	if (version_re==None):
+		    return False   # Looks like this "vmrun" is not real vmrun
 
-		conn.sendline(cmd_line)
+	version_array=version_re.group(1).split(".")
 
-		conn.log_expect(options,COMMAND_PROMPT_REG,POWER_TIMEOUT)
-
-	except pexpect.EOF:
-		fail(EC_CONNECTION_LOST)
-	except pexpect.TIMEOUT:
-		fail(EC_TIMED_OUT)
-		
+	try:
+		if (int(version_array[0])<VMRUN_MINIMUM_REQUIRED_VERSION):
+			return False
+	except Exception:
+		return False
+
+	return True
+
+# Define new options
+def vmware_define_defaults():
+	all_opt["vmware_type"]["default"]=VMWARE_DEFAULT_TYPE
+
+# Check vmware type, set vmware_internal_type to one of VMWARE_TYPE_ value and
+# options["-e"] to path (if not specified)
+def vmware_check_vmware_type(options):
+	global vmware_internal_type
+
+	options["-d"]=options["-d"].lower()
+
+	if (options["-d"]=="esx"):
+		vmware_internal_type=VMWARE_TYPE_ESX
+		if (not options.has_key("-e")):
+			options["-e"]=VMHELPER_COMMAND
+	elif (options["-d"]=="server2"):
+		vmware_internal_type=VMWARE_TYPE_SERVER2
+		if (not options.has_key("-e")):
+			options["-e"]=VMRUN_COMMAND
+	elif (options["-d"]=="server1"):
+		vmware_internal_type=VMWARE_TYPE_SERVER1
+		if (not options.has_key("-e")):
+			options["-e"]=VMRUN_COMMAND
+	else:
+		fail_usage("vmware_type can be esx,server2 or server1!")
+
+# Main agent method
 def main():
-	device_opt = [  "help", "version", "agent", "quiet", "verbose", "debug",
-			"action", "ipaddr", "login", "passwd", "passwd_script",
-			"secure",  "identity_file", "test" , "vmipaddr", "vmlogin", 
-			"vmpasswd", "port", "vmpasswd_script", "separator" ]
+	device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug",
+		       "action", "ipaddr", "login", "passwd", "passwd_script",
+		       "test", "port", "separator", "exec", "vmware_type",
+		       "vmware_datacenter", "secure",
+		       "power_timeout", "shell_timeout", "login_timeout", "power_wait" ]
 
 	atexit.register(atexit_handler)
 
+	vmware_define_defaults()
+
 	options = check_input(device_opt, process_input(device_opt))
 
-	## 
-	## Fence agent specific defaults
-	#####
-        if 0 == options.has_key("-c"):
-            options["-c"] = "\$ "
-
-        if 0 == options.has_key("-A"):
-            options["-A"] = "localhost"
-    
-    	options["-x"] = 1
-
-    	show_docs(options)
-	##
-	## Operate the fencing device
-	####
-	conn = fence_login(options)
-	fence_action(conn, options, set_power_status, get_power_status, get_outlet_list)
-
-	##
-	## Logout from system
-	######
-	try:
-		conn.sendline("logout")
-		conn.close()
-	except exceptions.OSError:
-		pass
-	except pexpect.ExceptionPexpect:
-		pass
+	# Default is secure connection
+	options["-x"] = 1
+
+	docs = { }
+	docs["shortdesc"] = "Fence agent for VMWare"
+	docs["longdesc"] = "fence_vmware is an I/O Fencing agent \
+which can be used with the VMware ESX, VMware ESXi or VMware Server \
+to fence virtual machines.\
+\n.P\n\
+Before you can use this agent, it must be installed VI Perl Toolkit or \
+vmrun command on every node you want to make fencing.\
+\n.P\n\
+VI Perl Toolkit is preferred for VMware ESX/ESXi and Virtual Center. Vmrun \
+command is only solution for VMware Server 1/2 (this command will works against \
+ESX/ESXi 3.5 up2 and VC up2 too, but not cluster aware!) and is available as part \
+of VMware VIX API SDK package. VI Perl and VIX API SDK are both available from \
+VMware web pages (not int RHEL repository!). \
+\n.P\n\
+You can specify type of VMware you are connecting to with \\fB-d\\fP switch \
+(or \\fIvmware_type\\fR for stdin). Possible values are esx, server2 and server1.\
+Default value is esx, which will use VI Perl. With server1 and server2, vmrun \
+command is used.\
+\n.P\n\
+After you have successfully installed VI Perl Toolkit or VIX API, you should \
+be able to run fence_vmware_helper (part of this agent) or vmrun command. \
+This agent supports only vmrun from version 2.0.0 (VIX API 1.6.0)."
+	show_docs(options, docs)
+
+	# Check vmware type and set path
+	vmware_check_vmware_type(options)
+
+	# Test user vmrun command version
+	if ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)):
+		if (not (vmware_is_supported_vmrun_version(options))):
+			fail_usage("Unsupported version of vmrun command! You must use at least version %d!"%(VMRUN_MINIMUM_REQUIRED_VERSION))
+
+	# Operate the fencing device
+	result = fence_action(None, options, set_power_status, get_power_status, get_outlets_status)
+	
+	sys.exit(result)
 
 if __name__ == "__main__":
 	main()
diff --git a/fence/agents/vmware/fence_vmware_helper.pl b/fence/agents/vmware/fence_vmware_helper.pl
new file mode 100644
index 0000000..a0b5cea
--- /dev/null
+++ b/fence/agents/vmware/fence_vmware_helper.pl
@@ -0,0 +1,276 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my $ME = $0;
+
+END {
+  defined fileno STDOUT or return;
+  close STDOUT and return;
+  warn "$ME: failed to close standard output: $!\n";
+  $? ||= 1;
+}
+
+my ($RELEASE_VERSION, $REDHAT_COPYRIGHT, $BUILD_DATE);
+
+#BEGIN_VERSION_GENERATION
+$RELEASE_VERSION="";
+$REDHAT_COPYRIGHT="";
+$BUILD_DATE="";
+#END_VERSION_GENERATION
+
+#### FUNCTIONS #####
+# Show error message
+sub show_error {
+  print STDERR @_;
+}
+
+sub my_exit {
+  my ($exit_code)=@_;
+
+  # Disconnect from server
+  Util::disconnect();
+
+  exit $exit_code;
+}
+
+# Convert one field (string) to format acceptable by DSV. This
+# means replace any : with \: and \ with \\.
+sub convert_field_to_dsv {
+  my ($input_line)=@_;
+
+  $input_line =~ s/([\\:])/\\$1/g;
+  return $input_line
+}
+
+#### Global variables #####
+# Aditional options
+my %opts = (
+   'operation' => {
+      type => "=s",
+      help => "The operation to perform (on,off,list,status). "
+             . "Operations on/off/status require name of the virtual machine",
+      default => "list",
+      required => 0,
+   },
+   'vmname' => {
+      type => "=s",
+      help => "The name of the virtual machine",
+      required => 0,
+   },
+   'datacenter' => {
+      type => "=s",
+      help => "The name of the datacenter",
+      required => 0,
+   }
+);
+
+#################
+##### MAIN ######
+#################
+
+# Conditional use of VIRuntime
+eval "use VMware::VIRuntime;";
+
+if ($@) {
+  show_error "Please install VI Perl API package to use this tool!\nPerl error: $@";
+  exit 1;
+}
+
+# Parse options
+Opts::add_options(%opts);
+Opts::parse();
+Opts::validate();
+
+if (!(Opts::get_option('operation')=~/^(on|off|list|status)$/i)) {
+  show_error "Operation should be on, off, list or status!\n";
+  exit 2;
+}
+
+my $operation=lc(Opts::get_option('operation'));
+
+if (($operation ne 'list') && (!defined Opts::get_option('vmname'))) {
+  show_error "Operation on, off, status require vmname parameter!\n";
+  exit 2;
+}
+
+
+# Try connect to machine
+eval {
+  Util::connect();
+};
+
+if ($@) {
+  show_error "Cannot connect to server!\nVMware error:".$@;
+  exit 3;
+}
+
+my ($datacenter, $datacenter_view, $vm_views,$vm);
+# We are connected to machine
+
+# If user want's datacenter, we must first find datacenter
+my %filter=(view_type => 'VirtualMachine');
+
+if( defined (Opts::get_option('datacenter')) ) {
+  $datacenter = Opts::get_option('datacenter');
+  $datacenter_view = Vim::find_entity_view(view_type => 'Datacenter',
+                                            filter => { name => $datacenter });
+  if (!$datacenter_view) {
+    show_error "Cannot find datacenter ".$datacenter."!\n";
+
+    my_exit 4;
+  }
+
+  $filter{'begin_entity'}=$datacenter_view;
+}
+
+if ($operation ne 'list') {
+  $filter{'filter'}= {"config.name" => Opts::get_option('vmname')};
+}
+
+$vm_views = Vim::find_entity_views(%filter);
+
+my $found=0;
+
+# Traverse all found vm
+foreach $vm(@$vm_views) {
+  if (($operation eq 'list') or ($operation eq 'status')) {
+    if (!$vm->summary->config->template) {
+      print convert_field_to_dsv($vm->name).":".
+            convert_field_to_dsv($vm->summary->config->vmPathName).":".
+            convert_field_to_dsv($vm->runtime->powerState->val).":".
+            convert_field_to_dsv($vm->runtime->connectionState->val)."\n";
+    }
+  } elsif ($operation eq 'on') {
+    eval {
+      $vm->PowerOnVM();
+    };
+
+    if ($@) {
+      # If error is SoapFault with InvalidPowerState, user maybe use some auto power on tool.
+      # This is not error, warning is enought.
+      if (ref($@) eq 'SoapFault') {
+        if (ref($@->detail) eq 'InvalidPowerState') {
+          show_error "Warning: Cannot power on vm (somebody done it before???) ".Opts::get_option('vmname').
+                     "!\nVMware error:".$@."\n";
+        }
+      } else {
+        # Some other more serious problem
+        show_error "Cannot power on vm ".Opts::get_option('vmname')."!\nVMware error:".$@."\n";
+        my_exit 6;
+      }
+    }
+  } elsif ($operation eq 'off') {
+    eval {
+      $vm->PowerOffVM();
+    };
+
+    if ($@) {
+      # If error is SoapFault with InvalidPowerState, user maybe use some auto power off tool.
+      # This is not error, warning is enought.
+      if (ref($@) eq 'SoapFault') {
+        if (ref($@->detail) eq 'InvalidPowerState') {
+          show_error "Warning: Cannot power off vm (somebody done it before???) ".Opts::get_option('vmname').
+                     "!\nVMware error:".$@."\n";
+        }
+      } else {
+        # Some other more serious problem
+        show_error "Cannot power off vm ".Opts::get_option('vmname')."!\nVMware error:".$@."\n";
+        my_exit 6;
+      }
+    }
+  } else {
+    show_error "Operation should be on, off or list!\n";
+    my_exit 2;
+  }
+  $found++;
+}
+
+if ((!$found) && ($operation ne 'list')) {
+  show_error "Cannot find vm ".Opts::get_option('vmname')."!\n";
+  my_exit 5;
+}
+
+# Should be 0 -> success all, or 6 in case of error
+my_exit 0;
+
+__END__
+
+=head1 NAME
+
+fence_vmware_helper - Perform list of virtual machines and
+               poweron, poweroff  of operations on virtual machines.
+
+=head1 SYNOPSIS
+
+ fence_vmware_helper --operation <on|off|list|status> [options]
+
+=head1 DESCRIPTION
+
+This VI Perl command-line utility provides an interface for
+seven common provisioning operations on one or more virtual
+machines: powering on, powering off and listing virtual mode.
+
+=head1 OPTIONS
+
+=head2 GENERAL OPTIONS
+
+=over
+
+=item B<operation>
+
+Operation to be performed.  One of the following:
+
+  <on> (power on one or more virtual machines),
+  <off> (power off one  or more virtual machines),
+  <list> (list virtual machines and their status)
+  <status> (same as list, but show only machines with vmname)
+
+=item B<vmname>
+
+Optional. Name of the virtual machine on which the
+operation is to be performed.
+
+=item B<datacenter>
+
+Optional. Name of the  datacenter for the virtual machine(s).
+Operations will be performed on all the virtual machines under the given datacenter.
+
+=back
+
+=head1 EXAMPLES
+
+Power on a virtual machine
+
+   fence_vmware_helper --username administrator --password administrator --operation on
+                --vmname rhel --server win1
+
+   fence_vmware_helper --username administrator --password administrator --operation on
+                --vmname rhel --server win1 --datacenter Datacenter
+
+Power off a virtual machine
+
+   fence_vmware_helper --username administrator --password administrator --operation off
+                --vmname rhel --server win1
+
+   perl fence_vmware_helper --username administrator --password administrator --operation off
+                --vmname rhel --server win1 --datacenter Datacenter
+
+List of virtual machines
+
+   fence_vmware_helper --username administrator --password administrator --server win1
+
+   fence_vmware_helper --username administrator --password administrator --server win1
+                --operation list
+
+Get status of virtual machine
+
+   fence_vmware_helper --username administrator --password administrator --server win1
+	    --vmname rhel --operation status
+
+=head1 SUPPORTED PLATFORMS
+
+All operations supported on ESX 3.0.1
+
+All operations supported on Virtual Center 2.0.1
-- 
1.6.0.6