diff --git a/.fence-agents.metadata b/.fence-agents.metadata new file mode 100644 index 0000000..3cece23 --- /dev/null +++ b/.fence-agents.metadata @@ -0,0 +1 @@ +6be7c01343d69945df899c104b59571e51b7e6a9 SOURCES/fence-agents-4.0.11.tar.xz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55cd481 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/fence-agents-4.0.11.tar.xz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/backward-rename_fence_scsi_check_to_pl.patch b/SOURCES/backward-rename_fence_scsi_check_to_pl.patch new file mode 100644 index 0000000..f5746d5 --- /dev/null +++ b/SOURCES/backward-rename_fence_scsi_check_to_pl.patch @@ -0,0 +1,76 @@ +diff -urN fence-agents-4.0.11/fence/agents/scsi/fence_scsi.py fence-agents-4.0.11.scsi/fence/agents/scsi/fence_scsi.py +--- fence-agents-4.0.11/fence/agents/scsi/fence_scsi.py 2014-08-06 09:35:09.000000000 +0200 ++++ fence-agents-4.0.11.scsi/fence/agents/scsi/fence_scsi.py 2014-09-03 13:00:37.000000000 +0200 +@@ -387,7 +387,7 @@ + all_opt["delay"]["getopt"] = "H:" + + #fence_scsi_check +- if os.path.basename(sys.argv[0]) == "fence_scsi_check": ++ if os.path.basename(sys.argv[0]) == "fence_scsi_check.pl": + sys.exit(scsi_check()) + + options = check_input(device_opt, process_input(device_opt)) +diff -urN fence-agents-4.0.11/fence/agents/scsi/Makefile.am fence-agents-4.0.11.scsi/fence/agents/scsi/Makefile.am +--- fence-agents-4.0.11/fence/agents/scsi/Makefile.am 2014-08-27 15:32:14.000000000 +0200 ++++ fence-agents-4.0.11.scsi/fence/agents/scsi/Makefile.am 2014-09-03 13:10:22.000000000 +0200 +@@ -4,10 +4,10 @@ + + SRC = $(TARGET).py + +-EXTRA_DIST = $(SRC) ++EXTRA_DIST = $(SRC) + + scsidatadir = $(CLUSTERDATA) +-scsidata_SCRIPTS = fence_scsi_check ++scsidata_SCRIPTS = fence_scsi_check.pl + + sbin_SCRIPTS = $(TARGET) + +@@ -15,7 +15,7 @@ + + FENCE_TEST_ARGS = -k 1 + +-fence_scsi_check: $(TARGET) ++fence_scsi_check.pl: $(TARGET) + cp $^ $@ + + include $(top_srcdir)/make/fencebuild.mk +@@ -23,4 +23,4 @@ + include $(top_srcdir)/make/agentpycheck.mk + + clean-local: clean-man +- rm -f $(TARGET) $(SYMTARGET) fence_scsi_check ++ rm -f $(TARGET) $(SYMTARGET) fence_scsi_check.pl +diff -urN fence-agents-4.0.11/fence/agents/scsi/Makefile.in fence-agents-4.0.11.scsi/fence/agents/scsi/Makefile.in +--- fence-agents-4.0.11/fence/agents/scsi/Makefile.in 2014-08-27 15:52:24.000000000 +0200 ++++ fence-agents-4.0.11.scsi/fence/agents/scsi/Makefile.in 2014-09-03 13:10:37.000000000 +0200 +@@ -285,9 +285,9 @@ + MAINTAINERCLEANFILES = Makefile.in + TARGET = fence_scsi + SRC = $(TARGET).py +-EXTRA_DIST = $(SRC) ++EXTRA_DIST = $(SRC) + scsidatadir = $(CLUSTERDATA) +-scsidata_SCRIPTS = fence_scsi_check ++scsidata_SCRIPTS = fence_scsi_check.pl + sbin_SCRIPTS = $(TARGET) + man_MANS = $(TARGET).8 + FENCE_TEST_ARGS = -k 1 +@@ -607,7 +607,7 @@ + uninstall-sbinSCRIPTS uninstall-scsidataSCRIPTS + + +-fence_scsi_check: $(TARGET) ++fence_scsi_check.pl: $(TARGET) + cp $^ $@ + $(TARGET): $(SRC) + bash $(top_srcdir)/scripts/fenceparse \ +@@ -664,7 +664,7 @@ + python ./$(INPUT) --delay 0 $(FENCE_TEST_ARGS) -- + + clean-local: clean-man +- rm -f $(TARGET) $(SYMTARGET) fence_scsi_check ++ rm -f $(TARGET) $(SYMTARGET) fence_scsi_check.pl + + # Tell versions [3.59,3.63) of GNU make to not export all variables. + # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/SOURCES/bz1072564-1-add_ssl_secure_and_ssl_insecure.patch b/SOURCES/bz1072564-1-add_ssl_secure_and_ssl_insecure.patch new file mode 100644 index 0000000..a9a969a --- /dev/null +++ b/SOURCES/bz1072564-1-add_ssl_secure_and_ssl_insecure.patch @@ -0,0 +1,207 @@ +From 809b909651118c06d2ab48d7911bbee2e512e478 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 1 Sep 2014 15:05:20 +0200 +Subject: [PATCH 1/2] fencing: Add new options --ssl-secure and --ssl-insecure + +These new options extends current --ssl (same as --ssl-secure). Until now certificate of the fence device +was not validated what can possibly lead to attack on infrastructe. With this patch, user can decide +if certificate should (--ssl-secure) or should not (--ssl-insecure) be verified. + +The default option is to validate certificate. + +Resolves: rhbz#1072564 +--- + fence/agents/cisco_ucs/fence_cisco_ucs.py | 9 ++++++-- + fence/agents/lib/fencing.py.py | 28 ++++++++++++++++++++--- + fence/agents/rhevm/fence_rhevm.py | 9 ++++++-- + fence/agents/vmware_soap/fence_vmware_soap.py | 33 +++++++++++++++++++++++---- + 4 files changed, 68 insertions(+), 11 deletions(-) + +diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py +index f72e696..888d689 100644 +--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py +@@ -90,8 +90,13 @@ def send_command(opt, command, timeout): + conn.setopt(pycurl.POSTFIELDS, command) + conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write) + conn.setopt(pycurl.TIMEOUT, timeout) +- conn.setopt(pycurl.SSL_VERIFYPEER, 0) +- conn.setopt(pycurl.SSL_VERIFYHOST, 0) ++ if opt.has_key("--ssl") or opt.has_key("--ssl-secure"): ++ conn.setopt(pycurl.SSL_VERIFYPEER, 1) ++ conn.setopt(pycurl.SSL_VERIFYHOST, 2) ++ ++ if opt.has_key("--ssl-insecure"): ++ conn.setopt(pycurl.SSL_VERIFYPEER, 0) ++ conn.setopt(pycurl.SSL_VERIFYHOST, 0) + conn.perform() + result = web_buffer.getvalue() + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index d1d5aae..557358a 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -179,6 +179,21 @@ all_opt = { + "required" : "0", + "shortdesc" : "SSL connection", + "order" : 1}, ++ "ssl_insecure" : { ++ "getopt" : "9", ++ "longopt" : "ssl-insecure", ++ "help" : "--ssl-insecure Use ssl connection without verifying certificate", ++ "required" : "0", ++ "shortdesc" : "SSL connection without verifying fence device's certificate", ++ "order" : 1}, ++ "ssl_secure" : { ++ "getopt" : "9", ++ "longopt" : "ssl-secure", ++ "help" : "--ssl-secure Use ssl connection with verifying certificate", ++ "required" : "0", ++ "shortdesc" : "SSL connection with verifying fence device's certificate", ++ "order" : 1}, ++ + "notls" : { + "getopt" : "t", + "longopt" : "notls", +@@ -385,6 +400,7 @@ DEPENDENCY_OPT = { + "secure" : ["identity_file", "ssh_options"], + "ipaddr" : ["ipport", "inet4_only", "inet6_only"], + "port" : ["separator"], ++ "ssl" : ["ssl_secure", "ssl_insecure"], + "community" : ["snmp_auth_prot", "snmp_sec_level", "snmp_priv_prot", \ + "snmp_priv_passwd", "snmp_priv_passwd_script"] + } +@@ -662,7 +678,7 @@ def check_input(device_opt, opt): + elif options.has_key("--ssh") or (all_opt["secure"].has_key("default") and all_opt["secure"]["default"] == '1'): + all_opt["ipport"]["default"] = 22 + all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 22)" +- elif options.has_key("--ssl") or (all_opt["ssl"].has_key("default") and all_opt["ssl"]["default"] == '1'): ++ elif options.has_key("--ssl") or options.has_key("--ssl-secure") or options.has_key("--ssl-insecure") or (all_opt["ssl"].has_key("default") and all_opt["ssl"]["default"] == '1'): + all_opt["ipport"]["default"] = 443 + all_opt["ipport"]["help"] = "-u, --ipport=[port] TCP/UDP port to use (default 443)" + elif device_opt.count("web"): +@@ -972,11 +988,17 @@ def fence_login(options, re_login_string=r"(login\s*: )|(Login Name: )|(usernam + + if options.has_key("--ssl"): + gnutls_opts = "" ++ ssl_opts = "" ++ + if options.has_key("--notls"): + gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:+VERS-SSL3.0\"" + +- command = '%s %s --insecure --crlf -p %s %s' % \ +- (SSL_PATH, gnutls_opts, options["--ipport"], options["--ip"]) ++ # --ssl is same as the --ssl-secure ++ if options.has_key("--ssl-insecure"): ++ ssl_opts = "--insecure" ++ ++ command = '%s %s %s --insecure --crlf -p %s %s' % \ ++ (SSL_PATH, gnutls_opts, ssl_opts, options["--ipport"], options["--ip"]) + try: + conn = fspawn(options, command) + except pexpect.ExceptionPexpect, ex: +diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py +index a0d8d59..444fb56 100644 +--- a/fence/agents/rhevm/fence_rhevm.py ++++ b/fence/agents/rhevm/fence_rhevm.py +@@ -91,8 +91,13 @@ def send_command(opt, command, method="GET"): + conn.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC) + conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"]) + conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"])) +- conn.setopt(pycurl.SSL_VERIFYPEER, 0) +- conn.setopt(pycurl.SSL_VERIFYHOST, 0) ++ if opt.has_key("--ssl") or opt.has_key("--ssl-secure"): ++ conn.setopt(pycurl.SSL_VERIFYPEER, 1) ++ conn.setopt(pycurl.SSL_VERIFYHOST, 2) ++ ++ if opt.has_key("--ssl-insecure"): ++ conn.setopt(pycurl.SSL_VERIFYPEER, 0) ++ conn.setopt(pycurl.SSL_VERIFYHOST, 0) + + if method == "POST": + conn.setopt(pycurl.POSTFIELDS, "") +diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py +index 53fd9ea..3217c6b 100644 +--- a/fence/agents/vmware_soap/fence_vmware_soap.py ++++ b/fence/agents/vmware_soap/fence_vmware_soap.py +@@ -2,12 +2,14 @@ + + import sys + import shutil, tempfile, suds +-import logging ++import logging, requests + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + + from suds.client import Client + from suds.sudsobject import Property ++from suds.transport.http import HttpAuthenticated ++from suds.transport import Reply, TransportError + from fencing import * + from fencing import fail, EC_STATUS, EC_LOGIN_DENIED, EC_INVALID_PRIVILEGES, EC_WAITING_ON, EC_WAITING_OFF + from fencing import run_delay +@@ -18,12 +20,31 @@ REDHAT_COPYRIGHT="" + BUILD_DATE="April, 2011" + #END_VERSION_GENERATION + ++class RequestsTransport(HttpAuthenticated): ++ def __init__(self, **kwargs): ++ self.cert = kwargs.pop('cert', None) ++ self.verify = kwargs.pop('verify', True) ++ self.session = requests.Session() ++ # super won't work because not using new style class ++ HttpAuthenticated.__init__(self, **kwargs) ++ ++ def send(self, request): ++ self.addcredentials(request) ++ resp = self.session.post(request.url, data = request.message, headers = request.headers, cert = self.cert, verify = self.verify) ++ result = Reply(resp.status_code, resp.headers, resp.content) ++ return result ++ + def soap_login(options): + run_delay(options) + +- if options.has_key("--ssl"): ++ if options.has_key("--ssl") or options.has_key("--ssl-secure") or options.has_key("--ssl-insecure"): ++ if options.has_key("--ssl-insecure"): ++ verify = False ++ else: ++ verify = True + url = "https://" + else: ++ verify = False + url = "http://" + + url += options["--ip"] + ":" + str(options["--ipport"]) + "/sdk" +@@ -33,8 +54,8 @@ def soap_login(options): + atexit.register(remove_tmp_dir, tmp_dir) + + try: +- conn = Client(url + "/vimService.wsdl") +- conn.set_options(location=url) ++ headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : ""} ++ conn = Client(url + "/vimService.wsdl", location = url, transport = RequestsTransport(verify = verify), headers = headers) + + mo_ServiceInstance = Property('ServiceInstance') + mo_ServiceInstance._type = 'ServiceInstance' +@@ -43,6 +64,8 @@ def soap_login(options): + mo_SessionManager._type = 'SessionManager' + + conn.service.Login(mo_SessionManager, options["--username"], options["--password"]) ++ except requests.exceptions.SSLError, ex: ++ fail_usage("Server side certificate verification failed") + except Exception: + fail(EC_LOGIN_DENIED) + +@@ -205,6 +228,8 @@ Alternatively you can always use UUID to access virtual machine." + + logging.basicConfig(level=logging.INFO) + logging.getLogger('suds.client').setLevel(logging.CRITICAL) ++ logging.getLogger("requests").setLevel(logging.CRITICAL) ++ logging.getLogger("urllib3").setLevel(logging.CRITICAL) + + ## + ## Operate the fencing device +-- +1.9.3 + diff --git a/SOURCES/bz1072564-2-add_ssl_secure_and_ssl_insecure.patch b/SOURCES/bz1072564-2-add_ssl_secure_and_ssl_insecure.patch new file mode 100644 index 0000000..95e7dee --- /dev/null +++ b/SOURCES/bz1072564-2-add_ssl_secure_and_ssl_insecure.patch @@ -0,0 +1,186 @@ +From 6b7ba7c2969169a96146c0f3ed1fa6a0b34ff00f Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 1 Sep 2014 16:37:50 +0200 +Subject: [PATCH 2/2] [tests] Update XML metadata of fence agents + +added --ssl-secure, --ssl-insecure +--- + tests/data/metadata/fence_cisco_ucs.xml | 10 ++++++++++ + tests/data/metadata/fence_docker.xml | 10 ++++++++++ + tests/data/metadata/fence_ilo.xml | 10 ++++++++++ + tests/data/metadata/fence_ilo2.xml | 10 ++++++++++ + tests/data/metadata/fence_rhevm.xml | 10 ++++++++++ + tests/data/metadata/fence_vmware_soap.xml | 10 ++++++++++ + 6 files changed, 60 insertions(+) + +diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +index 30a3cb4..75e45ce 100644 +--- a/tests/data/metadata/fence_cisco_ucs.xml ++++ b/tests/data/metadata/fence_cisco_ucs.xml +@@ -13,6 +13,11 @@ + + Disable TLS negotiation + ++ ++ ++ ++ SSL connection with verifying fence device's certificate ++ + + + +@@ -53,6 +58,11 @@ + + Additional path needed to access suborganization + ++ ++ ++ ++ SSL connection without verifying fence device's certificate ++ + + + +diff --git a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml +index bda31d01..d100b8c 100644 +--- a/tests/data/metadata/fence_docker.xml ++++ b/tests/data/metadata/fence_docker.xml +@@ -8,6 +8,11 @@ + + TCP/UDP port to use for connection with device + ++ ++ ++ ++ SSL connection with verifying fence device's certificate ++ + + + +@@ -41,6 +46,11 @@ + + SSL connection + ++ ++ ++ ++ SSL connection without verifying fence device's certificate ++ + + + +diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +index eb8951c..25d9d54 100644 +--- a/tests/data/metadata/fence_ilo.xml ++++ b/tests/data/metadata/fence_ilo.xml +@@ -19,6 +19,11 @@ + + Force ribcl version to use + ++ ++ ++ ++ SSL connection with verifying fence device's certificate ++ + + + +@@ -54,6 +59,11 @@ + + SSL connection + ++ ++ ++ ++ SSL connection without verifying fence device's certificate ++ + + + +diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +index 4d65808..47e8e28 100644 +--- a/tests/data/metadata/fence_ilo2.xml ++++ b/tests/data/metadata/fence_ilo2.xml +@@ -19,6 +19,11 @@ + + Force ribcl version to use + ++ ++ ++ ++ SSL connection with verifying fence device's certificate ++ + + + +@@ -54,6 +59,11 @@ + + SSL connection + ++ ++ ++ ++ SSL connection without verifying fence device's certificate ++ + + + +diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +index a47f025..c9d6eeb 100644 +--- a/tests/data/metadata/fence_rhevm.xml ++++ b/tests/data/metadata/fence_rhevm.xml +@@ -13,6 +13,11 @@ + + Disable TLS negotiation + ++ ++ ++ ++ SSL connection with verifying fence device's certificate ++ + + + +@@ -48,6 +53,11 @@ + + SSL connection + ++ ++ ++ ++ SSL connection without verifying fence device's certificate ++ + + + +diff --git a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml +index 97d8fc6..d0a465f 100644 +--- a/tests/data/metadata/fence_vmware_soap.xml ++++ b/tests/data/metadata/fence_vmware_soap.xml +@@ -15,6 +15,11 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + + Disable TLS negotiation + ++ ++ ++ ++ SSL connection with verifying fence device's certificate ++ + + + +@@ -50,6 +55,11 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + + SSL connection + ++ ++ ++ ++ SSL connection without verifying fence device's certificate ++ + + + +-- +1.9.3 + diff --git a/SOURCES/bz1102727-2-duplicate_getopt.patch b/SOURCES/bz1102727-2-duplicate_getopt.patch new file mode 100644 index 0000000..2d685b0 --- /dev/null +++ b/SOURCES/bz1102727-2-duplicate_getopt.patch @@ -0,0 +1,36 @@ +From 4d8159cadc7e7d0acca5d3d27be1c281828a4def Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 7 Jan 2015 14:40:07 +0100 +Subject: [PATCH 4/6] fence_mpath: Fix duplicate "getopt" which was not + propagated anywhere + +Found by integrated tests. +--- + fence/agents/mpath/fence_mpath.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/mpath/fence_mpath.py b/fence/agents/mpath/fence_mpath.py +index 8a4811c..1dc3a20 100644 +--- a/fence/agents/mpath/fence_mpath.py ++++ b/fence/agents/mpath/fence_mpath.py +@@ -181,7 +181,7 @@ be removed from the device(s).", + "order": 1 + } + all_opt["mpathpersist_path"] = { +- "getopt" : "X:", ++ "getopt" : ":", + "longopt" : "mpathpersist-path", + "help" : "--mpathpersist-path=[path] Path to mpathpersist binary", + "required" : "0", +@@ -190,7 +190,7 @@ be removed from the device(s).", + "order": 200 + } + all_opt["store_path"] = { +- "getopt" : "X:", ++ "getopt" : ":", + "longopt" : "store-path", + "help" : "--store-path=[path] Path to directory containing cached keys", + "required" : "0", +-- +1.9.3 + diff --git a/SOURCES/bz1102727-2-fence_mpath.patch b/SOURCES/bz1102727-2-fence_mpath.patch new file mode 100644 index 0000000..f46f669 --- /dev/null +++ b/SOURCES/bz1102727-2-fence_mpath.patch @@ -0,0 +1,34 @@ +From de46962a4f4204570a6d2d7d7bf70794d33ec902 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 29 Jun 2015 21:01:46 +0200 +Subject: [PATCH] fence_mpath: Fix --sudo-path + +--- + fence/agents/mpath/fence_mpath.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/mpath/fence_mpath.py b/fence/agents/mpath/fence_mpath.py +index 1dc3a20..6992dc7 100644 +--- a/fence/agents/mpath/fence_mpath.py ++++ b/fence/agents/mpath/fence_mpath.py +@@ -8,7 +8,7 @@ import logging + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import fail_usage, run_command, atexit_handler, check_input, process_input, show_docs +-from fencing import fence_action, all_opt, run_delay ++from fencing import fence_action, all_opt, run_delay, SUDO_PATH + + #BEGIN_VERSION_GENERATION + RELEASE_VERSION="" +@@ -80,7 +80,7 @@ def run_cmd(options, cmd): + ret = {} + + if options.has_key("--use-sudo"): +- prefix = options["--sudo-path"] + " " ++ prefix = SUDO_PATH + " " + else: + prefix = "" + +-- +1.9.3 + diff --git a/SOURCES/bz1102727-3-fence_mpath.patch b/SOURCES/bz1102727-3-fence_mpath.patch new file mode 100644 index 0000000..395ecd6 --- /dev/null +++ b/SOURCES/bz1102727-3-fence_mpath.patch @@ -0,0 +1,50 @@ +From 39eb1ed82067d6c720bff3be5af08acedd85ef04 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 12 Aug 2015 15:08:30 +0200 +Subject: [PATCH] fence_mpath: Fix unfencing problems when /var/run/cluster is + removed and monitor these files + +This patch solves same problem as 2f1be046c0c880ec14caff2193b4daa18bcecab7 and 5b3c2b26e5dfa4784d44ac875c7780495bacdde8 +for fence_scsi. +--- + fence/agents/mpath/fence_mpath.py | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/fence/agents/mpath/fence_mpath.py b/fence/agents/mpath/fence_mpath.py +index 6992dc7..2d1e218 100644 +--- a/fence/agents/mpath/fence_mpath.py ++++ b/fence/agents/mpath/fence_mpath.py +@@ -26,6 +26,10 @@ def get_status(conn, options): + else: + logging.debug("No registration for key "\ + + options["--key"] + " on device " + dev + "\n") ++ ++ if options["--action"] == "monitor": ++ dev_read(options) ++ + return status + + +@@ -133,8 +137,8 @@ def get_registration_keys(options, dev): + def dev_write(options, dev): + file_path = options["--store-path"] + "/mpath.devices" + +- if not os.path.isdir(os.path.dirname(options["--store-path"])): +- os.makedirs(os.path.dirname(options["--store-path"])) ++ if not os.path.isdir(options["--store-path"]): ++ os.makedirs(options["--store-path"]) + + try: + store_fh = open(file_path, "a+") +@@ -203,7 +207,7 @@ def main(): + atexit.register(atexit_handler) + + device_opt = ["no_login", "no_password", "devices", "key", "sudo", \ +- "fabric_fencing", "on_target", "store_path", "mpathpersist_path"] ++ "fabric_fencing", "on_target", "store_path", "mpathpersist_path", "force_on"] + + define_new_opts() + +-- +1.9.3 + diff --git a/SOURCES/bz1102727-fence_mpath.patch b/SOURCES/bz1102727-fence_mpath.patch new file mode 100644 index 0000000..2cb54f4 --- /dev/null +++ b/SOURCES/bz1102727-fence_mpath.patch @@ -0,0 +1,443 @@ +From 1e1c7ecf7b3190e24d8e99d46c886c0b17df6bbe Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 19 Nov 2014 10:51:57 +0100 +Subject: [PATCH 3/6] fence_mpath: new fence agent for dm-multipath based on + mpathpersist + +Previously, scenario with multipath and underlying SCSI devices was solved by using +fence_scsi what works correctly but there are some limitation. The most important +is that unfencing has to be done when all paths are available as it is executed only once. +This new fence agent solve this situation properly as most of this situations are solved +by mpathpersist which is part of dm-multipath. + +Conflicts: + configure.ac + make/fencebuild.mk +--- + configure.ac | 4 + + fence/agents/mpath/Makefile.am | 17 +++ + fence/agents/mpath/fence_mpath.py | 244 ++++++++++++++++++++++++++++++++++++ + make/fencebuild.mk | 6 + + tests/data/metadata/fence_mpath.xml | 96 ++++++++++++++ + 5 files changed, 367 insertions(+) + create mode 100644 fence/agents/mpath/Makefile.am + create mode 100644 fence/agents/mpath/fence_mpath.py + create mode 100644 tests/data/metadata/fence_mpath.xml + +diff --git a/configure.ac b/configure.ac +index 7abd701..c7259da 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -168,6 +168,9 @@ AC_PATH_PROG([SG_PERSIST_PATH], [sg_persist], [/usr/bin/sg_persist]) + AC_PATH_PROG([SG_TURS_PATH], [sg_turs], [/usr/bin/sg_turs]) + AC_PATH_PROG([VGS_PATH], [vgs], [/usr/sbin/vgs]) + AC_PATH_PROG([NOVA_PATH], [nova], [/usr/bin/nova]) ++AC_PATH_PROG([MPATH_PATH], [mpathpersist], [/usr/sbin/mpathpersist]) ++AC_PATH_PROG([SUDO_PATH], [mpathpersist], [/usr/bin/sudo]) ++ + ## do subst + + AC_SUBST([DEFAULT_CONFIG_DIR]) +@@ -289,6 +292,7 @@ AC_CONFIG_FILES([Makefile + fence/agents/lib/Makefile + fence/agents/lpar/Makefile + fence/agents/manual/Makefile ++ fence/agents/mpath/Makefile + fence/agents/netio/Makefile + fence/agents/ovh/Makefile + fence/agents/pve/Makefile +diff --git a/fence/agents/mpath/Makefile.am b/fence/agents/mpath/Makefile.am +new file mode 100644 +index 0000000..fd3d8d2 +--- /dev/null ++++ b/fence/agents/mpath/Makefile.am +@@ -0,0 +1,17 @@ ++MAINTAINERCLEANFILES = Makefile.in ++ ++TARGET = fence_mpath ++ ++SRC = $(TARGET).py ++ ++EXTRA_DIST = $(SRC) ++ ++sbin_SCRIPTS = $(TARGET) ++ ++man_MANS = $(TARGET).8 ++ ++FENCE_TEST_ARGS = -k 1 ++ ++include $(top_srcdir)/make/fencebuild.mk ++include $(top_srcdir)/make/fenceman.mk ++include $(top_srcdir)/make/agentpycheck.mk +diff --git a/fence/agents/mpath/fence_mpath.py b/fence/agents/mpath/fence_mpath.py +new file mode 100644 +index 0000000..8a4811c +--- /dev/null ++++ b/fence/agents/mpath/fence_mpath.py +@@ -0,0 +1,244 @@ ++#!/usr/bin/python -tt ++ ++import sys ++import stat ++import re ++import os ++import logging ++import atexit ++sys.path.append("@FENCEAGENTSLIBDIR@") ++from fencing import fail_usage, run_command, atexit_handler, check_input, process_input, show_docs ++from fencing import fence_action, all_opt, run_delay ++ ++#BEGIN_VERSION_GENERATION ++RELEASE_VERSION="" ++REDHAT_COPYRIGHT="" ++BUILD_DATE="" ++#END_VERSION_GENERATION ++ ++def get_status(conn, options): ++ del conn ++ status = "off" ++ for dev in options["devices"]: ++ is_block_device(dev) ++ if options["--key"] in get_registration_keys(options, dev): ++ status = "on" ++ else: ++ logging.debug("No registration for key "\ ++ + options["--key"] + " on device " + dev + "\n") ++ return status ++ ++ ++def set_status(conn, options): ++ del conn ++ count = 0 ++ if options["--action"] == "on": ++ for dev in options["devices"]: ++ is_block_device(dev) ++ ++ register_dev(options, dev) ++ if options["--key"] not in get_registration_keys(options, dev): ++ count += 1 ++ logging.debug("Failed to register key "\ ++ + options["--key"] + "on device " + dev + "\n") ++ continue ++ dev_write(options, dev) ++ ++ if get_reservation_key(options, dev) is None \ ++ and not reserve_dev(options, dev) \ ++ and get_reservation_key(options, dev) is None: ++ count += 1 ++ logging.debug("Failed to create reservation (key="\ ++ + options["--key"] + ", device=" + dev + ")\n") ++ ++ else: ++ dev_keys = dev_read(options) ++ ++ for dev in options["devices"]: ++ is_block_device(dev) ++ ++ if options["--key"] in get_registration_keys(options, dev): ++ preempt_abort(options, dev_keys[dev], dev) ++ ++ for dev in options["devices"]: ++ if options["--key"] in get_registration_keys(options, dev): ++ count += 1 ++ logging.debug("Failed to remove key "\ ++ + options["--key"] + " on device " + dev + "\n") ++ continue ++ ++ if not get_reservation_key(options, dev): ++ count += 1 ++ logging.debug("No reservation exists on device " + dev + "\n") ++ if count: ++ logging.error("Failed to verify " + str(count) + " device(s)") ++ sys.exit(1) ++ ++ ++#run command, returns dict, ret["err"] = exit code; ret["out"] = output ++def run_cmd(options, cmd): ++ ret = {} ++ ++ if options.has_key("--use-sudo"): ++ prefix = options["--sudo-path"] + " " ++ else: ++ prefix = "" ++ ++ (ret["err"], ret["out"], _) = run_command(options, prefix + cmd) ++ ret["out"] = "".join([i for i in ret["out"] if i is not None]) ++ return ret ++ ++ ++# check if device exist and is block device ++def is_block_device(dev): ++ if not os.path.exists(dev): ++ fail_usage("Failed: device \"" + dev + "\" does not exist") ++ if not stat.S_ISBLK(os.stat(dev).st_mode): ++ fail_usage("Failed: device \"" + dev + "\" is not a block device") ++ ++# cancel registration ++def preempt_abort(options, host, dev): ++ cmd = options["--mpathpersist-path"] + " -o --preempt-abort --prout-type=5 --param-rk=" + host +" --param-sark=" + options["--key"] +"-d " + dev ++ return not bool(run_cmd(options, cmd)["err"]) ++ ++def register_dev(options, dev): ++ cmd = options["--mpathpersist-path"] + " -o --register --param-sark=" + options["--key"] + " -d " + dev ++ #cmd return code != 0 but registration can be successful ++ return not bool(run_cmd(options, cmd)["err"]) ++ ++def reserve_dev(options, dev): ++ cmd = options["--mpathpersist-path"] + " -o --reserv --prout-type=5 --param-rk=" + options["--key"] + " -d " + dev ++ return not bool(run_cmd(options, cmd)["err"]) ++ ++def get_reservation_key(options, dev): ++ cmd = options["--mpathpersist-path"] + " -i -r -d " + dev ++ out = run_cmd(options, cmd) ++ if out["err"]: ++ fail_usage("Cannot get reservation key") ++ match = re.search(r"\s+key\s*=\s*0x(\S+)\s+", out["out"], re.IGNORECASE) ++ return match.group(1) if match else None ++ ++def get_registration_keys(options, dev): ++ keys = [] ++ cmd = options["--mpathpersist-path"] + " -i -k -d " + dev ++ out = run_cmd(options, cmd) ++ if out["err"]: ++ fail_usage("Cannot get registration keys") ++ for line in out["out"].split("\n"): ++ match = re.search(r"\s+0x(\S+)\s*", line) ++ if match: ++ keys.append(match.group(1)) ++ return keys ++ ++def dev_write(options, dev): ++ file_path = options["--store-path"] + "/mpath.devices" ++ ++ if not os.path.isdir(os.path.dirname(options["--store-path"])): ++ os.makedirs(os.path.dirname(options["--store-path"])) ++ ++ try: ++ store_fh = open(file_path, "a+") ++ except IOError: ++ fail_usage("Failed: Cannot open file \""+ file_path + "\"") ++ out = store_fh.read() ++ if not re.search(r"^" + dev + r"\s+", out): ++ store_fh.write(dev + "\t" + options["--key"] + "\n") ++ store_fh.close() ++ ++def dev_read(options): ++ dev_key = {} ++ file_path = options["--store-path"] + "/mpath.devices" ++ try: ++ store_fh = open(file_path, "r") ++ except IOError: ++ fail_usage("Failed: Cannot open file \"" + file_path + "\"") ++ # get not empty lines from file ++ for (device, key) in [line.strip().split() for line in store_fh if line.strip()]: ++ dev_key[device] = key ++ store_fh.close() ++ return dev_key ++ ++def define_new_opts(): ++ all_opt["devices"] = { ++ "getopt" : "d:", ++ "longopt" : "devices", ++ "help" : "-d, --devices=[devices] List of devices to use for current operation", ++ "required" : "0", ++ "shortdesc" : "List of devices to use for current operation. Devices can \ ++be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). \ ++Each device must support SCSI-3 persistent reservations.", ++ "order": 1 ++ } ++ all_opt["key"] = { ++ "getopt" : "k:", ++ "longopt" : "key", ++ "help" : "-k, --key=[key] Key to use for the current operation", ++ "required" : "1", ++ "shortdesc" : "Key to use for the current operation. This key should be \ ++unique to a node and have to be written in /etc/multipath.conf. For the \"on\" action, the key specifies the key use to \ ++register the local node. For the \"off\" action, this key specifies the key to \ ++be removed from the device(s).", ++ "order": 1 ++ } ++ all_opt["mpathpersist_path"] = { ++ "getopt" : "X:", ++ "longopt" : "mpathpersist-path", ++ "help" : "--mpathpersist-path=[path] Path to mpathpersist binary", ++ "required" : "0", ++ "shortdesc" : "Path to mpathpersist binary", ++ "default" : "@MPATH_PATH@", ++ "order": 200 ++ } ++ all_opt["store_path"] = { ++ "getopt" : "X:", ++ "longopt" : "store-path", ++ "help" : "--store-path=[path] Path to directory containing cached keys", ++ "required" : "0", ++ "shortdesc" : "Path to directory where fence agent can store information", ++ "default" : "@STORE_PATH@", ++ "order": 200 ++ } ++ ++def main(): ++ atexit.register(atexit_handler) ++ ++ device_opt = ["no_login", "no_password", "devices", "key", "sudo", \ ++ "fabric_fencing", "on_target", "store_path", "mpathpersist_path"] ++ ++ define_new_opts() ++ ++ options = check_input(device_opt, process_input(device_opt)) ++ ++ docs = {} ++ docs["shortdesc"] = "Fence agent for multipath persistent reservation" ++ docs["longdesc"] = "fence_mpath is an I/O fencing agent that uses SCSI-3 \ ++persistent reservations to control access multipath devices. Underlying \ ++devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ ++well as the \"preempt-and-abort\" subcommand.\nThe fence_mpath agent works by \ ++having an unique key for each pair of node and device that has to be set also \ ++in /etc/multipath.conf. Once registered, a single node will become the reservation holder \ ++by creating a \"write exclusive, registrants only\" reservation on the \ ++device(s). The result is that only registered nodes may write to the \ ++device(s). When a node failure occurs, the fence_mpath agent will remove the \ ++key belonging to the failed node from the device(s). The failed node will no \ ++longer be able to write to the device(s). A manual reboot is required." ++ docs["vendorurl"] = "https://www.sourceware.org/dm/" ++ show_docs(options, docs) ++ ++ run_delay(options) ++ ++ # Input control BEGIN ++ if not "--key" in options: ++ fail_usage("Failed: key is required") ++ ++ options["devices"] = options["--devices"].split(",") ++ ++ if not options["devices"]: ++ fail_usage("Failed: No devices found") ++ # Input control END ++ ++ result = fence_action(None, options, set_status, get_status) ++ sys.exit(result) ++ ++if __name__ == "__main__": ++ main() +diff --git a/make/fencebuild.mk b/make/fencebuild.mk +index b59c069..7df0fc7 100644 +--- a/make/fencebuild.mk ++++ b/make/fencebuild.mk +@@ -17,6 +17,12 @@ $(TARGET): $(SRC) + -e 's#@''SG_TURS_PATH@#${SG_TURS_PATH}#g' \ + -e 's#@''VGS_PATH@#${VGS_PATH}#g' \ + -e 's#@''NOVA_PATH@#${NOVA_PATH}#g' \ ++ -e 's#@''SUDO_PATH@#${SUDO_PATH}#g' \ ++ -e 's#@''SSH_PATH@#${SSH_PATH}#g' \ ++ -e 's#@''TELNET_PATH@#${TELNET_PATH}#g' \ ++ -e 's#@''MPATH_PATH@#${MPATH_PATH}#g' \ ++ -e 's#@''STORE_PATH@#${CLUSTERVARRUN}#g' \ ++ -e 's#@''SUDO_PATH@#${SUDO_PATH}#g' \ + > $@ + + if [ 0 -eq `echo "$(SRC)" | grep fence_ &> /dev/null; echo $$?` ]; then \ +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +new file mode 100644 +index 0000000..c62dd49 +--- /dev/null ++++ b/tests/data/metadata/fence_mpath.xml +@@ -0,0 +1,96 @@ ++ ++ ++fence_mpath is an I/O fencing agent that uses SCSI-3 persistent reservations to control access multipath devices. Underlying devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand. ++The fence_mpath agent works by having an unique key for each pair of node and device that has to be set also in /etc/multipath.conf. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_mpath agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. ++https://www.sourceware.org/dm/ ++ ++ ++ ++ ++ List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations. ++ ++ ++ ++ ++ Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s). ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Path to directory where fence agent can store information ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Path to mpathpersist binary ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.9.3 + diff --git a/SOURCES/bz1111597-1-fence_rsb.patch b/SOURCES/bz1111597-1-fence_rsb.patch new file mode 100644 index 0000000..0bb780a --- /dev/null +++ b/SOURCES/bz1111597-1-fence_rsb.patch @@ -0,0 +1,27 @@ +From 11def0b2e4dcd18c5f098ba6a4cb935af937784e Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 2 Oct 2014 16:08:26 +0200 +Subject: [PATCH 1/2] fence_rsb: Fix 62d90e3a0827fcdc5be632bdf4103d3c08b39622 + +Patch was not incorporated correctly from older version. + +Resolves: rhbz#1110428 +--- + fence/agents/rsb/fence_rsb.py | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py +index bcad1de..d21093f 100755 +--- a/fence/agents/rsb/fence_rsb.py ++++ b/fence/agents/rsb/fence_rsb.py +@@ -29,7 +29,6 @@ def set_power_status(conn, options): + conn.send("2") + conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) + conn.send_eol(action) +- conn.log_expect(options, ["want to power off", "'yes' or 'no'"], int(options["--shell-timeout"])) + conn.log_expect(options, ["want to power " + options["--action"], + "yes/no", "'yes' or 'no'"], int(options["--shell-timeout"])) + conn.send_eol("yes") +-- +1.9.3 + diff --git a/SOURCES/bz1111599-1-fence_cisco_and_soap_logout.patch b/SOURCES/bz1111599-1-fence_cisco_and_soap_logout.patch new file mode 100644 index 0000000..faafcc0 --- /dev/null +++ b/SOURCES/bz1111599-1-fence_cisco_and_soap_logout.patch @@ -0,0 +1,164 @@ +commit 91399dd3e884c50e2317ab738eea1569faa8d55a +Author: Marek 'marx' Grac +Date: Mon Sep 8 15:10:05 2014 +0200 + + fence_cisco_ucs & fence_vmware_soap: Logout has to be performed even when fencing fails + + Previously, logout was not performed in the case when fence agent was aborted e.g. timeout. What could + lead to a situation when connections were not closed correctly. In the extreme case, it was not possible + to log into device at all + + Resolves: rhbz#1111599 + +diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py +index 888d689..f411433 100644 +--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py +@@ -19,6 +19,8 @@ RE_STATUS = re.compile("", ++ int(options_global["--shell-timeout"])) ++ except Exception: ++ pass ++ + def main(): ++ global options_global + device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "port", "web", "suborg"] + + atexit.register(atexit_handler) ++ atexit.register(logout) + + define_new_opts() + +- options = check_input(device_opt, process_input(device_opt)) ++ options_global = check_input(device_opt, process_input(device_opt)) + + docs = {} + docs["shortdesc"] = "Fence agent for Cisco UCS" + docs["longdesc"] = "fence_cisco_ucs is an I/O Fencing agent which can be \ + used with Cisco UCS to fence machines." + docs["vendorurl"] = "http://www.cisco.com" +- show_docs(options, docs) ++ show_docs(options_global, docs) + +- run_delay(options) ++ run_delay(options_global) + ### Login + try: +- res = send_command(options, "", int(options["--login-timeout"])) ++ res = send_command(options_global, "", int(options_global["--login-timeout"])) + result = RE_COOKIE.search(res) + if result == None: + ## Cookie is absenting in response +@@ -143,22 +155,19 @@ used with Cisco UCS to fence machines." + except Exception: + fail(EC_LOGIN_DENIED) + +- options["cookie"] = result.group(1) ++ options_global["cookie"] = result.group(1) + + ## + ## Modify suborg to format /suborg +- if options["--suborg"] != "": +- options["--suborg"] = "/" + options["--suborg"].lstrip("/").rstrip("/") ++ if options_global["--suborg"] != "": ++ options_global["--suborg"] = "/" + options_global["--suborg"].lstrip("/").rstrip("/") + + ## + ## Fence operations + #### +- result = fence_action(None, options, set_power_status, get_power_status, get_list) +- +- ### Logout; we do not care about result as we will end in any case +- send_command(options, "", +- int(options["--shell-timeout"])) ++ result = fence_action(None, options_global, set_power_status, get_power_status, get_list) + ++ ## Logout is done every time at atexit phase + sys.exit(result) + + if __name__ == "__main__": +diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py +index 3217c6b..2cea105 100644 +--- a/fence/agents/vmware_soap/fence_vmware_soap.py ++++ b/fence/agents/vmware_soap/fence_vmware_soap.py +@@ -20,6 +20,9 @@ REDHAT_COPYRIGHT="" + BUILD_DATE="April, 2011" + #END_VERSION_GENERATION + ++options_global = None ++conn_global = None ++ + class RequestsTransport(HttpAuthenticated): + def __init__(self, **kwargs): + self.cert = kwargs.pop('cert', None) +@@ -203,12 +206,21 @@ def set_power_status(conn, options): + def remove_tmp_dir(tmp_dir): + shutil.rmtree(tmp_dir) + ++def logout(): ++ try: ++ conn_global.service.Logout(options_global["mo_SessionManager"]) ++ except Exception: ++ pass ++ + def main(): ++ global options_global ++ global conn_global + device_opt = ["ipaddr", "login", "passwd", "web", "ssl", "notls", "port"] + + atexit.register(atexit_handler) ++ atexit.register(logout) + +- options = check_input(device_opt, process_input(device_opt)) ++ options_global = check_input(device_opt, process_input(device_opt)) + + ## + ## Fence agent specific defaults +@@ -224,7 +236,7 @@ format (e.g. /datacenter/vm/Discovered virtual machine/myMachine). \ + In the cases when name of yours VM is unique you can use it instead. \ + Alternatively you can always use UUID to access virtual machine." + docs["vendorurl"] = "http://www.vmware.com" +- show_docs(options, docs) ++ show_docs(options_global, docs) + + logging.basicConfig(level=logging.INFO) + logging.getLogger('suds.client').setLevel(logging.CRITICAL) +@@ -234,18 +246,11 @@ Alternatively you can always use UUID to access virtual machine." + ## + ## Operate the fencing device + #### +- conn = soap_login(options) +- +- result = fence_action(conn, options, set_power_status, get_power_status, get_power_status) ++ conn_global = soap_login(options_global) + +- ## +- ## Logout from system +- ##### +- try: +- conn.service.Logout(options["mo_SessionManager"]) +- except Exception: +- pass ++ result = fence_action(conn_global, options_global, set_power_status, get_power_status, get_power_status) + ++ ## Logout from system is done automatically via atexit() + sys.exit(result) + + if __name__ == "__main__": diff --git a/SOURCES/bz1121122-1-fence_ilo_ssh.patch b/SOURCES/bz1121122-1-fence_ilo_ssh.patch new file mode 100644 index 0000000..fc469a2 --- /dev/null +++ b/SOURCES/bz1121122-1-fence_ilo_ssh.patch @@ -0,0 +1,134 @@ +From 5cb174f204865d7ffe6d9edbfe8177b54bd61b49 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 3 Sep 2014 14:22:38 +0200 +Subject: [PATCH] fence_ilo_ssh: New fence agent for HP iLO3/4 via SSH + +Resolves: rhbz#1121122 +--- + configure.ac | 1 + + fence/agents/ilo_ssh/Makefile.am | 20 ++++++++++ + fence/agents/ilo_ssh/fence_ilo_ssh.py | 73 +++++++++++++++++++++++++++++++++++ + 3 files changed, 94 insertions(+) + create mode 100644 fence/agents/ilo_ssh/Makefile.am + create mode 100644 fence/agents/ilo_ssh/fence_ilo_ssh.py + +diff --git a/configure.ac b/configure.ac +index 0569dfe..b603878 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -278,6 +278,7 @@ AC_CONFIG_FILES([Makefile + fence/agents/ilo/Makefile + fence/agents/ilo_moonshot/Makefile + fence/agents/ilo_mp/Makefile ++ fence/agents/ilo_ssh/Makefile + fence/agents/intelmodular/Makefile + fence/agents/ipmilan/Makefile + fence/agents/kdump/Makefile +diff --git a/fence/agents/ilo_ssh/Makefile.am b/fence/agents/ilo_ssh/Makefile.am +new file mode 100644 +index 0000000..d67d7d1 +--- /dev/null ++++ b/fence/agents/ilo_ssh/Makefile.am +@@ -0,0 +1,20 @@ ++MAINTAINERCLEANFILES = Makefile.in ++ ++TARGET = fence_ilo_ssh ++ ++SRC = $(TARGET).py ++ ++EXTRA_DIST = $(SRC) ++ ++sbin_SCRIPTS = $(TARGET) ++ ++man_MANS = $(TARGET).8 ++ ++FENCE_TEST_ARGS = -p test -a test ++ ++include $(top_srcdir)/make/fencebuild.mk ++include $(top_srcdir)/make/fenceman.mk ++include $(top_srcdir)/make/agentpycheck.mk ++ ++clean-local: clean-man ++ rm -f $(TARGET) +diff --git a/fence/agents/ilo_ssh/fence_ilo_ssh.py b/fence/agents/ilo_ssh/fence_ilo_ssh.py +new file mode 100644 +index 0000000..f75ac25 +--- /dev/null ++++ b/fence/agents/ilo_ssh/fence_ilo_ssh.py +@@ -0,0 +1,73 @@ ++#!/usr/bin/python -tt ++ ++import sys, re ++import atexit ++sys.path.append("@FENCEAGENTSLIBDIR@") ++from fencing import * ++ ++#BEGIN_VERSION_GENERATION ++RELEASE_VERSION="" ++REDHAT_COPYRIGHT="" ++BUILD_DATE="" ++#END_VERSION_GENERATION ++ ++def get_power_status(conn, options): ++ conn.send_eol("show /system1") ++ ++ re_state = re.compile('EnabledState=(.*)', re.IGNORECASE) ++ conn.log_expect(options, re_state, int(options["--shell-timeout"])) ++ ++ status = conn.match.group(1).lower() ++ ++ if status.startswith("enabled"): ++ return "on" ++ else: ++ return "off" ++ ++def set_power_status(conn, options): ++ if options["--action"] == "on": ++ conn.send_eol("start /system1") ++ else: ++ conn.send_eol("power off hard") ++ ++ conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) ++ ++ return ++ ++def reboot_cycle(conn, options): ++ conn.send_eol("reset hard /system1") ++ conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) ++ return ++ ++def main(): ++ device_opt = ["ipaddr", "login", "passwd", "secure", "cmd_prompt", "method"] ++ ++ atexit.register(atexit_handler) ++ ++ all_opt["cmd_prompt"]["default"] = ["MP>", "hpiLO->"] ++ all_opt["power_wait"]["default"] = 5 ++ all_opt["method"]["default"] = "onoff" ++ ++ options = check_input(device_opt, process_input(device_opt)) ++ ++ docs = {} ++ docs["shortdesc"] = "Fence agent for HP iLO over SSH" ++ docs["longdesc"] = "fence_ilo_ssh is a fence agent that connects to iLO device. It logs into \ ++device via ssh and reboot a specified outlet. " ++ docs["vendorurl"] = "http://www.hp.com" ++ docs["symlink"] = [("fence_ilo3_ssh", "Fence agent for HP iLO3 over SSH"), ++ ("fence_ilo4_ssh", "Fence agent for HP iLO4 over SSH")] ++ show_docs(options, docs) ++ ++ conn = fence_login(options) ++ conn.send_eol("SMCLP") ++ ++ ## ++ ## Fence operations ++ #### ++ result = fence_action(conn, options, set_power_status, get_power_status, None, reboot_cycle) ++ fence_logout(conn, "exit") ++ sys.exit(result) ++ ++if __name__ == "__main__": ++ main() +-- +1.9.3 + diff --git a/SOURCES/bz1121122-2-broken_syslog.patch b/SOURCES/bz1121122-2-broken_syslog.patch new file mode 100644 index 0000000..9167515 --- /dev/null +++ b/SOURCES/bz1121122-2-broken_syslog.patch @@ -0,0 +1,25 @@ +From 9db6e28d381b19f2a396ea1a0f06ae4d434c0a27 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 27 Nov 2014 13:36:16 +0100 +Subject: [PATCH 1/3] [fencing] Character \x00 can't be inside syslog message + +--- + fence/agents/lib/fencing.py.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 740a4e0..302bba2 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -1215,5 +1215,7 @@ class SyslogLibHandler(logging.StreamHandler): + }[record.levelno] + + msg = self.format(record) +- syslog.syslog(syslog_level, msg) ++ ++ # syslos.syslog can not have 0x00 character inside or exception is thrown ++ syslog.syslog(syslog_level, msg.replace("\x00","\n")) + return +-- +1.9.3 + diff --git a/SOURCES/bz1121122-3-eol_changed.patch b/SOURCES/bz1121122-3-eol_changed.patch new file mode 100644 index 0000000..4e8ce84 --- /dev/null +++ b/SOURCES/bz1121122-3-eol_changed.patch @@ -0,0 +1,29 @@ +From ffee19e58c7186c88e7aba58f52ab0098d0939a7 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 1 Dec 2014 10:10:00 +0100 +Subject: [PATCH 2/3] fence_ilo_ssh: Change EOL to \r + +Previously, we have used \r\n that works fine with iLO3 with firmware >=1.50 but +for iLO4 all firmware that we have tested works only with \r + +Resolves: rhbz#1121122 +--- + fence/agents/ilo_ssh/fence_ilo_ssh.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fence/agents/ilo_ssh/fence_ilo_ssh.py b/fence/agents/ilo_ssh/fence_ilo_ssh.py +index 2fc9de2..7451792 100644 +--- a/fence/agents/ilo_ssh/fence_ilo_ssh.py ++++ b/fence/agents/ilo_ssh/fence_ilo_ssh.py +@@ -59,6 +59,8 @@ device via ssh and reboot a specified outlet. " + ("fence_ilo4_ssh", "Fence agent for HP iLO4 over SSH")] + show_docs(options, docs) + ++ options["eol"] = "\r" ++ + conn = fence_login(options) + conn.send_eol("SMCLP") + +-- +1.9.3 + diff --git a/SOURCES/bz1121122-3.5-delay_test.patch b/SOURCES/bz1121122-3.5-delay_test.patch new file mode 100644 index 0000000..5badd5b --- /dev/null +++ b/SOURCES/bz1121122-3.5-delay_test.patch @@ -0,0 +1,19 @@ +commit fbef1a9288b311564e3abe840ba414a4fee59832 +Author: Marek 'marx' Grac +Date: Thu Oct 16 14:12:00 2014 +0200 + + [test] fence_ilo_ssh: Add required parameter for testing --delay + +diff --git a/fence/agents/ilo_ssh/Makefile.am b/fence/agents/ilo_ssh/Makefile.am +index 3605e3c..dff0e6a 100644 +--- a/fence/agents/ilo_ssh/Makefile.am ++++ b/fence/agents/ilo_ssh/Makefile.am +@@ -10,7 +10,7 @@ sbin_SCRIPTS = $(TARGET) + + man_MANS = $(TARGET).8 + +-FENCE_TEST_ARGS = -p test -a test ++FENCE_TEST_ARGS = -p test -a test -l test + + include $(top_srcdir)/make/fencebuild.mk + include $(top_srcdir)/make/fenceman.mk diff --git a/SOURCES/bz1121122-4-symlink_ilo34_ssh.patch b/SOURCES/bz1121122-4-symlink_ilo34_ssh.patch new file mode 100644 index 0000000..201de40 --- /dev/null +++ b/SOURCES/bz1121122-4-symlink_ilo34_ssh.patch @@ -0,0 +1,35 @@ +From 46bd07975854e3ad0b351af93d0cfc769811a81e Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 1 Dec 2014 10:11:38 +0100 +Subject: [PATCH 3/3] fence_ilo_ssh: Create symlinks for fence_ilo3_ssh and + fence_ilo4_ssh + +Resolves: rhbz#1121122 +--- + fence/agents/ilo_ssh/Makefile.am | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/ilo_ssh/Makefile.am b/fence/agents/ilo_ssh/Makefile.am +index dff0e6a..34769d9 100644 +--- a/fence/agents/ilo_ssh/Makefile.am ++++ b/fence/agents/ilo_ssh/Makefile.am +@@ -2,13 +2,15 @@ MAINTAINERCLEANFILES = Makefile.in + + TARGET = fence_ilo_ssh + ++SYMTARGET = fence_ilo3_ssh fence_ilo4_ssh ++ + SRC = $(TARGET).py + + EXTRA_DIST = $(SRC) + + sbin_SCRIPTS = $(TARGET) + +-man_MANS = $(TARGET).8 ++man_MANS = $(TARGET).8 $(SYMTARGET:%=%.8) + + FENCE_TEST_ARGS = -p test -a test -l test + +-- +1.9.3 + diff --git a/SOURCES/bz1121122-5-symlink_ilo34_ssh.patch b/SOURCES/bz1121122-5-symlink_ilo34_ssh.patch new file mode 100644 index 0000000..564e7bc --- /dev/null +++ b/SOURCES/bz1121122-5-symlink_ilo34_ssh.patch @@ -0,0 +1,35 @@ +From cf83b8aebf21dc9a306d42aff33d86bd5c20bcbc Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 1 Dec 2014 11:04:25 +0100 +Subject: [PATCH] fence_ilo_ssh: Create symlinks for fence_ilo3_ssh and + fence_ilo4_ssh + +Resolves: rhbz#1121122 +--- + fence/agents/ilo_ssh/Makefile.am | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/ilo_ssh/Makefile.am b/fence/agents/ilo_ssh/Makefile.am +index 34769d9..883c306 100644 +--- a/fence/agents/ilo_ssh/Makefile.am ++++ b/fence/agents/ilo_ssh/Makefile.am +@@ -8,12 +8,15 @@ SRC = $(TARGET).py + + EXTRA_DIST = $(SRC) + +-sbin_SCRIPTS = $(TARGET) ++sbin_SCRIPTS = $(TARGET) $(SYMTARGET) + + man_MANS = $(TARGET).8 $(SYMTARGET:%=%.8) + + FENCE_TEST_ARGS = -p test -a test -l test + ++$(SYMTARGET) : $(TARGET) ++ cp $^ $@ ++ + include $(top_srcdir)/make/fencebuild.mk + include $(top_srcdir)/make/fenceman.mk + include $(top_srcdir)/make/agentpycheck.mk +-- +1.9.3 + diff --git a/SOURCES/bz1140921-1-fence_zvm.patch b/SOURCES/bz1140921-1-fence_zvm.patch new file mode 100644 index 0000000..9362066 --- /dev/null +++ b/SOURCES/bz1140921-1-fence_zvm.patch @@ -0,0 +1,62 @@ +From ad16ebe302d8f7acee25afc767c03128a0daf98c Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Fri, 12 Sep 2014 21:02:59 +0200 +Subject: [PATCH] fence_zvm: Fixes for better upstream inclusion + +--- + fence/agents/zvm/Makefile.am | 7 +++++++ + fence/agents/zvm/fence_zvm.c | 1 + + fence/agents/zvm/fence_zvmip.c | 1 + + 3 files changed, 9 insertions(+) + +diff --git a/fence/agents/zvm/Makefile.am b/fence/agents/zvm/Makefile.am +index 2439985..62eb862 100644 +--- a/fence/agents/zvm/Makefile.am ++++ b/fence/agents/zvm/Makefile.am +@@ -1,5 +1,7 @@ + MAINTAINERCLEANFILES = Makefile.in + ++TARGET = fence_zvmip ++ + sbin_PROGRAMS = fence_zvm fence_zvmip + + noinst_HEADERS = fence_zvm.h +@@ -12,6 +14,11 @@ fence_zvmip_CFLAGS = -D_GNU_SOURCE + + dist_man_MANS = fence_zvm.8 fence_zvmip.8 + ++#include $(top_srcdir)/make/fencemanc.mk ++ ++clean-local: ++ rm -f $(sbin_PROGRAMS) ++ + FENCE_TEST_ARGS = -n test -a test -p test -u test + + include $(top_srcdir)/make/agentccheck.mk +diff --git a/fence/agents/zvm/fence_zvm.c b/fence/agents/zvm/fence_zvm.c +index 2ec4be9..e5a7c2b 100644 +--- a/fence/agents/zvm/fence_zvm.c ++++ b/fence/agents/zvm/fence_zvm.c +@@ -599,6 +599,7 @@ zvm_metadata() + fprintf (stdout, ""); + fprintf (stdout, "The fence_zvm agent is intended to be used with with z/VM SMAPI service."); + fprintf (stdout, "\n"); ++ fprintf (stdout, "http://www.ibm.com\n"); + + fprintf (stdout, "\n"); + +diff --git a/fence/agents/zvm/fence_zvmip.c b/fence/agents/zvm/fence_zvmip.c +index 94c9e2e..3342bc6 100644 +--- a/fence/agents/zvm/fence_zvmip.c ++++ b/fence/agents/zvm/fence_zvmip.c +@@ -804,6 +804,7 @@ zvm_metadata() + fprintf (stdout, ""); + fprintf (stdout, "The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP"); + fprintf (stdout, "\n"); ++ fprintf (stdout, "http://www.ibm.com\n"); + + fprintf (stdout, "\n"); + +-- +1.9.3 + diff --git a/SOURCES/bz1140921-2-fence_zvm.patch b/SOURCES/bz1140921-2-fence_zvm.patch new file mode 100644 index 0000000..4f25bc3 --- /dev/null +++ b/SOURCES/bz1140921-2-fence_zvm.patch @@ -0,0 +1,226 @@ +commit 004ce512d61867bcc981ae49c5fbf5ffb30172fa +Author: Marek 'marx' Grac +Date: Mon Sep 15 15:05:25 2014 +0200 + + fence_zvm: Add support for 'on', improve documentation + + Author: Neale Ferguson + +diff --git a/fence/agents/zvm/fence_zvm.8 b/fence/agents/zvm/fence_zvm.8 +index 359436e..8c0d35a 100644 +--- a/fence/agents/zvm/fence_zvm.8 ++++ b/fence/agents/zvm/fence_zvm.8 +@@ -52,7 +52,7 @@ forcibly terminated. Currently, this option is ignored. + This option is used by fence_node(8) and is ignored by fence_zvm. + .TP + \fIaction = < action >\fP +-Fencing action: "off" - fence off device; "metadata" - display device metadata; "status" - state of device ++Fencing action: "off" - deactivate virtual machine; "on" - activate virtual machine; "metadata" - display device metadata" - describe fence agent parameters; "status" - state of virtual machine + .TP + \fIport = < target >\fP + Name of virtual machine to recycle. +diff --git a/fence/agents/zvm/fence_zvm.c b/fence/agents/zvm/fence_zvm.c +index e5a7c2b..524e21e 100644 +--- a/fence/agents/zvm/fence_zvm.c ++++ b/fence/agents/zvm/fence_zvm.c +@@ -699,15 +699,15 @@ get_options_stdin (zvm_driver_t *zvm) + + if (!strcasecmp (opt, "action")) { + if (strcasecmp(arg, "off") == 0) { +- fence = 0; +- } else if (strcasecmp(arg, "on") == 0) { + fence = 1; +- } else if (strcasecmp(arg, "metadata") == 0) { ++ } else if (strcasecmp(arg, "on") == 0) { + fence = 2; +- } else if (strcasecmp(arg, "status") == 0) { ++ } else if (strcasecmp(arg, "metadata") == 0) { + fence = 3; +- } else { ++ } else if (strcasecmp(arg, "status") == 0) { + fence = 4; ++ } else { ++ fence = 5; + } + } else if (!strcasecmp (opt, "ipaddr")) { + lSrvName = MIN(strlen(arg), sizeof(zvm->smapiSrv)); +@@ -738,7 +738,7 @@ get_options_stdin (zvm_driver_t *zvm) + zvm->delay = DEFAULT_DELAY; + } + } else if (!strcasecmp (opt, "help")) { +- fence = 4; ++ fence = 5; + } + } + return(fence); +@@ -769,15 +769,15 @@ get_options(int argc, char **argv, zvm_driver_t *zvm) + break; + case 'o' : + if (strcasecmp(optarg, "off") == 0) { +- fence = 0; +- } else if (strcasecmp(optarg, "on") == 0) { + fence = 1; +- } else if (strcasecmp(optarg, "metadata") == 0) { ++ } else if (strcasecmp(optarg, "on") == 0) { + fence = 2; +- } else if (strcasecmp(optarg, "status") == 0) { ++ } else if (strcasecmp(optarg, "metadata") == 0) { + fence = 3; +- } else { ++ } else if (strcasecmp(optarg, "status") == 0) { + fence = 4; ++ } else { ++ fence = 5; + } + break; + case 'a' : +@@ -807,7 +807,7 @@ get_options(int argc, char **argv, zvm_driver_t *zvm) + memcpy(zvm->node, optarg, lSrvNode); + break; + default : +- fence = 4; ++ fence = 5; + } + } + return(fence); +@@ -874,22 +874,26 @@ main(int argc, char **argv) + fence = get_options_stdin(&zvm); + + switch(fence) { +- case 0 : // OFF ++ case 0 : // OFFON ++ if ((rc = check_parm(&zvm)) == 0) ++ rc = zvm_smapi_imageRecycle(&zvm); ++ break; ++ case 1 : // OFF + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageDeactivate(&zvm); + break; +- case 1 : // ON ++ case 2 : // ON + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageActivate(&zvm); + break; +- case 2 : // METADATA ++ case 3 : // METADATA + rc = zvm_metadata(); + break; +- case 3 : // STATUS ++ case 4 : // STATUS + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageQuery(&zvm); + break; +- case 4 : ++ case 5 : + rc = usage(); + } + closelog(); +diff --git a/fence/agents/zvm/fence_zvmip.8 b/fence/agents/zvm/fence_zvmip.8 +index 8217d61..6b01425 100644 +--- a/fence/agents/zvm/fence_zvmip.8 ++++ b/fence/agents/zvm/fence_zvmip.8 +@@ -55,7 +55,7 @@ Display usage information + This option is used by fence_node(8) and is ignored by fence_zvmip. + .TP + \fIaction = < action >\fP +-Fencing action: "off" - fence off device; "metadata" - display device metadata; "status" - state of device ++Fencing action: "off" - deactivate virtual machine; "on" - activate virtual machine; "metadata" - display device metadata" - describe fence agent parameters; "status" - state of virtual machine + .TP + \fIplug = < plug >\fP + Name of virtual machine to recycle. +diff --git a/fence/agents/zvm/fence_zvmip.c b/fence/agents/zvm/fence_zvmip.c +index 3342bc6..bd7c536 100644 +--- a/fence/agents/zvm/fence_zvmip.c ++++ b/fence/agents/zvm/fence_zvmip.c +@@ -677,15 +677,15 @@ get_options_stdin (zvm_driver_t *zvm) + + if (!strcasecmp (opt, "action")) { + if (strcasecmp(arg, "off") == 0) { +- fence = 0; +- } else if (strcasecmp(arg, "on") == 0) { + fence = 1; +- } else if (strcasecmp(arg, "metadata") == 0) { ++ } else if (strcasecmp(arg, "on") == 0) { + fence = 2; +- } else if (strcasecmp(arg, "status") == 0) { ++ } else if (strcasecmp(arg, "metadata") == 0) { + fence = 3; +- } else { ++ } else if (strcasecmp(arg, "status") == 0) { + fence = 4; ++ } else { ++ fence = 5; + } + } else if (!strcasecmp (opt, "ipaddr")) { + lSrvName = MIN(strlen(arg), sizeof(zvm->smapiSrv)-1); +@@ -712,7 +712,7 @@ get_options_stdin (zvm_driver_t *zvm) + zvm->timeOut = DEFAULT_TIMEOUT; + } + } else if (!strcasecmp (opt, "help")) { +- fence = 2; ++ fence = 5; + } + } + return(fence); +@@ -746,15 +746,15 @@ get_options(int argc, char **argv, zvm_driver_t *zvm) + break; + case 'o' : + if (strcasecmp(optarg, "off") == 0) { +- fence = 0; +- } else if (strcasecmp(optarg, "on") == 0) { + fence = 1; +- } else if (strcasecmp(optarg, "metadata") == 0) { ++ } else if (strcasecmp(optarg, "on") == 0) { + fence = 2; +- } else if (strcasecmp(optarg, "status") == 0) { ++ } else if (strcasecmp(optarg, "metadata") == 0) { + fence = 3; +- } else { ++ } else if (strcasecmp(optarg, "status") == 0) { + fence = 4; ++ } else { ++ fence = 5; + } + break; + case 'p' : +@@ -784,7 +784,7 @@ get_options(int argc, char **argv, zvm_driver_t *zvm) + } + break; + default : +- fence = 4; ++ fence = 5; + } + } + return(fence); +@@ -944,22 +944,26 @@ main(int argc, char **argv) + fence = get_options_stdin(&zvm); + + switch(fence) { +- case 0 : // OFF ++ case 0 : // OFFON ++ if ((rc = check_parm(&zvm)) == 0) ++ rc = zvm_smapi_imageRecycle(&zvm); ++ break; ++ case 1 : // OFF + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageDeactivate(&zvm); + break; +- case 1 : // ON ++ case 2 : // ON + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageActivate(&zvm); + break; +- case 2 : // METADATA ++ case 3 : // METADATA + rc = zvm_metadata(); + break; +- case 3 : // STATUS ++ case 4 : // STATUS + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageQuery(&zvm); + break; +- case 4 : ++ case 5 : + rc = usage(); + } + closelog(); diff --git a/SOURCES/bz1140921-3-fence_zvm.patch b/SOURCES/bz1140921-3-fence_zvm.patch new file mode 100644 index 0000000..dc28a48 --- /dev/null +++ b/SOURCES/bz1140921-3-fence_zvm.patch @@ -0,0 +1,417 @@ +commit c5ed2256e572bd06e8bf4ca00d6c891424ae4b00 +Author: Marek 'marx' Grac +Date: Thu Oct 23 16:33:26 2014 +0200 + + fence_zvm: Add support for 'monitor' + + Author: Neale Ferguson + +diff --git a/fence/agents/zvm/fence_zvm.c b/fence/agents/zvm/fence_zvm.c +index 524e21e..2f82e25 100644 +--- a/fence/agents/zvm/fence_zvm.c ++++ b/fence/agents/zvm/fence_zvm.c +@@ -51,6 +51,15 @@ + #define DEFAULT_TIMEOUT 300 + #define DEFAULT_DELAY 0 + ++#define ACT_OFFON 0 ++#define ACT_OFF 1 ++#define ACT_ON 2 ++#define ACT_METADATA 3 ++#define ACT_STATUS 4 ++#define ACT_MONITOR 5 ++#define ACT_LIST 6 ++#define ACT_HELP 7 ++ + static int zvm_smapi_reportError(void *, void *); + + static struct option longopts[] = { +@@ -64,7 +73,7 @@ static struct option longopts[] = { + {NULL, 0, NULL, 0} + }; + +-static char *optString = "a:ho:n:T:"; ++static const char *optString = "a:ho:n:T:"; + + static int zvm_metadata(void); + static int usage(void); +@@ -323,8 +332,7 @@ zvm_smapi_imageActivate(zvm_driver_t *zvm) + rc = 0; + } else { + if ((outPlist->hdr.rc == RCERR_IMAGEOP) & +- ((outPlist->hdr.reason == RS_NOT_ACTIVE) | +- (outPlist->hdr.reason == RS_BEING_DEACT))) { ++ (outPlist->hdr.reason == RS_ALREADY_ACTIVE)) { + syslog(LOG_INFO, "Activation of %s successful", + zvm->target); + rc = 0; +@@ -649,8 +657,11 @@ zvm_metadata() + + fprintf (stdout, "\n"); + fprintf (stdout, "\t\n"); +- fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); + fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); + fprintf (stdout, "\t\n"); + fprintf (stdout, "\n"); + +@@ -675,7 +686,7 @@ get_options_stdin (zvm_driver_t *zvm) + int32_t lSrvName, + lSrvNode, + lTarget; +- int fence = 0; ++ int fence = ACT_OFFON; + + while (fgets (buf, sizeof (buf), stdin) != 0) { + if (trim(buf) == 0) { +@@ -698,16 +709,22 @@ get_options_stdin (zvm_driver_t *zvm) + continue; + + if (!strcasecmp (opt, "action")) { +- if (strcasecmp(arg, "off") == 0) { +- fence = 1; ++ if (strcasecmp(arg, "reboot") == 0) { ++ fence = ACT_OFFON; ++ } else if (strcasecmp(arg, "off") == 0) { ++ fence = ACT_OFF; + } else if (strcasecmp(arg, "on") == 0) { +- fence = 2; ++ fence = ACT_ON; + } else if (strcasecmp(arg, "metadata") == 0) { +- fence = 3; ++ fence = ACT_METADATA; + } else if (strcasecmp(arg, "status") == 0) { +- fence = 4; ++ fence = ACT_STATUS; ++ } else if (strcasecmp(arg, "monitor") == 0) { ++ fence = ACT_MONITOR; ++ } else if (strcasecmp(arg, "list") == 0) { ++ fence = ACT_LIST; + } else { +- fence = 5; ++ fence = ACT_HELP; + } + } else if (!strcasecmp (opt, "ipaddr")) { + lSrvName = MIN(strlen(arg), sizeof(zvm->smapiSrv)); +@@ -738,7 +755,7 @@ get_options_stdin (zvm_driver_t *zvm) + zvm->delay = DEFAULT_DELAY; + } + } else if (!strcasecmp (opt, "help")) { +- fence = 5; ++ fence = ACT_HELP; + } + } + return(fence); +@@ -755,7 +772,7 @@ static int + get_options(int argc, char **argv, zvm_driver_t *zvm) + { + int c, +- fence = 0; ++ fence = ACT_OFFON; + int32_t lSrvName, + lSrvNode, + lTarget; +@@ -768,16 +785,22 @@ get_options(int argc, char **argv, zvm_driver_t *zvm) + memcpy(zvm->target, optarg, lTarget); + break; + case 'o' : +- if (strcasecmp(optarg, "off") == 0) { +- fence = 1; ++ if (strcasecmp(optarg, "reboot") == 0) { ++ fence = ACT_OFFON; ++ } else if (strcasecmp(optarg, "off") == 0) { ++ fence = ACT_OFF; + } else if (strcasecmp(optarg, "on") == 0) { +- fence = 2; ++ fence = ACT_ON; + } else if (strcasecmp(optarg, "metadata") == 0) { +- fence = 3; ++ fence = ACT_METADATA; + } else if (strcasecmp(optarg, "status") == 0) { +- fence = 4; ++ fence = ACT_STATUS; ++ } else if (strcasecmp(optarg, "monitor") == 0) { ++ fence = ACT_MONITOR; ++ } else if (strcasecmp(optarg, "list") == 0) { ++ fence = ACT_LIST; + } else { +- fence = 5; ++ fence = ACT_HELP; + } + break; + case 'a' : +@@ -807,7 +830,7 @@ get_options(int argc, char **argv, zvm_driver_t *zvm) + memcpy(zvm->node, optarg, lSrvNode); + break; + default : +- fence = 5; ++ fence = ACT_HELP; + } + } + return(fence); +@@ -822,7 +845,8 @@ usage() + { + fprintf(stderr,"Usage: fence_zvm [options]\n\n" + "\tWhere [options] =\n" +- "\t-o --action [action] - \"off\", \"on\", \"metadata\", \"status\"\n" ++ "\t-o --action [action] - \"off\", \"on\", \"list\", \"metadata\", " ++ "\"monitor\", \"reboot\", \"status\"\n" + "\t--delay [seconds] - Time to delay fencing action in seconds\n" + "\t-n --plug [target] - Name of virtual machine to fence\n" + "\t-a --ip [server] - Name of SMAPI IUCV Request server\n" +@@ -874,26 +898,33 @@ main(int argc, char **argv) + fence = get_options_stdin(&zvm); + + switch(fence) { +- case 0 : // OFFON ++ case ACT_OFFON : // OFFON + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageRecycle(&zvm); + break; +- case 1 : // OFF ++ case ACT_OFF : // OFF + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageDeactivate(&zvm); + break; +- case 2 : // ON ++ case ACT_ON : // ON + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageActivate(&zvm); + break; +- case 3 : // METADATA ++ case ACT_METADATA : // METADATA + rc = zvm_metadata(); + break; +- case 4 : // STATUS ++ case ACT_STATUS : // STATUS + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageQuery(&zvm); + break; +- case 5 : ++ case ACT_MONITOR : // MONITOR ++ rc = 0; ++ break; ++ case ACT_LIST : // LIST ++ printf("N/A"); ++ rc = 0; ++ break; ++ case ACT_HELP : + rc = usage(); + } + closelog(); +diff --git a/fence/agents/zvm/fence_zvmip.c b/fence/agents/zvm/fence_zvmip.c +index bd7c536..b16de48 100644 +--- a/fence/agents/zvm/fence_zvmip.c ++++ b/fence/agents/zvm/fence_zvmip.c +@@ -50,6 +50,15 @@ + #define DEFAULT_TIMEOUT 300 + #define DEFAULT_DELAY 0 + ++#define ACT_OFFON 0 ++#define ACT_OFF 1 ++#define ACT_ON 2 ++#define ACT_METADATA 3 ++#define ACT_STATUS 4 ++#define ACT_MONITOR 5 ++#define ACT_LIST 6 ++#define ACT_HELP 7 ++ + static int zvm_smapi_reportError(void *, void *); + + static struct option longopts[] = { +@@ -64,7 +73,7 @@ static struct option longopts[] = { + {NULL, 0, NULL, 0} + }; + +-static char *optString = "a:o:hn:p:t:u:"; ++static const char *optString = "a:o:hn:p:t:u:"; + + static int zvm_metadata(void); + static int usage(void); +@@ -376,8 +385,7 @@ zvm_smapi_imageActivate(zvm_driver_t *zvm) + rc = 0; + } else { + if ((outPlist->hdr.rc == RCERR_IMAGEOP) & +- ((outPlist->hdr.reason == RS_NOT_ACTIVE) | +- (outPlist->hdr.reason == RS_BEING_DEACT))) { ++ (outPlist->hdr.reason == RS_ALREADY_ACTIVE)) { + syslog(LOG_INFO, "Activation of %s successful", + zvm->target); + rc = 0; +@@ -653,7 +661,7 @@ get_options_stdin (zvm_driver_t *zvm) + *arg; + int32_t lSrvName, + lTarget; +- int fence = 0; ++ int fence = ACT_OFFON; + + while (fgets (buf, sizeof (buf), stdin) != 0) { + if (trim(buf) == 0) { +@@ -676,16 +684,22 @@ get_options_stdin (zvm_driver_t *zvm) + continue; + + if (!strcasecmp (opt, "action")) { +- if (strcasecmp(arg, "off") == 0) { +- fence = 1; ++ if (strcasecmp(arg, "reboot") == 0) { ++ fence = ACT_OFFON; ++ } else if (strcasecmp(arg, "off") == 0) { ++ fence = ACT_OFF; + } else if (strcasecmp(arg, "on") == 0) { +- fence = 2; ++ fence = ACT_ON; + } else if (strcasecmp(arg, "metadata") == 0) { +- fence = 3; ++ fence = ACT_METADATA; + } else if (strcasecmp(arg, "status") == 0) { +- fence = 4; ++ fence = ACT_STATUS; ++ } else if (strcasecmp(arg, "monitor") == 0) { ++ fence = ACT_MONITOR; ++ } else if (strcasecmp(arg, "list") == 0) { ++ fence = ACT_LIST; + } else { +- fence = 5; ++ fence = ACT_HELP; + } + } else if (!strcasecmp (opt, "ipaddr")) { + lSrvName = MIN(strlen(arg), sizeof(zvm->smapiSrv)-1); +@@ -712,7 +726,7 @@ get_options_stdin (zvm_driver_t *zvm) + zvm->timeOut = DEFAULT_TIMEOUT; + } + } else if (!strcasecmp (opt, "help")) { +- fence = 5; ++ fence = ACT_HELP; + } + } + return(fence); +@@ -729,7 +743,7 @@ static int + get_options(int argc, char **argv, zvm_driver_t *zvm) + { + int c, +- fence = 0; ++ fence = ACT_OFFON; + int32_t lSrvName, + lTarget; + char *endPtr; +@@ -745,16 +759,22 @@ get_options(int argc, char **argv, zvm_driver_t *zvm) + memcpy(zvm->target, optarg, lTarget); + break; + case 'o' : +- if (strcasecmp(optarg, "off") == 0) { +- fence = 1; ++ if (strcasecmp(optarg, "reboot") == 0) { ++ fence = ACT_OFFON; ++ } else if (strcasecmp(optarg, "off") == 0) { ++ fence = ACT_OFF; + } else if (strcasecmp(optarg, "on") == 0) { +- fence = 2; ++ fence = ACT_ON; + } else if (strcasecmp(optarg, "metadata") == 0) { +- fence = 3; ++ fence = ACT_METADATA; + } else if (strcasecmp(optarg, "status") == 0) { +- fence = 4; ++ fence = ACT_STATUS; ++ } else if (strcasecmp(optarg, "monitor") == 0) { ++ fence = ACT_MONITOR; ++ } else if (strcasecmp(optarg, "list") == 0) { ++ fence = ACT_LIST; + } else { +- fence = 5; ++ fence = ACT_HELP; + } + break; + case 'p' : +@@ -784,7 +804,7 @@ get_options(int argc, char **argv, zvm_driver_t *zvm) + } + break; + default : +- fence = 5; ++ fence = ACT_HELP; + } + } + return(fence); +@@ -861,9 +881,12 @@ zvm_metadata() + + fprintf (stdout, "\n"); + fprintf (stdout, "\t\n"); +- fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); + fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); + fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); + fprintf (stdout, "\n"); + + fprintf (stdout, "\n"); +@@ -881,7 +904,8 @@ usage() + { + fprintf(stderr,"Usage: fence_zvmip [options]\n\n" + "\tWhere [options] =\n" +- "\t-o --action [action] - \"off\", \"on\", \"metadata\", \"status\"\n" ++ "\t-o --action [action] - \"off\", \"on\", \"list\", \"metadata\", " ++ "\"monitor\", \"reboot\", \"status\"\n" + "\t--delay [seconds] - Time to delay fencing action in seconds\n" + "\t-n --plug [target] - Name of virtual machine to fence\n" + "\t-a --ip [server] - IP Name/Address of SMAPI Server\n" +@@ -944,26 +968,32 @@ main(int argc, char **argv) + fence = get_options_stdin(&zvm); + + switch(fence) { +- case 0 : // OFFON ++ case ACT_OFFON : // OFFON + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageRecycle(&zvm); + break; +- case 1 : // OFF ++ case ACT_OFF : // OFF + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageDeactivate(&zvm); + break; +- case 2 : // ON ++ case ACT_ON : // ON + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageActivate(&zvm); + break; +- case 3 : // METADATA ++ case ACT_METADATA : // METADATA + rc = zvm_metadata(); + break; +- case 4 : // STATUS ++ case ACT_STATUS : // STATUS + if ((rc = check_parm(&zvm)) == 0) + rc = zvm_smapi_imageQuery(&zvm); + break; +- case 5 : ++ case ACT_MONITOR : // MONITOR ++ rc = 0; ++ break; ++ case ACT_LIST : ++ printf("N/A"); ++ break; ++ case ACT_HELP : + rc = usage(); + } + closelog(); +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index 1e098d1..7791303 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -41,8 +41,11 @@ + + + +- ++ ++ + ++ + ++ + + diff --git a/SOURCES/bz1145769-fence_rhevm-cookies_auth.patch b/SOURCES/bz1145769-fence_rhevm-cookies_auth.patch new file mode 100644 index 0000000..cf11c88 --- /dev/null +++ b/SOURCES/bz1145769-fence_rhevm-cookies_auth.patch @@ -0,0 +1,89 @@ +commit 1dc12749623e3e3a06c3265260f5f049cdf6632b +Author: Marek 'marx' Grac +Date: Wed Jun 17 19:42:32 2015 +0200 + + fence_rhevm: Add support for cookies based authentication + + The first command is authenticated as usually but rest can be used without additional authentication. + This is useful only for reboot or obtaining status of several nodes at once. + + Resolves: rhbz#1145769 + +diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py +index 444fb56..bb34054 100644 +--- a/fence/agents/rhevm/fence_rhevm.py ++++ b/fence/agents/rhevm/fence_rhevm.py +@@ -87,9 +87,16 @@ def send_command(opt, command, method="GET"): + conn = pycurl.Curl() + web_buffer = StringIO.StringIO() + conn.setopt(pycurl.URL, url) +- conn.setopt(pycurl.HTTPHEADER, ["Content-type: application/xml", "Accept: application/xml"]) +- conn.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC) +- conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"]) ++ conn.setopt(pycurl.HTTPHEADER, ["Content-type: application/xml", "Accept: application/xml", "Prefer: persistent-auth"]) ++ ++ if opt.has_key("cookie"): ++ conn.setopt(pycurl.COOKIE, opt["cookie"]) ++ else: ++ conn.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC) ++ conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"]) ++ if opt.has_key("--use-cookies"): ++ conn.setopt(pycurl.COOKIEFILE, "") ++ + conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"])) + if opt.has_key("--ssl") or opt.has_key("--ssl-secure"): + conn.setopt(pycurl.SSL_VERIFYPEER, 1) +@@ -104,6 +111,15 @@ def send_command(opt, command, method="GET"): + + conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write) + conn.perform() ++ ++ if not opt.has_key("cookie") and opt.has_key("--use-cookies"): ++ cookie = "" ++ for c in conn.getinfo(pycurl.INFO_COOKIELIST): ++ tokens = c.split("\t",7) ++ cookie = cookie + tokens[5] + "=" + tokens[6] + ";" ++ ++ opt["cookie"] = cookie ++ + result = web_buffer.getvalue() + + logging.debug("%s\n", command) +@@ -111,10 +127,20 @@ def send_command(opt, command, method="GET"): + + return result + ++def define_new_opts(): ++ all_opt["use_cookies"] = { ++ "getopt" : "s", ++ "longopt" : "use-cookies", ++ "help" : "--use-cookies Reuse cookies for authentication", ++ "required" : "0", ++ "shortdesc" : "Reuse cookies for authentication", ++ "order" : 1} ++ + def main(): +- device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "web", "port"] ++ device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "web", "port", "use_cookies" ] + + atexit.register(atexit_handler) ++ define_new_opts() + + all_opt["power_wait"]["default"] = "1" + +diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +index 1eccd26..e0c9516 100644 +--- a/tests/data/metadata/fence_rhevm.xml ++++ b/tests/data/metadata/fence_rhevm.xml +@@ -53,6 +53,11 @@ + + SSL connection + ++ ++ ++ ++ Reuse cookies for authentication ++ + + + diff --git a/SOURCES/bz1148762-1-fence_wti_eol.patch b/SOURCES/bz1148762-1-fence_wti_eol.patch new file mode 100644 index 0000000..a9362f6 --- /dev/null +++ b/SOURCES/bz1148762-1-fence_wti_eol.patch @@ -0,0 +1,83 @@ +From d3d73eaa39dd49cc7fbc93b267daa7f51b1c5fff Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 2 Oct 2014 16:20:59 +0200 +Subject: [PATCH 2/2] fence_wti: Fix invalid "eol" + +Fence agent for WTI does not use standard telnet login because it is possible that username/password are not +required. EOL is set by fence_login() function that is not used, so we set it manually and replace +obsolete combination of send (+eol) to correct send_eol() + +Resolves: rhbz#1148762 +--- + fence/agents/wti/fence_wti.py | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py +index 78cd4e1..86f9a4d 100644 +--- a/fence/agents/wti/fence_wti.py ++++ b/fence/agents/wti/fence_wti.py +@@ -27,7 +27,7 @@ BUILD_DATE="March, 2008" + def get_listing(conn, options, listing_command): + listing = "" + +- conn.send(listing_command + "\r\n") ++ conn.send_eol(listing_command) + + if isinstance(options["--command-prompt"], list): + re_all = list(options["--command-prompt"]) +@@ -39,7 +39,7 @@ def get_listing(conn, options, listing_command): + result = conn.log_expect(options, re_all, int(options["--shell-timeout"])) + listing = conn.before + if result == (len(re_all) - 1): +- conn.send("\r\n") ++ conn.send_eol("") + conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) + listing += conn.before + +@@ -174,7 +174,7 @@ def set_power_status(conn, options): + 'off': "/off" + }[options["--action"]] + +- conn.send(action + " " + options["--plug"] + ",y\r\n") ++ conn.send_eol(action + " " + options["--plug"] + ",y") + conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) + + def main(): +@@ -207,6 +207,8 @@ is running because the connection will block any necessary fencing actions." + if options["--action"] in ["off", "reboot"]: + time.sleep(int(options["--delay"])) + ++ options["eol"] = "\r\n" ++ + conn = fspawn(options, TELNET_PATH) + conn.send("set binary\n") + conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"])) +@@ -217,14 +219,14 @@ is running because the connection will block any necessary fencing actions." + result = conn.log_expect(options, [re_login, "Password: ", re_prompt], int(options["--shell-timeout"])) + if result == 0: + if options.has_key("--username"): +- conn.send(options["--username"]+"\r\n") ++ conn.send_eol(options["--username"]) + result = conn.log_expect(options, [re_login, "Password: ", re_prompt], int(options["--shell-timeout"])) + else: + fail_usage("Failed: You have to set login name") + + if result == 1: + if options.has_key("--password"): +- conn.send(options["--password"]+"\r\n") ++ conn.send_eol(options["--password"]) + conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) + else: + fail_usage("Failed: You have to enter password or password script") +@@ -236,7 +238,7 @@ is running because the connection will block any necessary fencing actions." + conn = fence_login(options) + + result = fence_action(conn, options, set_power_status, get_power_status, get_power_status) +- fence_logout(conn, "/X\r\n") ++ fence_logout(conn, "/X") + sys.exit(result) + + if __name__ == "__main__": +-- +1.9.3 + diff --git a/SOURCES/bz1153059-1-fence_vmware_soap-fail_usage.patch b/SOURCES/bz1153059-1-fence_vmware_soap-fail_usage.patch new file mode 100644 index 0000000..37c5833 --- /dev/null +++ b/SOURCES/bz1153059-1-fence_vmware_soap-fail_usage.patch @@ -0,0 +1,60 @@ +commit a4cbf5ba86d196b236cc58ad2dee2f3317e1ee10 +Author: Marek 'marx' Grac +Date: Mon Sep 8 15:02:53 2014 +0200 + + [clenaup] Fix whitespace convention issues + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 557358a..640f81a 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -719,7 +719,6 @@ def check_input(device_opt, opt): + logging.getLogger().addHandler(SyslogLibHandler()) + ## add loggint to stderr + logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stderr)) +- + + acceptable_actions = ["on", "off", "status", "list", "monitor"] + if 1 == device_opt.count("fabric_fencing"): +@@ -1159,9 +1158,8 @@ def fence_logout(conn, logout_string, sleep=0): + def array_to_dict(ar): + return dict([[x[0].split(".")[-1], x[1]] for x in ar]) + +- + ## Own logger handler that uses old-style syslog handler as otherwise everything is sourced +-## from /dev/syslog ++## from /dev/syslog + class SyslogLibHandler(logging.StreamHandler): + """ + A handler class that correctly push messages into syslog +diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py +index 2cea105..e47f11e 100644 +--- a/fence/agents/vmware_soap/fence_vmware_soap.py ++++ b/fence/agents/vmware_soap/fence_vmware_soap.py +@@ -11,7 +11,7 @@ from suds.sudsobject import Property + from suds.transport.http import HttpAuthenticated + from suds.transport import Reply, TransportError + from fencing import * +-from fencing import fail, EC_STATUS, EC_LOGIN_DENIED, EC_INVALID_PRIVILEGES, EC_WAITING_ON, EC_WAITING_OFF ++from fencing import fail, fail_usage, EC_STATUS, EC_LOGIN_DENIED, EC_INVALID_PRIVILEGES, EC_WAITING_ON, EC_WAITING_OFF + from fencing import run_delay + + #BEGIN_VERSION_GENERATION +@@ -33,7 +33,7 @@ class RequestsTransport(HttpAuthenticated): + + def send(self, request): + self.addcredentials(request) +- resp = self.session.post(request.url, data = request.message, headers = request.headers, cert = self.cert, verify = self.verify) ++ resp = self.session.post(request.url, data=request.message, headers=request.headers, cert=self.cert, verify=self.verify) + result = Reply(resp.status_code, resp.headers, resp.content) + return result + +@@ -58,7 +58,7 @@ def soap_login(options): + + try: + headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : ""} +- conn = Client(url + "/vimService.wsdl", location = url, transport = RequestsTransport(verify = verify), headers = headers) ++ conn = Client(url + "/vimService.wsdl", location=url, transport=RequestsTransport(verify=verify), headers=headers) + + mo_ServiceInstance = Property('ServiceInstance') + mo_ServiceInstance._type = 'ServiceInstance' diff --git a/SOURCES/bz1162092-1-fix_ssl_secure.patch b/SOURCES/bz1162092-1-fix_ssl_secure.patch new file mode 100644 index 0000000..88b5246 --- /dev/null +++ b/SOURCES/bz1162092-1-fix_ssl_secure.patch @@ -0,0 +1,24 @@ +commit 83add70a8ef7690661d4d6d54500d85cc10d00ba +Author: Marek 'marx' Grac +Date: Mon Nov 10 10:58:54 2014 +0100 + + fencing: Fix problem with not validating SSL certificates + + In commit 809b909651118c06d2ab48d7911bbee2e512e478, --ssl-(in)secure options were + added. With --ssl be equal to --ssl-secure this was not implemented properly. + + Resolves: rhbz#1162092 + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 23270a7..29c0e47 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -996,7 +996,7 @@ def fence_login(options, re_login_string=r"(login\s*: )|(Login Name: )|(usernam + if options.has_key("--ssl-insecure"): + ssl_opts = "--insecure" + +- command = '%s %s %s --insecure --crlf -p %s %s' % \ ++ command = '%s %s %s --crlf -p %s %s' % \ + (SSL_PATH, gnutls_opts, ssl_opts, options["--ipport"], options["--ip"]) + try: + conn = fspawn(options, command) diff --git a/SOURCES/bz1165591-fence_cisco_ucs-https.patch b/SOURCES/bz1165591-fence_cisco_ucs-https.patch new file mode 100644 index 0000000..77e24ae --- /dev/null +++ b/SOURCES/bz1165591-fence_cisco_ucs-https.patch @@ -0,0 +1,27 @@ +From e283cfbba8bd6d6def515f59db5f150e0b58f780 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 19:47:00 +0200 +Subject: [PATCH 05/10] fence_cisco_ucs: protocol prefix of URL was not + correctly set with --ssl-(in)secure + +Resolves: rhbz#1165591 +--- + fence/agents/cisco_ucs/fence_cisco_ucs.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py +index f411433..825b5db 100644 +--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py +@@ -77,7 +77,7 @@ def get_list(conn, options): + + def send_command(opt, command, timeout): + ## setup correct URL +- if opt.has_key("--ssl"): ++ if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt: + url = "https:" + else: + url = "http:" +-- +1.9.3 + diff --git a/SOURCES/bz1171732-1-fence_emerson.patch b/SOURCES/bz1171732-1-fence_emerson.patch new file mode 100644 index 0000000..6d9a7b9 --- /dev/null +++ b/SOURCES/bz1171732-1-fence_emerson.patch @@ -0,0 +1,301 @@ +From 6c0e696eb3fa74645a269e8449829aecaf41200c Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 18 Jun 2015 18:38:04 +0200 +Subject: [PATCH 1/3] fence_emerson: New fence agent for Emerson's devices MPX + and MPH2 + +Thanks to Emerson Network Power + +Resolves: rhbz#1171732 +--- + configure.ac | 1 + + fence/agents/emerson/Makefile.am | 17 ++++ + fence/agents/emerson/fence_emerson.py | 67 ++++++++++++++ + tests/data/metadata/fence_emerson.xml | 165 ++++++++++++++++++++++++++++++++++ + 4 files changed, 250 insertions(+) + create mode 100644 fence/agents/emerson/Makefile.am + create mode 100644 fence/agents/emerson/fence_emerson.py + create mode 100644 tests/data/metadata/fence_emerson.xml + +diff --git a/configure.ac b/configure.ac +index 9d996d3..7abd701 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -272,6 +272,7 @@ AC_CONFIG_FILES([Makefile + fence/agents/drac5/Makefile + fence/agents/dummy/Makefile + fence/agents/eaton_snmp/Makefile ++ fence/agents/emerson/Makefile + fence/agents/eps/Makefile + fence/agents/hpblade/Makefile + fence/agents/ibmblade/Makefile +diff --git a/fence/agents/emerson/Makefile.am b/fence/agents/emerson/Makefile.am +new file mode 100644 +index 0000000..f7e5497 +--- /dev/null ++++ b/fence/agents/emerson/Makefile.am +@@ -0,0 +1,17 @@ ++MAINTAINERCLEANFILES = Makefile.in ++ ++TARGET = fence_emerson ++ ++SRC = $(TARGET).py ++ ++EXTRA_DIST = $(SRC) ++ ++sbin_SCRIPTS = $(TARGET) ++ ++man_MANS = $(TARGET).8 ++ ++FENCE_TEST_ARGS = -l test -p test -a test -n 1 ++ ++include $(top_srcdir)/make/fencebuild.mk ++include $(top_srcdir)/make/fenceman.mk ++include $(top_srcdir)/make/agentpycheck.mk +diff --git a/fence/agents/emerson/fence_emerson.py b/fence/agents/emerson/fence_emerson.py +new file mode 100644 +index 0000000..1ef911b +--- /dev/null ++++ b/fence/agents/emerson/fence_emerson.py +@@ -0,0 +1,67 @@ ++#!/usr/bin/python -tt ++ ++import sys ++import atexit ++sys.path.append("@FENCEAGENTSLIBDIR@") ++from fencing import * ++from fencing_snmp import FencingSnmp ++ ++#BEGIN_VERSION_GENERATION ++RELEASE_VERSION="Emerson SNMP fence agent" ++REDHAT_COPYRIGHT="" ++BUILD_DATE="" ++#END_VERSION_GENERATION ++ ++### CONSTANTS ### ++STATUSES_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.95" ++CONTROL_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.100" ++NAMES_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.10" ++ ++# Status constants returned as value from SNMP ++STATUS_DOWN = 1 ++STATUS_UP = 2 ++ ++# Status constants to set as value to SNMP ++STATUS_SET_OFF = 0 ++STATUS_SET_ON = 1 ++ ++def get_power_status(conn, options): ++ (_, status) = conn.get("%s.%s"% (STATUSES_OID, options["--plug"])) ++ return status == str(STATUS_UP) and "on" or "off" ++ ++def set_power_status(conn, options): ++ conn.set("%s.%s" % (CONTROL_OID, options["--plug"]), ++ (options["--action"] == "on" and STATUS_SET_ON or STATUS_SET_OFF)) ++ ++def get_outlets_status(conn, _): ++ result = {} ++ res_outlet = conn.walk(STATUSES_OID, 30) ++ ++ for outlet_info in res_outlet: ++ port_num = ".".join(outlet_info[0].split('.')[-3:]) ++ port_alias = conn.get("%s.%s"% (NAMES_OID, port_num))[1] ++ port_status = (outlet_info[1] == str(STATUS_UP) and "on" or "off") ++ result[port_num] = (port_alias, port_status) ++ return result ++ ++def main(): ++ device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \ ++ "port", "snmp_version", "community"] ++ ++ atexit.register(atexit_handler) ++ ++ options = check_input(device_opt, process_input(device_opt)) ++ ++ docs = {} ++ docs["shortdesc"] = "Fence agent for Emerson over SNMP" ++ docs["longdesc"] = "fence_emerson is an I/O Fencing agent \ ++ which can be used with MPX and MPH2 managed rack PDU." ++ docs["vendorurl"] = "http://www.emersonnetworkpower.com" ++ show_docs(options, docs) ++ ++ # Operate the fencing device ++ result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status) ++ ++ sys.exit(result) ++if __name__ == "__main__": ++ main() +diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +new file mode 100644 +index 0000000..3b49b56 +--- /dev/null ++++ b/tests/data/metadata/fence_emerson.xml +@@ -0,0 +1,165 @@ ++ ++ ++fence_emerson is an I/O Fencing agent which can be used with MPX and MPH2 managed rack PDU. ++http://www.emersonnetworkpower.com ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Set the community string ++ ++ ++ ++ ++ Forces agent to use IPv4 addresses only ++ ++ ++ ++ ++ Forces agent to use IPv6 addresses only ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ TCP/UDP port to use for connection with device ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ ++ Set authentication protocol (MD5|SHA) ++ ++ ++ ++ ++ Set privacy protocol password ++ ++ ++ ++ ++ Script to run to retrieve privacy password ++ ++ ++ ++ ++ ++ Set privacy protocol (DES|AES) ++ ++ ++ ++ ++ ++ Set security level (noAuthNoPriv|authNoPriv|authPriv) ++ ++ ++ ++ ++ ++ Specifies SNMP version to use (1,2c,3) ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Separator for CSV created by operation list ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.9.3 + diff --git a/SOURCES/bz1171732-2-fence_emerson.patch b/SOURCES/bz1171732-2-fence_emerson.patch new file mode 100644 index 0000000..e77b918 --- /dev/null +++ b/SOURCES/bz1171732-2-fence_emerson.patch @@ -0,0 +1,40 @@ +From 8411a5c5ef335a22f80244c81afc1aa2430cdb53 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 18 Jun 2015 18:38:42 +0200 +Subject: [PATCH 2/3] fence_emerson: Add power-wait=5seconds because device is + too fast + +Resolves: rhbz#1171732 +--- + fence/agents/emerson/fence_emerson.py | 1 + + tests/data/metadata/fence_emerson.xml | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/emerson/fence_emerson.py b/fence/agents/emerson/fence_emerson.py +index 1ef911b..af7f132 100644 +--- a/fence/agents/emerson/fence_emerson.py ++++ b/fence/agents/emerson/fence_emerson.py +@@ -50,6 +50,7 @@ def main(): + + atexit.register(atexit_handler) + ++ all_opt["power_wait"]["default"] = "5" + options = check_input(device_opt, process_input(device_opt)) + + docs = {} +diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +index 3b49b56..1aa5474 100644 +--- a/tests/data/metadata/fence_emerson.xml ++++ b/tests/data/metadata/fence_emerson.xml +@@ -139,7 +139,7 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + +-- +1.9.3 + diff --git a/SOURCES/bz1171732-3-fence_emerson.patch b/SOURCES/bz1171732-3-fence_emerson.patch new file mode 100644 index 0000000..df9c136 --- /dev/null +++ b/SOURCES/bz1171732-3-fence_emerson.patch @@ -0,0 +1,190 @@ +From 362b0e25859c044415a88361101ff4518b2d0d11 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 18 Jun 2015 18:41:46 +0200 +Subject: [PATCH 3/3] fence_emerson: Add XML metadata + +Resolves: rhbz#1171732 +--- + tests/data/metadata/fence_emerson.xml | 120 +++++++++++++++++----------------- + 1 file changed, 60 insertions(+), 60 deletions(-) + +diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +index 1aa5474..553fc37 100644 +--- a/tests/data/metadata/fence_emerson.xml ++++ b/tests/data/metadata/fence_emerson.xml +@@ -3,20 +3,37 @@ + fence_emerson is an I/O Fencing agent which can be used with MPX and MPH2 managed rack PDU. + http://www.emersonnetworkpower.com + +- +- +- +- Fencing Action ++ ++ ++ ++ TCP/UDP port to use for connection with device ++ ++ ++ ++ ++ ++ Specifies SNMP version to use (1,2c,3) + + + + + Set the community string + +- +- +- +- Forces agent to use IPv4 addresses only ++ ++ ++ ++ ++ Set privacy protocol (DES|AES) ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID + + + +@@ -28,30 +45,15 @@ + + IP Address or Hostname + +- +- +- +- TCP/UDP port to use for connection with device +- +- +- +- +- Login Name +- +- +- +- +- Login password or passphrase +- +- +- ++ ++ + +- Script to retrieve password ++ Set privacy protocol password + +- +- ++ ++ + +- Physical plug number, name of virtual machine or UUID ++ Script to run to retrieve privacy password + + + +@@ -61,23 +63,15 @@ + + Set authentication protocol (MD5|SHA) + +- +- +- +- Set privacy protocol password ++ ++ ++ ++ Forces agent to use IPv4 addresses only + +- +- ++ ++ + +- Script to run to retrieve privacy password +- +- +- +- +- +- Set privacy protocol (DES|AES) ++ Script to retrieve password + + + +@@ -88,14 +82,20 @@ + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- +- +- +- +- Specifies SNMP version to use (1,2c,3) ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Login Name + + + +@@ -122,10 +122,10 @@ + + Separator for CSV created by operation list + +- +- +- +- Wait X seconds before fencing is started ++ ++ ++ ++ Wait X seconds after issuing ON/OFF + + + +@@ -137,10 +137,10 @@ + + Test X seconds for status change after ON/OFF + +- +- +- +- Wait X seconds after issuing ON/OFF ++ ++ ++ ++ Wait X seconds before fencing is started + + + +-- +1.9.3 + diff --git a/SOURCES/bz1173178-1-rewrite_fence_zvmip.patch b/SOURCES/bz1173178-1-rewrite_fence_zvmip.patch new file mode 100644 index 0000000..ed38944 --- /dev/null +++ b/SOURCES/bz1173178-1-rewrite_fence_zvmip.patch @@ -0,0 +1,358 @@ +From f5401fc8dad9a39da0a279b7d55149dc0ebcba26 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 5 Jan 2015 10:15:36 +0100 +Subject: [PATCH] fence_zvmip: Port fence agent to fencing library + +This rewrite adds a correct result codes, support for 'list' action and +autogenerated manual page. The original code is still part of codebase as +new agent requires additional testing. +--- + fence/agents/lib/fencing.py.py | 4 + + fence/agents/zvm/Makefile.am | 26 ++---- + fence/agents/zvm/fence_zvmip.8 | 92 ------------------- + fence/agents/zvm/fence_zvmip.py | 172 ++++++++++++++++++++++++++++++++++++ + 5 files changed, 310 insertions(+), 149 deletions(-) + delete mode 100644 fence/agents/zvm/fence_zvmip.8 + create mode 100644 fence/agents/zvm/fence_zvmip.py + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index a8ea448..83bbfcd 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -7,6 +7,7 @@ import subprocess + import threading + import shlex + import exceptions ++import socket + import __main__ + + ## do not add code here. +@@ -805,6 +806,9 @@ def fence_action(connection, options, set_power_fn, get_power_fn, get_outlet_lis + except pycurl.error, ex: + logging.error("%s\n", str(ex)) + fail(EC_TIMED_OUT) ++ except socket.timeout, ex: ++ logging.error("%s\n", str(ex)) ++ fail(EC_TIMED_OUT) + + return result + +diff --git a/fence/agents/zvm/Makefile.am b/fence/agents/zvm/Makefile.am +index 62eb862..a29754d 100644 +--- a/fence/agents/zvm/Makefile.am ++++ b/fence/agents/zvm/Makefile.am +@@ -2,26 +2,16 @@ MAINTAINERCLEANFILES = Makefile.in + + TARGET = fence_zvmip + +-sbin_PROGRAMS = fence_zvm fence_zvmip ++SRC = $(TARGET).py + +-noinst_HEADERS = fence_zvm.h ++EXTRA_DIST = $(SRC) + +-fence_zvm_SOURCES = fence_zvm.c +-fence_zvm_CFLAGS = -D_GNU_SOURCE ++sbin_SCRIPTS = $(TARGET) + +-fence_zvmip_SOURCES = fence_zvmip.c +-fence_zvmip_CFLAGS = -D_GNU_SOURCE ++man_MANS = $(TARGET).8 + +-dist_man_MANS = fence_zvm.8 fence_zvmip.8 ++FENCE_TEST_ARGS = -l test -p test -a test -n 1 + +-#include $(top_srcdir)/make/fencemanc.mk +- +-clean-local: +- rm -f $(sbin_PROGRAMS) +- +-FENCE_TEST_ARGS = -n test -a test -p test -u test +- +-include $(top_srcdir)/make/agentccheck.mk +- +-# we do not test fence_zvm because it can be compiled only on specific architecture +-check: xml-check.fence_zvmip delay-check.fence_zvmip +\ No newline at end of file ++include $(top_srcdir)/make/fencebuild.mk ++include $(top_srcdir)/make/fenceman.mk ++include $(top_srcdir)/make/agentpycheck.mk +diff --git a/fence/agents/zvm/fence_zvmip.8 b/fence/agents/zvm/fence_zvmip.8 +deleted file mode 100644 +index 6b01425..0000000 +--- a/fence/agents/zvm/fence_zvmip.8 ++++ /dev/null +@@ -1,92 +0,0 @@ +-.TH fence_zvmip 8 +- +-.SH NAME +-fence_zvmip - Power Fencing agent for GFS on System z z/VM Clusters using IP interface to SMAPI +- +-.SH SYNOPSIS +-.B +-fence_zvmip +-[\fIOPTION\fR]... +- +-.SH DESCRIPTION +-fence_zvmip is a Power Fencing agent used on a GFS virtual machine in a System z z/VM cluster. +-It uses the TCP/IP SMAPI interface to recycle an active image. +- +-fence_zvmip accepts options on the command line as well as from stdin. +-fence_node sends the options through stdin when it execs the agent. +-fence_zvmip can be run by itself with command line options which is useful +-for testing. +- +-Vendor URL: http://www.sinenomine.net +- +-.SH OPTIONS +-.TP +-\fB-o --action\fP +-Fencing action: "off" - deactivate virtual machine; "on" - activate virtual machine; "metadata" - display device metadata" - describe fence agent parameters; "status" - state of virtual machine +-.TP +-\fB--delay\fP \fIseconds\fP +-Time to delay fencing action in seconds +-.TP +-\fB-n --plug\fP \fItarget\fP +-Name of target virtual machine to fence +-.TP +-\fB-h --help\fP +-Print out a help message describing available options, then exit. +-.TP +-\fB-a --ip\fP \fIsmapi Server\fP +-Host name or IP address of SMAPI server +-.TP +-\fB-u --username\fP \fISMAPI authorized user\fP +-Name of an authorized SMAPI user +-.TP +-\fB-p --password\fP \fISMAPI authorized user's password\fP +-Password of the authorized SMAPI user +-.TP +-\fB-t --timeout\fP \fIRecycle timeout\fP +-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being +-forcibly terminated. Currently this is ignored. +-.TP +-\fB-h --help\fP +-Display usage information +- +-.SH STDIN PARAMETERS +-.TP +-\fIagent = < param >\fP +-This option is used by fence_node(8) and is ignored by fence_zvmip. +-.TP +-\fIaction = < action >\fP +-Fencing action: "off" - deactivate virtual machine; "on" - activate virtual machine; "metadata" - display device metadata" - describe fence agent parameters; "status" - state of virtual machine +-.TP +-\fIplug = < plug >\fP +-Name of virtual machine to recycle. +-.TP +-\fIipaddr = < server host name or IP address >\fP +-Host name or IP address of SMAPI server +-.TP +-\fIlogin = < SMAPI authorized user >\fP +-Name of an authorized SMAPI user +-.TP +-\fIpasswd = < SMAPI authorized user's password >\fP +-Password of the authorized SMAPI user +-.TP +-\fItimeout = < shutdown timeout >\fP +-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being +-forcibly terminated. Currently this is ignored. +- +-.SH SEE ALSO +-fence(8), fenced(8), fence_node(8) +- +-.SH NOTES +-To use this agent the z/VM SMAPI service needs to be configured to allow the virtual +-machine running this agent to connect to it and issue the image_recycle operation. +-This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look +-something similar to this: +- +-.nf +-Column 1 Column 66 Column 131 +-| | | +-V V V +-XXXXXXXX ALL IMAGE_OPERATIONS +-.fi +- +-Where XXXXXXX is the name of the virtual machine used in the authuser field of the request. +diff --git a/fence/agents/zvm/fence_zvmip.py b/fence/agents/zvm/fence_zvmip.py +new file mode 100644 +index 0000000..63f7fa7 +--- /dev/null ++++ b/fence/agents/zvm/fence_zvmip.py +@@ -0,0 +1,172 @@ ++#!/usr/bin/python -tt ++ ++import sys ++import atexit ++import socket ++import struct ++import logging ++sys.path.append("@FENCEAGENTSLIBDIR@") ++from fencing import * ++from fencing import fail, fail_usage, run_delay, EC_LOGIN_DENIED, EC_TIMED_OUT ++ ++#BEGIN_VERSION_GENERATION ++RELEASE_VERSION="" ++REDHAT_COPYRIGHT="" ++BUILD_DATE="" ++#END_VERSION_GENERATION ++ ++INT4 = 4 ++ ++def open_socket(options): ++ try: ++ if "--inet6-only" in options: ++ protocol = socket.AF_INET6 ++ elif "--inet4-only" in options: ++ protocol = socket.AF_INET ++ else: ++ protocol = 0 ++ (_, _, _, _, addr) = socket.getaddrinfo( \ ++ options["--ip"], options["--ipport"], protocol, ++ 0, socket.IPPROTO_TCP, socket.AI_PASSIVE ++ )[0] ++ except socket.gaierror: ++ fail(EC_LOGIN_DENIED) ++ ++ conn = socket.socket() ++ conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ++ conn.settimeout(float(options["--shell-timeout"])) ++ try: ++ conn.connect(addr) ++ except socket.error: ++ fail(EC_LOGIN_DENIED) ++ ++ return conn ++ ++def smapi_pack_string(string): ++ return struct.pack("!i%ds" % (len(string)), len(string), string) ++ ++def prepare_smapi_command(options, smapi_function, additional_args): ++ packet_size = 3*INT4 + len(smapi_function) + len(options["--username"]) + len(options["--password"]) ++ for arg in additional_args: ++ packet_size += INT4 + len(arg) ++ ++ command = struct.pack("!i", packet_size) ++ command += smapi_pack_string(smapi_function) ++ command += smapi_pack_string(options["--username"]) ++ command += smapi_pack_string(options["--password"]) ++ for arg in additional_args: ++ command += smapi_pack_string(arg) ++ ++ return command ++ ++def get_power_status(conn, options): ++ del conn ++ ++ # '*' = list all active images ++ (return_code, reason_code, images_active) = \ ++ get_list_of_images(options, "Image_Status_Query", "*") ++ logging.debug("Image_Status_Query results are (%d,%d)", return_code, reason_code) ++ (return_code, reason_code, images_defined) = \ ++ get_list_of_images(options, "Image_Name_Query_DM", options["--username"]) ++ logging.debug("Image_Name_Query_DM results are (%d,%d)", return_code, reason_code) ++ ++ if ["list", "monitor"].count(options["--action"]) == 1: ++ return dict([(i, ("", "on" if i in images_active else "off")) for i in images_defined]) ++ else: ++ status = "error" ++ if options["--plug"].upper() in images_defined: ++ if options["--plug"].upper() in images_active: ++ status = "on" ++ else: ++ status = "off" ++ return status ++ ++def set_power_status(conn, options): ++ conn = open_socket(options) ++ ++ packet = None ++ if options["--action"] == "on": ++ packet = prepare_smapi_command(options, "Image_Activate", [options["--plug"]]) ++ elif options["--action"] == "off": ++ packet = prepare_smapi_command(options, "Image_Deactivate", [options["--plug"], "IMMED"]) ++ conn.send(packet) ++ ++ request_id = struct.unpack("!i", conn.recv(INT4))[0] ++ (output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4)) ++ logging.debug("Image_(De)Activate results are (%d,%d)", return_code, reason_code) ++ ++ conn.close() ++ return ++ ++def get_list_of_images(options, command, data_as_plug): ++ conn = open_socket(options) ++ ++ packet = prepare_smapi_command(options, command, [data_as_plug]) ++ conn.send(packet) ++ ++ request_id = struct.unpack("!i", conn.recv(INT4))[0] ++ (output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4)) ++ images = set() ++ ++ if output_len > 3*INT4: ++ array_len = struct.unpack("!i", conn.recv(INT4))[0] ++ data = "" ++ ++ while True: ++ read_data = conn.recv(1024, socket.MSG_WAITALL) ++ data += read_data ++ if array_len == len(data): ++ break ++ elif not read_data: ++ logging.error("Failed: Not enough data read from socket") ++ fail(EC_TIMED_OUT) ++ ++ parsed_len = 0 ++ while parsed_len < array_len: ++ string_len = struct.unpack("!i", data[parsed_len:parsed_len+INT4])[0] ++ parsed_len += INT4 ++ image_name = struct.unpack("!%ds" % (string_len), data[parsed_len:parsed_len+string_len])[0] ++ parsed_len += string_len ++ images.add(image_name) ++ ++ conn.close() ++ return (return_code, reason_code, images) ++ ++def main(): ++ device_opt = ["ipaddr", "login", "passwd", "port", "method"] ++ ++ atexit.register(atexit_handler) ++ ++ all_opt["ipport"]["default"] = "44444" ++ all_opt["shell_timeout"]["default"] = "5.0" ++ options = check_input(device_opt, process_input(device_opt)) ++ ++ if len(options.get("--plug", "")) > 8: ++ fail_usage("Failed: Name of image can not be longer than 8 characters") ++ ++ docs = {} ++ docs["shortdesc"] = "Fence agent for use with z/VM Virtual Machines" ++ docs["longdesc"] = """The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP ++ ++To use this agent the z/VM SMAPI service needs to be configured to allow the virtual machine running this agent to connect to it and issue ++the image_recycle operation. This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look something similar to ++this: ++ ++Column 1 Column 66 Column 131 ++ ++ | | | ++ V V V ++ ++XXXXXXXX ALL IMAGE_OPERATIONS ++ ++Where XXXXXXX is the name of the virtual machine used in the authuser field of the request. ++""" ++ docs["vendorurl"] = "http://www.ibm.com" ++ show_docs(options, docs) ++ ++ run_delay(options) ++ result = fence_action(None, options, set_power_status, get_power_status, get_power_status) ++ sys.exit(result) ++ ++if __name__ == "__main__": ++ main() +-- +1.9.3 + diff --git a/SOURCES/bz1185329-fence_rsa.patch b/SOURCES/bz1185329-fence_rsa.patch new file mode 100644 index 0000000..c60396b --- /dev/null +++ b/SOURCES/bz1185329-fence_rsa.patch @@ -0,0 +1,27 @@ +From 0a7ef22b8562539cbcff1bc68b9d6b8b65bbbbe0 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 5 Aug 2015 15:40:52 +0200 +Subject: [PATCH 4/4] fencing: Password was awaited twice in some cases when + connecting via telnet + +Resolves:rhbz#1185329 +--- + fence/agents/lib/fencing.py.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 8b14cf2..fb7b77d 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -1140,7 +1140,7 @@ def fence_login(options, re_login_string=r"(login\s*: )|(Login Name: )|(usernam + options["eol"] = "\n" + conn.send_eol(options["--username"]) + result = conn.log_expect(options, re_pass, int(options["--login-timeout"])) +- elif re_pass.search(screen) != None: ++ elif re_pass.search(screen) == None: + conn.log_expect(options, re_pass, int(options["--shell-timeout"])) + + try: +-- +1.9.3 + diff --git a/SOURCES/bz1188750-0-fence_zvmip-improve_usage_of_resources.patch b/SOURCES/bz1188750-0-fence_zvmip-improve_usage_of_resources.patch new file mode 100644 index 0000000..6151a72 --- /dev/null +++ b/SOURCES/bz1188750-0-fence_zvmip-improve_usage_of_resources.patch @@ -0,0 +1,192 @@ +commit 11627cc153c891b2e55d0d5e64d5a566516f29d8 +Author: Marek 'marx' Grac +Date: Mon Jan 5 10:15:36 2015 +0100 + + fence_zvmip: Port fence agent to fencing library + + This rewrite adds a correct result codes, support for 'list' action and + autogenerated manual page. The original code is still part of codebase as + new agent requires additional testing. + +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index 0a4ede1..03220cb 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -1,50 +1,138 @@ + +- +-The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP ++ ++The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP ++ ++To use this agent the z/VM SMAPI service needs to be configured to allow the virtual machine running this agent to connect to it and issue ++the image_recycle operation. This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look something similar to ++this: ++ ++Column 1 Column 66 Column 131 ++ ++ | | | ++ V V V ++ ++XXXXXXXX ALL IMAGE_OPERATIONS ++ ++Where XXXXXXX is the name of the virtual machine used in the authuser field of the request. ++ ++http://www.ibm.com + +- +- +- +- Name of the Virtual Machine to be fenced +- +- +- +- +- IP Name or Address of SMAPI Server +- +- +- +- +- Name of authorized SMAPI user +- +- +- +- +- Password of authorized SMAPI user +- +- +- +- +- Fencing action +- +- +- +- +- Time to delay fencing action in seconds +- +- ++ ++ ++ ++ TCP/UDP port to use for connection with device ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Forces agent to use IPv6 addresses only ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Forces agent to use IPv4 addresses only ++ ++ ++ ++ ++ ++ Method to fence (onoff|cycle) ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ + +- +- Print usage ++ ++ Display help and exit ++ ++ ++ ++ ++ Separator for CSV created by operation list ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Count of attempts to retry power on + + + ++ + +- ++ ++ + +- + +- +- ++ + + diff --git a/SOURCES/bz1188750-fence_zvmip-improve_usage_of_resources.patch b/SOURCES/bz1188750-fence_zvmip-improve_usage_of_resources.patch new file mode 100644 index 0000000..913fa24 --- /dev/null +++ b/SOURCES/bz1188750-fence_zvmip-improve_usage_of_resources.patch @@ -0,0 +1,133 @@ +From 4ef3bd1bc0e7bb3fcd3c3b2a7ce20e49e37d3332 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 22 Jun 2015 16:49:27 +0200 +Subject: [PATCH] fence_zvmip: Add --missing-as-off and improve usage of system + resources + +Resolves: rhbz#1188750 +--- + fence/agents/lib/fencing.py.py | 5 ++++ + fence/agents/zvm/fence_zvmip.py | 49 +++++++++++++++++++++++++------------ + tests/data/metadata/fence_zvmip.xml | 5 ++++ + 3 files changed, 44 insertions(+), 15 deletions(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 29b3a94..db620e8 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -902,7 +902,12 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list=None, + return + elif (options["--action"] == "list") or \ + ((options["--action"] == "monitor") and 1 == options["device_opt"].count("port")): ++ options["--original-action"] = options["--action"] ++ options["--action"] = "list" + outlets = get_outlet_list(tn, options) ++ options["--action"] = options["--original-action"] ++ del options["--original-action"] ++ + ## keys can be numbers (port numbers) or strings (names of VM) + for outlet_id in outlets.keys(): + (alias, status) = outlets[outlet_id] +diff --git a/fence/agents/zvm/fence_zvmip.py b/fence/agents/zvm/fence_zvmip.py +index 63f7fa7..3fe6f24 100644 +--- a/fence/agents/zvm/fence_zvmip.py ++++ b/fence/agents/zvm/fence_zvmip.py +@@ -62,24 +62,38 @@ def prepare_smapi_command(options, smapi_function, additional_args): + def get_power_status(conn, options): + del conn + +- # '*' = list all active images ++ if options.get("--original-action", None) == "monitor": ++ (return_code, reason_code, images_active) = \ ++ get_list_of_images(options, "Check_Authentication", None) ++ logging.debug("Check_Authenticate (%d,%d)", return_code, reason_code) ++ if return_code == 0: ++ return {} ++ else: ++ fail(EC_LOGIN_DENIED) ++ ++ if options["--action"] == "list": ++ # '*' = list all active images ++ options["--plug"] = "*" ++ + (return_code, reason_code, images_active) = \ +- get_list_of_images(options, "Image_Status_Query", "*") ++ get_list_of_images(options, "Image_Status_Query", options["--plug"]) + logging.debug("Image_Status_Query results are (%d,%d)", return_code, reason_code) +- (return_code, reason_code, images_defined) = \ ++ ++ if not options["--action"] == "list": ++ if (return_code == 0) and (reason_code == 0): ++ return "on" ++ elif (return_code == 0) and (reason_code == 12): ++ # We are running always with --missing-as-off because we can not check if image ++ # is defined or not (look at rhbz#1188750) ++ return "off" ++ else: ++ return "unknown" ++ else: ++ (return_code, reason_code, images_defined) = \ + get_list_of_images(options, "Image_Name_Query_DM", options["--username"]) +- logging.debug("Image_Name_Query_DM results are (%d,%d)", return_code, reason_code) ++ logging.debug("Image_Name_Query_DM results are (%d,%d)", return_code, reason_code) + +- if ["list", "monitor"].count(options["--action"]) == 1: + return dict([(i, ("", "on" if i in images_active else "off")) for i in images_defined]) +- else: +- status = "error" +- if options["--plug"].upper() in images_defined: +- if options["--plug"].upper() in images_active: +- status = "on" +- else: +- status = "off" +- return status + + def set_power_status(conn, options): + conn = open_socket(options) +@@ -101,7 +115,11 @@ def set_power_status(conn, options): + def get_list_of_images(options, command, data_as_plug): + conn = open_socket(options) + +- packet = prepare_smapi_command(options, command, [data_as_plug]) ++ if data_as_plug is None: ++ packet = prepare_smapi_command(options, command, []) ++ else: ++ packet = prepare_smapi_command(options, command, [data_as_plug]) ++ + conn.send(packet) + + request_id = struct.unpack("!i", conn.recv(INT4))[0] +@@ -133,12 +151,13 @@ def get_list_of_images(options, command, data_as_plug): + return (return_code, reason_code, images) + + def main(): +- device_opt = ["ipaddr", "login", "passwd", "port", "method"] ++ device_opt = ["ipaddr", "login", "passwd", "port", "method", "missing_as_off"] + + atexit.register(atexit_handler) + + all_opt["ipport"]["default"] = "44444" + all_opt["shell_timeout"]["default"] = "5.0" ++ all_opt["missing_as_off"]["default"] = "1" + options = check_input(device_opt, process_input(device_opt)) + + if len(options.get("--plug", "")) > 8: +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index 03220cb..993dfb3 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -120,6 +120,11 @@ Where XXXXXXX is the name of the virtual machine used in the authuser field of t + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Missing port returns OFF instead of failure ++ + + + +-- +1.9.3 + diff --git a/SOURCES/bz1196068-2-fence_kdump-add_monitor.patch b/SOURCES/bz1196068-2-fence_kdump-add_monitor.patch new file mode 100644 index 0000000..c18d802 --- /dev/null +++ b/SOURCES/bz1196068-2-fence_kdump-add_monitor.patch @@ -0,0 +1,25 @@ +From 42c623ef2bb7d1114a07f880bb93c0ebf2dbab14 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 19:49:36 +0200 +Subject: [PATCH 07/10] fence_kdump: Fix problem in metadata + +Resolves: rhbz#1196068 +--- + fence/agents/kdump/fence_kdump.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/fence/agents/kdump/fence_kdump.c b/fence/agents/kdump/fence_kdump.c +index 5cea11d..29abbda 100644 +--- a/fence/agents/kdump/fence_kdump.c ++++ b/fence/agents/kdump/fence_kdump.c +@@ -233,7 +233,6 @@ do_action_metadata (const char *self) + + fprintf (stdout, "\t\n"); + fprintf (stdout, "\t\t\n"); +- fprintf (stdout, "\t\t\n"); + fprintf (stdout, "\t\t\n"); + fprintf (stdout, "\t\t%s\n", + "Fencing action"); +-- +1.9.3 + diff --git a/SOURCES/bz1196068-3-fence_kdump-add_monitor.patch b/SOURCES/bz1196068-3-fence_kdump-add_monitor.patch new file mode 100644 index 0000000..26ee5c5 --- /dev/null +++ b/SOURCES/bz1196068-3-fence_kdump-add_monitor.patch @@ -0,0 +1,55 @@ +From 67d1a3ea5d12b1a9f6ff222b55f42b3536a8a745 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 2 Mar 2015 10:58:06 +0100 +Subject: [PATCH 08/10] fence_kdump: Fix possible problems according to + Coverity + +Previously, there was issue detected by Coverity. They do not matter too much +because we care only about return value and it will not be 0 if program crash. +But it is always better to have clean code, so fixing. + +Resolves: rhbz#1196068 +--- + fence/agents/kdump/fence_kdump.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/fence/agents/kdump/fence_kdump.c b/fence/agents/kdump/fence_kdump.c +index 29abbda..781df64 100644 +--- a/fence/agents/kdump/fence_kdump.c ++++ b/fence/agents/kdump/fence_kdump.c +@@ -118,21 +118,22 @@ do_action_monitor (void) + { + const char cmdline_path[] = "/proc/cmdline"; + FILE *procFile; +- size_t sz; +- char *lines; +- int result; ++ size_t sz = 0; ++ char *lines = NULL; ++ int result = 1; + + procFile = fopen(cmdline_path, "r"); +- sz = 0; + +- while (!feof (procFile)) { +- getline (&lines, &sz, procFile); ++ if (procFile == NULL) { ++ log_error (0, "Unable to open file %s (%s)\n", cmdline_path, strerror (errno)); ++ return 1; + } + +- if (strstr(lines, "crashkernel=") == NULL) { +- result = 1; +- } else { +- result = 0; ++ while (!feof (procFile)) { ++ ssize_t rv = getline (&lines, &sz, procFile); ++ if ((rv != -1) && (strstr(lines, "crashkernel=") != NULL)) { ++ result = 0; ++ } + } + + free (lines); +-- +1.9.3 + diff --git a/SOURCES/bz1196068-4-fence_kdump-add_monitor.patch b/SOURCES/bz1196068-4-fence_kdump-add_monitor.patch new file mode 100644 index 0000000..2696a99 --- /dev/null +++ b/SOURCES/bz1196068-4-fence_kdump-add_monitor.patch @@ -0,0 +1,25 @@ +From 11f7e98101574a6d3006d92558dcd1bb699a0804 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 19:50:44 +0200 +Subject: [PATCH 09/10] testing: Update XML metadata after 'monitor' was added. + +Resolves: rhbz#1196068 +--- + tests/data/metadata/fence_kdump.xml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/data/metadata/fence_kdump.xml b/tests/data/metadata/fence_kdump.xml +index c985cac..08967fd 100644 +--- a/tests/data/metadata/fence_kdump.xml ++++ b/tests/data/metadata/fence_kdump.xml +@@ -46,6 +46,7 @@ + + + ++ + + + +-- +1.9.3 + diff --git a/SOURCES/bz1196068-fence_kdump-add_monitor.patch b/SOURCES/bz1196068-fence_kdump-add_monitor.patch new file mode 100644 index 0000000..656157d --- /dev/null +++ b/SOURCES/bz1196068-fence_kdump-add_monitor.patch @@ -0,0 +1,106 @@ +From ed0599391ab4066ec8cfa907efc58a9ce237cef2 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 19:48:21 +0200 +Subject: [PATCH 06/10] fence_kdump: Add 'monitor' action which tests + possibility of doing kdump on local node + +In case of fence_kdump we can not test if remote 'fencing device' is working because +fence_kdump_send is started only after kernel crash. So, monitor action checks if LOCAL +node can enter kdump. The test looks if crashkernel=.. occurs between boot arguments. + +Resolves: rhbz#1196068 +--- + fence/agents/kdump/fence_kdump.c | 35 ++++++++++++++++++++++++++++++++++- + fence/agents/kdump/options.h | 2 ++ + 2 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/kdump/fence_kdump.c b/fence/agents/kdump/fence_kdump.c +index cae9842..5cea11d 100644 +--- a/fence/agents/kdump/fence_kdump.c ++++ b/fence/agents/kdump/fence_kdump.c +@@ -114,6 +114,34 @@ out: + } + + static int ++do_action_monitor (void) ++{ ++ const char cmdline_path[] = "/proc/cmdline"; ++ FILE *procFile; ++ size_t sz; ++ char *lines; ++ int result; ++ ++ procFile = fopen(cmdline_path, "r"); ++ sz = 0; ++ ++ while (!feof (procFile)) { ++ getline (&lines, &sz, procFile); ++ } ++ ++ if (strstr(lines, "crashkernel=") == NULL) { ++ result = 1; ++ } else { ++ result = 0; ++ } ++ ++ free (lines); ++ fclose (procFile); ++ ++ return result; ++} ++ ++static int + do_action_off (const fence_kdump_opts_t *opts) + { + int error; +@@ -205,6 +233,7 @@ do_action_metadata (const char *self) + + fprintf (stdout, "\t\n"); + fprintf (stdout, "\t\t\n"); ++ fprintf (stdout, "\t\t\n"); + fprintf (stdout, "\t\t\n"); + fprintf (stdout, "\t\t%s\n", + "Fencing action"); +@@ -242,6 +271,7 @@ do_action_metadata (const char *self) + + fprintf (stdout, "\n"); + fprintf (stdout, "\t\n"); ++ fprintf (stdout, "\t\n"); + fprintf (stdout, "\t\n"); + fprintf (stdout, "\n"); + +@@ -264,7 +294,7 @@ print_usage (const char *self) + fprintf (stdout, "%s\n", + " -f, --family=FAMILY Network family: ([auto], ipv4, ipv6)"); + fprintf (stdout, "%s\n", +- " -o, --action=ACTION Fencing action: ([off], metadata)"); ++ " -o, --action=ACTION Fencing action: ([off], monitor, metadata)"); + fprintf (stdout, "%s\n", + " -t, --timeout=TIMEOUT Timeout in seconds (default: 60)"); + fprintf (stdout, "%s\n", +@@ -501,6 +531,9 @@ main (int argc, char **argv) + case FENCE_KDUMP_ACTION_METADATA: + error = do_action_metadata (argv[0]); + break; ++ case FENCE_KDUMP_ACTION_MONITOR: ++ error = do_action_monitor (); ++ break; + default: + break; + } +diff --git a/fence/agents/kdump/options.h b/fence/agents/kdump/options.h +index 10fa2a2..22731d7 100644 +--- a/fence/agents/kdump/options.h ++++ b/fence/agents/kdump/options.h +@@ -189,6 +189,8 @@ set_option_action (fence_kdump_opts_t *opts, const char *arg) + opts->action = FENCE_KDUMP_ACTION_OFF; + } else if (!strcasecmp (arg, "metadata")) { + opts->action = FENCE_KDUMP_ACTION_METADATA; ++ } else if (!strcasecmp (arg, "monitor")) { ++ opts->action = FENCE_KDUMP_ACTION_MONITOR; + } else { + fprintf (stderr, "[error]: unsupported action '%s'\n", arg); + exit (1); +-- +1.9.3 + diff --git a/SOURCES/bz1199970-fence_ilo_support_tls10.patch b/SOURCES/bz1199970-fence_ilo_support_tls10.patch new file mode 100644 index 0000000..811f436 --- /dev/null +++ b/SOURCES/bz1199970-fence_ilo_support_tls10.patch @@ -0,0 +1,119 @@ +From 9a6bb12b2c8aaf9d30d0d228bf0b4d93e06e1153 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 25 Mar 2015 18:22:08 +0100 +Subject: [PATCH 4/5] fence_ilo: Add support for TLS1.0 + +HP iLO2 firmware 2.27 has broken implementation of TLS and SSLv3 is disabled by default. +gnutls (3.4.x) has support to disable proper negotiation and use only TLS1.0 that works well. + +Option --tls1.0 (tls1.0 on stdin) was added to enable this feature and fence_ilo(2) works +correctly also with this firmware. + +Resolves: rhbz#1199970 +--- + fence/agents/ilo/fence_ilo.py | 2 +- + fence/agents/lib/fencing.py.py | 16 +++++++++++++++- + tests/data/metadata/fence_ilo.xml | 7 ++++++- + tests/data/metadata/fence_ilo2.xml | 7 ++++++- + 4 files changed, 28 insertions(+), 4 deletions(-) + +diff --git a/fence/agents/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py +index 965aabf..047040b 100644 +--- a/fence/agents/ilo/fence_ilo.py ++++ b/fence/agents/ilo/fence_ilo.py +@@ -65,7 +65,7 @@ def define_new_opts(): + "order" : 1} + + def main(): +- device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "ribcl"] ++ device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "tls1.0", "ribcl"] + + atexit.register(atexit_handler) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 7209d5e..f893082 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -203,7 +203,19 @@ all_opt = { + " " + "This should only be used for devices that do not support TLS1.0 and up.", + "required" : "0", +- "shortdesc" : "Disable TLS negotiation", ++ "shortdesc" : "Disable TLS negotiation, force SSL 3.0", ++ "order" : 1}, ++ "tls1.0" : { ++ "getopt" : "", ++ "longopt" : "tls1.0", ++ "help" : "--tls1.0 " ++ "Disable TLS negotiation and force TLS1.0\n" ++ " " ++ "This should only be used for devices that\n" ++ " " ++ "do not support TLS1.1 and up.", ++ "required" : "0", ++ "shortdesc" : "Disable TLS negotiaton, force TLS 1.0", + "order" : 1}, + "port" : { + "getopt" : "n:", +@@ -995,6 +1007,8 @@ def fence_login(options, re_login_string=r"(login\s*: )|(Login Name: )|(usernam + + if options.has_key("--notls"): + gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:+VERS-SSL3.0\"" ++ elif options.has_key("--tls1.0"): ++ gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:+VERS-TLS1.0:%LATEST_RECORD_VERSION\"" + + # --ssl is same as the --ssl-secure + if options.has_key("--ssl-insecure"): +diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +index 25d9d54..ae7fe9c 100644 +--- a/tests/data/metadata/fence_ilo.xml ++++ b/tests/data/metadata/fence_ilo.xml +@@ -12,7 +12,7 @@ + + + +- Disable TLS negotiation ++ Disable TLS negotiation, force SSL 3.0 + + + +@@ -49,6 +49,11 @@ + + Script to retrieve password + ++ ++ ++ ++ Disable TLS negotiaton, force TLS 1.0 ++ + + + +diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +index 47e8e28..19a31a1 100644 +--- a/tests/data/metadata/fence_ilo2.xml ++++ b/tests/data/metadata/fence_ilo2.xml +@@ -12,7 +12,7 @@ + + + +- Disable TLS negotiation ++ Disable TLS negotiation, force SSL 3.0 + + + +@@ -49,6 +49,11 @@ + + Script to retrieve password + ++ ++ ++ ++ Disable TLS negotiaton, force TLS 1.0 ++ + + + +-- +1.9.3 + diff --git a/SOURCES/bz1203877-fence_ipmilan-default_cipher.patch b/SOURCES/bz1203877-fence_ipmilan-default_cipher.patch new file mode 100644 index 0000000..8c15361 --- /dev/null +++ b/SOURCES/bz1203877-fence_ipmilan-default_cipher.patch @@ -0,0 +1,109 @@ +From 05a6bf8619560b559bfb0ea3688635935a96ca94 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 19 Mar 2015 21:28:22 +0100 +Subject: [PATCH 5/5] fence_ipmilan: Un-set default cipher + +Previously, the default cipher was left to ipmitool, in one of latest releases we have changed it +to cipher=0. This commit removes this default and uses --cipher for ipmitool only when explicitly +set by user. + +Resolves: rhbz#1203877 +--- + fence/agents/ipmilan/fence_ipmilan.py | 4 ++-- + tests/data/metadata/fence_idrac.xml | 2 +- + tests/data/metadata/fence_ilo3.xml | 2 +- + tests/data/metadata/fence_ilo4.xml | 2 +- + tests/data/metadata/fence_imm.xml | 2 +- + tests/data/metadata/fence_ipmilan.xml | 2 +- + 6 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py +index eaff7b7..8490837 100644 +--- a/fence/agents/ipmilan/fence_ipmilan.py ++++ b/fence/agents/ipmilan/fence_ipmilan.py +@@ -53,7 +53,8 @@ def create_command(options, action): + cmd += " -P ''" + + # --cipher / -C +- cmd += " -C " + options["--cipher"] ++ if "--cipher" in options: ++ cmd += " -C " + options["--cipher"] + + # --port / -n + if options.has_key("--ipport"): +@@ -96,7 +97,6 @@ def define_new_opts(): + "help" : "-C, --cipher=[cipher] Ciphersuite to use (same as ipmitool -C parameter)", + "required" : "0", + "shortdesc" : "Ciphersuite to use (same as ipmitool -C parameter)", +- "default" : "0", + "order": 1 + } + all_opt["privlvl"] = { +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index 26a2758..dcb3235 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -61,7 +61,7 @@ + + + +- ++ + Ciphersuite to use (same as ipmitool -C parameter) + + +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index c1e01ae..e6a48bc 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -61,7 +61,7 @@ + + + +- ++ + Ciphersuite to use (same as ipmitool -C parameter) + + +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index bbba9a0..e7b0d60 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -61,7 +61,7 @@ + + + +- ++ + Ciphersuite to use (same as ipmitool -C parameter) + + +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index addfcd4..8fbdddd 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -61,7 +61,7 @@ + + + +- ++ + Ciphersuite to use (same as ipmitool -C parameter) + + +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index d15e352..199490c 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -61,7 +61,7 @@ + + + +- ++ + Ciphersuite to use (same as ipmitool -C parameter) + + +-- +1.9.3 + diff --git a/SOURCES/bz1207982-fence2rng-quotes.patch b/SOURCES/bz1207982-fence2rng-quotes.patch new file mode 100644 index 0000000..6d4532a --- /dev/null +++ b/SOURCES/bz1207982-fence2rng-quotes.patch @@ -0,0 +1,61 @@ +From 4bedbd33645d22a4da2c623ccccacb2175d49b99 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 19:57:05 +0200 +Subject: [PATCH 10/10] fence2rng.xsl: Correctly handle quotes in description + +Resolves: rhbz#1207982 +--- + fence/agents/lib/fence2rng.xsl | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/lib/fence2rng.xsl b/fence/agents/lib/fence2rng.xsl +index 432bc89..f6d465e 100644 +--- a/fence/agents/lib/fence2rng.xsl ++++ b/fence/agents/lib/fence2rng.xsl +@@ -124,6 +124,12 @@ + + + ++ ++ ++ ++ ++ ++ + + + +@@ -136,7 +142,7 @@ + + ++ 'rha:description=', $Q, normalize-space($escapeddesc), $Q, $SP)"/> + + + +@@ -158,4 +164,21 @@ + + + ++ ++ ++ ++ ++ ++ ++ &quot; ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +-- +1.9.3 + diff --git a/SOURCES/bz1213571-fence_scsi-add_monitor.patch b/SOURCES/bz1213571-fence_scsi-add_monitor.patch new file mode 100644 index 0000000..2735e18 --- /dev/null +++ b/SOURCES/bz1213571-fence_scsi-add_monitor.patch @@ -0,0 +1,49 @@ +From d452969b172da23604d58e14a7b60d19f87967df Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 19:34:53 +0200 +Subject: [PATCH 02/10] fence_scsi: Add support for monitor action + +Resolves: rhbz#1196068 +--- + fence/agents/scsi/fence_scsi.py | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index 3a899d1..de301a5 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -83,6 +83,21 @@ def set_status(conn, options): + sys.exit(1) + + ++# check if host is ready to execute actions ++def do_action_monitor(options): ++ if bool(run_cmd(options, options["--sg_persist-path"] + " -V")["err"]): ++ logging.error("Unable to run " + options["--sg_persist-path"]) ++ return 1 ++ elif bool(run_cmd(options, options["--sg_turs-path"] + " -V")["err"]): ++ logging.error("Unable to run " + options["--sg_turs-path"]) ++ return 1 ++ elif ("--devices" not in options and ++ bool(run_cmd(options, options["--vgs-path"] + " --version")["err"])): ++ logging.error("Unable to run " + options["--vgs-path"]) ++ return 1 ++ return 0 ++ ++ + #run command, returns dict, ret["err"] = exit code; ret["out"] = output + def run_cmd(options, cmd): + ret = {} +@@ -423,6 +438,9 @@ longer be able to write to the device(s). A manual reboot is required." + options["store_path"] = STORE_PATH + + # Input control BEGIN ++ if options["--action"] == "monitor": ++ sys.exit(do_action_monitor(options)) ++ + if not (("--nodename" in options and options["--nodename"])\ + or ("--key" in options and options["--key"])): + fail_usage("Failed: nodename or key is required") +-- +1.9.3 + diff --git a/SOURCES/bz1214359-1-fence_compute.patch b/SOURCES/bz1214359-1-fence_compute.patch new file mode 100644 index 0000000..60817ea --- /dev/null +++ b/SOURCES/bz1214359-1-fence_compute.patch @@ -0,0 +1,426 @@ +From 563c93016b0581c2f6beea1f3f18e76e25491895 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Fri, 5 Jun 2015 18:03:00 +0200 +Subject: [PATCH 1/4] fence_compute: Fence agent for Nova compute machines + +Author: Andrew Beekhof +--- + configure.ac | 2 + + fence/agents/compute/Makefile.am | 17 +++ + fence/agents/compute/fence_compute.py | 218 ++++++++++++++++++++++++++++++++++ + make/fencebuild.mk | 1 + + tests/data/metadata/fence_compute.xml | 121 +++++++++++++++++++ + 5 files changed, 359 insertions(+) + create mode 100644 fence/agents/compute/Makefile.am + create mode 100644 fence/agents/compute/fence_compute.py + create mode 100644 tests/data/metadata/fence_compute.xml + +diff --git a/configure.ac b/configure.ac +index b603878..9d996d3 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -167,6 +167,7 @@ AC_PATH_PROG([COROSYNC_CMAPCTL_PATH], [corosync-cmapctl], [/usr/sbin/corosync-cm + AC_PATH_PROG([SG_PERSIST_PATH], [sg_persist], [/usr/bin/sg_persist]) + AC_PATH_PROG([SG_TURS_PATH], [sg_turs], [/usr/bin/sg_turs]) + AC_PATH_PROG([VGS_PATH], [vgs], [/usr/sbin/vgs]) ++AC_PATH_PROG([NOVA_PATH], [nova], [/usr/bin/nova]) + ## do subst + + AC_SUBST([DEFAULT_CONFIG_DIR]) +@@ -265,6 +266,7 @@ AC_CONFIG_FILES([Makefile + fence/agents/brocade/Makefile + fence/agents/cisco_mds/Makefile + fence/agents/cisco_ucs/Makefile ++ fence/agents/compute/Makefile + fence/agents/docker/Makefile + fence/agents/drac/Makefile + fence/agents/drac5/Makefile +diff --git a/fence/agents/compute/Makefile.am b/fence/agents/compute/Makefile.am +new file mode 100644 +index 0000000..ab21272 +--- /dev/null ++++ b/fence/agents/compute/Makefile.am +@@ -0,0 +1,17 @@ ++MAINTAINERCLEANFILES = Makefile.in ++ ++TARGET = fence_compute ++ ++SRC = $(TARGET).py ++ ++EXTRA_DIST = $(SRC) ++ ++sbin_SCRIPTS = $(TARGET) ++ ++man_MANS = $(TARGET).8 ++ ++FENCE_TEST_ARGS = -l test -p test -n 1 ++ ++include $(top_srcdir)/make/fencebuild.mk ++include $(top_srcdir)/make/fenceman.mk ++include $(top_srcdir)/make/agentpycheck.mk +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +new file mode 100644 +index 0000000..2b37de7 +--- /dev/null ++++ b/fence/agents/compute/fence_compute.py +@@ -0,0 +1,218 @@ ++#!/usr/bin/python -tt ++ ++import sys ++import time ++import atexit ++import logging ++ ++sys.path.append("@FENCEAGENTSLIBDIR@") ++from fencing import * ++from fencing import fail_usage, is_executable, run_command, run_delay ++from novaclient import client as nova_client ++ ++#BEGIN_VERSION_GENERATION ++RELEASE_VERSION="4.0.11" ++BUILD_DATE="(built Wed Nov 12 06:33:38 EST 2014)" ++REDHAT_COPYRIGHT="Copyright (C) Red Hat, Inc. 2004-2010 All rights reserved." ++#END_VERSION_GENERATION ++ ++override_status = "" ++nova = None ++ ++def get_power_status(_, options): ++ global override_status ++ ++ status = "unknown" ++ logging.debug("get action: " + options["--action"]) ++ ++ if len(override_status): ++ logging.debug("Pretending we're " + override_status) ++ return override_status ++ ++ if nova: ++ try: ++ services = nova.services.list(host=options["--plug"]) ++ except Exception, e: ++ fail_usage(str(e)) ++ ++ for service in services: ++ if service.binary == "nova-compute": ++ if service.state == "up": ++ status = "on" ++ elif service.state == "down": ++ status = "down" ++ else: ++ logging.debug("Unknown status detected from nova: " + service.state) ++ break ++ return status ++ ++# NOTE(sbauza); We mimic the host-evacuate module since it's only a contrib ++# module which is not stable ++def _server_evacuate(server, on_shared_storage): ++ success = True ++ error_message = "" ++ try: ++ nova.servers.evacuate(server=server['uuid'], on_shared_storage=on_shared_storage) ++ except Exception as e: ++ success = False ++ error_message = "Error while evacuating instance: %s" % e ++ ++ return { ++ "server_uuid": server['uuid'], ++ "evacuate_accepted": success, ++ "error_message": error_message, ++ } ++ ++def _host_evacuate(host, on_shared_storage): ++ hypervisors = nova.hypervisors.search(host, servers=True) ++ response = [] ++ for hyper in hypervisors: ++ if hasattr(hyper, 'servers'): ++ for server in hyper.servers: ++ response.append(_server_evacuate(server, on_shared_storage)) ++ ++def set_power_status(_, options): ++ global override_status ++ ++ override_status = "" ++ logging.debug("set action: " + options["--action"]) ++ ++ if not nova: ++ return ++ ++ if options["--action"] == "on": ++ if get_power_status(_, options) == "on": ++ nova.services.enable(options["--plug"], 'nova-compute') ++ else: ++ # Pretend we're 'on' so that the fencing library doesn't loop forever waiting for the node to boot ++ override_status = "on" ++ return ++ ++ # need to wait for nova to update its internal status or we ++ # cannot call host-evacuate ++ while get_power_status(_, options) != "off": ++ # Loop forever if need be. ++ # ++ # Some callers (such as Pacemaker) will have a timer ++ # running and kill us if necessary ++ logging.debug("Waiting for nova to update it's internal state") ++ time.sleep(1) ++ ++ if "--no-shared-storage" not in options: ++ # If the admin sets this when they DO have shared ++ # storage in use, then they get what they asked for ++ on_shared_storage = True ++ else: ++ on_shared_storage = False ++ ++ _host_evacuate(options["--plug"], on_shared_storage) ++ return ++ ++def get_plugs_list(_, options): ++ result = {} ++ ++ if nova: ++ hypervisors = nova.hypervisors.list() ++ for hypervisor in hypervisors: ++ longhost = hypervisor.hypervisor_hostname ++ if options["--action"] == "list" and options["--domain"] != "": ++ shorthost = longhost.replace("." + options["--domain"], ++ "") ++ result[shorthost] = ("", None) ++ else: ++ result[longhost] = ("", None) ++ return result ++ ++ ++def define_new_opts(): ++ all_opt["tenant-name"] = { ++ "getopt" : "t:", ++ "longopt" : "tenant-name", ++ "help" : "-t, --tenant-name=[tenant] Keystone Admin Tenant", ++ "required" : "0", ++ "shortdesc" : "Keystone Admin Tenant", ++ "default" : "", ++ "order": 1, ++ } ++ all_opt["auth-url"] = { ++ "getopt" : "k:", ++ "longopt" : "auth-url", ++ "help" : "-k, --auth-url=[tenant] Keystone Admin Auth URL", ++ "required" : "0", ++ "shortdesc" : "Keystone Admin Auth URL", ++ "default" : "", ++ "order": 1, ++ } ++ all_opt["novatool-path"] = { ++ "getopt" : "i:", ++ "longopt" : "novatool-path", ++ "help" : "-i, --novatool-path=[path] Path to nova binary", ++ "required" : "0", ++ "shortdesc" : "Path to nova binary", ++ "default" : "@NOVA_PATH@", ++ "order": 6, ++ } ++ all_opt["domain"] = { ++ "getopt" : "d:", ++ "longopt" : "domain", ++ "help" : "-d, --domain=[string] DNS domain in which hosts live, useful when the cluster uses short names and nova uses FQDN", ++ "required" : "0", ++ "shortdesc" : "DNS domain in which hosts live", ++ "default" : "", ++ "order": 5, ++ } ++ all_opt["no-shared-storage"] = { ++ "getopt" : "", ++ "longopt" : "no-shared-storage", ++ "help" : "--no-shared-storage Disable functionality for shared storage", ++ "required" : "0", ++ "shortdesc" : "Disable functionality for dealing with shared storage", ++ "default" : "False", ++ "order": 5, ++ } ++ ++def main(): ++ global override_status ++ global nova ++ atexit.register(atexit_handler) ++ ++ device_opt = ["login", "passwd", "tenant-name", "auth-url", ++ "novatool-path", "no_login", "no_password", "port", "domain", "no-shared-storage"] ++ define_new_opts() ++ all_opt["shell_timeout"]["default"] = "180" ++ ++ options = check_input(device_opt, process_input(device_opt)) ++ ++ docs = {} ++ docs["shortdesc"] = "Fence agent for nova compute nodes" ++ docs["longdesc"] = "fence_nova_host is a Nova fencing notification agent" ++ docs["vendorurl"] = "" ++ ++ show_docs(options, docs) ++ ++ run_delay(options) ++ ++ # The first argument is the Nova client version ++ nova = nova_client.Client('2', ++ options["--username"], ++ options["--password"], ++ options["--tenant-name"], ++ options["--auth-url"]) ++ ++ if options["--action"] in ["off", "reboot"]: ++ # Pretend we're 'on' so that the fencing library will always call set_power_status(off) ++ override_status = "on" ++ ++ if options["--action"] == "on": ++ # Pretend we're 'off' so that the fencing library will always call set_power_status(on) ++ override_status = "off" ++ ++ # Potentially we should make this a pacemaker feature ++ if options["--action"] != "list" and options["--domain"] != "" and options.has_key("--plug"): ++ options["--plug"] = options["--plug"]+"."+options["--domain"] ++ ++ result = fence_action(None, options, set_power_status, get_power_status, get_plugs_list, None) ++ sys.exit(result) ++ ++if __name__ == "__main__": ++ main() +diff --git a/make/fencebuild.mk b/make/fencebuild.mk +index 1c4be6b..b59c069 100644 +--- a/make/fencebuild.mk ++++ b/make/fencebuild.mk +@@ -16,6 +16,7 @@ $(TARGET): $(SRC) + -e 's#@''SG_PERSIST_PATH@#${SG_PERSIST_PATH}#g' \ + -e 's#@''SG_TURS_PATH@#${SG_TURS_PATH}#g' \ + -e 's#@''VGS_PATH@#${VGS_PATH}#g' \ ++ -e 's#@''NOVA_PATH@#${NOVA_PATH}#g' \ + > $@ + + if [ 0 -eq `echo "$(SRC)" | grep fence_ &> /dev/null; echo $$?` ]; then \ +diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +new file mode 100644 +index 0000000..ff7c06c +--- /dev/null ++++ b/tests/data/metadata/fence_compute.xml +@@ -0,0 +1,121 @@ ++ ++ ++fence_nova_host is a Nova fencing notification agent ++ ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Keystone Admin Auth URL ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Keystone Admin Tenant ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ DNS domain in which hosts live ++ ++ ++ ++ ++ Disable functionality for dealing with shared storage ++ ++ ++ ++ ++ Path to nova binary ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Separator for CSV created by operation list ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.9.3 + diff --git a/SOURCES/bz1214359-2-fence_compute.patch b/SOURCES/bz1214359-2-fence_compute.patch new file mode 100644 index 0000000..d3246e0 --- /dev/null +++ b/SOURCES/bz1214359-2-fence_compute.patch @@ -0,0 +1,161 @@ +From 21c2154bedceb6ebef1cae369768280d4b0f8652 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Fri, 5 Jun 2015 18:07:55 +0200 +Subject: [PATCH 2/4] fence_compute: Improvement of fence agent + +--- + fence/agents/compute/fence_compute.py | 73 ++++++++++++++++++++++------------- + fence/agents/lib/fencing.py.py | 6 ++- + 2 files changed, 50 insertions(+), 29 deletions(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index 2b37de7..66cf08f 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -4,11 +4,11 @@ import sys + import time + import atexit + import logging ++import requests.exceptions + + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * + from fencing import fail_usage, is_executable, run_command, run_delay +-from novaclient import client as nova_client + + #BEGIN_VERSION_GENERATION + RELEASE_VERSION="4.0.11" +@@ -32,18 +32,18 @@ def get_power_status(_, options): + if nova: + try: + services = nova.services.list(host=options["--plug"]) +- except Exception, e: +- fail_usage(str(e)) +- +- for service in services: +- if service.binary == "nova-compute": +- if service.state == "up": +- status = "on" +- elif service.state == "down": +- status = "down" +- else: +- logging.debug("Unknown status detected from nova: " + service.state) +- break ++ ++ for service in services: ++ if service.binary == "nova-compute": ++ if service.state == "up": ++ status = "on" ++ elif service.state == "down": ++ status = "off" ++ else: ++ logging.debug("Unknown status detected from nova: " + service.state) ++ break ++ except ConnectionError as (err): ++ logging.warning("Nova connection failed: " + str(err)) + return status + + # NOTE(sbauza); We mimic the host-evacuate module since it's only a contrib +@@ -143,15 +143,6 @@ def define_new_opts(): + "default" : "", + "order": 1, + } +- all_opt["novatool-path"] = { +- "getopt" : "i:", +- "longopt" : "novatool-path", +- "help" : "-i, --novatool-path=[path] Path to nova binary", +- "required" : "0", +- "shortdesc" : "Path to nova binary", +- "default" : "@NOVA_PATH@", +- "order": 6, +- } + all_opt["domain"] = { + "getopt" : "d:", + "longopt" : "domain", +@@ -177,7 +168,7 @@ def main(): + atexit.register(atexit_handler) + + device_opt = ["login", "passwd", "tenant-name", "auth-url", +- "novatool-path", "no_login", "no_password", "port", "domain", "no-shared-storage"] ++ "no_login", "no_password", "port", "domain", "no-shared-storage"] + define_new_opts() + all_opt["shell_timeout"]["default"] = "180" + +@@ -192,6 +183,15 @@ def main(): + + run_delay(options) + ++ try: ++ from novaclient import client as nova_client ++ except ImportError: ++ fail_usage("nova not found or not accessible") ++ ++ # Potentially we should make this a pacemaker feature ++ if options["--action"] != "list" and options["--domain"] != "" and options.has_key("--plug"): ++ options["--plug"] = options["--plug"] + "." + options["--domain"] ++ + # The first argument is the Nova client version + nova = nova_client.Client('2', + options["--username"], +@@ -199,6 +199,29 @@ def main(): + options["--tenant-name"], + options["--auth-url"]) + ++ if options["--action"] in ["on", "off", "reboot" ]: ++ try: ++ nova.services.list(host=options["--plug"]) ++ except ConnectionError as (err): ++ # Yes, exit(0) ++ # ++ # Its possible that the control plane on which this ++ # agent depends is not functional ++ # ++ # In this situation, fencing is waiting for resource ++ # recovery and resource recovery is waiting for ++ # fencing. ++ # ++ # To break the cycle, we all the fencing agent to ++ # return 'done' immediately so that we can recover the ++ # control plane. We then rely on the NovaCompute RA ++ # to call this agent directly once the control plane ++ # is up. ++ # ++ # Yes its horrible, but still better than nova itself. ++ logging.warning("Nova connection failed: %s " % str(err)) ++ sys.exit(0) ++ + if options["--action"] in ["off", "reboot"]: + # Pretend we're 'on' so that the fencing library will always call set_power_status(off) + override_status = "on" +@@ -207,10 +230,6 @@ def main(): + # Pretend we're 'off' so that the fencing library will always call set_power_status(on) + override_status = "off" + +- # Potentially we should make this a pacemaker feature +- if options["--action"] != "list" and options["--domain"] != "" and options.has_key("--plug"): +- options["--plug"] = options["--plug"]+"."+options["--domain"] +- + result = fence_action(None, options, set_power_status, get_power_status, get_plugs_list, None) + sys.exit(result) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index f893082..29b3a94 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -1109,9 +1109,11 @@ def fence_login(options, re_login_string=r"(login\s*: )|(Login Name: )|(usernam + conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"])) + except KeyError: + fail(EC_PASSWORD_MISSING) +- except pexpect.EOF: ++ except pexpect.EOF, exception: ++ logging.debug("%s", str(exception)) + fail(EC_LOGIN_DENIED) +- except pexpect.TIMEOUT: ++ except pexpect.TIMEOUT, exception: ++ logging.debug("%s", str(exception)) + fail(EC_LOGIN_DENIED) + return conn + +-- +1.9.3 + diff --git a/SOURCES/bz1214359-3-fence_compute.patch b/SOURCES/bz1214359-3-fence_compute.patch new file mode 100644 index 0000000..a22ce65 --- /dev/null +++ b/SOURCES/bz1214359-3-fence_compute.patch @@ -0,0 +1,33 @@ +From da2f40c6f7ae8263b4dd27f076a8ffe9d03b1534 Mon Sep 17 00:00:00 2001 +From: "Fabio M. Di Nitto" +Date: Mon, 8 Jun 2015 13:27:47 +0200 +Subject: [PATCH 3/4] fence_compute: fix on-shared-storage option parsing + +Signed-off-by: Fabio M. Di Nitto +--- + fence/agents/compute/fence_compute.py | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index 66cf08f..c2c90fc 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -98,12 +98,10 @@ def set_power_status(_, options): + logging.debug("Waiting for nova to update it's internal state") + time.sleep(1) + +- if "--no-shared-storage" not in options: +- # If the admin sets this when they DO have shared +- # storage in use, then they get what they asked for +- on_shared_storage = True +- else: ++ if options["--no-shared-storage"] != "False": + on_shared_storage = False ++ else: ++ on_shared_storage = True + + _host_evacuate(options["--plug"], on_shared_storage) + return +-- +1.9.3 + diff --git a/SOURCES/bz1214359-4-fence_compute.patch b/SOURCES/bz1214359-4-fence_compute.patch new file mode 100644 index 0000000..841cef0 --- /dev/null +++ b/SOURCES/bz1214359-4-fence_compute.patch @@ -0,0 +1,52 @@ +From b1e7b610b51c0be23d7adc0e2ab369850d924f87 Mon Sep 17 00:00:00 2001 +From: "Fabio M. Di Nitto" +Date: Mon, 8 Jun 2015 14:43:00 +0200 +Subject: [PATCH 4/4] compute: add support for endpoint-type + +Signed-off-by: Fabio M. Di Nitto +--- + fence/agents/compute/fence_compute.py | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index c2c90fc..000aef7 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -123,6 +123,15 @@ def get_plugs_list(_, options): + + + def define_new_opts(): ++ all_opt["endpoint-type"] = { ++ "getopt" : "e:", ++ "longopt" : "endpoint-type", ++ "help" : "-e, --endpoint-type=[endpoint] Nova Endpoint type (publicURL, internalURL, adminURL)", ++ "required" : "0", ++ "shortdesc" : "Nova Endpoint type", ++ "default" : "internalURL", ++ "order": 1, ++ } + all_opt["tenant-name"] = { + "getopt" : "t:", + "longopt" : "tenant-name", +@@ -166,7 +175,7 @@ def main(): + atexit.register(atexit_handler) + + device_opt = ["login", "passwd", "tenant-name", "auth-url", +- "no_login", "no_password", "port", "domain", "no-shared-storage"] ++ "no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type"] + define_new_opts() + all_opt["shell_timeout"]["default"] = "180" + +@@ -195,7 +204,8 @@ def main(): + options["--username"], + options["--password"], + options["--tenant-name"], +- options["--auth-url"]) ++ options["--auth-url"], ++ endpoint_type=options["--endpoint-type"]) + + if options["--action"] in ["on", "off", "reboot" ]: + try: +-- +1.9.3 + diff --git a/SOURCES/bz1214359-5-fence_compute.patch b/SOURCES/bz1214359-5-fence_compute.patch new file mode 100644 index 0000000..b12fdf4 --- /dev/null +++ b/SOURCES/bz1214359-5-fence_compute.patch @@ -0,0 +1,77 @@ +From a1f988fa0f3f89f8dac17717295c4219a02757cf Mon Sep 17 00:00:00 2001 +From: "Fabio M. Di Nitto" +Date: Sat, 20 Jun 2015 07:45:08 +0200 +Subject: [PATCH 1/3] fence_compute: add support for recording fencing + operations in attrd + +This is required to support multiple compute nodes failure at once +with controller node failures happening at the same time. + +Signed-off-by: Fabio M. Di Nitto +--- + fence/agents/compute/fence_compute.py | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index 000aef7..d8a1e95 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -71,6 +71,10 @@ def _host_evacuate(host, on_shared_storage): + for server in hyper.servers: + response.append(_server_evacuate(server, on_shared_storage)) + ++def set_attrd_status(host, status, options): ++ logging.debug("Setting fencing status for %s to %s" % (host, status)) ++ run_command(options, "attrd_updater -p -n evacute -Q -N %s -v %s" % (host, status)) ++ + def set_power_status(_, options): + global override_status + +@@ -159,6 +163,15 @@ def define_new_opts(): + "default" : "", + "order": 5, + } ++ all_opt["record-only"] = { ++ "getopt" : "", ++ "longopt" : "record-only", ++ "help" : "--record-only Record the target as needing evacuation but as yet do not intiate it", ++ "required" : "0", ++ "shortdesc" : "Only record the target as needing evacuation", ++ "default" : "False", ++ "order": 5, ++ } + all_opt["no-shared-storage"] = { + "getopt" : "", + "longopt" : "no-shared-storage", +@@ -175,7 +188,8 @@ def main(): + atexit.register(atexit_handler) + + device_opt = ["login", "passwd", "tenant-name", "auth-url", +- "no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type"] ++ "no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type", ++ "record-only"] + define_new_opts() + all_opt["shell_timeout"]["default"] = "180" + +@@ -199,6 +213,18 @@ def main(): + if options["--action"] != "list" and options["--domain"] != "" and options.has_key("--plug"): + options["--plug"] = options["--plug"] + "." + options["--domain"] + ++ if options["--record-only"] != "False": ++ if options["--action"] == "on": ++ set_attrd_status(options["--plug"], "no", options) ++ sys.exit(0) ++ ++ elif options["--action"] in ["off", "reboot"]: ++ set_attrd_status(options["--plug"], "yes", options) ++ sys.exit(0) ++ ++ elif options["--action"] in ["status", "monitor"]: ++ sys.exit(0) ++ + # The first argument is the Nova client version + nova = nova_client.Client('2', + options["--username"], +-- +1.9.3 + diff --git a/SOURCES/bz1214359-6-fence_compute.patch b/SOURCES/bz1214359-6-fence_compute.patch new file mode 100644 index 0000000..ed1c851 --- /dev/null +++ b/SOURCES/bz1214359-6-fence_compute.patch @@ -0,0 +1,48 @@ +From a703fba575b965c843ec527621fdd5009425be35 Mon Sep 17 00:00:00 2001 +From: "Fabio M. Di Nitto" +Date: Sat, 20 Jun 2015 11:43:09 +0200 +Subject: [PATCH 2/3] fence_compute: resync with master and drop unnecessary + workaround + +Signed-off-by: Fabio M. Di Nitto +--- + fence/agents/compute/fence_compute.py | 23 ----------------------- + 1 file changed, 23 deletions(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index d8a1e95..82d9c46 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -233,29 +233,6 @@ def main(): + options["--auth-url"], + endpoint_type=options["--endpoint-type"]) + +- if options["--action"] in ["on", "off", "reboot" ]: +- try: +- nova.services.list(host=options["--plug"]) +- except ConnectionError as (err): +- # Yes, exit(0) +- # +- # Its possible that the control plane on which this +- # agent depends is not functional +- # +- # In this situation, fencing is waiting for resource +- # recovery and resource recovery is waiting for +- # fencing. +- # +- # To break the cycle, we all the fencing agent to +- # return 'done' immediately so that we can recover the +- # control plane. We then rely on the NovaCompute RA +- # to call this agent directly once the control plane +- # is up. +- # +- # Yes its horrible, but still better than nova itself. +- logging.warning("Nova connection failed: %s " % str(err)) +- sys.exit(0) +- + if options["--action"] in ["off", "reboot"]: + # Pretend we're 'on' so that the fencing library will always call set_power_status(off) + override_status = "on" +-- +1.9.3 + diff --git a/SOURCES/bz1214359-7-fence_compute_xml_test.patch b/SOURCES/bz1214359-7-fence_compute_xml_test.patch new file mode 100644 index 0000000..e3e5c8c --- /dev/null +++ b/SOURCES/bz1214359-7-fence_compute_xml_test.patch @@ -0,0 +1,28 @@ +From 360671cf5a78c4c02aca3ba598301fc77aa02c24 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 29 Jun 2015 15:19:28 +0200 +Subject: [PATCH 5/6] fence_compute: Update XML metadata for --record-only + +--- + tests/data/metadata/fence_compute.xml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +index f9b97fc..2c488c5 100644 +--- a/tests/data/metadata/fence_compute.xml ++++ b/tests/data/metadata/fence_compute.xml +@@ -53,6 +53,11 @@ + + Disable functionality for dealing with shared storage + ++ ++ ++ ++ Only record the target as needing evacuation ++ + + + +-- +1.9.3 + diff --git a/SOURCES/bz1214522-2-port_as_ip.patch b/SOURCES/bz1214522-2-port_as_ip.patch new file mode 100644 index 0000000..cc79b64 --- /dev/null +++ b/SOURCES/bz1214522-2-port_as_ip.patch @@ -0,0 +1,27 @@ +From f62091cb5d9bfd150a70fed51a98117b9e2172ab Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 5 Aug 2015 10:01:12 +0200 +Subject: [PATCH 2/4] fencing: Fix required options if --port-as-ip is used + +--- + fence/agents/lib/fencing.py.py | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 89c3379..f14d7e0 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -700,6 +700,10 @@ def check_input(device_opt, opt): + else: + all_opt["login"]["required"] = "0" + ++ if device_opt.count("port_as_ip"): ++ all_opt["ipaddr"]["required"] = "0" ++ all_opt["port"]["required"] = "0" ++ + if device_opt.count("fabric_fencing"): + all_opt["action"]["default"] = "off" + all_opt["action"]["help"] = "-o, --action=[action] Action: status, off (default) or on" +-- +1.9.3 + diff --git a/SOURCES/bz1214522-3-port_as_ip.patch b/SOURCES/bz1214522-3-port_as_ip.patch new file mode 100644 index 0000000..bff1091 --- /dev/null +++ b/SOURCES/bz1214522-3-port_as_ip.patch @@ -0,0 +1,504 @@ +From 3c4651ba655a7346f4e67335229b76ed24d1c917 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 5 Aug 2015 15:29:12 +0200 +Subject: [PATCH 3/4] fencing: Fix XML metadata and their creation for + 'port_as_ip' + +--- + fence/agents/dummy/fence_dummy.py | 1 + + fence/agents/lib/fencing.py.py | 5 +++- + tests/data/metadata/fence_alom.xml | 4 +-- + tests/data/metadata/fence_amt.xml | 4 +-- + tests/data/metadata/fence_drac.xml | 4 +-- + tests/data/metadata/fence_dummy.xml | 10 ------- + tests/data/metadata/fence_idrac.xml | 4 +-- + tests/data/metadata/fence_ilo.xml | 4 +-- + tests/data/metadata/fence_ilo2.xml | 4 +-- + tests/data/metadata/fence_ilo3.xml | 4 +-- + tests/data/metadata/fence_ilo3_ssh.xml | 4 +-- + tests/data/metadata/fence_ilo4.xml | 4 +-- + tests/data/metadata/fence_ilo4_ssh.xml | 4 +-- + tests/data/metadata/fence_ilo_mp.xml | 4 +-- + tests/data/metadata/fence_ilo_ssh.xml | 4 +-- + tests/data/metadata/fence_imm.xml | 4 +-- + tests/data/metadata/fence_ipmilan.xml | 4 +-- + tests/data/metadata/fence_mpath.xml | 54 ++++++++++++++-------------------- + tests/data/metadata/fence_rsa.xml | 4 +-- + tests/data/metadata/fence_rsb.xml | 4 +-- + 20 files changed, 59 insertions(+), 75 deletions(-) + +diff --git a/fence/agents/dummy/fence_dummy.py b/fence/agents/dummy/fence_dummy.py +index 9c4c5f1..7d6bd06 100644 +--- a/fence/agents/dummy/fence_dummy.py ++++ b/fence/agents/dummy/fence_dummy.py +@@ -115,6 +115,7 @@ def main(): + if (pinput.has_key("--type") and pinput["--type"] == "file") or (pinput.has_key("--type") == False): + # hack to have fence agents that require ports 'fail' and one that do not 'file' + device_opt.remove("port") ++ device_opt.remove("separator") + + options = check_input(device_opt, process_input(device_opt)) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index f14d7e0..8b14cf2 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -463,7 +463,10 @@ def add_dependency_options(options): + if DEPENDENCY_OPT.has_key(opt): + added_opt.extend([y for y in DEPENDENCY_OPT[opt] if options.count(y) == 0]) + +- if not "port" in (options + added_opt) and not "nodename" in (options + added_opt): ++ if not "port" in (options + added_opt) and \ ++ not "nodename" in (options + added_opt) and \ ++ "ipaddr" in (options + added_opt): ++ + added_opt.append("port_as_ip") + all_opt["port"]["help"] = "-n, --plug=[ip] IP address or hostname of fencing device " \ + "(together with --port-as-ip)" +diff --git a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml +index dfbe431..f7e2f36 100644 +--- a/tests/data/metadata/fence_alom.xml ++++ b/tests/data/metadata/fence_alom.xml +@@ -8,12 +8,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +diff --git a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml +index 17e38fc..61b39f5 100644 +--- a/tests/data/metadata/fence_amt.xml ++++ b/tests/data/metadata/fence_amt.xml +@@ -8,7 +8,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -18,7 +18,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +diff --git a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml +index 37697f7..1e94dbc 100644 +--- a/tests/data/metadata/fence_drac.xml ++++ b/tests/data/metadata/fence_drac.xml +@@ -8,7 +8,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -23,7 +23,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +diff --git a/tests/data/metadata/fence_dummy.xml b/tests/data/metadata/fence_dummy.xml +index eb31244..07ad2cc 100644 +--- a/tests/data/metadata/fence_dummy.xml ++++ b/tests/data/metadata/fence_dummy.xml +@@ -3,11 +3,6 @@ + fence_dummy + http://www.example.com + +- +- +- +- IP address or hostname of fencing device (together with --port-as-ip) +- + + + +@@ -63,11 +58,6 @@ + + Test X seconds for status change after ON/OFF + +- +- +- +- Make "port/plug" to be an alias to IP address +- + + + +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index b742161..0aced2a 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,7 +22,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +index 891b7f1..2eead1e 100644 +--- a/tests/data/metadata/fence_ilo.xml ++++ b/tests/data/metadata/fence_ilo.xml +@@ -34,12 +34,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +index 7ff697f..3be62f1 100644 +--- a/tests/data/metadata/fence_ilo2.xml ++++ b/tests/data/metadata/fence_ilo2.xml +@@ -34,12 +34,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index 05fd01c..67e869b 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,7 +22,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +diff --git a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +index ebdae65..8268daf 100644 +--- a/tests/data/metadata/fence_ilo3_ssh.xml ++++ b/tests/data/metadata/fence_ilo3_ssh.xml +@@ -10,12 +10,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index 4f29073..b7dd31a 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,7 +22,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +diff --git a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +index 197d627..4ca2397 100644 +--- a/tests/data/metadata/fence_ilo4_ssh.xml ++++ b/tests/data/metadata/fence_ilo4_ssh.xml +@@ -10,12 +10,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +diff --git a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml +index d2396e9..14fc3c8 100644 +--- a/tests/data/metadata/fence_ilo_mp.xml ++++ b/tests/data/metadata/fence_ilo_mp.xml +@@ -8,12 +8,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +diff --git a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +index 1d79308..4448d2d 100644 +--- a/tests/data/metadata/fence_ilo_ssh.xml ++++ b/tests/data/metadata/fence_ilo_ssh.xml +@@ -10,12 +10,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index 0302f84..0e7588d 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,7 +22,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index 4ed67eb..443365c 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,7 +22,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +index d3de9d5..c578f7a 100644 +--- a/tests/data/metadata/fence_mpath.xml ++++ b/tests/data/metadata/fence_mpath.xml +@@ -4,25 +4,20 @@ + The fence_mpath agent works by having an unique key for each pair of node and device that has to be set also in /etc/multipath.conf. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_mpath agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. + https://www.sourceware.org/dm/ + +- +- ++ ++ + +- IP address or hostname of fencing device (together with --port-as-ip) +- +- +- +- +- Fencing Action ++ List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations. + + + + + Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s). + +- +- +- +- List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations. ++ ++ ++ ++ Fencing Action + + + +@@ -44,31 +39,11 @@ The fence_mpath agent works by having an unique key for each pair of node and de + + Display help and exit + +- +- +- +- Wait X seconds after issuing ON/OFF +- +- +- +- +- Wait X seconds for cmd prompt after login +- +- +- +- +- Make "port/plug" to be an alias to IP address +- + + + + Wait X seconds before fencing is started + +- +- +- +- Path to mpathpersist binary +- + + + +@@ -84,6 +59,21 @@ The fence_mpath agent works by having an unique key for each pair of node and de + + Test X seconds for status change after ON/OFF + ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Path to mpathpersist binary ++ + + + +diff --git a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml +index 3f3a336..2981f04 100644 +--- a/tests/data/metadata/fence_rsa.xml ++++ b/tests/data/metadata/fence_rsa.xml +@@ -8,12 +8,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +diff --git a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml +index 36b9cdb..c27ebe4 100644 +--- a/tests/data/metadata/fence_rsb.xml ++++ b/tests/data/metadata/fence_rsb.xml +@@ -8,12 +8,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +-- +1.9.3 + diff --git a/SOURCES/bz1214522-4-port_as_ip.patch b/SOURCES/bz1214522-4-port_as_ip.patch new file mode 100644 index 0000000..b600398 --- /dev/null +++ b/SOURCES/bz1214522-4-port_as_ip.patch @@ -0,0 +1,26 @@ +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 3a6e2ab..bb8e3a4 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -657,6 +657,10 @@ def process_input(avail_opt): + opt = z + ## + ##### ++ ++ # This test should NOT be used for stdin input where it should be allowed (and ignored) ++ if "port_as_ip" in device_opt and not "--port-as-ip" in options and "--plug" in options: ++ fail_usage("Parser error: option -n/--plug is not recognized") + else: + opt = {} + name = "" +@@ -788,10 +792,6 @@ def check_input(device_opt, opt): + options["--action"] = "off" + + ## automatic detection and set of valid UUID from --plug +- +- if "port_as_ip" in device_opt and not "--port-as-ip" in options and "--plug" in options: +- fail_usage("Parser error: option -n/--plug is not recognized") +- + if not options.has_key("--username") and \ + device_opt.count("login") and (device_opt.count("no_login") == 0): + fail_usage("Failed: You have to set login name") diff --git a/SOURCES/bz1214522-5-port_as_ip.patch b/SOURCES/bz1214522-5-port_as_ip.patch new file mode 100644 index 0000000..02e2ba2 --- /dev/null +++ b/SOURCES/bz1214522-5-port_as_ip.patch @@ -0,0 +1,27 @@ +From 4e4213f1aabfbb0a09f66cabd16079dc6e71e042 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Tue, 11 Aug 2015 09:29:08 +0200 +Subject: [PATCH] fencing: Move checking of --plug and --port-as-ip to run them + only on getopt + +Fix wrong backporting of patch 4442f2548543f418fc8e094c701fa27edf8e6bfa +--- + fence/agents/lib/fencing.py.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index bb8e3a4..9a16aee 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -659,7 +659,7 @@ def process_input(avail_opt): + ##### + + # This test should NOT be used for stdin input where it should be allowed (and ignored) +- if "port_as_ip" in device_opt and not "--port-as-ip" in options and "--plug" in options: ++ if "port_as_ip" in avail_opt and not "--port-as-ip" in opt and "--plug" in opt: + fail_usage("Parser error: option -n/--plug is not recognized") + else: + opt = {} +-- +1.9.3 + diff --git a/SOURCES/bz1214522-port_as_ip.patch b/SOURCES/bz1214522-port_as_ip.patch new file mode 100644 index 0000000..e2e63d8 --- /dev/null +++ b/SOURCES/bz1214522-port_as_ip.patch @@ -0,0 +1,809 @@ +From 05bfc15535f3d28af5f09a9a8fedd16ab45c24d3 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 29 Jun 2015 19:55:00 +0200 +Subject: [PATCH 6/6] fencing: Introduce option --port-as-ip (port_as_ip on + stdin) + +Pacemaker's mapping between fence devices and appropriate ports works fine. But if +fence device is used only for single device (IPMI, iLO, DRAC, ...) then configuration +is more complex. With this new option, user can use --plug/-n/port to specify IP address +what simplify configuration. + +Resolves: rhbz#1214522 +--- + fence/agents/lib/fencing.py.py | 30 +++++++++++++++- + tests/data/metadata/fence_alom.xml | 10 ++++++ + tests/data/metadata/fence_amt.xml | 10 ++++++ + tests/data/metadata/fence_drac.xml | 64 ++++++++++++++++++++-------------- + tests/data/metadata/fence_dummy.xml | 15 +++++--- + tests/data/metadata/fence_hpblade.xml | 4 +-- + tests/data/metadata/fence_idrac.xml | 10 ++++++ + tests/data/metadata/fence_ilo.xml | 10 ++++++ + tests/data/metadata/fence_ilo2.xml | 10 ++++++ + tests/data/metadata/fence_ilo3.xml | 10 ++++++ + tests/data/metadata/fence_ilo3_ssh.xml | 10 ++++++ + tests/data/metadata/fence_ilo4.xml | 10 ++++++ + tests/data/metadata/fence_ilo4_ssh.xml | 10 ++++++ + tests/data/metadata/fence_ilo_mp.xml | 10 ++++++ + tests/data/metadata/fence_ilo_ssh.xml | 10 ++++++ + tests/data/metadata/fence_imm.xml | 10 ++++++ + tests/data/metadata/fence_ipmilan.xml | 10 ++++++ + tests/data/metadata/fence_mpath.xml | 54 ++++++++++++++++------------ + tests/data/metadata/fence_rsa.xml | 10 ++++++ + tests/data/metadata/fence_rsb.xml | 10 ++++++ + 20 files changed, 260 insertions(+), 57 deletions(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index db620e8..2ba98b8 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -399,6 +399,13 @@ all_opt = { + "default" : "onoff", + "choices" : ["onoff", "cycle"], + "order" : 1}, ++ "port_as_ip": { ++ "getopt" : "", ++ "longopt" : "port-as-ip", ++ "help" : "--port-as-ip Make \"port/plug\" to be an alias to IP address", ++ "required" : "0", ++ "shortdesc" : "Make \"port/plug\" to be an alias to IP address", ++ "order" : 200}, + "on_target": { + "getopt" : "", + "help" : "", +@@ -451,6 +458,13 @@ def add_dependency_options(options): + for opt in options + ["default"]: + if DEPENDENCY_OPT.has_key(opt): + added_opt.extend([y for y in DEPENDENCY_OPT[opt] if options.count(y) == 0]) ++ ++ if not "port" in (options + added_opt) and not "nodename" in (options + added_opt): ++ added_opt.append("port_as_ip") ++ all_opt["port"]["help"] = "-n, --plug=[ip] IP address or hostname of fencing device " \ ++ "(together with --port-as-ip)" ++ all_opt["port"]["shortdesc"] = "IP address or hostname of fencing device (together with --port-as-ip)" ++ + return added_opt + + def fail_usage(message=""): +@@ -580,6 +594,9 @@ def process_input(avail_opt): + os.putenv("LANG", "C") + os.putenv("LC_ALL", "C") + ++ if "port_as_ip" in avail_opt: ++ avail_opt.append("port") ++ + ## + ## Prepare list of options for getopt + ##### +@@ -653,6 +670,10 @@ def process_input(avail_opt): + opt["--"+all_opt[name]["longopt"].rstrip(":")] = value + elif value.lower() in ["1", "yes", "on", "true"]: + opt["--"+all_opt[name]["longopt"]] = "1" ++ ++ if "--port-as-ip" in opt and "--plug" in opt: ++ opt["--ip"] = opt["--plug"] ++ + return opt + + ## +@@ -755,6 +776,10 @@ def check_input(device_opt, opt): + options["--action"] = "off" + + ## automatic detection and set of valid UUID from --plug ++ ++ if "port_as_ip" in device_opt and not "--port-as-ip" in options and "--plug" in options: ++ fail_usage("Parser error: option -n/--plug is not recognized") ++ + if not options.has_key("--username") and \ + device_opt.count("login") and (device_opt.count("no_login") == 0): + fail_usage("Failed: You have to set login name") +@@ -779,7 +804,8 @@ def check_input(device_opt, opt): + fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist") + + if (0 == ["list", "monitor"].count(options["--action"])) and \ +- not options.has_key("--plug") and device_opt.count("port") and device_opt.count("no_port") == 0: ++ not options.has_key("--plug") and device_opt.count("port") and \ ++ device_opt.count("no_port") == 0 and not device_opt.count("port_as_ip"): + fail_usage("Failed: You have to enter plug number or machine identification") + + if options.has_key("--password-script"): +@@ -874,6 +900,8 @@ def show_docs(options, docs=None): + sys.exit(0) + + if options.get("--action", "") == "metadata": ++ if "port_as_ip" in device_opt: ++ device_opt.remove("separator") + metadata(device_opt, options, docs) + sys.exit(0) + +diff --git a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml +index 6bdefb7..32e6630 100644 +--- a/tests/data/metadata/fence_alom.xml ++++ b/tests/data/metadata/fence_alom.xml +@@ -13,6 +13,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -108,6 +113,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml +index b967b68..8524180 100644 +--- a/tests/data/metadata/fence_amt.xml ++++ b/tests/data/metadata/fence_amt.xml +@@ -8,6 +8,11 @@ + + TCP/UDP port to use for connection with device + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -107,6 +112,11 @@ + + Path to amttool binary + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml +index d2871c5..d480669 100644 +--- a/tests/data/metadata/fence_drac.xml ++++ b/tests/data/metadata/fence_drac.xml +@@ -8,6 +8,11 @@ + + TCP/UDP port to use for connection with device + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -18,36 +23,36 @@ + + Forces agent to use IPv6 addresses only + +- +- +- +- Login password or passphrase +- + + + + IP Address or Hostname + +- +- +- +- Fencing Action +- + + + + Forces agent to use IPv4 addresses only + +- +- +- +- Login Name +- + + + + Script to retrieve password + ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Login Name ++ + + + +@@ -68,30 +73,35 @@ + + Display help and exit + ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ + + + + Test X seconds for status change after ON/OFF + +- +- ++ ++ + +- Wait X seconds after issuing ON/OFF ++ Wait X seconds before fencing is started + + + + + Wait X seconds for cmd prompt after issuing command + +- +- +- +- Wait X seconds before fencing is started +- +- +- +- +- Wait X seconds for cmd prompt after login ++ ++ ++ ++ Make "port/plug" to be an alias to IP address + + + +diff --git a/tests/data/metadata/fence_dummy.xml b/tests/data/metadata/fence_dummy.xml +index 61c964e..9295544 100644 +--- a/tests/data/metadata/fence_dummy.xml ++++ b/tests/data/metadata/fence_dummy.xml +@@ -3,6 +3,11 @@ + fence_dummy + http://www.example.com + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -43,11 +48,6 @@ + + Display help and exit + +- +- +- +- Separator for CSV created by operation list +- + + + +@@ -63,6 +63,11 @@ + + Test X seconds for status change after ON/OFF + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_hpblade.xml b/tests/data/metadata/fence_hpblade.xml +index 4f0976b..a8a2b3a 100644 +--- a/tests/data/metadata/fence_hpblade.xml ++++ b/tests/data/metadata/fence_hpblade.xml +@@ -1,6 +1,6 @@ + + +-fence_hpblade is an I/O Fencing agent which can be used with HP BladeSystem. It logs into an enclosure via telnet or ssh and uses the command line interface to power on and off blades. ++fence_hpblade is an I/O Fencing agent which can be used with HP BladeSystem and HP Integrity Superdome X. It logs into the onboard administrator of an enclosure via telnet or ssh and uses the command line interface to power blades or partitions on or off. + http://www.hp.com + + +@@ -100,7 +100,7 @@ + + + +- ++ + Wait X seconds for cmd prompt after login + + +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index dcb3235..41ab729 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -12,6 +12,11 @@ + + TCP/UDP port to use for connection with device + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -134,6 +139,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +index ae7fe9c..bcb3d15 100644 +--- a/tests/data/metadata/fence_ilo.xml ++++ b/tests/data/metadata/fence_ilo.xml +@@ -39,6 +39,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -119,6 +124,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +index 19a31a1..95bf32a 100644 +--- a/tests/data/metadata/fence_ilo2.xml ++++ b/tests/data/metadata/fence_ilo2.xml +@@ -39,6 +39,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -119,6 +124,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index e6a48bc..e09e5e1 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -12,6 +12,11 @@ + + TCP/UDP port to use for connection with device + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -134,6 +139,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +index b3531b2..1bf85e7 100644 +--- a/tests/data/metadata/fence_ilo3_ssh.xml ++++ b/tests/data/metadata/fence_ilo3_ssh.xml +@@ -15,6 +15,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -118,6 +123,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index e7b0d60..9450e56 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -12,6 +12,11 @@ + + TCP/UDP port to use for connection with device + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -134,6 +139,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +index 2266ee1..3779ce7 100644 +--- a/tests/data/metadata/fence_ilo4_ssh.xml ++++ b/tests/data/metadata/fence_ilo4_ssh.xml +@@ -15,6 +15,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -118,6 +123,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml +index 93503a0..145fb36 100644 +--- a/tests/data/metadata/fence_ilo_mp.xml ++++ b/tests/data/metadata/fence_ilo_mp.xml +@@ -13,6 +13,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -108,6 +113,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +index a9bd1d3..6eb4ae4 100644 +--- a/tests/data/metadata/fence_ilo_ssh.xml ++++ b/tests/data/metadata/fence_ilo_ssh.xml +@@ -15,6 +15,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -118,6 +123,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index 8fbdddd..2e7d65c 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -12,6 +12,11 @@ + + TCP/UDP port to use for connection with device + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -134,6 +139,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index 199490c..ae528de 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -12,6 +12,11 @@ + + TCP/UDP port to use for connection with device + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -134,6 +139,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +index c62dd49..ccd41ff 100644 +--- a/tests/data/metadata/fence_mpath.xml ++++ b/tests/data/metadata/fence_mpath.xml +@@ -4,20 +4,25 @@ + The fence_mpath agent works by having an unique key for each pair of node and device that has to be set also in /etc/multipath.conf. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_mpath agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. + https://www.sourceware.org/dm/ + +- +- ++ ++ + +- List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations. ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Fencing Action + + + + + Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s). + +- +- +- +- Fencing Action ++ ++ ++ ++ List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations. + + + +@@ -39,11 +44,31 @@ The fence_mpath agent works by having an unique key for each pair of node and de + + Display help and exit + ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + + Wait X seconds before fencing is started + ++ ++ ++ ++ Path to mpathpersist binary ++ + + + +@@ -59,21 +84,6 @@ The fence_mpath agent works by having an unique key for each pair of node and de + + Test X seconds for status change after ON/OFF + +- +- +- +- Wait X seconds after issuing ON/OFF +- +- +- +- +- Wait X seconds for cmd prompt after login +- +- +- +- +- Path to mpathpersist binary +- + + + +diff --git a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml +index 749b21d..aa9caaa 100644 +--- a/tests/data/metadata/fence_rsa.xml ++++ b/tests/data/metadata/fence_rsa.xml +@@ -13,6 +13,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -108,6 +113,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +diff --git a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml +index 56421fc..b400d7e 100644 +--- a/tests/data/metadata/fence_rsb.xml ++++ b/tests/data/metadata/fence_rsb.xml +@@ -13,6 +13,11 @@ + + IP Address or Hostname + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ + + + +@@ -108,6 +113,11 @@ + + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + +-- +1.9.3 + diff --git a/SOURCES/bz1214919-fence_scsi-already_on.patch b/SOURCES/bz1214919-fence_scsi-already_on.patch new file mode 100644 index 0000000..6ecbcea --- /dev/null +++ b/SOURCES/bz1214919-fence_scsi-already_on.patch @@ -0,0 +1,35 @@ +From 4e338b93999996f9eae873d7aab84ef30dd0688e Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 19:40:11 +0200 +Subject: [PATCH 03/10] fence_scsi: Status report "off" if any device is off + during "on" action + +We need status to report "on" if any device is on most of the time so +that stonith or other entities can know if a host is capable of +accessing shared resources, but during an "on" action this is +problematic because even if some devices are off, we will skip turning +them on since we reported the status as on. This changes the behavior +to report "off" if any device is off, but only during "on" actions. + +Resolves: rhbz#1214919 +--- + fence/agents/scsi/fence_scsi.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index de301a5..f373e6b 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -32,6 +32,9 @@ def get_status(conn, options): + else: + logging.debug("No registration for key "\ + + options["--key"] + " on device " + dev + "\n") ++ if options["--action"] == "on": ++ status = "off" ++ break + return status + + +-- +1.9.3 + diff --git a/SOURCES/bz1216997-support_for_hp_superdome.patch b/SOURCES/bz1216997-support_for_hp_superdome.patch new file mode 100644 index 0000000..39b221e --- /dev/null +++ b/SOURCES/bz1216997-support_for_hp_superdome.patch @@ -0,0 +1,165 @@ +From 3d712dab6d8b1dc7c011a3d9399c3d278329387f Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 09:30:55 +0200 +Subject: [PATCH 2/6] fence_hpblade: Add support for HP Integrity Superdome X + (BL920s) + +Resolves: rhbz#1216997 +--- + fence/agents/hpblade/fence_hpblade.py | 85 ++++++++++++++++++++++++++++------- + 1 file changed, 68 insertions(+), 17 deletions(-) + +diff --git a/fence/agents/hpblade/fence_hpblade.py b/fence/agents/hpblade/fence_hpblade.py +index e0b8866..832819c 100644 +--- a/fence/agents/hpblade/fence_hpblade.py ++++ b/fence/agents/hpblade/fence_hpblade.py +@@ -3,31 +3,62 @@ + ##### + ## + ## The Following Agent Has Been Tested On: +-## * BladeSystem c7000 Enclosure ++## * HP BladeSystem c7000 Enclosure ++## * HP Integrity Superdome X (BL920s) + ##### + + import sys, re ++import pexpect, exceptions + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * + from fencing import fail, EC_STATUS + + #BEGIN_VERSION_GENERATION +-RELEASE_VERSION="New Bladecenter Agent - test release on steroids" +-REDHAT_COPYRIGHT="" +-BUILD_DATE="March, 2008" ++RELEASE_VERSION="4.0.11-HP" ++BUILD_DATE="(built Mon Mar 30 08:31:24 EDT 2015)" ++REDHAT_COPYRIGHT="Copyright (C) Red Hat, Inc. 2004-2010 All rights reserved." + #END_VERSION_GENERATION + ++def get_enclosure_type(conn, options): ++ conn.send_eol("show enclosure info") ++ conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) ++ ++ type_re=re.compile(r"^\s*Enclosure Type: (\w+)(.*?)\s*$") ++ enclosure="unknown" ++ for line in conn.before.splitlines(): ++ res = type_re.search(line) ++ if res != None: ++ enclosure=res.group(1) ++ ++ if enclosure == "unknown": ++ fail(EC_GENERIC_ERROR) ++ ++ return enclosure.lower().strip() ++ + def get_power_status(conn, options): +- conn.send_eol("show server status " + options["--plug"]) ++ if options["enc_type"] == "superdome": ++ cmd_send = "parstatus -M -p " + options["--plug"] ++ powrestr = "^partition:\\d\\s+:\\w+\\s+/(\\w+)\\s.*$" ++ else: ++ cmd_send = "show server status " + options["--plug"] ++ powrestr = "^\\s*Power: (.*?)\\s*$" ++ ++ conn.send_eol(cmd_send) + conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) + +- power_re = re.compile(r"^\s*Power: (.*?)\s*$") ++ power_re = re.compile(powrestr) + status = "unknown" + for line in conn.before.splitlines(): + res = power_re.search(line) + if res != None: +- status = res.group(1) ++ if options["enc_type"] == "superdome": ++ if res.group(1) == "DOWN": ++ status = "off" ++ else: ++ status = "on" ++ else: ++ status = res.group(1) + + if status == "unknown": + if options.has_key("--missing-as-off"): +@@ -38,23 +69,37 @@ def get_power_status(conn, options): + return status.lower().strip() + + def set_power_status(conn, options): ++ if options["enc_type"] == "superdome": ++ dev="partition " ++ else: ++ dev="server " ++ + if options["--action"] == "on": +- conn.send_eol("poweron server " + options["--plug"]) ++ conn.send_eol("poweron " + dev + options["--plug"]) + elif options["--action"] == "off": +- conn.send_eol("poweroff server " + options["--plug"] + " force") ++ conn.send_eol("poweroff " + dev + options["--plug"] + " force") + conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) + +-def get_blades_list(conn, options): ++def get_instances_list(conn, options): + outlets = {} +- +- conn.send_eol("show server list") ++ if options["enc_type"] == "superdome": ++ cmd_send = "parstatus -P -M" ++ listrestr = "^partition:(\\d+)\\s+:\\w+\\s+/(\\w+)\\s+:OK.*?:(\\w+)\\s*$" ++ else: ++ cmd_send = "show server list" ++ listrestr = "^\\s*(\\d+)\\s+(.*?)\\s+(.*?)\\s+OK\\s+(.*?)\\s+(.*?)\\s*$" ++ ++ conn.send_eol(cmd_send) + conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) + +- list_re = re.compile(r"^\s*(.*?)\s+(.*?)\s+(.*?)\s+OK\s+(.*?)\s+(.*?)\s*$") ++ list_re = re.compile(listrestr) + for line in conn.before.splitlines(): + res = list_re.search(line) + if res != None: +- outlets[res.group(1)] = (res.group(2), res.group(4).lower()) ++ if options["enc_type"] == "superdome": ++ outlets[res.group(1)] = (res.group(3), res.group(2).lower()) ++ else: ++ outlets[res.group(1)] = (res.group(2), res.group(4).lower()) + + return outlets + +@@ -64,14 +109,17 @@ def main(): + atexit.register(atexit_handler) + + all_opt["cmd_prompt"]["default"] = ["c7000oa>"] ++ all_opt["login_timeout"]["default"] = "10" + + options = check_input(device_opt, process_input(device_opt)) + + docs = {} + docs["shortdesc"] = "Fence agent for HP BladeSystem" + docs["longdesc"] = "fence_hpblade is an I/O Fencing agent \ +-which can be used with HP BladeSystem. It logs into an enclosure via telnet or ssh \ +-and uses the command line interface to power on and off blades." ++which can be used with HP BladeSystem and HP Integrity Superdome X. \ ++It logs into the onboard administrator of an enclosure via telnet or \ ++ssh and uses the command line interface to power blades or partitions \ ++on or off." + docs["vendorurl"] = "http://www.hp.com" + show_docs(options, docs) + +@@ -80,7 +128,10 @@ and uses the command line interface to power on and off blades." + ###### + options["eol"] = "\n" + conn = fence_login(options) +- result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list) ++ ++ options["enc_type"] = get_enclosure_type(conn, options) ++ ++ result = fence_action(conn, options, set_power_status, get_power_status, get_instances_list) + fence_logout(conn, "exit") + sys.exit(result) + +-- +1.9.3 + diff --git a/SOURCES/bz1241648-fence_ipmilan_password_verbose.patch b/SOURCES/bz1241648-fence_ipmilan_password_verbose.patch new file mode 100644 index 0000000..a509015 --- /dev/null +++ b/SOURCES/bz1241648-fence_ipmilan_password_verbose.patch @@ -0,0 +1,30 @@ +From 48bf31cb12ddca8df530739943744f2da7aa94c8 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Fri, 10 Jul 2015 10:55:23 +0200 +Subject: [PATCH 3/3] fence_ipmilan: Do not print password to debug info + +Resolves: rhbz#1241648 +--- + fence/agents/lib/fencing.py.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 9a16aee..7fddc47 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -1182,7 +1182,11 @@ def run_command(options, command, timeout=None, env=None): + if timeout is not None: + timeout = float(timeout) + +- logging.info("Executing: %s\n", command) ++ # For IPMI password occurs on command line, it should not be part of debug info ++ log_command = command ++ if "ipmitool" in log_command: ++ log_command = re.sub("-P (.+?) -p", "-P [set] -p", log_command) ++ logging.info("Executing: %s\n", log_command) + + try: + process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) +-- +1.9.3 + diff --git a/SOURCES/bz1243485-1-fence_scsi-force-on.patch b/SOURCES/bz1243485-1-fence_scsi-force-on.patch new file mode 100644 index 0000000..40d54b4 --- /dev/null +++ b/SOURCES/bz1243485-1-fence_scsi-force-on.patch @@ -0,0 +1,57 @@ +From 2a2aa2d03bc456ce1fa869fa54398c89956e409a Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 16 Jul 2015 09:26:32 +0200 +Subject: [PATCH 1/2] fencing: Add option that forces ON even if machine is + already ON + +This feature is required for fence_scsi when we have to do unfencing after reboot even +if node was not fenced at all. Keys for SCSI are stored in /var/run/cluster and so they +have to re-created. +--- + fence/agents/lib/fencing.py.py | 9 +++++++-- + fence/agents/scsi/fence_scsi.py | 2 +- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 2ba98b8..377c63f 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -82,6 +82,10 @@ all_opt = { + "getopt" : "", + "help" : "", + "order" : 1}, ++ "force_on" : { ++ "getopt" : "", ++ "help" : "", ++ "order" : 1}, + "action" : { + "getopt" : "o:", + "longopt" : "action", +@@ -949,8 +953,9 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list=None, + fail(EC_STATUS) + + if options["--action"] == status: +- print "Success: Already %s" % (status.upper()) +- return 0 ++ if not (status == "on" and "force_on" in options["device_opt"]): ++ print "Success: Already %s" % (status.upper()) ++ return 0 + + if options["--action"] == "on": + if set_multi_power_fn(tn, options, set_power_fn, get_power_fn, 1 + int(options["--retry-on"])): +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index f373e6b..445c5f8 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -396,7 +396,7 @@ def main(): + + device_opt = ["no_login", "no_password", "devices", "nodename", "key",\ + "aptpl", "fabric_fencing", "on_target", "corosync-cmap_path",\ +- "sg_persist_path", "sg_turs_path", "logfile", "vgs_path"] ++ "sg_persist_path", "sg_turs_path", "logfile", "vgs_path", "force_on"] + + define_new_opts() + +-- +1.9.3 + diff --git a/SOURCES/bz1243485-2-fence_scsi-monitor.patch b/SOURCES/bz1243485-2-fence_scsi-monitor.patch new file mode 100644 index 0000000..f7ad1e2 --- /dev/null +++ b/SOURCES/bz1243485-2-fence_scsi-monitor.patch @@ -0,0 +1,37 @@ +From 4a095f8d70ef90a50ed59917cca6874a3db1a433 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 16 Jul 2015 09:28:15 +0200 +Subject: [PATCH 2/2] fence_scsi: Monitor action checks also existence of files + with SCSI keys + +--- + fence/agents/scsi/fence_scsi.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index 445c5f8..7e7bc0d 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -88,6 +88,7 @@ def set_status(conn, options): + + # check if host is ready to execute actions + def do_action_monitor(options): ++ # Check if required binaries are installed + if bool(run_cmd(options, options["--sg_persist-path"] + " -V")["err"]): + logging.error("Unable to run " + options["--sg_persist-path"]) + return 1 +@@ -98,6 +99,11 @@ def do_action_monitor(options): + bool(run_cmd(options, options["--vgs-path"] + " --version")["err"])): + logging.error("Unable to run " + options["--vgs-path"]) + return 1 ++ ++ # Keys have to be present in order to fence/unfence ++ get_key() ++ dev_read() ++ + return 0 + + +-- +1.9.3 + diff --git a/SOURCES/bz1243485-3-fence_scsi_check.patch b/SOURCES/bz1243485-3-fence_scsi_check.patch new file mode 100644 index 0000000..9664609 --- /dev/null +++ b/SOURCES/bz1243485-3-fence_scsi_check.patch @@ -0,0 +1,67 @@ +From 5bc23bc764326a8ea2a5ffffbe1e9bea9a32b868 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 17 Aug 2015 10:46:25 +0200 +Subject: [PATCH] fence_scsi: Watchdog script should pass on a system that is + not configured + +--- + fence/agents/scsi/fence_scsi.py | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index 7e7bc0d..e18e473 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -205,12 +205,15 @@ def set_key(options): + + + # read node key from file +-def get_key(): ++def get_key(fail=True): + file_path = STORE_PATH + ".key" + try: + f = open(file_path, "r") + except IOError: +- fail_usage("Failed: Cannot open file \""+ file_path + "\"") ++ if fail: ++ fail_usage("Failed: Cannot open file \""+ file_path + "\"") ++ else: ++ return None + return f.readline().strip().lower() + + +@@ -228,12 +231,15 @@ def dev_write(dev, options): + f.close() + + +-def dev_read(): ++def dev_read(fail=True): + file_path = STORE_PATH + ".dev" + try: + f = open(file_path, "r") + except IOError: +- fail_usage("Failed: Cannot open file \"" + file_path + "\"") ++ if fail: ++ fail_usage("Failed: Cannot open file \"" + file_path + "\"") ++ else: ++ return None + # get not empty lines from file + devs = [line.strip() for line in f if line.strip()] + f.close() +@@ -378,11 +384,11 @@ def scsi_check(): + options["--power-timeout"] = "5" + if scsi_check_get_verbose(): + logging.getLogger().setLevel(logging.DEBUG) +- devs = dev_read() ++ devs = dev_read(fail=False) + if not devs: + logging.error("No devices found") + return 0 +- key = get_key() ++ key = get_key(fail=False) + if not key: + logging.error("Key not found") + return 0 +-- +1.9.3 + diff --git a/SOURCES/bz1250586-2-list_status.patch b/SOURCES/bz1250586-2-list_status.patch new file mode 100644 index 0000000..e55581c --- /dev/null +++ b/SOURCES/bz1250586-2-list_status.patch @@ -0,0 +1,27 @@ +From 9df35db45f9d3e78e4c4e382e85003b02297dd75 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 12 Aug 2015 14:32:07 +0200 +Subject: [PATCH 1/2] fencing: Actions 'list-status' and 'validate-all' were + not documented in manual pages + +--- + fence/agents/lib/fence2man.xsl | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fence/agents/lib/fence2man.xsl b/fence/agents/lib/fence2man.xsl +index 97786ea..fd923f5 100644 +--- a/fence/agents/lib/fence2man.xsl ++++ b/fence/agents/lib/fence2man.xsl +@@ -33,7 +33,9 @@ + Check the health of fence device + Display the XML metadata describing this resource. + List available plugs with aliases/virtual machines if there is support for more then one device. Returns N/A otherwise. ++List available plugs with aliases/virtual machines and their power state if it can be obtained without additional commands. + This returns the status of the plug/virtual machine. ++Validate if all required parameters are entered. + + The operational behavior of this is not known. + +-- +1.9.3 + diff --git a/SOURCES/bz1250586-list_status.patch b/SOURCES/bz1250586-list_status.patch new file mode 100644 index 0000000..5ad6881 --- /dev/null +++ b/SOURCES/bz1250586-list_status.patch @@ -0,0 +1,777 @@ +From 14d640ebddfd211c6512b5aa29df112a5fa867a4 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 5 Aug 2015 09:57:30 +0200 +Subject: [PATCH 1/4] fencing: Add suport for list-status + +--- + fence/agents/lib/fencing.py.py | 55 +++++++++++++++++------------- + fence/agents/ovh/fence_ovh.py | 3 ++ + tests/data/metadata/fence_alom.xml | 1 + + tests/data/metadata/fence_amt.xml | 1 + + tests/data/metadata/fence_apc.xml | 1 + + tests/data/metadata/fence_apc_snmp.xml | 1 + + tests/data/metadata/fence_bladecenter.xml | 1 + + tests/data/metadata/fence_brocade.xml | 1 + + tests/data/metadata/fence_cisco_mds.xml | 1 + + tests/data/metadata/fence_cisco_ucs.xml | 1 + + tests/data/metadata/fence_compute.xml | 1 + + tests/data/metadata/fence_docker.xml | 1 + + tests/data/metadata/fence_drac.xml | 1 + + tests/data/metadata/fence_drac5.xml | 1 + + tests/data/metadata/fence_dummy.xml | 1 + + tests/data/metadata/fence_eaton_snmp.xml | 1 + + tests/data/metadata/fence_emerson.xml | 1 + + tests/data/metadata/fence_eps.xml | 1 + + tests/data/metadata/fence_hds_cb.xml | 1 + + tests/data/metadata/fence_hpblade.xml | 1 + + tests/data/metadata/fence_ibmblade.xml | 1 + + tests/data/metadata/fence_idrac.xml | 1 + + tests/data/metadata/fence_ifmib.xml | 1 + + tests/data/metadata/fence_ilo.xml | 1 + + tests/data/metadata/fence_ilo2.xml | 1 + + tests/data/metadata/fence_ilo3.xml | 1 + + tests/data/metadata/fence_ilo3_ssh.xml | 1 + + tests/data/metadata/fence_ilo4.xml | 1 + + tests/data/metadata/fence_ilo4_ssh.xml | 1 + + tests/data/metadata/fence_ilo_moonshot.xml | 1 + + tests/data/metadata/fence_ilo_mp.xml | 1 + + tests/data/metadata/fence_ilo_ssh.xml | 1 + + tests/data/metadata/fence_imm.xml | 1 + + tests/data/metadata/fence_intelmodular.xml | 1 + + tests/data/metadata/fence_ipdu.xml | 1 + + tests/data/metadata/fence_ipmilan.xml | 1 + + tests/data/metadata/fence_ldom.xml | 1 + + tests/data/metadata/fence_lpar.xml | 1 + + tests/data/metadata/fence_mpath.xml | 1 + + tests/data/metadata/fence_netio.xml | 1 + + tests/data/metadata/fence_ovh.xml | 1 + + tests/data/metadata/fence_pve.xml | 1 + + tests/data/metadata/fence_raritan.xml | 1 + + tests/data/metadata/fence_rhevm.xml | 1 + + tests/data/metadata/fence_rsa.xml | 1 + + tests/data/metadata/fence_rsb.xml | 1 + + tests/data/metadata/fence_sanbox2.xml | 1 + + tests/data/metadata/fence_scsi.xml | 1 + + tests/data/metadata/fence_virsh.xml | 1 + + tests/data/metadata/fence_vmware_soap.xml | 1 + + tests/data/metadata/fence_wti.xml | 1 + + tests/data/metadata/fence_xenapi.xml | 1 + + tests/data/metadata/fence_zvmip.xml | 1 + + 53 files changed, 85 insertions(+), 24 deletions(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 377c63f..89c3379 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -584,6 +584,7 @@ def metadata(avail_opt, options, docs): + if avail_opt.count("no_status") == 0: + print "\t" + print "\t" ++ print "\t" + print "\t" + print "\t" + print "" +@@ -758,7 +759,7 @@ def check_input(device_opt, opt): + ## add loggint to stderr + logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stderr)) + +- acceptable_actions = ["on", "off", "status", "list", "monitor"] ++ acceptable_actions = ["on", "off", "status", "list", "list-status", "monitor"] + if 1 == device_opt.count("fabric_fencing"): + ## Compatibility layer + ##### +@@ -807,7 +808,7 @@ def check_input(device_opt, opt): + if not os.path.isfile(options["--identity-file"]): + fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist") + +- if (0 == ["list", "monitor"].count(options["--action"])) and \ ++ if (0 == ["list", "list-status", "monitor"].count(options["--action"])) and \ + not options.has_key("--plug") and device_opt.count("port") and \ + device_opt.count("no_port") == 0 and not device_opt.count("port_as_ip"): + fail_usage("Failed: You have to enter plug number or machine identification") +@@ -923,28 +924,34 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list=None, + + ## Process options that manipulate fencing device + ##### +- if options["--action"] == "list" and 0 == options["device_opt"].count("port"): +- print "N/A" +- return +- elif options["--action"] == "list" and get_outlet_list == None: +- ## @todo: exception? +- ## This is just temporal solution, we will remove default value +- ## None as soon as all existing agent will support this operation +- print "NOTICE: List option is not working on this device yet" +- return +- elif (options["--action"] == "list") or \ +- ((options["--action"] == "monitor") and 1 == options["device_opt"].count("port")): +- options["--original-action"] = options["--action"] +- options["--action"] = "list" +- outlets = get_outlet_list(tn, options) +- options["--action"] = options["--original-action"] +- del options["--original-action"] +- +- ## keys can be numbers (port numbers) or strings (names of VM) +- for outlet_id in outlets.keys(): +- (alias, status) = outlets[outlet_id] +- if options["--action"] != "monitor": +- print outlet_id + options["--separator"] + alias ++ if options["--action"] in ["list", "list-status"] or \ ++ ((options["--action"] == "monitor") and 1 == options["device_opt"].count("port")): ++ ++ if 0 == options["device_opt"].count("port"): ++ print "N/A" ++ elif get_outlet_list == None: ++ ## @todo: exception? ++ ## This is just temporal solution, we will remove default value ++ ## None as soon as all existing agent will support this operation ++ print "NOTICE: List option is not working on this device yet" ++ else: ++ options["--original-action"] = options["--action"] ++ options["--action"] = "list" ++ outlets = get_outlet_list(tn, options) ++ options["--action"] = options["--original-action"] ++ del options["--original-action"] ++ ++ ## keys can be numbers (port numbers) or strings (names of VM) ++ for outlet_id in outlets.keys(): ++ (alias, status) = outlets[outlet_id] ++ status = status.upper() ++ if not status in ["ON", "OFF"]: ++ status = "UNKNOWN" ++ ++ if options["--action"] == "list": ++ print outlet_id + options["--separator"] + alias ++ elif options["--action"] == "list-status": ++ print outlet_id + options["--separator"] + alias + options["--separator"] + status + return + + status = get_multi_power_fn(tn, options, get_power_fn) +diff --git a/fence/agents/ovh/fence_ovh.py b/fence/agents/ovh/fence_ovh.py +index 14a0706..1fef7e3 100644 +--- a/fence/agents/ovh/fence_ovh.py ++++ b/fence/agents/ovh/fence_ovh.py +@@ -97,6 +97,9 @@ Poweroff is simulated with a reboot into rescue-pro mode." + if options["--action"] == "list": + fail_usage("Action 'list' is not supported in this fence agent") + ++ if options["--action"] == "list-status": ++ fail_usage("Action 'list-status' is not supported in this fence agent") ++ + if options["--action"] != "monitor" and not options["--plug"].endswith(".ovh.net"): + options["--plug"] += ".ovh.net" + +diff --git a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml +index 32e6630..dfbe431 100644 +--- a/tests/data/metadata/fence_alom.xml ++++ b/tests/data/metadata/fence_alom.xml +@@ -130,6 +130,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml +index 8524180..17e38fc 100644 +--- a/tests/data/metadata/fence_amt.xml ++++ b/tests/data/metadata/fence_amt.xml +@@ -134,6 +134,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_apc.xml b/tests/data/metadata/fence_apc.xml +index 441de61..8233101 100644 +--- a/tests/data/metadata/fence_apc.xml ++++ b/tests/data/metadata/fence_apc.xml +@@ -135,6 +135,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_apc_snmp.xml b/tests/data/metadata/fence_apc_snmp.xml +index 886f1b0..d433735 100644 +--- a/tests/data/metadata/fence_apc_snmp.xml ++++ b/tests/data/metadata/fence_apc_snmp.xml +@@ -159,6 +159,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_bladecenter.xml b/tests/data/metadata/fence_bladecenter.xml +index ec1b011..7058c18 100644 +--- a/tests/data/metadata/fence_bladecenter.xml ++++ b/tests/data/metadata/fence_bladecenter.xml +@@ -135,6 +135,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_brocade.xml b/tests/data/metadata/fence_brocade.xml +index 5373d0e..6f69230 100644 +--- a/tests/data/metadata/fence_brocade.xml ++++ b/tests/data/metadata/fence_brocade.xml +@@ -129,6 +129,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_cisco_mds.xml b/tests/data/metadata/fence_cisco_mds.xml +index add75f3..df4aa61 100644 +--- a/tests/data/metadata/fence_cisco_mds.xml ++++ b/tests/data/metadata/fence_cisco_mds.xml +@@ -158,6 +158,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +index 66fc576..9834f5a 100644 +--- a/tests/data/metadata/fence_cisco_ucs.xml ++++ b/tests/data/metadata/fence_cisco_ucs.xml +@@ -135,6 +135,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +index 2c488c5..846a861 100644 +--- a/tests/data/metadata/fence_compute.xml ++++ b/tests/data/metadata/fence_compute.xml +@@ -120,6 +120,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml +index d100b8c..2c2261a 100644 +--- a/tests/data/metadata/fence_docker.xml ++++ b/tests/data/metadata/fence_docker.xml +@@ -133,6 +133,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml +index d480669..37697f7 100644 +--- a/tests/data/metadata/fence_drac.xml ++++ b/tests/data/metadata/fence_drac.xml +@@ -115,6 +115,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_drac5.xml b/tests/data/metadata/fence_drac5.xml +index d96484c..c1a78aa 100644 +--- a/tests/data/metadata/fence_drac5.xml ++++ b/tests/data/metadata/fence_drac5.xml +@@ -139,6 +139,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_dummy.xml b/tests/data/metadata/fence_dummy.xml +index 9295544..eb31244 100644 +--- a/tests/data/metadata/fence_dummy.xml ++++ b/tests/data/metadata/fence_dummy.xml +@@ -90,6 +90,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_eaton_snmp.xml b/tests/data/metadata/fence_eaton_snmp.xml +index 1cf0436..7bbe054 100644 +--- a/tests/data/metadata/fence_eaton_snmp.xml ++++ b/tests/data/metadata/fence_eaton_snmp.xml +@@ -159,6 +159,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +index 553fc37..b79186c 100644 +--- a/tests/data/metadata/fence_emerson.xml ++++ b/tests/data/metadata/fence_emerson.xml +@@ -159,6 +159,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml +index a64ce8e..fcf72b8 100644 +--- a/tests/data/metadata/fence_eps.xml ++++ b/tests/data/metadata/fence_eps.xml +@@ -117,6 +117,7 @@ Agent basically works by connecting to hidden page and pass appropriate argument + + + ++ + + + +diff --git a/tests/data/metadata/fence_hds_cb.xml b/tests/data/metadata/fence_hds_cb.xml +index 8f5279a..3230916 100644 +--- a/tests/data/metadata/fence_hds_cb.xml ++++ b/tests/data/metadata/fence_hds_cb.xml +@@ -135,6 +135,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_hpblade.xml b/tests/data/metadata/fence_hpblade.xml +index a8a2b3a..a9948c7 100644 +--- a/tests/data/metadata/fence_hpblade.xml ++++ b/tests/data/metadata/fence_hpblade.xml +@@ -135,6 +135,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ibmblade.xml b/tests/data/metadata/fence_ibmblade.xml +index 4731e5e..175df9b 100644 +--- a/tests/data/metadata/fence_ibmblade.xml ++++ b/tests/data/metadata/fence_ibmblade.xml +@@ -159,6 +159,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index 41ab729..b742161 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -161,6 +161,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ifmib.xml b/tests/data/metadata/fence_ifmib.xml +index 7faf2ab..49de1b3 100644 +--- a/tests/data/metadata/fence_ifmib.xml ++++ b/tests/data/metadata/fence_ifmib.xml +@@ -160,6 +160,7 @@ It was written with managed ethernet switches in mind, in order to fence iSCSI S + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +index bcb3d15..891b7f1 100644 +--- a/tests/data/metadata/fence_ilo.xml ++++ b/tests/data/metadata/fence_ilo.xml +@@ -141,6 +141,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +index 95bf32a..7ff697f 100644 +--- a/tests/data/metadata/fence_ilo2.xml ++++ b/tests/data/metadata/fence_ilo2.xml +@@ -141,6 +141,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index e09e5e1..05fd01c 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -161,6 +161,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +index 1bf85e7..ebdae65 100644 +--- a/tests/data/metadata/fence_ilo3_ssh.xml ++++ b/tests/data/metadata/fence_ilo3_ssh.xml +@@ -140,6 +140,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index 9450e56..4f29073 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -161,6 +161,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +index 3779ce7..197d627 100644 +--- a/tests/data/metadata/fence_ilo4_ssh.xml ++++ b/tests/data/metadata/fence_ilo4_ssh.xml +@@ -140,6 +140,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo_moonshot.xml b/tests/data/metadata/fence_ilo_moonshot.xml +index d7f2bc9..41303e2 100644 +--- a/tests/data/metadata/fence_ilo_moonshot.xml ++++ b/tests/data/metadata/fence_ilo_moonshot.xml +@@ -130,6 +130,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml +index 145fb36..d2396e9 100644 +--- a/tests/data/metadata/fence_ilo_mp.xml ++++ b/tests/data/metadata/fence_ilo_mp.xml +@@ -130,6 +130,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +index 6eb4ae4..1d79308 100644 +--- a/tests/data/metadata/fence_ilo_ssh.xml ++++ b/tests/data/metadata/fence_ilo_ssh.xml +@@ -140,6 +140,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index 2e7d65c..0302f84 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -161,6 +161,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_intelmodular.xml b/tests/data/metadata/fence_intelmodular.xml +index 707b37a..9d33115 100644 +--- a/tests/data/metadata/fence_intelmodular.xml ++++ b/tests/data/metadata/fence_intelmodular.xml +@@ -161,6 +161,7 @@ Note: Since firmware update version 2.7, SNMP v2 write support is removed, and r + + + ++ + + + +diff --git a/tests/data/metadata/fence_ipdu.xml b/tests/data/metadata/fence_ipdu.xml +index 66fa768..f656c1c 100644 +--- a/tests/data/metadata/fence_ipdu.xml ++++ b/tests/data/metadata/fence_ipdu.xml +@@ -159,6 +159,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index ae528de..4ed67eb 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -161,6 +161,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ldom.xml b/tests/data/metadata/fence_ldom.xml +index 082fd82..bab164a 100644 +--- a/tests/data/metadata/fence_ldom.xml ++++ b/tests/data/metadata/fence_ldom.xml +@@ -132,6 +132,7 @@ Very useful parameter is -c (or cmd_prompt in stdin mode). This must be set to s + + + ++ + + + +diff --git a/tests/data/metadata/fence_lpar.xml b/tests/data/metadata/fence_lpar.xml +index 9b6d62d..8c82925 100644 +--- a/tests/data/metadata/fence_lpar.xml ++++ b/tests/data/metadata/fence_lpar.xml +@@ -143,6 +143,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +index ccd41ff..d3de9d5 100644 +--- a/tests/data/metadata/fence_mpath.xml ++++ b/tests/data/metadata/fence_mpath.xml +@@ -100,6 +100,7 @@ The fence_mpath agent works by having an unique key for each pair of node and de + + + ++ + + + +diff --git a/tests/data/metadata/fence_netio.xml b/tests/data/metadata/fence_netio.xml +index f47238c..94db07e 100644 +--- a/tests/data/metadata/fence_netio.xml ++++ b/tests/data/metadata/fence_netio.xml +@@ -110,6 +110,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_ovh.xml b/tests/data/metadata/fence_ovh.xml +index 522da6c..bf7ebfe 100644 +--- a/tests/data/metadata/fence_ovh.xml ++++ b/tests/data/metadata/fence_ovh.xml +@@ -94,6 +94,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_pve.xml b/tests/data/metadata/fence_pve.xml +index 86c3cd7..99894e5 100644 +--- a/tests/data/metadata/fence_pve.xml ++++ b/tests/data/metadata/fence_pve.xml +@@ -115,6 +115,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_raritan.xml b/tests/data/metadata/fence_raritan.xml +index e970b99..d3a0d50 100644 +--- a/tests/data/metadata/fence_raritan.xml ++++ b/tests/data/metadata/fence_raritan.xml +@@ -110,6 +110,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +index e0c9516..aa033eb 100644 +--- a/tests/data/metadata/fence_rhevm.xml ++++ b/tests/data/metadata/fence_rhevm.xml +@@ -135,6 +135,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml +index aa9caaa..3f3a336 100644 +--- a/tests/data/metadata/fence_rsa.xml ++++ b/tests/data/metadata/fence_rsa.xml +@@ -130,6 +130,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml +index b400d7e..36b9cdb 100644 +--- a/tests/data/metadata/fence_rsb.xml ++++ b/tests/data/metadata/fence_rsb.xml +@@ -130,6 +130,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_sanbox2.xml b/tests/data/metadata/fence_sanbox2.xml +index 06826b6..950c629 100644 +--- a/tests/data/metadata/fence_sanbox2.xml ++++ b/tests/data/metadata/fence_sanbox2.xml +@@ -114,6 +114,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +index ba80e8c..d370e36 100644 +--- a/tests/data/metadata/fence_scsi.xml ++++ b/tests/data/metadata/fence_scsi.xml +@@ -110,6 +110,7 @@ The fence_scsi agent works by having each node in the cluster register a unique + + + ++ + + + +diff --git a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml +index 5febd77..3546a2c 100644 +--- a/tests/data/metadata/fence_virsh.xml ++++ b/tests/data/metadata/fence_virsh.xml +@@ -137,6 +137,7 @@ By default, virsh needs root account to do properly work. So you must allow ssh + + + ++ + + + +diff --git a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml +index 1308c85..fb54ef7 100644 +--- a/tests/data/metadata/fence_vmware_soap.xml ++++ b/tests/data/metadata/fence_vmware_soap.xml +@@ -132,6 +132,7 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + + + ++ + + + +diff --git a/tests/data/metadata/fence_wti.xml b/tests/data/metadata/fence_wti.xml +index c7cb9d1..5f2566a 100644 +--- a/tests/data/metadata/fence_wti.xml ++++ b/tests/data/metadata/fence_wti.xml +@@ -130,6 +130,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_xenapi.xml b/tests/data/metadata/fence_xenapi.xml +index 0dd0a78..6040e85 100644 +--- a/tests/data/metadata/fence_xenapi.xml ++++ b/tests/data/metadata/fence_xenapi.xml +@@ -95,6 +95,7 @@ + + + ++ + + + +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index 993dfb3..c688f42 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -137,6 +137,7 @@ Where XXXXXXX is the name of the virtual machine used in the authuser field of t + + + ++ + + + +-- +1.9.3 + diff --git a/SOURCES/bz1251491-none_as_state.patch b/SOURCES/bz1251491-none_as_state.patch new file mode 100644 index 0000000..e8897ab --- /dev/null +++ b/SOURCES/bz1251491-none_as_state.patch @@ -0,0 +1,33 @@ +From 76ddf8b54482ef4702abc35611cf1c0250c62dcd Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 10 Aug 2015 13:17:07 +0200 +Subject: [PATCH] fencing: Fence library should work correctly also when power + state is None + +Previously, valid states ON/OFF were accepted and all other values were mapped to UNKNOWN. But if value is None then +it is not possible to do state.upper() and fencing fails. + +Resolves: rhbz#1251491 +--- + fence/agents/lib/fencing.py.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index fb7b77d..3a6e2ab 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -951,9 +951,9 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list=None, + ## keys can be numbers (port numbers) or strings (names of VM) + for outlet_id in outlets.keys(): + (alias, status) = outlets[outlet_id] +- status = status.upper() +- if not status in ["ON", "OFF"]: ++ if status is None or (not status.upper() in ["ON", "OFF"]): + status = "UNKNOWN" ++ status = status.upper() + + if options["--action"] == "list": + print outlet_id + options["--separator"] + alias +-- +1.9.3 + diff --git a/SOURCES/bz1254821-fence_virsh-missing-as-off-1.patch b/SOURCES/bz1254821-fence_virsh-missing-as-off-1.patch new file mode 100644 index 0000000..d8097f6 --- /dev/null +++ b/SOURCES/bz1254821-fence_virsh-missing-as-off-1.patch @@ -0,0 +1,49 @@ +From 0aacfcf209c473ab4c1fff4de653a673b92484de Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 19 Aug 2015 09:55:06 +0200 +Subject: [PATCH] fence_virsh: Add --missing-as-off option + +Resolves: rhbz#1254821 +--- + fence/agents/virsh/fence_virsh.py | 4 +++- + tests/data/metadata/fence_virsh.xml | 5 +++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py +index 0a94136..24d360c 100644 +--- a/fence/agents/virsh/fence_virsh.py ++++ b/fence/agents/virsh/fence_virsh.py +@@ -54,6 +54,8 @@ def get_power_status(conn, options): + for line in conn.before.splitlines(): + if line.strip() in ["running", "blocked", "idle", "no state", "paused"]: + return "on" ++ if "error: failed to get domain" in line.strip() and options.has_key("missing_as_off"): ++ return "off" + if "error:" in line.strip(): + fail_usage("Failed: You have to enter existing name/UUID of virtual machine!") + +@@ -68,7 +70,7 @@ def set_power_status(conn, options): + time.sleep(int(options["--power-wait"])) + + def main(): +- device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "sudo"] ++ device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "sudo", "missing_as_off"] + + atexit.register(atexit_handler) + +diff --git a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml +index 642c72e..d664fc4 100644 +--- a/tests/data/metadata/fence_virsh.xml ++++ b/tests/data/metadata/fence_virsh.xml +@@ -105,6 +105,11 @@ By default, virsh needs root account to do properly work. So you must allow ssh + + Wait X seconds for cmd prompt after login + ++ ++ ++ ++ Missing port returns OFF instead of failure ++ + + + diff --git a/SOURCES/bz1254821-fence_virsh-missing-as-off-2.patch b/SOURCES/bz1254821-fence_virsh-missing-as-off-2.patch new file mode 100644 index 0000000..a5cd1b3 --- /dev/null +++ b/SOURCES/bz1254821-fence_virsh-missing-as-off-2.patch @@ -0,0 +1,23 @@ +From adfc26aeeeeb65d5f66debd2283cf8690827d48f Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 19 Aug 2015 15:41:58 +0200 +Subject: [PATCH] fence_virsh: Fix --missing-as-off + +Patch 0aacfcf209c473ab4c1fff4de653a673b92484de was pushed unintentionally before tests were done. +--- + fence/agents/virsh/fence_virsh.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py +index 24d360c..643f31f 100644 +--- a/fence/agents/virsh/fence_virsh.py ++++ b/fence/agents/virsh/fence_virsh.py +@@ -54,7 +54,7 @@ def get_power_status(conn, options): + for line in conn.before.splitlines(): + if line.strip() in ["running", "blocked", "idle", "no state", "paused"]: + return "on" +- if "error: failed to get domain" in line.strip() and options.has_key("missing_as_off"): ++ if "error: failed to get domain" in line.strip() and options.has_key("--missing-as-off"): + return "off" + if "error:" in line.strip(): + fail_usage("Failed: You have to enter existing name/UUID of virtual machine!") diff --git a/SOURCES/bz1256908-fence_ilo-tls_negotiation.patch b/SOURCES/bz1256908-fence_ilo-tls_negotiation.patch new file mode 100644 index 0000000..f173727 --- /dev/null +++ b/SOURCES/bz1256908-fence_ilo-tls_negotiation.patch @@ -0,0 +1,36 @@ +commit 1fe05064d950c24b6bb180170d314915c25331ec +Author: Marek 'marx' Grac +Date: Wed Aug 26 16:24:30 2015 +0200 + + fence_ilo: If gnutls can not open connection than --tls1.0 is tried in second attempt + + Resolves: rhbz#1256908 + +diff --git a/fence/agents/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py +index 047040b..d52b7a7 100644 +--- a/fence/agents/ilo/fence_ilo.py ++++ b/fence/agents/ilo/fence_ilo.py +@@ -95,6 +95,23 @@ the iLO card through an XML stream." + try: + conn.send("\r\n") + conn.log_expect(options, ["", ""], int(options["--login-timeout"])) ++ except pexpect.TIMEOUT: ++ fail(EC_LOGIN_DENIED) ++ except pexpect.EOF: ++ if "--tls1.0" in options: ++ fail(EC_LOGIN_DENIED) ++ options["--tls1.0"] = "1" ++ conn.close() ++ conn = fence_login(options) ++ try: ++ conn.send("\r\n") ++ conn.log_expect(options, ["", ""], int(options["--login-timeout"])) ++ except pexpect.TIMEOUT: ++ fail(EC_LOGIN_DENIED) ++ except pexpect.EOF: ++ fail(EC_LOGIN_DENIED) ++ ++ try: + version = re.compile(" +Date: Wed, 2 Sep 2015 14:35:23 +0200 +Subject: [PATCH 1/3] fence_ipmilan: Restore deprecated option -i which is + alias to -a / --ip + +Resolves: rhbz#1257137 +--- + fence/agents/ipmilan/fence_ipmilan.py | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py +index 8490837..8224b83 100644 +--- a/fence/agents/ipmilan/fence_ipmilan.py ++++ b/fence/agents/ipmilan/fence_ipmilan.py +@@ -119,12 +119,18 @@ def define_new_opts(): + "default" : "@IPMITOOL_PATH@", + "order": 200 + } ++ all_opt["obsolete_ip"] = { ++ "getopt" : "i:", ++ "longopt" : "obsolete-ip", ++ "help" : "", ++ "order" : 1 ++ } + + def main(): + atexit.register(atexit_handler) + +- device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd", +- "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method"] ++ device_opt = ["ipaddr", "ipport", "login", "no_login", "no_password", "passwd", ++ "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method", "obsolete_ip"] + define_new_opts() + + if os.path.basename(sys.argv[0]) == "fence_ilo3": +@@ -136,7 +142,11 @@ def main(): + + all_opt["ipport"]["default"] = "623" + +- options = check_input(device_opt, process_input(device_opt)) ++ pi = process_input(device_opt) ++ # Accept also deprecated option but do not propagate it at all ++ if "--obsolete-ip" in pi: ++ pi["--ip"] = pi["--obsolete-ip"] ++ options = check_input(device_opt, pi) + + docs = {} + docs["shortdesc"] = "Fence agent for IPMI" +-- +1.9.3 + diff --git a/SOURCES/bz1257137-2-fence_ipmilan_regression.patch b/SOURCES/bz1257137-2-fence_ipmilan_regression.patch new file mode 100644 index 0000000..03cd96f --- /dev/null +++ b/SOURCES/bz1257137-2-fence_ipmilan_regression.patch @@ -0,0 +1,325 @@ +From 4b06b842e57f80bda87ec57b9e0e047fe89ad25f Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 26 Aug 2015 12:54:47 +0200 +Subject: [PATCH 2/3] fence_ipmilan: Re-introduce -t / timeout option + +In the new fence agent this option was replaced by --*-timeout but old +option should work as before. It sets all *-timeout to a value 'timeout' + +Resolves: rhbz#1257137 +--- + fence/agents/ipmilan/fence_ipmilan.py | 16 +++++++++++++++- + tests/data/metadata/fence_idrac.xml | 23 ++++++++++++++--------- + tests/data/metadata/fence_ilo3.xml | 23 ++++++++++++++--------- + tests/data/metadata/fence_ilo4.xml | 23 ++++++++++++++--------- + tests/data/metadata/fence_imm.xml | 23 ++++++++++++++--------- + tests/data/metadata/fence_ipmilan.xml | 23 ++++++++++++++--------- + 6 files changed, 85 insertions(+), 46 deletions(-) + +diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py +index 8224b83..fd04110 100644 +--- a/fence/agents/ipmilan/fence_ipmilan.py ++++ b/fence/agents/ipmilan/fence_ipmilan.py +@@ -125,12 +125,21 @@ def define_new_opts(): + "help" : "", + "order" : 1 + } ++ all_opt["timeout"] = { ++ "getopt" : "t:", ++ "longopt" : "timeout", ++ "help" : "-t [seconds] Timeout (sec) for IPMI operation", ++ "required" : "0", ++ "shortdesc" : "Timeout (sec) for IPMI operation", ++ "order" : 1 ++ } + + def main(): + atexit.register(atexit_handler) + + device_opt = ["ipaddr", "ipport", "login", "no_login", "no_password", "passwd", +- "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method", "obsolete_ip"] ++ "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method", ++ "obsolete_ip", "timeout"] + define_new_opts() + + if os.path.basename(sys.argv[0]) == "fence_ilo3": +@@ -148,6 +157,11 @@ def main(): + pi["--ip"] = pi["--obsolete-ip"] + options = check_input(device_opt, pi) + ++ if "--timeout" in options: ++ options["--shell-timeout"] = options["--timeout"] ++ options["--power-timeout"] = options["--timeout"] ++ options["--login-timeout"] = options["--timeout"] ++ + docs = {} + docs["shortdesc"] = "Fence agent for IPMI" + docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent\ +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index 0aced2a..6e0b834 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -64,6 +64,11 @@ + + IPMI Lan Auth type. + ++ ++ ++ ++ Fencing Action ++ + + + +@@ -79,10 +84,10 @@ + + Privilege level on IPMI device + +- +- +- +- Fencing Action ++ ++ ++ ++ Timeout (sec) for IPMI operation + + + +@@ -119,16 +124,16 @@ + + Wait X seconds for cmd prompt after login + +- +- +- +- Test X seconds for status change after ON/OFF +- + + + + Wait X seconds before fencing is started + ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ + + + +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index 67e869b..1253539 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -64,6 +64,11 @@ + + IPMI Lan Auth type. + ++ ++ ++ ++ Fencing Action ++ + + + +@@ -79,10 +84,10 @@ + + Privilege level on IPMI device + +- +- +- +- Fencing Action ++ ++ ++ ++ Timeout (sec) for IPMI operation + + + +@@ -119,16 +124,16 @@ + + Wait X seconds for cmd prompt after login + +- +- +- +- Test X seconds for status change after ON/OFF +- + + + + Wait X seconds before fencing is started + ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ + + + +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index b7dd31a..6498be8 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -64,6 +64,11 @@ + + IPMI Lan Auth type. + ++ ++ ++ ++ Fencing Action ++ + + + +@@ -79,10 +84,10 @@ + + Privilege level on IPMI device + +- +- +- +- Fencing Action ++ ++ ++ ++ Timeout (sec) for IPMI operation + + + +@@ -119,16 +124,16 @@ + + Wait X seconds for cmd prompt after login + +- +- +- +- Test X seconds for status change after ON/OFF +- + + + + Wait X seconds before fencing is started + ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ + + + +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index 0e7588d..e6d67bc 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -64,6 +64,11 @@ + + IPMI Lan Auth type. + ++ ++ ++ ++ Fencing Action ++ + + + +@@ -79,10 +84,10 @@ + + Privilege level on IPMI device + +- +- +- +- Fencing Action ++ ++ ++ ++ Timeout (sec) for IPMI operation + + + +@@ -119,16 +124,16 @@ + + Wait X seconds for cmd prompt after login + +- +- +- +- Test X seconds for status change after ON/OFF +- + + + + Wait X seconds before fencing is started + ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ + + + +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index 443365c..97edfbb 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -64,6 +64,11 @@ + + IPMI Lan Auth type. + ++ ++ ++ ++ Fencing Action ++ + + + +@@ -79,10 +84,10 @@ + + Privilege level on IPMI device + +- +- +- +- Fencing Action ++ ++ ++ ++ Timeout (sec) for IPMI operation + + + +@@ -119,16 +124,16 @@ + + Wait X seconds for cmd prompt after login + +- +- +- +- Test X seconds for status change after ON/OFF +- + + + + Wait X seconds before fencing is started + ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ + + + +-- +1.9.3 + diff --git a/SOURCES/bz1257137-3-fence_ipmilan_regression.patch b/SOURCES/bz1257137-3-fence_ipmilan_regression.patch new file mode 100644 index 0000000..8791b2d --- /dev/null +++ b/SOURCES/bz1257137-3-fence_ipmilan_regression.patch @@ -0,0 +1,26 @@ +From 4dfb294646685e0e920b485b1fce2c6441918c19 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 17 Sep 2015 23:24:28 +0200 +Subject: [PATCH] fence_ipmilan: -i was used twice in fence_ipmilan + +-i was not propagated as --ipmitool-path so we have removed it. +--- + fence/agents/ipmilan/fence_ipmilan.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py +index fd04110..4c9eea8 100644 +--- a/fence/agents/ipmilan/fence_ipmilan.py ++++ b/fence/agents/ipmilan/fence_ipmilan.py +@@ -111,7 +111,7 @@ def define_new_opts(): + "order": 1 + } + all_opt["ipmitool_path"] = { +- "getopt" : "i:", ++ "getopt" : ":", + "longopt" : "ipmitool-path", + "help" : "--ipmitool-path=[path] Path to ipmitool binary", + "required" : "0", +-- +1.9.3 + diff --git a/SOURCES/bz1259319-fence_apc_v6.patch b/SOURCES/bz1259319-fence_apc_v6.patch new file mode 100644 index 0000000..2fcbcdc --- /dev/null +++ b/SOURCES/bz1259319-fence_apc_v6.patch @@ -0,0 +1,44 @@ +From ea8cc4949d562b75822d9362808cf3d333fb6d92 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 14 Sep 2015 13:27:45 +0200 +Subject: [PATCH] fence_apc: Support for v6.x firmware + +There are no changes in interface, so it is enough to accept new version number. +Login process over telnet has changed a bit and autodection of EOL did not work properly. Relevant part +of changed so it work correctly when after empty 'User Name', the device ask for it again. + +Resolves: rhbz#1259319 +--- + fence/agents/apc/fence_apc.py | 2 +- + fence/agents/lib/fencing.py.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py +index 83bfe07..b77d36e 100644 +--- a/fence/agents/apc/fence_apc.py ++++ b/fence/agents/apc/fence_apc.py +@@ -247,7 +247,7 @@ will block any necessary fencing actions." + #### + result = -1 + firmware_version = re.compile(r'\s*v(\d)*\.').search(conn.before) +- if (firmware_version != None) and (firmware_version.group(1) == "5"): ++ if (firmware_version != None) and (firmware_version.group(1) in [ "5", "6" ]): + result = fence_action(conn, options, set_power_status5, get_power_status5, get_power_status5) + else: + result = fence_action(conn, options, set_power_status, get_power_status, get_power_status) +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 7fddc47..fe602a5 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -1153,7 +1153,7 @@ def fence_login(options, re_login_string=r"(login\s*: )|(Login Name: )|(usernam + conn.send_eol("") + screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"])) + ## after sending EOL the fence device can either show 'Login' or 'Password' +- if re_login.search(screen) != None: ++ if re_login.search(conn.after + screen) != None: + conn.send_eol("") + conn.send_eol(options["--username"]) + conn.log_expect(options, re_pass, int(options["--login-timeout"])) +-- +2.4.3 + diff --git a/SOURCES/bz1265426-1-fence_scsi_hard.patch b/SOURCES/bz1265426-1-fence_scsi_hard.patch new file mode 100644 index 0000000..4d57484 --- /dev/null +++ b/SOURCES/bz1265426-1-fence_scsi_hard.patch @@ -0,0 +1,51 @@ +From 8cd85ba88193f9cdb0c933ba9f7261f1c3631868 Mon Sep 17 00:00:00 2001 +From: John Ruemker +Date: Tue, 22 Sep 2015 17:52:56 -0400 +Subject: [PATCH 1/4] fence_scsi: Reset device prior to all uses of sg_persist + +Currently the agent will reset prior to several areas where it runs +sg_persist, to clear out any "Unit Attention" conditions that could +otherwise cause the sg_persist command to report failures. However +several paths remain that could fail if a "Unit Attention" condition +exist, so we should reset before any use of sg_persist. +--- + fence/agents/scsi/fence_scsi.py | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index e18e473..8680828 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -125,6 +125,7 @@ def is_block_device(dev): + + # cancel registration + def preempt_abort(options, host, dev): ++ reset_dev(options,dev) + cmd = options["--sg_persist-path"] + " -n -o -A -T 5 -K " + host + " -S " + options["--key"] + " -d " + dev + return not bool(run_cmd(options, cmd)["err"]) + +@@ -147,11 +148,13 @@ def register_dev(options, dev): + + + def reserve_dev(options, dev): ++ reset_dev(options,dev) + cmd = options["--sg_persist-path"] + " -n -o -R -T 5 -K " + options["--key"] + " -d " + dev + return not bool(run_cmd(options, cmd)["err"]) + + + def get_reservation_key(options, dev): ++ reset_dev(options,dev) + cmd = options["--sg_persist-path"] + " -n -i -r -d " + dev + out = run_cmd(options, cmd) + if out["err"]: +@@ -161,6 +164,7 @@ def get_reservation_key(options, dev): + + + def get_registration_keys(options, dev): ++ reset_dev(options,dev) + keys = [] + cmd = options["--sg_persist-path"] + " -n -i -k -d " + dev + out = run_cmd(options, cmd) +-- +2.4.3 + diff --git a/SOURCES/bz1265426-2-fence_scsi_hard.patch b/SOURCES/bz1265426-2-fence_scsi_hard.patch new file mode 100644 index 0000000..df7b1d9 --- /dev/null +++ b/SOURCES/bz1265426-2-fence_scsi_hard.patch @@ -0,0 +1,52 @@ +From 5c8cf5613f9371b53d1aab6f97db99bdbf9db4b4 Mon Sep 17 00:00:00 2001 +From: John Ruemker +Date: Tue, 22 Sep 2015 18:02:37 -0400 +Subject: [PATCH 2/4] fence_scsi: Offer hard-reboot option for fence_scsi_check + script + +The existing implementation of fence_scsi_check returns an error if any +device is no longer registered properly, and this error return causes +watchdog to use its custom procedure to reboot the host. This procedure +is prone to blocking, especially when GFS2 file systems are mounted or +multipath devices are configured to queue indefinitely, so having the +check be able to hard-reboot the host instead of returning a failure +gives a means for avoiding these blockages. +--- + fence/agents/scsi/fence_scsi.py | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index 8680828..ff34721 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -379,7 +379,7 @@ def scsi_check_get_verbose(): + return bool(match) + + +-def scsi_check(): ++def scsi_check(hardreboot=False): + if len(sys.argv) >= 3 and sys.argv[1] == "repair": + return int(sys.argv[2]) + options = {} +@@ -403,6 +403,9 @@ def scsi_check(): + else: + logging.debug("key " + key + " not registered with device " + dev) + logging.debug("key " + key + " registered with any devices") ++ ++ if hardreboot == True: ++ os.system("reboot -f") + return 2 + + +@@ -423,6 +426,8 @@ def main(): + #fence_scsi_check + if os.path.basename(sys.argv[0]) == "fence_scsi_check.pl": + sys.exit(scsi_check()) ++ elif os.path.basename(sys.argv[0]) == "fence_scsi_check_hardreboot": ++ sys.exit(scsi_check(True)) + + options = check_input(device_opt, process_input(device_opt)) + +-- +2.4.3 + diff --git a/SOURCES/bz1265426-3-fence_scsi_hard.patch b/SOURCES/bz1265426-3-fence_scsi_hard.patch new file mode 100644 index 0000000..ce8cea7 --- /dev/null +++ b/SOURCES/bz1265426-3-fence_scsi_hard.patch @@ -0,0 +1,57 @@ +From c4de19f19121ee44cd9ffb4a307f386ea2b13efc Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Fri, 25 Sep 2015 11:14:08 +0200 +Subject: [PATCH 3/4] fence_scsi: Install fence_scsi_check_hardreboot and + fence_scsi_check + +--- + fence/agents/scsi/Makefile.am | 10 ++++++++-- + fence/agents/scsi/fence_scsi.py | 2 ++ + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/scsi/Makefile.am b/fence/agents/scsi/Makefile.am +index 5315215..ad65d1b 100644 +--- a/fence/agents/scsi/Makefile.am ++++ b/fence/agents/scsi/Makefile.am +@@ -7,7 +7,7 @@ SRC = $(TARGET).py + EXTRA_DIST = $(SRC) + + scsidatadir = $(CLUSTERDATA) +-scsidata_SCRIPTS = fence_scsi_check.pl ++scsidata_SCRIPTS = fence_scsi_check fence_scsi_check_hardreboot fence_scsi_check.pl + + sbin_SCRIPTS = $(TARGET) + +@@ -18,9 +18,15 @@ FENCE_TEST_ARGS = -k 1 + fence_scsi_check.pl: $(TARGET) + cp $^ $@ + ++fence_scsi_check: $(TARGET) ++ cp $^ $@ ++ ++fence_scsi_check_hardreboot: $(TARGET) ++ cp $^ $@ ++ + include $(top_srcdir)/make/fencebuild.mk + include $(top_srcdir)/make/fenceman.mk + include $(top_srcdir)/make/agentpycheck.mk + + clean-local: clean-man +- rm -f $(TARGET) $(SYMTARGET) fence_scsi_check.pl ++ rm -f $(TARGET) $(SYMTARGET) $(scsidata_SCRIPTS) +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index ff34721..c13d4ed 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -426,6 +426,8 @@ def main(): + #fence_scsi_check + if os.path.basename(sys.argv[0]) == "fence_scsi_check.pl": + sys.exit(scsi_check()) ++ elif os.path.basename(sys.argv[0]) == "fence_scsi_check": ++ sys.exit(scsi_check()) + elif os.path.basename(sys.argv[0]) == "fence_scsi_check_hardreboot": + sys.exit(scsi_check(True)) + +-- +2.4.3 + diff --git a/SOURCES/bz1265426-4-fence_scsi_hard.patch b/SOURCES/bz1265426-4-fence_scsi_hard.patch new file mode 100644 index 0000000..4c6a176 --- /dev/null +++ b/SOURCES/bz1265426-4-fence_scsi_hard.patch @@ -0,0 +1,34 @@ +From 463e5bcc58e7c9d49033d0427bdcbc263cf98165 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 16 Dec 2015 13:46:23 +0100 +Subject: [PATCH 4/4] fence_scsi: Replace hard reboot with direct call to libc + +--- + fence/agents/scsi/fence_scsi.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index c13d4ed..11eab73 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -8,6 +8,7 @@ import time + import logging + import atexit + import hashlib ++import ctypes + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import fail_usage, run_command, atexit_handler, check_input, process_input, show_docs, fence_action, all_opt + from fencing import run_delay +@@ -405,7 +406,8 @@ def scsi_check(hardreboot=False): + logging.debug("key " + key + " registered with any devices") + + if hardreboot == True: +- os.system("reboot -f") ++ libc = ctypes.cdll['libc.so.6'] ++ libc.reboot(0x1234567) + return 2 + + +-- +2.4.3 + diff --git a/SOURCES/bz1271780-fence_ipmilan-cycle-report-success-before-powered-off.patch b/SOURCES/bz1271780-fence_ipmilan-cycle-report-success-before-powered-off.patch new file mode 100644 index 0000000..5261ca2 --- /dev/null +++ b/SOURCES/bz1271780-fence_ipmilan-cycle-report-success-before-powered-off.patch @@ -0,0 +1,84 @@ +diff -uNr a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py +--- a/fence/agents/ipmilan/fence_ipmilan.py 2016-05-25 12:13:22.089965297 +0200 ++++ b/fence/agents/ipmilan/fence_ipmilan.py 2016-05-25 12:13:45.266723891 +0200 +@@ -155,6 +155,9 @@ + all_opt["lanplus"]["default"] = "1" + + all_opt["ipport"]["default"] = "623" ++ all_opt["method"]["help"] = "-m, --method=[method] Method to fence (onoff|cycle) (Default: cycle)\n" \ ++ "WARNING! This fence agent might report success before the node is powered off. " \ ++ "You should use -m/method onoff if your fence device works correctly with that option." + + pi = process_input(device_opt) + # Accept also deprecated option but do not propagate it at all +@@ -171,7 +174,9 @@ + docs["shortdesc"] = "Fence agent for IPMI" + docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent\ + which can be used with machines controlled by IPMI.\ +-This agent calls support software ipmitool (http://ipmitool.sf.net/)." ++This agent calls support software ipmitool (http://ipmitool.sf.net/). \ ++WARNING! This fence agent might report success before the node is powered off. \ ++You should use -m/method onoff if your fence device works correctly with that option." + docs["vendorurl"] = "" + docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"), + ("fence_ilo4", "Fence agent for HP iLO4"), +diff -uNr a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +--- a/tests/data/metadata/fence_idrac.xml 2016-05-25 12:13:22.089965297 +0200 ++++ b/tests/data/metadata/fence_idrac.xml 2016-05-25 12:13:45.267723880 +0200 +@@ -4,7 +4,7 @@ + + + +-fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). ++fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option. + + + +diff -uNr a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +--- a/tests/data/metadata/fence_ilo3.xml 2016-05-25 12:13:22.089965297 +0200 ++++ b/tests/data/metadata/fence_ilo3.xml 2016-05-25 12:13:45.267723880 +0200 +@@ -4,7 +4,7 @@ + + + +-fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). ++fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option. + + + +diff -uNr a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +--- a/tests/data/metadata/fence_ilo4.xml 2016-05-25 12:13:22.090965287 +0200 ++++ b/tests/data/metadata/fence_ilo4.xml 2016-05-25 12:13:45.268723870 +0200 +@@ -4,7 +4,7 @@ + + + +-fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). ++fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option. + + + +diff -uNr a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +--- a/tests/data/metadata/fence_imm.xml 2016-05-25 12:13:22.090965287 +0200 ++++ b/tests/data/metadata/fence_imm.xml 2016-05-25 12:13:45.268723870 +0200 +@@ -4,7 +4,7 @@ + + + +-fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). ++fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option. + + + +diff -uNr a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +--- a/tests/data/metadata/fence_ipmilan.xml 2016-05-25 12:13:22.090965287 +0200 ++++ b/tests/data/metadata/fence_ipmilan.xml 2016-05-25 12:13:45.268723870 +0200 +@@ -4,7 +4,7 @@ + + + +-fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). ++fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option. + + + diff --git a/SOURCES/bz1274432-fence_brocade-fix_incorrect_return.patch b/SOURCES/bz1274432-fence_brocade-fix_incorrect_return.patch new file mode 100644 index 0000000..44ee2ce --- /dev/null +++ b/SOURCES/bz1274432-fence_brocade-fix_incorrect_return.patch @@ -0,0 +1,26 @@ +From 43b32a3bc37e49c9e5e4a68228e6dc845c79a2c4 Mon Sep 17 00:00:00 2001 +From: John Ruemker +Date: Thu, 22 Oct 2015 13:30:42 -0400 +Subject: [PATCH 2/2] fence_brocade: Fix incorrect return when getting status + for "on", "off" + +--- + fence/agents/brocade/fence_brocade.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/brocade/fence_brocade.py b/fence/agents/brocade/fence_brocade.py +index e5a5063..5257bcc 100644 +--- a/fence/agents/brocade/fence_brocade.py ++++ b/fence/agents/brocade/fence_brocade.py +@@ -36,7 +36,7 @@ def get_power_status(conn, options): + status = "off" if len(tokens) > 7 and tokens[7] == "Disabled" else "on" + outlets[tokens[0]] = ("", status) + +- if options["--action"] == "status": ++ if ["list", "monitor"].count(options["--action"]) == 0: + (_, status) = outlets[options["--plug"]] + return status + else: +-- +2.4.3 + diff --git a/SOURCES/bz1275250-fence_ipmilan-fix-power_wait-regression.patch b/SOURCES/bz1275250-fence_ipmilan-fix-power_wait-regression.patch new file mode 100644 index 0000000..edcd270 --- /dev/null +++ b/SOURCES/bz1275250-fence_ipmilan-fix-power_wait-regression.patch @@ -0,0 +1,59 @@ +diff -uNr a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py +--- a/fence/agents/ipmilan/fence_ipmilan.py 2016-05-25 12:09:14.065548692 +0200 ++++ b/fence/agents/ipmilan/fence_ipmilan.py 2016-05-25 12:11:29.626136708 +0200 +@@ -142,6 +142,7 @@ + "obsolete_ip", "timeout"] + define_new_opts() + ++ all_opt["power_wait"]["default"] = 2 + if os.path.basename(sys.argv[0]) == "fence_ilo3": + all_opt["power_wait"]["default"] = "4" + all_opt["method"]["default"] = "cycle" +diff -uNr a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +--- a/tests/data/metadata/fence_idrac.xml 2016-05-25 12:09:14.062548723 +0200 ++++ b/tests/data/metadata/fence_idrac.xml 2016-05-25 12:11:29.627136697 +0200 +@@ -116,7 +116,7 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + +diff -uNr a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +--- a/tests/data/metadata/fence_ilo4.xml 2016-05-25 12:09:14.063548713 +0200 ++++ b/tests/data/metadata/fence_ilo4.xml 2016-05-25 12:11:29.627136697 +0200 +@@ -116,7 +116,7 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + +diff -uNr a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +--- a/tests/data/metadata/fence_imm.xml 2016-05-25 12:09:14.063548713 +0200 ++++ b/tests/data/metadata/fence_imm.xml 2016-05-25 12:11:29.627136697 +0200 +@@ -116,7 +116,7 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + +diff -uNr a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +--- a/tests/data/metadata/fence_ipmilan.xml 2016-05-25 12:09:14.063548713 +0200 ++++ b/tests/data/metadata/fence_ipmilan.xml 2016-05-25 12:11:29.627136697 +0200 +@@ -116,7 +116,7 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + diff --git a/SOURCES/bz1280139-fence_scsi-fix-persistentl-typo-in-short-desc.patch b/SOURCES/bz1280139-fence_scsi-fix-persistentl-typo-in-short-desc.patch new file mode 100644 index 0000000..91e3ee4 --- /dev/null +++ b/SOURCES/bz1280139-fence_scsi-fix-persistentl-typo-in-short-desc.patch @@ -0,0 +1,37 @@ +From 3648a9fefcbd91069f6f5f63fb16b215e82d652a Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Thu, 28 Jan 2016 14:43:30 +0100 +Subject: [PATCH] fence_scsi: fix "persistentl" typo in short desc + +--- + fence/agents/scsi/fence_scsi.py | 2 +- + tests/data/metadata/fence_scsi.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index 11eab73..6708de1 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -436,7 +436,7 @@ def main(): + options = check_input(device_opt, process_input(device_opt)) + + docs = {} +- docs["shortdesc"] = "Fence agent for SCSI persistentl reservation" ++ docs["shortdesc"] = "Fence agent for SCSI persistent reservation" + docs["longdesc"] = "fence_scsi is an I/O fencing agent that uses SCSI-3 \ + persistent reservations to control access to shared storage devices. These \ + devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ +diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +index d370e36..a80f1ef 100644 +--- a/tests/data/metadata/fence_scsi.xml ++++ b/tests/data/metadata/fence_scsi.xml +@@ -1,5 +1,5 @@ + +- ++ + fence_scsi is an I/O fencing agent that uses SCSI-3 persistent reservations to control access to shared storage devices. These devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand. + The fence_scsi agent works by having each node in the cluster register a unique key with the SCSI devive(s). Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_scsi agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. + +-- +2.5.0 + diff --git a/SOURCES/bz1280151-1-fence_scsi-remove-dev-dm-X-reference.patch b/SOURCES/bz1280151-1-fence_scsi-remove-dev-dm-X-reference.patch new file mode 100644 index 0000000..37ca735 --- /dev/null +++ b/SOURCES/bz1280151-1-fence_scsi-remove-dev-dm-X-reference.patch @@ -0,0 +1,50 @@ +diff -uNr a/fence/agents/mpath/fence_mpath.py b/fence/agents/mpath/fence_mpath.py +--- a/fence/agents/mpath/fence_mpath.py 2016-05-25 12:41:55.491900397 +0200 ++++ b/fence/agents/mpath/fence_mpath.py 2016-05-25 12:42:37.704454037 +0200 +@@ -169,7 +169,7 @@ + "help" : "-d, --devices=[devices] List of devices to use for current operation", + "required" : "0", + "shortdesc" : "List of devices to use for current operation. Devices can \ +-be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). \ ++be comma-separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). \ + Each device must support SCSI-3 persistent reservations.", + "order": 1 + } +diff -uNr a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +--- a/fence/agents/scsi/fence_scsi.py 2016-05-25 12:41:55.517900122 +0200 ++++ b/fence/agents/scsi/fence_scsi.py 2016-05-25 12:42:37.704454037 +0200 +@@ -291,8 +291,8 @@ + "help" : "-d, --devices=[devices] List of devices to use for current operation", + "required" : "0", + "shortdesc" : "List of devices to use for current operation. Devices can \ +-be comma-separated list of raw device (eg. /dev/sdc) or device-mapper multipath \ +-devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations.", ++be comma-separated list of raw devices (eg. /dev/sdc). Each device must support SCSI-3 \ ++persistent reservations.", + "order": 1 + } + all_opt["nodename"] = { +diff -uNr a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +--- a/tests/data/metadata/fence_mpath.xml 2016-05-25 12:41:55.486900450 +0200 ++++ b/tests/data/metadata/fence_mpath.xml 2016-05-25 12:42:37.704454037 +0200 +@@ -7,7 +7,7 @@ + + + +- List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations. ++ List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). Each device must support SCSI-3 persistent reservations. + + + +diff -uNr a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +--- a/tests/data/metadata/fence_scsi.xml 2016-05-25 12:41:55.517900122 +0200 ++++ b/tests/data/metadata/fence_scsi.xml 2016-05-25 12:42:37.704454037 +0200 +@@ -27,7 +27,7 @@ + + + +- List of devices to use for current operation. Devices can be comma-separated list of raw device (eg. /dev/sdc) or device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations. ++ List of devices to use for current operation. Devices can be comma-separated list of raw devices (eg. /dev/sdc). Each device must support SCSI-3 persistent reservations. + + + diff --git a/SOURCES/bz1280151-2-fence_scsi-remove-dev-dm-X-reference.patch b/SOURCES/bz1280151-2-fence_scsi-remove-dev-dm-X-reference.patch new file mode 100644 index 0000000..f089065 --- /dev/null +++ b/SOURCES/bz1280151-2-fence_scsi-remove-dev-dm-X-reference.patch @@ -0,0 +1,76 @@ +From a2276448ed32ee75cc5dbf5efbc0c400c3ee518e Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Wed, 17 Aug 2016 09:38:10 +0200 +Subject: [PATCH 1/2] fence_mpath: update unique key info to say that it's per + node and not per node/device + +--- + fence/agents/mpath/fence_mpath.py | 4 ++-- + tests/data/metadata/fence_mpath.xml | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/fence/agents/mpath/fence_mpath.py b/fence/agents/mpath/fence_mpath.py +index 349225f..5426a18 100644 +--- a/fence/agents/mpath/fence_mpath.py ++++ b/fence/agents/mpath/fence_mpath.py +@@ -219,8 +219,8 @@ def main(): + persistent reservations to control access multipath devices. Underlying \ + devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ + well as the \"preempt-and-abort\" subcommand.\nThe fence_mpath agent works by \ +-having an unique key for each pair of node and device that has to be set also \ +-in /etc/multipath.conf. Once registered, a single node will become the reservation holder \ ++having a unique key for each node that has to be set in /etc/multipath.conf. \ ++Once registered, a single node will become the reservation holder \ + by creating a \"write exclusive, registrants only\" reservation on the \ + device(s). The result is that only registered nodes may write to the \ + device(s). When a node failure occurs, the fence_mpath agent will remove the \ +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +index 6442354..5a31b98 100644 +--- a/tests/data/metadata/fence_mpath.xml ++++ b/tests/data/metadata/fence_mpath.xml +@@ -1,7 +1,7 @@ + + + fence_mpath is an I/O fencing agent that uses SCSI-3 persistent reservations to control access multipath devices. Underlying devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand. +-The fence_mpath agent works by having an unique key for each pair of node and device that has to be set also in /etc/multipath.conf. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_mpath agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. ++The fence_mpath agent works by having a unique key for each node that has to be set in /etc/multipath.conf. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_mpath agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. + https://www.sourceware.org/dm/ + + + +From 2f7285536550b71672ed1fbeaffb780d62c9fb24 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Wed, 17 Aug 2016 10:03:16 +0200 +Subject: [PATCH 2/2] fence_scsi: correct 'devive(s)' typo + +--- + fence/agents/scsi/fence_scsi.py | 2 +- + tests/data/metadata/fence_scsi.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +index d572ca3..37ff1d3 100644 +--- a/fence/agents/scsi/fence_scsi.py ++++ b/fence/agents/scsi/fence_scsi.py +@@ -438,7 +438,7 @@ def main(): + devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ + well as the \"preempt-and-abort\" subcommand.\nThe fence_scsi agent works by \ + having each node in the cluster register a unique key with the SCSI \ +-devive(s). Once registered, a single node will become the reservation holder \ ++device(s). Once registered, a single node will become the reservation holder \ + by creating a \"write exclusive, registrants only\" reservation on the \ + device(s). The result is that only registered nodes may write to the \ + device(s). When a node failure occurs, the fence_scsi agent will remove the \ +diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +index bb6f80b..7b59df5 100644 +--- a/tests/data/metadata/fence_scsi.xml ++++ b/tests/data/metadata/fence_scsi.xml +@@ -1,7 +1,7 @@ + + + fence_scsi is an I/O fencing agent that uses SCSI-3 persistent reservations to control access to shared storage devices. These devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand. +-The fence_scsi agent works by having each node in the cluster register a unique key with the SCSI devive(s). Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_scsi agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. ++The fence_scsi agent works by having each node in the cluster register a unique key with the SCSI device(s). Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_scsi agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. + + + diff --git a/SOURCES/bz1283084-fence_compute.patch b/SOURCES/bz1283084-fence_compute.patch new file mode 100644 index 0000000..f3671a7 --- /dev/null +++ b/SOURCES/bz1283084-fence_compute.patch @@ -0,0 +1,347 @@ +From e80e142092c53102a46886e9748b8e25465ce4f6 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 20 Jan 2016 11:32:21 +0100 +Subject: [PATCH] fence_compute: Sync with master branch + +--- + fence/agents/compute/fence_compute.py | 180 ++++++++++++++++++++++++++-------- + tests/data/metadata/fence_compute.xml | 16 +-- + 2 files changed, 150 insertions(+), 46 deletions(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index 82d9c46..d9fe54a 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -19,6 +19,9 @@ REDHAT_COPYRIGHT="Copyright (C) Red Hat, Inc. 2004-2010 All rights reserved." + override_status = "" + nova = None + ++EVACUABLE_TAG = "evacuable" ++TRUE_TAGS = ['true'] ++ + def get_power_status(_, options): + global override_status + +@@ -32,8 +35,8 @@ def get_power_status(_, options): + if nova: + try: + services = nova.services.list(host=options["--plug"]) +- + for service in services: ++ logging.debug("Status of %s is %s" % (service.binary, service.state)) + if service.binary == "nova-compute": + if service.state == "up": + status = "on" +@@ -49,31 +52,91 @@ def get_power_status(_, options): + # NOTE(sbauza); We mimic the host-evacuate module since it's only a contrib + # module which is not stable + def _server_evacuate(server, on_shared_storage): +- success = True ++ success = False + error_message = "" + try: +- nova.servers.evacuate(server=server['uuid'], on_shared_storage=on_shared_storage) ++ logging.debug("Resurrecting instance: %s" % server) ++ (response, dictionary) = nova.servers.evacuate(server=server, on_shared_storage=on_shared_storage) ++ ++ if response == None: ++ error_message = "No response while evacuating instance" ++ elif response.status_code == 200: ++ success = True ++ error_message = response.reason ++ else: ++ error_message = response.reason ++ + except Exception as e: +- success = False + error_message = "Error while evacuating instance: %s" % e + + return { +- "server_uuid": server['uuid'], +- "evacuate_accepted": success, +- "error_message": error_message, ++ "uuid": server, ++ "accepted": success, ++ "reason": error_message, + } + +-def _host_evacuate(host, on_shared_storage): +- hypervisors = nova.hypervisors.search(host, servers=True) +- response = [] +- for hyper in hypervisors: +- if hasattr(hyper, 'servers'): +- for server in hyper.servers: +- response.append(_server_evacuate(server, on_shared_storage)) ++def _is_server_evacuable(server, evac_flavors, evac_images): ++ if server.flavor.get('id') in evac_flavors: ++ return True ++ if server.image.get('id') in evac_images: ++ return True ++ return False ++ ++def _get_evacuable_flavors(): ++ result = [] ++ flavors = nova.flavors.list() ++ # Since the detailed view for all flavors doesn't provide the extra specs, ++ # we need to call each of the flavor to get them. ++ for flavor in flavors: ++ if flavor.get_keys().get(EVACUABLE_TAG).strip().lower() in TRUE_TAGS: ++ result.append(flavor.id) ++ return result ++ ++def _get_evacuable_images(): ++ result = [] ++ images = nova.images.list(detailed=True) ++ for image in images: ++ if hasattr(image, 'metadata'): ++ if image.metadata.get(EVACUABLE_TAG).strip.lower() in TRUE_TAGS: ++ result.append(image.id) ++ return result ++ ++def _host_evacuate(options): ++ result = True ++ servers = nova.servers.list(search_opts={'host': options["--plug"]}) ++ if options["--instance-filtering"] == "False": ++ evacuables = servers ++ else: ++ flavors = _get_evacuable_flavors() ++ images = _get_evacuable_images() ++ # Identify all evacuable servers ++ evacuables = [server for server in servers ++ if _is_server_evacuable(server, flavors, images)] ++ ++ if options["--no-shared-storage"] != "False": ++ on_shared_storage = False ++ else: ++ on_shared_storage = True ++ ++ for server in evacuables: ++ if hasattr(server, 'id'): ++ response = _server_evacuate(server.id, on_shared_storage) ++ if response["accepted"]: ++ logging.debug("Evacuated %s from %s: %s" % ++ (response["uuid"], options["--plug"], response["reason"])) ++ else: ++ logging.error("Evacuation of %s on %s failed: %s" % ++ (response["uuid"], options["--plug"], response["reason"])) ++ result = False ++ else: ++ logging.error("Could not evacuate instance: %s" % server.to_dict()) ++ # Should a malformed instance result in a failed evacuation? ++ # result = False ++ return result + + def set_attrd_status(host, status, options): + logging.debug("Setting fencing status for %s to %s" % (host, status)) +- run_command(options, "attrd_updater -p -n evacute -Q -N %s -v %s" % (host, status)) ++ run_command(options, "attrd_updater -p -n evacuate -Q -N %s -U %s" % (host, status)) + + def set_power_status(_, options): + global override_status +@@ -86,28 +149,53 @@ def set_power_status(_, options): + + if options["--action"] == "on": + if get_power_status(_, options) == "on": ++ # Forcing the service back up in case it was disabled + nova.services.enable(options["--plug"], 'nova-compute') ++ try: ++ # Forcing the host back up ++ nova.services.force_down( ++ options["--plug"], "nova-compute", force_down=False) ++ except Exception as e: ++ # In theory, if foce_down=False fails, that's for the exact ++ # same possible reasons that below with force_down=True ++ # eg. either an incompatible version or an old client. ++ # Since it's about forcing back to a default value, there is ++ # no real worries to just consider it's still okay even if the ++ # command failed ++ logging.info("Exception from attempt to force " ++ "host back up via nova API: " ++ "%s: %s" % (e.__class__.__name__, e)) + else: + # Pretend we're 'on' so that the fencing library doesn't loop forever waiting for the node to boot + override_status = "on" + return + +- # need to wait for nova to update its internal status or we +- # cannot call host-evacuate +- while get_power_status(_, options) != "off": +- # Loop forever if need be. +- # +- # Some callers (such as Pacemaker) will have a timer +- # running and kill us if necessary +- logging.debug("Waiting for nova to update it's internal state") +- time.sleep(1) +- +- if options["--no-shared-storage"] != "False": +- on_shared_storage = False +- else: +- on_shared_storage = True ++ try: ++ nova.services.force_down( ++ options["--plug"], "nova-compute", force_down=True) ++ except Exception as e: ++ # Something went wrong when we tried to force the host down. ++ # That could come from either an incompatible API version ++ # eg. UnsupportedVersion or VersionNotFoundForAPIMethod ++ # or because novaclient is old and doesn't include force_down yet ++ # eg. AttributeError ++ # In that case, fallbacking to wait for Nova to catch the right state. ++ ++ logging.error("Exception from attempt to force host down via nova API: " ++ "%s: %s" % (e.__class__.__name__, e)) ++ # need to wait for nova to update its internal status or we ++ # cannot call host-evacuate ++ while get_power_status(_, options) != "off": ++ # Loop forever if need be. ++ # ++ # Some callers (such as Pacemaker) will have a timer ++ # running and kill us if necessary ++ logging.debug("Waiting for nova to update it's internal state for %s" % options["--plug"]) ++ time.sleep(1) ++ ++ if not _host_evacuate(options): ++ sys.exit(1) + +- _host_evacuate(options["--plug"], on_shared_storage) + return + + def get_plugs_list(_, options): +@@ -117,9 +205,9 @@ def get_plugs_list(_, options): + hypervisors = nova.hypervisors.list() + for hypervisor in hypervisors: + longhost = hypervisor.hypervisor_hostname +- if options["--action"] == "list" and options["--domain"] != "": +- shorthost = longhost.replace("." + options["--domain"], +- "") ++ if options["--domain"] != "": ++ shorthost = longhost.replace("." + options["--domain"], "") ++ result[longhost] = ("", None) + result[shorthost] = ("", None) + else: + result[longhost] = ("", None) +@@ -164,7 +252,7 @@ def define_new_opts(): + "order": 5, + } + all_opt["record-only"] = { +- "getopt" : "", ++ "getopt" : "r:", + "longopt" : "record-only", + "help" : "--record-only Record the target as needing evacuation but as yet do not intiate it", + "required" : "0", +@@ -172,6 +260,15 @@ def define_new_opts(): + "default" : "False", + "order": 5, + } ++ all_opt["instance-filtering"] = { ++ "getopt" : "", ++ "longopt" : "instance-filtering", ++ "help" : "--instance-filtering Only evacuate instances create from images and flavors with evacuable=true", ++ "required" : "0", ++ "shortdesc" : "Only evacuate flagged instances", ++ "default" : "False", ++ "order": 5, ++ } + all_opt["no-shared-storage"] = { + "getopt" : "", + "longopt" : "no-shared-storage", +@@ -187,17 +284,17 @@ def main(): + global nova + atexit.register(atexit_handler) + +- device_opt = ["login", "passwd", "tenant-name", "auth-url", ++ device_opt = ["login", "passwd", "tenant-name", "auth-url", "fabric_fencing", "on_target", + "no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type", +- "record-only"] ++ "record-only", "instance-filtering"] + define_new_opts() + all_opt["shell_timeout"]["default"] = "180" + + options = check_input(device_opt, process_input(device_opt)) + + docs = {} +- docs["shortdesc"] = "Fence agent for nova compute nodes" +- docs["longdesc"] = "fence_nova_host is a Nova fencing notification agent" ++ docs["shortdesc"] = "Fence agent for the automatic resurrection of OpenStack compute instances" ++ docs["longdesc"] = "Used to tell Nova that compute nodes are down and to reschedule flagged instances" + docs["vendorurl"] = "" + + show_docs(options, docs) +@@ -213,7 +310,10 @@ def main(): + if options["--action"] != "list" and options["--domain"] != "" and options.has_key("--plug"): + options["--plug"] = options["--plug"] + "." + options["--domain"] + +- if options["--record-only"] != "False": ++ if options["--record-only"] in [ "2", "Disabled", "disabled" ]: ++ sys.exit(0) ++ ++ elif options["--record-only"] in [ "1", "True", "true", "Yes", "yes"]: + if options["--action"] == "on": + set_attrd_status(options["--plug"], "no", options) + sys.exit(0) +@@ -222,7 +322,7 @@ def main(): + set_attrd_status(options["--plug"], "yes", options) + sys.exit(0) + +- elif options["--action"] in ["status", "monitor"]: ++ elif options["--action"] in ["monitor", "status"]: + sys.exit(0) + + # The first argument is the Nova client version +diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +index 846a861..98bed4e 100644 +--- a/tests/data/metadata/fence_compute.xml ++++ b/tests/data/metadata/fence_compute.xml +@@ -1,6 +1,6 @@ + +- +-fence_nova_host is a Nova fencing notification agent ++ ++Used to tell Nova that compute nodes are down and to reschedule flagged instances + + + +@@ -35,7 +35,7 @@ + + + +- ++ + Fencing Action + + +@@ -48,6 +48,11 @@ + + DNS domain in which hosts live + ++ ++ ++ ++ Only evacuate flagged instances ++ + + + +@@ -55,7 +60,7 @@ + + + +- ++ + Only record the target as needing evacuation + + +@@ -115,9 +120,8 @@ + + + +- ++ + +- + + + +-- +2.4.3 + diff --git a/SOURCES/bz1285523-1-fence_compute-taggable-instance-support.patch b/SOURCES/bz1285523-1-fence_compute-taggable-instance-support.patch new file mode 100644 index 0000000..408eab2 --- /dev/null +++ b/SOURCES/bz1285523-1-fence_compute-taggable-instance-support.patch @@ -0,0 +1,79 @@ +diff -uNr a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +--- a/fence/agents/compute/fence_compute.py 2016-06-02 13:10:27.846973373 +0200 ++++ b/fence/agents/compute/fence_compute.py 2016-06-02 13:11:47.642169455 +0200 +@@ -89,7 +89,8 @@ + # Since the detailed view for all flavors doesn't provide the extra specs, + # we need to call each of the flavor to get them. + for flavor in flavors: +- if flavor.get_keys().get(EVACUABLE_TAG).strip().lower() in TRUE_TAGS: ++ tag = flavor.get_keys().get(EVACUABLE_TAG) ++ if tag.strip().lower() in TRUE_TAGS: + result.append(flavor.id) + return result + +@@ -98,23 +99,30 @@ + images = nova.images.list(detailed=True) + for image in images: + if hasattr(image, 'metadata'): +- if image.metadata.get(EVACUABLE_TAG).strip.lower() in TRUE_TAGS: ++ tag = image.metadata.get(EVACUABLE_TAG) ++ if tag and tag.strip().lower() in TRUE_TAGS: + result.append(image.id) + return result + + def _host_evacuate(options): + result = True ++ images = _get_evacuable_images() ++ flavors = _get_evacuable_flavors() + servers = nova.servers.list(search_opts={'host': options["--plug"], 'all_tenants': 1 }) ++ + if options["--instance-filtering"] == "False": +- logging.debug("Evacuating all images and flavors") +- evacuables = servers +- else: +- logging.debug("Filtering images and flavors") +- flavors = _get_evacuable_flavors() +- images = _get_evacuable_images() ++ logging.debug("Not evacuating anything") ++ evacuables = [] ++ elif len(flavors) or len(images): ++ logging.debug("Filtering images and flavors: %s %s" % (repr(flavors), repr(images))) + # Identify all evacuable servers ++ logging.debug("Checking %s" % repr(servers)) + evacuables = [server for server in servers + if _is_server_evacuable(server, flavors, images)] ++ logging.debug("Evacuating %s" % repr(evacuables)) ++ else: ++ logging.debug("Evacuating all images and flavors") ++ evacuables = servers + + if options["--no-shared-storage"] != "False": + on_shared_storage = False +@@ -267,10 +275,10 @@ + all_opt["instance-filtering"] = { + "getopt" : "", + "longopt" : "instance-filtering", +- "help" : "--instance-filtering Only evacuate instances create from images and flavors with evacuable=true", ++ "help" : "--instance-filtering Allow instances created from images and flavors with evacuable=true to be evacuated (or all if no images/flavors have been tagged)", + "required" : "0", +- "shortdesc" : "Only evacuate flagged instances", +- "default" : "False", ++ "shortdesc" : "Allow instances to be evacuated", ++ "default" : "True", + "order": 5, + } + all_opt["no-shared-storage"] = { +diff -uNr a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +--- a/tests/data/metadata/fence_compute.xml 2016-06-02 13:10:27.830973534 +0200 ++++ b/tests/data/metadata/fence_compute.xml 2016-06-02 13:11:47.642169455 +0200 +@@ -50,8 +50,8 @@ + + + +- +- Only evacuate flagged instances ++ ++ Allow instances to be evacuated + + + diff --git a/SOURCES/bz1285523-2-fence_compute-taggable-instance-support.patch b/SOURCES/bz1285523-2-fence_compute-taggable-instance-support.patch new file mode 100644 index 0000000..8c472c9 --- /dev/null +++ b/SOURCES/bz1285523-2-fence_compute-taggable-instance-support.patch @@ -0,0 +1,23 @@ +From 90dfc11618d7bb3aacb0f572b83518e6a6cf8bf5 Mon Sep 17 00:00:00 2001 +From: Andrew Beekhof +Date: Tue, 14 Jun 2016 20:43:49 +1000 +Subject: [PATCH] compute: Correctly handle installations without tagged + flavours + +--- + fence/agents/compute/fence_compute.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index c6b5083..ae19588 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -90,7 +90,7 @@ def _get_evacuable_flavors(): + # we need to call each of the flavor to get them. + for flavor in flavors: + tag = flavor.get_keys().get(EVACUABLE_TAG) +- if tag.strip().lower() in TRUE_TAGS: ++ if tag and tag.strip().lower() in TRUE_TAGS: + result.append(flavor.id) + return result + diff --git a/SOURCES/bz1286045-fence_ipmilan-add-diag-action.patch b/SOURCES/bz1286045-fence_ipmilan-add-diag-action.patch new file mode 100644 index 0000000..b7622db --- /dev/null +++ b/SOURCES/bz1286045-fence_ipmilan-add-diag-action.patch @@ -0,0 +1,134 @@ +diff -uNr a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py +--- a/fence/agents/ipmilan/fence_ipmilan.py 2016-03-14 10:33:38.419438036 +0100 ++++ b/fence/agents/ipmilan/fence_ipmilan.py 2016-03-14 10:41:41.376326426 +0100 +@@ -27,6 +27,10 @@ + output = run_command(options, create_command(options, "cycle")) + return bool(re.search('chassis power control: cycle', str(output).lower())) + ++def reboot_diag(_, options): ++ output = run_command(options, create_command(options, "diag")) ++ return bool(re.search('chassis power control: diag', str(output).lower())) ++ + def create_command(options, action): + cmd = options["--ipmitool-path"] + +@@ -137,7 +141,7 @@ + def main(): + atexit.register(atexit_handler) + +- device_opt = ["ipaddr", "ipport", "login", "no_login", "no_password", "passwd", ++ device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd", "diag", + "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method", + "obsolete_ip", "timeout"] + define_new_opts() +@@ -179,7 +183,15 @@ + if not is_executable(options["--ipmitool-path"]): + fail_usage("Ipmitool not found or not accessible") + +- result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle) ++ reboot_fn = reboot_cycle ++ if options["--action"] == "diag": ++ # Diag is a special action that can't be verified so we will reuse reboot functionality ++ # to minimize impact on generic library ++ options["--action"] = "reboot" ++ options["--method"] = "cycle" ++ reboot_fn = reboot_diag ++ ++ result = fence_action(None, options, set_power_status, get_power_status, None, reboot_fn) + sys.exit(result) + + if __name__ == "__main__": +diff -uNr a/fence/agents/lib/fence2man.xsl b/fence/agents/lib/fence2man.xsl +--- a/fence/agents/lib/fence2man.xsl 2016-03-14 10:33:38.411438131 +0100 ++++ b/fence/agents/lib/fence2man.xsl 2016-03-14 10:41:41.377326413 +0100 +@@ -20,6 +20,7 @@ + Enable fabric access. + Disable fabric access. + Reboot machine. ++Pulse a diagnostic interrupt to the processor(s). + Check the health of fence device + Display the XML metadata describing this resource. + List available plugs with aliases/virtual machines if there is support for more then one device. Returns N/A otherwise. +diff -uNr a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +--- a/fence/agents/lib/fencing.py.py 2016-03-14 10:33:38.418438048 +0100 ++++ b/fence/agents/lib/fencing.py.py 2016-03-14 10:41:44.366288571 +0100 +@@ -135,6 +135,10 @@ + "getopt" : "", + "help" : "", + "order" : 1}, ++ "diag" : { ++ "getopt" : "", ++ "help" : "", ++ "order" : ""}, + "passwd" : { + "getopt" : "p:", + "longopt" : "password", +@@ -590,6 +594,8 @@ + print "\t" + print "\t" + print "\t" ++ if avail_opt.count("diag") == 1: ++ print "\t" + print "" + print "" + +@@ -781,6 +787,9 @@ + if 1 == device_opt.count("no_status"): + acceptable_actions.remove("status") + ++ if 1 == device_opt.count("diag"): ++ acceptable_actions.extend(["diag"]) ++ + if 0 == acceptable_actions.count(options["--action"]): + fail_usage("Failed: Unrecognised action '" + options["--action"] + "'") + +diff -uNr a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +--- a/tests/data/metadata/fence_idrac.xml 2016-03-14 10:33:38.416438072 +0100 ++++ b/tests/data/metadata/fence_idrac.xml 2016-03-14 10:41:41.379326388 +0100 +@@ -169,5 +169,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +--- a/tests/data/metadata/fence_ilo3.xml 2016-03-14 10:33:38.416438072 +0100 ++++ b/tests/data/metadata/fence_ilo3.xml 2016-03-14 10:41:41.379326388 +0100 +@@ -169,5 +169,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +--- a/tests/data/metadata/fence_ilo4.xml 2016-03-14 10:33:38.416438072 +0100 ++++ b/tests/data/metadata/fence_ilo4.xml 2016-03-14 10:41:41.380326375 +0100 +@@ -169,5 +169,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +--- a/tests/data/metadata/fence_imm.xml 2016-03-14 10:33:38.416438072 +0100 ++++ b/tests/data/metadata/fence_imm.xml 2016-03-14 10:41:41.380326375 +0100 +@@ -169,5 +169,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +--- a/tests/data/metadata/fence_ipmilan.xml 2016-03-14 10:33:38.416438072 +0100 ++++ b/tests/data/metadata/fence_ipmilan.xml 2016-03-14 10:41:41.381326363 +0100 +@@ -169,5 +169,6 @@ + + + ++ + + diff --git a/SOURCES/bz1287059-1-fence_rhevm-add-filter-header.patch b/SOURCES/bz1287059-1-fence_rhevm-add-filter-header.patch new file mode 100644 index 0000000..c76c767 --- /dev/null +++ b/SOURCES/bz1287059-1-fence_rhevm-add-filter-header.patch @@ -0,0 +1,64 @@ +From 03eee868ec5f3a07024a6b7c65572e54238106c6 Mon Sep 17 00:00:00 2001 +From: Rik Theys +Date: Tue, 19 May 2015 13:24:09 +0200 +Subject: [PATCH 1/2] fence_rhevm: Add Filter header + +oVirt users who only have the UserRole role don't have enough privileges +to query the vm list, unless the Filter header is set to true. + +See rhbz#1102801 for details. +--- + fence/agents/rhevm/fence_rhevm.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py +index 427bed5..cf85689 100644 +--- a/fence/agents/rhevm/fence_rhevm.py ++++ b/fence/agents/rhevm/fence_rhevm.py +@@ -87,7 +87,7 @@ def send_command(opt, command, method="GET"): + conn = pycurl.Curl() + web_buffer = StringIO.StringIO() + conn.setopt(pycurl.URL, url) +- conn.setopt(pycurl.HTTPHEADER, ["Content-type: application/xml", "Accept: application/xml", "Prefer: persistent-auth"]) ++ conn.setopt(pycurl.HTTPHEADER, ["Content-type: application/xml", "Accept: application/xml", "Prefer: persistent-auth", "Filter: true"]) + + if opt.has_key("cookie"): + conn.setopt(pycurl.COOKIE, opt["cookie"]) +-- +2.5.0 + + +From d19bb9b0e3ae285fbf36ef0fc0b76e7dccddb5d8 Mon Sep 17 00:00:00 2001 +From: Rik Theys +Date: Tue, 19 May 2015 13:31:14 +0200 +Subject: [PATCH 2/2] fence_rhevm: Fill in outlet status in get_list + +The outlet status was set to None for all outlets. This results in a +traceback in fencing.py as it tries to execute the upper() function on +the status. This is fine when the account that tries to access the data +is an admin account as the list will be empty. If a UserRole user is +used, the vm list is not empty and the error occurs. + +Fill in the status of each vm in the outlet status to prevent the +traceback. +--- + fence/agents/rhevm/fence_rhevm.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py +index cf85689..3926f3b 100644 +--- a/fence/agents/rhevm/fence_rhevm.py ++++ b/fence/agents/rhevm/fence_rhevm.py +@@ -66,7 +66,8 @@ def get_list(conn, options): + lines = res.split(" +Date: Thu, 5 May 2016 11:50:03 +0200 +Subject: [PATCH] Explicitly use version 3 of the oVirt API + +Version on 4 of the oVirt engine will support two versions of the API: +version 3, which will be backwards compatible with older versions of the +engine, and version 4, which won't be compatible. The default used by +the server will be version 4, but clients can explicitly request a +version of the API using the "Version" header or the "/v3" URL prefix. +The header is the preferred mechanism because it is just ignored by +older versions of the server. This patch modifies the oVirt fence agent +so that the it will always send the "Version: 3" header, in order to +work correctly with version 3 compatibility mode of the API. + +Signed-off-by: Juan Hernandez +--- + fence/agents/rhevm/fence_rhevm.py | 34 +++++++++++++++++++++++++++++++--- + tests/data/metadata/fence_rhevm.xml | 5 +++++ + 2 files changed, 36 insertions(+), 3 deletions(-) + +diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py +index 3926f3b..46453c9 100644 +--- a/fence/agents/rhevm/fence_rhevm.py ++++ b/fence/agents/rhevm/fence_rhevm.py +@@ -81,14 +81,24 @@ def send_command(opt, command, method="GET"): + url = "https:" + else: + url = "http:" ++ if opt.has_key("--api-path"): ++ api_path = opt["--api-path"] ++ else: ++ api_path = "/ovirt-engine/api" + +- url += "//" + opt["--ip"] + ":" + str(opt["--ipport"]) + "/api/" + command ++ url += "//" + opt["--ip"] + ":" + str(opt["--ipport"]) + api_path + "/" + command + + ## send command through pycurl + conn = pycurl.Curl() + web_buffer = StringIO.StringIO() + conn.setopt(pycurl.URL, url) +- conn.setopt(pycurl.HTTPHEADER, ["Content-type: application/xml", "Accept: application/xml", "Prefer: persistent-auth", "Filter: true"]) ++ conn.setopt(pycurl.HTTPHEADER, [ ++ "Version: 3", ++ "Content-type: application/xml", ++ "Accept: application/xml", ++ "Prefer: persistent-auth", ++ "Filter: true", ++ ]) + + if opt.has_key("cookie"): + conn.setopt(pycurl.COOKIE, opt["cookie"]) +@@ -136,9 +146,27 @@ def define_new_opts(): + "required" : "0", + "shortdesc" : "Reuse cookies for authentication", + "order" : 1} ++ all_opt["api_path"] = { ++ "getopt" : ":", ++ "longopt" : "api-path", ++ "help" : "--api-path=[path] The path of the API URL", ++ "default" : "/ovirt-engine/api", ++ "required" : "0", ++ "shortdesc" : "The path of the API URL", ++ "order" : 2} + + def main(): +- device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "web", "port", "use_cookies" ] ++ device_opt = [ ++ "ipaddr", ++ "api_path", ++ "login", ++ "passwd", ++ "ssl", ++ "notls", ++ "web", ++ "port", ++ "use_cookies", ++ ] + + atexit.register(atexit_handler) + define_new_opts() +diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +index 893a3c5..5fa2e21 100644 +--- a/tests/data/metadata/fence_rhevm.xml ++++ b/tests/data/metadata/fence_rhevm.xml +@@ -73,6 +73,11 @@ + + Reuse cookies for authentication + ++ ++ ++ ++ The path of the API URL ++ + + + diff --git a/SOURCES/bz1287311-1-fence_compute-real-status-in-record-only-mode.patch b/SOURCES/bz1287311-1-fence_compute-real-status-in-record-only-mode.patch new file mode 100644 index 0000000..64083eb --- /dev/null +++ b/SOURCES/bz1287311-1-fence_compute-real-status-in-record-only-mode.patch @@ -0,0 +1,12 @@ +diff -uNr a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +--- a/fence/agents/compute/fence_compute.py 2016-06-15 14:46:26.558080906 +0200 ++++ b/fence/agents/compute/fence_compute.py 2016-06-15 15:27:52.987308060 +0200 +@@ -334,7 +334,7 @@ + set_attrd_status(options["--plug"], "yes", options) + sys.exit(0) + +- elif options["--action"] in ["monitor", "status"]: ++ elif options["--action"] in ["monitor"]: + sys.exit(0) + + # The first argument is the Nova client version diff --git a/SOURCES/bz1287311-2-fence_compute-real-status-in-record-only-mode.patch b/SOURCES/bz1287311-2-fence_compute-real-status-in-record-only-mode.patch new file mode 100644 index 0000000..809d200 --- /dev/null +++ b/SOURCES/bz1287311-2-fence_compute-real-status-in-record-only-mode.patch @@ -0,0 +1,44 @@ +From 6a2f0f2b24233ddfdd8672e380e697a425af3ed7 Mon Sep 17 00:00:00 2001 +From: Andrew Beekhof +Date: Wed, 6 Jul 2016 17:23:41 +1000 +Subject: [PATCH] compute: Prevent use of undefined variable + +--- + fence/agents/compute/fence_compute.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index e3d5061..0f05c12 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -252,17 +252,21 @@ def fix_domain(options): + + elif len(domains) == 1 and "--domain" not in options: + options["--domain"] = last_domain ++ return options["--domain"] + + elif len(domains) == 1: + logging.error("Overriding supplied domain '%s' does not match the one calculated from: %s" + % (options["--domain"], hypervisor.hypervisor_hostname)) + options["--domain"] = last_domain ++ return options["--domain"] + + elif len(domains) > 1: + logging.error("The supplied domain '%s' did not match any used inside nova: %s" + % (options["--domain"], repr(domains))) + sys.exit(1) + ++ return None ++ + def fix_plug_name(options): + if options["--action"] == "list": + return +@@ -270,7 +274,7 @@ def fix_plug_name(options): + if "--plug" not in options: + return + +- fix_domain(options) ++ calculated = fix_domain(options) + short_plug = options["--plug"].split('.')[0] + logging.debug("Checking target '%s' against calculated domain '%s'"% (options["--plug"], calculated)) + diff --git a/SOURCES/bz1298430-1-fence_cisco_ucs-Obtain-status-from-different-attr.patch b/SOURCES/bz1298430-1-fence_cisco_ucs-Obtain-status-from-different-attr.patch new file mode 100644 index 0000000..104951c --- /dev/null +++ b/SOURCES/bz1298430-1-fence_cisco_ucs-Obtain-status-from-different-attr.patch @@ -0,0 +1,40 @@ +commit d681273ff1b6fdc9c4e314aa9c9eb28b4a252230 +Author: Marek 'marx' Grac +Date: Tue Feb 9 09:46:21 2016 +0100 + + fence_cisco_ucs: Obtain 'status' from different attribute + +diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py +index bca8087..260925e 100644 +--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py +@@ -19,7 +19,7 @@ RE_STATUS = re.compile("", int(options["--shell-timeout"])) + +- result = RE_GET_OPERPOWER.search(res) ++ result = RE_GET_PRESENCE.search(res) + if result == None: + fail(EC_STATUS) + else: + status = result.group(1) + +- if status == "on": +- return "on" +- else: ++ if status in ["missing", "mismatch"]: + return "off" ++ else: ++ return "on" + + def set_power_status(conn, options): + del conn diff --git a/SOURCES/bz1298430-2-fence_cisco_ucs-Add-missing-as-off.patch b/SOURCES/bz1298430-2-fence_cisco_ucs-Add-missing-as-off.patch new file mode 100644 index 0000000..0ba7e74 --- /dev/null +++ b/SOURCES/bz1298430-2-fence_cisco_ucs-Add-missing-as-off.patch @@ -0,0 +1,43 @@ +From 0a34f115c378ed1791f2aceb5abdb0633c394d6f Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Tue, 9 Feb 2016 09:49:01 +0100 +Subject: [PATCH 2/4] fence_cisco_ucs: Add --missing-as-off + +--- + fence/agents/cisco_ucs/fence_cisco_ucs.py | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py +index 260925e..08da566 100644 +--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py +@@ -32,10 +32,16 @@ def get_power_status(conn, options): + + result = RE_GET_PNDN.search(res) + if result == None: +- fail(EC_STATUS) ++ pndn = "" + else: + pndn = result.group(1) + ++ if pndn.strip() == "": ++ if "--missing-as-off" in options: ++ return "off" ++ else: ++ fail(EC_STATUS) ++ + res = send_command(options, "", int(options["--shell-timeout"])) +@@ -139,7 +145,7 @@ def logout(): + + def main(): + global options_global +- device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "port", "web", "suborg"] ++ device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "port", "web", "suborg", "missing_as_off"] + + atexit.register(atexit_handler) + atexit.register(logout) +-- +2.4.3 + diff --git a/SOURCES/bz1298430-2-fence_cisco_ucs-status.patch b/SOURCES/bz1298430-2-fence_cisco_ucs-status.patch new file mode 100644 index 0000000..190001d --- /dev/null +++ b/SOURCES/bz1298430-2-fence_cisco_ucs-status.patch @@ -0,0 +1,52 @@ +From 9f9a6829ead6199ecb65c4f85f400a0e403c8c47 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 15 Aug 2016 10:48:47 +0200 +Subject: [PATCH] fence_cisco_ucs: Improve a method to obtain status + +On Cisco UCS there are two attributes which are important for obtaining +correct power status of blade. One checks if slot is powered ON and other if +the node is pulled off the blade. +--- + fence/agents/cisco_ucs/fence_cisco_ucs.py | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py +index 648e45f..0d9609d 100644 +--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py +@@ -19,6 +19,7 @@ RE_STATUS = re.compile(" +Date: Tue, 9 Feb 2016 09:55:35 +0100 +Subject: [PATCH 3/4] fence_cisco_ucs: Update XML metadata + +--- + tests/data/metadata/fence_cisco_ucs.xml | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +index 9834f5a..7114694 100644 +--- a/tests/data/metadata/fence_cisco_ucs.xml ++++ b/tests/data/metadata/fence_cisco_ucs.xml +@@ -108,6 +108,11 @@ + + Wait X seconds for cmd prompt after login + ++ ++ ++ ++ Missing port returns OFF instead of failure ++ + + + +-- +2.4.3 + diff --git a/SOURCES/bz1298430-4-Update-XML-metadata.patch b/SOURCES/bz1298430-4-Update-XML-metadata.patch new file mode 100644 index 0000000..5550354 --- /dev/null +++ b/SOURCES/bz1298430-4-Update-XML-metadata.patch @@ -0,0 +1,65 @@ +From 98f60a846ef12affc612063b733e40be45a9a284 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Tue, 9 Feb 2016 10:11:23 +0100 +Subject: [PATCH 4/4] fence_cisco_ucs: Re-order options in XML metadata + +RHEL7 uses different ordering than master branch +--- + tests/data/metadata/fence_cisco_ucs.xml | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +index 7114694..067966a 100644 +--- a/tests/data/metadata/fence_cisco_ucs.xml ++++ b/tests/data/metadata/fence_cisco_ucs.xml +@@ -13,6 +13,11 @@ + + Disable TLS negotiation, force SSL 3.0 + ++ ++ ++ ++ Additional path needed to access suborganization ++ + + + +@@ -53,11 +58,6 @@ + + SSL connection + +- +- +- +- Additional path needed to access suborganization +- + + + +@@ -108,11 +108,6 @@ + + Wait X seconds for cmd prompt after login + +- +- +- +- Missing port returns OFF instead of failure +- + + + +@@ -123,6 +118,11 @@ + + Wait X seconds before fencing is started + ++ ++ ++ ++ Missing port returns OFF instead of failure ++ + + + +-- +2.4.3 + diff --git a/SOURCES/bz1298430-fence_cisco_ucs-status.patch b/SOURCES/bz1298430-fence_cisco_ucs-status.patch new file mode 100644 index 0000000..a15fbee --- /dev/null +++ b/SOURCES/bz1298430-fence_cisco_ucs-status.patch @@ -0,0 +1,57 @@ +From 8f106de6bed0626787cae79aa2607992f1bbacec Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 1 Feb 2016 16:07:48 +0100 +Subject: [PATCH] fence_cisco_ucs: Obtain status of device from different + endpoint + +Resolves: rhbz#1298430 +--- + fence/agents/cisco_ucs/fence_cisco_ucs.py | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py +index 6288207..331f309 100644 +--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py +@@ -17,7 +17,9 @@ BUILD_DATE="March, 2008" + RE_COOKIE = re.compile("", int(options["--shell-timeout"])) ++ options["--plug"] + "\"/>", int(options["--shell-timeout"])) + +- result = RE_STATUS.search(res) ++ result = RE_GET_PNDN.search(res) ++ if result == None: ++ fail(EC_STATUS) ++ else: ++ pndn = result.group(1) ++ ++ res = send_command(options, "", int(options["--shell-timeout"])) ++ ++ result = RE_GET_OPERPOWER.search(res) + if result == None: + fail(EC_STATUS) + else: + status = result.group(1) + +- if status == "up": ++ if status == "on": + return "on" + else: + return "off" +-- +2.4.3 + diff --git a/SOURCES/bz1313561-fence_compute-locate-all-instances-to-be-evacuated.patch b/SOURCES/bz1313561-fence_compute-locate-all-instances-to-be-evacuated.patch new file mode 100644 index 0000000..adeb76b --- /dev/null +++ b/SOURCES/bz1313561-fence_compute-locate-all-instances-to-be-evacuated.patch @@ -0,0 +1,33 @@ +diff -uNr a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +--- a/fence/agents/compute/fence_compute.py 2016-03-30 16:07:11.600203519 +0200 ++++ b/fence/agents/compute/fence_compute.py 2016-03-30 16:09:17.184539645 +0200 +@@ -80,6 +80,7 @@ + return True + if server.image.get('id') in evac_images: + return True ++ logging.debug("Instance %s is not evacuable" % server.image.get('id')) + return False + + def _get_evacuable_flavors(): +@@ -103,10 +104,12 @@ + + def _host_evacuate(options): + result = True +- servers = nova.servers.list(search_opts={'host': options["--plug"]}) ++ servers = nova.servers.list(search_opts={'host': options["--plug"], 'all_tenants': 1 }) + if options["--instance-filtering"] == "False": ++ logging.debug("Evacuating all images and flavors") + evacuables = servers + else: ++ logging.debug("Filtering images and flavors") + flavors = _get_evacuable_flavors() + images = _get_evacuable_images() + # Identify all evacuable servers +@@ -119,6 +122,7 @@ + on_shared_storage = True + + for server in evacuables: ++ logging.debug("Processing %s" % server) + if hasattr(server, 'id'): + response = _server_evacuate(server.id, on_shared_storage) + if response["accepted"]: diff --git a/SOURCES/bz1334162-fence_compute-improved-fqdn-handling.patch b/SOURCES/bz1334162-fence_compute-improved-fqdn-handling.patch new file mode 100644 index 0000000..85e91fe --- /dev/null +++ b/SOURCES/bz1334162-fence_compute-improved-fqdn-handling.patch @@ -0,0 +1,136 @@ +From 33e63ce9959199bdfdf8167d2f64a85776d30141 Mon Sep 17 00:00:00 2001 +From: Andrew Beekhof +Date: Fri, 22 Apr 2016 12:27:10 +1000 +Subject: [PATCH] fence_compute: improved handling of compute nodes + with/without FQDNs + +--- + fence/agents/compute/fence_compute.py | 94 +++++++++++++++++++++++++++++++---- + 1 file changed, 84 insertions(+), 10 deletions(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index b93580b..be7fc22 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -202,6 +202,86 @@ def set_power_status(_, options): + + return + ++ ++def fix_domain(options): ++ domains = {} ++ last_domain = None ++ ++ if nova: ++ # Find it in nova ++ ++ hypervisors = nova.hypervisors.list() ++ for hypervisor in hypervisors: ++ shorthost = hypervisor.hypervisor_hostname.split('.')[0] ++ ++ if shorthost == hypervisor.hypervisor_hostname: ++ # Nova is not using FQDN ++ calculated = "" ++ else: ++ # Compute nodes are named as FQDN, strip off the hostname ++ calculated = hypervisor.hypervisor_hostname.replace(shorthost+".", "") ++ ++ domains[calculated] = shorthost ++ ++ if calculated == last_domain: ++ # Avoid complaining for each compute node with the same name ++ # One hopes they don't appear interleaved as A.com B.com A.com B.com ++ logging.debug("Calculated the same domain from: %s" % hypervisor.hypervisor_hostname) ++ ++ elif options.has_key("--domain") and options["--domain"] == calculated: ++ # Supplied domain name is valid ++ return ++ ++ elif options.has_key("--domain"): ++ # Warn in case nova isn't available at some point ++ logging.warning("Supplied domain '%s' does not match the one calculated from: %s" ++ % (options["--domain"], hypervisor.hypervisor_hostname)) ++ ++ last_domain = calculated ++ ++ if len(domains) == 0 and not options.has_key("--domain"): ++ logging.error("Could not calculate the domain names used by compute nodes in nova") ++ ++ elif len(domains) == 1 and not options.has_key("--domain"): ++ options["--domain"] = last_domain ++ ++ elif len(domains) == 1: ++ logging.error("Overriding supplied domain '%s' does not match the one calculated from: %s" ++ % (options["--domain"], hypervisor.hypervisor_hostname)) ++ options["--domain"] = last_domain ++ ++ elif len(domains) > 1: ++ logging.error("The supplied domain '%s' did not match any used inside nova: %s" ++ % (options["--domain"], repr(domains))) ++ sys.exit(1) ++ ++def fix_plug_name(options): ++ if options["--action"] == "list": ++ return ++ ++ if not options.has_key("--plug"): ++ return ++ ++ fix_domain(options) ++ short_plug = options["--plug"].split('.')[0] ++ logging.debug("Checking target '%s' against calculated domain '%s'"% (options["--plug"], calculated)) ++ ++ if not options.has_key("--domain"): ++ # Nothing supplied and nova not available... what to do... nothing ++ return ++ ++ elif options["--domain"] == "": ++ # Ensure any domain is stripped off since nova isn't using FQDN ++ options["--plug"] = short_plug ++ ++ elif options["--plug"].find(options["--domain"]): ++ # Plug already contains the domain, don't re-add ++ return ++ ++ else: ++ # Add the domain to the plug ++ options["--plug"] = short_plug + "." + options["--domain"] ++ + def get_plugs_list(_, options): + result = {} + +@@ -209,12 +289,9 @@ def get_plugs_list(_, options): + hypervisors = nova.hypervisors.list() + for hypervisor in hypervisors: + longhost = hypervisor.hypervisor_hostname +- if options["--domain"] != "": +- shorthost = longhost.replace("." + options["--domain"], "") +- result[longhost] = ("", None) +- result[shorthost] = ("", None) +- else: +- result[longhost] = ("", None) ++ shorthost = longhost.split('.')[0] ++ result[longhost] = ("", None) ++ result[shorthost] = ("", None) + return result + + +@@ -270,7 +347,6 @@ def define_new_opts(): + "help" : "-d, --domain=[string] DNS domain in which hosts live, useful when the cluster uses short names and nova uses FQDN", + "required" : "0", + "shortdesc" : "DNS domain in which hosts live", +- "default" : "", + "order": 5, + } + all_opt["record-only"] = { +@@ -328,9 +404,7 @@ def main(): + except ImportError: + fail_usage("nova not found or not accessible") + +- # Potentially we should make this a pacemaker feature +- if options["--action"] != "list" and options["--domain"] != "" and options.has_key("--plug"): +- options["--plug"] = options["--plug"] + "." + options["--domain"] ++ fix_plug_name(options) + + if options["--record-only"] in [ "2", "Disabled", "disabled" ]: + sys.exit(0) diff --git a/SOURCES/bz1337236-fence_sbd.patch b/SOURCES/bz1337236-fence_sbd.patch new file mode 100644 index 0000000..49acd87 --- /dev/null +++ b/SOURCES/bz1337236-fence_sbd.patch @@ -0,0 +1,563 @@ +diff -uNr a/configure.ac b/configure.ac +--- a/configure.ac 2017-01-16 16:20:32.299438841 +0100 ++++ b/configure.ac 2017-01-16 16:19:09.079326886 +0100 +@@ -309,6 +309,7 @@ + fence/agents/xenapi/Makefile + fence/agents/hds_cb/Makefile + fence/agents/zvm/Makefile ++ fence/agents/sbd/Makefile + doc/Makefile]) + + AC_OUTPUT +diff -uNr a/fence/agents/sbd/fence_sbd.py b/fence/agents/sbd/fence_sbd.py +--- a/fence/agents/sbd/fence_sbd.py 1970-01-01 01:00:00.000000000 +0100 ++++ b/fence/agents/sbd/fence_sbd.py 2017-01-16 16:22:39.273080656 +0100 +@@ -0,0 +1,422 @@ ++#!/usr/bin/python -tt ++ ++import sys, stat ++import logging ++import os ++import atexit ++sys.path.append("@FENCEAGENTSLIBDIR@") ++from fencing import fail_usage, run_command, fence_action, all_opt ++from fencing import atexit_handler, check_input, process_input, show_docs ++from fencing import run_delay ++ ++#BEGIN_VERSION_GENERATION ++RELEASE_VERSION="" ++REDHAT_COPYRIGHT="" ++BUILD_DATE="" ++#END_VERSION_GENERATION ++ ++DEVICE_INIT = 1 ++DEVICE_NOT_INIT = -3 ++PATH_NOT_EXISTS = -1 ++PATH_NOT_BLOCK = -2 ++ ++def is_block_device(filename): ++ """Checks if a given path is a valid block device ++ ++ Key arguments: ++ filename -- the file to check ++ ++ Return codes: ++ True if it's a valid block device ++ False, otherwise ++ """ ++ ++ try: ++ mode = os.lstat(filename).st_mode ++ except OSError: ++ return False ++ else: ++ return stat.S_ISBLK(mode) ++ ++def is_link(filename): ++ """Checks if a given path is a link. ++ ++ Key arguments: ++ filename -- the file to check ++ ++ Return codes: ++ True if it's a link ++ False, otherwise ++ """ ++ ++ try: ++ mode = os.lstat(filename).st_mode ++ except OSError: ++ return False ++ else: ++ return stat.S_ISLNK(mode) ++ ++def check_sbd_device(options, device_path): ++ """checks that a given sbd device exists and is initialized ++ ++ Key arguments: ++ options -- options dictionary ++ device_path -- device path to check ++ ++ Return Codes: ++ 1 / DEVICE_INIT if the device exists and is initialized ++ -1 / PATH_NOT_EXISTS if the path does not exists ++ -2 / PATH_NOT_BLOCK if the path exists but is not a valid block device ++ -3 / DEVICE_NOT_INIT if the sbd device is not initialized ++ """ ++ ++ # First of all we need to check if the device is valid ++ if not os.path.exists(device_path): ++ return PATH_NOT_EXISTS ++ ++ # We need to check if device path is a symbolic link. If so we resolve that ++ # link. ++ if is_link(device_path): ++ link_target = os.readlink(device_path) ++ device_path = os.path.join(os.path.dirname(device_path), link_target) ++ ++ # As second step we make sure it's a valid block device ++ if not is_block_device(device_path): ++ return PATH_NOT_BLOCK ++ ++ cmd = "%s -d %s dump" % (options["--sbd-path"], device_path) ++ ++ (return_code, out, err) = run_command(options, cmd) ++ ++ for line in out.split("\n"): ++ if len(line) == 0: ++ continue ++ ++ # If we read "NOT dumped" something went wrong, e.g. the device is not ++ # initialized. ++ if "NOT dumped" in line: ++ return DEVICE_NOT_INIT ++ ++ return DEVICE_INIT ++ ++def generate_sbd_command(options, command, arguments=None): ++ """Generates a sbd command based on given arguments. ++ ++ Return Value: ++ generated sbd command (string) ++ """ ++ cmd = options["--sbd-path"] ++ ++ # add "-d" for each sbd device ++ for device in parse_sbd_devices(options): ++ cmd += " -d %s" % device ++ ++ cmd += " %s %s" % (command, arguments) ++ ++ return cmd ++ ++def send_sbd_message(conn, options, plug, message): ++ """Sends a message to all sbd devices. ++ ++ Key arguments: ++ conn -- connection structure ++ options -- options dictionary ++ plug -- plug to sent the message to ++ message -- message to send ++ ++ Return Value: ++ (return_code, out, err) Tuple containing the error code, ++ """ ++ ++ del conn ++ ++ arguments = "%s %s" % (plug, message) ++ cmd = generate_sbd_command(options, "message", arguments) ++ ++ (return_code, out, err) = run_command(options, cmd) ++ ++ return (return_code, out, err) ++ ++def get_msg_timeout(options): ++ """Reads the configured sbd message timeout from each device. ++ ++ Key arguments: ++ options -- options dictionary ++ ++ Return Value: ++ msg_timeout (integer, seconds) ++ """ ++ ++ # get the defined msg_timeout ++ msg_timeout = -1 # default sbd msg timeout ++ ++ cmd = generate_sbd_command(options, "dump") ++ ++ (return_code, out, err) = run_command(options, cmd) ++ ++ for line in out.split("\n"): ++ if len(line) == 0: ++ continue ++ ++ if "msgwait" in line: ++ tmp_msg_timeout = int(line.split(':')[1]) ++ if -1 != msg_timeout and tmp_msg_timeout != msg_timeout: ++ logging.warn(\ ++ "sbd message timeouts differ in different devices") ++ # we only save the highest timeout ++ if tmp_msg_timeout > msg_timeout: ++ msg_timeout = tmp_msg_timeout ++ ++ return msg_timeout ++ ++def set_power_status(conn, options): ++ """send status to sbd device (poison pill) ++ ++ Key arguments: ++ conn -- connection structure ++ options -- options dictionary ++ ++ Return Value: ++ return_code -- action result (bool) ++ """ ++ ++ target_status = options["--action"] ++ plug = options["--plug"] ++ return_code = 99 ++ out = "" ++ err = "" ++ ++ # Map fencing actions to sbd messages ++ if "on" == target_status: ++ (return_code, out, err) = send_sbd_message(conn, options, plug, "clear") ++ elif "off" == target_status: ++ (return_code, out, err) = send_sbd_message(conn, options, plug, "off") ++ elif "reboot" == target_status: ++ (return_code, out, err) = send_sbd_message(conn, options, plug, "reset") ++ ++ if 0 != return_code: ++ logging.error("sending message to sbd device(s) \ ++ failed with return code %d", return_code) ++ logging.error("DETAIL: output on stdout was \"%s\"", out) ++ logging.error("DETAIL: output on stderr was \"%s\"", err) ++ ++ return not bool(return_code) ++ ++def reboot_cycle(conn, options): ++ """" trigger reboot by sbd messages ++ ++ Key arguments: ++ conn -- connection structure ++ options -- options dictionary ++ ++ Return Value: ++ return_code -- action result (bool) ++ """ ++ ++ plug = options["--plug"] ++ return_code = 99 ++ out = "" ++ err = "" ++ ++ (return_code, out, err) = send_sbd_message(conn, options, plug, "reset") ++ return not bool(return_code) ++ ++def get_power_status(conn, options): ++ """Returns the status of a specific node. ++ ++ Key arguments: ++ conn -- connection structure ++ options -- option dictionary ++ ++ Return Value: ++ status -- status code (string) ++ """ ++ ++ status = "UNKWNOWN" ++ plug = options["--plug"] ++ ++ nodelist = get_node_list(conn, options) ++ ++ # We need to check if the specified plug / node a already a allocated slot ++ # on the device. ++ if plug not in nodelist: ++ logging.error("node \"%s\" not found in node list", plug) ++ else: ++ status = nodelist[plug][1] ++ ++ ++ return status ++ ++def translate_status(sbd_status): ++ """Translates the sbd status to fencing status. ++ ++ Key arguments: ++ sbd_status -- status to translate (string) ++ ++ Return Value: ++ status -- fencing status (string) ++ """ ++ ++ status = "UNKNOWN" ++ ++ ++ # Currently we only accept "clear" to be marked as online. Eventually we ++ # should also check against "test" ++ online_status = ["clear"] ++ ++ offline_status = ["reset", "off"] ++ ++ if any(online_status_element in sbd_status \ ++ for online_status_element in online_status): ++ status = "on" ++ ++ if any(offline_status_element in sbd_status \ ++ for offline_status_element in offline_status): ++ status = "off" ++ ++ return status ++ ++def get_node_list(conn, options): ++ """Returns a list of hostnames, registerd on the sbd device. ++ ++ Key arguments: ++ conn -- connection options ++ options -- options ++ ++ Return Value: ++ nodelist -- dictionary wich contains all node names and there status ++ """ ++ ++ del conn ++ ++ nodelist = {} ++ ++ cmd = generate_sbd_command(options, "list") ++ ++ (return_code, out, err) = run_command(options, cmd) ++ ++ for line in out.split("\n"): ++ if len(line) == 0: ++ continue ++ ++ # if we read "unreadable" something went wrong ++ if "NOT dumped" in line: ++ return nodelist ++ ++ words = line.split() ++ port = words[1] ++ sbd_status = words[2] ++ nodelist[port] = (port, translate_status(sbd_status)) ++ ++ return nodelist ++ ++def parse_sbd_devices(options): ++ """Returns an array of all sbd devices. ++ ++ Key arguments: ++ options -- options dictionary ++ ++ Return Value: ++ devices -- array of device paths ++ """ ++ ++ devices = [str.strip(dev) \ ++ for dev in str.split(options["--devices"], ",")] ++ ++ return devices ++ ++def define_new_opts(): ++ """Defines the all opt list ++ """ ++ all_opt["devices"] = { ++ "getopt" : ":", ++ "longopt" : "devices", ++ "help":"--devices=[device_a,device_b] \ ++Comma separated list of sbd devices", ++ "required" : "1", ++ "shortdesc" : "SBD Device", ++ "order": 1 ++ } ++ ++ all_opt["sbd_path"] = { ++ "getopt" : ":", ++ "longopt" : "sbd-path", ++ "help" : "--sbd-path=[path] Path to SBD binary", ++ "required" : "0", ++ "default" : "/usr/sbin/sbd", ++ "shortdesc" : "Path to SBD binary", ++ "order": 200 ++ } ++ ++def main(): ++ """Main function ++ """ ++ # We need to define "no_password" otherwise we will be ask about it if ++ # we don't provide any password. ++ device_opt = ["no_password", "devices", "port", "method", "sbd_path"] ++ ++ # close stdout if we get interrupted ++ atexit.register(atexit_handler) ++ ++ define_new_opts() ++ ++ all_opt["method"]["default"] = "cycle" ++ all_opt["method"]["help"] = "-m, --method=[method] Method to fence (onoff|cycle) (Default: cycle)" ++ ++ options = check_input(device_opt, process_input(device_opt)) ++ ++ # fill the needed variables to generate metadata and help text output ++ docs = {} ++ docs["shortdesc"] = "Fence agent for sbd" ++ docs["longdesc"] = "fence_sbd is I/O Fencing agent \ ++which can be used in environments where sbd can be used (shared storage)." ++ docs["vendorurl"] = "" ++ show_docs(options, docs) ++ ++ # We need to check if --devices is given and not empty. ++ if "--devices" not in options: ++ fail_usage("No SBD devices specified. \ ++ At least one SBD device is required.") ++ ++ run_delay(options) ++ ++ # We need to check if the provided sbd_devices exists. We need to do ++ # that for every given device. ++ for device_path in parse_sbd_devices(options): ++ logging.debug("check device \"%s\"", device_path) ++ ++ return_code = check_sbd_device(options, device_path) ++ if PATH_NOT_EXISTS == return_code: ++ logging.error("\"%s\" does not exist", device_path) ++ elif PATH_NOT_BLOCK == return_code: ++ logging.error("\"%s\" is not a valid block device", device_path) ++ elif DEVICE_NOT_INIT == return_code: ++ logging.error("\"%s\" is not initialized", device_path) ++ elif DEVICE_INIT != return_code: ++ logging.error("UNKNOWN error while checking \"%s\"", device_path) ++ ++ # If we get any error while checking the device we need to exit at this ++ # point. ++ if DEVICE_INIT != return_code: ++ exit(return_code) ++ ++ # we check against the defined timeouts. If the pacemaker timeout is smaller ++ # then that defined within sbd we should report this. ++ power_timeout = int(options["--power-timeout"]) ++ sbd_msg_timeout = get_msg_timeout(options) ++ if power_timeout <= sbd_msg_timeout: ++ logging.warn("power timeout needs to be \ ++ greater then sbd message timeout") ++ ++ result = fence_action(\ ++ None, \ ++ options, \ ++ set_power_status, \ ++ get_power_status, \ ++ get_node_list, \ ++ reboot_cycle) ++ ++ sys.exit(result) ++ ++if __name__ == "__main__": ++ main() +diff -uNr a/fence/agents/sbd/Makefile.am b/fence/agents/sbd/Makefile.am +--- a/fence/agents/sbd/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ b/fence/agents/sbd/Makefile.am 2017-01-16 16:19:09.079326886 +0100 +@@ -0,0 +1,17 @@ ++MAINTAINERCLEANFILES = Makefile.in ++ ++TARGET = fence_sbd ++ ++SRC = $(TARGET).py ++ ++EXTRA_DIST = $(SRC) ++ ++sbin_SCRIPTS = $(TARGET) ++ ++man_MANS = $(TARGET).8 ++ ++FENCE_TEST_ARGS = -n test --devices test ++ ++include $(top_srcdir)/make/fencebuild.mk ++include $(top_srcdir)/make/fenceman.mk ++include $(top_srcdir)/make/agentpycheck.mk +diff -uNr a/tests/data/metadata/fence_sbd.xml b/tests/data/metadata/fence_sbd.xml +--- a/tests/data/metadata/fence_sbd.xml 1970-01-01 01:00:00.000000000 +0100 ++++ b/tests/data/metadata/fence_sbd.xml 2017-01-16 16:31:45.855219543 +0100 +@@ -0,0 +1,101 @@ ++ ++ ++fence_sbd is I/O Fencing agent which can be used in environments where sbd can be used (shared storage). ++ ++ ++ ++ ++ ++ Fencing action ++ ++ ++ ++ ++ SBD Device ++ ++ ++ ++ ++ ++ Method to fence ++ ++ ++ ++ ++ Physical plug number on device, UUID or identification of machine ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Separator for CSV created by 'list' operation ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Path to SBD binary ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --git a/SOURCES/bz1342584-fence_apc-fix-connection-timed-out.patch b/SOURCES/bz1342584-fence_apc-fix-connection-timed-out.patch new file mode 100644 index 0000000..b3ac1fb --- /dev/null +++ b/SOURCES/bz1342584-fence_apc-fix-connection-timed-out.patch @@ -0,0 +1,47 @@ +diff -uNr a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py +--- a/fence/agents/apc/fence_apc.py 2016-06-17 12:39:29.677024556 +0200 ++++ b/fence/agents/apc/fence_apc.py 2016-06-17 12:58:58.234215019 +0200 +@@ -14,7 +14,7 @@ + ## cipher (des/blowfish) have to be defined + ##### + +-import sys, re ++import sys, re, time + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +@@ -26,6 +26,10 @@ + BUILD_DATE="March, 2008" + #END_VERSION_GENERATION + ++# Fix for connection timed out issue in: ++# https://bugzilla.redhat.com/show_bug.cgi?id=1342584 ++TIMEDOUT_DELAY = 0.5 ++ + def get_power_status(conn, options): + exp_result = 0 + outlets = {} +@@ -78,6 +82,7 @@ + res = show_re.search(line) + if res != None: + outlets[res.group(2)] = (res.group(3), res.group(4)) ++ time.sleep(TIMEDOUT_DELAY) + conn.send_eol("") + if exp_result != 0: + break +@@ -151,6 +156,7 @@ + + while 0 == conn.log_expect(options, + ["Press "] + options["--command-prompt"], int(options["--shell-timeout"])): ++ time.sleep(TIMEDOUT_DELAY) + conn.send_eol("") + + conn.send_eol(options["--plug"]+"") +@@ -171,6 +177,7 @@ + conn.log_expect(options, "Enter 'YES' to continue or to cancel :", int(options["--shell-timeout"])) + conn.send_eol("YES") + conn.log_expect(options, "Press to continue...", int(options["--shell-timeout"])) ++ time.sleep(TIMEDOUT_DELAY) + conn.send_eol("") + conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) + conn.send(chr(03)) diff --git a/SOURCES/bz1376481-1-fence_lpar-fix-monitor-fails.patch b/SOURCES/bz1376481-1-fence_lpar-fix-monitor-fails.patch new file mode 100644 index 0000000..a64131f --- /dev/null +++ b/SOURCES/bz1376481-1-fence_lpar-fix-monitor-fails.patch @@ -0,0 +1,89 @@ +commit 2a56e0b3fd7ce168afb33b57685a6b1a59a0efe6 +Author: Marek 'marx' Grac +Date: Mon Sep 19 10:21:41 2016 +0200 + + fence_lpar: Add support for IVM + +diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py +index 31b0521..de8ce0d 100644 +--- a/fence/agents/lpar/fence_lpar.py ++++ b/fence/agents/lpar/fence_lpar.py +@@ -32,7 +32,7 @@ def get_power_status(conn, options): + re.IGNORECASE | re.MULTILINE).search(conn.before).group(1) + except AttributeError: + fail(EC_STATUS_HMC) +- elif options["--hmc-version"] == "4": ++ elif options["--hmc-version"] in ["4", "IVM"]: + conn.send("lssyscfg -r lpar -m "+ options["--managed"] + + " --filter 'lpar_names=" + options["--plug"] + "'\n") + conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) +@@ -56,7 +56,7 @@ def set_power_status(conn, options): + conn.send("chsysstate -o " + options["--action"] + " -r lpar -m " + options["--managed"] + + " -n " + options["--plug"] + "\n") + conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) +- elif options["--hmc-version"] == "4": ++ elif options["--hmc-version"] in ["4", "IVM"]: + if options["--action"] == "on": + conn.send("chsysstate -o on -r lpar -m " + options["--managed"] + + " -n " + options["--plug"] + +@@ -98,7 +98,29 @@ def get_lpar_list(conn, options): + + lines = res.group(1).split("\n") + for outlet_line in lines: +- (port, status) = outlet_line.split(":") ++ try: ++ (port, status) = outlet_line.split(":") ++ except ValueError: ++ fail_usage('Output does not match expected HMC version, try different one'); ++ outlets[port] = ("", status) ++ elif options["--hmc-version"] == "IVM": ++ conn.send("lssyscfg -r lpar -m " + options["--managed"] + ++ " -F name,state\n") ++ conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"])) ++ ++ ## We have to remove first line (command) and last line (part of new prompt) ++ #### ++ res = re.search("^.+?\n(.*)\n.*$", conn.before, re.S) ++ ++ if res == None: ++ fail_usage("Unable to parse output of list command") ++ ++ lines = res.group(1).split("\n") ++ for outlet_line in lines: ++ try: ++ (port, status) = outlet_line.split(",") ++ except ValueError: ++ fail_usage('Output does not match expected HMC version, try different one'); + outlets[port] = ("", status) + + return outlets +@@ -114,11 +136,11 @@ def define_new_opts(): + all_opt["hmc_version"] = { + "getopt" : "H:", + "longopt" : "hmc-version", +- "help" : "-H, --hmc-version=[version] Force HMC version to use: 3, 4 (default)", ++ "help" : "-H, --hmc-version=[version] Force HMC version to use: 3, 4 (default), ivm", + "required" : "0", +- "shortdesc" : "Force HMC version to use (3 or 4)", ++ "shortdesc" : "Force HMC version to use (3, 4 or IVM)", + "default" : "4", +- "choices" : ["3", "4"], ++ "choices" : ["3", "4", "ivm"], + "order" : 1} + + def main(): +diff --git a/tests/data/metadata/fence_lpar.xml b/tests/data/metadata/fence_lpar.xml +index 8c82925..199ca4e 100644 +--- a/tests/data/metadata/fence_lpar.xml ++++ b/tests/data/metadata/fence_lpar.xml +@@ -48,8 +48,9 @@ + + +- Force HMC version to use (3 or 4) ++ Force HMC version to use (3, 4 or IVM) + + + diff --git a/SOURCES/bz1376481-2-fence_lpar-fix-monitor-fails.patch b/SOURCES/bz1376481-2-fence_lpar-fix-monitor-fails.patch new file mode 100644 index 0000000..abc7a91 --- /dev/null +++ b/SOURCES/bz1376481-2-fence_lpar-fix-monitor-fails.patch @@ -0,0 +1,47 @@ +commit ef243397975d263ac886d71596581b08ecf234c5 +Author: Marek 'marx' Grac +Date: Mon Sep 19 12:55:57 2016 +0200 + + fence_lpar: Fix indentation + +diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py +index de8ce0d..2ba2bbe 100644 +--- a/fence/agents/lpar/fence_lpar.py ++++ b/fence/agents/lpar/fence_lpar.py +@@ -98,10 +98,10 @@ def get_lpar_list(conn, options): + + lines = res.group(1).split("\n") + for outlet_line in lines: +- try: ++ try: + (port, status) = outlet_line.split(":") +- except ValueError: +- fail_usage('Output does not match expected HMC version, try different one'); ++ except ValueError: ++ fail_usage('Output does not match expected HMC version, try different one'); + outlets[port] = ("", status) + elif options["--hmc-version"] == "IVM": + conn.send("lssyscfg -r lpar -m " + options["--managed"] + +@@ -117,10 +117,10 @@ def get_lpar_list(conn, options): + + lines = res.group(1).split("\n") + for outlet_line in lines: +- try: ++ try: + (port, status) = outlet_line.split(",") +- except ValueError: +- fail_usage('Output does not match expected HMC version, try different one'); ++ except ValueError: ++ fail_usage('Output does not match expected HMC version, try different one'); + outlets[port] = ("", status) + + return outlets +@@ -145,7 +145,7 @@ def define_new_opts(): + + def main(): + device_opt = ["ipaddr", "login", "passwd", "secure", "cmd_prompt", \ +- "port", "managed", "hmc_version"] ++ "port", "managed", "hmc_version"] + + atexit.register(atexit_handler) + diff --git a/SOURCES/bz1377389-fence_ipmilan-add-target-support.patch b/SOURCES/bz1377389-fence_ipmilan-add-target-support.patch new file mode 100644 index 0000000..4a2f43d --- /dev/null +++ b/SOURCES/bz1377389-fence_ipmilan-add-target-support.patch @@ -0,0 +1,148 @@ +diff -uNr a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py +--- a/fence/agents/ipmilan/fence_ipmilan.py 2017-05-04 14:32:36.357497106 +0200 ++++ b/fence/agents/ipmilan/fence_ipmilan.py 2017-05-04 14:37:32.567801127 +0200 +@@ -39,9 +39,18 @@ + cmd += " -I lanplus" + else: + cmd += " -I lan" ++ + # --ip / -a + cmd += " -H " + options["--ip"] + ++ # --port / -n ++ if options.has_key("--ipport"): ++ cmd += " -p " + options["--ipport"] ++ ++ # --target ++ if "--target" in options: ++ cmd += " -t " + options["--target"] ++ + # --username / -l + if options.has_key("--username") and len(options["--username"]) != 0: + cmd += " -U " + quote(options["--username"]) +@@ -60,10 +69,6 @@ + if "--cipher" in options: + cmd += " -C " + options["--cipher"] + +- # --port / -n +- if options.has_key("--ipport"): +- cmd += " -p " + options["--ipport"] +- + if options.has_key("--privlvl"): + cmd += " -L " + options["--privlvl"] + +@@ -123,6 +128,14 @@ + "default" : "@IPMITOOL_PATH@", + "order": 200 + } ++ all_opt["target"] = { ++ "getopt" : ":", ++ "longopt" : "target", ++ "help" : "--target=[targetaddress] Bridge IPMI requests to the remote target address", ++ "required" : "0", ++ "shortdesc" : "Bridge IPMI requests to the remote target address", ++ "order": 1 ++ } + all_opt["obsolete_ip"] = { + "getopt" : "i:", + "longopt" : "obsolete-ip", +@@ -141,9 +154,9 @@ + def main(): + atexit.register(atexit_handler) + +- device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd", "diag", +- "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method", +- "obsolete_ip", "timeout"] ++ device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd", ++ "diag", "lanplus", "auth", "cipher", "privlvl", "sudo", ++ "ipmitool_path", "method", "target", "obsolete_ip", "timeout"] + define_new_opts() + + all_opt["power_wait"]["default"] = 2 +diff -uNr a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +--- a/fence/agents/lib/fencing.py.py 2017-05-04 14:32:36.408496642 +0200 ++++ b/fence/agents/lib/fencing.py.py 2017-05-04 14:33:30.160007419 +0200 +@@ -845,7 +845,7 @@ + device_opt.count("login") and (device_opt.count("no_login") == 0): + fail_usage("Failed: You have to set login name") + +- if device_opt.count("ipaddr") and not options.has_key("--ip") and not options.has_key("--managed"): ++ if device_opt.count("ipaddr") and not options.has_key("--ip") and not options.has_key("--managed") and not options.has_key("--target"): + fail_usage("Failed: You have to enter fence address") + + if device_opt.count("no_password") == 0: +diff -uNr a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +--- a/tests/data/metadata/fence_idrac.xml 2017-05-04 14:32:36.410496624 +0200 ++++ b/tests/data/metadata/fence_idrac.xml 2017-05-04 14:33:30.160007419 +0200 +@@ -74,6 +74,11 @@ + + Ciphersuite to use (same as ipmitool -C parameter) + ++ ++ ++ ++ Bridge IPMI requests to the remote target address ++ + + + +diff -uNr a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +--- a/tests/data/metadata/fence_ilo3.xml 2017-05-04 14:32:36.411496614 +0200 ++++ b/tests/data/metadata/fence_ilo3.xml 2017-05-04 14:33:30.161007410 +0200 +@@ -74,6 +74,11 @@ + + Ciphersuite to use (same as ipmitool -C parameter) + ++ ++ ++ ++ Bridge IPMI requests to the remote target address ++ + + + +diff -uNr a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +--- a/tests/data/metadata/fence_ilo4.xml 2017-05-04 14:32:36.411496614 +0200 ++++ b/tests/data/metadata/fence_ilo4.xml 2017-05-04 14:33:30.161007410 +0200 +@@ -74,6 +74,11 @@ + + Ciphersuite to use (same as ipmitool -C parameter) + ++ ++ ++ ++ Bridge IPMI requests to the remote target address ++ + + + +diff -uNr a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +--- a/tests/data/metadata/fence_imm.xml 2017-05-04 14:32:36.412496605 +0200 ++++ b/tests/data/metadata/fence_imm.xml 2017-05-04 14:33:30.162007401 +0200 +@@ -74,6 +74,11 @@ + + Ciphersuite to use (same as ipmitool -C parameter) + ++ ++ ++ ++ Bridge IPMI requests to the remote target address ++ + + + +diff -uNr a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +--- a/tests/data/metadata/fence_ipmilan.xml 2017-05-04 14:32:36.412496605 +0200 ++++ b/tests/data/metadata/fence_ipmilan.xml 2017-05-04 14:33:30.162007401 +0200 +@@ -74,6 +74,11 @@ + + Ciphersuite to use (same as ipmitool -C parameter) + ++ ++ ++ ++ Bridge IPMI requests to the remote target address ++ + + + diff --git a/SOURCES/bz1377972-1-CI-dont-test-paths-in-metadata.patch b/SOURCES/bz1377972-1-CI-dont-test-paths-in-metadata.patch new file mode 100644 index 0000000..09ded8e --- /dev/null +++ b/SOURCES/bz1377972-1-CI-dont-test-paths-in-metadata.patch @@ -0,0 +1,3046 @@ +diff -uNr a/configure.ac b/configure.ac +--- a/configure.ac 2017-03-03 10:46:36.346404128 +0100 ++++ b/configure.ac 2017-03-03 11:18:02.533241361 +0100 +@@ -258,6 +258,7 @@ + CPPFLAGS="-I\$(top_builddir)/make -I\$(top_srcdir)/make -I. $ENV_CPPFLAGS" + LDFLAGS="$ENV_LDFLAGS" + ++AM_EXTRA_RECURSIVE_TARGETS([xml-upload]) + AC_CONFIG_FILES([Makefile + fence/Makefile + fence/agents/Makefile +diff -uNr a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +--- a/fence/agents/lib/fencing.py.py 2017-03-03 10:46:36.349404099 +0100 ++++ b/fence/agents/lib/fencing.py.py 2017-03-03 11:18:02.534241351 +0100 +@@ -69,6 +69,7 @@ + "delay" : { + "getopt" : "f:", + "longopt" : "delay", ++ "type" : "second", + "help" : "--delay=[seconds] Wait X seconds before fencing is started", + "required" : "0", + "shortdesc" : "Wait X seconds before fencing is started", +@@ -108,6 +109,7 @@ + "ipport" : { + "getopt" : "u:", + "longopt" : "ipport", ++ "type" : "integer", + "help" : "-u, --ipport=[port] TCP/UDP port to use", + "required" : "0", + "shortdesc" : "TCP/UDP port to use for connection with device", +@@ -340,6 +342,7 @@ + "login_timeout" : { + "getopt" : "y:", + "longopt" : "login-timeout", ++ "type" : "second", + "help" : "--login-timeout=[seconds] Wait X seconds for cmd prompt after login", + "default" : "5", + "required" : "0", +@@ -348,6 +351,7 @@ + "shell_timeout" : { + "getopt" : "Y:", + "longopt" : "shell-timeout", ++ "type" : "second", + "help" : "--shell-timeout=[seconds] Wait X seconds for cmd prompt after issuing command", + "default" : "3", + "required" : "0", +@@ -356,6 +360,7 @@ + "power_timeout" : { + "getopt" : "g:", + "longopt" : "power-timeout", ++ "type" : "second", + "help" : "--power-timeout=[seconds] Test X seconds for status change after ON/OFF", + "default" : "20", + "required" : "0", +@@ -364,6 +369,7 @@ + "power_wait" : { + "getopt" : "G:", + "longopt" : "power-wait", ++ "type" : "second", + "help" : "--power-wait=[seconds] Wait X seconds after issuing ON/OFF", + "default" : "0", + "required" : "0", +@@ -379,6 +385,7 @@ + "retry_on" : { + "getopt" : "F:", + "longopt" : "retry-on", ++ "type" : "integer", + "help" : "--retry-on=[attempts] Count of attempts to retry power on", + "default" : "1", + "required" : "0", +@@ -567,7 +574,8 @@ + print "\t\t\t" + elif all_opt[option]["getopt"].count(":") > 0: +- print "\t\t" ++ t = all_opt[option].get("type", "string") ++ print("\t\t") + else: + print "\t\t" + +@@ -859,6 +867,14 @@ + "for %s from the valid values: %s" % \ + ("--" + all_opt[opt]["longopt"], str(all_opt[opt]["choices"]))) + ++ for failed_opt in _get_opts_with_invalid_types(options): ++ valid_input = False ++ if all_opt[failed_opt]["type"] == "second": ++ fail_usage("Failed: The value you have entered for %s is not a valid time in seconds" % \ ++ ("--" + all_opt[failed_opt]["longopt"])) ++ else: ++ fail_usage("Failed: The value you have entered for %s is not a valid %s" % \ ++ ("--" + all_opt[failed_opt]["longopt"], all_opt[failed_opt]["type"])) + return options + + ## Obtain a power status from possibly more than one plug +@@ -1265,3 +1281,18 @@ + # syslos.syslog can not have 0x00 character inside or exception is thrown + syslog.syslog(syslog_level, msg.replace("\x00","\n")) + return ++ ++def _get_opts_with_invalid_types(options): ++ options_failed = [] ++ device_opt = options["device_opt"] ++ ++ for opt in device_opt: ++ if "type" in all_opt[opt]: ++ longopt = "--" + all_opt[opt]["longopt"] ++ if longopt in options: ++ if all_opt[opt]["type"] in ["integer", "second"]: ++ try: ++ number = int(options["--" + all_opt[opt]["longopt"]]) ++ except ValueError: ++ options_failed.append(opt) ++ return options_failed +diff -uNr a/fence/agents/lib/metadata.rng b/fence/agents/lib/metadata.rng +--- a/fence/agents/lib/metadata.rng 2014-08-06 09:35:08.000000000 +0200 ++++ b/fence/agents/lib/metadata.rng 2017-03-03 11:18:02.534241351 +0100 +@@ -29,6 +29,8 @@ + + boolean + string ++ second ++ integer + + + +diff -uNr a/fence/agents/zvm/fence_zvmip.py b/fence/agents/zvm/fence_zvmip.py +--- a/fence/agents/zvm/fence_zvmip.py 2017-03-03 10:46:36.279404777 +0100 ++++ b/fence/agents/zvm/fence_zvmip.py 2017-03-03 11:18:02.534241351 +0100 +@@ -156,7 +156,7 @@ + atexit.register(atexit_handler) + + all_opt["ipport"]["default"] = "44444" +- all_opt["shell_timeout"]["default"] = "5.0" ++ all_opt["shell_timeout"]["default"] = "5" + all_opt["missing_as_off"]["default"] = "1" + options = check_input(device_opt, process_input(device_opt)) + +diff -uNr a/make/agentccheck.mk b/make/agentccheck.mk +--- a/make/agentccheck.mk 2017-03-03 10:46:36.256405000 +0100 ++++ b/make/agentccheck.mk 2017-03-03 11:18:02.534241351 +0100 +@@ -2,6 +2,7 @@ + DATADIR:=$(abs_top_srcdir)/tests/data/metadata + + check: $(TARGET:%=xml-check.%) $(SYMTARGET:%=xml-check.%) ++xml-upload: $(TARGET:%=xml-upload.%) $(SYMTARGET:%=xml-upload.%) + + xml-check.%: % + $(eval INPUT=$(subst xml-check.,,$@)) +diff -uNr a/make/agentpycheck.mk b/make/agentpycheck.mk +--- a/make/agentpycheck.mk 2017-03-03 10:46:36.257404990 +0100 ++++ b/make/agentpycheck.mk 2017-03-03 11:18:02.534241351 +0100 +@@ -1,18 +1,19 @@ + TEMPFILE:=$(shell mktemp) +-#DATADIR:=$(abs_top_builddir)/tests/data/metadata + DATADIR:=$(abs_top_srcdir)/tests/data/metadata ++AWK_VAL='BEGIN {store=-1} /name=\".*_path\"/ {store=2} {if (store!=0) {print}; store--}' + + check: $(TARGET:%=xml-check.%) $(SYMTARGET:%=xml-check.%) $(TARGET:%=delay-check.%) ++xml-upload: $(TARGET:%=xml-upload.%) $(SYMTARGET:%=xml-upload.%) + + xml-check.%: % + $(eval INPUT=$(subst xml-check.,,$@)) +- PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib python ./$(INPUT) -o metadata > $(TEMPFILE) ++ PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib python ./$(INPUT) -o metadata | $(AWK) $(AWK_VAL) > $(TEMPFILE) + diff $(TEMPFILE) $(DATADIR)/$(INPUT).xml + rm $(TEMPFILE) + + xml-upload.%: % + $(eval INPUT=$(subst xml-upload.,,$@)) +- PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib python ./$(INPUT) -o metadata > $(DATADIR)/$(INPUT).xml ++ PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib python ./$(INPUT) -o metadata | $(AWK) $(AWK_VAL) > $(DATADIR)/$(INPUT).xml + + # If test will fail, rerun fence agents to show problems + delay-check.%: % +diff -uNr a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml +--- a/tests/data/metadata/fence_alom.xml 2017-03-03 10:46:36.297404603 +0100 ++++ b/tests/data/metadata/fence_alom.xml 2017-03-03 11:18:37.279904806 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -90,27 +90,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -120,7 +120,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml +--- a/tests/data/metadata/fence_amt.xml 2017-03-03 10:46:36.297404603 +0100 ++++ b/tests/data/metadata/fence_amt.xml 2017-03-03 11:18:38.389894055 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -84,32 +84,31 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- + Path to amttool binary + + +@@ -119,7 +118,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_apc_snmp.xml b/tests/data/metadata/fence_apc_snmp.xml +--- a/tests/data/metadata/fence_apc_snmp.xml 2017-03-03 10:46:36.291404661 +0100 ++++ b/tests/data/metadata/fence_apc_snmp.xml 2017-03-03 11:18:38.158896292 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -124,32 +124,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_apc.xml b/tests/data/metadata/fence_apc.xml +--- a/tests/data/metadata/fence_apc.xml 2017-03-03 10:46:36.291404661 +0100 ++++ b/tests/data/metadata/fence_apc.xml 2017-03-03 11:18:38.806890016 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -100,32 +100,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_bladecenter.xml b/tests/data/metadata/fence_bladecenter.xml +--- a/tests/data/metadata/fence_bladecenter.xml 2017-03-03 10:46:36.291404661 +0100 ++++ b/tests/data/metadata/fence_bladecenter.xml 2017-03-03 11:18:38.428893677 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -95,27 +95,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -125,7 +125,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_brocade.xml b/tests/data/metadata/fence_brocade.xml +--- a/tests/data/metadata/fence_brocade.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_brocade.xml 2017-03-03 11:18:38.582892186 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -95,32 +95,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_cisco_mds.xml b/tests/data/metadata/fence_cisco_mds.xml +--- a/tests/data/metadata/fence_cisco_mds.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_cisco_mds.xml 2017-03-03 11:18:38.844889648 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -124,32 +124,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +--- a/tests/data/metadata/fence_cisco_ucs.xml 2017-03-03 10:46:36.321404371 +0100 ++++ b/tests/data/metadata/fence_cisco_ucs.xml 2017-03-03 11:18:38.768890384 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -100,22 +100,22 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + +@@ -125,12 +125,12 @@ + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +--- a/tests/data/metadata/fence_compute.xml 2017-03-03 10:46:36.335404235 +0100 ++++ b/tests/data/metadata/fence_compute.xml 2017-03-03 11:18:39.219886015 +0100 +@@ -3,6 +3,11 @@ + Used to tell Nova that compute nodes are down and to reschedule flagged instances + + ++ ++ ++ ++ Region Name ++ + + + +@@ -14,7 +19,7 @@ + Script to retrieve password + + +- ++ + + Keystone Admin Auth URL + +@@ -43,6 +48,11 @@ + + Login Name + ++ ++ ++ ++ Allow Insecure TLS Requests ++ + + + +@@ -90,32 +100,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml +--- a/tests/data/metadata/fence_docker.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_docker.xml 2017-03-03 11:18:37.620901503 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -98,32 +98,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_drac5.xml b/tests/data/metadata/fence_drac5.xml +--- a/tests/data/metadata/fence_drac5.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_drac5.xml 2017-03-03 11:18:37.317904438 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -104,32 +104,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml +--- a/tests/data/metadata/fence_drac.xml 2017-03-03 10:46:36.298404593 +0100 ++++ b/tests/data/metadata/fence_drac.xml 2017-03-03 11:18:38.234895556 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -75,27 +75,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -105,7 +105,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_dummy.xml b/tests/data/metadata/fence_dummy.xml +--- a/tests/data/metadata/fence_dummy.xml 2017-03-03 10:46:36.298404593 +0100 ++++ b/tests/data/metadata/fence_dummy.xml 2017-03-03 11:18:37.433903315 +0100 +@@ -45,32 +45,32 @@ + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_eaton_snmp.xml b/tests/data/metadata/fence_eaton_snmp.xml +--- a/tests/data/metadata/fence_eaton_snmp.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_eaton_snmp.xml 2017-03-03 11:18:38.541892583 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -124,32 +124,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +--- a/tests/data/metadata/fence_emerson.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_emerson.xml 2017-03-03 11:18:38.120896660 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -124,32 +124,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml +--- a/tests/data/metadata/fence_eps.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_eps.xml 2017-03-03 11:18:37.477902888 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -82,32 +82,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_hds_cb.xml b/tests/data/metadata/fence_hds_cb.xml +--- a/tests/data/metadata/fence_hds_cb.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_hds_cb.xml 2017-03-03 11:18:38.196895924 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -95,27 +95,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -125,7 +125,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_hpblade.xml b/tests/data/metadata/fence_hpblade.xml +--- a/tests/data/metadata/fence_hpblade.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_hpblade.xml 2017-03-03 11:18:37.961898200 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -95,27 +95,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -125,7 +125,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ibmblade.xml b/tests/data/metadata/fence_ibmblade.xml +--- a/tests/data/metadata/fence_ibmblade.xml 2017-03-03 10:46:36.292404652 +0100 ++++ b/tests/data/metadata/fence_ibmblade.xml 2017-03-03 11:18:38.920888912 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -124,32 +124,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +--- a/tests/data/metadata/fence_idrac.xml 2017-03-03 10:46:36.349404099 +0100 ++++ b/tests/data/metadata/fence_idrac.xml 2017-03-03 11:18:37.924898559 +0100 +@@ -9,7 +9,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -121,32 +121,31 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- + Path to ipmitool binary + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -156,7 +155,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ifmib.xml b/tests/data/metadata/fence_ifmib.xml +--- a/tests/data/metadata/fence_ifmib.xml 2017-03-03 10:46:36.293404642 +0100 ++++ b/tests/data/metadata/fence_ifmib.xml 2017-03-03 11:18:37.744900302 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -126,32 +126,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +--- a/tests/data/metadata/fence_ilo2.xml 2017-03-03 10:46:36.298404593 +0100 ++++ b/tests/data/metadata/fence_ilo2.xml 2017-03-03 11:18:38.082897028 +0100 +@@ -6,7 +6,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -101,27 +101,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -131,7 +131,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +--- a/tests/data/metadata/fence_ilo3_ssh.xml 2017-03-03 10:46:36.298404593 +0100 ++++ b/tests/data/metadata/fence_ilo3_ssh.xml 2017-03-03 11:18:37.547902210 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -100,27 +100,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -130,7 +130,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +--- a/tests/data/metadata/fence_ilo3.xml 2017-03-03 10:46:36.349404099 +0100 ++++ b/tests/data/metadata/fence_ilo3.xml 2017-03-03 11:18:37.819899576 +0100 +@@ -9,7 +9,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -121,32 +121,31 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- + Path to ipmitool binary + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -156,7 +155,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +--- a/tests/data/metadata/fence_ilo4_ssh.xml 2017-03-03 10:46:36.298404593 +0100 ++++ b/tests/data/metadata/fence_ilo4_ssh.xml 2017-03-03 11:18:37.580901891 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -100,27 +100,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -130,7 +130,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +--- a/tests/data/metadata/fence_ilo4.xml 2017-03-03 10:46:36.350404090 +0100 ++++ b/tests/data/metadata/fence_ilo4.xml 2017-03-03 11:18:37.854899237 +0100 +@@ -9,7 +9,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -121,32 +121,31 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- + Path to ipmitool binary + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -156,7 +155,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo_moonshot.xml b/tests/data/metadata/fence_ilo_moonshot.xml +--- a/tests/data/metadata/fence_ilo_moonshot.xml 2017-03-03 10:46:36.293404642 +0100 ++++ b/tests/data/metadata/fence_ilo_moonshot.xml 2017-03-03 11:18:38.272895188 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -95,32 +95,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml +--- a/tests/data/metadata/fence_ilo_mp.xml 2017-03-03 10:46:36.298404593 +0100 ++++ b/tests/data/metadata/fence_ilo_mp.xml 2017-03-03 11:18:38.619891827 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -90,27 +90,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -120,7 +120,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +--- a/tests/data/metadata/fence_ilo_ssh.xml 2017-03-03 10:46:36.298404593 +0100 ++++ b/tests/data/metadata/fence_ilo_ssh.xml 2017-03-03 11:18:37.515902520 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -100,27 +100,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -130,7 +130,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +--- a/tests/data/metadata/fence_ilo.xml 2017-03-03 10:46:36.298404593 +0100 ++++ b/tests/data/metadata/fence_ilo.xml 2017-03-03 11:18:38.043897406 +0100 +@@ -6,7 +6,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -101,27 +101,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -131,7 +131,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +--- a/tests/data/metadata/fence_imm.xml 2017-03-03 10:46:36.350404090 +0100 ++++ b/tests/data/metadata/fence_imm.xml 2017-03-03 11:18:37.889898898 +0100 +@@ -9,7 +9,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -121,32 +121,31 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- + Path to ipmitool binary + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -156,7 +155,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_intelmodular.xml b/tests/data/metadata/fence_intelmodular.xml +--- a/tests/data/metadata/fence_intelmodular.xml 2017-03-03 10:46:36.293404642 +0100 ++++ b/tests/data/metadata/fence_intelmodular.xml 2017-03-03 11:18:38.655891478 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -126,32 +126,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ipdu.xml b/tests/data/metadata/fence_ipdu.xml +--- a/tests/data/metadata/fence_ipdu.xml 2017-03-03 10:46:36.293404642 +0100 ++++ b/tests/data/metadata/fence_ipdu.xml 2017-03-03 11:18:38.956888563 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -124,32 +124,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +--- a/tests/data/metadata/fence_ipmilan.xml 2017-03-03 10:46:36.350404090 +0100 ++++ b/tests/data/metadata/fence_ipmilan.xml 2017-03-03 11:18:37.784899915 +0100 +@@ -9,7 +9,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -121,32 +121,31 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- + Path to ipmitool binary + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -156,7 +155,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ldom.xml b/tests/data/metadata/fence_ldom.xml +--- a/tests/data/metadata/fence_ldom.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_ldom.xml 2017-03-03 11:18:39.153886655 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -97,32 +97,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_lpar.xml b/tests/data/metadata/fence_lpar.xml +--- a/tests/data/metadata/fence_lpar.xml 2017-03-03 10:46:36.351404080 +0100 ++++ b/tests/data/metadata/fence_lpar.xml 2017-03-03 11:18:38.350894433 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -109,32 +109,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +--- a/tests/data/metadata/fence_mpath.xml 2017-03-03 10:46:36.332404264 +0100 ++++ b/tests/data/metadata/fence_mpath.xml 2017-03-03 11:18:38.994888195 +0100 +@@ -4,20 +4,20 @@ + The fence_mpath agent works by having a unique key for each node that has to be set in /etc/multipath.conf. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_mpath agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. + https://www.sourceware.org/dm/ + +- +- +- +- List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). Each device must support SCSI-3 persistent reservations. ++ ++ ++ ++ Fencing Action + + + + + Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s). + +- +- +- +- Fencing Action ++ ++ ++ ++ List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). Each device must support SCSI-3 persistent reservations. + + + +@@ -39,44 +39,42 @@ + + Display help and exit + +- +- +- +- Wait X seconds before fencing is started +- +- +- +- +- Wait X seconds for cmd prompt after issuing command +- +- +- +- +- Path to directory where fence agent can store information +- +- +- +- +- Test X seconds for status change after ON/OFF +- + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ + + +- + Path to mpathpersist binary + ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ Path to directory where fence agent can store information ++ + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_netio.xml b/tests/data/metadata/fence_netio.xml +--- a/tests/data/metadata/fence_netio.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_netio.xml 2017-03-03 11:18:38.466893309 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -75,32 +75,32 @@ + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_ovh.xml b/tests/data/metadata/fence_ovh.xml +--- a/tests/data/metadata/fence_ovh.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_ovh.xml 2017-03-03 11:18:37.202905552 +0100 +@@ -60,32 +60,32 @@ + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_pve.xml b/tests/data/metadata/fence_pve.xml +--- a/tests/data/metadata/fence_pve.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_pve.xml 2017-03-03 11:18:39.114887033 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -80,32 +80,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_raritan.xml b/tests/data/metadata/fence_raritan.xml +--- a/tests/data/metadata/fence_raritan.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_raritan.xml 2017-03-03 11:18:38.728890771 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -75,32 +75,32 @@ + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +--- a/tests/data/metadata/fence_rhevm.xml 2017-03-03 10:46:36.343404157 +0100 ++++ b/tests/data/metadata/fence_rhevm.xml 2017-03-03 11:18:38.882889280 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -75,7 +75,6 @@ + + + +- + The path of the API URL + + +@@ -105,32 +104,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml +--- a/tests/data/metadata/fence_rsa.xml 2017-03-03 10:46:36.299404584 +0100 ++++ b/tests/data/metadata/fence_rsa.xml 2017-03-03 11:18:38.692891120 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -90,27 +90,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -120,7 +120,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml +--- a/tests/data/metadata/fence_rsb.xml 2017-03-03 10:46:36.299404584 +0100 ++++ b/tests/data/metadata/fence_rsb.xml 2017-03-03 11:18:39.069887468 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -90,27 +90,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -120,7 +120,7 @@ + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_sanbox2.xml b/tests/data/metadata/fence_sanbox2.xml +--- a/tests/data/metadata/fence_sanbox2.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_sanbox2.xml 2017-03-03 11:18:39.032887827 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -80,32 +80,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_sbd.xml b/tests/data/metadata/fence_sbd.xml +--- a/tests/data/metadata/fence_sbd.xml 2017-03-03 10:46:36.346404128 +0100 ++++ b/tests/data/metadata/fence_sbd.xml 2017-03-03 11:18:38.504892941 +0100 +@@ -3,11 +3,6 @@ + fence_sbd is I/O Fencing agent which can be used in environments where sbd can be used (shared storage). + + +- +- +- +- Fencing action +- + + + +@@ -19,12 +14,17 @@ + +- Method to fence ++ Method to fence (onoff|cycle) ++ ++ ++ ++ ++ Fencing Action + + + + +- Physical plug number on device, UUID or identification of machine ++ Physical plug number, name of virtual machine or UUID + + + +@@ -49,41 +49,40 @@ + + + +- Separator for CSV created by 'list' operation ++ Separator for CSV created by operation list + +- +- +- +- Wait X seconds before fencing is started ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command + +- +- +- +- Wait X seconds for cmd prompt after login ++ ++ ++ ++ Wait X seconds after issuing ON/OFF + + + +- ++ + Test X seconds for status change after ON/OFF + +- +- +- +- Wait X seconds after issuing ON/OFF ++ ++ ++ ++ Wait X seconds before fencing is started + + + +- + Path to SBD binary + +- +- +- +- Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ Wait X seconds for cmd prompt after login + + + +- ++ + Count of attempts to retry power on + + +@@ -96,6 +95,5 @@ + + + +- + + +diff -uNr a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +--- a/tests/data/metadata/fence_scsi.xml 2017-03-03 10:46:36.332404264 +0100 ++++ b/tests/data/metadata/fence_scsi.xml 2017-03-03 11:18:37.660901116 +0100 +@@ -56,52 +56,48 @@ + + + +- + Path to vgs binary + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- + Path to sg_persist binary + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- + Path to sg_turs binary + + + +- + Path to corosync-cmapctl binary + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml +--- a/tests/data/metadata/fence_virsh.xml 2017-03-03 10:46:36.323404351 +0100 ++++ b/tests/data/metadata/fence_virsh.xml 2017-03-03 11:18:37.242905165 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -97,37 +97,37 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + +- +- +- +- Missing port returns OFF instead of failure +- + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + ++ ++ ++ ++ Missing port returns OFF instead of failure ++ + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml +--- a/tests/data/metadata/fence_vmware_soap.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_vmware_soap.xml 2017-03-03 11:18:37.390903731 +0100 +@@ -7,7 +7,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -97,32 +97,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_wti.xml b/tests/data/metadata/fence_wti.xml +--- a/tests/data/metadata/fence_wti.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_wti.xml 2017-03-03 11:18:38.312894801 +0100 +@@ -5,7 +5,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -95,32 +95,32 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_xenapi.xml b/tests/data/metadata/fence_xenapi.xml +--- a/tests/data/metadata/fence_xenapi.xml 2017-03-03 10:46:36.294404632 +0100 ++++ b/tests/data/metadata/fence_xenapi.xml 2017-03-03 11:18:37.706900670 +0100 +@@ -60,32 +60,32 @@ + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Count of attempts to retry power on + + +diff -uNr a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +--- a/tests/data/metadata/fence_zvmip.xml 2017-03-03 10:46:36.295404622 +0100 ++++ b/tests/data/metadata/fence_zvmip.xml 2017-03-03 11:18:38.000897823 +0100 +@@ -19,7 +19,7 @@ + + + +- ++ + TCP/UDP port to use for connection with device + + +@@ -97,27 +97,27 @@ + + + +- ++ + Wait X seconds after issuing ON/OFF + + + +- ++ + Wait X seconds for cmd prompt after login + + + +- ++ + Test X seconds for status change after ON/OFF + + + +- ++ + Wait X seconds before fencing is started + + + +- ++ + Wait X seconds for cmd prompt after issuing command + + +@@ -127,7 +127,7 @@ + + + +- ++ + Count of attempts to retry power on + + diff --git a/SOURCES/bz1377972-2-CI-dont-test-paths-in-metadata.patch b/SOURCES/bz1377972-2-CI-dont-test-paths-in-metadata.patch new file mode 100644 index 0000000..6f3ce3f --- /dev/null +++ b/SOURCES/bz1377972-2-CI-dont-test-paths-in-metadata.patch @@ -0,0 +1,88 @@ +diff -uNr a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +--- a/tests/data/metadata/fence_rhevm.xml 2017-03-23 10:30:02.739217673 +0100 ++++ b/tests/data/metadata/fence_rhevm.xml 2017-03-23 10:31:07.439253864 +0100 +@@ -18,7 +18,7 @@ + + SSL connection with verifying fence device's certificate + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -28,7 +28,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -38,12 +38,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -68,11 +68,36 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + The path of the API URL +@@ -87,7 +112,12 @@ + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file diff --git a/SOURCES/bz1384073-fence_compute-fix-connectionerror-exception.patch b/SOURCES/bz1384073-fence_compute-fix-connectionerror-exception.patch new file mode 100644 index 0000000..a1484dd --- /dev/null +++ b/SOURCES/bz1384073-fence_compute-fix-connectionerror-exception.patch @@ -0,0 +1,22 @@ +From e7010cc1fe50866c54e98ba6775714445bdb8c80 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Mon, 17 Oct 2016 12:45:00 +0200 +Subject: [PATCH] fence_compute: fix ConnectionError by using full module name + +--- + fence/agents/compute/fence_compute.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index 0f05c12..ed51c25 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -45,7 +45,7 @@ def get_power_status(_, options): + else: + logging.debug("Unknown status detected from nova: " + service.state) + break +- except ConnectionError as err: ++ except requests.exception.ConnectionError as err: + logging.warning("Nova connection failed: " + str(err)) + return status + diff --git a/SOURCES/bz1387590-compute-fix-plug-domain-name-nova-force-down.patch b/SOURCES/bz1387590-compute-fix-plug-domain-name-nova-force-down.patch new file mode 100644 index 0000000..27e8e6f --- /dev/null +++ b/SOURCES/bz1387590-compute-fix-plug-domain-name-nova-force-down.patch @@ -0,0 +1,233 @@ +--- a/fence/agents/compute/fence_compute.py 2016-11-10 18:03:41.473498575 +1100 ++++ b/fence/agents/compute/fence_compute.py 2016-11-10 12:45:28.766603941 +1100 +@@ -45,7 +45,7 @@ def get_power_status(_, options): + else: + logging.debug("Unknown status detected from nova: " + service.state) + break +- except ConnectionError as (err): ++ except ConnectionError as err: + logging.warning("Nova connection failed: " + str(err)) + return status + +@@ -160,7 +160,7 @@ def set_power_status(_, options): + return + + if options["--action"] == "on": +- if get_power_status(_, options) == "on": ++ if get_power_status(_, options) != "on": + # Forcing the service back up in case it was disabled + nova.services.enable(options["--plug"], 'nova-compute') + try: +@@ -168,7 +168,7 @@ def set_power_status(_, options): + nova.services.force_down( + options["--plug"], "nova-compute", force_down=False) + except Exception as e: +- # In theory, if foce_down=False fails, that's for the exact ++ # In theory, if force_down=False fails, that's for the exact + # same possible reasons that below with force_down=True + # eg. either an incompatible version or an old client. + # Since it's about forcing back to a default value, there is +@@ -202,7 +202,7 @@ def set_power_status(_, options): + # + # Some callers (such as Pacemaker) will have a timer + # running and kill us if necessary +- logging.debug("Waiting for nova to update it's internal state for %s" % options["--plug"]) ++ logging.debug("Waiting for nova to update its internal state for %s" % options["--plug"]) + time.sleep(1) + + if not _host_evacuate(options): +@@ -236,49 +236,45 @@ def fix_domain(options): + # One hopes they don't appear interleaved as A.com B.com A.com B.com + logging.debug("Calculated the same domain from: %s" % hypervisor.hypervisor_hostname) + +- elif options.has_key("--domain") and options["--domain"] == calculated: ++ elif "--domain" in options and options["--domain"] == calculated: + # Supplied domain name is valid + return + +- elif options.has_key("--domain"): ++ elif "--domain" in options: + # Warn in case nova isn't available at some point + logging.warning("Supplied domain '%s' does not match the one calculated from: %s" + % (options["--domain"], hypervisor.hypervisor_hostname)) + + last_domain = calculated + +- if len(domains) == 0 and not options.has_key("--domain"): ++ if len(domains) == 0 and "--domain" not in options: + logging.error("Could not calculate the domain names used by compute nodes in nova") + +- elif len(domains) == 1 and not options.has_key("--domain"): ++ elif len(domains) == 1 and "--domain" not in options: + options["--domain"] = last_domain +- return options["--domain"] + + elif len(domains) == 1: + logging.error("Overriding supplied domain '%s' does not match the one calculated from: %s" + % (options["--domain"], hypervisor.hypervisor_hostname)) + options["--domain"] = last_domain +- return options["--domain"] + + elif len(domains) > 1: + logging.error("The supplied domain '%s' did not match any used inside nova: %s" + % (options["--domain"], repr(domains))) + sys.exit(1) + +- return None +- + def fix_plug_name(options): + if options["--action"] == "list": + return + +- if not options.has_key("--plug"): ++ if "--plug" not in options: + return + +- calculated = fix_domain(options) ++ fix_domain(options) + short_plug = options["--plug"].split('.')[0] +- logging.debug("Checking target '%s' against calculated domain '%s'"% (options["--plug"], calculated)) ++ logging.debug("Checking target '%s' against calculated domain '%s'"% (options["--plug"], options["--domain"])) + +- if not options.has_key("--domain"): ++ if "--domain" not in options: + # Nothing supplied and nova not available... what to do... nothing + return + +@@ -286,7 +282,7 @@ def fix_plug_name(options): + # Ensure any domain is stripped off since nova isn't using FQDN + options["--plug"] = short_plug + +- elif options["--plug"].find(options["--domain"]): ++ elif options["--domain"] in options["--plug"]: + # Plug already contains the domain, don't re-add + return + +@@ -306,6 +302,37 @@ def get_plugs_list(_, options): + result[shorthost] = ("", None) + return result + ++def create_nova_connection(options): ++ global nova ++ ++ try: ++ from novaclient import client ++ from novaclient.exceptions import NotAcceptable ++ except ImportError: ++ fail_usage("Nova not found or not accessible") ++ ++ versions = [ "2.11", "2" ] ++ for version in versions: ++ nova = client.Client(version, ++ options["--username"], ++ options["--password"], ++ options["--tenant-name"], ++ options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) ++ try: ++ nova.hypervisors.list() ++ return ++ ++ except NotAcceptable as e: ++ logging.warning(e) ++ ++ except Exception as e: ++ logging.warning("Nova connection failed. %s: %s" % (e.__class__.__name__, e)) ++ ++ logging.warning("Couldn't obtain a supported connection to nova, tried: %s\n" % repr(versions)) + + def define_new_opts(): + all_opt["endpoint-type"] = { +@@ -329,12 +356,30 @@ def define_new_opts(): + all_opt["auth-url"] = { + "getopt" : "k:", + "longopt" : "auth-url", +- "help" : "-k, --auth-url=[tenant] Keystone Admin Auth URL", ++ "help" : "-k, --auth-url=[url] Keystone Admin Auth URL", + "required" : "0", + "shortdesc" : "Keystone Admin Auth URL", + "default" : "", + "order": 1, + } ++ all_opt["region-name"] = { ++ "getopt" : "", ++ "longopt" : "region-name", ++ "help" : "--region-name=[region] Region Name", ++ "required" : "0", ++ "shortdesc" : "Region Name", ++ "default" : "", ++ "order": 1, ++ } ++ all_opt["insecure"] = { ++ "getopt" : "", ++ "longopt" : "insecure", ++ "help" : "--insecure Explicitly allow agent to perform \"insecure\" TLS (https) requests", ++ "required" : "0", ++ "shortdesc" : "Allow Insecure TLS Requests", ++ "default" : "False", ++ "order": 2, ++ } + all_opt["domain"] = { + "getopt" : "d:", + "longopt" : "domain", +@@ -373,12 +418,11 @@ def define_new_opts(): + + def main(): + global override_status +- global nova + atexit.register(atexit_handler) + + device_opt = ["login", "passwd", "tenant-name", "auth-url", "fabric_fencing", "on_target", + "no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type", +- "record-only", "instance-filtering"] ++ "record-only", "instance-filtering", "insecure", "region-name"] + define_new_opts() + all_opt["shell_timeout"]["default"] = "180" + +@@ -391,19 +435,15 @@ def main(): + + show_docs(options, docs) + ++ if options["--record-only"] in [ "2", "Disabled", "disabled" ]: ++ sys.exit(0) ++ + run_delay(options) + +- try: +- from novaclient import client as nova_client +- except ImportError: +- fail_usage("nova not found or not accessible") ++ create_nova_connection(options) + + fix_plug_name(options) +- +- if options["--record-only"] in [ "2", "Disabled", "disabled" ]: +- sys.exit(0) +- +- elif options["--record-only"] in [ "1", "True", "true", "Yes", "yes"]: ++ if options["--record-only"] in [ "1", "True", "true", "Yes", "yes"]: + if options["--action"] == "on": + set_attrd_status(options["--plug"], "no", options) + sys.exit(0) +@@ -412,17 +452,9 @@ def main(): + set_attrd_status(options["--plug"], "yes", options) + sys.exit(0) + +- elif options["--action"] in ["monitor"]: ++ elif options["--action"] in ["monitor", "status"]: + sys.exit(0) + +- # The first argument is the Nova client version +- nova = nova_client.Client('2', +- options["--username"], +- options["--password"], +- options["--tenant-name"], +- options["--auth-url"], +- endpoint_type=options["--endpoint-type"]) +- + if options["--action"] in ["off", "reboot"]: + # Pretend we're 'on' so that the fencing library will always call set_power_status(off) + override_status = "on" diff --git a/SOURCES/bz1390915-monitor_port_as_ip.patch b/SOURCES/bz1390915-monitor_port_as_ip.patch new file mode 100644 index 0000000..7d2585e --- /dev/null +++ b/SOURCES/bz1390915-monitor_port_as_ip.patch @@ -0,0 +1,30 @@ +From a22d964c8a4d21fa3cca5f4b8e284319d77c4779 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 27 Jul 2015 11:02:31 +0200 +Subject: [PATCH] fencing: If --port-as-ip is used then monitor action should + be 'status', not 'list' + +Resolves: rhbz#1390915 +--- + fence/agents/lib/fencing.py.py | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 1cc1eb0..8fa81c7 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -940,8 +940,9 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list=None, + + ## Process options that manipulate fencing device + ##### +- if options["--action"] in ["list", "list-status"] or \ +- ((options["--action"] == "monitor") and 1 == options["device_opt"].count("port")): ++ if (options["--action"] in ["list", "list-status"]) or \ ++ ((options["--action"] == "monitor") and 1 == options["device_opt"].count("port") and \ ++ 0 == options["device_opt"].count("port_as_ip")): + + if 0 == options["device_opt"].count("port"): + print "N/A" +-- +2.4.11 + diff --git a/SOURCES/bz1393962-fence_vmware_soap-ssl-insecure-suppress-warning.patch b/SOURCES/bz1393962-fence_vmware_soap-ssl-insecure-suppress-warning.patch new file mode 100644 index 0000000..2d93a82 --- /dev/null +++ b/SOURCES/bz1393962-fence_vmware_soap-ssl-insecure-suppress-warning.patch @@ -0,0 +1,22 @@ +From 9a7be1c6f8deb73070b12baa2332cd26ef17d0cd Mon Sep 17 00:00:00 2001 +From: Isaac Freeman +Date: Mon, 21 Nov 2016 11:30:05 -0500 +Subject: [PATCH] Suppress InsecureRequestWarning when ssl_insecure is given + +--- + fence/agents/vmware_soap/fence_vmware_soap.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py +index df84ae5..93f9658 100644 +--- a/fence/agents/vmware_soap/fence_vmware_soap.py ++++ b/fence/agents/vmware_soap/fence_vmware_soap.py +@@ -42,6 +42,8 @@ def soap_login(options): + + if options.has_key("--ssl") or options.has_key("--ssl-secure") or options.has_key("--ssl-insecure"): + if options.has_key("--ssl-insecure"): ++ from requests.packages.urllib3.exceptions import InsecureRequestWarning ++ requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + verify = False + else: + verify = True diff --git a/SOURCES/bz1403028-fencing-parameters_stdin.patch b/SOURCES/bz1403028-fencing-parameters_stdin.patch new file mode 100644 index 0000000..7654637 --- /dev/null +++ b/SOURCES/bz1403028-fencing-parameters_stdin.patch @@ -0,0 +1,4932 @@ +From ba136b80c495bf867eb71afbf295f84f36132d46 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 22 Mar 2017 17:32:38 +0100 +Subject: [PATCH] fencing: Parameters from command-line can be used also on + STDIN + +Resolves: rhbz#1403028 +--- + fence/agents/lib/fence2man.xsl | 6 +++ + fence/agents/lib/fencing.py.py | 56 ++++++++++++++------ + fence/agents/lib/metadata.rng | 3 +- + tests/data/metadata/fence_alom.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_amt.xml | 42 ++++++++++++--- + tests/data/metadata/fence_amt_ws.xml | 35 +++++++++++-- + tests/data/metadata/fence_apc.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_apc_snmp.xml | 42 ++++++++++++--- + tests/data/metadata/fence_bladecenter.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_brocade.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_cisco_mds.xml | 42 ++++++++++++--- + tests/data/metadata/fence_cisco_ucs.xml | 42 ++++++++++++--- + tests/data/metadata/fence_compute.xml | 84 +++++++++++++++++++++++++----- + tests/data/metadata/fence_docker.xml | 21 ++++++-- + tests/data/metadata/fence_drac.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_drac5.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_dummy.xml | 7 ++- + tests/data/metadata/fence_eaton_snmp.xml | 42 ++++++++++++--- + tests/data/metadata/fence_emerson.xml | 42 ++++++++++++--- + tests/data/metadata/fence_eps.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_hds_cb.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_hpblade.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_ibmblade.xml | 42 ++++++++++++--- + tests/data/metadata/fence_idrac.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_ifmib.xml | 42 ++++++++++++--- + tests/data/metadata/fence_ilo.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_ilo2.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_ilo3.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_ilo3_ssh.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_ilo4.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_ilo4_ssh.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_ilo_moonshot.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_ilo_mp.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_ilo_ssh.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_imm.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_intelmodular.xml | 42 ++++++++++++--- + tests/data/metadata/fence_ipdu.xml | 42 ++++++++++++--- + tests/data/metadata/fence_ipmilan.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_ldom.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_lpar.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_mpath.xml | 14 ++++- + tests/data/metadata/fence_netio.xml | 42 ++++++++++++--- + tests/data/metadata/fence_ovh.xml | 35 +++++++++++-- + tests/data/metadata/fence_pve.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_raritan.xml | 42 ++++++++++++--- + tests/data/metadata/fence_rhevm.xml | 42 ++++++++++++--- + tests/data/metadata/fence_rsa.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_rsb.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_sanbox2.xml | 49 ++++++++++++++--- + tests/data/metadata/fence_sbd.xml | 14 ++++- + tests/data/metadata/fence_scsi.xml | 13 ++++- + tests/data/metadata/fence_virsh.xml | 63 ++++++++++++++++++---- + tests/data/metadata/fence_vmware_soap.xml | 42 ++++++++++++--- + tests/data/metadata/fence_wti.xml | 56 +++++++++++++++++--- + tests/data/metadata/fence_xenapi.xml | 35 +++++++++++-- + tests/data/metadata/fence_zvmip.xml | 42 ++++++++++++--- + 56 files changed, 2140 insertions(+), 367 deletions(-) + +diff --git a/fence/agents/lib/fence2man.xsl b/fence/agents/lib/fence2man.xsl +index b31d33e..06fb7ab 100644 +--- a/fence/agents/lib/fence2man.xsl ++++ b/fence/agents/lib/fence2man.xsl +@@ -2,6 +2,7 @@ + + + ++ + .TP + .B + .B +@@ -9,6 +10,11 @@ + + This parameter is always required. + (Default Value: ) ++ ++ Obsoletes: ++ ++ ++ + + + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 3646d60..399dbf2 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -521,7 +521,12 @@ def usage(avail_opt): + + def metadata(avail_opt, options, docs): + # avail_opt has to be unique, if there are duplicities then they should be removed +- sorted_list = [(key, all_opt[key]) for key in list(set(avail_opt))] ++ sorted_list = [(key, all_opt[key]) for key in list(set(avail_opt)) if "longopt" in all_opt[key]] ++ # Find keys that are going to replace inconsistent names ++ mapping = dict([(opt["longopt"].replace("-", "_"), key) for (key, opt) in sorted_list if (key != opt["longopt"].replace("-", "_"))]) ++ new_options = [(key, all_opt[mapping[key]]) for key in mapping] ++ sorted_list.extend(new_options) ++ + sorted_list.sort(lambda x, y: cmp(x[1]["order"], y[1]["order"])) + + print "" +@@ -534,22 +539,32 @@ def metadata(avail_opt, options, docs): + if docs.has_key("vendorurl"): + print "" + docs["vendorurl"] + "" + print "" +- for option, _ in sorted_list: +- if all_opt[option].has_key("shortdesc"): +- print "\t" ++ ++ for (key, opt) in sorted_list: ++ info = "" ++ if key in all_opt: ++ if key != all_opt[key].get('longopt', key).replace("-", "_"): ++ info = "deprecated=\"1\"" ++ else: ++ info = "obsoletes=\"%s\"" % (mapping.get(key)) ++ ++ if opt.has_key("shortdesc"): ++ if info != "": ++ info = " " + info ++ print "\t" + + default = "" +- if all_opt[option].has_key("default"): +- default = str(all_opt[option]["default"]) +- elif options.has_key("--" + all_opt[option]["longopt"]) and all_opt[option]["getopt"].endswith(":"): +- if options["--" + all_opt[option]["longopt"]]: ++ if opt.has_key("default"): ++ default = str(opt["default"]) ++ elif options.has_key("--" + opt["longopt"]) and opt["getopt"].endswith(":"): ++ if options["--" + opt["longopt"]]: + try: +- default = options["--" + all_opt[option]["longopt"]] ++ default = options["--" + opt["longopt"]] + except TypeError: + ## @todo/@note: Currently there is no clean way how to handle lists + ## we can create a string from it but we can't set it on command line +- default = str(options["--" + all_opt[option]["longopt"]]) +- elif options.has_key("--" + all_opt[option]["longopt"]): ++ default = str(options["--" + opt["longopt"]]) ++ elif options.has_key("--" + opt["longopt"]): + default = "true" + + if default: +@@ -560,7 +575,7 @@ def metadata(avail_opt, options, docs): + default = default.replace("'", "'") + default = "default=\"" + default + "\" " + +- mixed = all_opt[option]["help"] ++ mixed = opt["help"] + ## split it between option and help text + res = re.compile(r"^(.*?--\S+)\s+", re.IGNORECASE | re.S).search(mixed) + if None != res: +@@ -568,18 +583,18 @@ def metadata(avail_opt, options, docs): + mixed = mixed.replace("<", "<").replace(">", ">") + print "\t\t" + +- if all_opt[option].has_key("choices"): ++ if opt.has_key("choices"): + print "\t\t" +- for choice in all_opt[option]["choices"]: ++ for choice in opt["choices"]: + print "\t\t\t" +- elif all_opt[option]["getopt"].count(":") > 0: +- t = all_opt[option].get("type", "string") ++ elif opt["getopt"].count(":") > 0: ++ t = opt.get("type", "string") + print("\t\t") + else: + print "\t\t" + +- print "\t\t" + all_opt[option]["shortdesc"] + "" ++ print "\t\t" + opt["shortdesc"] + "" + print "\t" + print "" + print "" +@@ -678,14 +693,21 @@ def process_input(avail_opt): + else: + opt = {} + name = "" ++ ++ mapping_longopt_names = dict([(all_opt[o].get("longopt"), o) for o in avail_opt]) ++ + for line in sys.stdin.readlines(): + line = line.strip() + if (line.startswith("#")) or (len(line) == 0): + continue + + (name, value) = (line + "=").split("=", 1) ++ name = name.replace("-", "_"); + value = value[:-1] + ++ if name in mapping_longopt_names: ++ name = mapping_longopt_names[name] ++ + if avail_opt.count(name) == 0 and name in ["nodename"]: + continue + elif avail_opt.count(name) == 0: +diff --git a/fence/agents/lib/metadata.rng b/fence/agents/lib/metadata.rng +index 2185cbf..e0cd441 100644 +--- a/fence/agents/lib/metadata.rng ++++ b/fence/agents/lib/metadata.rng +@@ -19,7 +19,8 @@ + + + +- ++ ++ + + + +diff --git a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml +index f266e84..bcad280 100644 +--- a/tests/data/metadata/fence_alom.xml ++++ b/tests/data/metadata/fence_alom.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml +index 6c0dacb..5fad57f 100644 +--- a/tests/data/metadata/fence_amt.xml ++++ b/tests/data/metadata/fence_amt.xml +@@ -8,7 +8,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -18,7 +18,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -36,12 +36,12 @@ + + Method to fence (onoff|cycle) + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -62,12 +62,37 @@ + + Fencing Action + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -121,7 +146,12 @@ + + Count of attempts to retry power on + +- ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ + + + Use sudo (without password) when calling 3rd party sotfware. +diff --git a/tests/data/metadata/fence_apc.xml b/tests/data/metadata/fence_apc.xml +index bd99eb2..eeb830c 100644 +--- a/tests/data/metadata/fence_apc.xml ++++ b/tests/data/metadata/fence_apc.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -68,17 +68,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_apc_snmp.xml b/tests/data/metadata/fence_apc_snmp.xml +index d7f6e1b..9bf7322 100644 +--- a/tests/data/metadata/fence_apc_snmp.xml ++++ b/tests/data/metadata/fence_apc_snmp.xml +@@ -30,7 +30,7 @@ + + Set privacy protocol (DES|AES) + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -40,7 +40,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -68,7 +68,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -82,7 +82,7 @@ + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- ++ + + + Login password or passphrase +@@ -92,17 +92,47 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_bladecenter.xml b/tests/data/metadata/fence_bladecenter.xml +index 70c76b7..26f2d00 100644 +--- a/tests/data/metadata/fence_bladecenter.xml ++++ b/tests/data/metadata/fence_bladecenter.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_brocade.xml b/tests/data/metadata/fence_brocade.xml +index fd0c399..38d2ac1 100644 +--- a/tests/data/metadata/fence_brocade.xml ++++ b/tests/data/metadata/fence_brocade.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_cisco_mds.xml b/tests/data/metadata/fence_cisco_mds.xml +index 305ac51..8a18ecb 100644 +--- a/tests/data/metadata/fence_cisco_mds.xml ++++ b/tests/data/metadata/fence_cisco_mds.xml +@@ -30,7 +30,7 @@ + + Set privacy protocol (DES|AES) + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -40,7 +40,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -68,7 +68,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -82,7 +82,7 @@ + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- ++ + + + Login password or passphrase +@@ -92,17 +92,47 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +index 34b280a..b2ab55d 100644 +--- a/tests/data/metadata/fence_cisco_ucs.xml ++++ b/tests/data/metadata/fence_cisco_ucs.xml +@@ -23,7 +23,7 @@ + + SSL connection with verifying fence device's certificate + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -33,7 +33,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -68,17 +68,47 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +index d90f167..0da03af 100644 +--- a/tests/data/metadata/fence_compute.xml ++++ b/tests/data/metadata/fence_compute.xml +@@ -3,37 +3,37 @@ + Used to tell Nova that compute nodes are down and to reschedule flagged instances + + +- ++ + + + Region Name + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + Script to retrieve password + +- ++ + + + Keystone Admin Auth URL + +- ++ + + + Login password or passphrase + +- ++ + + + Nova Endpoint type + +- ++ + + + Keystone Admin Tenant +@@ -43,11 +43,51 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Region Name ++ ++ ++ ++ ++ Keystone Admin Tenant ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Nova Endpoint type ++ ++ ++ ++ ++ Keystone Admin Auth URL ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + +@@ -58,27 +98,47 @@ + + DNS domain in which hosts live + +- ++ + + + Allow instances to be evacuated + +- ++ + + + Disable functionality for dealing with shared storage + +- ++ ++ ++ ++ Only record the target as needing evacuation ++ ++ + + + Only record the target as needing evacuation + ++ ++ ++ ++ Allow instances to be evacuated ++ ++ ++ ++ ++ Disable functionality for dealing with shared storage ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml +index 4842fa3..a56bd39 100644 +--- a/tests/data/metadata/fence_docker.xml ++++ b/tests/data/metadata/fence_docker.xml +@@ -13,7 +13,7 @@ + + SSL connection with verifying fence device's certificate + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -23,7 +23,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -56,6 +56,16 @@ + + Fencing Action + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ IP Address or Hostname ++ + + + +@@ -76,7 +86,12 @@ + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml +index 18ca08c..00665a0 100644 +--- a/tests/data/metadata/fence_drac.xml ++++ b/tests/data/metadata/fence_drac.xml +@@ -8,12 +8,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) + +- ++ + + + Force Python regex for command prompt +@@ -23,7 +23,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -33,12 +33,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -48,17 +48,52 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_drac5.xml b/tests/data/metadata/fence_drac5.xml +index 221c630..2990d7f 100644 +--- a/tests/data/metadata/fence_drac5.xml ++++ b/tests/data/metadata/fence_drac5.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -72,17 +72,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_dummy.xml b/tests/data/metadata/fence_dummy.xml +index a7f4cb2..e54bc10 100644 +--- a/tests/data/metadata/fence_dummy.xml ++++ b/tests/data/metadata/fence_dummy.xml +@@ -28,7 +28,12 @@ + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_eaton_snmp.xml b/tests/data/metadata/fence_eaton_snmp.xml +index 5a566a1..45eae2f 100644 +--- a/tests/data/metadata/fence_eaton_snmp.xml ++++ b/tests/data/metadata/fence_eaton_snmp.xml +@@ -30,7 +30,7 @@ + + Set privacy protocol (DES|AES) + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -40,7 +40,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -68,7 +68,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -82,7 +82,7 @@ + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- ++ + + + Login password or passphrase +@@ -92,17 +92,47 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +index 5c7c08d..29dd4de 100644 +--- a/tests/data/metadata/fence_emerson.xml ++++ b/tests/data/metadata/fence_emerson.xml +@@ -30,7 +30,7 @@ + + Set privacy protocol (DES|AES) + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -40,7 +40,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -68,7 +68,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -82,7 +82,7 @@ + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- ++ + + + Login password or passphrase +@@ -92,17 +92,47 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml +index acfd5f8..916cff4 100644 +--- a/tests/data/metadata/fence_eps.xml ++++ b/tests/data/metadata/fence_eps.xml +@@ -10,7 +10,7 @@ Agent basically works by connecting to hidden page and pass appropriate argument + + TCP/UDP port to use for connection with device + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -20,7 +20,7 @@ Agent basically works by connecting to hidden page and pass appropriate argument + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -30,17 +30,17 @@ Agent basically works by connecting to hidden page and pass appropriate argument + + Forces agent to use IPv4 addresses only + +- ++ + + + Name of hidden page + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -50,17 +50,52 @@ Agent basically works by connecting to hidden page and pass appropriate argument + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Name of hidden page ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_hds_cb.xml b/tests/data/metadata/fence_hds_cb.xml +index 282a575..3addcde 100644 +--- a/tests/data/metadata/fence_hds_cb.xml ++++ b/tests/data/metadata/fence_hds_cb.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_hpblade.xml b/tests/data/metadata/fence_hpblade.xml +index f77d928..d822658 100644 +--- a/tests/data/metadata/fence_hpblade.xml ++++ b/tests/data/metadata/fence_hpblade.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ibmblade.xml b/tests/data/metadata/fence_ibmblade.xml +index 7b04732..0884401 100644 +--- a/tests/data/metadata/fence_ibmblade.xml ++++ b/tests/data/metadata/fence_ibmblade.xml +@@ -30,7 +30,7 @@ + + Set privacy protocol (DES|AES) + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -40,7 +40,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -68,7 +68,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -82,7 +82,7 @@ + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- ++ + + + Login password or passphrase +@@ -92,17 +92,47 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index c1604a4..b768421 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,12 +22,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + Script to retrieve password +@@ -45,7 +45,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Login password or passphrase +@@ -94,17 +94,47 @@ + + Timeout (sec) for IPMI operation + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -158,7 +188,12 @@ + + Count of attempts to retry power on + +- ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ + + + Use sudo (without password) when calling 3rd party sotfware. +diff --git a/tests/data/metadata/fence_ifmib.xml b/tests/data/metadata/fence_ifmib.xml +index 8e347b5..56b3c24 100644 +--- a/tests/data/metadata/fence_ifmib.xml ++++ b/tests/data/metadata/fence_ifmib.xml +@@ -32,7 +32,7 @@ It was written with managed ethernet switches in mind, in order to fence iSCSI S + + Set privacy protocol (DES|AES) + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -42,7 +42,7 @@ It was written with managed ethernet switches in mind, in order to fence iSCSI S + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -70,7 +70,7 @@ It was written with managed ethernet switches in mind, in order to fence iSCSI S + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -84,7 +84,7 @@ It was written with managed ethernet switches in mind, in order to fence iSCSI S + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- ++ + + + Login password or passphrase +@@ -94,17 +94,47 @@ It was written with managed ethernet switches in mind, in order to fence iSCSI S + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +index 93bcb59..5966a42 100644 +--- a/tests/data/metadata/fence_ilo.xml ++++ b/tests/data/metadata/fence_ilo.xml +@@ -14,7 +14,7 @@ + + Disable TLS negotiation, force SSL 3.0 + +- ++ + + + Force ribcl version to use +@@ -34,12 +34,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -49,7 +49,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -59,7 +59,7 @@ + + Disable TLS negotiaton, force TLS 1.0 + +- ++ + + + Login password or passphrase +@@ -74,17 +74,52 @@ + + SSL connection without verifying fence device's certificate + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force ribcl version to use ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +index b607aea..c07f7a3 100644 +--- a/tests/data/metadata/fence_ilo2.xml ++++ b/tests/data/metadata/fence_ilo2.xml +@@ -14,7 +14,7 @@ + + Disable TLS negotiation, force SSL 3.0 + +- ++ + + + Force ribcl version to use +@@ -34,12 +34,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -49,7 +49,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -59,7 +59,7 @@ + + Disable TLS negotiaton, force TLS 1.0 + +- ++ + + + Login password or passphrase +@@ -74,17 +74,52 @@ + + SSL connection without verifying fence device's certificate + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force ribcl version to use ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index 6623070..875d19e 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,12 +22,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + Script to retrieve password +@@ -45,7 +45,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Login password or passphrase +@@ -94,17 +94,47 @@ + + Timeout (sec) for IPMI operation + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -158,7 +188,12 @@ + + Count of attempts to retry power on + +- ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ + + + Use sudo (without password) when calling 3rd party sotfware. +diff --git a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +index 5c1eec4..ee43daa 100644 +--- a/tests/data/metadata/fence_ilo3_ssh.xml ++++ b/tests/data/metadata/fence_ilo3_ssh.xml +@@ -10,22 +10,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -53,12 +53,12 @@ + + Method to fence (onoff|cycle) + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -73,17 +73,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index 4562c86..18ce056 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,12 +22,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + Script to retrieve password +@@ -45,7 +45,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Login password or passphrase +@@ -94,17 +94,47 @@ + + Timeout (sec) for IPMI operation + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -158,7 +188,12 @@ + + Count of attempts to retry power on + +- ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ + + + Use sudo (without password) when calling 3rd party sotfware. +diff --git a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +index 6c01add..9e37ebb 100644 +--- a/tests/data/metadata/fence_ilo4_ssh.xml ++++ b/tests/data/metadata/fence_ilo4_ssh.xml +@@ -10,22 +10,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -53,12 +53,12 @@ + + Method to fence (onoff|cycle) + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -73,17 +73,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ilo_moonshot.xml b/tests/data/metadata/fence_ilo_moonshot.xml +index 8a5bd21..a162daf 100644 +--- a/tests/data/metadata/fence_ilo_moonshot.xml ++++ b/tests/data/metadata/fence_ilo_moonshot.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml +index d1cbf04..59205ce 100644 +--- a/tests/data/metadata/fence_ilo_mp.xml ++++ b/tests/data/metadata/fence_ilo_mp.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +index 0c62fba..4489f01 100644 +--- a/tests/data/metadata/fence_ilo_ssh.xml ++++ b/tests/data/metadata/fence_ilo_ssh.xml +@@ -10,22 +10,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -53,12 +53,12 @@ + + Method to fence (onoff|cycle) + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -73,17 +73,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index 7966384..0b1a3f7 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,12 +22,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + Script to retrieve password +@@ -45,7 +45,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Login password or passphrase +@@ -94,17 +94,47 @@ + + Timeout (sec) for IPMI operation + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -158,7 +188,12 @@ + + Count of attempts to retry power on + +- ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ + + + Use sudo (without password) when calling 3rd party sotfware. +diff --git a/tests/data/metadata/fence_intelmodular.xml b/tests/data/metadata/fence_intelmodular.xml +index 5d7b7ed..5cb1759 100644 +--- a/tests/data/metadata/fence_intelmodular.xml ++++ b/tests/data/metadata/fence_intelmodular.xml +@@ -32,7 +32,7 @@ Note: Since firmware update version 2.7, SNMP v2 write support is removed, and r + + Set privacy protocol (DES|AES) + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -42,7 +42,7 @@ Note: Since firmware update version 2.7, SNMP v2 write support is removed, and r + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -70,7 +70,7 @@ Note: Since firmware update version 2.7, SNMP v2 write support is removed, and r + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -84,7 +84,7 @@ Note: Since firmware update version 2.7, SNMP v2 write support is removed, and r + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- ++ + + + Login password or passphrase +@@ -94,17 +94,47 @@ Note: Since firmware update version 2.7, SNMP v2 write support is removed, and r + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ipdu.xml b/tests/data/metadata/fence_ipdu.xml +index 5c613bf..0f4797a 100644 +--- a/tests/data/metadata/fence_ipdu.xml ++++ b/tests/data/metadata/fence_ipdu.xml +@@ -30,7 +30,7 @@ + + Set privacy protocol (DES|AES) + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -40,7 +40,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -68,7 +68,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password +@@ -82,7 +82,7 @@ + + Set security level (noAuthNoPriv|authNoPriv|authPriv) + +- ++ + + + Login password or passphrase +@@ -92,17 +92,47 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index a8efcfa..25079dd 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -12,7 +12,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) +@@ -22,12 +22,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname + +- ++ + + + Script to retrieve password +@@ -45,7 +45,7 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Login password or passphrase +@@ -94,17 +94,47 @@ + + Timeout (sec) for IPMI operation + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -158,7 +188,12 @@ + + Count of attempts to retry power on + +- ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ + + + Use sudo (without password) when calling 3rd party sotfware. +diff --git a/tests/data/metadata/fence_ldom.xml b/tests/data/metadata/fence_ldom.xml +index dc0147a..d697d0a 100644 +--- a/tests/data/metadata/fence_ldom.xml ++++ b/tests/data/metadata/fence_ldom.xml +@@ -10,22 +10,22 @@ Very useful parameter is -c (or cmd_prompt in stdin mode). This must be set to s + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -45,12 +45,12 @@ Very useful parameter is -c (or cmd_prompt in stdin mode). This must be set to s + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -65,17 +65,57 @@ Very useful parameter is -c (or cmd_prompt in stdin mode). This must be set to s + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_lpar.xml b/tests/data/metadata/fence_lpar.xml +index 77d61a1..f42ca1e 100644 +--- a/tests/data/metadata/fence_lpar.xml ++++ b/tests/data/metadata/fence_lpar.xml +@@ -13,17 +13,17 @@ + + Managed system name + +- ++ + + + SSH connection + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + Force Python regex for command prompt +@@ -33,7 +33,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -57,12 +57,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -77,17 +77,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +index b29d526..6e02a14 100644 +--- a/tests/data/metadata/fence_mpath.xml ++++ b/tests/data/metadata/fence_mpath.xml +@@ -24,7 +24,12 @@ The fence_mpath agent works by having an unique key for each pair of node and de + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -77,7 +82,12 @@ The fence_mpath agent works by having an unique key for each pair of node and de + + Count of attempts to retry power on + +- ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ + + + Use sudo (without password) when calling 3rd party sotfware. +diff --git a/tests/data/metadata/fence_netio.xml b/tests/data/metadata/fence_netio.xml +index 9b051db..ae0c918 100644 +--- a/tests/data/metadata/fence_netio.xml ++++ b/tests/data/metadata/fence_netio.xml +@@ -13,12 +13,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + Login password or passphrase + +- ++ + + + IP Address or Hostname +@@ -33,17 +33,42 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Login Name + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ + + + Script to retrieve password +@@ -53,7 +78,12 @@ + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_ovh.xml b/tests/data/metadata/fence_ovh.xml +index bdf2676..b0e6434 100644 +--- a/tests/data/metadata/fence_ovh.xml ++++ b/tests/data/metadata/fence_ovh.xml +@@ -3,7 +3,7 @@ + fence_ovh is an Power Fencing agent which can be used within OVH datecentre. Poweroff is simulated with a reboot into rescue-pro mode. + http://www.ovh.net + +- ++ + + + Login password or passphrase +@@ -18,17 +18,37 @@ + + Fencing Action + +- ++ + + + Script to retrieve password + +- ++ + + + Login Name + +- ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ + + + Physical plug number, name of virtual machine or UUID +@@ -38,7 +58,12 @@ + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_pve.xml b/tests/data/metadata/fence_pve.xml +index 03a1124..42b8cbb 100644 +--- a/tests/data/metadata/fence_pve.xml ++++ b/tests/data/metadata/fence_pve.xml +@@ -8,7 +8,7 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + Id of the virtual machine. +@@ -18,7 +18,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname of a node within the Proxmox cluster. +@@ -28,12 +28,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -43,12 +43,42 @@ + + Fencing Action + +- ++ + + + Login Name + +- ++ ++ ++ ++ Id of the virtual machine. ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname of a node within the Proxmox cluster. ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Node on which machine is located. (Optional, will be automatically determined) ++ ++ + + + Node on which machine is located. (Optional, will be automatically determined) +@@ -58,7 +88,12 @@ + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_raritan.xml b/tests/data/metadata/fence_raritan.xml +index f1910bb..697972b 100644 +--- a/tests/data/metadata/fence_raritan.xml ++++ b/tests/data/metadata/fence_raritan.xml +@@ -13,12 +13,12 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + Login password or passphrase + +- ++ + + + IP Address or Hostname +@@ -33,17 +33,42 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Login Name + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ + + + Script to retrieve password +@@ -53,7 +78,12 @@ + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml +index 16f9184..df6aacf 100644 +--- a/tests/data/metadata/fence_rsa.xml ++++ b/tests/data/metadata/fence_rsa.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml +index 554fd18..220926a 100644 +--- a/tests/data/metadata/fence_rsb.xml ++++ b/tests/data/metadata/fence_rsb.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + IP address or hostname of fencing device (together with --port-as-ip) + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_sanbox2.xml b/tests/data/metadata/fence_sanbox2.xml +index 3d42e6e..57ad2a7 100644 +--- a/tests/data/metadata/fence_sanbox2.xml ++++ b/tests/data/metadata/fence_sanbox2.xml +@@ -8,12 +8,12 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + Force Python regex for command prompt +@@ -23,7 +23,7 @@ + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -33,12 +33,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -48,17 +48,52 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_sbd.xml b/tests/data/metadata/fence_sbd.xml +index e5de1f6..b1820d5 100644 +--- a/tests/data/metadata/fence_sbd.xml ++++ b/tests/data/metadata/fence_sbd.xml +@@ -21,7 +21,12 @@ + + Fencing Action + +- ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ + + + Physical plug number, name of virtual machine or UUID +@@ -31,7 +36,12 @@ + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +index 2b7d9d7..f947259 100644 +--- a/tests/data/metadata/fence_scsi.xml ++++ b/tests/data/metadata/fence_scsi.xml +@@ -39,7 +39,12 @@ The fence_scsi agent works by having each node in the cluster register a unique + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -91,7 +96,11 @@ The fence_scsi agent works by having each node in the cluster register a unique + + Path to sg_turs binary + +- ++ ++ ++ Path to corosync-cmapctl binary ++ ++ + + Path to corosync-cmapctl binary + +diff --git a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml +index b381345..bae3cdc 100644 +--- a/tests/data/metadata/fence_virsh.xml ++++ b/tests/data/metadata/fence_virsh.xml +@@ -10,22 +10,22 @@ By default, virsh needs root account to do properly work. So you must allow ssh + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -45,12 +45,12 @@ By default, virsh needs root account to do properly work. So you must allow ssh + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -65,17 +65,57 @@ By default, virsh needs root account to do properly work. So you must allow ssh + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +@@ -130,7 +170,12 @@ By default, virsh needs root account to do properly work. So you must allow ssh + + Count of attempts to retry power on + +- ++ ++ ++ ++ Use sudo (without password) when calling 3rd party sotfware. ++ ++ + + + Use sudo (without password) when calling 3rd party sotfware. +diff --git a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml +index f5d6d76..b174406 100644 +--- a/tests/data/metadata/fence_vmware_soap.xml ++++ b/tests/data/metadata/fence_vmware_soap.xml +@@ -20,7 +20,7 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + + SSL connection with verifying fence device's certificate + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -30,7 +30,7 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -40,12 +40,12 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -65,17 +65,47 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_wti.xml b/tests/data/metadata/fence_wti.xml +index bfbcb35..e1485ad 100644 +--- a/tests/data/metadata/fence_wti.xml ++++ b/tests/data/metadata/fence_wti.xml +@@ -8,22 +8,22 @@ + + TCP/UDP port to use for connection with device + +- ++ + + + IP Address or Hostname + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + SSH connection + +- ++ + + + Force Python regex for command prompt +@@ -43,12 +43,12 @@ + + Forces agent to use IPv4 addresses only + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -63,17 +63,57 @@ + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Force Python regex for command prompt ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_xenapi.xml b/tests/data/metadata/fence_xenapi.xml +index 156ed53..4d74033 100644 +--- a/tests/data/metadata/fence_xenapi.xml ++++ b/tests/data/metadata/fence_xenapi.xml +@@ -3,7 +3,7 @@ + fence_cxs is an I/O Fencing agent used on Citrix XenServer hosts. It uses the XenAPI, supplied by Citrix, to establish an XML-RPC sesssion to a XenServer host. Once the session is established, further XML-RPC commands are issued in order to switch on, switch off, restart and query the status of virtual machines running on the host. + http://www.xenproject.org + +- ++ + + + Login password or passphrase +@@ -18,27 +18,52 @@ + + Fencing Action + +- ++ + + + Login Name + +- ++ + + + Physical plug number, name of virtual machine or UUID + +- ++ + + + Script to retrieve password + ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index 5222a22..41393c2 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -22,7 +22,7 @@ Where XXXXXXX is the name of the virtual machine used in the authuser field of t + + TCP/UDP port to use for connection with device + +- ++ + + + Physical plug number, name of virtual machine or UUID +@@ -32,7 +32,7 @@ Where XXXXXXX is the name of the virtual machine used in the authuser field of t + + Forces agent to use IPv6 addresses only + +- ++ + + + IP Address or Hostname +@@ -50,12 +50,12 @@ Where XXXXXXX is the name of the virtual machine used in the authuser field of t + + Method to fence (onoff|cycle) + +- ++ + + + Script to retrieve password + +- ++ + + + Login password or passphrase +@@ -65,17 +65,47 @@ Where XXXXXXX is the name of the virtual machine used in the authuser field of t + + Fencing Action + +- ++ + + + Login Name + ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ + + + + Verbose mode + +- ++ ++ ++ ++ Write debug information to given file ++ ++ + + + Write debug information to given file +-- +2.4.11 + diff --git a/SOURCES/bz1410881-cisco_ucs-admin.patch b/SOURCES/bz1410881-cisco_ucs-admin.patch new file mode 100644 index 0000000..22076ce --- /dev/null +++ b/SOURCES/bz1410881-cisco_ucs-admin.patch @@ -0,0 +1,28 @@ +From eb43835fc430651712271a046c61eec1c5ecdedb Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Mon, 23 Jan 2017 14:49:14 +0100 +Subject: [PATCH] fence_cisco_ucs: Commands sent to Cisco UCS are changed to + +Resolves: rhbz#1410881 +--- + fence/agents/cisco_ucs/fence_cisco_ucs.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py +index d21b278..701f690 100644 +--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py +@@ -71,8 +71,8 @@ def set_power_status(conn, options): + del conn + + action = { +- 'on' : "up", +- 'off' : "down" ++ 'on' : "admin-up", ++ 'off' : "admin-down" + }[options["--action"]] + + send_command(options, "" + +-- +2.4.11 + diff --git a/SOURCES/bz1422499-fence_rhevm-disable-http-filter.patch b/SOURCES/bz1422499-fence_rhevm-disable-http-filter.patch new file mode 100644 index 0000000..d34f7f3 --- /dev/null +++ b/SOURCES/bz1422499-fence_rhevm-disable-http-filter.patch @@ -0,0 +1,61 @@ +diff -uNr a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py +--- a/fence/agents/rhevm/fence_rhevm.py 2017-03-21 14:38:42.785643063 +0100 ++++ b/fence/agents/rhevm/fence_rhevm.py 2017-03-21 14:40:24.199654871 +0100 +@@ -85,6 +85,10 @@ + api_path = opt["--api-path"] + else: + api_path = "/ovirt-engine/api" ++ if opt.has_key("--disable-http-filter"): ++ http_filter = 'false' ++ else: ++ http_filter = 'true' + + url += "//" + opt["--ip"] + ":" + str(opt["--ipport"]) + api_path + "/" + command + +@@ -97,7 +101,7 @@ + "Content-type: application/xml", + "Accept: application/xml", + "Prefer: persistent-auth", +- "Filter: true", ++ "Filter: {}".format(http_filter), + ]) + + if opt.has_key("cookie"): +@@ -154,6 +158,14 @@ + "required" : "0", + "shortdesc" : "The path of the API URL", + "order" : 2} ++ all_opt["disable_http_filter"] = { ++ "getopt" : "", ++ "longopt" : "disable-http-filter", ++ "help" : "--disable-http-filter Set HTTP Filter header to false", ++ "required" : "0", ++ "shortdesc" : "Set HTTP Filter header to false", ++ "order" : 3} ++ + + def main(): + device_opt = [ +@@ -166,6 +178,7 @@ + "web", + "port", + "use_cookies", ++ "disable_http_filter", + ] + + atexit.register(atexit_handler) +diff -uNr a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +--- a/tests/data/metadata/fence_rhevm.xml 2017-03-21 14:38:42.808642839 +0100 ++++ b/tests/data/metadata/fence_rhevm.xml 2017-03-21 14:40:54.832356380 +0100 +@@ -77,6 +77,11 @@ + + The path of the API URL + ++ ++ ++ ++ Set HTTP Filter header to false ++ + + + diff --git a/SOURCES/bz1426693-1-fence_compute-project_id-to-project_name.patch b/SOURCES/bz1426693-1-fence_compute-project_id-to-project_name.patch new file mode 100644 index 0000000..1823835 --- /dev/null +++ b/SOURCES/bz1426693-1-fence_compute-project_id-to-project_name.patch @@ -0,0 +1,77 @@ +diff --git a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +index 0a238b6..4b229b0 100644 +--- a/fence/agents/compute/fence_compute.py ++++ b/fence/agents/compute/fence_compute.py +@@ -4,6 +4,7 @@ import sys + import time + import atexit + import logging ++import inspect + import requests.exceptions + + sys.path.append("@FENCEAGENTSLIBDIR@") +@@ -310,15 +311,46 @@ def create_nova_connection(options): + + versions = [ "2.11", "2" ] + for version in versions: +- nova = client.Client(version, +- options["--username"], +- options["--password"], +- options["--tenant-name"], +- options["--auth-url"], +- insecure=options["--insecure"], +- region_name=options["--region-name"], +- endpoint_type=options["--endpoint-type"], +- http_log_debug=options.has_key("--verbose")) ++ clientargs = inspect.getargspec(client.Client).varargs ++ ++ # Some versions of Openstack prior to Ocata only ++ # supported positional arguments for username, ++ # password and tenant. ++ # ++ # Versions since Ocata only support named arguments. ++ # ++ # So we need to use introspection to figure out how to ++ # create a Nova client. ++ # ++ # Happy days ++ # ++ if clientargs: ++ # OSP < 11 ++ # ArgSpec(args=['version', 'username', 'password', 'project_id', 'auth_url'], ++ # varargs=None, ++ # keywords='kwargs', defaults=(None, None, None, None)) ++ nova = client.Client(version, ++ options["--username"], ++ options["--password"], ++ options["--tenant-name"], ++ options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) ++ else: ++ # OSP >= 11 ++ # ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None) ++ nova = client.Client(version, ++ username=options["--username"], ++ password=options["--password"], ++ tenant_name=options["--tenant-name"], ++ auth_url=options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) ++ + try: + nova.hypervisors.list() + return +@@ -417,7 +449,7 @@ def main(): + global override_status + atexit.register(atexit_handler) + +- device_opt = ["login", "passwd", "tenant-name", "auth-url", "fabric_fencing", "on_target", ++ device_opt = ["login", "passwd", "tenant-name", "auth-url", "fabric_fencing", + "no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type", + "record-only", "instance-filtering", "insecure", "region-name"] + define_new_opts() diff --git a/SOURCES/bz1426693-2-fence_compute-project_id-to-project_name.patch b/SOURCES/bz1426693-2-fence_compute-project_id-to-project_name.patch new file mode 100644 index 0000000..2b2e158 --- /dev/null +++ b/SOURCES/bz1426693-2-fence_compute-project_id-to-project_name.patch @@ -0,0 +1,121 @@ +diff -uNr a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +--- a/fence/agents/compute/fence_compute.py 2017-04-03 13:54:40.694961510 +0200 ++++ b/fence/agents/compute/fence_compute.py 2017-04-03 14:29:52.957804288 +0200 +@@ -314,45 +314,45 @@ + + versions = [ "2.11", "2" ] + for version in versions: +- clientargs = inspect.getargspec(client.Client).varargs ++ clientargs = inspect.getargspec(client.Client).varargs + +- # Some versions of Openstack prior to Ocata only +- # supported positional arguments for username, +- # password and tenant. +- # +- # Versions since Ocata only support named arguments. +- # +- # So we need to use introspection to figure out how to +- # create a Nova client. +- # +- # Happy days +- # +- if clientargs: +- # OSP < 11 +- # ArgSpec(args=['version', 'username', 'password', 'project_id', 'auth_url'], +- # varargs=None, +- # keywords='kwargs', defaults=(None, None, None, None)) +- nova = client.Client(version, +- options["--username"], +- options["--password"], +- options["--tenant-name"], +- options["--auth-url"], +- insecure=options["--insecure"], +- region_name=options["--region-name"], +- endpoint_type=options["--endpoint-type"], +- http_log_debug=options.has_key("--verbose")) +- else: +- # OSP >= 11 +- # ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None) +- nova = client.Client(version, +- username=options["--username"], +- password=options["--password"], +- tenant_name=options["--tenant-name"], +- auth_url=options["--auth-url"], +- insecure=options["--insecure"], +- region_name=options["--region-name"], +- endpoint_type=options["--endpoint-type"], +- http_log_debug=options.has_key("--verbose")) ++ # Some versions of Openstack prior to Ocata only ++ # supported positional arguments for username, ++ # password and tenant. ++ # ++ # Versions since Ocata only support named arguments. ++ # ++ # So we need to use introspection to figure out how to ++ # create a Nova client. ++ # ++ # Happy days ++ # ++ if clientargs: ++ # OSP < 11 ++ # ArgSpec(args=['version', 'username', 'password', 'project_id', 'auth_url'], ++ # varargs=None, ++ # keywords='kwargs', defaults=(None, None, None, None)) ++ nova = client.Client(version, ++ options["--username"], ++ options["--password"], ++ options["--tenant-name"], ++ options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) ++ else: ++ # OSP >= 11 ++ # ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None) ++ nova = client.Client(version, ++ username=options["--username"], ++ password=options["--password"], ++ tenant_name=options["--tenant-name"], ++ auth_url=options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) + + try: + nova.hypervisors.list() +diff -uNr a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +--- a/tests/data/metadata/fence_compute.xml 2017-04-03 13:54:40.687961577 +0200 ++++ b/tests/data/metadata/fence_compute.xml 2017-04-03 14:30:35.975395245 +0200 +@@ -113,16 +113,16 @@ + + Only record the target as needing evacuation + +- +- +- +- Only record the target as needing evacuation +- + + + + Allow instances to be evacuated + ++ ++ ++ ++ Only record the target as needing evacuation ++ + + + +@@ -190,7 +190,7 @@ + + + +- ++ + + + diff --git a/SOURCES/bz1433948-1-validate-all-action.patch b/SOURCES/bz1433948-1-validate-all-action.patch new file mode 100644 index 0000000..5b348ac --- /dev/null +++ b/SOURCES/bz1433948-1-validate-all-action.patch @@ -0,0 +1,672 @@ +diff -uNr a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +--- a/fence/agents/lib/fencing.py.py 2017-03-20 15:01:35.821589253 +0100 ++++ b/fence/agents/lib/fencing.py.py 2017-03-20 16:09:44.303299554 +0100 +@@ -20,6 +20,7 @@ + __all__ = ['atexit_handler', 'check_input', 'process_input', 'all_opt', 'show_docs', + 'fence_login', 'fence_action', 'fence_logout'] + ++EC_OK = 0 + EC_GENERIC_ERROR = 1 + EC_BAD_ARGS = 2 + EC_LOGIN_DENIED = 3 +@@ -485,11 +486,12 @@ + + return added_opt + +-def fail_usage(message=""): ++def fail_usage(message="", stop=True): + if len(message) > 0: + logging.error("%s\n", message) +- logging.error("Please use '-h' for usage\n") +- sys.exit(EC_GENERIC_ERROR) ++ if stop: ++ logging.error("Please use '-h' for usage\n") ++ sys.exit(EC_GENERIC_ERROR) + + def fail(error_code): + message = { +@@ -602,6 +604,7 @@ + print "\t" + print "\t" + print "\t" ++ print "\t" + if avail_opt.count("diag") == 1: + print "\t" + print "" +@@ -707,7 +710,7 @@ + ## in each of the fencing agents. It looks for possible errors and run + ## password script to set a correct password + ###### +-def check_input(device_opt, opt): ++def check_input(device_opt, opt, other_conditions = False): + + device_opt.extend(add_dependency_options(device_opt)) + +@@ -784,7 +787,7 @@ + ## add loggint to stderr + logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stderr)) + +- acceptable_actions = ["on", "off", "status", "list", "list-status", "monitor"] ++ acceptable_actions = ["on", "off", "status", "list", "list-status", "monitor", "validate-all"] + if 1 == device_opt.count("fabric_fencing"): + ## Compatibility layer + ##### +@@ -808,6 +811,12 @@ + if options["--action"] == "disable": + options["--action"] = "off" + ++ if options["--action"] == "validate-all" and not other_conditions: ++ _validate_input(options, False) ++ sys.exit(EC_OK) ++ else: ++ _validate_input(options, True) ++ + ## automatic detection and set of valid UUID from --plug + if not options.has_key("--username") and \ + device_opt.count("login") and (device_opt.count("no_login") == 0): +@@ -1282,6 +1291,80 @@ + syslog.syslog(syslog_level, msg.replace("\x00","\n")) + return + ++# stop = True/False : exit fence agent when problem is encountered ++def _validate_input(options, stop = True): ++ device_opt = options["device_opt"] ++ valid_input = True ++ ++ if "--username" not in options and \ ++ device_opt.count("login") and (device_opt.count("no_login") == 0): ++ valid_input = False ++ fail_usage("Failed: You have to set login name", stop) ++ ++ if device_opt.count("ipaddr") and "--ip" not in options and "--managed" not in options and "--target" not in options: ++ valid_input = False ++ fail_usage("Failed: You have to enter fence address", stop) ++ ++ if device_opt.count("no_password") == 0: ++ if 0 == device_opt.count("identity_file"): ++ if not ("--password" in options or "--password-script" in options): ++ valid_input = False ++ fail_usage("Failed: You have to enter password or password script", stop) ++ else: ++ if not ("--password" in options or \ ++ "--password-script" in options or "--identity-file" in options): ++ valid_input = False ++ fail_usage("Failed: You have to enter password, password script or identity file", stop) ++ ++ if "--ssh" not in options and "--identity-file" in options: ++ valid_input = False ++ fail_usage("Failed: You have to use identity file together with ssh connection (-x)", stop) ++ ++ if "--identity-file" in options and not os.path.isfile(options["--identity-file"]): ++ valid_input = False ++ fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist", stop) ++ ++ if (0 == ["list", "list-status", "monitor"].count(options["--action"])) and \ ++ "--plug" not in options and device_opt.count("port") and \ ++ device_opt.count("no_port") == 0 and not device_opt.count("port_as_ip"): ++ valid_input = False ++ fail_usage("Failed: You have to enter plug number or machine identification", stop) ++ ++ if "--plug" in options and len(options["--plug"].split(",")) > 1 and \ ++ "--method" in options and options["--method"] == "cycle": ++ valid_input = False ++ fail_usage("Failed: Cannot use --method cycle for more than 1 plug", stop) ++ ++ for failed_opt in _get_opts_with_invalid_choices(options): ++ valid_input = False ++ fail_usage("Failed: You have to enter a valid choice for %s from the valid values: %s" % \ ++ ("--" + all_opt[failed_opt]["longopt"], str(all_opt[failed_opt]["choices"])), stop) ++ ++ for failed_opt in _get_opts_with_invalid_types(options): ++ valid_input = False ++ if all_opt[failed_opt]["type"] == "second": ++ fail_usage("Failed: The value you have entered for %s is not a valid time in seconds" % \ ++ ("--" + all_opt[failed_opt]["longopt"]), stop) ++ else: ++ fail_usage("Failed: The value you have entered for %s is not a valid %s" % \ ++ ("--" + all_opt[failed_opt]["longopt"], all_opt[failed_opt]["type"]), stop) ++ ++ return valid_input ++ ++def _get_opts_with_invalid_choices(options): ++ options_failed = [] ++ device_opt = options["device_opt"] ++ ++ for opt in device_opt: ++ if "choices" in all_opt[opt]: ++ longopt = "--" + all_opt[opt]["longopt"] ++ possible_values_upper = [y.upper() for y in all_opt[opt]["choices"]] ++ if longopt in options: ++ options[longopt] = options[longopt].upper() ++ if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper: ++ options_failed.append(opt) ++ return options_failed ++ + def _get_opts_with_invalid_types(options): + options_failed = [] + device_opt = options["device_opt"] +diff -uNr a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml +--- a/tests/data/metadata/fence_alom.xml 2017-03-20 15:01:35.822589244 +0100 ++++ b/tests/data/metadata/fence_alom.xml 2017-03-20 16:11:03.193530549 +0100 +@@ -133,5 +133,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml +--- a/tests/data/metadata/fence_amt.xml 2017-03-20 15:01:35.822589244 +0100 ++++ b/tests/data/metadata/fence_amt.xml 2017-03-20 16:11:03.193530549 +0100 +@@ -136,5 +136,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_apc_snmp.xml b/tests/data/metadata/fence_apc_snmp.xml +--- a/tests/data/metadata/fence_apc_snmp.xml 2017-03-20 15:01:35.822589244 +0100 ++++ b/tests/data/metadata/fence_apc_snmp.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -162,5 +162,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_apc.xml b/tests/data/metadata/fence_apc.xml +--- a/tests/data/metadata/fence_apc.xml 2017-03-20 15:01:35.822589244 +0100 ++++ b/tests/data/metadata/fence_apc.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -138,5 +138,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_bladecenter.xml b/tests/data/metadata/fence_bladecenter.xml +--- a/tests/data/metadata/fence_bladecenter.xml 2017-03-20 15:01:35.822589244 +0100 ++++ b/tests/data/metadata/fence_bladecenter.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -138,5 +138,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_brocade.xml b/tests/data/metadata/fence_brocade.xml +--- a/tests/data/metadata/fence_brocade.xml 2017-03-20 15:01:35.822589244 +0100 ++++ b/tests/data/metadata/fence_brocade.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -132,5 +132,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_cisco_mds.xml b/tests/data/metadata/fence_cisco_mds.xml +--- a/tests/data/metadata/fence_cisco_mds.xml 2017-03-20 15:01:35.823589234 +0100 ++++ b/tests/data/metadata/fence_cisco_mds.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -161,5 +161,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +--- a/tests/data/metadata/fence_cisco_ucs.xml 2017-03-20 15:01:35.823589234 +0100 ++++ b/tests/data/metadata/fence_cisco_ucs.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -143,5 +143,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +--- a/tests/data/metadata/fence_compute.xml 2017-03-20 15:01:35.823589234 +0100 ++++ b/tests/data/metadata/fence_compute.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -137,5 +137,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml +--- a/tests/data/metadata/fence_docker.xml 2017-03-20 15:01:35.823589234 +0100 ++++ b/tests/data/metadata/fence_docker.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -136,5 +136,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_drac5.xml b/tests/data/metadata/fence_drac5.xml +--- a/tests/data/metadata/fence_drac5.xml 2017-03-20 15:01:35.823589234 +0100 ++++ b/tests/data/metadata/fence_drac5.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -142,5 +142,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml +--- a/tests/data/metadata/fence_drac.xml 2017-03-20 15:01:35.823589234 +0100 ++++ b/tests/data/metadata/fence_drac.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -118,5 +118,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_dummy.xml b/tests/data/metadata/fence_dummy.xml +--- a/tests/data/metadata/fence_dummy.xml 2017-03-20 15:01:35.823589234 +0100 ++++ b/tests/data/metadata/fence_dummy.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -83,5 +83,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_eaton_snmp.xml b/tests/data/metadata/fence_eaton_snmp.xml +--- a/tests/data/metadata/fence_eaton_snmp.xml 2017-03-20 15:01:35.823589234 +0100 ++++ b/tests/data/metadata/fence_eaton_snmp.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -162,5 +162,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +--- a/tests/data/metadata/fence_emerson.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_emerson.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -162,5 +162,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml +--- a/tests/data/metadata/fence_eps.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_eps.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -120,5 +120,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_hds_cb.xml b/tests/data/metadata/fence_hds_cb.xml +--- a/tests/data/metadata/fence_hds_cb.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_hds_cb.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -138,5 +138,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_hpblade.xml b/tests/data/metadata/fence_hpblade.xml +--- a/tests/data/metadata/fence_hpblade.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_hpblade.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -138,5 +138,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ibmblade.xml b/tests/data/metadata/fence_ibmblade.xml +--- a/tests/data/metadata/fence_ibmblade.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_ibmblade.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -162,5 +162,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +--- a/tests/data/metadata/fence_idrac.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_idrac.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -173,6 +173,7 @@ + + + ++ + + + +diff -uNr a/tests/data/metadata/fence_ifmib.xml b/tests/data/metadata/fence_ifmib.xml +--- a/tests/data/metadata/fence_ifmib.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_ifmib.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -163,5 +163,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +--- a/tests/data/metadata/fence_ilo2.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_ilo2.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -144,5 +144,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +--- a/tests/data/metadata/fence_ilo3_ssh.xml 2017-03-20 15:01:35.824589224 +0100 ++++ b/tests/data/metadata/fence_ilo3_ssh.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -143,5 +143,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +--- a/tests/data/metadata/fence_ilo3.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_ilo3.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -173,6 +173,7 @@ + + + ++ + + + +diff -uNr a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +--- a/tests/data/metadata/fence_ilo4_ssh.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_ilo4_ssh.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -143,5 +143,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +--- a/tests/data/metadata/fence_ilo4.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_ilo4.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -173,6 +173,7 @@ + + + ++ + + + +diff -uNr a/tests/data/metadata/fence_ilo_moonshot.xml b/tests/data/metadata/fence_ilo_moonshot.xml +--- a/tests/data/metadata/fence_ilo_moonshot.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_ilo_moonshot.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -133,5 +133,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml +--- a/tests/data/metadata/fence_ilo_mp.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_ilo_mp.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -133,5 +133,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +--- a/tests/data/metadata/fence_ilo_ssh.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_ilo_ssh.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -143,5 +143,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +--- a/tests/data/metadata/fence_ilo.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_ilo.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -144,5 +144,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +--- a/tests/data/metadata/fence_imm.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_imm.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -173,6 +173,7 @@ + + + ++ + + + +diff -uNr a/tests/data/metadata/fence_intelmodular.xml b/tests/data/metadata/fence_intelmodular.xml +--- a/tests/data/metadata/fence_intelmodular.xml 2017-03-20 15:01:35.825589214 +0100 ++++ b/tests/data/metadata/fence_intelmodular.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -164,5 +164,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ipdu.xml b/tests/data/metadata/fence_ipdu.xml +--- a/tests/data/metadata/fence_ipdu.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_ipdu.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -162,5 +162,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +--- a/tests/data/metadata/fence_ipmilan.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_ipmilan.xml 2017-03-20 16:11:03.194530540 +0100 +@@ -173,6 +173,7 @@ + + + ++ + + + +diff -uNr a/tests/data/metadata/fence_ldom.xml b/tests/data/metadata/fence_ldom.xml +--- a/tests/data/metadata/fence_ldom.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_ldom.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -135,5 +135,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_lpar.xml b/tests/data/metadata/fence_lpar.xml +--- a/tests/data/metadata/fence_lpar.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_lpar.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -147,5 +147,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +--- a/tests/data/metadata/fence_mpath.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_mpath.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -91,5 +91,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_netio.xml b/tests/data/metadata/fence_netio.xml +--- a/tests/data/metadata/fence_netio.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_netio.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -113,5 +113,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_ovh.xml b/tests/data/metadata/fence_ovh.xml +--- a/tests/data/metadata/fence_ovh.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_ovh.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -97,5 +97,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_pve.xml b/tests/data/metadata/fence_pve.xml +--- a/tests/data/metadata/fence_pve.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_pve.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -118,5 +118,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_raritan.xml b/tests/data/metadata/fence_raritan.xml +--- a/tests/data/metadata/fence_raritan.xml 2017-03-20 15:01:35.826589205 +0100 ++++ b/tests/data/metadata/fence_raritan.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -113,5 +113,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +--- a/tests/data/metadata/fence_rhevm.xml 2017-03-20 15:01:35.827589195 +0100 ++++ b/tests/data/metadata/fence_rhevm.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -142,5 +142,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml +--- a/tests/data/metadata/fence_rsa.xml 2017-03-20 15:01:35.827589195 +0100 ++++ b/tests/data/metadata/fence_rsa.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -133,5 +133,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml +--- a/tests/data/metadata/fence_rsb.xml 2017-03-20 15:01:35.827589195 +0100 ++++ b/tests/data/metadata/fence_rsb.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -133,5 +133,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_sanbox2.xml b/tests/data/metadata/fence_sanbox2.xml +--- a/tests/data/metadata/fence_sanbox2.xml 2017-03-20 15:01:35.827589195 +0100 ++++ b/tests/data/metadata/fence_sanbox2.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -117,5 +117,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_sbd.xml b/tests/data/metadata/fence_sbd.xml +--- a/tests/data/metadata/fence_sbd.xml 2017-03-20 15:01:35.827589195 +0100 ++++ b/tests/data/metadata/fence_sbd.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -95,5 +95,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +--- a/tests/data/metadata/fence_scsi.xml 2017-03-20 15:01:35.827589195 +0100 ++++ b/tests/data/metadata/fence_scsi.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -109,5 +109,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml +--- a/tests/data/metadata/fence_virsh.xml 2017-03-20 15:01:35.827589195 +0100 ++++ b/tests/data/metadata/fence_virsh.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -145,5 +145,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml +--- a/tests/data/metadata/fence_vmware_soap.xml 2017-03-20 15:01:35.827589195 +0100 ++++ b/tests/data/metadata/fence_vmware_soap.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -135,5 +135,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_wti.xml b/tests/data/metadata/fence_wti.xml +--- a/tests/data/metadata/fence_wti.xml 2017-03-20 15:01:35.828589185 +0100 ++++ b/tests/data/metadata/fence_wti.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -133,5 +133,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_xenapi.xml b/tests/data/metadata/fence_xenapi.xml +--- a/tests/data/metadata/fence_xenapi.xml 2017-03-20 15:01:35.828589185 +0100 ++++ b/tests/data/metadata/fence_xenapi.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -98,5 +98,6 @@ + + + ++ + + +diff -uNr a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +--- a/tests/data/metadata/fence_zvmip.xml 2017-03-20 15:01:35.828589185 +0100 ++++ b/tests/data/metadata/fence_zvmip.xml 2017-03-20 16:11:03.195530530 +0100 +@@ -140,5 +140,6 @@ + + + ++ + + diff --git a/SOURCES/bz1433948-2-validate-all-action.patch b/SOURCES/bz1433948-2-validate-all-action.patch new file mode 100644 index 0000000..cdf66d6 --- /dev/null +++ b/SOURCES/bz1433948-2-validate-all-action.patch @@ -0,0 +1,23 @@ +From 57782246a43fac8640086c737597b7747120bb6d Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Tue, 21 Mar 2017 13:29:42 +0100 +Subject: [PATCH] validate-all: check _validate_input() return code + +--- + fence/agents/lib/fencing.py.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py +index 6d32101..546640e 100644 +--- a/fence/agents/lib/fencing.py.py ++++ b/fence/agents/lib/fencing.py.py +@@ -680,7 +680,8 @@ def check_input(device_opt, opt, other_conditions = False): + + + if options["--action"] == "validate-all" and not other_conditions: +- _validate_input(options, False) ++ if not _validate_input(options, False): ++ fail_usage("validate-all failed") + sys.exit(EC_OK) + else: + _validate_input(options, True) diff --git a/SOURCES/bz1459199-fence_vmware_soap-fix-for-selfsigned-certificate.patch b/SOURCES/bz1459199-fence_vmware_soap-fix-for-selfsigned-certificate.patch new file mode 100644 index 0000000..fa50b6c --- /dev/null +++ b/SOURCES/bz1459199-fence_vmware_soap-fix-for-selfsigned-certificate.patch @@ -0,0 +1,24 @@ +From ffb302ccca647984a9903074fd3ac97ba701741e Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Tue, 6 Jun 2017 17:18:42 +0200 +Subject: [PATCH] fence_vmware_soap: fix for selfsigned certificate + +--- + fence/agents/vmware_soap/fence_vmware_soap.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py +index 93f96583..007a1c67 100644 +--- a/fence/agents/vmware_soap/fence_vmware_soap.py ++++ b/fence/agents/vmware_soap/fence_vmware_soap.py +@@ -42,7 +42,10 @@ def soap_login(options): + + if options.has_key("--ssl") or options.has_key("--ssl-secure") or options.has_key("--ssl-insecure"): + if options.has_key("--ssl-insecure"): ++ import ssl + from requests.packages.urllib3.exceptions import InsecureRequestWarning ++ if hasattr(ssl, '_create_unverified_context'): ++ ssl._create_default_https_context = ssl._create_unverified_context + requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + verify = False + else: diff --git a/SOURCES/bz1479851-fence_compute-fence_scsi-fix-parameters.patch b/SOURCES/bz1479851-fence_compute-fence_scsi-fix-parameters.patch new file mode 100644 index 0000000..e1b8b80 --- /dev/null +++ b/SOURCES/bz1479851-fence_compute-fence_scsi-fix-parameters.patch @@ -0,0 +1,100 @@ +diff -uNr a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +--- a/fence/agents/compute/fence_compute.py 2017-07-24 12:16:11.193996848 +0200 ++++ b/fence/agents/compute/fence_compute.py 2017-07-24 12:18:18.012271280 +0200 +@@ -367,7 +367,7 @@ + logging.warning("Couldn't obtain a supported connection to nova, tried: %s\n" % repr(versions)) + + def define_new_opts(): +- all_opt["endpoint-type"] = { ++ all_opt["endpoint_type"] = { + "getopt" : "e:", + "longopt" : "endpoint-type", + "help" : "-e, --endpoint-type=[endpoint] Nova Endpoint type (publicURL, internalURL, adminURL)", +@@ -376,7 +376,7 @@ + "default" : "internalURL", + "order": 1, + } +- all_opt["tenant-name"] = { ++ all_opt["tenant_name"] = { + "getopt" : "t:", + "longopt" : "tenant-name", + "help" : "-t, --tenant-name=[tenant] Keystone Admin Tenant", +@@ -385,7 +385,7 @@ + "default" : "", + "order": 1, + } +- all_opt["auth-url"] = { ++ all_opt["auth_url"] = { + "getopt" : "k:", + "longopt" : "auth-url", + "help" : "-k, --auth-url=[url] Keystone Admin Auth URL", +@@ -394,7 +394,7 @@ + "default" : "", + "order": 1, + } +- all_opt["region-name"] = { ++ all_opt["region_name"] = { + "getopt" : "", + "longopt" : "region-name", + "help" : "--region-name=[region] Region Name", +@@ -420,7 +420,7 @@ + "shortdesc" : "DNS domain in which hosts live", + "order": 5, + } +- all_opt["record-only"] = { ++ all_opt["record_only"] = { + "getopt" : "r:", + "longopt" : "record-only", + "help" : "--record-only Record the target as needing evacuation but as yet do not intiate it", +@@ -429,7 +429,7 @@ + "default" : "False", + "order": 5, + } +- all_opt["instance-filtering"] = { ++ all_opt["instance_filtering"] = { + "getopt" : "", + "longopt" : "instance-filtering", + "help" : "--instance-filtering Allow instances created from images and flavors with evacuable=true to be evacuated (or all if no images/flavors have been tagged)", +@@ -438,7 +438,7 @@ + "default" : "True", + "order": 5, + } +- all_opt["no-shared-storage"] = { ++ all_opt["no_shared_storage"] = { + "getopt" : "", + "longopt" : "no-shared-storage", + "help" : "--no-shared-storage Disable functionality for shared storage", +@@ -452,9 +452,9 @@ + global override_status + atexit.register(atexit_handler) + +- device_opt = ["login", "passwd", "tenant-name", "auth-url", "fabric_fencing", +- "no_login", "no_password", "port", "domain", "no-shared-storage", "endpoint-type", +- "record-only", "instance-filtering", "insecure", "region-name"] ++ device_opt = ["login", "passwd", "tenant_name", "auth_url", "fabric_fencing", ++ "no_login", "no_password", "port", "domain", "no_shared_storage", "endpoint_type", ++ "record_only", "instance_filtering", "insecure", "region_name"] + define_new_opts() + all_opt["shell_timeout"]["default"] = "180" + +diff -uNr a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py +--- a/fence/agents/scsi/fence_scsi.py 2017-07-24 12:16:11.135997637 +0200 ++++ b/fence/agents/scsi/fence_scsi.py 2017-07-24 12:20:21.987584397 +0200 +@@ -332,7 +332,7 @@ + "shortdesc" : "Log output (stdout and stderr) to file", + "order": 5 + } +- all_opt["corosync-cmap_path"] = { ++ all_opt["corosync_cmap_path"] = { + "getopt" : "Z:", + "longopt" : "corosync-cmap-path", + "help" : "--corosync-cmap-path=[path] Path to corosync-cmapctl binary", +@@ -416,7 +416,7 @@ + atexit.register(atexit_handler) + + device_opt = ["no_login", "no_password", "devices", "nodename", "key",\ +- "aptpl", "fabric_fencing", "on_target", "corosync-cmap_path",\ ++ "aptpl", "fabric_fencing", "on_target", "corosync_cmap_path",\ + "sg_persist_path", "sg_turs_path", "logfile", "vgs_path", "force_on"] + + define_new_opts() diff --git a/SOURCES/bz1497072-fence_compute-fence_evacuate-Instance-HA-OSP12.patch b/SOURCES/bz1497072-fence_compute-fence_evacuate-Instance-HA-OSP12.patch new file mode 100644 index 0000000..6ca484d --- /dev/null +++ b/SOURCES/bz1497072-fence_compute-fence_evacuate-Instance-HA-OSP12.patch @@ -0,0 +1,1119 @@ +diff -uNr a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +--- a/fence/agents/compute/fence_compute.py 2017-09-27 15:01:34.974642469 +0200 ++++ b/fence/agents/compute/fence_compute.py 2017-09-27 15:24:57.482819900 +0200 +@@ -18,173 +18,115 @@ + #END_VERSION_GENERATION + + override_status = "" +-nova = None + + EVACUABLE_TAG = "evacuable" + TRUE_TAGS = ['true'] + +-def get_power_status(_, options): +- global override_status +- +- status = "unknown" +- logging.debug("get action: " + options["--action"]) ++def get_power_status(connection, options): + + if len(override_status): + logging.debug("Pretending we're " + override_status) + return override_status + +- if nova: ++ status = "unknown" ++ logging.debug("get action: " + options["--action"]) ++ ++ if connection: + try: +- services = nova.services.list(host=options["--plug"]) ++ services = connection.services.list(host=options["--plug"], binary="nova-compute") + for service in services: +- logging.debug("Status of %s is %s" % (service.binary, service.state)) +- if service.binary == "nova-compute": +- if service.state == "up": +- status = "on" +- elif service.state == "down": +- status = "off" +- else: +- logging.debug("Unknown status detected from nova: " + service.state) +- break ++ logging.debug("Status of %s on %s is %s, %s" % (service.binary, options["--plug"], service.state, service.status)) ++ if service.state == "up" and service.status == "enabled": ++ # Up and operational ++ status = "on" ++ ++ elif service.state == "down" and service.status == "disabled": ++ # Down and fenced ++ status = "off" ++ ++ elif service.state == "down": ++ # Down and requires fencing ++ status = "failed" ++ ++ elif service.state == "up": ++ # Up and requires unfencing ++ status = "running" ++ else: ++ logging.warning("Unknown status detected from nova for %s: %s, %s" % (options["--plug"], service.state, service.status)) ++ status = "%s %s" % (service.state, service.status) ++ break + except requests.exception.ConnectionError as err: + logging.warning("Nova connection failed: " + str(err)) ++ logging.debug("Final status of %s is %s" % (options["--plug"], status)) + return status + +-# NOTE(sbauza); We mimic the host-evacuate module since it's only a contrib +-# module which is not stable +-def _server_evacuate(server, on_shared_storage): +- success = False +- error_message = "" +- try: +- logging.debug("Resurrecting instance: %s" % server) +- (response, dictionary) = nova.servers.evacuate(server=server, on_shared_storage=on_shared_storage) +- +- if response == None: +- error_message = "No response while evacuating instance" +- elif response.status_code == 200: +- success = True +- error_message = response.reason +- else: +- error_message = response.reason +- +- except Exception as e: +- error_message = "Error while evacuating instance: %s" % e +- +- return { +- "uuid": server, +- "accepted": success, +- "reason": error_message, +- } +- +-def _is_server_evacuable(server, evac_flavors, evac_images): +- if server.flavor.get('id') in evac_flavors: +- return True +- if server.image.get('id') in evac_images: +- return True +- logging.debug("Instance %s is not evacuable" % server.image.get('id')) +- return False +- +-def _get_evacuable_flavors(): +- result = [] +- flavors = nova.flavors.list() +- # Since the detailed view for all flavors doesn't provide the extra specs, +- # we need to call each of the flavor to get them. +- for flavor in flavors: +- tag = flavor.get_keys().get(EVACUABLE_TAG) +- if tag and tag.strip().lower() in TRUE_TAGS: +- result.append(flavor.id) +- return result +- +-def _get_evacuable_images(): +- result = [] +- images = nova.images.list(detailed=True) +- for image in images: +- if hasattr(image, 'metadata'): +- tag = image.metadata.get(EVACUABLE_TAG) +- if tag and tag.strip().lower() in TRUE_TAGS: +- result.append(image.id) +- return result +- +-def _host_evacuate(options): +- result = True +- images = _get_evacuable_images() +- flavors = _get_evacuable_flavors() +- servers = nova.servers.list(search_opts={'host': options["--plug"], 'all_tenants': 1 }) +- +- if options["--instance-filtering"] == "False": +- logging.debug("Not evacuating anything") +- evacuables = [] +- elif len(flavors) or len(images): +- logging.debug("Filtering images and flavors: %s %s" % (repr(flavors), repr(images))) +- # Identify all evacuable servers +- logging.debug("Checking %s" % repr(servers)) +- evacuables = [server for server in servers +- if _is_server_evacuable(server, flavors, images)] +- logging.debug("Evacuating %s" % repr(evacuables)) +- else: +- logging.debug("Evacuating all images and flavors") +- evacuables = servers +- +- if options["--no-shared-storage"] != "False": +- on_shared_storage = False +- else: +- on_shared_storage = True +- +- for server in evacuables: +- logging.debug("Processing %s" % server) +- if hasattr(server, 'id'): +- response = _server_evacuate(server.id, on_shared_storage) +- if response["accepted"]: +- logging.debug("Evacuated %s from %s: %s" % +- (response["uuid"], options["--plug"], response["reason"])) +- else: +- logging.error("Evacuation of %s on %s failed: %s" % +- (response["uuid"], options["--plug"], response["reason"])) +- result = False +- else: +- logging.error("Could not evacuate instance: %s" % server.to_dict()) +- # Should a malformed instance result in a failed evacuation? +- # result = False +- return result ++def get_power_status_simple(connection, options): ++ status = get_power_status(connection, options) ++ if status in [ "off" ]: ++ return status ++ return "on" + + def set_attrd_status(host, status, options): + logging.debug("Setting fencing status for %s to %s" % (host, status)) + run_command(options, "attrd_updater -p -n evacuate -Q -N %s -U %s" % (host, status)) + +-def set_power_status(_, options): +- global override_status +- +- override_status = "" +- logging.debug("set action: " + options["--action"]) ++def get_attrd_status(host, options): ++ (status, pipe_stdout, pipe_stderr) = run_command(options, "attrd_updater -p -n evacuate -Q -N %s" % (host)) ++ fields = pipe_stdout.split('"') ++ if len(fields) > 6: ++ return fields[5] ++ logging.debug("Got %s: o:%s e:%s n:%d" % (status, pipe_stdout, pipe_stderr, len(fields))) ++ return "" ++ ++def set_power_status_on(connection, options): ++ # Wait for any evacuations to complete ++ while True: ++ current = get_attrd_status(options["--plug"], options) ++ if current in ["no", ""]: ++ logging.info("Evacuation complete for: %s '%s'" % (options["--plug"], current)) ++ break ++ else: ++ logging.info("Waiting for %s to complete evacuations: %s" % (options["--plug"], current)) ++ time.sleep(2) + +- if not nova: +- return ++ status = get_power_status(connection, options) ++ # Should we do it for 'failed' too? ++ if status in [ "off", "running", "failed" ]: ++ try: ++ # Forcing the host back up ++ logging.info("Forcing nova-compute back up on "+options["--plug"]) ++ connection.services.force_down(options["--plug"], "nova-compute", force_down=False) ++ logging.info("Forced nova-compute back up on "+options["--plug"]) ++ except Exception as e: ++ # In theory, if force_down=False fails, that's for the exact ++ # same possible reasons that below with force_down=True ++ # eg. either an incompatible version or an old client. ++ # Since it's about forcing back to a default value, there is ++ # no real worries to just consider it's still okay even if the ++ # command failed ++ logging.warn("Exception from attempt to force " ++ "host back up via nova API: " ++ "%s: %s" % (e.__class__.__name__, e)) ++ ++ # Forcing the service back up in case it was disabled ++ logging.info("Enabling nova-compute on "+options["--plug"]) ++ connection.services.enable(options["--plug"], 'nova-compute') + +- if options["--action"] == "on": +- if get_power_status(_, options) != "on": +- # Forcing the service back up in case it was disabled +- nova.services.enable(options["--plug"], 'nova-compute') +- try: +- # Forcing the host back up +- nova.services.force_down( +- options["--plug"], "nova-compute", force_down=False) +- except Exception as e: +- # In theory, if force_down=False fails, that's for the exact +- # same possible reasons that below with force_down=True +- # eg. either an incompatible version or an old client. +- # Since it's about forcing back to a default value, there is +- # no real worries to just consider it's still okay even if the +- # command failed +- logging.info("Exception from attempt to force " +- "host back up via nova API: " +- "%s: %s" % (e.__class__.__name__, e)) +- else: +- # Pretend we're 'on' so that the fencing library doesn't loop forever waiting for the node to boot +- override_status = "on" ++ # Pretend we're 'on' so that the fencing library doesn't loop forever waiting for the node to boot ++ override_status = "on" ++ elif status not in ["on"]: ++ # Not safe to unfence, don't waste time looping to see if the status changes to "on" ++ options["--power-timeout"] = "0" ++ ++def set_power_status_off(connection, options): ++ status = get_power_status(connection, options) ++ if status in [ "off" ]: + return + ++ connection.services.disable(options["--plug"], 'nova-compute') + try: +- nova.services.force_down( ++ # Until 2.53 ++ connection.services.force_down( + options["--plug"], "nova-compute", force_down=True) + except Exception as e: + # Something went wrong when we tried to force the host down. +@@ -198,7 +140,7 @@ + "%s: %s" % (e.__class__.__name__, e)) + # need to wait for nova to update its internal status or we + # cannot call host-evacuate +- while get_power_status(_, options) != "off": ++ while get_power_status(connection, options) not in ["off"]: + # Loop forever if need be. + # + # Some callers (such as Pacemaker) will have a timer +@@ -206,47 +148,55 @@ + logging.debug("Waiting for nova to update its internal state for %s" % options["--plug"]) + time.sleep(1) + +- if not _host_evacuate(options): +- sys.exit(1) ++ set_attrd_status(options["--plug"], "yes", options) ++ ++def set_power_status(connection, options): ++ global override_status + +- return ++ override_status = "" ++ logging.debug("set action: " + options["--action"]) ++ ++ if not connection: ++ return + ++ if options["--action"] in ["off", "reboot"]: ++ set_power_status_off(connection, options) ++ else: ++ set_power_status_on(connection, options) ++ logging.debug("set action passed: " + options["--action"]) ++ sys.exit(0) + +-def fix_domain(options): ++def fix_domain(connection, options): + domains = {} + last_domain = None + +- if nova: ++ if connection: + # Find it in nova + +- hypervisors = nova.hypervisors.list() +- for hypervisor in hypervisors: +- shorthost = hypervisor.hypervisor_hostname.split('.')[0] ++ services = connection.services.list(binary="nova-compute") ++ for service in services: ++ shorthost = service.host.split('.')[0] + +- if shorthost == hypervisor.hypervisor_hostname: ++ if shorthost == service.host: + # Nova is not using FQDN + calculated = "" + else: + # Compute nodes are named as FQDN, strip off the hostname +- calculated = hypervisor.hypervisor_hostname.replace(shorthost+".", "") +- +- domains[calculated] = shorthost ++ calculated = service.host.replace(shorthost+".", "") + + if calculated == last_domain: + # Avoid complaining for each compute node with the same name + # One hopes they don't appear interleaved as A.com B.com A.com B.com +- logging.debug("Calculated the same domain from: %s" % hypervisor.hypervisor_hostname) ++ logging.debug("Calculated the same domain from: %s" % service.host) ++ continue + +- elif "--domain" in options and options["--domain"] == calculated: +- # Supplied domain name is valid +- return ++ domains[calculated] = service.host ++ last_domain = calculated + +- elif "--domain" in options: ++ if "--domain" in options and options["--domain"] != calculated: + # Warn in case nova isn't available at some point + logging.warning("Supplied domain '%s' does not match the one calculated from: %s" +- % (options["--domain"], hypervisor.hypervisor_hostname)) +- +- last_domain = calculated ++ % (options["--domain"], service.host)) + + if len(domains) == 0 and "--domain" not in options: + logging.error("Could not calculate the domain names used by compute nodes in nova") +@@ -254,9 +204,9 @@ + elif len(domains) == 1 and "--domain" not in options: + options["--domain"] = last_domain + +- elif len(domains) == 1: +- logging.error("Overriding supplied domain '%s' does not match the one calculated from: %s" +- % (options["--domain"], hypervisor.hypervisor_hostname)) ++ elif len(domains) == 1 and options["--domain"] != last_domain: ++ logging.error("Overriding supplied domain '%s' as it does not match the one calculated from: %s" ++ % (options["--domain"], domains[last_domain])) + options["--domain"] = last_domain + + elif len(domains) > 1: +@@ -264,47 +214,49 @@ + % (options["--domain"], repr(domains))) + sys.exit(1) + +-def fix_plug_name(options): ++ return last_domain ++ ++def fix_plug_name(connection, options): + if options["--action"] == "list": + return + + if "--plug" not in options: + return + +- fix_domain(options) +- short_plug = options["--plug"].split('.')[0] +- logging.debug("Checking target '%s' against calculated domain '%s'"% (options["--plug"], options["--domain"])) +- +- if "--domain" not in options: ++ calculated = fix_domain(connection, options) ++ if calculated is None or "--domain" not in options: + # Nothing supplied and nova not available... what to do... nothing + return + +- elif options["--domain"] == "": ++ short_plug = options["--plug"].split('.')[0] ++ logging.debug("Checking target '%s' against calculated domain '%s'"% (options["--plug"], calculated)) ++ ++ if options["--domain"] == "": + # Ensure any domain is stripped off since nova isn't using FQDN + options["--plug"] = short_plug + +- elif options["--domain"] in options["--plug"]: +- # Plug already contains the domain, don't re-add ++ elif options["--plug"].endswith(options["--domain"]): ++ # Plug already uses the domain, don't re-add + return + + else: + # Add the domain to the plug + options["--plug"] = short_plug + "." + options["--domain"] + +-def get_plugs_list(_, options): ++def get_plugs_list(connection, options): + result = {} + +- if nova: +- hypervisors = nova.hypervisors.list() +- for hypervisor in hypervisors: +- longhost = hypervisor.hypervisor_hostname ++ if connection: ++ services = connection.services.list(binary="nova-compute") ++ for service in services: ++ longhost = service.host + shorthost = longhost.split('.')[0] + result[longhost] = ("", None) + result[shorthost] = ("", None) + return result + + def create_nova_connection(options): +- global nova ++ nova = None + + try: + from novaclient import client +@@ -330,41 +282,42 @@ + if clientargs: + # OSP < 11 + # ArgSpec(args=['version', 'username', 'password', 'project_id', 'auth_url'], +- # varargs=None, +- # keywords='kwargs', defaults=(None, None, None, None)) ++ # varargs=None, ++ # keywords='kwargs', defaults=(None, None, None, None)) + nova = client.Client(version, +- options["--username"], +- options["--password"], +- options["--tenant-name"], +- options["--auth-url"], +- insecure=options["--insecure"], +- region_name=options["--region-name"], +- endpoint_type=options["--endpoint-type"], +- http_log_debug=options.has_key("--verbose")) ++ options["--username"], ++ options["--password"], ++ options["--tenant-name"], ++ options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) + else: + # OSP >= 11 + # ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None) + nova = client.Client(version, +- username=options["--username"], +- password=options["--password"], +- tenant_name=options["--tenant-name"], +- auth_url=options["--auth-url"], +- insecure=options["--insecure"], +- region_name=options["--region-name"], +- endpoint_type=options["--endpoint-type"], +- http_log_debug=options.has_key("--verbose")) ++ username=options["--username"], ++ password=options["--password"], ++ tenant_name=options["--tenant-name"], ++ auth_url=options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) + + try: + nova.hypervisors.list() +- return ++ return nova + + except NotAcceptable as e: + logging.warning(e) + + except Exception as e: + logging.warning("Nova connection failed. %s: %s" % (e.__class__.__name__, e)) +- ++ + logging.warning("Couldn't obtain a supported connection to nova, tried: %s\n" % repr(versions)) ++ return None + + def define_new_opts(): + all_opt["endpoint_type"] = { +@@ -448,11 +401,23 @@ + "order": 5, + } + ++def set_multi_power_fn(connection, options, set_power_fn, get_power_fn, retry_attempts=1): ++ for _ in range(retry_attempts): ++ set_power_fn(connection, options) ++ time.sleep(int(options["--power-wait"])) ++ ++ for _ in range(int(options["--power-timeout"])): ++ if get_power_fn(connection, options) != options["--action"]: ++ time.sleep(1) ++ else: ++ return True ++ return False ++ + def main(): + global override_status + atexit.register(atexit_handler) + +- device_opt = ["login", "passwd", "tenant_name", "auth_url", "fabric_fencing", ++ device_opt = ["login", "passwd", "tenant_name", "auth_url", "fabric_fencing", + "no_login", "no_password", "port", "domain", "no_shared_storage", "endpoint_type", + "record_only", "instance_filtering", "insecure", "region_name"] + define_new_opts() +@@ -472,30 +437,28 @@ + + run_delay(options) + +- create_nova_connection(options) ++ logging.debug("Running "+options["--action"]) ++ connection = create_nova_connection(options) + +- fix_plug_name(options) +- if options["--record-only"] in [ "1", "True", "true", "Yes", "yes"]: +- if options["--action"] == "on": +- set_attrd_status(options["--plug"], "no", options) +- sys.exit(0) +- +- elif options["--action"] in ["off", "reboot"]: +- set_attrd_status(options["--plug"], "yes", options) +- sys.exit(0) ++ if options["--action"] in ["off", "on", "reboot", "status"]: ++ fix_plug_name(connection, options) + +- elif options["--action"] in ["monitor", "status"]: +- sys.exit(0) + +- if options["--action"] in ["off", "reboot"]: +- # Pretend we're 'on' so that the fencing library will always call set_power_status(off) +- override_status = "on" +- +- if options["--action"] == "on": +- # Pretend we're 'off' so that the fencing library will always call set_power_status(on) +- override_status = "off" ++ if options["--action"] in ["reboot"]: ++ options["--action"]="off" ++ ++ if options["--action"] in ["off", "on"]: ++ # No status first, call our own version ++ result = not set_multi_power_fn(connection, options, set_power_status, get_power_status_simple, ++ 1 + int(options["--retry-on"])) ++ elif options["--action"] in ["monitor"]: ++ result = 0 ++ else: ++ result = fence_action(connection, options, set_power_status, get_power_status_simple, get_plugs_list, None) + +- result = fence_action(None, options, set_power_status, get_power_status, get_plugs_list, None) ++ logging.debug("Result for "+options["--action"]+": "+repr(result)) ++ if result == None: ++ result = 0 + sys.exit(result) + + if __name__ == "__main__": +diff -uNr a/fence/agents/compute/fence_evacuate.py b/fence/agents/compute/fence_evacuate.py +--- a/fence/agents/compute/fence_evacuate.py 1970-01-01 01:00:00.000000000 +0100 ++++ b/fence/agents/compute/fence_evacuate.py 2017-09-27 15:25:54.234304769 +0200 +@@ -0,0 +1,366 @@ ++#!/usr/bin/python -tt ++ ++import sys ++import time ++import atexit ++import logging ++import inspect ++import requests.exceptions ++ ++sys.path.append("@FENCEAGENTSLIBDIR@") ++from fencing import * ++from fencing import fail_usage, is_executable, run_command, run_delay ++ ++EVACUABLE_TAG = "evacuable" ++TRUE_TAGS = ['true'] ++ ++def get_power_status(connection, options): ++ ++ status = "unknown" ++ logging.debug("get action: " + options["--action"]) ++ ++ if connection: ++ try: ++ services = connection.services.list(host=options["--plug"], binary="nova-compute") ++ for service in services: ++ logging.debug("Status of %s is %s, %s" % (service.binary, service.state, service.status)) ++ if service.state == "up" and service.status == "enabled": ++ # Up and operational ++ status = "on" ++ ++ elif service.state == "down" and service.status == "disabled": ++ # Down and fenced ++ status = "off" ++ ++ elif service.state == "down": ++ # Down and requires fencing ++ status = "failed" ++ ++ elif service.state == "up": ++ # Up and requires unfencing ++ status = "running" ++ else: ++ logging.warning("Unknown status detected from nova for %s: %s, %s" % (options["--plug"], service.state, service.status)) ++ status = "%s %s" % (service.state, service.status) ++ break ++ except requests.exception.ConnectionError as err: ++ logging.warning("Nova connection failed: " + str(err)) ++ return status ++ ++# NOTE(sbauza); We mimic the host-evacuate module since it's only a contrib ++# module which is not stable ++def _server_evacuate(connection, server, on_shared_storage): ++ success = False ++ error_message = "" ++ try: ++ logging.debug("Resurrecting instance: %s" % server) ++ (response, dictionary) = connection.servers.evacuate(server=server, on_shared_storage=on_shared_storage) ++ ++ if response == None: ++ error_message = "No response while evacuating instance" ++ elif response.status_code == 200: ++ success = True ++ error_message = response.reason ++ else: ++ error_message = response.reason ++ ++ except Exception as e: ++ error_message = "Error while evacuating instance: %s" % e ++ ++ return { ++ "uuid": server, ++ "accepted": success, ++ "reason": error_message, ++ } ++ ++def _is_server_evacuable(server, evac_flavors, evac_images): ++ if server.flavor.get('id') in evac_flavors: ++ return True ++ if hasattr(server.image, 'get'): ++ if server.image.get('id') in evac_images: ++ return True ++ logging.debug("Instance %s is not evacuable" % server.image.get('id')) ++ return False ++ ++def _get_evacuable_flavors(connection): ++ result = [] ++ flavors = connection.flavors.list() ++ # Since the detailed view for all flavors doesn't provide the extra specs, ++ # we need to call each of the flavor to get them. ++ for flavor in flavors: ++ tag = flavor.get_keys().get(EVACUABLE_TAG) ++ if tag and tag.strip().lower() in TRUE_TAGS: ++ result.append(flavor.id) ++ return result ++ ++def _get_evacuable_images(connection): ++ result = [] ++ images = [] ++ if hasattr(connection, "images"): ++ images = connection.images.list(detailed=True) ++ elif hasattr(connection, "glance"): ++ # OSP12+ ++ images = connection.glance.list() ++ ++ for image in images: ++ if hasattr(image, 'metadata'): ++ tag = image.metadata.get(EVACUABLE_TAG) ++ if tag and tag.strip().lower() in TRUE_TAGS: ++ result.append(image.id) ++ elif hasattr(image, 'tags'): ++ # OSP12+ ++ if EVACUABLE_TAG in image.tags: ++ result.append(image.id) ++ return result ++ ++def _host_evacuate(connection, options): ++ result = True ++ images = _get_evacuable_images(connection) ++ flavors = _get_evacuable_flavors(connection) ++ servers = connection.servers.list(search_opts={'host': options["--plug"], 'all_tenants': 1 }) ++ ++ if options["--instance-filtering"] == "False": ++ logging.debug("Not evacuating anything") ++ evacuables = [] ++ elif len(flavors) or len(images): ++ logging.debug("Filtering images and flavors: %s %s" % (repr(flavors), repr(images))) ++ # Identify all evacuable servers ++ logging.debug("Checking %s" % repr(servers)) ++ evacuables = [server for server in servers ++ if _is_server_evacuable(server, flavors, images)] ++ logging.debug("Evacuating %s" % repr(evacuables)) ++ else: ++ logging.debug("Evacuating all images and flavors") ++ evacuables = servers ++ ++ if options["--no-shared-storage"] != "False": ++ on_shared_storage = False ++ else: ++ on_shared_storage = True ++ ++ for server in evacuables: ++ logging.debug("Processing %s" % server) ++ if hasattr(server, 'id'): ++ response = _server_evacuate(connection, server.id, on_shared_storage) ++ if response["accepted"]: ++ logging.debug("Evacuated %s from %s: %s" % ++ (response["uuid"], options["--plug"], response["reason"])) ++ else: ++ logging.error("Evacuation of %s on %s failed: %s" % ++ (response["uuid"], options["--plug"], response["reason"])) ++ result = False ++ else: ++ logging.error("Could not evacuate instance: %s" % server.to_dict()) ++ # Should a malformed instance result in a failed evacuation? ++ # result = False ++ return result ++ ++def set_attrd_status(host, status, options): ++ logging.debug("Setting fencing status for %s to %s" % (host, status)) ++ run_command(options, "attrd_updater -p -n evacuate -Q -N %s -U %s" % (host, status)) ++ ++def set_power_status(connection, options): ++ logging.debug("set action: " + options["--action"]) ++ ++ if not connection: ++ return ++ ++ if options["--action"] == "off" and not _host_evacuate(options): ++ sys.exit(1) ++ ++ sys.exit(0) ++ ++def get_plugs_list(connection, options): ++ result = {} ++ ++ if connection: ++ services = connection.services.list(binary="nova-compute") ++ for service in services: ++ longhost = service.host ++ shorthost = longhost.split('.')[0] ++ result[longhost] = ("", None) ++ result[shorthost] = ("", None) ++ return result ++ ++def create_nova_connection(options): ++ nova = None ++ ++ try: ++ from novaclient import client ++ from novaclient.exceptions import NotAcceptable ++ except ImportError: ++ fail_usage("Nova not found or not accessible") ++ ++ versions = [ "2.11", "2" ] ++ for version in versions: ++ clientargs = inspect.getargspec(client.Client).varargs ++ ++ # Some versions of Openstack prior to Ocata only ++ # supported positional arguments for username, ++ # password and tenant. ++ # ++ # Versions since Ocata only support named arguments. ++ # ++ # So we need to use introspection to figure out how to ++ # create a Nova client. ++ # ++ # Happy days ++ # ++ if clientargs: ++ # OSP < 11 ++ # ArgSpec(args=['version', 'username', 'password', 'project_id', 'auth_url'], ++ # varargs=None, ++ # keywords='kwargs', defaults=(None, None, None, None)) ++ nova = client.Client(version, ++ options["--username"], ++ options["--password"], ++ options["--tenant-name"], ++ options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) ++ else: ++ # OSP >= 11 ++ # ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None) ++ nova = client.Client(version, ++ username=options["--username"], ++ password=options["--password"], ++ tenant_name=options["--tenant-name"], ++ auth_url=options["--auth-url"], ++ insecure=options["--insecure"], ++ region_name=options["--region-name"], ++ endpoint_type=options["--endpoint-type"], ++ http_log_debug=options.has_key("--verbose")) ++ ++ try: ++ nova.hypervisors.list() ++ return nova ++ ++ except NotAcceptable as e: ++ logging.warning(e) ++ ++ except Exception as e: ++ logging.warning("Nova connection failed. %s: %s" % (e.__class__.__name__, e)) ++ ++ logging.warning("Couldn't obtain a supported connection to nova, tried: %s\n" % repr(versions)) ++ return None ++ ++def define_new_opts(): ++ all_opt["endpoint_type"] = { ++ "getopt" : "e:", ++ "longopt" : "endpoint-type", ++ "help" : "-e, --endpoint-type=[endpoint] Nova Endpoint type (publicURL, internalURL, adminURL)", ++ "required" : "0", ++ "shortdesc" : "Nova Endpoint type", ++ "default" : "internalURL", ++ "order": 1, ++ } ++ all_opt["tenant_name"] = { ++ "getopt" : "t:", ++ "longopt" : "tenant-name", ++ "help" : "-t, --tenant-name=[tenant] Keystone Admin Tenant", ++ "required" : "0", ++ "shortdesc" : "Keystone Admin Tenant", ++ "default" : "", ++ "order": 1, ++ } ++ all_opt["auth_url"] = { ++ "getopt" : "k:", ++ "longopt" : "auth-url", ++ "help" : "-k, --auth-url=[url] Keystone Admin Auth URL", ++ "required" : "0", ++ "shortdesc" : "Keystone Admin Auth URL", ++ "default" : "", ++ "order": 1, ++ } ++ all_opt["region_name"] = { ++ "getopt" : "", ++ "longopt" : "region-name", ++ "help" : "--region-name=[region] Region Name", ++ "required" : "0", ++ "shortdesc" : "Region Name", ++ "default" : "", ++ "order": 1, ++ } ++ all_opt["insecure"] = { ++ "getopt" : "", ++ "longopt" : "insecure", ++ "help" : "--insecure Explicitly allow agent to perform \"insecure\" TLS (https) requests", ++ "required" : "0", ++ "shortdesc" : "Allow Insecure TLS Requests", ++ "default" : "False", ++ "order": 2, ++ } ++ all_opt["domain"] = { ++ "getopt" : "d:", ++ "longopt" : "domain", ++ "help" : "-d, --domain=[string] DNS domain in which hosts live, useful when the cluster uses short names and nova uses FQDN", ++ "required" : "0", ++ "shortdesc" : "DNS domain in which hosts live", ++ "order": 5, ++ } ++ all_opt["instance_filtering"] = { ++ "getopt" : "", ++ "longopt" : "instance-filtering", ++ "help" : "--instance-filtering Allow instances created from images and flavors with evacuable=true to be evacuated (or all if no images/flavors have been tagged)", ++ "required" : "0", ++ "shortdesc" : "Allow instances to be evacuated", ++ "default" : "True", ++ "order": 5, ++ } ++ all_opt["no_shared_storage"] = { ++ "getopt" : "", ++ "longopt" : "no-shared-storage", ++ "help" : "--no-shared-storage Disable functionality for shared storage", ++ "required" : "0", ++ "shortdesc" : "Disable functionality for dealing with shared storage", ++ "default" : "False", ++ "order": 5, ++ } ++ ++def main(): ++ atexit.register(atexit_handler) ++ ++ device_opt = ["login", "passwd", "tenant_name", "auth_url", ++ "no_login", "no_password", "port", "domain", "no_shared_storage", "endpoint_type", ++ "instance_filtering", "insecure", "region_name"] ++ define_new_opts() ++ all_opt["shell_timeout"]["default"] = "180" ++ ++ options = check_input(device_opt, process_input(device_opt)) ++ ++ docs = {} ++ docs["shortdesc"] = "Fence agent for the automatic resurrection of OpenStack compute instances" ++ docs["longdesc"] = "Used to reschedule flagged instances" ++ docs["vendorurl"] = "" ++ ++ show_docs(options, docs) ++ ++ run_delay(options) ++ ++ connection = create_nova_connection(options) ++ ++ # Un-evacuating a server doesn't make sense ++ if options["--action"] in ["on"]: ++ logging.error("Action %s is not supported by this agent" % (options["--action"])) ++ sys.exit(1) ++ ++ if options["--action"] in ["off", "reboot"]: ++ status = get_power_status(connection, options) ++ if status != "off": ++ logging.error("Cannot resurrect instances from %s in state '%s'" % (options["--plug"], status)) ++ sys.exit(1) ++ ++ elif not _host_evacuate(connection, options): ++ logging.error("Resurrection of instances from %s failed" % (options["--plug"])) ++ sys.exit(1) ++ ++ logging.info("Resurrection of instances from %s complete" % (options["--plug"])) ++ sys.exit(0) ++ ++ result = fence_action(connection, options, set_power_status, get_power_status, get_plugs_list, None) ++ sys.exit(result) ++ ++if __name__ == "__main__": ++ main() +diff -uNr a/fence/agents/compute/Makefile.am b/fence/agents/compute/Makefile.am +--- a/fence/agents/compute/Makefile.am 2017-09-27 15:01:34.844643650 +0200 ++++ b/fence/agents/compute/Makefile.am 2017-09-27 15:57:50.963839738 +0200 +@@ -1,14 +1,14 @@ + MAINTAINERCLEANFILES = Makefile.in + +-TARGET = fence_compute ++TARGET = fence_compute fence_evacuate + +-SRC = $(TARGET).py ++SRC = $(TARGET:=.py) + + EXTRA_DIST = $(SRC) + + sbin_SCRIPTS = $(TARGET) + +-man_MANS = $(TARGET).8 ++man_MANS = $(TARGET:=.8) + + FENCE_TEST_ARGS = -l test -p test -n 1 + +diff -uNr a/tests/data/metadata/fence_evacuate.xml b/tests/data/metadata/fence_evacuate.xml +--- a/tests/data/metadata/fence_evacuate.xml 1970-01-01 01:00:00.000000000 +0100 ++++ b/tests/data/metadata/fence_evacuate.xml 2017-09-27 15:28:10.978063549 +0200 +@@ -0,0 +1,163 @@ ++ ++ ++Used to reschedule flagged instances ++ ++ ++ ++ ++ ++ Keystone Admin Tenant ++ ++ ++ ++ ++ Keystone Admin Auth URL ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Region Name ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Nova Endpoint type ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Physical plug number, name of virtual machine or UUID ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Allow Insecure TLS Requests ++ ++ ++ ++ ++ DNS domain in which hosts live ++ ++ ++ ++ ++ Allow instances to be evacuated ++ ++ ++ ++ ++ Disable functionality for dealing with shared storage ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Separator for CSV created by operation list ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --git a/SOURCES/bz1497241-fence_compute-fence_scsi-fix-parameters.patch b/SOURCES/bz1497241-fence_compute-fence_scsi-fix-parameters.patch new file mode 100644 index 0000000..2d24cf4 --- /dev/null +++ b/SOURCES/bz1497241-fence_compute-fence_scsi-fix-parameters.patch @@ -0,0 +1,18 @@ +--- a/fence/agents/lib/fencing.py.py 2017-09-19 12:29:04.158438532 +0200 ++++ b/fence/agents/lib/fencing.py.py 2017-09-19 12:48:22.252509114 +0200 +@@ -705,11 +705,12 @@ + continue + + (name, value) = (line + "=").split("=", 1) +- name = name.replace("-", "_"); + value = value[:-1] + +- if name in mapping_longopt_names: +- name = mapping_longopt_names[name] ++ if name.replace("-", "_") in mapping_longopt_names: ++ name = mapping_longopt_names[name.replace("-", "_")] ++ elif name.replace("_", "-") in mapping_longopt_names: ++ name = mapping_longopt_names[name.replace("_", "-")] + + if avail_opt.count(name) == 0 and name in ["nodename"]: + continue diff --git a/SOURCES/bz1535415-fence_compute-fence_evacuate-add-support-for-keystone-v3-authentication.patch b/SOURCES/bz1535415-fence_compute-fence_evacuate-add-support-for-keystone-v3-authentication.patch new file mode 100644 index 0000000..f653339 --- /dev/null +++ b/SOURCES/bz1535415-fence_compute-fence_evacuate-add-support-for-keystone-v3-authentication.patch @@ -0,0 +1,281 @@ +diff -uNr a/fence/agents/compute/fence_compute.py b/fence/agents/compute/fence_compute.py +--- a/fence/agents/compute/fence_compute.py 2018-01-10 13:46:17.965287100 +0100 ++++ b/fence/agents/compute/fence_compute.py 2018-01-11 10:01:12.288043619 +0100 +@@ -11,12 +11,6 @@ + from fencing import * + from fencing import fail_usage, is_executable, run_command, run_delay + +-#BEGIN_VERSION_GENERATION +-RELEASE_VERSION="4.0.11" +-BUILD_DATE="(built Wed Nov 12 06:33:38 EST 2014)" +-REDHAT_COPYRIGHT="Copyright (C) Red Hat, Inc. 2004-2010 All rights reserved." +-#END_VERSION_GENERATION +- + override_status = "" + + EVACUABLE_TAG = "evacuable" +@@ -264,13 +258,37 @@ + except ImportError: + fail_usage("Nova not found or not accessible") + +- versions = [ "2.11", "2" ] +- for version in versions: +- clientargs = inspect.getargspec(client.Client).varargs ++ from keystoneauth1 import loading ++ from keystoneauth1 import session ++ from keystoneclient import discover ++ ++ # Prefer the oldest and strip the leading 'v' ++ keystone_versions = discover.available_versions(options["--auth-url"]) ++ keystone_version = keystone_versions[0]['id'][1:] ++ kwargs = dict( ++ auth_url=options["--auth-url"], ++ username=options["--username"], ++ password=options["--password"] ++ ) ++ ++ if discover.version_match("2", keystone_version): ++ kwargs["tenant_name"] = options["--tenant-name"] ++ ++ elif discover.version_match("3", keystone_version): ++ kwargs["project_name"] = options["--tenant-name"] ++ kwargs["user_domain_name"] = options["--user-domain"] ++ kwargs["project_domain_name"] = options["--project-domain"] ++ ++ loader = loading.get_plugin_loader('password') ++ keystone_auth = loader.load_from_options(**kwargs) ++ keystone_session = session.Session(auth=keystone_auth, verify=(not options["--insecure"])) + ++ nova_versions = [ "2.11", "2" ] ++ for version in nova_versions: ++ clientargs = inspect.getargspec(client.Client).varargs + # Some versions of Openstack prior to Ocata only + # supported positional arguments for username, +- # password and tenant. ++ # password, and tenant. + # + # Versions since Ocata only support named arguments. + # +@@ -285,25 +303,22 @@ + # varargs=None, + # keywords='kwargs', defaults=(None, None, None, None)) + nova = client.Client(version, +- options["--username"], +- options["--password"], +- options["--tenant-name"], +- options["--auth-url"], ++ None, # User ++ None, # Password ++ None, # Tenant ++ None, # Auth URL + insecure=options["--insecure"], + region_name=options["--region-name"], + endpoint_type=options["--endpoint-type"], ++ session=keystone_session, auth=keystone_auth, + http_log_debug=options.has_key("--verbose")) + else: + # OSP >= 11 + # ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None) + nova = client.Client(version, +- username=options["--username"], +- password=options["--password"], +- tenant_name=options["--tenant-name"], +- auth_url=options["--auth-url"], +- insecure=options["--insecure"], + region_name=options["--region-name"], + endpoint_type=options["--endpoint-type"], ++ session=keystone_session, auth=keystone_auth, + http_log_debug=options.has_key("--verbose")) + + try: +@@ -316,7 +331,7 @@ + except Exception as e: + logging.warning("Nova connection failed. %s: %s" % (e.__class__.__name__, e)) + +- logging.warning("Couldn't obtain a supported connection to nova, tried: %s\n" % repr(versions)) ++ logging.warning("Couldn't obtain a supported connection to nova, tried: %s\n" % repr(nova_versions)) + return None + + def define_new_opts(): +@@ -332,12 +347,30 @@ + all_opt["tenant_name"] = { + "getopt" : "t:", + "longopt" : "tenant-name", +- "help" : "-t, --tenant-name=[tenant] Keystone Admin Tenant", ++ "help" : "-t, --tenant-name=[name] Keystone v2 Tenant or v3 Project Name", + "required" : "0", +- "shortdesc" : "Keystone Admin Tenant", ++ "shortdesc" : "Keystone Admin Tenant or v3 Project", + "default" : "", + "order": 1, + } ++ all_opt["user-domain"] = { ++ "getopt" : "u:", ++ "longopt" : "user-domain", ++ "help" : "-u, --user-domain=[name] Keystone v3 User Domain", ++ "required" : "0", ++ "shortdesc" : "Keystone v3 User Domain", ++ "default" : "Default", ++ "order": 2, ++ } ++ all_opt["project-domain"] = { ++ "getopt" : "P:", ++ "longopt" : "project-domain", ++ "help" : "-d, --project-domain=[name] Keystone v3 Project Domain", ++ "required" : "0", ++ "shortdesc" : "Keystone v3 Project Domain", ++ "default" : "Default", ++ "order": 2, ++ } + all_opt["auth_url"] = { + "getopt" : "k:", + "longopt" : "auth-url", +@@ -365,7 +398,7 @@ + "default" : "False", + "order": 2, + } +- all_opt["domain"] = { ++ all_opt["compute-domain"] = { + "getopt" : "d:", + "longopt" : "domain", + "help" : "-d, --domain=[string] DNS domain in which hosts live, useful when the cluster uses short names and nova uses FQDN", +@@ -418,8 +451,8 @@ + atexit.register(atexit_handler) + + device_opt = ["login", "passwd", "tenant_name", "auth_url", "fabric_fencing", +- "no_login", "no_password", "port", "domain", "no_shared_storage", "endpoint_type", +- "record_only", "instance_filtering", "insecure", "region_name"] ++ "no_login", "no_password", "port", "compute-domain", "project-domain", "user-domain", ++ "no_shared_storage", "endpoint_type", "record_only", "instance_filtering", "insecure", "region_name"] + define_new_opts() + all_opt["shell_timeout"]["default"] = "180" + +diff -uNr a/fence/agents/compute/fence_evacuate.py b/fence/agents/compute/fence_evacuate.py +--- a/fence/agents/compute/fence_evacuate.py 2018-01-10 13:46:17.966287090 +0100 ++++ b/fence/agents/compute/fence_evacuate.py 2018-01-10 13:48:19.375158060 +0100 +@@ -191,13 +191,38 @@ + except ImportError: + fail_usage("Nova not found or not accessible") + ++ from keystoneauth1 import loading ++ from keystoneauth1 import session ++ from keystoneclient import discover ++ ++ # Prefer the oldest and strip the leading 'v' ++ keystone_versions = discover.available_versions(options["--auth-url"]) ++ keystone_version = keystone_versions[0]['id'][1:] ++ kwargs = dict( ++ auth_url=options["--auth-url"], ++ username=options["--username"], ++ password=options["--password"] ++ ) ++ ++ if discover.version_match("2", keystone_version): ++ kwargs["tenant_name"] = options["--tenant-name"] ++ ++ elif discover.version_match("3", keystone_version): ++ kwargs["project_name"] = options["--tenant-name"] ++ kwargs["user_domain_name"] = options["--user-domain"] ++ kwargs["project_domain_name"] = options["--project-domain"] ++ ++ loader = loading.get_plugin_loader('password') ++ keystone_auth = loader.load_from_options(**kwargs) ++ keystone_session = session.Session(auth=keystone_auth, verify=(not options["--insecure"])) ++ + versions = [ "2.11", "2" ] + for version in versions: + clientargs = inspect.getargspec(client.Client).varargs + + # Some versions of Openstack prior to Ocata only + # supported positional arguments for username, +- # password and tenant. ++ # password, and tenant. + # + # Versions since Ocata only support named arguments. + # +@@ -212,25 +237,22 @@ + # varargs=None, + # keywords='kwargs', defaults=(None, None, None, None)) + nova = client.Client(version, +- options["--username"], +- options["--password"], +- options["--tenant-name"], +- options["--auth-url"], ++ None, # User ++ None, # Password ++ None, # Tenant ++ None, # Auth URL + insecure=options["--insecure"], + region_name=options["--region-name"], + endpoint_type=options["--endpoint-type"], ++ session=keystone_session, auth=keystone_auth, + http_log_debug=options.has_key("--verbose")) + else: + # OSP >= 11 + # ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None) + nova = client.Client(version, +- username=options["--username"], +- password=options["--password"], +- tenant_name=options["--tenant-name"], +- auth_url=options["--auth-url"], +- insecure=options["--insecure"], + region_name=options["--region-name"], + endpoint_type=options["--endpoint-type"], ++ session=keystone_session, auth=keystone_auth, + http_log_debug=options.has_key("--verbose")) + + try: +@@ -259,12 +281,30 @@ + all_opt["tenant_name"] = { + "getopt" : "t:", + "longopt" : "tenant-name", +- "help" : "-t, --tenant-name=[tenant] Keystone Admin Tenant", ++ "help" : "-t, --tenant-name=[name] Keystone v2 Tenant or v3 Project Name", + "required" : "0", +- "shortdesc" : "Keystone Admin Tenant", ++ "shortdesc" : "Keystone Admin Tenant or v3 Project", + "default" : "", + "order": 1, + } ++ all_opt["user-domain"] = { ++ "getopt" : "u:", ++ "longopt" : "user-domain", ++ "help" : "-u, --user-domain=[name] Keystone v3 User Domain", ++ "required" : "0", ++ "shortdesc" : "Keystone v3 User Domain", ++ "default" : "Default", ++ "order": 2, ++ } ++ all_opt["project-domain"] = { ++ "getopt" : "P:", ++ "longopt" : "project-domain", ++ "help" : "-d, --project-domain=[name] Keystone v3 Project Domain", ++ "required" : "0", ++ "shortdesc" : "Keystone v3 Project Domain", ++ "default" : "Default", ++ "order": 2, ++ } + all_opt["auth_url"] = { + "getopt" : "k:", + "longopt" : "auth-url", +@@ -292,7 +332,7 @@ + "default" : "False", + "order": 2, + } +- all_opt["domain"] = { ++ all_opt["compute-domain"] = { + "getopt" : "d:", + "longopt" : "domain", + "help" : "-d, --domain=[string] DNS domain in which hosts live, useful when the cluster uses short names and nova uses FQDN", +@@ -323,8 +363,9 @@ + atexit.register(atexit_handler) + + device_opt = ["login", "passwd", "tenant_name", "auth_url", +- "no_login", "no_password", "port", "domain", "no_shared_storage", "endpoint_type", +- "instance_filtering", "insecure", "region_name"] ++ "no_login", "no_password", "port", "compute-domain", "project-domain", ++ "user-domain", "no_shared_storage", "endpoint_type", ++ "instance_filtering", "insecure", "region_name"] + define_new_opts() + all_opt["shell_timeout"]["default"] = "180" + diff --git a/SOURCES/test-01-fix_xml_metadata.patch b/SOURCES/test-01-fix_xml_metadata.patch new file mode 100644 index 0000000..2941a57 --- /dev/null +++ b/SOURCES/test-01-fix_xml_metadata.patch @@ -0,0 +1,82 @@ +From 7614464c6a7df9512643b62048481d66dc1f989c Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 17 Jun 2015 19:20:10 +0200 +Subject: [PATCH 01/10] testing: Fix XML metadata + +--- + tests/data/metadata/fence_cisco_ucs.xml | 2 +- + tests/data/metadata/fence_compute.xml | 10 +++++----- + tests/data/metadata/fence_rhevm.xml | 2 +- + tests/data/metadata/fence_vmware_soap.xml | 2 +- + 4 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +index 75e45ce..66fc576 100644 +--- a/tests/data/metadata/fence_cisco_ucs.xml ++++ b/tests/data/metadata/fence_cisco_ucs.xml +@@ -11,7 +11,7 @@ + + + +- Disable TLS negotiation ++ Disable TLS negotiation, force SSL 3.0 + + + +diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +index ff7c06c..f9b97fc 100644 +--- a/tests/data/metadata/fence_compute.xml ++++ b/tests/data/metadata/fence_compute.xml +@@ -23,6 +23,11 @@ + + Login password or passphrase + ++ ++ ++ ++ Nova Endpoint type ++ + + + +@@ -48,11 +53,6 @@ + + Disable functionality for dealing with shared storage + +- +- +- +- Path to nova binary +- + + + +diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +index c9d6eeb..1eccd26 100644 +--- a/tests/data/metadata/fence_rhevm.xml ++++ b/tests/data/metadata/fence_rhevm.xml +@@ -11,7 +11,7 @@ + + + +- Disable TLS negotiation ++ Disable TLS negotiation, force SSL 3.0 + + + +diff --git a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml +index d0a465f..1308c85 100644 +--- a/tests/data/metadata/fence_vmware_soap.xml ++++ b/tests/data/metadata/fence_vmware_soap.xml +@@ -13,7 +13,7 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + + + +- Disable TLS negotiation ++ Disable TLS negotiation, force SSL 3.0 + + + +-- +1.9.3 + diff --git a/SOURCES/tests-01.patch b/SOURCES/tests-01.patch new file mode 100644 index 0000000..15bc477 --- /dev/null +++ b/SOURCES/tests-01.patch @@ -0,0 +1,36 @@ +From 8270ec5d2d2526ff32ef0836ba8dca707ffa4d41 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Thu, 16 Oct 2014 14:13:24 +0200 +Subject: [PATCH 2/5] [build] Fix paths in process of building releases + +--- + make/agentccheck.mk | 2 +- + make/agentpycheck.mk | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/make/agentccheck.mk b/make/agentccheck.mk +index 3ef97f9..46e2055 100644 +--- a/make/agentccheck.mk ++++ b/make/agentccheck.mk +@@ -1,5 +1,5 @@ + TEMPFILE:=$(shell mktemp) +-DATADIR:=$(abs_top_builddir)/../tests/data/metadata ++DATADIR:=$(abs_top_srcdir)/tests/data/metadata + + check: $(TARGET:%=xml-check.%) $(SYMTARGET:%=xml-check.%) + +diff --git a/make/agentpycheck.mk b/make/agentpycheck.mk +index ae4e477..63cb9da 100644 +--- a/make/agentpycheck.mk ++++ b/make/agentpycheck.mk +@@ -1,5 +1,6 @@ + TEMPFILE:=$(shell mktemp) +-DATADIR:=$(abs_top_builddir)/../tests/data/metadata ++#DATADIR:=$(abs_top_builddir)/tests/data/metadata ++DATADIR:=$(abs_top_srcdir)/tests/data/metadata + + check: $(TARGET:%=xml-check.%) $(SYMTARGET:%=xml-check.%) $(TARGET:%=delay-check.%) + +-- +1.9.3 + diff --git a/SOURCES/tests-02.patch b/SOURCES/tests-02.patch new file mode 100644 index 0000000..c0087b3 --- /dev/null +++ b/SOURCES/tests-02.patch @@ -0,0 +1,443 @@ +From a09307e2723f4536c71fe9b3b650b1d6ab8e9b79 Mon Sep 17 00:00:00 2001 +From: Marek 'marx' Grac +Date: Wed, 25 Mar 2015 17:53:14 +0100 +Subject: [PATCH 3/5] [tests] Add XML metadata for fence_ilo*_ssh + +--- + tests/data/metadata/fence_ilo3_ssh.xml | 136 +++++++++++++++++++++++++++++++++ + tests/data/metadata/fence_ilo4_ssh.xml | 136 +++++++++++++++++++++++++++++++++ + tests/data/metadata/fence_ilo_ssh.xml | 136 +++++++++++++++++++++++++++++++++ + 3 files changed, 408 insertions(+) + create mode 100644 tests/data/metadata/fence_ilo3_ssh.xml + create mode 100644 tests/data/metadata/fence_ilo4_ssh.xml + create mode 100644 tests/data/metadata/fence_ilo_ssh.xml + +diff --git a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +new file mode 100644 +index 0000000..b3531b2 +--- /dev/null ++++ b/tests/data/metadata/fence_ilo3_ssh.xml +@@ -0,0 +1,136 @@ ++ ++ ++ ++ ++fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. ++http://www.hp.com ++ ++ ++ ++ ++ TCP/UDP port to use for connection with device ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Force Python regex for command prompt ++ ++ ++ ++ ++ Forces agent to use IPv6 addresses only ++ ++ ++ ++ ++ Identity file for ssh ++ ++ ++ ++ ++ Forces agent to use IPv4 addresses only ++ ++ ++ ++ ++ ++ Method to fence (onoff|cycle) ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ SSH options to use ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +new file mode 100644 +index 0000000..2266ee1 +--- /dev/null ++++ b/tests/data/metadata/fence_ilo4_ssh.xml +@@ -0,0 +1,136 @@ ++ ++ ++ ++ ++fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. ++http://www.hp.com ++ ++ ++ ++ ++ TCP/UDP port to use for connection with device ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Force Python regex for command prompt ++ ++ ++ ++ ++ Forces agent to use IPv6 addresses only ++ ++ ++ ++ ++ Identity file for ssh ++ ++ ++ ++ ++ Forces agent to use IPv4 addresses only ++ ++ ++ ++ ++ ++ Method to fence (onoff|cycle) ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ SSH options to use ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +new file mode 100644 +index 0000000..a9bd1d3 +--- /dev/null ++++ b/tests/data/metadata/fence_ilo_ssh.xml +@@ -0,0 +1,136 @@ ++ ++ ++ ++ ++fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. ++http://www.hp.com ++ ++ ++ ++ ++ TCP/UDP port to use for connection with device ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ SSH connection ++ ++ ++ ++ ++ Force Python regex for command prompt ++ ++ ++ ++ ++ Forces agent to use IPv6 addresses only ++ ++ ++ ++ ++ Identity file for ssh ++ ++ ++ ++ ++ Forces agent to use IPv4 addresses only ++ ++ ++ ++ ++ ++ Method to fence (onoff|cycle) ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ SSH options to use ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.9.3 + diff --git a/SPECS/fence-agents.spec b/SPECS/fence-agents.spec new file mode 100644 index 0000000..d489267 --- /dev/null +++ b/SPECS/fence-agents.spec @@ -0,0 +1,1325 @@ +############################################################################### +############################################################################### +## +## Copyright (C) 2004-2011 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. +## +############################################################################### +############################################################################### + +# keep around ready for later user +## global alphatag git0a6184070 + +Name: fence-agents +Summary: Fence Agents for Red Hat Cluster +Version: 4.0.11 +Release: 66%{?alphatag:.%{alphatag}}%{?dist}.4 +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +URL: http://sourceware.org/cluster/wiki/ +Source0: https://fedorahosted.org/releases/f/e/fence-agents/%{name}-%{version}.tar.xz +Patch0: bz1072564-1-add_ssl_secure_and_ssl_insecure.patch +Patch1: bz1072564-2-add_ssl_secure_and_ssl_insecure.patch +Patch2: backward-rename_fence_scsi_check_to_pl.patch +Patch3: bz1121122-1-fence_ilo_ssh.patch +Patch4: bz1140921-1-fence_zvm.patch +Patch5: bz1111597-1-fence_rsb.patch +Patch6: bz1148762-1-fence_wti_eol.patch +Patch7: bz1153059-1-fence_vmware_soap-fail_usage.patch +Patch8: bz1111599-1-fence_cisco_and_soap_logout.patch +Patch9: bz1162092-1-fix_ssl_secure.patch +Patch10: bz1140921-2-fence_zvm.patch +Patch11: bz1140921-3-fence_zvm.patch +Patch12: bz1121122-2-broken_syslog.patch +Patch13: bz1121122-3-eol_changed.patch +Patch14: bz1121122-3.5-delay_test.patch +Patch15: bz1121122-4-symlink_ilo34_ssh.patch +Patch16: bz1121122-5-symlink_ilo34_ssh.patch +Patch17: bz1173178-1-rewrite_fence_zvmip.patch +Patch18: tests-01.patch +Patch19: tests-02.patch +Patch20: bz1199970-fence_ilo_support_tls10.patch +Patch21: bz1203877-fence_ipmilan-default_cipher.patch +Patch22: bz1214359-1-fence_compute.patch +Patch23: bz1214359-2-fence_compute.patch +Patch24: bz1214359-3-fence_compute.patch +Patch25: bz1214359-4-fence_compute.patch +Patch26: test-01-fix_xml_metadata.patch +Patch27: bz1213571-fence_scsi-add_monitor.patch +Patch28: bz1214919-fence_scsi-already_on.patch +Patch29: bz1145769-fence_rhevm-cookies_auth.patch +Patch30: bz1165591-fence_cisco_ucs-https.patch +Patch31: bz1196068-fence_kdump-add_monitor.patch +Patch32: bz1196068-2-fence_kdump-add_monitor.patch +Patch33: bz1196068-3-fence_kdump-add_monitor.patch +Patch34: bz1196068-4-fence_kdump-add_monitor.patch +Patch35: bz1207982-fence2rng-quotes.patch +Patch36: bz1171732-1-fence_emerson.patch +Patch37: bz1171732-2-fence_emerson.patch +Patch38: bz1171732-3-fence_emerson.patch +Patch39: bz1188750-0-fence_zvmip-improve_usage_of_resources.patch +Patch40: bz1188750-fence_zvmip-improve_usage_of_resources.patch +Patch41: bz1214359-5-fence_compute.patch +Patch42: bz1214359-6-fence_compute.patch +Patch43: bz1216997-support_for_hp_superdome.patch +Patch44: bz1102727-fence_mpath.patch +Patch45: bz1102727-2-duplicate_getopt.patch +Patch46: bz1214359-7-fence_compute_xml_test.patch +Patch47: bz1214522-port_as_ip.patch +Patch48: bz1102727-2-fence_mpath.patch +Patch49: bz1243485-1-fence_scsi-force-on.patch +Patch50: bz1243485-2-fence_scsi-monitor.patch +Patch51: bz1250586-list_status.patch +Patch52: bz1214522-2-port_as_ip.patch +Patch53: bz1214522-3-port_as_ip.patch +Patch54: bz1185329-fence_rsa.patch +Patch55: bz1251491-none_as_state.patch +Patch56: bz1214522-4-port_as_ip.patch +Patch57: bz1214522-5-port_as_ip.patch +Patch58: bz1102727-3-fence_mpath.patch +Patch59: bz1250586-2-list_status.patch +Patch60: bz1243485-3-fence_scsi_check.patch +Patch61: bz1241648-fence_ipmilan_password_verbose.patch +Patch62: bz1257137-1-fence_ipmilan_regression.patch +Patch63: bz1257137-2-fence_ipmilan_regression.patch +Patch64: bz1256908-fence_ilo-tls_negotiation.patch +Patch65: bz1259319-fence_apc_v6.patch +Patch66: bz1257137-3-fence_ipmilan_regression.patch +Patch67: bz1274432-fence_brocade-fix_incorrect_return.patch +Patch68: bz1265426-1-fence_scsi_hard.patch +Patch69: bz1265426-2-fence_scsi_hard.patch +Patch70: bz1265426-3-fence_scsi_hard.patch +Patch71: bz1265426-4-fence_scsi_hard.patch +Patch72: bz1283084-fence_compute.patch +Patch73: bz1298430-fence_cisco_ucs-status.patch +Patch74: bz1298430-2-fence_cisco_ucs-Add-missing-as-off.patch +Patch75: bz1298430-3-Update-XML-metadata.patch +Patch76: bz1298430-4-Update-XML-metadata.patch +Patch77: bz1298430-1-fence_cisco_ucs-Obtain-status-from-different-attr.patch +Patch78: bz1254821-fence_virsh-missing-as-off-1.patch +Patch79: bz1254821-fence_virsh-missing-as-off-2.patch +Patch80: bz1275250-fence_ipmilan-fix-power_wait-regression.patch +Patch81: bz1286045-fence_ipmilan-add-diag-action.patch +Patch82: bz1271780-fence_ipmilan-cycle-report-success-before-powered-off.patch +Patch83: bz1280139-fence_scsi-fix-persistentl-typo-in-short-desc.patch +Patch84: bz1280151-1-fence_scsi-remove-dev-dm-X-reference.patch +Patch85: bz1280151-2-fence_scsi-remove-dev-dm-X-reference.patch +Patch86: bz1287059-1-fence_rhevm-add-filter-header.patch +#Patch87: bz1296201-fence_amt_ws-new-fence-agent.patch +Patch88: bz1313561-fence_compute-locate-all-instances-to-be-evacuated.patch +Patch89: bz1285523-1-fence_compute-taggable-instance-support.patch +Patch90: bz1285523-2-fence_compute-taggable-instance-support.patch +Patch91: bz1334162-fence_compute-improved-fqdn-handling.patch +Patch92: bz1342584-fence_apc-fix-connection-timed-out.patch +Patch93: bz1287311-1-fence_compute-real-status-in-record-only-mode.patch +Patch94: bz1287311-2-fence_compute-real-status-in-record-only-mode.patch +Patch95: bz1298430-2-fence_cisco_ucs-status.patch +Patch96: bz1287059-2-fence_rhevm-add-filter-header.patch +Patch97: bz1387590-compute-fix-plug-domain-name-nova-force-down.patch +Patch98: bz1390915-monitor_port_as_ip.patch +Patch99: bz1337236-fence_sbd.patch +Patch100: bz1410881-cisco_ucs-admin.patch +Patch101: bz1384073-fence_compute-fix-connectionerror-exception.patch +Patch102: bz1377389-fence_ipmilan-add-target-support.patch +Patch103: bz1376481-1-fence_lpar-fix-monitor-fails.patch +Patch104: bz1376481-2-fence_lpar-fix-monitor-fails.patch +Patch105: bz1393962-fence_vmware_soap-ssl-insecure-suppress-warning.patch +Patch106: bz1377972-1-CI-dont-test-paths-in-metadata.patch +Patch107: bz1433948-1-validate-all-action.patch +Patch108: bz1433948-2-validate-all-action.patch +Patch109: bz1422499-fence_rhevm-disable-http-filter.patch +Patch110: bz1403028-fencing-parameters_stdin.patch +Patch111: bz1377972-2-CI-dont-test-paths-in-metadata.patch +Patch112: bz1426693-1-fence_compute-project_id-to-project_name.patch +Patch113: bz1426693-2-fence_compute-project_id-to-project_name.patch +Patch114: bz1459199-fence_vmware_soap-fix-for-selfsigned-certificate.patch +Patch115: bz1479851-fence_compute-fence_scsi-fix-parameters.patch +Patch116: bz1497072-fence_compute-fence_evacuate-Instance-HA-OSP12.patch +Patch117: bz1497241-fence_compute-fence_scsi-fix-parameters.patch +Patch118: bz1535415-fence_compute-fence_evacuate-add-support-for-keystone-v3-authentication.patch + +%if 0%{?rhel} +%global supportedagents apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps hpblade ibmblade ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan mpath kdump rhevm rsa rsb sbd scsi vmware_soap wti +%global allfenceagents fence-agents-apc fence-agents-apc-snmp fence-agents-bladecenter fence-agents-brocade fence-agents-cisco-mds fence-agents-cisco-ucs fence-agents-compute fence-agents-drac5 fence-agents-eaton-snmp fence-agents-emerson fence-agents-eps fence-agents-hpblade fence-agents-ibmblade fence-agents-ifmib fence-agents-ilo2 fence-agents-ilo-moonshot fence-agents-ilo-mp fence-agents-ilo-ssh fence-agents-intelmodular fence-agents-ipdu fence-agents-ipmilan fence-agents-mpath fence-agents-kdump fence-agents-rhevm fence-agents-rsa fence-agents-rsb fence-agents-sbd fence-agents-scsi fence-agents-vmware-soap fence-agents-wti +%ifarch ppc64le +%global testagents virsh lpar +%endif +%ifarch s390x +%global testagents virsh zvm +%endif +%ifnarch ppc64le s390x +%global testagents virsh +%endif +%endif + +## Setup/build bits + +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) + +# Build dependencies +BuildRequires: glibc-devel +BuildRequires: gnutls-utils +BuildRequires: libxslt +BuildRequires: python pexpect python-pycurl python-suds python-requests openwsman-python +BuildRequires: net-snmp-utils +BuildRequires: autoconf automake libtool + +%prep +%setup -q -n %{name}-%{version} +%patch0 -p1 -b .bz1072564-1 +%patch1 -p1 -b .bz1072564-2 +%patch2 -p1 -b .backward-fence_scsi_check_rename +%patch3 -p1 -b .bz1121122-1 +%patch4 -p1 -b .bz1140921-1 +%patch5 -p1 -b .bz1111597-1 +%patch6 -p1 -b .bz1148762-1 +%patch7 -p1 -b .bz1153059-1 +%patch8 -p1 -b .bz1111599-1 +%patch9 -p1 -b .bz1162092-1 +%patch10 -p1 -b .bz1140921-2 +%patch11 -p1 -b .bz1140921-3 +%patch12 -p1 -b .bz1121122-2 +%patch13 -p1 -b .bz1121122-3 +%patch14 -p1 -b .bz1121122-3.5 +%patch15 -p1 -b .bz1121122-4 +%patch16 -p1 -b .bz1121122-5 +%patch17 -p1 -b .bz1173178-1 +%patch18 -p1 -b .tests-01 +%patch19 -p1 -b .tests-02 +%patch20 -p1 -b .bz1199970-1 +%patch21 -p1 -b .bz1203877-1 +%patch22 -p1 -b .bz1214359-1 +%patch23 -p1 -b .bz1214359-2 +%patch24 -p1 -b .bz1214359-3 +%patch25 -p1 -b .bz1214359-4 +%patch26 -p1 -b .test-01-fix_xml_metadata.patch +%patch27 -p1 -b .bz1213571 +%patch28 -p1 -b .bz1214919 +%patch29 -p1 -b .bz1145769 +%patch30 -p1 -b .bz1165591 +%patch31 -p1 -b .bz1196068 +%patch32 -p1 -b .bz1196068-2 +%patch33 -p1 -b .bz1196068-3 +%patch34 -p1 -b .bz1196068-4 +%patch35 -p1 -b .bz1207982 +%patch36 -p1 -b .bz1171732.1 +%patch37 -p1 -b .bz1171732.2 +%patch38 -p1 -b .bz1171732.3 +%patch39 -p1 -b .bz1188750.0 +%patch40 -p1 -b .bz1188750 +%patch41 -p1 -b .bz1214359-5 +%patch42 -p1 -b .bz1214359-6 +%patch43 -p1 -b .bz1216997 +%patch44 -p1 -b .bz1102727 +%patch45 -p1 -b .bz1102727-2 +%patch46 -p1 -b .bz1214359-7 +%patch47 -p1 -b .bz1214522 +%patch48 -p1 -b .bz1102727-2 +%patch49 -p1 -b .bz1243485-1 +%patch50 -p1 -b .bz1243485-2 +%patch51 -p1 -b .bz1250586 +%patch52 -p1 -b .bz1214522-2 +%patch53 -p1 -b .bz1214522-3 +%patch54 -p1 -b .bz1185329 +%patch55 -p1 -b .bz1251491 +%patch56 -p1 -b .bz1214522-4 +%patch57 -p1 -b .bz1214522-5 +%patch58 -p1 -b .bz1102727-3 +%patch59 -p1 -b .bz1250586-2 +%patch60 -p1 -b .bz1243485-3 +%patch61 -p1 -b .bz1241648 +%patch62 -p1 -b .bz1257137-1 +%patch63 -p1 -b .bz1257137-2 +%patch64 -p1 -b .bz1256908 +%patch65 -p1 -b .bz1259319 +%patch66 -p1 -b .bz1257137-3 +%patch67 -p1 -b .bz1274432-1 +%patch68 -p1 -b .bz1265426-1 +%patch69 -p1 -b .bz1265426-2 +%patch70 -p1 -b .bz1265426-3 +%patch71 -p1 -b .bz1265426-4 +%patch72 -p1 -b .bz1283084 +%patch73 -p1 -b .bz1298430 +%patch74 -p1 -b .bz1298430-2 +%patch75 -p1 -b .bz1298430-3 +%patch76 -p1 -b .bz1298430-4 +%patch77 -p1 -b .bz1298430-1 +%patch78 -p1 -b .bz1254821-1 +%patch79 -p1 -b .bz1254821-2 +%patch80 -p1 -b .bz1275250 +%patch81 -p1 -b .bz1286045 +%patch82 -p1 -b .bz1271780 +%patch83 -p1 -b .bz1280139 +%patch84 -p1 -b .bz1280151-1 +%patch85 -p1 -F1 -b .bz1280151-2 +%patch86 -p1 -b .bz1287059-1 +#%patch87 -p1 -b .bz1296201 +%patch88 -p1 -b .bz1313561 +%patch89 -p1 -b .bz1285523-1 +%patch90 -p1 -b .bz1285523-2 +%patch91 -p1 -b .bz1334162 +%patch92 -p1 -b .bz1342584 +%patch93 -p1 -b .bz1287311-1 +%patch94 -p1 -F2 -b .bz1287311-2 +%patch95 -p1 -b .bz1298430-2 +%patch96 -p1 -F2 -b .bz1287059-2 +%patch97 -p1 -b .bz1387590 +%patch98 -p1 -b .bz1390915 +%patch99 -p1 -b .bz1337236 +%patch100 -p1 -b .bz1410881 +%patch101 -p1 -b .bz1384073 +%patch102 -p1 -b .bz1377389 +%patch103 -p1 -F2 -b .bz1376481-1 +%patch104 -p1 -b .bz1376481-2 +%patch105 -p1 -b .bz1393962 +%patch106 -p1 -b .bz1377972-1 +%patch107 -p1 -b .bz1433948-1 +%patch108 -p1 -F1 -b .bz1433948-2 +%patch109 -p1 -b .bz1422499 +%patch110 -p1 -b .bz1403028 +%patch111 -p1 -b .bz1377972-2 +%patch112 -p1 -b .bz1426693-1 +%patch113 -p1 -b .bz1426693-2 +%patch114 -p1 -b .bz1459199 +%patch115 -p1 -b .bz1479851 +%patch116 -p1 -b .bz1497072 +%patch117 -p1 -b .bz1497241 +%patch118 -p1 -b .bz1535415 + +%build +./autogen.sh +%{configure} --with-agents='%{supportedagents} %{testagents}' +CFLAGS="$(echo '%{optflags}')" make %{_smp_mflags} + +%install +rm -rf %{buildroot} +make install DESTDIR=%{buildroot} + +## tree fix up +# fix libfence permissions +chmod 0755 %{buildroot}%{_datadir}/fence/*.py +# remove docs +rm -rf %{buildroot}/usr/share/doc/fence-agents + +%clean +rm -rf %{buildroot} + +%description +Red Hat Fence Agents is a collection of scripts to handle remote +power management for several devices. + +%package common +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Common utilities for fence agents +Requires: python pexpect python-pycurl policycoreutils-python +%description common +Red Hat Fence Agents is a collection of scripts and libraries to handle remote power management for various devices. +%post common +/usr/sbin/semanage boolean -S targeted -N -m --on fenced_can_ssh +/usr/sbin/semanage boolean -S targeted -N -m --on fenced_can_network_connect +%files common +%defattr(-,root,root,-) +%doc doc/COPYING.* doc/COPYRIGHT doc/README.licence +%{_datadir}/fence +%{_datadir}/cluster +%{_datadir}/fence/fencing.py +%{_datadir}/fence/fencing_snmp.py + +%package all +License: GPLv2+, LGPLv2+ and ASL 2.0 +Group: System Environment/Base +Summary: Fence agents +Requires: %{allfenceagents} +%ifarch i686 x86_64 +Requires: fence-virt +%endif +%ifarch ppc64le +Requires: fence-agents-lpar +%endif +%ifarch s390x +Requires: fence-agents-zvm +%endif +Provides: fence-agents = %{version}-%{release} +Obsoletes: fence-agents < 3.1.13 +%description all +Red Hat Fence Agents is a collection of all supported fence agents. +%files all + +%if 0%{?fedora} +%package alom +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for SUN ALOM +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description alom +Red Hat Fence Agents +%files alom +%defattr(-,root,root,-) +%{_sbindir}/fence_alom +%{_mandir}/man8/fence_alom.8* +%endif + +%package apc +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for APC devices +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description apc +The fence-agents-apc package contains a fence agent for APC devices that are accessed via telnet or SSH. +%files apc +%defattr(-,root,root,-) +%{_sbindir}/fence_apc +%{_mandir}/man8/fence_apc.8* + +%package apc-snmp +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for APC devices (SNMP) +Requires: fence-agents-common >= %{version}-%{release} +Requires: net-snmp-utils +Obsoletes: fence-agents +%description apc-snmp +The fence-agents-apc-snmp package contains a fence agent for APC devices that are accessed via the SNMP protocol. +%files apc-snmp +%defattr(-,root,root,-) +%{_sbindir}/fence_apc_snmp +%{_mandir}/man8/fence_apc_snmp.8* + +%package bladecenter +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for IBM BladeCenter +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description bladecenter +The fence-agents-bladecenter package contains a fence agent for IBM BladeCenter devices that are accessed via telnet or SSH. +%files bladecenter +%defattr(-,root,root,-) +%{_sbindir}/fence_bladecenter +%{_mandir}/man8/fence_bladecenter.8* + +%package brocade +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for HP Brocade +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description brocade +The fence-agents-brocade package contains a fence agent for HP Brocade devices that are accessed via telnet or SSH. +%files brocade +%defattr(-,root,root,-) +%{_sbindir}/fence_brocade +%{_mandir}/man8/fence_brocade.8* + +%package cisco-mds +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Cisco MDS 9000 series +Requires: fence-agents-common >= %{version}-%{release} +Requires: net-snmp-utils +Obsoletes: fence-agents +%description cisco-mds +The fence-agents-cisco-mds package contains a fence agent for Cisco MDS 9000 series devices that are accessed via the SNMP protocol. +%files cisco-mds +%defattr(-,root,root,-) +%{_sbindir}/fence_cisco_mds +%{_mandir}/man8/fence_cisco_mds.8* + +%package cisco-ucs +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Cisco UCS series +Requires: fence-agents-common >= %{version}-%{release} +Requires: pycurl +Obsoletes: fence-agents +%description cisco-ucs +The fence-agents-cisco-ucs package contains a fence agent for Cisco UCS series devices that are accessed via the SNMP protocol. +%files cisco-ucs +%defattr(-,root,root,-) +%{_sbindir}/fence_cisco_ucs +%{_mandir}/man8/fence_cisco_ucs.8* + +%package compute +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Nova compute nodes +Requires: fence-agents-common >= %{version}-%{release} +Requires: python-requests +Obsoletes: fence-agents +%description compute +The fence-agents-compute package contains a fence agent for Nova compute nodes. +%files compute +%defattr(-,root,root,-) +%{_sbindir}/fence_compute +%{_sbindir}/fence_evacuate +%{_mandir}/man8/fence_compute.8* +%{_mandir}/man8/fence_evacuate.8* + +%package drac5 +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Dell DRAC 5 +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description drac5 +The fence-agents-drac5 package contains a fence agent for Dell DRAC 5 series devices that are accessed via telnet or SSH. +%files drac5 +%defattr(-,root,root,-) +%{_sbindir}/fence_drac5 +%{_mandir}/man8/fence_drac5.8* + +%package eaton-snmp +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Eaton network power switches +Requires: fence-agents-common >= %{version}-%{release} +Requires: net-snmp-utils +Obsoletes: fence-agents +%description eaton-snmp +The fence-agents-eaton-snmp package contains a fence agent for Eaton network power switches that are accessed via the SNMP protocol. +%files eaton-snmp +%defattr(-,root,root,-) +%{_sbindir}/fence_eaton_snmp +%{_mandir}/man8/fence_eaton_snmp.8* + +%package emerson +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Emerson devices (SNMP) +Requires: fence-agents-common >= %{version}-%{release} +Obsoletes: fence-agents +%description emerson +The fence-agents-emerson package contains a fence agent for Emerson devices that are accessed via the SNMP protocol. +%files emerson +%defattr(-,root,root,-) +%{_sbindir}/fence_emerson +%{_mandir}/man8/fence_emerson.8* + +%package eps +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for ePowerSwitch 8M+ power switches +Requires: fence-agents-common >= %{version}-%{release} +Obsoletes: fence-agents +%description eps +The fence-agents-eps package contains a fence agent for ePowerSwitch 8M+ power switches that are accessed via the HTTP(s) protocol. +%files eps +%defattr(-,root,root,-) +%{_sbindir}/fence_eps +%{_mandir}/man8/fence_eps.8* + +%package hpblade +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for HP BladeSystem devices +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description hpblade +The fence-agents-hpblade package contains a fence agent for HP BladeSystem devices that are accessed via telnet or SSH. +%files hpblade +%defattr(-,root,root,-) +%{_sbindir}/fence_hpblade +%{_mandir}/man8/fence_hpblade.8* + +%package ibmblade +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for IBM BladeCenter +Requires: fence-agents-common >= %{version}-%{release} +Requires: net-snmp-utils +Obsoletes: fence-agents +%description ibmblade +The fence-agents-ibmblade package contains a fence agent for IBM BladeCenter devices that are accessed via the SNMP protocol. +%files ibmblade +%defattr(-,root,root,-) +%{_sbindir}/fence_ibmblade +%{_mandir}/man8/fence_ibmblade.8* + +%package ifmib +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for devices with IF-MIB interfaces +Requires: fence-agents-common >= %{version}-%{release} +Requires: net-snmp-utils +Obsoletes: fence-agents +%description ifmib +The fence-agents-ifmib package contains a fence agent for IF-MIB interfaces that are accessed via the SNMP protocol. +%files ifmib +%defattr(-,root,root,-) +%{_sbindir}/fence_ifmib +%{_mandir}/man8/fence_ifmib.8* + +%package ilo2 +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for HP iLO2 devices +Requires: fence-agents-common >= %{version}-%{release} +Requires: gnutls-utils +Obsoletes: fence-agents +%description ilo2 +The fence-agents-ilo2 package contains a fence agent for HP iLO2 devices that are accessed via the HTTP(s) protocol. +%files ilo2 +%defattr(-,root,root,-) +%{_sbindir}/fence_ilo +%{_sbindir}/fence_ilo2 +%{_mandir}/man8/fence_ilo.8* +%{_mandir}/man8/fence_ilo2.8* + +%package ilo-moonshot +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for HP iLO Moonshot devices +Requires: telnet openssh-clients +Requires: fence-agents-common >= %{version}-%{release} +Obsoletes: fence-agents +%description ilo-moonshot +The fence-agents-ilo-moonshot package contains a fence agent for HP iLO Moonshot devices that are accessed via telnet or SSH. +%files ilo-moonshot +%defattr(-,root,root,-) +%{_sbindir}/fence_ilo_moonshot +%{_mandir}/man8/fence_ilo_moonshot.8* + +%package ilo-mp +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for HP iLO MP devices +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description ilo-mp +The fence-agents-ilo-mp package contains a fence agent for HP iLO MP devices that are accessed via telnet or SSH. +%files ilo-mp +%defattr(-,root,root,-) +%{_sbindir}/fence_ilo_mp +%{_mandir}/man8/fence_ilo_mp.8* + +%package ilo-ssh +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for HP iLO devices via SSH +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description ilo-ssh +The fence-agents-ilo-ssh package contains a fence agent for HP iLO devices that are accessed via SSH. +%files ilo-ssh +%defattr(-,root,root,-) +%{_sbindir}/fence_ilo_ssh +%{_mandir}/man8/fence_ilo_ssh.8* +%{_sbindir}/fence_ilo3_ssh +%{_mandir}/man8/fence_ilo3_ssh.8* +%{_sbindir}/fence_ilo4_ssh +%{_mandir}/man8/fence_ilo4_ssh.8* + +%package intelmodular +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for devices with Intel Modular interfaces +Requires: fence-agents-common >= %{version}-%{release} +Requires: net-snmp-utils +Obsoletes: fence-agents +%description intelmodular +The fence-agents-intelmodular package contains a fence agent for Intel Modular interfaces that are accessed via the SNMP protocol. +%files intelmodular +%defattr(-,root,root,-) +%{_sbindir}/fence_intelmodular +%{_mandir}/man8/fence_intelmodular.8* + +%package ipdu +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for IBM iPDU network power switches +Requires: fence-agents-common >= %{version}-%{release} +Requires: net-snmp-utils +Obsoletes: fence-agents +%description ipdu +The fence-agents-ipdu package contains a fence agent for IBM iPDU network power switches that are accessed via the SNMP protocol. +%files ipdu +%defattr(-,root,root,-) +%{_sbindir}/fence_ipdu +%{_mandir}/man8/fence_ipdu.8* + +%package ipmilan +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for devices with IPMI interface +Requires: fence-agents-common >= %{version}-%{release} +Requires: /usr/bin/ipmitool +Obsoletes: fence-agents +%description ipmilan +The fence-agents-ipmilan package contains a fence agent for devices with IPMI interface. +%files ipmilan +%defattr(-,root,root,-) +%{_sbindir}/fence_ipmilan +%{_mandir}/man8/fence_ipmilan.8* +%{_sbindir}/fence_idrac +%{_mandir}/man8/fence_idrac.8* +%{_sbindir}/fence_ilo3 +%{_mandir}/man8/fence_ilo3.8* +%{_sbindir}/fence_ilo4 +%{_mandir}/man8/fence_ilo4.8* +%{_sbindir}/fence_imm +%{_mandir}/man8/fence_imm.8* + +%package mpath +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for reservations over Device Mapper Multipath +Requires: fence-agents-common >= %{version}-%{release} +Requires: device-mapper-multipath +Obsoletes: fence-agents +%description mpath +The fence-agents-mpath package contains fence agent for SCSI persisent reservation over Device Mapper Multipath +%files mpath +%defattr(-,root,root,-) +%{_sbindir}/fence_mpath +%{_mandir}/man8/fence_mpath.8* + +%package kdump +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for use with kdump crash recovery service +Requires: fence-agents-common >= %{version}-%{release} +Obsoletes: fence-agents +%description kdump +The fence-agents-kdump package contains a fence agent for use with kdump crash recovery service. +%files kdump +%defattr(-,root,root,-) +%{_sbindir}/fence_kdump +%{_libexecdir}/fence_kdump_send +%{_mandir}/man8/fence_kdump.8* +%{_mandir}/man8/fence_kdump_send.8* + +%if 0%{?fedora} +%package ldom +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Sun LDom virtual machines +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description ldom +The fence-agents-ldom package contains a fence agent for Sun LDom devices that are accessed via telnet or SSH. +%files ldom +%defattr(-,root,root,-) +%{_sbindir}/fence_ldom +%{_mandir}/man8/fence_ldom.8* +%endif + +%ifarch ppc64le +%package lpar +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for IBM LPAR +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description lpar +The fence-agents-lpar package contains a fence agent for IBM LPAR devices that are accessed via telnet or SSH. +%files lpar +%defattr(-,root,root,-) +%{_sbindir}/fence_lpar +%{_mandir}/man8/fence_lpar.8* +%endif + +%package rhevm +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for RHEV-M +Requires: fence-agents-common >= %{version}-%{release} +Obsoletes: fence-agents +%description rhevm +The fence-agents-rhevm package contains a fence agent for RHEV-M via REST API +%files rhevm +%defattr(-,root,root,-) +%{_sbindir}/fence_rhevm +%{_mandir}/man8/fence_rhevm.8* + +%package rsa +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for IBM RSA II +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description rsa +The fence-agents-rsa package contains a fence agent for IBM RSA II devices that are accessed via telnet or SSH. +%files rsa +%defattr(-,root,root,-) +%{_sbindir}/fence_rsa +%{_mandir}/man8/fence_rsa.8* + +%package rsb +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Fujitsu RSB +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description rsb +The fence-agents-rsb package contains a fence agent for Fujitsu RSB devices that are accessed via telnet or SSH. +%files rsb +%defattr(-,root,root,-) +%{_sbindir}/fence_rsb +%{_mandir}/man8/fence_rsb.8* + +%if 0 +%package sanbox2 +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for QLogic SANBox2 FC switches +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet +Obsoletes: fence-agents +%description sanbox2 +The fence-agents-sanbox2 package contains a fence agent for QLogic SANBox2 switches that are accessed via telnet. +%files sanbox2 +%defattr(-,root,root,-) +%{_sbindir}/fence_sanbox2 +%{_mandir}/man8/fence_sanbox2.8* +%endif + +%package sbd +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for SBD (storage-based death) +Requires: fence-agents-common >= %{version}-%{release} +Obsoletes: fence-agents +%description sbd +The fence-agents-sbd package contains fence agent for SBD (storage-based death) +%files sbd +%defattr(-,root,root,-) +%{_sbindir}/fence_sbd +%{_mandir}/man8/fence_sbd.8* + +%package scsi +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for SCSI persisent reservations +Requires: sg3_utils fence-agents-common >= %{version}-%{release} +Obsoletes: fence-agents +%description scsi +The fence-agents-scsi package contains fence agent for SCSI persisent reservations +%files scsi +%defattr(-,root,root,-) +%{_sbindir}/fence_scsi +%{_datadir}/cluster/fence_scsi_check.pl +%{_datadir}/cluster/fence_scsi_check +%{_datadir}/cluster/fence_scsi_check_hardreboot +%{_mandir}/man8/fence_scsi.8* + +%package virsh +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for virtual machines based on libvirt +Requires: fence-agents-common >= %{version}-%{release} +Requires: openssh-clients /usr/bin/virsh +Obsoletes: fence-agents +%description virsh +The fence-agents-virsh package contains a fence agent for virtual machines that are accessed via SSH. +%files virsh +%defattr(-,root,root,-) +%{_sbindir}/fence_virsh +%{_mandir}/man8/fence_virsh.8* + +%package vmware-soap +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for VMWare with SOAP API v4.1+ +Requires: fence-agents-common >= %{version}-%{release} +Requires: python-suds python-requests +Obsoletes: fence-agents +%description vmware-soap +The fence-agents-vmware-soap package contains a fence agent for VMWare with SOAP API v4.1+ +%files vmware-soap +%defattr(-,root,root,-) +%{_sbindir}/fence_vmware_soap +%{_mandir}/man8/fence_vmware_soap.8* + +%package wti +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for WTI Network power switches +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description wti +The fence-agents-wti package contains a fence agent for WTI network power switches that are accessed via telnet or SSH. +%files wti +%defattr(-,root,root,-) +%{_sbindir}/fence_wti +%{_mandir}/man8/fence_wti.8* + +%ifarch s390x +%package zvm +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for z/VM hypervisors +Requires: fence-agents-common >= %{version}-%{release} +Requires: telnet openssh-clients +Obsoletes: fence-agents +%description zvm +The fence-agents-zvm package contains a fence agent for z/VM hypervisors +%files zvm +%defattr(-,root,root,-) +%{_sbindir}/fence_zvmip +%{_mandir}/man8/fence_zvmip.8* +%endif + +%changelog +* Wed Jan 17 2018 Oyvind Albrigtsen - 4.0.11-66.4 +- fence_compute/fence_evacuate: add support for keystone v3 authentication + Resolves: rhbz#1535415 + +* Fri Sep 29 2017 Oyvind Albrigtsen - 4.0.11-66.3 +- fence_compute/fence_scsi: fix issue with some parameters + (for ABI compatibility) + Resolves: rhbz#1497241 + +* Fri Sep 29 2017 Oyvind Albrigtsen - 4.0.11-66.2 +- fence_compute/fence_evacuate: changes to support Instance HA on OSP12 + Resolves: rhbz#1497072 + +* Thu Aug 10 2017 Oyvind Albrigtsen - 4.0.11-66.1 +- fence_compute/fence_scsi: fix issue with some parameters + Resolves: rhbz#1479851 + +* Fri Jun 16 2017 Marek Grac - 4.0.11-66 +- Set SELinux booleans even when SELinux is disabled + Resolves: rhbz#1457887 + +* Thu Jun 15 2017 Marek Grac - 4.0.11-65 +- Set SELinux booleans even when SELinux is disabled + Resolves: rhbz#1457887 + +* Wed Jun 7 2017 Oyvind Albrigtsen - 4.0.11-64 +- fence_vmware_soap: fix for self-signed certificates + Resolves: rhbz#1459199 + +* Tue May 30 2017 Marek Grac - 4.0.11-63 +- Add dependencies on policycoreutils + Resolves: rhbz#1427986 + +* Wed May 17 2017 Marek Grac - 4.0.11-62 +- Set SELinux booleans required for fence agent integration with cluster + Resolves: rhbz#1427986 + +* Thu May 4 2017 Oyvind Albrigtsen - 4.0.11-61 +- fence_ipmilan: add target (ipmilan -t ) support + Resolves: rhbz#1377389 + +* Mon Apr 3 2017 Oyvind Albrigtsen - 4.0.11-60 +- fence_compute: fix project_id changed to project_name in Nova API + Resolves: rhbz#1426693 + +* Thu Mar 23 2017 Oyvind Albrigtsen - 4.0.11-58 +- CI: dont test paths in metadata + Resolves: rhbz#1377972 + +* Wed Mar 22 2017 Marek Grac - 4.0.11-57 +- Set SELinux booleans required for fence agent integration with cluster + Resolves: rhbz#1427986 +- Add consistency of parameters between STDIN and command-line + Resolves: rhbz#1403028 + +* Tue Mar 21 2017 Oyvind Albrigtsen - 4.0.11-56 +- fencing: add validate-all action + Resolves: rhbz#1433948 +- fence_rhevm: add "--disable-http-filter" to be able to explicitly + use oVirt API version 3 + Resolves: rhbz#1422499 + +* Wed Mar 01 2017 Marek Grac - 4.0.11-54 +- fence_lpar: Fix monitor action on IVM systems + Resolves: rhbz#1376481 + +* Tue Feb 21 2017 Oyvind Albrigtsen - 4.0.11-53 +- fence_compute: Improved FQDN and Nova handling + Resolves: rhbz#1387590 + +* Tue Feb 14 2017 Oyvind Albrigtsen - 4.0.11-52 +- fence_compute: fix ConnectionError + Resolves: rhbz#1384073 +- fence_lpar: add IVM support and improve error handling + Resolves: rhbz#1376481 +- fence_vmware_soap: suppress warning for --ssl-insecure + Resolves: rhbz#1393962 +- Add support for "s" for seconds for delay, *_timeout, *_wait parameters + Resolves: rhbz#1377928 +- fence-agents-zvm: add to fence-agents-all dependencies for s390x + Resolves: rhbz#1255700 +- Build for ppc64le + Resolves: rhbz#1402566 + +* Mon Jan 23 2017 Marek Grac +- fence_cisco_ucs: Change commands send to UCS + Resolves: rhbz#1410881 + +* Wed Jan 11 2017 Oyvind Albrigtsen - 4.0.11-50 +- fence_sbd: new fence agent + Resolves: rhbz#1337236 + +* Wed Nov 23 2016 Marek Grac - 4.0.11-49 +- fencing: Fix 'monitor' action for devices with --port-as-ip + Resolves: rhbz#1390915 + +* Wed Aug 31 2016 Oyvind Albrigtsen - 4.0.11-47 +- fence_rhevm: fix issues on RHEV 4 + Resolves: rhbz#1287059 + +* Thu Aug 25 2016 Oyvind Albrigtsen - 4.0.11-46 + Resolves: rhbz#1298430 + +* Thu Aug 25 2016 Marek Grac - 4.0.11-45 +- fence_cisco_ucs: Change method for obtaining status + Resolves: rhbz#1298430 + +* Wed Aug 17 2016 Oyvind Albrigtsen - 4.0.11-44 +- fence_mpath: update info to say unique key per node instead of per + node/device + Resolves: rhbz#1280151 + +* Tue Jul 12 2016 Marek Grac - 4.0.11-43 +- change in spec file + Resolves: rhbz#1353221 + +* Thu Jul 7 2016 Oyvind Albrigtsen - 4.0.11-42 +- fence-agents-common: add dependency on python-pycurl + Resolves: rhbz#1353221 + +* Wed Jul 6 2016 Oyvind Albrigtsen - 4.0.11-41 +- fence_compute: perform real status operation in record-only mode + Resolves: rhbz#1287311 + +* Mon Jul 4 2016 Oyvind Albrigtsen - 4.0.11-40 +- fence_compute: improved FQDN handling + Resolves: rhbz#1334162 + +* Wed Jun 22 2016 Oyvind Albrigtsen - 4.0.11-39 +- fence_apc: fix "Connection timed out" issue + Resolves: rhbz#1342584 + +* Wed Jun 15 2016 Oyvind Albrigtsen - 4.0.11-38 +- fence_compute: advertise as fabric device + Resolves: rhbz#1287301 + +* Tue Jun 14 2016 Oyvind Albrigtsen - 4.0.11-37 +- fence_compute: add taggable instance support + Resolves: rhbz#1285523 + +* Tue May 31 2016 Oyvind Albrigtsen - 4.0.11-34 +- fence_virsh: add --missing-as-off + Resolves: rhbz#1254821 +- fence_ipmilan: fix power_wait regression + Resolves: rhbz#1275250 +- fence_ipmilan: add diag action + Resolves: rhbz#1286045 +- fence_ipmilan: warn that cycle method can report success before node + is powered off + Resolves: rhbz#1271780 +- fence_scsi: fix persistentl typo in short desc + Resolves: rhbz#1280139 +- fence_scsi: remove /dev/dm-X reference + Resolves: rhbz#1280151 +- fence_rhevm: add Filter header + Resolves: rhbz#1287059 +- fence_amt_ws: new fence agent + Resolves: rhbz#1296201 +- fence_compute: fix to locate all instances to be evacuated + Resolves: rhbz#1313561 + +* Mon Feb 22 2016 Marek Grac - 4.0.11-33 +- fence_cisco_ucs: Obtain status from different attribute + Resolves: rhbz#1298430 + +* Tue Feb 09 2016 Marek Grac - 4.0.11-32 +- fence_cisco_ucs: Obtain status from different endpoint + Resolves: rhbz#1298430 + +* Mon Feb 01 2016 Marek Grac - 4.0.11-31 +- fence_cisco_ucs: Obtain status from different endpoint + Resolves: rhbz#1298430 + +* Wed Jan 20 2016 Marek Grac - 4.0.11-30 +- fence_compute: Replace with current implementation + Resolves: rhbz#1283084 + +* Wed Dec 16 2015 Marek Grac - 4.0.11-28 +- fence_scsi: Add fence_scsi_check_hardreboot + Resolves: rhbz#bz1265426 + +* Mon Oct 26 2015 Marek Grac - 4.0.11-27 +- fence_brocade: Fix return status in get_power_status + Resolves: rhbz#1274431 + +* Thu Sep 17 2015 Marek Grac - 4.0.11-26 +- fence_ipmilan: Fix -i attribute + Resolves: rhbz#1257137 + +* Mon Sep 14 2015 Marek Grac - 4.0.11-25 +- fence_apc: Support for v6.x + Resolves: rhbz#1259319 + +* Wed Sep 02 2015 Marek Grac - 4.0.11-24 +- fence_ipmilan: Add removed attributes -i & timeout + Resolves: rhbz#1257137 +- fence_ipmilan: Do not print password in verbose mode + Resolves: rhbz#1241648 +- fence_ilo: Negotiation of TLS1.0 is more automatic + Resolves: rhbz#1256908 + +* Mon Aug 17 2015 Marek Grac - 4.0.11-23 +- fence_scsi: Fix watchdog script broken by more strict 'monitor' + Resolves: 1243485 + +* Wed Aug 12 2015 Marek Grac - 4.0.11-21 +- fence_mpath: Fix unfencing after non-cluster reboot + Resolves: 1102727 +- manual pages now describe 'list-status' properly + +bz1102727-3-fence_mpath.patch bz1250586-2-list_status.patch +* Tue Aug 11 2015 Marek Grac - 4.0.11-20 +- fencing: Fix place where --plug + --port-as-ip are tested + Resolves: rhbz#1214522 + +* Mon Aug 10 2015 Marek Grac - 4.0.11-19 +- fencing: do not fail when state is None + Resolves: rhbz#1251491 + +* Wed Aug 05 2015 Marek Grac - 4.0.11-18 +- fence_rsa: Fix login issue + Resolves: rhbz#1185329 +- fencing: support for list-status + Resolves: rhbz#1250586 +- fencing: Fix support for --port-as-ip + Resolves: rhbz#1214522 + +* Thu Jul 16 2015 Marek Grac - 4.0.11-17 +- fence_scsi: Improve monitoring and add option to force ON + Resolves: rhbz#1243485 + +* Mon Jun 29 2015 Marek Grac - 4.0.11-16 +- fence_compute: Agent cleanup + Resolves: rhbz#1214359 +- fence_hpblade: Add support for HP Integrity Superdome + Resolves: rhbz#1216997 +- fence_zvmip: Add --missing-as-off and change monitor/status actions + Resolves: rhbz#1188750 +- fence_mpath: new fence agent + Resolves: rhbz#1102727 +- fencing: Option --port-as-ip + Resolves: rhbz#1214522 + +* Mon Jun 22 2015 Marek Grac - 4.0.11-15 +- fence_zvmip: Connection timeout issues + Resolves: rhbz#1188750 + +* Thu Jun 18 2015 Marek Grac - 4.0.11-14 +- fence_rhevm: Add authentication via cookies + Resolves: rhbz#1145769 +- fence_ilo_moonshot: New fence agent + Resolves: rhbz#1152917 +- fence_emerson: New fence agent + Resolves: rhbz#1171732 +- fence_rsa: New fence agent + Resolves: rhbz#1185329 + +* Wed Jun 17 2015 Marek Grac - 4.0.11-13 +- fence_scsi: Add monitor operation + Resolves: rhbz#1213571 +- fence_scsi: Force unfence if any of paths is off + Resolves: rhbz#1214919 +- fence_cisco_ucs: Fix https:// prefix with --ssl-(in)secure + Resolves: rhbz#1165591 +- fence_kdump: Add monitor operation + Resolves: rhbz#1196068 +- fence2rng: Fix problem with quotes + Resolves: rhbz#1207982 + +* Mon Jun 08 2015 Marek Grac - 4.0.11-12 +- New fence agent fence_compute + Resolves: rhbz#1214359 + +* Wed Mar 25 2015 Marek Grac - 4.0.11-11 +- fence_ipmilan: Unset default cipher + Resolves: rhbz#1203877 +- fence_ilo2: Add --tls1.0 + Resolves: rhbz#1199970 +- update scripts so 'make check' is working again + +* Mon Jan 05 2015 Marek Grac - 4.0.11-10 +- fence_zvmip: Add fence_zvmip ported to fencing library + Resolves: rhbz#1173178 + +* Mon Dec 01 2014 Marek Grac - 4.0.11-9 +- fence_ilo_ssh: Fix EOL issue, syslog problem and add fence_ilo_[34]_ssh symlink + Resolves: rhbz#1121122 + +* Wed Nov 12 2014 Marek Grac - 4.0.11-8 +- fence_zvm: Add 'monitor' support for fence_zvmip + Resolves: rhbz#1140921 + +* Mon Nov 10 2014 Marek Grac - 4.0.11-7 +- HTTPS connection do not validate certificate (introduced with rebase) + Resolves: rhbz#1162092 + +* Thu Oct 16 2014 Marek Grac - 4.0.11-6 +- fence_cisco_ucs and fence_vmware_soap should logout even in case of failure + Resolves: rhbz#1111599 +- fence_vmware_soap: Fix issue with import of fail_usage + Resolves: rhbz#1153059 + +* Thu Oct 02 2014 Marek Grac - 4.0.11-5 +- fence_wti: Fix problem with EOL introduced by rebase + Resolves: rhbz#1148762 +- fence_rsb: Fix issue with new firmware + Resolves: rhbz#1111597 + +* Sat Sep 20 2014 Fabio M. Di Nitto - 4.0.11-4 +- add initial support for IBM z/VM + Resolves: rhbz#1140921 + +* Mon Sep 15 2014 Marek Grac - 4.0.11-3 +- temporary removes fence-agents-amt because amtterm is missing + +* Wed Sep 03 2014 Marek Grac - 4.0.11-2 +- add a fence agents for AMT and iLO-ssh + Resolves: rhbz#1121122 rhbz#1107439 + +* Wed Sep 03 2014 Marek Grac - 4.0.11-1 +- rebase of fence agents + Resolves: rhbz#1120682 +- INFO: fence_scsi_check.pl is now a python script + +* Wed Mar 19 2014 Marek Grac - 4.0.2-21 +- fencing: Add --ssl-secure and --ssl-insecure for fence_vmware_soap + Resolves: rhbz#1072564 + +* Fri Mar 07 2014 Marek Grac - 4.0.2-20 +- fencing: Add --ssl-secure and --ssl-insecure for fence_vmware_soap + Resolves: rhbz#1072564 + +* Wed Mar 05 2014 Marek Grac - 4.0.2-19 +- fencing: Add --ssl-secure and --ssl-insecure + Resolves: rhbz#1072564 + +* Thu Feb 27 2014 Fabio M. Di Nitto - 4.0.2-18 +- fence_vmware_soap: fix short/long option parsing traceback + Resolves: rhbz#1018780 + +* Wed Feb 26 2014 Fabio M. Di Nitto - 4.0.2-17 +- Fix fence-agents-* Requires on proper fence-agents-common and silence + suds error + Resolves: rhbz#1018780 + +* Thu Feb 20 2014 Fabio M. Di Nitto - 4.0.2-16 +- Allow ssl connections to disable TLS negotiation with "notls" option. + Resolves: rhbz#990539 + +* Wed Feb 19 2014 Marek Grac - 4.0.2-15 +- Fix dependencies issues + +* Mon Feb 17 2014 Marek Grac - 4.0.2-14 +- fence_vmware_soap: Fix unexpected exception + Resolves: rhbz#1018780 +- nss_wrapper was replaced by gnutls-cli + Resolves: rhbz#990539 + +* Wed Jan 29 2014 Marek Grac - 4.0.2-13 +- fencing: Do not use public key if identity file is not defined + Resolves: rhbz#1048843 +- fence_vmware_soap: Add support for --delay option + Resolves: rhbz#1057299 +- fence_wti: Add support for named groups (also for firmware 1.43) + Resolves: rhbz#1022536 + +* Fri Jan 24 2014 Daniel Mach - 4.0.2-12 +- Mass rebuild 2014-01-24 + +* Thu Jan 23 2014 Marek Grac - 4.0.2-11 +- fencing: Ensure validity of XML metadata using Relax NG + Resolves: rhbz#1022529 + +* Thu Jan 23 2014 Marek Grac - 4.0.2-10 +- fix default action for fabric fencing agents + Resolves: rhbz#1021392 +- modify key generation in fence_scsi to support pacemaker/corosync cluster + Resolves: rhbz#994466 + +* Fri Dec 27 2013 Daniel Mach - 4.0.2-9 +- Mass rebuild 2013-12-27 + +* Wed Nov 20 2013 Marek Grac - 4.0.2-8 +- fence-agents-all now includes fence-virt which is not available everywhere + Resolves: rhbz#1028940 + +* Tue Nov 12 2013 Marek Grac - 4.0.2-7 +- fence-agents-all now includes fence-virt + Resolves: rhbz#1028940 + +* Mon Nov 04 2013 Marek Grac - 4.0.2-6 +- fencing: Ensure validity of XML metadata using Relax NG + Resolves: rhbz#1022529 +- fencing: Fix invalid use of options[".."] + Resolves: rhbz#1022533 +- fence_brocade: Add fence agent + Resolves: rhbz#1021392 + +* Mon Nov 04 2013 Marek Grac - 4.0.2-5 +- fence_vmware_soap: Report if user privileges are not enough for given operation + Resolves: rhbz#1018780 +- fence_wti: Add support for named groups + Resolves: rhbz#1022536 +- fence_rsb: Update regular expression to match newer firmware version + Resolves: rhbz#1022538 + +* Mon Nov 04 2013 Marek Grac - 4.0.2-4 +- fence_vmware_soap: Disable cache in SUDS library to resolve SELinux problems + Resolves: rhbz#1022528 +- fencing: Add information that operation 'unfence' should be run automatically after start of the cluster + Resolves: rhbz#1012994 +- Aligned to upstream 4.0.4 + +* Mon Sep 02 2013 Marek Grac - 4.0.2-3 +- fence_bladecenter: Fix telnet login failure +- fence_brocade: Rewrite to fencing library +- fencing_snmp: Fix 'KeyError --a' +- fence_scsi: Fix XML metadata +- fence_scsi: Add a documentation of "delay" +- fence_ilo2: Unable to login when password contains " + +* Tue Jul 30 2013 Marek Grac - 4.0.2-2 +- new upstream release + +* Tue Jul 09 2013 Marek Grac - 4.0.1-1 +- new upstream release + +* Mon Jun 24 2013 Marek Grac - 4.0.0-5 +- fence-agents-all should provide fence-agent for clean update path + +* Wed Apr 03 2013 Marek Grac - 4.0.0-4 +- minor changes in spec file + +* Thu Mar 21 2013 Marek Grac - 4.0.0-3 +- minor changes in spec file + +* Mon Mar 18 2013 Marek Grac - 4.0.0-2 +- minor changes in spec file + +* Mon Mar 11 2013 Marek Grac - 4.0.0-1 +- new upstream release +- introducing subpackages + +