import resource-agents-4.10.0-23.el9
This commit is contained in:
parent
456162fc4d
commit
b854697c92
543
SOURCES/bz2063877-all-agents-use-promotable-terms.patch
Normal file
543
SOURCES/bz2063877-all-agents-use-promotable-terms.patch
Normal file
@ -0,0 +1,543 @@
|
|||||||
|
From 3e469239e8c853725b28a9c6b509152aacc2c5cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 13 Jun 2022 11:24:05 +0200
|
||||||
|
Subject: [PATCH 1/2] all agents: update to promotable terms
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/SAPInstance | 22 +++++++++++-----------
|
||||||
|
heartbeat/conntrackd.in | 6 +++---
|
||||||
|
heartbeat/db2 | 12 ++++++------
|
||||||
|
heartbeat/dnsupdate.in | 2 +-
|
||||||
|
heartbeat/galera.in | 26 +++++++++++++-------------
|
||||||
|
heartbeat/iface-bridge | 6 +++---
|
||||||
|
heartbeat/mariadb.in | 30 +++++++++++++++---------------
|
||||||
|
heartbeat/mpathpersist.in | 24 ++++++++++++------------
|
||||||
|
heartbeat/mysql | 4 ++--
|
||||||
|
heartbeat/mysql-proxy | 2 +-
|
||||||
|
heartbeat/pgsql | 2 +-
|
||||||
|
heartbeat/redis.in | 4 ++--
|
||||||
|
heartbeat/sg_persist.in | 4 ++--
|
||||||
|
14 files changed, 74 insertions(+), 74 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/SAPInstance b/heartbeat/SAPInstance
|
||||||
|
index 016f59aff..e3fe788ae 100755
|
||||||
|
--- a/heartbeat/SAPInstance
|
||||||
|
+++ b/heartbeat/SAPInstance
|
||||||
|
@@ -25,8 +25,8 @@
|
||||||
|
# OCF_RESKEY_AUTOMATIC_RECOVER (optional, automatic startup recovery using cleanipc, default is false)
|
||||||
|
# OCF_RESKEY_MONITOR_SERVICES (optional, default is to monitor critical services only)
|
||||||
|
# OCF_RESKEY_SHUTDOWN_METHOD (optional, defaults to NORMAL, KILL: terminate the SAP instance with OS commands - faster, at your own risk)
|
||||||
|
-# OCF_RESKEY_ERS_InstanceName (optional, InstanceName of the ERS instance in a Master/Slave configuration)
|
||||||
|
-# OCF_RESKEY_ERS_START_PROFILE (optional, START_PROFILE of the ERS instance in a Master/Slave configuration)
|
||||||
|
+# OCF_RESKEY_ERS_InstanceName (optional, InstanceName of the ERS instance in a Promotable configuration)
|
||||||
|
+# OCF_RESKEY_ERS_START_PROFILE (optional, START_PROFILE of the ERS instance in a Promotable configuration)
|
||||||
|
# OCF_RESKEY_PRE_START_USEREXIT (optional, lists a script which can be executed before the resource is started)
|
||||||
|
# OCF_RESKEY_POST_START_USEREXIT (optional, lists a script which can be executed after the resource is started)
|
||||||
|
# OCF_RESKEY_PRE_STOP_USEREXIT (optional, lists a script which can be executed before the resource is stopped)
|
||||||
|
@@ -92,11 +92,11 @@ sapinstance_usage() {
|
||||||
|
|
||||||
|
$0 manages a SAP Instance as an HA resource.
|
||||||
|
|
||||||
|
- The 'start' operation starts the instance or the ERS instance in a Master/Slave configuration
|
||||||
|
+ The 'start' operation starts the instance or the ERS instance in a Promotable configuration
|
||||||
|
The 'stop' operation stops the instance
|
||||||
|
The 'status' operation reports whether the instance is running
|
||||||
|
The 'monitor' operation reports whether the instance seems to be working
|
||||||
|
- The 'promote' operation starts the primary instance in a Master/Slave configuration
|
||||||
|
+ The 'promote' operation starts the primary instance in a Promotable configuration
|
||||||
|
The 'demote' operation stops the primary instance and starts the ERS instance
|
||||||
|
The 'reload' operation allows changed parameters (non-unique only) without restarting the service
|
||||||
|
The 'notify' operation always returns SUCCESS
|
||||||
|
@@ -201,11 +201,11 @@ You may specify multiple services separated by a | (pipe) sign in this parameter
|
||||||
|
<content type="string" default="${OCF_RESKEY_SHUTDOWN_METHOD_default}"/>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="ERS_InstanceName" unique="1" required="0">
|
||||||
|
- <longdesc lang="en">Only used in a Master/Slave resource configuration:
|
||||||
|
+ <longdesc lang="en">Only used in a Promotable resource configuration:
|
||||||
|
The full qualified SAP enqueue replication instance name. e.g. P01_ERS02_sapp01ers. Usually this is the name of the SAP instance profile.
|
||||||
|
-The enqueue replication instance must be installed, before you want to configure a master-slave cluster resource.
|
||||||
|
+The enqueue replication instance must be installed, before you want to configure a promotable cluster resource.
|
||||||
|
|
||||||
|
-The master-slave configuration in the cluster must use this properties:
|
||||||
|
+The promotable configuration in the cluster must use this properties:
|
||||||
|
clone_max = 2
|
||||||
|
clone_node_max = 1
|
||||||
|
master_node_max = 1
|
||||||
|
@@ -215,7 +215,7 @@ master_max = 1
|
||||||
|
<content type="string" default="${OCF_RESKEY_ERS_InstanceName_default}"/>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="ERS_START_PROFILE" unique="1" required="0">
|
||||||
|
- <longdesc lang="en">Only used in a Master/Slave resource configuration:
|
||||||
|
+ <longdesc lang="en">Only used in a Promotable resource configuration:
|
||||||
|
The parameter ERS_InstanceName must also be set in this configuration.
|
||||||
|
The name of the SAP START profile. Specify this parameter, if you have changed the name of the SAP START profile after the default SAP installation. As SAP release 7.10 does not have a START profile anymore, you need to specify the Instance Profile than.
|
||||||
|
</longdesc>
|
||||||
|
@@ -243,7 +243,7 @@ The name of the SAP START profile. Specify this parameter, if you have changed t
|
||||||
|
<content type="string" default="${OCF_RESKEY_POST_STOP_USEREXIT_default}" />
|
||||||
|
</parameter>
|
||||||
|
<parameter name="IS_ERS" unique="0" required="0">
|
||||||
|
- <longdesc lang="en">Only used for ASCS/ERS SAP Netweaver installations without implementing a master/slave resource to
|
||||||
|
+ <longdesc lang="en">Only used for ASCS/ERS SAP Netweaver installations without implementing a promotable resource to
|
||||||
|
allow the ASCS to 'find' the ERS running on another cluster node after a resource failure. This parameter should be set
|
||||||
|
to true 'only' for the ERS instance for implementations following the SAP NetWeaver 7.40 HA certification (NW-HA-CLU-740). This includes also
|
||||||
|
systems for NetWeaver less than 7.40, if you like to implement the NW-HA-CLU-740 scenario.
|
||||||
|
@@ -266,8 +266,8 @@ The name of the SAP START profile. Specify this parameter, if you have changed t
|
||||||
|
<action name="stop" timeout="240s" />
|
||||||
|
<action name="status" timeout="60s" />
|
||||||
|
<action name="monitor" depth="0" timeout="60s" interval="120s" />
|
||||||
|
-<action name="monitor" depth="0" timeout="60s" interval="121s" role="Slave" />
|
||||||
|
-<action name="monitor" depth="0" timeout="60s" interval="119s" role="Master" />
|
||||||
|
+<action name="monitor" depth="0" timeout="60s" interval="121s" role="Unpromoted" />
|
||||||
|
+<action name="monitor" depth="0" timeout="60s" interval="119s" role="Promoted" />
|
||||||
|
<action name="promote" timeout="320s" />
|
||||||
|
<action name="demote" timeout="320s" />
|
||||||
|
<action name="reload" timeout="320s" />
|
||||||
|
diff --git a/heartbeat/conntrackd.in b/heartbeat/conntrackd.in
|
||||||
|
index f115250d6..1c2ee955b 100644
|
||||||
|
--- a/heartbeat/conntrackd.in
|
||||||
|
+++ b/heartbeat/conntrackd.in
|
||||||
|
@@ -50,7 +50,7 @@ meta_data() {
|
||||||
|
<version>1.0</version>
|
||||||
|
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Master/Slave OCF Resource Agent for conntrackd
|
||||||
|
+Promotable OCF Resource Agent for conntrackd
|
||||||
|
</longdesc>
|
||||||
|
|
||||||
|
<shortdesc lang="en">This resource agent manages conntrackd</shortdesc>
|
||||||
|
@@ -81,8 +81,8 @@ For example "/packages/conntrackd-0.9.14/etc/conntrackd/conntrackd.conf"</longde
|
||||||
|
<action name="demote" timeout="30s" />
|
||||||
|
<action name="notify" timeout="30s" />
|
||||||
|
<action name="stop" timeout="30s" />
|
||||||
|
-<action name="monitor" timeout="20s" interval="20s" role="Slave" />
|
||||||
|
-<action name="monitor" timeout="20s" interval="10s" role="Master" />
|
||||||
|
+<action name="monitor" timeout="20s" interval="20s" role="Unpromoted" />
|
||||||
|
+<action name="monitor" timeout="20s" interval="10s" role="Promoted" />
|
||||||
|
<action name="meta-data" timeout="5s" />
|
||||||
|
<action name="validate-all" timeout="30s" />
|
||||||
|
</actions>
|
||||||
|
diff --git a/heartbeat/db2 b/heartbeat/db2
|
||||||
|
index 4a4b2f477..620b89583 100755
|
||||||
|
--- a/heartbeat/db2
|
||||||
|
+++ b/heartbeat/db2
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
# db2
|
||||||
|
#
|
||||||
|
# Resource agent that manages a DB2 LUW database in Standard role
|
||||||
|
-# or HADR configuration in master/slave configuration.
|
||||||
|
+# or HADR configuration in promotable configuration.
|
||||||
|
# Multi partition is supported as well.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2011 Holger Teutsch <holger.teutsch@web.de>
|
||||||
|
@@ -61,7 +61,7 @@ cat <<END
|
||||||
|
<resource-agent name="db2" version="1.0">
|
||||||
|
<version>1.0</version>
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Resource Agent that manages an IBM DB2 LUW databases in Standard role as primitive or in HADR roles in master/slave configuration. Multiple partitions are supported.
|
||||||
|
+Resource Agent that manages an IBM DB2 LUW databases in Standard role as primitive or in HADR roles in promotable configuration. Multiple partitions are supported.
|
||||||
|
|
||||||
|
Standard mode:
|
||||||
|
|
||||||
|
@@ -71,8 +71,8 @@ Configure each partition as a separate primitive resource.
|
||||||
|
HADR mode:
|
||||||
|
|
||||||
|
A single database in HADR configuration is made highly available by automating takeover operations.
|
||||||
|
-Configure a master / slave resource with notifications enabled and an
|
||||||
|
-additional monitoring operation with role "Master".
|
||||||
|
+Configure a promotable resource with notifications enabled and an
|
||||||
|
+additional monitoring operation with role "Promoted".
|
||||||
|
|
||||||
|
In case of HADR be very deliberate in specifying intervals/timeouts. The detection of a failure including promote must complete within HADR_PEER_WINDOW.
|
||||||
|
|
||||||
|
@@ -84,7 +84,7 @@ In addition to honoring requirements for crash recovery etc. for your specific d
|
||||||
|
|
||||||
|
For further information and examples consult http://www.linux-ha.org/wiki/db2_(resource_agent)
|
||||||
|
</longdesc>
|
||||||
|
-<shortdesc lang="en">Resource Agent that manages an IBM DB2 LUW databases in Standard role as primitive or in HADR roles as master/slave configuration. Multiple partitions are supported.</shortdesc>
|
||||||
|
+<shortdesc lang="en">Resource Agent that manages an IBM DB2 LUW databases in Standard role as primitive or in HADR roles as promotable configuration. Multiple partitions are supported.</shortdesc>
|
||||||
|
|
||||||
|
<parameters>
|
||||||
|
<parameter name="instance" unique="1" required="1">
|
||||||
|
@@ -125,7 +125,7 @@ The number of the partition (DBPARTITIONNUM) to be managed.
|
||||||
|
<action name="demote" timeout="120s"/>
|
||||||
|
<action name="notify" timeout="10s"/>
|
||||||
|
<action name="monitor" depth="0" timeout="60s" interval="20s"/>
|
||||||
|
-<action name="monitor" depth="0" timeout="60s" role="Master" interval="22s"/>
|
||||||
|
+<action name="monitor" depth="0" timeout="60s" role="Promoted" interval="22s"/>
|
||||||
|
<action name="validate-all" timeout="5s"/>
|
||||||
|
<action name="meta-data" timeout="5s"/>
|
||||||
|
</actions>
|
||||||
|
diff --git a/heartbeat/dnsupdate.in b/heartbeat/dnsupdate.in
|
||||||
|
index 35b7c99bb..b54822cd8 100755
|
||||||
|
--- a/heartbeat/dnsupdate.in
|
||||||
|
+++ b/heartbeat/dnsupdate.in
|
||||||
|
@@ -119,7 +119,7 @@ the exact syntax.
|
||||||
|
<parameter name="server" unique="0" required="0">
|
||||||
|
<longdesc lang="en">
|
||||||
|
Which DNS server to send these updates for. When no
|
||||||
|
-server is provided, this defaults to the master server
|
||||||
|
+server is provided, this defaults to the promoted server
|
||||||
|
for the correct zone.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">DNS server to contact</shortdesc>
|
||||||
|
diff --git a/heartbeat/galera.in b/heartbeat/galera.in
|
||||||
|
index c363eb254..546b1a853 100755
|
||||||
|
--- a/heartbeat/galera.in
|
||||||
|
+++ b/heartbeat/galera.in
|
||||||
|
@@ -26,31 +26,31 @@
|
||||||
|
##
|
||||||
|
# README.
|
||||||
|
#
|
||||||
|
-# This agent only supports being configured as a multistate Master
|
||||||
|
+# This agent only supports being configured as a multistate Promoted
|
||||||
|
# resource.
|
||||||
|
#
|
||||||
|
-# Slave vs Master role:
|
||||||
|
+# Unpromoted vs Promoted role:
|
||||||
|
#
|
||||||
|
-# During the 'Slave' role, galera instances are in read-only mode and
|
||||||
|
+# During the 'Unpromoted' role, galera instances are in read-only mode and
|
||||||
|
# will not attempt to connect to the cluster. This role exists only as
|
||||||
|
# a means to determine which galera instance is the most up-to-date. The
|
||||||
|
# most up-to-date node will be used to bootstrap a galera cluster that
|
||||||
|
# has no current members.
|
||||||
|
#
|
||||||
|
-# The galera instances will only begin to be promoted to the Master role
|
||||||
|
+# The galera instances will only begin to be promoted to the Promoted role
|
||||||
|
# once all the nodes in the 'wsrep_cluster_address' connection address
|
||||||
|
# have entered read-only mode. At that point the node containing the
|
||||||
|
-# database that is most current will be promoted to Master. Once the first
|
||||||
|
-# Master instance bootstraps the galera cluster, the other nodes will be
|
||||||
|
-# promoted to Master as well.
|
||||||
|
+# database that is most current will be promoted to Promoted. Once the first
|
||||||
|
+# Promoted instance bootstraps the galera cluster, the other nodes will be
|
||||||
|
+# promoted to Promoted as well.
|
||||||
|
#
|
||||||
|
# Example: Create a galera cluster using nodes rhel7-node1 rhel7-node2 rhel7-node3
|
||||||
|
#
|
||||||
|
# pcs resource create db galera enable_creation=true \
|
||||||
|
-# wsrep_cluster_address="gcomm://rhel7-auto1,rhel7-auto2,rhel7-auto3" meta master-max=3 --master
|
||||||
|
+# wsrep_cluster_address="gcomm://rhel7-auto1,rhel7-auto2,rhel7-auto3" meta promoted-max=3 --promoted
|
||||||
|
#
|
||||||
|
# By setting the 'enable_creation' option, the database will be automatically
|
||||||
|
-# generated at startup. The meta attribute 'master-max=3' means that all 3
|
||||||
|
+# generated at startup. The meta attribute 'promoted-max=3' means that all 3
|
||||||
|
# nodes listed in the wsrep_cluster_address list will be allowed to connect
|
||||||
|
# to the galera cluster and perform replication.
|
||||||
|
#
|
||||||
|
@@ -114,8 +114,8 @@ The 'start' operation starts the database.
|
||||||
|
The 'stop' operation stops the database.
|
||||||
|
The 'status' operation reports whether the database is running
|
||||||
|
The 'monitor' operation reports whether the database seems to be working
|
||||||
|
-The 'promote' operation makes this mysql server run as master
|
||||||
|
-The 'demote' operation makes this mysql server run as slave
|
||||||
|
+The 'promote' operation makes this mysql server run as promoted
|
||||||
|
+The 'demote' operation makes this mysql server run as unpromoted
|
||||||
|
The 'validate-all' operation reports whether the parameters are valid
|
||||||
|
|
||||||
|
UEND
|
||||||
|
@@ -298,8 +298,8 @@ Use it with caution! (and fencing)
|
||||||
|
<action name="stop" timeout="120s" />
|
||||||
|
<action name="status" timeout="60s" />
|
||||||
|
<action name="monitor" depth="0" timeout="30s" interval="20s" />
|
||||||
|
-<action name="monitor" role="Master" depth="0" timeout="30s" interval="10s" />
|
||||||
|
-<action name="monitor" role="Slave" depth="0" timeout="30s" interval="30s" />
|
||||||
|
+<action name="monitor" role="Promoted" depth="0" timeout="30s" interval="10s" />
|
||||||
|
+<action name="monitor" role="Unpromoted" depth="0" timeout="30s" interval="30s" />
|
||||||
|
<action name="promote" timeout="300s" />
|
||||||
|
<action name="demote" timeout="120s" />
|
||||||
|
<action name="validate-all" timeout="5s" />
|
||||||
|
diff --git a/heartbeat/iface-bridge b/heartbeat/iface-bridge
|
||||||
|
index 75d5371dd..a4e50adb9 100755
|
||||||
|
--- a/heartbeat/iface-bridge
|
||||||
|
+++ b/heartbeat/iface-bridge
|
||||||
|
@@ -211,7 +211,7 @@ bridge_meta_data() {
|
||||||
|
<longdesc lang="en">
|
||||||
|
Set the port cost. This is a dimensionless metric.
|
||||||
|
A list of port/cost can be specified using the following
|
||||||
|
- format: slave cost slave cost.
|
||||||
|
+ format: unpromoted cost unpromoted cost.
|
||||||
|
Example: eth0 100 eth1 1000
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">
|
||||||
|
@@ -228,7 +228,7 @@ bridge_meta_data() {
|
||||||
|
This metric is used in the designated port and root port
|
||||||
|
selection algorithms.
|
||||||
|
A list of port/priority can be specified using the following
|
||||||
|
- format: slave cost slave cost.
|
||||||
|
+ format: unpromoted cost unpromoted cost.
|
||||||
|
Example: eth0 10 eth1 60
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">
|
||||||
|
@@ -262,7 +262,7 @@ bridge_meta_data() {
|
||||||
|
Enable or disable a port from the multicast router.
|
||||||
|
Kernel enables all port by default.
|
||||||
|
A list of port can be specified using the following
|
||||||
|
- format: slave 0|1 slave 0|1.
|
||||||
|
+ format: unpromoted 0|1 unpromoted 0|1.
|
||||||
|
Example: eth0 1 eth1 0
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">
|
||||||
|
diff --git a/heartbeat/mariadb.in b/heartbeat/mariadb.in
|
||||||
|
index 39ad191bb..5a39ccb66 100644
|
||||||
|
--- a/heartbeat/mariadb.in
|
||||||
|
+++ b/heartbeat/mariadb.in
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
#
|
||||||
|
# MariaDB
|
||||||
|
#
|
||||||
|
-# Description: Manages a MariaDB Master/Slave database as Linux-HA resource
|
||||||
|
+# Description: Manages a MariaDB Promotable database as Linux-HA resource
|
||||||
|
#
|
||||||
|
# Authors: Alan Robertson: DB2 Script
|
||||||
|
# Jakub Janczak: rewrite as MySQL
|
||||||
|
@@ -61,8 +61,8 @@ The 'start' operation starts the database.
|
||||||
|
The 'stop' operation stops the database.
|
||||||
|
The 'status' operation reports whether the database is running
|
||||||
|
The 'monitor' operation reports whether the database seems to be working
|
||||||
|
-The 'promote' operation makes this mysql server run as master
|
||||||
|
-The 'demote' operation makes this mysql server run as slave
|
||||||
|
+The 'promote' operation makes this mysql server run as promoted
|
||||||
|
+The 'demote' operation makes this mysql server run as unpromoted
|
||||||
|
The 'validate-all' operation reports whether the parameters are valid
|
||||||
|
|
||||||
|
UEND
|
||||||
|
@@ -78,20 +78,20 @@ meta_data() {
|
||||||
|
<longdesc lang="en">
|
||||||
|
Resource script for MariaDB.
|
||||||
|
|
||||||
|
-Manages a complete master/slave replication setup with GTID, for simpler
|
||||||
|
+Manages a complete promotable replication setup with GTID, for simpler
|
||||||
|
uses look at the mysql resource agent which supports older replication
|
||||||
|
forms which mysql and mariadb have in common.
|
||||||
|
|
||||||
|
The resource must be setup to use notifications. Set 'notify=true' in the metadata
|
||||||
|
-attributes when defining a MariaDB master/slave instance.
|
||||||
|
+attributes when defining a MariaDB promotable instance.
|
||||||
|
|
||||||
|
-The default behavior is to use uname -n values in the change master to command.
|
||||||
|
+The default behavior is to use uname -n values in the change promoted to command.
|
||||||
|
Other IPs can be specified manually by adding a node attribute
|
||||||
|
\${INSTANCE_ATTR_NAME}_mysql_master_IP giving the IP to use for replication.
|
||||||
|
For example, if the mariadb primitive you are using is p_mariadb, the
|
||||||
|
attribute to set will be p_mariadb_mysql_master_IP.
|
||||||
|
</longdesc>
|
||||||
|
-<shortdesc lang="en">Manages a MariaDB master/slave instance</shortdesc>
|
||||||
|
+<shortdesc lang="en">Manages a MariaDB promotable instance</shortdesc>
|
||||||
|
<parameters>
|
||||||
|
|
||||||
|
<parameter name="binary" unique="0" required="0">
|
||||||
|
@@ -154,7 +154,7 @@ The logfile to be used for mysqld.
|
||||||
|
<longdesc lang="en">
|
||||||
|
All node names of nodes that will execute mariadb.
|
||||||
|
Please separate each node name with a space.
|
||||||
|
-This is required for the master selection to function.
|
||||||
|
+This is required for the promoted selection to function.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">node list</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_node_list_default}" />
|
||||||
|
@@ -220,11 +220,11 @@ Additional parameters which are passed to the mysqld on startup.
|
||||||
|
<parameter name="replication_user" unique="0" required="0">
|
||||||
|
<longdesc lang="en">
|
||||||
|
MariaDB replication user. This user is used for starting and stopping
|
||||||
|
-MariaDB replication, for setting and resetting the master host, and for
|
||||||
|
+MariaDB replication, for setting and resetting the promoted host, and for
|
||||||
|
setting and unsetting read-only mode. Because of that, this user must
|
||||||
|
have SUPER, REPLICATION SLAVE, REPLICATION CLIENT, PROCESS and RELOAD
|
||||||
|
privileges on all nodes within the cluster. Mandatory if you define a
|
||||||
|
-master-slave resource.
|
||||||
|
+promotable resource.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">MariaDB replication user</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_replication_user_default}" />
|
||||||
|
@@ -232,8 +232,8 @@ master-slave resource.
|
||||||
|
|
||||||
|
<parameter name="replication_passwd" unique="0" required="0">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-MariaDB replication password. Used for replication client and slave.
|
||||||
|
-Mandatory if you define a master-slave resource.
|
||||||
|
+MariaDB replication password. Used for replication client and unpromoted.
|
||||||
|
+Mandatory if you define a promotable resource.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">MariaDB replication user password</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_replication_passwd_default}" />
|
||||||
|
@@ -241,7 +241,7 @@ Mandatory if you define a master-slave resource.
|
||||||
|
|
||||||
|
<parameter name="replication_port" unique="0" required="0">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-The port on which the Master MariaDB instance is listening.
|
||||||
|
+The port on which the Promoted MariaDB instance is listening.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">MariaDB replication port</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_replication_port_default}" />
|
||||||
|
@@ -254,8 +254,8 @@ The port on which the Master MariaDB instance is listening.
|
||||||
|
<action name="stop" timeout="120s" />
|
||||||
|
<action name="status" timeout="60s" />
|
||||||
|
<action name="monitor" depth="0" timeout="30s" interval="20s" />
|
||||||
|
-<action name="monitor" role="Master" depth="0" timeout="30s" interval="10s" />
|
||||||
|
-<action name="monitor" role="Slave" depth="0" timeout="30s" interval="30s" />
|
||||||
|
+<action name="monitor" role="Promoted" depth="0" timeout="30s" interval="10s" />
|
||||||
|
+<action name="monitor" role="Unpromoted" depth="0" timeout="30s" interval="30s" />
|
||||||
|
<action name="promote" timeout="120s" />
|
||||||
|
<action name="demote" timeout="120s" />
|
||||||
|
<action name="notify" timeout="90s" />
|
||||||
|
diff --git a/heartbeat/mpathpersist.in b/heartbeat/mpathpersist.in
|
||||||
|
index fcf1b3a4b..e47fef4bd 100644
|
||||||
|
--- a/heartbeat/mpathpersist.in
|
||||||
|
+++ b/heartbeat/mpathpersist.in
|
||||||
|
@@ -80,9 +80,9 @@ meta_data() {
|
||||||
|
<longdesc lang="en">
|
||||||
|
This resource agent manages SCSI persistent reservations on multipath devices.
|
||||||
|
"mpathpersist" from multipath-tools is used, please see its documentation.
|
||||||
|
-Should be used as multistate (Master/Slave) resource
|
||||||
|
-Slave registers its node id ("crm_node -i") as reservation key ( --param-sark ) on each device in the params "devs" list.
|
||||||
|
-Master reserves all devices from params "devs" list with reservation "--prout-type" value from "reservation_type" parameter.
|
||||||
|
+Should be used as multistate (Promotable) resource
|
||||||
|
+Unpromoted registers its node id ("crm_node -i") as reservation key ( --param-sark ) on each device in the params "devs" list.
|
||||||
|
+Promoted reserves all devices from params "devs" list with reservation "--prout-type" value from "reservation_type" parameter.
|
||||||
|
Please see man sg_persist(8) and mpathpersist(8) for reservation_type details.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">Manages SCSI persistent reservations on multipath devices</shortdesc>
|
||||||
|
@@ -132,7 +132,7 @@ reservation type
|
||||||
|
master_score_base value
|
||||||
|
"master_score_base" value is used in "master_score" calculation:
|
||||||
|
master_score = master_score_base + master_score_dev_factor * working_devs
|
||||||
|
-if set to bigger value in mpathpersist resource configuration on some node, this node will be "preferred" for master role.
|
||||||
|
+if set to bigger value in mpathpersist resource configuration on some node, this node will be "preferred" for promoted role.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">base master_score value</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_master_score_base_default}" />
|
||||||
|
@@ -140,9 +140,9 @@ if set to bigger value in mpathpersist resource configuration on some node, this
|
||||||
|
|
||||||
|
<parameter name="master_score_dev_factor" unique="0" required="0">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Working device factor in master_score calculation
|
||||||
|
+Working device factor in promoted calculation
|
||||||
|
each "working" device provides additional value to "master_score",
|
||||||
|
-so the node that sees more devices will be preferred for the "Master"-role
|
||||||
|
+so the node that sees more devices will be preferred for the "Promoted"-role
|
||||||
|
Setting it to 0 will disable this behavior.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">working device factor in master_score calculation</shortdesc>
|
||||||
|
@@ -151,10 +151,10 @@ Setting it to 0 will disable this behavior.
|
||||||
|
|
||||||
|
<parameter name="master_score_delay" unique="0" required="0">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-master/slave decreases/increases its master_score after delay of "master_score_delay" seconds
|
||||||
|
-so if some device gets inaccessible, the slave decreases its master_score first and the resource will no be watched
|
||||||
|
-and after this device reappears again the master increases its master_score first
|
||||||
|
-this can work only if the master_score_delay is bigger then monitor interval on both master and slave
|
||||||
|
+promoted/unpromoted decreases/increases its master_score after delay of "master_score_delay" seconds
|
||||||
|
+so if some device gets inaccessible, the unpromoted decreases its promoted first and the resource will no be watched
|
||||||
|
+and after this device reappears again the promoted increases its master_score first
|
||||||
|
+this can work only if the master_score_delay is bigger then monitor interval on both promoted and unpromoted
|
||||||
|
Setting it to 0 will disable this behavior.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">master_score decrease/increase delay time</shortdesc>
|
||||||
|
@@ -168,8 +168,8 @@ Setting it to 0 will disable this behavior.
|
||||||
|
<action name="demote" timeout="30s" />
|
||||||
|
<action name="notify" timeout="30s" />
|
||||||
|
<action name="stop" timeout="30s" />
|
||||||
|
-<action name="monitor" depth="0" timeout="20s" interval="29s" role="Slave" />
|
||||||
|
-<action name="monitor" depth="0" timeout="20s" interval="60s" role="Master" />
|
||||||
|
+<action name="monitor" depth="0" timeout="20s" interval="29s" role="Unpromoted" />
|
||||||
|
+<action name="monitor" depth="0" timeout="20s" interval="60s" role="Promoted" />
|
||||||
|
<action name="meta-data" timeout="5s" />
|
||||||
|
<action name="validate-all" timeout="30s" />
|
||||||
|
</actions>
|
||||||
|
diff --git a/heartbeat/mysql b/heartbeat/mysql
|
||||||
|
index 720de8c1a..aec44fe5e 100755
|
||||||
|
--- a/heartbeat/mysql
|
||||||
|
+++ b/heartbeat/mysql
|
||||||
|
@@ -321,8 +321,8 @@ whether a node is usable for clients to read from.</shortdesc>
|
||||||
|
<action name="stop" timeout="120s" />
|
||||||
|
<action name="status" timeout="60s" />
|
||||||
|
<action name="monitor" depth="0" timeout="30s" interval="20s" />
|
||||||
|
-<action name="monitor" role="Master" depth="0" timeout="30s" interval="10s" />
|
||||||
|
-<action name="monitor" role="Slave" depth="0" timeout="30s" interval="30s" />
|
||||||
|
+<action name="monitor" role="Promoted" depth="0" timeout="30s" interval="10s" />
|
||||||
|
+<action name="monitor" role="Unpromoted" depth="0" timeout="30s" interval="30s" />
|
||||||
|
<action name="promote" timeout="120s" />
|
||||||
|
<action name="demote" timeout="120s" />
|
||||||
|
<action name="notify" timeout="90s" />
|
||||||
|
diff --git a/heartbeat/mysql-proxy b/heartbeat/mysql-proxy
|
||||||
|
index e34396d9a..fdf2fa230 100755
|
||||||
|
--- a/heartbeat/mysql-proxy
|
||||||
|
+++ b/heartbeat/mysql-proxy
|
||||||
|
@@ -162,7 +162,7 @@ Address:port of the remote back-end servers (default: 127.0.0.1:3306).
|
||||||
|
|
||||||
|
<parameter name="proxy_read_only_backend_addresses" unique="0" required="0">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Address:port of the remote (read only) slave-server (default: ).
|
||||||
|
+Address:port of the remote (read only) unpromoted-server (default: ).
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">MySql Proxy read only back-end servers</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_proxy_read_only_backend_addresses_default}" />
|
||||||
|
diff --git a/heartbeat/pgsql b/heartbeat/pgsql
|
||||||
|
index e3a39038f..94aceb324 100755
|
||||||
|
--- a/heartbeat/pgsql
|
||||||
|
+++ b/heartbeat/pgsql
|
||||||
|
@@ -458,7 +458,7 @@ wal receiver is not running in the master and the attribute shows status as
|
||||||
|
<action name="stop" timeout="120s" />
|
||||||
|
<action name="status" timeout="60s" />
|
||||||
|
<action name="monitor" depth="0" timeout="30s" interval="30s"/>
|
||||||
|
-<action name="monitor" depth="0" timeout="30s" interval="29s" role="Master" />
|
||||||
|
+<action name="monitor" depth="0" timeout="30s" interval="29s" role="Promoted" />
|
||||||
|
<action name="promote" timeout="120s" />
|
||||||
|
<action name="demote" timeout="120s" />
|
||||||
|
<action name="notify" timeout="90s" />
|
||||||
|
diff --git a/heartbeat/redis.in b/heartbeat/redis.in
|
||||||
|
index 7f886c7ea..6429477e1 100755
|
||||||
|
--- a/heartbeat/redis.in
|
||||||
|
+++ b/heartbeat/redis.in
|
||||||
|
@@ -220,8 +220,8 @@ is in use.
|
||||||
|
<action name="stop" timeout="120s" />
|
||||||
|
<action name="status" timeout="60s" />
|
||||||
|
<action name="monitor" depth="0" timeout="60s" interval="45s" />
|
||||||
|
-<action name="monitor" role="Master" depth="0" timeout="60s" interval="20s" />
|
||||||
|
-<action name="monitor" role="Slave" depth="0" timeout="60s" interval="60s" />
|
||||||
|
+<action name="monitor" role="Promoted" depth="0" timeout="60s" interval="20s" />
|
||||||
|
+<action name="monitor" role="Unpromoted" depth="0" timeout="60s" interval="60s" />
|
||||||
|
<action name="promote" timeout="120s" />
|
||||||
|
<action name="demote" timeout="120s" />
|
||||||
|
<action name="notify" timeout="90s" />
|
||||||
|
diff --git a/heartbeat/sg_persist.in b/heartbeat/sg_persist.in
|
||||||
|
index 678762f40..0497cc469 100644
|
||||||
|
--- a/heartbeat/sg_persist.in
|
||||||
|
+++ b/heartbeat/sg_persist.in
|
||||||
|
@@ -168,8 +168,8 @@ Setting it to 0 will disable this behavior.
|
||||||
|
<action name="demote" timeout="30s" />
|
||||||
|
<action name="notify" timeout="30s" />
|
||||||
|
<action name="stop" timeout="30s" />
|
||||||
|
-<action name="monitor" depth="0" timeout="20s" interval="29s" role="Slave" />
|
||||||
|
-<action name="monitor" depth="0" timeout="20s" interval="60s" role="Master" />
|
||||||
|
+<action name="monitor" depth="0" timeout="20s" interval="29s" role="Unpromoted" />
|
||||||
|
+<action name="monitor" depth="0" timeout="20s" interval="60s" role="Promoted" />
|
||||||
|
<action name="meta-data" timeout="5s" />
|
||||||
|
<action name="validate-all" timeout="30s" />
|
||||||
|
</actions>
|
||||||
|
|
||||||
|
From 14e5cb71e3749d311745f110f90cc1139f9cedaf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Thu, 16 Jun 2022 15:54:39 +0200
|
||||||
|
Subject: [PATCH 2/2] metadata: update to promoted roles
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/metadata.rng | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/metadata.rng b/heartbeat/metadata.rng
|
||||||
|
index 3dd735547..909efc284 100644
|
||||||
|
--- a/heartbeat/metadata.rng
|
||||||
|
+++ b/heartbeat/metadata.rng
|
||||||
|
@@ -85,8 +85,8 @@
|
||||||
|
|
||||||
|
<define name="role-values">
|
||||||
|
<choice>
|
||||||
|
- <value>Master</value>
|
||||||
|
- <value>Slave</value>
|
||||||
|
+ <value>Promoted</value>
|
||||||
|
+ <value>Unpromoted</value>
|
||||||
|
</choice>
|
||||||
|
</define>
|
||||||
|
|
102
SOURCES/bz2065125-LVM-activate-fix-fence-issue.patch
Normal file
102
SOURCES/bz2065125-LVM-activate-fix-fence-issue.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
From e651576c1b5c1ffbe0fd1b78f209be9a3f9764e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: XingWei-Liu <liuxingwei@uniontech.com>
|
||||||
|
Date: Thu, 10 Mar 2022 10:38:11 +0800
|
||||||
|
Subject: [PATCH 1/4] change lvm_status return value from ocf_not_running to
|
||||||
|
ocf_err_generic
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/LVM-activate | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/LVM-activate b/heartbeat/LVM-activate
|
||||||
|
index aed672ea3..0aef76706 100755
|
||||||
|
--- a/heartbeat/LVM-activate
|
||||||
|
+++ b/heartbeat/LVM-activate
|
||||||
|
@@ -790,7 +790,7 @@ lvm_status() {
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $dm_count -eq 0 ]; then
|
||||||
|
- return $OCF_NOT_RUNNING
|
||||||
|
+ return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$OCF_CHECK_LEVEL" in
|
||||||
|
|
||||||
|
From 540ae56436a4f9547bb17aa206fe0e8c7a7fea87 Mon Sep 17 00:00:00 2001
|
||||||
|
From: XingWei-Liu <liuxingwei@uniontech.com>
|
||||||
|
Date: Thu, 10 Mar 2022 16:44:25 +0800
|
||||||
|
Subject: [PATCH 2/4] add if ocf_is_probe in monitor func
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/LVM-activate | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/LVM-activate b/heartbeat/LVM-activate
|
||||||
|
index 0aef76706..c86606637 100755
|
||||||
|
--- a/heartbeat/LVM-activate
|
||||||
|
+++ b/heartbeat/LVM-activate
|
||||||
|
@@ -790,7 +790,11 @@ lvm_status() {
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $dm_count -eq 0 ]; then
|
||||||
|
- return $OCF_ERR_GENERIC
|
||||||
|
+ if ocf_is_probe ;then
|
||||||
|
+ return $OCF_NOT_RUNNING
|
||||||
|
+ else
|
||||||
|
+ return $OCF_ERR_GENERIC
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$OCF_CHECK_LEVEL" in
|
||||||
|
|
||||||
|
From ae3f35d4f671f3288034a257c6dd8eff9a83447a Mon Sep 17 00:00:00 2001
|
||||||
|
From: XingWei-Liu <liuxingwei@uniontech.com>
|
||||||
|
Date: Thu, 10 Mar 2022 16:50:04 +0800
|
||||||
|
Subject: [PATCH 3/4] add if ocf_is_probe in monitor func
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/LVM-activate | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/LVM-activate b/heartbeat/LVM-activate
|
||||||
|
index c86606637..f345f73a9 100755
|
||||||
|
--- a/heartbeat/LVM-activate
|
||||||
|
+++ b/heartbeat/LVM-activate
|
||||||
|
@@ -791,9 +791,9 @@ lvm_status() {
|
||||||
|
|
||||||
|
if [ $dm_count -eq 0 ]; then
|
||||||
|
if ocf_is_probe ;then
|
||||||
|
- return $OCF_NOT_RUNNING
|
||||||
|
- else
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
+ else
|
||||||
|
+ return $OCF_NOT_RUNNING
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
From 1072c0490ef936a1a7dfd8411da434dce1569457 Mon Sep 17 00:00:00 2001
|
||||||
|
From: XingWei-Liu <liuxingwei@uniontech.com>
|
||||||
|
Date: Thu, 10 Mar 2022 18:10:21 +0800
|
||||||
|
Subject: [PATCH 4/4] reverse return value in monitor func
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/LVM-activate | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/LVM-activate b/heartbeat/LVM-activate
|
||||||
|
index f345f73a9..c86606637 100755
|
||||||
|
--- a/heartbeat/LVM-activate
|
||||||
|
+++ b/heartbeat/LVM-activate
|
||||||
|
@@ -791,9 +791,9 @@ lvm_status() {
|
||||||
|
|
||||||
|
if [ $dm_count -eq 0 ]; then
|
||||||
|
if ocf_is_probe ;then
|
||||||
|
- return $OCF_ERR_GENERIC
|
||||||
|
- else
|
||||||
|
return $OCF_NOT_RUNNING
|
||||||
|
+ else
|
||||||
|
+ return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,312 @@
|
|||||||
|
From fd1d6426a2d05f521207c305d10b49fedd92c2df Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Pavlu <petr.pavlu@suse.com>
|
||||||
|
Date: Mon, 28 Feb 2022 09:27:42 +0100
|
||||||
|
Subject: [PATCH 1/4] IPaddr2: Allow to disable Duplicate Address Detection for
|
||||||
|
IPv6
|
||||||
|
|
||||||
|
"Starting" an IPv6 address with IPaddr2 involves performing Duplicate
|
||||||
|
Address Detection which typically takes at least 1000 ms. Allow the user
|
||||||
|
to disable DAD if they can guarantee that the configured address is not
|
||||||
|
duplicate and they wish to start the resource faster.
|
||||||
|
---
|
||||||
|
heartbeat/IPaddr2 | 15 +++++++++++++++
|
||||||
|
1 file changed, 15 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/IPaddr2 b/heartbeat/IPaddr2
|
||||||
|
index 735dd7779..650392b70 100755
|
||||||
|
--- a/heartbeat/IPaddr2
|
||||||
|
+++ b/heartbeat/IPaddr2
|
||||||
|
@@ -88,6 +88,7 @@ OCF_RESKEY_arp_sender_default=""
|
||||||
|
OCF_RESKEY_send_arp_opts_default=""
|
||||||
|
OCF_RESKEY_flush_routes_default="false"
|
||||||
|
OCF_RESKEY_run_arping_default=false
|
||||||
|
+OCF_RESKEY_nodad_default=false
|
||||||
|
OCF_RESKEY_noprefixroute_default="false"
|
||||||
|
OCF_RESKEY_preferred_lft_default="forever"
|
||||||
|
OCF_RESKEY_network_namespace_default=""
|
||||||
|
@@ -110,6 +111,7 @@ OCF_RESKEY_network_namespace_default=""
|
||||||
|
: ${OCF_RESKEY_send_arp_opts=${OCF_RESKEY_send_arp_opts_default}}
|
||||||
|
: ${OCF_RESKEY_flush_routes=${OCF_RESKEY_flush_routes_default}}
|
||||||
|
: ${OCF_RESKEY_run_arping=${OCF_RESKEY_run_arping_default}}
|
||||||
|
+: ${OCF_RESKEY_nodad=${OCF_RESKEY_nodad_default}}
|
||||||
|
: ${OCF_RESKEY_noprefixroute=${OCF_RESKEY_noprefixroute_default}}
|
||||||
|
: ${OCF_RESKEY_preferred_lft=${OCF_RESKEY_preferred_lft_default}}
|
||||||
|
: ${OCF_RESKEY_network_namespace=${OCF_RESKEY_network_namespace_default}}
|
||||||
|
@@ -391,6 +393,14 @@ Whether or not to run arping for IPv4 collision detection check.
|
||||||
|
<content type="string" default="${OCF_RESKEY_run_arping_default}"/>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
+<parameter name="nodad">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+For IPv6, do not perform Duplicate Address Detection when adding the address.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Use nodad flag</shortdesc>
|
||||||
|
+<content type="string" default="${OCF_RESKEY_nodad_default}"/>
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
<parameter name="noprefixroute">
|
||||||
|
<longdesc lang="en">
|
||||||
|
Use noprefixroute flag (see 'man ip-address').
|
||||||
|
@@ -662,6 +672,11 @@ add_interface () {
|
||||||
|
msg="Adding $FAMILY address $ipaddr/$netmask with broadcast address $broadcast to device $iface"
|
||||||
|
fi
|
||||||
|
|
||||||
|
+ if [ "$FAMILY" = "inet6" ] && ocf_is_true "${OCF_RESKEY_nodad}"; then
|
||||||
|
+ cmd="$cmd nodad"
|
||||||
|
+ msg="${msg} (with nodad)"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
if ocf_is_true "${OCF_RESKEY_noprefixroute}"; then
|
||||||
|
cmd="$cmd noprefixroute"
|
||||||
|
msg="${msg} (with noprefixroute)"
|
||||||
|
|
||||||
|
From f4a9e3281d48c5d37f5df593d014706c46ddb3a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Pavlu <petr.pavlu@suse.com>
|
||||||
|
Date: Mon, 7 Mar 2022 17:21:59 +0100
|
||||||
|
Subject: [PATCH 2/4] IPaddr2: Allow to send IPv6 Neighbor Advertisements in
|
||||||
|
background
|
||||||
|
|
||||||
|
"Starting" an IPv6 address with IPaddr2 involves sending Neighbor
|
||||||
|
Advertisement packets to inform neighboring machines about the new
|
||||||
|
IP+MAC translation. By default, 5x packets with 200 ms sleep after each
|
||||||
|
are sent which delays the start by 1000 ms. Allow the user to run this
|
||||||
|
operation in background, similarly as is possible with GARP for IPv4.
|
||||||
|
---
|
||||||
|
heartbeat/IPaddr2 | 33 +++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 29 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/IPaddr2 b/heartbeat/IPaddr2
|
||||||
|
index 650392b70..e243a642d 100755
|
||||||
|
--- a/heartbeat/IPaddr2
|
||||||
|
+++ b/heartbeat/IPaddr2
|
||||||
|
@@ -83,7 +83,7 @@ OCF_RESKEY_unique_clone_address_default=false
|
||||||
|
OCF_RESKEY_arp_interval_default=200
|
||||||
|
OCF_RESKEY_arp_count_default=5
|
||||||
|
OCF_RESKEY_arp_count_refresh_default=0
|
||||||
|
-OCF_RESKEY_arp_bg_default=true
|
||||||
|
+OCF_RESKEY_arp_bg_default=""
|
||||||
|
OCF_RESKEY_arp_sender_default=""
|
||||||
|
OCF_RESKEY_send_arp_opts_default=""
|
||||||
|
OCF_RESKEY_flush_routes_default="false"
|
||||||
|
@@ -336,9 +336,10 @@ situations.
|
||||||
|
|
||||||
|
<parameter name="arp_bg">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Whether or not to send the ARP packets in the background.
|
||||||
|
+Whether or not to send the ARP (IPv4) or NA (IPv6) packets in the background.
|
||||||
|
+The default is true for IPv4 and false for IPv6.
|
||||||
|
</longdesc>
|
||||||
|
-<shortdesc lang="en">ARP from background</shortdesc>
|
||||||
|
+<shortdesc lang="en">ARP/NA from background</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_arp_bg_default}"/>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
@@ -507,6 +508,9 @@ ip_init() {
|
||||||
|
ocf_exit_reason "IPv4 does not support lvs_ipv6_addrlabel"
|
||||||
|
exit $OCF_ERR_CONFIGURED
|
||||||
|
fi
|
||||||
|
+ if [ -z "$OCF_RESKEY_arp_bg" ]; then
|
||||||
|
+ OCF_RESKEY_arp_bg=true
|
||||||
|
+ fi
|
||||||
|
else
|
||||||
|
FAMILY=inet6
|
||||||
|
# address sanitization defined in RFC5952
|
||||||
|
@@ -527,6 +531,9 @@ ip_init() {
|
||||||
|
exit $OCF_ERR_CONFIGURED
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
+ if [ -z "$OCF_RESKEY_arp_bg" ]; then
|
||||||
|
+ OCF_RESKEY_arp_bg=false
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# support nic:iflabel format in nic parameter
|
||||||
|
@@ -893,6 +900,20 @@ run_arp_sender() {
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
+log_send_ua() {
|
||||||
|
+ local cmdline
|
||||||
|
+ local output
|
||||||
|
+ local rc
|
||||||
|
+
|
||||||
|
+ cmdline="$@"
|
||||||
|
+ output=$($cmdline 2>&1)
|
||||||
|
+ rc=$?
|
||||||
|
+ if [ $rc -ne 0 ] ; then
|
||||||
|
+ ocf_log err "Could not send ICMPv6 Unsolicited Neighbor Advertisements: rc=$rc"
|
||||||
|
+ fi
|
||||||
|
+ ocf_log info "$output"
|
||||||
|
+ return $rc
|
||||||
|
+}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Run send_ua to note send ICMPv6 Unsolicited Neighbor Advertisements.
|
||||||
|
@@ -930,7 +951,11 @@ run_send_ua() {
|
||||||
|
|
||||||
|
ARGS="-i $OCF_RESKEY_arp_interval -c $OCF_RESKEY_arp_count $OCF_RESKEY_ip $NETMASK $NIC"
|
||||||
|
ocf_log info "$SENDUA $ARGS"
|
||||||
|
- $SENDUA $ARGS || ocf_log err "Could not send ICMPv6 Unsolicited Neighbor Advertisements."
|
||||||
|
+ if ocf_is_true $OCF_RESKEY_arp_bg; then
|
||||||
|
+ log_send_ua $SENDUA $ARGS &
|
||||||
|
+ else
|
||||||
|
+ log_send_ua $SENDUA $ARGS
|
||||||
|
+ fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Do we already serve this IP address on the given $NIC?
|
||||||
|
|
||||||
|
From c8afb43012c264f3ee24013a92b2a2f3566db2fd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Pavlu <petr.pavlu@suse.com>
|
||||||
|
Date: Tue, 8 Mar 2022 12:35:56 +0100
|
||||||
|
Subject: [PATCH 3/4] IPaddr2: Log 'ip addr add' options together
|
||||||
|
|
||||||
|
Change the log message in add_interface() from
|
||||||
|
"Adding ... (with <opt1>) (with <opt2>)"
|
||||||
|
to
|
||||||
|
"Adding ... (with <opt1> <opt2>)".
|
||||||
|
---
|
||||||
|
heartbeat/IPaddr2 | 19 ++++++++++---------
|
||||||
|
1 file changed, 10 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/IPaddr2 b/heartbeat/IPaddr2
|
||||||
|
index e243a642d..dca1b6f5b 100755
|
||||||
|
--- a/heartbeat/IPaddr2
|
||||||
|
+++ b/heartbeat/IPaddr2
|
||||||
|
@@ -651,7 +651,7 @@ delete_interface () {
|
||||||
|
# Add an interface
|
||||||
|
#
|
||||||
|
add_interface () {
|
||||||
|
- local cmd msg ipaddr netmask broadcast iface label
|
||||||
|
+ local cmd msg extra_opts ipaddr netmask broadcast iface label
|
||||||
|
|
||||||
|
ipaddr="$1"
|
||||||
|
netmask="$2"
|
||||||
|
@@ -679,23 +679,24 @@ add_interface () {
|
||||||
|
msg="Adding $FAMILY address $ipaddr/$netmask with broadcast address $broadcast to device $iface"
|
||||||
|
fi
|
||||||
|
|
||||||
|
+ extra_opts=""
|
||||||
|
if [ "$FAMILY" = "inet6" ] && ocf_is_true "${OCF_RESKEY_nodad}"; then
|
||||||
|
- cmd="$cmd nodad"
|
||||||
|
- msg="${msg} (with nodad)"
|
||||||
|
+ extra_opts="$extra_opts nodad"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ocf_is_true "${OCF_RESKEY_noprefixroute}"; then
|
||||||
|
- cmd="$cmd noprefixroute"
|
||||||
|
- msg="${msg} (with noprefixroute)"
|
||||||
|
+ extra_opts="$extra_opts noprefixroute"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$label" ]; then
|
||||||
|
- cmd="$cmd label $label"
|
||||||
|
- msg="${msg} (with label $label)"
|
||||||
|
+ extra_opts="$extra_opts label $label"
|
||||||
|
fi
|
||||||
|
if [ "$FAMILY" = "inet6" ] ;then
|
||||||
|
- cmd="$cmd preferred_lft $OCF_RESKEY_preferred_lft"
|
||||||
|
- msg="${msg} (with preferred_lft $OCF_RESKEY_preferred_lft)"
|
||||||
|
+ extra_opts="$extra_opts preferred_lft $OCF_RESKEY_preferred_lft"
|
||||||
|
+ fi
|
||||||
|
+ if [ -n "$extra_opts" ]; then
|
||||||
|
+ cmd="$cmd$extra_opts"
|
||||||
|
+ msg="$msg (with$extra_opts)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ocf_log info "$msg"
|
||||||
|
|
||||||
|
From cb4d52ead694718282a40eab24e04b6d85bcc802 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Pavlu <petr.pavlu@suse.com>
|
||||||
|
Date: Mon, 7 Mar 2022 17:25:02 +0100
|
||||||
|
Subject: [PATCH 4/4] IPaddr2: Clarify behavior of 'arp_*' parameters for IPv4
|
||||||
|
and IPv6
|
||||||
|
|
||||||
|
* Mention that 'arp_*' parameters are shared by the IPv4 and IPv6 code.
|
||||||
|
* Clarify description of these parameters and mark which of them apply
|
||||||
|
only to IPv4.
|
||||||
|
---
|
||||||
|
heartbeat/IPaddr2 | 26 +++++++++++++++++---------
|
||||||
|
1 file changed, 17 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/IPaddr2 b/heartbeat/IPaddr2
|
||||||
|
index dca1b6f5b..97a7431a2 100755
|
||||||
|
--- a/heartbeat/IPaddr2
|
||||||
|
+++ b/heartbeat/IPaddr2
|
||||||
|
@@ -157,6 +157,12 @@ and/or clone-max < number of nodes. In case of node failure,
|
||||||
|
clone instances need to be re-allocated on surviving nodes.
|
||||||
|
This would not be possible if there is already an instance
|
||||||
|
on those nodes, and clone-node-max=1 (which is the default).
|
||||||
|
+
|
||||||
|
+When the specified IP address gets assigned to a respective interface, the
|
||||||
|
+resource agent sends unsolicited ARP (Address Resolution Protocol, IPv4) or NA
|
||||||
|
+(Neighbor Advertisement, IPv6) packets to inform neighboring machines about the
|
||||||
|
+change. This functionality is controlled for both IPv4 and IPv6 by shared
|
||||||
|
+'arp_*' parameters.
|
||||||
|
</longdesc>
|
||||||
|
|
||||||
|
<shortdesc lang="en">Manages virtual IPv4 and IPv6 addresses (Linux specific version)</shortdesc>
|
||||||
|
@@ -306,28 +312,30 @@ a unique address to manage
|
||||||
|
|
||||||
|
<parameter name="arp_interval">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Specify the interval between unsolicited ARP packets in milliseconds.
|
||||||
|
+Specify the interval between unsolicited ARP (IPv4) or NA (IPv6) packets in
|
||||||
|
+milliseconds.
|
||||||
|
|
||||||
|
This parameter is deprecated and used for the backward compatibility only.
|
||||||
|
It is effective only for the send_arp binary which is built with libnet,
|
||||||
|
and send_ua for IPv6. It has no effect for other arp_sender.
|
||||||
|
</longdesc>
|
||||||
|
-<shortdesc lang="en">ARP packet interval in ms (deprecated)</shortdesc>
|
||||||
|
+<shortdesc lang="en">ARP/NA packet interval in ms (deprecated)</shortdesc>
|
||||||
|
<content type="integer" default="${OCF_RESKEY_arp_interval_default}"/>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="arp_count">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Number of unsolicited ARP packets to send at resource initialization.
|
||||||
|
+Number of unsolicited ARP (IPv4) or NA (IPv6) packets to send at resource
|
||||||
|
+initialization.
|
||||||
|
</longdesc>
|
||||||
|
-<shortdesc lang="en">ARP packet count sent during initialization</shortdesc>
|
||||||
|
+<shortdesc lang="en">ARP/NA packet count sent during initialization</shortdesc>
|
||||||
|
<content type="integer" default="${OCF_RESKEY_arp_count_default}"/>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="arp_count_refresh">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Number of unsolicited ARP packets to send during resource monitoring. Doing
|
||||||
|
-so helps mitigate issues of stuck ARP caches resulting from split-brain
|
||||||
|
+For IPv4, number of unsolicited ARP packets to send during resource monitoring.
|
||||||
|
+Doing so helps mitigate issues of stuck ARP caches resulting from split-brain
|
||||||
|
situations.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">ARP packet count sent during monitoring</shortdesc>
|
||||||
|
@@ -345,7 +353,7 @@ The default is true for IPv4 and false for IPv6.
|
||||||
|
|
||||||
|
<parameter name="arp_sender">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-The program to send ARP packets with on start. Available options are:
|
||||||
|
+For IPv4, the program to send ARP packets with on start. Available options are:
|
||||||
|
- send_arp: default
|
||||||
|
- ipoibarping: default for infiniband interfaces if ipoibarping is available
|
||||||
|
- iputils_arping: use arping in iputils package
|
||||||
|
@@ -357,7 +365,7 @@ The program to send ARP packets with on start. Available options are:
|
||||||
|
|
||||||
|
<parameter name="send_arp_opts">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Extra options to pass to the arp_sender program.
|
||||||
|
+For IPv4, extra options to pass to the arp_sender program.
|
||||||
|
Available options are vary depending on which arp_sender is used.
|
||||||
|
|
||||||
|
A typical use case is specifying '-A' for iputils_arping to use
|
||||||
|
@@ -388,7 +396,7 @@ IP address goes away.
|
||||||
|
|
||||||
|
<parameter name="run_arping">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Whether or not to run arping for IPv4 collision detection check.
|
||||||
|
+For IPv4, whether or not to run arping for collision detection check.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">Run arping for IPv4 collision detection check</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_run_arping_default}"/>
|
401
SOURCES/bz2069270-corosync-qnetd-new-ra.patch
Normal file
401
SOURCES/bz2069270-corosync-qnetd-new-ra.patch
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
From d59a000da2766476538bb82d1889f5c0f3882f9f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Friesse <jfriesse@redhat.com>
|
||||||
|
Date: Wed, 2 Mar 2022 18:43:31 +0100
|
||||||
|
Subject: [PATCH] corosync-qnetd: Add resource agent
|
||||||
|
|
||||||
|
Mostly for better monitor operation using corosync-qnetd-tool. As qnetd
|
||||||
|
is (almost) stateless only directory which has to be copied (once)
|
||||||
|
across the nodes is nss db directory (usually
|
||||||
|
/etc/corosync/qnetd/nssdb).
|
||||||
|
|
||||||
|
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
|
||||||
|
---
|
||||||
|
doc/man/Makefile.am | 1 +
|
||||||
|
heartbeat/Makefile.am | 1 +
|
||||||
|
heartbeat/corosync-qnetd | 353 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 355 insertions(+)
|
||||||
|
create mode 100755 heartbeat/corosync-qnetd
|
||||||
|
|
||||||
|
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
|
||||||
|
index 1093717fe..013aa392d 100644
|
||||||
|
--- a/doc/man/Makefile.am
|
||||||
|
+++ b/doc/man/Makefile.am
|
||||||
|
@@ -127,6 +127,7 @@ man_MANS = ocf_heartbeat_AoEtarget.7 \
|
||||||
|
ocf_heartbeat_azure-lb.7 \
|
||||||
|
ocf_heartbeat_clvm.7 \
|
||||||
|
ocf_heartbeat_conntrackd.7 \
|
||||||
|
+ ocf_heartbeat_corosync-qnetd.7 \
|
||||||
|
ocf_heartbeat_crypt.7 \
|
||||||
|
ocf_heartbeat_db2.7 \
|
||||||
|
ocf_heartbeat_dhcpd.7 \
|
||||||
|
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
|
||||||
|
index 67b400679..38154e2da 100644
|
||||||
|
--- a/heartbeat/Makefile.am
|
||||||
|
+++ b/heartbeat/Makefile.am
|
||||||
|
@@ -101,6 +101,7 @@ ocf_SCRIPTS = AoEtarget \
|
||||||
|
azure-lb \
|
||||||
|
clvm \
|
||||||
|
conntrackd \
|
||||||
|
+ corosync-qnetd \
|
||||||
|
crypt \
|
||||||
|
db2 \
|
||||||
|
dhcpd \
|
||||||
|
diff --git a/heartbeat/corosync-qnetd b/heartbeat/corosync-qnetd
|
||||||
|
new file mode 100755
|
||||||
|
index 000000000..6b9777711
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/heartbeat/corosync-qnetd
|
||||||
|
@@ -0,0 +1,353 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+#
|
||||||
|
+# Copyright (C) 2022 Red Hat, Inc. All rights reserved.
|
||||||
|
+#
|
||||||
|
+# Authors: Jan Friesse <jfriesse@redhat.com>
|
||||||
|
+#
|
||||||
|
+# This program is free software; you can redistribute it and/or modify
|
||||||
|
+# it under the terms of version 2 of the GNU General Public License as
|
||||||
|
+# published by the Free Software Foundation.
|
||||||
|
+#
|
||||||
|
+# This program is distributed in the hope that it would be useful, but
|
||||||
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
+#
|
||||||
|
+# Further, this software is distributed without any warranty that it is
|
||||||
|
+# free of the rightful claim of any third person regarding infringement
|
||||||
|
+# or the like. Any license provided herein, whether implied or
|
||||||
|
+# otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
+# any, provided herein do not apply to combinations of this program with
|
||||||
|
+# other software, or any other product whatsoever.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write the Free Software Foundation,
|
||||||
|
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+# Initialization:
|
||||||
|
+: "${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}"
|
||||||
|
+. "${OCF_FUNCTIONS_DIR}/ocf-shellfuncs"
|
||||||
|
+
|
||||||
|
+# Use runuser if available for SELinux.
|
||||||
|
+if [ -x "/sbin/runuser" ]; then
|
||||||
|
+ SU="runuser"
|
||||||
|
+else
|
||||||
|
+ SU="su"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+# Attempt to detect a default binary
|
||||||
|
+OCF_RESKEY_binary_default=$(which corosync-qnetd 2> /dev/null)
|
||||||
|
+if [ "${OCF_RESKEY_binary_default}" = "" ]; then
|
||||||
|
+ OCF_RESKEY_binary_default="/usr/bin/corosync-qnetd"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+# Defaults
|
||||||
|
+OCF_RESKEY_qnetd_opts_default=""
|
||||||
|
+OCF_RESKEY_qnetd_tool_binary_default="/usr/bin/corosync-qnetd-tool"
|
||||||
|
+OCF_RESKEY_ip_default=""
|
||||||
|
+OCF_RESKEY_port_default=""
|
||||||
|
+OCF_RESKEY_nss_db_dir_default=""
|
||||||
|
+OCF_RESKEY_pid_default="/var/run/corosync-qnetd/corosync-qnetd-${OCF_RESOURCE_INSTANCE}.pid"
|
||||||
|
+OCF_RESKEY_ipc_sock_default="/var/run/corosync-qnetd/corosync-qnetd-${OCF_RESOURCE_INSTANCE}.sock"
|
||||||
|
+OCF_RESKEY_user_default="coroqnetd"
|
||||||
|
+OCF_RESKEY_group_default="${OCF_RESKEY_user_default}"
|
||||||
|
+
|
||||||
|
+: "${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}"
|
||||||
|
+: "${OCF_RESKEY_qnetd_opts=${OCF_RESKEY_qnetd_opts_default}}"
|
||||||
|
+: "${OCF_RESKEY_qnetd_tool_binary=${OCF_RESKEY_qnetd_tool_binary_default}}"
|
||||||
|
+: "${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}}"
|
||||||
|
+: "${OCF_RESKEY_port=${OCF_RESKEY_port_default}}"
|
||||||
|
+: "${OCF_RESKEY_nss_db_dir=${OCF_RESKEY_nss_db_dir_default}}"
|
||||||
|
+: "${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}"
|
||||||
|
+: "${OCF_RESKEY_ipc_sock=${OCF_RESKEY_ipc_sock_default}}"
|
||||||
|
+: "${OCF_RESKEY_user=${OCF_RESKEY_user_default}}"
|
||||||
|
+: "${OCF_RESKEY_group=${OCF_RESKEY_group_default}}"
|
||||||
|
+
|
||||||
|
+corosync_qnetd_usage() {
|
||||||
|
+ cat <<END
|
||||||
|
+usage: $0 {start|stop|status|monitor|validate-all|meta-data}
|
||||||
|
+
|
||||||
|
+Expects to have a fully populated OCF RA-compliant environment set.
|
||||||
|
+END
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+corosync_qnetd_meta_data() {
|
||||||
|
+ cat <<END
|
||||||
|
+<?xml version="1.0"?>
|
||||||
|
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
|
||||||
|
+<resource-agent name="corosync-qnetd" version="1.0">
|
||||||
|
+<version>1.0</version>
|
||||||
|
+
|
||||||
|
+<longdesc lang="en">OCF Resource script for corosync-qnetd. It manages a corosync-qnetd
|
||||||
|
+instance as a HA resource. It is required to copy nss db directory (usually /etc/corosync/qnetd/nssdb)
|
||||||
|
+across all nodes (only once - after database is initialized).</longdesc>
|
||||||
|
+<shortdesc lang="en">Corosync QNet daemon resource agent</shortdesc>
|
||||||
|
+
|
||||||
|
+<parameters>
|
||||||
|
+
|
||||||
|
+<parameter name="binary">
|
||||||
|
+ <longdesc lang="en">Location of the corosync-qnetd binary</longdesc>
|
||||||
|
+ <shortdesc lang="en">corosync-qnetd binary</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_binary_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="qnetd_opts">
|
||||||
|
+ <longdesc lang="en">
|
||||||
|
+ Additional options for corosync-qnetd binary. "-4" for example.
|
||||||
|
+ </longdesc>
|
||||||
|
+ <shortdesc lang="en">corosync-qnetd extra options</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_qnetd_opts_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="qnetd_tool_binary">
|
||||||
|
+ <longdesc lang="en">
|
||||||
|
+ The absolute path to the corosync-qnetd-tool for monitoring with OCF_CHECK_LEVEL greater zero.
|
||||||
|
+ </longdesc>
|
||||||
|
+ <shortdesc lang="en">The absolute path to the corosync-qnetd-tool binary</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_qnetd_tool_binary_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="ip">
|
||||||
|
+ <longdesc lang="en">
|
||||||
|
+ IP address to listen on. By default the daemon listens on all addresses (wildcard).
|
||||||
|
+ </longdesc>
|
||||||
|
+ <shortdesc lang="en">IP address to listen on</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_ip_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="port">
|
||||||
|
+ <longdesc lang="en">
|
||||||
|
+ TCP port to listen on. Default port is 5403.
|
||||||
|
+ </longdesc>
|
||||||
|
+ <shortdesc lang="en">TCP port to listen on</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_port_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="nss_db_dir">
|
||||||
|
+ <longdesc lang="en">
|
||||||
|
+ Location of the corosync-qnetd nss db directory (empty for default - usually /etc/corosync/qnetd/nssdb)
|
||||||
|
+ </longdesc>
|
||||||
|
+ <shortdesc lang="en">corosync-qnetd nss db directory</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_nss_db_dir_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="pid">
|
||||||
|
+ <longdesc lang="en">
|
||||||
|
+ Location of the corosync-qnetd pid/lock
|
||||||
|
+ </longdesc>
|
||||||
|
+ <shortdesc lang="en">corosync-qnetd pid file</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_pid_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="ipc_sock">
|
||||||
|
+ <longdesc lang="en">
|
||||||
|
+ Location of the corosync-qnetd ipc socket
|
||||||
|
+ </longdesc>
|
||||||
|
+ <shortdesc lang="en">corosync-qnetd ipc socket file</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_ipc_sock_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="user">
|
||||||
|
+ <longdesc lang="en">User running corosync-qnetd</longdesc>
|
||||||
|
+ <shortdesc lang="en">corosync-qnetd user</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_user_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="group">
|
||||||
|
+ <longdesc lang="en">Group running corosync-qnetd</longdesc>
|
||||||
|
+ <shortdesc lang="en">corosync-qnetd group</shortdesc>
|
||||||
|
+ <content type="string" default="${OCF_RESKEY_group_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+</parameters>
|
||||||
|
+
|
||||||
|
+<actions>
|
||||||
|
+<action name="start" timeout="20s" />
|
||||||
|
+<action name="stop" timeout="20s" />
|
||||||
|
+<action name="status" timeout="20s" />
|
||||||
|
+<action name="monitor" depth="0" timeout="20s" interval="10s" start-delay="10s" />
|
||||||
|
+<action name="validate-all" timeout="20s" />
|
||||||
|
+<action name="meta-data" timeout="20s" />
|
||||||
|
+</actions>
|
||||||
|
+</resource-agent>
|
||||||
|
+END
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+corosync_qnetd_status() {
|
||||||
|
+ ocf_pidfile_status "${OCF_RESKEY_pid}" > /dev/null 2>&1
|
||||||
|
+ case "$?" in
|
||||||
|
+ 0)
|
||||||
|
+ rc="$OCF_SUCCESS"
|
||||||
|
+ ;;
|
||||||
|
+ 1|2)
|
||||||
|
+ rc="$OCF_NOT_RUNNING"
|
||||||
|
+ ;;
|
||||||
|
+ *)
|
||||||
|
+ rc="$OCF_ERR_GENERIC"
|
||||||
|
+ ;;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ return "$rc"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+corosync_qnetd_start() {
|
||||||
|
+ corosync_qnetd_validate_all
|
||||||
|
+ rc="$?"
|
||||||
|
+
|
||||||
|
+ if [ "$rc" -ne 0 ]; then
|
||||||
|
+ return "$rc"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ # if resource is already running,no need to continue code after this.
|
||||||
|
+ if corosync_qnetd_status; then
|
||||||
|
+ ocf_log info "corosync-qnetd is already running"
|
||||||
|
+ return "${OCF_SUCCESS}"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ pid_dir=$(dirname "${OCF_RESKEY_pid}")
|
||||||
|
+ sock_dir=$(dirname "${OCF_RESKEY_ipc_sock}")
|
||||||
|
+
|
||||||
|
+ for d in "$pid_dir" "$sock_dir";do
|
||||||
|
+ if [ ! -d "$d" ];then
|
||||||
|
+ mkdir -p "$d"
|
||||||
|
+ chmod 0770 "$d"
|
||||||
|
+ chown "${OCF_RESKEY_user}:${OCF_RESKEY_group}" "$d"
|
||||||
|
+ fi
|
||||||
|
+ done
|
||||||
|
+
|
||||||
|
+ params="-S \"local_socket_file=${OCF_RESKEY_ipc_sock}\" -S \"lock_file=${OCF_RESKEY_pid}\""
|
||||||
|
+
|
||||||
|
+ if [ -n "${OCF_RESKEY_nss_db_dir}" ];then
|
||||||
|
+ params="$params -S \"nss_db_dir=${OCF_RESKEY_nss_db_dir}\""
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ if [ -n "${OCF_RESKEY_ip}" ];then
|
||||||
|
+ params="$params -l \"${OCF_RESKEY_ip}\""
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ if [ -n "${OCF_RESKEY_port}" ];then
|
||||||
|
+ params="$params -p \"${OCF_RESKEY_port}\""
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ params="$params ${OCF_RESKEY_qnetd_opts}"
|
||||||
|
+
|
||||||
|
+ ocf_run "$SU" -s "/bin/sh" "${OCF_RESKEY_user}" -c "${OCF_RESKEY_binary} $params"
|
||||||
|
+
|
||||||
|
+ while :; do
|
||||||
|
+ corosync_qnetd_monitor "debug"
|
||||||
|
+ rc="$?"
|
||||||
|
+
|
||||||
|
+ if [ "$rc" -eq "${OCF_SUCCESS}" ]; then
|
||||||
|
+ break
|
||||||
|
+ fi
|
||||||
|
+ sleep 1
|
||||||
|
+
|
||||||
|
+ ocf_log debug "corosync-qnetd still hasn't started yet. Waiting..."
|
||||||
|
+ done
|
||||||
|
+
|
||||||
|
+ ocf_log info "corosync-qnetd started"
|
||||||
|
+ return "${OCF_SUCCESS}"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+corosync_qnetd_stop() {
|
||||||
|
+ corosync_qnetd_status
|
||||||
|
+
|
||||||
|
+ if [ "$?" -ne "$OCF_SUCCESS" ]; then
|
||||||
|
+ # Currently not running. Nothing to do.
|
||||||
|
+ ocf_log info "corosync-qnetd is already stopped"
|
||||||
|
+
|
||||||
|
+ return "$OCF_SUCCESS"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ pid=$(cat "${OCF_RESKEY_pid}")
|
||||||
|
+ kill "$pid"
|
||||||
|
+
|
||||||
|
+ # Wait for process to stop
|
||||||
|
+ while corosync_qnetd_monitor "debug"; do
|
||||||
|
+ sleep 1
|
||||||
|
+ done
|
||||||
|
+
|
||||||
|
+ ocf_log info "corosync-qnetd stopped"
|
||||||
|
+ return "$OCF_SUCCESS"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+corosync_qnetd_monitor() {
|
||||||
|
+ loglevel=${1:-err}
|
||||||
|
+
|
||||||
|
+ corosync_qnetd_status
|
||||||
|
+ rc="$?"
|
||||||
|
+
|
||||||
|
+ if [ "$rc" -ne "$OCF_SUCCESS" ];then
|
||||||
|
+ return "$rc"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ out=$("${OCF_RESKEY_qnetd_tool_binary}" -s -p "${OCF_RESKEY_ipc_sock}" 2>&1 >/dev/null)
|
||||||
|
+ rc="$?"
|
||||||
|
+
|
||||||
|
+ if [ "$rc" != 0 ];then
|
||||||
|
+ ocf_log "$loglevel" "$out"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ case "$rc" in
|
||||||
|
+ "0") rc="$OCF_SUCCESS" ;;
|
||||||
|
+ "3") rc="$OCF_NOT_RUNNING" ;;
|
||||||
|
+ *) rc="$OCF_ERR_GENERIC" ;;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
+ return "$rc"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+corosync_qnetd_validate_all() {
|
||||||
|
+ check_binary "${OCF_RESKEY_binary}"
|
||||||
|
+
|
||||||
|
+ check_binary "${OCF_RESKEY_qnetd_tool_binary}"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+# **************************** MAIN SCRIPT ************************************
|
||||||
|
+
|
||||||
|
+# Make sure meta-data and usage always succeed
|
||||||
|
+case "$__OCF_ACTION" in
|
||||||
|
+ meta-data)
|
||||||
|
+ corosync_qnetd_meta_data
|
||||||
|
+ exit "$OCF_SUCCESS"
|
||||||
|
+ ;;
|
||||||
|
+ usage|help)
|
||||||
|
+ corosync_qnetd_usage
|
||||||
|
+ exit "$OCF_SUCCESS"
|
||||||
|
+ ;;
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+# This OCF agent script need to be run as root user.
|
||||||
|
+if ! ocf_is_root; then
|
||||||
|
+ echo "$0 agent script need to be run as root user."
|
||||||
|
+ ocf_log debug "$0 agent script need to be run as root user."
|
||||||
|
+ exit "$OCF_ERR_GENERIC"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+# Translate each action into the appropriate function call
|
||||||
|
+case "$__OCF_ACTION" in
|
||||||
|
+ start)
|
||||||
|
+ corosync_qnetd_start
|
||||||
|
+ ;;
|
||||||
|
+ stop)
|
||||||
|
+ corosync_qnetd_stop
|
||||||
|
+ ;;
|
||||||
|
+ status)
|
||||||
|
+ corosync_qnetd_status
|
||||||
|
+ ;;
|
||||||
|
+ monitor)
|
||||||
|
+ corosync_qnetd_monitor
|
||||||
|
+ ;;
|
||||||
|
+ validate-all)
|
||||||
|
+ corosync_qnetd_validate_all
|
||||||
|
+ ;;
|
||||||
|
+ *)
|
||||||
|
+ corosync_qnetd_usage
|
||||||
|
+ exit "$OCF_ERR_UNIMPLEMENTED"
|
||||||
|
+ ;;
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+rc="$?"
|
||||||
|
+exit "$rc"
|
||||||
|
+# End of this script
|
@ -0,0 +1,44 @@
|
|||||||
|
From 26de0ad2f0f975166fe79ef72ab08e2c03519eea Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 28 Mar 2022 13:25:35 +0200
|
||||||
|
Subject: [PATCH] Filesystem: fix logic for UUID/label devices with space
|
||||||
|
between parameter and UUID/label
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/Filesystem | 14 ++++++++++----
|
||||||
|
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem
|
||||||
|
index 1a90d6a42..72a1b8623 100755
|
||||||
|
--- a/heartbeat/Filesystem
|
||||||
|
+++ b/heartbeat/Filesystem
|
||||||
|
@@ -596,11 +596,11 @@ Filesystem_start()
|
||||||
|
flushbufs "$DEVICE"
|
||||||
|
# Mount the filesystem.
|
||||||
|
case "$FSTYPE" in
|
||||||
|
- none) $MOUNT $options "$DEVICE" "$MOUNTPOINT" &&
|
||||||
|
+ none) $MOUNT $options $device_opt "$DEVICE" "$MOUNTPOINT" &&
|
||||||
|
bind_mount
|
||||||
|
;;
|
||||||
|
- "") $MOUNT $options "$DEVICE" "$MOUNTPOINT" ;;
|
||||||
|
- *) $MOUNT -t "$FSTYPE" $options "$DEVICE" "$MOUNTPOINT" ;;
|
||||||
|
+ "") $MOUNT $options $device_opt "$DEVICE" "$MOUNTPOINT" ;;
|
||||||
|
+ *) $MOUNT -t "$FSTYPE" $options $device_opt "$DEVICE" "$MOUNTPOINT" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
@@ -902,7 +902,13 @@ set_blockdevice_var() {
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$DEVICE" in
|
||||||
|
- -*) # Oh... An option to mount instead... Typically -U or -L
|
||||||
|
+ --*) # Typically --uuid or --label
|
||||||
|
+ device_opt=$(echo $DEVICE | sed -E "s/([[:blank:]]|=).*//")
|
||||||
|
+ DEVICE=$(echo $DEVICE | sed -E "s/$device_opt([[:blank:]]*|=)//")
|
||||||
|
+ ;;
|
||||||
|
+ -*) # Oh... An option to mount instead... Typically -U or -L
|
||||||
|
+ device_opt=$(echo $DEVICE | cut -c1-2)
|
||||||
|
+ DEVICE=$(echo $DEVICE | sed "s/$device_opt[[:blank:]]*//")
|
||||||
|
;;
|
||||||
|
/dev/null) # Special case for BSC
|
||||||
|
blockdevice=yes
|
@ -0,0 +1,38 @@
|
|||||||
|
From d9b46474fc19d9c57e2cfb752d60319017da8410 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Wed, 6 Apr 2022 14:14:19 +0200
|
||||||
|
Subject: [PATCH] Filesystem: improve logic for UUID/label and add note that
|
||||||
|
/dev/disk/by-{uuid,label}/ are preferred on Linux
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/Filesystem | 8 +++++---
|
||||||
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem
|
||||||
|
index 72a1b8623..44270ad98 100755
|
||||||
|
--- a/heartbeat/Filesystem
|
||||||
|
+++ b/heartbeat/Filesystem
|
||||||
|
@@ -163,6 +163,8 @@ directory where the status file is to be placed.
|
||||||
|
<parameter name="device" required="1">
|
||||||
|
<longdesc lang="en">
|
||||||
|
The name of block device for the filesystem, or -U, -L options for mount, or NFS mount specification.
|
||||||
|
+
|
||||||
|
+NOTE: On Linux /dev/disk/by-{uuid,label}/ are preferred to -U/-L.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">block device</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_device_default}" />
|
||||||
|
@@ -902,11 +904,11 @@ set_blockdevice_var() {
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$DEVICE" in
|
||||||
|
- --*) # Typically --uuid or --label
|
||||||
|
- device_opt=$(echo $DEVICE | sed -E "s/([[:blank:]]|=).*//")
|
||||||
|
+ --uuid=*|--uuid\ *|--label=*|--label\ *)
|
||||||
|
+ device_opt=$(echo $DEVICE | sed "s/\([[:blank:]]\|=\).*//")
|
||||||
|
DEVICE=$(echo $DEVICE | sed -E "s/$device_opt([[:blank:]]*|=)//")
|
||||||
|
;;
|
||||||
|
- -*) # Oh... An option to mount instead... Typically -U or -L
|
||||||
|
+ -U*|-L*) # short versions of --uuid/--label
|
||||||
|
device_opt=$(echo $DEVICE | cut -c1-2)
|
||||||
|
DEVICE=$(echo $DEVICE | sed "s/$device_opt[[:blank:]]*//")
|
||||||
|
;;
|
@ -0,0 +1,55 @@
|
|||||||
|
From bb5cfa172ca58cd8adcedcaca92bde54d0645661 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Thu, 14 Jul 2022 10:55:19 +0200
|
||||||
|
Subject: [PATCH] openstack-agents: set domain parameter's default to Default
|
||||||
|
and fix missing parameter name in ocf_exit_reason
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/openstack-common.sh | 10 +++++++---
|
||||||
|
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/openstack-common.sh b/heartbeat/openstack-common.sh
|
||||||
|
index b6eec09c..14d290bd 100644
|
||||||
|
--- a/heartbeat/openstack-common.sh
|
||||||
|
+++ b/heartbeat/openstack-common.sh
|
||||||
|
@@ -1,6 +1,10 @@
|
||||||
|
+OCF_RESKEY_user_domain_name_default="Default"
|
||||||
|
+OCF_RESKEY_project_domain_name_default="Default"
|
||||||
|
OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
|
||||||
|
OCF_RESKEY_insecure_default="false"
|
||||||
|
|
||||||
|
+: ${OCF_RESKEY_user_domain_name=${OCF_RESKEY_user_domain_name_default}}
|
||||||
|
+: ${OCF_RESKEY_project_domain_name=${OCF_RESKEY_project_domain_name_default}}
|
||||||
|
: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
|
||||||
|
: ${OCF_RESKEY_insecure=${OCF_RESKEY_insecure_default}}
|
||||||
|
|
||||||
|
@@ -64,7 +68,7 @@ Keystone Project.
|
||||||
|
Keystone User Domain Name.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">Keystone User Domain Name</shortdesc>
|
||||||
|
-<content type="string" />
|
||||||
|
+<content type="string" default="${OCF_RESKEY_user_domain_name_default}" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="project_domain_name" required="0">
|
||||||
|
@@ -72,7 +76,7 @@ Keystone User Domain Name.
|
||||||
|
Keystone Project Domain Name.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">Keystone Project Domain Name</shortdesc>
|
||||||
|
-<content type="string" />
|
||||||
|
+<content type="string" default="${OCF_RESKEY_project_domain_name_default}" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="openstackcli">
|
||||||
|
@@ -133,7 +137,7 @@ get_config() {
|
||||||
|
exit $OCF_ERR_CONFIGURED
|
||||||
|
fi
|
||||||
|
if [ -z "$OCF_RESKEY_project_domain_name" ]; then
|
||||||
|
- ocf_exit_reason " not set"
|
||||||
|
+ ocf_exit_reason "project_domain_name not set"
|
||||||
|
exit $OCF_ERR_CONFIGURED
|
||||||
|
fi
|
||||||
|
|
||||||
|
--
|
||||||
|
2.36.1
|
||||||
|
|
@ -0,0 +1,282 @@
|
|||||||
|
From ebea4c3620261c529cad908c0e52064df84b0c61 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Mon, 11 Jul 2022 10:28:11 +0200
|
||||||
|
Subject: [PATCH] openstack-agents: warn when openstackcli is slow
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/openstack-cinder-volume | 19 +++++++++++--------
|
||||||
|
heartbeat/openstack-common.sh | 22 ++++++++++++++++++++++
|
||||||
|
heartbeat/openstack-floating-ip | 17 ++++++++++-------
|
||||||
|
heartbeat/openstack-info.in | 20 ++++++++++----------
|
||||||
|
heartbeat/openstack-virtual-ip | 20 ++++++++++----------
|
||||||
|
5 files changed, 63 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/openstack-cinder-volume b/heartbeat/openstack-cinder-volume
|
||||||
|
index 19bf04faf..116442c41 100755
|
||||||
|
--- a/heartbeat/openstack-cinder-volume
|
||||||
|
+++ b/heartbeat/openstack-cinder-volume
|
||||||
|
@@ -113,11 +113,14 @@ _get_node_id() {
|
||||||
|
}
|
||||||
|
|
||||||
|
osvol_validate() {
|
||||||
|
+ local result
|
||||||
|
+
|
||||||
|
check_binary "$OCF_RESKEY_openstackcli"
|
||||||
|
|
||||||
|
get_config
|
||||||
|
|
||||||
|
- if ! $OCF_RESKEY_openstackcli volume list|grep -q $OCF_RESKEY_volume_id ; then
|
||||||
|
+ result=$(run_openstackcli "volume list")
|
||||||
|
+ if ! echo "$result" | grep -q $OCF_RESKEY_volume_id; then
|
||||||
|
ocf_exit_reason "volume-id $OCF_RESKEY_volume_id not found"
|
||||||
|
return $OCF_ERR_CONFIGURED
|
||||||
|
fi
|
||||||
|
@@ -156,17 +159,17 @@ osvol_monitor() {
|
||||||
|
# Is the volue attached?
|
||||||
|
# We use the API
|
||||||
|
#
|
||||||
|
- result=$($OCF_RESKEY_openstackcli volume show \
|
||||||
|
+ result=$(run_openstackcli "volume show \
|
||||||
|
--column status \
|
||||||
|
--column attachments \
|
||||||
|
--format value \
|
||||||
|
- $OCF_RESKEY_volume_id)
|
||||||
|
+ $OCF_RESKEY_volume_id")
|
||||||
|
|
||||||
|
- if echo "$result" | grep -q available ; then
|
||||||
|
+ if echo "$result" | grep -q available; then
|
||||||
|
ocf_log warn "$OCF_RESKEY_volume_id is not attached to any instance"
|
||||||
|
return $OCF_NOT_RUNNING
|
||||||
|
else
|
||||||
|
- export attached_server_id=$(echo $result|head -n1|
|
||||||
|
+ export attached_server_id=$(echo "$result"|head -n1|
|
||||||
|
grep -P -o "'server_id': '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}'"|
|
||||||
|
grep -P -o "[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}")
|
||||||
|
ocf_log info "$OCF_RESKEY_volume_id is attached to instance $attached_server_id"
|
||||||
|
@@ -199,7 +202,7 @@ osvol_stop() {
|
||||||
|
#
|
||||||
|
# Detach the volume
|
||||||
|
#
|
||||||
|
- if ! $OCF_RESKEY_openstackcli server remove volume $node_id $OCF_RESKEY_volume_id ; then
|
||||||
|
+ if ! run_openstackcli "server remove volume $node_id $OCF_RESKEY_volume_id"; then
|
||||||
|
ocf_log error "Couldn't remove volume $OCF_RESKEY_volume_id from instance $node_id"
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
@@ -225,7 +228,7 @@ osvol_start() {
|
||||||
|
# TODO: make it optional in case multi-attachment is allowed by Cinder
|
||||||
|
#
|
||||||
|
if [ ! -z $attached_server_id ] ; then
|
||||||
|
- if ! $OCF_RESKEY_openstackcli server remove volume $attached_server_id $OCF_RESKEY_volume_id ; then
|
||||||
|
+ if ! run_openstackcli "server remove volume $attached_server_id $OCF_RESKEY_volume_id"; then
|
||||||
|
ocf_log error "Couldn't remove volume $OCF_RESKEY_volume_id from instance $attached_server_id"
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
@@ -238,7 +241,7 @@ osvol_start() {
|
||||||
|
#
|
||||||
|
# Attach the volume
|
||||||
|
#
|
||||||
|
- $OCF_RESKEY_openstackcli server add volume $node_id $OCF_RESKEY_volume_id
|
||||||
|
+ run_openstackcli "server add volume $node_id $OCF_RESKEY_volume_id"
|
||||||
|
if [ $? != $OCF_SUCCESS ]; then
|
||||||
|
ocf_log error "Couldn't add volume $OCF_RESKEY_volume_id to instance $node_id"
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
diff --git a/heartbeat/openstack-common.sh b/heartbeat/openstack-common.sh
|
||||||
|
index 4763c90db..b6eec09c2 100644
|
||||||
|
--- a/heartbeat/openstack-common.sh
|
||||||
|
+++ b/heartbeat/openstack-common.sh
|
||||||
|
@@ -145,3 +145,25 @@ get_config() {
|
||||||
|
OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-project-domain-name $OCF_RESKEY_project_domain_name"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+run_openstackcli() {
|
||||||
|
+ local cmd="${OCF_RESKEY_openstackcli} $1"
|
||||||
|
+ local result
|
||||||
|
+ local rc
|
||||||
|
+ local start_time=$(date +%s)
|
||||||
|
+ local end_time
|
||||||
|
+ local elapsed_time
|
||||||
|
+
|
||||||
|
+ result=$($cmd)
|
||||||
|
+ rc=$?
|
||||||
|
+ end_time=$(date +%s)
|
||||||
|
+ elapsed_time=$(expr $end_time - $start_time)
|
||||||
|
+
|
||||||
|
+ if [ $elapsed_time -gt 20 ]; then
|
||||||
|
+ ocf_log warn "$cmd took ${elapsed_time}s to complete"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ echo "$result"
|
||||||
|
+
|
||||||
|
+ return $rc
|
||||||
|
+}
|
||||||
|
diff --git a/heartbeat/openstack-floating-ip b/heartbeat/openstack-floating-ip
|
||||||
|
index 6e2895654..7317f19a8 100755
|
||||||
|
--- a/heartbeat/openstack-floating-ip
|
||||||
|
+++ b/heartbeat/openstack-floating-ip
|
||||||
|
@@ -101,11 +101,14 @@ END
|
||||||
|
}
|
||||||
|
|
||||||
|
osflip_validate() {
|
||||||
|
+ local result
|
||||||
|
+
|
||||||
|
check_binary "$OCF_RESKEY_openstackcli"
|
||||||
|
|
||||||
|
get_config
|
||||||
|
|
||||||
|
- if ! $OCF_RESKEY_openstackcli floating ip list|grep -q $OCF_RESKEY_ip_id ; then
|
||||||
|
+ result=$(run_openstackcli "floating ip list")
|
||||||
|
+ if ! echo "$result" | grep -q $OCF_RESKEY_ip_id; then
|
||||||
|
ocf_exit_reason "ip-id $OCF_RESKEY_ip_id not found"
|
||||||
|
return $OCF_ERR_CONFIGURED
|
||||||
|
fi
|
||||||
|
@@ -132,14 +135,14 @@ osflip_monitor() {
|
||||||
|
| awk '{gsub("[^ ]*:", "");print}')
|
||||||
|
|
||||||
|
# Is the IP active and attached?
|
||||||
|
- result=$($OCF_RESKEY_openstackcli floating ip show \
|
||||||
|
+ result=$(run_openstackcli "floating ip show \
|
||||||
|
--column port_id --column floating_ip_address \
|
||||||
|
--format yaml \
|
||||||
|
- $OCF_RESKEY_ip_id)
|
||||||
|
+ $OCF_RESKEY_ip_id")
|
||||||
|
|
||||||
|
for port in $node_port_ids ; do
|
||||||
|
- if echo $result | grep -q $port ; then
|
||||||
|
- floating_ip=$(echo $result | awk '/floating_ip_address/ {print $2}')
|
||||||
|
+ if echo "$result" | grep -q $port ; then
|
||||||
|
+ floating_ip=$(echo "$result" | awk '/floating_ip_address/ {print $2}')
|
||||||
|
${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n openstack_floating_ip -v $floating_ip
|
||||||
|
|
||||||
|
return $OCF_SUCCESS
|
||||||
|
@@ -160,7 +163,7 @@ osflip_stop() {
|
||||||
|
return $OCF_SUCCESS
|
||||||
|
fi
|
||||||
|
|
||||||
|
- if ! $OCF_RESKEY_openstackcli floating ip unset --port $OCF_RESKEY_ip_id ; then
|
||||||
|
+ if ! run_openstackcli "floating ip unset --port $OCF_RESKEY_ip_id"; then
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
|
||||||
|
@@ -194,7 +197,7 @@ osflip_start() {
|
||||||
|
|
||||||
|
ocf_log info "Moving IP address $OCF_RESKEY_ip_id to port ID $node_port_id"
|
||||||
|
|
||||||
|
- $OCF_RESKEY_openstackcli floating ip set --port $node_port_id $OCF_RESKEY_ip_id
|
||||||
|
+ run_openstackcli "floating ip set --port $node_port_id $OCF_RESKEY_ip_id"
|
||||||
|
if [ $? != $OCF_SUCCESS ]; then
|
||||||
|
ocf_log error "$OCF_RESKEY_ip_id Cannot be set to port $node_port_id"
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
diff --git a/heartbeat/openstack-info.in b/heartbeat/openstack-info.in
|
||||||
|
index f3a59fc7a..6502f1df1 100755
|
||||||
|
--- a/heartbeat/openstack-info.in
|
||||||
|
+++ b/heartbeat/openstack-info.in
|
||||||
|
@@ -119,9 +119,7 @@ END
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
OSInfoStats() {
|
||||||
|
- local result
|
||||||
|
local value
|
||||||
|
- local node
|
||||||
|
local node_id
|
||||||
|
|
||||||
|
get_config
|
||||||
|
@@ -141,31 +139,33 @@ OSInfoStats() {
|
||||||
|
${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_id -v "$node_id"
|
||||||
|
|
||||||
|
# Nova data: flavor
|
||||||
|
- value=$($OCF_RESKEY_openstackcli server show \
|
||||||
|
+ value=$(run_openstackcli "server show \
|
||||||
|
--format value \
|
||||||
|
--column flavor \
|
||||||
|
- $node_id)
|
||||||
|
+ $node_id")
|
||||||
|
|
||||||
|
${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_flavor -v "$value"
|
||||||
|
|
||||||
|
# Nova data: availability zone
|
||||||
|
- value=$($OCF_RESKEY_openstackcli server show \
|
||||||
|
+ value=$(run_openstackcli "server show \
|
||||||
|
--format value \
|
||||||
|
--column OS-EXT-AZ:availability_zone \
|
||||||
|
- $node_id)
|
||||||
|
+ $node_id")
|
||||||
|
|
||||||
|
${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_az -v "$value"
|
||||||
|
|
||||||
|
# Network data: ports
|
||||||
|
value=""
|
||||||
|
- for port_id in $($OCF_RESKEY_openstackcli port list \
|
||||||
|
+ for port_id in $(run_openstackcli "port list \
|
||||||
|
--format value \
|
||||||
|
--column id \
|
||||||
|
- --server $node_id); do
|
||||||
|
- subnet_id=$($OCF_RESKEY_openstackcli port show \
|
||||||
|
+ --server $node_id"); do
|
||||||
|
+ subnet_result=$(run_openstackcli "port show \
|
||||||
|
--format json \
|
||||||
|
--column fixed_ips \
|
||||||
|
- ${port_id} | grep -P '\"subnet_id\": \".*\",$' |
|
||||||
|
+ ${port_id}")
|
||||||
|
+ subnet_id=$(echo "$subnet_result" |
|
||||||
|
+ grep -P '\"subnet_id\": \".*\",$' |
|
||||||
|
grep -P -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}')
|
||||||
|
value="${value}${subnet_id}:${port_id},"
|
||||||
|
done
|
||||||
|
diff --git a/heartbeat/openstack-virtual-ip b/heartbeat/openstack-virtual-ip
|
||||||
|
index c654d980a..361357d55 100755
|
||||||
|
--- a/heartbeat/openstack-virtual-ip
|
||||||
|
+++ b/heartbeat/openstack-virtual-ip
|
||||||
|
@@ -132,11 +132,11 @@ osvip_monitor() {
|
||||||
|
|
||||||
|
node_port_id=$(osvip_port_id)
|
||||||
|
|
||||||
|
- result=$($OCF_RESKEY_openstackcli port show \
|
||||||
|
+ result=$(run_openstackcli "port show \
|
||||||
|
--format value \
|
||||||
|
--column allowed_address_pairs \
|
||||||
|
- ${node_port_id})
|
||||||
|
- if echo $result | grep -q "$OCF_RESKEY_ip"; then
|
||||||
|
+ ${node_port_id}")
|
||||||
|
+ if echo "$result" | grep -q "$OCF_RESKEY_ip"; then
|
||||||
|
${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n openstack_virtual_ip -v $OCF_RESKEY_ip
|
||||||
|
|
||||||
|
return $OCF_SUCCESS
|
||||||
|
@@ -158,20 +158,20 @@ osvip_stop() {
|
||||||
|
return $OCF_SUCCESS
|
||||||
|
fi
|
||||||
|
|
||||||
|
- mac_address=$($OCF_RESKEY_openstackcli port show \
|
||||||
|
+ mac_address=$(run_openstackcli "port show \
|
||||||
|
--format value \
|
||||||
|
--column mac_address \
|
||||||
|
- $node_port_id)
|
||||||
|
- echo ${mac_address} | grep -q -P "^([0-9a-f]{2}:){5}[0-9a-f]{2}$"
|
||||||
|
+ $node_port_id")
|
||||||
|
+ echo "${mac_address}" | grep -q -P "^([0-9a-f]{2}:){5}[0-9a-f]{2}$"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
ocf_log error "MAC address '${mac_address}' is not valid."
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
|
||||||
|
- if ! $OCF_RESKEY_openstackcli port unset \
|
||||||
|
+ if ! run_openstackcli "port unset \
|
||||||
|
--allowed-address \
|
||||||
|
ip-address=$OCF_RESKEY_ip,mac-address=${mac_address} \
|
||||||
|
- $node_port_id; then
|
||||||
|
+ $node_port_id"; then
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
|
||||||
|
@@ -196,9 +196,9 @@ osvip_start() {
|
||||||
|
|
||||||
|
ocf_log info "Moving IP address $OCF_RESKEY_ip to port ID $node_port_id"
|
||||||
|
|
||||||
|
- $OCF_RESKEY_openstackcli port set \
|
||||||
|
+ run_openstackcli "port set \
|
||||||
|
--allowed-address ip-address=$OCF_RESKEY_ip \
|
||||||
|
- $node_port_id
|
||||||
|
+ $node_port_id"
|
||||||
|
if [ $? != $OCF_SUCCESS ]; then
|
||||||
|
ocf_log error "$OCF_RESKEY_ip Cannot be set to port $node_port_id"
|
||||||
|
return $OCF_ERR_GENERIC
|
@ -0,0 +1,770 @@
|
|||||||
|
diff --color -uNr a/heartbeat/Makefile.am b/heartbeat/Makefile.am
|
||||||
|
--- a/heartbeat/Makefile.am 2022-03-15 16:14:29.355209012 +0100
|
||||||
|
+++ b/heartbeat/Makefile.am 2022-03-15 16:18:35.917048467 +0100
|
||||||
|
@@ -217,6 +217,7 @@
|
||||||
|
lvm-clvm.sh \
|
||||||
|
lvm-plain.sh \
|
||||||
|
lvm-tag.sh \
|
||||||
|
+ openstack-common.sh \
|
||||||
|
ora-common.sh \
|
||||||
|
mysql-common.sh \
|
||||||
|
nfsserver-redhat.sh \
|
||||||
|
diff --color -uNr a/heartbeat/openstack-cinder-volume b/heartbeat/openstack-cinder-volume
|
||||||
|
--- a/heartbeat/openstack-cinder-volume 2022-03-15 16:14:29.370209063 +0100
|
||||||
|
+++ b/heartbeat/openstack-cinder-volume 2022-03-15 16:17:36.231840008 +0100
|
||||||
|
@@ -34,11 +34,11 @@
|
||||||
|
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
|
||||||
|
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
|
||||||
|
|
||||||
|
+. ${OCF_FUNCTIONS_DIR}/openstack-common.sh
|
||||||
|
+
|
||||||
|
# Defaults
|
||||||
|
-OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
|
||||||
|
OCF_RESKEY_volume_local_check_default="true"
|
||||||
|
|
||||||
|
-: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
|
||||||
|
: ${OCF_RESKEY_volume_local_check=${OCF_RESKEY_volume_local_check_default}}
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
@@ -68,14 +68,11 @@
|
||||||
|
<shortdesc lang="en">Attach a cinder volume</shortdesc>
|
||||||
|
|
||||||
|
<parameters>
|
||||||
|
-<parameter name="openstackcli">
|
||||||
|
-<longdesc lang="en">
|
||||||
|
-Path to command line tools for openstack.
|
||||||
|
-</longdesc>
|
||||||
|
-<shortdesc lang="en">Path to Openstack CLI tool</shortdesc>
|
||||||
|
-<content type="string" default="${OCF_RESKEY_openstackcli_default}" />
|
||||||
|
-</parameter>
|
||||||
|
+END
|
||||||
|
|
||||||
|
+common_meta_data
|
||||||
|
+
|
||||||
|
+cat <<END
|
||||||
|
<parameter name="volume_local_check">
|
||||||
|
<longdesc lang="en">
|
||||||
|
This option allows the cluster to monitor the cinder volume presence without
|
||||||
|
@@ -85,28 +82,19 @@
|
||||||
|
<content type="boolean" default="${OCF_RESKEY_volume_local_check_default}" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
-<parameter name="openrc" required="1">
|
||||||
|
-<longdesc lang="en">
|
||||||
|
-Valid Openstack credentials as openrc file from api_access/openrc.
|
||||||
|
-</longdesc>
|
||||||
|
-<shortdesc lang="en">openrc file</shortdesc>
|
||||||
|
-<content type="string" />
|
||||||
|
-</parameter>
|
||||||
|
-
|
||||||
|
<parameter name="volume_id" required="1">
|
||||||
|
<longdesc lang="en">
|
||||||
|
-Cinder volume identifier to use to attach the bloc storage.
|
||||||
|
+Cinder volume identifier to use to attach the block storage.
|
||||||
|
</longdesc>
|
||||||
|
<shortdesc lang="en">Volume ID</shortdesc>
|
||||||
|
<content type="string" />
|
||||||
|
</parameter>
|
||||||
|
-
|
||||||
|
</parameters>
|
||||||
|
|
||||||
|
<actions>
|
||||||
|
<action name="start" timeout="180s" />
|
||||||
|
<action name="stop" timeout="180s" />
|
||||||
|
-<action name="monitor" depth="0" timeout="30s" interval="60s" />
|
||||||
|
+<action name="monitor" depth="0" timeout="180s" interval="60s" />
|
||||||
|
<action name="validate-all" timeout="5s" />
|
||||||
|
<action name="meta-data" timeout="5s" />
|
||||||
|
</actions>
|
||||||
|
@@ -127,17 +115,7 @@
|
||||||
|
osvol_validate() {
|
||||||
|
check_binary "$OCF_RESKEY_openstackcli"
|
||||||
|
|
||||||
|
- if [ -z "$OCF_RESKEY_openrc" ]; then
|
||||||
|
- ocf_exit_reason "openrc parameter not set"
|
||||||
|
- return $OCF_ERR_CONFIGURED
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
- if [ ! -f "$OCF_RESKEY_openrc" ] ; then
|
||||||
|
- ocf_exit_reason "openrc file not found"
|
||||||
|
- return $OCF_ERR_CONFIGURED
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
- . $OCF_RESKEY_openrc
|
||||||
|
+ get_config
|
||||||
|
|
||||||
|
if ! $OCF_RESKEY_openstackcli volume list|grep -q $OCF_RESKEY_volume_id ; then
|
||||||
|
ocf_exit_reason "volume-id $OCF_RESKEY_volume_id not found"
|
||||||
|
diff --color -uNr a/heartbeat/openstack-common.sh b/heartbeat/openstack-common.sh
|
||||||
|
--- a/heartbeat/openstack-common.sh 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ b/heartbeat/openstack-common.sh 2022-03-15 16:17:36.232840011 +0100
|
||||||
|
@@ -0,0 +1,147 @@
|
||||||
|
+OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
|
||||||
|
+OCF_RESKEY_insecure_default="false"
|
||||||
|
+
|
||||||
|
+: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
|
||||||
|
+: ${OCF_RESKEY_insecure=${OCF_RESKEY_insecure_default}}
|
||||||
|
+
|
||||||
|
+if ocf_is_true "${OCF_RESKEY_insecure}"; then
|
||||||
|
+ OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --insecure"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+common_meta_data() {
|
||||||
|
+ cat <<END
|
||||||
|
+
|
||||||
|
+<parameter name="cloud" required="0">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Openstack cloud (from ~/.config/openstack/clouds.yaml or /etc/openstack/clouds.yaml).
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Cloud from clouds.yaml</shortdesc>
|
||||||
|
+<content type="string" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="openrc" required="0">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Openstack credentials as openrc file from api_access/openrc.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">openrc file</shortdesc>
|
||||||
|
+<content type="string" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="auth_url" required="0">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Keystone Auth URL
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Keystone Auth URL</shortdesc>
|
||||||
|
+<content type="string" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="username" required="0">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Username.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Username</shortdesc>
|
||||||
|
+<content type="string" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="password" required="0">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Password.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Password</shortdesc>
|
||||||
|
+<content type="string" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="project_name" required="0">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Keystone Project.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Keystone Project</shortdesc>
|
||||||
|
+<content type="string" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="user_domain_name" required="0">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Keystone User Domain Name.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Keystone User Domain Name</shortdesc>
|
||||||
|
+<content type="string" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="project_domain_name" required="0">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Keystone Project Domain Name.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Keystone Project Domain Name</shortdesc>
|
||||||
|
+<content type="string" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="openstackcli">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Path to command line tools for openstack.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Path to Openstack CLI tool</shortdesc>
|
||||||
|
+<content type="string" default="${OCF_RESKEY_openstackcli_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="insecure">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Allow insecure connections
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Allow insecure connections</shortdesc>
|
||||||
|
+<content type="boolean" default="${OCF_RESKEY_insecure_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+END
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+get_config() {
|
||||||
|
+ if [ -n "$OCF_RESKEY_cloud" ]; then
|
||||||
|
+ TILDE=$(echo ~)
|
||||||
|
+ clouds_yaml="$TILDE/.config/openstack/clouds.yaml"
|
||||||
|
+ if [ ! -f "$clouds_yaml" ]; then
|
||||||
|
+ clouds_yaml="/etc/openstack/clouds.yaml"
|
||||||
|
+ fi
|
||||||
|
+ if [ ! -f "$clouds_yaml" ]; then
|
||||||
|
+ ocf_exit_reason "~/.config/openstack/clouds.yaml and /etc/openstack/clouds.yaml does not exist"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+ OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-cloud $OCF_RESKEY_cloud"
|
||||||
|
+ elif [ -n "$OCF_RESKEY_openrc" ]; then
|
||||||
|
+ if [ ! -f "$OCF_RESKEY_openrc" ]; then
|
||||||
|
+ ocf_exit_reason "$OCF_RESKEY_openrc does not exist"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+ . $OCF_RESKEY_openrc
|
||||||
|
+ else
|
||||||
|
+ if [ -z "$OCF_RESKEY_auth_url" ]; then
|
||||||
|
+ ocf_exit_reason "auth_url not set"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$OCF_RESKEY_username" ]; then
|
||||||
|
+ ocf_exit_reason "username not set"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$OCF_RESKEY_password" ]; then
|
||||||
|
+ ocf_exit_reason "password not set"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$OCF_RESKEY_project_name" ]; then
|
||||||
|
+ ocf_exit_reason "project_name not set"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$OCF_RESKEY_user_domain_name" ]; then
|
||||||
|
+ ocf_exit_reason "user_domain_name not set"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$OCF_RESKEY_project_domain_name" ]; then
|
||||||
|
+ ocf_exit_reason " not set"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-auth-url $OCF_RESKEY_auth_url"
|
||||||
|
+ OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-username $OCF_RESKEY_username"
|
||||||
|
+ OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-password $OCF_RESKEY_password"
|
||||||
|
+ OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-project-name $OCF_RESKEY_project_name"
|
||||||
|
+ OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-user-domain-name $OCF_RESKEY_user_domain_name"
|
||||||
|
+ OCF_RESKEY_openstackcli="${OCF_RESKEY_openstackcli} --os-project-domain-name $OCF_RESKEY_project_domain_name"
|
||||||
|
+ fi
|
||||||
|
+}
|
||||||
|
diff --color -uNr a/heartbeat/openstack-floating-ip b/heartbeat/openstack-floating-ip
|
||||||
|
--- a/heartbeat/openstack-floating-ip 2022-03-15 16:14:29.370209063 +0100
|
||||||
|
+++ b/heartbeat/openstack-floating-ip 2022-03-15 16:17:36.233840014 +0100
|
||||||
|
@@ -34,10 +34,9 @@
|
||||||
|
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
|
||||||
|
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
|
||||||
|
|
||||||
|
-# Defaults
|
||||||
|
-OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
|
||||||
|
+. ${OCF_FUNCTIONS_DIR}/openstack-common.sh
|
||||||
|
|
||||||
|
-: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
|
||||||
|
+# Defaults
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
@@ -67,22 +66,11 @@
|
||||||
|
<shortdesc lang="en">Move a floating IP</shortdesc>
|
||||||
|
|
||||||
|
<parameters>
|
||||||
|
-<parameter name="openstackcli">
|
||||||
|
-<longdesc lang="en">
|
||||||
|
-Path to command line tools for openstack.
|
||||||
|
-</longdesc>
|
||||||
|
-<shortdesc lang="en">Path to Openstack CLI tool</shortdesc>
|
||||||
|
-<content type="string" default="${OCF_RESKEY_openstackcli_default}" />
|
||||||
|
-</parameter>
|
||||||
|
+END
|
||||||
|
|
||||||
|
-<parameter name="openrc" required="1">
|
||||||
|
-<longdesc lang="en">
|
||||||
|
-Valid Openstack credentials as openrc file from api_access/openrc.
|
||||||
|
-</longdesc>
|
||||||
|
-<shortdesc lang="en">openrc file</shortdesc>
|
||||||
|
-<content type="string" />
|
||||||
|
-</parameter>
|
||||||
|
+common_meta_data
|
||||||
|
|
||||||
|
+cat <<END
|
||||||
|
<parameter name="ip_id" required="1">
|
||||||
|
<longdesc lang="en">
|
||||||
|
Floating IP Identifier.
|
||||||
|
@@ -104,7 +92,7 @@
|
||||||
|
<actions>
|
||||||
|
<action name="start" timeout="180s" />
|
||||||
|
<action name="stop" timeout="180s" />
|
||||||
|
-<action name="monitor" depth="0" timeout="30s" interval="60s" />
|
||||||
|
+<action name="monitor" depth="0" timeout="180s" interval="60s" />
|
||||||
|
<action name="validate-all" timeout="5s" />
|
||||||
|
<action name="meta-data" timeout="5s" />
|
||||||
|
</actions>
|
||||||
|
@@ -115,17 +103,7 @@
|
||||||
|
osflip_validate() {
|
||||||
|
check_binary "$OCF_RESKEY_openstackcli"
|
||||||
|
|
||||||
|
- if [ -z "$OCF_RESKEY_openrc" ]; then
|
||||||
|
- ocf_exit_reason "openrc parameter not set"
|
||||||
|
- return $OCF_ERR_CONFIGURED
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
- if [ ! -f "$OCF_RESKEY_openrc" ] ; then
|
||||||
|
- ocf_exit_reason "openrc file not found"
|
||||||
|
- return $OCF_ERR_CONFIGURED
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
- . $OCF_RESKEY_openrc
|
||||||
|
+ get_config
|
||||||
|
|
||||||
|
if ! $OCF_RESKEY_openstackcli floating ip list|grep -q $OCF_RESKEY_ip_id ; then
|
||||||
|
ocf_exit_reason "ip-id $OCF_RESKEY_ip_id not found"
|
||||||
|
diff --color -uNr a/heartbeat/openstack-info b/heartbeat/openstack-info
|
||||||
|
--- a/heartbeat/openstack-info 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ b/heartbeat/openstack-info 2022-03-15 16:17:36.234840018 +0100
|
||||||
|
@@ -0,0 +1,270 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+#
|
||||||
|
+#
|
||||||
|
+# OCF resource agent to set attributes from Openstack instance details.
|
||||||
|
+# It records (in the CIB) various attributes of a node
|
||||||
|
+#
|
||||||
|
+# Copyright (c) 2018 Mathieu Grzybek
|
||||||
|
+# All Rights Reserved.
|
||||||
|
+#
|
||||||
|
+# This program is free software; you can redistribute it and/or modify
|
||||||
|
+# it under the terms of version 2 of the GNU General Public License as
|
||||||
|
+# published by the Free Software Foundation.
|
||||||
|
+#
|
||||||
|
+# This program is distributed in the hope that it would be useful, but
|
||||||
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
+#
|
||||||
|
+# Further, this software is distributed without any warranty that it is
|
||||||
|
+# free of the rightful claim of any third person regarding infringement
|
||||||
|
+# or the like. Any license provided herein, whether implied or
|
||||||
|
+# otherwise, applies only to this software file. Patent licenses, if
|
||||||
|
+# any, provided herein do not apply to combinations of this program with
|
||||||
|
+# other software, or any other product whatsoever.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write the Free Software Foundation,
|
||||||
|
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
+#
|
||||||
|
+#######################################################################
|
||||||
|
+# Initialization:
|
||||||
|
+
|
||||||
|
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
|
||||||
|
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
|
||||||
|
+
|
||||||
|
+. ${OCF_FUNCTIONS_DIR}/openstack-common.sh
|
||||||
|
+
|
||||||
|
+# Defaults
|
||||||
|
+OCF_RESKEY_pidfile_default="$HA_RSCTMP/OSInfo-${OCF_RESOURCE_HOSTNAME}"
|
||||||
|
+OCF_RESKEY_delay_default="0"
|
||||||
|
+OCF_RESKEY_clone_default="0"
|
||||||
|
+OCF_RESKEY_curlcli_default="/usr/bin/curl"
|
||||||
|
+OCF_RESKEY_pythoncli_default="/usr/bin/python"
|
||||||
|
+
|
||||||
|
+: ${OCF_RESKEY_curlcli=${OCF_RESKEY_curlcli_default}}
|
||||||
|
+: ${OCF_RESKEY_pythoncli=${OCF_RESKEY_pythoncli_default}}
|
||||||
|
+: ${OCF_RESKEY_pidfile=${OCF_RESKEY_pidfile_default}}
|
||||||
|
+: ${OCF_RESKEY_delay=${OCF_RESKEY_delay_default}}
|
||||||
|
+: ${OCF_RESKEY_clone=${OCF_RESKEY_clone_default}}
|
||||||
|
+
|
||||||
|
+#######################################################################
|
||||||
|
+
|
||||||
|
+meta_data() {
|
||||||
|
+ cat <<END
|
||||||
|
+<?xml version="1.0"?>
|
||||||
|
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
|
||||||
|
+<resource-agent name="openstack-info" version="1.0">
|
||||||
|
+<version>1.0</version>
|
||||||
|
+
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+OCF resource agent to set attributes from Openstack instance details.
|
||||||
|
+It records (in the CIB) various attributes of a node.
|
||||||
|
+Sample output:
|
||||||
|
+ openstack_az : nova
|
||||||
|
+ openstack_flavor : c1.small
|
||||||
|
+ openstack_id : 60ac4343-5828-49b1-8aac-7c69b1417f31
|
||||||
|
+ openstack_ports : 7960d889-9750-4160-bf41-c69a41ad72d9:96530d18-57a3-4718-af32-30f2a74c22a2,b0e55a06-bd75-468d-8baa-22cfeb65799f:a55ae917-8016-4b1e-8ffa-04311b9dc7d6
|
||||||
|
+
|
||||||
|
+The layout of openstack_ports is a comma-separated list of tuples "subnet_id:port_id".
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Records various node attributes in the CIB</shortdesc>
|
||||||
|
+
|
||||||
|
+<parameters>
|
||||||
|
+END
|
||||||
|
+
|
||||||
|
+common_meta_data
|
||||||
|
+
|
||||||
|
+ cat <<END
|
||||||
|
+<parameter name="pidfile" unique="0">
|
||||||
|
+<longdesc lang="en">PID file</longdesc>
|
||||||
|
+<shortdesc lang="en">PID file</shortdesc>
|
||||||
|
+<content type="string" default="${OCF_RESKEY_pidfile_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="delay" unique="0">
|
||||||
|
+<longdesc lang="en">Interval to allow values to stabilize</longdesc>
|
||||||
|
+<shortdesc lang="en">Dampening Delay</shortdesc>
|
||||||
|
+<content type="string" default="${OCF_RESKEY_delay_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="curlcli">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Path to command line cURL binary.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Path to cURL binary</shortdesc>
|
||||||
|
+<content type="string" default="${OCF_RESKEY_curlcli_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+<parameter name="pythoncli">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+Path to command line Python interpreter.
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Path to Python interpreter</shortdesc>
|
||||||
|
+<content type="string" default="${OCF_RESKEY_pythoncli_default}" />
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
+</parameters>
|
||||||
|
+
|
||||||
|
+<actions>
|
||||||
|
+<action name="start" timeout="180s" />
|
||||||
|
+<action name="stop" timeout="180s" />
|
||||||
|
+<action name="monitor" timeout="30s" interval="60s"/>
|
||||||
|
+<action name="meta-data" timeout="5s" />
|
||||||
|
+<action name="validate-all" timeout="20s" />
|
||||||
|
+</actions>
|
||||||
|
+</resource-agent>
|
||||||
|
+END
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#######################################################################
|
||||||
|
+
|
||||||
|
+OSInfoStats() {
|
||||||
|
+ local result
|
||||||
|
+ local value
|
||||||
|
+ local node
|
||||||
|
+ local node_id
|
||||||
|
+
|
||||||
|
+ get_config
|
||||||
|
+
|
||||||
|
+ # Nova data: server ID
|
||||||
|
+ node_id=$($OCF_RESKEY_curlcli \
|
||||||
|
+ -s http://169.254.169.254/openstack/latest/meta_data.json |
|
||||||
|
+ $OCF_RESKEY_pythoncli -m json.tool |
|
||||||
|
+ grep -P '\"uuid\": \".*\",$' |
|
||||||
|
+ grep -P -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}')
|
||||||
|
+
|
||||||
|
+ if [ $? -ne 0 ] ; then
|
||||||
|
+ ocf_exit_reason "Cannot find server ID"
|
||||||
|
+ exit $OCF_ERR_GENERIC
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_id -v "$node_id"
|
||||||
|
+
|
||||||
|
+ # Nova data: flavor
|
||||||
|
+ value=$($OCF_RESKEY_openstackcli server show \
|
||||||
|
+ --format value \
|
||||||
|
+ --column flavor \
|
||||||
|
+ $node_id)
|
||||||
|
+
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_flavor -v "$value"
|
||||||
|
+
|
||||||
|
+ # Nova data: availability zone
|
||||||
|
+ value=$($OCF_RESKEY_openstackcli server show \
|
||||||
|
+ --format value \
|
||||||
|
+ --column OS-EXT-AZ:availability_zone \
|
||||||
|
+ $node_id)
|
||||||
|
+
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_az -v "$value"
|
||||||
|
+
|
||||||
|
+ # Network data: ports
|
||||||
|
+ value=""
|
||||||
|
+ for port_id in $($OCF_RESKEY_openstackcli port list \
|
||||||
|
+ --format value \
|
||||||
|
+ --column id \
|
||||||
|
+ --server $node_id); do
|
||||||
|
+ subnet_id=$($OCF_RESKEY_openstackcli port show \
|
||||||
|
+ --format json \
|
||||||
|
+ --column fixed_ips \
|
||||||
|
+ ${port_id} | grep -P '\"subnet_id\": \".*\",$' |
|
||||||
|
+ grep -P -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}')
|
||||||
|
+ value+="${subnet_id}:${port_id},"
|
||||||
|
+ done
|
||||||
|
+ value=$(echo ${value} | sed -e 's/,$//g')
|
||||||
|
+
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_ports -v "$value"
|
||||||
|
+
|
||||||
|
+ if [ ! -z "$OS_REGION_NAME" ] ; then
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_region -v "$OS_REGION_NAME"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ if [ ! -z "$OS_TENANT_ID" ] ; then
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_tenant_id -v "$OS_TENANT_ID"
|
||||||
|
+
|
||||||
|
+ if [ ! -z "$OS_TENANT_NAME" ] ; then
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_tenant_name -v "$OS_TENANT_NAME"
|
||||||
|
+ fi
|
||||||
|
+ else
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_project_id -v "$OS_PROJECT_ID"
|
||||||
|
+
|
||||||
|
+ if [ ! -z "$OS_PROJECT_NAME" ] ; then
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_project_name -v "$OS_PROJECT_NAME"
|
||||||
|
+ fi
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+OSInfo_usage() {
|
||||||
|
+ cat <<END
|
||||||
|
+usage: $0 {start|stop|monitor|validate-all|meta-data}
|
||||||
|
+
|
||||||
|
+Expects to have a fully populated OCF RA-compliant environment set.
|
||||||
|
+END
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+OSInfo_start() {
|
||||||
|
+ echo $OCF_RESKEY_clone > $OCF_RESKEY_pidfile
|
||||||
|
+ OSInfoStats
|
||||||
|
+ exit $OCF_SUCCESS
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+OSInfo_stop() {
|
||||||
|
+ rm -f $OCF_RESKEY_pidfile
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_id
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_flavor
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_az
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_ports
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_region
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_tenant_id
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_tenant_name
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_project_id
|
||||||
|
+ ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -D -n openstack_project_name
|
||||||
|
+ exit $OCF_SUCCESS
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+OSInfo_monitor() {
|
||||||
|
+ if [ -f "$OCF_RESKEY_pidfile" ] ; then
|
||||||
|
+ OSInfoStats
|
||||||
|
+ exit $OCF_RUNNING
|
||||||
|
+ fi
|
||||||
|
+ exit $OCF_NOT_RUNNING
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+OSInfo_validate() {
|
||||||
|
+ check_binary "$OCF_RESKEY_curlcli"
|
||||||
|
+ check_binary "$OCF_RESKEY_openstackcli"
|
||||||
|
+ check_binary "$OCF_RESKEY_pythoncli"
|
||||||
|
+
|
||||||
|
+ return $OCF_SUCCESS
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+if [ $# -ne 1 ]; then
|
||||||
|
+ OSInfo_usage
|
||||||
|
+ exit $OCF_ERR_ARGS
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ x != x${OCF_RESKEY_delay} ]; then
|
||||||
|
+ OCF_RESKEY_delay="-d ${OCF_RESKEY_delay}"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+case $__OCF_ACTION in
|
||||||
|
+meta-data) meta_data
|
||||||
|
+ exit $OCF_SUCCESS
|
||||||
|
+ ;;
|
||||||
|
+start) OSInfo_validate || exit $?
|
||||||
|
+ OSInfo_start
|
||||||
|
+ ;;
|
||||||
|
+stop) OSInfo_stop
|
||||||
|
+ ;;
|
||||||
|
+monitor) OSInfo_monitor
|
||||||
|
+ ;;
|
||||||
|
+validate-all) OSInfo_validate
|
||||||
|
+ ;;
|
||||||
|
+usage|help) OSInfo_usage
|
||||||
|
+ exit $OCF_SUCCESS
|
||||||
|
+ ;;
|
||||||
|
+*) OSInfo_usage
|
||||||
|
+ exit $OCF_ERR_UNIMPLEMENTED
|
||||||
|
+ ;;
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+exit $?
|
||||||
|
diff --color -uNr a/heartbeat/openstack-info.in b/heartbeat/openstack-info.in
|
||||||
|
--- a/heartbeat/openstack-info.in 2022-03-15 16:14:29.370209063 +0100
|
||||||
|
+++ b/heartbeat/openstack-info.in 2022-03-15 16:17:36.234840018 +0100
|
||||||
|
@@ -32,16 +32,16 @@
|
||||||
|
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
|
||||||
|
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
|
||||||
|
|
||||||
|
+. ${OCF_FUNCTIONS_DIR}/openstack-common.sh
|
||||||
|
+
|
||||||
|
# Defaults
|
||||||
|
OCF_RESKEY_pidfile_default="$HA_RSCTMP/OSInfo-${OCF_RESOURCE_HOSTNAME}"
|
||||||
|
OCF_RESKEY_delay_default="0"
|
||||||
|
OCF_RESKEY_clone_default="0"
|
||||||
|
OCF_RESKEY_curlcli_default="/usr/bin/curl"
|
||||||
|
-OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
|
||||||
|
OCF_RESKEY_pythoncli_default="@PYTHON@"
|
||||||
|
|
||||||
|
: ${OCF_RESKEY_curlcli=${OCF_RESKEY_curlcli_default}}
|
||||||
|
-: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
|
||||||
|
: ${OCF_RESKEY_pythoncli=${OCF_RESKEY_pythoncli_default}}
|
||||||
|
: ${OCF_RESKEY_pidfile=${OCF_RESKEY_pidfile_default}}
|
||||||
|
: ${OCF_RESKEY_delay=${OCF_RESKEY_delay_default}}
|
||||||
|
@@ -70,25 +70,23 @@
|
||||||
|
<shortdesc lang="en">Records various node attributes in the CIB</shortdesc>
|
||||||
|
|
||||||
|
<parameters>
|
||||||
|
+END
|
||||||
|
+
|
||||||
|
+common_meta_data
|
||||||
|
+
|
||||||
|
+ cat <<END
|
||||||
|
<parameter name="pidfile" unique="0">
|
||||||
|
<longdesc lang="en">PID file</longdesc>
|
||||||
|
<shortdesc lang="en">PID file</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_pidfile_default}" />
|
||||||
|
</parameter>
|
||||||
|
+
|
||||||
|
<parameter name="delay" unique="0">
|
||||||
|
<longdesc lang="en">Interval to allow values to stabilize</longdesc>
|
||||||
|
<shortdesc lang="en">Dampening Delay</shortdesc>
|
||||||
|
<content type="string" default="${OCF_RESKEY_delay_default}" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
-<parameter name="openrc" required="1">
|
||||||
|
-<longdesc lang="en">
|
||||||
|
-Valid Openstack credentials as openrc file from api_access/openrc.
|
||||||
|
-</longdesc>
|
||||||
|
-<shortdesc lang="en">openrc file</shortdesc>
|
||||||
|
-<content type="string" />
|
||||||
|
-</parameter>
|
||||||
|
-
|
||||||
|
<parameter name="curlcli">
|
||||||
|
<longdesc lang="en">
|
||||||
|
Path to command line cURL binary.
|
||||||
|
@@ -97,14 +95,6 @@
|
||||||
|
<content type="string" default="${OCF_RESKEY_curlcli_default}" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
-<parameter name="openstackcli">
|
||||||
|
-<longdesc lang="en">
|
||||||
|
-Path to command line tools for openstack.
|
||||||
|
-</longdesc>
|
||||||
|
-<shortdesc lang="en">Path to Openstack CLI tool</shortdesc>
|
||||||
|
-<content type="string" default="${OCF_RESKEY_openstackcli_default}" />
|
||||||
|
-</parameter>
|
||||||
|
-
|
||||||
|
<parameter name="pythoncli">
|
||||||
|
<longdesc lang="en">
|
||||||
|
Path to command line Python interpreter.
|
||||||
|
@@ -116,9 +106,9 @@
|
||||||
|
</parameters>
|
||||||
|
|
||||||
|
<actions>
|
||||||
|
-<action name="start" timeout="20s" />
|
||||||
|
-<action name="stop" timeout="20s" />
|
||||||
|
-<action name="monitor" timeout="20s" interval="60s"/>
|
||||||
|
+<action name="start" timeout="180s" />
|
||||||
|
+<action name="stop" timeout="180s" />
|
||||||
|
+<action name="monitor" timeout="180s" interval="60s"/>
|
||||||
|
<action name="meta-data" timeout="5s" />
|
||||||
|
<action name="validate-all" timeout="20s" />
|
||||||
|
</actions>
|
||||||
|
@@ -134,7 +124,7 @@
|
||||||
|
local node
|
||||||
|
local node_id
|
||||||
|
|
||||||
|
- . $OCF_RESKEY_openrc
|
||||||
|
+ get_config
|
||||||
|
|
||||||
|
# Nova data: server ID
|
||||||
|
node_id=$($OCF_RESKEY_curlcli \
|
||||||
|
@@ -244,16 +234,6 @@
|
||||||
|
check_binary "$OCF_RESKEY_openstackcli"
|
||||||
|
check_binary "$OCF_RESKEY_pythoncli"
|
||||||
|
|
||||||
|
- if [ -z "$OCF_RESKEY_openrc" ]; then
|
||||||
|
- ocf_exit_reason "openrc parameter not set"
|
||||||
|
- return $OCF_ERR_CONFIGURED
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
- if [ ! -f "$OCF_RESKEY_openrc" ] ; then
|
||||||
|
- ocf_exit_reason "openrc file not found"
|
||||||
|
- return $OCF_ERR_CONFIGURED
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
return $OCF_SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --color -uNr a/heartbeat/openstack-virtual-ip b/heartbeat/openstack-virtual-ip
|
||||||
|
--- a/heartbeat/openstack-virtual-ip 2022-03-15 16:14:29.370209063 +0100
|
||||||
|
+++ b/heartbeat/openstack-virtual-ip 2022-03-15 16:17:36.235840021 +0100
|
||||||
|
@@ -34,10 +34,9 @@
|
||||||
|
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
|
||||||
|
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
|
||||||
|
|
||||||
|
-# Defaults
|
||||||
|
-OCF_RESKEY_openstackcli_default="/usr/bin/openstack"
|
||||||
|
+. ${OCF_FUNCTIONS_DIR}/openstack-common.sh
|
||||||
|
|
||||||
|
-: ${OCF_RESKEY_openstackcli=${OCF_RESKEY_openstackcli_default}}
|
||||||
|
+# Defaults
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
@@ -68,22 +67,11 @@
|
||||||
|
<shortdesc lang="en">Move a virtual IP</shortdesc>
|
||||||
|
|
||||||
|
<parameters>
|
||||||
|
-<parameter name="openstackcli">
|
||||||
|
-<longdesc lang="en">
|
||||||
|
-Path to command line tools for openstack.
|
||||||
|
-</longdesc>
|
||||||
|
-<shortdesc lang="en">Path to Openstack CLI tool</shortdesc>
|
||||||
|
-<content type="string" default="${OCF_RESKEY_openstackcli_default}" />
|
||||||
|
-</parameter>
|
||||||
|
+END
|
||||||
|
|
||||||
|
-<parameter name="openrc" required="1">
|
||||||
|
-<longdesc lang="en">
|
||||||
|
-Valid Openstack credentials as openrc file from api_access/openrc.
|
||||||
|
-</longdesc>
|
||||||
|
-<shortdesc lang="en">openrc file</shortdesc>
|
||||||
|
-<content type="string" />
|
||||||
|
-</parameter>
|
||||||
|
+common_meta_data
|
||||||
|
|
||||||
|
+cat <<END
|
||||||
|
<parameter name="ip" required="1">
|
||||||
|
<longdesc lang="en">
|
||||||
|
Virtual IP Address.
|
||||||
|
@@ -105,7 +93,7 @@
|
||||||
|
<actions>
|
||||||
|
<action name="start" timeout="180s" />
|
||||||
|
<action name="stop" timeout="180s" />
|
||||||
|
-<action name="monitor" depth="0" timeout="30s" interval="60s" />
|
||||||
|
+<action name="monitor" depth="0" timeout="180s" interval="60s" />
|
||||||
|
<action name="validate-all" timeout="5s" />
|
||||||
|
<action name="meta-data" timeout="5s" />
|
||||||
|
</actions>
|
||||||
|
@@ -128,17 +116,7 @@
|
||||||
|
osvip_validate() {
|
||||||
|
check_binary "$OCF_RESKEY_openstackcli"
|
||||||
|
|
||||||
|
- if [ -z "$OCF_RESKEY_openrc" ]; then
|
||||||
|
- ocf_exit_reason "openrc parameter not set"
|
||||||
|
- return $OCF_ERR_CONFIGURED
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
- if [ ! -f "$OCF_RESKEY_openrc" ] ; then
|
||||||
|
- ocf_exit_reason "openrc file not found"
|
||||||
|
- return $OCF_ERR_CONFIGURED
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
- . $OCF_RESKEY_openrc
|
||||||
|
+ get_config
|
||||||
|
|
||||||
|
${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $(crm_node -n) > /dev/null 2>&1
|
||||||
|
if [ $? -ne 0 ] ; then
|
@ -0,0 +1,72 @@
|
|||||||
|
From 64f434014bc198055478a139532c7cc133967c5d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Fri, 8 Jul 2022 15:41:34 +0200
|
||||||
|
Subject: [PATCH] openstack-agents: fixes
|
||||||
|
|
||||||
|
- openstack-cinder-volume: dont do volume_local_check during start/stop-action
|
||||||
|
- openstack-floating-ip/openstack-virtual-ip: dont fail in validate()
|
||||||
|
during probe-calls
|
||||||
|
- openstack-floating-ip: fix awk only catching last id for node_port_ids
|
||||||
|
---
|
||||||
|
heartbeat/openstack-cinder-volume | 2 +-
|
||||||
|
heartbeat/openstack-floating-ip | 4 ++--
|
||||||
|
heartbeat/openstack-virtual-ip | 4 ++--
|
||||||
|
3 files changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/openstack-cinder-volume b/heartbeat/openstack-cinder-volume
|
||||||
|
index cc12e58ae..19bf04faf 100755
|
||||||
|
--- a/heartbeat/openstack-cinder-volume
|
||||||
|
+++ b/heartbeat/openstack-cinder-volume
|
||||||
|
@@ -138,7 +138,7 @@ osvol_monitor() {
|
||||||
|
|
||||||
|
node_id=$(_get_node_id)
|
||||||
|
|
||||||
|
- if ocf_is_true $OCF_RESKEY_volume_local_check ; then
|
||||||
|
+ if [ "$__OCF_ACTION" = "monitor" ] && ocf_is_true $OCF_RESKEY_volume_local_check ; then
|
||||||
|
#
|
||||||
|
# Is the volue attached?
|
||||||
|
# We check the local devices
|
||||||
|
diff --git a/heartbeat/openstack-floating-ip b/heartbeat/openstack-floating-ip
|
||||||
|
index 8c135cc24..6e2895654 100755
|
||||||
|
--- a/heartbeat/openstack-floating-ip
|
||||||
|
+++ b/heartbeat/openstack-floating-ip
|
||||||
|
@@ -111,7 +111,7 @@ osflip_validate() {
|
||||||
|
fi
|
||||||
|
|
||||||
|
${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $(crm_node -n) > /dev/null 2>&1
|
||||||
|
- if [ $? -ne 0 ] ; then
|
||||||
|
+ if [ $? -ne 0 ] && ! ocf_is_probe; then
|
||||||
|
ocf_log warn "attr_updater failed to get openstack_ports attribute of node $OCF_RESOURCE_INSTANCE"
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
@@ -129,7 +129,7 @@ osflip_monitor() {
|
||||||
|
node_port_ids=$(${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $(crm_node -n) \
|
||||||
|
| awk -F= '{gsub("\"","");print $NF}' \
|
||||||
|
| tr ',' ' ' \
|
||||||
|
- | awk -F: '{print $NF}')
|
||||||
|
+ | awk '{gsub("[^ ]*:", "");print}')
|
||||||
|
|
||||||
|
# Is the IP active and attached?
|
||||||
|
result=$($OCF_RESKEY_openstackcli floating ip show \
|
||||||
|
diff --git a/heartbeat/openstack-virtual-ip b/heartbeat/openstack-virtual-ip
|
||||||
|
index a1084c420..c654d980a 100755
|
||||||
|
--- a/heartbeat/openstack-virtual-ip
|
||||||
|
+++ b/heartbeat/openstack-virtual-ip
|
||||||
|
@@ -119,7 +119,7 @@ osvip_validate() {
|
||||||
|
get_config
|
||||||
|
|
||||||
|
${HA_SBIN_DIR}/attrd_updater --query -n openstack_ports -N $(crm_node -n) > /dev/null 2>&1
|
||||||
|
- if [ $? -ne 0 ] ; then
|
||||||
|
+ if [ $? -ne 0 ] && ! ocf_is_probe; then
|
||||||
|
ocf_log warn "attr_updater failed to get openstack_ports attribute of node $OCF_RESOURCE_INSTANCE"
|
||||||
|
return $OCF_ERR_GENERIC
|
||||||
|
fi
|
||||||
|
@@ -136,7 +136,7 @@ osvip_monitor() {
|
||||||
|
--format value \
|
||||||
|
--column allowed_address_pairs \
|
||||||
|
${node_port_id})
|
||||||
|
- if echo $result | grep -q $OCF_RESKEY_ip ; then
|
||||||
|
+ if echo $result | grep -q "$OCF_RESKEY_ip"; then
|
||||||
|
${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n openstack_virtual_ip -v $OCF_RESKEY_ip
|
||||||
|
|
||||||
|
return $OCF_SUCCESS
|
26
SOURCES/bz2083090-openstack-info-fix-bashism.patch
Normal file
26
SOURCES/bz2083090-openstack-info-fix-bashism.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
From 8b1d3257e5176a2f50a843a21888c4b4f51f370b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Valentin Vidic <vvidic@valentin-vidic.from.hr>
|
||||||
|
Date: Sun, 3 Apr 2022 20:31:50 +0200
|
||||||
|
Subject: [PATCH] openstack-info: fix bashism
|
||||||
|
|
||||||
|
Also simplify striping of trailing comma.
|
||||||
|
---
|
||||||
|
heartbeat/openstack-info.in | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/openstack-info.in b/heartbeat/openstack-info.in
|
||||||
|
index f6dc1ee4d..f3a59fc7a 100755
|
||||||
|
--- a/heartbeat/openstack-info.in
|
||||||
|
+++ b/heartbeat/openstack-info.in
|
||||||
|
@@ -167,9 +167,9 @@ OSInfoStats() {
|
||||||
|
--column fixed_ips \
|
||||||
|
${port_id} | grep -P '\"subnet_id\": \".*\",$' |
|
||||||
|
grep -P -o '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}')
|
||||||
|
- value+="${subnet_id}:${port_id},"
|
||||||
|
+ value="${value}${subnet_id}:${port_id},"
|
||||||
|
done
|
||||||
|
- value=$(echo ${value} | sed -e 's/,$//g')
|
||||||
|
+ value=${value%,}
|
||||||
|
|
||||||
|
${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -n openstack_ports -v "$value"
|
||||||
|
|
@ -0,0 +1,82 @@
|
|||||||
|
From 4420ef84f3172c67fc7b8b6ae41ea173de017bf4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Pavlu <petr.pavlu@suse.com>
|
||||||
|
Date: Wed, 25 May 2022 15:12:33 +0200
|
||||||
|
Subject: [PATCH] aws-vpc-move-ip: Allow to set the interface label
|
||||||
|
|
||||||
|
Add a parameter to specify an interface label to distinguish the IP
|
||||||
|
address managed by aws-vpc-move-ip, similarly as can be done with
|
||||||
|
IPaddr2. This allows to easily recognize the address from other
|
||||||
|
addresses assigned to a given interface.
|
||||||
|
---
|
||||||
|
heartbeat/aws-vpc-move-ip | 30 +++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 29 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/aws-vpc-move-ip b/heartbeat/aws-vpc-move-ip
|
||||||
|
index 5d5204080..dee040300 100755
|
||||||
|
--- a/heartbeat/aws-vpc-move-ip
|
||||||
|
+++ b/heartbeat/aws-vpc-move-ip
|
||||||
|
@@ -43,6 +43,7 @@ OCF_RESKEY_address_default=""
|
||||||
|
OCF_RESKEY_routing_table_default=""
|
||||||
|
OCF_RESKEY_routing_table_role_default=""
|
||||||
|
OCF_RESKEY_interface_default="eth0"
|
||||||
|
+OCF_RESKEY_iflabel_default=""
|
||||||
|
OCF_RESKEY_monapi_default="false"
|
||||||
|
OCF_RESKEY_lookup_type_default="InstanceId"
|
||||||
|
|
||||||
|
@@ -54,6 +55,7 @@ OCF_RESKEY_lookup_type_default="InstanceId"
|
||||||
|
: ${OCF_RESKEY_routing_table=${OCF_RESKEY_routing_table_default}}
|
||||||
|
: ${OCF_RESKEY_routing_table_role=${OCF_RESKEY_routing_table_role_default}}
|
||||||
|
: ${OCF_RESKEY_interface=${OCF_RESKEY_interface_default}}
|
||||||
|
+: ${OCF_RESKEY_iflabel=${OCF_RESKEY_iflabel_default}}
|
||||||
|
: ${OCF_RESKEY_monapi=${OCF_RESKEY_monapi_default}}
|
||||||
|
: ${OCF_RESKEY_lookup_type=${OCF_RESKEY_lookup_type_default}}
|
||||||
|
|
||||||
|
@@ -149,6 +151,18 @@ Name of the network interface, i.e. eth0
|
||||||
|
<content type="string" default="${OCF_RESKEY_interface_default}" />
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
+<parameter name="iflabel">
|
||||||
|
+<longdesc lang="en">
|
||||||
|
+You can specify an additional label for your IP address here.
|
||||||
|
+This label is appended to your interface name.
|
||||||
|
+
|
||||||
|
+The kernel allows alphanumeric labels up to a maximum length of 15
|
||||||
|
+characters including the interface name and colon (e.g. eth0:foobar1234)
|
||||||
|
+</longdesc>
|
||||||
|
+<shortdesc lang="en">Interface label</shortdesc>
|
||||||
|
+<content type="string" default="${OCF_RESKEY_iflabel_default}"/>
|
||||||
|
+</parameter>
|
||||||
|
+
|
||||||
|
<parameter name="monapi">
|
||||||
|
<longdesc lang="en">
|
||||||
|
Enable enhanced monitoring using AWS API calls to check route table entry
|
||||||
|
@@ -215,6 +229,14 @@ ec2ip_validate() {
|
||||||
|
return $OCF_ERR_CONFIGURED
|
||||||
|
fi
|
||||||
|
|
||||||
|
+ if [ -n "$OCF_RESKEY_iflabel" ]; then
|
||||||
|
+ label=${OCF_RESKEY_interface}:${OFC_RESKEY_iflabel}
|
||||||
|
+ if [ ${#label} -gt 15 ]; then
|
||||||
|
+ ocf_exit_reason "Interface label [$label] exceeds maximum character limit of 15"
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
||||||
|
EC2_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id -H "X-aws-ec2-metadata-token: $TOKEN")
|
||||||
|
|
||||||
|
@@ -363,7 +385,13 @@ ec2ip_get_and_configure() {
|
||||||
|
|
||||||
|
# Reconfigure the local ip address
|
||||||
|
ec2ip_drop
|
||||||
|
- cmd="ip addr add ${OCF_RESKEY_ip}/32 dev $OCF_RESKEY_interface"
|
||||||
|
+
|
||||||
|
+ extra_opts=""
|
||||||
|
+ if [ -n "$OCF_RESKEY_iflabel" ]; then
|
||||||
|
+ extra_opts="$extra_opts label $OCF_RESKEY_interface:$OCF_RESKEY_iflabel"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ cmd="ip addr add ${OCF_RESKEY_ip}/32 dev $OCF_RESKEY_interface $extra_opts"
|
||||||
|
ocf_log debug "executing command: $cmd"
|
||||||
|
$cmd
|
||||||
|
rc=$?
|
@ -0,0 +1,25 @@
|
|||||||
|
From b3885f7d95fe390371f806c7f3debb3ec8ad012d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 7 Jun 2022 15:20:11 +0200
|
||||||
|
Subject: [PATCH] lvmlockd: fail when use_lvmlockd has not been set
|
||||||
|
|
||||||
|
---
|
||||||
|
heartbeat/lvmlockd | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/lvmlockd b/heartbeat/lvmlockd
|
||||||
|
index 05bb0a2e5..dc7bd2d7e 100755
|
||||||
|
--- a/heartbeat/lvmlockd
|
||||||
|
+++ b/heartbeat/lvmlockd
|
||||||
|
@@ -179,6 +179,11 @@ setup_lvm_config()
|
||||||
|
out=$(lvmconfig 'global/locking_type' 2> /dev/null)
|
||||||
|
lock_type=$(echo "$out" | cut -d'=' -f2)
|
||||||
|
|
||||||
|
+ if [ -z "$use_lvmlockd" ]; then
|
||||||
|
+ ocf_exit_reason "\"use_lvmlockd\" not set in /etc/lvm/lvm.conf ..."
|
||||||
|
+ exit $OCF_ERR_CONFIGURED
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
if [ -n "$use_lvmlockd" ] && [ "$use_lvmlockd" != 1 ] ; then
|
||||||
|
ocf_log info "setting \"use_lvmlockd=1\" in /etc/lvm/lvm.conf ..."
|
||||||
|
sed -i 's,^[[:blank:]]*use_lvmlockd[[:blank:]]*=.*,\ \ \ \ use_lvmlockd = 1,g' /etc/lvm/lvm.conf
|
39
SOURCES/bz2103374-ocf-tester-1-update.patch
Normal file
39
SOURCES/bz2103374-ocf-tester-1-update.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 46e8d346ca4803245f51a157591c4df1126d3b49 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 12 Jul 2022 12:45:52 +0200
|
||||||
|
Subject: [PATCH] ocf-tester: use promotable terms
|
||||||
|
|
||||||
|
---
|
||||||
|
tools/ocf-tester.in | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/ocf-tester.in b/tools/ocf-tester.in
|
||||||
|
index 10822a5a06..f1703ba1b7 100755
|
||||||
|
--- a/tools/ocf-tester.in
|
||||||
|
+++ b/tools/ocf-tester.in
|
||||||
|
@@ -295,10 +295,10 @@ if [ $rc -eq 3 ]; then
|
||||||
|
|
||||||
|
elif [ $rc -eq 8 ]; then
|
||||||
|
test_command demote "Cleanup, demote"
|
||||||
|
- assert $? 0 "Your agent was a master and could not be demoted" 1
|
||||||
|
+ assert $? 0 "Your agent was promoted and could not be demoted" 1
|
||||||
|
|
||||||
|
test_command stop "Cleanup, stop"
|
||||||
|
- assert $? 0 "Your agent was a master and could not be stopped" 1
|
||||||
|
+ assert $? 0 "Your agent was promoted and could not be stopped" 1
|
||||||
|
|
||||||
|
elif [ $rc -ne 7 ]; then
|
||||||
|
test_command stop
|
||||||
|
@@ -370,10 +370,10 @@ if [ $has_promote -eq 1 -a $has_demote -eq 1 ]; then
|
||||||
|
assert $? 0 "Demote failed" 1
|
||||||
|
|
||||||
|
elif [ $has_promote -eq 0 -a $has_demote -eq 0 ]; then
|
||||||
|
- info "* Your agent does not support master/slave (optional)"
|
||||||
|
+ info "* Your agent does not support promotable clones (optional)"
|
||||||
|
|
||||||
|
else
|
||||||
|
- echo "* Your agent partially supports master/slave"
|
||||||
|
+ echo "* Your agent partially supports promotable clones"
|
||||||
|
num_errors=`expr $num_errors + 1`
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,166 @@
|
|||||||
|
From 687aa646852d5fd5d4e811b2ec562ebffa15e23d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Thu, 14 Jul 2022 14:52:07 +0200
|
||||||
|
Subject: [PATCH] ocf-tester: remove deprecated lrmd/lrmadmin code that hasnt
|
||||||
|
worked since pre-pacemaker days
|
||||||
|
|
||||||
|
---
|
||||||
|
tools/ocf-tester.8 | 12 ++-----
|
||||||
|
tools/ocf-tester.in | 81 ---------------------------------------------
|
||||||
|
2 files changed, 2 insertions(+), 91 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/ocf-tester.8 b/tools/ocf-tester.8
|
||||||
|
index 850ec0be04..3f398282d2 100644
|
||||||
|
--- a/tools/ocf-tester.8
|
||||||
|
+++ b/tools/ocf-tester.8
|
||||||
|
@@ -1,9 +1,9 @@
|
||||||
|
-.TH OCF-TESTER "8" "January 2012" "Tool for testing if a cluster resource is OCF compliant" "System Administration Utilities"
|
||||||
|
+.TH OCF-TESTER "8" "July 2022" "Tool for testing if a cluster resource is OCF compliant" "System Administration Utilities"
|
||||||
|
.SH NAME
|
||||||
|
ocf-tester \- Part of the Linux-HA project
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B ocf-tester
|
||||||
|
-[\fI-LhvqdX\fR] \fI-n resource_name \fR[\fI-o name=value\fR]\fI* /full/path/to/resource/agent\fR
|
||||||
|
+[\fI-hvqdX\fR] \fI-n resource_name \fR[\fI-o name=value\fR]\fI* /full/path/to/resource/agent\fR
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Tool for testing if a cluster resource is OCF compliant
|
||||||
|
.SH OPTIONS
|
||||||
|
@@ -26,11 +26,6 @@ Name of the resource
|
||||||
|
\fB\-o\fR name=value
|
||||||
|
Name and value of any parameters required by the agent
|
||||||
|
.TP
|
||||||
|
-\fB\-L\fR
|
||||||
|
-Use lrmadmin/lrmd for tests
|
||||||
|
-.PP
|
||||||
|
-Usage: ocf\-tester [\-Lh] \fB\-n\fR resource_name [\-o name=value]* /full/path/to/resource/agent
|
||||||
|
-.TP
|
||||||
|
\fB\-h\fR
|
||||||
|
This text
|
||||||
|
.TP
|
||||||
|
@@ -51,6 +46,3 @@ Name of the resource
|
||||||
|
.TP
|
||||||
|
\fB\-o\fR name=value
|
||||||
|
Name and value of any parameters required by the agent
|
||||||
|
-.TP
|
||||||
|
-\fB\-L\fR
|
||||||
|
-Use lrmadmin/lrmd for tests
|
||||||
|
diff --git a/tools/ocf-tester.in b/tools/ocf-tester.in
|
||||||
|
index 10822a5a06..15b14e51ea 100755
|
||||||
|
--- a/tools/ocf-tester.in
|
||||||
|
+++ b/tools/ocf-tester.in
|
||||||
|
@@ -25,8 +25,6 @@
|
||||||
|
# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
-LRMD=@libdir@/heartbeat/lrmd
|
||||||
|
-LRMADMIN=@sbindir@/lrmadmin
|
||||||
|
DATADIR=@datadir@
|
||||||
|
METADATA_LINT="xmllint --noout --valid -"
|
||||||
|
|
||||||
|
@@ -61,7 +59,6 @@ usage() {
|
||||||
|
echo " -X Turn on RA tracing (expect large output)"
|
||||||
|
echo " -n name Name of the resource"
|
||||||
|
echo " -o name=value Name and value of any parameters required by the agent"
|
||||||
|
- echo " -L Use lrmadmin/lrmd for tests"
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -104,7 +101,6 @@ while test "$done" = "0"; do
|
||||||
|
-o) name=${2%%=*}; value=${2#*=};
|
||||||
|
lrm_ra_args="$lrm_ra_args $2";
|
||||||
|
ra_args="$ra_args OCF_RESKEY_$name='$value'"; shift; shift;;
|
||||||
|
- -L) use_lrmd=1; shift;;
|
||||||
|
-v) verbose=1; shift;;
|
||||||
|
-d) export HA_debug=1; shift;;
|
||||||
|
-X) export OCF_TRACE_RA=1; verbose=1; shift;;
|
||||||
|
@@ -140,79 +136,6 @@ stopped_rc=7
|
||||||
|
has_demote=1
|
||||||
|
has_promote=1
|
||||||
|
|
||||||
|
-start_lrmd() {
|
||||||
|
- lrmd_timeout=0
|
||||||
|
- lrmd_interval=0
|
||||||
|
- lrmd_target_rc=EVERYTIME
|
||||||
|
- lrmd_started=""
|
||||||
|
- $LRMD -s 2>/dev/null
|
||||||
|
- rc=$?
|
||||||
|
- if [ $rc -eq 3 ]; then
|
||||||
|
- lrmd_started=1
|
||||||
|
- $LRMD &
|
||||||
|
- sleep 1
|
||||||
|
- $LRMD -s 2>/dev/null
|
||||||
|
- else
|
||||||
|
- return $rc
|
||||||
|
- fi
|
||||||
|
-}
|
||||||
|
-add_resource() {
|
||||||
|
- $LRMADMIN -A $OCF_RESOURCE_INSTANCE \
|
||||||
|
- ocf \
|
||||||
|
- `basename $agent` \
|
||||||
|
- $(basename `dirname $agent`) \
|
||||||
|
- $lrm_ra_args > /dev/null
|
||||||
|
-}
|
||||||
|
-del_resource() {
|
||||||
|
- $LRMADMIN -D $OCF_RESOURCE_INSTANCE
|
||||||
|
-}
|
||||||
|
-parse_lrmadmin_output() {
|
||||||
|
- awk '
|
||||||
|
-BEGIN{ rc=1; }
|
||||||
|
-/Waiting for lrmd to callback.../ { n=1; next; }
|
||||||
|
-n==1 && /----------------operation--------------/ { n++; next; }
|
||||||
|
-n==2 && /return code:/ { rc=$0; sub("return code: *","",rc); next }
|
||||||
|
-n==2 && /---------------------------------------/ {
|
||||||
|
- n++;
|
||||||
|
- next;
|
||||||
|
-}
|
||||||
|
-END{
|
||||||
|
- if( n!=3 ) exit 1;
|
||||||
|
- else exit rc;
|
||||||
|
-}
|
||||||
|
-'
|
||||||
|
-}
|
||||||
|
-exec_resource() {
|
||||||
|
- op="$1"
|
||||||
|
- args="$2"
|
||||||
|
- $LRMADMIN -E $OCF_RESOURCE_INSTANCE \
|
||||||
|
- $op $lrmd_timeout $lrmd_interval \
|
||||||
|
- $lrmd_target_rc \
|
||||||
|
- $args | parse_lrmadmin_output
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-if [ "$use_lrmd" = 1 ]; then
|
||||||
|
- echo "Using lrmd/lrmadmin for all tests"
|
||||||
|
- start_lrmd || {
|
||||||
|
- echo "could not start lrmd" >&2
|
||||||
|
- exit 1
|
||||||
|
- }
|
||||||
|
- trap '
|
||||||
|
- [ "$lrmd_started" = 1 ] && $LRMD -k
|
||||||
|
- ' EXIT
|
||||||
|
- add_resource || {
|
||||||
|
- echo "failed to add resource to lrmd" >&2
|
||||||
|
- exit 1
|
||||||
|
- }
|
||||||
|
-fi
|
||||||
|
-
|
||||||
|
-lrm_test_command() {
|
||||||
|
- action="$1"
|
||||||
|
- msg="$2"
|
||||||
|
- debug "$msg"
|
||||||
|
- exec_resource $action "$lrm_ra_args"
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
test_permissions() {
|
||||||
|
action=meta-data
|
||||||
|
debug ${1:-"Testing permissions with uid nobody"}
|
||||||
|
@@ -233,10 +156,6 @@ test_command() {
|
||||||
|
action=$1; shift
|
||||||
|
export __OCF_ACTION=$action
|
||||||
|
msg=${1:-"Testing: $action"}
|
||||||
|
- if [ "$use_lrmd" = 1 ]; then
|
||||||
|
- lrm_test_command $action "$msg"
|
||||||
|
- return $?
|
||||||
|
- fi
|
||||||
|
#echo Running: "export $ra_args; $agent $action 2>&1 > /dev/null"
|
||||||
|
if [ $verbose -eq 0 ]; then
|
||||||
|
command_output=`$agent $action 2>&1`
|
@ -0,0 +1,75 @@
|
|||||||
|
From 0063164d72bbaca68f12a2f0a7dbae9ccb41fa39 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
||||||
|
Date: Tue, 26 Jul 2022 09:08:26 +0200
|
||||||
|
Subject: [PATCH] ethmonitor/ovsmonitor/pgsql: remove ignored attrd_updater
|
||||||
|
"-q" parameter
|
||||||
|
|
||||||
|
attrd_updater in 2.1.3 no longer ignores the -q parameter, which makes
|
||||||
|
these agents break. It never did anything in attrd_updater, and is
|
||||||
|
probably left-over from copy/paste crm_attribute code that got changed
|
||||||
|
to attrd_updater.
|
||||||
|
---
|
||||||
|
heartbeat/ethmonitor | 2 +-
|
||||||
|
heartbeat/ovsmonitor | 2 +-
|
||||||
|
heartbeat/pgsql | 8 ++++----
|
||||||
|
3 files changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/heartbeat/ethmonitor b/heartbeat/ethmonitor
|
||||||
|
index ba8574131..451738a0b 100755
|
||||||
|
--- a/heartbeat/ethmonitor
|
||||||
|
+++ b/heartbeat/ethmonitor
|
||||||
|
@@ -464,7 +464,7 @@ END
|
||||||
|
|
||||||
|
set_cib_value() {
|
||||||
|
local score=`expr $1 \* $OCF_RESKEY_multiplier`
|
||||||
|
- attrd_updater -n $ATTRNAME -v $score -q
|
||||||
|
+ attrd_updater -n $ATTRNAME -v $score
|
||||||
|
local rc=$?
|
||||||
|
case $rc in
|
||||||
|
0) ocf_log debug "attrd_updater: Updated $ATTRNAME = $score" ;;
|
||||||
|
diff --git a/heartbeat/ovsmonitor b/heartbeat/ovsmonitor
|
||||||
|
index 872ce86eb..6765da4b9 100755
|
||||||
|
--- a/heartbeat/ovsmonitor
|
||||||
|
+++ b/heartbeat/ovsmonitor
|
||||||
|
@@ -355,7 +355,7 @@ END
|
||||||
|
|
||||||
|
set_cib_value() {
|
||||||
|
local score=`expr $1 \* $OCF_RESKEY_multiplier`
|
||||||
|
- attrd_updater -n $ATTRNAME -v $score -q
|
||||||
|
+ attrd_updater -n $ATTRNAME -v $score
|
||||||
|
local rc=$?
|
||||||
|
case $rc in
|
||||||
|
0) ocf_log debug "attrd_updater: Updated $ATTRNAME = $score" ;;
|
||||||
|
diff --git a/heartbeat/pgsql b/heartbeat/pgsql
|
||||||
|
index 94aceb324..e93d66855 100755
|
||||||
|
--- a/heartbeat/pgsql
|
||||||
|
+++ b/heartbeat/pgsql
|
||||||
|
@@ -808,7 +808,7 @@ pgsql_real_stop() {
|
||||||
|
local stop_escalate
|
||||||
|
|
||||||
|
if ocf_is_true ${OCF_RESKEY_check_wal_receiver}; then
|
||||||
|
- attrd_updater -n "$PGSQL_WAL_RECEIVER_STATUS_ATTR" -D -q
|
||||||
|
+ attrd_updater -n "$PGSQL_WAL_RECEIVER_STATUS_ATTR" -D
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! pgsql_status
|
||||||
|
@@ -937,16 +937,16 @@ pgsql_wal_receiver_status() {
|
||||||
|
receiver_parent_pids=`ps -ef | tr -s " " | grep "[w]al\s*receiver" | cut -d " " -f 3`
|
||||||
|
|
||||||
|
if echo "$receiver_parent_pids" | grep -q -w "$PID" ; then
|
||||||
|
- attrd_updater -n "$PGSQL_WAL_RECEIVER_STATUS_ATTR" -v "normal" -q
|
||||||
|
+ attrd_updater -n "$PGSQL_WAL_RECEIVER_STATUS_ATTR" -v "normal"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $pgsql_real_monitor_status -eq "$OCF_RUNNING_MASTER" ]; then
|
||||||
|
- attrd_updater -n "$PGSQL_WAL_RECEIVER_STATUS_ATTR" -v "normal (master)" -q
|
||||||
|
+ attrd_updater -n "$PGSQL_WAL_RECEIVER_STATUS_ATTR" -v "normal (master)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
- attrd_updater -n "$PGSQL_WAL_RECEIVER_STATUS_ATTR" -v "ERROR" -q
|
||||||
|
+ attrd_updater -n "$PGSQL_WAL_RECEIVER_STATUS_ATTR" -v "ERROR"
|
||||||
|
ocf_log warn "wal receiver process is not running"
|
||||||
|
return 1
|
||||||
|
}
|
@ -1,903 +0,0 @@
|
|||||||
From 5dcd5153f0318e4766f7f4d3e61dfdb4b352c39c Mon Sep 17 00:00:00 2001
|
|
||||||
From: MSSedusch <sedusch@microsoft.com>
|
|
||||||
Date: Mon, 30 May 2022 15:08:10 +0200
|
|
||||||
Subject: [PATCH 1/2] add new Azure Events AZ resource agent
|
|
||||||
|
|
||||||
---
|
|
||||||
.gitignore | 1 +
|
|
||||||
configure.ac | 8 +
|
|
||||||
doc/man/Makefile.am | 4 +
|
|
||||||
heartbeat/Makefile.am | 4 +
|
|
||||||
heartbeat/azure-events-az.in | 782 +++++++++++++++++++++++++++++++++++
|
|
||||||
5 files changed, 799 insertions(+)
|
|
||||||
create mode 100644 heartbeat/azure-events-az.in
|
|
||||||
|
|
||||||
diff --git a/.gitignore b/.gitignore
|
|
||||||
index 0c259b5cf..e2b7c039c 100644
|
|
||||||
--- a/.gitignore
|
|
||||||
+++ b/.gitignore
|
|
||||||
@@ -54,6 +54,7 @@ heartbeat/Squid
|
|
||||||
heartbeat/SysInfo
|
|
||||||
heartbeat/aws-vpc-route53
|
|
||||||
heartbeat/azure-events
|
|
||||||
+heartbeat/azure-events-az
|
|
||||||
heartbeat/clvm
|
|
||||||
heartbeat/conntrackd
|
|
||||||
heartbeat/dnsupdate
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
|
||||||
index eeecfad0e..5716a2be2 100644
|
|
||||||
--- a/configure.ac
|
|
||||||
+++ b/configure.ac
|
|
||||||
@@ -523,6 +523,13 @@ if test -z "$PYTHON" || test $BUILD_OCF_PY -eq 0; then
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(BUILD_AZURE_EVENTS, test $BUILD_AZURE_EVENTS -eq 1)
|
|
||||||
|
|
||||||
+BUILD_AZURE_EVENTS_AZ=1
|
|
||||||
+if test -z "$PYTHON" || test $BUILD_OCF_PY -eq 0; then
|
|
||||||
+ BUILD_AZURE_EVENTS_AZ=0
|
|
||||||
+ AC_MSG_WARN("Not building azure-events-az")
|
|
||||||
+fi
|
|
||||||
+AM_CONDITIONAL(BUILD_AZURE_EVENTS_AZ, test $BUILD_AZURE_EVENTS_AZ -eq 1)
|
|
||||||
+
|
|
||||||
BUILD_GCP_PD_MOVE=1
|
|
||||||
if test -z "$PYTHON" || test "x${HAVE_PYMOD_GOOGLEAPICLIENT}" != xyes || test $BUILD_OCF_PY -eq 0; then
|
|
||||||
BUILD_GCP_PD_MOVE=0
|
|
||||||
@@ -976,6 +983,7 @@ rgmanager/Makefile \
|
|
||||||
|
|
||||||
dnl Files we output that need to be executable
|
|
||||||
AC_CONFIG_FILES([heartbeat/azure-events], [chmod +x heartbeat/azure-events])
|
|
||||||
+AC_CONFIG_FILES([heartbeat/azure-events-az], [chmod +x heartbeat/azure-events-az])
|
|
||||||
AC_CONFIG_FILES([heartbeat/AoEtarget], [chmod +x heartbeat/AoEtarget])
|
|
||||||
AC_CONFIG_FILES([heartbeat/ManageRAID], [chmod +x heartbeat/ManageRAID])
|
|
||||||
AC_CONFIG_FILES([heartbeat/ManageVE], [chmod +x heartbeat/ManageVE])
|
|
||||||
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
|
|
||||||
index cd8fd16bf..658c700ac 100644
|
|
||||||
--- a/doc/man/Makefile.am
|
|
||||||
+++ b/doc/man/Makefile.am
|
|
||||||
@@ -219,6 +219,10 @@ if BUILD_AZURE_EVENTS
|
|
||||||
man_MANS += ocf_heartbeat_azure-events.7
|
|
||||||
endif
|
|
||||||
|
|
||||||
+if BUILD_AZURE_EVENTS_AZ
|
|
||||||
+man_MANS += ocf_heartbeat_azure-events-az.7
|
|
||||||
+endif
|
|
||||||
+
|
|
||||||
if BUILD_GCP_PD_MOVE
|
|
||||||
man_MANS += ocf_heartbeat_gcp-pd-move.7
|
|
||||||
endif
|
|
||||||
diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
|
|
||||||
index 20d41e36a..1133dc13e 100644
|
|
||||||
--- a/heartbeat/Makefile.am
|
|
||||||
+++ b/heartbeat/Makefile.am
|
|
||||||
@@ -188,6 +188,10 @@ if BUILD_AZURE_EVENTS
|
|
||||||
ocf_SCRIPTS += azure-events
|
|
||||||
endif
|
|
||||||
|
|
||||||
+if BUILD_AZURE_EVENTS_AZ
|
|
||||||
+ocf_SCRIPTS += azure-events-az
|
|
||||||
+endif
|
|
||||||
+
|
|
||||||
if BUILD_GCP_PD_MOVE
|
|
||||||
ocf_SCRIPTS += gcp-pd-move
|
|
||||||
endif
|
|
||||||
diff --git a/heartbeat/azure-events-az.in b/heartbeat/azure-events-az.in
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..616fc8d9e
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/heartbeat/azure-events-az.in
|
|
||||||
@@ -0,0 +1,782 @@
|
|
||||||
+#!@PYTHON@ -tt
|
|
||||||
+#
|
|
||||||
+# Resource agent for monitoring Azure Scheduled Events
|
|
||||||
+#
|
|
||||||
+# License: GNU General Public License (GPL)
|
|
||||||
+# (c) 2018 Tobias Niekamp, Microsoft Corp.
|
|
||||||
+# and Linux-HA contributors
|
|
||||||
+
|
|
||||||
+import os
|
|
||||||
+import sys
|
|
||||||
+import time
|
|
||||||
+import subprocess
|
|
||||||
+import json
|
|
||||||
+try:
|
|
||||||
+ import urllib2
|
|
||||||
+ from urllib2 import URLError
|
|
||||||
+except ImportError:
|
|
||||||
+ import urllib.request as urllib2
|
|
||||||
+ from urllib.error import URLError
|
|
||||||
+import socket
|
|
||||||
+from collections import defaultdict
|
|
||||||
+
|
|
||||||
+OCF_FUNCTIONS_DIR = os.environ.get("OCF_FUNCTIONS_DIR", "%s/lib/heartbeat" % os.environ.get("OCF_ROOT"))
|
|
||||||
+sys.path.append(OCF_FUNCTIONS_DIR)
|
|
||||||
+import ocf
|
|
||||||
+
|
|
||||||
+##############################################################################
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+VERSION = "0.10"
|
|
||||||
+USER_AGENT = "Pacemaker-ResourceAgent/%s %s" % (VERSION, ocf.distro())
|
|
||||||
+
|
|
||||||
+attr_globalPullState = "azure-events-az_globalPullState"
|
|
||||||
+attr_lastDocVersion = "azure-events-az_lastDocVersion"
|
|
||||||
+attr_curNodeState = "azure-events-az_curNodeState"
|
|
||||||
+attr_pendingEventIDs = "azure-events-az_pendingEventIDs"
|
|
||||||
+attr_healthstate = "#health-azure"
|
|
||||||
+
|
|
||||||
+default_loglevel = ocf.logging.INFO
|
|
||||||
+default_relevantEventTypes = set(["Reboot", "Redeploy"])
|
|
||||||
+
|
|
||||||
+global_pullMaxAttempts = 3
|
|
||||||
+global_pullDelaySecs = 1
|
|
||||||
+
|
|
||||||
+##############################################################################
|
|
||||||
+
|
|
||||||
+class attrDict(defaultdict):
|
|
||||||
+ """
|
|
||||||
+ A wrapper for accessing dict keys like an attribute
|
|
||||||
+ """
|
|
||||||
+ def __init__(self, data):
|
|
||||||
+ super(attrDict, self).__init__(attrDict)
|
|
||||||
+ for d in data.keys():
|
|
||||||
+ self.__setattr__(d, data[d])
|
|
||||||
+
|
|
||||||
+ def __getattr__(self, key):
|
|
||||||
+ try:
|
|
||||||
+ return self[key]
|
|
||||||
+ except KeyError:
|
|
||||||
+ raise AttributeError(key)
|
|
||||||
+
|
|
||||||
+ def __setattr__(self, key, value):
|
|
||||||
+ self[key] = value
|
|
||||||
+
|
|
||||||
+##############################################################################
|
|
||||||
+
|
|
||||||
+class azHelper:
|
|
||||||
+ """
|
|
||||||
+ Helper class for Azure's metadata API (including Scheduled Events)
|
|
||||||
+ """
|
|
||||||
+ metadata_host = "http://169.254.169.254/metadata"
|
|
||||||
+ instance_api = "instance"
|
|
||||||
+ events_api = "scheduledevents"
|
|
||||||
+ api_version = "2019-08-01"
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def _sendMetadataRequest(endpoint, postData=None):
|
|
||||||
+ """
|
|
||||||
+ Send a request to Azure's Azure Metadata Service API
|
|
||||||
+ """
|
|
||||||
+ url = "%s/%s?api-version=%s" % (azHelper.metadata_host, endpoint, azHelper.api_version)
|
|
||||||
+ data = ""
|
|
||||||
+ ocf.logger.debug("_sendMetadataRequest: begin; endpoint = %s, postData = %s" % (endpoint, postData))
|
|
||||||
+ ocf.logger.debug("_sendMetadataRequest: url = %s" % url)
|
|
||||||
+
|
|
||||||
+ if postData and type(postData) != bytes:
|
|
||||||
+ postData = postData.encode()
|
|
||||||
+
|
|
||||||
+ req = urllib2.Request(url, postData)
|
|
||||||
+ req.add_header("Metadata", "true")
|
|
||||||
+ req.add_header("User-Agent", USER_AGENT)
|
|
||||||
+ try:
|
|
||||||
+ resp = urllib2.urlopen(req)
|
|
||||||
+ except URLError as e:
|
|
||||||
+ if hasattr(e, 'reason'):
|
|
||||||
+ ocf.logger.warning("Failed to reach the server: %s" % e.reason)
|
|
||||||
+ clusterHelper.setAttr(attr_globalPullState, "IDLE")
|
|
||||||
+ elif hasattr(e, 'code'):
|
|
||||||
+ ocf.logger.warning("The server couldn\'t fulfill the request. Error code: %s" % e.code)
|
|
||||||
+ clusterHelper.setAttr(attr_globalPullState, "IDLE")
|
|
||||||
+ else:
|
|
||||||
+ data = resp.read()
|
|
||||||
+ ocf.logger.debug("_sendMetadataRequest: response = %s" % data)
|
|
||||||
+
|
|
||||||
+ if data:
|
|
||||||
+ data = json.loads(data)
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("_sendMetadataRequest: finished")
|
|
||||||
+ return data
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def getInstanceInfo():
|
|
||||||
+ """
|
|
||||||
+ Fetch details about the current VM from Azure's Azure Metadata Service API
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("getInstanceInfo: begin")
|
|
||||||
+
|
|
||||||
+ jsondata = azHelper._sendMetadataRequest(azHelper.instance_api)
|
|
||||||
+ ocf.logger.debug("getInstanceInfo: json = %s" % jsondata)
|
|
||||||
+
|
|
||||||
+ if jsondata:
|
|
||||||
+ ocf.logger.debug("getInstanceInfo: finished, returning {}".format(jsondata["compute"]))
|
|
||||||
+ return attrDict(jsondata["compute"])
|
|
||||||
+ else:
|
|
||||||
+ ocf.ocf_exit_reason("getInstanceInfo: Unable to get instance info")
|
|
||||||
+ sys.exit(ocf.OCF_ERR_GENERIC)
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def pullScheduledEvents():
|
|
||||||
+ """
|
|
||||||
+ Retrieve all currently scheduled events via Azure Metadata Service API
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("pullScheduledEvents: begin")
|
|
||||||
+
|
|
||||||
+ jsondata = azHelper._sendMetadataRequest(azHelper.events_api)
|
|
||||||
+ ocf.logger.debug("pullScheduledEvents: json = %s" % jsondata)
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("pullScheduledEvents: finished")
|
|
||||||
+ return attrDict(jsondata)
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def forceEvents(eventIDs):
|
|
||||||
+ """
|
|
||||||
+ Force a set of events to start immediately
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("forceEvents: begin")
|
|
||||||
+
|
|
||||||
+ events = []
|
|
||||||
+ for e in eventIDs:
|
|
||||||
+ events.append({
|
|
||||||
+ "EventId": e,
|
|
||||||
+ })
|
|
||||||
+ postData = {
|
|
||||||
+ "StartRequests" : events
|
|
||||||
+ }
|
|
||||||
+ ocf.logger.info("forceEvents: postData = %s" % postData)
|
|
||||||
+ resp = azHelper._sendMetadataRequest(azHelper.events_api, postData=json.dumps(postData))
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("forceEvents: finished")
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+##############################################################################
|
|
||||||
+
|
|
||||||
+class clusterHelper:
|
|
||||||
+ """
|
|
||||||
+ Helper functions for Pacemaker control via crm
|
|
||||||
+ """
|
|
||||||
+ @staticmethod
|
|
||||||
+ def _getLocation(node):
|
|
||||||
+ """
|
|
||||||
+ Helper function to retrieve local/global attributes
|
|
||||||
+ """
|
|
||||||
+ if node:
|
|
||||||
+ return ["--node", node]
|
|
||||||
+ else:
|
|
||||||
+ return ["--type", "crm_config"]
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def _exec(command, *args):
|
|
||||||
+ """
|
|
||||||
+ Helper function to execute a UNIX command
|
|
||||||
+ """
|
|
||||||
+ args = list(args)
|
|
||||||
+ ocf.logger.debug("_exec: begin; command = %s, args = %s" % (command, str(args)))
|
|
||||||
+
|
|
||||||
+ def flatten(*n):
|
|
||||||
+ return (str(e) for a in n
|
|
||||||
+ for e in (flatten(*a) if isinstance(a, (tuple, list)) else (str(a),)))
|
|
||||||
+ command = list(flatten([command] + args))
|
|
||||||
+ ocf.logger.debug("_exec: cmd = %s" % " ".join(command))
|
|
||||||
+ try:
|
|
||||||
+ ret = subprocess.check_output(command)
|
|
||||||
+ if type(ret) != str:
|
|
||||||
+ ret = ret.decode()
|
|
||||||
+ ocf.logger.debug("_exec: return = %s" % ret)
|
|
||||||
+ return ret.rstrip()
|
|
||||||
+ except Exception as err:
|
|
||||||
+ ocf.logger.exception(err)
|
|
||||||
+ return None
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def setAttr(key, value, node=None):
|
|
||||||
+ """
|
|
||||||
+ Set the value of a specific global/local attribute in the Pacemaker cluster
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("setAttr: begin; key = %s, value = %s, node = %s" % (key, value, node))
|
|
||||||
+
|
|
||||||
+ if value:
|
|
||||||
+ ret = clusterHelper._exec("crm_attribute",
|
|
||||||
+ "--name", key,
|
|
||||||
+ "--update", value,
|
|
||||||
+ clusterHelper._getLocation(node))
|
|
||||||
+ else:
|
|
||||||
+ ret = clusterHelper._exec("crm_attribute",
|
|
||||||
+ "--name", key,
|
|
||||||
+ "--delete",
|
|
||||||
+ clusterHelper._getLocation(node))
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("setAttr: finished")
|
|
||||||
+ return len(ret) == 0
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def getAttr(key, node=None):
|
|
||||||
+ """
|
|
||||||
+ Retrieve a global/local attribute from the Pacemaker cluster
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("getAttr: begin; key = %s, node = %s" % (key, node))
|
|
||||||
+
|
|
||||||
+ val = clusterHelper._exec("crm_attribute",
|
|
||||||
+ "--name", key,
|
|
||||||
+ "--query", "--quiet",
|
|
||||||
+ "--default", "",
|
|
||||||
+ clusterHelper._getLocation(node))
|
|
||||||
+ ocf.logger.debug("getAttr: finished")
|
|
||||||
+ if not val:
|
|
||||||
+ return None
|
|
||||||
+ return val if not val.isdigit() else int(val)
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def getAllNodes():
|
|
||||||
+ """
|
|
||||||
+ Get a list of hostnames for all nodes in the Pacemaker cluster
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("getAllNodes: begin")
|
|
||||||
+
|
|
||||||
+ nodes = []
|
|
||||||
+ nodeList = clusterHelper._exec("crm_node", "--list")
|
|
||||||
+ for n in nodeList.split("\n"):
|
|
||||||
+ nodes.append(n.split()[1])
|
|
||||||
+ ocf.logger.debug("getAllNodes: finished; return %s" % str(nodes))
|
|
||||||
+
|
|
||||||
+ return nodes
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def getHostNameFromAzName(azName):
|
|
||||||
+ """
|
|
||||||
+ Helper function to get the actual host name from an Azure node name
|
|
||||||
+ """
|
|
||||||
+ return clusterHelper.getAttr("hostName_%s" % azName)
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def removeHoldFromNodes():
|
|
||||||
+ """
|
|
||||||
+ Remove the ON_HOLD state from all nodes in the Pacemaker cluster
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("removeHoldFromNodes: begin")
|
|
||||||
+
|
|
||||||
+ for n in clusterHelper.getAllNodes():
|
|
||||||
+ if clusterHelper.getAttr(attr_curNodeState, node=n) == "ON_HOLD":
|
|
||||||
+ clusterHelper.setAttr(attr_curNodeState, "AVAILABLE", node=n)
|
|
||||||
+ ocf.logger.info("removeHoldFromNodes: removed ON_HOLD from node %s" % n)
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("removeHoldFromNodes: finished")
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def otherNodesAvailable(exceptNode):
|
|
||||||
+ """
|
|
||||||
+ Check if there are any nodes (except a given node) in the Pacemaker cluster that have state AVAILABLE
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("otherNodesAvailable: begin; exceptNode = %s" % exceptNode)
|
|
||||||
+
|
|
||||||
+ for n in clusterHelper.getAllNodes():
|
|
||||||
+ state = clusterHelper.getAttr(attr_curNodeState, node=n)
|
|
||||||
+ state = stringToNodeState(state) if state else AVAILABLE
|
|
||||||
+ if state == AVAILABLE and n != exceptNode.hostName:
|
|
||||||
+ ocf.logger.info("otherNodesAvailable: at least %s is available" % n)
|
|
||||||
+ ocf.logger.debug("otherNodesAvailable: finished")
|
|
||||||
+ return True
|
|
||||||
+ ocf.logger.info("otherNodesAvailable: no other nodes are available")
|
|
||||||
+ ocf.logger.debug("otherNodesAvailable: finished")
|
|
||||||
+
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def transitionSummary():
|
|
||||||
+ """
|
|
||||||
+ Get the current Pacemaker transition summary (used to check if all resources are stopped when putting a node standby)
|
|
||||||
+ """
|
|
||||||
+ # <tniek> Is a global crm_simulate "too much"? Or would it be sufficient it there are no planned transitions for a particular node?
|
|
||||||
+ # # crm_simulate -Ls
|
|
||||||
+ # Transition Summary:
|
|
||||||
+ # * Promote rsc_SAPHana_HN1_HDB03:0 (Slave -> Master hsr3-db1)
|
|
||||||
+ # * Stop rsc_SAPHana_HN1_HDB03:1 (hsr3-db0)
|
|
||||||
+ # * Move rsc_ip_HN1_HDB03 (Started hsr3-db0 -> hsr3-db1)
|
|
||||||
+ # * Start rsc_nc_HN1_HDB03 (hsr3-db1)
|
|
||||||
+ # # Excepted result when there are no pending actions:
|
|
||||||
+ # Transition Summary:
|
|
||||||
+ ocf.logger.debug("transitionSummary: begin")
|
|
||||||
+
|
|
||||||
+ summary = clusterHelper._exec("crm_simulate", "-Ls")
|
|
||||||
+ if not summary:
|
|
||||||
+ ocf.logger.warning("transitionSummary: could not load transition summary")
|
|
||||||
+ return False
|
|
||||||
+ if summary.find("Transition Summary:") < 0:
|
|
||||||
+ ocf.logger.warning("transitionSummary: received unexpected transition summary: %s" % summary)
|
|
||||||
+ return False
|
|
||||||
+ summary = summary.split("Transition Summary:")[1]
|
|
||||||
+ ret = summary.split("\n").pop(0)
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("transitionSummary: finished; return = %s" % str(ret))
|
|
||||||
+ return ret
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def listOperationsOnNode(node):
|
|
||||||
+ """
|
|
||||||
+ Get a list of all current operations for a given node (used to check if any resources are pending)
|
|
||||||
+ """
|
|
||||||
+ # hsr3-db1:/home/tniek # crm_resource --list-operations -N hsr3-db0
|
|
||||||
+ # rsc_azure-events-az (ocf::heartbeat:azure-events-az): Started: rsc_azure-events-az_start_0 (node=hsr3-db0, call=91, rc=0, last-rc-change=Fri Jun 8 22:37:46 2018, exec=115ms): complete
|
|
||||||
+ # rsc_azure-events-az (ocf::heartbeat:azure-events-az): Started: rsc_azure-events-az_monitor_10000 (node=hsr3-db0, call=93, rc=0, last-rc-change=Fri Jun 8 22:37:47 2018, exec=197ms): complete
|
|
||||||
+ # rsc_SAPHana_HN1_HDB03 (ocf::suse:SAPHana): Master: rsc_SAPHana_HN1_HDB03_start_0 (node=hsr3-db0, call=-1, rc=193, last-rc-change=Fri Jun 8 22:37:46 2018, exec=0ms): pending
|
|
||||||
+ # rsc_SAPHanaTopology_HN1_HDB03 (ocf::suse:SAPHanaTopology): Started: rsc_SAPHanaTopology_HN1_HDB03_start_0 (node=hsr3-db0, call=90, rc=0, last-rc-change=Fri Jun 8 22:37:46 2018, exec=3214ms): complete
|
|
||||||
+ ocf.logger.debug("listOperationsOnNode: begin; node = %s" % node)
|
|
||||||
+
|
|
||||||
+ resources = clusterHelper._exec("crm_resource", "--list-operations", "-N", node)
|
|
||||||
+ if len(resources) == 0:
|
|
||||||
+ ret = []
|
|
||||||
+ else:
|
|
||||||
+ ret = resources.split("\n")
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("listOperationsOnNode: finished; return = %s" % str(ret))
|
|
||||||
+ return ret
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def noPendingResourcesOnNode(node):
|
|
||||||
+ """
|
|
||||||
+ Check that there are no pending resources on a given node
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("noPendingResourcesOnNode: begin; node = %s" % node)
|
|
||||||
+
|
|
||||||
+ for r in clusterHelper.listOperationsOnNode(node):
|
|
||||||
+ ocf.logger.debug("noPendingResourcesOnNode: * %s" % r)
|
|
||||||
+ resource = r.split()[-1]
|
|
||||||
+ if resource == "pending":
|
|
||||||
+ ocf.logger.info("noPendingResourcesOnNode: found resource %s that is still pending" % resource)
|
|
||||||
+ ocf.logger.debug("noPendingResourcesOnNode: finished; return = False")
|
|
||||||
+ return False
|
|
||||||
+ ocf.logger.info("noPendingResourcesOnNode: no pending resources on node %s" % node)
|
|
||||||
+ ocf.logger.debug("noPendingResourcesOnNode: finished; return = True")
|
|
||||||
+
|
|
||||||
+ return True
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def allResourcesStoppedOnNode(node):
|
|
||||||
+ """
|
|
||||||
+ Check that all resources on a given node are stopped
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("allResourcesStoppedOnNode: begin; node = %s" % node)
|
|
||||||
+
|
|
||||||
+ if clusterHelper.noPendingResourcesOnNode(node):
|
|
||||||
+ if len(clusterHelper.transitionSummary()) == 0:
|
|
||||||
+ ocf.logger.info("allResourcesStoppedOnNode: no pending resources on node %s and empty transition summary" % node)
|
|
||||||
+ ocf.logger.debug("allResourcesStoppedOnNode: finished; return = True")
|
|
||||||
+ return True
|
|
||||||
+ ocf.logger.info("allResourcesStoppedOnNode: transition summary is not empty")
|
|
||||||
+ ocf.logger.debug("allResourcesStoppedOnNode: finished; return = False")
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
+ ocf.logger.info("allResourcesStoppedOnNode: still pending resources on node %s" % node)
|
|
||||||
+ ocf.logger.debug("allResourcesStoppedOnNode: finished; return = False")
|
|
||||||
+ return False
|
|
||||||
+
|
|
||||||
+##############################################################################
|
|
||||||
+
|
|
||||||
+AVAILABLE = 0 # Node is online and ready to handle events
|
|
||||||
+STOPPING = 1 # Standby has been triggered, but some resources are still running
|
|
||||||
+IN_EVENT = 2 # All resources are stopped, and event has been initiated via Azure Metadata Service
|
|
||||||
+ON_HOLD = 3 # Node has a pending event that cannot be started there are no other nodes available
|
|
||||||
+
|
|
||||||
+def stringToNodeState(name):
|
|
||||||
+ if type(name) == int: return name
|
|
||||||
+ if name == "STOPPING": return STOPPING
|
|
||||||
+ if name == "IN_EVENT": return IN_EVENT
|
|
||||||
+ if name == "ON_HOLD": return ON_HOLD
|
|
||||||
+ return AVAILABLE
|
|
||||||
+
|
|
||||||
+def nodeStateToString(state):
|
|
||||||
+ if state == STOPPING: return "STOPPING"
|
|
||||||
+ if state == IN_EVENT: return "IN_EVENT"
|
|
||||||
+ if state == ON_HOLD: return "ON_HOLD"
|
|
||||||
+ return "AVAILABLE"
|
|
||||||
+
|
|
||||||
+##############################################################################
|
|
||||||
+
|
|
||||||
+class Node:
|
|
||||||
+ """
|
|
||||||
+ Core class implementing logic for a cluster node
|
|
||||||
+ """
|
|
||||||
+ def __init__(self, ra):
|
|
||||||
+ self.raOwner = ra
|
|
||||||
+ self.azInfo = azHelper.getInstanceInfo()
|
|
||||||
+ self.azName = self.azInfo.name
|
|
||||||
+ self.hostName = socket.gethostname()
|
|
||||||
+ self.setAttr("azName", self.azName)
|
|
||||||
+ clusterHelper.setAttr("hostName_%s" % self.azName, self.hostName)
|
|
||||||
+
|
|
||||||
+ def getAttr(self, key):
|
|
||||||
+ """
|
|
||||||
+ Get a local attribute
|
|
||||||
+ """
|
|
||||||
+ return clusterHelper.getAttr(key, node=self.hostName)
|
|
||||||
+
|
|
||||||
+ def setAttr(self, key, value):
|
|
||||||
+ """
|
|
||||||
+ Set a local attribute
|
|
||||||
+ """
|
|
||||||
+ return clusterHelper.setAttr(key, value, node=self.hostName)
|
|
||||||
+
|
|
||||||
+ def selfOrOtherNode(self, node):
|
|
||||||
+ """
|
|
||||||
+ Helper function to distinguish self/other node
|
|
||||||
+ """
|
|
||||||
+ return node if node else self.hostName
|
|
||||||
+
|
|
||||||
+ def setState(self, state, node=None):
|
|
||||||
+ """
|
|
||||||
+ Set the state for a given node (or self)
|
|
||||||
+ """
|
|
||||||
+ node = self.selfOrOtherNode(node)
|
|
||||||
+ ocf.logger.debug("setState: begin; node = %s, state = %s" % (node, nodeStateToString(state)))
|
|
||||||
+
|
|
||||||
+ clusterHelper.setAttr(attr_curNodeState, nodeStateToString(state), node=node)
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("setState: finished")
|
|
||||||
+
|
|
||||||
+ def getState(self, node=None):
|
|
||||||
+ """
|
|
||||||
+ Get the state for a given node (or self)
|
|
||||||
+ """
|
|
||||||
+ node = self.selfOrOtherNode(node)
|
|
||||||
+ ocf.logger.debug("getState: begin; node = %s" % node)
|
|
||||||
+
|
|
||||||
+ state = clusterHelper.getAttr(attr_curNodeState, node=node)
|
|
||||||
+ ocf.logger.debug("getState: state = %s" % state)
|
|
||||||
+ ocf.logger.debug("getState: finished")
|
|
||||||
+ if not state:
|
|
||||||
+ return AVAILABLE
|
|
||||||
+ return stringToNodeState(state)
|
|
||||||
+
|
|
||||||
+ def setEventIDs(self, eventIDs, node=None):
|
|
||||||
+ """
|
|
||||||
+ Set pending EventIDs for a given node (or self)
|
|
||||||
+ """
|
|
||||||
+ node = self.selfOrOtherNode(node)
|
|
||||||
+ ocf.logger.debug("setEventIDs: begin; node = %s, eventIDs = %s" % (node, str(eventIDs)))
|
|
||||||
+
|
|
||||||
+ if eventIDs:
|
|
||||||
+ eventIDStr = ",".join(eventIDs)
|
|
||||||
+ else:
|
|
||||||
+ eventIDStr = None
|
|
||||||
+ clusterHelper.setAttr(attr_pendingEventIDs, eventIDStr, node=node)
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("setEventIDs: finished")
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ def getEventIDs(self, node=None):
|
|
||||||
+ """
|
|
||||||
+ Get pending EventIDs for a given node (or self)
|
|
||||||
+ """
|
|
||||||
+ node = self.selfOrOtherNode(node)
|
|
||||||
+ ocf.logger.debug("getEventIDs: begin; node = %s" % node)
|
|
||||||
+
|
|
||||||
+ eventIDStr = clusterHelper.getAttr(attr_pendingEventIDs, node=node)
|
|
||||||
+ if eventIDStr:
|
|
||||||
+ eventIDs = eventIDStr.split(",")
|
|
||||||
+ else:
|
|
||||||
+ eventIDs = None
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("getEventIDs: finished; eventIDs = %s" % str(eventIDs))
|
|
||||||
+ return eventIDs
|
|
||||||
+
|
|
||||||
+ def updateNodeStateAndEvents(self, state, eventIDs, node=None):
|
|
||||||
+ """
|
|
||||||
+ Set the state and pending EventIDs for a given node (or self)
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("updateNodeStateAndEvents: begin; node = %s, state = %s, eventIDs = %s" % (node, nodeStateToString(state), str(eventIDs)))
|
|
||||||
+
|
|
||||||
+ self.setState(state, node=node)
|
|
||||||
+ self.setEventIDs(eventIDs, node=node)
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("updateNodeStateAndEvents: finished")
|
|
||||||
+ return state
|
|
||||||
+
|
|
||||||
+ def putNodeStandby(self, node=None):
|
|
||||||
+ """
|
|
||||||
+ Put self to standby
|
|
||||||
+ """
|
|
||||||
+ node = self.selfOrOtherNode(node)
|
|
||||||
+ ocf.logger.debug("putNodeStandby: begin; node = %s" % node)
|
|
||||||
+
|
|
||||||
+ clusterHelper._exec("crm_attribute",
|
|
||||||
+ "--node", node,
|
|
||||||
+ "--name", attr_healthstate,
|
|
||||||
+ "--update", "-1000000",
|
|
||||||
+ "--lifetime=forever")
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("putNodeStandby: finished")
|
|
||||||
+
|
|
||||||
+ def isNodeInStandby(self, node=None):
|
|
||||||
+ """
|
|
||||||
+ check if node is in standby
|
|
||||||
+ """
|
|
||||||
+ node = self.selfOrOtherNode(node)
|
|
||||||
+ ocf.logger.debug("isNodeInStandby: begin; node = %s" % node)
|
|
||||||
+ isInStandy = False
|
|
||||||
+
|
|
||||||
+ healthAttributeStr = clusterHelper.getAttr(attr_healthstate, node)
|
|
||||||
+ if healthAttributeStr is not None:
|
|
||||||
+ try:
|
|
||||||
+ healthAttribute = int(healthAttributeStr)
|
|
||||||
+ isInStandy = healthAttribute < 0
|
|
||||||
+ except ValueError:
|
|
||||||
+ # Handle the exception
|
|
||||||
+ ocf.logger.warn("Health attribute %s on node %s cannot be converted to an integer value" % (healthAttributeStr, node))
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("isNodeInStandby: finished - result %s" % isInStandy)
|
|
||||||
+ return isInStandy
|
|
||||||
+
|
|
||||||
+ def putNodeOnline(self, node=None):
|
|
||||||
+ """
|
|
||||||
+ Put self back online
|
|
||||||
+ """
|
|
||||||
+ node = self.selfOrOtherNode(node)
|
|
||||||
+ ocf.logger.debug("putNodeOnline: begin; node = %s" % node)
|
|
||||||
+
|
|
||||||
+ clusterHelper._exec("crm_attribute",
|
|
||||||
+ "--node", node,
|
|
||||||
+ "--name", "#health-azure",
|
|
||||||
+ "--update", "0",
|
|
||||||
+ "--lifetime=forever")
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("putNodeOnline: finished")
|
|
||||||
+
|
|
||||||
+ def separateEvents(self, events):
|
|
||||||
+ """
|
|
||||||
+ Split own/other nodes' events
|
|
||||||
+ """
|
|
||||||
+ ocf.logger.debug("separateEvents: begin; events = %s" % str(events))
|
|
||||||
+
|
|
||||||
+ localEvents = []
|
|
||||||
+ remoteEvents = []
|
|
||||||
+ for e in events:
|
|
||||||
+ e = attrDict(e)
|
|
||||||
+ if e.EventType not in self.raOwner.relevantEventTypes:
|
|
||||||
+ continue
|
|
||||||
+ if self.azName in e.Resources:
|
|
||||||
+ localEvents.append(e)
|
|
||||||
+ else:
|
|
||||||
+ remoteEvents.append(e)
|
|
||||||
+ ocf.logger.debug("separateEvents: finished; localEvents = %s, remoteEvents = %s" % (str(localEvents), str(remoteEvents)))
|
|
||||||
+ return (localEvents, remoteEvents)
|
|
||||||
+
|
|
||||||
+##############################################################################
|
|
||||||
+
|
|
||||||
+class raAzEvents:
|
|
||||||
+ """
|
|
||||||
+ Main class for resource agent
|
|
||||||
+ """
|
|
||||||
+ def __init__(self, relevantEventTypes):
|
|
||||||
+ self.node = Node(self)
|
|
||||||
+ self.relevantEventTypes = relevantEventTypes
|
|
||||||
+
|
|
||||||
+ def monitor(self):
|
|
||||||
+ ocf.logger.debug("monitor: begin")
|
|
||||||
+
|
|
||||||
+ events = azHelper.pullScheduledEvents()
|
|
||||||
+
|
|
||||||
+ # get current document version
|
|
||||||
+ curDocVersion = events.DocumentIncarnation
|
|
||||||
+ lastDocVersion = self.node.getAttr(attr_lastDocVersion)
|
|
||||||
+ ocf.logger.debug("monitor: lastDocVersion = %s; curDocVersion = %s" % (lastDocVersion, curDocVersion))
|
|
||||||
+
|
|
||||||
+ # split events local/remote
|
|
||||||
+ (localEvents, remoteEvents) = self.node.separateEvents(events.Events)
|
|
||||||
+
|
|
||||||
+ # ensure local events are only executing once
|
|
||||||
+ if curDocVersion == lastDocVersion:
|
|
||||||
+ ocf.logger.info("monitor: already handled curDocVersion, skip")
|
|
||||||
+ return ocf.OCF_SUCCESS
|
|
||||||
+
|
|
||||||
+ localAzEventIDs = set()
|
|
||||||
+ for e in localEvents:
|
|
||||||
+ localAzEventIDs.add(e.EventId)
|
|
||||||
+
|
|
||||||
+ curState = self.node.getState()
|
|
||||||
+ clusterEventIDs = self.node.getEventIDs()
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("monitor: curDocVersion has not been handled yet")
|
|
||||||
+
|
|
||||||
+ if clusterEventIDs:
|
|
||||||
+ # there are pending events set, so our state must be STOPPING or IN_EVENT
|
|
||||||
+ i = 0; touchedEventIDs = False
|
|
||||||
+ while i < len(clusterEventIDs):
|
|
||||||
+ # clean up pending events that are already finished according to AZ
|
|
||||||
+ if clusterEventIDs[i] not in localAzEventIDs:
|
|
||||||
+ ocf.logger.info("monitor: remove finished local clusterEvent %s" % (clusterEventIDs[i]))
|
|
||||||
+ clusterEventIDs.pop(i)
|
|
||||||
+ touchedEventIDs = True
|
|
||||||
+ else:
|
|
||||||
+ i += 1
|
|
||||||
+ if len(clusterEventIDs) > 0:
|
|
||||||
+ # there are still pending events (either because we're still stopping, or because the event is still in place)
|
|
||||||
+ # either way, we need to wait
|
|
||||||
+ if touchedEventIDs:
|
|
||||||
+ ocf.logger.info("monitor: added new local clusterEvent %s" % str(clusterEventIDs))
|
|
||||||
+ self.node.setEventIDs(clusterEventIDs)
|
|
||||||
+ else:
|
|
||||||
+ ocf.logger.info("monitor: no local clusterEvents were updated")
|
|
||||||
+ else:
|
|
||||||
+ # there are no more pending events left after cleanup
|
|
||||||
+ if clusterHelper.noPendingResourcesOnNode(self.node.hostName):
|
|
||||||
+ # and no pending resources on the node -> set it back online
|
|
||||||
+ ocf.logger.info("monitor: all local events finished -> clean up, put node online and AVAILABLE")
|
|
||||||
+ curState = self.node.updateNodeStateAndEvents(AVAILABLE, None)
|
|
||||||
+ self.node.putNodeOnline()
|
|
||||||
+ clusterHelper.removeHoldFromNodes()
|
|
||||||
+ # If Azure Scheduled Events are not used for 24 hours (e.g. because the cluster was asleep), it will be disabled for a VM.
|
|
||||||
+ # When the cluster wakes up and starts using it again, the DocumentIncarnation is reset.
|
|
||||||
+ # We need to remove it during cleanup, otherwise azure-events-az will not process the event after wakeup
|
|
||||||
+ self.node.setAttr(attr_lastDocVersion, None)
|
|
||||||
+ else:
|
|
||||||
+ ocf.logger.info("monitor: all local events finished, but some resources have not completed startup yet -> wait")
|
|
||||||
+ else:
|
|
||||||
+ if curState == AVAILABLE:
|
|
||||||
+ if len(localAzEventIDs) > 0:
|
|
||||||
+ if clusterHelper.otherNodesAvailable(self.node):
|
|
||||||
+ ocf.logger.info("monitor: can handle local events %s -> set state STOPPING" % (str(localAzEventIDs)))
|
|
||||||
+ curState = self.node.updateNodeStateAndEvents(STOPPING, localAzEventIDs)
|
|
||||||
+ else:
|
|
||||||
+ ocf.logger.info("monitor: cannot handle azEvents %s (only node available) -> set state ON_HOLD" % str(localAzEventIDs))
|
|
||||||
+ self.node.setState(ON_HOLD)
|
|
||||||
+ else:
|
|
||||||
+ ocf.logger.debug("monitor: no local azEvents to handle")
|
|
||||||
+
|
|
||||||
+ if curState == STOPPING:
|
|
||||||
+ eventIDsForNode = {}
|
|
||||||
+ if clusterHelper.noPendingResourcesOnNode(self.node.hostName):
|
|
||||||
+ if not self.node.isNodeInStandby():
|
|
||||||
+ ocf.logger.info("monitor: all local resources are started properly -> put node standby and exit")
|
|
||||||
+ self.node.putNodeStandby()
|
|
||||||
+ return ocf.OCF_SUCCESS
|
|
||||||
+
|
|
||||||
+ for e in localEvents:
|
|
||||||
+ ocf.logger.info("monitor: handling remote event %s (%s; nodes = %s)" % (e.EventId, e.EventType, str(e.Resources)))
|
|
||||||
+ # before we can force an event to start, we need to ensure all nodes involved have stopped their resources
|
|
||||||
+ if e.EventStatus == "Scheduled":
|
|
||||||
+ allNodesStopped = True
|
|
||||||
+ for azName in e.Resources:
|
|
||||||
+ hostName = clusterHelper.getHostNameFromAzName(azName)
|
|
||||||
+ state = self.node.getState(node=hostName)
|
|
||||||
+ if state == STOPPING:
|
|
||||||
+ # the only way we can continue is when node state is STOPPING, but all resources have been stopped
|
|
||||||
+ if not clusterHelper.allResourcesStoppedOnNode(hostName):
|
|
||||||
+ ocf.logger.info("monitor: (at least) node %s has still resources running -> wait" % hostName)
|
|
||||||
+ allNodesStopped = False
|
|
||||||
+ break
|
|
||||||
+ elif state in (AVAILABLE, IN_EVENT, ON_HOLD):
|
|
||||||
+ ocf.logger.info("monitor: node %s is still %s -> remote event needs to be picked up locally" % (hostName, nodeStateToString(state)))
|
|
||||||
+ allNodesStopped = False
|
|
||||||
+ break
|
|
||||||
+ if allNodesStopped:
|
|
||||||
+ ocf.logger.info("monitor: nodes %s are stopped -> add remote event %s to force list" % (str(e.Resources), e.EventId))
|
|
||||||
+ for n in e.Resources:
|
|
||||||
+ hostName = clusterHelper.getHostNameFromAzName(n)
|
|
||||||
+ if hostName in eventIDsForNode:
|
|
||||||
+ eventIDsForNode[hostName].append(e.EventId)
|
|
||||||
+ else:
|
|
||||||
+ eventIDsForNode[hostName] = [e.EventId]
|
|
||||||
+ elif e.EventStatus == "Started":
|
|
||||||
+ ocf.logger.info("monitor: remote event already started")
|
|
||||||
+
|
|
||||||
+ # force the start of all events whose nodes are ready (i.e. have no more resources running)
|
|
||||||
+ if len(eventIDsForNode.keys()) > 0:
|
|
||||||
+ eventIDsToForce = set([item for sublist in eventIDsForNode.values() for item in sublist])
|
|
||||||
+ ocf.logger.info("monitor: set nodes %s to IN_EVENT; force remote events %s" % (str(eventIDsForNode.keys()), str(eventIDsToForce)))
|
|
||||||
+ for node, eventId in eventIDsForNode.items():
|
|
||||||
+ self.node.updateNodeStateAndEvents(IN_EVENT, eventId, node=node)
|
|
||||||
+ azHelper.forceEvents(eventIDsToForce)
|
|
||||||
+ self.node.setAttr(attr_lastDocVersion, curDocVersion)
|
|
||||||
+ else:
|
|
||||||
+ ocf.logger.info("monitor: some local resources are not clean yet -> wait")
|
|
||||||
+
|
|
||||||
+ ocf.logger.debug("monitor: finished")
|
|
||||||
+ return ocf.OCF_SUCCESS
|
|
||||||
+
|
|
||||||
+##############################################################################
|
|
||||||
+
|
|
||||||
+def setLoglevel(verbose):
|
|
||||||
+ # set up writing into syslog
|
|
||||||
+ loglevel = default_loglevel
|
|
||||||
+ if verbose:
|
|
||||||
+ opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1))
|
|
||||||
+ urllib2.install_opener(opener)
|
|
||||||
+ loglevel = ocf.logging.DEBUG
|
|
||||||
+ ocf.log.setLevel(loglevel)
|
|
||||||
+
|
|
||||||
+description = (
|
|
||||||
+ "Microsoft Azure Scheduled Events monitoring agent",
|
|
||||||
+ """This resource agent implements a monitor for scheduled
|
|
||||||
+(maintenance) events for a Microsoft Azure VM.
|
|
||||||
+
|
|
||||||
+If any relevant events are found, it moves all Pacemaker resources
|
|
||||||
+away from the affected node to allow for a graceful shutdown.
|
|
||||||
+
|
|
||||||
+ Usage:
|
|
||||||
+ [OCF_RESKEY_eventTypes=VAL] [OCF_RESKEY_verbose=VAL] azure-events-az ACTION
|
|
||||||
+
|
|
||||||
+ action (required): Supported values: monitor, help, meta-data
|
|
||||||
+ eventTypes (optional): List of event types to be considered
|
|
||||||
+ relevant by the resource agent (comma-separated).
|
|
||||||
+ Supported values: Freeze,Reboot,Redeploy
|
|
||||||
+ Default = Reboot,Redeploy
|
|
||||||
+/ verbose (optional): If set to true, displays debug info.
|
|
||||||
+ Default = false
|
|
||||||
+
|
|
||||||
+ Deployment:
|
|
||||||
+ crm configure primitive rsc_azure-events-az ocf:heartbeat:azure-events-az \
|
|
||||||
+ op monitor interval=10s
|
|
||||||
+ crm configure clone cln_azure-events-az rsc_azure-events-az
|
|
||||||
+
|
|
||||||
+For further information on Microsoft Azure Scheduled Events, please
|
|
||||||
+refer to the following documentation:
|
|
||||||
+https://docs.microsoft.com/en-us/azure/virtual-machines/linux/scheduled-events
|
|
||||||
+""")
|
|
||||||
+
|
|
||||||
+def monitor_action(eventTypes):
|
|
||||||
+ relevantEventTypes = set(eventTypes.split(",") if eventTypes else [])
|
|
||||||
+ ra = raAzEvents(relevantEventTypes)
|
|
||||||
+ return ra.monitor()
|
|
||||||
+
|
|
||||||
+def validate_action(eventTypes):
|
|
||||||
+ if eventTypes:
|
|
||||||
+ for event in eventTypes.split(","):
|
|
||||||
+ if event not in ("Freeze", "Reboot", "Redeploy"):
|
|
||||||
+ ocf.ocf_exit_reason("Event type not one of Freeze, Reboot, Redeploy: " + eventTypes)
|
|
||||||
+ return ocf.OCF_ERR_CONFIGURED
|
|
||||||
+ return ocf.OCF_SUCCESS
|
|
||||||
+
|
|
||||||
+def main():
|
|
||||||
+ agent = ocf.Agent("azure-events-az", shortdesc=description[0], longdesc=description[1])
|
|
||||||
+ agent.add_parameter(
|
|
||||||
+ "eventTypes",
|
|
||||||
+ shortdesc="List of resources to be considered",
|
|
||||||
+ longdesc="A comma-separated list of event types that will be handled by this resource agent. (Possible values: Freeze,Reboot,Redeploy)",
|
|
||||||
+ content_type="string",
|
|
||||||
+ default="Reboot,Redeploy")
|
|
||||||
+ agent.add_parameter(
|
|
||||||
+ "verbose",
|
|
||||||
+ shortdesc="Enable verbose agent logging",
|
|
||||||
+ longdesc="Set to true to enable verbose logging",
|
|
||||||
+ content_type="boolean",
|
|
||||||
+ default="false")
|
|
||||||
+ agent.add_action("start", timeout=10, handler=lambda: ocf.OCF_SUCCESS)
|
|
||||||
+ agent.add_action("stop", timeout=10, handler=lambda: ocf.OCF_SUCCESS)
|
|
||||||
+ agent.add_action("validate-all", timeout=20, handler=validate_action)
|
|
||||||
+ agent.add_action("monitor", timeout=240, interval=10, handler=monitor_action)
|
|
||||||
+ setLoglevel(ocf.is_true(ocf.get_parameter("verbose", "false")))
|
|
||||||
+ agent.run()
|
|
||||||
+
|
|
||||||
+if __name__ == '__main__':
|
|
||||||
+ main()
|
|
||||||
\ No newline at end of file
|
|
||||||
|
|
||||||
From a95337d882c7cc69d604b050159ad50b679f18be Mon Sep 17 00:00:00 2001
|
|
||||||
From: MSSedusch <sedusch@microsoft.com>
|
|
||||||
Date: Thu, 2 Jun 2022 14:10:33 +0200
|
|
||||||
Subject: [PATCH 2/2] Remove developer documentation
|
|
||||||
|
|
||||||
---
|
|
||||||
heartbeat/azure-events-az.in | 11 -----------
|
|
||||||
1 file changed, 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/heartbeat/azure-events-az.in b/heartbeat/azure-events-az.in
|
|
||||||
index 616fc8d9e..59d095306 100644
|
|
||||||
--- a/heartbeat/azure-events-az.in
|
|
||||||
+++ b/heartbeat/azure-events-az.in
|
|
||||||
@@ -723,17 +723,6 @@ description = (
|
|
||||||
If any relevant events are found, it moves all Pacemaker resources
|
|
||||||
away from the affected node to allow for a graceful shutdown.
|
|
||||||
|
|
||||||
- Usage:
|
|
||||||
- [OCF_RESKEY_eventTypes=VAL] [OCF_RESKEY_verbose=VAL] azure-events-az ACTION
|
|
||||||
-
|
|
||||||
- action (required): Supported values: monitor, help, meta-data
|
|
||||||
- eventTypes (optional): List of event types to be considered
|
|
||||||
- relevant by the resource agent (comma-separated).
|
|
||||||
- Supported values: Freeze,Reboot,Redeploy
|
|
||||||
- Default = Reboot,Redeploy
|
|
||||||
-/ verbose (optional): If set to true, displays debug info.
|
|
||||||
- Default = false
|
|
||||||
-
|
|
||||||
Deployment:
|
|
||||||
crm configure primitive rsc_azure-events-az ocf:heartbeat:azure-events-az \
|
|
||||||
op monitor interval=10s
|
|
@ -1,147 +0,0 @@
|
|||||||
From 237d55120a7c8d761f839c96651e722b3bb3bc88 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
|
||||||
Date: Wed, 12 Oct 2022 13:57:30 +0200
|
|
||||||
Subject: [PATCH 1/4] IPsrcaddr: fix PROTO regex
|
|
||||||
|
|
||||||
---
|
|
||||||
heartbeat/IPsrcaddr | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/heartbeat/IPsrcaddr b/heartbeat/IPsrcaddr
|
|
||||||
index 7dbf65ff5..24406d296 100755
|
|
||||||
--- a/heartbeat/IPsrcaddr
|
|
||||||
+++ b/heartbeat/IPsrcaddr
|
|
||||||
@@ -188,7 +188,7 @@ IPADDR="\($OCTET\.\)\{3\}$OCTET"
|
|
||||||
SRCCLAUSE="src$WS$WS*\($IPADDR\)"
|
|
||||||
MATCHROUTE="\(.*${WS}\)\($SRCCLAUSE\)\($WS.*\|$\)"
|
|
||||||
METRICCLAUSE=".*\(metric$WS[^ ]\+\)"
|
|
||||||
-PROTOCLAUSE=".*\(proto$WS[^ ]\+\)"
|
|
||||||
+PROTOCLAUSE=".*\(proto$WS[^ ]\+\).*"
|
|
||||||
FINDIF=findif
|
|
||||||
|
|
||||||
# findif needs that to be set
|
|
||||||
|
|
||||||
From c70ba457851a401cb201cb87d23bdbc5f4fcd2b3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
|
||||||
Date: Wed, 12 Oct 2022 14:00:30 +0200
|
|
||||||
Subject: [PATCH 2/4] IPsrcaddr: detect metric for main table only, and allow
|
|
||||||
specifying metric if necessary
|
|
||||||
|
|
||||||
---
|
|
||||||
heartbeat/IPsrcaddr | 18 +++++++++++++++++-
|
|
||||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/heartbeat/IPsrcaddr b/heartbeat/IPsrcaddr
|
|
||||||
index 24406d296..4745eb8a7 100755
|
|
||||||
--- a/heartbeat/IPsrcaddr
|
|
||||||
+++ b/heartbeat/IPsrcaddr
|
|
||||||
@@ -59,12 +59,14 @@ OCF_RESKEY_ipaddress_default=""
|
|
||||||
OCF_RESKEY_cidr_netmask_default=""
|
|
||||||
OCF_RESKEY_destination_default="0.0.0.0/0"
|
|
||||||
OCF_RESKEY_proto_default=""
|
|
||||||
+OCF_RESKEY_metric_default=""
|
|
||||||
OCF_RESKEY_table_default=""
|
|
||||||
|
|
||||||
: ${OCF_RESKEY_ipaddress=${OCF_RESKEY_ipaddress_default}}
|
|
||||||
: ${OCF_RESKEY_cidr_netmask=${OCF_RESKEY_cidr_netmask_default}}
|
|
||||||
: ${OCF_RESKEY_destination=${OCF_RESKEY_destination_default}}
|
|
||||||
: ${OCF_RESKEY_proto=${OCF_RESKEY_proto_default}}
|
|
||||||
+: ${OCF_RESKEY_metric=${OCF_RESKEY_metric_default}}
|
|
||||||
: ${OCF_RESKEY_table=${OCF_RESKEY_table_default}}
|
|
||||||
#######################################################################
|
|
||||||
|
|
||||||
@@ -143,6 +145,14 @@ Proto to match when finding network. E.g. "kernel".
|
|
||||||
<content type="string" default="${OCF_RESKEY_proto_default}" />
|
|
||||||
</parameter>
|
|
||||||
|
|
||||||
+<parameter name="metric">
|
|
||||||
+<longdesc lang="en">
|
|
||||||
+Metric. Only needed if incorrect metric value is used.
|
|
||||||
+</longdesc>
|
|
||||||
+<shortdesc lang="en">Metric</shortdesc>
|
|
||||||
+<content type="string" default="${OCF_RESKEY_metric_default}" />
|
|
||||||
+</parameter>
|
|
||||||
+
|
|
||||||
<parameter name="table">
|
|
||||||
<longdesc lang="en">
|
|
||||||
Table to modify. E.g. "local".
|
|
||||||
@@ -548,8 +558,14 @@ rc=$?
|
|
||||||
|
|
||||||
INTERFACE=`echo $findif_out | awk '{print $1}'`
|
|
||||||
LISTROUTE=`$IP2UTIL route list dev $INTERFACE scope link $PROTO match $ipaddress`
|
|
||||||
-METRIC=`echo $LISTROUTE | sed -n "s/$METRICCLAUSE/\1/p"`
|
|
||||||
[ -z "$PROTO" ] && PROTO=`echo $LISTROUTE | sed -n "s/$PROTOCLAUSE/\1/p"`
|
|
||||||
+if [ -n "$OCF_RESKEY_metric" ]; then
|
|
||||||
+ METRIC="metric $OCF_RESKEY_metric"
|
|
||||||
+elif [ -z "$TABLE" ] || [ "${TABLE#table }" = "main" ]; then
|
|
||||||
+ METRIC=`echo $LISTROUTE | sed -n "s/$METRICCLAUSE/\1/p"`
|
|
||||||
+else
|
|
||||||
+ METRIC=""
|
|
||||||
+fi
|
|
||||||
if [ "$OCF_RESKEY_destination" = "0.0.0.0/0" ] ;then
|
|
||||||
NETWORK=`echo $LISTROUTE | grep -m 1 -o '^[^ ]*'`
|
|
||||||
|
|
||||||
|
|
||||||
From c514f12f7a19440f475938f2a4659e5e9667fa25 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
|
||||||
Date: Wed, 12 Oct 2022 14:01:26 +0200
|
|
||||||
Subject: [PATCH 3/4] IPsrcaddr: use scope host when using non-main tables
|
|
||||||
|
|
||||||
---
|
|
||||||
heartbeat/IPsrcaddr | 8 +++++++-
|
|
||||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/heartbeat/IPsrcaddr b/heartbeat/IPsrcaddr
|
|
||||||
index 4745eb8a7..926246008 100755
|
|
||||||
--- a/heartbeat/IPsrcaddr
|
|
||||||
+++ b/heartbeat/IPsrcaddr
|
|
||||||
@@ -279,8 +279,14 @@ srca_stop() {
|
|
||||||
|
|
||||||
[ $rc = 2 ] && errorexit "The address you specified to stop does not match the preferred source address"
|
|
||||||
|
|
||||||
+ if [ -z "$TABLE" ] || [ "${TABLE#table }" = "main" ]; then
|
|
||||||
+ SCOPE="link"
|
|
||||||
+ else
|
|
||||||
+ SCOPE="host"
|
|
||||||
+ fi
|
|
||||||
+
|
|
||||||
PRIMARY_IP="$($IP2UTIL -4 -o addr show dev $INTERFACE primary | awk '{split($4,a,"/");print a[1]}')"
|
|
||||||
- OPTS="proto kernel scope link src $PRIMARY_IP"
|
|
||||||
+ OPTS="proto kernel scope $SCOPE src $PRIMARY_IP"
|
|
||||||
|
|
||||||
$IP2UTIL route replace $TABLE $NETWORK dev $INTERFACE $OPTS $METRIC || \
|
|
||||||
errorexit "command 'ip route replace $TABLE $NETWORK dev $INTERFACE $OPTS $METRIC' failed"
|
|
||||||
|
|
||||||
From 1f387ac8017b3eee23b41eadafd58ce21a29eb21 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
|
|
||||||
Date: Thu, 13 Oct 2022 13:11:28 +0200
|
|
||||||
Subject: [PATCH 4/4] IPsrcaddr: fix monitor/status for default route not being
|
|
||||||
equal to src IP before start, and change route src correctly in stop-action
|
|
||||||
|
|
||||||
---
|
|
||||||
heartbeat/IPsrcaddr | 5 +++--
|
|
||||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/heartbeat/IPsrcaddr b/heartbeat/IPsrcaddr
|
|
||||||
index 926246008..1bd41a930 100755
|
|
||||||
--- a/heartbeat/IPsrcaddr
|
|
||||||
+++ b/heartbeat/IPsrcaddr
|
|
||||||
@@ -229,6 +229,7 @@ srca_read() {
|
|
||||||
|
|
||||||
[ -z "$SRCIP" ] && return 1
|
|
||||||
[ $SRCIP = $1 ] && return 0
|
|
||||||
+ [ "$__OCF_ACTION" = "monitor" ] || [ "$__OCF_ACTION" = "status" ] && [ "${ROUTE%% *}" = "default" ] && return 1
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -292,8 +293,8 @@ srca_stop() {
|
|
||||||
errorexit "command 'ip route replace $TABLE $NETWORK dev $INTERFACE $OPTS $METRIC' failed"
|
|
||||||
|
|
||||||
if [ "$OCF_RESKEY_destination" = "0.0.0.0/0" ] ;then
|
|
||||||
- $CMDCHANGE $ROUTE_WO_SRC || \
|
|
||||||
- errorexit "command '$CMDCHANGE $ROUTE_WO_SRC' failed"
|
|
||||||
+ $CMDCHANGE $ROUTE_WO_SRC src $PRIMARY_IP || \
|
|
||||||
+ errorexit "command '$CMDCHANGE $ROUTE_WO_SRC src $PRIMARY_IP' failed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return $?
|
|
@ -45,7 +45,7 @@
|
|||||||
Name: resource-agents
|
Name: resource-agents
|
||||||
Summary: Open Source HA Reusable Cluster Resource Scripts
|
Summary: Open Source HA Reusable Cluster Resource Scripts
|
||||||
Version: 4.10.0
|
Version: 4.10.0
|
||||||
Release: 9%{?rcver:%{rcver}}%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist}.5
|
Release: 23%{?rcver:%{rcver}}%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist}
|
||||||
License: GPLv2+ and LGPLv2+
|
License: GPLv2+ and LGPLv2+
|
||||||
URL: https://github.com/ClusterLabs/resource-agents
|
URL: https://github.com/ClusterLabs/resource-agents
|
||||||
Source0: %{upstream_prefix}-%{upstream_version}.tar.gz
|
Source0: %{upstream_prefix}-%{upstream_version}.tar.gz
|
||||||
@ -61,9 +61,23 @@ Patch8: bz2055016-1-IPsrcaddr-dhcp-warning.patch
|
|||||||
Patch9: bz2055016-2-IPsrcaddr-error-message-route-not-found.patch
|
Patch9: bz2055016-2-IPsrcaddr-error-message-route-not-found.patch
|
||||||
Patch10: bz2055016-3-IPsrcaddr-fix-indentation.patch
|
Patch10: bz2055016-3-IPsrcaddr-fix-indentation.patch
|
||||||
Patch11: bz2055016-4-IPsrcaddr-fixes.patch
|
Patch11: bz2055016-4-IPsrcaddr-fixes.patch
|
||||||
Patch12: bz2087930-NovaEvacuate-add-user_domain-project_domain.patch
|
Patch12: bz2069270-corosync-qnetd-new-ra.patch
|
||||||
Patch13: bz2130990-azure-events-az-new-ra.patch
|
Patch13: bz2065125-LVM-activate-fix-fence-issue.patch
|
||||||
Patch14: bz2134542-IPsrcaddr-proto-metric-scope-default-route-fixes.patch
|
Patch14: bz2065138-IPaddr2-enable-more-control-for-IPv6-addresses.patch
|
||||||
|
Patch15: bz2072371-Filesystem-1-fix-uuid-label-device-whitespace.patch
|
||||||
|
Patch16: bz2072371-Filesystem-2-improve-uuid-label-device-logic.patch
|
||||||
|
Patch17: bz2083081-bz2083086-bz2083090-bz2083092-update-openstack-agents.patch
|
||||||
|
Patch18: bz2081585-NovaEvacuate-add-user_domain-project_domain.patch
|
||||||
|
Patch19: bz2094828-lvmlockd-fail-when-use_lvmlockd-not-set.patch
|
||||||
|
Patch20: bz2093213-aws-vpc-move-ip-add-interface-label-support.patch
|
||||||
|
Patch21: bz2063877-all-agents-use-promotable-terms.patch
|
||||||
|
Patch22: bz2083090-openstack-info-fix-bashism.patch
|
||||||
|
Patch23: bz2083081-bz2083086-bz2083092-openstack-agents-fixes.patch
|
||||||
|
Patch24: bz2083081-bz2083086-bz2083090-bz2083092-openstack-agents-warn-when-openstackcli-slow.patch
|
||||||
|
Patch25: bz2083081-bz2083086-bz2083090-bz2083092-openstack-agents-set-domain-parameters-default.patch
|
||||||
|
Patch26: bz2103374-ocf-tester-1-update.patch
|
||||||
|
Patch27: bz2103374-ocf-tester-2-remove-deprecated-lrmd-lrmadmin-code.patch
|
||||||
|
Patch28: bz2110452-ethmonitor-ovsmonitor-pgsql-fix-attrd_updater-q.patch
|
||||||
|
|
||||||
# bundled ha-cloud-support libs
|
# bundled ha-cloud-support libs
|
||||||
Patch500: ha-cloud-support-aws.patch
|
Patch500: ha-cloud-support-aws.patch
|
||||||
@ -118,7 +132,7 @@ Requires: /sbin/fsck
|
|||||||
Requires: /usr/sbin/fsck.ext2 /usr/sbin/fsck.ext3 /usr/sbin/fsck.ext4
|
Requires: /usr/sbin/fsck.ext2 /usr/sbin/fsck.ext3 /usr/sbin/fsck.ext4
|
||||||
Requires: /usr/sbin/fsck.xfs
|
Requires: /usr/sbin/fsck.xfs
|
||||||
Requires: /sbin/mount.nfs /sbin/mount.nfs4
|
Requires: /sbin/mount.nfs /sbin/mount.nfs4
|
||||||
%if 0%{?fedora} < 33 || (0%{?rhel} && 0%{?rhel} < 9) || (0%{?centos} && 0%{?centos} < 9) || 0%{?suse_version}
|
%if (0%{?fedora} && 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)
|
%if (0%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8)
|
||||||
Requires: /usr/sbin/mount.cifs
|
Requires: /usr/sbin/mount.cifs
|
||||||
%else
|
%else
|
||||||
@ -202,6 +216,20 @@ exit 1
|
|||||||
%patch12 -p1
|
%patch12 -p1
|
||||||
%patch13 -p1
|
%patch13 -p1
|
||||||
%patch14 -p1
|
%patch14 -p1
|
||||||
|
%patch15 -p1
|
||||||
|
%patch16 -p1
|
||||||
|
%patch17 -p1
|
||||||
|
%patch18 -p1
|
||||||
|
%patch19 -p1
|
||||||
|
%patch20 -p1
|
||||||
|
%patch21 -p1
|
||||||
|
%patch22 -p1
|
||||||
|
%patch23 -p1
|
||||||
|
%patch24 -p1
|
||||||
|
%patch25 -p1
|
||||||
|
%patch26 -p1
|
||||||
|
%patch27 -p1
|
||||||
|
%patch28 -p1
|
||||||
|
|
||||||
# bundled ha-cloud-support libs
|
# bundled ha-cloud-support libs
|
||||||
%patch500 -p1
|
%patch500 -p1
|
||||||
@ -314,6 +342,7 @@ rm -rf %{buildroot}/usr/share/doc/resource-agents
|
|||||||
%exclude %{_datadir}/%{name}/ocft/runocft
|
%exclude %{_datadir}/%{name}/ocft/runocft
|
||||||
%exclude %{_datadir}/%{name}/ocft/runocft.prereq
|
%exclude %{_datadir}/%{name}/ocft/runocft.prereq
|
||||||
|
|
||||||
|
%{_sbindir}/ocf-tester
|
||||||
%{_sbindir}/ocft
|
%{_sbindir}/ocft
|
||||||
|
|
||||||
%{_includedir}/heartbeat
|
%{_includedir}/heartbeat
|
||||||
@ -325,6 +354,7 @@ rm -rf %{buildroot}/usr/share/doc/resource-agents
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%{_mandir}/man7/*.7*
|
%{_mandir}/man7/*.7*
|
||||||
|
%{_mandir}/man8/ocf-tester.8*
|
||||||
|
|
||||||
###
|
###
|
||||||
# Supported, but in another sub package
|
# Supported, but in another sub package
|
||||||
@ -398,10 +428,6 @@ rm -rf %{buildroot}/usr/share/doc/resource-agents
|
|||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/mpathpersist
|
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/mpathpersist
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/mysql-proxy
|
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/mysql-proxy
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/nvmet-*
|
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/nvmet-*
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/openstack-cinder-volume
|
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/openstack-floating-ip
|
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/openstack-info
|
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/openstack-virtual-ip
|
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/ovsmonitor
|
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/ovsmonitor
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/pgagent
|
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/pgagent
|
||||||
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/pingd
|
%exclude %{_usr}/lib/ocf/resource.d/heartbeat/pingd
|
||||||
@ -466,10 +492,6 @@ rm -rf %{buildroot}/usr/share/doc/resource-agents
|
|||||||
%exclude %{_mandir}/man7/ocf_heartbeat_mpathpersist.7.gz
|
%exclude %{_mandir}/man7/ocf_heartbeat_mpathpersist.7.gz
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_mysql-proxy.7.gz
|
%exclude %{_mandir}/man7/ocf_heartbeat_mysql-proxy.7.gz
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_nvmet-*.7.gz
|
%exclude %{_mandir}/man7/ocf_heartbeat_nvmet-*.7.gz
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_openstack-cinder-volume.7.gz
|
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_openstack-floating-ip.7.gz
|
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_openstack-info.7.gz
|
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_openstack-virtual-ip.7.gz
|
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_ovsmonitor.7.gz
|
%exclude %{_mandir}/man7/ocf_heartbeat_ovsmonitor.7.gz
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_pgagent.7.gz
|
%exclude %{_mandir}/man7/ocf_heartbeat_pgagent.7.gz
|
||||||
%exclude %{_mandir}/man7/ocf_heartbeat_pingd.7.gz
|
%exclude %{_mandir}/man7/ocf_heartbeat_pingd.7.gz
|
||||||
@ -490,9 +512,6 @@ rm -rf %{buildroot}/usr/share/doc/resource-agents
|
|||||||
###
|
###
|
||||||
# Other excluded files.
|
# Other excluded files.
|
||||||
###
|
###
|
||||||
# This tool has to be updated for the new pacemaker lrmd.
|
|
||||||
%exclude %{_sbindir}/ocf-tester
|
|
||||||
%exclude %{_mandir}/man8/ocf-tester.8*
|
|
||||||
# ldirectord is not supported
|
# ldirectord is not supported
|
||||||
%exclude /etc/ha.d/resource.d/ldirectord
|
%exclude /etc/ha.d/resource.d/ldirectord
|
||||||
%exclude %{_sysconfdir}/init.d/ldirectord
|
%exclude %{_sysconfdir}/init.d/ldirectord
|
||||||
@ -532,22 +551,61 @@ rm -rf %{buildroot}/usr/share/doc/resource-agents
|
|||||||
%{_usr}/lib/ocf/lib/heartbeat/OCF_*.pm
|
%{_usr}/lib/ocf/lib/heartbeat/OCF_*.pm
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Fri Oct 14 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-9.5
|
* Tue Jul 26 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-23
|
||||||
- IPsrcaddr: proto, metric, scope and default route fixes
|
- ethmonitor/pgsql: remove attrd_updater "-q" parameter to solve issue
|
||||||
|
with Pacemaker 2.1.3+ not ignoring it
|
||||||
|
|
||||||
Resolves: rhbz#2134542
|
Resolves: rhbz#2110452
|
||||||
|
|
||||||
* Tue Oct 4 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-9.4
|
* Thu Jul 14 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-22
|
||||||
- azure-events-az: new resource agent
|
- ocf-tester: add testing tool
|
||||||
|
|
||||||
Resolves: rhbz#2130990
|
Resolves: rhbz#2103374
|
||||||
|
|
||||||
* Thu Jun 9 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-9.3
|
* Thu Jul 14 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-20
|
||||||
|
- openstack-cinder-volume/openstack-floating-ip/openstack-info/
|
||||||
|
openstack-virtual-ip: new resource agents
|
||||||
|
|
||||||
|
Resolves: rhbz#2083081, rhbz#2083086, rhbz#2083090, rhbz#2083092
|
||||||
|
|
||||||
|
* Mon Jun 20 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-18
|
||||||
|
- all agents: use promotable terms
|
||||||
|
|
||||||
|
Resolves: rhbz#2063877
|
||||||
|
|
||||||
|
* Thu Jun 9 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-17
|
||||||
|
- lvmlockd: fail when use_lvmlockd has not been set
|
||||||
|
- aws-vpc-move-ip: add interface label support
|
||||||
|
|
||||||
|
Resolves: rhbz#2094828
|
||||||
|
Resolves: rhbz#2093213
|
||||||
|
|
||||||
|
* Tue May 17 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-15
|
||||||
- NovaEvacuate: add user_domain and project_domain parameters
|
- NovaEvacuate: add user_domain and project_domain parameters
|
||||||
|
|
||||||
Resolves: rhbz#2087930
|
Resolves: rhbz#2081585
|
||||||
|
|
||||||
* Thu Mar 3 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-9
|
* Thu Apr 21 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-12
|
||||||
|
- Filesystem: fix UUID/label device support when there's whitespace
|
||||||
|
between parameter and UUID/label
|
||||||
|
|
||||||
|
Resolves: rhbz#2072371
|
||||||
|
|
||||||
|
* Tue Apr 5 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-11
|
||||||
|
- LVM-activate: use correct return code to fence failed node
|
||||||
|
- IPaddr2: enable more control for IPv6 addresses
|
||||||
|
|
||||||
|
Resolves: rhbz#2065125
|
||||||
|
Resolves: rhbz#2065138
|
||||||
|
|
||||||
|
* Tue Mar 29 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-10
|
||||||
|
- corosync-qnetd: new resource agent
|
||||||
|
- spec: remove Samba/CIFS dependency
|
||||||
|
|
||||||
|
Resolves: rhbz#2069270
|
||||||
|
Resolves: rhbz#1826455
|
||||||
|
|
||||||
|
* Thu Mar 3 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-8
|
||||||
- IPsrcaddr: add warning about possible issues when used with DHCP,
|
- IPsrcaddr: add warning about possible issues when used with DHCP,
|
||||||
and add error message when matching route not found
|
and add error message when matching route not found
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user