fence-agents: master - fence_rhevm: New fence agent for RHEV-M REST API

Marek Grác marx at fedoraproject.org
Fri Sep 24 20:40:44 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=commitdiff;h=5035c43a1f595a6d776d0c6b988b4eb122877f19
Commit:        5035c43a1f595a6d776d0c6b988b4eb122877f19
Parent:        ae8ee07ad63567264bcd5da282ea6a338c039cc2
Author:        Marek 'marx' Grac <mgrac at redhat.com>
AuthorDate:    Fri Sep 24 20:02:00 2010 +0200
Committer:     Marek 'marx' Grac <mgrac at redhat.com>
CommitterDate: Fri Sep 24 20:02:00 2010 +0200

fence_rhevm: New fence agent for RHEV-M REST API

---
 configure.ac                      |    1 +
 fence/agents/Makefile.am          |    1 +
 fence/agents/lib/fencing.py.py    |    8 ++-
 fence/agents/rhevm/Makefile.am    |   15 ++++
 fence/agents/rhevm/fence_rhevm.py |  145 +++++++++++++++++++++++++++++++++++++
 5 files changed, 169 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index 71bc6d2..439eb9f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -262,6 +262,7 @@ AC_CONFIG_FILES([Makefile
 		 fence/agents/node_assassin/Makefile
 		 fence/agents/nss_wrapper/Makefile
 		 fence/agents/rackswitch/Makefile
+		 fence/agents/rhevm/Makefile
 		 fence/agents/rsa/Makefile
 		 fence/agents/rsb/Makefile
 		 fence/agents/sanbox2/Makefile
diff --git a/fence/agents/Makefile.am b/fence/agents/Makefile.am
index 2159558..4cd1564 100644
--- a/fence/agents/Makefile.am
+++ b/fence/agents/Makefile.am
@@ -27,6 +27,7 @@ SUBDIRS 		= lib \
 			  node_assassin \
 			  nss_wrapper \
 			  rackswitch \
+			  rhevm \
 			  rsa \
 			  rsb \
 			  sanbox2 \
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 4c5a0db..7e49649 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -75,6 +75,10 @@ all_opt = {
 		"getopt" : "",
 		"help" : "",
 		"order" : 1 },
+	"web"    : {
+		"getopt" : "",
+		"help" : "",
+		"order" : 1 },
 	"action" : {
 		"getopt" : "o:",
 		"longopt" : "action",
@@ -342,7 +346,7 @@ all_opt = {
 		"help" : "--shell-timeout <seconds>      Wait X seconds for cmd prompt after issuing command",
 		"default" : "3", 
 		"required" : "0",
-		"shortdesc" : "Wait X seconds for cmd promprt after issuing command",
+		"shortdesc" : "Wait X seconds for cmd prompt after issuing command",
 		"order" : 200 },
 	"power_timeout" : {
 		"getopt" : "g:",
@@ -693,6 +697,8 @@ def check_input(device_opt, opt):
 			options["-u"] = 22
 		elif options.has_key("-z"):
 			options["-u"] = 443
+		elif device_opt.count("web"):
+			options["-u"] = 80
 		else:
 			options["-u"] = 23
 
diff --git a/fence/agents/rhevm/Makefile.am b/fence/agents/rhevm/Makefile.am
new file mode 100644
index 0000000..fc4635f
--- /dev/null
+++ b/fence/agents/rhevm/Makefile.am
@@ -0,0 +1,15 @@
+MAINTAINERCLEANFILES	= Makefile.in
+
+TARGET			= fence_rhevm
+
+EXTRA_DIST		= $(TARGET).py
+
+sbin_SCRIPTS		= $(TARGET)
+
+dist_man_MANS		= $(TARGET).8
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+
+clean-local: clean-man
+	rm -f $(TARGET)
diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py
new file mode 100755
index 0000000..376e6e3
--- /dev/null
+++ b/fence/agents/rhevm/fence_rhevm.py
@@ -0,0 +1,145 @@
+#!/usr/bin/python
+
+import sys, re, pexpect, socket
+import pycurl, StringIO
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION="New RHEV-M Agent - test release on steroids"
+REDHAT_COPYRIGHT=""
+BUILD_DATE="March, 2008"
+#END_VERSION_GENERATION
+
+
+re_get_id = re.compile("<vm id=\"(.*?)\"", re.IGNORECASE);
+re_status = re.compile("<status>(.*?)</status>", re.IGNORECASE);
+re_get_name = re.compile("<name>(.*?)</name>", re.IGNORECASE); 
+
+def get_power_status(conn, options):
+	### Obtain real ID from name
+	try:
+		res = send_command(options, "vms/?search=name%3D" + options["-n"])
+	except pycurl.error, e:
+		sys.stderr.write(e[1] + "\n")
+		fail(EC_TIMED_OUT)
+
+	result = re_get_id.search(res)
+	if (result == None):
+		# Unable to obtain ID needed to access virtual machine
+		fail(EC_STATUS)
+
+	options["id"] = result.group(1);
+	
+	re_status.search(res)
+	result = re_status.search(res)
+	if (result == None):
+		# We were able to parse ID so output is correct
+		# in some cases it is possible that RHEV-M output does not
+		# contain <status> line. We can assume machine is OFF then
+		return "off"
+	else:
+		status = result.group(1)
+
+	if (status == "RUNNING"):
+		return "on"
+	else:
+		return "off"
+
+def set_power_status(conn, options):
+	action = {
+		'on' : "start",
+		'off' : "stop"
+	}[options["-o"]]
+
+	url = "vms/" + options["id"] + "/" + action
+	try:
+		res = send_command(options, url, "POST")
+	except pycurl.error, e:
+		sys.stderr.write(e[1] + "\n")
+		fail(EC_TIMED_OUT)
+	
+	return
+
+def get_list(conn, options):
+	outlets = { }
+
+	try:
+		try:
+			res = send_command(options, "vms")
+		except pycurl.error, e:
+			sys.stderr.write(e[1] + "\n")
+			fail(EC_TIMED_OUT)	
+
+		lines = res.split("<vm ")
+		for i in range(1, len(lines)):
+			name = re_get_name.search(lines[i]).group(1)
+			outlets[name] = ("", None)
+	except AttributeError:
+		return { }
+	except IndexError:
+		return { }
+
+	return outlets
+
+def send_command(opt, command, method = "GET"):
+	## setup correct URL
+	if opt.has_key("-z"):
+		url = "https:"
+	else:
+		url = "http:"
+
+	url += "//" + opt["-a"] + ":" + str(opt["-u"]) + "/rhevm-api-powershell/" + command
+
+	## send command through pycurl
+	c = pycurl.Curl()
+	b = StringIO.StringIO()
+	c.setopt(pycurl.URL, url)
+	c.setopt(pycurl.HTTPHEADER, [ "Content-type: application/xml", "Accept: application/xml" ])
+	c.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
+	c.setopt(pycurl.USERPWD, opt["-l"] + ":" + opt["-p"])
+	c.setopt(pycurl.TIMEOUT, int(opt["-Y"]))
+	c.setopt(pycurl.SSL_VERIFYPEER, 0)
+
+	if (method == "POST"):
+		c.setopt(pycurl.POSTFIELDS, "<action />")
+
+	c.setopt(pycurl.WRITEFUNCTION, b.write)
+	c.perform()
+	result = b.getvalue()
+
+	if opt["log"] >= LOG_MODE_VERBOSE:
+		opt["debug_fh"].write(command + "\n")
+		opt["debug_fh"].write(result + "\n")
+
+	return result
+
+def main():
+	device_opt = [  "help", "version", "agent", "quiet", "verbose", "debug",
+			"action", "ipaddr", "login", "passwd", "passwd_script",
+			"ssl", "inet4_only", "inet6_only", "ipport", "port", 
+			"web", "separator", "power_wait", "power_timeout", 
+			"shell_timeout" ]
+
+	atexit.register(atexit_handler)
+
+	all_opt["power_wait"]["default"] = "1"
+	
+	options = check_input(device_opt, process_input(device_opt))
+
+	docs = { }
+	docs["shortdesc"] = "Fence agent for RHEV-M REST API"
+	docs["longdesc"] = "fence_rhevm is an I/O Fencing agent which can be \
+used with RHEV-M REST API to fence virtual machines."
+	docs["vendorurl"] = "http://www.redhat.com"
+	show_docs(options, docs)
+
+	##
+	## Fence operations
+	####
+	result = fence_action(None, options, set_power_status, get_power_status, get_list)
+
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()


More information about the cluster-commits mailing list