From 09283ba8afe820f8ae375e9a307c33ef418a7064 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2016 05:47:58 +0000 Subject: import fence-agents-4.0.11-47.el7 --- 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/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/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/bz1299577-fence_compute.patch b/SOURCES/bz1299577-fence_compute.patch deleted file mode 100644 index f3671a7..0000000 --- a/SOURCES/bz1299577-fence_compute.patch +++ /dev/null @@ -1,347 +0,0 @@ -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/bz1303698-2-fence_cisco_ucs-Add-missing-as-off.patch b/SOURCES/bz1303698-2-fence_cisco_ucs-Add-missing-as-off.patch deleted file mode 100644 index 0ba7e74..0000000 --- a/SOURCES/bz1303698-2-fence_cisco_ucs-Add-missing-as-off.patch +++ /dev/null @@ -1,43 +0,0 @@ -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/bz1303698-3-fence_cisco_ucs-Update-XML-metadata.patch b/SOURCES/bz1303698-3-fence_cisco_ucs-Update-XML-metadata.patch deleted file mode 100644 index 8054cbe..0000000 --- a/SOURCES/bz1303698-3-fence_cisco_ucs-Update-XML-metadata.patch +++ /dev/null @@ -1,28 +0,0 @@ -From ddb6b61ac1ba4d6cb461a7ad8ed75528785f8138 Mon Sep 17 00:00:00 2001 -From: Marek 'marx' Grac -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/bz1303698-4-fence_cisco_ucs-Update-XML-metadata.patch b/SOURCES/bz1303698-4-fence_cisco_ucs-Update-XML-metadata.patch deleted file mode 100644 index 5550354..0000000 --- a/SOURCES/bz1303698-4-fence_cisco_ucs-Update-XML-metadata.patch +++ /dev/null @@ -1,65 +0,0 @@ -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/bz1303698-fence_cisco_ucs-Obtain-status-of-device-from-differe.patch b/SOURCES/bz1303698-fence_cisco_ucs-Obtain-status-of-device-from-differe.patch deleted file mode 100644 index a15fbee..0000000 --- a/SOURCES/bz1303698-fence_cisco_ucs-Obtain-status-of-device-from-differe.patch +++ /dev/null @@ -1,57 +0,0 @@ -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/bz1322702-fix-automatic-nova-evacuate.patch b/SOURCES/bz1322702-fix-automatic-nova-evacuate.patch deleted file mode 100644 index adeb76b..0000000 --- a/SOURCES/bz1322702-fix-automatic-nova-evacuate.patch +++ /dev/null @@ -1,33 +0,0 @@ -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/bz1323962-1-fence_cisco_ucs-Obtain-status-from-different-attr.patch b/SOURCES/bz1323962-1-fence_cisco_ucs-Obtain-status-from-different-attr.patch deleted file mode 100644 index 104951c..0000000 --- a/SOURCES/bz1323962-1-fence_cisco_ucs-Obtain-status-from-different-attr.patch +++ /dev/null @@ -1,40 +0,0 @@ -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/bz1323962-2-fence_cisco_ucs-Obtain-status-from-different-attr.patch b/SOURCES/bz1323962-2-fence_cisco_ucs-Obtain-status-from-different-attr.patch deleted file mode 100644 index 190001d..0000000 --- a/SOURCES/bz1323962-2-fence_cisco_ucs-Obtain-status-from-different-attr.patch +++ /dev/null @@ -1,52 +0,0 @@ -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: 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/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/SPECS/fence-agents.spec b/SPECS/fence-agents.spec index 2759e3d..7c8c74a 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: 27%{?alphatag:.%{alphatag}}%{?dist}.9 +Release: 47%{?alphatag:.%{alphatag}}%{?dist} License: GPLv2+ and LGPLv2+ Group: System Environment/Base URL: http://sourceware.org/cluster/wiki/ @@ -93,14 +93,31 @@ 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: bz1299577-fence_compute.patch -Patch73: bz1303698-fence_cisco_ucs-Obtain-status-of-device-from-differe.patch -Patch74: bz1303698-2-fence_cisco_ucs-Add-missing-as-off.patch -Patch75: bz1303698-3-fence_cisco_ucs-Update-XML-metadata.patch -Patch76: bz1303698-4-fence_cisco_ucs-Update-XML-metadata.patch -Patch77: bz1322702-fix-automatic-nova-evacuate.patch -Patch78: bz1323962-1-fence_cisco_ucs-Obtain-status-from-different-attr.patch -Patch79: bz1323962-2-fence_cisco_ucs-Obtain-status-from-different-attr.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 %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 @@ -120,7 +137,7 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) BuildRequires: glibc-devel BuildRequires: gnutls-utils BuildRequires: libxslt -BuildRequires: python pexpect python-pycurl python-suds python-requests +BuildRequires: python pexpect python-pycurl python-suds python-requests openwsman-python BuildRequires: net-snmp-utils BuildRequires: autoconf automake libtool @@ -198,14 +215,31 @@ BuildRequires: autoconf automake libtool %patch69 -p1 -b .bz1265426-2 %patch70 -p1 -b .bz1265426-3 %patch71 -p1 -b .bz1265426-4 -%patch72 -p1 -b .bz1299577 -%patch73 -p1 -b .bz1303698 -%patch74 -p1 -b .bz1303698-2 -%patch75 -p1 -b .bz1303698-3 -%patch76 -p1 -b .bz1303698-4 -%patch77 -p1 -b .bz1322702 -%patch78 -p1 -b .bz1323962 -%patch79 -p1 -b .bz1323962-2 +%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 %build ./autogen.sh @@ -233,7 +267,7 @@ power management for several devices. License: GPLv2+ and LGPLv2+ Group: System Environment/Base Summary: Common utilities for fence agents -Requires: python pexpect +Requires: python pexpect python-pycurl %description common Red Hat Fence Agents is a collection of scripts and libraries to handle remote power management for various devices. %files common @@ -245,7 +279,7 @@ Red Hat Fence Agents is a collection of scripts and libraries to handle remote p %{_datadir}/fence/fencing_snmp.py %package all -License: GPLv2+ and LGPLv2+ +License: GPLv2+, LGPLv2+ and ASL 2.0 Group: System Environment/Base Summary: Fence agents Requires: %{allfenceagents} @@ -773,34 +807,90 @@ The fence-agents-zvm package contains a fence agent for z/VM hypervisors %endif %changelog -* Thu Aug 25 2016 Marek Grac - 4.0.11-27.9 -- fence_cisco_ucs: Change endpoint for 'status' action - Resolves: rhbz#1323962 - -* Wed Apr 13 2016 Marek Grac - 4.0.11-27.8 -- fence_cisco_ucs: Change endpoint for 'status' action - Resolves: rhbz#1323962 - -* Tue Apr 05 2016 Oyvind Albrigtsen - 4.0.11-27.7 -- fence_compute: fix evacuation not working when instance was created - by non-admin user - Resolves: rhbz#1322702 - -* Tue Feb 09 2016 Marek Grac - 4.0.11-27.5 -- fence_cisco_ucs: Change endpoint for 'status' action - Resolves: rhbz#1303698 - -* Tue Feb 02 2016 Marek Grac - 4.0.11-27.4 -- fence_cisco_ucs: Change endpoint for 'status' action - Resolves: rhbz#1303698 +* 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#1299577 + Resolves: rhbz#1283084 -* Wed Dec 16 2015 Marek Grac - 4.0.11-27.2 +* Wed Dec 16 2015 Marek Grac - 4.0.11-28 - fence_scsi: Add fence_scsi_check_hardreboot - Resolves: rhbz#bz1292071 + Resolves: rhbz#bz1265426 * Mon Oct 26 2015 Marek Grac - 4.0.11-27 - fence_brocade: Fix return status in get_power_status @@ -831,6 +921,7 @@ The fence-agents-zvm package contains a fence agent for z/VM hypervisors 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