Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=204... Commit: 20433b6cab6465b2cdaefb3d383d12da68cab309 Parent: 1d2a31568a1b502b65bb33358424539911e55d4d Author: Marek 'marx' Grac mgrac@redhat.com AuthorDate: Sat Sep 25 00:25:35 2010 +0200 Committer: Marek 'marx' Grac mgrac@redhat.com CommitterDate: Sat Sep 25 00:39:30 2010 +0200
fence_rhevm: New fence agent for RHEV-M REST API
Resolves: rhbz#595385 --- fence/agents/lib/fencing.py.py | 8 ++- fence/agents/rhevm/Makefile | 38 ++++++++++ fence/agents/rhevm/fence_rhevm.py | 144 +++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 1 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py index 43eafe2..be2a44e 100644 --- a/fence/agents/lib/fencing.py.py +++ b/fence/agents/lib/fencing.py.py @@ -79,6 +79,10 @@ all_opt = { "getopt" : "", "help" : "", "order" : 1 }, + "web" : { + "getopt" : "", + "help" : "", + "order" : 1 }, "action" : { "getopt" : "o:", "longopt" : "action", @@ -346,7 +350,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:", @@ -697,6 +701,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 b/fence/agents/rhevm/Makefile new file mode 100644 index 0000000..4315a91 --- /dev/null +++ b/fence/agents/rhevm/Makefile @@ -0,0 +1,38 @@ +############################################################################### +############################################################################### +## +## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. +## Copyright (C) 2004 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. +## +############################################################################### +############################################################################### + +SOURCE= fence_rhevm.py +TARGET= fence_rhevm + +top_srcdir=../.. +include ${top_srcdir}/make/defines.mk + +all: $(TARGET) + +fence_rhevm: $(SOURCE) + : > $(TARGET) + awk "{print}($$1 ~ /#BEGIN_VERSION_GENERATION/){exit 0}" $(SOURCE) >> $(TARGET) + echo "FENCE_RELEASE_NAME="${RELEASE}";" >> $(TARGET) + ${top_srcdir}/scripts/define2var ${top_srcdir}/config/copyright.cf sh REDHAT_COPYRIGHT >> $(TARGET) + echo "BUILD_DATE="(built `date`)";" >> $(TARGET) + awk -v p=0 "($$1 ~ /#END_VERSION_GENERATION/){p = 1} {if(p==1)print}" $(SOURCE) >> $(TARGET) + chmod +x $(TARGET) + +install: all + if [ ! -d ${sbindir} ]; then \ + install -d ${sbindir}; \ + fi + install -m755 ${TARGET} ${sbindir} + +clean: + 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..92272b9 --- /dev/null +++ b/fence/agents/rhevm/fence_rhevm.py @@ -0,0 +1,144 @@ +#!/usr/bin/python + +import sys, re, pexpect, socket +import pycurl, StringIO +sys.path.append("/usr/lib/fence") +from fencing import * + +#BEGIN_VERSION_GENERATION +FENCE_RELEASE_NAME="" +REDHAT_COPYRIGHT="" +BUILD_DATE="" +#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()
cluster-commits@lists.fedorahosted.org