import fence-agents-4.2.1-88.el8
This commit is contained in:
parent
e281264d6d
commit
c364d436e4
@ -1,5 +1,38 @@
|
||||
3297473a9d57e93ff378eab173990c1b64673c01 SOURCES/Jinja2-3.0.2.tar.gz
|
||||
e1b766b2b1601fde67b3b19ed2f13b9746bb1cca SOURCES/MarkupSafe-2.0.1.tar.gz
|
||||
a8c40a3ae9d4c159382a58db3153d83e5521c51e SOURCES/PyYAML-6.0.tar.gz
|
||||
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
|
||||
2512ff4ef016cad0b916006f6acf2a309f908c4d SOURCES/botocore-1.23.46.tar.gz
|
||||
0d12f48faa727f0979e9ad5c4c80dfa32b73caff SOURCES/cachetools-4.2.4.tar.gz
|
||||
b13e22d55867e2ca5f92e5289cfdc21ba6e343aa SOURCES/certifi-2021.10.8.tar.gz
|
||||
2384f6cfba4685d901262e073a4455d4cf76d102 SOURCES/chardet-4.0.0.tar.gz
|
||||
865df92e66e5dc7b940144cbad8115c07dc8784f SOURCES/charset-normalizer-2.0.7.tar.gz
|
||||
e2561df8e7ff9113dab118a651371dd88dab0142 SOURCES/fence-agents-4.2.1.tar.gz
|
||||
f4e578dc0ed68d6667d7b36cdfc2647d55e9858f SOURCES/google-auth-2.3.0.tar.gz
|
||||
74ec77d2e2ef6b2ef8503e6e398faa6f3ba298ae SOURCES/httplib2-0.19.1-py3-none-any.whl
|
||||
08c0449533fc94462f78652dea209099754d9ee4 SOURCES/idna-3.3.tar.gz
|
||||
356c48dfea2214dd9e7e2b222a99dddfe9c0d05c SOURCES/jmespath-0.10.0.tar.gz
|
||||
d06a9547b1a87e9c51b0a7c708189d993f2e3d89 SOURCES/kubernetes-12.0.1.tar.gz
|
||||
f6efa66f6106b069b5c0e0cf8cc677e4e96c91ca SOURCES/oauthlib-3.1.1.tar.gz
|
||||
570d69d8c108ebb8aee562389d13b07dfb61ce25 SOURCES/openshift-0.12.1.tar.gz
|
||||
bccbc1bf76a9db46998eb8e1ffa2f2a2baf9237a SOURCES/packaging-21.2-py3-none-any.whl
|
||||
e0fa19f8fda46a1fa2253477499b116b33f67175 SOURCES/pyasn1-0.4.8.tar.gz
|
||||
43b89feb6864fe359aae89120627165219de313b SOURCES/pyasn1-modules-0.2.8.tar.gz
|
||||
326a73f58a62ebee00c11a12cfdd838b196e0e8e SOURCES/pycryptodome-3.6.4.tar.gz
|
||||
c8307f47e3b75a2d02af72982a2dfefa3f56e407 SOURCES/pyparsing-2.4.7-py2.py3-none-any.whl
|
||||
6082312a090f5be5e796e0854294da0738ec0379 SOURCES/pyparsing-3.0.1.tar.gz
|
||||
c2ba10c775b7a52a4b57cac4d4110a0c0f812a82 SOURCES/python-dateutil-2.8.2.tar.gz
|
||||
1dc2fa004aa6517f1620e55d8a7b8e68a9cf2a47 SOURCES/python-string-utils-1.0.0.tar.gz
|
||||
8c7a89d183d3e9b70bf91ba5b75eccf7111b9d8d SOURCES/requests-2.26.0.tar.gz
|
||||
f139aed770519b6a095b8fdc888d03955cbe9d8e SOURCES/requests-oauthlib-1.3.0.tar.gz
|
||||
e8a53067e03fe1b6682fd99a40a7359396a06daa SOURCES/rsa-4.7.2.tar.gz
|
||||
d1011ff44cd5a045de0460c1b79ec65592e86860 SOURCES/ruamel.yaml-0.17.16.tar.gz
|
||||
27de97227bbbde5a9f571f9fad223578d7bdf7cc SOURCES/ruamel.yaml.clib-0.2.6.tar.gz
|
||||
d5354718cb8c9330d3abc27445467ce8a5ed9d70 SOURCES/setuptools-58.3.0.tar.gz
|
||||
a4f02fddae697614e356cadfddb6241cc7737f38 SOURCES/setuptools_scm-6.3.2.tar.gz
|
||||
06fa0bb50f2a4e2917fd14c21e9d2d5508ce0163 SOURCES/six-1.16.0.tar.gz
|
||||
b42b7960047441db7dc021cc20e14279bd836f8d SOURCES/tomli-1.0.1.tar.gz
|
||||
eb35c3fd8b0867ae988a15917d6b80e8bdf60222 SOURCES/urllib3-1.26.7.tar.gz
|
||||
540f083782c584989c1a0f69ffd69ba7aae07db6 SOURCES/websocket-client-1.2.1.tar.gz
|
||||
|
33
.gitignore
vendored
33
.gitignore
vendored
@ -1,5 +1,38 @@
|
||||
SOURCES/Jinja2-3.0.2.tar.gz
|
||||
SOURCES/MarkupSafe-2.0.1.tar.gz
|
||||
SOURCES/PyYAML-6.0.tar.gz
|
||||
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/botocore-1.23.46.tar.gz
|
||||
SOURCES/cachetools-4.2.4.tar.gz
|
||||
SOURCES/certifi-2021.10.8.tar.gz
|
||||
SOURCES/chardet-4.0.0.tar.gz
|
||||
SOURCES/charset-normalizer-2.0.7.tar.gz
|
||||
SOURCES/fence-agents-4.2.1.tar.gz
|
||||
SOURCES/google-auth-2.3.0.tar.gz
|
||||
SOURCES/httplib2-0.19.1-py3-none-any.whl
|
||||
SOURCES/idna-3.3.tar.gz
|
||||
SOURCES/jmespath-0.10.0.tar.gz
|
||||
SOURCES/kubernetes-12.0.1.tar.gz
|
||||
SOURCES/oauthlib-3.1.1.tar.gz
|
||||
SOURCES/openshift-0.12.1.tar.gz
|
||||
SOURCES/packaging-21.2-py3-none-any.whl
|
||||
SOURCES/pyasn1-0.4.8.tar.gz
|
||||
SOURCES/pyasn1-modules-0.2.8.tar.gz
|
||||
SOURCES/pycryptodome-3.6.4.tar.gz
|
||||
SOURCES/pyparsing-2.4.7-py2.py3-none-any.whl
|
||||
SOURCES/pyparsing-3.0.1.tar.gz
|
||||
SOURCES/python-dateutil-2.8.2.tar.gz
|
||||
SOURCES/python-string-utils-1.0.0.tar.gz
|
||||
SOURCES/requests-2.26.0.tar.gz
|
||||
SOURCES/requests-oauthlib-1.3.0.tar.gz
|
||||
SOURCES/rsa-4.7.2.tar.gz
|
||||
SOURCES/ruamel.yaml-0.17.16.tar.gz
|
||||
SOURCES/ruamel.yaml.clib-0.2.6.tar.gz
|
||||
SOURCES/setuptools-58.3.0.tar.gz
|
||||
SOURCES/setuptools_scm-6.3.2.tar.gz
|
||||
SOURCES/six-1.16.0.tar.gz
|
||||
SOURCES/tomli-1.0.1.tar.gz
|
||||
SOURCES/urllib3-1.26.7.tar.gz
|
||||
SOURCES/websocket-client-1.2.1.tar.gz
|
||||
|
198
SOURCES/bz1470827-all-agents-log-exceptions-fail.patch
Normal file
198
SOURCES/bz1470827-all-agents-log-exceptions-fail.patch
Normal file
@ -0,0 +1,198 @@
|
||||
From bf32059e26f6a7d019df0f7949ce66adf997bc21 Mon Sep 17 00:00:00 2001
|
||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||
Date: Fri, 8 Feb 2019 14:16:31 +0100
|
||||
Subject: [PATCH] log exceptions to be more detailed when failing
|
||||
|
||||
---
|
||||
agents/apc/fence_apc.py | 6 ++++--
|
||||
agents/cisco_ucs/fence_cisco_ucs.py | 3 ++-
|
||||
agents/eps/fence_eps.py | 3 ++-
|
||||
agents/ilo_moonshot/fence_ilo_moonshot.py | 3 ++-
|
||||
agents/lpar/fence_lpar.py | 6 ++++--
|
||||
agents/ovh/fence_ovh.py | 3 ++-
|
||||
agents/sanbox2/fence_sanbox2.py | 12 ++++++++----
|
||||
agents/vmware_soap/fence_vmware_soap.py | 9 ++++++---
|
||||
8 files changed, 30 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/agents/apc/fence_apc.py b/agents/apc/fence_apc.py
|
||||
index 24a5a4232..dd0287f83 100644
|
||||
--- a/agents/apc/fence_apc.py
|
||||
+++ b/agents/apc/fence_apc.py
|
||||
@@ -90,7 +90,8 @@ def get_power_status(conn, options):
|
||||
try:
|
||||
(_, status) = outlets[options["--plug"]]
|
||||
return status.lower().strip()
|
||||
- except KeyError:
|
||||
+ except KeyError as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_STATUS)
|
||||
|
||||
def set_power_status(conn, options):
|
||||
@@ -199,7 +200,8 @@ def get_power_status5(conn, options):
|
||||
try:
|
||||
(_, status) = outlets[options["--plug"]]
|
||||
return status.lower().strip()
|
||||
- except KeyError:
|
||||
+ except KeyError as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_STATUS)
|
||||
|
||||
def set_power_status5(conn, options):
|
||||
diff --git a/agents/cisco_ucs/fence_cisco_ucs.py b/agents/cisco_ucs/fence_cisco_ucs.py
|
||||
index ec3117548..2280dbbc7 100644
|
||||
--- a/agents/cisco_ucs/fence_cisco_ucs.py
|
||||
+++ b/agents/cisco_ucs/fence_cisco_ucs.py
|
||||
@@ -174,7 +174,8 @@ def main():
|
||||
if result == None:
|
||||
## Cookie is absenting in response
|
||||
fail(EC_LOGIN_DENIED)
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_LOGIN_DENIED)
|
||||
|
||||
options_global["cookie"] = result.group(1)
|
||||
diff --git a/agents/eps/fence_eps.py b/agents/eps/fence_eps.py
|
||||
index 74c89b95b..f0df86231 100644
|
||||
--- a/agents/eps/fence_eps.py
|
||||
+++ b/agents/eps/fence_eps.py
|
||||
@@ -56,7 +56,8 @@ def eps_run_command(options, params):
|
||||
conn.close()
|
||||
except socket.timeout:
|
||||
fail(EC_TIMED_OUT)
|
||||
- except socket.error:
|
||||
+ except socket.error as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_LOGIN_DENIED)
|
||||
|
||||
return result
|
||||
diff --git a/agents/ilo_moonshot/fence_ilo_moonshot.py b/agents/ilo_moonshot/fence_ilo_moonshot.py
|
||||
index a066a9c91..6f5cca320 100644
|
||||
--- a/agents/ilo_moonshot/fence_ilo_moonshot.py
|
||||
+++ b/agents/ilo_moonshot/fence_ilo_moonshot.py
|
||||
@@ -21,7 +21,8 @@ def get_power_status(conn, options):
|
||||
try:
|
||||
(_, status) = nodes[options["--plug"]]
|
||||
return status.lower()
|
||||
- except KeyError:
|
||||
+ except KeyError as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_STATUS)
|
||||
|
||||
def set_power_status(conn, options):
|
||||
diff --git a/agents/lpar/fence_lpar.py b/agents/lpar/fence_lpar.py
|
||||
index a16103733..66cb65e41 100644
|
||||
--- a/agents/lpar/fence_lpar.py
|
||||
+++ b/agents/lpar/fence_lpar.py
|
||||
@@ -37,7 +37,8 @@ def get_power_status(conn, options):
|
||||
try:
|
||||
status = re.compile("^" + options["--plug"] + ",(.*?),.*$",
|
||||
re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
|
||||
- except AttributeError:
|
||||
+ except AttributeError as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_STATUS_HMC)
|
||||
elif options["--hmc-version"] in ["4", "IVM"]:
|
||||
conn.send("lssyscfg -r lpar -m "+ options["--managed"] +
|
||||
@@ -49,7 +50,8 @@ def get_power_status(conn, options):
|
||||
|
||||
try:
|
||||
status = re.compile(",state=(.*?),", re.IGNORECASE).search(conn.before).group(1)
|
||||
- except AttributeError:
|
||||
+ except AttributeError as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_STATUS_HMC)
|
||||
|
||||
return _normalize_status(status)
|
||||
diff --git a/agents/ovh/fence_ovh.py b/agents/ovh/fence_ovh.py
|
||||
index f5403c54d..2b7eb864f 100644
|
||||
--- a/agents/ovh/fence_ovh.py
|
||||
+++ b/agents/ovh/fence_ovh.py
|
||||
@@ -66,7 +66,8 @@ def soap_login(options):
|
||||
try:
|
||||
soap = Client(url, doctor=d)
|
||||
session = soap.service.login(options["--username"], options["--password"], 'en', 0)
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_LOGIN_DENIED)
|
||||
|
||||
options["session"] = session
|
||||
diff --git a/agents/sanbox2/fence_sanbox2.py b/agents/sanbox2/fence_sanbox2.py
|
||||
index 679d1d983..179fe0e8b 100644
|
||||
--- a/agents/sanbox2/fence_sanbox2.py
|
||||
+++ b/agents/sanbox2/fence_sanbox2.py
|
||||
@@ -28,7 +28,8 @@ def get_power_status(conn, options):
|
||||
conn.send_eol("admin end")
|
||||
conn.send_eol("exit")
|
||||
conn.close()
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
pass
|
||||
fail(EC_TIMED_OUT)
|
||||
|
||||
@@ -54,7 +55,8 @@ def set_power_status(conn, options):
|
||||
conn.send_eol("admin end")
|
||||
conn.send_eol("exit")
|
||||
conn.close()
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
pass
|
||||
fail(EC_TIMED_OUT)
|
||||
|
||||
@@ -66,7 +68,8 @@ def set_power_status(conn, options):
|
||||
conn.send_eol("admin end")
|
||||
conn.send_eol("exit")
|
||||
conn.close()
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
pass
|
||||
fail(EC_TIMED_OUT)
|
||||
|
||||
@@ -91,7 +94,8 @@ def get_list_devices(conn, options):
|
||||
conn.send_eol("admin end")
|
||||
conn.send_eol("exit")
|
||||
conn.close()
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
pass
|
||||
fail(EC_TIMED_OUT)
|
||||
|
||||
diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py
|
||||
index f2ab68b02..a7f08b3d6 100644
|
||||
--- a/agents/vmware_soap/fence_vmware_soap.py
|
||||
+++ b/agents/vmware_soap/fence_vmware_soap.py
|
||||
@@ -68,7 +68,8 @@ def soap_login(options):
|
||||
conn.service.Login(mo_SessionManager, options["--username"], options["--password"])
|
||||
except requests.exceptions.SSLError as ex:
|
||||
fail_usage("Server side certificate verification failed: %s" % ex)
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Server side certificate verification failed: {}".format(str(e)))
|
||||
fail(EC_LOGIN_DENIED)
|
||||
|
||||
options["ServiceContent"] = ServiceContent
|
||||
@@ -126,7 +127,8 @@ def get_power_status(conn, options):
|
||||
|
||||
try:
|
||||
raw_machines = conn.service.RetrievePropertiesEx(mo_PropertyCollector, propFilterSpec)
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_STATUS)
|
||||
|
||||
(machines, uuid, mappingToUUID) = process_results(raw_machines, {}, {}, {})
|
||||
@@ -135,7 +137,8 @@ def get_power_status(conn, options):
|
||||
while hasattr(raw_machines, 'token'):
|
||||
try:
|
||||
raw_machines = conn.service.ContinueRetrievePropertiesEx(mo_PropertyCollector, raw_machines.token)
|
||||
- except Exception:
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed: {}".format(str(e)))
|
||||
fail(EC_STATUS)
|
||||
(more_machines, more_uuid, more_mappingToUUID) = process_results(raw_machines, {}, {}, {})
|
||||
machines.update(more_machines)
|
@ -0,0 +1,740 @@
|
||||
From 3078e4d55d3bad2bbf9309785fdb2b53afac8d65 Mon Sep 17 00:00:00 2001
|
||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||
Date: Tue, 13 Jul 2021 13:39:33 +0200
|
||||
Subject: [PATCH] fence_ibm_vpc/fence_ibm_powervs: new fence agents
|
||||
|
||||
---
|
||||
agents/ibm_powervs/fence_ibm_powervs.py | 202 +++++++++++++++++++
|
||||
agents/ibm_vpc/fence_ibm_vpc.py | 230 ++++++++++++++++++++++
|
||||
tests/data/metadata/fence_ibm_powervs.xml | 134 +++++++++++++
|
||||
tests/data/metadata/fence_ibm_vpc.xml | 134 +++++++++++++
|
||||
5 files changed, 724 insertions(+)
|
||||
create mode 100755 agents/ibm_powervs/fence_ibm_powervs.py
|
||||
create mode 100755 agents/ibm_vpc/fence_ibm_vpc.py
|
||||
create mode 100644 tests/data/metadata/fence_ibm_powervs.xml
|
||||
create mode 100644 tests/data/metadata/fence_ibm_vpc.xml
|
||||
|
||||
diff --git a/agents/ibm_powervs/fence_ibm_powervs.py b/agents/ibm_powervs/fence_ibm_powervs.py
|
||||
new file mode 100755
|
||||
index 000000000..6649771ea
|
||||
--- /dev/null
|
||||
+++ b/agents/ibm_powervs/fence_ibm_powervs.py
|
||||
@@ -0,0 +1,202 @@
|
||||
+#!@PYTHON@ -tt
|
||||
+
|
||||
+import sys
|
||||
+import pycurl, io, json
|
||||
+import logging
|
||||
+import atexit
|
||||
+sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||
+from fencing import *
|
||||
+from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS
|
||||
+
|
||||
+state = {
|
||||
+ "ACTIVE": "on",
|
||||
+ "SHUTOFF": "off",
|
||||
+ "ERROR": "unknown"
|
||||
+}
|
||||
+
|
||||
+def get_list(conn, options):
|
||||
+ outlets = {}
|
||||
+
|
||||
+ try:
|
||||
+ command = "cloud-instances/{}/pvm-instances".format(options["--instance"])
|
||||
+ res = send_command(conn, command)
|
||||
+ except Exception as e:
|
||||
+ logging.debug("Failed: {}".format(e))
|
||||
+ return outlets
|
||||
+
|
||||
+ for r in res["pvmInstances"]:
|
||||
+ if "--verbose" in options:
|
||||
+ logging.debug(json.dumps(r, indent=2))
|
||||
+ outlets[r["pvmInstanceID"]] = (r["serverName"], state[r["status"]])
|
||||
+
|
||||
+ return outlets
|
||||
+
|
||||
+def get_power_status(conn, options):
|
||||
+ try:
|
||||
+ command = "cloud-instances/{}/pvm-instances/{}".format(
|
||||
+ options["--instance"], options["--plug"])
|
||||
+ res = send_command(conn, command)
|
||||
+ result = get_list(conn, options)[options["--plug"]][1]
|
||||
+ except KeyError as e:
|
||||
+ logging.debug("Failed: Unable to get status for {}".format(e))
|
||||
+ fail(EC_STATUS)
|
||||
+
|
||||
+ return result
|
||||
+
|
||||
+def set_power_status(conn, options):
|
||||
+ action = {
|
||||
+ "on" : '{"action" : "start"}',
|
||||
+ "off" : '{"action" : "immediate-shutdown"}',
|
||||
+ }[options["--action"]]
|
||||
+
|
||||
+ try:
|
||||
+ send_command(conn, "cloud-instances/{}/pvm-instances/{}/action".format(
|
||||
+ options["--instance"], options["--plug"]), "POST", action)
|
||||
+ except Exception as e:
|
||||
+ logging.debug("Failed: Unable to set power to {} for {}".format(options["--action"], e))
|
||||
+ fail(EC_STATUS)
|
||||
+
|
||||
+def connect(opt):
|
||||
+ conn = pycurl.Curl()
|
||||
+
|
||||
+ ## setup correct URL
|
||||
+ conn.base_url = "https://" + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/"
|
||||
+
|
||||
+ if opt["--verbose-level"] > 1:
|
||||
+ conn.setopt(pycurl.VERBOSE, 1)
|
||||
+
|
||||
+ conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
|
||||
+ conn.setopt(pycurl.SSL_VERIFYPEER, 1)
|
||||
+ conn.setopt(pycurl.SSL_VERIFYHOST, 2)
|
||||
+
|
||||
+ # set auth token for later requests
|
||||
+ conn.setopt(pycurl.HTTPHEADER, [
|
||||
+ "Content-Type: application/json",
|
||||
+ "Authorization: Bearer {}".format(opt["--token"]),
|
||||
+ "CRN: {}".format(opt["--crn"]),
|
||||
+ "User-Agent: curl",
|
||||
+ ])
|
||||
+
|
||||
+ return conn
|
||||
+
|
||||
+def disconnect(conn):
|
||||
+ conn.close()
|
||||
+
|
||||
+def send_command(conn, command, method="GET", action=None):
|
||||
+ url = conn.base_url + command
|
||||
+
|
||||
+ conn.setopt(pycurl.URL, url.encode("ascii"))
|
||||
+
|
||||
+ web_buffer = io.BytesIO()
|
||||
+
|
||||
+ if method == "GET":
|
||||
+ conn.setopt(pycurl.POST, 0)
|
||||
+ if method == "POST":
|
||||
+ conn.setopt(pycurl.POSTFIELDS, action)
|
||||
+ if method == "DELETE":
|
||||
+ conn.setopt(pycurl.CUSTOMREQUEST, "DELETE")
|
||||
+
|
||||
+ conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
|
||||
+
|
||||
+ try:
|
||||
+ conn.perform()
|
||||
+ except Exception as e:
|
||||
+ raise(e)
|
||||
+
|
||||
+ rc = conn.getinfo(pycurl.HTTP_CODE)
|
||||
+ result = web_buffer.getvalue().decode("UTF-8")
|
||||
+
|
||||
+ web_buffer.close()
|
||||
+
|
||||
+ if rc != 200:
|
||||
+ if len(result) > 0:
|
||||
+ raise Exception("{}: {}".format(rc,
|
||||
+ result["value"]["messages"][0]["default_message"]))
|
||||
+ else:
|
||||
+ raise Exception("Remote returned {} for request to {}".format(rc, url))
|
||||
+
|
||||
+ if len(result) > 0:
|
||||
+ result = json.loads(result)
|
||||
+
|
||||
+ logging.debug("url: {}".format(url))
|
||||
+ logging.debug("method: {}".format(method))
|
||||
+ logging.debug("response code: {}".format(rc))
|
||||
+ logging.debug("result: {}\n".format(result))
|
||||
+
|
||||
+ return result
|
||||
+
|
||||
+def define_new_opts():
|
||||
+ all_opt["token"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "token",
|
||||
+ "help" : "--token=[token] Bearer Token",
|
||||
+ "required" : "1",
|
||||
+ "shortdesc" : "Bearer Token",
|
||||
+ "order" : 0
|
||||
+ }
|
||||
+ all_opt["crn"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "crn",
|
||||
+ "help" : "--crn=[crn] CRN",
|
||||
+ "required" : "1",
|
||||
+ "shortdesc" : "CRN",
|
||||
+ "order" : 0
|
||||
+ }
|
||||
+ all_opt["instance"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "instance",
|
||||
+ "help" : "--instance=[instance] PowerVS Instance",
|
||||
+ "required" : "1",
|
||||
+ "shortdesc" : "PowerVS Instance",
|
||||
+ "order" : 0
|
||||
+ }
|
||||
+ all_opt["region"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "region",
|
||||
+ "help" : "--region=[region] Region",
|
||||
+ "required" : "1",
|
||||
+ "shortdesc" : "Region",
|
||||
+ "order" : 0
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+def main():
|
||||
+ device_opt = [
|
||||
+ "token",
|
||||
+ "crn",
|
||||
+ "instance",
|
||||
+ "region",
|
||||
+ "port",
|
||||
+ "no_password",
|
||||
+ ]
|
||||
+
|
||||
+ atexit.register(atexit_handler)
|
||||
+ define_new_opts()
|
||||
+
|
||||
+ all_opt["shell_timeout"]["default"] = "15"
|
||||
+ all_opt["power_timeout"]["default"] = "30"
|
||||
+ all_opt["power_wait"]["default"] = "1"
|
||||
+
|
||||
+ options = check_input(device_opt, process_input(device_opt))
|
||||
+
|
||||
+ docs = {}
|
||||
+ docs["shortdesc"] = "Fence agent for IBM PowerVS"
|
||||
+ docs["longdesc"] = """fence_ibm_powervs is an I/O Fencing agent which can be \
|
||||
+used with IBM PowerVS to fence virtual machines."""
|
||||
+ docs["vendorurl"] = "https://www.ibm.com"
|
||||
+ show_docs(options, docs)
|
||||
+
|
||||
+ ####
|
||||
+ ## Fence operations
|
||||
+ ####
|
||||
+ run_delay(options)
|
||||
+
|
||||
+ conn = connect(options)
|
||||
+ atexit.register(disconnect, conn)
|
||||
+
|
||||
+ result = fence_action(conn, options, set_power_status, get_power_status, get_list)
|
||||
+
|
||||
+ sys.exit(result)
|
||||
+
|
||||
+if __name__ == "__main__":
|
||||
+ main()
|
||||
diff --git a/agents/ibm_vpc/fence_ibm_vpc.py b/agents/ibm_vpc/fence_ibm_vpc.py
|
||||
new file mode 100755
|
||||
index 000000000..9f84f7b2d
|
||||
--- /dev/null
|
||||
+++ b/agents/ibm_vpc/fence_ibm_vpc.py
|
||||
@@ -0,0 +1,230 @@
|
||||
+#!@PYTHON@ -tt
|
||||
+
|
||||
+import sys
|
||||
+import pycurl, io, json
|
||||
+import logging
|
||||
+import atexit
|
||||
+sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||
+from fencing import *
|
||||
+from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS
|
||||
+
|
||||
+state = {
|
||||
+ "running": "on",
|
||||
+ "stopped": "off",
|
||||
+ "starting": "unknown",
|
||||
+ "stopping": "unknown",
|
||||
+ "restarting": "unknown",
|
||||
+ "pending": "unknown",
|
||||
+}
|
||||
+
|
||||
+def get_list(conn, options):
|
||||
+ outlets = {}
|
||||
+
|
||||
+ try:
|
||||
+ command = "instances?version=2021-05-25&generation=2&limit={}".format(options["--limit"])
|
||||
+ res = send_command(conn, command)
|
||||
+ except Exception as e:
|
||||
+ logging.debug("Failed: Unable to get list: {}".format(e))
|
||||
+ return outlets
|
||||
+
|
||||
+ for r in res["instances"]:
|
||||
+ if options["--verbose-level"] > 1:
|
||||
+ logging.debug("Node:\n{}".format(json.dumps(r, indent=2)))
|
||||
+ logging.debug("Status: " + state[r["status"]])
|
||||
+ outlets[r["id"]] = (r["name"], state[r["status"]])
|
||||
+
|
||||
+ return outlets
|
||||
+
|
||||
+def get_power_status(conn, options):
|
||||
+ try:
|
||||
+ command = "instances/{}?version=2021-05-25&generation=2".format(options["--plug"])
|
||||
+ res = send_command(conn, command)
|
||||
+ result = state[res["status"]]
|
||||
+ if options["--verbose-level"] > 1:
|
||||
+ logging.debug("Result:\n{}".format(json.dumps(res, indent=2)))
|
||||
+ logging.debug("Status: " + result)
|
||||
+ except Exception as e:
|
||||
+ logging.debug("Failed: Unable to get status for {}: {}".format(options["--plug"], e))
|
||||
+ fail(EC_STATUS)
|
||||
+
|
||||
+ return result
|
||||
+
|
||||
+def set_power_status(conn, options):
|
||||
+ action = {
|
||||
+ "on" : '{"type" : "start"}',
|
||||
+ "off" : '{"type" : "stop"}',
|
||||
+ }[options["--action"]]
|
||||
+
|
||||
+ try:
|
||||
+ command = "instances/{}/actions?version=2021-05-25&generation=2".format(options["--plug"])
|
||||
+ send_command(conn, command, "POST", action, 201)
|
||||
+ except Exception as e:
|
||||
+ logging.debug("Failed: Unable to set power to {} for {}".format(options["--action"], e))
|
||||
+ fail(EC_STATUS)
|
||||
+
|
||||
+def get_bearer_token(conn, options):
|
||||
+ token = None
|
||||
+ try:
|
||||
+ conn.setopt(pycurl.HTTPHEADER, [
|
||||
+ "Content-Type: application/x-www-form-urlencoded",
|
||||
+ "User-Agent: curl",
|
||||
+ ])
|
||||
+ token = send_command(conn, "https://iam.cloud.ibm.com/identity/token", "POST", "grant_type=urn:ibm:params:oauth:grant-type:apikey&apikey={}".format(options["--apikey"]))["access_token"]
|
||||
+ except Exception:
|
||||
+ logging.error("Failed: Unable to authenticate")
|
||||
+ fail(EC_LOGIN_DENIED)
|
||||
+
|
||||
+ return token
|
||||
+
|
||||
+def connect(opt):
|
||||
+ conn = pycurl.Curl()
|
||||
+
|
||||
+ ## setup correct URL
|
||||
+ conn.base_url = "https://" + opt["--region"] + ".iaas.cloud.ibm.com/v1/"
|
||||
+
|
||||
+ if opt["--verbose-level"] > 1:
|
||||
+ conn.setopt(pycurl.VERBOSE, 1)
|
||||
+
|
||||
+ conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
|
||||
+ conn.setopt(pycurl.SSL_VERIFYPEER, 1)
|
||||
+ conn.setopt(pycurl.SSL_VERIFYHOST, 2)
|
||||
+
|
||||
+ # get bearer token
|
||||
+ bearer_token = get_bearer_token(conn, opt)
|
||||
+
|
||||
+ # set auth token for later requests
|
||||
+ conn.setopt(pycurl.HTTPHEADER, [
|
||||
+ "Content-Type: application/json",
|
||||
+ "Authorization: Bearer {}".format(bearer_token),
|
||||
+ "User-Agent: curl",
|
||||
+ ])
|
||||
+
|
||||
+ return conn
|
||||
+
|
||||
+def disconnect(conn):
|
||||
+ conn.close()
|
||||
+
|
||||
+def send_command(conn, command, method="GET", action=None, expected_rc=200):
|
||||
+ if not command.startswith("https"):
|
||||
+ url = conn.base_url + command
|
||||
+ else:
|
||||
+ url = command
|
||||
+
|
||||
+ conn.setopt(pycurl.URL, url.encode("ascii"))
|
||||
+
|
||||
+ web_buffer = io.BytesIO()
|
||||
+
|
||||
+ if method == "GET":
|
||||
+ conn.setopt(pycurl.POST, 0)
|
||||
+ if method == "POST":
|
||||
+ conn.setopt(pycurl.POSTFIELDS, action)
|
||||
+ if method == "DELETE":
|
||||
+ conn.setopt(pycurl.CUSTOMREQUEST, "DELETE")
|
||||
+
|
||||
+ conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
|
||||
+
|
||||
+ try:
|
||||
+ conn.perform()
|
||||
+ except Exception as e:
|
||||
+ raise(e)
|
||||
+
|
||||
+ rc = conn.getinfo(pycurl.HTTP_CODE)
|
||||
+ result = web_buffer.getvalue().decode("UTF-8")
|
||||
+
|
||||
+ web_buffer.close()
|
||||
+
|
||||
+ # actions (start/stop/reboot) report 201 when they've been created
|
||||
+ if rc != expected_rc:
|
||||
+ logging.debug("rc: {}, result: {}".format(rc, result))
|
||||
+ if len(result) > 0:
|
||||
+ raise Exception("{}: {}".format(rc,
|
||||
+ result["value"]["messages"][0]["default_message"]))
|
||||
+ else:
|
||||
+ raise Exception("Remote returned {} for request to {}".format(rc, url))
|
||||
+
|
||||
+ if len(result) > 0:
|
||||
+ result = json.loads(result)
|
||||
+
|
||||
+ logging.debug("url: {}".format(url))
|
||||
+ logging.debug("method: {}".format(method))
|
||||
+ logging.debug("response code: {}".format(rc))
|
||||
+ logging.debug("result: {}\n".format(result))
|
||||
+
|
||||
+ return result
|
||||
+
|
||||
+def define_new_opts():
|
||||
+ all_opt["apikey"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "apikey",
|
||||
+ "help" : "--apikey=[key] API Key",
|
||||
+ "required" : "1",
|
||||
+ "shortdesc" : "API Key",
|
||||
+ "order" : 0
|
||||
+ }
|
||||
+ all_opt["instance"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "instance",
|
||||
+ "help" : "--instance=[instance] Cloud Instance",
|
||||
+ "required" : "1",
|
||||
+ "shortdesc" : "Cloud Instance",
|
||||
+ "order" : 0
|
||||
+ }
|
||||
+ all_opt["region"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "region",
|
||||
+ "help" : "--region=[region] Region",
|
||||
+ "required" : "1",
|
||||
+ "shortdesc" : "Region",
|
||||
+ "order" : 0
|
||||
+ }
|
||||
+ all_opt["limit"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "limit",
|
||||
+ "help" : "--limit=[number] Limit number of nodes returned by API",
|
||||
+ "required" : "1",
|
||||
+ "default": 50,
|
||||
+ "shortdesc" : "Number of nodes returned by API",
|
||||
+ "order" : 0
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+def main():
|
||||
+ device_opt = [
|
||||
+ "apikey",
|
||||
+ "instance",
|
||||
+ "region",
|
||||
+ "limit",
|
||||
+ "port",
|
||||
+ "no_password",
|
||||
+ ]
|
||||
+
|
||||
+ atexit.register(atexit_handler)
|
||||
+ define_new_opts()
|
||||
+
|
||||
+ all_opt["shell_timeout"]["default"] = "15"
|
||||
+ all_opt["power_timeout"]["default"] = "30"
|
||||
+ all_opt["power_wait"]["default"] = "1"
|
||||
+
|
||||
+ options = check_input(device_opt, process_input(device_opt))
|
||||
+
|
||||
+ docs = {}
|
||||
+ docs["shortdesc"] = "Fence agent for IBM Cloud VPC"
|
||||
+ docs["longdesc"] = """fence_ibm_vpc is an I/O Fencing agent which can be \
|
||||
+used with IBM Cloud VPC to fence virtual machines."""
|
||||
+ docs["vendorurl"] = "https://www.ibm.com"
|
||||
+ show_docs(options, docs)
|
||||
+
|
||||
+ ####
|
||||
+ ## Fence operations
|
||||
+ ####
|
||||
+ run_delay(options)
|
||||
+
|
||||
+ conn = connect(options)
|
||||
+ atexit.register(disconnect, conn)
|
||||
+
|
||||
+ result = fence_action(conn, options, set_power_status, get_power_status, get_list)
|
||||
+
|
||||
+ sys.exit(result)
|
||||
+
|
||||
+if __name__ == "__main__":
|
||||
+ main()
|
||||
diff --git a/tests/data/metadata/fence_ibm_powervs.xml b/tests/data/metadata/fence_ibm_powervs.xml
|
||||
new file mode 100644
|
||||
index 000000000..fe86331bd
|
||||
--- /dev/null
|
||||
+++ b/tests/data/metadata/fence_ibm_powervs.xml
|
||||
@@ -0,0 +1,134 @@
|
||||
+<?xml version="1.0" ?>
|
||||
+<resource-agent name="fence_ibm_powervs" shortdesc="Fence agent for IBM PowerVS" >
|
||||
+<longdesc>fence_ibm_powervs is an I/O Fencing agent which can be used with IBM PowerVS to fence virtual machines.</longdesc>
|
||||
+<vendor-url>https://www.ibm.com</vendor-url>
|
||||
+<parameters>
|
||||
+ <parameter name="crn" unique="0" required="1">
|
||||
+ <getopt mixed="--crn=[crn]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">CRN</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="instance" unique="0" required="1">
|
||||
+ <getopt mixed="--instance=[instance]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">PowerVS Instance</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="region" unique="0" required="1">
|
||||
+ <getopt mixed="--region=[region]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">Region</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="token" unique="0" required="1">
|
||||
+ <getopt mixed="--token=[token]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">Bearer Token</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="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="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. Multiple -v flags can be stacked on the command line (e.g., -vvv) to increase verbosity.</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="verbose_level" unique="0" required="0">
|
||||
+ <getopt mixed="--verbose-level" />
|
||||
+ <content type="integer" />
|
||||
+ <shortdesc lang="en">Level of debugging detail in output. Defaults to the number of --verbose flags specified on the command line, or to 1 if verbose=1 in a stonith device configuration (i.e., on stdin).</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="disable_timeout" unique="0" required="0">
|
||||
+ <getopt mixed="--disable-timeout=[true/false]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">Disable timeout (true/false) (default: true when run from Pacemaker 2.0+)</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="30" />
|
||||
+ <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="1" />
|
||||
+ <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="15" />
|
||||
+ <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="stonith_status_sleep" unique="0" required="0">
|
||||
+ <getopt mixed="--stonith-status-sleep=[seconds]" />
|
||||
+ <content type="second" default="1" />
|
||||
+ <shortdesc lang="en">Sleep X seconds between status calls during a STONITH action</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="manpage" />
|
||||
+ <action name="validate-all" />
|
||||
+</actions>
|
||||
+</resource-agent>
|
||||
diff --git a/tests/data/metadata/fence_ibm_vpc.xml b/tests/data/metadata/fence_ibm_vpc.xml
|
||||
new file mode 100644
|
||||
index 000000000..926efcaa0
|
||||
--- /dev/null
|
||||
+++ b/tests/data/metadata/fence_ibm_vpc.xml
|
||||
@@ -0,0 +1,134 @@
|
||||
+<?xml version="1.0" ?>
|
||||
+<resource-agent name="fence_ibm_vpc" shortdesc="Fence agent for IBM Cloud VPC" >
|
||||
+<longdesc>fence_ibm_vpc is an I/O Fencing agent which can be used with IBM Cloud VPC to fence virtual machines.</longdesc>
|
||||
+<vendor-url>https://www.ibm.com</vendor-url>
|
||||
+<parameters>
|
||||
+ <parameter name="apikey" unique="0" required="1">
|
||||
+ <getopt mixed="--apikey=[key]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">API Key</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="instance" unique="0" required="1">
|
||||
+ <getopt mixed="--instance=[instance]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">Cloud Instance</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="limit" unique="0" required="1">
|
||||
+ <getopt mixed="--limit=[number]" />
|
||||
+ <content type="string" default="50" />
|
||||
+ <shortdesc lang="en">Number of nodes returned by API</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="region" unique="0" required="1">
|
||||
+ <getopt mixed="--region=[region]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">Region</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="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="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. Multiple -v flags can be stacked on the command line (e.g., -vvv) to increase verbosity.</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="verbose_level" unique="0" required="0">
|
||||
+ <getopt mixed="--verbose-level" />
|
||||
+ <content type="integer" />
|
||||
+ <shortdesc lang="en">Level of debugging detail in output. Defaults to the number of --verbose flags specified on the command line, or to 1 if verbose=1 in a stonith device configuration (i.e., on stdin).</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="disable_timeout" unique="0" required="0">
|
||||
+ <getopt mixed="--disable-timeout=[true/false]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">Disable timeout (true/false) (default: true when run from Pacemaker 2.0+)</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="30" />
|
||||
+ <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="1" />
|
||||
+ <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="15" />
|
||||
+ <shortdesc lang="en">Wait X seconds for cmd prompt after issuing command</shortdesc>
|
||||
+ </parameter>
|
||||
+ <parameter name="stonith_status_sleep" unique="0" required="0">
|
||||
+ <getopt mixed="--stonith-status-sleep=[seconds]" />
|
||||
+ <content type="second" default="1" />
|
||||
+ <shortdesc lang="en">Sleep X seconds between status calls during a STONITH action</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="manpage" />
|
||||
+ <action name="validate-all" />
|
||||
+</actions>
|
||||
+</resource-agent>
|
100
SOURCES/bz1963163-fence_zvmip-add-ssl-tls-support.patch
Normal file
100
SOURCES/bz1963163-fence_zvmip-add-ssl-tls-support.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From 81be3c529ec1165f3135b4f14fbec2a19403cfbe Mon Sep 17 00:00:00 2001
|
||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||
Date: Fri, 27 Aug 2021 08:53:36 +0200
|
||||
Subject: [PATCH] fence_zvmip: add ssl/tls support
|
||||
|
||||
---
|
||||
agents/zvm/fence_zvmip.py | 20 ++++++++++++++++----
|
||||
tests/data/metadata/fence_zvmip.xml | 19 +++++++++++++++++++
|
||||
2 files changed, 35 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py
|
||||
index 001106a44..874eb699f 100644
|
||||
--- a/agents/zvm/fence_zvmip.py
|
||||
+++ b/agents/zvm/fence_zvmip.py
|
||||
@@ -26,12 +26,22 @@ def open_socket(options):
|
||||
except socket.gaierror:
|
||||
fail(EC_LOGIN_DENIED)
|
||||
|
||||
- conn = socket.socket()
|
||||
+ if "--ssl" in options:
|
||||
+ import ssl
|
||||
+ sock = socket.socket()
|
||||
+ sslcx = ssl.create_default_context()
|
||||
+ if "--ssl-insecure" in options:
|
||||
+ sslcx.check_hostname = False
|
||||
+ sslcx.verify_mode = ssl.CERT_NONE
|
||||
+ conn = sslcx.wrap_socket(sock, server_hostname=options["--ip"])
|
||||
+ else:
|
||||
+ conn = socket.socket()
|
||||
conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
conn.settimeout(float(options["--shell-timeout"]) or None)
|
||||
try:
|
||||
conn.connect(addr)
|
||||
- except socket.error:
|
||||
+ except socket.error as e:
|
||||
+ logging.debug(e)
|
||||
fail(EC_LOGIN_DENIED)
|
||||
|
||||
return conn
|
||||
@@ -122,11 +132,12 @@ def get_list_of_images(options, command, data_as_plug):
|
||||
images = set()
|
||||
|
||||
if output_len > 3*INT4:
|
||||
+ recvflag = socket.MSG_WAITALL if "--ssl" not in options else 0
|
||||
array_len = struct.unpack("!i", conn.recv(INT4))[0]
|
||||
data = ""
|
||||
|
||||
while True:
|
||||
- read_data = conn.recv(1024, socket.MSG_WAITALL).decode("UTF-8")
|
||||
+ read_data = conn.recv(1024, recvflag).decode("UTF-8")
|
||||
data += read_data
|
||||
if array_len == len(data):
|
||||
break
|
||||
@@ -146,7 +157,8 @@ def get_list_of_images(options, command, data_as_plug):
|
||||
return (return_code, reason_code, images)
|
||||
|
||||
def main():
|
||||
- device_opt = ["ipaddr", "login", "passwd", "port", "method", "missing_as_off", "inet4_only", "inet6_only"]
|
||||
+ device_opt = ["ipaddr", "login", "passwd", "port", "method", "missing_as_off",
|
||||
+ "inet4_only", "inet6_only", "ssl"]
|
||||
|
||||
atexit.register(atexit_handler)
|
||||
|
||||
diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml
|
||||
index f84115c08..d91192946 100644
|
||||
--- a/tests/data/metadata/fence_zvmip.xml
|
||||
+++ b/tests/data/metadata/fence_zvmip.xml
|
||||
@@ -91,6 +91,21 @@ to access the system's directory manager.
|
||||
<content type="string" />
|
||||
<shortdesc lang="en">Physical plug number on device, UUID or identification of machine</shortdesc>
|
||||
</parameter>
|
||||
+ <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="username" unique="0" required="1" obsoletes="login">
|
||||
<getopt mixed="-l, --username=[name]" />
|
||||
<content type="string" />
|
||||
@@ -181,6 +196,10 @@ to access the system's directory manager.
|
||||
<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"/>
|
70
SOURCES/bz1969953-fence_gce-1-add-proxy-support.patch
Normal file
70
SOURCES/bz1969953-fence_gce-1-add-proxy-support.patch
Normal file
@ -0,0 +1,70 @@
|
||||
diff --color -uNr a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||
--- a/agents/gce/fence_gce.py 2021-06-11 14:57:01.138390529 +0200
|
||||
+++ b/agents/gce/fence_gce.py 2021-06-11 15:12:45.829855806 +0200
|
||||
@@ -1,6 +1,7 @@
|
||||
#!@PYTHON@ -tt
|
||||
|
||||
import atexit
|
||||
+import httplib2
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
@@ -18,6 +19,7 @@
|
||||
from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action
|
||||
try:
|
||||
import googleapiclient.discovery
|
||||
+ import socks
|
||||
try:
|
||||
from google.oauth2.credentials import Credentials as GoogleCredentials
|
||||
except:
|
||||
@@ -189,13 +191,30 @@
|
||||
"required" : "0",
|
||||
"order" : 9
|
||||
}
|
||||
+ all_opt["proxyhost"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "proxyhost",
|
||||
+ "help" : "--proxyhost=[proxy_host] The proxy host to use, if one is needed to access the internet (Example: 10.122.0.33)",
|
||||
+ "shortdesc" : "If a proxy is used for internet access, the proxy host should be specified.",
|
||||
+ "required" : "0",
|
||||
+ "order" : 10
|
||||
+ }
|
||||
+ all_opt["proxyport"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "type" : "integer",
|
||||
+ "longopt" : "proxyport",
|
||||
+ "help" : "--proxyport=[proxy_port] The proxy port to use, if one is needed to access the internet (Example: 3127)",
|
||||
+ "shortdesc" : "If a proxy is used for internet access, the proxy port should be specified.",
|
||||
+ "required" : "0",
|
||||
+ "order" : 11
|
||||
+ }
|
||||
|
||||
|
||||
def main():
|
||||
conn = None
|
||||
|
||||
device_opt = ["port", "no_password", "zone", "project", "stackdriver-logging",
|
||||
- "method", "serviceaccount"]
|
||||
+ "method", "serviceaccount", "proxyhost", "proxyport"]
|
||||
|
||||
atexit.register(atexit_handler)
|
||||
|
||||
@@ -259,7 +278,17 @@
|
||||
credentials = GoogleCredentials.get_application_default()
|
||||
logging.debug("using application default credentials")
|
||||
|
||||
- conn = googleapiclient.discovery.build('compute', 'v1', credentials=credentials)
|
||||
+ if options.get("--proxyhost") and options.get("--proxyport"):
|
||||
+ proxy_info = httplib2.ProxyInfo(
|
||||
+ proxy_type=socks.PROXY_TYPE_HTTP,
|
||||
+ proxy_host=options.get("--proxyhost"),
|
||||
+ proxy_port=int(options.get("--proxyport")))
|
||||
+ http = credentials.authorize(httplib2.Http(proxy_info=proxy_info))
|
||||
+ conn = googleapiclient.discovery.build(
|
||||
+ 'compute', 'v1', http=http, cache_discovery=False)
|
||||
+ else:
|
||||
+ conn = googleapiclient.discovery.build(
|
||||
+ 'compute', 'v1', credentials=credentials, cache_discovery=False)
|
||||
except Exception as err:
|
||||
fail_usage("Failed: Create GCE compute v1 connection: {}".format(str(err)))
|
||||
|
10
SOURCES/bz1969953-fence_gce-2-bundled.patch
Normal file
10
SOURCES/bz1969953-fence_gce-2-bundled.patch
Normal file
@ -0,0 +1,10 @@
|
||||
--- a/agents/gce/fence_gce.py 2021-09-07 11:39:36.718667514 +0200
|
||||
+++ b/agents/gce/fence_gce.py 2021-09-07 11:39:30.423648309 +0200
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action
|
||||
try:
|
||||
+ sys.path.insert(0, '/usr/lib/fence-agents/bundled/google')
|
||||
import googleapiclient.discovery
|
||||
try:
|
||||
from google.oauth2.credentials import Credentials as GoogleCredentials
|
18
SOURCES/bz1969953-fence_gce-3-fix-httplib2-import.patch
Normal file
18
SOURCES/bz1969953-fence_gce-3-fix-httplib2-import.patch
Normal file
@ -0,0 +1,18 @@
|
||||
--- a/agents/gce/fence_gce.py 2021-10-19 10:29:17.000000000 +0000
|
||||
+++ b/agents/gce/fence_gce.py 2021-10-26 15:26:11.348781027 +0000
|
||||
@@ -1,7 +1,6 @@
|
||||
#!@PYTHON@ -tt
|
||||
|
||||
import atexit
|
||||
-import httplib2
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
@@ -19,6 +18,7 @@
|
||||
from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action
|
||||
try:
|
||||
sys.path.insert(0, '/usr/lib/fence-agents/bundled/google')
|
||||
+ import httplib2
|
||||
import googleapiclient.discovery
|
||||
import socks
|
||||
try:
|
@ -0,0 +1,23 @@
|
||||
From b220f963934f69044a39109fa065a95cd0972183 Mon Sep 17 00:00:00 2001
|
||||
From: Hideo Yamauchi <renayama19661014@ybb.ne.jp>
|
||||
Date: Fri, 2 Jul 2021 09:09:49 +0900
|
||||
Subject: [PATCH] Mid: fence_sbd: A warning message is output when
|
||||
disable-timeout is enabled.
|
||||
|
||||
---
|
||||
agents/sbd/fence_sbd.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/agents/sbd/fence_sbd.py b/agents/sbd/fence_sbd.py
|
||||
index 3ae8df6e3..0c876b16e 100644
|
||||
--- a/agents/sbd/fence_sbd.py
|
||||
+++ b/agents/sbd/fence_sbd.py
|
||||
@@ -398,7 +398,7 @@ def main():
|
||||
# then that defined within sbd we should report this.
|
||||
power_timeout = int(options["--power-timeout"])
|
||||
sbd_msg_timeout = get_msg_timeout(options)
|
||||
- if power_timeout <= sbd_msg_timeout:
|
||||
+ if 0 < power_timeout <= sbd_msg_timeout:
|
||||
logging.warn("power timeout needs to be \
|
||||
greater then sbd message timeout")
|
||||
|
22
SOURCES/bz1977588-1-fencing-add-EC_FETCH_VM_UUID.patch
Normal file
22
SOURCES/bz1977588-1-fencing-add-EC_FETCH_VM_UUID.patch
Normal file
@ -0,0 +1,22 @@
|
||||
diff --color -uNr a/lib/fencing.py.py b/lib/fencing.py.py
|
||||
--- a/lib/fencing.py.py 2021-11-01 10:14:04.045398051 +0100
|
||||
+++ b/lib/fencing.py.py 2021-11-01 10:24:47.111235305 +0100
|
||||
@@ -29,6 +29,7 @@
|
||||
EC_STATUS_HMC = 9
|
||||
EC_PASSWORD_MISSING = 10
|
||||
EC_INVALID_PRIVILEGES = 11
|
||||
+EC_FETCH_VM_UUID = 12
|
||||
|
||||
LOG_FORMAT = "%(asctime)-15s %(levelname)s: %(message)s"
|
||||
|
||||
@@ -574,7 +575,9 @@
|
||||
EC_STATUS_HMC : "Failed: Either unable to obtain correct plug status, "
|
||||
"partition is not available or incorrect HMC version used",
|
||||
EC_PASSWORD_MISSING : "Failed: You have to set login password",
|
||||
- EC_INVALID_PRIVILEGES : "Failed: The user does not have the correct privileges to do the requested action."
|
||||
+ EC_INVALID_PRIVILEGES : "Failed: The user does not have the correct privileges to do the requested action.",
|
||||
+ EC_FETCH_VM_UUID : "Failed: Can not find VM UUID by its VM name given in the <plug> parameter."
|
||||
+
|
||||
}[error_code] + "\n"
|
||||
logging.error("%s\n", message)
|
||||
if stop:
|
144
SOURCES/bz1977588-2-fence_kubevirt.patch
Normal file
144
SOURCES/bz1977588-2-fence_kubevirt.patch
Normal file
@ -0,0 +1,144 @@
|
||||
diff --color -uNr a/agents/kubevirt/fence_kubevirt.py b/agents/kubevirt/fence_kubevirt.py
|
||||
--- a/agents/kubevirt/fence_kubevirt.py 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/agents/kubevirt/fence_kubevirt.py 2021-10-25 13:25:59.904501348 +0200
|
||||
@@ -0,0 +1,140 @@
|
||||
+#!@PYTHON@ -tt
|
||||
+
|
||||
+import sys
|
||||
+import logging
|
||||
+sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||
+from fencing import *
|
||||
+from fencing import fail, fail_usage, run_delay, EC_STATUS
|
||||
+
|
||||
+try:
|
||||
+ sys.path.insert(0, '/usr/lib/fence-agents/bundled/kubevirt')
|
||||
+ from kubernetes.client.exceptions import ApiException
|
||||
+except ImportError:
|
||||
+ logging.error("Couldn\'t import kubernetes.client.exceptions.ApiException - not found or not accessible")
|
||||
+
|
||||
+def get_nodes_list(conn, options):
|
||||
+ logging.debug("Starting list/monitor operation")
|
||||
+ result = {}
|
||||
+ try:
|
||||
+ apiversion = options.get("--apiversion")
|
||||
+ namespace = options.get("--namespace")
|
||||
+ include_uninitialized = True
|
||||
+ vm_api = conn.resources.get(api_version=apiversion, kind='VirtualMachine')
|
||||
+ vm_list = vm_api.get(namespace=namespace)
|
||||
+ for vm in vm_list.items:
|
||||
+ result[vm.metadata.name] = ("", None)
|
||||
+ except Exception as e:
|
||||
+ logging.error("Exception when calling VirtualMachine list: %s", e)
|
||||
+ return result
|
||||
+
|
||||
+def get_power_status(conn, options):
|
||||
+ logging.debug("Starting get status operation")
|
||||
+ try:
|
||||
+ apiversion = options.get("--apiversion")
|
||||
+ namespace = options.get("--namespace")
|
||||
+ name = options.get("--plug")
|
||||
+ vmi_api = conn.resources.get(api_version=apiversion,
|
||||
+ kind='VirtualMachineInstance')
|
||||
+ vmi = vmi_api.get(name=name, namespace=namespace)
|
||||
+ if vmi is not None:
|
||||
+ phase = vmi.status.phase
|
||||
+ if phase == "Running":
|
||||
+ return "on"
|
||||
+ return "off"
|
||||
+ except ApiException as e:
|
||||
+ if e.status == 404:
|
||||
+ return "off"
|
||||
+ logging.error("Failed to get power status, with API Exception: %s", e)
|
||||
+ fail(EC_STATUS)
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed to get power status, with Exception: %s", e)
|
||||
+ fail(EC_STATUS)
|
||||
+
|
||||
+def set_power_status(conn, options):
|
||||
+ logging.debug("Starting set status operation")
|
||||
+ try:
|
||||
+ apiversion= options.get("--apiversion")
|
||||
+ namespace = options.get("--namespace")
|
||||
+ name = options.get("--plug")
|
||||
+ action = 'start' if options["--action"] == "on" else 'stop'
|
||||
+ virtctl_vm_action(conn, action, namespace, name, apiversion)
|
||||
+ except Exception as e:
|
||||
+ logging.error("Failed to set power status, with Exception: %s", e)
|
||||
+ fail(EC_STATUS)
|
||||
+
|
||||
+def define_new_opts():
|
||||
+ all_opt["namespace"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "namespace",
|
||||
+ "help" : "--namespace=[namespace] Namespace of the KubeVirt machine",
|
||||
+ "shortdesc" : "Namespace of the KubeVirt machine.",
|
||||
+ "required" : "1",
|
||||
+ "order" : 2
|
||||
+ }
|
||||
+ all_opt["kubeconfig"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "kubeconfig",
|
||||
+ "help" : "--kubeconfig=[kubeconfig] Kubeconfig file path",
|
||||
+ "shortdesc": "Kubeconfig file path",
|
||||
+ "required": "0",
|
||||
+ "order": 4
|
||||
+ }
|
||||
+ all_opt["apiversion"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "apiversion",
|
||||
+ "help" : "--apiversion=[apiversion] Version of the KubeVirt API",
|
||||
+ "shortdesc" : "Version of the KubeVirt API.",
|
||||
+ "required" : "0",
|
||||
+ "default" : "kubevirt.io/v1",
|
||||
+ "order" : 5
|
||||
+ }
|
||||
+
|
||||
+def virtctl_vm_action(conn, action, namespace, name, apiversion):
|
||||
+ path = '/apis/subresources.{api_version}/namespaces/{namespace}/virtualmachines/{name}/{action}'
|
||||
+ path = path.format(api_version=apiversion, namespace=namespace, name=name, action=action)
|
||||
+ return conn.request('put', path, header_params={'accept': '*/*'})
|
||||
+
|
||||
+def validate_options(required_options_list, options):
|
||||
+ for required_option in required_options_list:
|
||||
+ if required_option not in options:
|
||||
+ fail_usage("Failed: %s option must be provided" % required_option)
|
||||
+
|
||||
+# Main agent method
|
||||
+def main():
|
||||
+ conn = None
|
||||
+
|
||||
+ device_opt = ["port", "namespace", "kubeconfig", "ssl_insecure", "no_password", "apiversion"]
|
||||
+ define_new_opts()
|
||||
+ options = check_input(device_opt, process_input(device_opt))
|
||||
+
|
||||
+ docs = {}
|
||||
+ docs["shortdesc"] = "Fence agent for KubeVirt"
|
||||
+ docs["longdesc"] = "fence_kubevirt is an I/O Fencing agent for KubeVirt."
|
||||
+ docs["vendorurl"] = "https://kubevirt.io/"
|
||||
+ show_docs(options, docs)
|
||||
+
|
||||
+ run_delay(options)
|
||||
+
|
||||
+ validate_options(['--namespace'], options)
|
||||
+
|
||||
+ # Disable insecure-certificate-warning message
|
||||
+ if "--ssl-insecure" in options:
|
||||
+ import urllib3
|
||||
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
+
|
||||
+ try:
|
||||
+ from kubernetes import config
|
||||
+ from openshift.dynamic import DynamicClient
|
||||
+ kubeconfig = options.get('--kubeconfig')
|
||||
+ k8s_client = config.new_client_from_config(config_file=kubeconfig)
|
||||
+ conn = DynamicClient(k8s_client)
|
||||
+ except ImportError:
|
||||
+ logging.error("Couldn\'t import kubernetes.config or "
|
||||
+ "openshift.dynamic.DynamicClient - not found or not accessible")
|
||||
+
|
||||
+ # 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()
|
55
SOURCES/bz1977588-3-fence_kubevirt-fix-status.patch
Normal file
55
SOURCES/bz1977588-3-fence_kubevirt-fix-status.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From c23bfc3b9fc6e1dc7b1350e340171f3827fb6fb7 Mon Sep 17 00:00:00 2001
|
||||
From: Nir Argaman <nargaman@redhat.com>
|
||||
Date: Mon, 1 Nov 2021 08:34:00 +0200
|
||||
Subject: [PATCH] fence_kubevirt: Fix kubevirt VM status
|
||||
|
||||
---
|
||||
agents/kubevirt/fence_kubevirt.py | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/agents/kubevirt/fence_kubevirt.py b/agents/kubevirt/fence_kubevirt.py
|
||||
index 70c14d89a..61ffcaa09 100755
|
||||
--- a/agents/kubevirt/fence_kubevirt.py
|
||||
+++ b/agents/kubevirt/fence_kubevirt.py
|
||||
@@ -4,7 +4,7 @@
|
||||
import logging
|
||||
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||
from fencing import *
|
||||
-from fencing import fail, fail_usage, run_delay, EC_STATUS
|
||||
+from fencing import fail, fail_usage, run_delay, EC_STATUS, EC_FETCH_VM_UUID
|
||||
|
||||
try:
|
||||
from kubernetes.client.exceptions import ApiException
|
||||
@@ -35,13 +35,15 @@ def get_power_status(conn, options):
|
||||
vmi_api = conn.resources.get(api_version=apiversion,
|
||||
kind='VirtualMachineInstance')
|
||||
vmi = vmi_api.get(name=name, namespace=namespace)
|
||||
- if vmi is not None:
|
||||
- phase = vmi.status.phase
|
||||
- if phase == "Running":
|
||||
- return "on"
|
||||
- return "off"
|
||||
+ return translate_status(vmi.status.phase)
|
||||
except ApiException as e:
|
||||
if e.status == 404:
|
||||
+ try:
|
||||
+ vm_api = conn.resources.get(api_version=apiversion, kind='VirtualMachine')
|
||||
+ vm = vm_api.get(name=name, namespace=namespace)
|
||||
+ except ApiException as e:
|
||||
+ logging.error("VM %s doesn't exist", name)
|
||||
+ fail(EC_FETCH_VM_UUID)
|
||||
return "off"
|
||||
logging.error("Failed to get power status, with API Exception: %s", e)
|
||||
fail(EC_STATUS)
|
||||
@@ -49,6 +51,11 @@ def get_power_status(conn, options):
|
||||
logging.error("Failed to get power status, with Exception: %s", e)
|
||||
fail(EC_STATUS)
|
||||
|
||||
+def translate_status(instance_status):
|
||||
+ if instance_status == "Running":
|
||||
+ return "on"
|
||||
+ return "unknown"
|
||||
+
|
||||
def set_power_status(conn, options):
|
||||
logging.debug("Starting set status operation")
|
||||
try:
|
35
SOURCES/bz1977588-4-fence_kubevirt-power-timeout-40s.patch
Normal file
35
SOURCES/bz1977588-4-fence_kubevirt-power-timeout-40s.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From a3d8ce78ed5687954847560f77daafe6474de33f Mon Sep 17 00:00:00 2001
|
||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||
Date: Tue, 2 Nov 2021 09:44:33 +0100
|
||||
Subject: [PATCH] fence_kubevirt: set default power-timeout to 40s
|
||||
|
||||
---
|
||||
agents/kubevirt/fence_kubevirt.py | 6 ++++++
|
||||
tests/data/metadata/fence_kubevirt.xml | 2 +-
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/agents/kubevirt/fence_kubevirt.py b/agents/kubevirt/fence_kubevirt.py
|
||||
index 61ffcaa09..8392b75a0 100755
|
||||
--- a/agents/kubevirt/fence_kubevirt.py
|
||||
+++ b/agents/kubevirt/fence_kubevirt.py
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import sys
|
||||
import logging
|
||||
+import atexit
|
||||
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||
from fencing import *
|
||||
from fencing import fail, fail_usage, run_delay, EC_STATUS, EC_FETCH_VM_UUID
|
||||
@@ -110,7 +111,12 @@ def main():
|
||||
conn = None
|
||||
|
||||
device_opt = ["port", "namespace", "kubeconfig", "ssl_insecure", "no_password", "apiversion"]
|
||||
+
|
||||
+ atexit.register(atexit_handler)
|
||||
define_new_opts()
|
||||
+
|
||||
+ all_opt["power_timeout"]["default"] = "40"
|
||||
+
|
||||
options = check_input(device_opt, process_input(device_opt))
|
||||
|
||||
docs = {}
|
@ -0,0 +1,88 @@
|
||||
From 647841dea9d93922779a4aa7d0b5f52f5bc2b4e9 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kenigsberg <danken@redhat.com>
|
||||
Date: Thu, 13 Jan 2022 14:57:26 +0200
|
||||
Subject: [PATCH] fence_kubevirt: take default namespace from context
|
||||
|
||||
If --namespace is not provided to kubectl, a default one is taken from
|
||||
kubeconfig context. Let fence_kubevirt behave similarly.
|
||||
|
||||
Signed-off-by: Dan Kenigsberg <danken@redhat.com>
|
||||
---
|
||||
agents/kubevirt/fence_kubevirt.py | 24 +++++++++++++-----------
|
||||
2 files changed, 14 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/agents/kubevirt/fence_kubevirt.py b/agents/kubevirt/fence_kubevirt.py
|
||||
index 8392b75a0..8c27a0334 100755
|
||||
--- a/agents/kubevirt/fence_kubevirt.py
|
||||
+++ b/agents/kubevirt/fence_kubevirt.py
|
||||
@@ -12,12 +12,21 @@
|
||||
except ImportError:
|
||||
logging.error("Couldn\'t import kubernetes.client.exceptions.ApiException - not found or not accessible")
|
||||
|
||||
+def _get_namespace(options):
|
||||
+ from kubernetes import config
|
||||
+
|
||||
+ ns = options.get("--namespace")
|
||||
+ if ns is None:
|
||||
+ ns = config.kube_config.list_kube_config_contexts()[1]['context']['namespace']
|
||||
+
|
||||
+ return ns
|
||||
+
|
||||
def get_nodes_list(conn, options):
|
||||
logging.debug("Starting list/monitor operation")
|
||||
result = {}
|
||||
try:
|
||||
apiversion = options.get("--apiversion")
|
||||
- namespace = options.get("--namespace")
|
||||
+ namespace = _get_namespace(options)
|
||||
include_uninitialized = True
|
||||
vm_api = conn.resources.get(api_version=apiversion, kind='VirtualMachine')
|
||||
vm_list = vm_api.get(namespace=namespace)
|
||||
@@ -31,7 +40,7 @@ def get_power_status(conn, options):
|
||||
logging.debug("Starting get status operation")
|
||||
try:
|
||||
apiversion = options.get("--apiversion")
|
||||
- namespace = options.get("--namespace")
|
||||
+ namespace = _get_namespace(options)
|
||||
name = options.get("--plug")
|
||||
vmi_api = conn.resources.get(api_version=apiversion,
|
||||
kind='VirtualMachineInstance')
|
||||
@@ -61,7 +70,7 @@ def set_power_status(conn, options):
|
||||
logging.debug("Starting set status operation")
|
||||
try:
|
||||
apiversion= options.get("--apiversion")
|
||||
- namespace = options.get("--namespace")
|
||||
+ namespace = _get_namespace(options)
|
||||
name = options.get("--plug")
|
||||
action = 'start' if options["--action"] == "on" else 'stop'
|
||||
virtctl_vm_action(conn, action, namespace, name, apiversion)
|
||||
@@ -75,7 +84,7 @@ def define_new_opts():
|
||||
"longopt" : "namespace",
|
||||
"help" : "--namespace=[namespace] Namespace of the KubeVirt machine",
|
||||
"shortdesc" : "Namespace of the KubeVirt machine.",
|
||||
- "required" : "1",
|
||||
+ "required" : "0",
|
||||
"order" : 2
|
||||
}
|
||||
all_opt["kubeconfig"] = {
|
||||
@@ -101,11 +110,6 @@ def virtctl_vm_action(conn, action, namespace, name, apiversion):
|
||||
path = path.format(api_version=apiversion, namespace=namespace, name=name, action=action)
|
||||
return conn.request('put', path, header_params={'accept': '*/*'})
|
||||
|
||||
-def validate_options(required_options_list, options):
|
||||
- for required_option in required_options_list:
|
||||
- if required_option not in options:
|
||||
- fail_usage("Failed: %s option must be provided" % required_option)
|
||||
-
|
||||
# Main agent method
|
||||
def main():
|
||||
conn = None
|
||||
@@ -127,8 +131,6 @@ def main():
|
||||
|
||||
run_delay(options)
|
||||
|
||||
- validate_options(['--namespace'], options)
|
||||
-
|
||||
# Disable insecure-certificate-warning message
|
||||
if "--ssl-insecure" in options:
|
||||
import urllib3
|
22
SOURCES/bz2010710-1-fence_amt_ws-fix-or-dead-code.patch
Normal file
22
SOURCES/bz2010710-1-fence_amt_ws-fix-or-dead-code.patch
Normal file
@ -0,0 +1,22 @@
|
||||
From 06855a8227fa91f6216119daa3d32d5858c62837 Mon Sep 17 00:00:00 2001
|
||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||
Date: Mon, 27 Sep 2021 12:05:41 +0200
|
||||
Subject: [PATCH] fence_amt_ws: fix "or" causing dead code
|
||||
|
||||
---
|
||||
agents/amt_ws/fence_amt_ws.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/agents/amt_ws/fence_amt_ws.py b/agents/amt_ws/fence_amt_ws.py
|
||||
index 23c8a61a4..122cec309 100755
|
||||
--- a/agents/amt_ws/fence_amt_ws.py
|
||||
+++ b/agents/amt_ws/fence_amt_ws.py
|
||||
@@ -148,7 +148,7 @@ def set_boot_order(_, client, options):
|
||||
|
||||
if options["--boot-option"] == "pxe":
|
||||
device = "Intel(r) AMT: Force PXE Boot"
|
||||
- elif options["--boot-option"] == "hd" or "hdsafe":
|
||||
+ elif options["--boot-option"] in ["hd", "hdsafe"]:
|
||||
device = "Intel(r) AMT: Force Hard-drive Boot"
|
||||
elif options["--boot-option"] == "cd":
|
||||
device = "Intel(r) AMT: Force CD/DVD Boot"
|
32
SOURCES/bz2010710-2-fence_amt_ws-boot-option.patch
Normal file
32
SOURCES/bz2010710-2-fence_amt_ws-boot-option.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 9812473270e9a404c632358c1debfa4a1fb440fe Mon Sep 17 00:00:00 2001
|
||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||
Date: Wed, 20 Oct 2021 15:46:42 +0200
|
||||
Subject: [PATCH] fence_amt_ws: fix --boot-option (choices are uppercased while
|
||||
getting parsed)
|
||||
|
||||
---
|
||||
agents/amt_ws/fence_amt_ws.py | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/agents/amt_ws/fence_amt_ws.py b/agents/amt_ws/fence_amt_ws.py
|
||||
index 122cec309..5e7452a97 100755
|
||||
--- a/agents/amt_ws/fence_amt_ws.py
|
||||
+++ b/agents/amt_ws/fence_amt_ws.py
|
||||
@@ -146,13 +146,13 @@ def set_boot_order(_, client, options):
|
||||
wsman = 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd'
|
||||
namespace = CIM_BootConfigSetting
|
||||
|
||||
- if options["--boot-option"] == "pxe":
|
||||
+ if options["--boot-option"] == "PXE":
|
||||
device = "Intel(r) AMT: Force PXE Boot"
|
||||
- elif options["--boot-option"] in ["hd", "hdsafe"]:
|
||||
+ elif options["--boot-option"] in ["HD", "HDSAFE"]:
|
||||
device = "Intel(r) AMT: Force Hard-drive Boot"
|
||||
- elif options["--boot-option"] == "cd":
|
||||
+ elif options["--boot-option"] == "CD":
|
||||
device = "Intel(r) AMT: Force CD/DVD Boot"
|
||||
- elif options["--boot-option"] == "diag":
|
||||
+ elif options["--boot-option"] == "DIAG":
|
||||
device = "Intel(r) AMT: Force Diagnostic Boot"
|
||||
else:
|
||||
logging.error('Boot device: %s not supported.', \
|
11
SOURCES/bz2048857-fence_aws-botocore-bundled.patch
Normal file
11
SOURCES/bz2048857-fence_aws-botocore-bundled.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/agents/aws/fence_aws.py 2022-02-09 10:51:19.579385154 +0100
|
||||
+++ b/agents/aws/fence_aws.py 2022-02-09 10:51:47.148478185 +0100
|
||||
@@ -7,6 +7,8 @@
|
||||
from fencing import *
|
||||
from fencing import fail, fail_usage, run_delay, EC_STATUS, SyslogLibHandler
|
||||
|
||||
+sys.path.insert(0, '/usr/lib/fence-agents/bundled/aws')
|
||||
+
|
||||
import requests
|
||||
import boto3
|
||||
from requests import HTTPError
|
@ -25,19 +25,121 @@
|
||||
%global aliyunsdkvpc aliyun-python-sdk-vpc
|
||||
%global aliyunsdkvpc_version 3.0.2
|
||||
%global aliyunsdkvpc_dir %{bundled_lib_dir}/aliyun/%{aliyunsdkvpc}
|
||||
# aws
|
||||
%global botocore botocore
|
||||
%global botocore_version 1.23.46
|
||||
%global chardet chardet
|
||||
%global chardet_version 4.0.0
|
||||
## for pip install only
|
||||
%global jmespath jmespath
|
||||
%global jmespath_version 0.10.0
|
||||
# google cloud
|
||||
%global httplib2 httplib2
|
||||
%global httplib2_version 0.19.1
|
||||
# kubevirt
|
||||
%global openshift openshift
|
||||
%global openshift_version 0.12.1
|
||||
%global ruamelyamlclib ruamel.yaml.clib
|
||||
%global ruamelyamlclib_version 0.2.6
|
||||
%global kubernetes kubernetes
|
||||
%global kubernetes_version 12.0.1
|
||||
%global certifi certifi
|
||||
%global certifi_version 2021.10.8
|
||||
%global googleauth google-auth
|
||||
%global googleauth_version 2.3.0
|
||||
%global cachetools cachetools
|
||||
%global cachetools_version 4.2.4
|
||||
%global pyasn1modules pyasn1-modules
|
||||
%global pyasn1modules_version 0.2.8
|
||||
%global pyasn1 pyasn1
|
||||
%global pyasn1_version 0.4.8
|
||||
%global dateutil dateutil
|
||||
%global dateutil_version 2.8.2
|
||||
%global pyyaml PyYAML
|
||||
%global pyyaml_version 6.0
|
||||
%global six six
|
||||
%global six_version 1.16.0
|
||||
%global urllib3 urllib3
|
||||
%global urllib3_version 1.26.7
|
||||
%global websocketclient websocket-client
|
||||
%global websocketclient_version 1.2.1
|
||||
%global jinja2 Jinja2
|
||||
%global jinja2_version 3.0.2
|
||||
%global markupsafe MarkupSafe
|
||||
%global markupsafe_version 2.0.1
|
||||
%global stringutils string-utils
|
||||
%global stringutils_version 1.0.0
|
||||
%global requests requests
|
||||
%global requests_version 2.26.0
|
||||
%global chrstnormalizer charset-normalizer
|
||||
%global chrstnormalizer_version 2.0.7
|
||||
%global idna idna
|
||||
%global idna_version 3.3
|
||||
%global reqstsoauthlib requests-oauthlib
|
||||
%global reqstsoauthlib_version 1.3.0
|
||||
%global oauthlib oauthlib
|
||||
%global oauthlib_version 3.1.1
|
||||
%global ruamelyaml ruamel.yaml
|
||||
%global ruamelyaml_version 0.17.16
|
||||
%global setuptools setuptools
|
||||
%global setuptools_version 58.3.0
|
||||
|
||||
Name: fence-agents
|
||||
Summary: Set of unified programs capable of host isolation ("fencing")
|
||||
Version: 4.2.1
|
||||
Release: 75%{?alphatag:.%{alphatag}}%{?dist}
|
||||
Release: 88%{?alphatag:.%{alphatag}}%{?dist}
|
||||
License: GPLv2+ and LGPLv2+
|
||||
Group: System Environment/Base
|
||||
URL: https://github.com/ClusterLabs/fence-agents
|
||||
Source0: https://fedorahosted.org/releases/f/e/fence-agents/%{name}-%{version}.tar.gz
|
||||
# aliyun
|
||||
Source1: %{pycryptodome}-%{pycryptodome_version}.tar.gz
|
||||
Source2: %{aliyunsdkcore}-%{aliyunsdkcore_version}.tar.gz
|
||||
Source3: %{aliyunsdkecs}-%{aliyunsdkecs_version}.tar.gz
|
||||
Source4: %{aliyunsdkvpc}-%{aliyunsdkvpc_version}.tar.gz
|
||||
# google cloud
|
||||
Source5: %{httplib2}-%{httplib2_version}-py3-none-any.whl
|
||||
Source6: pyparsing-2.4.7-py2.py3-none-any.whl
|
||||
# aws
|
||||
Source7: %{botocore}-%{botocore_version}.tar.gz
|
||||
Source8: %{jmespath}-%{jmespath_version}.tar.gz
|
||||
Source9: %{chardet}-%{chardet_version}.tar.gz
|
||||
# kubevirt
|
||||
## pip download --no-binary :all: openshift "ruamel.yaml.clib>=0.1.2"
|
||||
### BEGIN
|
||||
Source10: %{openshift}-%{openshift_version}.tar.gz
|
||||
Source11: %{ruamelyamlclib}-%{ruamelyamlclib_version}.tar.gz
|
||||
Source12: %{kubernetes}-%{kubernetes_version}.tar.gz
|
||||
Source13: %{certifi}-%{certifi_version}.tar.gz
|
||||
Source14: %{googleauth}-%{googleauth_version}.tar.gz
|
||||
Source15: %{cachetools}-%{cachetools_version}.tar.gz
|
||||
Source16: %{pyasn1modules}-%{pyasn1modules_version}.tar.gz
|
||||
Source17: %{pyasn1}-%{pyasn1_version}.tar.gz
|
||||
Source18: python-%{dateutil}-%{dateutil_version}.tar.gz
|
||||
Source19: %{pyyaml}-%{pyyaml_version}.tar.gz
|
||||
## rsa is dependency for "pip install",
|
||||
## but gets removed to use cryptography lib instead
|
||||
Source20: rsa-4.7.2.tar.gz
|
||||
Source21: %{six}-%{six_version}.tar.gz
|
||||
Source22: %{urllib3}-%{urllib3_version}.tar.gz
|
||||
Source23: %{websocketclient}-%{websocketclient_version}.tar.gz
|
||||
Source24: %{jinja2}-%{jinja2_version}.tar.gz
|
||||
Source25: %{markupsafe}-%{markupsafe_version}.tar.gz
|
||||
Source26: python-%{stringutils}-%{stringutils_version}.tar.gz
|
||||
Source27: %{requests}-%{requests_version}.tar.gz
|
||||
Source28: %{chrstnormalizer}-%{chrstnormalizer_version}.tar.gz
|
||||
Source29: %{idna}-%{idna_version}.tar.gz
|
||||
Source30: %{reqstsoauthlib}-%{reqstsoauthlib_version}.tar.gz
|
||||
Source31: %{oauthlib}-%{oauthlib_version}.tar.gz
|
||||
Source32: %{ruamelyaml}-%{ruamelyaml_version}.tar.gz
|
||||
Source33: %{setuptools}-%{setuptools_version}.tar.gz
|
||||
## required for installation
|
||||
Source34: setuptools_scm-6.3.2.tar.gz
|
||||
Source35: packaging-21.2-py3-none-any.whl
|
||||
Source36: pyparsing-3.0.1.tar.gz
|
||||
Source37: tomli-1.0.1.tar.gz
|
||||
### END
|
||||
|
||||
Patch0: fence_impilan-fence_ilo_ssh-add-ilo5-support.patch
|
||||
Patch1: fence_mpath-watchdog-support.patch
|
||||
Patch2: fence_ilo3-fence_ipmilan-show-correct-default-method.patch
|
||||
@ -132,9 +234,24 @@ Patch90: bz1920947-fence_redfish-2-add-diag-action-logic.patch
|
||||
Patch91: bz1920947-fence_redfish-3-fix-typo.patch
|
||||
Patch92: bz1922437-fence_mpath-watchdog-retry-support.patch
|
||||
Patch93: bz1685814-fence_gce-add-serviceaccount-file-support.patch
|
||||
Patch94: bz1728203-bz1874862-fence_ibm_vpc-fence_ibm_powervs.patch
|
||||
Patch95: bz1969953-fence_gce-1-add-proxy-support.patch
|
||||
Patch96: bz1969953-fence_gce-2-bundled.patch
|
||||
Patch97: bz1470827-all-agents-log-exceptions-fail.patch
|
||||
Patch98: bz2010710-1-fence_amt_ws-fix-or-dead-code.patch
|
||||
Patch99: bz2010710-2-fence_amt_ws-boot-option.patch
|
||||
Patch100: bz1969953-fence_gce-3-fix-httplib2-import.patch
|
||||
Patch101: bz1971683-fence_sbd-dont-spam-logs-disable-timeout.patch
|
||||
Patch102: bz1977588-1-fencing-add-EC_FETCH_VM_UUID.patch
|
||||
Patch103: bz1977588-2-fence_kubevirt.patch
|
||||
Patch104: bz1977588-3-fence_kubevirt-fix-status.patch
|
||||
Patch105: bz1977588-4-fence_kubevirt-power-timeout-40s.patch
|
||||
Patch106: bz1963163-fence_zvmip-add-ssl-tls-support.patch
|
||||
Patch107: bz1977588-5-fence_kubevirt-get-namespace-from-context.patch
|
||||
Patch108: bz2048857-fence_aws-botocore-bundled.patch
|
||||
|
||||
%if 0%{?fedora} || 0%{?rhel} > 7
|
||||
%global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate hds_cb hpblade ibmblade ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan kdump lpar mpath redfish rhevm rsa rsb sbd scsi vmware_rest vmware_soap wti
|
||||
%global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate hds_cb hpblade ibmblade ibm_powervs ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan kdump kubevirt lpar mpath redfish rhevm rsa rsb sbd scsi vmware_rest vmware_soap wti
|
||||
%ifarch x86_64
|
||||
%global testagents virsh heuristics_ping aliyun aws azure_arm gce
|
||||
%endif
|
||||
@ -200,7 +317,7 @@ BuildRequires: gnutls-utils
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: python3-pexpect python3-pycurl python3-requests
|
||||
BuildRequires: python3-suds openwsman-python3 python3-boto3
|
||||
BuildRequires: python3-google-api-client
|
||||
BuildRequires: python3-google-api-client python3-pip python3-wheel python3-jinja2
|
||||
|
||||
# turn off the brp-python-bytecompile script
|
||||
# (for F28+ or equivalent, the latter is the preferred form)
|
||||
@ -303,6 +420,21 @@ BuildRequires: python3-google-api-client
|
||||
%patch91 -p1
|
||||
%patch92 -p1
|
||||
%patch93 -p1
|
||||
%patch94 -p1
|
||||
%patch95 -p1
|
||||
%patch96 -p1 -F2
|
||||
%patch97 -p1
|
||||
%patch98 -p1
|
||||
%patch99 -p1
|
||||
%patch100 -p1
|
||||
%patch101 -p1
|
||||
%patch102 -p1
|
||||
%patch103 -p1
|
||||
%patch104 -p1 -F1
|
||||
%patch105 -p1
|
||||
%patch106 -p1
|
||||
%patch107 -p1
|
||||
%patch108 -p1
|
||||
|
||||
# prevent compilation of something that won't get used anyway
|
||||
sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac
|
||||
@ -386,8 +518,27 @@ popd
|
||||
pushd %{aliyunsdkvpc_dir}
|
||||
%{__python3} setup.py install -O1 --skip-build --root %{buildroot} --install-lib /usr/lib/fence-agents/%{bundled_lib_dir}/aliyun
|
||||
popd
|
||||
|
||||
# google cloud
|
||||
## for httplib2 install only
|
||||
%{__python3} -m pip install --user --no-index --find-links %{_sourcedir} pyparsing
|
||||
%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/google --no-index --find-links %{_sourcedir} httplib2
|
||||
%endif
|
||||
|
||||
# aws/kubevirt
|
||||
%{__python3} -m pip install --user --no-index --find-links %{_sourcedir} setuptools-scm
|
||||
|
||||
# aws
|
||||
%ifarch x86_64
|
||||
%{__python3} -m pip install --user --no-index --find-links %{_sourcedir} jmespath
|
||||
%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/aws --no-index --find-links %{_sourcedir} botocore
|
||||
%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/aws --no-index --find-links %{_sourcedir} requests
|
||||
%endif
|
||||
|
||||
# kubevirt
|
||||
%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/kubevirt --no-index --find-links %{_sourcedir} openshift
|
||||
rm -rf %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/kubevirt/rsa*
|
||||
|
||||
## tree fix up
|
||||
# fix libfence permissions
|
||||
chmod 0755 %{buildroot}%{_datadir}/fence/*.py
|
||||
@ -538,6 +689,16 @@ Group: System Environment/Base
|
||||
Summary: Fence agent for Amazon AWS
|
||||
Requires: fence-agents-common >= %{version}-%{release}
|
||||
Requires: python3-boto3
|
||||
Provides: bundled(python3-%{botocore}) = %{botocore_version}
|
||||
Provides: bundled(python3-%{urllib3}) = %{urllib3_version}
|
||||
Provides: bundled(python3-%{requests}) = %{requests_version}
|
||||
Provides: bundled(python3-%{certifi}) = %{certifi_version}
|
||||
Provides: bundled(python3-%{chrstnormalizer}) = %{chrstnormalizer_version}
|
||||
Provides: bundled(python3-%{idna}) = %{idna_version}
|
||||
Provides: bundled(python3-%{chardet}) = %{chardet_version}
|
||||
Provides: bundled(python3-%{dateutil}) = %{dateutil_version}
|
||||
Provides: bundled(python3-%{six}) = %{six_version}
|
||||
Provides: bundled(python3-%{jmespath}) = %{jmespath_version}
|
||||
Obsoletes: %{name} < %{version}-%{release}
|
||||
BuildArch: noarch
|
||||
%description aws
|
||||
@ -545,6 +706,8 @@ Fence agent for Amazon AWS instances.
|
||||
%files aws
|
||||
%{_sbindir}/fence_aws
|
||||
%{_mandir}/man8/fence_aws.8*
|
||||
# bundled libraries
|
||||
/usr/lib/fence-agents/%{bundled_lib_dir}/aws
|
||||
%endif
|
||||
|
||||
%ifarch x86_64
|
||||
@ -721,12 +884,14 @@ via the HTTP(s) protocol.
|
||||
|
||||
%ifarch x86_64
|
||||
%package gce
|
||||
License: GPLv2+ and LGPLv2+
|
||||
License: GPLv2+ and LGPLv2+ and MIT
|
||||
Group: System Environment/Base
|
||||
Summary: Fence agent for GCE (Google Cloud Engine)
|
||||
Requires: fence-agents-common >= %{version}-%{release}
|
||||
Requires: python3-google-api-client
|
||||
Requires: python3-pysocks
|
||||
# google cloud
|
||||
Provides: bundled(python-httplib2) = %{httplib2_version}
|
||||
Obsoletes: %{name} < %{version}-%{release}
|
||||
BuildArch: noarch
|
||||
%description gce
|
||||
@ -734,6 +899,8 @@ Fence agent for GCE (Google Cloud Engine) instances.
|
||||
%files gce
|
||||
%{_sbindir}/fence_gce
|
||||
%{_mandir}/man8/fence_gce.8*
|
||||
# bundled libraries
|
||||
/usr/lib/fence-agents/%{bundled_lib_dir}/google
|
||||
%endif
|
||||
|
||||
%package heuristics-ping
|
||||
@ -787,6 +954,18 @@ via the SNMP protocol.
|
||||
%{_sbindir}/fence_ibmblade
|
||||
%{_mandir}/man8/fence_ibmblade.8*
|
||||
|
||||
%package ibm-powervs
|
||||
License: GPLv2+ and LGPLv2+
|
||||
Group: System Environment/Base
|
||||
Summary: Fence agent for IBM PowerVS
|
||||
Requires: fence-agents-common = %{version}-%{release}
|
||||
BuildArch: noarch
|
||||
%description ibm-powervs
|
||||
Fence agent for IBM PowerVS that are accessed via REST API.
|
||||
%files ibm-powervs
|
||||
%{_sbindir}/fence_ibm_powervs
|
||||
%{_mandir}/man8/fence_ibm_powervs.8*
|
||||
|
||||
%package ifmib
|
||||
License: GPLv2+ and LGPLv2+
|
||||
Group: System Environment/Base
|
||||
@ -954,6 +1133,41 @@ Fence agent for use with kdump crash recovery service.
|
||||
%{_mandir}/man8/fence_kdump.8*
|
||||
%{_mandir}/man8/fence_kdump_send.8*
|
||||
|
||||
%package kubevirt
|
||||
License: GPLv2+ and LGPLv2+ and ASL 2.0 and BSD and BSD-2-Clause and BSD-3-Clause and ISC and MIT and MPL-2.0
|
||||
Summary: Fence agent for KubeVirt platform
|
||||
Requires: fence-agents-common = %{version}-%{release}
|
||||
Provides: bundled(python3-%{openshift}) = %{openshift_version}
|
||||
Provides: bundled(python3-%{ruamelyamlclib}) = %{ruamelyamlclib_version}
|
||||
Provides: bundled(python3-%{kubernetes}) = %{kubernetes_version}
|
||||
Provides: bundled(python3-%{certifi}) = %{certifi_version}
|
||||
Provides: bundled(python3-%{googleauth}) = %{googleauth_version}
|
||||
Provides: bundled(python3-%{cachetools}) = %{cachetools_version}
|
||||
Provides: bundled(python3-%{pyasn1modules}) = %{pyasn1modules_version}
|
||||
Provides: bundled(python3-%{pyasn1}) = %{pyasn1_version}
|
||||
Provides: bundled(python3-%{dateutil}) = %{dateutil_version}
|
||||
Provides: bundled(python3-%{pyyaml}) = %{pyyaml_version}
|
||||
Provides: bundled(python3-%{six}) = %{six_version}
|
||||
Provides: bundled(python3-%{urllib3}) = %{urllib3_version}
|
||||
Provides: bundled(python3-%{websocketclient}) = %{websocketclient_version}
|
||||
Provides: bundled(python3-%{jinja2}) = %{jinja2_version}
|
||||
Provides: bundled(python3-%{markupsafe}) = %{markupsafe_version}
|
||||
Provides: bundled(python3-%{stringutils}) = %{stringutils_version}
|
||||
Provides: bundled(python3-%{requests}) = %{requests_version}
|
||||
Provides: bundled(python3-%{chrstnormalizer}) = %{chrstnormalizer_version}
|
||||
Provides: bundled(python3-%{idna}) = %{idna_version}
|
||||
Provides: bundled(python3-%{reqstsoauthlib}) = %{reqstsoauthlib_version}
|
||||
Provides: bundled(python3-%{oauthlib}) = %{oauthlib_version}
|
||||
Provides: bundled(python3-%{ruamelyaml}) = %{ruamelyaml_version}
|
||||
Provides: bundled(python3-%{setuptools}) = %{setuptools_version}
|
||||
%description kubevirt
|
||||
Fence agent for KubeVirt platform.
|
||||
%files kubevirt
|
||||
%{_sbindir}/fence_kubevirt
|
||||
%{_mandir}/man8/fence_kubevirt.8*
|
||||
# bundled libraries
|
||||
/usr/lib/fence-agents/%{bundled_lib_dir}/kubevirt
|
||||
|
||||
%package lpar
|
||||
License: GPLv2+ and LGPLv2+
|
||||
Group: System Environment/Base
|
||||
@ -1175,6 +1389,36 @@ Fence agent for IBM z/VM over IP.
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Feb 11 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-88
|
||||
- fence_aws: upgrade botocore to fix IMDSv2 support
|
||||
Resolves: rhbz#2048857
|
||||
|
||||
* Wed Jan 19 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-85
|
||||
- fence_ibm_powervs: new fence agent
|
||||
Resolves: rhbz#1874862
|
||||
|
||||
* Mon Jan 17 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-84
|
||||
- fence_kubevirt: new fence agent
|
||||
Resolves: rhbz#1977588
|
||||
|
||||
* Thu Nov 11 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-83
|
||||
- fence_zvmip: add SSL/TLS support
|
||||
Resolves: rhbz#1963163
|
||||
|
||||
* Tue Nov 2 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-80
|
||||
- fence_sbd: dont spam logs when disable_timeout is enabled
|
||||
Resolves: rhbz#1971683
|
||||
|
||||
* Wed Oct 27 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-79
|
||||
- fence_amt_ws: fix "or" causing dead code
|
||||
Resolves: rhbz#2010710
|
||||
- fence_gce: add proxy support
|
||||
Resolves: rhbz#1969953
|
||||
|
||||
* Tue Oct 19 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-78
|
||||
- all agents: log exceptions when failing
|
||||
Resolves: rhbz#1470827
|
||||
|
||||
* Wed Aug 11 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-75
|
||||
- fence_gce: add serviceaccount JSON file support
|
||||
Resolves: rhbz#1685814
|
||||
|
Loading…
Reference in New Issue
Block a user