diff options
author | CoprDistGit <infra@openeuler.org> | 2024-08-01 14:21:23 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-08-01 14:21:23 +0000 |
commit | 247fc79a80bec95c23eac2c1d19b47ed30f7350b (patch) | |
tree | 59f40f8d3835d3954a48242fe49c7195f9cb55c5 | |
parent | 656cec46a0f3499446d93967253acac7c8acfe6f (diff) |
automatic import of fence-agentsopeneuler24.03_LTS
70 files changed, 12579 insertions, 0 deletions
@@ -0,0 +1,103 @@ +/Jinja2-3.1.3.tar.gz +/MarkupSafe-2.0.1.tar.gz +/PyJWT-2.1.0-py3-none-any.whl +/PyYAML-5.1.tar.gz +/adal-1.2.7-py2.py3-none-any.whl +/aliyun-cli-3.0.198.tar.gz +/aliyun-cli-go-vendor.tar.gz +/aliyun-openapi-meta-5cf98b660.tar.gz +/aliyun-python-sdk-core-2.11.5.tar.gz +/aliyun_python_sdk_ecs-4.24.7-py2.py3-none-any.whl +/awscli-2.2.15.tar.gz +/awscrt-0.11.13-cp39-cp39-manylinux2014_x86_64.whl +/azure-identity-1.10.0.zip +/azure_common-1.1.27-py2.py3-none-any.whl +/azure_core-1.15.0-py2.py3-none-any.whl +/azure_mgmt_compute-21.0.0-py2.py3-none-any.whl +/azure_mgmt_core-1.2.2-py2.py3-none-any.whl +/azure_mgmt_network-19.0.0-py2.py3-none-any.whl +/boto3-1.17.102-py2.py3-none-any.whl +/botocore-1.20.102-py2.py3-none-any.whl +/botocore-2.0.0dev123.zip +/cachetools-4.2.2-py3-none-any.whl +/cachetools-4.2.4.tar.gz +/certifi-2023.7.22.tar.gz +/cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl +/chardet-3.0.4-py2.py3-none-any.whl +/chardet-4.0.0-py2.py3-none-any.whl +/charset-normalizer-2.0.7.tar.gz +/colorama-0.3.3.tar.gz +/colorama-0.4.3-py2.py3-none-any.whl +/cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl +/distro-1.5.0-py2.py3-none-any.whl +/docutils-0.15.2-py3-none-any.whl +/fence-agents-4.10.0.tar.gz +/flit_core-3.9.0.tar.gz +/google-auth-2.3.0.tar.gz +/google_api_core-1.30.0-py2.py3-none-any.whl +/google_api_python_client-1.12.8-py2.py3-none-any.whl +/google_auth-1.32.0-py2.py3-none-any.whl +/google_auth_httplib2-0.1.0-py2.py3-none-any.whl +/googleapis_common_protos-1.53.0-py2.py3-none-any.whl +/httplib2-0.19.1-py3-none-any.whl +/idna-2.10-py2.py3-none-any.whl +/idna-3.3.tar.gz +/isodate-0.6.0-py2.py3-none-any.whl +/jmespath-0.7.1-py2.py3-none-any.whl +/kubernetes-12.0.1.tar.gz +/msal-1.18.0.tar.gz +/msal-extensions-1.0.0.tar.gz +/msrest-0.6.21-py2.py3-none-any.whl +/msrestazure-0.6.4-py2.py3-none-any.whl +/oauthlib-3.2.2.tar.gz +/openshift-0.12.1.tar.gz +/packaging-20.9-py2.py3-none-any.whl +/packaging-21.2-py3-none-any.whl +/pexpect-4.8.0-py2.py3-none-any.whl +/poetry-core-1.0.7.tar.gz +/portalocker-2.5.1.tar.gz +/prompt_toolkit-2.0.10-py3-none-any.whl +/protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl +/ptyprocess-0.7.0-py2.py3-none-any.whl +/pyasn1-0.4.8-py2.py3-none-any.whl +/pyasn1-0.4.8.tar.gz +/pyasn1-modules-0.2.8.tar.gz +/pyasn1_modules-0.2.8-py2.py3-none-any.whl +/pycparser-2.20-py2.py3-none-any.whl +/pycryptodome-3.20.0.tar.gz +/pyparsing-2.4.7-py2.py3-none-any.whl +/pyparsing-3.0.1.tar.gz +/pyroute2-0.7.12.tar.gz +/pyroute2.core-0.6.13.tar.gz +/pyroute2.ethtool-0.6.13.tar.gz +/pyroute2.ipdb-0.6.13.tar.gz +/pyroute2.ipset-0.6.13.tar.gz +/pyroute2.ndb-0.6.13.tar.gz +/pyroute2.nftables-0.6.13.tar.gz +/pyroute2.nslink-0.6.13.tar.gz +/python-dateutil-2.8.2.tar.gz +/python-string-utils-1.0.0.tar.gz +/python_dateutil-2.8.1-py2.py3-none-any.whl +/pytz-2021.1-py2.py3-none-any.whl +/requests-2.25.1-py2.py3-none-any.whl +/requests-2.26.0.tar.gz +/requests-oauthlib-1.3.0.tar.gz +/requests_oauthlib-1.3.0-py2.py3-none-any.whl +/rsa-4.7.2-py3-none-any.whl +/rsa-4.7.2.tar.gz +/ruamel.yaml-0.15.100.tar.gz +/ruamel.yaml-0.17.16.tar.gz +/ruamel.yaml.clib-0.2.6.tar.gz +/s3transfer-0.4.2-py2.py3-none-any.whl +/setuptools-71.1.0.tar.gz +/setuptools_scm-8.1.0.tar.gz +/six-1.16.0-py2.py3-none-any.whl +/six-1.16.0.tar.gz +/suds_community-0.8.5-py3-none-any.whl +/tomli-2.0.1.tar.gz +/typing_extensions-4.12.2.tar.gz +/uritemplate-3.0.1-py2.py3-none-any.whl +/urllib3-1.26.18.tar.gz +/wcwidth-0.1.9-py2.py3-none-any.whl +/websocket-client-1.2.1.tar.gz +/wheel-0.37.0-py2.py3-none-any.whl diff --git a/RHEL-14030-1-all-agents-metadata-update-IO-Power-Network.patch b/RHEL-14030-1-all-agents-metadata-update-IO-Power-Network.patch new file mode 100644 index 0000000..79c5885 --- /dev/null +++ b/RHEL-14030-1-all-agents-metadata-update-IO-Power-Network.patch @@ -0,0 +1,1916 @@ +From aed06661b0b6fd4e69d44672f59bb8d3eecccc67 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Wed, 18 Oct 2023 10:53:14 +0200 +Subject: [PATCH] all agents: update metadata from I/O to e.g. Power, Network, + etc for non-I/O agents + +--- + agents/aliyun/fence_aliyun.py | 2 +- + agents/alom/fence_alom.py | 4 ++-- + agents/amt/fence_amt.py | 2 +- + agents/amt_ws/fence_amt_ws.py | 2 +- + agents/apc/fence_apc.py | 2 +- + agents/apc_snmp/fence_apc_snmp.py | 6 +++--- + agents/aws/fence_aws.py | 2 +- + agents/azure_arm/fence_azure_arm.py | 2 +- + agents/bladecenter/fence_bladecenter.py | 2 +- + agents/cdu/fence_cdu.py | 2 +- + agents/cisco_mds/fence_cisco_mds.py | 2 +- + agents/cisco_ucs/fence_cisco_ucs.py | 2 +- + agents/cyberpower_ssh/fence_cyberpower_ssh.py | 2 +- + agents/docker/fence_docker.py | 2 +- + agents/drac/fence_drac.py | 4 ++-- + agents/drac5/fence_drac5.py | 2 +- + agents/eaton_snmp/fence_eaton_snmp.py | 2 +- + agents/eaton_ssh/fence_eaton_ssh.py | 2 +- + agents/ecloud/fence_ecloud.py | 2 +- + agents/emerson/fence_emerson.py | 4 ++-- + agents/eps/fence_eps.py | 2 +- + agents/gce/fence_gce.py | 2 +- + agents/hds_cb/fence_hds_cb.py | 2 +- + agents/hpblade/fence_hpblade.py | 2 +- + agents/ibm_powervs/fence_ibm_powervs.py | 2 +- + agents/ibm_vpc/fence_ibm_vpc.py | 2 +- + agents/ibmblade/fence_ibmblade.py | 2 +- + agents/ibmz/fence_ibmz.py | 2 +- + agents/ilo/fence_ilo.py | 6 +++--- + agents/ilo_moonshot/fence_ilo_moonshot.py | 2 ++ + agents/ilo_mp/fence_ilo_mp.py | 3 ++- + agents/ilo_ssh/fence_ilo_ssh.py | 6 +++--- + agents/intelmodular/fence_intelmodular.py | 2 +- + agents/ipdu/fence_ipdu.py | 2 +- + agents/ipmilan/fence_ipmilan.py | 4 ++-- + agents/ironic/fence_ironic.py | 2 +- + agents/kubevirt/fence_kubevirt.py | 2 +- + agents/ldom/fence_ldom.py | 2 +- + agents/lindy_pdu/fence_lindypdu.py | 2 +- + agents/lpar/fence_lpar.py | 2 +- + agents/mpath/fence_mpath.py | 2 +- + agents/netio/fence_netio.py | 4 ++-- + agents/openstack/fence_openstack.py | 2 +- + agents/ovh/fence_ovh.py | 2 +- + agents/powerman/fence_powerman.py | 2 +- + agents/pve/fence_pve.py | 4 ++-- + agents/raritan/fence_raritan.py | 4 ++-- + agents/raritan_px3/fence_raritan_px3.py | 4 ++-- + agents/rcd_serial/fence_rcd_serial.py | 11 ++++++----- + agents/redfish/fence_redfish.py | 4 ++-- + agents/rhevm/fence_rhevm.py | 2 +- + agents/rsa/fence_rsa.py | 2 +- + agents/rsb/fence_rsb.py | 4 ++-- + agents/sbd/fence_sbd.py | 2 +- + agents/scsi/fence_scsi.py | 2 +- + agents/skalar/fence_skalar.py | 2 +- + agents/vbox/fence_vbox.py | 2 +- + agents/virsh/fence_virsh.py | 2 +- + agents/virt/client/options.c | 2 +- + agents/vmware/fence_vmware.py | 2 +- + agents/vmware_rest/fence_vmware_rest.py | 2 +- + agents/vmware_soap/fence_vmware_soap.py | 2 +- + agents/vmware_vcloud/fence_vmware_vcloud.py | 3 ++- + agents/wti/fence_wti.py | 2 +- + agents/xenapi/fence_xenapi.py | 2 +- + agents/zvm/fence_zvmip.py | 4 ++-- + tests/data/metadata/fence_aliyun.xml | 2 +- + tests/data/metadata/fence_alom.xml | 2 +- + tests/data/metadata/fence_amt.xml | 2 +- + tests/data/metadata/fence_amt_ws.xml | 2 +- + tests/data/metadata/fence_apc.xml | 2 +- + tests/data/metadata/fence_apc_snmp.xml | 2 +- + tests/data/metadata/fence_aws.xml | 2 +- + tests/data/metadata/fence_azure_arm.xml | 2 +- + tests/data/metadata/fence_bladecenter.xml | 2 +- + tests/data/metadata/fence_cdu.xml | 2 +- + tests/data/metadata/fence_cisco_mds.xml | 2 +- + tests/data/metadata/fence_cisco_ucs.xml | 2 +- + tests/data/metadata/fence_cyberpower_ssh.xml | 2 +- + tests/data/metadata/fence_docker.xml | 2 +- + tests/data/metadata/fence_drac.xml | 4 ++-- + tests/data/metadata/fence_drac5.xml | 2 +- + tests/data/metadata/fence_eaton_snmp.xml | 2 +- + tests/data/metadata/fence_eaton_ssh.xml | 2 +- + tests/data/metadata/fence_ecloud.xml | 2 +- + tests/data/metadata/fence_emerson.xml | 2 +- + tests/data/metadata/fence_eps.xml | 2 +- + tests/data/metadata/fence_gce.xml | 2 +- + tests/data/metadata/fence_hds_cb.xml | 2 +- + tests/data/metadata/fence_hpblade.xml | 2 +- + tests/data/metadata/fence_ibm_powervs.xml | 2 +- + tests/data/metadata/fence_ibm_vpc.xml | 2 +- + tests/data/metadata/fence_ibmblade.xml | 2 +- + tests/data/metadata/fence_ibmz.xml | 2 +- + tests/data/metadata/fence_idrac.xml | 2 +- + tests/data/metadata/fence_ilo.xml | 2 +- + tests/data/metadata/fence_ilo2.xml | 2 +- + tests/data/metadata/fence_ilo3.xml | 2 +- + tests/data/metadata/fence_ilo3_ssh.xml | 2 +- + tests/data/metadata/fence_ilo4.xml | 2 +- + tests/data/metadata/fence_ilo4_ssh.xml | 2 +- + tests/data/metadata/fence_ilo5.xml | 2 +- + tests/data/metadata/fence_ilo5_ssh.xml | 2 +- + tests/data/metadata/fence_ilo_mp.xml | 2 +- + tests/data/metadata/fence_ilo_ssh.xml | 2 +- + tests/data/metadata/fence_imm.xml | 2 +- + tests/data/metadata/fence_intelmodular.xml | 2 +- + tests/data/metadata/fence_ipdu.xml | 2 +- + tests/data/metadata/fence_ipmilan.xml | 2 +- + tests/data/metadata/fence_ipmilanplus.xml | 2 +- + tests/data/metadata/fence_ironic.xml | 2 +- + tests/data/metadata/fence_kubevirt.xml | 2 +- + tests/data/metadata/fence_ldom.xml | 2 +- + tests/data/metadata/fence_lindypdu.xml | 2 +- + tests/data/metadata/fence_lpar.xml | 2 +- + tests/data/metadata/fence_mpath.xml | 2 +- + tests/data/metadata/fence_netio.xml | 4 ++-- + tests/data/metadata/fence_openstack.xml | 2 +- + tests/data/metadata/fence_ovh.xml | 2 +- + tests/data/metadata/fence_powerman.xml | 2 +- + tests/data/metadata/fence_pve.xml | 2 +- + tests/data/metadata/fence_raritan.xml | 4 ++-- + tests/data/metadata/fence_raritan_px3.xml | 4 ++-- + tests/data/metadata/fence_rcd_serial.xml | 2 +- + tests/data/metadata/fence_redfish.xml | 4 ++-- + tests/data/metadata/fence_rhevm.xml | 2 +- + tests/data/metadata/fence_rsa.xml | 2 +- + tests/data/metadata/fence_rsb.xml | 4 ++-- + tests/data/metadata/fence_sbd.xml | 2 +- + tests/data/metadata/fence_scsi.xml | 2 +- + tests/data/metadata/fence_skalar.xml | 2 +- + tests/data/metadata/fence_tripplite_snmp.xml | 2 +- + tests/data/metadata/fence_vbox.xml | 2 +- + tests/data/metadata/fence_virsh.xml | 2 +- + tests/data/metadata/fence_virt.xml | 2 +- + tests/data/metadata/fence_vmware.xml | 2 +- + tests/data/metadata/fence_vmware_rest.xml | 2 +- + tests/data/metadata/fence_vmware_soap.xml | 2 +- + tests/data/metadata/fence_vmware_vcloud.xml | 2 +- + tests/data/metadata/fence_wti.xml | 2 +- + tests/data/metadata/fence_xenapi.xml | 2 +- + tests/data/metadata/fence_zvmip.xml | 3 +-- + 142 files changed, 173 insertions(+), 169 deletions(-) + +diff --git a/agents/aliyun/fence_aliyun.py b/agents/aliyun/fence_aliyun.py +index c7785a2b2..134cc5ab6 100644 +--- a/agents/aliyun/fence_aliyun.py ++++ b/agents/aliyun/fence_aliyun.py +@@ -175,7 +175,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Aliyun (Aliyun Web Services)" +- docs["longdesc"] = "fence_aliyun is an I/O Fencing agent for Aliyun" ++ docs["longdesc"] = "fence_aliyun is a Power Fencing agent for Aliyun." + docs["vendorurl"] = "http://www.aliyun.com" + show_docs(options, docs) + +diff --git a/agents/alom/fence_alom.py b/agents/alom/fence_alom.py +index 7b03dc2a6..a8e216f3f 100644 +--- a/agents/alom/fence_alom.py ++++ b/agents/alom/fence_alom.py +@@ -38,8 +38,8 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Sun ALOM" +- docs["longdesc"] = "fence_alom is an I/O Fencing \ +-agent which can be used with ALOM connected machines." ++ docs["longdesc"] = "fence_alom is a Power Fencing agent \ ++which can be used with ALOM connected machines." + docs["vendorurl"] = "http://www.sun.com" + show_docs(options, docs) + +diff --git a/agents/amt/fence_amt.py b/agents/amt/fence_amt.py +index 80d3f74c1..183bbc713 100644 +--- a/agents/amt/fence_amt.py ++++ b/agents/amt/fence_amt.py +@@ -113,7 +113,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for AMT" +- docs["longdesc"] = "fence_amt is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_amt is a Power Fencing agent \ + which can be used with Intel AMT. This agent calls support software amttool\ + (http://www.kraxel.org/cgit/amtterm/)." + docs["vendorurl"] = "http://www.intel.com/" +diff --git a/agents/amt_ws/fence_amt_ws.py b/agents/amt_ws/fence_amt_ws.py +index 5e7452a97..89500d4bf 100755 +--- a/agents/amt_ws/fence_amt_ws.py ++++ b/agents/amt_ws/fence_amt_ws.py +@@ -222,7 +222,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for AMT (WS)" +- docs["longdesc"] = "fence_amt_ws is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_amt_ws is a Power Fencing agent \ + which can be used with Intel AMT (WS). This agent requires \ + the pywsman Python library which is included in OpenWSMAN. \ + (http://openwsman.github.io/)." +diff --git a/agents/apc/fence_apc.py b/agents/apc/fence_apc.py +index 3ea0f37d6..bc52aa244 100644 +--- a/agents/apc/fence_apc.py ++++ b/agents/apc/fence_apc.py +@@ -227,7 +227,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for APC over telnet/ssh" +- docs["longdesc"] = "fence_apc is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_apc is a Power Fencing agent \ + which can be used with the APC network power switch. It logs into device \ + via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh connections \ + should be avoided while a GFS cluster is running because the connection \ +diff --git a/agents/apc_snmp/fence_apc_snmp.py b/agents/apc_snmp/fence_apc_snmp.py +index cd601662c..1091f0da9 100644 +--- a/agents/apc_snmp/fence_apc_snmp.py ++++ b/agents/apc_snmp/fence_apc_snmp.py +@@ -13,7 +13,7 @@ + # - Tripplite PDUMH20HVNET 12.04.0055 - SNMP v1, v2c, v3 + # - Tripplite PDU15NETLX 15.5.4 - SNMP v1, v2c, v3 + +-import sys ++import sys, os + import atexit + import logging + sys.path.append("@FENCEAGENTSLIBDIR@") +@@ -216,10 +216,10 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for APC, Tripplite PDU over SNMP" +- docs["longdesc"] = "fence_apc_snmp is an I/O Fencing agent \ ++ docs["longdesc"] = "{} is a Power Fencing agent \ + which can be used with the APC network power switch or Tripplite PDU devices.\ + It logs into a device via SNMP and reboots a specified outlet. It supports \ +-SNMP v1, v2c, v3 with all combinations of authenticity/privacy settings." ++SNMP v1, v2c, v3 with all combinations of authenticity/privacy settings.".format(os.path.basename(__file__)) + docs["vendorurl"] = "http://www.apc.com" + docs["symlink"] = [("fence_tripplite_snmp", "Fence agent for Tripplife over SNMP")] + show_docs(options, docs) +diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py +index 0a375bbec..5b32106f0 100644 +--- a/agents/aws/fence_aws.py ++++ b/agents/aws/fence_aws.py +@@ -185,7 +185,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for AWS (Amazon Web Services)" +- docs["longdesc"] = "fence_aws is an I/O Fencing agent for AWS (Amazon Web\ ++ docs["longdesc"] = "fence_aws is a Power Fencing agent for AWS (Amazon Web\ + Services). It uses the boto3 library to connect to AWS.\ + \n.P\n\ + boto3 can be configured with AWS CLI or by creating ~/.aws/credentials.\n\ +diff --git a/agents/azure_arm/fence_azure_arm.py b/agents/azure_arm/fence_azure_arm.py +index 515aae294..0dca8f30d 100755 +--- a/agents/azure_arm/fence_azure_arm.py ++++ b/agents/azure_arm/fence_azure_arm.py +@@ -221,7 +221,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Azure Resource Manager" +- docs["longdesc"] = "fence_azure_arm is an I/O Fencing agent for Azure Resource Manager. It uses Azure SDK for Python to connect to Azure.\ ++ docs["longdesc"] = "fence_azure_arm is a Power Fencing agent for Azure Resource Manager. It uses Azure SDK for Python to connect to Azure.\ + \n.P\n\ + For instructions to setup credentials see: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal\ + \n.P\n\ +diff --git a/agents/bladecenter/fence_bladecenter.py b/agents/bladecenter/fence_bladecenter.py +index d670367f2..2f2c65fce 100644 +--- a/agents/bladecenter/fence_bladecenter.py ++++ b/agents/bladecenter/fence_bladecenter.py +@@ -86,7 +86,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for IBM BladeCenter" +- docs["longdesc"] = "fence_bladecenter is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_bladecenter is a Power Fencing agent \ + which can be used with IBM Bladecenters with recent enough firmware that \ + includes telnet support. It logs into a Brocade chasis via telnet or ssh \ + and uses the command line interface to power on and off blades." +diff --git a/agents/cdu/fence_cdu.py b/agents/cdu/fence_cdu.py +index 483ac5128..ba76e6d76 100644 +--- a/agents/cdu/fence_cdu.py ++++ b/agents/cdu/fence_cdu.py +@@ -136,7 +136,7 @@ def main(): + + docs = { } + docs["shortdesc"] = "Fence agent for a Sentry Switch CDU over telnet" +- docs["longdesc"] = "fence_cdu is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_cdu is a Power Fencing agent \ + which can be used with the Sentry Switch CDU. It logs into the device \ + via telnet and power's on/off an outlet." + docs["vendorurl"] = "http://www.servertech.com" +diff --git a/agents/cisco_mds/fence_cisco_mds.py b/agents/cisco_mds/fence_cisco_mds.py +index fbb876a94..04cd1f842 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 an I/O Fencing agent \ ++ docs["longdesc"] = "fence_cisco_mds is a Power 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/agents/cisco_ucs/fence_cisco_ucs.py b/agents/cisco_ucs/fence_cisco_ucs.py +index b85379a73..cada20d5e 100644 +--- a/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/agents/cisco_ucs/fence_cisco_ucs.py +@@ -161,7 +161,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Cisco UCS" +- docs["longdesc"] = "fence_cisco_ucs is an I/O Fencing agent which can be \ ++ docs["longdesc"] = "fence_cisco_ucs is a Power Fencing agent which can be \ + used with Cisco UCS to fence machines." + docs["vendorurl"] = "http://www.cisco.com" + show_docs(options_global, docs) +diff --git a/agents/docker/fence_docker.py b/agents/docker/fence_docker.py +index 004402518..8042515a3 100644 +--- a/agents/docker/fence_docker.py ++++ b/agents/docker/fence_docker.py +@@ -143,7 +143,7 @@ def main(): + + docs = { } + docs["shortdesc"] = "Fence agent for Docker" +- docs["longdesc"] = "fence_docker is I/O fencing agent which \ ++ docs["longdesc"] = "fence_docker is a Power Fencing agent which \ + can be used with the Docker Engine containers. You can use this \ + fence-agent without any authentication, or you can use TLS authentication \ + (use --ssl option, more info about TLS authentication in docker: \ +diff --git a/agents/drac/fence_drac.py b/agents/drac/fence_drac.py +index be3e9a584..b7d335640 100644 +--- a/agents/drac/fence_drac.py ++++ b/agents/drac/fence_drac.py +@@ -34,8 +34,8 @@ def main(): + options = check_input(device_opt, opt) + + docs = {} +- docs["shortdesc"] = "I/O Fencing agent for Dell DRAC IV" +- docs["longdesc"] = "fence_drac is an I/O Fencing agent which can be used with \ ++ docs["shortdesc"] = "Power Fencing agent for Dell DRAC IV" ++ docs["longdesc"] = "fence_drac is a Power Fencing agent which can be used with \ + the Dell Remote Access Card (DRAC). This card provides remote access to controlling \ + power to a server. It logs into the DRAC through the telnet interface of the card. By \ + default, the telnet interface is not enabled. To enable the interface, you will need \ +diff --git a/agents/drac5/fence_drac5.py b/agents/drac5/fence_drac5.py +index 648ecd917..7b279217e 100644 +--- a/agents/drac5/fence_drac5.py ++++ b/agents/drac5/fence_drac5.py +@@ -110,7 +110,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Dell DRAC CMC/5" +- docs["longdesc"] = "fence_drac5 is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_drac5 is a Power Fencing agent \ + which can be used with the Dell Remote Access Card v5 or CMC (DRAC). \ + This device provides remote access to controlling power to a server. \ + It logs into the DRAC through the telnet/ssh interface of the card. \ +diff --git a/agents/eaton_snmp/fence_eaton_snmp.py b/agents/eaton_snmp/fence_eaton_snmp.py +index 9fbc05634..83ec92a27 100644 +--- a/agents/eaton_snmp/fence_eaton_snmp.py ++++ b/agents/eaton_snmp/fence_eaton_snmp.py +@@ -214,7 +214,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Eaton over SNMP" +- docs["longdesc"] = "fence_eaton_snmp is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_eaton_snmp is a Power Fencing agent \ + which can be used with the Eaton network power switch. It logs \ + into a device via SNMP and reboots a specified outlet. It supports \ + SNMP v1 and v3 with all combinations of authenticity/privacy settings." +diff --git a/agents/emerson/fence_emerson.py b/agents/emerson/fence_emerson.py +index 2e65cda0e..67b3a4106 100644 +--- a/agents/emerson/fence_emerson.py ++++ b/agents/emerson/fence_emerson.py +@@ -49,8 +49,8 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Emerson over SNMP" +- docs["longdesc"] = "fence_emerson is an I/O Fencing agent \ +- which can be used with MPX and MPH2 managed rack PDU." ++ docs["longdesc"] = "fence_emerson is a Power Fencing agent \ ++which can be used with MPX and MPH2 managed rack PDU." + docs["vendorurl"] = "http://www.emersonnetworkpower.com" + show_docs(options, docs) + +diff --git a/agents/eps/fence_eps.py b/agents/eps/fence_eps.py +index f0df86231..81e439533 100644 +--- a/agents/eps/fence_eps.py ++++ b/agents/eps/fence_eps.py +@@ -108,7 +108,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for ePowerSwitch" +- docs["longdesc"] = "fence_eps is an I/O Fencing agent \ ++ docs["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. \ +diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py +index 2c815b849..b8871038e 100644 +--- a/agents/gce/fence_gce.py ++++ b/agents/gce/fence_gce.py +@@ -515,7 +515,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for GCE (Google Cloud Engine)" +- docs["longdesc"] = "fence_gce is an I/O Fencing agent for GCE (Google Cloud " \ ++ docs["longdesc"] = "fence_gce is a Power Fencing agent for GCE (Google Cloud " \ + "Engine). It uses the googleapiclient library to connect to GCE.\n" \ + "googleapiclient can be configured with Google SDK CLI or by " \ + "executing 'gcloud auth application-default login'.\n" \ +diff --git a/agents/hds_cb/fence_hds_cb.py b/agents/hds_cb/fence_hds_cb.py +index 375054cf2..1a064644b 100755 +--- a/agents/hds_cb/fence_hds_cb.py ++++ b/agents/hds_cb/fence_hds_cb.py +@@ -113,7 +113,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Hitachi Compute Blade systems" +- docs["longdesc"] = "fence_hds_cb is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_hds_cb is a Power Fencing agent \ + which can be used with Hitachi Compute Blades with recent enough firmware that \ + includes telnet support." + docs["vendorurl"] = "http://www.hds.com" +diff --git a/agents/hpblade/fence_hpblade.py b/agents/hpblade/fence_hpblade.py +index fbc89f614..eb8f459b2 100644 +--- a/agents/hpblade/fence_hpblade.py ++++ b/agents/hpblade/fence_hpblade.py +@@ -110,7 +110,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for HP BladeSystem" +- docs["longdesc"] = "fence_hpblade is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_hpblade is a Power Fencing agent \ + which can be used with HP BladeSystem and HP Integrity Superdome X. \ + It logs into the onboard administrator of an enclosure via telnet or \ + ssh and uses the command line interface to power blades or partitions \ +diff --git a/agents/ibm_powervs/fence_ibm_powervs.py b/agents/ibm_powervs/fence_ibm_powervs.py +index e65462cb9..73dfe0ab1 100755 +--- a/agents/ibm_powervs/fence_ibm_powervs.py ++++ b/agents/ibm_powervs/fence_ibm_powervs.py +@@ -275,7 +275,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for IBM PowerVS" +- docs["longdesc"] = """fence_ibm_powervs is an I/O Fencing agent which can be \ ++ docs["longdesc"] = """fence_ibm_powervs is a Power Fencing agent which can be \ + used with IBM PowerVS to fence virtual machines.""" + docs["vendorurl"] = "https://www.ibm.com" + show_docs(options, docs) +diff --git a/agents/ibm_vpc/fence_ibm_vpc.py b/agents/ibm_vpc/fence_ibm_vpc.py +index 847010584..035a3235a 100755 +--- a/agents/ibm_vpc/fence_ibm_vpc.py ++++ b/agents/ibm_vpc/fence_ibm_vpc.py +@@ -295,7 +295,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for IBM Cloud VPC" +- docs["longdesc"] = """fence_ibm_vpc is an I/O Fencing agent which can be \ ++ docs["longdesc"] = """fence_ibm_vpc is a Power Fencing agent which can be \ + used with IBM Cloud VPC to fence virtual machines.""" + docs["vendorurl"] = "https://www.ibm.com" + show_docs(options, docs) +diff --git a/agents/ibmblade/fence_ibmblade.py b/agents/ibmblade/fence_ibmblade.py +index d623fff3d..ca6e21793 100644 +--- a/agents/ibmblade/fence_ibmblade.py ++++ b/agents/ibmblade/fence_ibmblade.py +@@ -57,7 +57,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for IBM BladeCenter over SNMP" +- docs["longdesc"] = "fence_ibmblade is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_ibmblade is a Power Fencing agent \ + which can be used with IBM BladeCenter chassis. It issues SNMP Set \ + request to BladeCenter chassis, rebooting, powering up or down \ + the specified Blade Server." +diff --git a/agents/ibmz/fence_ibmz.py b/agents/ibmz/fence_ibmz.py +index d477adeb9..a4cc12d5c 100644 +--- a/agents/ibmz/fence_ibmz.py ++++ b/agents/ibmz/fence_ibmz.py +@@ -520,7 +520,7 @@ def main(): + docs = { + "shortdesc": "Fence agent for IBM z LPARs", + "longdesc": ( +- "fence_ibmz is a power fencing agent which uses the HMC Web " ++ "fence_ibmz is a Power Fencing agent which uses the HMC Web " + "Services API to fence IBM z LPARs."), + "vendorurl": "http://www.ibm.com" + } +diff --git a/agents/ilo/fence_ilo.py b/agents/ilo/fence_ilo.py +index 612450568..f30a1da28 100644 +--- a/agents/ilo/fence_ilo.py ++++ b/agents/ilo/fence_ilo.py +@@ -11,7 +11,7 @@ + ## iLO2 / firmware 1.50 / RIBCL 2.22 + ##### + +-import sys, re ++import sys, os, re + sys.path.insert(0, '/usr/lib/fence-agents/support/common') + try: + import pexpect +@@ -73,11 +73,11 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for HP iLO" +- docs["longdesc"] = "fence_ilo is an I/O Fencing agent \ ++ docs["longdesc"] = "{} is a Power Fencing agent \ + used for HP servers with the Integrated Light Out (iLO) PCI card.\ + The agent opens an SSL connection to the iLO card. Once the SSL \ + connection is established, the agent is able to communicate with \ +-the iLO card through an XML stream." ++the iLO card through an XML stream.".format(os.path.basename(__file__)) + docs["vendorurl"] = "http://www.hp.com" + docs["symlink"] = [("fence_ilo2", "Fence agent for HP iLO2")] + show_docs(options, docs) +diff --git a/agents/ilo_moonshot/fence_ilo_moonshot.py b/agents/ilo_moonshot/fence_ilo_moonshot.py +index 1923eeb1c..92bc74525 100644 +--- a/agents/ilo_moonshot/fence_ilo_moonshot.py ++++ b/agents/ilo_moonshot/fence_ilo_moonshot.py +@@ -48,6 +48,8 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for HP Moonshot iLO" ++ docs["longdesc"] = "fence_ilo_moonshot is a Power Fencing agent \ ++for HP Moonshot iLO." + docs["longdesc"] = "" + docs["vendorurl"] = "http://www.hp.com" + show_docs(options, docs) +diff --git a/agents/ilo_mp/fence_ilo_mp.py b/agents/ilo_mp/fence_ilo_mp.py +index 1ae4d3ed5..cc1c2decd 100644 +--- a/agents/ilo_mp/fence_ilo_mp.py ++++ b/agents/ilo_mp/fence_ilo_mp.py +@@ -40,7 +40,8 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for HP iLO MP" +- docs["longdesc"] = "" ++ docs["longdesc"] = "fence_ilo_mp is a Power Fencing agent \ ++for HP iLO MP." + docs["vendorurl"] = "http://www.hp.com" + show_docs(options, docs) + +diff --git a/agents/ilo_ssh/fence_ilo_ssh.py b/agents/ilo_ssh/fence_ilo_ssh.py +index a27e34189..1d5be21ef 100644 +--- a/agents/ilo_ssh/fence_ilo_ssh.py ++++ b/agents/ilo_ssh/fence_ilo_ssh.py +@@ -1,6 +1,6 @@ + #!@PYTHON@ -tt + +-import sys, re ++import sys, os, re + import atexit + import logging + sys.path.append("@FENCEAGENTSLIBDIR@") +@@ -50,11 +50,11 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for HP iLO over SSH" +- docs["longdesc"] = "fence_ilo_ssh is a fence agent that connects to iLO device. It logs into \ ++ docs["longdesc"] = "{} is a Power Fencing agent that connects to iLO device. It logs into \ + device via ssh and reboot a specified outlet.\ + \n.P\n\ + WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent \ +-to avoid this issue." ++to avoid this issue.".format(os.path.basename(__file__)) + docs["vendorurl"] = "http://www.hp.com" + docs["symlink"] = [("fence_ilo3_ssh", "Fence agent for HP iLO3 over SSH"), + ("fence_ilo4_ssh", "Fence agent for HP iLO4 over SSH"), +diff --git a/agents/intelmodular/fence_intelmodular.py b/agents/intelmodular/fence_intelmodular.py +index 294ea4ddb..e9c417a95 100644 +--- a/agents/intelmodular/fence_intelmodular.py ++++ b/agents/intelmodular/fence_intelmodular.py +@@ -66,7 +66,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Intel Modular" +- docs["longdesc"] = "fence_intelmodular is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_intelmodular is a Power Fencing agent \ + which can be used with Intel Modular device (tested on Intel MFSYS25, should \ + work with MFSYS35 as well). \ + \n.P\n\ +diff --git a/agents/ipdu/fence_ipdu.py b/agents/ipdu/fence_ipdu.py +index da34d2b64..f7093b8bc 100644 +--- a/agents/ipdu/fence_ipdu.py ++++ b/agents/ipdu/fence_ipdu.py +@@ -138,7 +138,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for iPDU over SNMP" +- docs["longdesc"] = "fence_ipdu is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_ipdu is a Power Fencing agent \ + which can be used with the IBM iPDU network power switch. It logs \ + into a device via SNMP and reboots a specified outlet. It supports \ + SNMP v3 with all combinations of authenticity/privacy settings." +diff --git a/agents/ipmilan/fence_ipmilan.py b/agents/ipmilan/fence_ipmilan.py +index 91e09ac7d..a47fbdd82 100644 +--- a/agents/ipmilan/fence_ipmilan.py ++++ b/agents/ipmilan/fence_ipmilan.py +@@ -203,11 +203,11 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for IPMI" +- docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent \ ++ docs["longdesc"] = "{} is a Power Fencing agent \ + which can be used with machines controlled by IPMI. \ + This agent calls support software ipmitool (http://ipmitool.sf.net/). \ + WARNING! This fence agent might report success before the node is powered off. \ +-You should use -m/method onoff if your fence device works correctly with that option." ++You should use -m/method onoff if your fence device works correctly with that option.".format(os.path.basename(__file__)) + docs["vendorurl"] = "" + docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"), + ("fence_ilo4", "Fence agent for HP iLO4"), +diff --git a/agents/ironic/fence_ironic.py b/agents/ironic/fence_ironic.py +index d0c9d9c19..76a9250f1 100644 +--- a/agents/ironic/fence_ironic.py ++++ b/agents/ironic/fence_ironic.py +@@ -115,7 +115,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for OpenStack's Ironic (Bare Metal as a service) service" +- docs["longdesc"] = "fence_ironic is a Fencing agent \ ++ docs["longdesc"] = "fence_ironic is a Power Fencing agent \ + which can be used with machines controlled by the Ironic service. \ + This agent calls the openstack CLI. \ + WARNING! This fence agent is not intended for production use. Relying on a functional ironic service for fencing is not a good design choice." +diff --git a/agents/kubevirt/fence_kubevirt.py b/agents/kubevirt/fence_kubevirt.py +index 8c27a0334..e3817b0fb 100755 +--- a/agents/kubevirt/fence_kubevirt.py ++++ b/agents/kubevirt/fence_kubevirt.py +@@ -125,7 +125,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for KubeVirt" +- docs["longdesc"] = "fence_kubevirt is an I/O Fencing agent for KubeVirt." ++ docs["longdesc"] = "fence_kubevirt is a Power Fencing agent for KubeVirt." + docs["vendorurl"] = "https://kubevirt.io/" + show_docs(options, docs) + +diff --git a/agents/ldom/fence_ldom.py b/agents/ldom/fence_ldom.py +index 0cb3320b3..78edd2950 100644 +--- a/agents/ldom/fence_ldom.py ++++ b/agents/ldom/fence_ldom.py +@@ -75,7 +75,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Sun LDOM" +- docs["longdesc"] = "fence_ldom is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_ldom is a Power Fencing agent \ + which can be used with LDoms virtual machines. This agent works \ + so, that run ldm command on host machine. So ldm must be directly \ + runnable.\ +diff --git a/agents/lindy_pdu/fence_lindypdu.py b/agents/lindy_pdu/fence_lindypdu.py +index 432b74151..f51288449 100644 +--- a/agents/lindy_pdu/fence_lindypdu.py ++++ b/agents/lindy_pdu/fence_lindypdu.py +@@ -191,7 +191,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for Lindy over SNMP" +- docs["longdesc"] = "fence_lindypdu is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_lindypdu is a Power Fencing agent \ + which can be used with the Lindy PDU network power switch. It logs \ + into a device via SNMP and reboots a specified outlet. It supports \ + SNMP v1 with all combinations of authenticity/privacy settings." +diff --git a/agents/lpar/fence_lpar.py b/agents/lpar/fence_lpar.py +index 975971a57..a18e1c9ae 100644 +--- a/agents/lpar/fence_lpar.py ++++ b/agents/lpar/fence_lpar.py +@@ -175,7 +175,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for IBM LPAR" +- docs["longdesc"] = "" ++ docs["longdesc"] = "fence_lpar is a Power Fencing agent for IBM LPAR." + docs["vendorurl"] = "http://www.ibm.com" + show_docs(options, docs) + +diff --git a/agents/mpath/fence_mpath.py b/agents/mpath/fence_mpath.py +index 6976fee90..0e5d9ed30 100644 +--- a/agents/mpath/fence_mpath.py ++++ b/agents/mpath/fence_mpath.py +@@ -304,7 +304,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for multipath persistent reservation" +- docs["longdesc"] = "fence_mpath is an I/O fencing agent that uses SCSI-3 \ ++ docs["longdesc"] = "fence_mpath is an I/O Fencing agent that uses SCSI-3 \ + persistent reservations to control access multipath devices. Underlying \ + devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ + well as the \"preempt-and-abort\" subcommand.\nThe fence_mpath agent works by \ +diff --git a/agents/netio/fence_netio.py b/agents/netio/fence_netio.py +index 4fb59cffc..fc3bf9d83 100755 +--- a/agents/netio/fence_netio.py ++++ b/agents/netio/fence_netio.py +@@ -58,8 +58,8 @@ def main(): + options = check_input(device_opt, opt) + + docs = {} +- docs["shortdesc"] = "I/O Fencing agent for Koukaam NETIO-230B" +- docs["longdesc"] = "fence_netio is an I/O Fencing agent which can be \ ++ docs["shortdesc"] = "Power Fencing agent for Koukaam NETIO-230B" ++ docs["longdesc"] = "fence_netio is a Power Fencing agent which can be \ + used with the Koukaam NETIO-230B Power Distribution Unit. It logs into \ + device via telnet and reboots a specified outlet. Lengthy telnet connections \ + should be avoided while a GFS cluster is running because the connection will \ +diff --git a/agents/openstack/fence_openstack.py b/agents/openstack/fence_openstack.py +index 666016d78..e7aea0865 100644 +--- a/agents/openstack/fence_openstack.py ++++ b/agents/openstack/fence_openstack.py +@@ -301,7 +301,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for OpenStack's Nova service" +- docs["longdesc"] = "fence_openstack is a Fencing agent \ ++ docs["longdesc"] = "fence_openstack is a Power Fencing agent \ + which can be used with machines controlled by the Openstack's Nova service. \ + This agent calls the python-novaclient and it is mandatory to be installed " + docs["vendorurl"] = "https://wiki.openstack.org/wiki/Nova" +diff --git a/agents/ovh/fence_ovh.py b/agents/ovh/fence_ovh.py +index 2b7eb864f..f0ea67c69 100644 +--- a/agents/ovh/fence_ovh.py ++++ b/agents/ovh/fence_ovh.py +@@ -86,7 +86,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for OVH" +- docs["longdesc"] = "fence_ovh is an Power Fencing agent \ ++ docs["longdesc"] = "fence_ovh is a Power Fencing agent \ + which can be used within OVH datecentre. \ + Poweroff is simulated with a reboot into rescue-pro mode." + +diff --git a/agents/powerman/fence_powerman.py b/agents/powerman/fence_powerman.py +index 7aeeaf125..cdca5d36d 100755 +--- a/agents/powerman/fence_powerman.py ++++ b/agents/powerman/fence_powerman.py +@@ -231,7 +231,7 @@ def main(): + options = check_input(device_opt, process_input(device_opt)) + docs = {} + docs["shortdesc"] = "Fence Agent for Powerman" +- docs["longdesc"] = "This is a Pacemaker Fence Agent for the \ ++ docs["longdesc"] = "fence_powerman is a Power Fence Agent for the \ + Powerman management utility that was designed for LLNL systems." + docs["vendorurl"] = "https://github.com/chaos/powerman" + show_docs(options, docs) +diff --git a/agents/pve/fence_pve.py b/agents/pve/fence_pve.py +index 0d820355f..f97007dc5 100755 +--- a/agents/pve/fence_pve.py ++++ b/agents/pve/fence_pve.py +@@ -195,8 +195,8 @@ def main(): + options = check_input(device_opt, process_input(device_opt)) + docs = {} + docs["shortdesc"] = "Fencing agent for the Proxmox Virtual Environment" +- docs["longdesc"] = "The fence_pve agent can be used to fence virtual \ +-machines acting as nodes in a virtualized cluster." ++ docs["longdesc"] = "fence_pve is a Power Fencing agent for virtual machines \ ++acting as nodes in a virtualized cluster." + docs["vendorurl"] = "http://www.proxmox.com/" + + show_docs(options, docs) +diff --git a/agents/raritan/fence_raritan.py b/agents/raritan/fence_raritan.py +index 169fa8197..d3510e4a1 100644 +--- a/agents/raritan/fence_raritan.py ++++ b/agents/raritan/fence_raritan.py +@@ -39,8 +39,8 @@ def main(): + options = check_input(device_opt, opt) + + docs = {} +- docs["shortdesc"] = "I/O Fencing agent for Raritan Dominion PX" +- docs["longdesc"] = "fence_raritan is an I/O Fencing agent which can be \ ++ docs["shortdesc"] = "Power Fencing agent for Raritan Dominion PX" ++ docs["longdesc"] = "fence_raritan is a Power Fencing agent which can be \ + used with the Raritan DPXS12-20 Power Distribution Unit. It logs into \ + device via telnet and reboots a specified outlet. Lengthy telnet connections \ + should be avoided while a GFS cluster is running because the connection will \ +diff --git a/agents/rcd_serial/fence_rcd_serial.py b/agents/rcd_serial/fence_rcd_serial.py +index 2614772ff..d14b4c661 100644 +--- a/agents/rcd_serial/fence_rcd_serial.py ++++ b/agents/rcd_serial/fence_rcd_serial.py +@@ -77,11 +77,12 @@ def main(): + + docs = {} + docs["shortdesc"] = "rcd_serial fence agent" +- docs["longdesc"] = "fence_rcd_serial operates a serial cable that toggles a \ +-reset of an opposing server using the reset switch on its motherboard. The \ +-cable itself is simple with no power, network or moving parts. An example of \ +-the cable is available here: https://smcleod.net/rcd-stonith/ and the circuit \ +-design is available in the fence-agents src as SVG" ++ docs["longdesc"] = "fence_rcd_serial is a Power Fencing agent that \ ++operates a serial cable that toggles a reset of an opposing server using the \ ++reset switch on its motherboard. The cable itself is simple with no power, \ ++network or moving parts. An example of the cable is available here: \ ++https://smcleod.net/rcd-stonith/ and the circuit design is available in the \ ++fence-agents src as SVG" + docs["vendorurl"] = "https://github.com/sammcj/fence_rcd_serial" + show_docs(options, docs) + +diff --git a/agents/redfish/fence_redfish.py b/agents/redfish/fence_redfish.py +index 0f5af523c..a935122ec 100644 +--- a/agents/redfish/fence_redfish.py ++++ b/agents/redfish/fence_redfish.py +@@ -132,8 +132,8 @@ def main(): + options = check_input(device_opt, opt) + + docs = {} +- docs["shortdesc"] = "I/O Fencing agent for Redfish" +- docs["longdesc"] = "fence_redfish is an I/O Fencing agent which can be used with \ ++ docs["shortdesc"] = "Power Fencing agent for Redfish" ++ docs["longdesc"] = "fence_redfish is a Power Fencing agent which can be used with \ + Out-of-Band controllers that support Redfish APIs. These controllers provide remote \ + access to control power on a server." + docs["vendorurl"] = "http://www.dmtf.org" +diff --git a/agents/rhevm/fence_rhevm.py b/agents/rhevm/fence_rhevm.py +index 5f74d06f6..1eb53bed0 100644 +--- a/agents/rhevm/fence_rhevm.py ++++ b/agents/rhevm/fence_rhevm.py +@@ -232,7 +232,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for RHEV-M REST API" +- docs["longdesc"] = "fence_rhevm is an I/O Fencing agent which can be \ ++ docs["longdesc"] = "fence_rhevm is a Power Fencing agent which can be \ + used with RHEV-M REST API to fence virtual machines." + docs["vendorurl"] = "http://www.redhat.com" + show_docs(options, docs) +diff --git a/agents/rsa/fence_rsa.py b/agents/rsa/fence_rsa.py +index 44fdd9d05..79ed109eb 100644 +--- a/agents/rsa/fence_rsa.py ++++ b/agents/rsa/fence_rsa.py +@@ -42,7 +42,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for IBM RSA" +- docs["longdesc"] = "fence_rsa is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_rsa is a Power Fencing agent \ + which can be used with the IBM RSA II management interface. It \ + logs into an RSA II device via telnet and reboots the associated \ + machine. Lengthy telnet connections to the RSA II device should \ +diff --git a/agents/rsb/fence_rsb.py b/agents/rsb/fence_rsb.py +index 45355f51e..e4622ae9f 100755 +--- a/agents/rsb/fence_rsb.py ++++ b/agents/rsb/fence_rsb.py +@@ -49,8 +49,8 @@ def main(): + options = check_input(device_opt, opt) + + docs = {} +- docs["shortdesc"] = "I/O Fencing agent for Fujitsu-Siemens RSB" +- docs["longdesc"] = "fence_rsb is an I/O Fencing agent \ ++ docs["shortdesc"] = "Power Fencing agent for Fujitsu-Siemens RSB" ++ docs["longdesc"] = "fence_rsb is a Power Fencing agent \ + which can be used with the Fujitsu-Siemens RSB management interface. It logs \ + into device via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh \ + connections should be avoided while a GFS cluster is running because the connection \ +diff --git a/agents/sbd/fence_sbd.py b/agents/sbd/fence_sbd.py +index 2b0127d55..5c498263e 100644 +--- a/agents/sbd/fence_sbd.py ++++ b/agents/sbd/fence_sbd.py +@@ -377,7 +377,7 @@ def main(): + # fill the needed variables to generate metadata and help text output + docs = {} + docs["shortdesc"] = "Fence agent for sbd" +- docs["longdesc"] = "fence_sbd is I/O Fencing agent \ ++ docs["longdesc"] = "fence_sbd is an I/O Fencing agent \ + which can be used in environments where sbd can be used (shared storage)." + docs["vendorurl"] = "" + show_docs(options, docs) +diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py +index 519319bf5..5cb5dbee9 100644 +--- a/agents/scsi/fence_scsi.py ++++ b/agents/scsi/fence_scsi.py +@@ -546,7 +546,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for SCSI persistent reservation" +- docs["longdesc"] = "fence_scsi is an I/O fencing agent that uses SCSI-3 \ ++ docs["longdesc"] = "fence_scsi is an I/O Fencing agent that uses SCSI-3 \ + persistent reservations to control access to shared storage devices. These \ + devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \ + well as the \"preempt-and-abort\" subcommand.\nThe fence_scsi agent works by \ +diff --git a/agents/skalar/fence_skalar.py b/agents/skalar/fence_skalar.py +index 0e11d83f9..c8589c1a4 100644 +--- a/agents/skalar/fence_skalar.py ++++ b/agents/skalar/fence_skalar.py +@@ -192,7 +192,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Skala-R Fence agent" +- docs["longdesc"] = "A fence agent for Skala-R." ++ docs["longdesc"] = "fence_skalar is a Power Fencing agent for Skala-R." + docs["vendorurl"] = "https://www.skala-r.ru/" + show_docs(options, docs) + options["eol"] = "\r" +diff --git a/agents/vbox/fence_vbox.py b/agents/vbox/fence_vbox.py +index c2df28811..52f0a2a8a 100644 +--- a/agents/vbox/fence_vbox.py ++++ b/agents/vbox/fence_vbox.py +@@ -115,7 +115,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for VirtualBox" +- docs["longdesc"] = "fence_vbox is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_vbox is a Power Fencing agent \ + which can be used with the virtual machines managed by VirtualBox. \ + It logs via ssh to a dom0 where it runs VBoxManage to do all of \ + the work. \ +diff --git a/agents/virsh/fence_virsh.py b/agents/virsh/fence_virsh.py +index 88cee48de..bde189c2b 100644 +--- a/agents/virsh/fence_virsh.py ++++ b/agents/virsh/fence_virsh.py +@@ -76,7 +76,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for virsh" +- docs["longdesc"] = "fence_virsh is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_virsh is a Power Fencing agent \ + which can be used with the virtual machines managed by libvirt. \ + It logs via ssh to a dom0 and there run virsh command, which does \ + all work. \ +diff --git a/agents/virt/client/options.c b/agents/virt/client/options.c +index ddd6bc4e0..ce7ba14da 100644 +--- a/agents/virt/client/options.c ++++ b/agents/virt/client/options.c +@@ -765,7 +765,7 @@ args_metadata(char *progname, const char *optstr) + + printf("<?xml version=\"1.0\" ?>\n"); + printf("<resource-agent name=\"%s\" shortdesc=\"Fence agent for virtual machines\">\n", basename(progname)); +- printf("<longdesc>%s is an I/O Fencing agent which can be used with " ++ printf("<longdesc>%s is a Power Fencing agent which can be used with " + "virtual machines.\n\nNOTE: reboot-action does not power on nodes that are powered off." + "</longdesc>\n", basename(progname)); + printf("<vendor-url>https://libvirt.org</vendor-url>\n"); +diff --git a/agents/vmware/fence_vmware.py b/agents/vmware/fence_vmware.py +index bc1785f4c..ccef92bb2 100644 +--- a/agents/vmware/fence_vmware.py ++++ b/agents/vmware/fence_vmware.py +@@ -292,7 +292,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for VMWare" +- docs["longdesc"] = "fence_vmware is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_vmware is a Power Fencing agent \ + which can be used with the VMware ESX, VMware ESXi or VMware Server \ + to fence virtual machines.\ + \n.P\n\ +diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py +index 4b884fc62..378771863 100644 +--- a/agents/vmware_rest/fence_vmware_rest.py ++++ b/agents/vmware_rest/fence_vmware_rest.py +@@ -204,7 +204,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for VMware REST API" +- docs["longdesc"] = """fence_vmware_rest is an I/O Fencing agent which can be \ ++ docs["longdesc"] = """fence_vmware_rest is a Power Fencing agent which can be \ + used with VMware API to fence virtual machines. + + NOTE: If there's more than 1000 VMs there is a filter parameter to work around \ +diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py +index 4a4ec1780..4b3c404ce 100644 +--- a/agents/vmware_soap/fence_vmware_soap.py ++++ b/agents/vmware_soap/fence_vmware_soap.py +@@ -235,7 +235,7 @@ def main(): + ##### + docs = {} + docs["shortdesc"] = "Fence agent for VMWare over SOAP API" +- docs["longdesc"] = "fence_vmware_soap is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_vmware_soap is a Power Fencing agent \ + which can be used with the virtual machines managed by VMWare products \ + that have SOAP API v4.1+. \ + \n.P\n\ +diff --git a/agents/vmware_vcloud/fence_vmware_vcloud.py b/agents/vmware_vcloud/fence_vmware_vcloud.py +index 7626b82bb..e0a714b84 100644 +--- a/agents/vmware_vcloud/fence_vmware_vcloud.py ++++ b/agents/vmware_vcloud/fence_vmware_vcloud.py +@@ -194,7 +194,8 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for VMware vCloud Director API" +- docs["longdesc"] = "fence_vmware_vcloud is an I/O Fencing agent which can be used with VMware vCloud Director API to fence virtual machines." ++ docs["longdesc"] = "fence_vmware_vcloud is a Power Fencing agent which \ ++can be used with VMware vCloud Director API to fence virtual machines." + docs["vendorurl"] = "https://www.vmware.com" + show_docs(options, docs) + +diff --git a/agents/wti/fence_wti.py b/agents/wti/fence_wti.py +index 97cc66de2..ffa3d019c 100644 +--- a/agents/wti/fence_wti.py ++++ b/agents/wti/fence_wti.py +@@ -184,7 +184,7 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for WTI" +- docs["longdesc"] = "fence_wti is an I/O Fencing agent \ ++ docs["longdesc"] = "fence_wti is a Power Fencing agent \ + which can be used with the WTI Network Power Switch (NPS). It logs \ + into an NPS via telnet or ssh and boots a specified plug. \ + Lengthy telnet connections to the NPS should be avoided while a GFS cluster \ +diff --git a/agents/xenapi/fence_xenapi.py b/agents/xenapi/fence_xenapi.py +index 10c8ee03e..884fbc79f 100644 +--- a/agents/xenapi/fence_xenapi.py ++++ b/agents/xenapi/fence_xenapi.py +@@ -202,7 +202,7 @@ def main(): + docs = {} + docs["shortdesc"] = "Fence agent for Citrix XenServer over XenAPI" + docs["longdesc"] = "\ +-fence_cxs is an I/O Fencing agent used on Citrix XenServer hosts. \ ++fence_xenapi is a Power Fencing agent used on Citrix XenServer hosts. \ + It uses the XenAPI, supplied by Citrix, to establish an XML-RPC session \ + to a XenServer host. Once the session is established, further XML-RPC \ + commands are issued in order to switch on, switch off, restart and query \ +diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py +index c37950a20..f1cea2652 100644 +--- a/agents/zvm/fence_zvmip.py ++++ b/agents/zvm/fence_zvmip.py +@@ -199,8 +199,8 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for use with z/VM Virtual Machines" +- docs["longdesc"] = """The fence_zvmip agent is intended to be used with the +-z/VM SMAPI service via TCP/IP. ++ docs["longdesc"] = """fence_zvmip is a Power Fencing agent for z/VM \ ++SMAPI service via TCP/IP. + + 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, +diff --git a/tests/data/metadata/fence_aliyun.xml b/tests/data/metadata/fence_aliyun.xml +index b06718891..a52de014c 100644 +--- a/tests/data/metadata/fence_aliyun.xml ++++ b/tests/data/metadata/fence_aliyun.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_aliyun" shortdesc="Fence agent for Aliyun (Aliyun Web Services)" > +-<longdesc>fence_aliyun is an I/O Fencing agent for Aliyun</longdesc> ++<longdesc>fence_aliyun is a Power Fencing agent for Aliyun.</longdesc> + <vendor-url>http://www.aliyun.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml +index 6532ad6dd..de0a4b60d 100644 +--- a/tests/data/metadata/fence_alom.xml ++++ b/tests/data/metadata/fence_alom.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_alom" shortdesc="Fence agent for Sun ALOM" > +-<longdesc>fence_alom is an I/O Fencing agent which can be used with ALOM connected machines.</longdesc> ++<longdesc>fence_alom is a Power Fencing agent which can be used with ALOM connected machines.</longdesc> + <vendor-url>http://www.sun.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml +index 809c2dfea..58eb86761 100644 +--- a/tests/data/metadata/fence_amt.xml ++++ b/tests/data/metadata/fence_amt.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_amt" shortdesc="Fence agent for AMT" > +-<longdesc>fence_amt is an I/O Fencing agent which can be used with Intel AMT. This agent calls support software amttool(http://www.kraxel.org/cgit/amtterm/).</longdesc> ++<longdesc>fence_amt is a Power Fencing agent which can be used with Intel AMT. This agent calls support software amttool(http://www.kraxel.org/cgit/amtterm/).</longdesc> + <vendor-url>http://www.intel.com/</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_amt_ws.xml b/tests/data/metadata/fence_amt_ws.xml +index 97a222526..08ed75148 100644 +--- a/tests/data/metadata/fence_amt_ws.xml ++++ b/tests/data/metadata/fence_amt_ws.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_amt_ws" shortdesc="Fence agent for AMT (WS)" > +-<longdesc>fence_amt_ws is an I/O Fencing agent which can be used with Intel AMT (WS). This agent requires the pywsman Python library which is included in OpenWSMAN. (http://openwsman.github.io/).</longdesc> ++<longdesc>fence_amt_ws is a Power Fencing agent which can be used with Intel AMT (WS). This agent requires the pywsman Python library which is included in OpenWSMAN. (http://openwsman.github.io/).</longdesc> + <vendor-url>http://www.intel.com/</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_apc.xml b/tests/data/metadata/fence_apc.xml +index 6081b1ff5..e40c7879d 100644 +--- a/tests/data/metadata/fence_apc.xml ++++ b/tests/data/metadata/fence_apc.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_apc" shortdesc="Fence agent for APC over telnet/ssh" > +-<longdesc>fence_apc is an I/O Fencing agent which can be used with the APC network power switch. It logs into device via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> ++<longdesc>fence_apc is a Power Fencing agent which can be used with the APC network power switch. It logs into device via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> + <vendor-url>http://www.apc.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_apc_snmp.xml b/tests/data/metadata/fence_apc_snmp.xml +index 02efbb0b0..8df05345c 100644 +--- a/tests/data/metadata/fence_apc_snmp.xml ++++ b/tests/data/metadata/fence_apc_snmp.xml +@@ -1,7 +1,7 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_apc_snmp" shortdesc="Fence agent for APC, Tripplite PDU over SNMP" > + <symlink name="fence_tripplite_snmp" shortdesc="Fence agent for Tripplife over SNMP"/> +-<longdesc>fence_apc_snmp is an I/O Fencing agent which can be used with the APC network power switch or Tripplite PDU devices.It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1, v2c, v3 with all combinations of authenticity/privacy settings.</longdesc> ++<longdesc>fence_apc_snmp is a Power Fencing agent which can be used with the APC network power switch or Tripplite PDU devices.It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1, v2c, v3 with all combinations of authenticity/privacy settings.</longdesc> + <vendor-url>http://www.apc.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_aws.xml b/tests/data/metadata/fence_aws.xml +index 32de4418a..ad471c797 100644 +--- a/tests/data/metadata/fence_aws.xml ++++ b/tests/data/metadata/fence_aws.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_aws" shortdesc="Fence agent for AWS (Amazon Web Services)" > +-<longdesc>fence_aws is an I/O Fencing agent for AWS (Amazon WebServices). It uses the boto3 library to connect to AWS. ++<longdesc>fence_aws is a Power Fencing agent for AWS (Amazon WebServices). It uses the boto3 library to connect to AWS. + + boto3 can be configured with AWS CLI or by creating ~/.aws/credentials. + For instructions see: https://boto3.readthedocs.io/en/latest/guide/quickstart.html#configuration</longdesc> +diff --git a/tests/data/metadata/fence_azure_arm.xml b/tests/data/metadata/fence_azure_arm.xml +index 8b7450762..59c3b7433 100644 +--- a/tests/data/metadata/fence_azure_arm.xml ++++ b/tests/data/metadata/fence_azure_arm.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_azure_arm" shortdesc="Fence agent for Azure Resource Manager" > +-<longdesc>fence_azure_arm is an I/O Fencing agent for Azure Resource Manager. It uses Azure SDK for Python to connect to Azure. ++<longdesc>fence_azure_arm is a Power Fencing agent for Azure Resource Manager. It uses Azure SDK for Python to connect to Azure. + + For instructions to setup credentials see: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal + +diff --git a/tests/data/metadata/fence_bladecenter.xml b/tests/data/metadata/fence_bladecenter.xml +index 3cc415355..e8468e336 100644 +--- a/tests/data/metadata/fence_bladecenter.xml ++++ b/tests/data/metadata/fence_bladecenter.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_bladecenter" shortdesc="Fence agent for IBM BladeCenter" > +-<longdesc>fence_bladecenter is an I/O Fencing agent which can be used with IBM Bladecenters with recent enough firmware that includes telnet support. It logs into a Brocade chasis via telnet or ssh and uses the command line interface to power on and off blades.</longdesc> ++<longdesc>fence_bladecenter is a Power Fencing agent which can be used with IBM Bladecenters with recent enough firmware that includes telnet support. It logs into a Brocade chasis via telnet or ssh and uses the command line interface to power on and off blades.</longdesc> + <vendor-url>http://www.ibm.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_cdu.xml b/tests/data/metadata/fence_cdu.xml +index ef87d795d..b92e7a937 100644 +--- a/tests/data/metadata/fence_cdu.xml ++++ b/tests/data/metadata/fence_cdu.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_cdu" shortdesc="Fence agent for a Sentry Switch CDU over telnet" > +-<longdesc>fence_cdu is an I/O Fencing agent which can be used with the Sentry Switch CDU. It logs into the device via telnet and power's on/off an outlet.</longdesc> ++<longdesc>fence_cdu is a Power Fencing agent which can be used with the Sentry Switch CDU. It logs into the device via telnet and power's on/off an outlet.</longdesc> + <vendor-url>http://www.servertech.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_cisco_mds.xml b/tests/data/metadata/fence_cisco_mds.xml +index 829c9dcbe..2105ecccc 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 an I/O Fencing agent which can be used with any Cisco MDS 9000 series with SNMP enabled device.</longdesc> ++<longdesc>fence_cisco_mds is a Power 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"> +diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +index 76d15e9f4..a9368e8be 100644 +--- a/tests/data/metadata/fence_cisco_ucs.xml ++++ b/tests/data/metadata/fence_cisco_ucs.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_cisco_ucs" shortdesc="Fence agent for Cisco UCS" > +-<longdesc>fence_cisco_ucs is an I/O Fencing agent which can be used with Cisco UCS to fence machines.</longdesc> ++<longdesc>fence_cisco_ucs is a Power Fencing agent which can be used with Cisco UCS to fence machines.</longdesc> + <vendor-url>http://www.cisco.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml +index f685b1162..f0cacd4d9 100644 +--- a/tests/data/metadata/fence_docker.xml ++++ b/tests/data/metadata/fence_docker.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_docker" shortdesc="Fence agent for Docker" > +-<longdesc>fence_docker is I/O fencing agent which can be used with the Docker Engine containers. You can use this fence-agent without any authentication, or you can use TLS authentication (use --ssl option, more info about TLS authentication in docker: http://docs.docker.com/examples/https/).</longdesc> ++<longdesc>fence_docker is a Power Fencing agent which can be used with the Docker Engine containers. You can use this fence-agent without any authentication, or you can use TLS authentication (use --ssl option, more info about TLS authentication in docker: http://docs.docker.com/examples/https/).</longdesc> + <vendor-url>www.docker.io</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml +index a99126132..b2ce0825f 100644 +--- a/tests/data/metadata/fence_drac.xml ++++ b/tests/data/metadata/fence_drac.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> +-<resource-agent name="fence_drac" shortdesc="I/O Fencing agent for Dell DRAC IV" > +-<longdesc>fence_drac is an I/O Fencing agent which can be used with the Dell Remote Access Card (DRAC). This card provides remote access to controlling power to a server. It logs into the DRAC through the telnet interface of the card. By default, the telnet interface is not enabled. To enable the interface, you will need to use the racadm command in the racser-devel rpm available from Dell. To enable telnet on the DRAC: [root]# racadm config -g cfgSerial -o cfgSerialTelnetEnable 1 [root]# racadm racreset </longdesc> ++<resource-agent name="fence_drac" shortdesc="Power Fencing agent for Dell DRAC IV" > ++<longdesc>fence_drac is a Power Fencing agent which can be used with the Dell Remote Access Card (DRAC). This card provides remote access to controlling power to a server. It logs into the DRAC through the telnet interface of the card. By default, the telnet interface is not enabled. To enable the interface, you will need to use the racadm command in the racser-devel rpm available from Dell. To enable telnet on the DRAC: [root]# racadm config -g cfgSerial -o cfgSerialTelnetEnable 1 [root]# racadm racreset </longdesc> + <vendor-url>http://www.dell.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_drac5.xml b/tests/data/metadata/fence_drac5.xml +index a0c73ebf8..a633d43b5 100644 +--- a/tests/data/metadata/fence_drac5.xml ++++ b/tests/data/metadata/fence_drac5.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_drac5" shortdesc="Fence agent for Dell DRAC CMC/5" > +-<longdesc>fence_drac5 is an I/O Fencing agent which can be used with the Dell Remote Access Card v5 or CMC (DRAC). This device provides remote access to controlling power to a server. It logs into the DRAC through the telnet/ssh interface of the card. By default, the telnet interface is not enabled.</longdesc> ++<longdesc>fence_drac5 is a Power Fencing agent which can be used with the Dell Remote Access Card v5 or CMC (DRAC). This device provides remote access to controlling power to a server. It logs into the DRAC through the telnet/ssh interface of the card. By default, the telnet interface is not enabled.</longdesc> + <vendor-url>http://www.dell.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_eaton_snmp.xml b/tests/data/metadata/fence_eaton_snmp.xml +index 1d89b5272..cb852fb0d 100644 +--- a/tests/data/metadata/fence_eaton_snmp.xml ++++ b/tests/data/metadata/fence_eaton_snmp.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_eaton_snmp" shortdesc="Fence agent for Eaton over SNMP" > +-<longdesc>fence_eaton_snmp is an I/O Fencing agent which can be used with the Eaton network power switch. It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1 and v3 with all combinations of authenticity/privacy settings.</longdesc> ++<longdesc>fence_eaton_snmp is a Power Fencing agent which can be used with the Eaton network power switch. It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1 and v3 with all combinations of authenticity/privacy settings.</longdesc> + <vendor-url>http://powerquality.eaton.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +index 1ed792e2b..fde75bd54 100644 +--- a/tests/data/metadata/fence_emerson.xml ++++ b/tests/data/metadata/fence_emerson.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_emerson" shortdesc="Fence agent for Emerson over SNMP" > +-<longdesc>fence_emerson is an I/O Fencing agent which can be used with MPX and MPH2 managed rack PDU.</longdesc> ++<longdesc>fence_emerson is a Power Fencing agent which can be used with MPX and MPH2 managed rack PDU.</longdesc> + <vendor-url>http://www.emersonnetworkpower.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml +index a8cf8ad41..3f9ebdc22 100644 +--- a/tests/data/metadata/fence_eps.xml ++++ b/tests/data/metadata/fence_eps.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_eps" shortdesc="Fence agent for ePowerSwitch" > +-<longdesc>fence_eps is an I/O 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. ++<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. + + 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> +diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml +index 2a89b16c2..8226e1aa0 100644 +--- a/tests/data/metadata/fence_gce.xml ++++ b/tests/data/metadata/fence_gce.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_gce" shortdesc="Fence agent for GCE (Google Cloud Engine)" > +-<longdesc>fence_gce is an I/O Fencing agent for GCE (Google Cloud Engine). It uses the googleapiclient library to connect to GCE. ++<longdesc>fence_gce is a Power Fencing agent for GCE (Google Cloud Engine). It uses the googleapiclient library to connect to GCE. + googleapiclient can be configured with Google SDK CLI or by executing 'gcloud auth application-default login'. + For instructions see: https://cloud.google.com/compute/docs/tutorials/python-guide</longdesc> + <vendor-url>http://cloud.google.com</vendor-url> +diff --git a/tests/data/metadata/fence_hds_cb.xml b/tests/data/metadata/fence_hds_cb.xml +index e25d889e3..1e3a4889e 100644 +--- a/tests/data/metadata/fence_hds_cb.xml ++++ b/tests/data/metadata/fence_hds_cb.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_hds_cb" shortdesc="Fence agent for Hitachi Compute Blade systems" > +-<longdesc>fence_hds_cb is an I/O Fencing agent which can be used with Hitachi Compute Blades with recent enough firmware that includes telnet support.</longdesc> ++<longdesc>fence_hds_cb is a Power Fencing agent which can be used with Hitachi Compute Blades with recent enough firmware that includes telnet support.</longdesc> + <vendor-url>http://www.hds.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_hpblade.xml b/tests/data/metadata/fence_hpblade.xml +index 0957fcdd4..3f05be222 100644 +--- a/tests/data/metadata/fence_hpblade.xml ++++ b/tests/data/metadata/fence_hpblade.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_hpblade" shortdesc="Fence agent for HP BladeSystem" > +-<longdesc>fence_hpblade is an I/O Fencing agent which can be used with HP BladeSystem and HP Integrity Superdome X. It logs into the onboard administrator of an enclosure via telnet or ssh and uses the command line interface to power blades or partitions on or off.</longdesc> ++<longdesc>fence_hpblade is a Power Fencing agent which can be used with HP BladeSystem and HP Integrity Superdome X. It logs into the onboard administrator of an enclosure via telnet or ssh and uses the command line interface to power blades or partitions on or off.</longdesc> + <vendor-url>http://www.hp.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ibm_powervs.xml b/tests/data/metadata/fence_ibm_powervs.xml +index 7bdee4e29..c1dc034dc 100644 +--- a/tests/data/metadata/fence_ibm_powervs.xml ++++ b/tests/data/metadata/fence_ibm_powervs.xml +@@ -1,6 +1,6 @@ + <?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> ++<longdesc>fence_ibm_powervs is a Power 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="api-type" unique="0" required="0" deprecated="1"> +diff --git a/tests/data/metadata/fence_ibm_vpc.xml b/tests/data/metadata/fence_ibm_vpc.xml +index fe29ffb89..fafcad214 100644 +--- a/tests/data/metadata/fence_ibm_vpc.xml ++++ b/tests/data/metadata/fence_ibm_vpc.xml +@@ -1,6 +1,6 @@ + <?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> ++<longdesc>fence_ibm_vpc is a Power 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"> +diff --git a/tests/data/metadata/fence_ibmblade.xml b/tests/data/metadata/fence_ibmblade.xml +index 3286ca6de..61366ca3c 100644 +--- a/tests/data/metadata/fence_ibmblade.xml ++++ b/tests/data/metadata/fence_ibmblade.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ibmblade" shortdesc="Fence agent for IBM BladeCenter over SNMP" > +-<longdesc>fence_ibmblade is an I/O Fencing agent which can be used with IBM BladeCenter chassis. It issues SNMP Set request to BladeCenter chassis, rebooting, powering up or down the specified Blade Server.</longdesc> ++<longdesc>fence_ibmblade is a Power Fencing agent which can be used with IBM BladeCenter chassis. It issues SNMP Set request to BladeCenter chassis, rebooting, powering up or down the specified Blade Server.</longdesc> + <vendor-url>http://www.ibm.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ibmz.xml b/tests/data/metadata/fence_ibmz.xml +index ba74fa6fe..7554d4d78 100644 +--- a/tests/data/metadata/fence_ibmz.xml ++++ b/tests/data/metadata/fence_ibmz.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ibmz" shortdesc="Fence agent for IBM z LPARs" > +-<longdesc>fence_ibmz is a power fencing agent which uses the HMC Web Services API to fence IBM z LPARs.</longdesc> ++<longdesc>fence_ibmz is a Power Fencing agent which uses the HMC Web Services API to fence IBM z LPARs.</longdesc> + <vendor-url>http://www.ibm.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index d1f283e4a..aa291345a 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_idrac is a Power Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +index 0bac03c83..f8fe61cbb 100644 +--- a/tests/data/metadata/fence_ilo.xml ++++ b/tests/data/metadata/fence_ilo.xml +@@ -1,7 +1,7 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ilo" shortdesc="Fence agent for HP iLO" > + <symlink name="fence_ilo2" shortdesc="Fence agent for HP iLO2"/> +-<longdesc>fence_ilo is an I/O Fencing agent used for HP servers with the Integrated Light Out (iLO) PCI card.The agent opens an SSL connection to the iLO card. Once the SSL connection is established, the agent is able to communicate with the iLO card through an XML stream.</longdesc> ++<longdesc>fence_ilo is a Power Fencing agent used for HP servers with the Integrated Light Out (iLO) PCI card.The agent opens an SSL connection to the iLO card. Once the SSL connection is established, the agent is able to communicate with the iLO card through an XML stream.</longdesc> + <vendor-url>http://www.hp.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +index 3d954a345..d7e72084e 100644 +--- a/tests/data/metadata/fence_ilo2.xml ++++ b/tests/data/metadata/fence_ilo2.xml +@@ -1,7 +1,7 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ilo2" shortdesc="Fence agent for HP iLO" > + <symlink name="fence_ilo2" shortdesc="Fence agent for HP iLO2"/> +-<longdesc>fence_ilo is an I/O Fencing agent used for HP servers with the Integrated Light Out (iLO) PCI card.The agent opens an SSL connection to the iLO card. Once the SSL connection is established, the agent is able to communicate with the iLO card through an XML stream.</longdesc> ++<longdesc>fence_ilo2 is a Power Fencing agent used for HP servers with the Integrated Light Out (iLO) PCI card.The agent opens an SSL connection to the iLO card. Once the SSL connection is established, the agent is able to communicate with the iLO card through an XML stream.</longdesc> + <vendor-url>http://www.hp.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index 5aca0211b..90dc2f657 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ilo3 is a Power Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +index e2a25661d..f46ec7d13 100644 +--- a/tests/data/metadata/fence_ilo3_ssh.xml ++++ b/tests/data/metadata/fence_ilo3_ssh.xml +@@ -3,7 +3,7 @@ + <symlink name="fence_ilo3_ssh" shortdesc="Fence agent for HP iLO3 over SSH"/> + <symlink name="fence_ilo4_ssh" shortdesc="Fence agent for HP iLO4 over SSH"/> + <symlink name="fence_ilo5_ssh" shortdesc="Fence agent for HP iLO5 over SSH"/> +-<longdesc>fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. ++<longdesc>fence_ilo3_ssh is a Power Fencing agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. + + WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent to avoid this issue.</longdesc> + <vendor-url>http://www.hp.com</vendor-url> +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index 3aa001ad2..494ff0b3b 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ilo4 is a Power Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +index 4fd6b2ef1..e2a5b7167 100644 +--- a/tests/data/metadata/fence_ilo4_ssh.xml ++++ b/tests/data/metadata/fence_ilo4_ssh.xml +@@ -3,7 +3,7 @@ + <symlink name="fence_ilo3_ssh" shortdesc="Fence agent for HP iLO3 over SSH"/> + <symlink name="fence_ilo4_ssh" shortdesc="Fence agent for HP iLO4 over SSH"/> + <symlink name="fence_ilo5_ssh" shortdesc="Fence agent for HP iLO5 over SSH"/> +-<longdesc>fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. ++<longdesc>fence_ilo4_ssh is a Power Fencing agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. + + WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent to avoid this issue.</longdesc> + <vendor-url>http://www.hp.com</vendor-url> +diff --git a/tests/data/metadata/fence_ilo5.xml b/tests/data/metadata/fence_ilo5.xml +index 262787905..25e7446b3 100644 +--- a/tests/data/metadata/fence_ilo5.xml ++++ b/tests/data/metadata/fence_ilo5.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ilo5 is a Power Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo5_ssh.xml b/tests/data/metadata/fence_ilo5_ssh.xml +index 036aec5c6..f4bd8622b 100644 +--- a/tests/data/metadata/fence_ilo5_ssh.xml ++++ b/tests/data/metadata/fence_ilo5_ssh.xml +@@ -3,7 +3,7 @@ + <symlink name="fence_ilo3_ssh" shortdesc="Fence agent for HP iLO3 over SSH"/> + <symlink name="fence_ilo4_ssh" shortdesc="Fence agent for HP iLO4 over SSH"/> + <symlink name="fence_ilo5_ssh" shortdesc="Fence agent for HP iLO5 over SSH"/> +-<longdesc>fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. ++<longdesc>fence_ilo5_ssh is a Power Fencing agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. + + WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent to avoid this issue.</longdesc> + <vendor-url>http://www.hp.com</vendor-url> +diff --git a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml +index 7d4fd22d5..4ac9484d6 100644 +--- a/tests/data/metadata/fence_ilo_mp.xml ++++ b/tests/data/metadata/fence_ilo_mp.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ilo_mp" shortdesc="Fence agent for HP iLO MP" > +-<longdesc></longdesc> ++<longdesc>fence_ilo_mp is a Power Fencing agent for HP iLO MP.</longdesc> + <vendor-url>http://www.hp.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +index 2e1cb84b2..7564200da 100644 +--- a/tests/data/metadata/fence_ilo_ssh.xml ++++ b/tests/data/metadata/fence_ilo_ssh.xml +@@ -3,7 +3,7 @@ + <symlink name="fence_ilo3_ssh" shortdesc="Fence agent for HP iLO3 over SSH"/> + <symlink name="fence_ilo4_ssh" shortdesc="Fence agent for HP iLO4 over SSH"/> + <symlink name="fence_ilo5_ssh" shortdesc="Fence agent for HP iLO5 over SSH"/> +-<longdesc>fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. ++<longdesc>fence_ilo_ssh is a Power Fencing agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. + + WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent to avoid this issue.</longdesc> + <vendor-url>http://www.hp.com</vendor-url> +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index 26f9a76d3..943e9c3f2 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_imm is a Power Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_intelmodular.xml b/tests/data/metadata/fence_intelmodular.xml +index 5dad0d0bd..66ddb47ae 100644 +--- a/tests/data/metadata/fence_intelmodular.xml ++++ b/tests/data/metadata/fence_intelmodular.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_intelmodular" shortdesc="Fence agent for Intel Modular" > +-<longdesc>fence_intelmodular is an I/O Fencing agent which can be used with Intel Modular device (tested on Intel MFSYS25, should work with MFSYS35 as well). ++<longdesc>fence_intelmodular is a Power Fencing agent which can be used with Intel Modular device (tested on Intel MFSYS25, should work with MFSYS35 as well). + + Note: Since firmware update version 2.7, SNMP v2 write support is removed, and replaced by SNMP v3 support. So agent now has default SNMP version 3. If you are using older firmware, please supply -d for command line and snmp_version option for your cluster.conf.</longdesc> + <vendor-url>http://www.intel.com</vendor-url> +diff --git a/tests/data/metadata/fence_ipdu.xml b/tests/data/metadata/fence_ipdu.xml +index 22024a7a1..941dcbedf 100644 +--- a/tests/data/metadata/fence_ipdu.xml ++++ b/tests/data/metadata/fence_ipdu.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ipdu" shortdesc="Fence agent for iPDU over SNMP" > +-<longdesc>fence_ipdu is an I/O Fencing agent which can be used with the IBM iPDU network power switch. It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v3 with all combinations of authenticity/privacy settings.</longdesc> ++<longdesc>fence_ipdu is a Power Fencing agent which can be used with the IBM iPDU network power switch. It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v3 with all combinations of authenticity/privacy settings.</longdesc> + <vendor-url>http://www.ibm.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index daad65a70..3107cad33 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilan is a Power Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ipmilanplus.xml b/tests/data/metadata/fence_ipmilanplus.xml +index 7b678b245..146d05a70 100644 +--- a/tests/data/metadata/fence_ipmilanplus.xml ++++ b/tests/data/metadata/fence_ipmilanplus.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilanplus is a Power Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ironic.xml b/tests/data/metadata/fence_ironic.xml +index 813b03732..f9bec38da 100644 +--- a/tests/data/metadata/fence_ironic.xml ++++ b/tests/data/metadata/fence_ironic.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ironic" shortdesc="Fence agent for OpenStack's Ironic (Bare Metal as a service) service" > +-<longdesc>fence_ironic is a Fencing agent which can be used with machines controlled by the Ironic service. This agent calls the openstack CLI. WARNING! This fence agent is not intended for production use. Relying on a functional ironic service for fencing is not a good design choice.</longdesc> ++<longdesc>fence_ironic is a Power Fencing agent which can be used with machines controlled by the Ironic service. This agent calls the openstack CLI. WARNING! This fence agent is not intended for production use. Relying on a functional ironic service for fencing is not a good design choice.</longdesc> + <vendor-url>https://wiki.openstack.org/wiki/Ironic</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_kubevirt.xml b/tests/data/metadata/fence_kubevirt.xml +index e6b42aa55..2850c3434 100644 +--- a/tests/data/metadata/fence_kubevirt.xml ++++ b/tests/data/metadata/fence_kubevirt.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_kubevirt" shortdesc="Fence agent for KubeVirt" > +-<longdesc>fence_kubevirt is an I/O Fencing agent for KubeVirt.</longdesc> ++<longdesc>fence_kubevirt is a Power Fencing agent for KubeVirt.</longdesc> + <vendor-url>https://kubevirt.io/</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ldom.xml b/tests/data/metadata/fence_ldom.xml +index 59facad6f..aaa737015 100644 +--- a/tests/data/metadata/fence_ldom.xml ++++ b/tests/data/metadata/fence_ldom.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ldom" shortdesc="Fence agent for Sun LDOM" > +-<longdesc>fence_ldom is an I/O Fencing agent which can be used with LDoms virtual machines. This agent works so, that run ldm command on host machine. So ldm must be directly runnable. ++<longdesc>fence_ldom is a Power Fencing agent which can be used with LDoms virtual machines. This agent works so, that run ldm command on host machine. So ldm must be directly runnable. + + Very useful parameter is -c (or cmd_prompt in stdin mode). This must be set to something, what is displayed after successful login to host machine. Default string is space on end of string (default for root in bash). But (for example) csh use ], so in that case you must use parameter -c with argument ]. Very similar situation is, if you use bash and login to host machine with other user than root. Than prompt is $, so again, you must use parameter -c.</longdesc> + <vendor-url>http://www.sun.com</vendor-url> +diff --git a/tests/data/metadata/fence_lindypdu.xml b/tests/data/metadata/fence_lindypdu.xml +index 56f81f4cb..79be15a8f 100644 +--- a/tests/data/metadata/fence_lindypdu.xml ++++ b/tests/data/metadata/fence_lindypdu.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_lindypdu" shortdesc="Fence agent for Lindy over SNMP" > +-<longdesc>fence_lindypdu is an I/O Fencing agent which can be used with the Lindy PDU network power switch. It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1 with all combinations of authenticity/privacy settings.</longdesc> ++<longdesc>fence_lindypdu is a Power Fencing agent which can be used with the Lindy PDU network power switch. It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1 with all combinations of authenticity/privacy settings.</longdesc> + <vendor-url>http://www.lindy.co.uk</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_lpar.xml b/tests/data/metadata/fence_lpar.xml +index 22f12dc23..018409e26 100644 +--- a/tests/data/metadata/fence_lpar.xml ++++ b/tests/data/metadata/fence_lpar.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_lpar" shortdesc="Fence agent for IBM LPAR" > +-<longdesc></longdesc> ++<longdesc>fence_lpar is a Power Fencing agent for IBM LPAR.</longdesc> + <vendor-url>http://www.ibm.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +index 262956dca..b36fab96e 100644 +--- a/tests/data/metadata/fence_mpath.xml ++++ b/tests/data/metadata/fence_mpath.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_mpath" shortdesc="Fence agent for multipath persistent reservation" > +-<longdesc>fence_mpath is an I/O fencing agent that uses SCSI-3 persistent reservations to control access multipath devices. Underlying devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand. ++<longdesc>fence_mpath is an I/O Fencing agent that uses SCSI-3 persistent reservations to control access multipath devices. Underlying devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand. + The fence_mpath agent works by having a unique key for each node that has to be set in /etc/multipath.conf. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_mpath agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. + + When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and verbose=yes parameters in /etc/sysconfig/stonith if you have issues with it failing.</longdesc> +diff --git a/tests/data/metadata/fence_netio.xml b/tests/data/metadata/fence_netio.xml +index 95f3cf34a..c1486c955 100644 +--- a/tests/data/metadata/fence_netio.xml ++++ b/tests/data/metadata/fence_netio.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> +-<resource-agent name="fence_netio" shortdesc="I/O Fencing agent for Koukaam NETIO-230B" > +-<longdesc>fence_netio is an I/O Fencing agent which can be used with the Koukaam NETIO-230B Power Distribution Unit. It logs into device via telnet and reboots a specified outlet. Lengthy telnet connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> ++<resource-agent name="fence_netio" shortdesc="Power Fencing agent for Koukaam NETIO-230B" > ++<longdesc>fence_netio is a Power Fencing agent which can be used with the Koukaam NETIO-230B Power Distribution Unit. It logs into device via telnet and reboots a specified outlet. Lengthy telnet connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> + <vendor-url>http://www.koukaam.se/</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_openstack.xml b/tests/data/metadata/fence_openstack.xml +index 0bf1a78e2..5eeaee018 100644 +--- a/tests/data/metadata/fence_openstack.xml ++++ b/tests/data/metadata/fence_openstack.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_openstack" shortdesc="Fence agent for OpenStack's Nova service" > +-<longdesc>fence_openstack is a Fencing agent which can be used with machines controlled by the Openstack's Nova service. This agent calls the python-novaclient and it is mandatory to be installed </longdesc> ++<longdesc>fence_openstack is a Power Fencing agent which can be used with machines controlled by the Openstack's Nova service. This agent calls the python-novaclient and it is mandatory to be installed </longdesc> + <vendor-url>https://wiki.openstack.org/wiki/Nova</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ovh.xml b/tests/data/metadata/fence_ovh.xml +index 79d5eda94..f369f46ca 100644 +--- a/tests/data/metadata/fence_ovh.xml ++++ b/tests/data/metadata/fence_ovh.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_ovh" shortdesc="Fence agent for OVH" > +-<longdesc>fence_ovh is an Power Fencing agent which can be used within OVH datecentre. Poweroff is simulated with a reboot into rescue-pro mode.</longdesc> ++<longdesc>fence_ovh is a Power Fencing agent which can be used within OVH datecentre. Poweroff is simulated with a reboot into rescue-pro mode.</longdesc> + <vendor-url>http://www.ovh.net</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_powerman.xml b/tests/data/metadata/fence_powerman.xml +index 10514fd3c..09d0b2bae 100644 +--- a/tests/data/metadata/fence_powerman.xml ++++ b/tests/data/metadata/fence_powerman.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_powerman" shortdesc="Fence Agent for Powerman" > +-<longdesc>This is a Pacemaker Fence Agent for the Powerman management utility that was designed for LLNL systems.</longdesc> ++<longdesc>fence_powerman is a Power Fence Agent for the Powerman management utility that was designed for LLNL systems.</longdesc> + <vendor-url>https://github.com/chaos/powerman</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_pve.xml b/tests/data/metadata/fence_pve.xml +index 1ed3cda4f..1aeebfe3f 100644 +--- a/tests/data/metadata/fence_pve.xml ++++ b/tests/data/metadata/fence_pve.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_pve" shortdesc="Fencing agent for the Proxmox Virtual Environment" > +-<longdesc>The fence_pve agent can be used to fence virtual machines acting as nodes in a virtualized cluster.</longdesc> ++<longdesc>fence_pve is a Power Fencing agent for virtual machines acting as nodes in a virtualized cluster.</longdesc> + <vendor-url>http://www.proxmox.com/</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_raritan.xml b/tests/data/metadata/fence_raritan.xml +index 5e387c784..00bfadb7a 100644 +--- a/tests/data/metadata/fence_raritan.xml ++++ b/tests/data/metadata/fence_raritan.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> +-<resource-agent name="fence_raritan" shortdesc="I/O Fencing agent for Raritan Dominion PX" > +-<longdesc>fence_raritan is an I/O Fencing agent which can be used with the Raritan DPXS12-20 Power Distribution Unit. It logs into device via telnet and reboots a specified outlet. Lengthy telnet connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> ++<resource-agent name="fence_raritan" shortdesc="Power Fencing agent for Raritan Dominion PX" > ++<longdesc>fence_raritan is a Power Fencing agent which can be used with the Raritan DPXS12-20 Power Distribution Unit. It logs into device via telnet and reboots a specified outlet. Lengthy telnet connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> + <vendor-url>http://www.raritan.com/</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_rcd_serial.xml b/tests/data/metadata/fence_rcd_serial.xml +index c14d342f7..030696efe 100644 +--- a/tests/data/metadata/fence_rcd_serial.xml ++++ b/tests/data/metadata/fence_rcd_serial.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_rcd_serial" shortdesc="rcd_serial fence agent" > +-<longdesc>fence_rcd_serial operates a serial cable that toggles a reset of an opposing server using the reset switch on its motherboard. The cable itself is simple with no power, network or moving parts. An example of the cable is available here: https://smcleod.net/rcd-stonith/ and the circuit design is available in the fence-agents src as SVG</longdesc> ++<longdesc>fence_rcd_serial is a Power Fencing agent that operates a serial cable that toggles a reset of an opposing server using the reset switch on its motherboard. The cable itself is simple with no power, network or moving parts. An example of the cable is available here: https://smcleod.net/rcd-stonith/ and the circuit design is available in the fence-agents src as SVG</longdesc> + <vendor-url>https://github.com/sammcj/fence_rcd_serial</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_redfish.xml b/tests/data/metadata/fence_redfish.xml +index 76a23af30..3285f77c4 100644 +--- a/tests/data/metadata/fence_redfish.xml ++++ b/tests/data/metadata/fence_redfish.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> +-<resource-agent name="fence_redfish" shortdesc="I/O Fencing agent for Redfish" > +-<longdesc>fence_redfish is an I/O Fencing agent which can be used with Out-of-Band controllers that support Redfish APIs. These controllers provide remote access to control power on a server.</longdesc> ++<resource-agent name="fence_redfish" shortdesc="Power Fencing agent for Redfish" > ++<longdesc>fence_redfish is a Power Fencing agent which can be used with Out-of-Band controllers that support Redfish APIs. These controllers provide remote access to control power on a server.</longdesc> + <vendor-url>http://www.dmtf.org</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +index 0b2239931..a51be18eb 100644 +--- a/tests/data/metadata/fence_rhevm.xml ++++ b/tests/data/metadata/fence_rhevm.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_rhevm" shortdesc="Fence agent for RHEV-M REST API" > +-<longdesc>fence_rhevm is an I/O Fencing agent which can be used with RHEV-M REST API to fence virtual machines.</longdesc> ++<longdesc>fence_rhevm is a Power Fencing agent which can be used with RHEV-M REST API to fence virtual machines.</longdesc> + <vendor-url>http://www.redhat.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml +index 284f9184d..8563d5005 100644 +--- a/tests/data/metadata/fence_rsa.xml ++++ b/tests/data/metadata/fence_rsa.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_rsa" shortdesc="Fence agent for IBM RSA" > +-<longdesc>fence_rsa is an I/O Fencing agent which can be used with the IBM RSA II management interface. It logs into an RSA II device via telnet and reboots the associated machine. Lengthy telnet connections to the RSA II device should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> ++<longdesc>fence_rsa is a Power Fencing agent which can be used with the IBM RSA II management interface. It logs into an RSA II device via telnet and reboots the associated machine. Lengthy telnet connections to the RSA II device should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> + <vendor-url>http://www.ibm.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml +index e3d6e1096..ca42ff435 100644 +--- a/tests/data/metadata/fence_rsb.xml ++++ b/tests/data/metadata/fence_rsb.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> +-<resource-agent name="fence_rsb" shortdesc="I/O Fencing agent for Fujitsu-Siemens RSB" > +-<longdesc>fence_rsb is an I/O Fencing agent which can be used with the Fujitsu-Siemens RSB management interface. It logs into device via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> ++<resource-agent name="fence_rsb" shortdesc="Power Fencing agent for Fujitsu-Siemens RSB" > ++<longdesc>fence_rsb is a Power Fencing agent which can be used with the Fujitsu-Siemens RSB management interface. It logs into device via telnet/ssh and reboots a specified outlet. Lengthy telnet/ssh connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> + <vendor-url>http://www.fujitsu.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_sbd.xml b/tests/data/metadata/fence_sbd.xml +index d5600b7ce..82ded25b9 100644 +--- a/tests/data/metadata/fence_sbd.xml ++++ b/tests/data/metadata/fence_sbd.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_sbd" shortdesc="Fence agent for sbd" > +-<longdesc>fence_sbd is I/O Fencing agent which can be used in environments where sbd can be used (shared storage).</longdesc> ++<longdesc>fence_sbd is an I/O Fencing agent which can be used in environments where sbd can be used (shared storage).</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +index facb2f52e..b963fd772 100644 +--- a/tests/data/metadata/fence_scsi.xml ++++ b/tests/data/metadata/fence_scsi.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_scsi" shortdesc="Fence agent for SCSI persistent reservation" > +-<longdesc>fence_scsi is an I/O fencing agent that uses SCSI-3 persistent reservations to control access to shared storage devices. These devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand. ++<longdesc>fence_scsi is an I/O Fencing agent that uses SCSI-3 persistent reservations to control access to shared storage devices. These devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand. + The fence_scsi agent works by having each node in the cluster register a unique key with the SCSI device(s). Reservation key is generated from "node id" (default) or from "node name hash" (RECOMMENDED) by adjusting "key_value" option. Using hash is recommended to prevent issues when removing nodes from cluster without full cluster restart. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_scsi agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to the device(s). A manual reboot is required. + + When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and verbose=yes parameters in /etc/sysconfig/stonith if you have issues with it failing.</longdesc> +diff --git a/tests/data/metadata/fence_skalar.xml b/tests/data/metadata/fence_skalar.xml +index 84f3f4ea6..5ce022b32 100644 +--- a/tests/data/metadata/fence_skalar.xml ++++ b/tests/data/metadata/fence_skalar.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_skalar" shortdesc="Skala-R Fence agent" > +-<longdesc>A fence agent for Skala-R.</longdesc> ++<longdesc>fence_skalar is a Power Fencing agent for Skala-R.</longdesc> + <vendor-url>https://www.skala-r.ru/</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_tripplite_snmp.xml b/tests/data/metadata/fence_tripplite_snmp.xml +index c5f66d56f..418832f9c 100644 +--- a/tests/data/metadata/fence_tripplite_snmp.xml ++++ b/tests/data/metadata/fence_tripplite_snmp.xml +@@ -1,7 +1,7 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_tripplite_snmp" shortdesc="Fence agent for APC, Tripplite PDU over SNMP" > + <symlink name="fence_tripplite_snmp" shortdesc="Fence agent for Tripplife over SNMP"/> +-<longdesc>fence_apc_snmp is an I/O Fencing agent which can be used with the APC network power switch or Tripplite PDU devices.It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1, v2c, v3 with all combinations of authenticity/privacy settings.</longdesc> ++<longdesc>fence_tripplite_snmp is a Power Fencing agent which can be used with the APC network power switch or Tripplite PDU devices.It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1, v2c, v3 with all combinations of authenticity/privacy settings.</longdesc> + <vendor-url>http://www.apc.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_vbox.xml b/tests/data/metadata/fence_vbox.xml +index 35577a6b6..347f04c7e 100644 +--- a/tests/data/metadata/fence_vbox.xml ++++ b/tests/data/metadata/fence_vbox.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_vbox" shortdesc="Fence agent for VirtualBox" > +-<longdesc>fence_vbox is an I/O Fencing agent which can be used with the virtual machines managed by VirtualBox. It logs via ssh to a dom0 where it runs VBoxManage to do all of the work. ++<longdesc>fence_vbox is a Power Fencing agent which can be used with the virtual machines managed by VirtualBox. It logs via ssh to a dom0 where it runs VBoxManage to do all of the work. + + By default, vbox needs to log in as a user that is a member of the vboxusers group. Also, you must allow ssh login in your sshd_config.</longdesc> + <vendor-url>https://www.virtualbox.org/</vendor-url> +diff --git a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml +index 82fe9b6d1..dc36693fc 100644 +--- a/tests/data/metadata/fence_virsh.xml ++++ b/tests/data/metadata/fence_virsh.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_virsh" shortdesc="Fence agent for virsh" > +-<longdesc>fence_virsh is an I/O Fencing agent which can be used with the virtual machines managed by libvirt. It logs via ssh to a dom0 and there run virsh command, which does all work. ++<longdesc>fence_virsh is a Power Fencing agent which can be used with the virtual machines managed by libvirt. It logs via ssh to a dom0 and there run virsh command, which does all work. + + By default, virsh needs root account to do properly work. So you must allow ssh login in your sshd_config.</longdesc> + <vendor-url>http://libvirt.org</vendor-url> +diff --git a/tests/data/metadata/fence_virt.xml b/tests/data/metadata/fence_virt.xml +index 612d4d3cb..eec67ad8c 100644 +--- a/tests/data/metadata/fence_virt.xml ++++ b/tests/data/metadata/fence_virt.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_virt" shortdesc="Fence agent for virtual machines"> +-<longdesc>fence_virt is an I/O Fencing agent which can be used with virtual machines. ++<longdesc>fence_virt is a Power Fencing agent which can be used with virtual machines. + + NOTE: reboot-action does not power on nodes that are powered off.</longdesc> + <vendor-url>https://libvirt.org</vendor-url> +diff --git a/tests/data/metadata/fence_vmware.xml b/tests/data/metadata/fence_vmware.xml +index a46ffdb0f..a5fad2fd5 100644 +--- a/tests/data/metadata/fence_vmware.xml ++++ b/tests/data/metadata/fence_vmware.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_vmware" shortdesc="Fence agent for VMWare" > +-<longdesc>fence_vmware is an I/O Fencing agent which can be used with the VMware ESX, VMware ESXi or VMware Server to fence virtual machines. ++<longdesc>fence_vmware is a Power Fencing agent which can be used with the VMware ESX, VMware ESXi or VMware Server to fence virtual machines. + + Before you can use this agent, it must be installed VI Perl Toolkit or vmrun command on every node you want to make fencing. + +diff --git a/tests/data/metadata/fence_vmware_rest.xml b/tests/data/metadata/fence_vmware_rest.xml +index 5c69c2f21..672769d99 100644 +--- a/tests/data/metadata/fence_vmware_rest.xml ++++ b/tests/data/metadata/fence_vmware_rest.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_vmware_rest" shortdesc="Fence agent for VMware REST API" > +-<longdesc>fence_vmware_rest is an I/O Fencing agent which can be used with VMware API to fence virtual machines. ++<longdesc>fence_vmware_rest is a Power Fencing agent which can be used with VMware API to fence virtual machines. + + NOTE: If there's more than 1000 VMs there is a filter parameter to work around the API limit. See https://code.vmware.com/apis/62/vcenter-management#/VM%20/get_vcenter_vm for full list of filters.</longdesc> + <vendor-url>https://www.vmware.com</vendor-url> +diff --git a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml +index 72b27e351..5d5ff36e4 100644 +--- a/tests/data/metadata/fence_vmware_soap.xml ++++ b/tests/data/metadata/fence_vmware_soap.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_vmware_soap" shortdesc="Fence agent for VMWare over SOAP API" > +-<longdesc>fence_vmware_soap is an I/O Fencing agent which can be used with the virtual machines managed by VMWare products that have SOAP API v4.1+. ++<longdesc>fence_vmware_soap is a Power Fencing agent which can be used with the virtual machines managed by VMWare products that have SOAP API v4.1+. + + Name of virtual machine (-n / port) has to be used in inventory path format (e.g. /datacenter/vm/Discovered virtual machine/myMachine). In the cases when name of yours VM is unique you can use it instead. Alternatively you can always use UUID to access virtual machine.</longdesc> + <vendor-url>http://www.vmware.com</vendor-url> +diff --git a/tests/data/metadata/fence_vmware_vcloud.xml b/tests/data/metadata/fence_vmware_vcloud.xml +index 3c8bb74a3..c017daf5a 100644 +--- a/tests/data/metadata/fence_vmware_vcloud.xml ++++ b/tests/data/metadata/fence_vmware_vcloud.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_vmware_vcloud" shortdesc="Fence agent for VMware vCloud Director API" > +-<longdesc>fence_vmware_vcloud is an I/O Fencing agent which can be used with VMware vCloud Director API to fence virtual machines.</longdesc> ++<longdesc>fence_vmware_vcloud is a Power Fencing agent which can be used with VMware vCloud Director API to fence virtual machines.</longdesc> + <vendor-url>https://www.vmware.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_wti.xml b/tests/data/metadata/fence_wti.xml +index b9eb9c6bc..72e6d17f7 100644 +--- a/tests/data/metadata/fence_wti.xml ++++ b/tests/data/metadata/fence_wti.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_wti" shortdesc="Fence agent for WTI" > +-<longdesc>fence_wti is an I/O Fencing agent which can be used with the WTI Network Power Switch (NPS). It logs into an NPS via telnet or ssh and boots a specified plug. Lengthy telnet connections to the NPS should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> ++<longdesc>fence_wti is a Power Fencing agent which can be used with the WTI Network Power Switch (NPS). It logs into an NPS via telnet or ssh and boots a specified plug. Lengthy telnet connections to the NPS should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc> + <vendor-url>http://www.wti.com</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_xenapi.xml b/tests/data/metadata/fence_xenapi.xml +index 380ac28da..c61d465f1 100644 +--- a/tests/data/metadata/fence_xenapi.xml ++++ b/tests/data/metadata/fence_xenapi.xml +@@ -1,6 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_xenapi" shortdesc="Fence agent for Citrix XenServer over XenAPI" > +-<longdesc>fence_cxs is an I/O Fencing agent used on Citrix XenServer hosts. It uses the XenAPI, supplied by Citrix, to establish an XML-RPC session to a XenServer host. Once the session is established, further XML-RPC commands are issued in order to switch on, switch off, restart and query the status of virtual machines running on the host.</longdesc> ++<longdesc>fence_xenapi is a Power Fencing agent used on Citrix XenServer hosts. It uses the XenAPI, supplied by Citrix, to establish an XML-RPC session to a XenServer host. Once the session is established, further XML-RPC commands are issued in order to switch on, switch off, restart and query the status of virtual machines running on the host.</longdesc> + <vendor-url>http://www.xenproject.org</vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index 96393bdfa..67104386e 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -1,7 +1,6 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_zvmip" shortdesc="Fence agent for use with z/VM Virtual Machines" > +-<longdesc>The fence_zvmip agent is intended to be used with the +-z/VM SMAPI service via TCP/IP. ++<longdesc>fence_zvmip is a Power Fencing agent for z/VM SMAPI service via TCP/IP. + + 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, diff --git a/RHEL-14030-2-fence_cisco_mds-undo-metadata-change.patch b/RHEL-14030-2-fence_cisco_mds-undo-metadata-change.patch new file mode 100644 index 0000000..a80b818 --- /dev/null +++ b/RHEL-14030-2-fence_cisco_mds-undo-metadata-change.patch @@ -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"> diff --git a/RHEL-14344-fence_zvmip-1-document-user-permissions.patch b/RHEL-14344-fence_zvmip-1-document-user-permissions.patch new file mode 100644 index 0000000..95c6b53 --- /dev/null +++ b/RHEL-14344-fence_zvmip-1-document-user-permissions.patch @@ -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> diff --git a/RHEL-14344-fence_zvmip-2-fix-manpage-formatting.patch b/RHEL-14344-fence_zvmip-2-fix-manpage-formatting.patch new file mode 100644 index 0000000..e650b0f --- /dev/null +++ b/RHEL-14344-fence_zvmip-2-fix-manpage-formatting.patch @@ -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 diff --git a/RHEL-25256-fence_vmware_rest-detect-user-sufficient-rights.patch b/RHEL-25256-fence_vmware_rest-detect-user-sufficient-rights.patch new file mode 100644 index 0000000..5f2027a --- /dev/null +++ b/RHEL-25256-fence_vmware_rest-detect-user-sufficient-rights.patch @@ -0,0 +1,26 @@ +From fc7d7c4baef64f510bd3332c9f008d3e1128dc7b Mon Sep 17 00:00:00 2001 +From: Peter Varkoly <varkoly@suse.com> +Date: Sun, 11 Feb 2024 09:13:51 +0100 +Subject: [PATCH] fence_vmware_rest : monitoring is not detecting if the API + user has sufficient right to manage the fence device. The call + https://{api_host}/api/vcenter/vm is subject to permission checks. If the + delivered list is empty the user has no rights. + +--- + agents/vmware_rest/fence_vmware_rest.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py +index 378771863..9dc9a12f4 100644 +--- a/agents/vmware_rest/fence_vmware_rest.py ++++ b/agents/vmware_rest/fence_vmware_rest.py +@@ -60,6 +60,9 @@ def get_list(conn, options): + else: + fail(EC_STATUS) + ++ if options.get("--original-action") == "monitor" and not res["value"]: ++ logging.error("API user does not have sufficient rights to manage the power status.") ++ fail(EC_STATUS) + for r in res["value"]: + outlets[r["name"]] = ("", state[r["power_state"]]) + diff --git a/RHEL-31488-RHEL-31485-RHEL-31483-fence_aliyun-update.patch b/RHEL-31488-RHEL-31485-RHEL-31483-fence_aliyun-update.patch new file mode 100644 index 0000000..b9bb334 --- /dev/null +++ b/RHEL-31488-RHEL-31485-RHEL-31483-fence_aliyun-update.patch @@ -0,0 +1,209 @@ +--- a/agents/aliyun/fence_aliyun.py 2024-04-04 10:22:53.720906183 +0200 ++++ b/agents/aliyun/fence_aliyun.py 2024-04-04 10:21:47.626425090 +0200 +@@ -1,53 +1,67 @@ + #!@PYTHON@ -tt + +-import sys, re ++import sys + import logging + import atexit + import json ++ + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +-from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay ++from fencing import fail_usage, run_delay ++ + + try: + sys.path.insert(0, '/usr/lib/fence-agents/support/aliyun') + from aliyunsdkcore import client + from aliyunsdkcore.auth.credentials import EcsRamRoleCredential ++ from aliyunsdkcore.profile import region_provider ++except ImportError as e: ++ logging.warn("The 'aliyunsdkcore' module has been not installed or is unavailable, try to execute the command 'pip install aliyun-python-sdk-core --upgrade' to solve. error: %s" % e) ++ ++ ++try: + from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest + from aliyunsdkecs.request.v20140526.StartInstanceRequest import StartInstanceRequest + from aliyunsdkecs.request.v20140526.StopInstanceRequest import StopInstanceRequest + from aliyunsdkecs.request.v20140526.RebootInstanceRequest import RebootInstanceRequest +- from aliyunsdkcore.profile import region_provider +-except ImportError: +- pass ++except ImportError as e: ++ logging.warn("The 'aliyunsdkecs' module has been not installed or is unavailable, try to execute the command 'pip install aliyun-python-sdk-ecs --upgrade' to solve. error: %s" % e) ++ + + def _send_request(conn, request): ++ logging.debug("send request action: %s" % request.get_action_name()) + request.set_accept_format('json') + try: + response_str = conn.do_action_with_exception(request) +- response_detail = json.loads(response_str) +- logging.debug("_send_request reponse: %s" % response_detail) +- return response_detail + except Exception as e: +- fail_usage("Failed: _send_request failed: %s" % e) ++ fail_usage("Failed: send request failed: Error: %s" % e) ++ ++ response_detail = json.loads(response_str) ++ logging.debug("reponse: %s" % response_detail) ++ return response_detail + + def start_instance(conn, instance_id): ++ logging.debug("start instance %s" % instance_id) + request = StartInstanceRequest() + request.set_InstanceId(instance_id) + _send_request(conn, request) + + def stop_instance(conn, instance_id): ++ logging.debug("stop instance %s" % instance_id) + request = StopInstanceRequest() + request.set_InstanceId(instance_id) + request.set_ForceStop('true') + _send_request(conn, request) + + def reboot_instance(conn, instance_id): ++ logging.debug("reboot instance %s" % instance_id) + request = RebootInstanceRequest() + request.set_InstanceId(instance_id) + request.set_ForceStop('true') + _send_request(conn, request) + + def get_status(conn, instance_id): ++ logging.debug("get instance %s status" % instance_id) + request = DescribeInstancesRequest() + request.set_InstanceIds(json.dumps([instance_id])) + response = _send_request(conn, request) +@@ -59,20 +73,30 @@ + return instance_status + + def get_nodes_list(conn, options): ++ logging.debug("start to get nodes list") + result = {} + request = DescribeInstancesRequest() + request.set_PageSize(100) ++ ++ if "--filter" in options: ++ filter_key = options["--filter"].split("=")[0].strip() ++ filter_value = options["--filter"].split("=")[1].strip() ++ params = request.get_query_params() ++ params[filter_key] = filter_value ++ request.set_query_params(params) ++ + response = _send_request(conn, request) +- instance_status = None + if response is not None: + instance_list = response.get('Instances').get('Instance') + for item in instance_list: + instance_id = item.get('InstanceId') + instance_name = item.get('InstanceName') + result[instance_id] = (instance_name, None) ++ logging.debug("get nodes list: %s" % result) + return result + + def get_power_status(conn, options): ++ logging.debug("start to get power(%s) status" % options["--plug"]) + state = get_status(conn, options["--plug"]) + + if state == "Running": +@@ -81,14 +105,11 @@ + status = "off" + else: + status = "unknown" +- +- logging.info("get_power_status: %s" % status) +- ++ logging.debug("the power(%s) status is %s" % (options["--plug"], status)) + return status + +- + def set_power_status(conn, options): +- logging.info("set_power_status: %s" % options["--action"]) ++ logging.info("start to set power(%s) status to %s" % (options["--plug"], options["--action"])) + + if (options["--action"]=="off"): + stop_instance(conn, options["--plug"]) +@@ -97,7 +118,6 @@ + elif (options["--action"]=="reboot"): + reboot_instance(conn, options["--plug"]) + +- + def define_new_opts(): + all_opt["region"] = { + "getopt" : "r:", +@@ -126,17 +146,42 @@ + all_opt["ram_role"] = { + "getopt": ":", + "longopt": "ram-role", +- "help": "--ram-role=[name] Ram Role", ++ "help": "--ram-role=[name] Ram Role", + "shortdesc": "Ram Role.", + "required": "0", + "order": 5 + } ++ all_opt["credentials_file"] = { ++ "getopt": ":", ++ "longopt": "credentials-file", ++ "help": "--credentials-file=[path] Path to aliyun-cli credentials file", ++ "shortdesc": "Path to credentials file", ++ "required": "0", ++ "order": 6 ++ } ++ all_opt["credentials_file_profile"] = { ++ "getopt": ":", ++ "longopt": "credentials-file-profile", ++ "help": "--credentials-file-profile=[profile] Credentials file profile", ++ "shortdesc": "Credentials file profile", ++ "required": "0", ++ "default": "default", ++ "order": 7 ++ } ++ all_opt["filter"] = { ++ "getopt": ":", ++ "longopt": "filter", ++ "help": "--filter=[key=value] Filter (e.g. InstanceIds=[\"i-XXYYZZAA1\",\"i-XXYYZZAA2\"]", ++ "shortdesc": "Filter for list-action.", ++ "required": "0", ++ "order": 8 ++ } + + # Main agent method + def main(): + conn = None + +- device_opt = ["port", "no_password", "region", "access_key", "secret_key", "ram_role"] ++ device_opt = ["port", "no_password", "region", "access_key", "secret_key", "ram_role", "credentials_file", "credentials_file_profile", "filter"] + + atexit.register(atexit_handler) + +@@ -164,8 +209,25 @@ + ram_role = options["--ram-role"] + role = EcsRamRoleCredential(ram_role) + conn = client.AcsClient(region_id=region, credential=role) +- region_provider.modify_point('Ecs', region, 'ecs.%s.aliyuncs.com' % region) +- ++ elif "--credentials-file" in options and "--credentials-file-profile" in options: ++ import os, configparser ++ try: ++ config = configparser.ConfigParser() ++ config.read(os.path.expanduser(options["--credentials-file"])) ++ access_key = config.get(options["--credentials-file-profile"], "aliyun_access_key_id") ++ secret_key = config.get(options["--credentials-file-profile"], "aliyun_access_key_secret") ++ conn = client.AcsClient(access_key, secret_key, region) ++ except Exception as e: ++ fail_usage("Failed: failed to read credentials file: %s" % e) ++ else: ++ fail_usage("Failed: User credentials are not set. Please set the Access Key and the Secret Key, or configure the RAM role.") ++ ++ # Use intranet endpoint to access ECS service ++ try: ++ region_provider.modify_point('Ecs', region, 'ecs.%s.aliyuncs.com' % region) ++ except Exception as e: ++ logging.warn("Failed: failed to modify endpoint to 'ecs.%s.aliyuncs.com': %s" % (region, e)) ++ + # Operate the fencing device + result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list) + sys.exit(result) diff --git a/RHEL-35263-fence_eps-add-fence_epsr2-for-ePowerSwitch-R2-and-newer.patch b/RHEL-35263-fence_eps-add-fence_epsr2-for-ePowerSwitch-R2-and-newer.patch new file mode 100644 index 0000000..4086e43 --- /dev/null +++ b/RHEL-35263-fence_eps-add-fence_epsr2-for-ePowerSwitch-R2-and-newer.patch @@ -0,0 +1,380 @@ +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/fence-agents.spec.in b/fence-agents.spec.in +index e139e6da5..5b8066122 100644 +--- a/fence-agents.spec.in ++++ b/fence-agents.spec.in +@@ -597,8 +597,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* + + %package gce + License: GPL-2.0-or-later AND LGPL-2.0-or-later +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> diff --git a/RHEL-35649-kubevirt-fix-bundled-jinja2-CVE-2024-34064.patch b/RHEL-35649-kubevirt-fix-bundled-jinja2-CVE-2024-34064.patch new file mode 100644 index 0000000..700ab80 --- /dev/null +++ b/RHEL-35649-kubevirt-fix-bundled-jinja2-CVE-2024-34064.patch @@ -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)}"') + diff --git a/RHEL-43235-fence_aws-1-list-add-instance-name-status.patch b/RHEL-43235-fence_aws-1-list-add-instance-name-status.patch new file mode 100644 index 0000000..0cf8961 --- /dev/null +++ b/RHEL-43235-fence_aws-1-list-add-instance-name-status.patch @@ -0,0 +1,99 @@ +From a4502b3bf15a3be2ebd64b6829cd4f6641f2506b Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Fri, 14 Jun 2024 15:28:28 +0200 +Subject: [PATCH 1/2] fencing: use formatted strings to avoid failing when plug + is int + +--- + lib/fencing.py.py | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/lib/fencing.py.py b/lib/fencing.py.py +index 66e2ff156..9c090100d 100644 +--- a/lib/fencing.py.py ++++ b/lib/fencing.py.py +@@ -985,9 +985,9 @@ + status = status.upper() + + if options["--action"] == "list": +- print(outlet_id + options["--separator"] + alias) ++ print("{}{}{}".format(outlet_id, options["--separator"], alias)) + elif options["--action"] == "list-status": +- print(outlet_id + options["--separator"] + alias + options["--separator"] + status) ++ print("{}{}{}{}{}".format(outlet_id, options["--separator"], alias, options["--separator"], status)) + + return + + +From f1ef26c885cdedb17eb366e4c8922ffb01aefc7c Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Fri, 14 Jun 2024 15:29:12 +0200 +Subject: [PATCH 2/2] fence_aws: improve list, list-status and status actions + +--- + agents/aws/fence_aws.py | 31 +++++++++++++++++++------------ + 1 file changed, 19 insertions(+), 12 deletions(-) + +diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py +index a9308dd9c..b8d38462e 100644 +--- a/agents/aws/fence_aws.py ++++ b/agents/aws/fence_aws.py +@@ -22,6 +22,15 @@ + logger.addHandler(SyslogLibHandler()) + logging.getLogger('botocore.vendored').propagate = False + ++status = { ++ "running": "on", ++ "stopped": "off", ++ "pending": "unknown", ++ "stopping": "unknown", ++ "shutting-down": "unknown", ++ "terminated": "unknown" ++} ++ + def get_instance_id(options): + try: + token = requests.put('http://169.254.169.254/latest/api/token', headers={"X-aws-ec2-metadata-token-ttl-seconds" : "21600"}).content.decode("UTF-8") +@@ -45,11 +54,14 @@ def get_nodes_list(conn, options): + filter_key = options["--filter"].split("=")[0].strip() + filter_value = options["--filter"].split("=")[1].strip() + filter = [{ "Name": filter_key, "Values": [filter_value] }] +- for instance in conn.instances.filter(Filters=filter): +- result[instance.id] = ("", None) +- else: +- for instance in conn.instances.all(): +- result[instance.id] = ("", None) ++ logging.debug("Filter: {}".format(filter)) ++ ++ for instance in conn.instances.filter(Filters=filter if 'filter' in vars() else []): ++ instance_name = "" ++ for tag in instance.tags or []: ++ if tag.get("Key") == "Name": ++ instance_name = tag["Value"] ++ result[instance.id] = (instance_name, status[instance.state["Name"]]) + except ClientError: + fail_usage("Failed: Incorrect Access Key or Secret Key.") + except EndpointConnectionError: +@@ -67,12 +79,7 @@ def get_power_status(conn, options): + instance = conn.instances.filter(Filters=[{"Name": "instance-id", "Values": [options["--plug"]]}]) + state = list(instance)[0].state["Name"] + logger.debug("Status operation for EC2 instance %s returned state: %s",options["--plug"],state.upper()) +- if state == "running": +- return "on" +- elif state == "stopped": +- return "off" +- else: +- return "unknown" ++ return status[state] + + except ClientError: + fail_usage("Failed: Incorrect Access Key or Secret Key.") +@@ -146,7 +153,7 @@ def define_new_opts(): + all_opt["filter"] = { + "getopt" : ":", + "longopt" : "filter", +- "help" : "--filter=[key=value] Filter (e.g. vpc-id=[vpc-XXYYZZAA]", ++ "help" : "--filter=[key=value] Filter (e.g. vpc-id=[vpc-XXYYZZAA])", + "shortdesc": "Filter for list-action", + "required": "0", + "order": 5 diff --git a/RHEL-43235-fence_aws-2-log-error-for-unknown-states.patch b/RHEL-43235-fence_aws-2-log-error-for-unknown-states.patch new file mode 100644 index 0000000..edc7d35 --- /dev/null +++ b/RHEL-43235-fence_aws-2-log-error-for-unknown-states.patch @@ -0,0 +1,41 @@ +From c2753c1882b5892b8b7a0fd093baded4a359b2a5 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 17 Jun 2024 11:19:12 +0200 +Subject: [PATCH] fence_aws: log error if unknown state returned + +--- + agents/aws/fence_aws.py | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py +index b8d38462e..5459a06c4 100644 +--- a/agents/aws/fence_aws.py ++++ b/agents/aws/fence_aws.py +@@ -61,7 +61,12 @@ def get_nodes_list(conn, options): + for tag in instance.tags or []: + if tag.get("Key") == "Name": + instance_name = tag["Value"] +- result[instance.id] = (instance_name, status[instance.state["Name"]]) ++ try: ++ result[instance.id] = (instance_name, status[instance.state["Name"]]) ++ except KeyError as e: ++ if options.get("--original-action") == "list-status": ++ logger.error("Unknown status \"{}\" returned for {} ({})".format(instance.state["Name"], instance.id, instance_name)) ++ result[instance.id] = (instance_name, "unknown") + except ClientError: + fail_usage("Failed: Incorrect Access Key or Secret Key.") + except EndpointConnectionError: +@@ -79,8 +84,11 @@ def get_power_status(conn, options): + instance = conn.instances.filter(Filters=[{"Name": "instance-id", "Values": [options["--plug"]]}]) + state = list(instance)[0].state["Name"] + logger.debug("Status operation for EC2 instance %s returned state: %s",options["--plug"],state.upper()) +- return status[state] +- ++ try: ++ return status[state] ++ except KeyError as e: ++ logger.error("Unknown status \"{}\" returned".format(state)) ++ return "unknown" + except ClientError: + fail_usage("Failed: Incorrect Access Key or Secret Key.") + except EndpointConnectionError: diff --git a/RHEL-43562-fix-bundled-urllib3-CVE-2024-37891.patch b/RHEL-43562-fix-bundled-urllib3-CVE-2024-37891.patch new file mode 100644 index 0000000..2c2de0e --- /dev/null +++ b/RHEL-43562-fix-bundled-urllib3-CVE-2024-37891.patch @@ -0,0 +1,96 @@ +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/awscli/urllib3/util/retry.py b/awscli/urllib3/util/retry.py +index 7a76a4a6ad..0456cceba4 100644 +--- a/awscli/urllib3/util/retry.py ++++ b/awscli/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 + +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 + +diff --git a/azure/urllib3/util/retry.py b/azure/urllib3/util/retry.py +index 7a76a4a6ad..0456cceba4 100644 +--- a/azure/urllib3/util/retry.py ++++ b/azure/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 + +diff --git a/google/urllib3/util/retry.py b/google/urllib3/util/retry.py +index 7a76a4a6ad..0456cceba4 100644 +--- a/google/urllib3/util/retry.py ++++ b/google/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 + +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 diff --git a/RHEL-5396-fence_scsi-1-fix-ISID-reg-handling.patch b/RHEL-5396-fence_scsi-1-fix-ISID-reg-handling.patch new file mode 100644 index 0000000..9641fd7 --- /dev/null +++ b/RHEL-5396-fence_scsi-1-fix-ISID-reg-handling.patch @@ -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)["rc"]) + + diff --git a/RHEL-5396-fence_scsi-2-fix-ISID-reg-handling-off.patch b/RHEL-5396-fence_scsi-2-fix-ISID-reg-handling-off.patch new file mode 100644 index 0000000..cfafaa7 --- /dev/null +++ b/RHEL-5396-fence_scsi-2-fix-ISID-reg-handling-off.patch @@ -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"]) + diff --git a/bundled-pexpect.patch b/bundled-pexpect.patch new file mode 100644 index 0000000..41f355d --- /dev/null +++ b/bundled-pexpect.patch @@ -0,0 +1,358 @@ +diff --color -uNr a/agents/azure_arm/fence_azure_arm.py b/agents/azure_arm/fence_azure_arm.py +--- a/agents/azure_arm/fence_azure_arm.py 2020-06-30 11:26:43.000000000 +0200 ++++ b/agents/azure_arm/fence_azure_arm.py 2021-06-03 13:16:16.547120822 +0200 +@@ -1,6 +1,11 @@ + #!@PYTHON@ -tt + +-import sys, re, pexpect ++import sys, re ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import logging + import atexit + import xml.etree.ElementTree as ET +diff --color -uNr a/agents/hpblade/fence_hpblade.py b/agents/hpblade/fence_hpblade.py +--- a/agents/hpblade/fence_hpblade.py 2019-08-16 10:55:11.000000000 +0200 ++++ b/agents/hpblade/fence_hpblade.py 2021-06-03 13:16:16.547120822 +0200 +@@ -8,7 +8,11 @@ + ##### + + import sys, re +-import pexpect ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +diff --color -uNr a/agents/ilo/fence_ilo.py b/agents/ilo/fence_ilo.py +--- a/agents/ilo/fence_ilo.py 2019-02-04 09:45:05.000000000 +0100 ++++ b/agents/ilo/fence_ilo.py 2021-06-03 13:16:16.547120822 +0200 +@@ -11,7 +11,12 @@ + ## iLO2 / firmware 1.50 / RIBCL 2.22 + ##### + +-import sys, re, pexpect ++import sys, re ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import atexit + from xml.sax.saxutils import quoteattr + sys.path.append("@FENCEAGENTSLIBDIR@") +diff --color -uNr a/agents/ldom/fence_ldom.py b/agents/ldom/fence_ldom.py +--- a/agents/ldom/fence_ldom.py 2019-02-04 09:45:05.000000000 +0100 ++++ b/agents/ldom/fence_ldom.py 2021-06-03 13:16:16.547120822 +0200 +@@ -7,7 +7,12 @@ + ## + ##### + +-import sys, re, pexpect ++import sys, re ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +diff --color -uNr a/agents/Makefile.am b/agents/Makefile.am +--- a/agents/Makefile.am 2021-03-16 12:26:37.000000000 +0100 ++++ b/agents/Makefile.am 2021-06-03 13:16:16.547120822 +0200 +@@ -112,10 +112,10 @@ + cisco_mds/fence_cisco_mds.delay-check: cisco_mds/fence_cisco_mds + $(eval INPUT=$(subst .delay-check,,$@)) + FENCE_TEST_ARGS_CISCO_MDS=$$(printf '$(FENCE_TEST_ARGS)' | sed 's#port=1#port=fc1/1#'); \ +- test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib /usr/bin/time -p \ ++ test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common /usr/bin/time -p \ + sh -c "printf 'delay=10\n $$FENCE_TEST_ARGS_CISCO_MDS' | $(PYTHON) ./$(INPUT)" 2>&1 |\ + awk -F"[. ]" -vOFS= '/real/ {print $$2,$$3}'` -ge 1000 || ( \ +- PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib /usr/bin/time -p \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common /usr/bin/time -p \ + sh -c "printf "delay=0\n $$FENCE_TEST_ARGS_CISCO_MDS" | $(PYTHON) ./$(INPUT)"; false ) + + include $(top_srcdir)/make/fencebuild.mk +diff --color -uNr a/agents/netio/fence_netio.py b/agents/netio/fence_netio.py +--- a/agents/netio/fence_netio.py 2019-02-04 09:45:05.000000000 +0100 ++++ b/agents/netio/fence_netio.py 2021-06-03 13:16:16.547120822 +0200 +@@ -1,6 +1,11 @@ + #!@PYTHON@ -tt + +-import sys, re, pexpect ++import sys, re ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +diff --color -uNr a/agents/raritan/fence_raritan.py b/agents/raritan/fence_raritan.py +--- a/agents/raritan/fence_raritan.py 2019-08-16 10:55:11.000000000 +0200 ++++ b/agents/raritan/fence_raritan.py 2021-06-03 13:16:16.547120822 +0200 +@@ -1,6 +1,11 @@ + #!@PYTHON@ -tt + +-import sys, re, pexpect ++import sys, re ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +diff --color -uNr a/agents/sanbox2/fence_sanbox2.py b/agents/sanbox2/fence_sanbox2.py +--- a/agents/sanbox2/fence_sanbox2.py 2019-02-11 13:05:48.000000000 +0100 ++++ b/agents/sanbox2/fence_sanbox2.py 2021-06-03 13:16:16.547120822 +0200 +@@ -8,7 +8,12 @@ + ## +-----------------+---------------------------+ + ##### + +-import sys, re, pexpect ++import sys, re ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import logging + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") +diff --color -uNr a/agents/vmware/fence_vmware.py b/agents/vmware/fence_vmware.py +--- a/agents/vmware/fence_vmware.py 2019-02-04 09:45:05.000000000 +0100 ++++ b/agents/vmware/fence_vmware.py 2021-06-03 13:16:16.547120822 +0200 +@@ -22,7 +22,12 @@ + # VMware vCenter 4.0.0 + # + +-import sys, re, pexpect ++import sys, re ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import logging + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") +diff --color -uNr a/agents/wti/fence_wti.py b/agents/wti/fence_wti.py +--- a/agents/wti/fence_wti.py 2019-02-04 09:45:05.000000000 +0100 ++++ b/agents/wti/fence_wti.py 2021-06-03 13:17:33.435380703 +0200 +@@ -11,12 +11,21 @@ + ## WTI IPS-800-CE v1.40h (no username) ('list' tested) + ##### + +-import sys, re, pexpect ++import sys, re ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass + import atexit + import time + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +-from fencing import fspawn, fail, fail_usage, EC_LOGIN_DENIED ++from fencing import fail, fail_usage, EC_LOGIN_DENIED ++try: ++ from fencing import fspawn ++except ImportError: ++ pass + + def get_listing(conn, options, listing_command): + listing = "" +diff --color -uNr a/lib/fencing.py.py b/lib/fencing.py.py +--- a/lib/fencing.py.py 2021-06-03 10:34:00.000000000 +0200 ++++ b/lib/fencing.py.py 2021-06-03 13:16:16.548120826 +0200 +@@ -1,7 +1,12 @@ + #!@PYTHON@ -tt + + import sys, getopt, time, os, uuid, pycurl, stat +-import pexpect, re, syslog ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass ++import re, syslog + import logging + import subprocess + import threading +@@ -491,29 +496,32 @@ + "snmpset_path", "snmpget_path", "snmpwalk_path"] + } + +-class fspawn(pexpect.spawn): +- def __init__(self, options, command, **kwargs): +- if sys.version_info[0] > 2: +- kwargs.setdefault('encoding', 'utf-8') +- logging.info("Running command: %s", command) +- pexpect.spawn.__init__(self, command, **kwargs) +- self.opt = options +- +- def log_expect(self, pattern, timeout): +- result = self.expect(pattern, timeout if timeout != 0 else None) +- logging.debug("Received: %s", self.before + self.after) +- return result +- +- def read_nonblocking(self, size, timeout): +- return pexpect.spawn.read_nonblocking(self, size=100, timeout=timeout if timeout != 0 else None) +- +- def send(self, message): +- logging.debug("Sent: %s", message) +- return pexpect.spawn.send(self, message) +- +- # send EOL according to what was detected in login process (telnet) +- def send_eol(self, message): +- return self.send(message + self.opt["eol"]) ++try: ++ class fspawn(pexpect.spawn): ++ def __init__(self, options, command, **kwargs): ++ if sys.version_info[0] > 2: ++ kwargs.setdefault('encoding', 'utf-8') ++ logging.info("Running command: %s", command) ++ pexpect.spawn.__init__(self, command, **kwargs) ++ self.opt = options ++ ++ def log_expect(self, pattern, timeout): ++ result = self.expect(pattern, timeout if timeout != 0 else None) ++ logging.debug("Received: %s", self.before + self.after) ++ return result ++ ++ def read_nonblocking(self, size, timeout): ++ return pexpect.spawn.read_nonblocking(self, size=100, timeout=timeout if timeout != 0 else None) ++ ++ def send(self, message): ++ logging.debug("Sent: %s", message) ++ return pexpect.spawn.send(self, message) ++ ++ # send EOL according to what was detected in login process (telnet) ++ def send_eol(self, message): ++ return self.send(message + self.opt["eol"]) ++except: ++ pass + + def frun(command, timeout=30, withexitstatus=False, events=None, + extra_args=None, logfile=None, cwd=None, env=None, **kwargs): +diff --color -uNr a/lib/fencing_snmp.py.py b/lib/fencing_snmp.py.py +--- a/lib/fencing_snmp.py.py 2019-02-04 09:45:05.000000000 +0100 ++++ b/lib/fencing_snmp.py.py 2021-06-03 13:16:16.548120826 +0200 +@@ -2,7 +2,13 @@ + + # For example of use please see fence_cisco_mds + +-import re, pexpect ++import sys ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++try: ++ import pexpect ++except: ++ pass ++import re + import logging + from fencing import * + from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay, frun +diff --color -uNr a/make/agentpycheck.mk b/make/agentpycheck.mk +--- a/make/agentpycheck.mk 2020-06-30 11:26:43.000000000 +0200 ++++ b/make/agentpycheck.mk 2021-06-03 13:16:16.548120826 +0200 +@@ -9,34 +9,34 @@ + + %.xml-check: %.8 + $(eval INPUT=$(subst .xml-check,,$(@F))) +- for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ + TEMPFILE=$$(mktemp); \ +- PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $$TEMPFILE && \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $$TEMPFILE && \ + diff $$TEMPFILE $(DATADIR)/$$x.xml || exit 1 && \ + rm $$TEMPFILE; \ + done + + %.xml-upload: %.8 + $(eval INPUT=$(subst .xml-upload,,$(@F))) +- for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ +- PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $(DATADIR)/$$x.xml; \ ++ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $(DATADIR)/$$x.xml; \ + done + + # If test will fail, rerun fence agents to show problems + %.delay-check: % + $(eval INPUT=$(subst .delay-check,,$(@F))) +- for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ +- test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib /usr/bin/time -p \ ++ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common /usr/bin/time -p \ + sh -c "printf 'delay=10\n $(FENCE_TEST_ARGS)' | $(PYTHON) $(@D)/$$x" 2>&1 |\ + awk -F"[. ]" -vOFS= '/real/ {print $$2,$$3}'` -ge 1000 || ( \ +- PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib /usr/bin/time -p \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common /usr/bin/time -p \ + sh -c "printf 'delay=0\n $(FENCE_TEST_ARGS)' | $(PYTHON) $(@D)/$$x"; false ); \ + done + + %.rng-check: % + $(eval INPUT=$(subst .rng-check,,$(@F))) +- for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ +- PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$$x -o metadata | \ ++ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$$x -o metadata | \ + xsltproc ${abs_top_srcdir}/lib/fence2rng.xsl - | \ + sed -e 's/ rha:description=/ description=/g' -e 's/ rha:name=/ name=/g' | \ + xmllint --nsclean --noout -; \ +diff --color -uNr a/make/fencebuild.mk b/make/fencebuild.mk +--- a/make/fencebuild.mk 2021-03-16 09:32:22.000000000 +0100 ++++ b/make/fencebuild.mk 2021-06-03 13:16:16.548120826 +0200 +@@ -34,10 +34,10 @@ + > $@ + + if [ 0 -eq `echo "$(@)" | grep fence_ > /dev/null 2>&1; echo $$?` ]; then \ +- PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(top_srcdir)/lib/check_used_options.py $@; \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(top_srcdir)/lib/check_used_options.py $@; \ + else true ; fi + +- for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ + cp -f $(@) $(@D)/$$x; \ + $(MAKE) $(@D)/$$x.8; \ + done +@@ -64,7 +64,7 @@ + fi + for p in $(TARGET); do \ + dir=`dirname $$p`; \ +- for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ + echo " $(INSTALL_SCRIPT) $$dir/$$x '$(DESTDIR)$(sbindir)'"; \ + $(INSTALL_SCRIPT) $$dir/$$x "$(DESTDIR)$(sbindir)" || exit $$?; \ + echo " $(INSTALL_DATA) '$$dir/$$x.8' '$(DESTDIR)$(man8dir)'"; \ +@@ -74,7 +74,7 @@ + + uninstall-hook: $(TARGET) + files=`for p in $(TARGET); do \ +- for x in \`PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"\`; do \ ++ for x in \`PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"\`; do \ + echo " rm -f '$(DESTDIR)$(sbindir)/$$x'"; \ + rm -f "$(DESTDIR)$(sbindir)/$$x"; \ + echo " rm -f '$(DESTDIR)$(man8dir)/$$x.8'"; \ +diff --color -uNr a/make/fenceman.mk b/make/fenceman.mk +--- a/make/fenceman.mk 2021-03-11 16:10:15.000000000 +0100 ++++ b/make/fenceman.mk 2021-06-03 13:16:16.548120826 +0200 +@@ -1,6 +1,6 @@ + %.8: % $(top_srcdir)/lib/fence2man.xsl + set -e && \ +- PYTHONPATH=$(abs_srcdir)/lib:$(abs_builddir)/../lib:$(abs_builddir)/lib \ ++ PYTHONPATH=$(abs_srcdir)/lib:$(abs_builddir)/../lib:$(abs_builddir)/lib:$(abs_top_builddir)/support/common \ + $(PYTHON) $* -o manpage > $(@D)/.$(@F).tmp && \ + xmllint --noout --relaxng $(top_srcdir)/lib/metadata.rng $(@D)/.$(@F).tmp && \ + xsltproc $(top_srcdir)/lib/fence2man.xsl $(@D)/.$(@F).tmp > $@ diff --git a/bundled-suds.patch b/bundled-suds.patch new file mode 100644 index 0000000..b8a6ba1 --- /dev/null +++ b/bundled-suds.patch @@ -0,0 +1,10 @@ +--- a/agents/vmware_soap/fence_vmware_soap.py 2021-08-24 15:38:05.145039598 +0200 ++++ b/agents/vmware_soap/fence_vmware_soap.py 2021-08-24 15:37:51.885003751 +0200 +@@ -1,6 +1,7 @@ + #!@PYTHON@ -tt + + import sys ++sys.path.insert(0, '/usr/lib/fence-agents/support/common') + import shutil, tempfile, suds + import logging, requests + import atexit, signal diff --git a/bz2000954-1-configure-fix-virt.patch b/bz2000954-1-configure-fix-virt.patch new file mode 100644 index 0000000..de556a4 --- /dev/null +++ b/bz2000954-1-configure-fix-virt.patch @@ -0,0 +1,24 @@ +From 52de83b30a8eea638b01f649f4884f50417121c0 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 8 Nov 2021 09:55:11 +0100 +Subject: [PATCH] configure: fix --with-agents to not match *virt in regex + +--- + configure.ac | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 7aa51e75d..76aec7186 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -173,8 +173,8 @@ if echo "$AGENTS_LIST" | grep -q -E "all|zvm( |$)"; then + fi + + FENCE_VIRT=0 +-if echo "$AGENTS_LIST" | grep -q -E "all|virt( |$)"; then +- AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s/virt( |$)//") ++if echo "$AGENTS_LIST" | grep -q -E "all|(^| )virt( |$)"; then ++ AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s/(^| )virt( |$)//") + case "$host_os" in + *bsd*) + ;; diff --git a/bz2000954-2-fence_kubevirt.patch b/bz2000954-2-fence_kubevirt.patch new file mode 100644 index 0000000..44ac751 --- /dev/null +++ b/bz2000954-2-fence_kubevirt.patch @@ -0,0 +1,160 @@ +--- fence-agents-4.10.0/agents/kubevirt/fence_kubevirt.py 2021-07-08 13:09:05.000000000 +0200 ++++ /home/oalbrigt/rhpkg/fence-agents-8.6/fence-agents-4.2.1/agents/kubevirt/fence_kubevirt.py 2021-11-02 15:35:46.217440426 +0100 +@@ -2,24 +2,25 @@ + + import sys + import logging ++import atexit + 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: ++ sys.path.insert(0, '/usr/lib/fence-agents/support/kubevirt') + from kubernetes.client.exceptions import ApiException + except ImportError: + logging.error("Couldn\'t import kubernetes.client.exceptions.ApiException - not found or not accessible") + +-API_VERSION='kubevirt.io/v1' +- + 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=API_VERSION, kind='VirtualMachine') ++ 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) +@@ -30,18 +31,21 @@ + 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=API_VERSION, ++ 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,38 +53,53 @@ + 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: ++ 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) ++ 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["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): ++def virtctl_vm_action(conn, action, namespace, name, apiversion): + path = '/apis/subresources.{api_version}/namespaces/{namespace}/virtualmachines/{name}/{action}' +- path = path.format(api_version=API_VERSION, namespace=namespace, name=name, action=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): +@@ -92,8 +111,13 @@ + def main(): + conn = None + +- device_opt = ["port", "namespace", "kubeconfig", "separator", "no_password"] ++ 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 = {} +@@ -106,6 +130,11 @@ + + 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 diff --git a/bz2000954-3-fence_kubevirt-get-namespace-from-context.patch b/bz2000954-3-fence_kubevirt-get-namespace-from-context.patch new file mode 100644 index 0000000..799bf31 --- /dev/null +++ b/bz2000954-3-fence_kubevirt-get-namespace-from-context.patch @@ -0,0 +1,102 @@ +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 +++++++++++++----------- + tests/data/metadata/fence_kubevirt.xml | 2 +- + 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 +diff --git a/tests/data/metadata/fence_kubevirt.xml b/tests/data/metadata/fence_kubevirt.xml +index 24e975587..ccb20c224 100644 +--- a/tests/data/metadata/fence_kubevirt.xml ++++ b/tests/data/metadata/fence_kubevirt.xml +@@ -23,7 +23,7 @@ + <content type="boolean" /> + <shortdesc lang="en">Use SSL connection without verifying certificate</shortdesc> + </parameter> +- <parameter name="namespace" unique="0" required="1"> ++ <parameter name="namespace" unique="0" required="0"> + <getopt mixed="--namespace=[namespace]" /> + <content type="string" /> + <shortdesc lang="en">Namespace of the KubeVirt machine.</shortdesc> diff --git a/bz2010652-fence_azure_arm-fix-sovereign-cloud-msi-support.patch b/bz2010652-fence_azure_arm-fix-sovereign-cloud-msi-support.patch new file mode 100644 index 0000000..4077484 --- /dev/null +++ b/bz2010652-fence_azure_arm-fix-sovereign-cloud-msi-support.patch @@ -0,0 +1,139 @@ +From e339f304d4423a0e661d915f72ba88553b21d74a Mon Sep 17 00:00:00 2001 +From: MSSedusch <sedusch@microsoft.com> +Date: Tue, 28 Sep 2021 12:23:37 +0000 +Subject: [PATCH 1/2] add support for sovereign clouds and MSI + +--- + lib/azure_fence.py.py | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/lib/azure_fence.py.py b/lib/azure_fence.py.py +index 1f38bd4ea..75b63fdad 100644 +--- a/lib/azure_fence.py.py ++++ b/lib/azure_fence.py.py +@@ -286,11 +286,11 @@ def get_azure_credentials(config): + credentials = None
+ cloud_environment = get_azure_cloud_environment(config)
+ if config.UseMSI and cloud_environment:
+- from msrestazure.azure_active_directory import MSIAuthentication
+- credentials = MSIAuthentication(cloud_environment=cloud_environment)
++ from azure.identity import ManagedIdentityCredential
++ credentials = ManagedIdentityCredential(cloud_environment=cloud_environment)
+ elif config.UseMSI:
+- from msrestazure.azure_active_directory import MSIAuthentication
+- credentials = MSIAuthentication()
++ from azure.identity import ManagedIdentityCredential
++ credentials = ManagedIdentityCredential()
+ elif cloud_environment:
+ try:
+ # try to use new libraries ClientSecretCredential (azure.identity, based on azure.core)
+@@ -340,7 +340,8 @@ def get_azure_compute_client(config): + compute_client = ComputeManagementClient(
+ credentials,
+ config.SubscriptionId,
+- base_url=cloud_environment.endpoints.resource_manager
++ base_url=cloud_environment.endpoints.resource_manager,
++ credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
+ )
+ else:
+ compute_client = ComputeManagementClient(
+@@ -359,7 +360,8 @@ def get_azure_network_client(config): + network_client = NetworkManagementClient(
+ credentials,
+ config.SubscriptionId,
+- base_url=cloud_environment.endpoints.resource_manager
++ base_url=cloud_environment.endpoints.resource_manager,
++ credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
+ )
+ else:
+ network_client = NetworkManagementClient(
+ +From f08f02a7561e78dd9c95c66ccdcf6246c5ee7d6a Mon Sep 17 00:00:00 2001 +From: MSSedusch <sedusch@microsoft.com> +Date: Fri, 1 Oct 2021 15:28:39 +0000 +Subject: [PATCH 2/2] compatiblity fix + +--- + lib/azure_fence.py.py | 54 ++++++++++++++++++++++++++++++------------- + 1 file changed, 38 insertions(+), 16 deletions(-) + +diff --git a/lib/azure_fence.py.py b/lib/azure_fence.py.py +index 75b63fdad..5ca71eb42 100644 +--- a/lib/azure_fence.py.py ++++ b/lib/azure_fence.py.py +@@ -286,11 +286,19 @@ def get_azure_credentials(config): + credentials = None
+ cloud_environment = get_azure_cloud_environment(config)
+ if config.UseMSI and cloud_environment:
+- from azure.identity import ManagedIdentityCredential
+- credentials = ManagedIdentityCredential(cloud_environment=cloud_environment)
++ try:
++ from azure.identity import ManagedIdentityCredential
++ credentials = ManagedIdentityCredential(cloud_environment=cloud_environment)
++ except ImportError:
++ from msrestazure.azure_active_directory import MSIAuthentication
++ credentials = MSIAuthentication(cloud_environment=cloud_environment)
+ elif config.UseMSI:
+- from azure.identity import ManagedIdentityCredential
+- credentials = ManagedIdentityCredential()
++ try:
++ from azure.identity import ManagedIdentityCredential
++ credentials = ManagedIdentityCredential()
++ except ImportError:
++ from msrestazure.azure_active_directory import MSIAuthentication
++ credentials = MSIAuthentication()
+ elif cloud_environment:
+ try:
+ # try to use new libraries ClientSecretCredential (azure.identity, based on azure.core)
+@@ -337,12 +345,19 @@ def get_azure_compute_client(config): + credentials = get_azure_credentials(config)
+
+ if cloud_environment:
+- compute_client = ComputeManagementClient(
+- credentials,
+- config.SubscriptionId,
+- base_url=cloud_environment.endpoints.resource_manager,
+- credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
+- )
++ try:
++ compute_client = ComputeManagementClient(
++ credentials,
++ config.SubscriptionId,
++ base_url=cloud_environment.endpoints.resource_manager,
++ credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
++ )
++ except TypeError:
++ compute_client = ComputeManagementClient(
++ credentials,
++ config.SubscriptionId,
++ base_url=cloud_environment.endpoints.resource_manager
++ )
+ else:
+ compute_client = ComputeManagementClient(
+ credentials,
+@@ -357,12 +372,19 @@ def get_azure_network_client(config): + credentials = get_azure_credentials(config)
+
+ if cloud_environment:
+- network_client = NetworkManagementClient(
+- credentials,
+- config.SubscriptionId,
+- base_url=cloud_environment.endpoints.resource_manager,
+- credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
+- )
++ try:
++ network_client = NetworkManagementClient(
++ credentials,
++ config.SubscriptionId,
++ base_url=cloud_environment.endpoints.resource_manager,
++ credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
++ )
++ except TypeError:
++ network_client = NetworkManagementClient(
++ credentials,
++ config.SubscriptionId,
++ base_url=cloud_environment.endpoints.resource_manager
++ )
+ else:
+ network_client = NetworkManagementClient(
+ credentials,
diff --git a/bz2010709-1-fence_amt_ws-fix-or-causing-dead-code.patch b/bz2010709-1-fence_amt_ws-fix-or-causing-dead-code.patch new file mode 100644 index 0000000..bdbeab0 --- /dev/null +++ b/bz2010709-1-fence_amt_ws-fix-or-causing-dead-code.patch @@ -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" diff --git a/bz2010709-2-fence_amt_ws-boot-option.patch b/bz2010709-2-fence_amt_ws-boot-option.patch new file mode 100644 index 0000000..dd37fef --- /dev/null +++ b/bz2010709-2-fence_amt_ws-boot-option.patch @@ -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.', \ diff --git a/bz2022334-fence_zvmip-add-disable-ssl.patch b/bz2022334-fence_zvmip-add-disable-ssl.patch new file mode 100644 index 0000000..916391d --- /dev/null +++ b/bz2022334-fence_zvmip-add-disable-ssl.patch @@ -0,0 +1,98 @@ +From 90c4f78e005ca4141039d1dce032b5f2c2ff4783 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 10 Feb 2022 12:22:58 +0100 +Subject: [PATCH 1/2] fencing: add ability to set bool parameters to 0 or false + +--- + lib/fencing.py.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/fencing.py.py b/lib/fencing.py.py +index 55e38c407..696388d55 100644 +--- a/lib/fencing.py.py ++++ b/lib/fencing.py.py +@@ -1502,6 +1502,8 @@ def _parse_input_stdin(avail_opt): + opt["--"+all_opt[name]["longopt"].rstrip(":")] = value + elif value.lower() in ["1", "yes", "on", "true"]: + opt["--"+all_opt[name]["longopt"]] = "1" ++ elif value.lower() in ["0", "no", "off", "false"]: ++ opt["--"+all_opt[name]["longopt"]] = "0" + else: + logging.warning("Parse error: Ignoring option '%s' because it does not have value\n", name) + + +From 249abc8e5620fb1a3d97a0af6db34b1f2cbf3ae5 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 10 Feb 2022 12:27:02 +0100 +Subject: [PATCH 2/2] fence_zvmip: add --disable-ssl + +--- + agents/zvm/fence_zvmip.py | 18 +++++++++++++++++- + tests/data/metadata/fence_zvmip.xml | 7 ++++++- + 2 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py +index 96021b13e..e8f849eda 100644 +--- a/agents/zvm/fence_zvmip.py ++++ b/agents/zvm/fence_zvmip.py +@@ -156,11 +156,24 @@ def get_list_of_images(options, command, data_as_plug): + conn.close() + return (return_code, reason_code, images) + ++def define_new_opts(): ++ all_opt["disable_ssl"] = { ++ "getopt" : "", ++ "longopt" : "disable-ssl", ++ "help" : "--disable-ssl Don't use SSL connection", ++ "required" : "0", ++ "shortdesc" : "Don't use SSL", ++ "order": 2 ++ } ++ + def main(): + device_opt = ["ipaddr", "login", "passwd", "port", "method", "missing_as_off", +- "inet4_only", "inet6_only", "ssl"] ++ "inet4_only", "inet6_only", "ssl", "disable_ssl"] + + atexit.register(atexit_handler) ++ define_new_opts() ++ ++ all_opt["ssl"]["help"] = "-z, --ssl Use SSL connection with verifying certificate (Default)" + + all_opt["ipport"]["default"] = "44444" + all_opt["shell_timeout"]["default"] = "5" +@@ -168,6 +181,9 @@ def main(): + all_opt["ssl"]["default"] = "1" + options = check_input(device_opt, process_input(device_opt), other_conditions=True) + ++ if "--disable-ssl" in options or options["--ssl"] == "0": ++ del options["--ssl"] ++ + if len(options.get("--plug", "")) > 8: + fail_usage("Failed: Name of image can not be longer than 8 characters") + +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index f32fc159d..0b7ba4785 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -94,7 +94,7 @@ to access the system's directory manager. + <parameter name="ssl" unique="0" required="0"> + <getopt mixed="-z, --ssl" /> + <content type="boolean" default="1" /> +- <shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc> ++ <shortdesc lang="en">Use SSL connection with verifying certificate (Default)</shortdesc> + </parameter> + <parameter name="ssl_insecure" unique="0" required="0"> + <getopt mixed="--ssl-insecure" /> +@@ -111,6 +111,11 @@ to access the system's directory manager. + <content type="string" /> + <shortdesc lang="en">Login name</shortdesc> + </parameter> ++ <parameter name="disable_ssl" unique="0" required="0"> ++ <getopt mixed="--disable-ssl" /> ++ <content type="boolean" /> ++ <shortdesc lang="en">Don't use SSL</shortdesc> ++ </parameter> + <parameter name="quiet" unique="0" required="0"> + <getopt mixed="-q, --quiet" /> + <content type="boolean" /> diff --git a/bz2022334-fence_zvmip-add-ssl-tls-support.patch b/bz2022334-fence_zvmip-add-ssl-tls-support.patch new file mode 100644 index 0000000..71607bc --- /dev/null +++ b/bz2022334-fence_zvmip-add-ssl-tls-support.patch @@ -0,0 +1,136 @@ +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 1/2] 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"/> + +From 8021e698095c5bd0ef33ee5f56fc448e946cb92c Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Wed, 10 Nov 2021 16:31:24 +0100 +Subject: [PATCH 2/2] fence_zvmip: use ssl by default + +--- + agents/zvm/fence_zvmip.py | 1 + + tests/data/metadata/fence_zvmip.xml | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py +index 874eb699f..96021b13e 100644 +--- a/agents/zvm/fence_zvmip.py ++++ b/agents/zvm/fence_zvmip.py +@@ -165,6 +165,7 @@ def main(): + all_opt["ipport"]["default"] = "44444" + all_opt["shell_timeout"]["default"] = "5" + all_opt["missing_as_off"]["default"] = "1" ++ all_opt["ssl"]["default"] = "1" + options = check_input(device_opt, process_input(device_opt), other_conditions=True) + + if len(options.get("--plug", "")) > 8: +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index d91192946..f32fc159d 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -93,7 +93,7 @@ to access the system's directory manager. + </parameter> + <parameter name="ssl" unique="0" required="0"> + <getopt mixed="-z, --ssl" /> +- <content type="boolean" /> ++ <content type="boolean" default="1" /> + <shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc> + </parameter> + <parameter name="ssl_insecure" unique="0" required="0"> diff --git a/bz2029791-1-fence_openstack-add-ssl-insecure.patch b/bz2029791-1-fence_openstack-add-ssl-insecure.patch new file mode 100644 index 0000000..e616cc8 --- /dev/null +++ b/bz2029791-1-fence_openstack-add-ssl-insecure.patch @@ -0,0 +1,72 @@ +From f79436d3a5e4cf279be0974e9633ad8994a017f7 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 6 Dec 2021 12:59:31 +0100 +Subject: [PATCH] fence_openstack: add --ssl-insecure + +--- + agents/openstack/fence_openstack.py | 7 +++++-- + tests/data/metadata/fence_openstack.xml | 5 +++++ + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/agents/openstack/fence_openstack.py b/agents/openstack/fence_openstack.py +index c480596c1..c2d9df160 100755 +--- a/agents/openstack/fence_openstack.py ++++ b/agents/openstack/fence_openstack.py +@@ -89,7 +89,7 @@ def set_power_status(conn, options): + + + def nova_login(username, password, projectname, auth_url, user_domain_name, +- project_domain_name, cacert, apitimeout): ++ project_domain_name, ssl_insecure, cacert, apitimeout): + legacy_import = False + + try: +@@ -127,7 +127,7 @@ def nova_login(username, password, projectname, auth_url, user_domain_name, + cacert=cacert, + ) + +- session = ksc_session.Session(auth=auth, verify=cacert, timeout=apitimeout) ++ session = ksc_session.Session(auth=auth, verify=False if ssl_insecure else cacert, timeout=apitimeout) + nova = client.Client("2", session=session, timeout=apitimeout) + apiversion = None + try: +@@ -220,6 +220,7 @@ def main(): + "port", + "no_port", + "uuid", ++ "ssl_insecure", + "cacert", + "apitimeout", + ] +@@ -268,6 +269,7 @@ def main(): + fail_usage("Failed: You have to set the Keystone service endpoint for authorization") + user_domain_name = options["--user-domain-name"] + project_domain_name = options["--project-domain-name"] ++ ssl_insecure = "--ssl-insecure" in options + cacert = options["--cacert"] + apitimeout = options["--apitimeout"] + try: +@@ -278,6 +280,7 @@ def main(): + auth_url, + user_domain_name, + project_domain_name, ++ ssl_insecure, + cacert, + apitimeout, + ) +diff --git a/tests/data/metadata/fence_openstack.xml b/tests/data/metadata/fence_openstack.xml +index 84503bbe0..926d18c3d 100644 +--- a/tests/data/metadata/fence_openstack.xml ++++ b/tests/data/metadata/fence_openstack.xml +@@ -43,6 +43,11 @@ + <content type="string" /> + <shortdesc lang="en">UUID of the node to be fenced.</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="username" unique="0" required="1" obsoletes="login"> + <getopt mixed="-l, --username=[name]" /> + <content type="string" /> diff --git a/bz2029791-2-fence_openstack-cacert-default.patch b/bz2029791-2-fence_openstack-cacert-default.patch new file mode 100644 index 0000000..419ce33 --- /dev/null +++ b/bz2029791-2-fence_openstack-cacert-default.patch @@ -0,0 +1,59 @@ +From b7032d16a07997ecab3b2c11a6436b3fa21f9043 Mon Sep 17 00:00:00 2001 +From: "Fabio M. Di Nitto" <fdinitto@redhat.com> +Date: Thu, 6 Jan 2022 12:53:28 +0100 +Subject: [PATCH] fence_openstack: relax ssl cacert default + +allow the agent to use Base OS defaults vs forcing a specific file +to increase portability. + +Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com> +--- + agents/openstack/fence_openstack.py | 12 +++++++++--- + tests/data/metadata/fence_openstack.xml | 2 +- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/agents/openstack/fence_openstack.py b/agents/openstack/fence_openstack.py +index c2d9df160..36b353b52 100755 +--- a/agents/openstack/fence_openstack.py ++++ b/agents/openstack/fence_openstack.py +@@ -127,7 +127,13 @@ def nova_login(username, password, projectname, auth_url, user_domain_name, + cacert=cacert, + ) + +- session = ksc_session.Session(auth=auth, verify=False if ssl_insecure else cacert, timeout=apitimeout) ++ caverify=True ++ if ssl_insecure: ++ caverify=False ++ elif cacert: ++ caverify=cacert ++ ++ session = ksc_session.Session(auth=auth, verify=caverify, timeout=apitimeout) + nova = client.Client("2", session=session, timeout=apitimeout) + apiversion = None + try: +@@ -189,10 +195,10 @@ def define_new_opts(): + all_opt["cacert"] = { + "getopt": ":", + "longopt": "cacert", +- "help": "--cacert=[cacert] Path to the PEM file with trusted authority certificates", ++ "help": "--cacert=[cacert] Path to the PEM file with trusted authority certificates (override global CA trust)", + "required": "0", + "shortdesc": "SSL X.509 certificates file", +- "default": "/etc/pki/tls/certs/ca-bundle.crt", ++ "default": "", + "order": 7, + } + all_opt["apitimeout"] = { +diff --git a/tests/data/metadata/fence_openstack.xml b/tests/data/metadata/fence_openstack.xml +index 926d18c3d..c8dc2e60f 100644 +--- a/tests/data/metadata/fence_openstack.xml ++++ b/tests/data/metadata/fence_openstack.xml +@@ -100,7 +100,7 @@ + </parameter> + <parameter name="cacert" unique="0" required="0"> + <getopt mixed="--cacert=[cacert]" /> +- <content type="string" default="/etc/pki/tls/certs/ca-bundle.crt" /> ++ <content type="string" default="" /> + <shortdesc lang="en">SSL X.509 certificates file</shortdesc> + </parameter> + <parameter name="apitimeout" unique="0" required="0"> diff --git a/bz2041933-bz2041935-1-fence_openstack-clouds-openrc.patch b/bz2041933-bz2041935-1-fence_openstack-clouds-openrc.patch new file mode 100644 index 0000000..06363d8 --- /dev/null +++ b/bz2041933-bz2041935-1-fence_openstack-clouds-openrc.patch @@ -0,0 +1,313 @@ +From 2f741df2ce73da85bbd205d861b527aa141d9776 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Fri, 14 Jan 2022 14:47:41 +0100 +Subject: [PATCH 1/2] fencing: add source_env() + +--- + lib/fencing.py.py | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/lib/fencing.py.py b/lib/fencing.py.py +index d85b23568..55e38c407 100644 +--- a/lib/fencing.py.py ++++ b/lib/fencing.py.py +@@ -1143,6 +1143,14 @@ def fence_logout(conn, logout_string, sleep=0): + except pexpect.ExceptionPexpect: + pass + ++def source_env(env_file): ++ # POSIX: name shall not contain '=', value doesn't contain '\0' ++ output = subprocess.check_output("source {} && env -0".format(env_file), shell=True, ++ executable="/bin/sh") ++ # replace env ++ os.environ.clear() ++ os.environ.update(line.partition('=')[::2] for line in output.decode("utf-8").split('\0')) ++ + # Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is + # in format a.b.c.d...z and returned dict has key only z + def array_to_dict(array): + +From fe2183a97e0a5734702e9cba8da21f01afd8f577 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Fri, 14 Jan 2022 14:54:10 +0100 +Subject: [PATCH 2/2] fence_openstack: add support for reading config from + clouds.yaml and openrc + +--- + agents/openstack/fence_openstack.py | 116 ++++++++++++++++++++---- + tests/data/metadata/fence_openstack.xml | 32 +++++-- + 2 files changed, 126 insertions(+), 22 deletions(-) + mode change 100755 => 100644 agents/openstack/fence_openstack.py + +diff --git a/agents/openstack/fence_openstack.py b/agents/openstack/fence_openstack.py +old mode 100755 +new mode 100644 +index 36b353b52..d3a4be3aa +--- a/agents/openstack/fence_openstack.py ++++ b/agents/openstack/fence_openstack.py +@@ -8,7 +8,7 @@ + + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +-from fencing import fail_usage, run_delay ++from fencing import fail_usage, run_delay, source_env + + try: + from novaclient import client +@@ -26,6 +26,23 @@ def translate_status(instance_status): + return "off" + return "unknown" + ++def get_cloud(options): ++ import os, yaml ++ ++ clouds_yaml = os.path.expanduser("~/.config/openstack/clouds.yaml") ++ if os.path.exists(clouds_yaml): ++ with open(clouds_yaml, "r") as yaml_stream: ++ try: ++ clouds = yaml.safe_load(yaml_stream) ++ except yaml.YAMLError as exc: ++ fail_usage("Failed: Unable to read: " + clouds_yaml) ++ ++ cloud = clouds.get("clouds").get(options["--cloud"]) ++ if not cloud: ++ fail_usage("Cloud: {} not found.".format(options["--cloud"])) ++ ++ return cloud ++ + + def get_nodes_list(conn, options): + logging.info("Running %s action", options["--action"]) +@@ -153,7 +170,7 @@ def define_new_opts(): + "getopt": ":", + "longopt": "auth-url", + "help": "--auth-url=[authurl] Keystone Auth URL", +- "required": "1", ++ "required": "0", + "shortdesc": "Keystone Auth URL", + "order": 2, + } +@@ -161,7 +178,7 @@ def define_new_opts(): + "getopt": ":", + "longopt": "project-name", + "help": "--project-name=[project] Tenant Or Project Name", +- "required": "1", ++ "required": "0", + "shortdesc": "Keystone Project", + "default": "admin", + "order": 3, +@@ -184,13 +201,38 @@ def define_new_opts(): + "default": "Default", + "order": 5, + } ++ all_opt["clouds-yaml"] = { ++ "getopt": ":", ++ "longopt": "clouds-yaml", ++ "help": "--clouds-yaml=[clouds-yaml] Path to the clouds.yaml config file", ++ "required": "0", ++ "shortdesc": "clouds.yaml config file", ++ "default": "~/.config/openstack/clouds.yaml", ++ "order": 6, ++ } ++ all_opt["cloud"] = { ++ "getopt": ":", ++ "longopt": "cloud", ++ "help": "--cloud=[cloud] Openstack cloud (from clouds.yaml).", ++ "required": "0", ++ "shortdesc": "Cloud from clouds.yaml", ++ "order": 7, ++ } ++ all_opt["openrc"] = { ++ "getopt": ":", ++ "longopt": "openrc", ++ "help": "--openrc=[openrc] Path to the openrc config file", ++ "required": "0", ++ "shortdesc": "openrc config file", ++ "order": 8, ++ } + all_opt["uuid"] = { + "getopt": ":", + "longopt": "uuid", + "help": "--uuid=[uuid] Replaced by -n, --plug", + "required": "0", + "shortdesc": "Replaced by port/-n/--plug", +- "order": 6, ++ "order": 9, + } + all_opt["cacert"] = { + "getopt": ":", +@@ -199,7 +241,7 @@ def define_new_opts(): + "required": "0", + "shortdesc": "SSL X.509 certificates file", + "default": "", +- "order": 7, ++ "order": 10, + } + all_opt["apitimeout"] = { + "getopt": ":", +@@ -209,7 +251,7 @@ def define_new_opts(): + "shortdesc": "Timeout in seconds to use for API calls, default is 60.", + "required": "0", + "default": 60, +- "order": 8, ++ "order": 11, + } + + +@@ -218,11 +260,16 @@ def main(): + + device_opt = [ + "login", ++ "no_login", + "passwd", ++ "no_password", + "auth-url", + "project-name", + "user-domain-name", + "project-domain-name", ++ "clouds-yaml", ++ "cloud", ++ "openrc", + "port", + "no_port", + "uuid", +@@ -265,19 +312,56 @@ def main(): + + run_delay(options) + +- username = options["--username"] +- password = options["--password"] +- projectname = options["--project-name"] +- auth_url = None +- try: +- auth_url = options["--auth-url"] +- except KeyError: +- fail_usage("Failed: You have to set the Keystone service endpoint for authorization") +- user_domain_name = options["--user-domain-name"] +- project_domain_name = options["--project-domain-name"] ++ if options.get("--clouds-yaml"): ++ if not os.path.exists(os.path.expanduser(options["--clouds-yaml"])): ++ fail_usage("Failed: {} does not exist".format(options.get("--clouds-yaml"))) ++ if not options.get("--cloud"): ++ fail_usage("Failed: \"cloud\" not specified") ++ cloud = get_cloud(options) ++ username = cloud.get("username") ++ password = cloud.get("password") ++ projectname = cloud.get("project_name") ++ auth_url = None ++ try: ++ auth_url = cloud.get("auth_url") ++ except KeyError: ++ fail_usage("Failed: You have to set the Keystone service endpoint for authorization") ++ user_domain_name = cloud.get("user_domain_name") ++ project_domain_name = cloud.get("project_domain_name") ++ caverify = cloud.get("verify") ++ if caverify in [True, False]: ++ options["--ssl-insecure"] = caverify ++ else: ++ options["--cacert"] = caverify ++ if options.get("--openrc") and os.path.exists(os.path.expanduser(options["--openrc"])): ++ source_env(options["--openrc"]) ++ env = os.environ ++ username = env.get("OS_USERNAME") ++ password = env.get("OS_PASSWORD") ++ projectname = env.get("OS_PROJECT_NAME") ++ auth_url = None ++ try: ++ auth_url = env["OS_AUTH_URL"] ++ except KeyError: ++ fail_usage("Failed: You have to set the Keystone service endpoint for authorization") ++ user_domain_name = env.get("OS_USER_DOMAIN_NAME") ++ project_domain_name = env.get("OS_PROJECT_DOMAIN_NAME") ++ else: ++ username = options["--username"] ++ password = options["--password"] ++ projectname = options["--project-name"] ++ auth_url = None ++ try: ++ auth_url = options["--auth-url"] ++ except KeyError: ++ fail_usage("Failed: You have to set the Keystone service endpoint for authorization") ++ user_domain_name = options["--user-domain-name"] ++ project_domain_name = options["--project-domain-name"] ++ + ssl_insecure = "--ssl-insecure" in options + cacert = options["--cacert"] + apitimeout = options["--apitimeout"] ++ + try: + conn = nova_login( + username, +diff --git a/tests/data/metadata/fence_openstack.xml b/tests/data/metadata/fence_openstack.xml +index c8dc2e60f..55a57b4d7 100644 +--- a/tests/data/metadata/fence_openstack.xml ++++ b/tests/data/metadata/fence_openstack.xml +@@ -8,7 +8,7 @@ + <content type="string" default="reboot" /> + <shortdesc lang="en">Fencing action</shortdesc> + </parameter> +- <parameter name="login" unique="0" required="1" deprecated="1"> ++ <parameter name="login" unique="0" required="0" deprecated="1"> + <getopt mixed="-l, --username=[name]" /> + <content type="string" /> + <shortdesc lang="en">Login name</shortdesc> +@@ -48,27 +48,27 @@ + <content type="boolean" /> + <shortdesc lang="en">Use SSL connection without verifying certificate</shortdesc> + </parameter> +- <parameter name="username" unique="0" required="1" obsoletes="login"> ++ <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="auth-url" unique="0" required="1" deprecated="1"> ++ <parameter name="auth-url" unique="0" required="0" deprecated="1"> + <getopt mixed="--auth-url=[authurl]" /> + <content type="string" /> + <shortdesc lang="en">Keystone Auth URL</shortdesc> + </parameter> +- <parameter name="auth_url" unique="0" required="1" obsoletes="auth-url"> ++ <parameter name="auth_url" unique="0" required="0" obsoletes="auth-url"> + <getopt mixed="--auth-url=[authurl]" /> + <content type="string" /> + <shortdesc lang="en">Keystone Auth URL</shortdesc> + </parameter> +- <parameter name="project-name" unique="0" required="1" deprecated="1"> ++ <parameter name="project-name" unique="0" required="0" deprecated="1"> + <getopt mixed="--project-name=[project]" /> + <content type="string" default="admin" /> + <shortdesc lang="en">Keystone Project</shortdesc> + </parameter> +- <parameter name="project_name" unique="0" required="1" obsoletes="project-name"> ++ <parameter name="project_name" unique="0" required="0" obsoletes="project-name"> + <getopt mixed="--project-name=[project]" /> + <content type="string" default="admin" /> + <shortdesc lang="en">Keystone Project</shortdesc> +@@ -93,6 +93,26 @@ + <content type="string" default="Default" /> + <shortdesc lang="en">Keystone Project Domain Name</shortdesc> + </parameter> ++ <parameter name="clouds-yaml" unique="0" required="0" deprecated="1"> ++ <getopt mixed="--clouds-yaml=[clouds-yaml]" /> ++ <content type="string" default="~/.config/openstack/clouds.yaml" /> ++ <shortdesc lang="en">clouds.yaml config file</shortdesc> ++ </parameter> ++ <parameter name="clouds_yaml" unique="0" required="0" obsoletes="clouds-yaml"> ++ <getopt mixed="--clouds-yaml=[clouds-yaml]" /> ++ <content type="string" default="~/.config/openstack/clouds.yaml" /> ++ <shortdesc lang="en">clouds.yaml config file</shortdesc> ++ </parameter> ++ <parameter name="cloud" unique="0" required="0"> ++ <getopt mixed="--cloud=[cloud]" /> ++ <content type="string" /> ++ <shortdesc lang="en">Cloud from clouds.yaml</shortdesc> ++ </parameter> ++ <parameter name="openrc" unique="0" required="0"> ++ <getopt mixed="--openrc=[openrc]" /> ++ <content type="string" /> ++ <shortdesc lang="en">openrc config file</shortdesc> ++ </parameter> + <parameter name="uuid" unique="0" required="0"> + <getopt mixed="--uuid=[uuid]" /> + <content type="string" /> diff --git a/bz2041933-bz2041935-2-fence_openstack-clouds-openrc.patch b/bz2041933-bz2041935-2-fence_openstack-clouds-openrc.patch new file mode 100644 index 0000000..6daa2bb --- /dev/null +++ b/bz2041933-bz2041935-2-fence_openstack-clouds-openrc.patch @@ -0,0 +1,171 @@ +From 7d9572ec947d23fa18ac530f07fe33ba148c9634 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 17 Jan 2022 14:32:53 +0100 +Subject: [PATCH] fence_openstack: fix issues with new clouds.yaml/openrc + parameters - hardcoded clouds.yaml paths to work like the openstack cli + client (used by the resource agents) + +--- + agents/openstack/fence_openstack.py | 55 +++++++++++-------------- + tests/data/metadata/fence_openstack.xml | 10 ----- + 2 files changed, 25 insertions(+), 40 deletions(-) + +diff --git a/agents/openstack/fence_openstack.py b/agents/openstack/fence_openstack.py +index d3a4be3aa..666016d78 100644 +--- a/agents/openstack/fence_openstack.py ++++ b/agents/openstack/fence_openstack.py +@@ -3,6 +3,7 @@ + import atexit + import logging + import sys ++import os + + import urllib3 + +@@ -27,9 +28,15 @@ def translate_status(instance_status): + return "unknown" + + def get_cloud(options): +- import os, yaml ++ import yaml + +- clouds_yaml = os.path.expanduser("~/.config/openstack/clouds.yaml") ++ clouds_yaml = "~/.config/openstack/clouds.yaml" ++ if not os.path.exists(os.path.expanduser(clouds_yaml)): ++ clouds_yaml = "/etc/openstack/clouds.yaml" ++ if not os.path.exists(os.path.expanduser(clouds_yaml)): ++ fail_usage("Failed: ~/.config/openstack/clouds.yaml and /etc/openstack/clouds.yaml does not exist") ++ ++ clouds_yaml = os.path.expanduser(clouds_yaml) + if os.path.exists(clouds_yaml): + with open(clouds_yaml, "r") as yaml_stream: + try: +@@ -201,22 +208,13 @@ def define_new_opts(): + "default": "Default", + "order": 5, + } +- all_opt["clouds-yaml"] = { +- "getopt": ":", +- "longopt": "clouds-yaml", +- "help": "--clouds-yaml=[clouds-yaml] Path to the clouds.yaml config file", +- "required": "0", +- "shortdesc": "clouds.yaml config file", +- "default": "~/.config/openstack/clouds.yaml", +- "order": 6, +- } + all_opt["cloud"] = { + "getopt": ":", + "longopt": "cloud", +- "help": "--cloud=[cloud] Openstack cloud (from clouds.yaml).", ++ "help": "--cloud=[cloud] Openstack cloud (from ~/.config/openstack/clouds.yaml or /etc/openstack/clouds.yaml).", + "required": "0", + "shortdesc": "Cloud from clouds.yaml", +- "order": 7, ++ "order": 6, + } + all_opt["openrc"] = { + "getopt": ":", +@@ -224,7 +222,7 @@ def define_new_opts(): + "help": "--openrc=[openrc] Path to the openrc config file", + "required": "0", + "shortdesc": "openrc config file", +- "order": 8, ++ "order": 7, + } + all_opt["uuid"] = { + "getopt": ":", +@@ -232,7 +230,7 @@ def define_new_opts(): + "help": "--uuid=[uuid] Replaced by -n, --plug", + "required": "0", + "shortdesc": "Replaced by port/-n/--plug", +- "order": 9, ++ "order": 8, + } + all_opt["cacert"] = { + "getopt": ":", +@@ -241,7 +239,7 @@ def define_new_opts(): + "required": "0", + "shortdesc": "SSL X.509 certificates file", + "default": "", +- "order": 10, ++ "order": 9, + } + all_opt["apitimeout"] = { + "getopt": ":", +@@ -251,7 +249,7 @@ def define_new_opts(): + "shortdesc": "Timeout in seconds to use for API calls, default is 60.", + "required": "0", + "default": 60, +- "order": 11, ++ "order": 10, + } + + +@@ -267,7 +265,6 @@ def main(): + "project-name", + "user-domain-name", + "project-domain-name", +- "clouds-yaml", + "cloud", + "openrc", + "port", +@@ -312,28 +309,26 @@ def main(): + + run_delay(options) + +- if options.get("--clouds-yaml"): +- if not os.path.exists(os.path.expanduser(options["--clouds-yaml"])): +- fail_usage("Failed: {} does not exist".format(options.get("--clouds-yaml"))) +- if not options.get("--cloud"): +- fail_usage("Failed: \"cloud\" not specified") ++ if options.get("--cloud"): + cloud = get_cloud(options) +- username = cloud.get("username") +- password = cloud.get("password") +- projectname = cloud.get("project_name") ++ username = cloud.get("auth").get("username") ++ password = cloud.get("auth").get("password") ++ projectname = cloud.get("auth").get("project_name") + auth_url = None + try: +- auth_url = cloud.get("auth_url") ++ auth_url = cloud.get("auth").get("auth_url") + except KeyError: + fail_usage("Failed: You have to set the Keystone service endpoint for authorization") +- user_domain_name = cloud.get("user_domain_name") +- project_domain_name = cloud.get("project_domain_name") ++ user_domain_name = cloud.get("auth").get("user_domain_name") ++ project_domain_name = cloud.get("auth").get("project_domain_name") + caverify = cloud.get("verify") + if caverify in [True, False]: + options["--ssl-insecure"] = caverify + else: + options["--cacert"] = caverify +- if options.get("--openrc") and os.path.exists(os.path.expanduser(options["--openrc"])): ++ elif options.get("--openrc"): ++ if not os.path.exists(os.path.expanduser(options["--openrc"])): ++ fail_usage("Failed: {} does not exist".format(options.get("--openrc"))) + source_env(options["--openrc"]) + env = os.environ + username = env.get("OS_USERNAME") +diff --git a/tests/data/metadata/fence_openstack.xml b/tests/data/metadata/fence_openstack.xml +index 55a57b4d7..67b2191b7 100644 +--- a/tests/data/metadata/fence_openstack.xml ++++ b/tests/data/metadata/fence_openstack.xml +@@ -93,16 +93,6 @@ + <content type="string" default="Default" /> + <shortdesc lang="en">Keystone Project Domain Name</shortdesc> + </parameter> +- <parameter name="clouds-yaml" unique="0" required="0" deprecated="1"> +- <getopt mixed="--clouds-yaml=[clouds-yaml]" /> +- <content type="string" default="~/.config/openstack/clouds.yaml" /> +- <shortdesc lang="en">clouds.yaml config file</shortdesc> +- </parameter> +- <parameter name="clouds_yaml" unique="0" required="0" obsoletes="clouds-yaml"> +- <getopt mixed="--clouds-yaml=[clouds-yaml]" /> +- <content type="string" default="~/.config/openstack/clouds.yaml" /> +- <shortdesc lang="en">clouds.yaml config file</shortdesc> +- </parameter> + <parameter name="cloud" unique="0" required="0"> + <getopt mixed="--cloud=[cloud]" /> + <content type="string" /> diff --git a/bz2041933-bz2041935-3-fencing-source_env-dont-process-empty-lines.patch b/bz2041933-bz2041935-3-fencing-source_env-dont-process-empty-lines.patch new file mode 100644 index 0000000..8803895 --- /dev/null +++ b/bz2041933-bz2041935-3-fencing-source_env-dont-process-empty-lines.patch @@ -0,0 +1,22 @@ +From fbca33a536413565108374dd4ed3237b6f7896bd Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 15 Aug 2022 10:40:19 +0200 +Subject: [PATCH] fencing: source_env(): dont process empty lines + +--- + lib/fencing.py.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/fencing.py.py b/lib/fencing.py.py +index fc3679e33..940bd01d1 100644 +--- a/lib/fencing.py.py ++++ b/lib/fencing.py.py +@@ -1264,7 +1264,7 @@ def source_env(env_file): + executable="/bin/sh") + # replace env + os.environ.clear() +- os.environ.update(line.partition('=')[::2] for line in output.decode("utf-8").split('\0')) ++ os.environ.update(line.partition('=')[::2] for line in output.decode("utf-8").split('\0') if not re.match("^\s*$", line)) + + # Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is + # in format a.b.c.d...z and returned dict has key only z diff --git a/bz2042496-fence_ibm_vpc-fence_ibm_powervs.patch b/bz2042496-fence_ibm_vpc-fence_ibm_powervs.patch new file mode 100644 index 0000000..d68612c --- /dev/null +++ b/bz2042496-fence_ibm_vpc-fence_ibm_powervs.patch @@ -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> diff --git a/bz2065114-fence_lpar-refactor.patch b/bz2065114-fence_lpar-refactor.patch new file mode 100644 index 0000000..599a22c --- /dev/null +++ b/bz2065114-fence_lpar-refactor.patch @@ -0,0 +1,65 @@ +From e3dff8570b70f0c19eca84cf02f0aadd68e16599 Mon Sep 17 00:00:00 2001 +From: Thomas Renninger <trenn@suse.com> +Date: Fri, 25 Feb 2022 14:05:42 +0100 +Subject: [PATCH] fence_lpar: fix missing import logging, use fail_usage + +and slightly re-factor code to avoid duplicate code lines. +Should be cleanup only, no functional change. +--- + agents/lpar/fence_lpar.py | 39 ++++++++++++++++++--------------------- + 1 file changed, 18 insertions(+), 21 deletions(-) + +diff --git a/agents/lpar/fence_lpar.py b/agents/lpar/fence_lpar.py +index ad18c6191..2046b0e4e 100644 +--- a/agents/lpar/fence_lpar.py ++++ b/agents/lpar/fence_lpar.py +@@ -28,31 +28,28 @@ def _normalize_status(status): + + def get_power_status(conn, options): + if options["--hmc-version"] == "3": +- conn.send("lssyscfg -r lpar -m " + options["--managed"] + " -n " + options["--plug"] + " -F name,state\n") +- +- # First line (command) may cause parsing issues if long +- conn.readline() +- conn.log_expect(options["--command-prompt"], int(options["--power-timeout"])) +- +- try: +- status = re.compile("^" + options["--plug"] + ",(.*?),.*$", +- re.IGNORECASE | re.MULTILINE).search(conn.before).group(1) +- except AttributeError as e: +- logging.error("Failed: {}".format(str(e))) +- fail(EC_STATUS_HMC) ++ command = "lssyscfg -r lpar -m " + options["--managed"] + " -n " + options["--plug"] + " -F name,state\n" + elif options["--hmc-version"] in ["4", "IVM"]: +- conn.send("lssyscfg -r lpar -m "+ options["--managed"] + +- " --filter 'lpar_names=" + options["--plug"] + "'\n") ++ command = "lssyscfg -r lpar -m "+ options["--managed"] + \ ++ " --filter 'lpar_names=" + options["--plug"] + "'\n" ++ else: ++ # Bad HMC Version cannot be reached ++ fail(EC_STATUS_HMC) + +- # First line (command) may cause parsing issues if long +- conn.readline() +- conn.log_expect(options["--command-prompt"], int(options["--power-timeout"])) ++ conn.send(command) ++ # First line (command) may cause parsing issues if long ++ conn.readline() ++ conn.log_expect(options["--command-prompt"], int(options["--power-timeout"])) + +- try: ++ try: ++ if options["--hmc-version"] == "3": ++ status = re.compile("^" + options["--plug"] + ",(.*?),.*$", ++ re.IGNORECASE | re.MULTILINE).search(conn.before).group(1) ++ elif options["--hmc-version"] in ["4", "IVM"]: + status = re.compile(",state=(.*?),", re.IGNORECASE).search(conn.before).group(1) +- except AttributeError as e: +- logging.error("Failed: {}".format(str(e))) +- fail(EC_STATUS_HMC) ++ except AttributeError as e: ++ fail_usage("Command on HMC failed: {}\n{}".format(command, str(e)), False) ++ fail(EC_STATUS_HMC) + + return _normalize_status(status) + diff --git a/bz2072420-1-all-agents-unify-ssl-parameters.patch b/bz2072420-1-all-agents-unify-ssl-parameters.patch new file mode 100644 index 0000000..6f8f0af --- /dev/null +++ b/bz2072420-1-all-agents-unify-ssl-parameters.patch @@ -0,0 +1,291 @@ +From 999f2f8b4dc7d258679daf8c3f13d9b317ff4435 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 7 Apr 2022 13:11:12 +0200 +Subject: [PATCH] all agents: unify ssl parameters to avoid having to use --ssl + when using --ssl-secure/--ssl-insecure for some agents + +THIS MIGHT BREAK SETUPS USING fence_docker or fence_pve! +--- + agents/cisco_ucs/fence_cisco_ucs.py | 9 +++++---- + agents/docker/fence_docker.py | 9 ++++++--- + agents/ibmz/fence_ibmz.py | 4 ++-- + agents/rhevm/fence_rhevm.py | 8 ++++---- + agents/skalar/fence_skalar.py | 2 +- + agents/vmware_rest/fence_vmware_rest.py | 8 ++++---- + agents/vmware_soap/fence_vmware_soap.py | 2 +- + agents/vmware_vcloud/fence_vmware_vcloud.py | 4 ++-- + agents/zvm/fence_zvmip.py | 8 +++++--- + lib/fencing.py.py | 6 ++++++ + tests/data/metadata/fence_docker.xml | 4 ++-- + 13 files changed, 64 insertions(+), 31 deletions(-) + +diff --git a/agents/cisco_ucs/fence_cisco_ucs.py b/agents/cisco_ucs/fence_cisco_ucs.py +index 2280dbbc7..b85379a73 100644 +--- a/agents/cisco_ucs/fence_cisco_ucs.py ++++ b/agents/cisco_ucs/fence_cisco_ucs.py +@@ -99,7 +99,7 @@ def get_list(conn, options): + + def send_command(opt, command, timeout): + ## setup correct URL +- if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt: ++ if "--ssl-secure" in opt or "--ssl-insecure" in opt: + url = "https:" + else: + url = "http:" +@@ -114,13 +114,14 @@ def send_command(opt, command, timeout): + conn.setopt(pycurl.POSTFIELDS, command.encode("ascii")) + conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write) + conn.setopt(pycurl.TIMEOUT, timeout) +- if "--ssl" in opt or "--ssl-secure" in opt: ++ ++ if "--ssl-secure" in opt: + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) +- +- if "--ssl-insecure" in opt: ++ elif "--ssl-insecure" in opt: + conn.setopt(pycurl.SSL_VERIFYPEER, 0) + conn.setopt(pycurl.SSL_VERIFYHOST, 0) ++ + conn.perform() + result = web_buffer.getvalue().decode() + +diff --git a/agents/docker/fence_docker.py b/agents/docker/fence_docker.py +index fef87da86..004402518 100644 +--- a/agents/docker/fence_docker.py ++++ b/agents/docker/fence_docker.py +@@ -43,7 +43,7 @@ def get_list(conn, options): + + + def send_cmd(options, cmd, post = False): +- url = "http%s://%s:%s/v%s/%s" % ("s" if "--ssl" in options else "", options["--ip"], options["--ipport"], options["--api-version"], cmd) ++ url = "http%s://%s:%s/v%s/%s" % ("s" if "--ssl-secure" in options or "--ssl-insecure" in options else "", options["--ip"], options["--ipport"], options["--api-version"], cmd) + conn = pycurl.Curl() + output_buffer = io.BytesIO() + if logging.getLogger().getEffectiveLevel() < logging.WARNING: +@@ -55,7 +55,8 @@ def send_cmd(options, cmd, post = False): + conn.setopt(pycurl.POSTFIELDSIZE, 0) + conn.setopt(pycurl.WRITEFUNCTION, output_buffer.write) + conn.setopt(pycurl.TIMEOUT, int(options["--shell-timeout"])) +- if "--ssl" in options: ++ ++ if "--ssl-secure" in options: + if not (set(("--tlscert", "--tlskey", "--tlscacert")) <= set(options)): + fail_usage("Failed. If --ssl option is used, You have to also \ + specify: --tlscert, --tlskey and --tlscacert") +@@ -63,7 +64,7 @@ def send_cmd(options, cmd, post = False): + conn.setopt(pycurl.SSLCERT, options["--tlscert"]) + conn.setopt(pycurl.SSLKEY, options["--tlskey"]) + conn.setopt(pycurl.CAINFO, options["--tlscacert"]) +- else: ++ elif "--ssl-insecure" in options: + conn.setopt(pycurl.SSL_VERIFYPEER, 0) + conn.setopt(pycurl.SSL_VERIFYHOST, 0) + +@@ -136,6 +137,8 @@ def main(): + + device_opt = ["ipaddr", "no_password", "no_login", "port", "method", "web", "tlscert", "tlskey", "tlscacert", "ssl", "api_version"] + ++ all_opt["ssl"]["default"] = "1" ++ + options = check_input(device_opt, process_input(device_opt)) + + docs = { } +diff --git a/agents/ibmz/fence_ibmz.py b/agents/ibmz/fence_ibmz.py +index 47408ccf4..d477adeb9 100644 +--- a/agents/ibmz/fence_ibmz.py ++++ b/agents/ibmz/fence_ibmz.py +@@ -534,7 +534,7 @@ def main(): + requests_log.propagate = True + if "--verbose" in options: + requests_log.setLevel(logging.DEBUG) +- if "--ssl-secure" not in options: ++ if "--ssl-insecure" in options: + urllib3.disable_warnings( + category=urllib3.exceptions.InsecureRequestWarning) + +@@ -548,7 +548,7 @@ def main(): + 'connect_timeout': int(options['--connect-timeout']), + 'read_timeout': int(options['--read-timeout']), + 'port': int(options['--ipport']), +- 'ssl_verify': bool('--ssl-secure' in options), ++ 'ssl_verify': bool('--ssl-insecure' not in options), + } + try: + conn = APIClient(hmc_address, hmc_userid, hmc_password, config) +diff --git a/agents/rhevm/fence_rhevm.py b/agents/rhevm/fence_rhevm.py +index 25aecbe58..5f74d06f6 100644 +--- a/agents/rhevm/fence_rhevm.py ++++ b/agents/rhevm/fence_rhevm.py +@@ -85,7 +85,7 @@ def send_command(opt, command, method="GET"): + logging.debug("auto-detected API version: " + opt["--api-version"]) + + ## setup correct URL +- if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt: ++ if "--ssl-secure" in opt or "--ssl-insecure" in opt: + url = "https:" + else: + url = "http:" +@@ -126,11 +126,11 @@ def send_command(opt, command, method="GET"): + conn.setopt(pycurl.COOKIEJAR, cookie_file) + + conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"])) +- if "--ssl" in opt or "--ssl-secure" in opt: ++ ++ if "--ssl-secure" in opt: + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) +- +- if "--ssl-insecure" in opt: ++ elif "--ssl-insecure" in opt: + conn.setopt(pycurl.SSL_VERIFYPEER, 0) + conn.setopt(pycurl.SSL_VERIFYHOST, 0) + +diff --git a/agents/skalar/fence_skalar.py b/agents/skalar/fence_skalar.py +index 959527411..0e11d83f9 100644 +--- a/agents/skalar/fence_skalar.py ++++ b/agents/skalar/fence_skalar.py +@@ -200,7 +200,7 @@ def main(): + run_delay(options) + + proto = "https://" +- if "--ssl" in options or "--ssl-secure" in options: ++ if "--ssl-secure" in options: + ssl_verify = True + elif "--ssl-insecure" in options: + ssl_verify = False +diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py +index e49fd5663..4b884fc62 100644 +--- a/agents/vmware_rest/fence_vmware_rest.py ++++ b/agents/vmware_rest/fence_vmware_rest.py +@@ -69,7 +69,7 @@ def connect(opt): + conn = pycurl.Curl() + + ## setup correct URL +- if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt: ++ if "--ssl-secure" in opt or "--ssl-insecure" in opt: + conn.base_url = "https:" + else: + conn.base_url = "http:" +@@ -89,11 +89,11 @@ def connect(opt): + conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"]) + + conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"])) +- if "--ssl" in opt or "--ssl-secure" in opt: ++ ++ if "--ssl-secure" in opt: + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) +- +- if "--ssl-insecure" in opt: ++ elif "--ssl-insecure" in opt: + conn.setopt(pycurl.SSL_VERIFYPEER, 0) + conn.setopt(pycurl.SSL_VERIFYHOST, 0) + +diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py +index 2cd45e0b3..51fb0f147 100644 +--- a/agents/vmware_soap/fence_vmware_soap.py ++++ b/agents/vmware_soap/fence_vmware_soap.py +@@ -34,7 +34,7 @@ def send(self, request): + def soap_login(options): + run_delay(options) + +- if "--ssl" in options or "--ssl-secure" in options or "--ssl-insecure" in options: ++ if "--ssl-secure" in options or "--ssl-insecure" in options: + if "--ssl-insecure" in options: + import ssl + import urllib3 +diff --git a/agents/vmware_vcloud/fence_vmware_vcloud.py b/agents/vmware_vcloud/fence_vmware_vcloud.py +index 42372a83d..7626b82bb 100644 +--- a/agents/vmware_vcloud/fence_vmware_vcloud.py ++++ b/agents/vmware_vcloud/fence_vmware_vcloud.py +@@ -60,7 +60,7 @@ def connect(opt): + conn = pycurl.Curl() + + ## setup correct URL +- if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt: ++ if "--ssl-secure" in opt or "--ssl-insecure" in opt: + conn.base_url = "https:" + else: + conn.base_url = "http:" +@@ -76,7 +76,7 @@ def connect(opt): + conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"]) + + conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"])) +- if "--ssl" in opt or "--ssl-secure" in opt: ++ if "--ssl-secure" in opt: + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) + elif "--ssl-insecure" in opt: +diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py +index e8f849eda..90ca95d45 100644 +--- a/agents/zvm/fence_zvmip.py ++++ b/agents/zvm/fence_zvmip.py +@@ -26,7 +26,7 @@ def open_socket(options): + except socket.gaierror: + fail(EC_LOGIN_DENIED) + +- if "--ssl" in options: ++ if "--ssl-secure" in options or "--ssl-insecure" in options: + import ssl + sock = socket.socket() + sslcx = ssl.create_default_context() +@@ -132,7 +132,7 @@ 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 ++ recvflag = socket.MSG_WAITALL if "--ssl-secure" not in options and "--ssl-insecure" not in options else 0 + array_len = struct.unpack("!i", conn.recv(INT4))[0] + data = "" + +@@ -182,7 +182,9 @@ def main(): + options = check_input(device_opt, process_input(device_opt), other_conditions=True) + + if "--disable-ssl" in options or options["--ssl"] == "0": +- del options["--ssl"] ++ for k in ["--ssl", "--ssl-secure", "--ssl-insecure"]: ++ if k in options: ++ del options[k] + + if len(options.get("--plug", "")) > 8: + fail_usage("Failed: Name of image can not be longer than 8 characters") +diff --git a/lib/fencing.py.py b/lib/fencing.py.py +index 696388d55..b746ede8b 100644 +--- a/lib/fencing.py.py ++++ b/lib/fencing.py.py +@@ -789,6 +789,12 @@ def check_input(device_opt, opt, other_conditions = False): + if "--password-script" in options: + options["--password"] = os.popen(options["--password-script"]).read().rstrip() + ++ if "--ssl-secure" in options or "--ssl-insecure" in options: ++ options["--ssl"] = "" ++ ++ if "--ssl" in options and "--ssl-insecure" not in options: ++ options["--ssl-secure"] = "" ++ + if os.environ.get("PCMK_service") == "pacemaker-fenced" and "--disable-timeout" not in options: + options["--disable-timeout"] = "1" + +diff --git a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml +index 723e72280..51c7c470a 100644 +--- a/tests/data/metadata/fence_docker.xml ++++ b/tests/data/metadata/fence_docker.xml +@@ -20,7 +20,7 @@ + </parameter> + <parameter name="ipport" unique="0" required="0"> + <getopt mixed="-u, --ipport=[port]" /> +- <content type="integer" default="80" /> ++ <content type="integer" default="443" /> + <shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc> + </parameter> + <parameter name="method" unique="0" required="0"> +@@ -43,7 +43,7 @@ + </parameter> + <parameter name="ssl" unique="0" required="0"> + <getopt mixed="-z, --ssl" /> +- <content type="boolean" /> ++ <content type="boolean" default="1" /> + <shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc> + </parameter> + <parameter name="ssl_insecure" unique="0" required="0"> diff --git a/bz2072420-2-fence_zvmip-connect-error.patch b/bz2072420-2-fence_zvmip-connect-error.patch new file mode 100644 index 0000000..1a1bd97 --- /dev/null +++ b/bz2072420-2-fence_zvmip-connect-error.patch @@ -0,0 +1,30 @@ +From 6430104318b4bf349425b08636183bf839812e04 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Tue, 31 May 2022 08:55:25 +0200 +Subject: [PATCH] fence_zvmip: show unable to connect error instead of full + stacktrace, e.g. when not using --ssl for SSL devices + +--- + agents/zvm/fence_zvmip.py | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py +index 90ca95d45..4f538e10d 100644 +--- a/agents/zvm/fence_zvmip.py ++++ b/agents/zvm/fence_zvmip.py +@@ -127,8 +127,13 @@ def get_list_of_images(options, command, data_as_plug): + + conn.send(packet) + +- request_id = struct.unpack("!i", conn.recv(INT4))[0] +- (output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4)) ++ try: ++ request_id = struct.unpack("!i", conn.recv(INT4))[0] ++ (output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4)) ++ except struct.error: ++ logging.debug(sys.exc_info()) ++ fail_usage("Failed: Unable to connect to {} port: {} SSL: {} \n".format(options["--ip"], options["--ipport"], bool("--ssl" in options))) ++ + images = set() + + if output_len > 3*INT4: diff --git a/bz2079889-fence_gce-update.patch b/bz2079889-fence_gce-update.patch new file mode 100644 index 0000000..97e5193 --- /dev/null +++ b/bz2079889-fence_gce-update.patch @@ -0,0 +1,410 @@ +--- fence-agents-4.10.0/agents/gce/fence_gce.py 2022-04-29 10:13:50.317888041 +0200 ++++ fence-agents-4.10.0/agents/gce/fence_gce.py2 2022-04-29 10:17:54.813248566 +0200 +@@ -2,10 +2,10 @@ + + # + # Requires the googleapiclient and oauth2client +-# RHEL 7.x: google-api-python-client==1.6.7 python-gflags==2.0 pyasn1==0.4.8 rsa==3.4.2 +-# RHEL 8.x: nothing additional needed +-# SLES 12.x: python-google-api-python-client python-oauth2client python-oauth2client-gce +-# SLES 15.x: python3-google-api-python-client python3-oauth2client python3-oauth2client-gce ++# RHEL 7.x: google-api-python-client==1.6.7 python-gflags==2.0 pyasn1==0.4.8 rsa==3.4.2 pysocks==1.7.1 httplib2==0.19.0 ++# RHEL 8.x: pysocks==1.7.1 httplib2==0.19.0 ++# SLES 12.x: python-google-api-python-client python-oauth2client python-oauth2client-gce pysocks==1.7.1 httplib2==0.19.0 ++# SLES 15.x: python3-google-api-python-client python3-oauth2client pysocks==1.7.1 httplib2==0.19.0 + # + + import atexit +@@ -27,7 +27,7 @@ + import urllib2 as urlrequest + sys.path.append("@FENCEAGENTSLIBDIR@") + +-from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action ++from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action, run_command + try: + sys.path.insert(0, '/usr/lib/fence-agents/support/google') + import httplib2 +@@ -42,6 +42,19 @@ + + METADATA_SERVER = 'http://metadata.google.internal/computeMetadata/v1/' + METADATA_HEADERS = {'Metadata-Flavor': 'Google'} ++INSTANCE_LINK = 'https://www.googleapis.com/compute/v1/projects/{}/zones/{}/instances/{}' ++ ++def run_on_fail(options): ++ if "--runonfail" in options: ++ run_command(options, options["--runonfail"]) ++ ++def fail_fence_agent(options, message): ++ run_on_fail(options) ++ fail_usage(message) ++ ++def raise_fence_agent(options, message): ++ run_on_fail(options) ++ raise Exception(message) + + # + # Will use baremetalsolution setting or the environment variable +@@ -66,7 +79,7 @@ + { + "matchlength": 4, + "match": "https://compute.googleapis.com/compute/v1/projects/(.*)/zones/(.*)/instances/(.*)/reset(.*)", +- "replace": "https://baremetalsolution.googleapis.com/v1alpha1/projects/\\1/locations/\\2/instances/\\3:resetInstance\\4" ++ "replace": "https://baremetalsolution.googleapis.com/v1/projects/\\1/locations/\\2/instances/\\3:resetInstance\\4" + }) + for uri_replacement in uri_replacements: + # each uri_replacement should have matchlength, match, and replace +@@ -121,14 +134,17 @@ + + def get_nodes_list(conn, options): + result = {} ++ if "--zone" not in options: ++ fail_fence_agent(options, "Failed: get_nodes_list: Please specify the --zone in the command") + try: +- instanceList = retry_api_execute(options, conn.instances().list( +- project=options["--project"], +- zone=options["--zone"])) +- for instance in instanceList["items"]: +- result[instance["id"]] = (instance["name"], translate_status(instance["status"])) ++ for zone in options["--zone"].split(","): ++ instanceList = retry_api_execute(options, conn.instances().list( ++ project=options["--project"], ++ zone=zone)) ++ for instance in instanceList["items"]: ++ result[instance["id"]] = (instance["name"], translate_status(instance["status"])) + except Exception as err: +- fail_usage("Failed: get_nodes_list: {}".format(str(err))) ++ fail_fence_agent(options, "Failed: get_nodes_list: {}".format(str(err))) + + return result + +@@ -142,23 +158,54 @@ + return "off" + else: + return "on" ++ # If zone is not listed for an entry we attempt to get it automatically ++ instance = options["--plug"] ++ zone = get_zone(conn, options, instance) if "--plugzonemap" not in options else options["--plugzonemap"][instance] ++ instance_status = get_instance_power_status(conn, options, instance, zone) ++ # If any of the instances do not match the intended status we return the ++ # the opposite status so that the fence agent can change it. ++ if instance_status != options.get("--action"): ++ return instance_status ++ ++ return options.get("--action") ++ ++ ++def get_instance_power_status(conn, options, instance, zone): + try: +- instance = retry_api_execute(options, conn.instances().get( +- project=options["--project"], +- zone=options["--zone"], +- instance=options["--plug"])) ++ instance = retry_api_execute( ++ options, ++ conn.instances().get(project=options["--project"], zone=zone, instance=instance)) + return translate_status(instance["status"]) + except Exception as err: +- fail_usage("Failed: get_power_status: {}".format(str(err))) ++ fail_fence_agent(options, "Failed: get_instance_power_status: {}".format(str(err))) + + +-def wait_for_operation(conn, options, operation): ++def check_for_existing_operation(conn, options, instance, zone, operation_type): ++ logging.debug("check_for_existing_operation") ++ if "--baremetalsolution" in options: ++ # There is no API for checking in progress operations ++ return False ++ ++ project = options["--project"] ++ target_link = INSTANCE_LINK.format(project, zone, instance) ++ query_filter = '(targetLink = "{}") AND (operationType = "{}") AND (status = "RUNNING")'.format(target_link, operation_type) ++ result = retry_api_execute( ++ options, ++ conn.zoneOperations().list(project=project, zone=zone, filter=query_filter, maxResults=1)) ++ ++ if "items" in result and result["items"]: ++ logging.info("Existing %s operation found", operation_type) ++ return result["items"][0] ++ ++ ++def wait_for_operation(conn, options, zone, operation): + if 'name' not in operation: + logging.warning('Cannot wait for operation to complete, the' + ' requested operation will continue asynchronously') +- return ++ return False ++ ++ wait_time = 0 + project = options["--project"] +- zone = options["--zone"] + while True: + result = retry_api_execute(options, conn.zoneOperations().get( + project=project, +@@ -166,56 +213,93 @@ + operation=operation['name'])) + if result['status'] == 'DONE': + if 'error' in result: +- raise Exception(result['error']) +- return ++ raise_fence_agent(options, result['error']) ++ return True ++ ++ if "--errortimeout" in options and wait_time > int(options["--errortimeout"]): ++ raise_fence_agent(options, "Operation did not complete before the timeout.") ++ ++ if "--warntimeout" in options and wait_time > int(options["--warntimeout"]): ++ logging.warning("Operation did not complete before the timeout.") ++ if "--runonwarn" in options: ++ run_command(options, options["--runonwarn"]) ++ return False ++ ++ wait_time = wait_time + 1 + time.sleep(1) + + + def set_power_status(conn, options): +- logging.debug("set_power_status"); ++ logging.debug("set_power_status") ++ instance = options["--plug"] ++ # If zone is not listed for an entry we attempt to get it automatically ++ zone = get_zone(conn, options, instance) if "--plugzonemap" not in options else options["--plugzonemap"][instance] ++ set_instance_power_status(conn, options, instance, zone, options["--action"]) ++ ++ ++def set_instance_power_status(conn, options, instance, zone, action): ++ logging.info("Setting power status of %s in zone %s", instance, zone) ++ project = options["--project"] ++ + try: +- if options["--action"] == "off": +- logging.info("Issuing poweroff of %s in zone %s" % (options["--plug"], options["--zone"])) +- operation = retry_api_execute(options, conn.instances().stop( +- project=options["--project"], +- zone=options["--zone"], +- instance=options["--plug"])) ++ if action == "off": ++ logging.info("Issuing poweroff of %s in zone %s", instance, zone) ++ operation = check_for_existing_operation(conn, options, instance, zone, "stop") ++ if operation and "--earlyexit" in options: ++ return ++ if not operation: ++ operation = retry_api_execute( ++ options, ++ conn.instances().stop(project=project, zone=zone, instance=instance)) + logging.info("Poweroff command completed, waiting for the operation to complete") +- wait_for_operation(conn, options, operation) +- logging.info("Poweroff of %s in zone %s complete" % (options["--plug"], options["--zone"])) +- elif options["--action"] == "on": +- logging.info("Issuing poweron of %s in zone %s" % (options["--plug"], options["--zone"])) +- operation = retry_api_execute(options, conn.instances().start( +- project=options["--project"], +- zone=options["--zone"], +- instance=options["--plug"])) +- wait_for_operation(conn, options, operation) +- logging.info("Poweron of %s in zone %s complete" % (options["--plug"], options["--zone"])) ++ if wait_for_operation(conn, options, zone, operation): ++ logging.info("Poweroff of %s in zone %s complete", instance, zone) ++ elif action == "on": ++ logging.info("Issuing poweron of %s in zone %s", instance, zone) ++ operation = check_for_existing_operation(conn, options, instance, zone, "start") ++ if operation and "--earlyexit" in options: ++ return ++ if not operation: ++ operation = retry_api_execute( ++ options, ++ conn.instances().start(project=project, zone=zone, instance=instance)) ++ if wait_for_operation(conn, options, zone, operation): ++ logging.info("Poweron of %s in zone %s complete", instance, zone) + except Exception as err: +- fail_usage("Failed: set_power_status: {}".format(str(err))) +- ++ fail_fence_agent(options, "Failed: set_instance_power_status: {}".format(str(err))) + + def power_cycle(conn, options): +- logging.debug("power_cycle"); ++ logging.debug("power_cycle") ++ instance = options["--plug"] ++ # If zone is not listed for an entry we attempt to get it automatically ++ zone = get_zone(conn, options, instance) if "--plugzonemap" not in options else options["--plugzonemap"][instance] ++ return power_cycle_instance(conn, options, instance, zone) ++ ++ ++def power_cycle_instance(conn, options, instance, zone): ++ logging.info("Issuing reset of %s in zone %s", instance, zone) ++ project = options["--project"] ++ + try: +- logging.info('Issuing reset of %s in zone %s' % (options["--plug"], options["--zone"])) +- operation = retry_api_execute(options, conn.instances().reset( +- project=options["--project"], +- zone=options["--zone"], +- instance=options["--plug"])) +- logging.info("Reset command completed, waiting for the operation to complete") +- wait_for_operation(conn, options, operation) +- logging.info('Reset of %s in zone %s complete' % (options["--plug"], options["--zone"])) ++ operation = check_for_existing_operation(conn, options, instance, zone, "reset") ++ if operation and "--earlyexit" in options: ++ return True ++ if not operation: ++ operation = retry_api_execute( ++ options, ++ conn.instances().reset(project=project, zone=zone, instance=instance)) ++ logging.info("Reset command sent, waiting for the operation to complete") ++ if wait_for_operation(conn, options, zone, operation): ++ logging.info("Reset of %s in zone %s complete", instance, zone) + return True + except Exception as err: +- logging.error("Failed: power_cycle: {}".format(str(err))) +- return False ++ logging.exception("Failed: power_cycle") ++ raise err + + +-def get_zone(conn, options): ++def get_zone(conn, options, instance): + logging.debug("get_zone"); + project = options['--project'] +- instance = options['--plug'] + fl = 'name="%s"' % instance + request = replace_api_uri(options, conn.instances().aggregatedList(project=project, filter=fl)) + while request is not None: +@@ -227,7 +311,7 @@ + return inst['zone'].split("/")[-1] + request = replace_api_uri(options, conn.instances().aggregatedList_next( + previous_request=request, previous_response=response)) +- raise Exception("Unable to find instance %s" % (instance)) ++ raise_fence_agent(options, "Unable to find instance %s" % (instance)) + + + def get_metadata(metadata_key, params=None, timeout=None): +@@ -326,13 +410,21 @@ + "required" : "0", + "order" : 9 + } ++ all_opt["plugzonemap"] = { ++ "getopt" : ":", ++ "longopt" : "plugzonemap", ++ "help" : "--plugzonemap=[plugzonemap] Comma separated zone map when fencing multiple plugs", ++ "shortdesc" : "Comma separated zone map when fencing multiple plugs.", ++ "required" : "0", ++ "order" : 10 ++ } + 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 ++ "order" : 11 + } + all_opt["proxyport"] = { + "getopt" : ":", +@@ -341,7 +433,49 @@ + "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 ++ "order" : 12 ++ } ++ all_opt["earlyexit"] = { ++ "getopt" : "", ++ "longopt" : "earlyexit", ++ "help" : "--earlyexit Return early if reset is already in progress", ++ "shortdesc" : "If an existing reset operation is detected, the fence agent will return before the operation completes with a 0 return code.", ++ "required" : "0", ++ "order" : 13 ++ } ++ all_opt["warntimeout"] = { ++ "getopt" : ":", ++ "type" : "second", ++ "longopt" : "warntimeout", ++ "help" : "--warntimeout=[warn_timeout] Timeout seconds before logging a warning and returning a 0 status code", ++ "shortdesc" : "If the operation is not completed within the timeout, the cluster operations are allowed to continue.", ++ "required" : "0", ++ "order" : 14 ++ } ++ all_opt["errortimeout"] = { ++ "getopt" : ":", ++ "type" : "second", ++ "longopt" : "errortimeout", ++ "help" : "--errortimeout=[error_timeout] Timeout seconds before failing and returning a non-zero status code", ++ "shortdesc" : "If the operation is not completed within the timeout, cluster is notified of the operation failure.", ++ "required" : "0", ++ "order" : 15 ++ } ++ all_opt["runonwarn"] = { ++ "getopt" : ":", ++ "longopt" : "runonwarn", ++ "help" : "--runonwarn=[run_on_warn] If a timeout occurs and warning is generated, run the supplied command", ++ "shortdesc" : "If a timeout would occur while running the agent, then the supplied command is run.", ++ "required" : "0", ++ "order" : 16 ++ } ++ all_opt["runonfail"] = { ++ "getopt" : ":", ++ "longopt" : "runonfail", ++ "help" : "--runonfail=[run_on_fail] If a failure occurs, run the supplied command", ++ "shortdesc" : "If a failure would occur while running the agent, then the supplied command is run.", ++ "required" : "0", ++ "order" : 17 + } + + +@@ -350,7 +484,8 @@ + + device_opt = ["port", "no_password", "zone", "project", "stackdriver-logging", + "method", "baremetalsolution", "apitimeout", "retries", "retrysleep", +- "serviceaccount", "proxyhost", "proxyport"] ++ "serviceaccount", "plugzonemap", "proxyhost", "proxyport", "earlyexit", ++ "warntimeout", "errortimeout", "runonwarn", "runonfail"] + + atexit.register(atexit_handler) + +@@ -431,22 +566,39 @@ + 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))) ++ fail_fence_agent(options, "Failed: Create GCE compute v1 connection: {}".format(str(err))) + + # Get project and zone + if not options.get("--project"): + try: + options["--project"] = get_metadata('project/project-id') + except Exception as err: +- fail_usage("Failed retrieving GCE project. Please provide --project option: {}".format(str(err))) ++ fail_fence_agent(options, "Failed retrieving GCE project. Please provide --project option: {}".format(str(err))) + + if "--baremetalsolution" in options: + options["--zone"] = "none" +- if not options.get("--zone"): +- try: +- options["--zone"] = get_zone(conn, options) +- except Exception as err: +- fail_usage("Failed retrieving GCE zone. Please provide --zone option: {}".format(str(err))) ++ ++ # Populates zone automatically if missing from the command ++ zones = [] if not "--zone" in options else options["--zone"].split(",") ++ options["--plugzonemap"] = {} ++ if "--plug" in options: ++ for i, instance in enumerate(options["--plug"].split(",")): ++ if len(zones) == 1: ++ # If only one zone is specified, use it across all plugs ++ options["--plugzonemap"][instance] = zones[0] ++ continue ++ ++ if len(zones) - 1 >= i: ++ # If we have enough zones specified with the --zone flag use the zone at ++ # the same index as the plug ++ options["--plugzonemap"][instance] = zones[i] ++ continue ++ ++ try: ++ # In this case we do not have a zone specified so we attempt to detect it ++ options["--plugzonemap"][instance] = get_zone(conn, options, instance) ++ except Exception as err: ++ fail_fence_agent(options, "Failed retrieving GCE zone. Please provide --zone option: {}".format(str(err))) + + # Operate the fencing device + result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list, power_cycle) diff --git a/bz2081235-fence_ibm_vpc-fix-parameters.patch b/bz2081235-fence_ibm_vpc-fix-parameters.patch new file mode 100644 index 0000000..5e031ad --- /dev/null +++ b/bz2081235-fence_ibm_vpc-fix-parameters.patch @@ -0,0 +1,65 @@ +From d0254345472c9415af1e06e9e8df2fe0ce464db0 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 2 May 2022 11:14:42 +0200 +Subject: [PATCH] fence_ibm_vpc: remove unused instance parameter and make + limit optional + +--- + agents/ibm_vpc/fence_ibm_vpc.py | 11 +---------- + tests/data/metadata/fence_ibm_vpc.xml | 7 +------ + 2 files changed, 2 insertions(+), 16 deletions(-) + +diff --git a/agents/ibm_vpc/fence_ibm_vpc.py b/agents/ibm_vpc/fence_ibm_vpc.py +index 9f84f7b2d..9e38e8301 100755 +--- a/agents/ibm_vpc/fence_ibm_vpc.py ++++ b/agents/ibm_vpc/fence_ibm_vpc.py +@@ -161,14 +161,6 @@ def define_new_opts(): + "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", +@@ -181,7 +173,7 @@ def define_new_opts(): + "getopt" : ":", + "longopt" : "limit", + "help" : "--limit=[number] Limit number of nodes returned by API", +- "required" : "1", ++ "required" : "0", + "default": 50, + "shortdesc" : "Number of nodes returned by API", + "order" : 0 +@@ -191,7 +183,6 @@ def define_new_opts(): + def main(): + device_opt = [ + "apikey", +- "instance", + "region", + "limit", + "port", +diff --git a/tests/data/metadata/fence_ibm_vpc.xml b/tests/data/metadata/fence_ibm_vpc.xml +index 926efcaa0..ee7151673 100644 +--- a/tests/data/metadata/fence_ibm_vpc.xml ++++ b/tests/data/metadata/fence_ibm_vpc.xml +@@ -8,12 +8,7 @@ + <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"> ++ <parameter name="limit" unique="0" required="0"> + <getopt mixed="--limit=[number]" /> + <content type="string" default="50" /> + <shortdesc lang="en">Number of nodes returned by API</shortdesc> diff --git a/bz2086559-fence_apc-fence_ilo_moonshot-import-logging.patch b/bz2086559-fence_apc-fence_ilo_moonshot-import-logging.patch new file mode 100644 index 0000000..dbbde08 --- /dev/null +++ b/bz2086559-fence_apc-fence_ilo_moonshot-import-logging.patch @@ -0,0 +1,34 @@ +From 6ea2c6b5d1cc51e93fa7084d76d9272512461e58 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 16 May 2022 11:01:21 +0200 +Subject: [PATCH] fence_apc/fence_ilo_moonshot: add missing "import logging" + +--- + agents/apc/fence_apc.py | 1 + + agents/ilo_moonshot/fence_ilo_moonshot.py | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/agents/apc/fence_apc.py b/agents/apc/fence_apc.py +index 901aad25e..3ea0f37d6 100644 +--- a/agents/apc/fence_apc.py ++++ b/agents/apc/fence_apc.py +@@ -15,6 +15,7 @@ + ##### + + import sys, re, time ++import logging + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +diff --git a/agents/ilo_moonshot/fence_ilo_moonshot.py b/agents/ilo_moonshot/fence_ilo_moonshot.py +index 6f5cca320..1923eeb1c 100644 +--- a/agents/ilo_moonshot/fence_ilo_moonshot.py ++++ b/agents/ilo_moonshot/fence_ilo_moonshot.py +@@ -1,6 +1,7 @@ + #!@PYTHON@ -tt + + import sys ++import logging + import atexit + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * diff --git a/bz2092385-fence_ibm_vpc-add-proxy-support.patch b/bz2092385-fence_ibm_vpc-add-proxy-support.patch new file mode 100644 index 0000000..39a2e2e --- /dev/null +++ b/bz2092385-fence_ibm_vpc-add-proxy-support.patch @@ -0,0 +1,62 @@ +From be409554bbc99df2bba22cb01e8a6df634af896d Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Tue, 31 May 2022 15:46:40 +0200 +Subject: [PATCH] fence_ibm_vpc: add proxy support + +--- + agents/ibm_vpc/fence_ibm_vpc.py | 11 +++++++++++ + tests/data/metadata/fence_ibm_vpc.xml | 5 +++++ + 2 files changed, 16 insertions(+) + +diff --git a/agents/ibm_vpc/fence_ibm_vpc.py b/agents/ibm_vpc/fence_ibm_vpc.py +index 9e38e8301..3da3ce056 100755 +--- a/agents/ibm_vpc/fence_ibm_vpc.py ++++ b/agents/ibm_vpc/fence_ibm_vpc.py +@@ -88,6 +88,7 @@ def connect(opt): + conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"])) + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) ++ conn.setopt(pycurl.PROXY, "{}".format(opt["--proxy"])) + + # get bearer token + bearer_token = get_bearer_token(conn, opt) +@@ -169,6 +170,15 @@ def define_new_opts(): + "shortdesc" : "Region", + "order" : 0 + } ++ all_opt["proxy"] = { ++ "getopt" : ":", ++ "longopt" : "proxy", ++ "help" : "--proxy=[http://<URL>:<PORT>] Proxy: 'http://<URL>:<PORT>'", ++ "required" : "0", ++ "default": "", ++ "shortdesc" : "Network proxy", ++ "order" : 0 ++ } + all_opt["limit"] = { + "getopt" : ":", + "longopt" : "limit", +@@ -185,6 +195,7 @@ def main(): + "apikey", + "region", + "limit", ++ "proxy", + "port", + "no_password", + ] +diff --git a/tests/data/metadata/fence_ibm_vpc.xml b/tests/data/metadata/fence_ibm_vpc.xml +index ee7151673..09da0e303 100644 +--- a/tests/data/metadata/fence_ibm_vpc.xml ++++ b/tests/data/metadata/fence_ibm_vpc.xml +@@ -13,6 +13,11 @@ + <content type="string" default="50" /> + <shortdesc lang="en">Number of nodes returned by API</shortdesc> + </parameter> ++ <parameter name="proxy" unique="0" required="0"> ++ <getopt mixed="--proxy=[http://<URL>:<PORT>]" /> ++ <content type="string" default="" /> ++ <shortdesc lang="en">Network proxy</shortdesc> ++ </parameter> + <parameter name="region" unique="0" required="1"> + <getopt mixed="--region=[region]" /> + <content type="string" /> diff --git a/bz2093216-fence_ibm_powervs-proxy-private-api-servers.patch b/bz2093216-fence_ibm_powervs-proxy-private-api-servers.patch new file mode 100644 index 0000000..36f07fc --- /dev/null +++ b/bz2093216-fence_ibm_powervs-proxy-private-api-servers.patch @@ -0,0 +1,455 @@ +From 98fec5c6d55369ad681abc0cde0d8677835957ab Mon Sep 17 00:00:00 2001 +From: Arnold Beilmann <arnoldbeilmann@macbook-pro.speedport.ip> +Date: Thu, 5 May 2022 15:26:22 +0200 +Subject: [PATCH 1/2] modified for PowerVS + +--- + agents/ibm_powervs/fence_ibm_powervs.py | 108 +++++++++++++++++++----- + 1 file changed, 89 insertions(+), 19 deletions(-) + +diff --git a/agents/ibm_powervs/fence_ibm_powervs.py b/agents/ibm_powervs/fence_ibm_powervs.py +index 6649771ea..727009220 100755 +--- a/agents/ibm_powervs/fence_ibm_powervs.py ++++ b/agents/ibm_powervs/fence_ibm_powervs.py +@@ -1,10 +1,11 @@ +-#!@PYTHON@ -tt ++#!/usr/libexec/platform-python -tt + + import sys + import pycurl, io, json + import logging + import atexit +-sys.path.append("@FENCEAGENTSLIBDIR@") ++import time ++sys.path.append("/usr/share/fence") + from fencing import * + from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS + +@@ -14,16 +15,30 @@ + "ERROR": "unknown" + } + ++def get_token(conn, options): ++ ++ try: ++ command = "identity/token" ++ action = "grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey&apikey={}".format(options["--token"]) ++ res = send_command(conn, command, "POST", action, printResult=False) ++ except Exception as e: ++ logging.debug("Failed: {}".format(e)) ++ return "TOKEN_IS_MISSING_OR_WRONG" ++ ++ #if "--verbose" in options: ++ # logging.debug(json.dumps(res, indent=2)) ++ ++ return res["access_token"] ++ + 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)) +@@ -32,6 +47,7 @@ def get_list(conn, options): + return outlets + + def get_power_status(conn, options): ++ + try: + command = "cloud-instances/{}/pvm-instances/{}".format( + options["--instance"], options["--plug"]) +@@ -40,10 +56,11 @@ def get_power_status(conn, options): + 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"}', +@@ -56,35 +73,63 @@ def set_power_status(conn, options): + logging.debug("Failed: Unable to set power to {} for {}".format(options["--action"], e)) + fail(EC_STATUS) + +-def connect(opt): ++def connect(opt, token): + conn = pycurl.Curl() + + ## setup correct URL +- conn.base_url = "https://" + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/" ++ conn.base_url = "https://private." + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/" ++ if opt["--api-type"] == "public": ++ 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.VERBOSE, 0) + ++ conn.setopt(pycurl.CONNECTTIMEOUT,int(opt["--shell-timeout"])) + conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"])) + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) ++ conn.setopt(pycurl.PROXY, "{}".format(opt["--proxy"])) + + # set auth token for later requests + conn.setopt(pycurl.HTTPHEADER, [ + "Content-Type: application/json", +- "Authorization: Bearer {}".format(opt["--token"]), ++ "Authorization: Bearer {}".format(token), + "CRN: {}".format(opt["--crn"]), + "User-Agent: curl", + ]) ++ ++ return conn ++ ++def auth_connect(opt): ++ conn = pycurl.Curl() ++ ++ # setup correct URL ++ conn.base_url = "https://iam.cloud.ibm.com/" ++ ++ if opt["--verbose-level"] > 1: ++ conn.setopt(pycurl.VERBOSE, 1) ++ ++ conn.setopt(pycurl.CONNECTTIMEOUT,int(opt["--shell-timeout"])) ++ conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"])) ++ conn.setopt(pycurl.SSL_VERIFYPEER, 1) ++ conn.setopt(pycurl.SSL_VERIFYHOST, 2) ++ conn.setopt(pycurl.PROXY, "{}".format(opt["--proxy"])) ++ ++ # set auth token for later requests ++ conn.setopt(pycurl.HTTPHEADER, [ ++ "Content-type: application/x-www-form-urlencoded", ++ "Accept: application/json", ++ "User-Agent: curl", ++ ]) + + return conn + + def disconnect(conn): + conn.close() + +-def send_command(conn, command, method="GET", action=None): ++def send_command(conn, command, method="GET", action=None, printResult=True): + url = conn.base_url + command +- ++ + conn.setopt(pycurl.URL, url.encode("ascii")) + + web_buffer = io.BytesIO() +@@ -99,8 +144,10 @@ def send_command(conn, command, method="GET", action=None): + conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write) + + try: ++ time.sleep(3) + conn.perform() + except Exception as e: ++ logging.error("ADD_DEBUG: {}".format(e)) + raise(e) + + rc = conn.getinfo(pycurl.HTTP_CODE) +@@ -110,8 +157,7 @@ def send_command(conn, command, method="GET", action=None): + + if rc != 200: + if len(result) > 0: +- raise Exception("{}: {}".format(rc, +- result["value"]["messages"][0]["default_message"])) ++ raise Exception("{}: {}".format(rc,result)) + else: + raise Exception("Remote returned {} for request to {}".format(rc, url)) + +@@ -121,7 +167,8 @@ def send_command(conn, command, method="GET", action=None): + logging.debug("url: {}".format(url)) + logging.debug("method: {}".format(method)) + logging.debug("response code: {}".format(rc)) +- logging.debug("result: {}\n".format(result)) ++ if printResult: ++ logging.debug("result: {}\n".format(result)) + + return result + +@@ -129,9 +176,9 @@ def define_new_opts(): + all_opt["token"] = { + "getopt" : ":", + "longopt" : "token", +- "help" : "--token=[token] Bearer Token", ++ "help" : "--token=[token] API Token", + "required" : "1", +- "shortdesc" : "Bearer Token", ++ "shortdesc" : "API Token", + "order" : 0 + } + all_opt["crn"] = { +@@ -158,6 +205,22 @@ def define_new_opts(): + "shortdesc" : "Region", + "order" : 0 + } ++ all_opt["api-type"] = { ++ "getopt" : ":", ++ "longopt" : "api-type", ++ "help" : "--api-type=[private|public] API-type: 'private' (default) or 'public'", ++ "required" : "0", ++ "shortdesc" : "API-type (private|public)", ++ "order" : 0 ++ } ++ all_opt["proxy"] = { ++ "getopt" : ":", ++ "longopt" : "proxy", ++ "help" : "--proxy=[http://<URL>:<PORT>] Proxy: 'http://<URL>:<PORT>'", ++ "required" : "0", ++ "shortdesc" : "Network proxy", ++ "order" : 0 ++ } + + + def main(): +@@ -166,6 +229,8 @@ def main(): + "crn", + "instance", + "region", ++ "api-type", ++ "proxy", + "port", + "no_password", + ] +@@ -173,9 +238,11 @@ def main(): + atexit.register(atexit_handler) + define_new_opts() + +- all_opt["shell_timeout"]["default"] = "15" ++ all_opt["shell_timeout"]["default"] = "500" + all_opt["power_timeout"]["default"] = "30" + all_opt["power_wait"]["default"] = "1" ++ all_opt["api-type"]["default"] = "private" ++ all_opt["proxy"]["default"] = "" + + options = check_input(device_opt, process_input(device_opt)) + +@@ -190,8 +257,11 @@ def main(): + ## Fence operations + #### + run_delay(options) +- +- conn = connect(options) ++ ++ auth_conn = auth_connect(options) ++ token = get_token(auth_conn, options) ++ disconnect(auth_conn) ++ conn = connect(options, token) + atexit.register(disconnect, conn) + + result = fence_action(conn, options, set_power_status, get_power_status, get_list) + +From fbe9a539ac8f40686a8027b7e768d9f7b799e485 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Fri, 6 May 2022 11:22:47 +0200 +Subject: [PATCH 2/2] fence_ibm_powervs: cleanup and fixes + +--- + agents/ibm_powervs/fence_ibm_powervs.py | 37 ++++++++++------------- + tests/data/metadata/fence_ibm_powervs.xml | 19 ++++++++++-- + 2 files changed, 33 insertions(+), 23 deletions(-) + +diff --git a/agents/ibm_powervs/fence_ibm_powervs.py b/agents/ibm_powervs/fence_ibm_powervs.py +index 727009220..819ab8896 100755 +--- a/agents/ibm_powervs/fence_ibm_powervs.py ++++ b/agents/ibm_powervs/fence_ibm_powervs.py +@@ -1,11 +1,11 @@ +-#!/usr/libexec/platform-python -tt ++#!@PYTHON@ -tt + + import sys + import pycurl, io, json + import logging + import atexit + import time +-sys.path.append("/usr/share/fence") ++sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * + from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS + +@@ -16,7 +16,6 @@ + } + + def get_token(conn, options): +- + try: + command = "identity/token" + action = "grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey&apikey={}".format(options["--token"]) +@@ -25,20 +24,18 @@ def get_token(conn, options): + logging.debug("Failed: {}".format(e)) + return "TOKEN_IS_MISSING_OR_WRONG" + +- #if "--verbose" in options: +- # logging.debug(json.dumps(res, indent=2)) +- + return res["access_token"] + + 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)) +@@ -47,7 +44,6 @@ def get_list(conn, options): + return outlets + + def get_power_status(conn, options): +- + try: + command = "cloud-instances/{}/pvm-instances/{}".format( + options["--instance"], options["--plug"]) +@@ -56,11 +52,10 @@ def get_power_status(conn, options): + 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"}', +@@ -77,11 +72,11 @@ def connect(opt, token): + conn = pycurl.Curl() + + ## setup correct URL +- conn.base_url = "https://private." + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/" +- if opt["--api-type"] == "public": +- conn.base_url = "https://" + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/" ++ conn.base_url = "https://" + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/" ++ if opt["--api-type"] == "private": ++ conn.base_url = "https://private." + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/" + +- if opt["--verbose-level"] > 1: ++ if opt["--verbose-level"] < 3: + conn.setopt(pycurl.VERBOSE, 0) + + conn.setopt(pycurl.CONNECTTIMEOUT,int(opt["--shell-timeout"])) +@@ -129,7 +124,7 @@ def disconnect(conn): + + def send_command(conn, command, method="GET", action=None, printResult=True): + url = conn.base_url + command +- ++ + conn.setopt(pycurl.URL, url.encode("ascii")) + + web_buffer = io.BytesIO() +@@ -144,10 +139,9 @@ def send_command(conn, command, method="GET", action=None, printResult=True): + conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write) + + try: +- time.sleep(3) + conn.perform() + except Exception as e: +- logging.error("ADD_DEBUG: {}".format(e)) ++ logging.error("send_command(): {}".format(e)) + raise(e) + + rc = conn.getinfo(pycurl.HTTP_CODE) +@@ -208,9 +202,9 @@ def define_new_opts(): + all_opt["api-type"] = { + "getopt" : ":", + "longopt" : "api-type", +- "help" : "--api-type=[private|public] API-type: 'private' (default) or 'public'", ++ "help" : "--api-type=[public|private] API-type: 'public' (default) or 'private'", + "required" : "0", +- "shortdesc" : "API-type (private|public)", ++ "shortdesc" : "API-type (public|private)", + "order" : 0 + } + all_opt["proxy"] = { +@@ -238,9 +232,10 @@ def main(): + atexit.register(atexit_handler) + define_new_opts() + +- all_opt["shell_timeout"]["default"] = "500" ++ all_opt["shell_timeout"]["default"] = "15" + all_opt["power_timeout"]["default"] = "30" + all_opt["power_wait"]["default"] = "1" ++ all_opt["stonith_status_sleep"]["default"] = "3" + all_opt["api-type"]["default"] = "private" + all_opt["proxy"]["default"] = "" + +@@ -257,7 +252,7 @@ def main(): + ## Fence operations + #### + run_delay(options) +- ++ + auth_conn = auth_connect(options) + token = get_token(auth_conn, options) + disconnect(auth_conn) +diff --git a/tests/data/metadata/fence_ibm_powervs.xml b/tests/data/metadata/fence_ibm_powervs.xml +index fe86331bd..81cea4379 100644 +--- a/tests/data/metadata/fence_ibm_powervs.xml ++++ b/tests/data/metadata/fence_ibm_powervs.xml +@@ -3,6 +3,16 @@ + <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="api-type" unique="0" required="0" deprecated="1"> ++ <getopt mixed="--api-type=[public|private]" /> ++ <content type="string" default="private" /> ++ <shortdesc lang="en">API-type (public|private)</shortdesc> ++ </parameter> ++ <parameter name="api_type" unique="0" required="0" obsoletes="api-type"> ++ <getopt mixed="--api-type=[public|private]" /> ++ <content type="string" default="private" /> ++ <shortdesc lang="en">API-type (public|private)</shortdesc> ++ </parameter> + <parameter name="crn" unique="0" required="1"> + <getopt mixed="--crn=[crn]" /> + <content type="string" /> +@@ -13,6 +23,11 @@ + <content type="string" /> + <shortdesc lang="en">PowerVS Instance</shortdesc> + </parameter> ++ <parameter name="proxy" unique="0" required="0"> ++ <getopt mixed="--proxy=[http://<URL>:<PORT>]" /> ++ <content type="string" default="" /> ++ <shortdesc lang="en">Network proxy</shortdesc> ++ </parameter> + <parameter name="region" unique="0" required="1"> + <getopt mixed="--region=[region]" /> + <content type="string" /> +@@ -21,7 +36,7 @@ + <parameter name="token" unique="0" required="1"> + <getopt mixed="--token=[token]" /> + <content type="string" /> +- <shortdesc lang="en">Bearer Token</shortdesc> ++ <shortdesc lang="en">API Token</shortdesc> + </parameter> + <parameter name="action" unique="0" required="1"> + <getopt mixed="-o, --action=[action]" /> +@@ -110,7 +125,7 @@ + </parameter> + <parameter name="stonith_status_sleep" unique="0" required="0"> + <getopt mixed="--stonith-status-sleep=[seconds]" /> +- <content type="second" default="1" /> ++ <content type="second" default="3" /> + <shortdesc lang="en">Sleep X seconds between status calls during a STONITH action</shortdesc> + </parameter> + <parameter name="retry_on" unique="0" required="0"> diff --git a/bz2111998-fence_ibm_vpc-add-token-cache-support.patch b/bz2111998-fence_ibm_vpc-add-token-cache-support.patch new file mode 100644 index 0000000..a3002a7 --- /dev/null +++ b/bz2111998-fence_ibm_vpc-add-token-cache-support.patch @@ -0,0 +1,432 @@ +From bccac64a5135815ada30d385ab573409f1176905 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 7 Jul 2022 14:18:21 +0200 +Subject: [PATCH 1/3] build: make xml-check: ignore detected paths in *_file + parameters not matching saved metadata + +--- + make/agentpycheck.mk | 2 +- + 83 files changed, 1 insertion(+), 108 deletions(-) + +diff --git a/make/agentpycheck.mk b/make/agentpycheck.mk +index f686c4c89..4044dbad3 100644 +--- a/make/agentpycheck.mk ++++ b/make/agentpycheck.mk +@@ -1,5 +1,5 @@ + DATADIR:=$(abs_top_srcdir)/tests/data/metadata +-AWK_VAL='BEGIN {store=-1} /name=".*_path"/ {store=2} {if (store!=0) {print}; store--}' ++AWK_VAL='BEGIN {store=-1} /name=".*_path"/ || /name=".*_file"/ {store=2} {if (store!=0) {print}; store--}' + + TEST_TARGET=$(filter-out $(TEST_TARGET_SKIP),$(TARGET)) + +From 1b7f3cc431ca53962506e6d96e7a4938c4388416 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Fri, 1 Jul 2022 13:29:16 +0200 +Subject: [PATCH 2/3] build: add FENCETMPDIR for state files + +--- + Makefile.am | 3 ++- + configure.ac | 30 ++++++++++++++++++++++++++++++ + m4/PKG_CHECK_VAR.m4 | 24 ++++++++++++++++++++++++ + make/fencebuild.mk | 1 + + systemd/Makefile.am | 24 ++++++++++++++++++++++++ + systemd/fence-agents.conf.in | 1 + + 7 files changed, 97 insertions(+), 2 deletions(-) + create mode 100644 m4/PKG_CHECK_VAR.m4 + create mode 100644 systemd/Makefile.am + create mode 100644 systemd/fence-agents.conf.in + +diff --git a/Makefile.am b/Makefile.am +index c1091b93a..1d115e5aa 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -23,7 +23,7 @@ TARFILES = $(PACKAGE_NAME)-$(VERSION).tar.bz2 \ + + ACLOCAL_AMFLAGS = -I m4 + +-SUBDIRS = lib agents doc ++SUBDIRS = lib agents doc systemd + + .PHONY: $(SUBDIRS) + +@@ -34,6 +34,7 @@ doc: agents + install-exec-local: + $(INSTALL) -d $(DESTDIR)/$(LOGDIR) + $(INSTALL) -d $(DESTDIR)/$(CLUSTERVARRUN) ++ $(INSTALL) -d -m 1755 $(DESTDIR)$(FENCETMPDIR) + + uninstall-local: + rmdir $(DESTDIR)/$(LOGDIR) || :; +diff --git a/configure.ac b/configure.ac +index 1bad8e3b0..d7afb8dbe 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -135,10 +135,38 @@ AC_ARG_WITH([agents], + [ AGENTS_LIST="$withval" ], + [ AGENTS_LIST="all" ]) + ++FENCETMPDIR=${localstatedir}/run/fence-agents ++AC_ARG_WITH(fencetmpdir, ++ [ --with-fencetmpdir=DIR directory for fence agents state files [${FENCETMPDIR}]], ++ [ FENCETMPDIR="$withval" ]) ++ ++# Expand $prefix ++eval FENCETMPDIR="`eval echo ${FENCETMPDIR}`" ++AC_DEFINE_UNQUOTED(FENCETMPDIR,"$FENCETMPDIR", Where Fence agents keep state files) ++AC_SUBST(FENCETMPDIR) ++ ++ + if test "x$AGENTS_LIST" = x; then + AC_ERROR([No agents selected]) + fi + ++# PKG_CHECK_MODULES will fail if systemd is not found by default, so make sure ++# we set the proper vars and deal with it ++PKG_CHECK_MODULES([systemd], [systemd], [HAS_SYSTEMD=yes], [HAS_SYSTEMD=no]) ++if test "x$HAS_SYSTEMD" == "xyes"; then ++ PKG_CHECK_VAR([SYSTEMD_TMPFILES_DIR], [systemd], [tmpfilesdir]) ++ if test "x$SYSTEMD_TMPFILES_DIR" == "x"; then ++ AC_MSG_ERROR([Unable to detect systemd tmpfiles directory automatically]) ++ fi ++ ++ # sanitize systed vars when using non standard prefix ++ if test "$prefix" != "/usr"; then ++ SYSTEMD_TMPFILES_DIR="$prefix/$SYSTEMD_TMPFILES_DIR" ++ AC_SUBST([SYSTEMD_TMPFILES_DIR]) ++ fi ++fi ++AM_CONDITIONAL(HAVE_SYSTEMD, [test "x$HAS_SYSTEMD" == xyes ]) ++ + FENCE_KDUMP=0 + if echo "$AGENTS_LIST" | grep -q -E "all|kdump"; then + case "$host_os" in +@@ -552,6 +580,8 @@ AC_CONFIG_FILES([Makefile + agents/Makefile + lib/Makefile + doc/Makefile ++ systemd/Makefile ++ systemd/fence-agents.conf + agents/virt/Makefile + agents/virt/config/Makefile + agents/virt/common/Makefile +diff --git a/m4/PKG_CHECK_VAR.m4 b/m4/PKG_CHECK_VAR.m4 +new file mode 100644 +index 000000000..2221a69eb +--- /dev/null ++++ b/m4/PKG_CHECK_VAR.m4 +@@ -0,0 +1,24 @@ ++dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, ++dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++dnl ------------------------------------------- ++dnl Since: 0.28 ++dnl ++dnl Retrieves the value of the pkg-config variable for the given module. ++dnl ++dnl Origin (declared license: GPLv2+ with less restrictive exception): ++dnl https://cgit.freedesktop.org/pkg-config/tree/pkg.m4.in?h=pkg-config-0.29.1#n261 ++dnl (AS_VAR_COPY replaced with backward-compatible equivalent and guard ++dnl to prefer system-wide variant by Jan Pokorny <jpokorny@redhat.com>) ++ ++m4_ifndef([PKG_CHECK_VAR],[ ++AC_DEFUN([PKG_CHECK_VAR], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl ++ ++_PKG_CONFIG([$1], [variable="][$3]["], [$2]) ++dnl AS_VAR_COPY([$1], [pkg_cv_][$1]) ++$1=AS_VAR_GET([pkg_cv_][$1]) ++ ++AS_VAR_IF([$1], [""], [$5], [$4])dnl ++])dnl PKG_CHECK_VAR ++])dnl m4_ifndef +diff --git a/make/fencebuild.mk b/make/fencebuild.mk +index 762db62c4..9a3c6d6dd 100644 +--- a/make/fencebuild.mk ++++ b/make/fencebuild.mk +@@ -8,6 +8,7 @@ define gen_agent_from_py + -e 's#@''LOGDIR@#${LOGDIR}#g' \ + -e 's#@''SBINDIR@#${sbindir}#g' \ + -e 's#@''LIBEXECDIR@#${libexecdir}#g' \ ++ -e 's#@''FENCETMPDIR@#${FENCETMPDIR}#g' \ + -e 's#@''IPMITOOL_PATH@#${IPMITOOL_PATH}#g' \ + -e 's#@''OPENSTACK_PATH@#${OPENSTACK_PATH}#g' \ + -e 's#@''AMTTOOL_PATH@#${AMTTOOL_PATH}#g' \ +diff --git a/systemd/Makefile.am b/systemd/Makefile.am +new file mode 100644 +index 000000000..aa3a01679 +--- /dev/null ++++ b/systemd/Makefile.am +@@ -0,0 +1,24 @@ ++# ++# Copyright (C) 2017 Oyvind Albrigtsen ++# ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License ++# as published by the Free Software Foundation; either version 2 ++# of the License, or (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++# ++ ++MAINTAINERCLEANFILES = Makefile.in ++ ++if HAVE_SYSTEMD ++tmpfilesdir = $(SYSTEMD_TMPFILES_DIR) ++tmpfiles_DATA = fence-agents.conf ++endif +diff --git a/systemd/fence-agents.conf.in b/systemd/fence-agents.conf.in +new file mode 100644 +index 000000000..4181287da +--- /dev/null ++++ b/systemd/fence-agents.conf.in +@@ -0,0 +1 @@ ++d @FENCETMPDIR@ 1755 root root + +From d5a12d9c30b66eb8720e037c4dce5fe0f3ad7dbb Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 30 Jun 2022 13:20:37 +0200 +Subject: [PATCH 3/3] fence_ibm_vpc: add token cache support + +--- + agents/ibm_vpc/fence_ibm_vpc.py | 126 ++++++++++++++++++++---- + tests/data/metadata/fence_ibm_vpc.xml | 4 + + 3 files changed, 110 insertions(+), 22 deletions(-) + + def auth_connect(opt): +diff --git a/agents/ibm_vpc/fence_ibm_vpc.py b/agents/ibm_vpc/fence_ibm_vpc.py +index 3da3ce056..847010584 100755 +--- a/agents/ibm_vpc/fence_ibm_vpc.py ++++ b/agents/ibm_vpc/fence_ibm_vpc.py +@@ -4,9 +4,10 @@ + import pycurl, io, json + import logging + import atexit ++import hashlib + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * +-from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS ++from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS, EC_GENERIC_ERROR + + state = { + "running": "on", +@@ -22,7 +23,7 @@ def get_list(conn, options): + + try: + command = "instances?version=2021-05-25&generation=2&limit={}".format(options["--limit"]) +- res = send_command(conn, command) ++ res = send_command(conn, options, command) + except Exception as e: + logging.debug("Failed: Unable to get list: {}".format(e)) + return outlets +@@ -38,7 +39,7 @@ def get_list(conn, options): + def get_power_status(conn, options): + try: + command = "instances/{}?version=2021-05-25&generation=2".format(options["--plug"]) +- res = send_command(conn, command) ++ res = send_command(conn, options, command) + result = state[res["status"]] + if options["--verbose-level"] > 1: + logging.debug("Result:\n{}".format(json.dumps(res, indent=2))) +@@ -57,27 +58,71 @@ def set_power_status(conn, options): + + try: + command = "instances/{}/actions?version=2021-05-25&generation=2".format(options["--plug"]) +- send_command(conn, command, "POST", action, 201) ++ send_command(conn, options, 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): ++ import os, errno ++ ++ try: ++ # FIPS requires usedforsecurity=False and might not be ++ # available on all distros: https://bugs.python.org/issue9216 ++ hash = hashlib.sha256(options["--apikey"].encode("utf-8"), usedforsecurity=False).hexdigest() ++ except (AttributeError, TypeError): ++ hash = hashlib.sha256(options["--apikey"].encode("utf-8")).hexdigest() ++ file_path = options["--token-file"].replace("[hash]", hash) + token = None ++ ++ if not os.path.isdir(os.path.dirname(file_path)): ++ os.makedirs(os.path.dirname(file_path)) ++ ++ # For security, remove file with potentially elevated mode + 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) ++ os.remove(file_path) ++ except OSError: ++ pass ++ ++ try: ++ oldumask = os.umask(0) ++ file_handle = os.open(file_path, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600) ++ except OSError as e: ++ if e.errno == errno.EEXIST: # Failed as the file already exists. ++ logging.error("Failed: File already exists: {}".format(e)) ++ sys.exit(EC_GENERIC_ERROR) ++ else: # Something unexpected went wrong ++ logging.error("Failed: Unable to open file: {}".format(e)) ++ sys.exit(EC_GENERIC_ERROR) ++ else: # No exception, so the file must have been created successfully. ++ with os.fdopen(file_handle, 'w') as file_obj: ++ try: ++ conn.setopt(pycurl.HTTPHEADER, [ ++ "Content-Type: application/x-www-form-urlencoded", ++ "User-Agent: curl", ++ ]) ++ token = send_command(conn, options, "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 as e: ++ logging.error("Failed: Unable to authenticate: {}".format(e)) ++ fail(EC_LOGIN_DENIED) ++ file_obj.write(token) ++ finally: ++ os.umask(oldumask) + + return token + ++def set_bearer_token(conn, bearer_token): ++ conn.setopt(pycurl.HTTPHEADER, [ ++ "Content-Type: application/json", ++ "Authorization: Bearer {}".format(bearer_token), ++ "User-Agent: curl", ++ ]) ++ ++ return conn ++ + def connect(opt): + conn = pycurl.Curl() ++ bearer_token = "" + + ## setup correct URL + conn.base_url = "https://" + opt["--region"] + ".iaas.cloud.ibm.com/v1/" +@@ -91,21 +136,28 @@ def connect(opt): + conn.setopt(pycurl.PROXY, "{}".format(opt["--proxy"])) + + # get bearer token +- bearer_token = get_bearer_token(conn, opt) ++ try: ++ try: ++ # FIPS requires usedforsecurity=False and might not be ++ # available on all distros: https://bugs.python.org/issue9216 ++ hash = hashlib.sha256(opt["--apikey"].encode("utf-8"), usedforsecurity=False).hexdigest() ++ except (AttributeError, TypeError): ++ hash = hashlib.sha256(opt["--apikey"].encode("utf-8")).hexdigest() ++ f = open(opt["--token-file"].replace("[hash]", hash)) ++ bearer_token = f.read() ++ f.close() ++ except IOError: ++ 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", +- ]) ++ conn = set_bearer_token(conn, bearer_token) + + return conn + + def disconnect(conn): + conn.close() + +-def send_command(conn, command, method="GET", action=None, expected_rc=200): ++def send_command(conn, options, command, method="GET", action=None, expected_rc=200): + if not command.startswith("https"): + url = conn.base_url + command + else: +@@ -130,6 +182,26 @@ def send_command(conn, command, method="GET", action=None, expected_rc=200): + raise(e) + + rc = conn.getinfo(pycurl.HTTP_CODE) ++ ++ # auth if token has expired ++ if rc in [400, 401, 415]: ++ tokenconn = pycurl.Curl() ++ token = get_bearer_token(tokenconn, options) ++ tokenconn.close() ++ conn = set_bearer_token(conn, token) ++ ++ # flush web_buffer ++ web_buffer.close() ++ web_buffer = io.BytesIO() ++ 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() +@@ -173,7 +245,7 @@ def define_new_opts(): + all_opt["proxy"] = { + "getopt" : ":", + "longopt" : "proxy", +- "help" : "--proxy=[http://<URL>:<PORT>] Proxy: 'http://<URL>:<PORT>'", ++ "help" : "--proxy=[http://<URL>:<PORT>] Proxy: 'http://<URL>:<PORT>'", + "required" : "0", + "default": "", + "shortdesc" : "Network proxy", +@@ -188,14 +260,26 @@ def define_new_opts(): + "shortdesc" : "Number of nodes returned by API", + "order" : 0 + } ++ all_opt["token_file"] = { ++ "getopt" : ":", ++ "longopt" : "token-file", ++ "help" : "--token-file=[path] Path to the token cache file\n" ++ "\t\t\t\t (Default: @FENCETMPDIR@/fence_ibm_vpc/[hash].token)\n" ++ "\t\t\t\t [hash] will be replaced by a hashed value", ++ "required" : "0", ++ "default": "@FENCETMPDIR@/fence_ibm_vpc/[hash].token", ++ "shortdesc" : "Path to the token cache file", ++ "order" : 0 ++ } + + + def main(): + device_opt = [ + "apikey", + "region", +- "limit", + "proxy", ++ "limit", ++ "token_file", + "port", + "no_password", + ] +diff --git a/tests/data/metadata/fence_ibm_vpc.xml b/tests/data/metadata/fence_ibm_vpc.xml +index acf4925fc..c35bc4619 100644 +--- a/tests/data/metadata/fence_ibm_vpc.xml ++++ b/tests/data/metadata/fence_ibm_vpc.xml +@@ -23,6 +23,10 @@ + <content type="string" /> + <shortdesc lang="en">Region</shortdesc> + </parameter> ++ <parameter name="token_file" unique="0" required="0"> ++ <getopt mixed="--token-file=[path]" /> ++ <shortdesc lang="en">Path to the token cache file</shortdesc> ++ </parameter> + <parameter name="action" unique="0" required="1"> + <getopt mixed="-o, --action=[action]" /> + <content type="string" default="reboot" /> diff --git a/bz2122944-1-fence_vmware_soap-set-timeout-cleanup-tmp-dirs.patch b/bz2122944-1-fence_vmware_soap-set-timeout-cleanup-tmp-dirs.patch new file mode 100644 index 0000000..fee804b --- /dev/null +++ b/bz2122944-1-fence_vmware_soap-set-timeout-cleanup-tmp-dirs.patch @@ -0,0 +1,70 @@ +From d4d2dd5066b62210a05c1256c6aee39609e3a974 Mon Sep 17 00:00:00 2001 +From: Thanasis Katsios <thkatsios@gmail.com> +Date: Mon, 1 Nov 2021 12:31:36 +0200 +Subject: [PATCH 1/3] fence_vmware_soap: Use --login-timeout option + +Fixes issue #446. +--- + agents/vmware_soap/fence_vmware_soap.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py +index a7f08b3d6..034695931 100644 +--- a/agents/vmware_soap/fence_vmware_soap.py ++++ b/agents/vmware_soap/fence_vmware_soap.py +@@ -57,7 +57,8 @@ def soap_login(options): + + try: + headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : "vim25"} +- conn = Client(url + "/vimService.wsdl", location=url, transport=RequestsTransport(verify=verify), headers=headers) ++ login_timeout = int(options["--login-timeout"]) ++ conn = Client(url + "/vimService.wsdl", location=url, transport=RequestsTransport(verify=verify), headers=headers, timeout=login_timeout) + + mo_ServiceInstance = Property('ServiceInstance') + mo_ServiceInstance._type = 'ServiceInstance' + +From 1e8f0d7582c7768149269f8d002d71b2febbdda0 Mon Sep 17 00:00:00 2001 +From: Thanasis Katsios <thkatsios@gmail.com> +Date: Tue, 2 Nov 2021 16:52:59 +0200 +Subject: [PATCH 2/3] Set timeout to 60s when disable-timeouts is used + +--- + agents/vmware_soap/fence_vmware_soap.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py +index 034695931..38101352e 100644 +--- a/agents/vmware_soap/fence_vmware_soap.py ++++ b/agents/vmware_soap/fence_vmware_soap.py +@@ -57,7 +57,7 @@ def soap_login(options): + + try: + headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : "vim25"} +- login_timeout = int(options["--login-timeout"]) ++ login_timeout = 60 if "--disable-timeout" in options and options["--disable-timeout"] != "false" else int(options["--login-timeout"]) + conn = Client(url + "/vimService.wsdl", location=url, transport=RequestsTransport(verify=verify), headers=headers, timeout=login_timeout) + + mo_ServiceInstance = Property('ServiceInstance') + +From 8094c8a5a06adf0bd891d4fddcc0b72861a0947e Mon Sep 17 00:00:00 2001 +From: Thanasis Katsios <thkatsios@gmail.com> +Date: Tue, 2 Nov 2021 18:51:02 +0200 +Subject: [PATCH 3/3] Support disable-timeout simplification + +--- + agents/vmware_soap/fence_vmware_soap.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py +index 38101352e..2cd45e0b3 100644 +--- a/agents/vmware_soap/fence_vmware_soap.py ++++ b/agents/vmware_soap/fence_vmware_soap.py +@@ -57,7 +57,7 @@ def soap_login(options): + + try: + headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : "vim25"} +- login_timeout = 60 if "--disable-timeout" in options and options["--disable-timeout"] != "false" else int(options["--login-timeout"]) ++ login_timeout = int(options["--login-timeout"]) or 60 + conn = Client(url + "/vimService.wsdl", location=url, transport=RequestsTransport(verify=verify), headers=headers, timeout=login_timeout) + + mo_ServiceInstance = Property('ServiceInstance') diff --git a/bz2122944-2-fence_vmware_soap-login-timeout-15s.patch b/bz2122944-2-fence_vmware_soap-login-timeout-15s.patch new file mode 100644 index 0000000..58b90bc --- /dev/null +++ b/bz2122944-2-fence_vmware_soap-login-timeout-15s.patch @@ -0,0 +1,23 @@ +From 2d4b3ea47fa7a9a301d34cefc8f279cae7df4afd Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 26 Jan 2023 13:19:16 +0100 +Subject: [PATCH] fence_vmware_soap: set login_timeout lower than default + pcmk_monitor_timeout (20s) to remove tmp dirs on fail + +--- + agents/vmware_soap/fence_vmware_soap.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py +index b1d27a9fb..4a4ec1780 100644 +--- a/agents/vmware_soap/fence_vmware_soap.py ++++ b/agents/vmware_soap/fence_vmware_soap.py +@@ -57,7 +57,7 @@ def soap_login(options): + + try: + headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : "vim25"} +- login_timeout = int(options["--login-timeout"]) or 60 ++ login_timeout = int(options["--login-timeout"]) or 15 + conn = Client(url + "/vimService.wsdl", location=url, transport=RequestsTransport(verify=verify), headers=headers, timeout=login_timeout) + + mo_ServiceInstance = Property('ServiceInstance') diff --git a/bz2132008-fence_virt-add-note-reboot-action.patch b/bz2132008-fence_virt-add-note-reboot-action.patch new file mode 100644 index 0000000..212a051 --- /dev/null +++ b/bz2132008-fence_virt-add-note-reboot-action.patch @@ -0,0 +1,51 @@ +From d664c254608c9342785f92d3da2ff6ba2466df3b Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Tue, 4 Oct 2022 13:43:13 +0200 +Subject: [PATCH] fence_virt: add note that reboot-action doesnt power on nodes + that are powered off + +--- + agents/virt/client/options.c | 7 ++++--- + tests/data/metadata/fence_virt.xml | 4 +++- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/agents/virt/client/options.c b/agents/virt/client/options.c +index ff624481b..ddd6bc4e0 100644 +--- a/agents/virt/client/options.c ++++ b/agents/virt/client/options.c +@@ -734,9 +734,9 @@ args_usage(char *progname, const char *optstr, int print_stdin) + + if (!print_stdin) { + if (progname) { +- printf("usage: %s [args]\n", progname); ++ printf("usage: %s [args]\n\nNOTE: reboot-action does not power on nodes that are powered off.\n\n", progname); + } else { +- printf("usage: fence_virt [args]\n"); ++ printf("usage: fence_virt [args]\n\nNOTE: reboot-action does not power on nodes that are powered off.\n\n"); + } + } + +@@ -766,7 +766,8 @@ args_metadata(char *progname, const char *optstr) + printf("<?xml version=\"1.0\" ?>\n"); + printf("<resource-agent name=\"%s\" shortdesc=\"Fence agent for virtual machines\">\n", basename(progname)); + printf("<longdesc>%s is an I/O Fencing agent which can be used with " +- "virtual machines.</longdesc>\n", basename(progname)); ++ "virtual machines.\n\nNOTE: reboot-action does not power on nodes that are powered off." ++ "</longdesc>\n", basename(progname)); + printf("<vendor-url>https://libvirt.org</vendor-url>\n"); + printf("<parameters>\n"); + +diff --git a/tests/data/metadata/fence_virt.xml b/tests/data/metadata/fence_virt.xml +index eb1959a11..612d4d3cb 100644 +--- a/tests/data/metadata/fence_virt.xml ++++ b/tests/data/metadata/fence_virt.xml +@@ -1,6 +1,8 @@ + <?xml version="1.0" ?> + <resource-agent name="fence_virt" shortdesc="Fence agent for virtual machines"> +-<longdesc>fence_virt is an I/O Fencing agent which can be used with virtual machines.</longdesc> ++<longdesc>fence_virt is an I/O Fencing agent which can be used with virtual machines. ++ ++NOTE: reboot-action does not power on nodes that are powered off.</longdesc> + <vendor-url>https://libvirt.org</vendor-url> + <parameters> + <parameter name="debug" unique="0" required="0"> diff --git a/bz2134015-fence_lpar-only-output-additional-info-on-debug.patch b/bz2134015-fence_lpar-only-output-additional-info-on-debug.patch new file mode 100644 index 0000000..8d29594 --- /dev/null +++ b/bz2134015-fence_lpar-only-output-additional-info-on-debug.patch @@ -0,0 +1,33 @@ +From 46f94d4dbad868afc70b96bd612323221991d06e Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Tue, 11 Oct 2022 09:51:24 +0200 +Subject: [PATCH] fence_lpar: only output additional error output on DEBUG + level + +Without this patch we get ERROR logged with trace info when doing +status-action for nodes that doesnt exist. +--- + agents/lpar/fence_lpar.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/agents/lpar/fence_lpar.py b/agents/lpar/fence_lpar.py +index 2046b0e4e..975971a57 100644 +--- a/agents/lpar/fence_lpar.py ++++ b/agents/lpar/fence_lpar.py +@@ -12,6 +12,7 @@ + + import sys, re + import atexit ++import logging + sys.path.append("@FENCEAGENTSLIBDIR@") + from fencing import * + from fencing import fail, fail_usage, EC_STATUS_HMC +@@ -48,7 +49,7 @@ def get_power_status(conn, options): + elif options["--hmc-version"] in ["4", "IVM"]: + status = re.compile(",state=(.*?),", re.IGNORECASE).search(conn.before).group(1) + except AttributeError as e: +- fail_usage("Command on HMC failed: {}\n{}".format(command, str(e)), False) ++ logging.debug("Command on HMC failed: {}\n{}".format(command, str(e))) + fail(EC_STATUS_HMC) + + return _normalize_status(status) diff --git a/bz2136191-fence_ibm_powervs-improve-defaults.patch b/bz2136191-fence_ibm_powervs-improve-defaults.patch new file mode 100644 index 0000000..7f5e578 --- /dev/null +++ b/bz2136191-fence_ibm_powervs-improve-defaults.patch @@ -0,0 +1,46 @@ +From 3373431dc49d6e429bbf613765385cb33a56e917 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Tue, 25 Oct 2022 10:39:29 +0200 +Subject: [PATCH] fence_ibm_powervs: improve defaults based on testing + +--- + agents/ibm_powervs/fence_ibm_powervs.py | 4 ++-- + tests/data/metadata/fence_ibm_powervs.xml | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/agents/ibm_powervs/fence_ibm_powervs.py b/agents/ibm_powervs/fence_ibm_powervs.py +index b0caed7c5..183893616 100755 +--- a/agents/ibm_powervs/fence_ibm_powervs.py ++++ b/agents/ibm_powervs/fence_ibm_powervs.py +@@ -232,10 +232,10 @@ def main(): + atexit.register(atexit_handler) + define_new_opts() + +- all_opt["shell_timeout"]["default"] = "15" ++ all_opt["shell_timeout"]["default"] = "500" + all_opt["power_timeout"]["default"] = "30" + all_opt["power_wait"]["default"] = "1" +- all_opt["stonith_status_sleep"]["default"] = "3" ++ all_opt["stonith_status_sleep"]["default"] = "2" + all_opt["api-type"]["default"] = "private" + all_opt["proxy"]["default"] = "" + +diff --git a/tests/data/metadata/fence_ibm_powervs.xml b/tests/data/metadata/fence_ibm_powervs.xml +index 40c494110..326bc2378 100644 +--- a/tests/data/metadata/fence_ibm_powervs.xml ++++ b/tests/data/metadata/fence_ibm_powervs.xml +@@ -119,12 +119,12 @@ + </parameter> + <parameter name="shell_timeout" unique="0" required="0"> + <getopt mixed="--shell-timeout=[seconds]" /> +- <content type="second" default="15" /> ++ <content type="second" default="500" /> + <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="3" /> ++ <content type="second" default="2" /> + <shortdesc lang="en">Sleep X seconds between status calls during a STONITH action</shortdesc> + </parameter> + <parameter name="retry_on" unique="0" required="0"> diff --git a/bz2138823-fence_virtd-update-manpage.patch b/bz2138823-fence_virtd-update-manpage.patch new file mode 100644 index 0000000..076992d --- /dev/null +++ b/bz2138823-fence_virtd-update-manpage.patch @@ -0,0 +1,29 @@ +From 6817d9ff018aa1af6fb9775bc9ae1f1cc07fa1ea Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 31 Oct 2022 10:54:10 +0100 +Subject: [PATCH] fence_virtd: add link and non-user socket example to man page + +--- + agents/virt/man/fence_virt.conf.5 | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/agents/virt/man/fence_virt.conf.5 b/agents/virt/man/fence_virt.conf.5 +index c23ffd943..c8434ed65 100644 +--- a/agents/virt/man/fence_virt.conf.5 ++++ b/agents/virt/man/fence_virt.conf.5 +@@ -230,6 +230,15 @@ by a user running a cluster of virtual machines on a single desktop computer. + . + the URI to use when connecting to libvirt. + ++All libvirt URIs are accepted and passed as-is. ++ ++See https://libvirt.org/uri.html#remote-uris for examples. ++ ++NOTE: When VMs are run as non-root user the socket path must be set as part ++of the URI. ++ ++Example: qemu:///session?socket=/run/user/<UID>/libvirt/virtqemud-sock ++ + .SS libvirt-qmf + + The libvirt-qmf plugin acts as a QMFv2 Console to the libvirt-qmf daemon in diff --git a/bz2144531-fence_virtd-warn-files-not-mode-600.patch b/bz2144531-fence_virtd-warn-files-not-mode-600.patch new file mode 100644 index 0000000..5d72acb --- /dev/null +++ b/bz2144531-fence_virtd-warn-files-not-mode-600.patch @@ -0,0 +1,114 @@ +From 3b311a1b069cec59f3d47242282f5d9c67a82e06 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 21 Nov 2022 12:33:22 +0100 +Subject: [PATCH] fence_virtd: make fence_virtd.conf file mode 600 and fail if + fence_virtd.conf or key file are not mode 600 + +--- + agents/virt/config/Makefile.am | 3 +++ + agents/virt/include/simpleconfig.h | 2 ++ + agents/virt/server/config.c | 26 ++++++++++++++++++++++++++ + agents/virt/server/main.c | 16 ++++++++++++++++ + 4 files changed, 47 insertions(+) + +diff --git a/agents/virt/config/Makefile.am b/agents/virt/config/Makefile.am +index 86d8df415..19d974278 100644 +--- a/agents/virt/config/Makefile.am ++++ b/agents/virt/config/Makefile.am +@@ -37,5 +37,8 @@ y.tab.c: config.y + config.c: y.tab.c config.l + $(LEX) -oconfig.c $(srcdir)/config.l + ++install-exec-hook: ++ chmod 600 $(DESTDIR)$(sysconfdir)/fence_virt.conf ++ + clean-local: + rm -f config.tab.c config.tab.h config.c y.tab.c y.tab.h +diff --git a/agents/virt/include/simpleconfig.h b/agents/virt/include/simpleconfig.h +index 83d54377a..6aba85f02 100644 +--- a/agents/virt/include/simpleconfig.h ++++ b/agents/virt/include/simpleconfig.h +@@ -49,6 +49,8 @@ config_object_t *sc_init(void); + /* Frees a previously-allocated copy of our simple config object */ + void sc_release(config_object_t *c); + ++int check_file_permissions(const char *fname); ++ + int do_configure(config_object_t *config, const char *filename); + + #endif +diff -uNr a/agents/virt/server/config.c b/agents/virt/server/config.c +--- a/agents/virt/server/config.c 2021-07-08 13:09:05.000000000 +0200 ++++ b/agents/virt/server/config.c 2022-11-22 10:59:09.547919852 +0100 +@@ -11,6 +11,7 @@ + #include <fcntl.h> + #include <net/if.h> + #include <arpa/inet.h> ++#include <errno.h> + + #include "simpleconfig.h" + #include "static_map.h" +@@ -595,6 +596,31 @@ listener_configure(config_object_t *config) + } + + ++int ++check_file_permissions(const char *fname) ++{ ++ struct stat st; ++ mode_t file_perms = 0600; ++ int ret; ++ ++ ret = stat(fname, &st); ++ if (ret != 0) { ++ printf("stat failed on file '%s': %s\n", ++ fname, strerror(errno)); ++ return 1; ++ } ++ ++ if ((st.st_mode & 0777) != file_perms) { ++ printf("WARNING: invalid permissions on file " ++ "'%s': has 0%o should be 0%o\n", fname, ++ (unsigned int)(st.st_mode & 0777), ++ (unsigned int)file_perms); ++ return 1; ++ } ++ ++ return 0; ++} ++ + int + do_configure(config_object_t *config, const char *config_file) + { +diff -uNr a/agents/virt/server/main.c b/agents/virt/server/main.c +--- a/agents/virt/server/main.c 2021-07-08 13:09:05.000000000 +0200 ++++ b/agents/virt/server/main.c 2022-11-22 10:58:05.894530187 +0100 +@@ -14,7 +14,9 @@ + /* Local includes */ + #include "simpleconfig.h" + #include "static_map.h" ++#include "xvm.h" + #include "server_plugin.h" ++#include "simple_auth.h" + #include "debug.h" + + /* configure.c */ +@@ -203,6 +205,18 @@ + snprintf(pid_file, PATH_MAX, "/var/run/%s.pid", basename(argv[0])); + } + ++ check_file_permissions(config_file); ++ ++ sprintf(val, "listeners/%s/@key_file", listener_name); ++ if (sc_get(config, val, ++ val, sizeof(val)-1) == 0) { ++ dbg_printf(1, "Got %s for key_file\n", val); ++ } else { ++ snprintf(val, sizeof(val), "%s", DEFAULT_KEY_FILE); ++ } ++ ++ check_file_permissions(val); ++ + openlog(basename(argv[0]), LOG_NDELAY | LOG_PID, LOG_DAEMON); + + daemon_init(basename(argv[0]), pid_file, foreground); diff --git a/bz2149655-fence_virtd-update-fence_virt.conf-manpage.patch b/bz2149655-fence_virtd-update-fence_virt.conf-manpage.patch new file mode 100644 index 0000000..8633a5f --- /dev/null +++ b/bz2149655-fence_virtd-update-fence_virt.conf-manpage.patch @@ -0,0 +1,55 @@ +From 6f213eb637bf7d957ba035e3aa09ce1f1bbccf84 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Tue, 29 Nov 2022 16:21:18 +0100 +Subject: [PATCH] fence_virtd: add info about using multiple uuid/ip entries + for groups + +--- + agents/virt/man/fence_virt.conf.5 | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/agents/virt/man/fence_virt.conf.5 b/agents/virt/man/fence_virt.conf.5 +index c8434ed65..dfb3504f5 100644 +--- a/agents/virt/man/fence_virt.conf.5 ++++ b/agents/virt/man/fence_virt.conf.5 +@@ -1,4 +1,4 @@ +-.TH fence_virtd.conf 5 ++.TH fence_virt.conf 5 + + .SH NAME + fence_virt.conf - configuration file for fence_virtd +@@ -304,15 +304,17 @@ This defines a group. + .TP + .B uuid + . +-defines UUID as a member of a group. ++Defines UUID as a member of a group. It can be used multiple times ++to specify both node name and UUID values that can be fenced. + + .TP + .B ip + . +-defines an IP which is allowed to send fencing requests +-for members of this group (e.g. for multicast). It is +-highly recommended that this be used in conjunction with +-a key file. ++Defines an IP which is allowed to send fencing requests ++for members of this group (e.g. for multicast). It can be used ++multiple times to allow more than 1 IP to send fencing requests to ++the group. It is highly recommended that this be used in conjunction ++with a key file. + + + +@@ -340,8 +342,11 @@ a key file. + groups { + group { + ip = "192.168.1.1"; ++ ip = "192.168.1.2"; + uuid = "44179d3f-6c63-474f-a212-20c8b4b25b16"; + uuid = "1ce02c4b-dfa1-42cb-b5b1-f0b1091ece60"; ++ uuid = "node1"; ++ uuid = "node2"; + } + } + diff --git a/bz2152107-fencing-1-add-plug_separator.patch b/bz2152107-fencing-1-add-plug_separator.patch new file mode 100644 index 0000000..e0a8f08 --- /dev/null +++ b/bz2152107-fencing-1-add-plug_separator.patch @@ -0,0 +1,74 @@ +From 90ea995038e560222f9345310f31a79b595a5219 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 24 Nov 2022 10:19:29 +0100 +Subject: [PATCH 1/2] fencing: add plug_separator parameter to be able to + specify one that isnt part of the plug name(s) + +--- + lib/fencing.py.py | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/lib/fencing.py.py b/lib/fencing.py.py +index 940bd01d1..cf1c48e78 100644 +--- a/lib/fencing.py.py ++++ b/lib/fencing.py.py +@@ -322,6 +322,13 @@ + "help" : "-6, --inet6-only Forces agent to use IPv6 addresses only", + "required" : "0", + "order" : 1}, ++ "plug_separator" : { ++ "getopt" : ":", ++ "longopt" : "plug-separator", ++ "help" : "--plug-separator=[char] Separator for plug parameter when specifying more than 1 plug", ++ "default" : ",", ++ "required" : "0", ++ "order" : 100}, + "separator" : { + "getopt" : "C:", + "longopt" : "separator", +@@ -934,7 +941,7 @@ def fence_action(connection, options, set_power_fn, get_power_fn, get_outlet_lis + + try: + if "--plug" in options: +- options["--plugs"] = options["--plug"].split(",") ++ options["--plugs"] = options["--plug"].split(options["--plug-separator"]) + + ## Process options that manipulate fencing device + ##### + +From 55e2a56b81ed2188dedfce07cc3155e2175183cd Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Mon, 28 Nov 2022 12:40:00 +0100 +Subject: [PATCH 2/2] fence_wti: increase login timeout to avoid random + timeouts + +--- + agents/wti/fence_wti.py | 1 + + tests/data/metadata/fence_wti.xml | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/agents/wti/fence_wti.py b/agents/wti/fence_wti.py +index 68640ae65..97cc66de2 100644 +--- a/agents/wti/fence_wti.py ++++ b/agents/wti/fence_wti.py +@@ -178,6 +178,7 @@ def main(): + atexit.register(atexit_handler) + + all_opt["cmd_prompt"]["default"] = ["RSM>", "MPC>", "IPS>", "TPS>", "NBB>", "NPS>", "VMR>"] ++ all_opt["login_timeout"]["default"] = "10" + + options = check_input(device_opt, process_input(device_opt)) + +diff --git a/tests/data/metadata/fence_wti.xml b/tests/data/metadata/fence_wti.xml +index 6bdccd2dc..8e15f4852 100644 +--- a/tests/data/metadata/fence_wti.xml ++++ b/tests/data/metadata/fence_wti.xml +@@ -153,7 +153,7 @@ + </parameter> + <parameter name="login_timeout" unique="0" required="0"> + <getopt mixed="--login-timeout=[seconds]" /> +- <content type="second" default="5" /> ++ <content type="second" default="10" /> + <shortdesc lang="en">Wait X seconds for cmd prompt after login</shortdesc> + </parameter> + <parameter name="power_timeout" unique="0" required="0"> diff --git a/bz2152107-fencing-2-update-DEPENDENCY_OPT.patch b/bz2152107-fencing-2-update-DEPENDENCY_OPT.patch new file mode 100644 index 0000000..3a6b943 --- /dev/null +++ b/bz2152107-fencing-2-update-DEPENDENCY_OPT.patch @@ -0,0 +1,1382 @@ +From 0f280ea4a299037a7d4e99d80b0193fd6fcdbd79 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Tue, 24 Jan 2023 12:19:41 +0100 +Subject: [PATCH] fencing: add plug_separator to default DEPENDENCY_OPT + +--- + lib/fencing.py.py | 2 +- + tests/data/metadata/fence_aliyun.xml | 5 +++++ + tests/data/metadata/fence_alom.xml | 5 +++++ + tests/data/metadata/fence_amt.xml | 5 +++++ + tests/data/metadata/fence_amt_ws.xml | 5 +++++ + tests/data/metadata/fence_apc.xml | 5 +++++ + tests/data/metadata/fence_apc_snmp.xml | 5 +++++ + tests/data/metadata/fence_aws.xml | 5 +++++ + tests/data/metadata/fence_azure_arm.xml | 5 +++++ + tests/data/metadata/fence_bladecenter.xml | 5 +++++ + tests/data/metadata/fence_brocade.xml | 5 +++++ + tests/data/metadata/fence_cdu.xml | 5 +++++ + tests/data/metadata/fence_cisco_mds.xml | 5 +++++ + tests/data/metadata/fence_cisco_ucs.xml | 5 +++++ + tests/data/metadata/fence_compute.xml | 5 +++++ + tests/data/metadata/fence_crosslink.xml | 5 +++++ + tests/data/metadata/fence_docker.xml | 5 +++++ + tests/data/metadata/fence_drac.xml | 5 +++++ + tests/data/metadata/fence_drac5.xml | 5 +++++ + tests/data/metadata/fence_dummy.xml | 5 +++++ + tests/data/metadata/fence_eaton_snmp.xml | 5 +++++ + tests/data/metadata/fence_emerson.xml | 5 +++++ + tests/data/metadata/fence_eps.xml | 5 +++++ + tests/data/metadata/fence_evacuate.xml | 5 +++++ + tests/data/metadata/fence_gce.xml | 5 +++++ + tests/data/metadata/fence_hds_cb.xml | 5 +++++ + tests/data/metadata/fence_heuristics_ping.xml | 5 +++++ + tests/data/metadata/fence_hpblade.xml | 5 +++++ + tests/data/metadata/fence_ibm_powervs.xml | 5 +++++ + tests/data/metadata/fence_ibm_vpc.xml | 5 +++++ + tests/data/metadata/fence_ibmblade.xml | 5 +++++ + tests/data/metadata/fence_ibmz.xml | 5 +++++ + tests/data/metadata/fence_idrac.xml | 5 +++++ + tests/data/metadata/fence_ifmib.xml | 5 +++++ + tests/data/metadata/fence_ilo.xml | 5 +++++ + tests/data/metadata/fence_ilo2.xml | 5 +++++ + tests/data/metadata/fence_ilo3.xml | 5 +++++ + tests/data/metadata/fence_ilo3_ssh.xml | 5 +++++ + tests/data/metadata/fence_ilo4.xml | 5 +++++ + tests/data/metadata/fence_ilo4_ssh.xml | 5 +++++ + tests/data/metadata/fence_ilo5.xml | 5 +++++ + tests/data/metadata/fence_ilo5_ssh.xml | 5 +++++ + tests/data/metadata/fence_ilo_moonshot.xml | 5 +++++ + tests/data/metadata/fence_ilo_mp.xml | 5 +++++ + tests/data/metadata/fence_ilo_ssh.xml | 5 +++++ + tests/data/metadata/fence_imm.xml | 5 +++++ + tests/data/metadata/fence_intelmodular.xml | 5 +++++ + tests/data/metadata/fence_ipdu.xml | 5 +++++ + tests/data/metadata/fence_ipmilan.xml | 5 +++++ + tests/data/metadata/fence_ipmilanplus.xml | 5 +++++ + tests/data/metadata/fence_ironic.xml | 5 +++++ + tests/data/metadata/fence_kubevirt.xml | 5 +++++ + tests/data/metadata/fence_ldom.xml | 5 +++++ + tests/data/metadata/fence_lindypdu.xml | 5 +++++ + tests/data/metadata/fence_lpar.xml | 5 +++++ + tests/data/metadata/fence_mpath.xml | 5 +++++ + tests/data/metadata/fence_netio.xml | 5 +++++ + tests/data/metadata/fence_openstack.xml | 5 +++++ + tests/data/metadata/fence_ovh.xml | 5 +++++ + tests/data/metadata/fence_powerman.xml | 5 +++++ + tests/data/metadata/fence_pve.xml | 5 +++++ + tests/data/metadata/fence_raritan.xml | 5 +++++ + tests/data/metadata/fence_rcd_serial.xml | 5 +++++ + tests/data/metadata/fence_redfish.xml | 5 +++++ + tests/data/metadata/fence_rhevm.xml | 5 +++++ + tests/data/metadata/fence_rsa.xml | 5 +++++ + tests/data/metadata/fence_rsb.xml | 5 +++++ + tests/data/metadata/fence_sanbox2.xml | 5 +++++ + tests/data/metadata/fence_sbd.xml | 5 +++++ + tests/data/metadata/fence_scsi.xml | 5 +++++ + tests/data/metadata/fence_skalar.xml | 5 +++++ + tests/data/metadata/fence_tripplite_snmp.xml | 5 +++++ + tests/data/metadata/fence_vbox.xml | 5 +++++ + tests/data/metadata/fence_virsh.xml | 5 +++++ + tests/data/metadata/fence_vmware.xml | 5 +++++ + tests/data/metadata/fence_vmware_rest.xml | 5 +++++ + tests/data/metadata/fence_vmware_soap.xml | 5 +++++ + tests/data/metadata/fence_vmware_vcloud.xml | 5 +++++ + tests/data/metadata/fence_wti.xml | 5 +++++ + tests/data/metadata/fence_xenapi.xml | 5 +++++ + tests/data/metadata/fence_zvmip.xml | 5 +++++ + 84 files changed, 416 insertions(+), 1 deletion(-) + +diff --git a/lib/fencing.py.py b/lib/fencing.py.py +index cf1c48e78..c5b5e94a1 100644 +--- a/lib/fencing.py.py ++++ b/lib/fencing.py.py +@@ -494,7 +494,7 @@ + "version", "action", "agent", "power_timeout", + "shell_timeout", "login_timeout", "disable_timeout", + "power_wait", "stonith_status_sleep", "retry_on", "delay", +- "quiet"], ++ "plug_separator", "quiet"], + "passwd" : ["passwd_script"], + "sudo" : ["sudo_path"], + "secure" : ["identity_file", "ssh_options", "ssh_path", "inet4_only", "inet6_only"], +diff --git a/tests/data/metadata/fence_aliyun.xml b/tests/data/metadata/fence_aliyun.xml +index 35112eb68..56d792048 100644 +--- a/tests/data/metadata/fence_aliyun.xml ++++ b/tests/data/metadata/fence_aliyun.xml +@@ -72,6 +72,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml +index 939b3a56e..6532ad6dd 100644 +--- a/tests/data/metadata/fence_alom.xml ++++ b/tests/data/metadata/fence_alom.xml +@@ -136,6 +136,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml +index 98b5ceeb4..809c2dfea 100644 +--- a/tests/data/metadata/fence_amt.xml ++++ b/tests/data/metadata/fence_amt.xml +@@ -106,6 +106,11 @@ + <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="amttool_path" unique="0" required="0"> + <getopt mixed="--amttool-path=[path]" /> + <shortdesc lang="en">Path to amttool binary</shortdesc> +diff --git a/tests/data/metadata/fence_amt_ws.xml b/tests/data/metadata/fence_amt_ws.xml +index af7c433f0..97a222526 100644 +--- a/tests/data/metadata/fence_amt_ws.xml ++++ b/tests/data/metadata/fence_amt_ws.xml +@@ -106,6 +106,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_apc.xml b/tests/data/metadata/fence_apc.xml +index da029bbb0..6081b1ff5 100644 +--- a/tests/data/metadata/fence_apc.xml ++++ b/tests/data/metadata/fence_apc.xml +@@ -141,6 +141,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_apc_snmp.xml b/tests/data/metadata/fence_apc_snmp.xml +index 5f5a33398..02efbb0b0 100644 +--- a/tests/data/metadata/fence_apc_snmp.xml ++++ b/tests/data/metadata/fence_apc_snmp.xml +@@ -147,6 +147,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_aws.xml b/tests/data/metadata/fence_aws.xml +index 682b9f0de..76995ecf2 100644 +--- a/tests/data/metadata/fence_aws.xml ++++ b/tests/data/metadata/fence_aws.xml +@@ -80,6 +80,11 @@ For instructions see: https://boto3.readthedocs.io/en/latest/guide/quickstart.ht + <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="," /> +diff --git a/tests/data/metadata/fence_azure_arm.xml b/tests/data/metadata/fence_azure_arm.xml +index f7882fa23..c6e1f203b 100644 +--- a/tests/data/metadata/fence_azure_arm.xml ++++ b/tests/data/metadata/fence_azure_arm.xml +@@ -132,6 +132,11 @@ When using network fencing the reboot-action will cause a quick-return once the + <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="," /> +diff --git a/tests/data/metadata/fence_bladecenter.xml b/tests/data/metadata/fence_bladecenter.xml +index 656d12b8b..3cc415355 100644 +--- a/tests/data/metadata/fence_bladecenter.xml ++++ b/tests/data/metadata/fence_bladecenter.xml +@@ -136,6 +136,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_brocade.xml b/tests/data/metadata/fence_brocade.xml +index e6265b68f..a78738d96 100644 +--- a/tests/data/metadata/fence_brocade.xml ++++ b/tests/data/metadata/fence_brocade.xml +@@ -136,6 +136,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_cdu.xml b/tests/data/metadata/fence_cdu.xml +index 7505b1bd9..ef87d795d 100644 +--- a/tests/data/metadata/fence_cdu.xml ++++ b/tests/data/metadata/fence_cdu.xml +@@ -102,6 +102,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_cisco_mds.xml b/tests/data/metadata/fence_cisco_mds.xml +index e2f5c5b6a..829c9dcbe 100644 +--- a/tests/data/metadata/fence_cisco_mds.xml ++++ b/tests/data/metadata/fence_cisco_mds.xml +@@ -146,6 +146,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml +index e232f33bc..76d15e9f4 100644 +--- a/tests/data/metadata/fence_cisco_ucs.xml ++++ b/tests/data/metadata/fence_cisco_ucs.xml +@@ -122,6 +122,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_compute.xml b/tests/data/metadata/fence_compute.xml +index 1b25910f5..f6aa1920b 100644 +--- a/tests/data/metadata/fence_compute.xml ++++ b/tests/data/metadata/fence_compute.xml +@@ -157,6 +157,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_crosslink.xml b/tests/data/metadata/fence_crosslink.xml +index 7f67337cd..1102b4e6b 100644 +--- a/tests/data/metadata/fence_crosslink.xml ++++ b/tests/data/metadata/fence_crosslink.xml +@@ -62,6 +62,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml +index 12725b95a..f685b1162 100644 +--- a/tests/data/metadata/fence_docker.xml ++++ b/tests/data/metadata/fence_docker.xml +@@ -110,6 +110,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml +index bb83f5860..a99126132 100644 +--- a/tests/data/metadata/fence_drac.xml ++++ b/tests/data/metadata/fence_drac.xml +@@ -107,6 +107,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_drac5.xml b/tests/data/metadata/fence_drac5.xml +index c539923c0..a0c73ebf8 100644 +--- a/tests/data/metadata/fence_drac5.xml ++++ b/tests/data/metadata/fence_drac5.xml +@@ -145,6 +145,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_dummy.xml b/tests/data/metadata/fence_dummy.xml +index a711d3869..0651f5ae0 100644 +--- a/tests/data/metadata/fence_dummy.xml ++++ b/tests/data/metadata/fence_dummy.xml +@@ -56,6 +56,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_eaton_snmp.xml b/tests/data/metadata/fence_eaton_snmp.xml +index b3e870b95..1d89b5272 100644 +--- a/tests/data/metadata/fence_eaton_snmp.xml ++++ b/tests/data/metadata/fence_eaton_snmp.xml +@@ -146,6 +146,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml +index b46ef8293..1ed792e2b 100644 +--- a/tests/data/metadata/fence_emerson.xml ++++ b/tests/data/metadata/fence_emerson.xml +@@ -146,6 +146,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml +index 6cf772895..a8cf8ad41 100644 +--- a/tests/data/metadata/fence_eps.xml ++++ b/tests/data/metadata/fence_eps.xml +@@ -109,6 +109,11 @@ Agent basically works by connecting to hidden page and pass appropriate argument + <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="," /> +diff --git a/tests/data/metadata/fence_evacuate.xml b/tests/data/metadata/fence_evacuate.xml +index 10b84abca..df2181eb6 100644 +--- a/tests/data/metadata/fence_evacuate.xml ++++ b/tests/data/metadata/fence_evacuate.xml +@@ -152,6 +152,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml +index c7d400e10..2a89b16c2 100644 +--- a/tests/data/metadata/fence_gce.xml ++++ b/tests/data/metadata/fence_gce.xml +@@ -147,6 +147,11 @@ For instructions see: https://cloud.google.com/compute/docs/tutorials/python-gui + <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="," /> +diff --git a/tests/data/metadata/fence_hds_cb.xml b/tests/data/metadata/fence_hds_cb.xml +index 90f4d2809..e25d889e3 100644 +--- a/tests/data/metadata/fence_hds_cb.xml ++++ b/tests/data/metadata/fence_hds_cb.xml +@@ -136,6 +136,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_heuristics_ping.xml b/tests/data/metadata/fence_heuristics_ping.xml +index 3832e3c9d..b10189b91 100644 +--- a/tests/data/metadata/fence_heuristics_ping.xml ++++ b/tests/data/metadata/fence_heuristics_ping.xml +@@ -82,6 +82,11 @@ This is not a fence agent by itself! Its only purpose is to enable/disable anoth + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_hpblade.xml b/tests/data/metadata/fence_hpblade.xml +index 6f190f3f3..0957fcdd4 100644 +--- a/tests/data/metadata/fence_hpblade.xml ++++ b/tests/data/metadata/fence_hpblade.xml +@@ -136,6 +136,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_ibm_powervs.xml b/tests/data/metadata/fence_ibm_powervs.xml +index 326bc2378..79878a9a7 100644 +--- a/tests/data/metadata/fence_ibm_powervs.xml ++++ b/tests/data/metadata/fence_ibm_powervs.xml +@@ -87,6 +87,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_ibm_vpc.xml b/tests/data/metadata/fence_ibm_vpc.xml +index c35bc4619..fe29ffb89 100644 +--- a/tests/data/metadata/fence_ibm_vpc.xml ++++ b/tests/data/metadata/fence_ibm_vpc.xml +@@ -76,6 +76,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_ibmblade.xml b/tests/data/metadata/fence_ibmblade.xml +index 9598abf6f..3286ca6de 100644 +--- a/tests/data/metadata/fence_ibmblade.xml ++++ b/tests/data/metadata/fence_ibmblade.xml +@@ -146,6 +146,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_ibmz.xml b/tests/data/metadata/fence_ibmz.xml +index 0671efc0e..ba74fa6fe 100644 +--- a/tests/data/metadata/fence_ibmz.xml ++++ b/tests/data/metadata/fence_ibmz.xml +@@ -132,6 +132,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index a38345629..2d4876493 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -150,6 +150,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ifmib.xml b/tests/data/metadata/fence_ifmib.xml +index c9328797e..4b56e2335 100644 +--- a/tests/data/metadata/fence_ifmib.xml ++++ b/tests/data/metadata/fence_ifmib.xml +@@ -148,6 +148,11 @@ It was written with managed ethernet switches in mind, in order to fence iSCSI S + <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="," /> +diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml +index 384b40dc6..0bac03c83 100644 +--- a/tests/data/metadata/fence_ilo.xml ++++ b/tests/data/metadata/fence_ilo.xml +@@ -133,6 +133,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml +index 3c98719d9..3d954a345 100644 +--- a/tests/data/metadata/fence_ilo2.xml ++++ b/tests/data/metadata/fence_ilo2.xml +@@ -133,6 +133,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index b0183ecee..0567b539c 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -150,6 +150,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml +index 1a9e56c50..e2a25661d 100644 +--- a/tests/data/metadata/fence_ilo3_ssh.xml ++++ b/tests/data/metadata/fence_ilo3_ssh.xml +@@ -149,6 +149,11 @@ WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent t + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index 22df71375..647bb1021 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -150,6 +150,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml +index 78aed1c4e..4fd6b2ef1 100644 +--- a/tests/data/metadata/fence_ilo4_ssh.xml ++++ b/tests/data/metadata/fence_ilo4_ssh.xml +@@ -149,6 +149,11 @@ WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent t + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo5.xml b/tests/data/metadata/fence_ilo5.xml +index 2648c4bbc..6c99db22a 100644 +--- a/tests/data/metadata/fence_ilo5.xml ++++ b/tests/data/metadata/fence_ilo5.xml +@@ -150,6 +150,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo5_ssh.xml b/tests/data/metadata/fence_ilo5_ssh.xml +index d0d1096e8..036aec5c6 100644 +--- a/tests/data/metadata/fence_ilo5_ssh.xml ++++ b/tests/data/metadata/fence_ilo5_ssh.xml +@@ -149,6 +149,11 @@ WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent t + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo_moonshot.xml b/tests/data/metadata/fence_ilo_moonshot.xml +index b38be58f3..c88c5922f 100644 +--- a/tests/data/metadata/fence_ilo_moonshot.xml ++++ b/tests/data/metadata/fence_ilo_moonshot.xml +@@ -136,6 +136,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml +index ea0a8e69c..7d4fd22d5 100644 +--- a/tests/data/metadata/fence_ilo_mp.xml ++++ b/tests/data/metadata/fence_ilo_mp.xml +@@ -136,6 +136,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml +index b8ffe3c6d..2e1cb84b2 100644 +--- a/tests/data/metadata/fence_ilo_ssh.xml ++++ b/tests/data/metadata/fence_ilo_ssh.xml +@@ -149,6 +149,11 @@ WARNING: The monitor-action is prone to timeouts. Use the fence_ilo-equivalent t + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index 5ed4e8c30..5c5bf910f 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -150,6 +150,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_intelmodular.xml b/tests/data/metadata/fence_intelmodular.xml +index 03c7c55d8..5dad0d0bd 100644 +--- a/tests/data/metadata/fence_intelmodular.xml ++++ b/tests/data/metadata/fence_intelmodular.xml +@@ -148,6 +148,11 @@ Note: Since firmware update version 2.7, SNMP v2 write support is removed, and r + <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="," /> +diff --git a/tests/data/metadata/fence_ipdu.xml b/tests/data/metadata/fence_ipdu.xml +index d9a44dd0f..22024a7a1 100644 +--- a/tests/data/metadata/fence_ipdu.xml ++++ b/tests/data/metadata/fence_ipdu.xml +@@ -146,6 +146,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index f8ede91cd..a31afcfd4 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -150,6 +150,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ipmilanplus.xml b/tests/data/metadata/fence_ipmilanplus.xml +index 92f0cf8cf..19c252933 100644 +--- a/tests/data/metadata/fence_ipmilanplus.xml ++++ b/tests/data/metadata/fence_ipmilanplus.xml +@@ -150,6 +150,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_ironic.xml b/tests/data/metadata/fence_ironic.xml +index 4da784826..813b03732 100644 +--- a/tests/data/metadata/fence_ironic.xml ++++ b/tests/data/metadata/fence_ironic.xml +@@ -102,6 +102,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_kubevirt.xml b/tests/data/metadata/fence_kubevirt.xml +index 66701099a..e6b42aa55 100644 +--- a/tests/data/metadata/fence_kubevirt.xml ++++ b/tests/data/metadata/fence_kubevirt.xml +@@ -72,6 +72,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_ldom.xml b/tests/data/metadata/fence_ldom.xml +index 0c8c45e24..59facad6f 100644 +--- a/tests/data/metadata/fence_ldom.xml ++++ b/tests/data/metadata/fence_ldom.xml +@@ -138,6 +138,11 @@ Very useful parameter is -c (or cmd_prompt in stdin mode). This must be set to s + <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="," /> +diff --git a/tests/data/metadata/fence_lindypdu.xml b/tests/data/metadata/fence_lindypdu.xml +index 2e1d5c760..56f81f4cb 100644 +--- a/tests/data/metadata/fence_lindypdu.xml ++++ b/tests/data/metadata/fence_lindypdu.xml +@@ -151,6 +151,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_lpar.xml b/tests/data/metadata/fence_lpar.xml +index e2adbc334..22f12dc23 100644 +--- a/tests/data/metadata/fence_lpar.xml ++++ b/tests/data/metadata/fence_lpar.xml +@@ -150,6 +150,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +index d656013bb..e22d3a1f9 100644 +--- a/tests/data/metadata/fence_mpath.xml ++++ b/tests/data/metadata/fence_mpath.xml +@@ -75,6 +75,11 @@ When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and ve + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_netio.xml b/tests/data/metadata/fence_netio.xml +index 7d8a4c723..95f3cf34a 100644 +--- a/tests/data/metadata/fence_netio.xml ++++ b/tests/data/metadata/fence_netio.xml +@@ -97,6 +97,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_openstack.xml b/tests/data/metadata/fence_openstack.xml +index 2e5bd9ff4..0bf1a78e2 100644 +--- a/tests/data/metadata/fence_openstack.xml ++++ b/tests/data/metadata/fence_openstack.xml +@@ -152,6 +152,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_ovh.xml b/tests/data/metadata/fence_ovh.xml +index 5913e49ad..79d5eda94 100644 +--- a/tests/data/metadata/fence_ovh.xml ++++ b/tests/data/metadata/fence_ovh.xml +@@ -87,6 +87,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_powerman.xml b/tests/data/metadata/fence_powerman.xml +index eb2509452..10514fd3c 100644 +--- a/tests/data/metadata/fence_powerman.xml ++++ b/tests/data/metadata/fence_powerman.xml +@@ -67,6 +67,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="3" /> +diff --git a/tests/data/metadata/fence_pve.xml b/tests/data/metadata/fence_pve.xml +index ec1405448..1ed3cda4f 100644 +--- a/tests/data/metadata/fence_pve.xml ++++ b/tests/data/metadata/fence_pve.xml +@@ -145,6 +145,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_raritan.xml b/tests/data/metadata/fence_raritan.xml +index 9983cc08c..5e387c784 100644 +--- a/tests/data/metadata/fence_raritan.xml ++++ b/tests/data/metadata/fence_raritan.xml +@@ -97,6 +97,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_rcd_serial.xml b/tests/data/metadata/fence_rcd_serial.xml +index 2d0a49d9f..c14d342f7 100644 +--- a/tests/data/metadata/fence_rcd_serial.xml ++++ b/tests/data/metadata/fence_rcd_serial.xml +@@ -55,6 +55,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_redfish.xml b/tests/data/metadata/fence_redfish.xml +index 5bdb32365..76a23af30 100644 +--- a/tests/data/metadata/fence_redfish.xml ++++ b/tests/data/metadata/fence_redfish.xml +@@ -132,6 +132,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml +index 372c1bbca..0b2239931 100644 +--- a/tests/data/metadata/fence_rhevm.xml ++++ b/tests/data/metadata/fence_rhevm.xml +@@ -140,6 +140,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml +index 6dfb0925c..284f9184d 100644 +--- a/tests/data/metadata/fence_rsa.xml ++++ b/tests/data/metadata/fence_rsa.xml +@@ -136,6 +136,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml +index 52978583c..e3d6e1096 100644 +--- a/tests/data/metadata/fence_rsb.xml ++++ b/tests/data/metadata/fence_rsb.xml +@@ -136,6 +136,11 @@ + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_sanbox2.xml b/tests/data/metadata/fence_sanbox2.xml +index 2fa3f295b..b29b8bb75 100644 +--- a/tests/data/metadata/fence_sanbox2.xml ++++ b/tests/data/metadata/fence_sanbox2.xml +@@ -107,6 +107,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_sbd.xml b/tests/data/metadata/fence_sbd.xml +index 7248b864a..d5600b7ce 100644 +--- a/tests/data/metadata/fence_sbd.xml ++++ b/tests/data/metadata/fence_sbd.xml +@@ -65,6 +65,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +index 97c44cc21..4fa86189c 100644 +--- a/tests/data/metadata/fence_scsi.xml ++++ b/tests/data/metadata/fence_scsi.xml +@@ -90,6 +90,11 @@ When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and ve + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_skalar.xml b/tests/data/metadata/fence_skalar.xml +index 5e9f94264..84f3f4ea6 100644 +--- a/tests/data/metadata/fence_skalar.xml ++++ b/tests/data/metadata/fence_skalar.xml +@@ -122,6 +122,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_tripplite_snmp.xml b/tests/data/metadata/fence_tripplite_snmp.xml +index b767597c5..c5f66d56f 100644 +--- a/tests/data/metadata/fence_tripplite_snmp.xml ++++ b/tests/data/metadata/fence_tripplite_snmp.xml +@@ -147,6 +147,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_vbox.xml b/tests/data/metadata/fence_vbox.xml +index daf8ee98a..35577a6b6 100644 +--- a/tests/data/metadata/fence_vbox.xml ++++ b/tests/data/metadata/fence_vbox.xml +@@ -138,6 +138,11 @@ By default, vbox needs to log in as a user that is a member of the vboxusers gro + <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="," /> +diff --git a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml +index b9b4082fe..82fe9b6d1 100644 +--- a/tests/data/metadata/fence_virsh.xml ++++ b/tests/data/metadata/fence_virsh.xml +@@ -138,6 +138,11 @@ By default, virsh needs root account to do properly work. So you must allow ssh + <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="," /> +diff --git a/tests/data/metadata/fence_vmware.xml b/tests/data/metadata/fence_vmware.xml +index 8d6eabc6f..a46ffdb0f 100644 +--- a/tests/data/metadata/fence_vmware.xml ++++ b/tests/data/metadata/fence_vmware.xml +@@ -149,6 +149,11 @@ After you have successfully installed VI Perl Toolkit or VIX API, you should be + <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="delay" unique="0" required="0"> + <getopt mixed="--delay=[seconds]" /> + <content type="second" default="0" /> +diff --git a/tests/data/metadata/fence_vmware_rest.xml b/tests/data/metadata/fence_vmware_rest.xml +index e46c7a993..5c69c2f21 100644 +--- a/tests/data/metadata/fence_vmware_rest.xml ++++ b/tests/data/metadata/fence_vmware_rest.xml +@@ -128,6 +128,11 @@ NOTE: If there's more than 1000 VMs there is a filter parameter to work around t + <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="," /> +diff --git a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml +index 1327abac6..72b27e351 100644 +--- a/tests/data/metadata/fence_vmware_soap.xml ++++ b/tests/data/metadata/fence_vmware_soap.xml +@@ -119,6 +119,11 @@ Name of virtual machine (-n / port) has to be used in inventory path format (e.g + <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="," /> +diff --git a/tests/data/metadata/fence_vmware_vcloud.xml b/tests/data/metadata/fence_vmware_vcloud.xml +index 85d970e0a..3c8bb74a3 100644 +--- a/tests/data/metadata/fence_vmware_vcloud.xml ++++ b/tests/data/metadata/fence_vmware_vcloud.xml +@@ -121,6 +121,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_wti.xml b/tests/data/metadata/fence_wti.xml +index 8e15f4852..b9eb9c6bc 100644 +--- a/tests/data/metadata/fence_wti.xml ++++ b/tests/data/metadata/fence_wti.xml +@@ -136,6 +136,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_xenapi.xml b/tests/data/metadata/fence_xenapi.xml +index 83c83fff0..380ac28da 100644 +--- a/tests/data/metadata/fence_xenapi.xml ++++ b/tests/data/metadata/fence_xenapi.xml +@@ -87,6 +87,11 @@ + <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="," /> +diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml +index 192d1e76b..6996ab736 100644 +--- a/tests/data/metadata/fence_zvmip.xml ++++ b/tests/data/metadata/fence_zvmip.xml +@@ -150,6 +150,11 @@ to access the system's directory manager. + <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="," /> diff --git a/bz2160480-fence_scsi-fix-validate-all.patch b/bz2160480-fence_scsi-fix-validate-all.patch new file mode 100644 index 0000000..1aadca1 --- /dev/null +++ b/bz2160480-fence_scsi-fix-validate-all.patch @@ -0,0 +1,30 @@ +From a416a367a804f1e5abaf142c629fe6ab5572d3b6 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 12 Jan 2023 15:46:41 +0100 +Subject: [PATCH] fence_scsi: skip key generation during validate-all action + +--- + agents/scsi/fence_scsi.py | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py +index e33339614..f9e6823b2 100644 +--- a/agents/scsi/fence_scsi.py ++++ b/agents/scsi/fence_scsi.py +@@ -566,11 +566,12 @@ def main(): + or ("--key" in options and options["--key"])): + fail_usage("Failed: nodename or key is required", stop_after_error) + +- if not ("--key" in options and options["--key"]): +- options["--key"] = generate_key(options) ++ if options["--action"] != "validate-all": ++ if not ("--key" in options and options["--key"]): ++ options["--key"] = generate_key(options) + +- if options["--key"] == "0" or not options["--key"]: +- fail_usage("Failed: key cannot be 0", stop_after_error) ++ if options["--key"] == "0" or not options["--key"]: ++ fail_usage("Failed: key cannot be 0", stop_after_error) + + if "--key-value" in options\ + and (options["--key-value"] != "id" and options["--key-value"] != "hash"): diff --git a/bz2183162-fence_aws-1-add-skip-race-check-parameter.patch b/bz2183162-fence_aws-1-add-skip-race-check-parameter.patch new file mode 100644 index 0000000..254e4ff --- /dev/null +++ b/bz2183162-fence_aws-1-add-skip-race-check-parameter.patch @@ -0,0 +1,165 @@ +From 73fdae1b9da5aa1ba1d371dcc47fe31a4d22bb31 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 30 Mar 2023 12:20:05 +0200 +Subject: [PATCH] fence_aws: fixes to allow running outside of AWS network + +- add --skip-race-check parameter to allow running outside of AWS + network e.g. for openshift +- fixed and improved logging logic +- use --debug-file parameter for file logging +--- + agents/aws/fence_aws.py | 50 ++++++++++++++++++++----------- + tests/data/metadata/fence_aws.xml | 5 ++++ + 2 files changed, 37 insertions(+), 18 deletions(-) + +diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py +index c947bf29c..5d1677144 100644 +--- a/agents/aws/fence_aws.py ++++ b/agents/aws/fence_aws.py +@@ -16,13 +16,13 @@ + except ImportError: + pass + +-logger = logging.getLogger("fence_aws") ++logger = logging.getLogger() + logger.propagate = False + logger.setLevel(logging.INFO) + logger.addHandler(SyslogLibHandler()) + logging.getLogger('botocore.vendored').propagate = False + +-def get_instance_id(): ++def get_instance_id(options): + try: + token = requests.put('http://169.254.169.254/latest/api/token', headers={"X-aws-ec2-metadata-token-ttl-seconds" : "21600"}).content.decode("UTF-8") + r = requests.get('http://169.254.169.254/latest/meta-data/instance-id', headers={"X-aws-ec2-metadata-token" : token}).content.decode("UTF-8") +@@ -30,12 +30,15 @@ def get_instance_id(): + except HTTPError as http_err: + logger.error('HTTP error occurred while trying to access EC2 metadata server: %s', http_err) + except Exception as err: +- logger.error('A fatal error occurred while trying to access EC2 metadata server: %s', err) ++ if "--skip-race-check" not in options: ++ logger.error('A fatal error occurred while trying to access EC2 metadata server: %s', err) ++ else: ++ logger.debug('A fatal error occurred while trying to access EC2 metadata server: %s', err) + return None +- ++ + + def get_nodes_list(conn, options): +- logger.info("Starting monitor operation") ++ logger.debug("Starting monitor operation") + result = {} + try: + if "--filter" in options: +@@ -63,7 +66,7 @@ def get_power_status(conn, options): + try: + instance = conn.instances.filter(Filters=[{"Name": "instance-id", "Values": [options["--plug"]]}]) + state = list(instance)[0].state["Name"] +- logger.info("Status operation for EC2 instance %s returned state: %s",options["--plug"],state.upper()) ++ logger.debug("Status operation for EC2 instance %s returned state: %s",options["--plug"],state.upper()) + if state == "running": + return "on" + elif state == "stopped": +@@ -78,7 +81,7 @@ def get_power_status(conn, options): + except IndexError: + fail(EC_STATUS) + except Exception as e: +- logging.error("Failed to get power status: %s", e) ++ logger.error("Failed to get power status: %s", e) + fail(EC_STATUS) + + def get_self_power_status(conn, instance_id): +@@ -86,10 +89,10 @@ def get_self_power_status(conn, instance_id): + instance = conn.instances.filter(Filters=[{"Name": "instance-id", "Values": [instance_id]}]) + state = list(instance)[0].state["Name"] + if state == "running": +- logging.debug("Captured my (%s) state and it %s - returning OK - Proceeding with fencing",instance_id,state.upper()) ++ logger.debug("Captured my (%s) state and it %s - returning OK - Proceeding with fencing",instance_id,state.upper()) + return "ok" + else: +- logging.debug("Captured my (%s) state it is %s - returning Alert - Unable to fence other nodes",instance_id,state.upper()) ++ logger.debug("Captured my (%s) state it is %s - returning Alert - Unable to fence other nodes",instance_id,state.upper()) + return "alert" + + except ClientError: +@@ -100,18 +103,18 @@ def get_self_power_status(conn, instance_id): + return "fail" + + def set_power_status(conn, options): +- my_instance = get_instance_id() ++ my_instance = get_instance_id(options) + try: + if (options["--action"]=="off"): +- if (get_self_power_status(conn,my_instance) == "ok"): ++ if "--skip-race-check" in options or get_self_power_status(conn,my_instance) == "ok": + conn.instances.filter(InstanceIds=[options["--plug"]]).stop(Force=True) +- logger.info("Called StopInstance API call for %s", options["--plug"]) ++ logger.debug("Called StopInstance API call for %s", options["--plug"]) + else: +- logger.info("Skipping fencing as instance is not in running status") ++ logger.debug("Skipping fencing as instance is not in running status") + elif (options["--action"]=="on"): + conn.instances.filter(InstanceIds=[options["--plug"]]).start() + except Exception as e: +- logger.error("Failed to power %s %s: %s", \ ++ logger.debug("Failed to power %s %s: %s", \ + options["--action"], options["--plug"], e) + + def define_new_opts(): +@@ -156,12 +159,20 @@ def define_new_opts(): + "default": "False", + "order": 6 + } ++ all_opt["skip_race_check"] = { ++ "getopt" : "", ++ "longopt" : "skip-race-check", ++ "help" : "--skip-race-check Skip race condition check", ++ "shortdesc": "Skip race condition check", ++ "required": "0", ++ "order": 7 ++ } + + # Main agent method + def main(): + conn = None + +- device_opt = ["port", "no_password", "region", "access_key", "secret_key", "filter", "boto3_debug"] ++ device_opt = ["port", "no_password", "region", "access_key", "secret_key", "filter", "boto3_debug", "skip_race_check"] + + atexit.register(atexit_handler) + +@@ -183,12 +194,15 @@ def main(): + + run_delay(options) + +- if options.get("--verbose") is not None: +- lh = logging.FileHandler('/var/log/fence_aws_debug.log') ++ if "--debug-file" in options: ++ for handler in logger.handlers: ++ if isinstance(handler, logging.FileHandler): ++ logger.removeHandler(handler) ++ lh = logging.FileHandler(options["--debug-file"]) + logger.addHandler(lh) + lhf = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + lh.setFormatter(lhf) +- logger.setLevel(logging.DEBUG) ++ lh.setLevel(logging.DEBUG) + + if options["--boto3_debug"].lower() not in ["1", "yes", "on", "true"]: + boto3.set_stream_logger('boto3',logging.INFO) +diff --git a/tests/data/metadata/fence_aws.xml b/tests/data/metadata/fence_aws.xml +index 76995ecf2..32de4418a 100644 +--- a/tests/data/metadata/fence_aws.xml ++++ b/tests/data/metadata/fence_aws.xml +@@ -46,6 +46,11 @@ For instructions see: https://boto3.readthedocs.io/en/latest/guide/quickstart.ht + <content type="string" default="False" /> + <shortdesc lang="en">Boto Lib debug</shortdesc> + </parameter> ++ <parameter name="skip_race_check" unique="0" required="0"> ++ <getopt mixed="--skip-race-check" /> ++ <content type="boolean" /> ++ <shortdesc lang="en">Skip race condition check</shortdesc> ++ </parameter> + <parameter name="quiet" unique="0" required="0"> + <getopt mixed="-q, --quiet" /> + <content type="boolean" /> diff --git a/bz2183162-fence_aws-2-fail-when-power-action-request-fails.patch b/bz2183162-fence_aws-2-fail-when-power-action-request-fails.patch new file mode 100644 index 0000000..63ebe1a --- /dev/null +++ b/bz2183162-fence_aws-2-fail-when-power-action-request-fails.patch @@ -0,0 +1,21 @@ +From a2e2432cfec0af9a8a90f9d7fed18759da6f9b0c Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Thu, 13 Apr 2023 10:14:31 +0200 +Subject: [PATCH] fence_aws: fail when power action request fails + +--- + agents/aws/fence_aws.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/agents/aws/fence_aws.py b/agents/aws/fence_aws.py +index 5d1677144..0a375bbec 100644 +--- a/agents/aws/fence_aws.py ++++ b/agents/aws/fence_aws.py +@@ -116,6 +116,7 @@ def set_power_status(conn, options): + except Exception as e: + logger.debug("Failed to power %s %s: %s", \ + options["--action"], options["--plug"], e) ++ fail(EC_STATUS) + + def define_new_opts(): + all_opt["region"] = { diff --git a/bz2187327-fence_scsi-1-detect-devices-in-shared-vgs.patch b/bz2187327-fence_scsi-1-detect-devices-in-shared-vgs.patch new file mode 100644 index 0000000..c3f953d --- /dev/null +++ b/bz2187327-fence_scsi-1-detect-devices-in-shared-vgs.patch @@ -0,0 +1,58 @@ +From 4661b6f625c57a728ec58023da89ba378d4d1c27 Mon Sep 17 00:00:00 2001 +From: Arslan Ahmad <arslan.ahmad97@googlemail.com> +Date: Mon, 17 Apr 2023 15:59:49 +0530 +Subject: [PATCH] fence_scsi: Automatically detect devices for shared VGs + +Currently, if no devices option is given, fence_scsi automatically +builds a device list containing all LVM PVs that back VGs with the +clustered ('c') bit set. With this commit, fence_scsi will also consider +VGs with the shared ('s') bit set. + +Additionally, the existing check is too broad. We should consider a +volume group to be clustered or shared only if the 6th bit is set to 'c' +or 's'. This way, we can avoid false positives. + +Closes RHBZ#2187327 +Closes RHBZ#2187329 +--- + agents/scsi/fence_scsi.py | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py +index 85e4f29e6..3de4ba0b2 100644 +--- a/agents/scsi/fence_scsi.py ++++ b/agents/scsi/fence_scsi.py +@@ -314,7 +314,7 @@ def dev_read(fail=True, opt=None): + return devs + + +-def get_clvm_devices(options): ++def get_shared_devices(options): + devs = [] + cmd = options["--vgs-path"] + " " +\ + "--noheadings " +\ +@@ -324,10 +324,11 @@ def get_clvm_devices(options): + "--config 'global { locking_type = 0 } devices { preferred_names = [ \"^/dev/dm\" ] }'" + out = run_cmd(options, cmd) + if out["rc"]: +- fail_usage("Failed: Cannot get clvm devices") +- for line in out["out"].split("\n"): +- if 'c' in line.split(":")[0]: +- devs.append(line.split(":")[1]) ++ fail_usage("Failed: Cannot get shared devices") ++ for line in out["out"].splitlines(): ++ vg_attr, pv_name = line.strip().split(":") ++ if vg_attr[5] in "cs": ++ devs.append(pv_name) + return devs + + +@@ -612,7 +613,7 @@ def main(): + options["--key"] = options["--key"].lstrip('0') + + if not ("--devices" in options and options["--devices"].split(",")): +- options["devices"] = get_clvm_devices(options) ++ options["devices"] = get_shared_devices(options) + else: + options["devices"] = options["--devices"].split(",") + diff --git a/bz2187327-fence_scsi-2-support-space-separated-devices.patch b/bz2187327-fence_scsi-2-support-space-separated-devices.patch new file mode 100644 index 0000000..ab33efc --- /dev/null +++ b/bz2187327-fence_scsi-2-support-space-separated-devices.patch @@ -0,0 +1,92 @@ +From e363e55169a7be1cbeac5568fe2a32692867d4c6 Mon Sep 17 00:00:00 2001 +From: Arslan Ahmad <arslan.ahmad97@googlemail.com> +Date: Thu, 4 May 2023 12:55:41 +0530 +Subject: [PATCH] fence_scsi: Add support for space-separated devices and + update in meta-data + +Currently the devices associated with fence_scsi should be +comma-separated. With this commit, fence_scsi will also work if the +'devices' are space-separated. + +Additionally, this commit includes meta-data update: +1. For fence_scsi: + - The 'devices' parameter is optional if the cluster is configured with +clvm/lvmlock. + - The 'devices' parameter can be comma or space-separated. + +2. For fence_mpath: + - The 'devices' parameter can be comma or space-separated. +--- + agents/mpath/fence_mpath.py | 2 +- + agents/scsi/fence_scsi.py | 8 ++++---- + tests/data/metadata/fence_mpath.xml | 2 +- + tests/data/metadata/fence_scsi.xml | 2 +- + 4 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/agents/mpath/fence_mpath.py b/agents/mpath/fence_mpath.py +index ee81eab3a..6976fee90 100644 +--- a/agents/mpath/fence_mpath.py ++++ b/agents/mpath/fence_mpath.py +@@ -226,7 +226,7 @@ def define_new_opts(): + "help" : "-d, --devices=[devices] List of devices to use for current operation", + "required" : "0", + "shortdesc" : "List of devices to use for current operation. Devices can \ +-be comma-separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). \ ++be comma or space separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). \ + Each device must support SCSI-3 persistent reservations.", + "order": 1 + } +diff --git a/agents/scsi/fence_scsi.py b/agents/scsi/fence_scsi.py +index 3de4ba0b2..42530ceb5 100644 +--- a/agents/scsi/fence_scsi.py ++++ b/agents/scsi/fence_scsi.py +@@ -350,8 +350,8 @@ def define_new_opts(): + "help" : "-d, --devices=[devices] List of devices to use for current operation", + "required" : "0", + "shortdesc" : "List of devices to use for current operation. Devices can \ +-be comma-separated list of raw devices (eg. /dev/sdc). Each device must support SCSI-3 \ +-persistent reservations.", ++be comma or space separated list of raw devices (eg. /dev/sdc). Each device must support SCSI-3 \ ++persistent reservations. Optional if cluster is configured with clvm or lvmlockd.", + "order": 1 + } + all_opt["nodename"] = { +@@ -612,10 +612,10 @@ def main(): + + options["--key"] = options["--key"].lstrip('0') + +- if not ("--devices" in options and options["--devices"].split(",")): ++ if not ("--devices" in options and [d for d in re.split("\s*,\s*|\s+", options["--devices"].strip()) if d]): + options["devices"] = get_shared_devices(options) + else: +- options["devices"] = options["--devices"].split(",") ++ options["devices"] = [d for d in re.split("\s*,\s*|\s+", options["--devices"].strip()) if d] + + if not options["devices"]: + fail_usage("Failed: No devices found") +diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml +index e22d3a1f9..262956dca 100644 +--- a/tests/data/metadata/fence_mpath.xml ++++ b/tests/data/metadata/fence_mpath.xml +@@ -14,7 +14,7 @@ When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and ve + <parameter name="devices" unique="0" required="0"> + <getopt mixed="-d, --devices=[devices]" /> + <content type="string" /> +- <shortdesc lang="en">List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). Each device must support SCSI-3 persistent reservations.</shortdesc> ++ <shortdesc lang="en">List of devices to use for current operation. Devices can be comma or space separated list of device-mapper multipath devices (eg. /dev/mapper/3600508b400105df70000e00000ac0000 or /dev/mapper/mpath1). Each device must support SCSI-3 persistent reservations.</shortdesc> + </parameter> + <parameter name="key" unique="0" required="0"> + <getopt mixed="-k, --key=[key]" /> +diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml +index 4fa86189c..facb2f52e 100644 +--- a/tests/data/metadata/fence_scsi.xml ++++ b/tests/data/metadata/fence_scsi.xml +@@ -19,7 +19,7 @@ When used as a watchdog device you can define e.g. retry=1, retry-sleep=2 and ve + <parameter name="devices" unique="0" required="0"> + <getopt mixed="-d, --devices=[devices]" /> + <content type="string" /> +- <shortdesc lang="en">List of devices to use for current operation. Devices can be comma-separated list of raw devices (eg. /dev/sdc). Each device must support SCSI-3 persistent reservations.</shortdesc> ++ <shortdesc lang="en">List of devices to use for current operation. Devices can be comma or space separated list of raw devices (eg. /dev/sdc). Each device must support SCSI-3 persistent reservations. Optional if cluster is configured with clvm or lvmlockd.</shortdesc> + </parameter> + <parameter name="key" unique="0" required="0"> + <getopt mixed="-k, --key=[key]" /> diff --git a/bz2211930-fence_azure-arm-stack-hub-support.patch b/bz2211930-fence_azure-arm-stack-hub-support.patch new file mode 100644 index 0000000..9afa1cc --- /dev/null +++ b/bz2211930-fence_azure-arm-stack-hub-support.patch @@ -0,0 +1,170 @@ +From 6e0228536d30ca1bd95bfd1628c0247f094ecaa8 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Wed, 2 Mar 2022 13:49:16 +0100 +Subject: [PATCH 1/2] fence_azure_arm: add stack cloud support + +--- + agents/azure_arm/fence_azure_arm.py | 18 ++++++++++++++---- + lib/azure_fence.py.py | 10 ++++++++++ + tests/data/metadata/fence_azure_arm.xml | 10 ++++++++++ + 3 files changed, 34 insertions(+), 4 deletions(-) + +diff --git a/agents/azure_arm/fence_azure_arm.py b/agents/azure_arm/fence_azure_arm.py +index 6908169c8..e3b7c85c7 100755 +--- a/agents/azure_arm/fence_azure_arm.py ++++ b/agents/azure_arm/fence_azure_arm.py +@@ -183,20 +183,30 @@ def define_new_opts(): + "getopt" : ":", + "longopt" : "cloud", + "help" : "--cloud=[name] Name of the cloud you want to use. Supported\n\ +- values are china, germany or usgov. Do not use\n\ +- this parameter if you want to use public\n\ +- Azure.", ++ values are china, germany, usgov, or stack. Do\n\ ++ not use this parameter if you want to use\n\ ++ public Azure.", + "shortdesc" : "Name of the cloud you want to use.", + "required" : "0", + "order" : 7 + } ++ all_opt["metadata-endpoint"] = { ++ "getopt" : ":", ++ "longopt" : "metadata-endpoint", ++ "help" : "--metadata-endpoint=[URL] URL to metadata endpoint (used when cloud=stack).", ++ "shortdesc" : "URL to metadata endpoint (used when cloud=stack).", ++ "required" : "0", ++ "order" : 8 ++ } + + # Main agent method + def main(): + compute_client = None + network_client = None + +- device_opt = ["login", "no_login", "no_password", "passwd", "port", "resourceGroup", "tenantId", "subscriptionId", "network-fencing", "msi", "cloud"] ++ device_opt = ["login", "no_login", "no_password", "passwd", "port", ++ "resourceGroup", "tenantId", "subscriptionId", ++ "network-fencing", "msi", "cloud", "metadata-endpoint"] + + atexit.register(atexit_handler) + +diff --git a/lib/azure_fence.py.py b/lib/azure_fence.py.py +index 5ca71eb42..6f1eee5b9 100644 +--- a/lib/azure_fence.py.py ++++ b/lib/azure_fence.py.py +@@ -251,6 +251,7 @@ def get_azure_config(options): + config.VMName = options.get("--plug")
+ config.SubscriptionId = options.get("--subscriptionId")
+ config.Cloud = options.get("--cloud")
++ config.MetadataEndpoint = options.get("--metadata-endpoint")
+ config.UseMSI = "--msi" in options
+ config.Tenantid = options.get("--tenantId")
+ config.ApplicationId = options.get("--username")
+@@ -279,6 +280,9 @@ def get_azure_cloud_environment(config): + elif (config.Cloud.lower() == "usgov"):
+ from msrestazure.azure_cloud import AZURE_US_GOV_CLOUD
+ cloud_environment = AZURE_US_GOV_CLOUD
++ elif (config.Cloud.lower() == "stack"):
++ from msrestazure.azure_cloud import get_cloud_from_metadata_endpoint
++ cloud_environment = get_cloud_from_metadata_endpoint(config.MetadataEndpoint)
+
+ return cloud_environment
+
+@@ -345,6 +349,9 @@ def get_azure_compute_client(config): + credentials = get_azure_credentials(config)
+
+ if cloud_environment:
++ if (config.Cloud.lower() == "stack") and not config.MetadataEndpoint:
++ fail_usage("metadata-endpoint not specified")
++
+ try:
+ compute_client = ComputeManagementClient(
+ credentials,
+@@ -372,6 +379,9 @@ def get_azure_network_client(config): + credentials = get_azure_credentials(config)
+
+ if cloud_environment:
++ if (config.Cloud.lower() == "stack") and not config.MetadataEndpoint:
++ fail_usage("metadata-endpoint not specified")
++
+ try:
+ network_client = NetworkManagementClient(
+ credentials,
+diff --git a/tests/data/metadata/fence_azure_arm.xml b/tests/data/metadata/fence_azure_arm.xml +index c6e1f203b..8b7450762 100644 +--- a/tests/data/metadata/fence_azure_arm.xml ++++ b/tests/data/metadata/fence_azure_arm.xml +@@ -98,6 +98,16 @@ When using network fencing the reboot-action will cause a quick-return once the + <content type="string" /> + <shortdesc lang="en">Name of the cloud you want to use.</shortdesc> + </parameter> ++ <parameter name="metadata-endpoint" unique="0" required="0" deprecated="1"> ++ <getopt mixed="--metadata-endpoint=[URL]" /> ++ <content type="string" /> ++ <shortdesc lang="en">URL to metadata endpoint (used when cloud=stack).</shortdesc> ++ </parameter> ++ <parameter name="metadata_endpoint" unique="0" required="0" obsoletes="metadata-endpoint"> ++ <getopt mixed="--metadata-endpoint=[URL]" /> ++ <content type="string" /> ++ <shortdesc lang="en">URL to metadata endpoint (used when cloud=stack).</shortdesc> ++ </parameter> + <parameter name="quiet" unique="0" required="0"> + <getopt mixed="-q, --quiet" /> + <content type="boolean" /> + +From 9087760db005abfd9b3e07319846232214d8dae2 Mon Sep 17 00:00:00 2001 +From: Oyvind Albrigtsen <oalbrigt@redhat.com> +Date: Fri, 16 Jun 2023 16:03:11 +0200 +Subject: [PATCH 2/2] azure_fence: use correct credential_scope and profile for + stack hub + +--- + lib/azure_fence.py.py | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/lib/azure_fence.py.py b/lib/azure_fence.py.py +index 6f1eee5b9..ab40b483a 100644 +--- a/lib/azure_fence.py.py ++++ b/lib/azure_fence.py.py +@@ -353,11 +353,19 @@ def get_azure_compute_client(config): + fail_usage("metadata-endpoint not specified")
+
+ try:
++ from azure.profiles import KnownProfiles
++ if (config.Cloud.lower() == "stack"):
++ client_profile = KnownProfiles.v2020_09_01_hybrid
++ credential_scope = cloud_environment.endpoints.active_directory_resource_id + "/.default"
++ else:
++ client_profile = KnownProfiles.default
++ credential_scope = cloud_environment.endpoints.resource_manager + "/.default"
+ compute_client = ComputeManagementClient(
+ credentials,
+ config.SubscriptionId,
+ base_url=cloud_environment.endpoints.resource_manager,
+- credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
++ profile=client_profile,
++ credential_scopes=[credential_scope],
+ )
+ except TypeError:
+ compute_client = ComputeManagementClient(
+@@ -383,11 +391,19 @@ def get_azure_network_client(config): + fail_usage("metadata-endpoint not specified")
+
+ try:
++ from azure.profiles import KnownProfiles
++ if (config.Cloud.lower() == "stack"):
++ client_profile = KnownProfiles.v2020_09_01_hybrid
++ credential_scope = cloud_environment.endpoints.active_directory_resource_id + "/.default"
++ else:
++ client_profile = KnownProfiles.default
++ credential_scope = cloud_environment.endpoints.resource_manager + "/.default"
+ network_client = NetworkManagementClient(
+ credentials,
+ config.SubscriptionId,
+ base_url=cloud_environment.endpoints.resource_manager,
+- credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
++ profile=client_profile,
++ credential_scopes=[credential_scope],
+ )
+ except TypeError:
+ network_client = NetworkManagementClient(
diff --git a/bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch b/bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch new file mode 100644 index 0000000..97707a5 --- /dev/null +++ b/bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch @@ -0,0 +1,17 @@ +--- a/kubevirt/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 ++++ b/kubevirt/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 +@@ -21,7 +21,12 @@ + try: + with TarFile.open(filename) as tf: + for name in zonegroups: +- tf.extract(name, tmpdir) ++ if hasattr(tarfile, 'data_filter'): ++ # Python with CVE-2007-4559 mitigation (PEP 706) ++ tf.extract(name, tmpdir, filter='data') ++ else: ++ # Fallback to a possibly dangerous extraction (before PEP 706) ++ tf.extract(name, tmpdir) + filepaths = [os.path.join(tmpdir, n) for n in zonegroups] + + _run_zic(zonedir, filepaths) + diff --git a/bz2217902-2-aws-awscli-azure-fix-bundled-dateutil-CVE-2007-4559.patch b/bz2217902-2-aws-awscli-azure-fix-bundled-dateutil-CVE-2007-4559.patch new file mode 100644 index 0000000..9706cec --- /dev/null +++ b/bz2217902-2-aws-awscli-azure-fix-bundled-dateutil-CVE-2007-4559.patch @@ -0,0 +1,50 @@ +--- a/aws/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 ++++ b/aws/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 +@@ -21,7 +21,12 @@ + try: + with TarFile.open(filename) as tf: + for name in zonegroups: +- tf.extract(name, tmpdir) ++ if hasattr(tarfile, 'data_filter'): ++ # Python with CVE-2007-4559 mitigation (PEP 706) ++ tf.extract(name, tmpdir, filter='data') ++ else: ++ # Fallback to a possibly dangerous extraction (before PEP 706) ++ tf.extract(name, tmpdir) + filepaths = [os.path.join(tmpdir, n) for n in zonegroups] + + _run_zic(zonedir, filepaths) + +--- a/awscli/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 ++++ b/awscli/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 +@@ -21,7 +21,12 @@ + try: + with TarFile.open(filename) as tf: + for name in zonegroups: +- tf.extract(name, tmpdir) ++ if hasattr(tarfile, 'data_filter'): ++ # Python with CVE-2007-4559 mitigation (PEP 706) ++ tf.extract(name, tmpdir, filter='data') ++ else: ++ # Fallback to a possibly dangerous extraction (before PEP 706) ++ tf.extract(name, tmpdir) + filepaths = [os.path.join(tmpdir, n) for n in zonegroups] + + _run_zic(zonedir, filepaths) + +--- a/azure/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 ++++ b/azure/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 +@@ -21,7 +21,12 @@ + try: + with TarFile.open(filename) as tf: + for name in zonegroups: +- tf.extract(name, tmpdir) ++ if hasattr(tarfile, 'data_filter'): ++ # Python with CVE-2007-4559 mitigation (PEP 706) ++ tf.extract(name, tmpdir, filter='data') ++ else: ++ # Fallback to a possibly dangerous extraction (before PEP 706) ++ tf.extract(name, tmpdir) + filepaths = [os.path.join(tmpdir, n) for n in zonegroups] + + _run_zic(zonedir, filepaths) diff --git a/bz2221643-fence_ibm_powervs-performance-improvements.patch b/bz2221643-fence_ibm_powervs-performance-improvements.patch new file mode 100644 index 0000000..c232a3c --- /dev/null +++ b/bz2221643-fence_ibm_powervs-performance-improvements.patch @@ -0,0 +1,150 @@ +From 22935608247816be0ccec85fc590f19b509f3614 Mon Sep 17 00:00:00 2001 +From: Andreas Schauberer <74912604+andscha@users.noreply.github.com> +Date: Thu, 15 Jun 2023 16:34:13 +0200 +Subject: [PATCH 1/3] fence_ibm_powervs: improved performance + +fence_ibm_powervs: improved performance +- improved performance using less power-iaas.cloud.ibm.com API calls +- add support for reboot_cycle, method to fence (onoff|cycle) (Default: onoff) + +Addressed comments by oalbrigt in ClusterLabs #PR542 +- you can use if options["--verbose-level"] > 1: to only print it when -vv or more or verbose_level is set to 2 or higher. +- Removed all_opt["method"] defaults +--- + agents/ibm_powervs/fence_ibm_powervs.py | 70 ++++++++++++++++++------- + 1 file changed, 51 insertions(+), 19 deletions(-) + +diff --git a/agents/ibm_powervs/fence_ibm_powervs.py b/agents/ibm_powervs/fence_ibm_powervs.py +index 183893616..e65462cb9 100755 +--- a/agents/ibm_powervs/fence_ibm_powervs.py ++++ b/agents/ibm_powervs/fence_ibm_powervs.py +@@ -12,6 +12,8 @@ + state = { + "ACTIVE": "on", + "SHUTOFF": "off", ++ "HARD_REBOOT": "on", ++ "SOFT_REBOOT": "on", + "ERROR": "unknown" + } + +@@ -37,21 +39,30 @@ def get_list(conn, options): + return outlets + + for r in res["pvmInstances"]: +- if "--verbose" in options: ++ if options["--verbose-level"] > 1: + logging.debug(json.dumps(r, indent=2)) + outlets[r["pvmInstanceID"]] = (r["serverName"], state[r["status"]]) + + return outlets + + def get_power_status(conn, options): ++ outlets = {} ++ logging.debug("Info: getting power status for LPAR " + options["--plug"] + " instance " + options["--instance"]) + try: + command = "cloud-instances/{}/pvm-instances/{}".format( + options["--instance"], options["--plug"]) + res = send_command(conn, command) +- result = get_list(conn, options)[options["--plug"]][1] ++ outlets[res["pvmInstanceID"]] = (res["serverName"], state[res["status"]]) ++ if options["--verbose-level"] > 1: ++ logging.debug(json.dumps(res, indent=2)) ++ result = outlets[options["--plug"]][1] ++ logging.debug("Info: Status: {}".format(result)) + except KeyError as e: +- logging.debug("Failed: Unable to get status for {}".format(e)) +- fail(EC_STATUS) ++ try: ++ result = get_list(conn, options)[options["--plug"]][1] ++ except KeyError as ex: ++ logging.debug("Failed: Unable to get status for {}".format(ex)) ++ fail(EC_STATUS) + + return result + +@@ -61,6 +72,7 @@ def set_power_status(conn, options): + "off" : '{"action" : "immediate-shutdown"}', + }[options["--action"]] + ++ logging.debug("Info: set power status to " + options["--action"] + " for LPAR " + options["--plug"] + " instance " + options["--instance"]) + try: + send_command(conn, "cloud-instances/{}/pvm-instances/{}/action".format( + options["--instance"], options["--plug"]), "POST", action) +@@ -68,6 +80,25 @@ def set_power_status(conn, options): + logging.debug("Failed: Unable to set power to {} for {}".format(options["--action"], e)) + fail(EC_STATUS) + ++def reboot_cycle(conn, options): ++ action = { ++ "reboot" : '{"action" : "hard-reboot"}', ++ }[options["--action"]] ++ ++ logging.debug("Info: start reboot cycle with action " + options["--action"] + " for LPAR " + options["--plug"] + " instance " + options["--instance"]) ++ try: ++ send_command(conn, "cloud-instances/{}/pvm-instances/{}/action".format( ++ options["--instance"], options["--plug"]), "POST", action) ++ except Exception as e: ++ result = get_power_status(conn, options) ++ logging.debug("Info: Status {}".format(result)) ++ if result == "off": ++ return True ++ else: ++ logging.debug("Failed: Unable to cycle with {} for {}".format(options["--action"], e)) ++ fail(EC_STATUS) ++ return True ++ + def connect(opt, token): + conn = pycurl.Curl() + +@@ -200,21 +231,21 @@ def define_new_opts(): + "order" : 0 + } + all_opt["api-type"] = { +- "getopt" : ":", +- "longopt" : "api-type", +- "help" : "--api-type=[public|private] API-type: 'public' (default) or 'private'", +- "required" : "0", +- "shortdesc" : "API-type (public|private)", +- "order" : 0 +- } ++ "getopt" : ":", ++ "longopt" : "api-type", ++ "help" : "--api-type=[public|private] API-type: 'public' (default) or 'private'", ++ "required" : "0", ++ "shortdesc" : "API-type (public|private)", ++ "order" : 0 ++ } + all_opt["proxy"] = { +- "getopt" : ":", +- "longopt" : "proxy", +- "help" : "--proxy=[http://<URL>:<PORT>] Proxy: 'http://<URL>:<PORT>'", +- "required" : "0", +- "shortdesc" : "Network proxy", +- "order" : 0 +- } ++ "getopt" : ":", ++ "longopt" : "proxy", ++ "help" : "--proxy=[http://<URL>:<PORT>] Proxy: 'http://<URL>:<PORT>'", ++ "required" : "0", ++ "shortdesc" : "Network proxy", ++ "order" : 0 ++ } + + + def main(): +@@ -227,6 +258,7 @@ def main(): + "proxy", + "port", + "no_password", ++ "method", + ] + + atexit.register(atexit_handler) +@@ -259,7 +291,7 @@ def main(): + conn = connect(options, token) + atexit.register(disconnect, conn) + +- result = fence_action(conn, options, set_power_status, get_power_status, get_list) ++ result = fence_action(conn, options, set_power_status, get_power_status, get_list, reboot_cycle) + + sys.exit(result) diff --git a/bz2224267-fence_ipmilan-fix-typos-in-metadata.patch b/bz2224267-fence_ipmilan-fix-typos-in-metadata.patch new file mode 100644 index 0000000..61342cf --- /dev/null +++ b/bz2224267-fence_ipmilan-fix-typos-in-metadata.patch @@ -0,0 +1,123 @@ +From ddfaa29150d0d6fd8841b3e39fa5e806812542b5 Mon Sep 17 00:00:00 2001 +From: razo7 <oraz@redhat.com> +Date: Wed, 19 Jul 2023 16:33:01 +0300 +Subject: [PATCH] Fix typo in fence_ipmilan description + +Add spaces in the long description +--- + agents/ipmilan/fence_ipmilan.py | 4 ++-- + tests/data/metadata/fence_idrac.xml | 2 +- + tests/data/metadata/fence_ilo3.xml | 2 +- + tests/data/metadata/fence_ilo4.xml | 2 +- + tests/data/metadata/fence_ilo5.xml | 2 +- + tests/data/metadata/fence_imm.xml | 2 +- + tests/data/metadata/fence_ipmilan.xml | 2 +- + tests/data/metadata/fence_ipmilanplus.xml | 2 +- + 8 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/agents/ipmilan/fence_ipmilan.py b/agents/ipmilan/fence_ipmilan.py +index 0acf977da..91e09ac7d 100644 +--- a/agents/ipmilan/fence_ipmilan.py ++++ b/agents/ipmilan/fence_ipmilan.py +@@ -203,8 +203,8 @@ def main(): + + docs = {} + docs["shortdesc"] = "Fence agent for IPMI" +- docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent\ +-which can be used with machines controlled by IPMI.\ ++ docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent \ ++which can be used with machines controlled by IPMI. \ + This agent calls support software ipmitool (http://ipmitool.sf.net/). \ + WARNING! This fence agent might report success before the node is powered off. \ + You should use -m/method onoff if your fence device works correctly with that option." +diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml +index 2d4876493..d1f283e4a 100644 +--- a/tests/data/metadata/fence_idrac.xml ++++ b/tests/data/metadata/fence_idrac.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml +index 0567b539c..5aca0211b 100644 +--- a/tests/data/metadata/fence_ilo3.xml ++++ b/tests/data/metadata/fence_ilo3.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml +index 647bb1021..3aa001ad2 100644 +--- a/tests/data/metadata/fence_ilo4.xml ++++ b/tests/data/metadata/fence_ilo4.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ilo5.xml b/tests/data/metadata/fence_ilo5.xml +index 6c99db22a..262787905 100644 +--- a/tests/data/metadata/fence_ilo5.xml ++++ b/tests/data/metadata/fence_ilo5.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml +index 5c5bf910f..26f9a76d3 100644 +--- a/tests/data/metadata/fence_imm.xml ++++ b/tests/data/metadata/fence_imm.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml +index a31afcfd4..daad65a70 100644 +--- a/tests/data/metadata/fence_ipmilan.xml ++++ b/tests/data/metadata/fence_ipmilan.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> +diff --git a/tests/data/metadata/fence_ipmilanplus.xml b/tests/data/metadata/fence_ipmilanplus.xml +index 19c252933..7b678b245 100644 +--- a/tests/data/metadata/fence_ipmilanplus.xml ++++ b/tests/data/metadata/fence_ipmilanplus.xml +@@ -6,7 +6,7 @@ + <symlink name="fence_ipmilanplus" shortdesc="Fence agent for IPMIv2 lanplus"/> + <symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/> + <symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/> +-<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> ++<longdesc>fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software ipmitool (http://ipmitool.sf.net/). WARNING! This fence agent might report success before the node is powered off. You should use -m/method onoff if your fence device works correctly with that option.</longdesc> + <vendor-url></vendor-url> + <parameters> + <parameter name="action" unique="0" required="1"> diff --git a/fence-agents.spec b/fence-agents.spec new file mode 100644 index 0000000..7be5335 --- /dev/null +++ b/fence-agents.spec @@ -0,0 +1,2014 @@ +# Copyright 2004-2011 Red Hat, Inc. +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions +# of the GNU General Public License v.2. + +# keep around ready for later user +## global alphatag git0a6184070 + +# bundles +# azure +%global oauthlib oauthlib +%global oauthlib_version 3.2.2 +# 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 2023.7.22 +%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 5.1 +%global six six +%global six_version 1.16.0 +%global urllib3 urllib3 +%global urllib3_version 1.26.18 +%global websocketclient websocket-client +%global websocketclient_version 1.2.1 +%global jinja2 Jinja2 +%global jinja2_version 3.1.3 +%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 ruamelyaml ruamel.yaml +%global ruamelyaml_version 0.17.16 + +Name: fence-agents +Summary: Set of unified programs capable of host isolation ("fencing") +Version: 4.10.0 +Release: 76%{?alphatag:.%{alphatag}}%{?dist} +License: GPLv2+ and LGPLv2+ +URL: https://github.com/ClusterLabs/fence-agents +Source0: https://fedorahosted.org/releases/f/e/fence-agents/%{name}-%{version}.tar.gz +### HA support requirements-*.txt ### +Source100: requirements-aliyun.txt +Source101: requirements-aws.txt +Source102: requirements-azure.txt +Source103: requirements-google.txt +Source104: requirements-common.txt +### HA support libs/utils ### +# awscli 2+ is only available from github (and needs to be renamed from aws-cli... to awscli) +Source900: awscli-2.2.15.tar.gz +# From awscli's requirements.txt: https://github.com/boto/botocore/zipball/v2#egg=botocore +Source901: botocore-2.0.0dev123.zip +# update with ./update-ha-support.sh and replace lines below with output +### BEGIN ### +# aliyun +Source1000: aliyun-python-sdk-core-2.11.5.tar.gz +Source1001: aliyun_python_sdk_ecs-4.24.7-py2.py3-none-any.whl +Source1002: cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl +Source1003: colorama-0.3.3.tar.gz +Source1004: jmespath-0.7.1-py2.py3-none-any.whl +Source1005: pycryptodome-3.20.0.tar.gz +Source1006: pycparser-2.20-py2.py3-none-any.whl +# aliyun-cli +Source2000: aliyun-cli-3.0.198.tar.gz +## TAG=$(git log --pretty="format:%h" -n 1) +## distdir="aliyun-openapi-meta-${TAG}" +## TARFILE="${distdir}.tar.gz" +## rm -rf $TARFILE $distdir +## git archive --prefix=$distdir/ HEAD | gzip > $TARFILE +Source2001: aliyun-openapi-meta-5cf98b660.tar.gz +## go mod vendor +Source2002: aliyun-cli-go-vendor.tar.gz +# awscli +Source1008: awscrt-0.11.13-cp39-cp39-manylinux2014_x86_64.whl +Source1009: colorama-0.4.3-py2.py3-none-any.whl +Source1010: cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl +Source1011: distro-1.5.0-py2.py3-none-any.whl +Source1012: docutils-0.15.2-py3-none-any.whl +Source1013: prompt_toolkit-2.0.10-py3-none-any.whl +Source1014: ruamel.yaml-0.15.100.tar.gz +Source1015: six-1.16.0-py2.py3-none-any.whl +Source1016: wcwidth-0.1.9-py2.py3-none-any.whl +# aws +Source1017: boto3-1.17.102-py2.py3-none-any.whl +Source1018: botocore-1.20.102-py2.py3-none-any.whl +Source1019: python_dateutil-2.8.1-py2.py3-none-any.whl +Source1020: s3transfer-0.4.2-py2.py3-none-any.whl +Source1021: urllib3-1.26.18.tar.gz +# azure +Source1022: adal-1.2.7-py2.py3-none-any.whl +Source1023: azure_common-1.1.27-py2.py3-none-any.whl +Source1024: azure_core-1.15.0-py2.py3-none-any.whl +Source1025: azure_mgmt_compute-21.0.0-py2.py3-none-any.whl +Source1026: azure_mgmt_core-1.2.2-py2.py3-none-any.whl +Source1027: azure_mgmt_network-19.0.0-py2.py3-none-any.whl +Source1028: azure-identity-1.10.0.zip +Source1029: chardet-4.0.0-py2.py3-none-any.whl +Source1030: idna-2.10-py2.py3-none-any.whl +Source1031: isodate-0.6.0-py2.py3-none-any.whl +Source1032: msrest-0.6.21-py2.py3-none-any.whl +Source1033: msrestazure-0.6.4-py2.py3-none-any.whl +Source1034: %{oauthlib}-%{oauthlib_version}.tar.gz +Source1035: PyJWT-2.1.0-py3-none-any.whl +Source1036: requests-2.25.1-py2.py3-none-any.whl +Source1037: requests_oauthlib-1.3.0-py2.py3-none-any.whl +Source1038: msal-1.18.0.tar.gz +Source1039: msal-extensions-1.0.0.tar.gz +Source1040: portalocker-2.5.1.tar.gz +# google +Source1041: cachetools-4.2.2-py3-none-any.whl +Source1042: chardet-3.0.4-py2.py3-none-any.whl +Source1043: google_api_core-1.30.0-py2.py3-none-any.whl +Source1044: google_api_python_client-1.12.8-py2.py3-none-any.whl +Source1045: googleapis_common_protos-1.53.0-py2.py3-none-any.whl +Source1046: google_auth-1.32.0-py2.py3-none-any.whl +Source1047: google_auth_httplib2-0.1.0-py2.py3-none-any.whl +Source1048: httplib2-0.19.1-py3-none-any.whl +Source1049: packaging-20.9-py2.py3-none-any.whl +Source1050: protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl +Source1051: pyasn1-0.4.8-py2.py3-none-any.whl +Source1052: pyasn1_modules-0.2.8-py2.py3-none-any.whl +Source1053: pyparsing-2.4.7-py2.py3-none-any.whl +Source1054: pyroute2-0.7.12.tar.gz +Source1055: pyroute2.core-0.6.13.tar.gz +Source1056: pyroute2.ethtool-0.6.13.tar.gz +Source1057: pyroute2.ipdb-0.6.13.tar.gz +Source1058: pyroute2.ipset-0.6.13.tar.gz +Source1059: pyroute2.ndb-0.6.13.tar.gz +Source1060: pyroute2.nftables-0.6.13.tar.gz +Source1061: pyroute2.nslink-0.6.13.tar.gz +Source1062: pytz-2021.1-py2.py3-none-any.whl +Source1063: rsa-4.7.2-py3-none-any.whl +Source1064: setuptools-71.1.0.tar.gz +Source1065: uritemplate-3.0.1-py2.py3-none-any.whl +# common (pexpect / suds) +Source1066: pexpect-4.8.0-py2.py3-none-any.whl +Source1067: ptyprocess-0.7.0-py2.py3-none-any.whl +Source1068: suds_community-0.8.5-py3-none-any.whl +### END ### +# kubevirt +## pip download --no-binary :all: openshift "ruamel.yaml.clib>=0.1.2" +### BEGIN +Source1069: %{openshift}-%{openshift_version}.tar.gz +Source1070: %{ruamelyamlclib}-%{ruamelyamlclib_version}.tar.gz +Source1071: %{kubernetes}-%{kubernetes_version}.tar.gz +Source1072: %{certifi}-%{certifi_version}.tar.gz +Source1073: %{googleauth}-%{googleauth_version}.tar.gz +Source1074: %{cachetools}-%{cachetools_version}.tar.gz +Source1075: %{pyasn1modules}-%{pyasn1modules_version}.tar.gz +Source1076: %{pyasn1}-%{pyasn1_version}.tar.gz +Source1077: python-%{dateutil}-%{dateutil_version}.tar.gz +Source1078: %{pyyaml}-%{pyyaml_version}.tar.gz +## rsa is dependency for "pip install", +## but gets removed to use cryptography lib instead +Source1079: rsa-4.7.2.tar.gz +Source1080: %{six}-%{six_version}.tar.gz +Source1081: %{websocketclient}-%{websocketclient_version}.tar.gz +Source1082: %{jinja2}-%{jinja2_version}.tar.gz +Source1083: %{markupsafe}-%{markupsafe_version}.tar.gz +Source1084: python-%{stringutils}-%{stringutils_version}.tar.gz +Source1085: %{requests}-%{requests_version}.tar.gz +Source1086: %{chrstnormalizer}-%{chrstnormalizer_version}.tar.gz +Source1087: %{idna}-%{idna_version}.tar.gz +Source1088: %{reqstsoauthlib}-%{reqstsoauthlib_version}.tar.gz +Source1089: %{ruamelyaml}-%{ruamelyaml_version}.tar.gz +## required for installation +Source1090: setuptools_scm-8.1.0.tar.gz +Source1091: packaging-21.2-py3-none-any.whl +Source1092: poetry-core-1.0.7.tar.gz +Source1093: pyparsing-3.0.1.tar.gz +Source1094: tomli-2.0.1.tar.gz +Source1095: flit_core-3.9.0.tar.gz +Source1096: typing_extensions-4.12.2.tar.gz +Source1097: wheel-0.37.0-py2.py3-none-any.whl +### END + +Patch0: ha-cloud-support-aliyun.patch +Patch1: ha-cloud-support-aws.patch +Patch2: ha-cloud-support-azure.patch +Patch3: ha-cloud-support-google.patch +Patch4: bundled-pexpect.patch +Patch5: bundled-suds.patch +Patch6: bz2010652-fence_azure_arm-fix-sovereign-cloud-msi-support.patch +Patch7: bz2010709-1-fence_amt_ws-fix-or-causing-dead-code.patch +Patch8: bz2010709-2-fence_amt_ws-boot-option.patch +Patch9: bz2000954-1-configure-fix-virt.patch +Patch10: bz2000954-2-fence_kubevirt.patch +Patch11: bz2022334-fence_zvmip-add-ssl-tls-support.patch +Patch12: bz2029791-1-fence_openstack-add-ssl-insecure.patch +Patch13: bz2029791-2-fence_openstack-cacert-default.patch +Patch14: bz2000954-3-fence_kubevirt-get-namespace-from-context.patch +Patch15: bz2041933-bz2041935-1-fence_openstack-clouds-openrc.patch +Patch16: bz2041933-bz2041935-2-fence_openstack-clouds-openrc.patch +Patch17: bz2042496-fence_ibm_vpc-fence_ibm_powervs.patch +Patch18: bz2022334-fence_zvmip-add-disable-ssl.patch +Patch19: bz2065114-fence_lpar-refactor.patch +Patch20: bz2072420-1-all-agents-unify-ssl-parameters.patch +Patch21: bz2079889-fence_gce-update.patch +Patch22: bz2081235-fence_ibm_vpc-fix-parameters.patch +Patch23: bz2086559-fence_apc-fence_ilo_moonshot-import-logging.patch +Patch24: bz2072420-2-fence_zvmip-connect-error.patch +Patch25: bz2092385-fence_ibm_vpc-add-proxy-support.patch +Patch26: bz2093216-fence_ibm_powervs-proxy-private-api-servers.patch +Patch27: bz2041933-bz2041935-3-fencing-source_env-dont-process-empty-lines.patch +Patch28: bz2122944-1-fence_vmware_soap-set-timeout-cleanup-tmp-dirs.patch +Patch29: bz2122944-2-fence_vmware_soap-login-timeout-15s.patch +Patch30: bz2111998-fence_ibm_vpc-add-token-cache-support.patch +Patch31: bz2132008-fence_virt-add-note-reboot-action.patch +Patch32: bz2134015-fence_lpar-only-output-additional-info-on-debug.patch +Patch33: bz2136191-fence_ibm_powervs-improve-defaults.patch +Patch34: bz2138823-fence_virtd-update-manpage.patch +Patch35: bz2144531-fence_virtd-warn-files-not-mode-600.patch +Patch36: bz2149655-fence_virtd-update-fence_virt.conf-manpage.patch +Patch37: bz2160480-fence_scsi-fix-validate-all.patch +Patch38: bz2152107-fencing-1-add-plug_separator.patch +Patch39: bz2152107-fencing-2-update-DEPENDENCY_OPT.patch +Patch40: bz2183162-fence_aws-1-add-skip-race-check-parameter.patch +Patch41: bz2183162-fence_aws-2-fail-when-power-action-request-fails.patch +Patch42: bz2187327-fence_scsi-1-detect-devices-in-shared-vgs.patch +Patch43: bz2187327-fence_scsi-2-support-space-separated-devices.patch +Patch44: bz2211930-fence_azure-arm-stack-hub-support.patch +Patch45: bz2221643-fence_ibm_powervs-performance-improvements.patch +Patch46: bz2224267-fence_ipmilan-fix-typos-in-metadata.patch +Patch47: RHEL-5396-fence_scsi-1-fix-ISID-reg-handling.patch +Patch48: RHEL-5396-fence_scsi-2-fix-ISID-reg-handling-off.patch +Patch49: RHEL-14344-fence_zvmip-1-document-user-permissions.patch +Patch50: RHEL-14030-1-all-agents-metadata-update-IO-Power-Network.patch +Patch51: RHEL-14030-2-fence_cisco_mds-undo-metadata-change.patch +Patch52: RHEL-14344-fence_zvmip-2-fix-manpage-formatting.patch +Patch53: RHEL-31488-RHEL-31485-RHEL-31483-fence_aliyun-update.patch +Patch54: RHEL-35263-fence_eps-add-fence_epsr2-for-ePowerSwitch-R2-and-newer.patch +Patch55: RHEL-25256-fence_vmware_rest-detect-user-sufficient-rights.patch +Patch56: RHEL-43235-fence_aws-1-list-add-instance-name-status.patch +Patch57: RHEL-43235-fence_aws-2-log-error-for-unknown-states.patch + +### HA support libs/utils ### +# all archs +Patch1000: bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch +Patch1001: RHEL-35649-kubevirt-fix-bundled-jinja2-CVE-2024-34064.patch +# cloud (x86_64 only) +Patch2000: bz2217902-2-aws-awscli-azure-fix-bundled-dateutil-CVE-2007-4559.patch +Patch2001: RHEL-43562-fix-bundled-urllib3-CVE-2024-37891.patch + +%global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate 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 +%ifarch x86_64 +%global testagents virsh heuristics_ping aliyun aws azure_arm gce openstack virt +%endif +%ifarch ppc64le +%global testagents virsh heuristics_ping openstack +%endif +%ifarch s390x +%global testagents virsh zvm heuristics_ping +%endif +%ifnarch x86_64 ppc64le s390x +%global testagents virsh heuristics_ping +%endif + +# skipped: pve, raritan, rcd-serial, virsh +%global allfenceagents %(cat <<EOF +fence-agents-amt-ws \\ +fence-agents-apc \\ +fence-agents-apc-snmp \\ +fence-agents-bladecenter \\ +fence-agents-brocade \\ +fence-agents-cisco-mds \\ +fence-agents-cisco-ucs \\ +fence-agents-drac5 \\ +fence-agents-eaton-snmp \\ +fence-agents-emerson \\ +fence-agents-eps \\ +fence-agents-heuristics-ping \\ +fence-agents-hpblade \\ +fence-agents-ibmblade \\ +fence-agents-ifmib \\ +fence-agents-ilo-moonshot \\ +fence-agents-ilo-mp \\ +fence-agents-ilo-ssh \\ +fence-agents-ilo2 \\ +fence-agents-intelmodular \\ +fence-agents-ipdu \\ +fence-agents-ipmilan \\ +fence-agents-kdump \\ +fence-agents-mpath \\ +fence-agents-redfish \\ +fence-agents-rhevm \\ +fence-agents-rsa \\ +fence-agents-rsb \\ +fence-agents-sbd \\ +fence-agents-scsi \\ +fence-agents-vmware-rest \\ +fence-agents-vmware-soap \\ +fence-agents-wti \\ + +EOF) + +%ifarch x86_64 +%global allfenceagents %(cat <<EOF +%{allfenceagents} \\ +fence-virt \\ + +EOF) +%endif + +# Build dependencies +## general +BuildRequires: autoconf automake libtool make +## compiled code (-kdump) +BuildRequires: gcc +## man pages generating +BuildRequires: libxslt +## Python dependencies +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} +BuildRequires: python3-devel +# dependencies for building HA support subpackages +BuildRequires: python3-pip python3-wheel +%ifarch x86_64 +BuildRequires: golang git +%endif +BuildRequires: python3-pycurl python3-requests +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 +BuildRequires: openwsman-python3 +%endif +%if 0%{?suse_version} +BuildRequires: python3-openwsman +%endif +%else +BuildRequires: python-devel +BuildRequires: python-pycurl python-requests +BuildRequires: openwsman-python +%endif + +# fence-virt +%if 0%{?suse_version} +%define nss_devel mozilla-nss-devel +%define nspr_devel mozilla-nspr-devel +%define systemd_units systemd +%else +%define nss_devel nss-devel +%define nspr_devel nspr-devel +%define systemd_units systemd-units +%endif + +BuildRequires: corosynclib-devel libvirt-devel +BuildRequires: libxml2-devel %{nss_devel} %{nspr_devel} +BuildRequires: flex bison libuuid-devel +BuildRequires: %{systemd_units} + + +# turn off the brp-python-bytecompile script +# (for F28+ or equivalent, the latter is the preferred form) +%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompilespace:.*$!!g') +#undefine __brp_python_bytecompile + +%prep +%setup -q -n %{name}-%{version}%{?rcver:%{rcver}}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}} +%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 -F2 +%patch -p1 -P 15 -F1 +%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 +%patch -p1 -P 31 +%patch -p1 -P 32 +%patch -p1 -P 33 +%patch -p1 -P 34 +%patch -p1 -P 35 +%patch -p1 -P 36 +%patch -p1 -P 37 +%patch -p1 -P 38 +%patch -p1 -P 39 +%patch -p1 -P 40 +%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 +%patch -p1 -P 49 +%patch -p1 -P 50 +%patch -p1 -P 51 +%patch -p1 -P 52 +%patch -p1 -P 53 +%patch -p1 -P 54 -F2 +%patch -p1 -P 55 +%patch -p1 -P 56 +%patch -p1 -P 57 + +# prevent compilation of something that won't get used anyway +sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac + +%build +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} + export PYTHON="%{__python3}" +%endif + +# aliyun-cli +%ifarch x86_64 +tar zxf %SOURCE2000 +pushd aliyun-cli-* +git init +rmdir aliyun-openapi-meta +tar zxf %SOURCE2001 +tar zxf %SOURCE2002 +mv aliyun-openapi-meta-* aliyun-openapi-meta +%define aliyun_cli_version 3.0.198 +# based on https://github.com/containers/podman/blob/main/rpm/podman.spec +%define gobuild(o:) go build -buildmode pie -compiler gc -tags="rpm_crashtraceback libtrust_openssl ${BUILDTAGS:-}" -ldflags "-linkmode=external -compressdwarf=false ${LDFLAGS:-} -B 0x$(head -c20 /dev/urandom|od -An -tx1|tr -d ' \\n') -extldflags '%__global_ldflags' -X github.com/aliyun/aliyun-cli/cli.Version=%{aliyun_cli_version}" -a -v -x -mod=vendor %{?**}; +%gobuild -o out/aliyun main/main.go +mkdir -p ../support/aliyun/aliyun-cli +install -m 0755 out/aliyun ../support/aliyun/aliyun-cli/ +popd +%endif + +# support libs +%ifarch x86_64 +LIBS="%{_sourcedir}/requirements-*.txt" +echo "awscli" >> %{_sourcedir}/requirements-awscli.txt +%endif +%ifnarch x86_64 +LIBS="%{_sourcedir}/requirements-common.txt" +%endif +for x in $LIBS; do + %{__python3} -m pip install --target support/$(echo $x | sed -E "s/.*requirements-(.*).txt/\1/") --no-index --find-links %{_sourcedir} -r $x +done + +# fix incorrect #! detected by CI +%ifarch x86_64 +sed -i -e "/^#\!\/Users/c#\!%{__python3}" support/aws/bin/jp support/awscli/bin/jp +%endif + +%ifarch x86_64 +sed -i -e "/^import awscli.clidriver/isys.path.insert(0, '/usr/lib/%{name}/support/awscli')" support/awscli/bin/aws +%endif + +# kubevirt +%{__python3} -m pip install --user --no-index --find-links %{_sourcedir} setuptools-scm +%{__python3} -m pip install --target support/kubevirt --no-index --find-links %{_sourcedir} openshift +rm -rf kubevirt/rsa* + +# regular patch doesnt work in build-section +pushd support +/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH1000} +/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH1001} + +%ifarch x86_64 +/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH2000} +/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH2001} +%endif +popd + +./autogen.sh +%{configure} --disable-libvirt-qmf-plugin PYTHONPATH="support/aliyun:support/aws:support/azure:support/google:support/common" \ +%if %{defined _tmpfilesdir} + SYSTEMD_TMPFILES_DIR=%{_tmpfilesdir} \ + --with-fencetmpdir=/run/fence-agents \ +%endif + --with-agents='%{supportedagents} %{testagents}' + +CFLAGS="$(echo '%{optflags}')" make %{_smp_mflags} + +%install +rm -rf %{buildroot} + +# support libs +mkdir -p %{buildroot}%{_usr}/lib/%{name} +mv support %{buildroot}%{_usr}/lib/%{name} + +export PYTHONPATH=%{buildroot}%{_usr}/lib/%{name}/support +make install DESTDIR=%{buildroot} +mkdir -p %{buildroot}/%{_unitdir}/ +%ifarch x86_64 +install -m 0644 agents/virt/fence_virtd.service %{buildroot}/%{_unitdir}/ +%endif +# bytecompile Python source code in a non-standard location +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 +%py_byte_compile %{__python3} %{buildroot}%{_datadir}/fence +%endif +# XXX unsure if /usr/sbin/fence_* should be compiled as well + +## tree fix up +# fix libfence permissions +chmod 0755 %{buildroot}%{_datadir}/fence/*.py +# remove docs +rm -rf %{buildroot}/usr/share/doc/fence-agents +# remove .a files +rm -f %{buildroot}/%{_libdir}/%{name}/*.*a +rm -f %{buildroot}/%{_libdir}/fence-virt/*.*a + +%post +ccs_update_schema > /dev/null 2>&1 ||: +# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Systemd +if [ $1 -eq 1 ] ; then + # Initial installation + /bin/systemctl daemon-reload >/dev/null 2>&1 || : +fi + +%preun +# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Systemd +if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable fence_virtd.service &> /dev/null || : + /bin/systemctl stop fence_virtd.service &> /dev/null || : +fi + +%postun +# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Systemd +/bin/systemctl daemon-reload &> /dev/null || : +if [ $1 -ge 1 ] ; then + # Package upgrade, not uninstall + /bin/systemctl try-restart fence_virtd.service &> /dev/null || : +fi + +%triggerun -- fence_virtd < 0.3.0-1 +# https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Packages_migrating_to_a_systemd_unit_file_from_a_SysV_initscript +/usr/bin/systemd-sysv-convert --save fence_virtd &> /dev/null || : +/sbin/chkconfig --del fence_virtd &> /dev/null || : +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +/bin/systemctl try-restart fence_virtd.service &> /dev/null || : + +%description +A collection of executables to handle isolation ("fencing") of possibly +misbehaving hosts by the means of remote power management, blocking +network, storage, or similar. They operate through a unified interface +(calling conventions) devised for the original Red Hat clustering solution. + +%package common +License: GPL-2.0-or-later AND LGPL-2.0-or-later AND LGPL-3.0-or-later AND ISC +Summary: Common base for Fence Agents +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} +Requires: python3-pycurl +%else +Requires: python-pycurl +%endif +# pexpect / suds +Provides: bundled(python-pexpect) = 4.8.0 +Provides: bundled(python-ptyprocess) = 0.7.0 +Provides: bundled(python-suds) = 0.8.5 +BuildArch: noarch +%description common +A collection of executables to handle isolation ("fencing") of possibly +misbehaving hosts by the means of remote power management, blocking +network, storage, or similar. + +This package contains support files including the Python fencing library. +%files common +%doc doc/COPYING.* doc/COPYRIGHT doc/README.licence +%{_datadir}/fence +%exclude %{_datadir}/fence/azure_fence.* +%exclude %{_datadir}/fence/__pycache__/azure_fence.* +%exclude %{_datadir}/fence/XenAPI.* +%exclude %{_datadir}/fence/__pycache__/XenAPI.* +%{_datadir}/cluster +%exclude %{_datadir}/cluster/fence_mpath_check* +%exclude %{_datadir}/cluster/fence_scsi_check* +%{_datadir}/pkgconfig/%{name}.pc +%exclude %{_sbindir}/* +%exclude %{_mandir}/man8/* +%if %{defined _tmpfilesdir} +%{_tmpfilesdir}/%{name}.conf +%endif +%if %{defined _tmpfilesdir} +%dir %attr (1755, root, root) /run/%{name} +%else +%dir %attr (1755, root, root) %{_var}/run/%{name} +%endif +%dir %{_usr}/lib/%{name} +%{_usr}/lib/%{name}/support/common + +%ifarch x86_64 +%package -n ha-cloud-support +License: GPL-2.0-or-later AND LGPL-2.0-or-later AND LGPL-2.1-or-later AND Apache-2.0 AND MIT AND BSD-2-Clause AND BSD-3-Clause AND MPL-2.0 AND Apache-2.0 AND PSF-2.0 AND Unlicense AND ISC +Summary: Support libraries for HA Cloud agents +# aliyun +Provides: bundled(python-aliyun-python-sdk-core) = 2.11.5 +Provides: bundled(python-aliyun-python-sdk-ecs) = 4.24.7 +Provides: bundled(python-cffi) = 1.14.5 +Provides: bundled(python-colorama) = 0.3.3 +Provides: bundled(python-jmespath) = 0.7.1 +Provides: bundled(python-pycryptodome) = 3.20.0 +Provides: bundled(python-pycparser) = 2.20 +Provides: bundled(aliyun-cli) = 3.0.198 +Provides: bundled(aliyun-openapi-meta) = 5cf98b660 +# awscli +Provides: bundled(awscli) = 2.2.15 +Provides: bundled(python-awscrt) = 0.11.13 +Provides: bundled(python-colorama) = 0.4.3 +Provides: bundled(python-cryptography) = 3.3.2 +Provides: bundled(python-distro) = 1.5.0 +Provides: bundled(python-docutils) = 0.15.2 +Provides: bundled(python-prompt-toolkit) = 2.0.10 +Provides: bundled(python-ruamel-yaml) = 0.15.100 +Provides: bundled(python-six) = 1.16.0 +Provides: bundled(python-wcwidth) = 0.1.9 +# aws +Provides: bundled(python-boto3) = 1.17.102 +Provides: bundled(python-botocore) = 1.20.102 +Provides: bundled(python-dateutil) = 2.8.1 +Provides: bundled(python-s3transfer) = 0.4.2 +Provides: bundled(python-urllib3) = 1.26.18 +# azure +Provides: bundled(python-adal) = 1.2.7 +Provides: bundled(python-azure-common) = 1.1.27 +Provides: bundled(python-azure-core) = 1.15.0 +Provides: bundled(python-azure-mgmt-compute) = 21.0.0 +Provides: bundled(python-azure-mgmt-core) = 1.2.2 +Provides: bundled(python-azure-mgmt-network) = 19.0.0 +Provides: bundled(python-certifi) = %{certifi_version} +Provides: bundled(python-chardet) = 4.0.0 +Provides: bundled(python-idna) = 2.10 +Provides: bundled(python-isodate) = 0.6.0 +Provides: bundled(python-msrest) = 0.6.21 +Provides: bundled(python-msrestazure) = 0.6.4 +Provides: bundled(python-oauthlib) = 3.1.1 +Provides: bundled(python-PyJWT) = 2.1.0 +Provides: bundled(python-requests) = 2.25.1 +Provides: bundled(python-requests-oauthlib) = 1.3.0 +# google +Provides: bundled(python-cachetools) = 4.2.2 +Provides: bundled(python-chardet) = 3.0.4 +Provides: bundled(python-google-api-core) = 1.30.0 +Provides: bundled(python-google-api-client) = 1.12.8 +Provides: bundled(python-googleapis-common-protos) = 1.53.0 +Provides: bundled(python-google-auth) = 1.32.0 +Provides: bundled(python-google-auth-httplib2) = 0.1.0 +Provides: bundled(python-httplib2) = 0.19.1 +Provides: bundled(python-packaging) = 20.9 +Provides: bundled(python-protobuf) = 3.17.3 +Provides: bundled(python-pyasn1) = 0.4.8 +Provides: bundled(python-pyasn1-modules) = 0.2.8 +Provides: bundled(python-pyparsing) = 2.4.7 +Provides: bundled(python-pyroute2) = 0.7.12 +Provides: bundled(python-pyroute2-core) = 0.6.13 +Provides: bundled(python-pyroute2-ethtool) = 0.6.13 +Provides: bundled(python-pyroute2-ipdb) = 0.6.13 +Provides: bundled(python-pyroute2-ipset) = 0.6.13 +Provides: bundled(python-pyroute2-ndb) = 0.6.13 +Provides: bundled(python-pyroute2-nftables) = 0.6.13 +Provides: bundled(python-pyroute2-nslink) = 0.6.13 +Provides: bundled(python-pytz) = 2021.1 +Provides: bundled(python-rsa) = 4.7.2 +Provides: bundled(python3-setuptools) = 71.1.0 +Provides: bundled(python-uritemplate) = 3.0.1 +%description -n ha-cloud-support +Support libraries for Fence Agents. +%files -n ha-cloud-support +%dir %{_usr}/lib/%{name} +%{_usr}/lib/%{name}/support +%exclude %{_usr}/lib/%{name}/support/common +%exclude %{_usr}/lib/%{name}/support/kubevirt +%endif + +%package all +License: GPLv2+ and LGPLv2+ and ASL 2.0 +Summary: Set of unified programs capable of host isolation ("fencing") +Requires: %{allfenceagents} +%ifarch ppc64le +Requires: fence-agents-lpar >= %{version}-%{release} +%endif +%ifarch s390x +Requires: fence-agents-zvm >= %{version}-%{release} +%endif +Provides: fence-agents = %{version}-%{release} +Obsoletes: fence-agents < 3.1.13 +%description all +A collection of executables to handle isolation ("fencing") of possibly +misbehaving hosts by the means of remote power management, blocking +network, storage, or similar. + +This package serves as a catch-all for all supported fence agents. +%files all + +%ifarch x86_64 +%package aliyun +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Alibaba Cloud (Aliyun) +Requires: fence-agents-common >= %{version}-%{release} +Requires: ha-cloud-support = %{version}-%{release} +Requires: python3-jmespath >= 0.9.0 +Obsoletes: %{name} < %{version}-%{release} +%description aliyun +The fence-agents-aliyun package contains a fence agent for Alibaba Cloud (Aliyun) instances. +%files aliyun +%defattr(-,root,root,-) +%{_sbindir}/fence_aliyun +%{_mandir}/man8/fence_aliyun.8* +%endif + +%package amt-ws +License: ASL 2.0 +Summary: Fence agent for Intel AMT (WS-Man) devices +Requires: fence-agents-common = %{version}-%{release} +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 +Requires: openwsman-python3 +%endif +%if 0%{?suse_version} +Requires: python3-openwsman +%endif +%else +Requires: openwsman-python +%endif +BuildArch: noarch +%description amt-ws +Fence agent for AMT (WS-Man) devices. +%files amt-ws +%{_sbindir}/fence_amt_ws +%{_mandir}/man8/fence_amt_ws.8* + +%package apc +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for APC devices +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description apc +Fence agent for APC devices that are accessed via telnet or SSH. +%files apc +%{_sbindir}/fence_apc +%{_mandir}/man8/fence_apc.8* + +%package apc-snmp +License: GPLv2+ and LGPLv2+ +Summary: Fence agents for APC devices (SNMP) +Requires: net-snmp-utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description apc-snmp +Fence agents for APC devices that are accessed via the SNMP protocol. +%files apc-snmp +%{_sbindir}/fence_apc_snmp +%{_mandir}/man8/fence_apc_snmp.8* +%{_sbindir}/fence_tripplite_snmp +%{_mandir}/man8/fence_tripplite_snmp.8* + +%ifarch x86_64 +%package aws +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Amazon AWS +Requires: fence-agents-common = %{version}-%{release} +Requires: ha-cloud-support = %{version}-%{release} +Obsoletes: fence-agents < 3.1.13 +%description aws +Fence agent for Amazon AWS instances. +%files aws +%{_sbindir}/fence_aws +%{_mandir}/man8/fence_aws.8* +%endif + +%ifarch x86_64 +%package azure-arm +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Azure Resource Manager +Requires: fence-agents-common = %{version}-%{release} +Requires: ha-cloud-support = %{version}-%{release} +Obsoletes: fence-agents < 3.1.13 +%description azure-arm +Fence agent for Azure Resource Manager instances. +%files azure-arm +%{_sbindir}/fence_azure_arm +%{_datadir}/fence/azure_fence.py* +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 +%{_datadir}/fence/__pycache__/azure_fence.* +%endif +%{_mandir}/man8/fence_azure_arm.8* +%endif + +%package bladecenter +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for IBM BladeCenter +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description bladecenter +Fence agent for IBM BladeCenter devices that are accessed +via telnet or SSH. +%files bladecenter +%{_sbindir}/fence_bladecenter +%{_mandir}/man8/fence_bladecenter.8* + +%package brocade +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Brocade switches +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description brocade +Fence agent for Brocade devices that are accessed via telnet or SSH. +%files brocade +%{_sbindir}/fence_brocade +%{_mandir}/man8/fence_brocade.8* + +%package cisco-mds +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Cisco MDS 9000 series +Requires: net-snmp-utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description cisco-mds +Fence agent for Cisco MDS 9000 series devices that are accessed +via the SNMP protocol. +%files cisco-mds +%{_sbindir}/fence_cisco_mds +%{_mandir}/man8/fence_cisco_mds.8* + +%package cisco-ucs +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Cisco UCS series +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} +Requires: python3-pycurl +%else +Requires: python-pycurl +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description cisco-ucs +Fence agent for Cisco UCS series devices that are accessed +via the SNMP protocol. +%files cisco-ucs +%{_sbindir}/fence_cisco_ucs +%{_mandir}/man8/fence_cisco_ucs.8* + +%ifarch x86_64 ppc64le +%package compute +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Nova compute nodes +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} +Requires: python3-requests +%else +Requires: python-requests +%endif +Requires: fence-agents-common = %{version}-%{release} +Obsoletes: ha-openstack-support <= %{version}-%{release} +%description compute +Fence agent for Nova compute nodes. +%files compute +%{_sbindir}/fence_compute +%{_sbindir}/fence_evacuate +%{_mandir}/man8/fence_compute.8* +%{_mandir}/man8/fence_evacuate.8* +%endif + +%package drac5 +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Dell DRAC 5 +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description drac5 +Fence agent for Dell DRAC 5 series devices that are accessed +via telnet or SSH. +%files drac5 +%{_sbindir}/fence_drac5 +%{_mandir}/man8/fence_drac5.8* + +%package eaton-snmp +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Eaton network power switches +Requires: net-snmp-utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description eaton-snmp +Fence agent for Eaton network power switches that are accessed +via the SNMP protocol. +%files eaton-snmp +%{_sbindir}/fence_eaton_snmp +%{_mandir}/man8/fence_eaton_snmp.8* + +%package emerson +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Emerson devices (SNMP) +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description emerson +Fence agent for Emerson devices that are accessed via +the SNMP protocol. +%files emerson +%{_sbindir}/fence_emerson +%{_mandir}/man8/fence_emerson.8* + +%package eps +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for ePowerSwitch 8M+ power switches +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description eps +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* + +%ifarch x86_64 +%package gce +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for GCE (Google Cloud Engine) +Requires: fence-agents-common = %{version}-%{release} +Requires: ha-cloud-support = %{version}-%{release} +Obsoletes: fence-agents < 3.1.13 +%description gce +Fence agent for GCE (Google Cloud Engine) instances. +%files gce +%{_sbindir}/fence_gce +%{_mandir}/man8/fence_gce.8* +%endif + +%package heuristics-ping +License: GPLv2+ and LGPLv2+ +Summary: Pseudo fence agent to affect other agents based on ping-heuristics +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +Obsoletes: fence-agents < 3.1.13 +%description heuristics-ping +Fence pseudo agent used to affect other agents based on +ping-heuristics. +%files heuristics-ping +%{_sbindir}/fence_heuristics_ping +%{_mandir}/man8/fence_heuristics_ping.8* + +%package hpblade +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for HP BladeSystem devices +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description hpblade +Fence agent for HP BladeSystem devices that are accessed via telnet +or SSH. +%files hpblade +%{_sbindir}/fence_hpblade +%{_mandir}/man8/fence_hpblade.8* + +%package ibmblade +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for IBM BladeCenter +Requires: net-snmp-utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ibmblade +Fence agent for IBM BladeCenter devices that are accessed +via the SNMP protocol. +%files ibmblade +%{_sbindir}/fence_ibmblade +%{_mandir}/man8/fence_ibmblade.8* + +%package ibm-powervs +License: GPLv2+ and LGPLv2+ +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 ibm-vpc +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for IBM Cloud VPC +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ibm-vpc +Fence agent for IBM Cloud VPC that are accessed via REST API. +%files ibm-vpc +%{_sbindir}/fence_ibm_vpc +%{_mandir}/man8/fence_ibm_vpc.8* + +%package ifmib +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for devices with IF-MIB interfaces +Requires: net-snmp-utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ifmib +Fence agent for IF-MIB interfaces that are accessed via +the SNMP protocol. +%files ifmib +%{_sbindir}/fence_ifmib +%{_mandir}/man8/fence_ifmib.8* + +%package ilo2 +License: GPLv2+ and LGPLv2+ +Summary: Fence agents for HP iLO2 devices +Requires: gnutls-utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ilo2 +Fence agents for HP iLO2 devices that are accessed via +the HTTP(s) protocol. +%files ilo2 +%{_sbindir}/fence_ilo +%{_sbindir}/fence_ilo2 +%{_mandir}/man8/fence_ilo.8* +%{_mandir}/man8/fence_ilo2.8* + +%package ilo-moonshot +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for HP iLO Moonshot devices +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ilo-moonshot +Fence agent for HP iLO Moonshot devices that are accessed +via telnet or SSH. +%files ilo-moonshot +%{_sbindir}/fence_ilo_moonshot +%{_mandir}/man8/fence_ilo_moonshot.8* + +%package ilo-mp +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for HP iLO MP devices +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ilo-mp +Fence agent for HP iLO MP devices that are accessed via telnet or SSH. +%files ilo-mp +%{_sbindir}/fence_ilo_mp +%{_mandir}/man8/fence_ilo_mp.8* + +%package ilo-ssh +License: GPLv2+ and LGPLv2+ +Summary: Fence agents for HP iLO devices over SSH +Requires: openssh-clients +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ilo-ssh +Fence agents for HP iLO devices that are accessed via telnet or SSH. +%files ilo-ssh +%{_sbindir}/fence_ilo_ssh +%{_mandir}/man8/fence_ilo_ssh.8* +%{_sbindir}/fence_ilo3_ssh +%{_mandir}/man8/fence_ilo3_ssh.8* +%{_sbindir}/fence_ilo4_ssh +%{_mandir}/man8/fence_ilo4_ssh.8* +%{_sbindir}/fence_ilo5_ssh +%{_mandir}/man8/fence_ilo5_ssh.8* + +%package intelmodular +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for devices with Intel Modular interfaces +Requires: net-snmp-utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description intelmodular +Fence agent for Intel Modular interfaces that are accessed +via the SNMP protocol. +%files intelmodular +%{_sbindir}/fence_intelmodular +%{_mandir}/man8/fence_intelmodular.8* + +%package ipdu +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for IBM iPDU network power switches +Requires: net-snmp-utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ipdu +Fence agent for IBM iPDU network power switches that are accessed +via the SNMP protocol. +%files ipdu +%{_sbindir}/fence_ipdu +%{_mandir}/man8/fence_ipdu.8* + +%package ipmilan +License: GPLv2+ and LGPLv2+ +Summary: Fence agents for devices with IPMI interface +Requires: /usr/bin/ipmitool +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description ipmilan +Fence agents for devices with IPMI interface. +%files ipmilan +%{_sbindir}/fence_ipmilan +%{_mandir}/man8/fence_ipmilan.8* +%{_sbindir}/fence_idrac +%{_mandir}/man8/fence_idrac.8* +%{_sbindir}/fence_ilo3 +%{_mandir}/man8/fence_ilo3.8* +%{_sbindir}/fence_ilo4 +%{_mandir}/man8/fence_ilo4.8* +%{_sbindir}/fence_ilo5 +%{_mandir}/man8/fence_ilo5.8* +%{_sbindir}/fence_ipmilanplus +%{_mandir}/man8/fence_ipmilanplus.8* +%{_sbindir}/fence_imm +%{_mandir}/man8/fence_imm.8* + +%package kdump +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for use with kdump crash recovery service +Requires: fence-agents-common = %{version}-%{release} +# this cannot be noarch since it's compiled +%description kdump +Fence agent for use with kdump crash recovery service. +%files kdump +%{_sbindir}/fence_kdump +%{_libexecdir}/fence_kdump_send +%{_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) = 71.1.0 +%description kubevirt +Fence agent for KubeVirt platform. +%files kubevirt +%{_sbindir}/fence_kubevirt +%{_mandir}/man8/fence_kubevirt.8* +# bundled libraries +%{_usr}/lib/%{name}/support/kubevirt + +%package lpar +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for IBM LPAR +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description lpar +Fence agent for IBM LPAR devices that are accessed via telnet or SSH. +%files lpar +%{_sbindir}/fence_lpar +%{_mandir}/man8/fence_lpar.8* + +%package mpath +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for reservations over Device Mapper Multipath +Requires: device-mapper-multipath +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description mpath +Fence agent for SCSI persistent reservation over +Device Mapper Multipath. +%files mpath +%{_sbindir}/fence_mpath +%{_datadir}/cluster/fence_mpath_check* +%{_mandir}/man8/fence_mpath.8* + +%ifarch x86_64 ppc64le +%package openstack +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for OpenStack's Nova service +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} +Requires: python3-requests +%else +Requires: python-requests +%endif +Requires: fence-agents-common = %{version}-%{release} +Obsoletes: ha-openstack-support <= %{version}-%{release} +%description openstack +Fence agent for OpenStack's Nova service. +%files openstack +%{_sbindir}/fence_openstack +%{_mandir}/man8/fence_openstack.8* +%endif + +%package redfish +License: GPLv2+ and LGPLv2+ +Group: System Environment/Base +Summary: Fence agent for Redfish +Requires: fence-agents-common >= %{version}-%{release} +%if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} +Requires: python3-requests +%else +Requires: python-requests +%endif +Obsoletes: fence-agents < 3.1.13 +%description redfish +The fence-agents-redfish package contains a fence agent for Redfish +%files redfish +%defattr(-,root,root,-) +%{_sbindir}/fence_redfish +%{_mandir}/man8/fence_redfish.8* + +%package rhevm +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for RHEV-M +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description rhevm +Fence agent for RHEV-M via REST API. +%files rhevm +%{_sbindir}/fence_rhevm +%{_mandir}/man8/fence_rhevm.8* + +%package rsa +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for IBM RSA II +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description rsa +Fence agent for IBM RSA II devices that are accessed +via telnet or SSH. +%files rsa +%{_sbindir}/fence_rsa +%{_mandir}/man8/fence_rsa.8* + +%package rsb +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for Fujitsu RSB +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description rsb +Fence agent for Fujitsu RSB devices that are accessed +via telnet or SSH. +%files rsb +%{_sbindir}/fence_rsb +%{_mandir}/man8/fence_rsb.8* + +%package sbd +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for SBD (storage-based death) +Requires: sbd +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description sbd +Fence agent for SBD (storage-based death). +%files sbd +%{_sbindir}/fence_sbd +%{_mandir}/man8/fence_sbd.8* + +%package scsi +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for SCSI persistent reservations +Requires: sg3_utils +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description scsi +Fence agent for SCSI persistent reservations. +%files scsi +%{_sbindir}/fence_scsi +%{_datadir}/cluster/fence_scsi_check +%{_datadir}/cluster/fence_scsi_check_hardreboot +%{_mandir}/man8/fence_scsi.8* + +# skipped from allfenceagents +%package virsh +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for virtual machines based on libvirt +Requires: openssh-clients /usr/bin/virsh +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description virsh +Fence agent for virtual machines that are accessed via SSH. +%files virsh +%{_sbindir}/fence_virsh +%{_mandir}/man8/fence_virsh.8* + +%package vmware-rest +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for VMWare with REST API +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +Obsoletes: fence-agents < 3.1.13 +%description vmware-rest +Fence agent for VMWare with REST API. +%files vmware-rest +%{_sbindir}/fence_vmware_rest +%{_mandir}/man8/fence_vmware_rest.8* + +%package vmware-soap +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for VMWare with SOAP API v4.1+ +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description vmware-soap +Fence agent for VMWare with SOAP API v4.1+. +%files vmware-soap +%{_sbindir}/fence_vmware_soap +%{_mandir}/man8/fence_vmware_soap.8* + +%package wti +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for WTI Network power switches +Requires: openssh-clients +%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version} +%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8) +Requires: telnet +%else +Recommends: telnet +%endif +%endif +Requires: fence-agents-common = %{version}-%{release} +BuildArch: noarch +%description wti +Fence agent for WTI network power switches that are accessed +via telnet or SSH. +%files wti +%{_sbindir}/fence_wti +%{_mandir}/man8/fence_wti.8* + +%ifarch s390x +%package zvm +License: GPLv2+ and LGPLv2+ +Summary: Fence agent for IBM z/VM over IP +Requires: fence-agents-common = %{version}-%{release} +%description zvm +Fence agent for IBM z/VM over IP. +%files zvm +%{_sbindir}/fence_zvmip +%{_mandir}/man8/fence_zvmip.8* +%endif + +# fence-virt + +%ifarch x86_64 +%package -n fence-virt +Summary: A pluggable fencing framework for virtual machines +Requires(post): systemd-sysv %{systemd_units} +Requires(preun): %{systemd_units} +Requires(postun): %{systemd_units} +%description -n fence-virt +Fencing agent for virtual machines. +%files -n fence-virt +%doc agents/virt/docs/* +%{_sbindir}/fence_virt +%{_sbindir}/fence_xvm +%{_mandir}/man8/fence_virt.* +%{_mandir}/man8/fence_xvm.* + +%package -n fence-virtd +Summary: Daemon which handles requests from fence-virt +%description -n fence-virtd +This package provides the host server framework, fence_virtd, +for fence_virt. The fence_virtd host daemon is resposible for +processing fencing requests from virtual machines and routing +the requests to the appropriate physical machine for action. +%files -n fence-virtd +%{_sbindir}/fence_virtd +%{_unitdir}/fence_virtd.service +%config(noreplace) %{_sysconfdir}/fence_virt.conf +%dir %{_libdir}/fence-virt +%{_libdir}/fence-virt/vsock.so +%{_mandir}/man5/fence_virt.conf.* +%{_mandir}/man8/fence_virtd.* + +%package -n fence-virtd-multicast +Summary: Multicast listener for fence-virtd +Requires: fence-virtd +%description -n fence-virtd-multicast +Provides multicast listener capability for fence-virtd. +%files -n fence-virtd-multicast +%{_libdir}/fence-virt/multicast.so + +%package -n fence-virtd-serial +Summary: Serial VMChannel listener for fence-virtd +Requires: libvirt >= 0.6.2 +Requires: fence-virtd +%description -n fence-virtd-serial +Provides serial VMChannel listener capability for fence-virtd. +%files -n fence-virtd-serial +%{_libdir}/fence-virt/serial.so + +%package -n fence-virtd-tcp +Summary: TCP listener for fence-virtd +Requires: fence-virtd +%description -n fence-virtd-tcp +Provides TCP listener capability for fence-virtd. +%files -n fence-virtd-tcp +%{_libdir}/fence-virt/tcp.so + +%package -n fence-virtd-libvirt +Summary: Libvirt backend for fence-virtd +Requires: libvirt >= 0.6.0 +Requires: fence-virtd +%description -n fence-virtd-libvirt +Provides fence_virtd with a connection to libvirt to fence +virtual machines. Useful for running a cluster of virtual +machines on a desktop. +%files -n fence-virtd-libvirt +%{_libdir}/fence-virt/virt.so + +%package -n fence-virtd-cpg +Summary: CPG/libvirt backend for fence-virtd +Requires: corosynclib +Requires: fence-virtd +%description -n fence-virtd-cpg +Provides fence_virtd with a connection to libvirt to fence +virtual machines. Uses corosync CPG to keep track of VM +locations to allow for non-local VMs to be fenced when VMs +are located on corosync cluster nodes. +%files -n fence-virtd-cpg +%{_libdir}/fence-virt/cpg.so +%endif + +%changelog +* Tue Jul 23 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-76 +- bundled setuptools: fix CVE-2024-6345 + + Resolves: RHEL-49658 + +* Fri Jun 21 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-75 +- bundled urllib3: fix CVE-2024-37891 + Resolves: RHEL-43562 + +* Wed Jun 19 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-74 +- fence_aws: add instance name and status to list/list-status actions + Resolves: RHEL-43235 + +* Thu May 23 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-73 +- fence_vmware_rest: detect if the API user has sufficient rights to + manage the fence device + Resolves: RHEL-25256 + +* Wed May 15 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-72 +- bundled jinja2: fix CVE-2024-34064 + Resolves: RHEL-35649 + +* Fri May 3 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-71 +- fence_eps: add fence_epsr2 for ePowerSwitch R2 and newer + Resolves: RHEL-35263 + +* Thu Apr 4 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-70 +- fence_aliyun: add credentials file support, filter parameter, and + optimize log output + Resolves: RHEL-31488, RHEL-31485, RHEL-31483 + +* Thu Mar 21 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-69 +- ha-cloud-support: upgrade bundled pyroute2 libs to fix issue in + gcp-vpc-move-route's stop-action + Resolves: RHEL-29649 + +* Thu Mar 14 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-66 +- Add missing licenses to spec-file + Resolves: RHEL-27929 +- ha-cloud-support: fix aliyun-cli + Resolves: RHEL-28097 + +* Thu Jan 18 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-62 +- bundled urllib3: fix CVE-2023-45803 + Resolves: RHEL-18139 +- bundled pycryptodome: fix CVE-2023-52323 + Resolves: RHEL-20917 +- bundled jinja2: fix CVE-2024-22195 + Resolves: RHEL-21345 + +* Wed Jan 3 2024 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-61 +- fence_zvmip: document required user permissions in metadata/manpage + Resolves: RHEL-14344 + +* Mon Oct 23 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-60 +- all agents: update metadata in non-I/O agents to Power or Network + fencing + Resolves: RHEL-14030 + +* Wed Oct 11 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-57 +- bundled urllib3: fix CVE-2023-43804 + Resolves: RHEL-11999 + +* Wed Sep 27 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-56 +- fence_scsi: fix registration handling if ISID conflicts + Resolves: RHEL-5396 +- bundled certifi: fix CVE-2023-37920 + Resolves: RHEL-9446 + +* Thu Aug 3 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-55 +- bundled dateutil: fix tarfile CVE-2007-4559 + Resolves: rhbz#2217902 +- fence_ipmilan: fix typos in metadata + Resolves: rhbz#2224267 + +* Tue Jul 11 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-48 +- fence_ibm_powervs: performance improvements + Resolves: rhbz#2221643 + +* Tue Jun 20 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-47 +- fence_azure_arm: add Stack Hub support + Resolves: rhbz#2211930 + +* Thu May 4 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-46 +- fence_scsi: detect devices in shared VGs + Resolves: rhbz#2187327 + +* Wed May 3 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-45 +- fence_aws: add --skip-race-check parameter to allow running outside + of AWS network + Resolves: rhbz#2183162 + +* Thu Jan 26 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-43 +- fence_vmware_soap: set login_timeout lower than default + pcmk_monitor_timeout (20s) to remove tmp dirs + Resolves: rhbz#2122944 + +* Tue Jan 24 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-42 +- fencing/fence_wti: add --plug-separator to be able to avoid + characters that are in node name(s) + Resolves: rhbz#2152107 + +* Fri Jan 13 2023 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-41 +- fence_scsi: skip key generation during validate-all action + Resolves: rhbz#2160480 + +* Fri Dec 2 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-40 +- fence_virtd: add info about multiple uuid/ip entries to manpage + + Resolves: rhbz#2149655 + +* Tue Nov 22 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-39 +- fence_virtd: warn if config or key file(s) are not mode 600 + + Resolves: rhbz#2144531 + +* Tue Nov 8 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-37 +- Upgrade bundled python-oauthlib + Resolves: rhbz#2128564 + +* Mon Oct 31 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-36 +- fence_virtd: add link to uri examples and uri w/socket path + example for when VMS are run as non-root user to manpage + Resolves: rhbz#2138823 + +* Tue Oct 25 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-35 +- fence_ibm_powervs: improve defaults + Resolves: rhbz#2136191 + +* Wed Oct 12 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-34 +- fence_lpar: only output additional output info on DEBUG level + Resolves: rhbz#2134015 + +* Wed Oct 5 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-33 +- fence_virt: add note that reboot-action doesnt power on nodes that + are powered off + Resolves: rhbz#2132008 + +* Fri Sep 9 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-32 +- add azure-identity and dependencies + Resolves: rhbz#2121546 + +* Tue Aug 16 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-31 +- fence_ibm_vpc: add token cache support + Resolves: rhbz#2111998 + +* Tue Aug 16 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-30 +- fence_openstack: add support for reading config from clouds.yaml + and openrc + Resolves: rhbz#2041933, rhbz#2041935 + +* Wed Jun 22 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-27 +- fence_ibm_powervs: add support for proxy, private API servers and + get token via API key + Resolves: rhbz#2093216 + +* Wed Jun 1 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-26 +- fence_ibm_vpc: add proxy support + Resolves: rhbz#2092385 + +* Tue May 31 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-25 +- all agents: unify ssl parameters to avoid having to use --ssl when + using --ssl-secure/--ssl-insecure for some agents + Resolves: rhbz#2072420 + +* Tue May 17 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-24 +- fence_apc/fence_ilo_moonshot: add missing "import logging" + Resolves: rhbz#2086559 + +* Thu May 5 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-23 +- fence_ibm_vpc: remove unused instance parameter and make limit + optional + Resolves: rhbz#2081235 + +* Fri Apr 29 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-22 +- fence_gce: update fence agent + Resolves: rhbz#2079889 + +* Wed Apr 6 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-21 +- fence_lpar: refactor to avoid duplicate code + Resolves: rhbz#2065114 + +* Wed Mar 30 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-20 +- fence_azure_arm: fix sovereign cloud and MSI support + Resolves: rhbz#2010652 + +* Mon Mar 7 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-19 +- fence_ibm_vpc: new fence agent + Resolves: rhbz#2061321 + +* Fri Feb 11 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-18 +- fence_zvmip: add SSL/TLS support + Resolves: rhbz#2022334 + +* Mon Feb 7 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-17 +- fence_ibm_powervs: new fence agent + Resolves: rhbz#2042496 + +* Mon Jan 17 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-15 +- fence_kubevirt: new fence agent + Resolves: rhbz#2000954 + +* Tue Jan 11 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-14 +- fence_openstack: add --ssl-insecure + Resolves: rhbz#2029791 + +* Thu Dec 2 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-13 +- fence_amt_ws: fix "or" causing dead code + Resolves: rhbz#2010709 + +* Tue Aug 31 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-9 +- Only build fence-virt subpackages for x86_64 arch + Resolves: rhbz#1965988 + +* Tue Aug 31 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-8 +- OpenStack agents: add dependency + Resolves: rhbz#1857247 + +* Wed Aug 25 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-7 +- remove suds dependency + Resolves: rhbz#1989149 + +* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 4.10.0-4 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Mon Jul 26 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-2 +- new upstream release + Resolves: rhbz#1984803 + +* Wed Jul 7 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.9.0-5 +- Remove "BuildArch: noarch" for arch-specific subpackages + Resolves: rhbz#1979827 + +* Fri Jun 4 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.9.0-1 +- Rebase and add fence-virt subpackages + Resolves: rhbz#1965988 + +* Tue May 18 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.7.1-10 +- remove pexpect dependency + Resolves: rhbz#1961551 + +* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 4.7.1-9 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Tue Mar 23 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.7.1-8 +- cloud agents: only build for x86_64 + +* Thu Mar 4 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.7.1-5 +- update HA cloud support package + +* Mon Feb 15 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.7.1-4 +- create HA cloud support package + +* Thu Feb 11 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.7.1-3 +- add aliyun subpackage +- fence-agents-mpath: add missing fence_mpath_check* + +* Mon Feb 8 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.7.1-1 +- new upstream release + +* Wed Dec 9 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.7.0-1 +- new upstream release + +* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.5.2-4 +- Second attempt - Rebuilt for + https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.5.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.5.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Oct 23 2019 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.5.2-1 +- new upstream release +- added openstack subpackage +- spec improvements based on upstream spec-file + +* Tue Sep 24 2019 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.5.1-1 +- new upstream release + +* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 4.4.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Tue Jun 4 2019 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.4.0-1 +- new upstream release + +* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 4.3.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Wed Jan 16 2019 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.3.3-2 +- fence-agents-scsi: add missing fence-agents-common dependency + +* Mon Dec 3 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.3.3-1 +- new upstream release + +* Fri Oct 5 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.3.0-1 +- new upstream release + +* Wed Sep 19 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-6 +- Fix missing fence-agents-all subpackage after spec improvements + +* Wed Aug 22 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-5 +- Python 3: fix has_key() issues + +* Mon Aug 20 2018 Jan Pokorný <jpokorny+rpm-booth@fedoraproject.org> - 4.2.1-4 +- mark non-compiled packages properly as noarch, restructure excludes +- move azure_fence.py and XenAPI.py to respective subpackages from -common +- sanitize allfenceagents internally defined enumeration +- sanitize BuildRequires with respect to packaging guidelines +- bytecompile native Python modules and ship these bytecodes properly +- only refer to Python binary symbolically, drop buildroot cleanup +- cleanup package summaries/descriptions, order agent subpackages properly + +* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 4.2.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Mon Jun 18 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-2 +- fence_vmware_soap: fix python3-suds issue + +* Thu May 31 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.1-1 +- new upstream release + +* Fri May 25 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.0-2 +- fence_scsi: fix Python 3 encoding issue + +* Thu May 17 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.2.0-1 +- new upstream release + +* Thu Feb 15 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-1 +- new upstream release +- fence_vmware_soap / fence_ovh: use Python 2 till python3-suds bug + is fixed + +* Fri Feb 9 2018 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.0-2 +- new upstream release + +* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.24-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Jan 11 2018 Iryna Shcherbina <ishcherb@redhat.com> - 4.0.24-14 +- Cleanup no longer needed Python 2 dependencies + +* Tue Nov 07 2017 Troy Dawson <tdawson@redhat.com> - 4.0.24-13 +- Cleanup spec file conditionals + +* Tue Aug 29 2017 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.0.24-12 +- fence-agents-common: remove fence_scsi_check files +- fence-scsi: add "fence_scsi_check_hardreboot" + +* Thu Aug 3 2017 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.0.24-10 +- fence_zvm: fix "uintptr_t" undeclared + +* Thu Aug 3 2017 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.0.24-9 +- Fix encoding for pexpect with Python 3.6 + Resolves: rhbz#1473908 + +* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.24-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.24-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.24-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Dec 23 2016 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.0.24-5 +- Fix to build in Python 3 only environment + +* Mon Dec 19 2016 Miro Hrončok <mhroncok@redhat.com> - 4.0.24-4 +- Rebuild for Python 3.6 + +* Wed Sep 21 2016 Marek Grac <mgrac@redhat.com> - 4.0.24-4 +- Remove Obsoletes that are no longer valid + +* Fri Sep 2 2016 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.0.24-2 +- fence-agents-common: add dependency on python3-pycurl + +* Fri Aug 26 2016 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.0.24-1 +- new upstream release + +* Wed Jul 13 2016 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.0.23-2 +- fix build issue on s390 + +* Tue Jul 12 2016 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.0.23-1 +- new upstream release +- new package fence-agents-amt-ws +- new package fence-agents-compute +- new package fence-agents-drac +- new package fence-agents-hds-cb +- new package fence-agents-mpath +- new package fence-agents-sanbox2 +- new package fence-agents-sbd +- new package fence-agents-vbox +- new package fence-agents-vmware +- new package fence-agents-xenapi + +* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 4.0.20-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Tue Aug 11 2015 Marek Grac <mgrac@redhat.com> - 4.0.20-1 +- new upstream release +- new package fence-agents-rcd-serial + +* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 4.0.16-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Thu Mar 05 2015 Marek Grac <mgrac@redhat.com> - 4.0.16-1 +- new upstream release + +* Mon Feb 09 2015 Marek Grac <mgrac@redhat.com> - 4.0.15-1 +- new upstream release + +* Thu Jan 08 2015 Marek Grac <mgrac@redhat.com> - 4.0.14-1 +- new upstream release +- new packages fence-agents-zvm and fence-agents-emerson + +* Thu Oct 16 2014 Marek Grac <mgrac@redhat.com> - 4.0.12-1 +- new upstream release +- new package fence-agents-ilo-ssh + +* Wed Aug 27 2014 Marek Grac <mgrac@redhat.com> - 4.0.10 +- new upstream release +- new package fence-agents-ilo-moonshot + +* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 4.0.9-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Fri May 16 2014 Marek Grac <mgrac@redhat.com> - 4.0.9 +- new upstream release +- new package fence-agents-pve + +* Mon Apr 07 2014 Marek Grac <mgrac@redhat.com> - 4.0.8-1 +- new upstream release +- new package fence-agents-raritan + +* Wed Feb 26 2014 Marek Grac <mgrac@redhat.com> - 4.0.7-3 +- requires a specific version of fence-agents-common + +* Mon Feb 17 2014 Marek Grac <mgrac@redhat.com> - 4.0.7-2 +- new upstream release +- changed dependancy from nss/nspr to gnutls-utils + +* Fri Jan 10 2014 Marek Grac <mgrac@redhat.com> - 4.0.4-4 +- new upstream release +- new package fence-agents-amt + +* Mon Oct 07 2013 Marek Grac <mgrac@redhat.com> - 4.0.4-3 +- new upstream release +- new package fence-agents-netio + +* Tue Sep 03 2013 Marek Grac <mgrac@redhat.com> - 4.0.3-1 +- new upstream release +- new packages fence-agents-brocade and fence-agents-ovh + +* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 4.0.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Thu Jul 18 2013 Petr Pisar <ppisar@redhat.com> - 4.0.1-2 +- Perl 5.18 rebuild + +* Mon Jul 01 2013 Marek Grac <mgrac@redhat.com> - 4.0.1-1 +- new upstream release + +* Mon Jun 24 2013 Marek Grac <mgrac@redhat.com> - 4.0.0-5 +- fence-agents-all should provide fence-agent for clean update path + +* Wed Apr 03 2013 Marek Grac <mgrac@redhat.com> - 4.0.0-4 +- minor changes in spec file + +* Thu Mar 21 2013 Marek Grac <mgrac@redhat.com> - 4.0.0-3 +- minor changes in spec file + +* Mon Mar 18 2013 Marek Grac <mgrac@redhat.com> - 4.0.0-2 +- minor changes in spec file + +* Mon Mar 11 2013 Marek Grac <mgrac@redhat.com> - 4.0.0-1 +- new upstream release +- introducing subpackages + + diff --git a/ha-cloud-support-aliyun.patch b/ha-cloud-support-aliyun.patch new file mode 100644 index 0000000..5f310f1 --- /dev/null +++ b/ha-cloud-support-aliyun.patch @@ -0,0 +1,10 @@ +--- a/agents/aliyun/fence_aliyun.py 2021-02-08 16:27:46.587068911 +0100 ++++ b/agents/aliyun/fence_aliyun.py 2021-02-08 16:27:41.368054268 +0100 +@@ -9,6 +9,7 @@ + from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay + + try: ++ sys.path.insert(0, '/usr/lib/fence-agents/support/aliyun') + from aliyunsdkcore import client + from aliyunsdkcore.auth.credentials import EcsRamRoleCredential + from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest diff --git a/ha-cloud-support-aws.patch b/ha-cloud-support-aws.patch new file mode 100644 index 0000000..f4939dd --- /dev/null +++ b/ha-cloud-support-aws.patch @@ -0,0 +1,10 @@ +--- a/agents/aws/fence_aws.py 2021-02-08 13:31:49.748362643 +0100 ++++ b/agents/aws/fence_aws.py 2021-02-08 13:31:46.836356513 +0100 +@@ -11,6 +11,7 @@ + from requests import HTTPError + + try: ++ sys.path.insert(0, '/usr/lib/fence-agents/support/aws') + import boto3 + from botocore.exceptions import ConnectionError, ClientError, EndpointConnectionError, NoRegionError + except ImportError: diff --git a/ha-cloud-support-azure.patch b/ha-cloud-support-azure.patch new file mode 100644 index 0000000..f8290f5 --- /dev/null +++ b/ha-cloud-support-azure.patch @@ -0,0 +1,12 @@ +--- fence-agents-4.7.1/lib/azure_fence.py.py 2021-02-08 16:52:32.955244393 +0100 ++++ fence-agents-4.7.1/lib/azure_fence.py.py.modif 2021-02-08 16:52:28.150234151 +0100 +@@ -1,6 +1,9 @@ + import logging, re, time
+ from fencing import fail_usage
+
++import sys
++sys.path.insert(0, '/usr/lib/fence-agents/support/azure')
++
+ FENCE_SUBNET_NAME = "fence-subnet"
+ FENCE_INBOUND_RULE_NAME = "FENCE_DENY_ALL_INBOUND"
+ FENCE_INBOUND_RULE_DIRECTION = "Inbound"
diff --git a/ha-cloud-support-google.patch b/ha-cloud-support-google.patch new file mode 100644 index 0000000..5335073 --- /dev/null +++ b/ha-cloud-support-google.patch @@ -0,0 +1,21 @@ +diff --color -uNr a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py +--- a/agents/gce/fence_gce.py 2021-06-03 13:10:44.752999470 +0200 ++++ b/agents/gce/fence_gce.py 2021-06-03 13:10:36.512971619 +0200 +@@ -9,7 +9,6 @@ + # + + import atexit +-import httplib2 + import logging + import json + import re +@@ -30,6 +29,8 @@ + + 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/support/google') ++ import httplib2 + import googleapiclient.discovery + import socks + try: +Binary files a/agents/gce/.fence_gce.py.swp and b/agents/gce/.fence_gce.py.swp differ diff --git a/requirements-aliyun.txt b/requirements-aliyun.txt new file mode 100644 index 0000000..2ccf5b4 --- /dev/null +++ b/requirements-aliyun.txt @@ -0,0 +1 @@ +aliyun-python-sdk-ecs diff --git a/requirements-aws.txt b/requirements-aws.txt new file mode 100644 index 0000000..f702bb0 --- /dev/null +++ b/requirements-aws.txt @@ -0,0 +1,2 @@ +boto3 +jmespath<1.0.0 diff --git a/requirements-azure.txt b/requirements-azure.txt new file mode 100644 index 0000000..8e4b2b7 --- /dev/null +++ b/requirements-azure.txt @@ -0,0 +1,4 @@ +azure-mgmt-compute +azure-mgmt-network +azure-identity +msrestazure diff --git a/requirements-common.txt b/requirements-common.txt new file mode 100644 index 0000000..15ed87c --- /dev/null +++ b/requirements-common.txt @@ -0,0 +1,2 @@ +pexpect +suds-community diff --git a/requirements-google.txt b/requirements-google.txt new file mode 100644 index 0000000..4ef59ba --- /dev/null +++ b/requirements-google.txt @@ -0,0 +1,4 @@ +google-api-python-client==1.12.8 +chardet<4.0 +# for gcp-vpc-move-route +pyroute2 @@ -0,0 +1,103 @@ +caf5418c851eac59e70a78d9730d4cea Jinja2-3.1.3.tar.gz +892e0fefa3c488387e5cc0cad2daa523 MarkupSafe-2.0.1.tar.gz +326e03ddf1ad2a7c7929355033ec6c9e PyJWT-2.1.0-py3-none-any.whl +3b07eb596071bac75c886129de881d22 PyYAML-5.1.tar.gz +7357535b56322ca69e5b0587c7abeba8 adal-1.2.7-py2.py3-none-any.whl +fc38a2168ec9785693bb47e75dc67aaa aliyun-cli-3.0.198.tar.gz +ab023f0f4f3de0aef5c7422beac9d48d aliyun-cli-go-vendor.tar.gz +9911cf982f939bccf5c4888198516c26 aliyun-openapi-meta-5cf98b660.tar.gz +832fbc4db8822fcb0099edb7158ddf81 aliyun-python-sdk-core-2.11.5.tar.gz +4aaac7732a25a1ac95715236b7c36aec aliyun_python_sdk_ecs-4.24.7-py2.py3-none-any.whl +7c2d43fbfb0faeddec259a7f26adb8dc awscli-2.2.15.tar.gz +19535ef49fd3c810683aabfae499a886 awscrt-0.11.13-cp39-cp39-manylinux2014_x86_64.whl +1f421c0a7095020ac69edf4377143f04 azure-identity-1.10.0.zip +93f8df88e79c665105a6f81aa79a123e azure_common-1.1.27-py2.py3-none-any.whl +f25d1aee4e81c7a8ec660df63fb16846 azure_core-1.15.0-py2.py3-none-any.whl +2e3e216285ca9037683c7548a02a0773 azure_mgmt_compute-21.0.0-py2.py3-none-any.whl +9ca8a15da5419c05aadf036b6906f390 azure_mgmt_core-1.2.2-py2.py3-none-any.whl +a12c87d4a1c6428a37a0f2d61003eb76 azure_mgmt_network-19.0.0-py2.py3-none-any.whl +f8834d4c555d4b5691334970663a3e23 boto3-1.17.102-py2.py3-none-any.whl +958bfa5a66296b19661a1c70c2011618 botocore-1.20.102-py2.py3-none-any.whl +717bcef383ca2010dccb994329d5bdbe botocore-2.0.0dev123.zip +7d68465904f9c43fe5f22489a0cbef66 cachetools-4.2.2-py3-none-any.whl +c64f38a505b122a2ecf2b7d93c0ec4b7 cachetools-4.2.4.tar.gz +10a72845d3fc2c38d212b4b7b1872c76 certifi-2023.7.22.tar.gz +d70c8f8a27a42c15068652962157d772 cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl +0004b00caff7bb543a1d0d0bd0185a03 chardet-3.0.4-py2.py3-none-any.whl +504627b9b4fcd44720d5aa1345e29cc7 chardet-4.0.0-py2.py3-none-any.whl +b28e4463613ff3911d5a2dc62b96233f charset-normalizer-2.0.7.tar.gz +a56b8dc55158a41ab3c89c4c8feb8824 colorama-0.3.3.tar.gz +9e6c379e994d31f11945e90bbe7d93f4 colorama-0.4.3-py2.py3-none-any.whl +1d6c3f91deaa8360bf773bb34dc41730 cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl +97e69f92dbcc411c5ae974610794afad distro-1.5.0-py2.py3-none-any.whl +d1a2ad1eaafdddfceda3c5c8b9850a48 docutils-0.15.2-py3-none-any.whl +62655d4b45872572f243d0eb7e9dd1f9 fence-agents-4.10.0.tar.gz +3bc52f1952b9a78361114147da63c35b flit_core-3.9.0.tar.gz +a61b1015a213f1a9cf27252fbac579ee google-auth-2.3.0.tar.gz +f5f2d07d8fbc8806b8760f63e7578ec7 google_api_core-1.30.0-py2.py3-none-any.whl +17d37f499abce29a269f9f650adc21c5 google_api_python_client-1.12.8-py2.py3-none-any.whl +3cfcb9b5822cd29c457e1c47b1236a88 google_auth-1.32.0-py2.py3-none-any.whl +7af470278ed23e6a6aad8166ed3fe44c google_auth_httplib2-0.1.0-py2.py3-none-any.whl +7b6a55372774c6fe3356488d05abe93b googleapis_common_protos-1.53.0-py2.py3-none-any.whl +2a9cb08809eb0e11b5ea4e5137adbce1 httplib2-0.19.1-py3-none-any.whl +8f7d13f63706aa265d31ffedc8aa3053 idna-2.10-py2.py3-none-any.whl +5856306eac5f25db8249e37a4c6ee3e7 idna-3.3.tar.gz +d993beffb0b78627721d9ef1dda4df87 isodate-0.6.0-py2.py3-none-any.whl +1977b145d6923911ee1088d0b0221b8a jmespath-0.7.1-py2.py3-none-any.whl +d44bf469fcc16312e12fe8548cb177ee kubernetes-12.0.1.tar.gz +e46e2af1ad29245ddbd93972770f528b msal-1.18.0.tar.gz +93f47277871a06956432af604c543cb2 msal-extensions-1.0.0.tar.gz +675f30e4e56ace7c03f45598669dde5f msrest-0.6.21-py2.py3-none-any.whl +e3dad842cdb7d02229e694549fb7caff msrestazure-0.6.4-py2.py3-none-any.whl +2f7b898cc1af8c1409cc329e8843ea8f oauthlib-3.2.2.tar.gz +6aef637aec8c21ae1c41f02aa731fa29 openshift-0.12.1.tar.gz +7939efd344ec77a2147a8e27d7abb475 packaging-20.9-py2.py3-none-any.whl +794526bdce430e48e323aa7112ea6f60 packaging-21.2-py3-none-any.whl +7bf9120209a613a6792c6f0619bd8428 pexpect-4.8.0-py2.py3-none-any.whl +26909d08551f369fcde80f43529a1f92 poetry-core-1.0.7.tar.gz +3c4c381a4cecfd21f9f3259b7617efeb portalocker-2.5.1.tar.gz +99ba0f1e0ec70af191cfb256586e1404 prompt_toolkit-2.0.10-py3-none-any.whl +9a34949d547565016ddf367e2d6ace0a protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl +99ec04989f767cb72ac82ce671b561b0 ptyprocess-0.7.0-py2.py3-none-any.whl +9b019026fd706d25eb7ce5f707deb7bf pyasn1-0.4.8-py2.py3-none-any.whl +dffae4ff9f997a83324b3f33fe62be54 pyasn1-0.4.8.tar.gz +107e1ece7d0a41d782f69f8a95a4d9bc pyasn1-modules-0.2.8.tar.gz +b0da68111788ab964b8543d2ec1cb115 pyasn1_modules-0.2.8-py2.py3-none-any.whl +61112f106163fef25a95b73ad471c4cc pycparser-2.20-py2.py3-none-any.whl +7d60468c87fbdb1928aa4d8551c4fed1 pycryptodome-3.20.0.tar.gz +dbfd0a241aad2595f43377ec7f1836ea pyparsing-2.4.7-py2.py3-none-any.whl +e1a8c5ecb51dd87472362ff6ce575675 pyparsing-3.0.1.tar.gz +04e3b1a6550840c2eaa75da16b83f62b pyroute2-0.7.12.tar.gz +df79f1f2c7dcbac0e8e88de10f481f90 pyroute2.core-0.6.13.tar.gz +14309969be740f1350a4fafcda73c72b pyroute2.ethtool-0.6.13.tar.gz +8dc77ca3b33e7b81bf1732b56d3e2a5e pyroute2.ipdb-0.6.13.tar.gz +bb9d65e5b9f0a6f37365a15922440155 pyroute2.ipset-0.6.13.tar.gz +29aef69d25536baa1c0a121c8cefdf72 pyroute2.ndb-0.6.13.tar.gz +d0db73bc8015af946b3578330fb1e020 pyroute2.nftables-0.6.13.tar.gz +6016e3a0381e31cfeffd1e4e6f10843b pyroute2.nslink-0.6.13.tar.gz +5970010bb72452344df3d76a10281b65 python-dateutil-2.8.2.tar.gz +70ef5c5e6b05badc8675dcc3106d90cc python-string-utils-1.0.0.tar.gz +36ae406e144ce50dfa6950a6db17b1d9 python_dateutil-2.8.1-py2.py3-none-any.whl +2e039ef05cc965ffe161b3a8af018431 pytz-2021.1-py2.py3-none-any.whl +ec79209809129bf13cb002a0a573ef45 requests-2.25.1-py2.py3-none-any.whl +8c745949ad3e9ae83d9927fed213db8a requests-2.26.0.tar.gz +1ebcd55f1b1b9281940b4bc33010e2ba requests-oauthlib-1.3.0.tar.gz +68c604853902e57197522b1f3812e724 requests_oauthlib-1.3.0-py2.py3-none-any.whl +9e613a70e3aaacf6cdc8d0d371c1ac5d rsa-4.7.2-py3-none-any.whl +c21701cdd75c170f8d690f704a362c44 rsa-4.7.2.tar.gz +dd811a8f09dc0e622ad19a42508da7c1 ruamel.yaml-0.15.100.tar.gz +ef2af87b5f265163700b12165a541406 ruamel.yaml-0.17.16.tar.gz +e2397bedcd1f40b2f22b3696175082aa ruamel.yaml.clib-0.2.6.tar.gz +d647bb65f1406e151ca27877a089405c s3transfer-0.4.2-py2.py3-none-any.whl +2d7f698adca86005a771f8709686d5e4 setuptools-71.1.0.tar.gz +d8046dce093a94dc382b68b45f6a6257 setuptools_scm-8.1.0.tar.gz +529d7fd7e14612ccde86417b4402d6f3 six-1.16.0-py2.py3-none-any.whl +a7c927740e4964dd29b72cebfc1429bb six-1.16.0.tar.gz +8cd6c84c83eb5f43b6cb986e2180a650 suds_community-0.8.5-py3-none-any.whl +d4341621d423a7ca6822e23d6d52bb9a tomli-2.0.1.tar.gz +cf64c2313f5fa5eb04c1deb3fc93abe9 typing_extensions-4.12.2.tar.gz +f4be0d70d857dd295b78f220e7568372 uritemplate-3.0.1-py2.py3-none-any.whl +f986d8e9616d2a43389f678d5dad9893 urllib3-1.26.18.tar.gz +003327fdfbb7653dda1f3ce28fc57be1 wcwidth-0.1.9-py2.py3-none-any.whl +a043b9a04dc10a7c9f333cf55f6222df websocket-client-1.2.1.tar.gz +4176b79f0d1a39f4675c5ea21b403b61 wheel-0.37.0-py2.py3-none-any.whl |