Compare commits

...

3 Commits

Author SHA1 Message Date
5bc5592f90 Import from CS git 2024-09-04 15:44:42 +00:00
b1f2b2fba3 import CS fence-agents-4.2.1-129.el8.2 2024-07-03 08:54:47 +00:00
ba7ff866a0 Import from AlmaLinux stable repository 2024-05-31 17:35:59 +00:00
15 changed files with 3117 additions and 147 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
From 639732ddca765b2f147ef0c0a896968e3304ca49 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Mon, 23 Oct 2023 09:28:55 +0200
Subject: [PATCH] fence_cisco_mds: undo metadata change, as it is an I/O agent
---
agents/cisco_mds/fence_cisco_mds.py | 2 +-
tests/data/metadata/fence_cisco_mds.xml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/agents/cisco_mds/fence_cisco_mds.py b/agents/cisco_mds/fence_cisco_mds.py
index 04cd1f842..fbb876a94 100644
--- a/agents/cisco_mds/fence_cisco_mds.py
+++ b/agents/cisco_mds/fence_cisco_mds.py
@@ -77,7 +77,7 @@ def main():
docs = {}
docs["shortdesc"] = "Fence agent for Cisco MDS"
- docs["longdesc"] = "fence_cisco_mds is a Power Fencing agent \
+ docs["longdesc"] = "fence_cisco_mds is an I/O Fencing agent \
which can be used with any Cisco MDS 9000 series with SNMP enabled device."
docs["vendorurl"] = "http://www.cisco.com"
show_docs(options, docs)
diff --git a/tests/data/metadata/fence_cisco_mds.xml b/tests/data/metadata/fence_cisco_mds.xml
index 2105ecccc..829c9dcbe 100644
--- a/tests/data/metadata/fence_cisco_mds.xml
+++ b/tests/data/metadata/fence_cisco_mds.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" ?>
<resource-agent name="fence_cisco_mds" shortdesc="Fence agent for Cisco MDS" >
-<longdesc>fence_cisco_mds is a Power Fencing agent which can be used with any Cisco MDS 9000 series with SNMP enabled device.</longdesc>
+<longdesc>fence_cisco_mds is an I/O Fencing agent which can be used with any Cisco MDS 9000 series with SNMP enabled device.</longdesc>
<vendor-url>http://www.cisco.com</vendor-url>
<parameters>
<parameter name="action" unique="0" required="1">

View File

