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..26d1d0f --- /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 22:45:09.824853109 +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)) ++ ++ fail_usage("Couldn't obtain a supported connection to nova, tried: %s" % 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/bz1397889-monitor_port_as_ip.patch b/SOURCES/bz1397889-monitor_port_as_ip.patch new file mode 100644 index 0000000..7d2585e --- /dev/null +++ b/SOURCES/bz1397889-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/SPECS/fence-agents.spec b/SPECS/fence-agents.spec index 7c8c74a..53b956c 100644 --- a/SPECS/fence-agents.spec +++ b/SPECS/fence-agents.spec @@ -16,7 +16,7 @@ Name: fence-agents Summary: Fence Agents for Red Hat Cluster Version: 4.0.11 -Release: 47%{?alphatag:.%{alphatag}}%{?dist} +Release: 47%{?alphatag:.%{alphatag}}%{?dist}.2 License: GPLv2+ and LGPLv2+ Group: System Environment/Base URL: http://sourceware.org/cluster/wiki/ @@ -118,6 +118,8 @@ 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: bz1397889-monitor_port_as_ip.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 scsi vmware_soap wti @@ -240,6 +242,8 @@ BuildRequires: autoconf automake libtool %patch94 -p1 -F2 -b .bz1287311-2 %patch95 -p1 -b .bz1298430-2 %patch96 -p1 -F2 -b .bz1287059-2 +%patch97 -p1 -b .bz1393789 +%patch98 -p1 -b .bz1397889 %build ./autogen.sh @@ -807,6 +811,14 @@ The fence-agents-zvm package contains a fence agent for z/VM hypervisors %endif %changelog +* Wed Nov 23 2016 Marek Grac - 4.0.11-47.2 +- fencing: Fix 'monitor' action for devices with --port-as-ip + Resolves: rhbz#1397889 + +* Wed Nov 9 2016 Andrew Beekhof - 4.0.11-47.1 +- fence_compute: Improved FQDN and Nova handling + Resolves: rhbz#1393789 + * Wed Aug 31 2016 Oyvind Albrigtsen - 4.0.11-47 - fence_rhevm: fix issues on RHEV 4 Resolves: rhbz#1287059