import fence-agents-4.2.1-27.el8
This commit is contained in:
commit
510d72e4ea
5
.fence-agents.metadata
Normal file
5
.fence-agents.metadata
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
0a56f6d9ed2014a363486d33b63eca094379be06 SOURCES/aliyun-python-sdk-core-2.13.1.tar.gz
|
||||||
|
c2a98b9a1562d223a76514f05028488ca000c395 SOURCES/aliyun-python-sdk-ecs-4.9.3.tar.gz
|
||||||
|
f14647a4d37a9a254c4e711b95a7654fc418e41e SOURCES/aliyun-python-sdk-vpc-3.0.2.tar.gz
|
||||||
|
e2561df8e7ff9113dab118a651371dd88dab0142 SOURCES/fence-agents-4.2.1.tar.gz
|
||||||
|
326a73f58a62ebee00c11a12cfdd838b196e0e8e SOURCES/pycryptodome-3.6.4.tar.gz
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
SOURCES/aliyun-python-sdk-core-2.13.1.tar.gz
|
||||||
|
SOURCES/aliyun-python-sdk-ecs-4.9.3.tar.gz
|
||||||
|
SOURCES/aliyun-python-sdk-vpc-3.0.2.tar.gz
|
||||||
|
SOURCES/fence-agents-4.2.1.tar.gz
|
||||||
|
SOURCES/pycryptodome-3.6.4.tar.gz
|
12
SOURCES/bz1650214-fence_azure_arm-bundled.patch
Normal file
12
SOURCES/bz1650214-fence_azure_arm-bundled.patch
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
diff -uNr a/agents/azure_arm/fence_azure_arm.py b/agents/azure_arm/fence_azure_arm.py
|
||||||
|
--- a/agents/azure_arm/fence_azure_arm.py 2018-06-28 14:24:54.000000000 +0200
|
||||||
|
+++ b/agents/azure_arm/fence_azure_arm.py 2019-01-15 10:24:16.030092206 +0100
|
||||||
|
@@ -7,6 +7,8 @@
|
||||||
|
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
from fencing import *
|
||||||
|
from fencing import fail_usage, run_command, run_delay
|
||||||
|
+
|
||||||
|
+sys.path.insert(0, '/usr/lib/fence-agents/bundled/azure')
|
||||||
|
import azure_fence
|
||||||
|
|
||||||
|
def get_nodes_list(clients, options):
|
50
SOURCES/bz1654616-fence_hpblade-fix-log_expect_syntax.patch
Normal file
50
SOURCES/bz1654616-fence_hpblade-fix-log_expect_syntax.patch
Normal file
@ -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():
|
@ -0,0 +1,24 @@
|
|||||||
|
From f77297b654586bf539e78957f26cae1d22c6f081 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Fri, 2 Nov 2018 09:24:56 +0100
|
||||||
|
Subject: [PATCH] fence_scsi: fix incorrect SCSI key when node ID is 10 or
|
||||||
|
higher
|
||||||
|
|
||||||
|
The last four digits of the SCSI key will be zero padded digit between 0000-0009.
|
||||||
|
---
|
||||||
|
agents/scsi/fence_scsi.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py
|
||||||
|
index 2180d0c9..79ada4fa 100644
|
||||||
|
--- a/agents/scsi/fence_scsi.py
|
||||||
|
+++ b/agents/scsi/fence_scsi.py
|
||||||
|
@@ -191,7 +191,7 @@ def get_cluster_id(options):
|
||||||
|
def get_node_id(options):
|
||||||
|
cmd = options["--corosync-cmap-path"] + " nodelist"
|
||||||
|
|
||||||
|
- match = re.search(r".(\d).ring._addr \(str\) = " + options["--plug"] + "\n", run_cmd(options, cmd)["out"])
|
||||||
|
+ match = re.search(r".(\d+).ring._addr \(str\) = " + options["--plug"] + "\n", run_cmd(options, cmd)["out"])
|
||||||
|
return match.group(1) if match else fail_usage("Failed: unable to parse output of corosync-cmapctl or node does not exist")
|
||||||
|
|
||||||
|
|
41
SOURCES/bz1654973-fence_vmware_soap-cleanup-sigterm.patch
Normal file
41
SOURCES/bz1654973-fence_vmware_soap-cleanup-sigterm.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From 116fb7d1253ac31a8f174187dfe9f4a0c6546ade Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Fri, 7 Sep 2018 15:56:56 +0200
|
||||||
|
Subject: [PATCH] fence_vmware_soap: cleanup when receiving SIGTERM
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/vmware_soap/fence_vmware_soap.py | 7 ++++++-
|
||||||
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py
|
||||||
|
index b90edc9b..dd1a4ed6 100644
|
||||||
|
--- a/agents/vmware_soap/fence_vmware_soap.py
|
||||||
|
+++ b/agents/vmware_soap/fence_vmware_soap.py
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
import sys
|
||||||
|
import shutil, tempfile, suds
|
||||||
|
import logging, requests
|
||||||
|
-import atexit
|
||||||
|
+import atexit, signal
|
||||||
|
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
|
||||||
|
from suds.client import Client
|
||||||
|
@@ -211,6 +211,9 @@ def logout():
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
+def signal_handler(signum, frame):
|
||||||
|
+ raise Exception("Signal \"%d\" received which has triggered an exit of the process." % signum)
|
||||||
|
+
|
||||||
|
def main():
|
||||||
|
global options_global
|
||||||
|
global conn_global
|
||||||
|
@@ -219,6 +222,8 @@ def main():
|
||||||
|
atexit.register(atexit_handler)
|
||||||
|
atexit.register(logout)
|
||||||
|
|
||||||
|
+ signal.signal(signal.SIGTERM, signal_handler)
|
||||||
|
+
|
||||||
|
options_global = check_input(device_opt, process_input(device_opt))
|
||||||
|
|
||||||
|
##
|
146
SOURCES/bz1654976-1-fence_scsi-watchdog-retry-support.patch
Normal file
146
SOURCES/bz1654976-1-fence_scsi-watchdog-retry-support.patch
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
From 11a63822fbdc0a9ebe1b668b26a59f1cc9649f6c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
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 @@
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<resource-agent name="fence_scsi" shortdesc="Fence agent for SCSI persistent reservation" >
|
||||||
|
<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 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.</longdesc>
|
||||||
|
+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.</longdesc>
|
||||||
|
<vendor-url></vendor-url>
|
||||||
|
<parameters>
|
||||||
|
<parameter name="action" unique="0" required="1">
|
23
SOURCES/bz1654976-2-build-fix-check_used_options.patch
Normal file
23
SOURCES/bz1654976-2-build-fix-check_used_options.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
From 267afc5caa0580cc483220e671cda094413a4e16 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
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
|
||||||
|
|
812
SOURCES/bz1666914-1-fence_redfish.patch
Normal file
812
SOURCES/bz1666914-1-fence_redfish.patch
Normal file
@ -0,0 +1,812 @@
|
|||||||
|
From 64e3f3ef4d0abefd2836fe015c87173310b1e130 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jose Delarosa <jose.delarosa@dell.com>
|
||||||
|
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 @@
|
||||||
|
+<?xml version="1.0" ?>
|
||||||
|
+<resource-agent name="fence_redfish" shortdesc="I/O Fencing agent for Redfish" >
|
||||||
|
+<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.</longdesc>
|
||||||
|
+<vendor-url>http://www.dmtf.org</vendor-url>
|
||||||
|
+<parameters>
|
||||||
|
+ <parameter name="ipport" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-u, --ipport=[port]" />
|
||||||
|
+ <content type="integer" default="443" />
|
||||||
|
+ <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="ssl_secure" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--ssl-secure" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="systems-uri" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="--systems-uri=[uri]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="action" unique="0" required="1">
|
||||||
|
+ <getopt mixed="-o, --action=[action]" />
|
||||||
|
+ <content type="string" default="reboot" />
|
||||||
|
+ <shortdesc lang="en">Fencing Action</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="inet6_only" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-6, --inet6-only" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Forces agent to use IPv6 addresses only</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="ipaddr" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-a, --ip=[ip]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">IP Address or Hostname</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="port" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-n, --plug=[ip]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="passwd_script" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-S, --password-script=[script]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Script to retrieve password</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="inet4_only" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-4, --inet4-only" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Forces agent to use IPv4 addresses only</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="passwd" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-p, --password=[password]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Login password or passphrase</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="ssl" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-z, --ssl" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">SSL connection</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="redfish-uri" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="--redfish-uri=[uri]" />
|
||||||
|
+ <content type="string" default="/redfish/v1" />
|
||||||
|
+ <shortdesc lang="en">Base or starting Redfish URI</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="ssl_insecure" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--ssl-insecure" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="login" unique="0" required="1" deprecated="1">
|
||||||
|
+ <getopt mixed="-l, --username=[name]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Login Name</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="plug" unique="0" required="0" obsoletes="port">
|
||||||
|
+ <getopt mixed="-n, --plug=[ip]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="username" unique="0" required="1" obsoletes="login">
|
||||||
|
+ <getopt mixed="-l, --username=[name]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Login Name</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="redfish_uri" unique="0" required="0" obsoletes="redfish-uri">
|
||||||
|
+ <getopt mixed="--redfish-uri=[uri]" />
|
||||||
|
+ <content type="string" default="/redfish/v1" />
|
||||||
|
+ <shortdesc lang="en">Base or starting Redfish URI</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="ip" unique="0" required="0" obsoletes="ipaddr">
|
||||||
|
+ <getopt mixed="-a, --ip=[ip]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">IP Address or Hostname</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="systems_uri" unique="0" required="0" obsoletes="systems-uri">
|
||||||
|
+ <getopt mixed="--systems-uri=[uri]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="password" unique="0" required="0" obsoletes="passwd">
|
||||||
|
+ <getopt mixed="-p, --password=[password]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Login password or passphrase</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="password_script" unique="0" required="0" obsoletes="passwd_script">
|
||||||
|
+ <getopt mixed="-S, --password-script=[script]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Script to retrieve password</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="verbose" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-v, --verbose" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Verbose mode</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="debug" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-D, --debug-file=[debugfile]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Write debug information to given file</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="debug_file" unique="0" required="0" obsoletes="debug">
|
||||||
|
+ <getopt mixed="-D, --debug-file=[debugfile]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Write debug information to given file</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="version" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-V, --version" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Display version information and exit</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="help" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-h, --help" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Display help and exit</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="power_wait" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--power-wait=[seconds]" />
|
||||||
|
+ <content type="second" default="0" />
|
||||||
|
+ <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="login_timeout" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--login-timeout=[seconds]" />
|
||||||
|
+ <content type="second" default="5" />
|
||||||
|
+ <shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="power_timeout" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--power-timeout=[seconds]" />
|
||||||
|
+ <content type="second" default="20" />
|
||||||
|
+ <shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="delay" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--delay=[seconds]" />
|
||||||
|
+ <content type="second" default="0" />
|
||||||
|
+ <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="shell_timeout" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--shell-timeout=[seconds]" />
|
||||||
|
+ <content type="second" default="3" />
|
||||||
|
+ <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="port_as_ip" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--port-as-ip" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Make "port/plug" to be an alias to IP address</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="retry_on" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--retry-on=[attempts]" />
|
||||||
|
+ <content type="integer" default="1" />
|
||||||
|
+ <shortdesc lang="en">Count of attempts to retry power on</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+</parameters>
|
||||||
|
+<actions>
|
||||||
|
+ <action name="on" automatic="0"/>
|
||||||
|
+ <action name="off" />
|
||||||
|
+ <action name="reboot" />
|
||||||
|
+ <action name="status" />
|
||||||
|
+ <action name="monitor" />
|
||||||
|
+ <action name="metadata" />
|
||||||
|
+ <action name="validate-all" />
|
||||||
|
+</actions>
|
||||||
|
+</resource-agent>
|
||||||
|
|
||||||
|
From 6921a34d64d098a7b1f32205e0be434438c36898 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jose Delarosa <jose.delarosa@dell.com>
|
||||||
|
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 @@
|
||||||
|
<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.</longdesc>
|
||||||
|
<vendor-url>http://www.dmtf.org</vendor-url>
|
||||||
|
<parameters>
|
||||||
|
- <parameter name="ipport" unique="0" required="0">
|
||||||
|
- <getopt mixed="-u, --ipport=[port]" />
|
||||||
|
- <content type="integer" default="443" />
|
||||||
|
- <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
|
||||||
|
- </parameter>
|
||||||
|
- <parameter name="ssl_secure" unique="0" required="0">
|
||||||
|
- <getopt mixed="--ssl-secure" />
|
||||||
|
- <content type="boolean" />
|
||||||
|
- <shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc>
|
||||||
|
- </parameter>
|
||||||
|
- <parameter name="systems-uri" unique="0" required="0" deprecated="1">
|
||||||
|
- <getopt mixed="--systems-uri=[uri]" />
|
||||||
|
- <content type="string" />
|
||||||
|
- <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc>
|
||||||
|
- </parameter>
|
||||||
|
<parameter name="action" unique="0" required="1">
|
||||||
|
<getopt mixed="-o, --action=[action]" />
|
||||||
|
<content type="string" default="reboot" />
|
||||||
|
- <shortdesc lang="en">Fencing Action</shortdesc>
|
||||||
|
+ <shortdesc lang="en">Fencing action</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="inet4_only" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-4, --inet4-only" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Forces agent to use IPv4 addresses only</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="inet6_only" unique="0" required="0">
|
||||||
|
<getopt mixed="-6, --inet6-only" />
|
||||||
|
<content type="boolean" />
|
||||||
|
<shortdesc lang="en">Forces agent to use IPv6 addresses only</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="ipaddr" unique="0" required="0" deprecated="1">
|
||||||
|
+ <parameter name="ip" unique="0" required="0" obsoletes="ipaddr">
|
||||||
|
<getopt mixed="-a, --ip=[ip]" />
|
||||||
|
<content type="string" />
|
||||||
|
- <shortdesc lang="en">IP Address or Hostname</shortdesc>
|
||||||
|
+ <shortdesc lang="en">IP address or hostname of fencing device</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="port" unique="0" required="0" deprecated="1">
|
||||||
|
- <getopt mixed="-n, --plug=[ip]" />
|
||||||
|
+ <parameter name="ipaddr" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-a, --ip=[ip]" />
|
||||||
|
<content type="string" />
|
||||||
|
- <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc>
|
||||||
|
+ <shortdesc lang="en">IP address or hostname of fencing device</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="passwd_script" unique="0" required="0" deprecated="1">
|
||||||
|
- <getopt mixed="-S, --password-script=[script]" />
|
||||||
|
- <content type="string" />
|
||||||
|
- <shortdesc lang="en">Script to retrieve password</shortdesc>
|
||||||
|
+ <parameter name="ipport" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-u, --ipport=[port]" />
|
||||||
|
+ <content type="integer" default="443" />
|
||||||
|
+ <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="inet4_only" unique="0" required="0">
|
||||||
|
- <getopt mixed="-4, --inet4-only" />
|
||||||
|
- <content type="boolean" />
|
||||||
|
- <shortdesc lang="en">Forces agent to use IPv4 addresses only</shortdesc>
|
||||||
|
+ <parameter name="login" unique="0" required="1" deprecated="1">
|
||||||
|
+ <getopt mixed="-l, --username=[name]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Login name</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="passwd" unique="0" required="0" deprecated="1">
|
||||||
|
<getopt mixed="-p, --password=[password]" />
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">Login password or passphrase</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="ssl" unique="0" required="0">
|
||||||
|
- <getopt mixed="-z, --ssl" />
|
||||||
|
- <content type="boolean" />
|
||||||
|
- <shortdesc lang="en">SSL connection</shortdesc>
|
||||||
|
- </parameter>
|
||||||
|
- <parameter name="redfish-uri" unique="0" required="0" deprecated="1">
|
||||||
|
- <getopt mixed="--redfish-uri=[uri]" />
|
||||||
|
- <content type="string" default="/redfish/v1" />
|
||||||
|
- <shortdesc lang="en">Base or starting Redfish URI</shortdesc>
|
||||||
|
+ <parameter name="passwd_script" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-S, --password-script=[script]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Script to run to retrieve password</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="ssl_insecure" unique="0" required="0">
|
||||||
|
- <getopt mixed="--ssl-insecure" />
|
||||||
|
- <content type="boolean" />
|
||||||
|
- <shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc>
|
||||||
|
+ <parameter name="password" unique="0" required="0" obsoletes="passwd">
|
||||||
|
+ <getopt mixed="-p, --password=[password]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Login password or passphrase</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="login" unique="0" required="1" deprecated="1">
|
||||||
|
- <getopt mixed="-l, --username=[name]" />
|
||||||
|
+ <parameter name="password_script" unique="0" required="0" obsoletes="passwd_script">
|
||||||
|
+ <getopt mixed="-S, --password-script=[script]" />
|
||||||
|
<content type="string" />
|
||||||
|
- <shortdesc lang="en">Login Name</shortdesc>
|
||||||
|
+ <shortdesc lang="en">Script to run to retrieve password</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="plug" unique="0" required="0" obsoletes="port">
|
||||||
|
<getopt mixed="-n, --plug=[ip]" />
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="username" unique="0" required="1" obsoletes="login">
|
||||||
|
- <getopt mixed="-l, --username=[name]" />
|
||||||
|
+ <parameter name="port" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-n, --plug=[ip]" />
|
||||||
|
<content type="string" />
|
||||||
|
- <shortdesc lang="en">Login Name</shortdesc>
|
||||||
|
+ <shortdesc lang="en">IP address or hostname of fencing device (together with --port-as-ip)</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="redfish-uri" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="--redfish-uri=[uri]" />
|
||||||
|
+ <content type="string" default="/redfish/v1" />
|
||||||
|
+ <shortdesc lang="en">Base or starting Redfish URI</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="redfish_uri" unique="0" required="0" obsoletes="redfish-uri">
|
||||||
|
<getopt mixed="--redfish-uri=[uri]" />
|
||||||
|
<content type="string" default="/redfish/v1" />
|
||||||
|
<shortdesc lang="en">Base or starting Redfish URI</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="ip" unique="0" required="0" obsoletes="ipaddr">
|
||||||
|
- <getopt mixed="-a, --ip=[ip]" />
|
||||||
|
+ <parameter name="ssl" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-z, --ssl" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="ssl_insecure" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--ssl-insecure" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Use SSL connection without verifying certificate</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="ssl_secure" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--ssl-secure" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="systems-uri" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="--systems-uri=[uri]" />
|
||||||
|
<content type="string" />
|
||||||
|
- <shortdesc lang="en">IP Address or Hostname</shortdesc>
|
||||||
|
+ <shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="systems_uri" unique="0" required="0" obsoletes="systems-uri">
|
||||||
|
<getopt mixed="--systems-uri=[uri]" />
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">Redfish Systems resource URI, i.e. /redfish/v1/Systems/System.Embedded.1</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="password" unique="0" required="0" obsoletes="passwd">
|
||||||
|
- <getopt mixed="-p, --password=[password]" />
|
||||||
|
+ <parameter name="username" unique="0" required="1" obsoletes="login">
|
||||||
|
+ <getopt mixed="-l, --username=[name]" />
|
||||||
|
<content type="string" />
|
||||||
|
- <shortdesc lang="en">Login password or passphrase</shortdesc>
|
||||||
|
+ <shortdesc lang="en">Login name</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="password_script" unique="0" required="0" obsoletes="passwd_script">
|
||||||
|
- <getopt mixed="-S, --password-script=[script]" />
|
||||||
|
- <content type="string" />
|
||||||
|
- <shortdesc lang="en">Script to retrieve password</shortdesc>
|
||||||
|
+ <parameter name="quiet" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-q, --quiet" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Disable logging to stderr. Does not affect --verbose or --debug-file or logging to syslog.</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="verbose" unique="0" required="0">
|
||||||
|
<getopt mixed="-v, --verbose" />
|
||||||
|
@@ -133,41 +138,45 @@
|
||||||
|
<content type="boolean" />
|
||||||
|
<shortdesc lang="en">Display help and exit</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="power_wait" unique="0" required="0">
|
||||||
|
- <getopt mixed="--power-wait=[seconds]" />
|
||||||
|
+ <parameter name="delay" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--delay=[seconds]" />
|
||||||
|
<content type="second" default="0" />
|
||||||
|
- <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc>
|
||||||
|
+ <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="login_timeout" unique="0" required="0">
|
||||||
|
<getopt mixed="--login-timeout=[seconds]" />
|
||||||
|
<content type="second" default="5" />
|
||||||
|
<shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
+ <parameter name="port_as_ip" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--port-as-ip" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Make "port/plug" to be an alias to IP address</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
<parameter name="power_timeout" unique="0" required="0">
|
||||||
|
<getopt mixed="--power-timeout=[seconds]" />
|
||||||
|
<content type="second" default="20" />
|
||||||
|
<shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="delay" unique="0" required="0">
|
||||||
|
- <getopt mixed="--delay=[seconds]" />
|
||||||
|
+ <parameter name="power_wait" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--power-wait=[seconds]" />
|
||||||
|
<content type="second" default="0" />
|
||||||
|
- <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>
|
||||||
|
+ <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="shell_timeout" unique="0" required="0">
|
||||||
|
<getopt mixed="--shell-timeout=[seconds]" />
|
||||||
|
<content type="second" default="3" />
|
||||||
|
<shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="port_as_ip" unique="0" required="0">
|
||||||
|
- <getopt mixed="--port-as-ip" />
|
||||||
|
- <content type="boolean" />
|
||||||
|
- <shortdesc lang="en">Make "port/plug" to be an alias to IP address</shortdesc>
|
||||||
|
- </parameter>
|
||||||
|
<parameter name="retry_on" unique="0" required="0">
|
||||||
|
<getopt mixed="--retry-on=[attempts]" />
|
||||||
|
<content type="integer" default="1" />
|
||||||
|
<shortdesc lang="en">Count of attempts to retry power on</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
+ <parameter name="gnutlscli_path" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--gnutlscli-path=[path]" />
|
||||||
|
+ <shortdesc lang="en">Path to gnutls-cli binary</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
</parameters>
|
||||||
|
<actions>
|
||||||
|
<action name="on" automatic="0"/>
|
||||||
|
@@ -176,6 +185,7 @@
|
||||||
|
<action name="status" />
|
||||||
|
<action name="monitor" />
|
||||||
|
<action name="metadata" />
|
||||||
|
+ <action name="manpage" />
|
||||||
|
<action name="validate-all" />
|
||||||
|
</actions>
|
||||||
|
</resource-agent>
|
||||||
|
|
||||||
|
From 755627fadd711848ea256d72f5e75f36f83b4d31 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jose Delarosa <jose.delarosa@dell.com>
|
||||||
|
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 <jose.delarosa@dell.com>
|
||||||
|
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 <jose.delarosa@dell.com>
|
||||||
|
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 <jose.delarosa@dell.com>
|
||||||
|
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 @@
|
||||||
|
</parameter>
|
||||||
|
<parameter name="ssl" unique="0" required="0">
|
||||||
|
<getopt mixed="-z, --ssl" />
|
||||||
|
- <content type="boolean" />
|
||||||
|
+ <content type="boolean" default="1" />
|
||||||
|
<shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="ssl_insecure" unique="0" required="0">
|
||||||
|
|
||||||
|
From 5c25a85b22a17d6bbc3dcb47c99b76e3a99a5857 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jose Delarosa <jose.delarosa@dell.com>
|
||||||
|
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 <jose.delarosa@dell.com>
|
||||||
|
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']
|
60
SOURCES/bz1666914-2-fence_redfish-fail-invalid-cert.patch
Normal file
60
SOURCES/bz1666914-2-fence_redfish-fail-invalid-cert.patch
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
From 7aa3c50d1d02dd26bdeac99c49ada72f842d88e8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
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):
|
43
SOURCES/bz1677327-1-fence_redfish-use-ipport-parameter.patch
Normal file
43
SOURCES/bz1677327-1-fence_redfish-use-ipport-parameter.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 9ebd2e2e36ae0de5c9164f4ac3fd29bdac0cab61 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Thu, 14 Feb 2019 10:03:33 +0100
|
||||||
|
Subject: [PATCH] fence_redfish: use "ipport" parameter and improve logging
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/redfish/fence_redfish.py | 9 ++++++---
|
||||||
|
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py
|
||||||
|
index 5b719d4b..28840058 100644
|
||||||
|
--- a/agents/redfish/fence_redfish.py
|
||||||
|
+++ b/agents/redfish/fence_redfish.py
|
||||||
|
@@ -22,7 +22,10 @@ def get_power_status(conn, options):
|
||||||
|
fail_usage("Couldn't get power information")
|
||||||
|
data = response['data']
|
||||||
|
|
||||||
|
- logging.debug("PowerState is: " + data[u'PowerState'])
|
||||||
|
+ try:
|
||||||
|
+ logging.debug("PowerState is: " + data[u'PowerState'])
|
||||||
|
+ except Exception:
|
||||||
|
+ fail_usage("Unable to get PowerState: " + "https://" + options["--ip"] + ":" + str(options["--ipport"]) + options["--systems-uri"])
|
||||||
|
|
||||||
|
if data[u'PowerState'].strip() == "Off":
|
||||||
|
return "off"
|
||||||
|
@@ -52,7 +55,7 @@ def set_power_status(conn, options):
|
||||||
|
return
|
||||||
|
|
||||||
|
def send_get_request(options, uri):
|
||||||
|
- full_uri = "https://" + options["--ip"] + uri
|
||||||
|
+ full_uri = "https://" + options["--ip"] + ":" + str(options["--ipport"]) + uri
|
||||||
|
try:
|
||||||
|
resp = requests.get(full_uri, verify=not "--ssl-insecure" in options,
|
||||||
|
auth=(options["--username"], options["--password"]))
|
||||||
|
@@ -62,7 +65,7 @@ def send_get_request(options, uri):
|
||||||
|
return {'ret': True, 'data': data}
|
||||||
|
|
||||||
|
def send_post_request(options, uri, payload, headers):
|
||||||
|
- full_uri = "https://" + options["--ip"] + uri
|
||||||
|
+ full_uri = "https://" + options["--ip"] + ":" + str(options["--ipport"]) + uri
|
||||||
|
try:
|
||||||
|
requests.post(full_uri, data=json.dumps(payload),
|
||||||
|
headers=headers, verify=not "--ssl-insecure" in options,
|
@ -0,0 +1,24 @@
|
|||||||
|
From 21898e45ca2624546de99086a27a14dd1ff86a2b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Thu, 21 Feb 2019 09:08:03 +0100
|
||||||
|
Subject: [PATCH] fence_redfish: backwards compatibility for <ip>:<port>
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/redfish/fence_redfish.py | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py
|
||||||
|
index 28840058..f1424232 100644
|
||||||
|
--- a/agents/redfish/fence_redfish.py
|
||||||
|
+++ b/agents/redfish/fence_redfish.py
|
||||||
|
@@ -140,6 +140,10 @@ def main():
|
||||||
|
if "--ssl-insecure" in opt:
|
||||||
|
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||||
|
|
||||||
|
+ # backwards compatibility for <ip>:<port>
|
||||||
|
+ if options["--ip"].count(":") == 1:
|
||||||
|
+ (options["--ip"], options["--ipport"]) = options["--ip"].split(":")
|
||||||
|
+
|
||||||
|
if "--systems-uri" not in opt:
|
||||||
|
# Systems URI not provided, find it
|
||||||
|
sysresult = find_systems_resource(options)
|
22
SOURCES/bz1696584-fence_gce-fix-python3-encoding-issue.patch
Normal file
22
SOURCES/bz1696584-fence_gce-fix-python3-encoding-issue.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From 64ac6207152508392690b7c1dfcac3fe0a76adfd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Fri, 5 Apr 2019 09:48:52 +0200
|
||||||
|
Subject: [PATCH] fence_gce: fix Python 3 encoding issue
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index 93cd11801..b171710d9 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -146,7 +146,7 @@ def get_metadata(metadata_key, params=None, timeout=None):
|
||||||
|
url = '%s?%s' % (metadata_url, params)
|
||||||
|
request = urlrequest.Request(url, headers=METADATA_HEADERS)
|
||||||
|
request_opener = urlrequest.build_opener(urlrequest.ProxyHandler({}))
|
||||||
|
- return request_opener.open(request, timeout=timeout * 1.1).read()
|
||||||
|
+ return request_opener.open(request, timeout=timeout * 1.1).read().decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def define_new_opts():
|
48
SOURCES/bz1700546-fence_azure_arm-skip_shutdown.patch
Normal file
48
SOURCES/bz1700546-fence_azure_arm-skip_shutdown.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
From 1b3e548fcc0bd427dade178fa260567047ff3a0e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 6 May 2019 13:24:18 +0200
|
||||||
|
Subject: [PATCH] fence_azure_arm: use skip_shutdown feature when available
|
||||||
|
|
||||||
|
The "skip_shutdown" parameter is ignored in older Azure SDK, so there's
|
||||||
|
no need for a fallback option.
|
||||||
|
---
|
||||||
|
agents/azure_arm/fence_azure_arm.py | 6 +++---
|
||||||
|
tests/data/metadata/fence_azure_arm.xml | 2 +-
|
||||||
|
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/azure_arm/fence_azure_arm.py b/agents/azure_arm/fence_azure_arm.py
|
||||||
|
index 58b9eeb13..be0d40345 100755
|
||||||
|
--- a/agents/azure_arm/fence_azure_arm.py
|
||||||
|
+++ b/agents/azure_arm/fence_azure_arm.py
|
||||||
|
@@ -114,8 +114,8 @@ def set_power_status(clients, options):
|
||||||
|
azure_fence.set_network_state(compute_client, network_client, rgName, vmName, "unblock")
|
||||||
|
|
||||||
|
if (options["--action"]=="off"):
|
||||||
|
- logging.info("Deallocating " + vmName + " in resource group " + rgName)
|
||||||
|
- compute_client.virtual_machines.deallocate(rgName, vmName)
|
||||||
|
+ logging.info("Poweroff " + vmName + " in resource group " + rgName)
|
||||||
|
+ compute_client.virtual_machines.power_off(rgName, vmName, skip_shutdown=True)
|
||||||
|
elif (options["--action"]=="on"):
|
||||||
|
logging.info("Starting " + vmName + " in resource group " + rgName)
|
||||||
|
compute_client.virtual_machines.start(rgName, vmName)
|
||||||
|
@@ -199,7 +199,7 @@ def main():
|
||||||
|
|
||||||
|
docs = {}
|
||||||
|
docs["shortdesc"] = "Fence agent for Azure Resource Manager"
|
||||||
|
- docs["longdesc"] = "Used to deallocate virtual machines and to report power state of virtual machines running in Azure. It uses Azure SDK for Python to connect to Azure.\
|
||||||
|
+ docs["longdesc"] = "fence_azure_arm is an I/O Fencing agent for Azure Resource Manager. It uses Azure SDK for Python to connect to Azure.\
|
||||||
|
\n.P\n\
|
||||||
|
For instructions to setup credentials see: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal\
|
||||||
|
\n.P\n\
|
||||||
|
diff --git a/tests/data/metadata/fence_azure_arm.xml b/tests/data/metadata/fence_azure_arm.xml
|
||||||
|
index 1c0b6cc6b..97ecfdba4 100644
|
||||||
|
--- a/tests/data/metadata/fence_azure_arm.xml
|
||||||
|
+++ b/tests/data/metadata/fence_azure_arm.xml
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<resource-agent name="fence_azure_arm" shortdesc="Fence agent for Azure Resource Manager" >
|
||||||
|
-<longdesc>Used to deallocate virtual machines and to report power state of virtual machines running in Azure. It uses Azure SDK for Python to connect to Azure.
|
||||||
|
+<longdesc>fence_azure_arm is an I/O Fencing agent for Azure Resource Manager. It uses Azure SDK for Python to connect to Azure.
|
||||||
|
|
||||||
|
For instructions to setup credentials see: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal
|
||||||
|
|
@ -0,0 +1,65 @@
|
|||||||
|
From 75a74debba2205547d8eefae221221c2c71d99ce Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jose Delarosa <jose.delarosa@dell.com>
|
||||||
|
Date: Mon, 15 Apr 2019 12:46:42 -0500
|
||||||
|
Subject: [PATCH] fence_redfish: add headers to HTTP methods
|
||||||
|
|
||||||
|
* Needed for full compliance with Redfish spec.
|
||||||
|
* May cause errors in some devices if not sent.
|
||||||
|
---
|
||||||
|
agents/redfish/fence_redfish.py | 13 +++++++++----
|
||||||
|
1 file changed, 9 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py
|
||||||
|
index f1424232..390a4827 100644
|
||||||
|
--- a/agents/redfish/fence_redfish.py
|
||||||
|
+++ b/agents/redfish/fence_redfish.py
|
||||||
|
@@ -16,6 +16,11 @@
|
||||||
|
from fencing import *
|
||||||
|
from fencing import fail_usage, run_delay
|
||||||
|
|
||||||
|
+GET_HEADERS = {'accept': 'application/json', 'OData-Version': '4.0'}
|
||||||
|
+POST_HEADERS = {'content-type': 'application/json', 'accept': 'application/json',
|
||||||
|
+ 'OData-Version': '4.0'}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def get_power_status(conn, options):
|
||||||
|
response = send_get_request(options, options["--systems-uri"])
|
||||||
|
if response['ret'] is False:
|
||||||
|
@@ -40,7 +45,6 @@ def set_power_status(conn, options):
|
||||||
|
}[options["--action"]]
|
||||||
|
|
||||||
|
payload = {'ResetType': action}
|
||||||
|
- headers = {'content-type': 'application/json'}
|
||||||
|
|
||||||
|
# Search for 'Actions' key and extract URI from it
|
||||||
|
response = send_get_request(options, options["--systems-uri"])
|
||||||
|
@@ -49,7 +53,7 @@ def set_power_status(conn, options):
|
||||||
|
data = response['data']
|
||||||
|
action_uri = data["Actions"]["#ComputerSystem.Reset"]["target"]
|
||||||
|
|
||||||
|
- response = send_post_request(options, action_uri, payload, headers)
|
||||||
|
+ response = send_post_request(options, action_uri, payload)
|
||||||
|
if response['ret'] is False:
|
||||||
|
fail_usage("Error sending power command")
|
||||||
|
return
|
||||||
|
@@ -58,17 +62,18 @@ def send_get_request(options, uri):
|
||||||
|
full_uri = "https://" + options["--ip"] + ":" + str(options["--ipport"]) + uri
|
||||||
|
try:
|
||||||
|
resp = requests.get(full_uri, verify=not "--ssl-insecure" in options,
|
||||||
|
+ headers=GET_HEADERS,
|
||||||
|
auth=(options["--username"], options["--password"]))
|
||||||
|
data = resp.json()
|
||||||
|
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):
|
||||||
|
+def send_post_request(options, uri, payload):
|
||||||
|
full_uri = "https://" + options["--ip"] + ":" + str(options["--ipport"]) + uri
|
||||||
|
try:
|
||||||
|
requests.post(full_uri, data=json.dumps(payload),
|
||||||
|
- headers=headers, verify=not "--ssl-insecure" in options,
|
||||||
|
+ headers=POST_HEADERS, verify=not "--ssl-insecure" in options,
|
||||||
|
auth=(options["--username"], options["--password"]))
|
||||||
|
except Exception as e:
|
||||||
|
fail_usage("Failed: send_post_request: " + str(e))
|
164
SOURCES/bz1709780-fence_rhevm-RHEV-v4-API-support.patch
Normal file
164
SOURCES/bz1709780-fence_rhevm-RHEV-v4-API-support.patch
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
From a4e8b77ac51a0e4a6de489823ee1be47cbc7eb18 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Thu, 9 May 2019 12:09:48 +0200
|
||||||
|
Subject: [PATCH] fence_rhevm: add RHEV v4 API support and auto-detection
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/rhevm/fence_rhevm.py | 44 +++++++++++++++++++++++------
|
||||||
|
tests/data/metadata/fence_rhevm.xml | 7 ++++-
|
||||||
|
2 files changed, 41 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/rhevm/fence_rhevm.py b/agents/rhevm/fence_rhevm.py
|
||||||
|
index a1cdaf605..6012c4239 100644
|
||||||
|
--- a/agents/rhevm/fence_rhevm.py
|
||||||
|
+++ b/agents/rhevm/fence_rhevm.py
|
||||||
|
@@ -9,7 +9,8 @@
|
||||||
|
from fencing import fail, EC_FETCH_VM_UUID, run_delay
|
||||||
|
|
||||||
|
RE_GET_ID = re.compile("<vm( .*)? id=\"(.*?)\"", re.IGNORECASE)
|
||||||
|
-RE_STATUS = re.compile("<state>(.*?)</state>", re.IGNORECASE)
|
||||||
|
+RE_STATUS = re.compile("<status>(.*?)</status>", re.IGNORECASE)
|
||||||
|
+RE_STATE = re.compile("<state>(.*?)</state>", re.IGNORECASE)
|
||||||
|
RE_GET_NAME = re.compile("<name>(.*?)</name>", re.IGNORECASE)
|
||||||
|
|
||||||
|
def get_power_status(conn, options):
|
||||||
|
@@ -25,7 +26,10 @@ def get_power_status(conn, options):
|
||||||
|
|
||||||
|
options["id"] = result.group(2)
|
||||||
|
|
||||||
|
- result = RE_STATUS.search(res)
|
||||||
|
+ if tuple(map(int, options["--api-version"].split(".")))[0] > 3:
|
||||||
|
+ result = RE_STATUS.search(res)
|
||||||
|
+ else:
|
||||||
|
+ result = RE_STATE.search(res)
|
||||||
|
if result == None:
|
||||||
|
# We were able to parse ID so output is correct
|
||||||
|
# in some cases it is possible that RHEV-M output does not
|
||||||
|
@@ -59,7 +63,10 @@ def get_list(conn, options):
|
||||||
|
lines = res.split("<vm ")
|
||||||
|
for i in range(1, len(lines)):
|
||||||
|
name = RE_GET_NAME.search(lines[i]).group(1)
|
||||||
|
- status = RE_STATUS.search(lines[i]).group(1)
|
||||||
|
+ if tuple(map(int, options["--api-version"].split(".")))[0] > 3:
|
||||||
|
+ status = RE_STATUS.search(lines[i]).group(1)
|
||||||
|
+ else:
|
||||||
|
+ status = RE_STATE.search(lines[i]).group(1)
|
||||||
|
outlets[name] = ("", status)
|
||||||
|
except AttributeError:
|
||||||
|
return {}
|
||||||
|
@@ -69,6 +76,13 @@ def get_list(conn, options):
|
||||||
|
return outlets
|
||||||
|
|
||||||
|
def send_command(opt, command, method="GET"):
|
||||||
|
+ if opt["--api-version"] == "auto":
|
||||||
|
+ opt["--api-version"] = "4"
|
||||||
|
+ res = send_command(opt, "")
|
||||||
|
+ if re.search("<title>Error</title>", res):
|
||||||
|
+ opt["--api-version"] = "3"
|
||||||
|
+ logging.debug("auto-detected API version: " + opt["--api-version"])
|
||||||
|
+
|
||||||
|
## setup correct URL
|
||||||
|
if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt:
|
||||||
|
url = "https:"
|
||||||
|
@@ -90,7 +104,7 @@ def send_command(opt, command, method="GET"):
|
||||||
|
web_buffer = io.BytesIO()
|
||||||
|
conn.setopt(pycurl.URL, url.encode("UTF-8"))
|
||||||
|
conn.setopt(pycurl.HTTPHEADER, [
|
||||||
|
- "Version: 3",
|
||||||
|
+ "Version: {}".format(opt["--api-version"]),
|
||||||
|
"Content-type: application/xml",
|
||||||
|
"Accept: application/xml",
|
||||||
|
"Prefer: persistent-auth",
|
||||||
|
@@ -130,8 +144,9 @@ def send_command(opt, command, method="GET"):
|
||||||
|
|
||||||
|
result = web_buffer.getvalue().decode("UTF-8")
|
||||||
|
|
||||||
|
- logging.debug("%s\n", command)
|
||||||
|
- logging.debug("%s\n", result)
|
||||||
|
+ logging.debug("url: %s\n", url)
|
||||||
|
+ logging.debug("command: %s\n", command)
|
||||||
|
+ logging.debug("result: %s\n", result)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
@@ -151,6 +166,15 @@ def define_new_opts():
|
||||||
|
"required" : "0",
|
||||||
|
"shortdesc" : "Reuse cookies for authentication",
|
||||||
|
"order" : 1}
|
||||||
|
+ all_opt["api_version"] = {
|
||||||
|
+ "getopt" : ":",
|
||||||
|
+ "longopt" : "api-version",
|
||||||
|
+ "help" : "--api-version "
|
||||||
|
+ "Version of RHEV API (default: auto)",
|
||||||
|
+ "required" : "0",
|
||||||
|
+ "order" : 2,
|
||||||
|
+ "default" : "auto",
|
||||||
|
+ }
|
||||||
|
all_opt["api_path"] = {
|
||||||
|
"getopt" : ":",
|
||||||
|
"longopt" : "api-path",
|
||||||
|
@@ -158,20 +182,19 @@ def define_new_opts():
|
||||||
|
"default" : "/ovirt-engine/api",
|
||||||
|
"required" : "0",
|
||||||
|
"shortdesc" : "The path part of the API URL",
|
||||||
|
- "order" : 2}
|
||||||
|
+ "order" : 3}
|
||||||
|
all_opt["disable_http_filter"] = {
|
||||||
|
"getopt" : "",
|
||||||
|
"longopt" : "disable-http-filter",
|
||||||
|
"help" : "--disable-http-filter Set HTTP Filter header to false",
|
||||||
|
"required" : "0",
|
||||||
|
"shortdesc" : "Set HTTP Filter header to false",
|
||||||
|
- "order" : 3}
|
||||||
|
+ "order" : 4}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
device_opt = [
|
||||||
|
"ipaddr",
|
||||||
|
- "api_path",
|
||||||
|
"login",
|
||||||
|
"passwd",
|
||||||
|
"ssl",
|
||||||
|
@@ -179,6 +202,8 @@ def main():
|
||||||
|
"web",
|
||||||
|
"port",
|
||||||
|
"use_cookies",
|
||||||
|
+ "api_version",
|
||||||
|
+ "api_path",
|
||||||
|
"disable_http_filter",
|
||||||
|
]
|
||||||
|
|
||||||
|
@@ -186,6 +211,7 @@ def main():
|
||||||
|
define_new_opts()
|
||||||
|
|
||||||
|
all_opt["power_wait"]["default"] = "1"
|
||||||
|
+ all_opt["shell_timeout"]["default"] = "5"
|
||||||
|
|
||||||
|
options = check_input(device_opt, process_input(device_opt))
|
||||||
|
|
||||||
|
diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml
|
||||||
|
index 6344db79f..c56cf64b6 100644
|
||||||
|
--- a/tests/data/metadata/fence_rhevm.xml
|
||||||
|
+++ b/tests/data/metadata/fence_rhevm.xml
|
||||||
|
@@ -98,6 +98,11 @@
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">Login name</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
+ <parameter name="api_version" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--api-version" />
|
||||||
|
+ <content type="string" default="auto" />
|
||||||
|
+ <shortdesc lang="en">Version of RHEV API (default: auto)</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
<parameter name="api_path" unique="0" required="0">
|
||||||
|
<getopt mixed="--api-path=[path]" />
|
||||||
|
<shortdesc lang="en">The path part of the API URL</shortdesc>
|
||||||
|
@@ -164,7 +169,7 @@
|
||||||
|
</parameter>
|
||||||
|
<parameter name="shell_timeout" unique="0" required="0">
|
||||||
|
<getopt mixed="--shell-timeout=[seconds]" />
|
||||||
|
- <content type="second" default="3" />
|
||||||
|
+ <content type="second" default="5" />
|
||||||
|
<shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="retry_on" unique="0" required="0">
|
21
SOURCES/bz1709926-fence_mpath-fix-watchdog-hardreboot.patch
Normal file
21
SOURCES/bz1709926-fence_mpath-fix-watchdog-hardreboot.patch
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
From e5c6c2e134fd397ffe3319adc7afb8b633a251b2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 14 May 2019 16:44:59 +0200
|
||||||
|
Subject: [PATCH] fence_mpath: import ctypes to fix watchdog hardreboot
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/mpath/fence_mpath.py | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/agents/mpath/fence_mpath.py b/agents/mpath/fence_mpath.py
|
||||||
|
index d9ac2ef54..e4f598361 100644
|
||||||
|
--- a/agents/mpath/fence_mpath.py
|
||||||
|
+++ b/agents/mpath/fence_mpath.py
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import atexit
|
||||||
|
+import ctypes
|
||||||
|
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
from fencing import fail_usage, run_command, atexit_handler, check_input, process_input, show_docs
|
||||||
|
from fencing import fence_action, all_opt, run_delay
|
32
SOURCES/bz1712263-fence_rhevm-1-use-UTF8-encoding.patch
Normal file
32
SOURCES/bz1712263-fence_rhevm-1-use-UTF8-encoding.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From a77165d7c8caadf514462d359c6d564048c2c33a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sandro <42254081+Numblesix@users.noreply.github.com>
|
||||||
|
Date: Tue, 29 Jan 2019 13:29:52 +0100
|
||||||
|
Subject: [PATCH] Changed Encoding to UTF-8
|
||||||
|
|
||||||
|
Starting from RHV/Ovirt 4.2 we saw issues with the agent(unable to fence) after switching to UTF-8 all worked again.
|
||||||
|
---
|
||||||
|
agents/rhevm/fence_rhevm.py | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/rhevm/fence_rhevm.py b/agents/rhevm/fence_rhevm.py
|
||||||
|
index 2a5107cc6..a1cdaf605 100644
|
||||||
|
--- a/agents/rhevm/fence_rhevm.py
|
||||||
|
+++ b/agents/rhevm/fence_rhevm.py
|
||||||
|
@@ -88,7 +88,7 @@ def send_command(opt, command, method="GET"):
|
||||||
|
## send command through pycurl
|
||||||
|
conn = pycurl.Curl()
|
||||||
|
web_buffer = io.BytesIO()
|
||||||
|
- conn.setopt(pycurl.URL, url.encode("ascii"))
|
||||||
|
+ conn.setopt(pycurl.URL, url.encode("UTF-8"))
|
||||||
|
conn.setopt(pycurl.HTTPHEADER, [
|
||||||
|
"Version: 3",
|
||||||
|
"Content-type: application/xml",
|
||||||
|
@@ -128,7 +128,7 @@ def send_command(opt, command, method="GET"):
|
||||||
|
|
||||||
|
opt["cookie"] = cookie
|
||||||
|
|
||||||
|
- result = web_buffer.getvalue().decode()
|
||||||
|
+ result = web_buffer.getvalue().decode("UTF-8")
|
||||||
|
|
||||||
|
logging.debug("%s\n", command)
|
||||||
|
logging.debug("%s\n", result)
|
@ -0,0 +1,31 @@
|
|||||||
|
From 965924fe8bf7dcd0bc15fb0e9265ab49bb8a5dd8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 20 May 2019 15:49:39 +0200
|
||||||
|
Subject: [PATCH] fence_rhevm: fix debug encoding issues
|
||||||
|
|
||||||
|
Tested with UTF-8 encoded comment in result, which caused this issue,
|
||||||
|
and added to command and url in case they are in UTF-8 decoded state.
|
||||||
|
---
|
||||||
|
agents/rhevm/fence_rhevm.py | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/rhevm/fence_rhevm.py b/agents/rhevm/fence_rhevm.py
|
||||||
|
index 6012c423..9e4650cd 100644
|
||||||
|
--- a/agents/rhevm/fence_rhevm.py
|
||||||
|
+++ b/agents/rhevm/fence_rhevm.py
|
||||||
|
@@ -144,9 +144,9 @@ def send_command(opt, command, method="GET"):
|
||||||
|
|
||||||
|
result = web_buffer.getvalue().decode("UTF-8")
|
||||||
|
|
||||||
|
- logging.debug("url: %s\n", url)
|
||||||
|
- logging.debug("command: %s\n", command)
|
||||||
|
- logging.debug("result: %s\n", result)
|
||||||
|
+ logging.debug("url: %s\n", url.encode("UTF-8"))
|
||||||
|
+ logging.debug("command: %s\n", command.encode("UTF-8"))
|
||||||
|
+ logging.debug("result: %s\n", result.encode("UTF-8"))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
30
SOURCES/bz1714458-fence_scsi-node-id-new-format.patch
Normal file
30
SOURCES/bz1714458-fence_scsi-node-id-new-format.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 1c4a64ca803831b44c96c75022abe5bb8713cd1a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Wed, 22 May 2019 10:13:34 +0200
|
||||||
|
Subject: [PATCH] fence_scsi: detect node ID using new format, and fallback to
|
||||||
|
old format before failing
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/scsi/fence_scsi.py | 8 +++++++-
|
||||||
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py
|
||||||
|
index 8a1e4c77..5580e08b 100644
|
||||||
|
--- a/agents/scsi/fence_scsi.py
|
||||||
|
+++ b/agents/scsi/fence_scsi.py
|
||||||
|
@@ -192,8 +192,14 @@ def get_cluster_id(options):
|
||||||
|
|
||||||
|
def get_node_id(options):
|
||||||
|
cmd = options["--corosync-cmap-path"] + " nodelist"
|
||||||
|
+ out = run_cmd(options, cmd)["out"]
|
||||||
|
+
|
||||||
|
+ match = re.search(r".(\d+).name \(str\) = " + options["--plug"] + "\n", out)
|
||||||
|
+
|
||||||
|
+ # try old format before failing
|
||||||
|
+ if not match:
|
||||||
|
+ match = re.search(r".(\d+).ring._addr \(str\) = " + options["--plug"] + "\n", out)
|
||||||
|
|
||||||
|
- match = re.search(r".(\d+).ring._addr \(str\) = " + options["--plug"] + "\n", run_cmd(options, cmd)["out"])
|
||||||
|
return match.group(1) if match else fail_usage("Failed: unable to parse output of corosync-cmapctl or node does not exist")
|
||||||
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
From 418b3a36c8a7de0e984a0cd4707f2b90f279c4ce Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Thu, 13 Jun 2019 11:29:25 +0200
|
||||||
|
Subject: [PATCH] fence_scsi watchdog: dont exit when command fails using retry
|
||||||
|
parameter
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/fencing.py.py | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/fencing.py.py b/lib/fencing.py.py
|
||||||
|
index 8cd0a813..6f2526a9 100644
|
||||||
|
--- a/lib/fencing.py.py
|
||||||
|
+++ b/lib/fencing.py.py
|
||||||
|
@@ -530,7 +530,7 @@ def fail_usage(message="", stop=True):
|
||||||
|
logging.error("Please use '-h' for usage\n")
|
||||||
|
sys.exit(EC_GENERIC_ERROR)
|
||||||
|
|
||||||
|
-def fail(error_code):
|
||||||
|
+def fail(error_code, stop=True):
|
||||||
|
message = {
|
||||||
|
EC_LOGIN_DENIED : "Unable to connect/login to fencing device",
|
||||||
|
EC_CONNECTION_LOST : "Connection lost",
|
||||||
|
@@ -546,7 +546,8 @@ def fail(error_code):
|
||||||
|
|
||||||
|
}[error_code] + "\n"
|
||||||
|
logging.error("%s\n", message)
|
||||||
|
- sys.exit(EC_GENERIC_ERROR)
|
||||||
|
+ if stop:
|
||||||
|
+ sys.exit(EC_GENERIC_ERROR)
|
||||||
|
|
||||||
|
def usage(avail_opt):
|
||||||
|
print("Usage:")
|
||||||
|
@@ -1009,7 +1010,7 @@ def run_command(options, command, timeout=None, env=None, log_command=None):
|
||||||
|
thread.join(timeout)
|
||||||
|
if thread.is_alive():
|
||||||
|
process.kill()
|
||||||
|
- fail(EC_TIMED_OUT)
|
||||||
|
+ fail(EC_TIMED_OUT, stop=(int(options.get("retry", 0)) < 1))
|
||||||
|
|
||||||
|
status = process.wait()
|
||||||
|
|
344
SOURCES/fence_aliyun-1.patch
Normal file
344
SOURCES/fence_aliyun-1.patch
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
From 418df5845d1781e18e300cf17b2de714e4ff09d1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "feng.changf1" <feng.changf1@alibaba-inc.com>
|
||||||
|
Date: Tue, 24 Jul 2018 15:56:50 +0800
|
||||||
|
Subject: [PATCH 1/3] Add Aliyun fence agent.
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/aliyun/fence_aliyun.py | 146 ++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 146 insertions(+)
|
||||||
|
create mode 100644 agents/aliyun/fence_aliyun.py
|
||||||
|
|
||||||
|
diff --git a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..ec7d2316
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/agents/aliyun/fence_aliyun.py
|
||||||
|
@@ -0,0 +1,146 @@
|
||||||
|
+#!/usr/bin/python -tt
|
||||||
|
+
|
||||||
|
+import sys, re
|
||||||
|
+import logging
|
||||||
|
+import atexit
|
||||||
|
+import json
|
||||||
|
+sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
+from fencing import *
|
||||||
|
+from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
|
||||||
|
+
|
||||||
|
+from aliyunsdkcore import client
|
||||||
|
+
|
||||||
|
+from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
|
||||||
|
+from aliyunsdkecs.request.v20140526.StartInstanceRequest import StartInstanceRequest
|
||||||
|
+from aliyunsdkecs.request.v20140526.StopInstanceRequest import StopInstanceRequest
|
||||||
|
+from aliyunsdkecs.request.v20140526.RebootInstanceRequest import RebootInstanceRequest
|
||||||
|
+
|
||||||
|
+def _send_request(conn, request):
|
||||||
|
+ request.set_accept_format('json')
|
||||||
|
+ try:
|
||||||
|
+ response_str = conn.do_action_with_exception(request)
|
||||||
|
+ response_detail = json.loads(response_str)
|
||||||
|
+ return response_detail
|
||||||
|
+ except Exception as e:
|
||||||
|
+ fail_usage("Failed: _send_request failed")
|
||||||
|
+
|
||||||
|
+def start_instance(conn, instance_id):
|
||||||
|
+ request = StartInstanceRequest()
|
||||||
|
+ request.set_InstanceId(instance_id)
|
||||||
|
+ _send_request(conn, request)
|
||||||
|
+
|
||||||
|
+def stop_instance(conn, instance_id):
|
||||||
|
+ request = StopInstanceRequest()
|
||||||
|
+ request.set_InstanceId(instance_id)
|
||||||
|
+ request.set_ForceStop('true')
|
||||||
|
+ _send_request(conn, request)
|
||||||
|
+
|
||||||
|
+def reboot_instance(conn, instance_id):
|
||||||
|
+ request = RebootInstanceRequest()
|
||||||
|
+ request.set_InstanceId(instance_id)
|
||||||
|
+ request.set_ForceStop('true')
|
||||||
|
+ _send_request(conn, request)
|
||||||
|
+
|
||||||
|
+def get_status(conn, instance_id):
|
||||||
|
+ request = DescribeInstancesRequest()
|
||||||
|
+ request.set_InstanceIds(json.dumps([instance_id]))
|
||||||
|
+ response = _send_request(conn, request)
|
||||||
|
+ instance_status = None
|
||||||
|
+ if response is not None:
|
||||||
|
+ instance_list = response.get('Instances').get('Instance')
|
||||||
|
+ for item in instance_list:
|
||||||
|
+ instance_status = item.get('Status')
|
||||||
|
+ return instance_status
|
||||||
|
+
|
||||||
|
+def get_nodes_list(conn, options):
|
||||||
|
+ result = {}
|
||||||
|
+ request = DescribeInstancesRequest()
|
||||||
|
+ response = _send_request(conn, request)
|
||||||
|
+ instance_status = None
|
||||||
|
+ if response is not None:
|
||||||
|
+ instance_list = response.get('Instances').get('Instance')
|
||||||
|
+ for item in instance_list:
|
||||||
|
+ instance_id = item.get('InstanceId')
|
||||||
|
+ result[instance_id] = ("", None)
|
||||||
|
+ return result
|
||||||
|
+
|
||||||
|
+def get_power_status(conn, options):
|
||||||
|
+ state = get_status(conn, options["--plug"])
|
||||||
|
+ if state == "Running":
|
||||||
|
+ return "on"
|
||||||
|
+ elif state == "Stopped":
|
||||||
|
+ return "off"
|
||||||
|
+ else:
|
||||||
|
+ return "unknown"
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def set_power_status(conn, options):
|
||||||
|
+ if (options["--action"]=="off"):
|
||||||
|
+ stop_instance(conn, options["--plug"])
|
||||||
|
+ elif (options["--action"]=="on"):
|
||||||
|
+ start_instance(conn, options["--plug"])
|
||||||
|
+ elif (options["--action"]=="reboot"):
|
||||||
|
+ reboot_instance(conn, options["--plug"])
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def define_new_opts():
|
||||||
|
+ all_opt["region"] = {
|
||||||
|
+ "getopt" : "r:",
|
||||||
|
+ "longopt" : "region",
|
||||||
|
+ "help" : "-r, --region=[name] Region, e.g. cn-hangzhou",
|
||||||
|
+ "shortdesc" : "Region.",
|
||||||
|
+ "required" : "0",
|
||||||
|
+ "order" : 2
|
||||||
|
+ }
|
||||||
|
+ all_opt["access_key"] = {
|
||||||
|
+ "getopt" : "a:",
|
||||||
|
+ "longopt" : "access-key",
|
||||||
|
+ "help" : "-a, --access-key=[name] Access Key",
|
||||||
|
+ "shortdesc" : "Access Key.",
|
||||||
|
+ "required" : "0",
|
||||||
|
+ "order" : 3
|
||||||
|
+ }
|
||||||
|
+ all_opt["secret_key"] = {
|
||||||
|
+ "getopt" : "s:",
|
||||||
|
+ "longopt" : "secret-key",
|
||||||
|
+ "help" : "-s, --secret-key=[name] Secret Key",
|
||||||
|
+ "shortdesc" : "Secret Key.",
|
||||||
|
+ "required" : "0",
|
||||||
|
+ "order" : 4
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+# Main agent method
|
||||||
|
+def main():
|
||||||
|
+ conn = None
|
||||||
|
+
|
||||||
|
+ device_opt = ["port", "no_password", "region", "access_key", "secret_key"]
|
||||||
|
+
|
||||||
|
+ atexit.register(atexit_handler)
|
||||||
|
+
|
||||||
|
+ define_new_opts()
|
||||||
|
+
|
||||||
|
+ all_opt["power_timeout"]["default"] = "60"
|
||||||
|
+
|
||||||
|
+ options = check_input(device_opt, process_input(device_opt))
|
||||||
|
+
|
||||||
|
+ docs = {}
|
||||||
|
+ docs["shortdesc"] = "Fence agent for Aliyun (Aliyun Web Services)"
|
||||||
|
+ docs["longdesc"] = "fence_aliyun is an I/O Fencing agent for Aliyun"
|
||||||
|
+ docs["vendorurl"] = "http://www.aliyun.com"
|
||||||
|
+ show_docs(options, docs)
|
||||||
|
+
|
||||||
|
+ run_delay(options)
|
||||||
|
+
|
||||||
|
+ if "--region" in options and "--access-key" in options and "--secret-key" in options:
|
||||||
|
+ region = options["--region"]
|
||||||
|
+ access_key = options["--access-key"]
|
||||||
|
+ secret_key = options["--secret-key"]
|
||||||
|
+ conn = client.AcsClient(access_key, secret_key, region)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ # Operate the fencing device
|
||||||
|
+ result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
|
||||||
|
+ sys.exit(result)
|
||||||
|
+
|
||||||
|
+if __name__ == "__main__":
|
||||||
|
+ main()
|
||||||
|
|
||||||
|
From 28b55555abda9b6c278a7f082bb22c4f6f1e2474 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "feng.changf1" <feng.changf1@alibaba-inc.com>
|
||||||
|
Date: Tue, 24 Jul 2018 17:18:53 +0800
|
||||||
|
Subject: [PATCH 2/3] Add Aliyun fence agent.
|
||||||
|
|
||||||
|
---
|
||||||
|
tests/data/metadata/fence_aliyun.xml | 113 +++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 113 insertions(+)
|
||||||
|
create mode 100644 tests/data/metadata/fence_aliyun.xml
|
||||||
|
|
||||||
|
diff --git a/tests/data/metadata/fence_aliyun.xml b/tests/data/metadata/fence_aliyun.xml
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..1db692ee
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/data/metadata/fence_aliyun.xml
|
||||||
|
@@ -0,0 +1,113 @@
|
||||||
|
+<?xml version="1.0" ?>
|
||||||
|
+<resource-agent name="fence_aliyun" shortdesc="Fence agent for Aliyun (Aliyun Web Services)" >
|
||||||
|
+<longdesc>fence_aliyun is an I/O Fencing agent for Aliyun</longdesc>
|
||||||
|
+<vendor-url>http://www.aliyun.com</vendor-url>
|
||||||
|
+<parameters>
|
||||||
|
+ <parameter name="action" unique="0" required="1">
|
||||||
|
+ <getopt mixed="-o, --action=[action]" />
|
||||||
|
+ <content type="string" default="reboot" />
|
||||||
|
+ <shortdesc lang="en">Fencing action</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="plug" unique="0" required="1" obsoletes="port">
|
||||||
|
+ <getopt mixed="-n, --plug=[id]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Physical plug number on device, UUID or identification of machine</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="port" unique="0" required="1" deprecated="1">
|
||||||
|
+ <getopt mixed="-n, --plug=[id]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Physical plug number on device, UUID or identification of machine</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="region" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-r, --region=[name]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Region.</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="access_key" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-a, --access-key=[name]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Access Key.</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="secret_key" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-s, --secret-key=[name]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Secret Key.</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="quiet" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-q, --quiet" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Disable logging to stderr. Does not affect --verbose or --debug-file or logging to syslog.</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="verbose" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-v, --verbose" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Verbose mode</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="debug" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-D, --debug-file=[debugfile]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Write debug information to given file</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="debug_file" unique="0" required="0" obsoletes="debug">
|
||||||
|
+ <getopt mixed="-D, --debug-file=[debugfile]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Write debug information to given file</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="version" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-V, --version" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Display version information and exit</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="help" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-h, --help" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Display help and exit</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="separator" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-C, --separator=[char]" />
|
||||||
|
+ <content type="string" default="," />
|
||||||
|
+ <shortdesc lang="en">Separator for CSV created by 'list' operation</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="delay" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--delay=[seconds]" />
|
||||||
|
+ <content type="second" default="0" />
|
||||||
|
+ <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="login_timeout" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--login-timeout=[seconds]" />
|
||||||
|
+ <content type="second" default="5" />
|
||||||
|
+ <shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="power_timeout" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--power-timeout=[seconds]" />
|
||||||
|
+ <content type="second" default="60" />
|
||||||
|
+ <shortdesc lang="en">Test X seconds for status change after ON/OFF</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="power_wait" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--power-wait=[seconds]" />
|
||||||
|
+ <content type="second" default="0" />
|
||||||
|
+ <shortdesc lang="en">Wait X seconds after issuing ON/OFF</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="shell_timeout" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--shell-timeout=[seconds]" />
|
||||||
|
+ <content type="second" default="3" />
|
||||||
|
+ <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="retry_on" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--retry-on=[attempts]" />
|
||||||
|
+ <content type="integer" default="1" />
|
||||||
|
+ <shortdesc lang="en">Count of attempts to retry power on</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+</parameters>
|
||||||
|
+<actions>
|
||||||
|
+ <action name="on" automatic="0"/>
|
||||||
|
+ <action name="off" />
|
||||||
|
+ <action name="reboot" />
|
||||||
|
+ <action name="status" />
|
||||||
|
+ <action name="list" />
|
||||||
|
+ <action name="list-status" />
|
||||||
|
+ <action name="monitor" />
|
||||||
|
+ <action name="metadata" />
|
||||||
|
+ <action name="validate-all" />
|
||||||
|
+</actions>
|
||||||
|
+</resource-agent>
|
||||||
|
|
||||||
|
From 53bbd91e91c231c89ae8981238bb15d85d02207b Mon Sep 17 00:00:00 2001
|
||||||
|
From: "feng.changf1" <feng.changf1@alibaba-inc.com>
|
||||||
|
Date: Tue, 24 Jul 2018 17:26:45 +0800
|
||||||
|
Subject: [PATCH 3/3] Fix CI error.
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/aliyun/fence_aliyun.py | 32 +++++++++++++++++---------------
|
||||||
|
1 file changed, 17 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py
|
||||||
|
index ec7d2316..0f24b83e 100644
|
||||||
|
--- a/agents/aliyun/fence_aliyun.py
|
||||||
|
+++ b/agents/aliyun/fence_aliyun.py
|
||||||
|
@@ -1,20 +1,22 @@
|
||||||
|
#!/usr/bin/python -tt
|
||||||
|
|
||||||
|
-import sys, re
|
||||||
|
-import logging
|
||||||
|
-import atexit
|
||||||
|
-import json
|
||||||
|
-sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
-from fencing import *
|
||||||
|
-from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
|
||||||
|
-
|
||||||
|
-from aliyunsdkcore import client
|
||||||
|
-
|
||||||
|
-from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
|
||||||
|
-from aliyunsdkecs.request.v20140526.StartInstanceRequest import StartInstanceRequest
|
||||||
|
-from aliyunsdkecs.request.v20140526.StopInstanceRequest import StopInstanceRequest
|
||||||
|
-from aliyunsdkecs.request.v20140526.RebootInstanceRequest import RebootInstanceRequest
|
||||||
|
-
|
||||||
|
+try:
|
||||||
|
+ import sys, re
|
||||||
|
+ import logging
|
||||||
|
+ import atexit
|
||||||
|
+ import json
|
||||||
|
+ sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
+ from fencing import *
|
||||||
|
+ from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
|
||||||
|
+
|
||||||
|
+ from aliyunsdkcore import client
|
||||||
|
+
|
||||||
|
+ from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
|
||||||
|
+ from aliyunsdkecs.request.v20140526.StartInstanceRequest import StartInstanceRequest
|
||||||
|
+ from aliyunsdkecs.request.v20140526.StopInstanceRequest import StopInstanceRequest
|
||||||
|
+ from aliyunsdkecs.request.v20140526.RebootInstanceRequest import RebootInstanceRequest
|
||||||
|
+except ImportError:
|
||||||
|
+ pass
|
||||||
|
def _send_request(conn, request):
|
||||||
|
request.set_accept_format('json')
|
||||||
|
try:
|
58
SOURCES/fence_aliyun-2.patch
Normal file
58
SOURCES/fence_aliyun-2.patch
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
From 8db45537fb470624a754ea1243cc4f349a9b413d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 24 Jul 2018 13:10:41 +0200
|
||||||
|
Subject: [PATCH] fence_aliyun: fix CI and add Python detection
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/aliyun/fence_aliyun.py | 19 ++++++++++---------
|
||||||
|
tests/data/metadata/fence_aliyun.xml | 1 +
|
||||||
|
2 files changed, 11 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py
|
||||||
|
index 0f24b83e..aa6c0acf 100644
|
||||||
|
--- a/agents/aliyun/fence_aliyun.py
|
||||||
|
+++ b/agents/aliyun/fence_aliyun.py
|
||||||
|
@@ -1,14 +1,14 @@
|
||||||
|
-#!/usr/bin/python -tt
|
||||||
|
+#!@PYTHON@ -tt
|
||||||
|
|
||||||
|
-try:
|
||||||
|
- import sys, re
|
||||||
|
- import logging
|
||||||
|
- import atexit
|
||||||
|
- import json
|
||||||
|
- sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
- from fencing import *
|
||||||
|
- from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
|
||||||
|
+import sys, re
|
||||||
|
+import logging
|
||||||
|
+import atexit
|
||||||
|
+import json
|
||||||
|
+sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
+from fencing import *
|
||||||
|
+from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
|
||||||
|
|
||||||
|
+try:
|
||||||
|
from aliyunsdkcore import client
|
||||||
|
|
||||||
|
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
from aliyunsdkecs.request.v20140526.RebootInstanceRequest import RebootInstanceRequest
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
+
|
||||||
|
def _send_request(conn, request):
|
||||||
|
request.set_accept_format('json')
|
||||||
|
try:
|
||||||
|
diff --git a/tests/data/metadata/fence_aliyun.xml b/tests/data/metadata/fence_aliyun.xml
|
||||||
|
index 1db692ee..b41d82bf 100644
|
||||||
|
--- a/tests/data/metadata/fence_aliyun.xml
|
||||||
|
+++ b/tests/data/metadata/fence_aliyun.xml
|
||||||
|
@@ -108,6 +108,7 @@
|
||||||
|
<action name="list-status" />
|
||||||
|
<action name="monitor" />
|
||||||
|
<action name="metadata" />
|
||||||
|
+ <action name="manpage" />
|
||||||
|
<action name="validate-all" />
|
||||||
|
</actions>
|
||||||
|
</resource-agent>
|
51
SOURCES/fence_aliyun-3-logging.patch
Normal file
51
SOURCES/fence_aliyun-3-logging.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
From 790cbaa66f3927a84739af4a1f0e8bba295cdc36 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 30 Jul 2018 10:43:04 +0200
|
||||||
|
Subject: [PATCH] fence_aliyun: add logging
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/aliyun/fence_aliyun.py | 16 ++++++++++++----
|
||||||
|
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py
|
||||||
|
index aa6c0acf..2cda6b7f 100644
|
||||||
|
--- a/agents/aliyun/fence_aliyun.py
|
||||||
|
+++ b/agents/aliyun/fence_aliyun.py
|
||||||
|
@@ -23,9 +23,10 @@ def _send_request(conn, request):
|
||||||
|
try:
|
||||||
|
response_str = conn.do_action_with_exception(request)
|
||||||
|
response_detail = json.loads(response_str)
|
||||||
|
+ logging.debug("_send_request reponse: %s" % response_detail)
|
||||||
|
return response_detail
|
||||||
|
except Exception as e:
|
||||||
|
- fail_usage("Failed: _send_request failed")
|
||||||
|
+ fail_usage("Failed: _send_request failed: %s" % e)
|
||||||
|
|
||||||
|
def start_instance(conn, instance_id):
|
||||||
|
request = StartInstanceRequest()
|
||||||
|
@@ -69,15 +70,22 @@ def get_nodes_list(conn, options):
|
||||||
|
|
||||||
|
def get_power_status(conn, options):
|
||||||
|
state = get_status(conn, options["--plug"])
|
||||||
|
+
|
||||||
|
if state == "Running":
|
||||||
|
- return "on"
|
||||||
|
+ status = "on"
|
||||||
|
elif state == "Stopped":
|
||||||
|
- return "off"
|
||||||
|
+ status = "off"
|
||||||
|
else:
|
||||||
|
- return "unknown"
|
||||||
|
+ status = "unknown"
|
||||||
|
+
|
||||||
|
+ logging.info("get_power_status: %s" % status)
|
||||||
|
+
|
||||||
|
+ return status
|
||||||
|
|
||||||
|
|
||||||
|
def set_power_status(conn, options):
|
||||||
|
+ logging.info("set_power_status: %s" % options["--action"])
|
||||||
|
+
|
||||||
|
if (options["--action"]=="off"):
|
||||||
|
stop_instance(conn, options["--plug"])
|
||||||
|
elif (options["--action"]=="on"):
|
11
SOURCES/fence_aliyun-4-bundled.patch
Normal file
11
SOURCES/fence_aliyun-4-bundled.patch
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
diff -uNr a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py
|
||||||
|
--- a/agents/aliyun/fence_aliyun.py 2018-07-24 14:30:29.030311806 +0200
|
||||||
|
+++ b/agents/aliyun/fence_aliyun.py 2018-07-24 14:31:10.023884949 +0200
|
||||||
|
@@ -9,6 +9,7 @@
|
||||||
|
from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
|
||||||
|
|
||||||
|
try:
|
||||||
|
+ sys.path.insert(0, '/usr/lib/fence-agents/bundled/aliyun')
|
||||||
|
from aliyunsdkcore import client
|
||||||
|
|
||||||
|
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
|
31
SOURCES/fence_aliyun-5-list-instance-names.patch
Normal file
31
SOURCES/fence_aliyun-5-list-instance-names.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From c21d60fbcf0b11dcbf4f70006c8ffaeac4ca7dbd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 28 Aug 2018 15:20:10 +0200
|
||||||
|
Subject: [PATCH] fence_aliyun: list instance names and show up to 100
|
||||||
|
instances
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/aliyun/fence_aliyun.py | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py
|
||||||
|
index 2cda6b7f..b3aca12f 100644
|
||||||
|
--- a/agents/aliyun/fence_aliyun.py
|
||||||
|
+++ b/agents/aliyun/fence_aliyun.py
|
||||||
|
@@ -59,13 +59,15 @@ def get_status(conn, instance_id):
|
||||||
|
def get_nodes_list(conn, options):
|
||||||
|
result = {}
|
||||||
|
request = DescribeInstancesRequest()
|
||||||
|
+ request.set_PageSize(100)
|
||||||
|
response = _send_request(conn, request)
|
||||||
|
instance_status = None
|
||||||
|
if response is not None:
|
||||||
|
instance_list = response.get('Instances').get('Instance')
|
||||||
|
for item in instance_list:
|
||||||
|
instance_id = item.get('InstanceId')
|
||||||
|
- result[instance_id] = ("", None)
|
||||||
|
+ instance_name = item.get('InstanceName')
|
||||||
|
+ result[instance_id] = (instance_name, None)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_power_status(conn, options):
|
31
SOURCES/fence_aliyun-6-correct-help-indentation.patch
Normal file
31
SOURCES/fence_aliyun-6-correct-help-indentation.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From 588f935b1f79c8355d461fe9f8597151fbcd7fa2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Thu, 30 Aug 2018 09:11:58 +0200
|
||||||
|
Subject: [PATCH] fence_aliyun: correct indentation for *key in help
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/aliyun/fence_aliyun.py | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py
|
||||||
|
index 2cda6b7f..7d04c5bb 100644
|
||||||
|
--- a/agents/aliyun/fence_aliyun.py
|
||||||
|
+++ b/agents/aliyun/fence_aliyun.py
|
||||||
|
@@ -106,7 +106,7 @@ def define_new_opts():
|
||||||
|
all_opt["access_key"] = {
|
||||||
|
"getopt" : "a:",
|
||||||
|
"longopt" : "access-key",
|
||||||
|
- "help" : "-a, --access-key=[name] Access Key",
|
||||||
|
+ "help" : "-a, --access-key=[name] Access Key",
|
||||||
|
"shortdesc" : "Access Key.",
|
||||||
|
"required" : "0",
|
||||||
|
"order" : 3
|
||||||
|
@@ -114,7 +114,7 @@ def define_new_opts():
|
||||||
|
all_opt["secret_key"] = {
|
||||||
|
"getopt" : "s:",
|
||||||
|
"longopt" : "secret-key",
|
||||||
|
- "help" : "-s, --secret-key=[name] Secret Key",
|
||||||
|
+ "help" : "-s, --secret-key=[name] Secret Key",
|
||||||
|
"shortdesc" : "Secret Key.",
|
||||||
|
"required" : "0",
|
||||||
|
"order" : 4
|
22
SOURCES/fence_cisco_ucs-encode-POSTFIELDS.patch
Normal file
22
SOURCES/fence_cisco_ucs-encode-POSTFIELDS.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From 70bd4ffa245ef7e8b7698228bab3b41c240d50d2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 4 Sep 2018 12:35:07 +0200
|
||||||
|
Subject: [PATCH] fence_cisco_ucs: encode POSTFIELDS
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/cisco_ucs/fence_cisco_ucs.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/agents/cisco_ucs/fence_cisco_ucs.py b/agents/cisco_ucs/fence_cisco_ucs.py
|
||||||
|
index d509b3e0..ec311754 100644
|
||||||
|
--- a/agents/cisco_ucs/fence_cisco_ucs.py
|
||||||
|
+++ b/agents/cisco_ucs/fence_cisco_ucs.py
|
||||||
|
@@ -111,7 +111,7 @@ def send_command(opt, command, timeout):
|
||||||
|
web_buffer = io.BytesIO()
|
||||||
|
conn.setopt(pycurl.URL, url.encode("ascii"))
|
||||||
|
conn.setopt(pycurl.HTTPHEADER, ["Content-type: text/xml"])
|
||||||
|
- conn.setopt(pycurl.POSTFIELDS, command)
|
||||||
|
+ conn.setopt(pycurl.POSTFIELDS, command.encode("ascii"))
|
||||||
|
conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
|
||||||
|
conn.setopt(pycurl.TIMEOUT, timeout)
|
||||||
|
if "--ssl" in opt or "--ssl-secure" in opt:
|
232
SOURCES/fence_compute-fence_evacuate-fix-compute-domain.patch
Normal file
232
SOURCES/fence_compute-fence_evacuate-fix-compute-domain.patch
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
From 15635df9d12ce693f473d5ebcd5b7cacb81e2295 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 16 Jul 2018 11:14:16 +0200
|
||||||
|
Subject: [PATCH] fence_compute/fence_evacuate: workaround for compute-domain
|
||||||
|
regression
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/compute/fence_compute.py | 24 +++++++++++++++++++-----
|
||||||
|
agents/evacuate/fence_evacuate.py | 24 +++++++++++++++++++-----
|
||||||
|
tests/data/metadata/fence_compute.xml | 24 ++++++++++++++++++++++--
|
||||||
|
tests/data/metadata/fence_evacuate.xml | 24 ++++++++++++++++++++++--
|
||||||
|
4 files changed, 82 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/compute/fence_compute.py b/agents/compute/fence_compute.py
|
||||||
|
index ec2d093c..aac9b296 100644
|
||||||
|
--- a/agents/compute/fence_compute.py
|
||||||
|
+++ b/agents/compute/fence_compute.py
|
||||||
|
@@ -353,7 +353,7 @@ def define_new_opts():
|
||||||
|
"default" : "",
|
||||||
|
"order": 1,
|
||||||
|
}
|
||||||
|
- all_opt["user_domain"] = {
|
||||||
|
+ all_opt["user-domain"] = {
|
||||||
|
"getopt" : "u:",
|
||||||
|
"longopt" : "user-domain",
|
||||||
|
"help" : "-u, --user-domain=[name] Keystone v3 User Domain",
|
||||||
|
@@ -362,7 +362,7 @@ def define_new_opts():
|
||||||
|
"default" : "Default",
|
||||||
|
"order": 2,
|
||||||
|
}
|
||||||
|
- all_opt["project_domain"] = {
|
||||||
|
+ all_opt["project-domain"] = {
|
||||||
|
"getopt" : "P:",
|
||||||
|
"longopt" : "project-domain",
|
||||||
|
"help" : "-d, --project-domain=[name] Keystone v3 Project Domain",
|
||||||
|
@@ -433,6 +433,14 @@ def define_new_opts():
|
||||||
|
"default" : "False",
|
||||||
|
"order": 5,
|
||||||
|
}
|
||||||
|
+ all_opt["compute-domain"] = {
|
||||||
|
+ "getopt" : ":",
|
||||||
|
+ "longopt" : "compute-domain",
|
||||||
|
+ "help" : "--compute-domain=[string] Replaced by --domain",
|
||||||
|
+ "required" : "0",
|
||||||
|
+ "shortdesc" : "Replaced by domain",
|
||||||
|
+ "order": 6,
|
||||||
|
+ }
|
||||||
|
|
||||||
|
def set_multi_power_fn(connection, options, set_power_fn, get_power_fn, retry_attempts=1):
|
||||||
|
for _ in range(retry_attempts):
|
||||||
|
@@ -450,9 +458,10 @@ def main():
|
||||||
|
global override_status
|
||||||
|
atexit.register(atexit_handler)
|
||||||
|
|
||||||
|
- device_opt = ["login", "passwd", "tenant_name", "auth_url", "fabric_fencing",
|
||||||
|
- "no_login", "no_password", "port", "domain", "project_domain", "user_domain",
|
||||||
|
- "no_shared_storage", "endpoint_type", "record_only", "instance_filtering", "insecure", "region_name"]
|
||||||
|
+ device_opt = ["login", "passwd", "tenant_name", "auth_url", "fabric_fencing", "no_login",
|
||||||
|
+ "no_password", "port", "domain", "compute-domain", "project-domain",
|
||||||
|
+ "user-domain", "no_shared_storage", "endpoint_type", "record_only",
|
||||||
|
+ "instance_filtering", "insecure", "region_name"]
|
||||||
|
define_new_opts()
|
||||||
|
all_opt["shell_timeout"]["default"] = "180"
|
||||||
|
|
||||||
|
@@ -470,6 +479,11 @@ def main():
|
||||||
|
|
||||||
|
run_delay(options)
|
||||||
|
|
||||||
|
+ # workaround to avoid regressions
|
||||||
|
+ if "--compute-domain" in options and options["--compute-domain"]:
|
||||||
|
+ options["--domain"] = options["--compute-domain"]
|
||||||
|
+ del options["--domain"]
|
||||||
|
+
|
||||||
|
logging.debug("Running "+options["--action"])
|
||||||
|
connection = create_nova_connection(options)
|
||||||
|
|
||||||
|
diff --git a/agents/evacuate/fence_evacuate.py b/agents/evacuate/fence_evacuate.py
|
||||||
|
index 615dede7..529a60dd 100644
|
||||||
|
--- a/agents/evacuate/fence_evacuate.py
|
||||||
|
+++ b/agents/evacuate/fence_evacuate.py
|
||||||
|
@@ -287,7 +287,7 @@ def define_new_opts():
|
||||||
|
"default" : "",
|
||||||
|
"order": 1,
|
||||||
|
}
|
||||||
|
- all_opt["user_domain"] = {
|
||||||
|
+ all_opt["user-domain"] = {
|
||||||
|
"getopt" : "u:",
|
||||||
|
"longopt" : "user-domain",
|
||||||
|
"help" : "-u, --user-domain=[name] Keystone v3 User Domain",
|
||||||
|
@@ -296,7 +296,7 @@ def define_new_opts():
|
||||||
|
"default" : "Default",
|
||||||
|
"order": 2,
|
||||||
|
}
|
||||||
|
- all_opt["project_domain"] = {
|
||||||
|
+ all_opt["project-domain"] = {
|
||||||
|
"getopt" : "P:",
|
||||||
|
"longopt" : "project-domain",
|
||||||
|
"help" : "-d, --project-domain=[name] Keystone v3 Project Domain",
|
||||||
|
@@ -358,14 +358,22 @@ def define_new_opts():
|
||||||
|
"default" : "False",
|
||||||
|
"order": 5,
|
||||||
|
}
|
||||||
|
+ all_opt["compute-domain"] = {
|
||||||
|
+ "getopt" : ":",
|
||||||
|
+ "longopt" : "compute-domain",
|
||||||
|
+ "help" : "--compute-domain=[string] Replaced by --domain",
|
||||||
|
+ "required" : "0",
|
||||||
|
+ "shortdesc" : "Replaced by domain",
|
||||||
|
+ "order": 6,
|
||||||
|
+ }
|
||||||
|
|
||||||
|
def main():
|
||||||
|
atexit.register(atexit_handler)
|
||||||
|
|
||||||
|
device_opt = ["login", "passwd", "tenant_name", "auth_url",
|
||||||
|
- "no_login", "no_password", "port", "domain", "project_domain",
|
||||||
|
- "user_domain", "no_shared_storage", "endpoint_type",
|
||||||
|
- "instance_filtering", "insecure", "region_name"]
|
||||||
|
+ "no_login", "no_password", "port", "domain", "compute-domain",
|
||||||
|
+ "project-domain", "user-domain", "no_shared_storage",
|
||||||
|
+ "endpoint_type", "instance_filtering", "insecure", "region_name"]
|
||||||
|
define_new_opts()
|
||||||
|
all_opt["shell_timeout"]["default"] = "180"
|
||||||
|
|
||||||
|
@@ -380,6 +388,12 @@ def main():
|
||||||
|
|
||||||
|
run_delay(options)
|
||||||
|
|
||||||
|
+ # workaround to avoid regressions
|
||||||
|
+ if "--compute-domain" in options and options["--compute-domain"]:
|
||||||
|
+ options["--domain"] = options["--compute-domain"]
|
||||||
|
+ del options["--domain"]
|
||||||
|
+
|
||||||
|
+
|
||||||
|
connection = create_nova_connection(options)
|
||||||
|
|
||||||
|
# Un-evacuating a server doesn't make sense
|
||||||
|
diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml
|
||||||
|
index e1dac97c..1dcbfc54 100644
|
||||||
|
--- a/tests/data/metadata/fence_compute.xml
|
||||||
|
+++ b/tests/data/metadata/fence_compute.xml
|
||||||
|
@@ -73,12 +73,22 @@
|
||||||
|
<content type="boolean" default="False" />
|
||||||
|
<shortdesc lang="en">Allow Insecure TLS Requests</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="project_domain" unique="0" required="0">
|
||||||
|
+ <parameter name="project-domain" unique="0" required="0" deprecated="1">
|
||||||
|
<getopt mixed="-d, --project-domain=[name]" />
|
||||||
|
<content type="string" default="Default" />
|
||||||
|
<shortdesc lang="en">Keystone v3 Project Domain</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="user_domain" unique="0" required="0">
|
||||||
|
+ <parameter name="project_domain" unique="0" required="0" obsoletes="project-domain">
|
||||||
|
+ <getopt mixed="-d, --project-domain=[name]" />
|
||||||
|
+ <content type="string" default="Default" />
|
||||||
|
+ <shortdesc lang="en">Keystone v3 Project Domain</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="user-domain" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-u, --user-domain=[name]" />
|
||||||
|
+ <content type="string" default="Default" />
|
||||||
|
+ <shortdesc lang="en">Keystone v3 User Domain</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="user_domain" unique="0" required="0" obsoletes="user-domain">
|
||||||
|
<getopt mixed="-u, --user-domain=[name]" />
|
||||||
|
<content type="string" default="Default" />
|
||||||
|
<shortdesc lang="en">Keystone v3 User Domain</shortdesc>
|
||||||
|
@@ -103,6 +113,16 @@
|
||||||
|
<content type="string" default="False" />
|
||||||
|
<shortdesc lang="en">Only record the target as needing evacuation</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
+ <parameter name="compute-domain" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="--compute-domain=[string]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Replaced by domain</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="compute_domain" unique="0" required="0" obsoletes="compute-domain">
|
||||||
|
+ <getopt mixed="--compute-domain=[string]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Replaced by domain</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
<parameter name="quiet" unique="0" required="0">
|
||||||
|
<getopt mixed="-q, --quiet" />
|
||||||
|
<content type="boolean" />
|
||||||
|
diff --git a/tests/data/metadata/fence_evacuate.xml b/tests/data/metadata/fence_evacuate.xml
|
||||||
|
index 6f8bd0a4..4f1f6a58 100644
|
||||||
|
--- a/tests/data/metadata/fence_evacuate.xml
|
||||||
|
+++ b/tests/data/metadata/fence_evacuate.xml
|
||||||
|
@@ -73,12 +73,22 @@
|
||||||
|
<content type="boolean" default="False" />
|
||||||
|
<shortdesc lang="en">Allow Insecure TLS Requests</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="project_domain" unique="0" required="0">
|
||||||
|
+ <parameter name="project-domain" unique="0" required="0" deprecated="1">
|
||||||
|
<getopt mixed="-d, --project-domain=[name]" />
|
||||||
|
<content type="string" default="Default" />
|
||||||
|
<shortdesc lang="en">Keystone v3 Project Domain</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="user_domain" unique="0" required="0">
|
||||||
|
+ <parameter name="project_domain" unique="0" required="0" obsoletes="project-domain">
|
||||||
|
+ <getopt mixed="-d, --project-domain=[name]" />
|
||||||
|
+ <content type="string" default="Default" />
|
||||||
|
+ <shortdesc lang="en">Keystone v3 Project Domain</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="user-domain" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="-u, --user-domain=[name]" />
|
||||||
|
+ <content type="string" default="Default" />
|
||||||
|
+ <shortdesc lang="en">Keystone v3 User Domain</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="user_domain" unique="0" required="0" obsoletes="user-domain">
|
||||||
|
<getopt mixed="-u, --user-domain=[name]" />
|
||||||
|
<content type="string" default="Default" />
|
||||||
|
<shortdesc lang="en">Keystone v3 User Domain</shortdesc>
|
||||||
|
@@ -98,6 +108,16 @@
|
||||||
|
<content type="boolean" default="False" />
|
||||||
|
<shortdesc lang="en">Disable functionality for dealing with shared storage</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
+ <parameter name="compute-domain" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="--compute-domain=[string]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Replaced by domain</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="compute_domain" unique="0" required="0" obsoletes="compute-domain">
|
||||||
|
+ <getopt mixed="--compute-domain=[string]" />
|
||||||
|
+ <content type="string" />
|
||||||
|
+ <shortdesc lang="en">Replaced by domain</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
<parameter name="quiet" unique="0" required="0">
|
||||||
|
<getopt mixed="-q, --quiet" />
|
||||||
|
<content type="boolean" />
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
20
SOURCES/fence_evacuate-fix-evacuable-tag-mix-issue.patch
Normal file
20
SOURCES/fence_evacuate-fix-evacuable-tag-mix-issue.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
diff -uNr a/agents/evacuate/fence_evacuate.py b/agents/evacuate/fence_evacuate.py
|
||||||
|
--- a/agents/evacuate/fence_evacuate.py 2018-06-28 14:24:54.000000000 +0200
|
||||||
|
+++ b/agents/evacuate/fence_evacuate.py 2018-07-11 09:08:56.975072003 +0200
|
||||||
|
@@ -74,12 +74,15 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
def _is_server_evacuable(server, evac_flavors, evac_images):
|
||||||
|
+ reason = "flavor "+server.flavor.get('id')
|
||||||
|
if server.flavor.get('id') in evac_flavors:
|
||||||
|
return True
|
||||||
|
if hasattr(server.image, 'get'):
|
||||||
|
if server.image.get('id') in evac_images:
|
||||||
|
return True
|
||||||
|
- logging.debug("Instance %s is not evacuable" % server.image.get('id'))
|
||||||
|
+ reason = reason +" and image "+server.image.get('id')
|
||||||
|
+
|
||||||
|
+ logging.debug("Instance is not evacuable: no match for %s" % reason)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _get_evacuable_flavors(connection):
|
@ -0,0 +1,674 @@
|
|||||||
|
From 59ae9d00060da5329d7ca538974498292bbe1d91 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helen Koike <helen.koike@collabora.com>
|
||||||
|
Date: Tue, 26 Jun 2018 10:18:29 -0300
|
||||||
|
Subject: [PATCH 1/7] fence_gce: add support for stackdriver logging
|
||||||
|
|
||||||
|
Add --logging option to enable sending logs to google stackdriver
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 65 +++++++++++++++++++++++++++++++++++++--
|
||||||
|
tests/data/metadata/fence_gce.xml | 5 +++
|
||||||
|
2 files changed, 67 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index 3abb5207..3af5bfc8 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -1,12 +1,19 @@
|
||||||
|
#!@PYTHON@ -tt
|
||||||
|
|
||||||
|
import atexit
|
||||||
|
+import logging
|
||||||
|
+import platform
|
||||||
|
import sys
|
||||||
|
+import time
|
||||||
|
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
|
||||||
|
import googleapiclient.discovery
|
||||||
|
from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action
|
||||||
|
|
||||||
|
+
|
||||||
|
+LOGGER = logging
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def translate_status(instance_status):
|
||||||
|
"Returns on | off | unknown."
|
||||||
|
if instance_status == "RUNNING":
|
||||||
|
@@ -27,6 +34,7 @@ def get_nodes_list(conn, options):
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
+
|
||||||
|
def get_power_status(conn, options):
|
||||||
|
try:
|
||||||
|
instance = conn.instances().get(
|
||||||
|
@@ -38,18 +46,37 @@ def get_power_status(conn, options):
|
||||||
|
fail_usage("Failed: get_power_status: {}".format(str(err)))
|
||||||
|
|
||||||
|
|
||||||
|
+def wait_for_operation(conn, project, zone, operation):
|
||||||
|
+ while True:
|
||||||
|
+ result = conn.zoneOperations().get(
|
||||||
|
+ project=project,
|
||||||
|
+ zone=zone,
|
||||||
|
+ operation=operation['name']).execute()
|
||||||
|
+ if result['status'] == 'DONE':
|
||||||
|
+ if 'error' in result:
|
||||||
|
+ raise Exception(result['error'])
|
||||||
|
+ return
|
||||||
|
+ time.sleep(1)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def set_power_status(conn, options):
|
||||||
|
try:
|
||||||
|
if options["--action"] == "off":
|
||||||
|
- conn.instances().stop(
|
||||||
|
+ LOGGER.info("Issuing poweroff of %s in zone %s" % (options["--plug"], options["--zone"]))
|
||||||
|
+ operation = conn.instances().stop(
|
||||||
|
project=options["--project"],
|
||||||
|
zone=options["--zone"],
|
||||||
|
instance=options["--plug"]).execute()
|
||||||
|
+ wait_for_operation(conn, options["--project"], options["--zone"], operation)
|
||||||
|
+ LOGGER.info("Poweroff of %s in zone %s complete" % (options["--plug"], options["--zone"]))
|
||||||
|
elif options["--action"] == "on":
|
||||||
|
- conn.instances().start(
|
||||||
|
+ LOGGER.info("Issuing poweron of %s in zone %s" % (options["--plug"], options["--zone"]))
|
||||||
|
+ operation = conn.instances().start(
|
||||||
|
project=options["--project"],
|
||||||
|
zone=options["--zone"],
|
||||||
|
instance=options["--plug"]).execute()
|
||||||
|
+ wait_for_operation(conn, options["--project"], options["--zone"], operation)
|
||||||
|
+ LOGGER.info("Poweron of %s in zone %s complete" % (options["--plug"], options["--zone"]))
|
||||||
|
except Exception as err:
|
||||||
|
fail_usage("Failed: set_power_status: {}".format(str(err)))
|
||||||
|
|
||||||
|
@@ -71,11 +98,24 @@ def define_new_opts():
|
||||||
|
"required" : "1",
|
||||||
|
"order" : 3
|
||||||
|
}
|
||||||
|
+ all_opt["logging"] = {
|
||||||
|
+ "getopt" : ":",
|
||||||
|
+ "longopt" : "logging",
|
||||||
|
+ "help" : "--logging=[bool] Logging, true/false",
|
||||||
|
+ "shortdesc" : "Stackdriver-logging support.",
|
||||||
|
+ "longdesc" : "If enabled (set to true), IP failover logs will be posted to stackdriver logging.",
|
||||||
|
+ "required" : "0",
|
||||||
|
+ "default" : "false",
|
||||||
|
+ "order" : 4
|
||||||
|
+ }
|
||||||
|
|
||||||
|
def main():
|
||||||
|
conn = None
|
||||||
|
+ global LOGGER
|
||||||
|
+
|
||||||
|
+ hostname = platform.node()
|
||||||
|
|
||||||
|
- device_opt = ["port", "no_password", "zone", "project"]
|
||||||
|
+ device_opt = ["port", "no_password", "zone", "project", "logging"]
|
||||||
|
|
||||||
|
atexit.register(atexit_handler)
|
||||||
|
|
||||||
|
@@ -97,6 +137,25 @@ def main():
|
||||||
|
|
||||||
|
run_delay(options)
|
||||||
|
|
||||||
|
+ # Prepare logging
|
||||||
|
+ logging_env = options.get('--logging')
|
||||||
|
+ if logging_env:
|
||||||
|
+ logging_env = logging_env.lower()
|
||||||
|
+ if any(x in logging_env for x in ['yes', 'true', 'enabled']):
|
||||||
|
+ try:
|
||||||
|
+ import google.cloud.logging.handlers
|
||||||
|
+ client = google.cloud.logging.Client()
|
||||||
|
+ handler = google.cloud.logging.handlers.CloudLoggingHandler(client, name=hostname)
|
||||||
|
+ formatter = logging.Formatter('gcp:stonish "%(message)s"')
|
||||||
|
+ LOGGER = logging.getLogger(hostname)
|
||||||
|
+ handler.setFormatter(formatter)
|
||||||
|
+ LOGGER.addHandler(handler)
|
||||||
|
+ LOGGER.setLevel(logging.INFO)
|
||||||
|
+ except ImportError:
|
||||||
|
+ LOGGER.error('Couldn\'t import google.cloud.logging, '
|
||||||
|
+ 'disabling Stackdriver-logging support')
|
||||||
|
+
|
||||||
|
+ # Prepare cli
|
||||||
|
try:
|
||||||
|
credentials = None
|
||||||
|
if tuple(googleapiclient.__version__) < tuple("1.6.0"):
|
||||||
|
diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml
|
||||||
|
index 2a147f21..805ecc6b 100644
|
||||||
|
--- a/tests/data/metadata/fence_gce.xml
|
||||||
|
+++ b/tests/data/metadata/fence_gce.xml
|
||||||
|
@@ -30,6 +30,11 @@ For instructions see: https://cloud.google.com/compute/docs/tutorials/python-gui
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">Project ID.</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
+ <parameter name="logging" unique="0" required="0">
|
||||||
|
+ <getopt mixed="--logging=[bool]" />
|
||||||
|
+ <content type="string" default="false" />
|
||||||
|
+ <shortdesc lang="en">Stackdriver-logging support.</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
<parameter name="quiet" unique="0" required="0">
|
||||||
|
<getopt mixed="-q, --quiet" />
|
||||||
|
<content type="boolean" />
|
||||||
|
|
||||||
|
From bb34acd8b0b150599c393d56dd81a7d8185b27d3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helen Koike <helen.koike@collabora.com>
|
||||||
|
Date: Tue, 26 Jun 2018 10:44:41 -0300
|
||||||
|
Subject: [PATCH 2/7] fence_gce: set project and zone as not required
|
||||||
|
|
||||||
|
Try to retrieve the GCE project if the script is being executed inside a
|
||||||
|
GCE machine if --project is not provided.
|
||||||
|
Try to retrieve the zone automatically from GCE if --zone is not
|
||||||
|
provided.
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 63 +++++++++++++++++++++++++++++++++++++--
|
||||||
|
tests/data/metadata/fence_gce.xml | 4 +--
|
||||||
|
2 files changed, 63 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index 3af5bfc8..e53dc5a6 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -12,6 +12,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
LOGGER = logging
|
||||||
|
+METADATA_SERVER = 'http://metadata.google.internal/computeMetadata/v1/'
|
||||||
|
+METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
|
||||||
|
|
||||||
|
|
||||||
|
def translate_status(instance_status):
|
||||||
|
@@ -81,13 +83,56 @@ def set_power_status(conn, options):
|
||||||
|
fail_usage("Failed: set_power_status: {}".format(str(err)))
|
||||||
|
|
||||||
|
|
||||||
|
+def get_instance(conn, project, zone, instance):
|
||||||
|
+ request = conn.instances().get(
|
||||||
|
+ project=project, zone=zone, instance=instance)
|
||||||
|
+ return request.execute()
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def get_zone(conn, project, instance):
|
||||||
|
+ request = conn.instances().aggregatedList(project=project)
|
||||||
|
+ while request is not None:
|
||||||
|
+ response = request.execute()
|
||||||
|
+ zones = response.get('items', {})
|
||||||
|
+ for zone in zones.values():
|
||||||
|
+ for inst in zone.get('instances', []):
|
||||||
|
+ if inst['name'] == instance:
|
||||||
|
+ return inst['zone'].split("/")[-1]
|
||||||
|
+ request = conn.instances().aggregatedList_next(
|
||||||
|
+ previous_request=request, previous_response=response)
|
||||||
|
+ raise Exception("Unable to find instance %s" % (instance))
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def get_metadata(metadata_key, params=None, timeout=None):
|
||||||
|
+ """Performs a GET request with the metadata headers.
|
||||||
|
+
|
||||||
|
+ Args:
|
||||||
|
+ metadata_key: string, the metadata to perform a GET request on.
|
||||||
|
+ params: dictionary, the query parameters in the GET request.
|
||||||
|
+ timeout: int, timeout in seconds for metadata requests.
|
||||||
|
+
|
||||||
|
+ Returns:
|
||||||
|
+ HTTP response from the GET request.
|
||||||
|
+
|
||||||
|
+ Raises:
|
||||||
|
+ urlerror.HTTPError: raises when the GET request fails.
|
||||||
|
+ """
|
||||||
|
+ timeout = timeout or 60
|
||||||
|
+ metadata_url = os.path.join(METADATA_SERVER, metadata_key)
|
||||||
|
+ params = urlparse.urlencode(params or {})
|
||||||
|
+ url = '%s?%s' % (metadata_url, params)
|
||||||
|
+ request = urlrequest.Request(url, headers=METADATA_HEADERS)
|
||||||
|
+ request_opener = urlrequest.build_opener(urlrequest.ProxyHandler({}))
|
||||||
|
+ return request_opener.open(request, timeout=timeout * 1.1).read()
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def define_new_opts():
|
||||||
|
all_opt["zone"] = {
|
||||||
|
"getopt" : ":",
|
||||||
|
"longopt" : "zone",
|
||||||
|
"help" : "--zone=[name] Zone, e.g. us-central1-b",
|
||||||
|
"shortdesc" : "Zone.",
|
||||||
|
- "required" : "1",
|
||||||
|
+ "required" : "0",
|
||||||
|
"order" : 2
|
||||||
|
}
|
||||||
|
all_opt["project"] = {
|
||||||
|
@@ -95,7 +140,7 @@ def define_new_opts():
|
||||||
|
"longopt" : "project",
|
||||||
|
"help" : "--project=[name] Project ID",
|
||||||
|
"shortdesc" : "Project ID.",
|
||||||
|
- "required" : "1",
|
||||||
|
+ "required" : "0",
|
||||||
|
"order" : 3
|
||||||
|
}
|
||||||
|
all_opt["logging"] = {
|
||||||
|
@@ -109,6 +154,7 @@ def define_new_opts():
|
||||||
|
"order" : 4
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
def main():
|
||||||
|
conn = None
|
||||||
|
global LOGGER
|
||||||
|
@@ -165,6 +211,19 @@ def main():
|
||||||
|
except Exception as err:
|
||||||
|
fail_usage("Failed: Create GCE compute v1 connection: {}".format(str(err)))
|
||||||
|
|
||||||
|
+ # Get project and zone
|
||||||
|
+ if not options.get("--project"):
|
||||||
|
+ try:
|
||||||
|
+ options["--project"] = get_metadata('project/project-id')
|
||||||
|
+ except Exception as err:
|
||||||
|
+ fail_usage("Failed retrieving GCE project. Please provide --project option: {}".format(str(err)))
|
||||||
|
+
|
||||||
|
+ if not options.get("--zone"):
|
||||||
|
+ try:
|
||||||
|
+ options["--zone"] = get_zone(conn, options['--project'], options['--plug'])
|
||||||
|
+ except Exception as err:
|
||||||
|
+ fail_usage("Failed retrieving GCE zone. Please provide --zone option: {}".format(str(err)))
|
||||||
|
+
|
||||||
|
# Operate the fencing device
|
||||||
|
result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
|
||||||
|
sys.exit(result)
|
||||||
|
diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml
|
||||||
|
index 805ecc6b..507b8385 100644
|
||||||
|
--- a/tests/data/metadata/fence_gce.xml
|
||||||
|
+++ b/tests/data/metadata/fence_gce.xml
|
||||||
|
@@ -20,12 +20,12 @@ For instructions see: https://cloud.google.com/compute/docs/tutorials/python-gui
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">Physical plug number on device, UUID or identification of machine</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="zone" unique="0" required="1">
|
||||||
|
+ <parameter name="zone" unique="0" required="0">
|
||||||
|
<getopt mixed="--zone=[name]" />
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">Zone.</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="project" unique="0" required="1">
|
||||||
|
+ <parameter name="project" unique="0" required="0">
|
||||||
|
<getopt mixed="--project=[name]" />
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">Project ID.</shortdesc>
|
||||||
|
|
||||||
|
From 8ae1af8068d1718a861a25bf954e14392384fa55 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helen Koike <helen.koike@collabora.com>
|
||||||
|
Date: Wed, 4 Jul 2018 09:25:46 -0300
|
||||||
|
Subject: [PATCH 3/7] fence_gce: add power cycle as default method
|
||||||
|
|
||||||
|
Add function to power cycle an instance and set cycle as the default
|
||||||
|
method to reboot.
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 21 +++++++++++++++++++--
|
||||||
|
tests/data/metadata/fence_gce.xml | 8 ++++++++
|
||||||
|
2 files changed, 27 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index e53dc5a6..3f77dc24 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -83,6 +83,21 @@ def set_power_status(conn, options):
|
||||||
|
fail_usage("Failed: set_power_status: {}".format(str(err)))
|
||||||
|
|
||||||
|
|
||||||
|
+def power_cycle(conn, options):
|
||||||
|
+ try:
|
||||||
|
+ LOGGER.info('Issuing reset of %s in zone %s' % (options["--plug"], options["--zone"]))
|
||||||
|
+ operation = conn.instances().reset(
|
||||||
|
+ project=options["--project"],
|
||||||
|
+ zone=options["--zone"],
|
||||||
|
+ instance=options["--plug"]).execute()
|
||||||
|
+ wait_for_operation(conn, options["--project"], options["--zone"], operation)
|
||||||
|
+ LOGGER.info('Reset of %s in zone %s complete' % (options["--plug"], options["--zone"]))
|
||||||
|
+ return True
|
||||||
|
+ except Exception as err:
|
||||||
|
+ LOGGER.error("Failed: power_cycle: {}".format(str(err)))
|
||||||
|
+ return False
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def get_instance(conn, project, zone, instance):
|
||||||
|
request = conn.instances().get(
|
||||||
|
project=project, zone=zone, instance=instance)
|
||||||
|
@@ -161,13 +176,15 @@ def main():
|
||||||
|
|
||||||
|
hostname = platform.node()
|
||||||
|
|
||||||
|
- device_opt = ["port", "no_password", "zone", "project", "logging"]
|
||||||
|
+ device_opt = ["port", "no_password", "zone", "project", "logging", "method"]
|
||||||
|
|
||||||
|
atexit.register(atexit_handler)
|
||||||
|
|
||||||
|
define_new_opts()
|
||||||
|
|
||||||
|
all_opt["power_timeout"]["default"] = "60"
|
||||||
|
+ all_opt["method"]["default"] = "cycle"
|
||||||
|
+ all_opt["method"]["help"] = "-m, --method=[method] Method to fence (onoff|cycle) (Default: cycle)"
|
||||||
|
|
||||||
|
options = check_input(device_opt, process_input(device_opt))
|
||||||
|
|
||||||
|
@@ -225,7 +242,7 @@ def main():
|
||||||
|
fail_usage("Failed retrieving GCE zone. Please provide --zone option: {}".format(str(err)))
|
||||||
|
|
||||||
|
# Operate the fencing device
|
||||||
|
- result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
|
||||||
|
+ result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list, power_cycle)
|
||||||
|
sys.exit(result)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml
|
||||||
|
index 507b8385..f522550f 100644
|
||||||
|
--- a/tests/data/metadata/fence_gce.xml
|
||||||
|
+++ b/tests/data/metadata/fence_gce.xml
|
||||||
|
@@ -10,6 +10,14 @@ For instructions see: https://cloud.google.com/compute/docs/tutorials/python-gui
|
||||||
|
<content type="string" default="reboot" />
|
||||||
|
<shortdesc lang="en">Fencing action</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
+ <parameter name="method" unique="0" required="0">
|
||||||
|
+ <getopt mixed="-m, --method=[method]" />
|
||||||
|
+ <content type="select" default="cycle" >
|
||||||
|
+ <option value="onoff" />
|
||||||
|
+ <option value="cycle" />
|
||||||
|
+ </content>
|
||||||
|
+ <shortdesc lang="en">Method to fence</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
<parameter name="plug" unique="0" required="1" obsoletes="port">
|
||||||
|
<getopt mixed="-n, --plug=[id]" />
|
||||||
|
<content type="string" />
|
||||||
|
|
||||||
|
From 68644764695b79a3b75826fe009ea7da675677f7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helen Koike <helen.koike@collabora.com>
|
||||||
|
Date: Thu, 5 Jul 2018 11:04:32 -0300
|
||||||
|
Subject: [PATCH 4/7] fence_gce: add missing imports to retrieve the project
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 9 +++++++++
|
||||||
|
1 file changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index 3f77dc24..9b7b5e55 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -2,9 +2,18 @@
|
||||||
|
|
||||||
|
import atexit
|
||||||
|
import logging
|
||||||
|
+import os
|
||||||
|
import platform
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
+if sys.version_info >= (3, 0):
|
||||||
|
+ # Python 3 imports.
|
||||||
|
+ import urllib.parse as urlparse
|
||||||
|
+ import urllib.request as urlrequest
|
||||||
|
+else:
|
||||||
|
+ # Python 2 imports.
|
||||||
|
+ import urllib as urlparse
|
||||||
|
+ import urllib2 as urlrequest
|
||||||
|
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
|
||||||
|
import googleapiclient.discovery
|
||||||
|
|
||||||
|
From f8f3f11187341622c26e4e439dfda6a37ad660b0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helen Koike <helen.koike@collabora.com>
|
||||||
|
Date: Thu, 5 Jul 2018 11:05:32 -0300
|
||||||
|
Subject: [PATCH 5/7] fence_gce: s/--loging/--stackdriver-logging/
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 42 ++++++++++++++++++---------------------
|
||||||
|
tests/data/metadata/fence_gce.xml | 11 +++++++---
|
||||||
|
2 files changed, 27 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index 9b7b5e55..a6befe39 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -167,14 +167,13 @@ def define_new_opts():
|
||||||
|
"required" : "0",
|
||||||
|
"order" : 3
|
||||||
|
}
|
||||||
|
- all_opt["logging"] = {
|
||||||
|
- "getopt" : ":",
|
||||||
|
- "longopt" : "logging",
|
||||||
|
- "help" : "--logging=[bool] Logging, true/false",
|
||||||
|
+ all_opt["stackdriver-logging"] = {
|
||||||
|
+ "getopt" : "",
|
||||||
|
+ "longopt" : "stackdriver-logging",
|
||||||
|
+ "help" : "--stackdriver-logging Enable Logging to Stackdriver",
|
||||||
|
"shortdesc" : "Stackdriver-logging support.",
|
||||||
|
- "longdesc" : "If enabled (set to true), IP failover logs will be posted to stackdriver logging.",
|
||||||
|
+ "longdesc" : "If enabled IP failover logs will be posted to stackdriver logging.",
|
||||||
|
"required" : "0",
|
||||||
|
- "default" : "false",
|
||||||
|
"order" : 4
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -185,7 +184,7 @@ def main():
|
||||||
|
|
||||||
|
hostname = platform.node()
|
||||||
|
|
||||||
|
- device_opt = ["port", "no_password", "zone", "project", "logging", "method"]
|
||||||
|
+ device_opt = ["port", "no_password", "zone", "project", "stackdriver-logging", "method"]
|
||||||
|
|
||||||
|
atexit.register(atexit_handler)
|
||||||
|
|
||||||
|
@@ -210,22 +209,19 @@ def main():
|
||||||
|
run_delay(options)
|
||||||
|
|
||||||
|
# Prepare logging
|
||||||
|
- logging_env = options.get('--logging')
|
||||||
|
- if logging_env:
|
||||||
|
- logging_env = logging_env.lower()
|
||||||
|
- if any(x in logging_env for x in ['yes', 'true', 'enabled']):
|
||||||
|
- try:
|
||||||
|
- import google.cloud.logging.handlers
|
||||||
|
- client = google.cloud.logging.Client()
|
||||||
|
- handler = google.cloud.logging.handlers.CloudLoggingHandler(client, name=hostname)
|
||||||
|
- formatter = logging.Formatter('gcp:stonish "%(message)s"')
|
||||||
|
- LOGGER = logging.getLogger(hostname)
|
||||||
|
- handler.setFormatter(formatter)
|
||||||
|
- LOGGER.addHandler(handler)
|
||||||
|
- LOGGER.setLevel(logging.INFO)
|
||||||
|
- except ImportError:
|
||||||
|
- LOGGER.error('Couldn\'t import google.cloud.logging, '
|
||||||
|
- 'disabling Stackdriver-logging support')
|
||||||
|
+ if options.get('--stackdriver-logging'):
|
||||||
|
+ try:
|
||||||
|
+ import google.cloud.logging.handlers
|
||||||
|
+ client = google.cloud.logging.Client()
|
||||||
|
+ handler = google.cloud.logging.handlers.CloudLoggingHandler(client, name=hostname)
|
||||||
|
+ formatter = logging.Formatter('gcp:stonish "%(message)s"')
|
||||||
|
+ LOGGER = logging.getLogger(hostname)
|
||||||
|
+ handler.setFormatter(formatter)
|
||||||
|
+ LOGGER.addHandler(handler)
|
||||||
|
+ LOGGER.setLevel(logging.INFO)
|
||||||
|
+ except ImportError:
|
||||||
|
+ LOGGER.error('Couldn\'t import google.cloud.logging, '
|
||||||
|
+ 'disabling Stackdriver-logging support')
|
||||||
|
|
||||||
|
# Prepare cli
|
||||||
|
try:
|
||||||
|
diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml
|
||||||
|
index f522550f..79b82ebb 100644
|
||||||
|
--- a/tests/data/metadata/fence_gce.xml
|
||||||
|
+++ b/tests/data/metadata/fence_gce.xml
|
||||||
|
@@ -38,9 +38,14 @@ For instructions see: https://cloud.google.com/compute/docs/tutorials/python-gui
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">Project ID.</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="logging" unique="0" required="0">
|
||||||
|
- <getopt mixed="--logging=[bool]" />
|
||||||
|
- <content type="string" default="false" />
|
||||||
|
+ <parameter name="stackdriver-logging" unique="0" required="0" deprecated="1">
|
||||||
|
+ <getopt mixed="--stackdriver-logging" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
+ <shortdesc lang="en">Stackdriver-logging support.</shortdesc>
|
||||||
|
+ </parameter>
|
||||||
|
+ <parameter name="stackdriver_logging" unique="0" required="0" obsoletes="stackdriver-logging">
|
||||||
|
+ <getopt mixed="--stackdriver-logging" />
|
||||||
|
+ <content type="boolean" />
|
||||||
|
<shortdesc lang="en">Stackdriver-logging support.</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="quiet" unique="0" required="0">
|
||||||
|
|
||||||
|
From 9ae0a072424fa982e1d18a2cb661628c38601c3a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helen Koike <helen.koike@collabora.com>
|
||||||
|
Date: Sat, 7 Jul 2018 18:42:01 -0300
|
||||||
|
Subject: [PATCH 6/7] fence_gce: use root logger for stackdriver
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 29 +++++++++++++++--------------
|
||||||
|
1 file changed, 15 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index a6befe39..1d5095ae 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -20,7 +20,6 @@
|
||||||
|
from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action
|
||||||
|
|
||||||
|
|
||||||
|
-LOGGER = logging
|
||||||
|
METADATA_SERVER = 'http://metadata.google.internal/computeMetadata/v1/'
|
||||||
|
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
|
||||||
|
|
||||||
|
@@ -73,37 +72,37 @@ def wait_for_operation(conn, project, zone, operation):
|
||||||
|
def set_power_status(conn, options):
|
||||||
|
try:
|
||||||
|
if options["--action"] == "off":
|
||||||
|
- LOGGER.info("Issuing poweroff of %s in zone %s" % (options["--plug"], options["--zone"]))
|
||||||
|
+ logging.info("Issuing poweroff of %s in zone %s" % (options["--plug"], options["--zone"]))
|
||||||
|
operation = conn.instances().stop(
|
||||||
|
project=options["--project"],
|
||||||
|
zone=options["--zone"],
|
||||||
|
instance=options["--plug"]).execute()
|
||||||
|
wait_for_operation(conn, options["--project"], options["--zone"], operation)
|
||||||
|
- LOGGER.info("Poweroff of %s in zone %s complete" % (options["--plug"], options["--zone"]))
|
||||||
|
+ logging.info("Poweroff of %s in zone %s complete" % (options["--plug"], options["--zone"]))
|
||||||
|
elif options["--action"] == "on":
|
||||||
|
- LOGGER.info("Issuing poweron of %s in zone %s" % (options["--plug"], options["--zone"]))
|
||||||
|
+ logging.info("Issuing poweron of %s in zone %s" % (options["--plug"], options["--zone"]))
|
||||||
|
operation = conn.instances().start(
|
||||||
|
project=options["--project"],
|
||||||
|
zone=options["--zone"],
|
||||||
|
instance=options["--plug"]).execute()
|
||||||
|
wait_for_operation(conn, options["--project"], options["--zone"], operation)
|
||||||
|
- LOGGER.info("Poweron of %s in zone %s complete" % (options["--plug"], options["--zone"]))
|
||||||
|
+ logging.info("Poweron of %s in zone %s complete" % (options["--plug"], options["--zone"]))
|
||||||
|
except Exception as err:
|
||||||
|
fail_usage("Failed: set_power_status: {}".format(str(err)))
|
||||||
|
|
||||||
|
|
||||||
|
def power_cycle(conn, options):
|
||||||
|
try:
|
||||||
|
- LOGGER.info('Issuing reset of %s in zone %s' % (options["--plug"], options["--zone"]))
|
||||||
|
+ logging.info('Issuing reset of %s in zone %s' % (options["--plug"], options["--zone"]))
|
||||||
|
operation = conn.instances().reset(
|
||||||
|
project=options["--project"],
|
||||||
|
zone=options["--zone"],
|
||||||
|
instance=options["--plug"]).execute()
|
||||||
|
wait_for_operation(conn, options["--project"], options["--zone"], operation)
|
||||||
|
- LOGGER.info('Reset of %s in zone %s complete' % (options["--plug"], options["--zone"]))
|
||||||
|
+ logging.info('Reset of %s in zone %s complete' % (options["--plug"], options["--zone"]))
|
||||||
|
return True
|
||||||
|
except Exception as err:
|
||||||
|
- LOGGER.error("Failed: power_cycle: {}".format(str(err)))
|
||||||
|
+ logging.error("Failed: power_cycle: {}".format(str(err)))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@@ -180,7 +179,6 @@ def define_new_opts():
|
||||||
|
|
||||||
|
def main():
|
||||||
|
conn = None
|
||||||
|
- global LOGGER
|
||||||
|
|
||||||
|
hostname = platform.node()
|
||||||
|
|
||||||
|
@@ -209,18 +207,21 @@ def main():
|
||||||
|
run_delay(options)
|
||||||
|
|
||||||
|
# Prepare logging
|
||||||
|
- if options.get('--stackdriver-logging'):
|
||||||
|
+ if options.get('--stackdriver-logging') is not None:
|
||||||
|
try:
|
||||||
|
import google.cloud.logging.handlers
|
||||||
|
client = google.cloud.logging.Client()
|
||||||
|
handler = google.cloud.logging.handlers.CloudLoggingHandler(client, name=hostname)
|
||||||
|
+ handler.setLevel(logging.INFO)
|
||||||
|
formatter = logging.Formatter('gcp:stonish "%(message)s"')
|
||||||
|
- LOGGER = logging.getLogger(hostname)
|
||||||
|
handler.setFormatter(formatter)
|
||||||
|
- LOGGER.addHandler(handler)
|
||||||
|
- LOGGER.setLevel(logging.INFO)
|
||||||
|
+ root_logger = logging.getLogger()
|
||||||
|
+ if options.get('--verbose') is None:
|
||||||
|
+ root_logger.setLevel(logging.INFO)
|
||||||
|
+ logging.getLogger("googleapiclient").setLevel(logging.ERROR)
|
||||||
|
+ root_logger.addHandler(handler)
|
||||||
|
except ImportError:
|
||||||
|
- LOGGER.error('Couldn\'t import google.cloud.logging, '
|
||||||
|
+ logging.error('Couldn\'t import google.cloud.logging, '
|
||||||
|
'disabling Stackdriver-logging support')
|
||||||
|
|
||||||
|
# Prepare cli
|
||||||
|
|
||||||
|
From a52e643708908539d6e5fdb5d36a6cea935e4481 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helen Koike <helen.koike@collabora.com>
|
||||||
|
Date: Wed, 11 Jul 2018 17:16:49 -0300
|
||||||
|
Subject: [PATCH 7/7] fence_gce: minor changes in logging
|
||||||
|
|
||||||
|
- Remove hostname (use --plug instead).
|
||||||
|
- Supress messages from googleapiclient and oauth2client if not error in
|
||||||
|
non verbose mode.
|
||||||
|
- s/stonish/stonith
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 13 ++++++-------
|
||||||
|
1 file changed, 6 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index 1d5095ae..3eca0139 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -3,7 +3,6 @@
|
||||||
|
import atexit
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
-import platform
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
if sys.version_info >= (3, 0):
|
||||||
|
@@ -180,8 +179,6 @@ def define_new_opts():
|
||||||
|
def main():
|
||||||
|
conn = None
|
||||||
|
|
||||||
|
- hostname = platform.node()
|
||||||
|
-
|
||||||
|
device_opt = ["port", "no_password", "zone", "project", "stackdriver-logging", "method"]
|
||||||
|
|
||||||
|
atexit.register(atexit_handler)
|
||||||
|
@@ -207,18 +204,20 @@ def main():
|
||||||
|
run_delay(options)
|
||||||
|
|
||||||
|
# Prepare logging
|
||||||
|
- if options.get('--stackdriver-logging') is not None:
|
||||||
|
+ if options.get('--verbose') is None:
|
||||||
|
+ logging.getLogger('googleapiclient').setLevel(logging.ERROR)
|
||||||
|
+ logging.getLogger('oauth2client').setLevel(logging.ERROR)
|
||||||
|
+ if options.get('--stackdriver-logging') is not None and options.get('--plug'):
|
||||||
|
try:
|
||||||
|
import google.cloud.logging.handlers
|
||||||
|
client = google.cloud.logging.Client()
|
||||||
|
- handler = google.cloud.logging.handlers.CloudLoggingHandler(client, name=hostname)
|
||||||
|
+ handler = google.cloud.logging.handlers.CloudLoggingHandler(client, name=options['--plug'])
|
||||||
|
handler.setLevel(logging.INFO)
|
||||||
|
- formatter = logging.Formatter('gcp:stonish "%(message)s"')
|
||||||
|
+ formatter = logging.Formatter('gcp:stonith "%(message)s"')
|
||||||
|
handler.setFormatter(formatter)
|
||||||
|
root_logger = logging.getLogger()
|
||||||
|
if options.get('--verbose') is None:
|
||||||
|
root_logger.setLevel(logging.INFO)
|
||||||
|
- logging.getLogger("googleapiclient").setLevel(logging.ERROR)
|
||||||
|
root_logger.addHandler(handler)
|
||||||
|
except ImportError:
|
||||||
|
logging.error('Couldn\'t import google.cloud.logging, '
|
25
SOURCES/fence_gce-2-filter-aggregatedlist.patch
Normal file
25
SOURCES/fence_gce-2-filter-aggregatedlist.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From 8e801d513b9a500ac0d717476aadc1cdabc0a92e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Helen Koike <helen.koike@collabora.com>
|
||||||
|
Date: Thu, 19 Jul 2018 13:13:53 -0300
|
||||||
|
Subject: [PATCH] fence_gce: filter call to aggregatedList
|
||||||
|
|
||||||
|
Don't list all the instances in the project, filter only the one we are
|
||||||
|
interested in.
|
||||||
|
---
|
||||||
|
agents/gce/fence_gce.py | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
index 3eca0139..93cd1180 100644
|
||||||
|
--- a/agents/gce/fence_gce.py
|
||||||
|
+++ b/agents/gce/fence_gce.py
|
||||||
|
@@ -112,7 +112,8 @@ def get_instance(conn, project, zone, instance):
|
||||||
|
|
||||||
|
|
||||||
|
def get_zone(conn, project, instance):
|
||||||
|
- request = conn.instances().aggregatedList(project=project)
|
||||||
|
+ fl = 'name="%s"' % instance
|
||||||
|
+ request = conn.instances().aggregatedList(project=project, filter=fl)
|
||||||
|
while request is not None:
|
||||||
|
response = request.execute()
|
||||||
|
zones = response.get('items', {})
|
34
SOURCES/fence_gce-3-stackdriver-logging-note.patch
Normal file
34
SOURCES/fence_gce-3-stackdriver-logging-note.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
diff -uNr a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||||
|
--- a/agents/gce/fence_gce.py 2018-07-30 16:09:45.811531118 +0200
|
||||||
|
+++ b/agents/gce/fence_gce.py 2018-07-30 16:31:28.970202508 +0200
|
||||||
|
@@ -174,9 +174,9 @@
|
||||||
|
all_opt["stackdriver-logging"] = {
|
||||||
|
"getopt" : "",
|
||||||
|
"longopt" : "stackdriver-logging",
|
||||||
|
- "help" : "--stackdriver-logging Enable Logging to Stackdriver",
|
||||||
|
- "shortdesc" : "Stackdriver-logging support.",
|
||||||
|
- "longdesc" : "If enabled IP failover logs will be posted to stackdriver logging.",
|
||||||
|
+ "help" : "--stackdriver-logging Enable Logging to Stackdriver. Using stackdriver logging requires additional libraries (google-cloud-logging).",
|
||||||
|
+ "shortdesc" : "Stackdriver-logging support. Requires additional libraries (google-cloud-logging).",
|
||||||
|
+ "longdesc" : "If enabled IP failover logs will be posted to stackdriver logging. Using stackdriver logging requires additional libraries (google-cloud-logging).",
|
||||||
|
"required" : "0",
|
||||||
|
"order" : 4
|
||||||
|
}
|
||||||
|
diff -uNr a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml
|
||||||
|
--- a/tests/data/metadata/fence_gce.xml 2018-07-30 16:09:45.548532576 +0200
|
||||||
|
+++ b/tests/data/metadata/fence_gce.xml 2018-07-30 16:32:05.392988450 +0200
|
||||||
|
@@ -41,12 +41,12 @@
|
||||||
|
<parameter name="stackdriver-logging" unique="0" required="0" deprecated="1">
|
||||||
|
<getopt mixed="--stackdriver-logging" />
|
||||||
|
<content type="boolean" />
|
||||||
|
- <shortdesc lang="en">Stackdriver-logging support.</shortdesc>
|
||||||
|
+ <shortdesc lang="en">Stackdriver-logging support. Requires additional libraries (google-cloud-logging).</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="stackdriver_logging" unique="0" required="0" obsoletes="stackdriver-logging">
|
||||||
|
<getopt mixed="--stackdriver-logging" />
|
||||||
|
<content type="boolean" />
|
||||||
|
- <shortdesc lang="en">Stackdriver-logging support.</shortdesc>
|
||||||
|
+ <shortdesc lang="en">Stackdriver-logging support. Requires additional libraries (google-cloud-logging).</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="quiet" unique="0" required="0">
|
||||||
|
<getopt mixed="-q, --quiet" />
|
@ -0,0 +1,26 @@
|
|||||||
|
From bd1b11884f33f5fce5ca7618c9f87b540592e1b6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 2 Jul 2018 16:36:41 +0200
|
||||||
|
Subject: [PATCH] fence_ilo3/fence_ipmilan: show correct default method (onoff)
|
||||||
|
in help
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/ipmilan/fence_ipmilan.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/agents/ipmilan/fence_ipmilan.py b/agents/ipmilan/fence_ipmilan.py
|
||||||
|
index 453d7365..9610f1c6 100644
|
||||||
|
--- a/agents/ipmilan/fence_ipmilan.py
|
||||||
|
+++ b/agents/ipmilan/fence_ipmilan.py
|
||||||
|
@@ -171,7 +171,7 @@ def main():
|
||||||
|
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" \
|
||||||
|
+ all_opt["method"]["help"] = "-m, --method=[method] Method to fence (onoff|cycle) (Default: onoff)\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."
|
||||||
|
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
33
SOURCES/fence_impilan-fence_ilo_ssh-add-ilo5-support.patch
Normal file
33
SOURCES/fence_impilan-fence_ilo_ssh-add-ilo5-support.patch
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
diff -uNr a/agents/ilo_ssh/fence_ilo_ssh.py b/agents/ilo_ssh/fence_ilo_ssh.py
|
||||||
|
--- a/agents/ilo_ssh/fence_ilo_ssh.py 2018-06-18 12:14:35.000000000 +0200
|
||||||
|
+++ b/agents/ilo_ssh/fence_ilo_ssh.py 2018-06-28 12:26:14.274615003 +0200
|
||||||
|
@@ -54,7 +54,8 @@
|
||||||
|
device via ssh and reboot a specified outlet. "
|
||||||
|
docs["vendorurl"] = "http://www.hp.com"
|
||||||
|
docs["symlink"] = [("fence_ilo3_ssh", "Fence agent for HP iLO3 over SSH"),
|
||||||
|
- ("fence_ilo4_ssh", "Fence agent for HP iLO4 over SSH")]
|
||||||
|
+ ("fence_ilo4_ssh", "Fence agent for HP iLO4 over SSH"),
|
||||||
|
+ ("fence_ilo5_ssh", "Fence agent for HP iLO5 over SSH")]
|
||||||
|
show_docs(options, docs)
|
||||||
|
|
||||||
|
options["eol"] = "\r"
|
||||||
|
diff -uNr a/agents/ipmilan/fence_ipmilan.py b/agents/ipmilan/fence_ipmilan.py
|
||||||
|
--- a/agents/ipmilan/fence_ipmilan.py 2018-06-18 12:14:35.000000000 +0200
|
||||||
|
+++ b/agents/ipmilan/fence_ipmilan.py 2018-06-28 12:26:14.275614990 +0200
|
||||||
|
@@ -169,6 +169,8 @@
|
||||||
|
all_opt["lanplus"]["default"] = "1"
|
||||||
|
elif os.path.basename(sys.argv[0]) == "fence_ilo4":
|
||||||
|
all_opt["lanplus"]["default"] = "1"
|
||||||
|
+ elif os.path.basename(sys.argv[0]) == "fence_ilo5":
|
||||||
|
+ 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" \
|
||||||
|
@@ -187,6 +189,7 @@
|
||||||
|
docs["vendorurl"] = ""
|
||||||
|
docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"),
|
||||||
|
("fence_ilo4", "Fence agent for HP iLO4"),
|
||||||
|
+ ("fence_ilo5", "Fence agent for HP iLO5"),
|
||||||
|
("fence_imm", "Fence agent for IBM Integrated Management Module"),
|
||||||
|
("fence_idrac", "Fence agent for Dell iDRAC")]
|
||||||
|
show_docs(options, docs)
|
36
SOURCES/fence_kdump-fix-strncpy-issue.patch
Normal file
36
SOURCES/fence_kdump-fix-strncpy-issue.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From ac83d8ce3d8dd868b0e887528e7c269cee4dcac8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 31 Jul 2018 15:57:38 +0200
|
||||||
|
Subject: [PATCH] fence_kdump: fix strncpy issue
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/kdump/fence_kdump.c | 2 +-
|
||||||
|
agents/kdump/fence_kdump_send.c | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/kdump/fence_kdump.c b/agents/kdump/fence_kdump.c
|
||||||
|
index e2f3cd80..768a9344 100644
|
||||||
|
--- a/agents/kdump/fence_kdump.c
|
||||||
|
+++ b/agents/kdump/fence_kdump.c
|
||||||
|
@@ -351,7 +351,7 @@ get_options_node (fence_kdump_opts_t *opts)
|
||||||
|
hints.ai_protocol = IPPROTO_UDP;
|
||||||
|
hints.ai_flags = AI_NUMERICSERV;
|
||||||
|
|
||||||
|
- strncpy (node->name, opts->nodename, sizeof (node->name));
|
||||||
|
+ strncpy (node->name, opts->nodename, sizeof (node->name) - 1);
|
||||||
|
snprintf (node->port, sizeof (node->port), "%d", opts->ipport);
|
||||||
|
|
||||||
|
node->info = NULL;
|
||||||
|
diff --git a/agents/kdump/fence_kdump_send.c b/agents/kdump/fence_kdump_send.c
|
||||||
|
index d668bed3..638f8c97 100644
|
||||||
|
--- a/agents/kdump/fence_kdump_send.c
|
||||||
|
+++ b/agents/kdump/fence_kdump_send.c
|
||||||
|
@@ -116,7 +116,7 @@ get_options_node (fence_kdump_opts_t *opts)
|
||||||
|
hints.ai_protocol = IPPROTO_UDP;
|
||||||
|
hints.ai_flags = AI_NUMERICSERV;
|
||||||
|
|
||||||
|
- strncpy (node->name, opts->nodename, sizeof (node->name));
|
||||||
|
+ strncpy (node->name, opts->nodename, sizeof (node->name) - 1);
|
||||||
|
snprintf (node->port, sizeof (node->port), "%d", opts->ipport);
|
||||||
|
|
||||||
|
node->info = NULL;
|
176
SOURCES/fence_mpath-watchdog-support.patch
Normal file
176
SOURCES/fence_mpath-watchdog-support.patch
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
From 199b1efee0ba1f01c27ca689a15465cf4a258ee6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 22 Jan 2018 11:27:28 +0100
|
||||||
|
Subject: [PATCH] fence_mpath: add watchdog support
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/Makefile.am | 11 ++++++++
|
||||||
|
agents/mpath/fence_mpath.py | 50 ++++++++++++++++++++++++++++++++++---
|
||||||
|
configure.ac | 6 +++++
|
||||||
|
make/fencebuild.mk | 2 +-
|
||||||
|
tests/data/metadata/fence_mpath.xml | 2 +-
|
||||||
|
5 files changed, 66 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/Makefile.am b/agents/Makefile.am
|
||||||
|
index 2524a3ab..833d2af5 100644
|
||||||
|
--- a/agents/Makefile.am
|
||||||
|
+++ b/agents/Makefile.am
|
||||||
|
@@ -50,6 +50,11 @@ zvm_fence_zvm_SOURCES = zvm/fence_zvm.c
|
||||||
|
zvm_fence_zvm_CFLAGS = -D_GNU_SOURCE -Izvm
|
||||||
|
endif
|
||||||
|
|
||||||
|
+if BUILD_FENCE_MPATH
|
||||||
|
+mpathdatadir = $(CLUSTERDATA)
|
||||||
|
+mpathdata_SCRIPTS = mpath/fence_mpath_check mpath/fence_mpath_check_hardreboot
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
if BUILD_FENCE_SCSI
|
||||||
|
scsidatadir = $(CLUSTERDATA)
|
||||||
|
scsidata_SCRIPTS = scsi/fence_scsi_check scsi/fence_scsi_check_hardreboot
|
||||||
|
@@ -72,6 +77,12 @@ manual/fence_ack_manual: manual/fence_ack_manual.in
|
||||||
|
-e 's#@clustervarrun@#${CLUSTERVARRUN}#g' \
|
||||||
|
> $@
|
||||||
|
|
||||||
|
+mpath/fence_mpath_check: mpath/fence_mpath
|
||||||
|
+ cp $^ $@
|
||||||
|
+
|
||||||
|
+mpath/fence_mpath_check_hardreboot: mpath/fence_mpath
|
||||||
|
+ cp $^ $@
|
||||||
|
+
|
||||||
|
scsi/fence_scsi_check: scsi/fence_scsi
|
||||||
|
cp $^ $@
|
||||||
|
|
||||||
|
diff --git a/agents/mpath/fence_mpath.py b/agents/mpath/fence_mpath.py
|
||||||
|
index ac5bc794..d9ac2ef5 100644
|
||||||
|
--- a/agents/mpath/fence_mpath.py
|
||||||
|
+++ b/agents/mpath/fence_mpath.py
|
||||||
|
@@ -143,25 +143,63 @@ def dev_write(options, dev):
|
||||||
|
store_fh.write(dev + "\t" + options["--key"] + "\n")
|
||||||
|
store_fh.close()
|
||||||
|
|
||||||
|
-def dev_read(options):
|
||||||
|
+def dev_read(options, fail=True):
|
||||||
|
dev_key = {}
|
||||||
|
file_path = options["--store-path"] + "/mpath.devices"
|
||||||
|
try:
|
||||||
|
store_fh = open(file_path, "r")
|
||||||
|
except IOError:
|
||||||
|
- fail_usage("Failed: Cannot open file \"" + file_path + "\"")
|
||||||
|
+ if fail:
|
||||||
|
+ fail_usage("Failed: Cannot open file \"" + file_path + "\"")
|
||||||
|
+ else:
|
||||||
|
+ return None
|
||||||
|
# get not empty lines from file
|
||||||
|
for (device, key) in [line.strip().split() for line in store_fh if line.strip()]:
|
||||||
|
dev_key[device] = key
|
||||||
|
store_fh.close()
|
||||||
|
return dev_key
|
||||||
|
|
||||||
|
+def mpath_check_get_verbose():
|
||||||
|
+ try:
|
||||||
|
+ f = open("/etc/sysconfig/watchdog", "r")
|
||||||
|
+ except IOError:
|
||||||
|
+ return False
|
||||||
|
+ match = re.search(r"^\s*verbose=yes", "".join(f.readlines()), re.MULTILINE)
|
||||||
|
+ f.close()
|
||||||
|
+ return bool(match)
|
||||||
|
+
|
||||||
|
+def mpath_check(hardreboot=False):
|
||||||
|
+ if len(sys.argv) >= 3 and sys.argv[1] == "repair":
|
||||||
|
+ return int(sys.argv[2])
|
||||||
|
+ options = {}
|
||||||
|
+ options["--mpathpersist-path"] = "/usr/sbin/mpathpersist"
|
||||||
|
+ options["--store-path"] = "/var/run/cluster"
|
||||||
|
+ options["--power-timeout"] = "5"
|
||||||
|
+ if mpath_check_get_verbose():
|
||||||
|
+ logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
+ devs = dev_read(options, fail=False)
|
||||||
|
+ if not devs:
|
||||||
|
+ logging.error("No devices found")
|
||||||
|
+ return 0
|
||||||
|
+ for dev, key in list(devs.items()):
|
||||||
|
+ 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)
|
||||||
|
+ logging.debug("key " + key + " registered with any devices")
|
||||||
|
+
|
||||||
|
+ if hardreboot == True:
|
||||||
|
+ libc = ctypes.cdll['libc.so.6']
|
||||||
|
+ libc.reboot(0x1234567)
|
||||||
|
+ return 2
|
||||||
|
+
|
||||||
|
def define_new_opts():
|
||||||
|
all_opt["devices"] = {
|
||||||
|
"getopt" : "d:",
|
||||||
|
"longopt" : "devices",
|
||||||
|
"help" : "-d, --devices=[devices] List of devices to use for current operation",
|
||||||
|
- "required" : "1",
|
||||||
|
+ "required" : "0",
|
||||||
|
"shortdesc" : "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.",
|
||||||
|
@@ -205,6 +243,12 @@ def main():
|
||||||
|
|
||||||
|
define_new_opts()
|
||||||
|
|
||||||
|
+ # fence_mpath_check
|
||||||
|
+ if os.path.basename(sys.argv[0]) == "fence_mpath_check":
|
||||||
|
+ sys.exit(mpath_check())
|
||||||
|
+ elif os.path.basename(sys.argv[0]) == "fence_mpath_check_hardreboot":
|
||||||
|
+ sys.exit(mpath_check(hardreboot=True))
|
||||||
|
+
|
||||||
|
options = check_input(device_opt, process_input(device_opt), other_conditions=True)
|
||||||
|
|
||||||
|
docs = {}
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index e8b24211..24b857b3 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -148,6 +148,11 @@ if echo "$AGENTS_LIST" | grep -q -E "all|manual"; then
|
||||||
|
AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s/manual( |$)//")
|
||||||
|
fi
|
||||||
|
|
||||||
|
+FENCE_MPATH=0
|
||||||
|
+if echo "$AGENTS_LIST" | grep -q -E "all|mpath"; then
|
||||||
|
+ FENCE_MPATH=1
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
FENCE_SCSI=0
|
||||||
|
if echo "$AGENTS_LIST" | grep -q -E "all|scsi"; then
|
||||||
|
FENCE_SCSI=1
|
||||||
|
@@ -312,6 +317,7 @@ AC_SUBST([SNMPBIN])
|
||||||
|
AC_SUBST([AGENTS_LIST])
|
||||||
|
AM_CONDITIONAL(BUILD_FENCE_KDUMP, test $FENCE_KDUMP -eq 1)
|
||||||
|
AM_CONDITIONAL(BUILD_FENCE_MANUAL, test $FENCE_MANUAL -eq 1)
|
||||||
|
+AM_CONDITIONAL(BUILD_FENCE_MPATH, test $FENCE_MPATH -eq 1)
|
||||||
|
AM_CONDITIONAL(BUILD_FENCE_SCSI, test $FENCE_SCSI -eq 1)
|
||||||
|
AM_CONDITIONAL(BUILD_FENCE_ZVM, test $FENCE_ZVM -eq 1)
|
||||||
|
AM_CONDITIONAL(BUILD_XENAPILIB, test $XENAPILIB -eq 1)
|
||||||
|
diff --git a/make/fencebuild.mk b/make/fencebuild.mk
|
||||||
|
index e08d5200..6a7c6f63 100644
|
||||||
|
--- a/make/fencebuild.mk
|
||||||
|
+++ b/make/fencebuild.mk
|
||||||
|
@@ -51,7 +51,7 @@ $(TARGET):
|
||||||
|
$(call gen_agent_from_py)
|
||||||
|
|
||||||
|
clean: clean-man
|
||||||
|
- rm -f $(CLEAN_TARGET:%.8=%) $(CLEAN_TARGET_ADDITIONAL) $(scsidata_SCRIPTS) */*.pyc *.pyc */*.wiki
|
||||||
|
+ rm -f $(CLEAN_TARGET:%.8=%) $(CLEAN_TARGET_ADDITIONAL) $(mpathdata_SCRIPTS) $(scsidata_SCRIPTS) */*.pyc */*.wiki
|
||||||
|
|
||||||
|
if [ "$(abs_builddir)" = "$(abs_top_builddir)/lib" ]; then \
|
||||||
|
rm -f $(TARGET); \
|
||||||
|
diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml
|
||||||
|
index f384e50b..bbe9ad2b 100644
|
||||||
|
--- a/tests/data/metadata/fence_mpath.xml
|
||||||
|
+++ b/tests/data/metadata/fence_mpath.xml
|
||||||
|
@@ -9,7 +9,7 @@ The fence_mpath agent works by having a unique key for each node that has to be
|
||||||
|
<content type="string" default="off" />
|
||||||
|
<shortdesc lang="en">Fencing action</shortdesc>
|
||||||
|
</parameter>
|
||||||
|
- <parameter name="devices" unique="0" required="1">
|
||||||
|
+ <parameter name="devices" unique="0" required="0">
|
||||||
|
<getopt mixed="-d, --devices=[devices]" />
|
||||||
|
<content type="string" />
|
||||||
|
<shortdesc lang="en">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.</shortdesc>
|
10
SOURCES/fix-version.patch
Normal file
10
SOURCES/fix-version.patch
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
diff -uNr a/.tarball-version b/.tarball-version
|
||||||
|
--- a/.tarball-version 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ b/.tarball-version 2018-08-20 10:42:03.876068353 +0200
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+4.2.1
|
||||||
|
diff -uNr a/.version b/.version
|
||||||
|
--- a/.version 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ b/.version 2018-08-20 10:52:35.712060731 +0200
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+4.2.1
|
74
SOURCES/python3-has_key-fixes.patch
Normal file
74
SOURCES/python3-has_key-fixes.patch
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
From 29f93ed6f7f79cad801bf08ad9172c8a62183435 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 14 Aug 2018 12:33:41 +0200
|
||||||
|
Subject: [PATCH] fence_compute/fence_evacuate/fence_rhevm: dont use has_key
|
||||||
|
(not supported in Python 3)
|
||||||
|
|
||||||
|
---
|
||||||
|
agents/compute/fence_compute.py | 4 ++--
|
||||||
|
agents/evacuate/fence_evacuate.py | 4 ++--
|
||||||
|
agents/rhevm/fence_rhevm.py | 4 ++--
|
||||||
|
3 files changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/agents/compute/fence_compute.py b/agents/compute/fence_compute.py
|
||||||
|
index ec2d093c..254e2670 100644
|
||||||
|
--- a/agents/compute/fence_compute.py
|
||||||
|
+++ b/agents/compute/fence_compute.py
|
||||||
|
@@ -311,7 +311,7 @@ def create_nova_connection(options):
|
||||||
|
region_name=options["--region-name"],
|
||||||
|
endpoint_type=options["--endpoint-type"],
|
||||||
|
session=keystone_session, auth=keystone_auth,
|
||||||
|
- http_log_debug=options.has_key("--verbose"))
|
||||||
|
+ http_log_debug="--verbose" in options)
|
||||||
|
else:
|
||||||
|
# OSP >= 11
|
||||||
|
# ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None)
|
||||||
|
@@ -319,7 +319,7 @@ def create_nova_connection(options):
|
||||||
|
region_name=options["--region-name"],
|
||||||
|
endpoint_type=options["--endpoint-type"],
|
||||||
|
session=keystone_session, auth=keystone_auth,
|
||||||
|
- http_log_debug=options.has_key("--verbose"))
|
||||||
|
+ http_log_debug="--verbose" in options)
|
||||||
|
|
||||||
|
try:
|
||||||
|
nova.hypervisors.list()
|
||||||
|
diff --git a/agents/evacuate/fence_evacuate.py b/agents/evacuate/fence_evacuate.py
|
||||||
|
index 615dede7..6818c44f 100644
|
||||||
|
--- a/agents/evacuate/fence_evacuate.py
|
||||||
|
+++ b/agents/evacuate/fence_evacuate.py
|
||||||
|
@@ -245,7 +245,7 @@ def create_nova_connection(options):
|
||||||
|
region_name=options["--region-name"],
|
||||||
|
endpoint_type=options["--endpoint-type"],
|
||||||
|
session=keystone_session, auth=keystone_auth,
|
||||||
|
- http_log_debug=options.has_key("--verbose"))
|
||||||
|
+ http_log_debug="--verbose" in options)
|
||||||
|
else:
|
||||||
|
# OSP >= 11
|
||||||
|
# ArgSpec(args=['version'], varargs='args', keywords='kwargs', defaults=None)
|
||||||
|
@@ -253,7 +253,7 @@ def create_nova_connection(options):
|
||||||
|
region_name=options["--region-name"],
|
||||||
|
endpoint_type=options["--endpoint-type"],
|
||||||
|
session=keystone_session, auth=keystone_auth,
|
||||||
|
- http_log_debug=options.has_key("--verbose"))
|
||||||
|
+ http_log_debug="--verbose" in options)
|
||||||
|
|
||||||
|
try:
|
||||||
|
nova.hypervisors.list()
|
||||||
|
diff --git a/agents/rhevm/fence_rhevm.py b/agents/rhevm/fence_rhevm.py
|
||||||
|
index 0594e66b..c06b7c39 100644
|
||||||
|
--- a/agents/rhevm/fence_rhevm.py
|
||||||
|
+++ b/agents/rhevm/fence_rhevm.py
|
||||||
|
@@ -74,11 +74,11 @@ def send_command(opt, command, method="GET"):
|
||||||
|
url = "https:"
|
||||||
|
else:
|
||||||
|
url = "http:"
|
||||||
|
- if opt.has_key("--api-path"):
|
||||||
|
+ if "--api-path" in opt:
|
||||||
|
api_path = opt["--api-path"]
|
||||||
|
else:
|
||||||
|
api_path = "/ovirt-engine/api"
|
||||||
|
- if opt.has_key("--disable-http-filter"):
|
||||||
|
+ if "--disable-http-filter" in opt:
|
||||||
|
http_filter = 'false'
|
||||||
|
else:
|
||||||
|
http_filter = 'true'
|
1191
SPECS/fence-agents.spec
Normal file
1191
SPECS/fence-agents.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user