From bbedc230d68d85a31f08d7159c15b97e26669978 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jan 29 2019 15:47:00 +0000 Subject: import fence-agents-4.2.1-11.el7_6.7 --- diff --git a/SOURCES/bz1652115-fence_hpblade-fix-log_expect-syntax.patch b/SOURCES/bz1652115-fence_hpblade-fix-log_expect-syntax.patch new file mode 100644 index 0000000..bb239b1 --- /dev/null +++ b/SOURCES/bz1652115-fence_hpblade-fix-log_expect-syntax.patch @@ -0,0 +1,50 @@ +From 342570c5a5af4c277be283507ef7898a078e2df9 Mon Sep 17 00:00:00 2001 +From: mmartinv <32071463+mmartinv@users.noreply.github.com> +Date: Fri, 16 Nov 2018 12:55:58 +0100 +Subject: [PATCH] Fix 'log_expect' in fence_hpblade.py + +Update the 'log_expect' call to the new method definition. +--- + agents/hpblade/fence_hpblade.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/agents/hpblade/fence_hpblade.py b/agents/hpblade/fence_hpblade.py +index b2cc94a3..fbc89f61 100644 +--- a/agents/hpblade/fence_hpblade.py ++++ b/agents/hpblade/fence_hpblade.py +@@ -16,7 +16,7 @@ + + def get_enclosure_type(conn, options): + conn.send_eol("show enclosure info") +- conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) ++ conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"])) + + type_re=re.compile(r"^\s*Enclosure Type: (\w+)(.*?)\s*$") + enclosure="unknown" +@@ -39,7 +39,7 @@ def get_power_status(conn, options): + powrestr = "^\\s*Power: (.*?)\\s*$" + + conn.send_eol(cmd_send) +- conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) ++ conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"])) + + power_re = re.compile(powrestr) + status = "unknown" +@@ -72,7 +72,7 @@ def set_power_status(conn, options): + conn.send_eol("poweron " + dev + options["--plug"]) + elif options["--action"] == "off": + conn.send_eol("poweroff " + dev + options["--plug"] + " force") +- conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) ++ conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"])) + + def get_instances_list(conn, options): + outlets = {} +@@ -84,7 +84,7 @@ def get_instances_list(conn, options): + listrestr = "^\\s*(\\d+)\\s+(.*?)\\s+(.*?)\\s+OK\\s+(.*?)\\s+(.*?)\\s*$" + + conn.send_eol(cmd_send) +- conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"])) ++ conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"])) + + list_re = re.compile(listrestr) + for line in conn.before.splitlines(): diff --git a/SOURCES/bz1654172-1-fence_scsi-watchdog-retry-support.patch b/SOURCES/bz1654172-1-fence_scsi-watchdog-retry-support.patch new file mode 100644 index 0000000..276c439 --- /dev/null +++ b/SOURCES/bz1654172-1-fence_scsi-watchdog-retry-support.patch @@ -0,0 +1,146 @@ +From 11a63822fbdc0a9ebe1b668b26a59f1cc9649f6c Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Wed, 24 Oct 2018 14:51:27 +0200 +Subject: [PATCH] fence_scsi: watchdog retries support + +--- + agents/scsi/fence_scsi.py | 60 ++++++++++++++++++++---------- + tests/data/metadata/fence_scsi.xml | 4 +- + 2 files changed, 43 insertions(+), 21 deletions(-) + +diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py +index 79ada4fa..8a1e4c77 100644 +--- a/agents/scsi/fence_scsi.py ++++ b/agents/scsi/fence_scsi.py +@@ -158,13 +158,15 @@ def get_reservation_key(options, dev): + return match.group(1) if match else None + + +-def get_registration_keys(options, dev): ++def get_registration_keys(options, dev, fail=True): + reset_dev(options,dev) + keys = [] + cmd = options["--sg_persist-path"] + " -n -i -k -d " + dev + out = run_cmd(options, cmd) + if out["err"]: +- fail_usage("Cannot get registration keys") ++ fail_usage("Cannot get registration keys", fail) ++ if not fail: ++ return [] + for line in out["out"].split("\n"): + match = re.search(r"\s+0x(\S+)\s*", line) + if match: +@@ -218,9 +220,8 @@ def get_key(fail=True): + try: + f = open(file_path, "r") + except IOError: +- if fail: +- fail_usage("Failed: Cannot open file \""+ file_path + "\"") +- else: ++ fail_usage("Failed: Cannot open file \""+ file_path + "\"", fail) ++ if not fail: + return None + return f.readline().strip().lower() + +@@ -244,9 +245,8 @@ def dev_read(fail=True): + try: + f = open(file_path, "r") + except IOError: +- if fail: +- fail_usage("Failed: Cannot open file \"" + file_path + "\"") +- else: ++ fail_usage("Failed: Cannot open file \"" + file_path + "\"", fail) ++ if not fail: + return None + # get not empty lines from file + devs = [line.strip() for line in f if line.strip()] +@@ -371,14 +371,20 @@ def define_new_opts(): + } + + +-def scsi_check_get_verbose(): ++def scsi_check_get_options(options): + try: +- f = open("/etc/sysconfig/watchdog", "r") ++ f = open("/etc/sysconfig/stonith", "r") + except IOError: +- return False +- match = re.search(r"^\s*verbose=yes", "".join(f.readlines()), re.MULTILINE) ++ return options ++ ++ match = re.findall(r"^\s*(\S*)\s*=\s*(\S*)\s*", "".join(f.readlines()), re.MULTILINE) ++ ++ for m in match: ++ options[m[0].lower()] = m[1].lower() ++ + f.close() +- return bool(match) ++ ++ return options + + + def scsi_check(hardreboot=False): +@@ -388,7 +394,10 @@ def scsi_check(hardreboot=False): + options["--sg_turs-path"] = "@SG_TURS_PATH@" + options["--sg_persist-path"] = "@SG_PERSIST_PATH@" + options["--power-timeout"] = "5" +- if scsi_check_get_verbose(): ++ options["retry"] = "0" ++ options["retry-sleep"] = "1" ++ options = scsi_check_get_options(options) ++ if "verbose" in options and options["verbose"] == "yes": + logging.getLogger().setLevel(logging.DEBUG) + devs = dev_read(fail=False) + if not devs: +@@ -399,11 +408,18 @@ def scsi_check(hardreboot=False): + logging.error("Key not found") + return 0 + for dev in devs: +- if key in get_registration_keys(options, dev): +- logging.debug("key " + key + " registered with device " + dev) +- return 0 +- else: +- logging.debug("key " + key + " not registered with device " + dev) ++ for n in range(int(options["retry"]) + 1): ++ if n > 0: ++ logging.debug("retry: " + str(n) + " of " + options["retry"]) ++ if key in get_registration_keys(options, dev, fail=False): ++ logging.debug("key " + key + " registered with device " + dev) ++ return 0 ++ else: ++ logging.debug("key " + key + " not registered with device " + dev) ++ ++ if n < int(options["retry"]): ++ time.sleep(float(options["retry-sleep"])) ++ + logging.debug("key " + key + " registered with any devices") + + if hardreboot == True: +@@ -452,7 +468,11 @@ def main(): + 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." ++longer be able to write to the device(s). A manual reboot is required.\ ++\n.P\n\ ++When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and \ ++verbose=yes parameters in /etc/sysconfig/stonith if you have issues with it \ ++failing." + docs["vendorurl"] = "" + show_docs(options, docs) + +diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +index 45a84168..b8cdabd1 100644 +--- a/tests/data/metadata/fence_scsi.xml ++++ b/tests/data/metadata/fence_scsi.xml +@@ -1,7 +1,9 @@ + + + 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 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. ++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. ++ ++When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and verbose=yes parameters in /etc/sysconfig/stonith if you have issues with it failing. + + + diff --git a/SOURCES/bz1654172-2-build-fix-check_used_options.patch b/SOURCES/bz1654172-2-build-fix-check_used_options.patch new file mode 100644 index 0000000..068375d --- /dev/null +++ b/SOURCES/bz1654172-2-build-fix-check_used_options.patch @@ -0,0 +1,23 @@ +From 267afc5caa0580cc483220e671cda094413a4e16 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Wed, 28 Nov 2018 09:54:16 +0100 +Subject: [PATCH] build: fix if-redirection to make check_used_options run for + the agents as intended + +--- + make/fencebuild.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/make/fencebuild.mk b/make/fencebuild.mk +index 9e8bd692..143082f0 100644 +--- a/make/fencebuild.mk ++++ b/make/fencebuild.mk +@@ -33,7 +33,7 @@ define gen_agent_from_py + -e 's#@''PING4_CMD@#${PING4_CMD}#g' \ + > $@ + +- if [ 0 -eq `echo "$(@)" | grep fence_ 2>&1 /dev/null; echo $$?` ]; then \ ++ if [ 0 -eq `echo "$(@)" | grep fence_ > /dev/null 2>&1; echo $$?` ]; then \ + PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(top_srcdir)/lib/check_used_options.py $@; \ + else true ; fi + diff --git a/SOURCES/bz1666848-1-fence_redfish.patch b/SOURCES/bz1666848-1-fence_redfish.patch new file mode 100644 index 0000000..c6f5dfd --- /dev/null +++ b/SOURCES/bz1666848-1-fence_redfish.patch @@ -0,0 +1,812 @@ +From 64e3f3ef4d0abefd2836fe015c87173310b1e130 Mon Sep 17 00:00:00 2001 +From: Jose Delarosa +Date: Mon, 3 Dec 2018 10:11:15 -0600 +Subject: [PATCH 1/8] Add new fence agent for Redfish + +- Agent works on all fence devices that implement the Redfish API specification +- Agent programatically finds the Systems Resouce URI if it's not provided +--- + agents/redfish/fence_redfish.py | 151 +++++++++++++++++++++ + tests/data/metadata/fence_redfish.xml | 181 ++++++++++++++++++++++++++ + 2 files changed, 332 insertions(+) + create mode 100644 agents/redfish/fence_redfish.py + create mode 100644 tests/data/metadata/fence_redfish.xml + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +new file mode 100644 +index 00000000..df7cf8c2 +--- /dev/null ++++ b/agents/redfish/fence_redfish.py +@@ -0,0 +1,151 @@ ++#!@PYTHON@ -tt ++ ++# Copyright (c) 2018 Dell Inc. or its subsidiaries. All Rights Reserved. ++ ++# Fence agent for devices that support the Redfish API Specification. ++ ++import sys ++import re ++import json ++import requests ++import atexit ++sys.path.append("@FENCEAGENTSLIBDIR@") ++ ++from requests.packages.urllib3.exceptions import InsecureRequestWarning ++from fencing import * ++from fencing import fail_usage ++ ++def get_power_status(conn, options): ++ uri = options["--systems-uri"] ++ response = send_get_request(options, uri) ++ if response['ret'] is False: ++ fail_usage("Couldn't get power information") ++ data = response['data'] ++ if data[u'PowerState'].strip() == "On": ++ return "on" ++ else: ++ return "off" ++ ++def set_power_status(conn, options): ++ action = { ++ 'on' : "On", ++ 'off': "ForceOff", ++ 'reboot': "GracefulRestart" ++ }[options["--action"]] ++ ++ payload = {'ResetType': action} ++ headers = {'content-type': 'application/json'} ++ ++ # Search for 'Actions' key and extract URI from it ++ uri = options["--systems-uri"] ++ response = send_get_request(options, uri) ++ if response['ret'] is False: ++ return {'ret': False} ++ data = response['data'] ++ uri = data["Actions"]["#ComputerSystem.Reset"]["target"] ++ ++ response = send_post_request(options, uri, payload, headers) ++ if response['ret'] is False: ++ fail_usage("Error sending power command") ++ return ++ ++def send_get_request(options, uri): ++ full_uri = "https://" + options["--ip"] + uri ++ try: ++ resp = requests.get(full_uri, verify=False, ++ auth=(options["--username"], options["--password"])) ++ data = resp.json() ++ except: ++ return {'ret': False} ++ return {'ret': True, 'data': data} ++ ++def send_post_request(options, uri, payload, headers): ++ full_uri = "https://" + options["--ip"] + uri ++ try: ++ requests.post(full_uri, data=json.dumps(payload), ++ headers=headers, verify=False, ++ auth=(options["--username"], options["--password"])) ++ except: ++ return {'ret': False} ++ return {'ret': True} ++ ++def find_systems_resource(options): ++ uri = options["--redfish-uri"] ++ response = send_get_request(options, uri) ++ if response['ret'] is False: ++ return {'ret': False} ++ data = response['data'] ++ ++ if 'Systems' not in data: ++ # Systems resource not found" ++ return {'ret': False} ++ else: ++ uri = data["Systems"]["@odata.id"] ++ response = send_get_request(options, uri) ++ if response['ret'] is False: ++ return {'ret': False} ++ data = response['data'] ++ ++ # need to be able to handle more than one entry ++ for member in data[u'Members']: ++ system_uri = member[u'@odata.id'] ++ return {'ret': True, 'uri': system_uri} ++ ++def define_new_opts(): ++ all_opt["redfish-uri"] = { ++ "getopt" : ":", ++ "longopt" : "redfish-uri", ++ "help" : "--redfish-uri=[uri] Base or starting Redifsh URI", ++ "required" : "0", ++ "default" : "/redfish/v1", ++ "shortdesc" : "Base or starting Redfish URI", ++ "order": 1 ++ } ++ all_opt["systems-uri"] = { ++ "getopt" : ":", ++ "longopt" : "systems-uri", ++ "help" : "--systems-uri=[uri] Redfish Systems resource URI", ++ "required" : "0", ++ "shortdesc" : "Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1", ++ "order": 1 ++ } ++ ++def main(): ++ atexit.register(atexit_handler) ++ device_opt = ["ipaddr", "login", "passwd", "redfish-uri", "systems-uri", "ssl"] ++ define_new_opts() ++ ++ opt = process_input(device_opt) ++ ++ all_opt["ipport"]["default"] = "443" ++ options = check_input(device_opt, opt) ++ ++ docs = {} ++ docs["shortdesc"] = "I/O Fencing agent for Redfish" ++ docs["longdesc"] = "fence_redfish is an I/O Fencing agent which can be used with \ ++Out-of-Band controllers that support Redfish APIs. These controllers provide remote \ ++access to control power on a server." ++ docs["vendorurl"] = "http://www.dmtf.org" ++ show_docs(options, docs) ++ ++ ## ++ ## Operate the fencing device ++ #### ++ ++ # Disable insecure-certificate-warning message ++ if "--ssl-insecure" in opt: ++ requests.packages.urllib3.disable_warnings(InsecureRequestWarning) ++ ++ if "--systems-uri" not in opt: ++ # Systems URI not provided, find it ++ sysresult = find_systems_resource(options) ++ if sysresult['ret'] is False: ++ sys.exit(1) ++ else: ++ options["--systems-uri"] = sysresult["uri"] ++ ++ result = fence_action(None, options, set_power_status, get_power_status, None) ++ sys.exit(result) ++ ++if __name__ == "__main__": ++ main() +diff --git a/tests/data/metadata/fence_redfish.xml b/tests/data/metadata/fence_redfish.xml +new file mode 100644 +index 00000000..43d447d0 +--- /dev/null ++++ b/tests/data/metadata/fence_redfish.xml +@@ -0,0 +1,181 @@ ++ ++ ++fence_redfish is an I/O Fencing agent which can be used with Out-of-Band controllers that support Redfish APIs. These controllers provide remote access to control power on a server. ++http://www.dmtf.org ++ ++ ++ ++ ++ TCP/UDP port to use for connection with device ++ ++ ++ ++ ++ SSL connection with verifying fence device's certificate ++ ++ ++ ++ ++ Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1 ++ ++ ++ ++ ++ Fencing Action ++ ++ ++ ++ ++ Forces agent to use IPv6 addresses only ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Forces agent to use IPv4 addresses only ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ SSL connection ++ ++ ++ ++ ++ Base or starting Redfish URI ++ ++ ++ ++ ++ SSL connection without verifying fence device's certificate ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Login Name ++ ++ ++ ++ ++ Base or starting Redfish URI ++ ++ ++ ++ ++ IP Address or Hostname ++ ++ ++ ++ ++ Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1 ++ ++ ++ ++ ++ Login password or passphrase ++ ++ ++ ++ ++ Script to retrieve password ++ ++ ++ ++ ++ Verbose mode ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Write debug information to given file ++ ++ ++ ++ ++ Display version information and exit ++ ++ ++ ++ ++ Display help and exit ++ ++ ++ ++ ++ Wait X seconds after issuing ON/OFF ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after login ++ ++ ++ ++ ++ Test X seconds for status change after ON/OFF ++ ++ ++ ++ ++ Wait X seconds before fencing is started ++ ++ ++ ++ ++ Wait X seconds for cmd prompt after issuing command ++ ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ ++ ++ ++ ++ Count of attempts to retry power on ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +From 6921a34d64d098a7b1f32205e0be434438c36898 Mon Sep 17 00:00:00 2001 +From: Jose Delarosa +Date: Mon, 3 Dec 2018 10:46:52 -0600 +Subject: [PATCH 2/8] Updated fence_redfish.xml with make xml-upload + +--- + tests/data/metadata/fence_redfish.xml | 148 ++++++++++++++------------ + 1 file changed, 79 insertions(+), 69 deletions(-) + +diff --git a/tests/data/metadata/fence_redfish.xml b/tests/data/metadata/fence_redfish.xml +index 43d447d0..a39541e6 100644 +--- a/tests/data/metadata/fence_redfish.xml ++++ b/tests/data/metadata/fence_redfish.xml +@@ -3,110 +3,115 @@ + fence_redfish is an I/O Fencing agent which can be used with Out-of-Band controllers that support Redfish APIs. These controllers provide remote access to control power on a server. + http://www.dmtf.org + +- +- +- +- TCP/UDP port to use for connection with device +- +- +- +- +- SSL connection with verifying fence device's certificate +- +- +- +- +- Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1 +- + + + +- Fencing Action ++ Fencing action ++ ++ ++ ++ ++ Forces agent to use IPv4 addresses only + + + + + Forces agent to use IPv6 addresses only + +- ++ + + +- IP Address or Hostname ++ IP address or hostname of fencing device + +- +- ++ ++ + +- IP address or hostname of fencing device (together with --port-as-ip) ++ IP address or hostname of fencing device + +- +- +- +- Script to retrieve password ++ ++ ++ ++ TCP/UDP port to use for connection with device + +- +- +- +- Forces agent to use IPv4 addresses only ++ ++ ++ ++ Login name + + + + + Login password or passphrase + +- +- +- +- SSL connection +- +- +- +- +- Base or starting Redfish URI ++ ++ ++ ++ Script to run to retrieve password + +- +- +- +- SSL connection without verifying fence device's certificate ++ ++ ++ ++ Login password or passphrase + +- +- ++ ++ + +- Login Name ++ Script to run to retrieve password + + + + + IP address or hostname of fencing device (together with --port-as-ip) + +- +- ++ ++ + +- Login Name ++ IP address or hostname of fencing device (together with --port-as-ip) ++ ++ ++ ++ ++ Base or starting Redfish URI + + + + + Base or starting Redfish URI + +- +- ++ ++ ++ ++ Use SSL connection with verifying certificate ++ ++ ++ ++ ++ Use SSL connection without verifying certificate ++ ++ ++ ++ ++ Use SSL connection with verifying certificate ++ ++ ++ + +- IP Address or Hostname ++ Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1 + + + + + Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1 + +- +- ++ ++ + +- Login password or passphrase ++ Login name + +- +- +- +- Script to retrieve password ++ ++ ++ ++ Disable logging to stderr. Does not affect --verbose or --debug-file or logging to syslog. + + + +@@ -133,41 +138,45 @@ + + Display help and exit + +- +- ++ ++ + +- Wait X seconds after issuing ON/OFF ++ Wait X seconds before fencing is started + + + + + Wait X seconds for cmd prompt after login + ++ ++ ++ ++ Make "port/plug" to be an alias to IP address ++ + + + + Test X seconds for status change after ON/OFF + +- +- ++ ++ + +- Wait X seconds before fencing is started ++ Wait X seconds after issuing ON/OFF + + + + + Wait X seconds for cmd prompt after issuing command + +- +- +- +- Make "port/plug" to be an alias to IP address +- + + + + Count of attempts to retry power on + ++ ++ ++ Path to gnutls-cli binary ++ + + + +@@ -176,6 +185,7 @@ + + + ++ + + + + +From 755627fadd711848ea256d72f5e75f36f83b4d31 Mon Sep 17 00:00:00 2001 +From: Jose Delarosa +Date: Mon, 3 Dec 2018 11:55:23 -0600 +Subject: [PATCH 3/8] Added run_delay() + +--- + agents/redfish/fence_redfish.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +index df7cf8c2..0e4a4f68 100644 +--- a/agents/redfish/fence_redfish.py ++++ b/agents/redfish/fence_redfish.py +@@ -13,7 +13,7 @@ + + from requests.packages.urllib3.exceptions import InsecureRequestWarning + from fencing import * +-from fencing import fail_usage ++from fencing import fail_usage, run_delay + + def get_power_status(conn, options): + uri = options["--systems-uri"] +@@ -127,6 +127,7 @@ def main(): + access to control power on a server." + docs["vendorurl"] = "http://www.dmtf.org" + show_docs(options, docs) ++ run_delay(options) + + ## + ## Operate the fencing device + +From 15fef4c47f391a3f03c714d86c9670ea209dec99 Mon Sep 17 00:00:00 2001 +From: Jose Delarosa +Date: Tue, 4 Dec 2018 10:56:58 -0600 +Subject: [PATCH 4/8] Modify power status check + +- Only returns off if PowerState = Off +- Otherwise returns on +--- + agents/redfish/fence_redfish.py | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +index 0e4a4f68..7998fb1c 100644 +--- a/agents/redfish/fence_redfish.py ++++ b/agents/redfish/fence_redfish.py +@@ -21,10 +21,10 @@ def get_power_status(conn, options): + if response['ret'] is False: + fail_usage("Couldn't get power information") + data = response['data'] +- if data[u'PowerState'].strip() == "On": +- return "on" +- else: ++ if data[u'PowerState'].strip() == "Off": + return "off" ++ else: ++ return "on" + + def set_power_status(conn, options): + action = { + +From acf70f4672be65562841227ab0b4cacb87965f44 Mon Sep 17 00:00:00 2001 +From: Jose Delarosa +Date: Wed, 5 Dec 2018 10:39:32 -0600 +Subject: [PATCH 5/8] Changed reboot type to ForceRestart + +--- + agents/redfish/fence_redfish.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +index 7998fb1c..3fe2bfc0 100644 +--- a/agents/redfish/fence_redfish.py ++++ b/agents/redfish/fence_redfish.py +@@ -30,7 +30,7 @@ def set_power_status(conn, options): + action = { + 'on' : "On", + 'off': "ForceOff", +- 'reboot': "GracefulRestart" ++ 'reboot': "ForceRestart" + }[options["--action"]] + + payload = {'ResetType': action} + +From 56e3358d45050ac669c099c56873feefa1ecda38 Mon Sep 17 00:00:00 2001 +From: Jose Delarosa +Date: Wed, 5 Dec 2018 10:54:44 -0600 +Subject: [PATCH 6/8] Replaced default port 443 with default ssl enabled option + +--- + agents/redfish/fence_redfish.py | 2 +- + tests/data/metadata/fence_redfish.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +index 3fe2bfc0..6a2dbb76 100644 +--- a/agents/redfish/fence_redfish.py ++++ b/agents/redfish/fence_redfish.py +@@ -117,7 +117,7 @@ def main(): + + opt = process_input(device_opt) + +- all_opt["ipport"]["default"] = "443" ++ all_opt["ssl"]["default"] = "1" + options = check_input(device_opt, opt) + + docs = {} +diff --git a/tests/data/metadata/fence_redfish.xml b/tests/data/metadata/fence_redfish.xml +index a39541e6..e1c18584 100644 +--- a/tests/data/metadata/fence_redfish.xml ++++ b/tests/data/metadata/fence_redfish.xml +@@ -80,7 +80,7 @@ + + + +- ++ + Use SSL connection with verifying certificate + + + +From 5c25a85b22a17d6bbc3dcb47c99b76e3a99a5857 Mon Sep 17 00:00:00 2001 +From: Jose Delarosa +Date: Wed, 5 Dec 2018 13:29:42 -0600 +Subject: [PATCH 7/8] Renamed variable to avoid reusing variable name + +--- + agents/redfish/fence_redfish.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +index 6a2dbb76..1ea25cd8 100644 +--- a/agents/redfish/fence_redfish.py ++++ b/agents/redfish/fence_redfish.py +@@ -42,9 +42,9 @@ def set_power_status(conn, options): + if response['ret'] is False: + return {'ret': False} + data = response['data'] +- uri = data["Actions"]["#ComputerSystem.Reset"]["target"] ++ action_uri = data["Actions"]["#ComputerSystem.Reset"]["target"] + +- response = send_post_request(options, uri, payload, headers) ++ response = send_post_request(options, action_uri, payload, headers) + if response['ret'] is False: + fail_usage("Error sending power command") + return + +From 7dce8b1e22d57fec0d34e91a99fab9d8a06f1303 Mon Sep 17 00:00:00 2001 +From: Jose Delarosa +Date: Thu, 6 Dec 2018 10:33:06 -0600 +Subject: [PATCH 8/8] Removed unnecessary variable assignments to simplify code + +--- + agents/redfish/fence_redfish.py | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +index 1ea25cd8..67ef67ab 100644 +--- a/agents/redfish/fence_redfish.py ++++ b/agents/redfish/fence_redfish.py +@@ -16,8 +16,7 @@ + from fencing import fail_usage, run_delay + + def get_power_status(conn, options): +- uri = options["--systems-uri"] +- response = send_get_request(options, uri) ++ response = send_get_request(options, options["--systems-uri"]) + if response['ret'] is False: + fail_usage("Couldn't get power information") + data = response['data'] +@@ -37,8 +36,7 @@ def set_power_status(conn, options): + headers = {'content-type': 'application/json'} + + # Search for 'Actions' key and extract URI from it +- uri = options["--systems-uri"] +- response = send_get_request(options, uri) ++ response = send_get_request(options, options["--systems-uri"]) + if response['ret'] is False: + return {'ret': False} + data = response['data'] +@@ -70,8 +68,7 @@ def send_post_request(options, uri, payload, headers): + return {'ret': True} + + def find_systems_resource(options): +- uri = options["--redfish-uri"] +- response = send_get_request(options, uri) ++ response = send_get_request(options, options["--redfish-uri"]) + if response['ret'] is False: + return {'ret': False} + data = response['data'] +@@ -80,8 +77,7 @@ def find_systems_resource(options): + # Systems resource not found" + return {'ret': False} + else: +- uri = data["Systems"]["@odata.id"] +- response = send_get_request(options, uri) ++ response = send_get_request(options, data["Systems"]["@odata.id"]) + if response['ret'] is False: + return {'ret': False} + data = response['data'] diff --git a/SOURCES/bz1666848-2-fence_redfish-fail-invalid-cert.patch b/SOURCES/bz1666848-2-fence_redfish-fail-invalid-cert.patch new file mode 100644 index 0000000..a834644 --- /dev/null +++ b/SOURCES/bz1666848-2-fence_redfish-fail-invalid-cert.patch @@ -0,0 +1,60 @@ +From 7aa3c50d1d02dd26bdeac99c49ada72f842d88e8 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen +Date: Thu, 17 Jan 2019 16:52:52 +0100 +Subject: [PATCH] fence_redfish: fail when using invalid cert without + --ssl-insecure + +--- + agents/redfish/fence_redfish.py | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +index 67ef67ab..5b719d4b 100644 +--- a/agents/redfish/fence_redfish.py ++++ b/agents/redfish/fence_redfish.py +@@ -6,6 +6,7 @@ + + import sys + import re ++import logging + import json + import requests + import atexit +@@ -20,6 +21,9 @@ def get_power_status(conn, options): + if response['ret'] is False: + fail_usage("Couldn't get power information") + data = response['data'] ++ ++ logging.debug("PowerState is: " + data[u'PowerState']) ++ + if data[u'PowerState'].strip() == "Off": + return "off" + else: +@@ -50,21 +54,21 @@ def set_power_status(conn, options): + def send_get_request(options, uri): + full_uri = "https://" + options["--ip"] + uri + try: +- resp = requests.get(full_uri, verify=False, ++ resp = requests.get(full_uri, verify=not "--ssl-insecure" in options, + auth=(options["--username"], options["--password"])) + data = resp.json() +- except: +- return {'ret': False} ++ except Exception as e: ++ fail_usage("Failed: send_get_request: " + str(e)) + return {'ret': True, 'data': data} + + def send_post_request(options, uri, payload, headers): + full_uri = "https://" + options["--ip"] + uri + try: + requests.post(full_uri, data=json.dumps(payload), +- headers=headers, verify=False, ++ headers=headers, verify=not "--ssl-insecure" in options, + auth=(options["--username"], options["--password"])) +- except: +- return {'ret': False} ++ except Exception as e: ++ fail_usage("Failed: send_post_request: " + str(e)) + return {'ret': True} + + def find_systems_resource(options): diff --git a/SPECS/fence-agents.spec b/SPECS/fence-agents.spec index 03c389f..fd9a6fb 100644 --- a/SPECS/fence-agents.spec +++ b/SPECS/fence-agents.spec @@ -66,7 +66,7 @@ Name: fence-agents Summary: Fence Agents for Red Hat Cluster Version: 4.2.1 -Release: 11%{?alphatag:.%{alphatag}}%{?dist}.1 +Release: 11%{?alphatag:.%{alphatag}}%{?dist}.7 License: GPLv2+ and LGPLv2+ Group: System Environment/Base URL: https://github.com/ClusterLabs/fence-agents @@ -100,6 +100,11 @@ Patch14: bz1622229-1-fence_aliyun-list-instance-names.patch Patch15: bz1622229-2-fence_aliyun-correct-help-indentation.patch Patch16: bz1625164-fence_cisco_ucs-encode-POSTFIELDS.patch Patch17: bz1647522-fence_scsi-fix-incorrect-SCSI-key-node-ID-10-or-higher.patch +Patch18: bz1654172-1-fence_scsi-watchdog-retry-support.patch +Patch19: bz1654172-2-build-fix-check_used_options.patch +Patch20: bz1652115-fence_hpblade-fix-log_expect-syntax.patch +Patch21: bz1666848-1-fence_redfish.patch +Patch22: bz1666848-2-fence_redfish-fail-invalid-cert.patch # bundle patches Patch1000: bz1568753-4-fence_gce-bundled-libs.patch Patch1001: bz1568753-5-%{oauth2client}-docs-build-fix.patch @@ -112,7 +117,7 @@ Patch1007: python-%{httplib2}-0.9-cve-2013-2037.patch Patch1008: bz1568753-7-%{keyring}-fix-gnome-version-warning.patch %if 0%{?rhel} -%global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate hpblade ibmblade ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan mpath kdump rhevm rsa rsb sbd scsi vmware_rest vmware_soap wti +%global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate hpblade ibmblade ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan mpath kdump redfish rhevm rsa rsb sbd scsi vmware_rest vmware_soap wti %ifarch x86_64 %global testagents virsh heuristics_ping aliyun aws azure_arm gce %endif @@ -126,7 +131,7 @@ Patch1008: bz1568753-7-%{keyring}-fix-gnome-version-warning.patch %global testagents virsh heuristics_ping %endif -%global allfenceagents fence-agents-amt-ws fence-agents-apc fence-agents-apc-snmp fence-agents-bladecenter fence-agents-brocade fence-agents-cisco-mds fence-agents-cisco-ucs fence-agents-compute fence-agents-drac5 fence-agents-eaton-snmp fence-agents-emerson fence-agents-eps fence-agents-heuristics-ping fence-agents-hpblade fence-agents-ibmblade fence-agents-ifmib fence-agents-ilo2 fence-agents-ilo-moonshot fence-agents-ilo-mp fence-agents-ilo-ssh fence-agents-intelmodular fence-agents-ipdu fence-agents-ipmilan fence-agents-mpath fence-agents-kdump fence-agents-rhevm fence-agents-rsa fence-agents-rsb fence-agents-sbd fence-agents-scsi fence-agents-vmware-rest fence-agents-vmware-soap fence-agents-wti +%global allfenceagents fence-agents-amt-ws fence-agents-apc fence-agents-apc-snmp fence-agents-bladecenter fence-agents-brocade fence-agents-cisco-mds fence-agents-cisco-ucs fence-agents-compute fence-agents-drac5 fence-agents-eaton-snmp fence-agents-emerson fence-agents-eps fence-agents-heuristics-ping fence-agents-hpblade fence-agents-ibmblade fence-agents-ifmib fence-agents-ilo2 fence-agents-ilo-moonshot fence-agents-ilo-mp fence-agents-ilo-ssh fence-agents-intelmodular fence-agents-ipdu fence-agents-ipmilan fence-agents-mpath fence-agents-kdump fence-agents-redfish fence-agents-rhevm fence-agents-rsa fence-agents-rsb fence-agents-sbd fence-agents-scsi fence-agents-vmware-rest fence-agents-vmware-soap fence-agents-wti %endif ## Setup/build bits @@ -167,6 +172,11 @@ BuildRequires: python-six >= 1.6.1 %patch15 -p1 %patch16 -p1 %patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 %ifarch x86_64 # bundles @@ -954,6 +964,20 @@ The fence-agents-lpar package contains a fence agent for IBM LPAR devices that a %{_mandir}/man8/fence_lpar.8* %endif +%package redfish +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Redfish +Requires: fence-agents-common >= %{version}-%{release} +Requires: python-requests +Obsoletes: fence-agents +%description redfish +The fence-agents-redfish package contains a fence agent for Redfish +%files redfish +%defattr(-,root,root,-) +%{_sbindir}/fence_redfish +%{_mandir}/man8/fence_redfish.8* + %package rhevm License: GPLv2+ and LGPLv2+ Group: System Environment/Base @@ -1114,6 +1138,18 @@ The fence-agents-zvm package contains a fence agent for z/VM hypervisors %endif %changelog +* Thu Jan 17 2019 Oyvind Albrigtsen - 4.2.1-11.7 +- fence_redfish: new fence agent + Resolves: rhbz#1666848 + +* Thu Dec 6 2018 Oyvind Albrigtsen - 4.2.1-11.5 +- fence_scsi: add watchdog retry support + Resolves: rhbz#1654172 + +* Wed Nov 28 2018 Oyvind Albrigtsen - 4.2.1-11.4 +- fence_hpblade: fix log_expect syntax + Resolves: rhbz#1652115 + * Thu Nov 8 2018 Oyvind Albrigtsen - 4.2.1-11.1 - fence_scsi: fix incorrect SCSI-key when node ID is 10 or higher Resolves: rhbz#1647522