@ -0,0 +1,159 @@
From dcb8ddd13c3dfad02e00c07f283251e0c2a60c46 Mon Sep 17 00:00:00 2001
From: Reid Wahl <nrwahl@protonmail.com>
Date: Mon, 16 Aug 2021 17:44:13 -0700
Subject: [PATCH] fence_zvmip: Update longdesc to document all required
functions
In RHBZ#1935641, IBM explained that the requesting user needs
authorization for more functions than what is currently documented.
They said:
"""
What we found is that you need rights from three different NICKS:
SERVER_MANAGEMENT, IMAGE_CHARACTERISTICS and IMAGE_OPERATIONS.
You won't be able to give a user all three NICKS.
Therefore, you have to create a new NICK with all capabilities from all
three NICKS together and then assign the new NICK to the USER
"ZCLUSTER".
Even better is to just use the needed Subset with a new NICK.
We found five commands which are used in the fencing code and on the
z/VM Log which should be enough for fencing to work.
We suggest creating following files:
File VSMWORK1 NAMELIST:
```
:nick.ZVM_FENCE
:list.
IMAGE_ACTIVATE
IMAGE_DEACTIVATE
IMAGE_STATUS_QUERY
CHECK_AUTHENTICATION
IMAGE_NAME_QUERY_DM
```
File VSMWORK1 AUTHLIST:
```
ZCLUSTER ALL ZVM_FENCE
```
For details, we suggest adding a link to the current z/VM docu:
- NAMELIST: https://www.ibm.com/support/knowledgecenter/de/SSB27U_7.2.0/com.ibm.zvm.v720.dmse6/namelst.htm
- AUTHLIST: https://www.ibm.com/support/knowledgecenter/de/SSB27U_7.2.0/com.ibm.zvm.v720.dmse6/auf.htm
"""
Resolves: RHBZ1935641
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
---
agents/zvm/fence_zvmip.py | 37 ++++++++++++++++++++++-------
tests/data/metadata/fence_zvmip.xml | 37 ++++++++++++++++++++++-------
2 files changed, 56 insertions(+), 18 deletions(-)
diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py
index 4f538e10d..c37950a20 100644
--- a/agents/zvm/fence_zvmip.py
+++ b/agents/zvm/fence_zvmip.py
@@ -199,21 +199,40 @@ def main():
docs = {}
docs["shortdesc"] = "Fence agent for use with z/VM Virtual Machines"
- docs["longdesc"] = """The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP
+ docs["longdesc"] = """The fence_zvmip agent is intended to be used with the
+z/VM SMAPI service via TCP/IP.
-To use this agent the z/VM SMAPI service needs to be configured to allow the virtual machine running this agent to connect to it and issue
-the image_recycle operation. This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look something similar to
-this:
+The z/VM SMAPI service must be configured so that the virtual machine running
+the agent can connect to the service, access the system's directory manager,
+and shortly thereafter run image_deactivate and image_activate. This involves
+updating the VSMWORK1 NAMELIST and VSMWORK1 AUTHLIST VMSYS:VSMWORK1 files.
+
+The NAMELIST entry assigns all the required functions to one nick and should
+look similar to this:
+
+:nick.ZVM_FENCE
+:list.
+IMAGE_ACTIVATE
+IMAGE_DEACTIVATE
+IMAGE_STATUS_QUERY
+CHECK_AUTHENTICATION
+IMAGE_NAME_QUERY_DM
+
+
+The AUTHLIST entry authorizes the user to perform all the functions associated
+with the nick, and should look similar to this:
Column 1 Column 66 Column 131
- | | |
- V V V
+| | |
+V V V
+
+XXXXXXXX ALL ZVM_FENCE
-XXXXXXXX ALL IMAGE_CHARACTERISTICS
+where XXXXXXXX is the name of the user in the authuser field of the request.
-Where XXXXXXX is the name of the virtual machine used in the authuser field of the request. This virtual machine also has to be authorized
-to access the system's directory manager.
+Refer to the official z/VM documentation for complete instructions and
+reference materials.
"""
docs["vendorurl"] = "http://www.ibm.com"
show_docs(options, docs)
diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml
index 6996ab736..96393bdfa 100644
--- a/tests/data/metadata/fence_zvmip.xml
+++ b/tests/data/metadata/fence_zvmip.xml
@@ -1,20 +1,39 @@
<?xml version="1.0" ?>
<resource-agent name="fence_zvmip" shortdesc="Fence agent for use with z/VM Virtual Machines" >
-<longdesc>The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP
+<longdesc>The fence_zvmip agent is intended to be used with the
+z/VM SMAPI service via TCP/IP.
-To use this agent the z/VM SMAPI service needs to be configured to allow the virtual machine running this agent to connect to it and issue
-the image_recycle operation. This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look something similar to
-this:
+The z/VM SMAPI service must be configured so that the virtual machine running
+the agent can connect to the service, access the system's directory manager,
+and shortly thereafter run image_deactivate and image_activate. This involves
+updating the VSMWORK1 NAMELIST and VSMWORK1 AUTHLIST VMSYS:VSMWORK1 files.
+
+The NAMELIST entry assigns all the required functions to one nick and should
+look similar to this:
+
+:nick.ZVM_FENCE
+:list.
+IMAGE_ACTIVATE
+IMAGE_DEACTIVATE
+IMAGE_STATUS_QUERY
+CHECK_AUTHENTICATION
+IMAGE_NAME_QUERY_DM
+
+
+The AUTHLIST entry authorizes the user to perform all the functions associated
+with the nick, and should look similar to this:
Column 1 Column 66 Column 131
- | | |
- V V V
+| | |
+V V V
+
+XXXXXXXX ALL ZVM_FENCE
-XXXXXXXX ALL IMAGE_CHARACTERISTICS
+where XXXXXXXX is the name of the user in the authuser field of the request.
-Where XXXXXXX is the name of the virtual machine used in the authuser field of the request. This virtual machine also has to be authorized
-to access the system's directory manager.
+Refer to the official z/VM documentation for complete instructions and
+reference materials.
</longdesc>
<vendor-url>http://www.ibm.com</vendor-url>
<parameters>

View File

@ -0,0 +1,41 @@
From adac1d81c5758235b6df46d0a91f1e948655848a Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Wed, 3 Jan 2024 10:17:50 +0100
Subject: [PATCH] fence_zvmip: fix manpage formatting
---
agents/zvm/fence_zvmip.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py
index f1cea2652..bd8273c49 100644
--- a/agents/zvm/fence_zvmip.py
+++ b/agents/zvm/fence_zvmip.py
@@ -210,12 +210,12 @@ def main():
The NAMELIST entry assigns all the required functions to one nick and should
look similar to this:
-:nick.ZVM_FENCE
-:list.
-IMAGE_ACTIVATE
-IMAGE_DEACTIVATE
-IMAGE_STATUS_QUERY
-CHECK_AUTHENTICATION
+:nick.ZVM_FENCE\n.br\n\
+:list.\n.br\n\
+IMAGE_ACTIVATE\n.br\n\
+IMAGE_DEACTIVATE\n.br\n\
+IMAGE_STATUS_QUERY\n.br\n\
+CHECK_AUTHENTICATION\n.br\n\
IMAGE_NAME_QUERY_DM
@@ -224,7 +224,7 @@ def main():
Column 1 Column 66 Column 131
-| | |
+| | |\n.br\n\
V V V
XXXXXXXX ALL ZVM_FENCE

View File

@ -0,0 +1,65 @@
From d655030770081e2dfe46f90e27620472a502289d Mon Sep 17 00:00:00 2001
From: David Lord <davidism@gmail.com>
Date: Thu, 2 May 2024 09:14:00 -0700
Subject: [PATCH] disallow invalid characters in keys to xmlattr filter
---
CHANGES.rst | 6 ++++++
src/jinja2/filters.py | 22 +++++++++++++++++-----
tests/test_filters.py | 11 ++++++-----
3 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/kubevirt/jinja2/filters.py b/kubevirt/jinja2/filters.py
index 4cf3c11fb..acd11976e 100644
--- a/kubevirt/jinja2/filters.py
+++ b/kubevirt/jinja2/filters.py
@@ -250,7 +250,9 @@ def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[t.Tuple[K
yield from value.items()
-_space_re = re.compile(r"\s", flags=re.ASCII)
+# Check for characters that would move the parser state from key to value.
+# https://html.spec.whatwg.org/#attribute-name-state
+_attr_key_re = re.compile(r"[\s/>=]", flags=re.ASCII)
@pass_eval_context
@@ -259,8 +261,14 @@ def do_xmlattr(
) -> str:
"""Create an SGML/XML attribute string based on the items in a dict.
- If any key contains a space, this fails with a ``ValueError``. Values that
- are neither ``none`` nor ``undefined`` are automatically escaped.
+ **Values** that are neither ``none`` nor ``undefined`` are automatically
+ escaped, safely allowing untrusted user input.
+
+ User input should not be used as **keys** to this filter. If any key
+ contains a space, ``/`` solidus, ``>`` greater-than sign, or ``=`` equals
+ sign, this fails with a ``ValueError``. Regardless of this, user input
+ should never be used as keys to this filter, or must be separately validated
+ first.
.. sourcecode:: html+jinja
@@ -280,6 +288,10 @@ def do_xmlattr(
As you can see it automatically prepends a space in front of the item
if the filter returned something unless the second parameter is false.
+ .. versionchanged:: 3.1.4
+ Keys with ``/`` solidus, ``>`` greater-than sign, or ``=`` equals sign
+ are not allowed.
+
.. versionchanged:: 3.1.3
Keys with spaces are not allowed.
"""
@@ -289,8 +301,8 @@ def do_xmlattr(
if value is None or isinstance(value, Undefined):
continue
- if _space_re.search(key) is not None:
- raise ValueError(f"Spaces are not allowed in attributes: '{key}'")
+ if _attr_key_re.search(key) is not None:
+ raise ValueError(f"Invalid character in attribute name: {key!r}")
items.append(f'{escape(key)}="{escape(value)}"')

View File

@ -0,0 +1,32 @@
From accff72ecc2f6cf5a76d9570198a93ac7c90270e Mon Sep 17 00:00:00 2001
From: Quentin Pradet <quentin.pradet@gmail.com>
Date: Mon, 17 Jun 2024 11:09:06 +0400
Subject: [PATCH] Merge pull request from GHSA-34jh-p97f-mpxf
* Strip Proxy-Authorization header on redirects
* Fix test_retry_default_remove_headers_on_redirect
* Set release date
---
CHANGES.rst | 5 +++++
src/urllib3/util/retry.py | 4 +++-
test/test_retry.py | 6 ++++-
test/with_dummyserver/test_poolmanager.py | 27 ++++++++++++++++++++---
4 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/kubevirt/urllib3/util/retry.py b/kubevirt/urllib3/util/retry.py
index 7a76a4a6ad..0456cceba4 100644
--- a/kubevirt/urllib3/util/retry.py
+++ b/kubevirt/urllib3/util/retry.py
@@ -189,7 +189,9 @@ class Retry:
RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
#: Default headers to be used for ``remove_headers_on_redirect``
- DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"])
+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(
+ ["Cookie", "Authorization", "Proxy-Authorization"]
+ )
#: Default maximum backoff time.
DEFAULT_BACKOFF_MAX = 120

View File

@ -0,0 +1,32 @@
From accff72ecc2f6cf5a76d9570198a93ac7c90270e Mon Sep 17 00:00:00 2001
From: Quentin Pradet <quentin.pradet@gmail.com>
Date: Mon, 17 Jun 2024 11:09:06 +0400
Subject: [PATCH] Merge pull request from GHSA-34jh-p97f-mpxf
* Strip Proxy-Authorization header on redirects
* Fix test_retry_default_remove_headers_on_redirect
* Set release date
---
CHANGES.rst | 5 +++++
src/urllib3/util/retry.py | 4 +++-
test/test_retry.py | 6 ++++-
test/with_dummyserver/test_poolmanager.py | 27 ++++++++++++++++++++---
4 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/aws/urllib3/util/retry.py b/aws/urllib3/util/retry.py
index 7a76a4a6ad..0456cceba4 100644
--- a/aws/urllib3/util/retry.py
+++ b/aws/urllib3/util/retry.py
@@ -189,7 +189,9 @@ class Retry:
RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
#: Default headers to be used for ``remove_headers_on_redirect``
- DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"])
+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(
+ ["Cookie", "Authorization", "Proxy-Authorization"]
+ )
#: Default maximum backoff time.
DEFAULT_BACKOFF_MAX = 120

View File

@ -0,0 +1,203 @@
diff --color -uNr a/kubevirt/setuptools/package_index.py b/kubevirt/setuptools/package_index.py
--- a/kubevirt/setuptools/package_index.py 2021-10-22 22:55:51.000000000 +0200
+++ b/kubevirt/setuptools/package_index.py 2024-07-24 14:06:14.833852463 +0200
@@ -1,5 +1,6 @@
"""PyPI and direct package downloading"""
import sys
+import subprocess
import os
import re
import io
@@ -558,7 +559,7 @@
scheme = URL_SCHEME(spec)
if scheme:
# It's a url, download it to tmpdir
- found = self._download_url(scheme.group(1), spec, tmpdir)
+ found = self._download_url(spec, tmpdir)
base, fragment = egg_info_for_url(spec)
if base.endswith('.py'):
found = self.gen_setup(found, fragment, tmpdir)
@@ -777,7 +778,7 @@
raise DistutilsError("Download error for %s: %s"
% (url, v)) from v
- def _download_url(self, scheme, url, tmpdir):
+ def _download_url(self, url, tmpdir):
# Determine download filename
#
name, fragment = egg_info_for_url(url)
@@ -792,19 +793,59 @@
filename = os.path.join(tmpdir, name)
- # Download the file
- #
- if scheme == 'svn' or scheme.startswith('svn+'):
- return self._download_svn(url, filename)
- elif scheme == 'git' or scheme.startswith('git+'):
- return self._download_git(url, filename)
- elif scheme.startswith('hg+'):
- return self._download_hg(url, filename)
- elif scheme == 'file':
- return urllib.request.url2pathname(urllib.parse.urlparse(url)[2])
- else:
- self.url_ok(url, True) # raises error if not allowed
- return self._attempt_download(url, filename)
+ return self._download_vcs(url, filename) or self._download_other(url, filename)
+
+ @staticmethod
+ def _resolve_vcs(url):
+ """
+ >>> rvcs = PackageIndex._resolve_vcs
+ >>> rvcs('git+http://foo/bar')
+ 'git'
+ >>> rvcs('hg+https://foo/bar')
+ 'hg'
+ >>> rvcs('git:myhost')
+ 'git'
+ >>> rvcs('hg:myhost')
+ >>> rvcs('http://foo/bar')
+ """
+ scheme = urllib.parse.urlsplit(url).scheme
+ pre, sep, post = scheme.partition('+')
+ # svn and git have their own protocol; hg does not
+ allowed = set(['svn', 'git'] + ['hg'] * bool(sep))
+ return next(iter({pre} & allowed), None)
+
+ def _download_vcs(self, url, spec_filename):
+ vcs = self._resolve_vcs(url)
+ if not vcs:
+ return
+ if vcs == 'svn':
+ raise DistutilsError(
+ f"Invalid config, SVN download is not supported: {url}"
+ )
+
+ filename, _, _ = spec_filename.partition('#')
+ url, rev = self._vcs_split_rev_from_url(url)
+
+ self.info(f"Doing {vcs} clone from {url} to {filename}")
+ subprocess.check_call([vcs, 'clone', '--quiet', url, filename])
+
+ co_commands = dict(
+ git=[vcs, '-C', filename, 'checkout', '--quiet', rev],
+ hg=[vcs, '--cwd', filename, 'up', '-C', '-r', rev, '-q'],
+ )
+ if rev is not None:
+ self.info(f"Checking out {rev}")
+ subprocess.check_call(co_commands[vcs])
+
+ return filename
+
+ def _download_other(self, url, filename):
+ scheme = urllib.parse.urlsplit(url).scheme
+ if scheme == 'file': # pragma: no cover
+ return urllib.request.url2pathname(urllib.parse.urlparse(url).path)
+ # raise error if not allowed
+ self.url_ok(url, True)
+ return self._attempt_download(url, filename)
def scan_url(self, url):
self.process_url(url, True)
@@ -831,77 +872,37 @@
os.unlink(filename)
raise DistutilsError("Unexpected HTML page found at " + url)
- def _download_svn(self, url, filename):
- warnings.warn("SVN download support is deprecated", UserWarning)
- url = url.split('#', 1)[0] # remove any fragment for svn's sake
- creds = ''
- if url.lower().startswith('svn:') and '@' in url:
- scheme, netloc, path, p, q, f = urllib.parse.urlparse(url)
- if not netloc and path.startswith('//') and '/' in path[2:]:
- netloc, path = path[2:].split('/', 1)
- auth, host = _splituser(netloc)
- if auth:
- if ':' in auth:
- user, pw = auth.split(':', 1)
- creds = " --username=%s --password=%s" % (user, pw)
- else:
- creds = " --username=" + auth
- netloc = host
- parts = scheme, netloc, url, p, q, f
- url = urllib.parse.urlunparse(parts)
- self.info("Doing subversion checkout from %s to %s", url, filename)
- os.system("svn checkout%s -q %s %s" % (creds, url, filename))
- return filename
-
@staticmethod
- def _vcs_split_rev_from_url(url, pop_prefix=False):
- scheme, netloc, path, query, frag = urllib.parse.urlsplit(url)
-
- scheme = scheme.split('+', 1)[-1]
-
- # Some fragment identification fails
- path = path.split('#', 1)[0]
-
- rev = None
- if '@' in path:
- path, rev = path.rsplit('@', 1)
-
- # Also, discard fragment
- url = urllib.parse.urlunsplit((scheme, netloc, path, query, ''))
-
- return url, rev
-
- def _download_git(self, url, filename):
- filename = filename.split('#', 1)[0]
- url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
-
- self.info("Doing git clone from %s to %s", url, filename)
- os.system("git clone --quiet %s %s" % (url, filename))
+ def _vcs_split_rev_from_url(url):
+ """
+ Given a possible VCS URL, return a clean URL and resolved revision if any.
- if rev is not None:
- self.info("Checking out %s", rev)
- os.system("git -C %s checkout --quiet %s" % (
- filename,
- rev,
- ))
+ >>> vsrfu = PackageIndex._vcs_split_rev_from_url
+ >>> vsrfu('git+https://github.com/pypa/setuptools@v69.0.0#egg-info=setuptools')
+ ('https://github.com/pypa/setuptools', 'v69.0.0')
+ >>> vsrfu('git+https://github.com/pypa/setuptools#egg-info=setuptools')
+ ('https://github.com/pypa/setuptools', None)
+ >>> vsrfu('http://foo/bar')
+ ('http://foo/bar', None)
+ """
+ parts = urllib.parse.urlsplit(url)
- return filename
+ clean_scheme = parts.scheme.split('+', 1)[-1]
- def _download_hg(self, url, filename):
- filename = filename.split('#', 1)[0]
- url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True)
+ # Some fragment identification fails
+ no_fragment_path, _, _ = parts.path.partition('#')
- self.info("Doing hg clone from %s to %s", url, filename)
- os.system("hg clone --quiet %s %s" % (url, filename))
+ pre, sep, post = no_fragment_path.rpartition('@')
+ clean_path, rev = (pre, post) if sep else (post, None)
- if rev is not None:
- self.info("Updating to %s", rev)
- os.system("hg --cwd %s up -C -r %s -q" % (
- filename,
- rev,
- ))
+ resolved = parts._replace(
+ scheme=clean_scheme,
+ path=clean_path,
+ # discard the fragment
+ fragment='',
+ ).geturl()
- return filename
+ return resolved, rev
def debug(self, msg, *args):
log.debug(msg, *args)

View File

@ -0,0 +1,22 @@
--- a/agents/scsi/fence_scsi.py 2024-01-03 14:15:20.755284113 +0100
+++ b/agents/scsi/fence_scsi.py 2024-01-03 12:32:01.598598127 +0100
@@ -190,7 +190,8 @@
cmd = options["--sg_persist-path"] + " -n -i " + opts + "-r -d " + dev
out = run_cmd(options, cmd)
if out["rc"] and fail:
- fail_usage("Cannot get reservation key")
+ fail_usage('Cannot get reservation key on device "' + dev
+ + '": ' + out["err"])
match = re.search(r"\s+key=0x(\S+)\s+", out["out"], re.IGNORECASE)
return match.group(1) if match else None
@@ -204,7 +205,8 @@
cmd = options["--sg_persist-path"] + " -n -i " + opts + "-k -d " + dev
out = run_cmd(options, cmd)
if out["rc"]:
- fail_usage("Cannot get registration keys", fail)
+ fail_usage('Cannot get registration keys on device "' + dev
+ + '": ' + out["err"], fail)
if not fail:
return []
for line in out["out"].split("\n"):

View File

@ -0,0 +1,68 @@
From 9d0d0d013c7edae43a4ebc5f46bf2e7a4f127654 Mon Sep 17 00:00:00 2001
From: "sreejit.mohanan" <sreejit.mohanan@nutanix.com>
Date: Fri, 17 Feb 2023 18:04:03 -0800
Subject: [PATCH] fence_scsi: fix registration handling if ISID conflicts ISID
(Initiator Session ID) belonging to I_T Nexus changes for RHEL based on the
session ID. This means that the connection to the device can be set up with
different ISID on reconnects.
fence_scsi treats same key as a tip to ignore issuing registration
to the device but if the device was registered using a different
ISID, the key would be the same but the I_T Nexus (new ISID) would
not have access to the device.
Fixing this by preempting the old key and replacing with the current
one.
---
agents/scsi/fence_scsi.py | 35 ++++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py
index f9e6823b2..85e4f29e6 100644
--- a/agents/scsi/fence_scsi.py
+++ b/agents/scsi/fence_scsi.py
@@ -137,12 +137,41 @@ def register_dev(options, dev):
for slave in get_mpath_slaves(dev):
register_dev(options, slave)
return True
- if get_reservation_key(options, dev, False) == options["--key"]:
- return True
+
+ # Check if any registration exists for the key already. We track this in
+ # order to decide whether the existing registration needs to be cleared.
+ # This is needed since the previous registration could be for a
+ # different I_T nexus (different ISID).
+ registration_key_exists = False
+ if options["--key"] in get_registration_keys(options, dev):
+ registration_key_exists = True
+ if not register_helper(options, options["--key"], dev):
+ return False
+
+ if registration_key_exists:
+ # If key matches, make sure it matches with the connection that
+ # exists right now. To do this, we can issue a preempt with same key
+ # which should replace the old invalid entries from the target.
+ if not preempt(options, options["--key"], dev):
+ return False
+
+ # If there was no reservation, we need to issue another registration
+ # since the previous preempt would clear registration made above.
+ if get_reservation_key(options, dev, False) != options["--key"]:
+ return register_helper(options, options["--key"], dev)
+ return True
+
+# cancel registration without aborting tasks
+def preempt(options, host, dev):
+ reset_dev(options,dev)
+ cmd = options["--sg_persist-path"] + " -n -o -P -T 5 -K " + host + " -S " + options["--key"] + " -d " + dev
+ return not bool(run_cmd(options, cmd)["rc"])
+
+# helper function to send the register command
+def register_helper(options, host, dev):
reset_dev(options, dev)
cmd = options["--sg_persist-path"] + " -n -o -I -S " + options["--key"] + " -d " + dev
cmd += " -Z" if "--aptpl" in options else ""
- #cmd return code != 0 but registration can be successful
return not bool(run_cmd(options, cmd)["err"])

View File

@ -0,0 +1,103 @@
From 34baef58db442148b8e067509d2cdd37b7a91ef4 Mon Sep 17 00:00:00 2001
From: "sreejit.mohanan" <sreejit.mohanan@nutanix.com>
Date: Thu, 7 Sep 2023 15:57:51 -0700
Subject: [PATCH] fence_scsi: fix registration handling in device 'off'
workflows
ISID (Initiator Session ID) belonging to I_T Nexus changes for
RHEL based on the session ID. This means that the connection to
the device can be set up with different ISID on reconnects.
When a device is powered off, fence_scsi assumes that the client
has a registration to the device and sends a preempt-and-abort
request which ends up failing due to reservation conflict.
Fixing this by registering the host key with the device and preempting
the old registration (if it exists). This should make sure that the
host is able to preempt the other key successfully.
---
agents/scsi/fence_scsi.py | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py
index 42530ceb5..519319bf5 100644
--- a/agents/scsi/fence_scsi.py
+++ b/agents/scsi/fence_scsi.py
@@ -41,7 +41,7 @@ def set_status(conn, options):
for dev in options["devices"]:
is_block_device(dev)
- register_dev(options, dev)
+ register_dev(options, dev, options["--key"])
if options["--key"] not in get_registration_keys(options, dev):
count += 1
logging.debug("Failed to register key "\
@@ -62,7 +62,7 @@ def set_status(conn, options):
fail_usage("Failed: keys cannot be same. You can not fence yourself.")
for dev in options["devices"]:
is_block_device(dev)
-
+ register_dev(options, dev, host_key)
if options["--key"] in get_registration_keys(options, dev):
preempt_abort(options, host_key, dev)
@@ -131,11 +131,11 @@ def reset_dev(options, dev):
return run_cmd(options, options["--sg_turs-path"] + " " + dev)["rc"]
-def register_dev(options, dev):
+def register_dev(options, dev, key):
dev = os.path.realpath(dev)
if re.search(r"^dm", dev[5:]):
for slave in get_mpath_slaves(dev):
- register_dev(options, slave)
+ register_dev(options, slave, key)
return True
# Check if any registration exists for the key already. We track this in
@@ -143,34 +143,35 @@ def register_dev(options, dev):
# This is needed since the previous registration could be for a
# different I_T nexus (different ISID).
registration_key_exists = False
- if options["--key"] in get_registration_keys(options, dev):
+ if key in get_registration_keys(options, dev):
+ logging.debug("Registration key exists for device " + dev)
registration_key_exists = True
- if not register_helper(options, options["--key"], dev):
+ if not register_helper(options, dev, key):
return False
if registration_key_exists:
# If key matches, make sure it matches with the connection that
# exists right now. To do this, we can issue a preempt with same key
# which should replace the old invalid entries from the target.
- if not preempt(options, options["--key"], dev):
+ if not preempt(options, key, dev, key):
return False
# If there was no reservation, we need to issue another registration
# since the previous preempt would clear registration made above.
- if get_reservation_key(options, dev, False) != options["--key"]:
- return register_helper(options, options["--key"], dev)
+ if get_reservation_key(options, dev, False) != key:
+ return register_helper(options, dev, key)
return True
-# cancel registration without aborting tasks
-def preempt(options, host, dev):
+# helper function to preempt host with 'key' using 'host_key' without aborting tasks
+def preempt(options, host_key, dev, key):
reset_dev(options,dev)
- cmd = options["--sg_persist-path"] + " -n -o -P -T 5 -K " + host + " -S " + options["--key"] + " -d " + dev
+ cmd = options["--sg_persist-path"] + " -n -o -P -T 5 -K " + host_key + " -S " + key + " -d " + dev
return not bool(run_cmd(options, cmd)["rc"])
# helper function to send the register command
-def register_helper(options, host, dev):
+def register_helper(options, dev, key):
reset_dev(options, dev)
- cmd = options["--sg_persist-path"] + " -n -o -I -S " + options["--key"] + " -d " + dev
+ cmd = options["--sg_persist-path"] + " -n -o -I -S " + key + " -d " + dev
cmd += " -Z" if "--aptpl" in options else ""
return not bool(run_cmd(options, cmd)["rc"])

View File

@ -0,0 +1,93 @@
--- fence-agents-4.2.1/agents/scsi/fence_scsi.py.old 2024-01-02 12:22:30.198853290 +0100
+++ fence-agents-4.2.1/agents/scsi/fence_scsi.py 2024-01-02 12:24:35.509549785 +0100
@@ -84,14 +84,14 @@
# check if host is ready to execute actions
def do_action_monitor(options):
# Check if required binaries are installed
- if bool(run_cmd(options, options["--sg_persist-path"] + " -V")["err"]):
+ if bool(run_cmd(options, options["--sg_persist-path"] + " -V")["rc"]):
logging.error("Unable to run " + options["--sg_persist-path"])
return 1
- elif bool(run_cmd(options, options["--sg_turs-path"] + " -V")["err"]):
+ elif bool(run_cmd(options, options["--sg_turs-path"] + " -V")["rc"]):
logging.error("Unable to run " + options["--sg_turs-path"])
return 1
elif ("--devices" not in options and
- bool(run_cmd(options, options["--vgs-path"] + " --version")["err"])):
+ bool(run_cmd(options, options["--vgs-path"] + " --version")["rc"])):
logging.error("Unable to run " + options["--vgs-path"])
return 1
@@ -102,11 +102,13 @@
return 0
-#run command, returns dict, ret["err"] = exit code; ret["out"] = output
+# run command, returns dict, ret["rc"] = exit code; ret["out"] = output;
+# ret["err"] = error
def run_cmd(options, cmd):
ret = {}
- (ret["err"], ret["out"], _) = run_command(options, cmd)
+ (ret["rc"], ret["out"], ret["err"]) = run_command(options, cmd)
ret["out"] = "".join([i for i in ret["out"] if i is not None])
+ ret["err"] = "".join([i for i in ret["err"] if i is not None])
return ret
@@ -122,11 +124,11 @@
def preempt_abort(options, host, dev):
reset_dev(options,dev)
cmd = options["--sg_persist-path"] + " -n -o -A -T 5 -K " + host + " -S " + options["--key"] + " -d " + dev
- return not bool(run_cmd(options, cmd)["err"])
+ return not bool(run_cmd(options, cmd)["rc"])
def reset_dev(options, dev):
- return run_cmd(options, options["--sg_turs-path"] + " " + dev)["err"]
+ return run_cmd(options, options["--sg_turs-path"] + " " + dev)["rc"]
def register_dev(options, dev, key):
@@ -171,13 +173,13 @@
reset_dev(options, dev)
cmd = options["--sg_persist-path"] + " -n -o -I -S " + key + " -d " + dev
cmd += " -Z" if "--aptpl" in options else ""
- return not bool(run_cmd(options, cmd)["err"])
+ return not bool(run_cmd(options, cmd)["rc"])
def reserve_dev(options, dev):
reset_dev(options,dev)
cmd = options["--sg_persist-path"] + " -n -o -R -T 5 -K " + options["--key"] + " -d " + dev
- return not bool(run_cmd(options, cmd)["err"])
+ return not bool(run_cmd(options, cmd)["rc"])
def get_reservation_key(options, dev, fail=True):
@@ -187,7 +189,7 @@
opts = "-y "
cmd = options["--sg_persist-path"] + " -n -i " + opts + "-r -d " + dev
out = run_cmd(options, cmd)
- if out["err"] and fail:
+ if out["rc"] and fail:
fail_usage("Cannot get reservation key")
match = re.search(r"\s+key=0x(\S+)\s+", out["out"], re.IGNORECASE)
return match.group(1) if match else None
@@ -201,7 +203,7 @@
opts = "-y "
cmd = options["--sg_persist-path"] + " -n -i " + opts + "-k -d " + dev
out = run_cmd(options, cmd)
- if out["err"]:
+ if out["rc"]:
fail_usage("Cannot get registration keys", fail)
if not fail:
return []
@@ -319,7 +321,7 @@
"--options vg_attr,pv_name "+\
"--config 'global { locking_type = 0 } devices { preferred_names = [ \"^/dev/dm\" ] }'"
out = run_cmd(options, cmd)
- if out["err"]:
+ if out["rc"]:
fail_usage("Failed: Cannot get shared devices")
for line in out["out"].splitlines():
vg_attr, pv_name = line.strip().split(":")

View File

@ -0,0 +1,365 @@
From 55451b6fd007e6f9a6d6860e95304b7c5c27cc1b Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 2 May 2024 15:10:16 +0200
Subject: [PATCH 1/2] fencing: add support for docs["agent_name"] to use the
main agent name when generating manpages
---
lib/fencing.py.py | 12 +++++++++---
tests/data/metadata/fence_eps.xml | 9 ++++++---
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/lib/fencing.py.py b/lib/fencing.py.py
index 511eb2689..66e2ff156 100644
--- a/lib/fencing.py.py
+++ b/lib/fencing.py.py
@@ -603,7 +603,7 @@ def usage(avail_opt):
if len(value["help"]) != 0:
print(" " + _join_wrap([value["help"]], first_indent=3))
-def metadata(options, avail_opt, docs):
+def metadata(options, avail_opt, docs, agent_name=os.path.basename(sys.argv[0])):
# avail_opt has to be unique, if there are duplicities then they should be removed
sorted_list = [(key, all_opt[key]) for key in list(set(avail_opt)) if "longopt" in all_opt[key]]
# Find keys that are going to replace inconsistent names
@@ -617,7 +617,7 @@ def metadata(options, avail_opt, docs):
docs["longdesc"] = re.sub(r"\\f[BPIR]|\.P|\.TP|\.br\n", r"", docs["longdesc"])
print("<?xml version=\"1.0\" ?>")
- print("<resource-agent name=\"" + os.path.basename(sys.argv[0]) + \
+ print("<resource-agent name=\"" + agent_name + \
"\" shortdesc=\"" + docs["shortdesc"] + "\" >")
for (symlink, desc) in docs.get("symlink", []):
print("<symlink name=\"" + symlink + "\" shortdesc=\"" + desc + "\"/>")
@@ -928,9 +928,15 @@ def show_docs(options, docs=None):
sys.exit(0)
if options.get("--action", "") in ["metadata", "manpage"]:
+ if options["--action"] == "metadata" or "agent_name" not in docs:
+ agent_name=os.path.basename(sys.argv[0])
+ else:
+ agent_name=docs["agent_name"]
+
+
if "port_as_ip" in device_opt:
device_opt.remove("separator")
- metadata(options, device_opt, docs)
+ metadata(options, device_opt, docs, agent_name)
sys.exit(0)
if "--version" in options:
diff --git a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml
index 3f9ebdc22..a3aeb1aea 100644
--- a/tests/data/metadata/fence_eps.xml
+++ b/tests/data/metadata/fence_eps.xml
@@ -1,9 +1,12 @@
<?xml version="1.0" ?>
<resource-agent name="fence_eps" shortdesc="Fence agent for ePowerSwitch" >
-<longdesc>fence_eps is a Power Fencing agent which can be used with the ePowerSwitch 8M+ power switch to fence connected machines. Fence agent works ONLY on 8M+ device, because this is only one, which has support for hidden page feature.
+<symlink name="fence_epsr2" shortdesc="Fence agent for ePowerSwitch R2 and newer"/>
+<longdesc>fence_eps is a Power Fencing agent which can be used with the ePowerSwitch 8M+ power switch to fence connected machines. It ONLY works on 8M+ devices, as they support the hidden page feature.
-Agent basically works by connecting to hidden page and pass appropriate arguments to GET request. This means, that hidden page feature must be enabled and properly configured.</longdesc>
-<vendor-url>http://www.epowerswitch.com</vendor-url>
+The agent works by connecting to the hidden page and pass the appropriate arguments to GET request. This means, that the hidden page feature must be enabled and properly configured.
+
+NOTE: In most cases you want to use fence_epsr2, as fence_eps only works with older hardware.</longdesc>
+<vendor-url>https://www.neol.com</vendor-url>
<parameters>
<parameter name="action" unique="0" required="1">
<getopt mixed="-o, --action=[action]" />
From 639f5293e0b2c0153ea01bf37534b74f436dd630 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 13 Feb 2024 11:11:25 +0100
Subject: [PATCH 2/2] fence_eps: add fence_epsr2 for ePowerSwitch R2 and newer
---
agents/eps/fence_eps.py | 46 ++++---
fence-agents.spec.in | 4 +-
tests/data/metadata/fence_epsr2.xml | 178 ++++++++++++++++++++++++++++
3 files changed, 211 insertions(+), 17 deletions(-)
create mode 100644 tests/data/metadata/fence_epsr2.xml
diff --git a/agents/eps/fence_eps.py b/agents/eps/fence_eps.py
index 81e439533..1e6bda099 100644
--- a/agents/eps/fence_eps.py
+++ b/agents/eps/fence_eps.py
@@ -3,8 +3,8 @@
# The Following Agent Has Been Tested On:
# ePowerSwitch 8M+ version 1.0.0.4
-import sys, re
-import base64, string, socket
+import sys, os, re
+import base64, socket
import logging
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
@@ -37,7 +37,7 @@ def eps_run_command(options, params):
options["--password"] = "" # Default is empty password
# String for Authorization header
- auth_str = 'Basic ' + string.strip(base64.encodestring(options["--username"]+':'+options["--password"]))
+ auth_str = 'Basic ' + str(base64.encodebytes(bytes(options["--username"]+':'+options["--password"], "utf-8")).decode("utf-8").strip())
logging.debug("Authorization: %s\n", auth_str)
conn.putheader('Authorization', auth_str)
@@ -60,16 +60,22 @@ def eps_run_command(options, params):
logging.error("Failed: {}".format(str(e)))
fail(EC_LOGIN_DENIED)
- return result
+ return result.decode("utf-8", "ignore")
def get_power_status(conn, options):
del conn
ret_val = eps_run_command(options, "")
result = {}
- status = re.findall(r"p(\d{2})=(0|1)\s*\<br\>", ret_val.lower())
+ if os.path.basename(sys.argv[0]) == "fence_eps":
+ status = re.findall(r"p(\d{2})=(0|1)\s*\<br\>", ret_val.lower())
+ elif os.path.basename(sys.argv[0]) == "fence_epsr2":
+ status = re.findall(r"m0:o(\d)=(on|off)\s*", ret_val.lower())
for out_num, out_stat in status:
- result[out_num] = ("", (out_stat == "1" and "on" or "off"))
+ if os.path.basename(sys.argv[0]) == "fence_eps":
+ result[out_num] = ("", (out_stat == "1" and "on" or "off"))
+ elif os.path.basename(sys.argv[0]) == "fence_epsr2":
+ result[out_num] = ("", out_stat)
if not options["--action"] in ['monitor', 'list']:
if not options["--plug"] in result:
@@ -81,7 +87,12 @@ def get_power_status(conn, options):
def set_power_status(conn, options):
del conn
- eps_run_command(options, "P%s=%s"%(options["--plug"], (options["--action"] == "on" and "1" or "0")))
+ if os.path.basename(sys.argv[0]) == "fence_eps":
+ eps_run_command(options, "P%s=%s"%(options["--plug"], (options["--action"] == "on" and "1" or "0")))
+ elif os.path.basename(sys.argv[0]) == "fence_epsr2":
+ if options["--action"] == "reboot":
+ options["--action"] = "off"
+ eps_run_command(options, "M0:O%s=%s"%(options["--plug"], options["--action"]))
# Define new option
def eps_define_new_opts():
@@ -107,20 +118,25 @@ def main():
options = check_input(device_opt, process_input(device_opt))
docs = {}
+ docs["agent_name"] = "fence_eps"
docs["shortdesc"] = "Fence agent for ePowerSwitch"
- docs["longdesc"] = "fence_eps is a Power Fencing agent \
+ docs["longdesc"] = os.path.basename(sys.argv[0]) + " is a Power Fencing agent \
which can be used with the ePowerSwitch 8M+ power switch to fence \
-connected machines. Fence agent works ONLY on 8M+ device, because \
-this is only one, which has support for hidden page feature. \
+connected machines. It ONLY works on 8M+ devices, as \
+they support the hidden page feature. \
\n.TP\n\
-Agent basically works by connecting to hidden page and pass \
-appropriate arguments to GET request. This means, that hidden \
-page feature must be enabled and properly configured."
- docs["vendorurl"] = "http://www.epowerswitch.com"
+The agent works by connecting to the hidden page and pass \
+the appropriate arguments to GET request. This means, that the hidden \
+page feature must be enabled and properly configured. \
+\n.TP\n\
+NOTE: In most cases you want to use fence_epsr2, as fence_eps \
+only works with older hardware."
+ docs["vendorurl"] = "https://www.neol.com"
+ docs["symlink"] = [("fence_epsr2", "Fence agent for ePowerSwitch R2 and newer")]
show_docs(options, docs)
run_delay(options)
- #Run fence action. Conn is None, beacause we always need open new http connection
+ #Run fence action. Conn is None, because we always need open new http connection
result = fence_action(None, options, set_power_status, get_power_status, get_power_status)
sys.exit(result)
diff --git a/tests/data/metadata/fence_epsr2.xml b/tests/data/metadata/fence_epsr2.xml
new file mode 100644
index 000000000..37074e052
--- /dev/null
+++ b/tests/data/metadata/fence_epsr2.xml
@@ -0,0 +1,178 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_epsr2" shortdesc="Fence agent for ePowerSwitch" >
+<symlink name="fence_epsr2" shortdesc="Fence agent for ePowerSwitch R2 and newer"/>
+<longdesc>fence_epsr2 is a Power Fencing agent which can be used with the ePowerSwitch 8M+ power switch to fence connected machines. It ONLY works on 8M+ devices, as they support the hidden page feature.
+
+The agent works by connecting to the hidden page and pass the appropriate arguments to GET request. This means, that the hidden page feature must be enabled and properly configured.
+
+NOTE: In most cases you want to use fence_epsr2, as fence_eps only works with older hardware.</longdesc>
+<vendor-url>https://www.neol.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="hidden_page" unique="0" required="0" deprecated="1">
+ <getopt mixed="-c, --page=[page]" />
+ <content type="string" default="hidden.htm" />
+ <shortdesc lang="en">Name of hidden page</shortdesc>
+ </parameter>
+ <parameter name="ip" unique="0" required="1" obsoletes="ipaddr">
+ <getopt mixed="-a, --ip=[ip]" />
+ <content type="string" />
+ <shortdesc lang="en">IP address or hostname of fencing device</shortdesc>
+ </parameter>
+ <parameter name="ipaddr" unique="0" required="1" deprecated="1">
+ <getopt mixed="-a, --ip=[ip]" />
+ <content type="string" />
+ <shortdesc lang="en">IP address or hostname of fencing device</shortdesc>
+ </parameter>
+ <parameter name="ipport" unique="0" required="0">
+ <getopt mixed="-u, --ipport=[port]" />
+ <content type="integer" default="80" />
+ <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+ </parameter>
+ <parameter name="login" unique="0" required="0" deprecated="1">
+ <getopt mixed="-l, --username=[name]" />
+ <content type="string" />
+ <shortdesc lang="en">Login name</shortdesc>
+ </parameter>
+ <parameter name="page" unique="0" required="0" obsoletes="hidden_page">
+ <getopt mixed="-c, --page=[page]" />
+ <content type="string" default="hidden.htm" />
+ <shortdesc lang="en">Name of hidden page</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="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="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 run to retrieve password</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="username" unique="0" required="0" obsoletes="login">
+ <getopt mixed="-l, --username=[name]" />
+ <content type="string" />
+ <shortdesc lang="en">Login name</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]" />
+ <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="plug_separator" unique="0" required="0">
+ <getopt mixed="--plug-separator=[char]" />
+ <content type="string" default="," />
+ <shortdesc lang="en">Separator for plug parameter when specifying more than 1 plug</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="20" />
+ <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="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>

View File

@ -87,7 +87,7 @@
Name: fence-agents
Summary: Set of unified programs capable of host isolation ("fencing")
Version: 4.2.1
Release: 121%{?alphatag:.%{alphatag}}%{?dist}.4
Release: 129%{?alphatag:.%{alphatag}}%{?dist}.4
License: GPLv2+ and LGPLv2+
Group: System Environment/Base
URL: https://github.com/ClusterLabs/fence-agents
@ -274,13 +274,26 @@ Patch131: bz2187329-fence_scsi-2-support-space-separated-devices.patch
Patch132: bz2211460-fence_azure-arm-1-stack-hub-support.patch
Patch133: bz2211460-fence_azure-arm-2-metadata-endpoint-error-message.patch
Patch134: bz2155453-fence_ibm_powervs-performance-improvements.patch
Patch135: RHEL-14343-fence_zvmip-1-document-user-permissions.patch
Patch136: RHEL-14031-1-all-agents-metadata-update-IO-Power-Network.patch
Patch137: RHEL-14031-2-fence_cisco_mds-undo-metadata-change.patch
Patch138: RHEL-5397-fence_scsi-1-fix-ISID-reg-handling.patch
Patch139: RHEL-5397-fence_scsi-2-fix-ISID-reg-handling-off.patch
Patch140: RHEL-5397-fence_scsi-3-fix-run_cmd.patch
Patch141: RHEL-5397-4-fence_scsi-log-err.patch
Patch142: RHEL-14343-fence_zvmip-2-fix-manpage-formatting.patch
Patch143: RHEL-7734-fence_eps-add-fence_epsr2-for-ePowerSwitch-R2-and-newer.patch
### HA support libs/utils ###
# all archs
Patch1000: bz2218234-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch
Patch1001: RHEL-22179-kubevirt-fix-bundled-jinja2-CVE-2024-22195.patch
Patch1001: RHEL-22174-kubevirt-fix-bundled-jinja2-CVE-2024-22195.patch
Patch1002: RHEL-35655-kubevirt-fix-bundled-jinja2-CVE-2024-34064.patch
Patch1003: RHEL-43568-1-kubevirt-fix-bundled-urllib3-CVE-2024-37891.patch
Patch1004: RHEL-50223-setuptools-fix-CVE-2024-6345.patch
# cloud (x86_64 only)
Patch2000: bz2218234-2-aws-fix-bundled-dateutil-CVE-2007-4559.patch
Patch2001: RHEL-43568-2-aws-fix-bundled-urllib3-CVE-2024-37891.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 ibm_powervs ibm_vpc 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
@ -358,141 +371,150 @@ BuildRequires: python3-google-api-client python3-pip python3-wheel python3-jinja
%prep
%setup -q -n %{name}-%{version}
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1 -F2
%patch31 -p1 -F2
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1 -F1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1 -F2
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch47 -p1
%patch48 -p1 -F1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
%patch60 -p1 -F1
%patch61 -p1
%patch62 -p1
%patch63 -p1
%patch64 -p1
%patch65 -p1 -F1
%patch66 -p1
%patch67 -p1
%patch68 -p1
%patch69 -p1
%patch70 -p1
%patch71 -p1
%patch72 -p1
%patch73 -p1
%patch74 -p1
%patch75 -p1
%patch76 -p1
%patch77 -p1
%patch78 -p1
%patch79 -p1
%patch80 -p1
%patch81 -p1
%patch82 -p1
%patch83 -p1
%patch84 -p1
%patch85 -p1
%patch86 -p1 -F1
%patch87 -p1
%patch88 -p1
%patch89 -p1
%patch90 -p1
%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
%patch109 -p1
%patch110 -p1
%patch111 -p1
%patch112 -p1
%patch113 -p1
%patch114 -p1
%patch115 -p1
%patch116 -p1
%patch117 -p1
%patch118 -p1
%patch119 -p1
%patch120 -p1
%patch121 -p1
%patch122 -p1 -F2
%patch123 -p1
%patch124 -p1
%patch125 -p1
%patch126 -p1
%patch127 -p1
%patch128 -p1 -F2
%patch129 -p1
%patch130 -p1
%patch131 -p1
%patch132 -p1
%patch133 -p1
%patch134 -p1
%patch -p1 -P 0
%patch -p1 -P 1
%patch -p1 -P 2
%patch -p1 -P 3
%patch -p1 -P 4
%patch -p1 -P 5
%patch -p1 -P 6
%patch -p1 -P 7
%patch -p1 -P 8
%patch -p1 -P 9
%patch -p1 -P 10
%patch -p1 -P 11
%patch -p1 -P 12
%patch -p1 -P 13
%patch -p1 -P 14
%patch -p1 -P 15
%patch -p1 -P 16
%patch -p1 -P 17
%patch -p1 -P 18
%patch -p1 -P 19
%patch -p1 -P 20
%patch -p1 -P 21
%patch -p1 -P 22
%patch -p1 -P 23
%patch -p1 -P 24
%patch -p1 -P 25
%patch -p1 -P 26
%patch -p1 -P 27
%patch -p1 -P 28
%patch -p1 -P 29
%patch -p1 -P 30 -F2
%patch -p1 -P 31 -F2
%patch -p1 -P 32
%patch -p1 -P 33
%patch -p1 -P 34
%patch -p1 -P 35
%patch -p1 -P 36 -F1
%patch -p1 -P 37
%patch -p1 -P 38
%patch -p1 -P 39
%patch -p1 -P 40 -F2
%patch -p1 -P 41
%patch -p1 -P 42
%patch -p1 -P 43
%patch -p1 -P 44
%patch -p1 -P 45
%patch -p1 -P 46
%patch -p1 -P 47
%patch -p1 -P 48 -F1
%patch -p1 -P 49
%patch -p1 -P 50
%patch -p1 -P 51
%patch -p1 -P 52
%patch -p1 -P 53
%patch -p1 -P 54
%patch -p1 -P 55
%patch -p1 -P 56
%patch -p1 -P 57
%patch -p1 -P 58
%patch -p1 -P 59
%patch -p1 -P 60 -F1
%patch -p1 -P 61
%patch -p1 -P 62
%patch -p1 -P 63
%patch -p1 -P 64
%patch -p1 -P 65 -F1
%patch -p1 -P 66
%patch -p1 -P 67
%patch -p1 -P 68
%patch -p1 -P 69
%patch -p1 -P 70
%patch -p1 -P 71
%patch -p1 -P 72
%patch -p1 -P 73
%patch -p1 -P 74
%patch -p1 -P 75
%patch -p1 -P 76
%patch -p1 -P 77
%patch -p1 -P 78
%patch -p1 -P 79
%patch -p1 -P 80
%patch -p1 -P 81
%patch -p1 -P 82
%patch -p1 -P 83
%patch -p1 -P 84
%patch -p1 -P 85
%patch -p1 -P 86 -F1
%patch -p1 -P 87
%patch -p1 -P 88
%patch -p1 -P 89
%patch -p1 -P 90
%patch -p1 -P 91
%patch -p1 -P 92
%patch -p1 -P 93
%patch -p1 -P 94
%patch -p1 -P 95
%patch -p1 -P 96 -F2
%patch -p1 -P 97
%patch -p1 -P 98
%patch -p1 -P 99
%patch -p1 -P 100
%patch -p1 -P 101
%patch -p1 -P 102
%patch -p1 -P 103
%patch -p1 -P 104 -F1
%patch -p1 -P 105
%patch -p1 -P 106
%patch -p1 -P 107
%patch -p1 -P 108
%patch -p1 -P 109
%patch -p1 -P 110
%patch -p1 -P 111
%patch -p1 -P 112
%patch -p1 -P 113
%patch -p1 -P 114
%patch -p1 -P 115
%patch -p1 -P 116
%patch -p1 -P 117
%patch -p1 -P 118
%patch -p1 -P 119
%patch -p1 -P 120
%patch -p1 -P 121
%patch -p1 -P 122 -F2
%patch -p1 -P 123
%patch -p1 -P 124
%patch -p1 -P 125
%patch -p1 -P 126
%patch -p1 -P 127
%patch -p1 -P 128 -F2
%patch -p1 -P 129
%patch -p1 -P 130
%patch -p1 -P 131
%patch -p1 -P 132
%patch -p1 -P 133
%patch -p1 -P 134
%patch -p1 -P 135
%patch -p1 -P 136 -F2
%patch -p1 -P 137
%patch -p1 -P 138
%patch -p1 -P 139 -F2
%patch -p1 -P 140
%patch -p1 -P 141
%patch -p1 -P 142
%patch -p1 -P 143 -F1
# prevent compilation of something that won't get used anyway
sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac
@ -607,9 +629,13 @@ rm -rf %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/kubevirt/rsa*
pushd %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}
/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH1000}
/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=1 < %{PATCH1001}
/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=1 < %{PATCH1002}
/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH1003}
/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH1004}
%ifarch x86_64
/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH2000}
/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH2001}
%endif
popd
@ -961,8 +987,8 @@ BuildArch: noarch
Fence agent for ePowerSwitch 8M+ power switches that are accessed
via the HTTP(s) protocol.
%files eps
%{_sbindir}/fence_eps
%{_mandir}/man8/fence_eps.8*
%{_sbindir}/fence_eps*
%{_mandir}/man8/fence_eps*.8*
%ifarch x86_64
%package gce
@ -1500,21 +1526,46 @@ Fence agent for IBM z/VM over IP.
%endif
%changelog
* Mon Jan 22 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-121.4
* Wed Jul 24 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-129.4
- bundled setuptools: fix CVE-2024-6345
Resolves: RHEL-50223
* Tue Jun 25 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-129.3
- bundled urllib3: fix CVE-2024-37891
Resolves: RHEL-43568
* Thu May 30 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-129.2
- fence_eps: add fence_epsr2 for ePowerSwitch R2 and newer
Resolves: RHEL-7734
- bundled jinja2: fix CVE-2024-34064
Resolves: RHEL-35655
* Fri Jan 19 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-129
- bundled urllib3: fix CVE-2023-45803
Resolves: RHEL-21719
Resolves: RHEL-18132
- bundled pycryptodome: fix CVE-2023-52323
Resolves: RHEL-21727
Resolves: RHEL-20915
- bundled jinja2: fix CVE-2024-22195
Resolves: RHEL-22179
Resolves: RHEL-22174
* Fri Oct 13 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-121.2
* Wed Jan 3 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-127
- fence_scsi: fix registration handling if ISID conflicts
Resolves: RHEL-5397
- fence_zvmip: document required user permissions in metadata/manpage
Resolves: RHEL-14343
* Mon Oct 23 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-125
- all agents: update metadata in non-I/O agents to Power or Network
fencing
Resolves: RHEL-14031
* Thu Oct 12 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-123
- bundled urllib3: fix CVE-2023-43804
Resolves: RHEL-12434
Resolves: RHEL-11988
* Wed Sep 27 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-121.1
* Tue Sep 26 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-122
- bundled certifi: fix CVE-2023-37920
Resolves: RHEL-9452
Resolves: RHEL-6972
* Thu Aug 3 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-121
- bundled dateutil: fix tarfile CVE-2007-4559