diff --git a/SOURCES/bz1471182-crypt-1-new-ra.patch b/SOURCES/bz1471182-crypt-1-new-ra.patch
new file mode 100644
index 0000000..7ed08b5
--- /dev/null
+++ b/SOURCES/bz1471182-crypt-1-new-ra.patch
@@ -0,0 +1,415 @@
+From 019c3108feff48d8ad496cd0759349c46170dc2d Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Mon, 6 Apr 2020 10:23:51 +0200
+Subject: [PATCH 1/2] crypt: new resource agent
+
+---
+ doc/man/Makefile.am   |   1 +
+ heartbeat/Makefile.am |   1 +
+ heartbeat/crypt       | 337 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 339 insertions(+)
+ create mode 100755 heartbeat/crypt
+
+diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
+index 478fbe4f8..53c9975ec 100644
+--- a/doc/man/Makefile.am
++++ b/doc/man/Makefile.am
+@@ -105,6 +105,7 @@ man_MANS                = ocf_heartbeat_AoEtarget.7 \
+                           ocf_heartbeat_azure-lb.7 \
+                           ocf_heartbeat_clvm.7 \
+                           ocf_heartbeat_conntrackd.7 \
++                          ocf_heartbeat_crypt.7 \
+                           ocf_heartbeat_db2.7 \
+                           ocf_heartbeat_dhcpd.7 \
+                           ocf_heartbeat_docker.7 \
+diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am
+index 893115810..bbc9590ac 100644
+--- a/heartbeat/Makefile.am
++++ b/heartbeat/Makefile.am
+@@ -101,6 +101,7 @@ ocf_SCRIPTS	      = AoEtarget		\
+ 			azure-lb		\
+ 			clvm			\
+ 			conntrackd		\
++			crypt			\
+ 			db2			\
+ 			dhcpd			\
+ 			dnsupdate		\
+diff --git a/heartbeat/crypt b/heartbeat/crypt
+new file mode 100755
+index 000000000..6bffdff89
+--- /dev/null
++++ b/heartbeat/crypt
+@@ -0,0 +1,337 @@
++#!/bin/sh
++#
++#	crypt/LUKS OCF RA. Manages cryptsetup devices.
++#
++# Copyright (c) 2020 Red Hat GmbH, Heinz Mauelshagen
++#                    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
++
++# Parameter defaults
++OCF_RESKEY_encrypted_dev_default=""
++OCF_RESKEY_crypt_dev_default=""
++OCF_RESKEY_key_file_default=""
++OCF_RESKEY_crypt_type_default=""
++OCF_RESKEY_force_stop_default="false"
++
++: ${OCF_RESKEY_encrypted_dev=${OCF_RESKEY_encrypted_dev_default}}
++: ${OCF_RESKEY_crypt_dev=${OCF_RESKEY_crypt_dev_default}}
++: ${OCF_RESKEY_key_file=${OCF_RESKEY_key_file_default}}
++: ${OCF_RESKEY_crypt_type=${OCF_RESKEY_crypt_type_default}}
++: ${OCF_RESKEY_force_stop=${OCF_RESKEY_force_stop_default}}
++
++#######################################################################
++
++meta_data() {
++	cat <<END
++<?xml version="1.0"?>
++<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
++<resource-agent name="crypt">
++<version>1.0</version>
++
++<longdesc lang="en">
++This is a LUKS/crypt Resource Agent managing encrypted devices via cryptsetup(8).
++The agent imposes limitations on device types supported: luks, luks[1..N].
++</longdesc>
++<shortdesc lang="en">LUKS/crypt resource agent</shortdesc>
++
++<parameters>
++
++<parameter name="encrypted_dev" unique="1" required="1">
++<longdesc lang="en">
++Encrypted backing device, which should be defined by UUID,
++36 characters including '-'s as reported by blkid(8).
++
++Although it can be defined as a block device path (e.g. /dev/sdh),
++the UUID should be preferred over the block device path to allow for the
++unique discovery of the crypt backing device given the volatile nature of
++/dev entries (e.g. /dev/sdh on one node may be /dev/sdg on another).
++
++Only define as block device path if you know what you are doing.
++</longdesc>
++<shortdesc lang="en">Encrypted device</shortdesc>
++<content type="string" default="${OCF_RESKEY_encrypted_dev_default}" />
++</parameter>
++
++<parameter name="crypt_dev" unique="1" required="1">
++<longdesc lang="en">
++Encrypted device name, no path.  I.e. the one given in "cryptsetup open name ...".
++The resulting block device path is /dev/mapper/name.
++</longdesc>
++<shortdesc lang="en">Encrypted device</shortdesc>
++<content type="string" default="${OCF_RESKEY_crypt_dev_default}" />
++</parameter>
++
++<parameter name="key_file" unique="1" required="1">
++<longdesc lang="en">
++Key file path containing the encryption passphrase
++(aka key; see cryptsetup(8)).  For LUKS, the passphrase as of the key_file
++parameter is used to decrypt a randomly selected key when the device was created.
++</longdesc>
++<shortdesc lang="en">Key file</shortdesc>
++<content type="string" default="${OCF_RESKEY_key_file_default}" />
++</parameter>
++
++<parameter name="crypt_type" unique="1" required="1">
++<longdesc lang="en">
++Encryption (device) type (e.g. "luks" or "luks2").
++
++This parameter affirms the encryption format as of the crypt metadata
++thus allowing for safety measures when starting the encrypted resource.
++</longdesc>
++<shortdesc lang="en">Encryption type</shortdesc>
++<content type="string" default="${OCF_RESKEY_crypt_type_default}" />
++</parameter>
++
++<parameter name="force_stop" unique="0" required="0">
++<longdesc lang="en">
++If processes or kernel threads are using the crypt device, it cannot
++be stopped. We will try to stop processes, first by sending TERM and
++then, if that doesn't help in $PROC_CLEANUP_TIME seconds, using KILL.
++The lsof(8) program is required to get the list of array users.
++Of course, the kernel threads cannot be stopped this way.
++If the processes are critical for data integrity, then set this
++parameter to false. Note that in that case the stop operation
++will fail and the node will be fenced.
++</longdesc>
++<shortdesc lang="en">force stop processes using the crpyt device</shortdesc>
++<content type="boolean" default="${OCF_RESKEY_force_stop_default}" />
++</parameter>
++
++</parameters>
++
++<actions>
++<action name="start"        timeout="20s" />
++<action name="stop"         timeout="20s" />
++<action name="monitor"      timeout="20s" interval="10s" depth="0" />
++<action name="meta-data"    timeout="5s" />
++<action name="validate-all" timeout="10s" />
++</actions>
++</resource-agent>
++END
++}
++
++# Disable cryptsetup auto-recovery if cloned.
++disable_locks=""
++ocf_is_clone && disable_locks="--disable-locks"
++
++crypt_usage() {
++	cat <<END
++usage: $0 {start|stop|monitor|usage|meta-data|validate-all}
++
++Expects to have a fully populated OCF RA-compliant environment set.
++END
++}
++
++encrypted_dev="${OCF_RESKEY_encrypted_dev}"
++crypt_dev="${OCF_RESKEY_crypt_dev}"
++crypt_dev_path="/dev/mapper/$crypt_dev"
++key_file="${OCF_RESKEY_key_file}"
++crypt_type="${OCF_RESKEY_crypt_type}"
++force_stop="${OCF_RESKEY_force_stop}"
++
++crypt_validate_all() {
++	if ! have_binary cryptsetup; then
++		ocf_exit_reason "Please install cryptsetup(8)"
++		return $OCF_ERR_INSTALLED
++	fi
++	if [ -z "$encrypted_dev" ]; then
++		ocf_exit_reason "Undefined OCF_RESKEY_encrypted_dev"
++		return $OCF_ERR_CONFIGURED
++	fi
++	if [ -n "$encrypted_dev" ]; then
++		case "$encrypted_dev" in
++		*-*-*-*) if [ `echo "$encrypted_dev" | wc -c` -ne 37 ]; then
++				ocf_exit_reason "Bogus encrypted device UUID \"$encrypted_dev\""
++				return $OCF_ERR_ARGS
++			 fi
++			 encrypted_dev=/dev/disk/by-uuid/"$encrypted_dev";;
++		*)	 case "$encrypted_dev" in
++			 /dev/*) ;;
++			 *)	ocf_exit_reason "Bogus encrypted device path"
++				return $OCF_ERR_ARGS;;
++			 esac
++		esac
++	fi
++	if [ ! -b "$encrypted_dev" ]; then
++		ocf_exit_reason "Encrypted device $encrypted_dev not accessible"
++		return $OCF_ERR_ARGS
++	fi
++	echo "$crypt_dev" | grep "/" >/dev/null
++	if [ $? -eq 0 ] &&  [ -z "$crypt_dev" ]; then
++		ocf_exit_reason "Crypt device \"$crypt_dev\" name has to at least 1 character long and without path"
++		return $OCF_ERR_ARGS
++	fi
++	if [ ! -r "$key_file" ]; then
++		ocf_exit_reason "Hash key file $key_file not accessible"
++		return $OCF_ERR_ARGS
++	fi
++	if ! ocf_is_true "$force_stop"  && "$force_stop" != "false" ]]; then
++		ocf_exit_reason "Bogus force_stop=\"$force_stop\" attribute"
++		return $OCF_ERR_CONFIGURED
++	fi
++	if "$force_stop" = "true" && ! have_binary lsof; then
++		ocf_exit_reason "Force stop requested, please install lsof(8)"
++		return $OCF_ERR_INSTALLED
++	fi
++	cryptsetup isLuks $encrypted_dev 2>/dev/null
++	if [ $? -ne 0 ]; then
++		ocf_exit_reason "$encrypted_dev is not a Luks formatted device"
++		return $OCF_ERR_CONFIGURED
++	fi
++
++	return $OCF_SUCCESS
++}
++
++get_users_pids() {
++	ocf_log debug "running lsof to list \"$crypt_dev\" users..."
++	ocf_run -warn 'lsof $crypt_dev_path | tail -n +2 | awk "{print $2}" | sort -u'
++}
++
++stop_crypt_users() {
++	local pids=`get_users_pids`
++
++	if [ -z "$pids" ]; then
++		ocf_log warn "lsof reported no users holding arrays"
++		return 2
++	fi
++
++	ocf_stop_processes TERM $PROC_CLEANUP_TIME $pids
++}
++
++show_users() {
++	local dm_dev
++
++	ocf_log info "running lsof to list \"$crypt_dev\" users..."
++	ocf_run -warn lsof $crypt_dev_path
++
++	dm_dev=$(basename $(realpath $crypt_dev_path))
++	if [ -d /sys/block/$dm_dev/holders ]; then
++		ocf_log debug "ls -l /sys/block/$dm_dev/holders"
++		ocf_run -warn ls -l /sys/block/$dm_dev/holders
++	fi
++}
++
++crypt_stop_one() {
++	cryptsetup close $crypt_dev $disable_locks
++}
++
++#######################################################################
++#
++# Action: START an encrypted resource
++#
++crypt_start() {
++	local rc
++
++	cryptsetup open $encrypted_dev $crypt_dev --type $crypt_type $disable_locks --key-file=$key_file
++	rc=$?
++	if [ $rc -eq 0 ];then
++		crypt_monitor
++		rc=$?
++	else
++		rc=$OCF_ERR_GERNERIC
++	fi
++	[ $rc -ne $OCF_SUCCESS ] ocf_exit_reason "Failed to start encrypted device \"$crypt_dev\""
++
++	return $rc
++}
++
++#
++# Action: STOP an encrypted resource
++#
++crypt_stop() {
++	local rc
++
++	crypt_monitor
++	rc=$?
++	if [ $rc -ne $OCF_NOT_RUNNING ]; then
++		crypt_stop_one
++		crypt_monitor
++		rc=$?
++	fi
++	if [ $rc -ne $OCF_NOT_RUNNING ] && ocf_is_true $FORCESTOP; then
++		stop_crypt_users
++		case $? in
++		2) rc=$OCF_SUCCESS;;
++		*) crypt_stop_one
++		   crypt_monitor
++		   rc=$?;;
++		esac
++	fi
++	if [ $rc -ne $OCF_NOT_RUNNING ]; then
++		ocf_log warn "Couldn't stop crypt device \"$crypt_dev\" (rc=$rc)"
++		show_users
++		ocf_exit_reason "Failed to stop crypt device \"$crypt_dev\"!"
++		return $OCF_ERR_GENERIC
++	fi
++
++	return $OCF_SUCCESS
++}
++
++#
++# Action: MONITOR an encrypted resource
++#
++crypt_monitor() {
++	cryptsetup status $crypt_dev $disable_locks &>/dev/null
++	if [ $? -eq 0 ]; then
++		[ -L $crypt_dev_path ] && return $OCF_SUCCESS
++		return $OCF_ERR_GENERIC
++	fi
++
++        [ "$__OCF_ACTION" = "monitor" ] && ! ocf_is_probe && ocf_exit_reason "Crypt resource not running"
++	return $OCF_NOT_RUNNING
++}
++
++# Check for stange argument count.
++if [ $# -ne 1 ]; then
++	usage
++	exit $OCF_ERR_ARGS
++fi
++
++case "$__OCF_ACTION" in
++meta-data)	meta_data
++		exit $OCF_SUCCESS;;
++usage|help)	crypt_usage
++		exit $OCF_SUCCESS;;
++esac
++
++# XME: remove once pacemaker is fixed and calls this action
++crypt_validate_all
++rc=$?
++[ $rc -ne $OCF_SUCCESS ] && exit $rc
++
++case "$__OCF_ACTION" in
++start)		crypt_start; rc=$?;;
++stop)		crypt_stop; rc=$?;;
++monitor)	crypt_monitor; rc=$?;;
++validate-all)	rc=$OCF_SUCCESS;; # crypt_validate_all would have errored out above already.
++*)		crypt_usage
++		exit $OCF_ERR_UNIMPLEMENTED;;
++esac
++
++ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc"
++exit $rc
+
+From 5e0d35f8db967419ea9f1234ab621b88babcf3ea Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Tue, 7 Apr 2020 12:39:24 +0200
+Subject: [PATCH 2/2] crypt: force_stop check fixes
+
+---
+ heartbeat/crypt | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/heartbeat/crypt b/heartbeat/crypt
+index 6bffdff89..8bfa1094d 100755
+--- a/heartbeat/crypt
++++ b/heartbeat/crypt
+@@ -190,11 +190,7 @@ crypt_validate_all() {
+ 		ocf_exit_reason "Hash key file $key_file not accessible"
+ 		return $OCF_ERR_ARGS
+ 	fi
+-	if ! ocf_is_true "$force_stop"  && "$force_stop" != "false" ]]; then
+-		ocf_exit_reason "Bogus force_stop=\"$force_stop\" attribute"
+-		return $OCF_ERR_CONFIGURED
+-	fi
+-	if "$force_stop" = "true" && ! have_binary lsof; then
++	if ocf_is_true "$force_stop" && ! have_binary lsof; then
+ 		ocf_exit_reason "Force stop requested, please install lsof(8)"
+ 		return $OCF_ERR_INSTALLED
+ 	fi
+@@ -273,7 +269,7 @@ crypt_stop() {
+ 		crypt_monitor
+ 		rc=$?
+ 	fi
+-	if [ $rc -ne $OCF_NOT_RUNNING ] && ocf_is_true $FORCESTOP; then
++	if [ $rc -ne $OCF_NOT_RUNNING ] && ocf_is_true $force_stop; then
+ 		stop_crypt_users
+ 		case $? in
+ 		2) rc=$OCF_SUCCESS;;
diff --git a/SOURCES/bz1471182-crypt-2-fix-bashism.patch b/SOURCES/bz1471182-crypt-2-fix-bashism.patch
new file mode 100644
index 0000000..dace36f
--- /dev/null
+++ b/SOURCES/bz1471182-crypt-2-fix-bashism.patch
@@ -0,0 +1,22 @@
+From 2915fa336e95b609d3d738d335799f015022c493 Mon Sep 17 00:00:00 2001
+From: Valentin Vidic <vvidic@valentin-vidic.from.hr>
+Date: Sat, 13 Jun 2020 08:47:36 +0200
+Subject: [PATCH] crypt: fix bashism
+
+---
+ heartbeat/crypt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/heartbeat/crypt b/heartbeat/crypt
+index 8bfa1094d..2727b5b23 100755
+--- a/heartbeat/crypt
++++ b/heartbeat/crypt
+@@ -292,7 +292,7 @@ crypt_stop() {
+ # Action: MONITOR an encrypted resource
+ #
+ crypt_monitor() {
+-	cryptsetup status $crypt_dev $disable_locks &>/dev/null
++	cryptsetup status $crypt_dev $disable_locks >/dev/null 2>&1
+ 	if [ $? -eq 0 ]; then
+ 		[ -L $crypt_dev_path ] && return $OCF_SUCCESS
+ 		return $OCF_ERR_GENERIC
diff --git a/SOURCES/bz1471182-crypt-3-fix-missing-and.patch b/SOURCES/bz1471182-crypt-3-fix-missing-and.patch
new file mode 100644
index 0000000..8a0deaf
--- /dev/null
+++ b/SOURCES/bz1471182-crypt-3-fix-missing-and.patch
@@ -0,0 +1,22 @@
+From 635c344fb85ef225b8a0c094687d2838b0b0cd2c Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Mon, 26 Oct 2020 16:36:06 +0100
+Subject: [PATCH] crypt: fix missing && to set exit_reason
+
+---
+ heartbeat/crypt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/heartbeat/crypt b/heartbeat/crypt
+index 2727b5b23..0e49b6c2d 100755
+--- a/heartbeat/crypt
++++ b/heartbeat/crypt
+@@ -251,7 +251,7 @@ crypt_start() {
+ 	else
+ 		rc=$OCF_ERR_GERNERIC
+ 	fi
+-	[ $rc -ne $OCF_SUCCESS ] ocf_exit_reason "Failed to start encrypted device \"$crypt_dev\""
++	[ $rc -ne $OCF_SUCCESS ] && ocf_exit_reason "Failed to start encrypted device \"$crypt_dev\""
+ 
+ 	return $rc
+ }
diff --git a/SOURCES/bz1640587-pgsql-ignore-masters-re-promote.patch b/SOURCES/bz1640587-pgsql-ignore-masters-re-promote.patch
new file mode 100644
index 0000000..b371857
--- /dev/null
+++ b/SOURCES/bz1640587-pgsql-ignore-masters-re-promote.patch
@@ -0,0 +1,40 @@
+From 355cd29f2dee828bfe0a4ab64f425827aba7dd3b Mon Sep 17 00:00:00 2001
+From: Hideo Yamauchi <renayama19661014@ybb.ne.jp>
+Date: Wed, 17 Oct 2018 09:54:37 +0900
+Subject: [PATCH] Mid: pgsql: Fix to ignore Master's re-promote.
+
+---
+ heartbeat/pgsql | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/heartbeat/pgsql b/heartbeat/pgsql
+index 380866da1..38f6ceeb7 100755
+--- a/heartbeat/pgsql
++++ b/heartbeat/pgsql
+@@ -680,6 +680,7 @@ pgsql_start() {
+ 
+ #pgsql_promote: Promote PostgreSQL
+ pgsql_promote() {
++    local output
+     local target
+     local rc
+ 
+@@ -687,6 +688,18 @@ pgsql_promote() {
+         ocf_exit_reason "Not in a replication mode."
+         return $OCF_ERR_CONFIGURED
+     fi
++
++    output=`exec_sql "${CHECK_MS_SQL}"`
++    if [ $? -ne 0 ]; then
++        report_psql_error $rc $loglevel "Can't get PostgreSQL recovery status on promote."
++        return $OCF_ERR_GENERIC
++    fi
++
++    if [ "$output" = "f" ]; then
++        ocf_log info "PostgreSQL is alredy Master. Don't execute promote."
++        return $OCF_SUCCESS
++    fi
++
+     rm -f ${XLOG_NOTE_FILE}.*
+ 
+     for target in $NODE_LIST; do
diff --git a/SOURCES/bz1763249-manpages-fix-pcs-syntax.patch b/SOURCES/bz1763249-manpages-fix-pcs-syntax.patch
new file mode 100644
index 0000000..eff376b
--- /dev/null
+++ b/SOURCES/bz1763249-manpages-fix-pcs-syntax.patch
@@ -0,0 +1,53 @@
+From 0903a60930238238d5caa6c3b42b28d7bc4cccf4 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Mon, 26 Oct 2020 13:11:05 +0100
+Subject: [PATCH 1/2] man: use promotable keyword in manpage examples
+
+---
+ doc/man/ra2refentry.xsl | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/doc/man/ra2refentry.xsl b/doc/man/ra2refentry.xsl
+index d0535fd36..f3cdcdbb2 100644
+--- a/doc/man/ra2refentry.xsl
++++ b/doc/man/ra2refentry.xsl
+@@ -556,7 +556,7 @@
+      <!-- Insert a master/slave set definition if the resource
+       agent supports promotion and demotion -->
+       <xsl:if test="actions/action/@name = 'promote' and actions/action/@name = 'demote'">
+-          <xsl:text>--master</xsl:text>
++          <xsl:text>promotable</xsl:text>
+       </xsl:if>
+       </programlisting>
+ 
+
+From bfcd5796ae12e6a43a245d0c785f183342943393 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Mon, 26 Oct 2020 16:56:00 +0100
+Subject: [PATCH 2/2] man: use OCF_CHECK_LEVEL for depth parameters in pcs
+ examples
+
+---
+ doc/man/ra2refentry.xsl | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/doc/man/ra2refentry.xsl b/doc/man/ra2refentry.xsl
+index f3cdcdbb2..f8e12321f 100644
+--- a/doc/man/ra2refentry.xsl
++++ b/doc/man/ra2refentry.xsl
+@@ -612,7 +612,14 @@
+     <xsl:choose>
+       <xsl:when test="name() = 'name'"><!-- suppress --></xsl:when>
+       <xsl:otherwise>
+-        <xsl:value-of select="name()"/>
++        <xsl:choose>
++          <xsl:when test="name() != 'depth'">
++          <xsl:value-of select="name()"/>
++          </xsl:when>
++          <xsl:otherwise>
++            <xsl:text>OCF_CHECK_LEVEL</xsl:text>
++          </xsl:otherwise>
++        </xsl:choose>
+         <xsl:text>="</xsl:text>
+         <xsl:value-of select="current()"/>
+         <xsl:text>" </xsl:text>
diff --git a/SOURCES/bz1795535-pgsql-1-add-postgresql-12-support.patch b/SOURCES/bz1795535-pgsql-1-add-postgresql-12-support.patch
new file mode 100644
index 0000000..3c05aba
--- /dev/null
+++ b/SOURCES/bz1795535-pgsql-1-add-postgresql-12-support.patch
@@ -0,0 +1,105 @@
+From a43075be72683e1d4ddab700ec16d667164d359c Mon Sep 17 00:00:00 2001
+From: Kazutomo Nakahira <kazutomo_nakahira@newson.co.jp>
+Date: Mon, 25 Nov 2019 17:40:33 +0900
+Subject: [PATCH 1/2] High: pgsql: Support for PostgreSQL 12
+
+---
+ heartbeat/pgsql | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/heartbeat/pgsql b/heartbeat/pgsql
+index b1c070ead..5bc76cc4c 100755
+--- a/heartbeat/pgsql
++++ b/heartbeat/pgsql
+@@ -1612,12 +1612,24 @@ make_recovery_conf() {
+     fi
+ 
+ cat > $RECOVERY_CONF <<END
+-standby_mode = 'on'
+ primary_conninfo = 'host=${OCF_RESKEY_master_ip} port=${OCF_RESKEY_pgport} user=${OCF_RESKEY_repuser} application_name=${NODENAME} ${OCF_RESKEY_primary_conninfo_opt}'
+ restore_command = '${OCF_RESKEY_restore_command}'
+ recovery_target_timeline = 'latest'
+ END
+ 
++    if "${USE_STANDBY_SIGNAL}"; then
++        # create a standby.signal to start standby server.
++        runasowner "touch ${OCF_RESKEY_pgdata}/standby.signal"
++        if [ $? -ne 0 ]; then
++            ocf_exit_reason "Can't create ${OCF_RESKEY_pgdata}/standby.signal."
++            return 1
++        fi
++    else
++cat >> $RECOVERY_CONF <<END
++standby_mode = 'on'
++END
++    fi
++
+     user_recovery_conf >> $RECOVERY_CONF
+     ocf_log debug "Created recovery.conf. host=${OCF_RESKEY_master_ip}, user=${OCF_RESKEY_repuser}"
+     return 0
+@@ -1835,6 +1847,7 @@ pgsql_validate_all() {
+     local version
+     local check_config_rc
+     local rep_mode_string
++    local recovery_conf_string
+     local socket_directories
+     local rc
+ 
+@@ -1898,6 +1911,22 @@ pgsql_validate_all() {
+             ocf_exit_reason "Replication mode needs PostgreSQL 9.1 or higher."
+             return $OCF_ERR_INSTALLED
+         fi
++        ocf_version_cmp "$version" "12"
++        rc=$?
++        if [ $rc -eq 1 ]||[ $rc -eq 2 ]; then
++            # change the standby method for PosrgreSQL 12 or later.
++            USE_STANDBY_SIGNAL=true
++            # change the path to recovery.conf because it cause PostgreSQL start error.
++            RECOVERY_CONF=${OCF_RESKEY_tmpdir}/recovery.conf
++            if [ $check_config_rc -eq 0 ]; then
++                # adding recovery parameters to postgresql.conf.
++                recovery_conf_string="include '$RECOVERY_CONF' # added by pgsql RA"
++                if ! grep -q "^[[:space:]]*$recovery_conf_string" $OCF_RESKEY_config; then
++                    ocf_log info "adding include directive $recovery_conf_string into $OCF_RESKEY_config"
++                    echo "$recovery_conf_string" >> $OCF_RESKEY_config
++                fi
++            fi
++        fi
+         if [ ! -n "$OCF_RESKEY_master_ip" ]; then
+             ocf_exit_reason "master_ip can't be empty."
+             return $OCF_ERR_CONFIGURED
+@@ -2107,6 +2136,7 @@ RESOURCE_NAME=`echo $OCF_RESOURCE_INSTANCE | cut -d ":" -f 1`
+ PGSQL_WAL_RECEIVER_STATUS_ATTR="${RESOURCE_NAME}-receiver-status"
+ RECOVERY_CONF=${OCF_RESKEY_pgdata}/recovery.conf
+ NODENAME=$(ocf_local_nodename | tr '[A-Z]' '[a-z]')
++USE_STANDBY_SIGNAL=false
+ 
+ case "$1" in
+     methods)    pgsql_methods
+
+From 5ab3339e8cb236583d375f5577f5a4dc129d5b27 Mon Sep 17 00:00:00 2001
+From: munenari <munenari@gmail.com>
+Date: Thu, 16 Jan 2020 09:27:59 +0900
+Subject: [PATCH 2/2] Remove standby.signal when promote with restart
+
+---
+ heartbeat/pgsql | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/heartbeat/pgsql b/heartbeat/pgsql
+index 5bc76cc4c..d5baa7b35 100755
+--- a/heartbeat/pgsql
++++ b/heartbeat/pgsql
+@@ -720,7 +720,11 @@ pgsql_promote() {
+         ocf_log info "Restarting PostgreSQL instead of promote."
+         #stop : this function returns $OCF_SUCCESS only.
+         pgsql_real_stop slave
+-        rm -f $RECOVERY_CONF
++        if "${USE_STANDBY_SIGNAL}"; then
++            rm -f ${OCF_RESKEY_pgdata}/standby.signal
++        else
++            rm -f $RECOVERY_CONF
++        fi
+         pgsql_real_start
+         rc=$?
+         if [ $rc -ne $OCF_RUNNING_MASTER ]; then
diff --git a/SOURCES/bz1795535-pgsql-2-fix-uppercase-hostname-support.patch b/SOURCES/bz1795535-pgsql-2-fix-uppercase-hostname-support.patch
new file mode 100644
index 0000000..06c9aef
--- /dev/null
+++ b/SOURCES/bz1795535-pgsql-2-fix-uppercase-hostname-support.patch
@@ -0,0 +1,48 @@
+From e56d0e1727bf84d0664db544a129a0237a1757c0 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Fri, 11 Sep 2020 10:12:21 +0200
+Subject: [PATCH 1/2] pgsql: lower-case application_name to avoid issues with
+ upper-case hostnames
+
+---
+ heartbeat/pgsql | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/heartbeat/pgsql b/heartbeat/pgsql
+index 99e074287..de9f750c5 100755
+--- a/heartbeat/pgsql
++++ b/heartbeat/pgsql
+@@ -1960,7 +1960,7 @@ pgsql_validate_all() {
+         else
+             CHECK_XLOG_LOC_SQL="select pg_last_xlog_replay_location(),pg_last_xlog_receive_location()"
+         fi
+-        CHECK_REPLICATION_STATE_SQL="select application_name,upper(state),upper(sync_state) from pg_stat_replication"
++        CHECK_REPLICATION_STATE_SQL="select lower(application_name),upper(state),upper(sync_state) from pg_stat_replication"
+ 
+         PGSQL_STATUS_ATTR="${RESOURCE_NAME}-status"
+         PGSQL_DATA_STATUS_ATTR="${RESOURCE_NAME}-data-status"
+
+From 5aee799878180bb8daca82aebc2290c2735045eb Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Fri, 11 Sep 2020 10:13:47 +0200
+Subject: [PATCH 2/2] pgsql: set exit-reason when failing due to remaining
+ PGSQL.lock
+
+---
+ heartbeat/pgsql | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/heartbeat/pgsql b/heartbeat/pgsql
+index de9f750c5..5a0628b7a 100755
+--- a/heartbeat/pgsql
++++ b/heartbeat/pgsql
+@@ -966,6 +966,9 @@ pgsql_real_monitor() {
+     if ! pgsql_status
+     then
+         ocf_log info "PostgreSQL is down"
++        if [ "$__OCF_ACTION" = "monitor" ] && ! ocf_is_probe && [ -f $PGSQL_LOCK ]; then
++            ocf_exit_reason "My data may be inconsistent. You have to remove $PGSQL_LOCK file to force start."
++        fi
+         return $OCF_NOT_RUNNING
+     fi
+ 
diff --git a/SOURCES/bz1815013-redis-parse-password-correctly-based-on-version.patch b/SOURCES/bz1815013-redis-parse-password-correctly-based-on-version.patch
new file mode 100644
index 0000000..c61a306
--- /dev/null
+++ b/SOURCES/bz1815013-redis-parse-password-correctly-based-on-version.patch
@@ -0,0 +1,169 @@
+From 2270c5d6aaf8b3b6d663d413a8e7193a493cfdc5 Mon Sep 17 00:00:00 2001
+From: Konstantin Pokotilenko <pokotilenko@mail.ru>
+Date: Tue, 24 Sep 2019 17:26:11 +0300
+Subject: [PATCH 1/2] Consider redis-cli features to choose optimal password
+ passing method and warning filtering workaround
+
+---
+ heartbeat/redis.in | 60 +++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 57 insertions(+), 3 deletions(-)
+
+diff --git a/heartbeat/redis.in b/heartbeat/redis.in
+index ec7186d8b..409961d0b 100644
+--- a/heartbeat/redis.in
++++ b/heartbeat/redis.in
+@@ -237,6 +237,51 @@ CRM_ATTR_REPL_INFO="${HA_SBIN_DIR}/crm_attribute --type crm_config --name ${INST
+ MASTER_HOST=""
+ MASTER_ACTIVE_CACHED=""
+ MASTER_ACTIVE=""
++CLI_HAVE_AUTH_WARNING=0
++CLI_HAVE_ARG_NO_AUTH_WARNING=0
++CLI_HAVE_ENV_AUTH=0
++
++cmp_redis_version()
++{
++
++        if [ "$1" == "$2" ]; then
++                return 1
++        elif [ $(echo -e "$1\n$2" | sort -V | head -1) == "$1" ]; then
++                return 0
++        else
++                return 2
++        fi
++}
++
++redis_cli_features()
++{
++
++        CLI_VER=$(redis-cli --version | tr " " "\n" | tail -1)
++        # Starting with 4.0.10 there is a warning on stderr when using a pass
++        # Starting with 5.0.0 there is an argument to silence the warning: --no-auth-warning
++        # Starting with 5.0.3 there is an option to use REDISCLI_AUTH evironment variable for password, no warning in this case
++
++        cmp_redis_version $CLI_VER 5.0.3
++        res=$?
++        echo 5.0.3: $res
++        if [[ res -ge 1 ]]; then
++                CLI_HAVE_ENV_AUTH=1
++        fi
++
++        cmp_redis_version $CLI_VER 5.0.0
++        res=$?
++        echo 5.0.0: $res
++        if [[ res -ge 1 ]]; then
++                CLI_HAVE_ARG_NO_AUTH_WARNING=1
++        fi
++
++        cmp_redis_version $CLI_VER 4.0.10
++        res=$?
++        echo 4.0.10: $res
++        if [[ res -ge 1 ]]; then
++                CLI_HAVE_AUTH_WARNING=1
++        fi
++}
+ 
+ master_is_active()
+ {
+@@ -315,9 +360,16 @@ set_score()
+ redis_client() {
+ 	ocf_log debug "redis_client: '$REDIS_CLIENT' -s '$REDIS_SOCKET' $*"
+ 	if [ -n "$clientpasswd" ]; then
+-		# Starting with 4.0.10 there is a warning on stderr when using a pass
+-		# Once we stop supporting versions < 5.0.0 we can add --no-auth-warning here
+-		("$REDIS_CLIENT" -s "$REDIS_SOCKET" -a "$clientpasswd" "$@" 2>&1 >&3 3>&- | grep -v "Using a password" >&2 3>&-) 3>&1 | sed 's/\r//'
++		# Consider redis-cli features to choose optimal password passing method and warning filtering workaround
++		if [[ CLI_HAVE_ENV_AUTH -eq 1 ]]; then
++			REDISCLI_AUTH=$clientpasswd "$REDIS_CLIENT" -s "$REDIS_SOCKET" "$@" | sed 's/\r//'
++		elif [[ CLI_HAVE_ARG_NO_AUTH_WARNING -eq 1 ]]; then
++			"$REDIS_CLIENT" -s "$REDIS_SOCKET" -a "$clientpasswd" "$@" --no-auth-warning | sed 's/\r//'
++		elif [[ CLI_HAVE_AUTH_WARNING -eq 1 ]]; then
++			("$REDIS_CLIENT" -s "$REDIS_SOCKET" -a "$clientpasswd" "$@" 2>&1 >&3 3>&- | grep -v "Using a password" >&2 3>&-) 3>&1 | sed 's/\r//'
++		else
++			"$REDIS_CLIENT" -s "$REDIS_SOCKET" -a "$clientpasswd" "$@" | sed 's/\r//'
++		fi
+ 	else
+ 		"$REDIS_CLIENT" -s "$REDIS_SOCKET" "$@" | sed 's/\r//'
+ 	fi
+@@ -686,6 +738,8 @@ if [ -r "$REDIS_CONFIG" ]; then
+ 	clientpasswd="$(sed -n -e  's/^\s*requirepass\s*\(.*\)\s*$/\1/p' < $REDIS_CONFIG | tail -n 1)"
+ fi
+ 
++redis_cli_features
++
+ ocf_log debug "action=${1:-$__OCF_ACTION} notify_type=${OCF_RESKEY_CRM_meta_notify_type} notify_operation=${OCF_RESKEY_CRM_meta_notify_operation} master_host=${OCF_RESKEY_CRM_meta_notify_master_uname} slave_host=${OCF_RESKEY_CRM_meta_notify_slave_uname} promote_host=${OCF_RESKEY_CRM_meta_notify_promote_uname} demote_host=${OCF_RESKEY_CRM_meta_notify_demote_uname}; params: bin=${OCF_RESKEY_bin} client_bin=${OCF_RESKEY_client_bin} config=${OCF_RESKEY_config} user=${OCF_RESKEY_user} rundir=${OCF_RESKEY_rundir} port=${OCF_RESKEY_port}"
+ 
+ case "${1:-$__OCF_ACTION}" in
+
+From 0b9f942a88bfc3ad04938aa5135fad8f8bece69c Mon Sep 17 00:00:00 2001
+From: Konstantin Pokotilenko <pokotilenko@mail.ru>
+Date: Tue, 24 Sep 2019 18:35:59 +0300
+Subject: [PATCH 2/2] use ocf_version_cmp instead of own implementation use
+ same method of getting redis-cli version as already used before in file, this
+ also uses redis client from variable instead of hardcoded remove debug output
+ fix --no-auth-warning argument position
+
+---
+ heartbeat/redis.in | 25 +++++--------------------
+ 1 file changed, 5 insertions(+), 20 deletions(-)
+
+diff --git a/heartbeat/redis.in b/heartbeat/redis.in
+index 409961d0b..d722fb12c 100644
+--- a/heartbeat/redis.in
++++ b/heartbeat/redis.in
+@@ -241,43 +241,28 @@ CLI_HAVE_AUTH_WARNING=0
+ CLI_HAVE_ARG_NO_AUTH_WARNING=0
+ CLI_HAVE_ENV_AUTH=0
+ 
+-cmp_redis_version()
+-{
+-
+-        if [ "$1" == "$2" ]; then
+-                return 1
+-        elif [ $(echo -e "$1\n$2" | sort -V | head -1) == "$1" ]; then
+-                return 0
+-        else
+-                return 2
+-        fi
+-}
+-
+ redis_cli_features()
+ {
+ 
+-        CLI_VER=$(redis-cli --version | tr " " "\n" | tail -1)
++        CLI_VER=$("$REDIS_CLIENT" -v | awk '{print $NF}')
+         # Starting with 4.0.10 there is a warning on stderr when using a pass
+         # Starting with 5.0.0 there is an argument to silence the warning: --no-auth-warning
+         # Starting with 5.0.3 there is an option to use REDISCLI_AUTH evironment variable for password, no warning in this case
+ 
+-        cmp_redis_version $CLI_VER 5.0.3
++        ocf_version_cmp $CLI_VER 5.0.3
+         res=$?
+-        echo 5.0.3: $res
+         if [[ res -ge 1 ]]; then
+                 CLI_HAVE_ENV_AUTH=1
+         fi
+ 
+-        cmp_redis_version $CLI_VER 5.0.0
++        ocf_version_cmp $CLI_VER 5.0.0
+         res=$?
+-        echo 5.0.0: $res
+         if [[ res -ge 1 ]]; then
+                 CLI_HAVE_ARG_NO_AUTH_WARNING=1
+         fi
+ 
+-        cmp_redis_version $CLI_VER 4.0.10
++        ocf_version_cmp $CLI_VER 4.0.10
+         res=$?
+-        echo 4.0.10: $res
+         if [[ res -ge 1 ]]; then
+                 CLI_HAVE_AUTH_WARNING=1
+         fi
+@@ -364,7 +349,7 @@ redis_client() {
+ 		if [[ CLI_HAVE_ENV_AUTH -eq 1 ]]; then
+ 			REDISCLI_AUTH=$clientpasswd "$REDIS_CLIENT" -s "$REDIS_SOCKET" "$@" | sed 's/\r//'
+ 		elif [[ CLI_HAVE_ARG_NO_AUTH_WARNING -eq 1 ]]; then
+-			"$REDIS_CLIENT" -s "$REDIS_SOCKET" -a "$clientpasswd" "$@" --no-auth-warning | sed 's/\r//'
++			"$REDIS_CLIENT" -s "$REDIS_SOCKET" --no-auth-warning -a "$clientpasswd" "$@" | sed 's/\r//'
+ 		elif [[ CLI_HAVE_AUTH_WARNING -eq 1 ]]; then
+ 			("$REDIS_CLIENT" -s "$REDIS_SOCKET" -a "$clientpasswd" "$@" 2>&1 >&3 3>&- | grep -v "Using a password" >&2 3>&-) 3>&1 | sed 's/\r//'
+ 		else
diff --git a/SOURCES/bz1818997-3-nfsserver-nfsnotify-fix-selinux-label-issue.patch b/SOURCES/bz1818997-3-nfsserver-nfsnotify-fix-selinux-label-issue.patch
new file mode 100644
index 0000000..e470d50
--- /dev/null
+++ b/SOURCES/bz1818997-3-nfsserver-nfsnotify-fix-selinux-label-issue.patch
@@ -0,0 +1,48 @@
+From dbd45cb5fcce0a3378f6ecd0c14b578e6f843e3d Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Fri, 24 Jul 2020 16:03:20 +0200
+Subject: [PATCH 1/2] nfsserver: fix SELinux issue due to newer ls versions
+ giving additional output.
+
+This patch has been tested on RHEL6, 7 and 8.
+---
+ heartbeat/nfsserver | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver
+index 0dbc173f3..80d20676b 100755
+--- a/heartbeat/nfsserver
++++ b/heartbeat/nfsserver
+@@ -192,7 +192,7 @@ fi
+ which restorecon > /dev/null 2>&1 && selinuxenabled
+ SELINUX_ENABLED=$?
+ if [ $SELINUX_ENABLED -eq 0 ]; then
+-	export SELINUX_LABEL="$(ls -ldZ $STATD_PATH | cut -f4 -d' ')"
++	export SELINUX_LABEL="$(ls -dZ $STATD_PATH | grep -o '\S\+:\S\+:\S\+')"
+ fi
+ 
+ ##
+
+From 81118dbb25fe2cfc7d5fc803178cd7c3b445915e Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Mon, 27 Jul 2020 10:33:44 +0200
+Subject: [PATCH 2/2] nfsnotify: fix SELinux issue due to newer ls versions
+ giving additional output.
+
+---
+ heartbeat/nfsnotify.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/heartbeat/nfsnotify.in b/heartbeat/nfsnotify.in
+index 7f710bca7..851f6ad6b 100644
+--- a/heartbeat/nfsnotify.in
++++ b/heartbeat/nfsnotify.in
+@@ -305,7 +305,7 @@ esac
+ which restorecon > /dev/null 2>&1 && selinuxenabled
+ SELINUX_ENABLED=$?
+ if [ $SELINUX_ENABLED -eq 0 ]; then
+-	export SELINUX_LABEL="$(ls -ldZ $STATD_PATH | cut -f4 -d' ')"
++	export SELINUX_LABEL="$(ls -dZ $STATD_PATH | grep -o '\S\+:\S\+:\S\+')"
+ fi
+ 
+ case $__OCF_ACTION in
diff --git a/SOURCES/bz1818997-nfsserver-1-fix-nfsv4-only-support.patch b/SOURCES/bz1818997-nfsserver-1-fix-nfsv4-only-support.patch
new file mode 100644
index 0000000..b3efdce
--- /dev/null
+++ b/SOURCES/bz1818997-nfsserver-1-fix-nfsv4-only-support.patch
@@ -0,0 +1,43 @@
+From 47dd1d16f08de06d512f9e04c3966c35f0ac4d3f Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Wed, 27 May 2020 13:05:57 +0200
+Subject: [PATCH] nfsserver: fix NFSv4-only support
+
+When disabling NFSv2 and NFSv3 mountd doesnt register with rpcbind, but
+it's still running. This patch checks that mountd is running instead of
+basing its status on it being registered w/rpcbind.
+---
+ heartbeat/nfsserver | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver
+index acef0147a..9e6e1fcb1 100755
+--- a/heartbeat/nfsserver
++++ b/heartbeat/nfsserver
+@@ -316,7 +316,7 @@ nfsserver_systemd_monitor()
+ 	fi
+ 
+ 	ocf_log debug "Status: nfs-mountd"
+-	rpcinfo -t localhost 100005 > /dev/null 2>&1
++	ps axww | grep -q "[r]pc.mountd"
+ 	rc=$?
+ 	if [ "$rc" -ne "0" ]; then
+ 		ocf_exit_reason "nfs-mountd is not running"
+@@ -683,7 +683,7 @@ nfsserver_start ()
+ 		  local i=1
+ 		  while : ; do
+ 			ocf_log info "Start: nfs-mountd i: $i"
+-			rpcinfo -t localhost 100005 > /dev/null 2>&1
++			ps axww | grep -q "[r]pc.mountd"
+ 			rc=$?
+ 			if [ "$rc" -eq "0" ]; then
+ 				break;
+@@ -800,7 +800,7 @@ nfsserver_stop ()
+ 
+ 		  nfs_exec stop nfs-mountd > /dev/null 2>&1
+ 		  ocf_log info "Stop: nfs-mountd"
+-		  rpcinfo -t localhost 100005 > /dev/null 2>&1
++		  ps axww | grep -q "[r]pc.mountd"
+ 		  rc=$?
+ 		  if [ "$rc" -eq "0" ]; then
+ 			ocf_exit_reason "Failed to stop nfs-mountd"
diff --git a/SOURCES/bz1818997-nfsserver-2-stop-nfsdcld-if-present.patch b/SOURCES/bz1818997-nfsserver-2-stop-nfsdcld-if-present.patch
new file mode 100644
index 0000000..085a39a
--- /dev/null
+++ b/SOURCES/bz1818997-nfsserver-2-stop-nfsdcld-if-present.patch
@@ -0,0 +1,34 @@
+From 290741f43ff414630f558ee3432e830e39d1599d Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Wed, 22 Jul 2020 11:56:32 +0200
+Subject: [PATCH] nfsserver: stop nfsdcld if present during stop-action
+
+---
+ heartbeat/nfsserver | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver
+index 9e6e1fcb1..0dbc173f3 100755
+--- a/heartbeat/nfsserver
++++ b/heartbeat/nfsserver
+@@ -806,6 +806,20 @@ nfsserver_stop ()
+ 			ocf_exit_reason "Failed to stop nfs-mountd"
+ 			return $OCF_ERR_GENERIC
+ 		  fi
++
++		  if systemctl --no-legend list-unit-files "nfsdcld*" | grep -q nfsdcld; then
++		  	nfs_exec stop nfsdcld > /dev/null 2>&1
++		  	ocf_log info "Stop: nfsdcld"
++		  	fn=`mktemp`
++		  	nfs_exec status nfsdcld > $fn 2>&1
++		  	rc=$?
++		  	ocf_log debug "$(cat $fn)"
++		  	rm -f $fn
++		  	if [ "$rc" -eq "0" ]; then
++		  		ocf_exit_reason "Failed to stop nfsdcld"
++		  		return $OCF_ERR_GENERIC
++		  	fi
++		  fi
+ 	esac
+ 
+ 
diff --git a/SOURCES/bz1818997-nfsserver-fix-nfsv4-only-support.patch b/SOURCES/bz1818997-nfsserver-fix-nfsv4-only-support.patch
deleted file mode 100644
index b3efdce..0000000
--- a/SOURCES/bz1818997-nfsserver-fix-nfsv4-only-support.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 47dd1d16f08de06d512f9e04c3966c35f0ac4d3f Mon Sep 17 00:00:00 2001
-From: Oyvind Albrigtsen <oalbrigt@redhat.com>
-Date: Wed, 27 May 2020 13:05:57 +0200
-Subject: [PATCH] nfsserver: fix NFSv4-only support
-
-When disabling NFSv2 and NFSv3 mountd doesnt register with rpcbind, but
-it's still running. This patch checks that mountd is running instead of
-basing its status on it being registered w/rpcbind.
----
- heartbeat/nfsserver | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/heartbeat/nfsserver b/heartbeat/nfsserver
-index acef0147a..9e6e1fcb1 100755
---- a/heartbeat/nfsserver
-+++ b/heartbeat/nfsserver
-@@ -316,7 +316,7 @@ nfsserver_systemd_monitor()
- 	fi
- 
- 	ocf_log debug "Status: nfs-mountd"
--	rpcinfo -t localhost 100005 > /dev/null 2>&1
-+	ps axww | grep -q "[r]pc.mountd"
- 	rc=$?
- 	if [ "$rc" -ne "0" ]; then
- 		ocf_exit_reason "nfs-mountd is not running"
-@@ -683,7 +683,7 @@ nfsserver_start ()
- 		  local i=1
- 		  while : ; do
- 			ocf_log info "Start: nfs-mountd i: $i"
--			rpcinfo -t localhost 100005 > /dev/null 2>&1
-+			ps axww | grep -q "[r]pc.mountd"
- 			rc=$?
- 			if [ "$rc" -eq "0" ]; then
- 				break;
-@@ -800,7 +800,7 @@ nfsserver_stop ()
- 
- 		  nfs_exec stop nfs-mountd > /dev/null 2>&1
- 		  ocf_log info "Stop: nfs-mountd"
--		  rpcinfo -t localhost 100005 > /dev/null 2>&1
-+		  ps axww | grep -q "[r]pc.mountd"
- 		  rc=$?
- 		  if [ "$rc" -eq "0" ]; then
- 			ocf_exit_reason "Failed to stop nfs-mountd"
diff --git a/SOURCES/bz1819965-3-azure-events-decode-when-type-not-str.patch b/SOURCES/bz1819965-3-azure-events-decode-when-type-not-str.patch
new file mode 100644
index 0000000..3c62631
--- /dev/null
+++ b/SOURCES/bz1819965-3-azure-events-decode-when-type-not-str.patch
@@ -0,0 +1,59 @@
+From 57424bd1f158f1ff597034e09ca90da864925a16 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Thu, 16 Jul 2020 09:58:55 +0200
+Subject: [PATCH] azure-events: only decode() when exec() output not of type
+ str
+
+---
+ heartbeat/azure-events.in | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/heartbeat/azure-events.in b/heartbeat/azure-events.in
+index a48a86309..d4a166d9f 100644
+--- a/heartbeat/azure-events.in
++++ b/heartbeat/azure-events.in
+@@ -179,6 +179,8 @@ class clusterHelper:
+ 		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:
+@@ -232,7 +234,7 @@ class clusterHelper:
+ 
+ 		nodes = []
+ 		nodeList = clusterHelper._exec("crm_node", "--list")
+-		for n in nodeList.decode().split("\n"):
++		for n in nodeList.split("\n"):
+ 			nodes.append(n.split()[1])
+ 		ocf.logger.debug("getAllNodes: finished; return %s" % str(nodes))
+ 
+@@ -303,7 +305,7 @@ class clusterHelper:
+ 			ocf.logger.warning("transitionSummary: received unexpected transition summary: %s" % summary)
+ 			return False
+ 		summary = summary.split("Transition Summary:")[1]
+-		ret = summary.decode().split("\n").pop(0)
++		ret = summary.split("\n").pop(0)
+ 
+ 		ocf.logger.debug("transitionSummary: finished; return = %s" % str(ret))
+ 		return ret
+@@ -324,7 +326,7 @@ class clusterHelper:
+ 		if len(resources) == 0:
+ 			ret = []
+ 		else:
+-			ret = resources.decode().split("\n")
++			ret = resources.split("\n")
+ 
+ 		ocf.logger.debug("listOperationsOnNode: finished; return = %s" % str(ret))
+ 		return ret
+@@ -470,7 +472,7 @@ class Node:
+ 
+ 		eventIDStr = clusterHelper.getAttr(attr_pendingEventIDs, node=node)
+ 		if eventIDStr:
+-			eventIDs = eventIDStr.decode().split(",")
++			eventIDs = eventIDStr.split(",")
+ 		else:
+ 			eventIDs = None
+ 
diff --git a/SOURCES/bz1845574-azure-events-1-handle-exceptions-in-urlopen.patch b/SOURCES/bz1845574-azure-events-1-handle-exceptions-in-urlopen.patch
new file mode 100644
index 0000000..fa194c9
--- /dev/null
+++ b/SOURCES/bz1845574-azure-events-1-handle-exceptions-in-urlopen.patch
@@ -0,0 +1,70 @@
+From 194909ff08cfe75cd5da9f704d8ed4cc9ab40341 Mon Sep 17 00:00:00 2001
+From: Gustavo Figueira <gfigueira@suse.com>
+Date: Tue, 19 May 2020 10:58:34 +0200
+Subject: [PATCH 1/2] azure-events: handle exceptions in urlopen The locking in
+ azure-events does not correctly handle some failures.
+
+If the metadata server is not recheable or has an error
+handling the request, attr_globalPullState will never go
+back to IDLE unless the administrator manually changes it.
+
+> azure-events: ERROR: [Errno 104] Connection reset by peer
+> lrmd[2734]: notice: rsc_azure-events_monitor_10000:113088:stderr [ ocf-exit-reason:[Errno 104] Connection reset by peer ]
+---
+ heartbeat/azure-events.in | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/heartbeat/azure-events.in b/heartbeat/azure-events.in
+index 8709d97e3..bd812f4b2 100644
+--- a/heartbeat/azure-events.in
++++ b/heartbeat/azure-events.in
+@@ -82,9 +82,19 @@ class azHelper:
+ 		req = urllib2.Request(url, postData)
+ 		req.add_header("Metadata", "true")
+ 		req.add_header("User-Agent", USER_AGENT)
+-		resp = urllib2.urlopen(req)
+-		data = resp.read()
+-		ocf.logger.debug("_sendMetadataRequest: response = %s" % data)
++		try:
++			resp = urllib2.urlopen(req)
++		except URLError as e:
++			if hasattr(e, 'reason'):
++				print('We failed to reach a server. Reason: '), e.reason
++				clusterHelper.setAttr(attr_globalPullState, "IDLE")
++			elif hasattr(e, 'code'):
++				print('The server couldn\'t fulfill the request. Error code: '), e.code
++				clusterHelper.setAttr(attr_globalPullState, "IDLE")
++		else:
++			data = resp.read()
++			ocf.logger.debug("_sendMetadataRequest: response = %s" % data)
++
+ 		if data:
+ 			data = json.loads(data)
+ 
+
+From c4071ec4a82fcb831f170f341e0790633e4b904f Mon Sep 17 00:00:00 2001
+From: Gustavo Figueira <gfigueira@suse.com>
+Date: Tue, 19 May 2020 12:53:22 +0200
+Subject: [PATCH 2/2] azure-events: use ocf.logger.warning instead of print
+
+---
+ heartbeat/azure-events.in | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/heartbeat/azure-events.in b/heartbeat/azure-events.in
+index bd812f4b2..a48a86309 100644
+--- a/heartbeat/azure-events.in
++++ b/heartbeat/azure-events.in
+@@ -86,10 +86,10 @@ class azHelper:
+ 			resp = urllib2.urlopen(req)
+ 		except URLError as e:
+ 			if hasattr(e, 'reason'):
+-				print('We failed to reach a server. Reason: '), e.reason
++				ocf.logger.warning("Failed to reach the server: %s" % e.reason)
+ 				clusterHelper.setAttr(attr_globalPullState, "IDLE")
+ 			elif hasattr(e, 'code'):
+-				print('The server couldn\'t fulfill the request. Error code: '), 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()
diff --git a/SOURCES/bz1845574-azure-events-2-import-urlerror-encode-postdata.patch b/SOURCES/bz1845574-azure-events-2-import-urlerror-encode-postdata.patch
new file mode 100644
index 0000000..7795e78
--- /dev/null
+++ b/SOURCES/bz1845574-azure-events-2-import-urlerror-encode-postdata.patch
@@ -0,0 +1,68 @@
+From f2bf1d8a07ea810099b03469883cb7f485ab9ac1 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Mon, 27 Jul 2020 10:09:43 +0200
+Subject: [PATCH 1/2] azure-events: import URLError and encode postData when
+ necessary
+
+---
+ heartbeat/azure-events.in | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/heartbeat/azure-events.in b/heartbeat/azure-events.in
+index d4a166d9f..a7f359468 100644
+--- a/heartbeat/azure-events.in
++++ b/heartbeat/azure-events.in
+@@ -13,8 +13,10 @@ 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
+ 
+@@ -76,9 +78,13 @@ class azHelper:
+ 		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)
+
+From 1ab5d71bff95eb271f1e1bbc401961dc313219d9 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Wed, 29 Jul 2020 21:25:43 +0200
+Subject: [PATCH 2/2] azure-events: report error if jsondata not received
+
+---
+ heartbeat/azure-events.in | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/heartbeat/azure-events.in b/heartbeat/azure-events.in
+index a7f359468..3a24d6358 100644
+--- a/heartbeat/azure-events.in
++++ b/heartbeat/azure-events.in
+@@ -117,8 +117,12 @@ class azHelper:
+ 		jsondata = azHelper._sendMetadataRequest(azHelper.instance_api)
+ 		ocf.logger.debug("getInstanceInfo: json = %s" % jsondata)
+ 
+-		ocf.logger.debug("getInstanceInfo: finished, returning {}".format(jsondata["compute"]))
+-		return attrDict(jsondata["compute"])
++		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():
diff --git a/SOURCES/bz1845574-azure-events-handle-exceptions-in-urlopen.patch b/SOURCES/bz1845574-azure-events-handle-exceptions-in-urlopen.patch
deleted file mode 100644
index fa194c9..0000000
--- a/SOURCES/bz1845574-azure-events-handle-exceptions-in-urlopen.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 194909ff08cfe75cd5da9f704d8ed4cc9ab40341 Mon Sep 17 00:00:00 2001
-From: Gustavo Figueira <gfigueira@suse.com>
-Date: Tue, 19 May 2020 10:58:34 +0200
-Subject: [PATCH 1/2] azure-events: handle exceptions in urlopen The locking in
- azure-events does not correctly handle some failures.
-
-If the metadata server is not recheable or has an error
-handling the request, attr_globalPullState will never go
-back to IDLE unless the administrator manually changes it.
-
-> azure-events: ERROR: [Errno 104] Connection reset by peer
-> lrmd[2734]: notice: rsc_azure-events_monitor_10000:113088:stderr [ ocf-exit-reason:[Errno 104] Connection reset by peer ]
----
- heartbeat/azure-events.in | 16 +++++++++++++---
- 1 file changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/heartbeat/azure-events.in b/heartbeat/azure-events.in
-index 8709d97e3..bd812f4b2 100644
---- a/heartbeat/azure-events.in
-+++ b/heartbeat/azure-events.in
-@@ -82,9 +82,19 @@ class azHelper:
- 		req = urllib2.Request(url, postData)
- 		req.add_header("Metadata", "true")
- 		req.add_header("User-Agent", USER_AGENT)
--		resp = urllib2.urlopen(req)
--		data = resp.read()
--		ocf.logger.debug("_sendMetadataRequest: response = %s" % data)
-+		try:
-+			resp = urllib2.urlopen(req)
-+		except URLError as e:
-+			if hasattr(e, 'reason'):
-+				print('We failed to reach a server. Reason: '), e.reason
-+				clusterHelper.setAttr(attr_globalPullState, "IDLE")
-+			elif hasattr(e, 'code'):
-+				print('The server couldn\'t fulfill the request. Error code: '), e.code
-+				clusterHelper.setAttr(attr_globalPullState, "IDLE")
-+		else:
-+			data = resp.read()
-+			ocf.logger.debug("_sendMetadataRequest: response = %s" % data)
-+
- 		if data:
- 			data = json.loads(data)
- 
-
-From c4071ec4a82fcb831f170f341e0790633e4b904f Mon Sep 17 00:00:00 2001
-From: Gustavo Figueira <gfigueira@suse.com>
-Date: Tue, 19 May 2020 12:53:22 +0200
-Subject: [PATCH 2/2] azure-events: use ocf.logger.warning instead of print
-
----
- heartbeat/azure-events.in | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/heartbeat/azure-events.in b/heartbeat/azure-events.in
-index bd812f4b2..a48a86309 100644
---- a/heartbeat/azure-events.in
-+++ b/heartbeat/azure-events.in
-@@ -86,10 +86,10 @@ class azHelper:
- 			resp = urllib2.urlopen(req)
- 		except URLError as e:
- 			if hasattr(e, 'reason'):
--				print('We failed to reach a server. Reason: '), e.reason
-+				ocf.logger.warning("Failed to reach the server: %s" % e.reason)
- 				clusterHelper.setAttr(attr_globalPullState, "IDLE")
- 			elif hasattr(e, 'code'):
--				print('The server couldn\'t fulfill the request. Error code: '), 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()
diff --git a/SOURCES/bz1846733-gcp-vpc-move-vip-1-support-multiple-alias-ips.patch b/SOURCES/bz1846733-gcp-vpc-move-vip-1-support-multiple-alias-ips.patch
new file mode 100644
index 0000000..13401c2
--- /dev/null
+++ b/SOURCES/bz1846733-gcp-vpc-move-vip-1-support-multiple-alias-ips.patch
@@ -0,0 +1,317 @@
+--- a/heartbeat/gcp-vpc-move-vip.in	2020-08-17 10:33:22.132531259 +0200
++++ b/heartbeat/gcp-vpc-move-vip.in	2020-08-17 10:34:54.050633259 +0200
+@@ -22,7 +22,8 @@
+ import sys
+ import time
+ 
+-OCF_FUNCTIONS_DIR="%s/lib/heartbeat" % os.environ.get("OCF_ROOT")
++OCF_FUNCTIONS_DIR = os.environ.get("OCF_FUNCTIONS_DIR", "%s/lib/heartbeat"
++                                   % os.environ.get("OCF_ROOT"))
+ sys.path.append(OCF_FUNCTIONS_DIR)
+ 
+ from ocf import *
+@@ -43,6 +44,10 @@
+   import urllib2 as urlrequest
+ 
+ 
++# Constants for alias add/remove modes
++ADD = 0
++REMOVE = 1
++
+ CONN = None
+ THIS_VM = None
+ ALIAS = None
+@@ -53,27 +58,27 @@
+ <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+ <resource-agent name="gcp-vpc-move-vip">
+   <version>1.0</version>
+-  <longdesc lang="en">Floating IP Address on Google Cloud Platform - Using Alias IP address functionality to attach a secondary IP address to a running instance</longdesc>
+-  <shortdesc lang="en">Floating IP Address on Google Cloud Platform</shortdesc>
++  <longdesc lang="en">Floating IP Address or Range on Google Cloud Platform - Using Alias IP address functionality to attach a secondary IP range to a running instance</longdesc>
++  <shortdesc lang="en">Floating IP Address or Range on Google Cloud Platform</shortdesc>
+   <parameters>
+     <parameter name="alias_ip" unique="1" required="1">
+-      <longdesc lang="en">IP Address to be added including CIDR. E.g 192.168.0.1/32</longdesc>
+-      <shortdesc lang="en">IP Address to be added including CIDR. E.g 192.168.0.1/32</shortdesc>
++      <longdesc lang="en">IP range to be added including CIDR netmask (e.g., 192.168.0.1/32)</longdesc>
++      <shortdesc lang="en">IP range to be added including CIDR netmask (e.g., 192.168.0.1/32)</shortdesc>
+       <content type="string" default="" />
+     </parameter>
+-    <parameter name="alias_range_name" unique="1" required="0">
++    <parameter name="alias_range_name" unique="0" required="0">
+       <longdesc lang="en">Subnet name for the Alias IP</longdesc>
+       <shortdesc lang="en">Subnet name for the Alias IP</shortdesc>
+       <content type="string" default="" />
+     </parameter>
+-    <parameter name="hostlist" unique="1" required="0">
+-      <longdesc lang="en">List of hosts in the cluster</longdesc>
++    <parameter name="hostlist" unique="0" required="0">
++      <longdesc lang="en">List of hosts in the cluster, separated by spaces</longdesc>
+       <shortdesc lang="en">Host list</shortdesc>
+       <content type="string" default="" />
+     </parameter>
+     <parameter name="stackdriver_logging" unique="0" required="0">
+-      <longdesc lang="en">If enabled (set to true), IP failover logs will be posted to stackdriver logging. Using stackdriver logging requires additional libraries (google-cloud-logging).</longdesc>
+-      <shortdesc lang="en">Stackdriver-logging support. Requires additional libraries (google-cloud-logging).</shortdesc>
++      <longdesc lang="en">If enabled (set to true), IP failover logs will be posted to stackdriver logging</longdesc>
++      <shortdesc lang="en">Stackdriver-logging support</shortdesc>
+       <content type="boolean" default="" />
+     </parameter>
+   </parameters>
+@@ -107,7 +112,8 @@
+   url = '%s?%s' % (metadata_url, params)
+   request = urlrequest.Request(url, headers=METADATA_HEADERS)
+   request_opener = urlrequest.build_opener(urlrequest.ProxyHandler({}))
+-  return request_opener.open(request, timeout=timeout * 1.1).read().decode("utf-8")
++  return request_opener.open(
++      request, timeout=timeout * 1.1).read().decode("utf-8")
+ 
+ 
+ def get_instance(project, zone, instance):
+@@ -134,17 +140,21 @@
+     time.sleep(1)
+ 
+ 
+-def set_alias(project, zone, instance, alias, alias_range_name=None):
+-  fingerprint = get_network_ifaces(project, zone, instance)[0]['fingerprint']
++def set_aliases(project, zone, instance, aliases, fingerprint):
++  """Sets the alias IP ranges for an instance.
++
++  Args:
++    project: string, the project in which the instance resides.
++    zone: string, the zone in which the instance resides.
++    instance: string, the name of the instance.
++    aliases: list, the list of dictionaries containing alias IP ranges
++      to be added to or removed from the instance.
++    fingerprint: string, the fingerprint of the network interface.
++  """
+   body = {
+-      'aliasIpRanges': [],
+-      'fingerprint': fingerprint
++    'aliasIpRanges': aliases,
++    'fingerprint': fingerprint
+   }
+-  if alias:
+-    obj = {'ipCidrRange': alias}
+-    if alias_range_name:
+-      obj['subnetworkRangeName'] = alias_range_name
+-    body['aliasIpRanges'].append(obj)
+ 
+   request = CONN.instances().updateNetworkInterface(
+       instance=instance, networkInterface='nic0', project=project, zone=zone,
+@@ -153,21 +163,75 @@
+   wait_for_operation(project, zone, operation)
+ 
+ 
+-def get_alias(project, zone, instance):
+-  iface = get_network_ifaces(project, zone, instance)
++def add_rm_alias(mode, project, zone, instance, alias, alias_range_name=None):
++  """Adds or removes an alias IP range for a GCE instance.
++
++  Args:
++    mode: int, a constant (ADD (0) or REMOVE (1)) indicating the
++      operation type.
++    project: string, the project in which the instance resides.
++    zone: string, the zone in which the instance resides.
++    instance: string, the name of the instance.
++    alias: string, the alias IP range to be added to or removed from
++      the instance.
++    alias_range_name: string, the subnet name for the alias IP range.
++
++  Returns:
++    True if the existing list of alias IP ranges was modified, or False
++    otherwise.
++  """
++  ifaces = get_network_ifaces(project, zone, instance)
++  fingerprint = ifaces[0]['fingerprint']
++
++  try:
++    old_aliases = ifaces[0]['aliasIpRanges']
++  except KeyError:
++    old_aliases = []
++
++  new_aliases = [a for a in old_aliases if a['ipCidrRange'] != alias]
++
++  if alias:
++    if mode == ADD:
++      obj = {'ipCidrRange': alias}
++      if alias_range_name:
++        obj['subnetworkRangeName'] = alias_range_name
++      new_aliases.append(obj)
++    elif mode == REMOVE:
++      pass    # already removed during new_aliases build
++    else:
++      raise ValueError('Invalid value for mode: {}'.format(mode))
++
++  if (sorted(new_aliases) != sorted(old_aliases)):
++    set_aliases(project, zone, instance, new_aliases, fingerprint)
++    return True
++  else:
++    return False
++
++
++def add_alias(project, zone, instance, alias, alias_range_name=None):
++  return add_rm_alias(ADD, project, zone, instance, alias, alias_range_name)
++
++
++def remove_alias(project, zone, instance, alias):
++  return add_rm_alias(REMOVE, project, zone, instance, alias)
++
++
++def get_aliases(project, zone, instance):
++  ifaces = get_network_ifaces(project, zone, instance)
+   try:
+-    return iface[0]['aliasIpRanges'][0]['ipCidrRange']
++    aliases = ifaces[0]['aliasIpRanges']
++    return [a['ipCidrRange'] for a in aliases]
+   except KeyError:
+-    return ''
++    return []
+ 
+ 
+-def get_localhost_alias():
++def get_localhost_aliases():
+   net_iface = get_metadata('instance/network-interfaces', {'recursive': True})
+   net_iface = json.loads(net_iface)
+   try:
+-    return net_iface[0]['ipAliases'][0]
++    return net_iface[0]['ipAliases']
+   except (KeyError, IndexError):
+-    return ''
++    return []
+ 
+ 
+ def get_zone(project, instance):
+@@ -201,21 +265,17 @@
+ 
+ 
+ def gcp_alias_start(alias):
+-  my_alias = get_localhost_alias()
++  my_aliases = get_localhost_aliases()
+   my_zone = get_metadata('instance/zone').split('/')[-1]
+   project = get_metadata('project/project-id')
+ 
+-  # If I already have the IP, exit. If it has an alias IP that isn't the VIP,
+-  # then remove it
+-  if my_alias == alias:
++  if alias in my_aliases:
++    # TODO: Do we need to check alias_range_name?
+     logger.info(
+         '%s already has %s attached. No action required' % (THIS_VM, alias))
+     sys.exit(OCF_SUCCESS)
+-  elif my_alias:
+-    logger.info('Removing %s from %s' % (my_alias, THIS_VM))
+-    set_alias(project, my_zone, THIS_VM, '')
+ 
+-  # Loops through all hosts & remove the alias IP from the host that has it
++  # If the alias is currently attached to another host, detach it.
+   hostlist = os.environ.get('OCF_RESKEY_hostlist', '')
+   if hostlist:
+     hostlist = hostlist.replace(THIS_VM, '').split()
+@@ -223,47 +283,53 @@
+     hostlist = get_instances_list(project, THIS_VM)
+   for host in hostlist:
+     host_zone = get_zone(project, host)
+-    host_alias = get_alias(project, host_zone, host)
+-    if alias == host_alias:
++    host_aliases = get_aliases(project, host_zone, host)
++    if alias in host_aliases:
+       logger.info(
+-          '%s is attached to %s - Removing all alias IP addresses from %s' %
+-          (alias, host, host))
+-      set_alias(project, host_zone, host, '')
++          '%s is attached to %s - Removing %s from %s' %
++          (alias, host, alias, host))
++      remove_alias(project, host_zone, host, alias)
+       break
+ 
+-  # add alias IP to localhost
+-  set_alias(
++  # Add alias IP range to localhost
++  add_alias(
+       project, my_zone, THIS_VM, alias,
+       os.environ.get('OCF_RESKEY_alias_range_name'))
+ 
+-  # Check the IP has been added
+-  my_alias = get_localhost_alias()
+-  if alias == my_alias:
++  # Verify that the IP range has been added
++  my_aliases = get_localhost_aliases()
++  if alias in my_aliases:
+     logger.info('Finished adding %s to %s' % (alias, THIS_VM))
+-  elif my_alias:
+-    logger.error(
+-        'Failed to add IP. %s has an IP attached but it isn\'t %s' %
+-        (THIS_VM, alias))
+-    sys.exit(OCF_ERR_GENERIC)
+   else:
+-    logger.error('Failed to add IP address %s to %s' % (alias, THIS_VM))
++    if my_aliases:
++      logger.error(
++          'Failed to add alias IP range %s. %s has alias IP ranges attached but'
++          + ' they don\'t include %s' % (alias, THIS_VM, alias))
++    else:
++      logger.error(
++          'Failed to add IP range %s. %s has no alias IP ranges attached'
++           % (alias, THIS_VM))
+     sys.exit(OCF_ERR_GENERIC)
+ 
+ 
+ def gcp_alias_stop(alias):
+-  my_alias = get_localhost_alias()
++  my_aliases = get_localhost_aliases()
+   my_zone = get_metadata('instance/zone').split('/')[-1]
+   project = get_metadata('project/project-id')
+ 
+-  if my_alias == alias:
+-    logger.info('Removing %s from %s' % (my_alias, THIS_VM))
+-    set_alias(project, my_zone, THIS_VM, '')
++  if alias in my_aliases:
++    logger.info('Removing %s from %s' % (alias, THIS_VM))
++    remove_alias(project, my_zone, THIS_VM, alias)
++  else:
++    logger.info(
++        '%s is not attached to %s. No action required'
++        % (alias, THIS_VM))
+ 
+ 
+ def gcp_alias_status(alias):
+-  my_alias = get_localhost_alias()
+-  if alias == my_alias:
+-    logger.info('%s has the correct IP address attached' % THIS_VM)
++  my_aliases = get_localhost_aliases()
++  if alias in my_aliases:
++    logger.info('%s has the correct IP range attached' % THIS_VM)
+   else:
+     sys.exit(OCF_NOT_RUNNING)
+ 
+@@ -275,7 +341,8 @@
+ 
+   # Populate global vars
+   try:
+-    CONN = googleapiclient.discovery.build('compute', 'v1')
++    CONN = googleapiclient.discovery.build('compute', 'v1',
++                                           cache_discovery=False)
+   except Exception as e:
+     logger.error('Couldn\'t connect with google api: ' + str(e))
+     sys.exit(OCF_ERR_CONFIGURED)
+@@ -283,7 +350,8 @@
+   try:
+     THIS_VM = get_metadata('instance/name')
+   except Exception as e:
+-    logger.error('Couldn\'t get instance name, is this running inside GCE?: ' + str(e))
++    logger.error('Couldn\'t get instance name, is this running inside GCE?: '
++                 + str(e))
+     sys.exit(OCF_ERR_CONFIGURED)
+ 
+   ALIAS = os.environ.get('OCF_RESKEY_alias_ip')
+@@ -309,7 +377,8 @@
+         formatter = logging.Formatter('gcp:alias "%(message)s"')
+         handler.setFormatter(formatter)
+         log.addHandler(handler)
+-        logger = logging.LoggerAdapter(log, {'OCF_RESOURCE_INSTANCE': OCF_RESOURCE_INSTANCE})
++        logger = logging.LoggerAdapter(log, {'OCF_RESOURCE_INSTANCE':
++                                             OCF_RESOURCE_INSTANCE})
+       except ImportError:
+         logger.error('Couldn\'t import google.cloud.logging, '
+             'disabling Stackdriver-logging support')
diff --git a/SOURCES/bz1846733-gcp-vpc-move-vip-2-fix-list-sort.patch b/SOURCES/bz1846733-gcp-vpc-move-vip-2-fix-list-sort.patch
new file mode 100644
index 0000000..887fc99
--- /dev/null
+++ b/SOURCES/bz1846733-gcp-vpc-move-vip-2-fix-list-sort.patch
@@ -0,0 +1,32 @@
+From 2b22a14a128b87214bfb1ece221274aac78ba81b Mon Sep 17 00:00:00 2001
+From: Reid Wahl <nrwahl@protonmail.com>
+Date: Tue, 18 Aug 2020 18:43:13 -0700
+Subject: [PATCH] gcp-vpc-move-vip: Fix sort for list of dicts in python3
+
+python2 sorts a list of dicts of `{'ipCidrRange': <alias>}` correctly by
+default. python3 fails with a TypeError:
+
+`TypeError: '<' not supported between instances of 'dict' and 'dict'`
+
+Fix this by using the key parameter of sorted(). python2 also supports
+this.
+
+Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
+---
+ heartbeat/gcp-vpc-move-vip.in | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/heartbeat/gcp-vpc-move-vip.in b/heartbeat/gcp-vpc-move-vip.in
+index 85d59f6bb..01d91a59d 100755
+--- a/heartbeat/gcp-vpc-move-vip.in
++++ b/heartbeat/gcp-vpc-move-vip.in
+@@ -200,7 +200,8 @@ def add_rm_alias(mode, project, zone, instance, alias, alias_range_name=None):
+     else:
+       raise ValueError('Invalid value for mode: {}'.format(mode))
+ 
+-  if (sorted(new_aliases) != sorted(old_aliases)):
++  if (sorted(new_aliases, key=lambda item: item.get('ipCidrRange'))
++      != sorted(old_aliases, key=lambda item: item.get('ipCidrRange'))):
+     set_aliases(project, zone, instance, new_aliases, fingerprint)
+     return True
+   else:
diff --git a/SOURCES/bz1848025-sybaseASE-run-verify-for-start-action-only.patch b/SOURCES/bz1848025-sybaseASE-run-verify-for-start-action-only.patch
new file mode 100644
index 0000000..402bbd6
--- /dev/null
+++ b/SOURCES/bz1848025-sybaseASE-run-verify-for-start-action-only.patch
@@ -0,0 +1,41 @@
+From 953f689cb2a37606b6d4b2250ebec23f129f5095 Mon Sep 17 00:00:00 2001
+From: Reid wahl <nrwahl@protonmail.com>
+Date: Thu, 9 Jul 2020 23:32:22 -0700
+Subject: [PATCH] sybaseASE: Run verify_all() for start operation only
+
+The `sybaseASE` resource agent runs the `verify_all()` function at the
+beginning of start, stop, and monitor operations.
+
+When `verify_all()` is run for a probe (monitor) operation and
+`sybase_home` resides on a cluster-managed filesystem, the probe often
+fails with `$OCF_ERR_GENERIC` because the filesystem isn't mounted yet.
+This prevents the resource from starting on that node.
+
+For the stop operation, there's simply no reason to run `verify_all()`.
+
+This patch removes `verify_all()` for the stop and monitor operations.
+It is now only run for the start operation.
+
+Resolves: RHBZ#1848673
+Resolves: RHBZ#1848025
+---
+ heartbeat/sybaseASE.in | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/heartbeat/sybaseASE.in b/heartbeat/sybaseASE.in
+index 9ddd429be..7ff30bd31 100755
+--- a/heartbeat/sybaseASE.in
++++ b/heartbeat/sybaseASE.in
+@@ -864,12 +864,10 @@ case $__OCF_ACTION in
+ 		exit $?
+ 		;;
+ 	stop)
+-		verify_all || exit $OCF_ERR_GENERIC
+ 		ase_stop
+ 		exit $?
+ 		;;
+ 	status | monitor)
+-		verify_all || exit $OCF_ERR_GENERIC
+ 		ase_status $OCF_CHECK_LEVEL
+ 		exit $?
+ 		;;
diff --git a/SOURCES/bz1850778-azure-lb-fix-redirect-issue.patch b/SOURCES/bz1850778-azure-lb-fix-redirect-issue.patch
new file mode 100644
index 0000000..b171613
--- /dev/null
+++ b/SOURCES/bz1850778-azure-lb-fix-redirect-issue.patch
@@ -0,0 +1,54 @@
+From d22700fc5d5098c683b465ea0fede43803fd4d6b Mon Sep 17 00:00:00 2001
+From: Reid wahl <nrwahl@protonmail.com>
+Date: Tue, 7 Jul 2020 02:18:09 -0700
+Subject: [PATCH] azure-lb: Don't redirect nc listener output to pidfile
+
+The `lb_start()` function spawns an `nc` listener background process
+and echoes the resulting pid to `$pidfile`. Due to a bug in the
+redirection, all future data received by the `nc` process is also
+appended to `$pidfile`.
+
+If binary data is received later and appended to `$pidfile`, the
+monitor operation fails when `grep` searches the now-binary file.
+
+```
+line 97: kill: Binary: arguments must be process or job IDs ]
+line 97: kill: file: arguments must be process or job IDs ]
+line 97: kill: /var/run/nc_PF2_02.pid: arguments must be process or job
+    IDs ]
+line 97: kill: matches: arguments must be process or job IDs ]
+```
+
+Then the start operation fails during recovery. `lb_start()` spawns a
+new `nc` process, but the old process is still running and using the
+configured port.
+
+```
+nc_PF2_02_start_0:777:stderr [ Ncat: bind to :::62502: Address
+    already in use. QUITTING. ]
+```
+
+This patch fixes the issue by removing the `nc &` command from the
+section whose output gets redirected to `$pidfile`. Now, only the `nc`
+PID is echoed to `$pidfile`.
+
+Resolves: RHBZ#1850778
+Resolves: RHBZ#1850779
+---
+ heartbeat/azure-lb | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/heartbeat/azure-lb b/heartbeat/azure-lb
+index 05c134514..05755d778 100755
+--- a/heartbeat/azure-lb
++++ b/heartbeat/azure-lb
+@@ -113,7 +113,8 @@ lb_start() {
+ 	if ! lb_monitor; then
+ 		ocf_log debug "Starting $process: $cmd"
+ 		# Execute the command as created above
+-		eval "$cmd & echo \$!" > $pidfile
++		$cmd &
++		echo $! > $pidfile
+ 		if lb_monitor; then
+ 			ocf_log debug "$process: $cmd started successfully, calling monitor"
+ 			lb_monitor
diff --git a/SOURCES/bz1858752-Filesystem-support-whitespace-device-dir.patch b/SOURCES/bz1858752-Filesystem-support-whitespace-device-dir.patch
new file mode 100644
index 0000000..15fb71f
--- /dev/null
+++ b/SOURCES/bz1858752-Filesystem-support-whitespace-device-dir.patch
@@ -0,0 +1,566 @@
+From a8051cf9e21d231ce3c445f09631266157ffc2e0 Mon Sep 17 00:00:00 2001
+From: Reid wahl <nrwahl@protonmail.com>
+Date: Fri, 10 Jul 2020 03:44:18 -0700
+Subject: [PATCH 1/3] Filesystem: Support whitespace in device or directory
+ name
+
+Whitespace in a device name (e.g., a CIFS share) or a directory name
+breaks resource operations.
+
+One issue is that many of the variable occurrences aren't quoted, so a
+string containing whitespace is split into multiple tokens. This is a
+problem when the string meant to be passed as a single argument to a
+function (e.g., `list_submounts()`).
+
+Another issue involves the parsing of `list_mounts()` output.
+`list_mounts()` can pull data from `/proc/mounts`, `/etc/mtab`, or the
+`mount` command. `/proc/mounts` and `/etc/mtab` represent spaces within
+a field as octal `\040` strings, while `mount` represents them as
+literal space characters.
+
+`list_mounts()` had to be modified to output the mount list as three
+distinct fields ((`device`, `mountpoint`, `fstype`), separated by tab
+characters) regardless of the data source. Parsers of `list_mounts()`
+were modified to use tabs as field delimiters.
+
+The for loop in `Filesystem_stop()` also had to become a while loop to
+read line-by-line irrespective of spaces. A for loop splits on spaces.
+
+Resolves: RHBZ#1624591
+---
+ heartbeat/Filesystem | 106 +++++++++++++++++++++++++------------------
+ 1 file changed, 61 insertions(+), 45 deletions(-)
+
+diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem
+index 2f07a90ad..9a52aa712 100755
+--- a/heartbeat/Filesystem
++++ b/heartbeat/Filesystem
+@@ -91,6 +91,7 @@ fi
+ 
+ # Variables used by multiple methods
+ HOSTOS=`uname`
++TAB='	'
+ 
+ # The status file is going to an extra directory, by default
+ #
+@@ -100,7 +101,7 @@ suffix="${OCF_RESOURCE_INSTANCE}"
+ [ "$OCF_RESKEY_CRM_meta_clone" ] &&
+ 	suffix="${suffix}_$OCF_RESKEY_CRM_meta_clone"
+ suffix="${suffix}_`uname -n`"
+-STATUSFILE=${OCF_RESKEY_directory}/$prefix$suffix
++STATUSFILE="${OCF_RESKEY_directory}/$prefix$suffix"
+ 
+ #######################################################################
+ 
+@@ -283,6 +284,7 @@ flushbufs() {
+ is_bind_mount() {
+ 	echo "$options" | grep -w bind >/dev/null 2>&1
+ }
++
+ list_mounts() {
+ 	local inpf=""
+ 	local mount_list=""
+@@ -296,15 +298,23 @@ list_mounts() {
+ 
+ 	# Make sure that the mount list has not been changed while reading.
+ 	while [ "$mount_list" != "$check_list" ]; do
+-		check_list=$mount_list
++		check_list="$mount_list"
+ 		if [ "$inpf" ]; then
+-			mount_list=$(cut -d' ' -f1,2,3 < $inpf)
++			# <device> <mountpoint> <fstype> ...
++			# Spaces in device or mountpoint are octal \040 in $inpf
++			# Convert literal spaces (field separators) to tabs
++			mount_list=$(cut -d' ' -f1,2,3 < $inpf | tr ' ' "$TAB")
+ 		else
+-			mount_list=$($MOUNT | cut -d' ' -f1,3,5)
++			# <device> on <mountpoint> type <fstype> ...
++			# Use tabs as field separators
++			match_string='\(.*\) on \(.*\) type \([^[:space:]]\)'
++			replace_string="\\1${TAB}\\3${TAB}\\5"
++			mount_list=$($MOUNT | sed "s/$match_string/$replace_string/g")
+ 		fi
+ 	done
+ 
+-	echo "$mount_list"
++	# Convert octal \040 to space characters
++	printf "$mount_list"
+ }
+ 
+ determine_blockdevice() {
+@@ -318,7 +328,8 @@ determine_blockdevice() {
+ 	nfs4|nfs|smbfs|cifs|glusterfs|ceph|tmpfs|overlay|overlayfs|rozofs|zfs|cvfs|none|lustre)
+ 		: ;;
+ 	*)
+-		DEVICE=`list_mounts | grep " $CANONICALIZED_MOUNTPOINT " | cut -d' ' -f1`
++		match_string="${TAB}${CANONICALIZED_MOUNTPOINT}${TAB}"
++		DEVICE=`list_mounts | grep "$match_string" | cut -d"$TAB" -f1`
+ 		if [ -b "$DEVICE" ]; then
+ 			blockdevice=yes
+ 		fi
+@@ -329,7 +340,7 @@ determine_blockdevice() {
+ # Lists all filesystems potentially mounted under a given path,
+ # excluding the path itself.
+ list_submounts() {
+-	list_mounts | grep " $1/" | cut -d' ' -f2 | sort -r
++	list_mounts | grep "${TAB}${1}/" | cut -d"$TAB" -f2 | sort -r
+ }
+ 
+ # kernels < 2.6.26 can't handle bind remounts
+@@ -358,15 +369,15 @@ bind_mount() {
+ 	if is_bind_mount && [ "$options" != "-o bind" ]
+ 	then
+ 		bind_kernel_check
+-		bind_opts=`echo $options | sed 's/bind/remount/'`
+-		$MOUNT $bind_opts $MOUNTPOINT
++		bind_opts=`echo "$options" | sed 's/bind/remount/'`
++		$MOUNT $bind_opts "$MOUNTPOINT"
+ 	else
+ 		true # make sure to return OK
+ 	fi
+ }
+ 
+ is_option() {
+-	echo $OCF_RESKEY_options | grep -w "$1" >/dev/null 2>&1
++	echo "$OCF_RESKEY_options" | grep -w "$1" >/dev/null 2>&1
+ }
+ 
+ is_fsck_needed() {
+@@ -374,7 +385,7 @@ is_fsck_needed() {
+ 		force) true;;
+ 		no)    false;;
+ 		""|auto)
+-		case $FSTYPE in
++		case "$FSTYPE" in
+ 			ext4|ext4dev|ext3|reiserfs|reiser4|nss|xfs|jfs|vfat|fat|nfs4|nfs|cifs|smbfs|ocfs2|gfs2|none|lustre|glusterfs|ceph|tmpfs|overlay|overlayfs|rozofs|zfs|cvfs)
+ 			false;;
+ 			*)
+@@ -403,7 +414,7 @@ fstype_supported()
+ 	fi
+ 
+ 	# support fuse-filesystems (e.g. GlusterFS)
+-	case $FSTYPE in
++	case "$FSTYPE" in
+ 		fuse.*|glusterfs|rozofs) support="fuse";;
+ 	esac
+ 
+@@ -486,7 +497,8 @@ trigger_udev_rules_if_needed()
+ Filesystem_start()
+ {
+ 	# Check if there are any mounts mounted under the mountpoint
+-	if list_mounts | grep -q -E " $CANONICALIZED_MOUNTPOINT/\w+" >/dev/null 2>&1; then
++	match_string="${TAB}${CANONICALIZED_MOUNTPOINT}"
++	if list_mounts | grep -q -E "$match_string/\w+" >/dev/null 2>&1; then
+ 		ocf_log err "There is one or more mounts mounted under $MOUNTPOINT."
+ 		return $OCF_ERR_CONFIGURED
+ 	fi
+@@ -514,9 +526,9 @@ Filesystem_start()
+ 		if is_fsck_needed; then
+ 			ocf_log info  "Starting filesystem check on $DEVICE"
+ 			if [ -z "$FSTYPE" ]; then
+-				$FSCK -p $DEVICE
++				$FSCK -p "$DEVICE"
+ 			else
+-				$FSCK -t $FSTYPE -p $DEVICE
++				$FSCK -t "$FSTYPE" -p "$DEVICE"
+ 			fi
+ 
+ 			# NOTE: if any errors at all are detected, it returns non-zero
+@@ -529,20 +541,20 @@ Filesystem_start()
+ 	fi
+ 
+ 	[ -d "$MOUNTPOINT" ] ||
+-		ocf_run mkdir -p $MOUNTPOINT
++		ocf_run mkdir -p "$MOUNTPOINT"
+ 	if [ ! -d "$MOUNTPOINT" ] ; then
+ 		ocf_exit_reason "Couldn't find directory  [$MOUNTPOINT] to use as a mount point"
+ 		exit $OCF_ERR_INSTALLED
+ 	fi
+ 
+-	flushbufs $DEVICE
++	flushbufs "$DEVICE"
+ 	# Mount the filesystem.
+ 	case "$FSTYPE" in
+-		none) $MOUNT $options $DEVICE $MOUNTPOINT &&
++		none) $MOUNT $options "$DEVICE" "$MOUNTPOINT" &&
+ 			bind_mount
+ 			;;
+-		"") $MOUNT $options $DEVICE $MOUNTPOINT ;;
+-		*) $MOUNT -t $FSTYPE $options $DEVICE $MOUNTPOINT ;;
++		"") $MOUNT $options "$DEVICE" "$MOUNTPOINT" ;;
++		*) $MOUNT -t "$FSTYPE" $options "$DEVICE" "$MOUNTPOINT" ;;
+ 	esac
+ 
+ 	if [ $? -ne 0 ]; then
+@@ -595,23 +607,23 @@ signal_processes() {
+ 	done
+ }
+ try_umount() {
+-	local SUB=$1
+-	$UMOUNT $umount_force $SUB
+-	list_mounts | grep -q " $SUB " >/dev/null 2>&1 || {
++	local SUB="$1"
++	$UMOUNT $umount_force "$SUB"
++	list_mounts | grep -q "${TAB}${SUB}${TAB}" >/dev/null 2>&1 || {
+ 		ocf_log info "unmounted $SUB successfully"
+ 		return $OCF_SUCCESS
+ 	}
+ 	return $OCF_ERR_GENERIC
+ }
+ fs_stop() {
+-	local SUB=$1 timeout=$2 sig cnt
++	local SUB="$1" timeout=$2 sig cnt
+ 	for sig in TERM KILL; do
+ 		cnt=$((timeout/2)) # try half time with TERM
+ 		while [ $cnt -gt 0 ]; do
+-			try_umount $SUB &&
++			try_umount "$SUB" &&
+ 				return $OCF_SUCCESS
+ 			ocf_exit_reason "Couldn't unmount $SUB; trying cleanup with $sig"
+-			signal_processes $SUB $sig
++			signal_processes "$SUB" $sig
+ 			cnt=$((cnt-1))
+ 			sleep 1
+ 		done
+@@ -633,7 +645,7 @@ Filesystem_stop()
+ 		# Wipe the status file, but continue with a warning if
+ 		# removal fails -- the file system might be read only
+ 		if [ $OCF_CHECK_LEVEL -eq 20 ]; then
+-			rm -f ${STATUSFILE}
++			rm -f "${STATUSFILE}"
+ 			if [ $? -ne 0 ]; then
+ 				ocf_log warn "Failed to remove status file ${STATUSFILE}."
+ 			fi
+@@ -650,7 +662,7 @@ Filesystem_stop()
+ 
+ 		# Umount all sub-filesystems mounted under $MOUNTPOINT/ too.
+ 		local timeout
+-		for SUB in `list_submounts $MOUNTPOINT` $MOUNTPOINT; do
++		while read SUB; do
+ 			ocf_log info "Trying to unmount $SUB"
+ 			if ocf_is_true "$FAST_STOP"; then
+ 				timeout=6
+@@ -658,15 +670,18 @@ Filesystem_stop()
+ 				timeout=${OCF_RESKEY_CRM_meta_timeout:="20000"}
+ 				timeout=$((timeout/1000))
+ 			fi
+-			fs_stop $SUB $timeout
++			fs_stop "$SUB" $timeout
+ 			rc=$?
+ 			if [ $rc -ne $OCF_SUCCESS ]; then
+ 				ocf_exit_reason "Couldn't unmount $SUB, giving up!"
+ 			fi
+-		done
++		done <<-EOF
++			$(list_submounts "$CANONICALIZED_MOUNTPOINT"; \
++				echo $CANONICALIZED_MOUNTPOINT)
++			EOF
+ 	fi
+ 
+-	flushbufs $DEVICE
++	flushbufs "$DEVICE"
+ 
+ 	return $rc
+ }
+@@ -677,7 +692,8 @@ Filesystem_stop()
+ #
+ Filesystem_status()
+ {
+-	if list_mounts | grep -q " $CANONICALIZED_MOUNTPOINT " >/dev/null 2>&1; then
++	match_string="${TAB}${CANONICALIZED_MOUNTPOINT}${TAB}"
++	if list_mounts | grep -q "$match_string" >/dev/null 2>&1; then
+ 		rc=$OCF_SUCCESS
+ 		msg="$MOUNTPOINT is mounted (running)"
+ 	else
+@@ -712,7 +728,7 @@ Filesystem_monitor_10()
+ 		return $OCF_SUCCESS
+ 	fi
+ 	dd_opts="iflag=direct bs=4k count=1"
+-	err_output=`dd if=$DEVICE $dd_opts 2>&1 >/dev/null`
++	err_output=`dd if="$DEVICE" $dd_opts 2>&1 >/dev/null`
+ 	if [ $? -ne 0 ]; then
+ 		ocf_exit_reason "Failed to read device $DEVICE"
+ 		ocf_log err "dd said: $err_output"
+@@ -733,20 +749,20 @@ Filesystem_monitor_20()
+ 		# to bypass caches.
+ 		dd_opts="oflag=direct,sync bs=4k conv=fsync,sync"
+ 	fi
+-	status_dir=`dirname $STATUSFILE`
++	status_dir=$(dirname "$STATUSFILE")
+ 	[ -d "$status_dir" ] || mkdir -p "$status_dir"
+-	err_output=`echo "${OCF_RESOURCE_INSTANCE}" | dd of=${STATUSFILE} $dd_opts 2>&1`
++	err_output=`echo "${OCF_RESOURCE_INSTANCE}" | dd of="${STATUSFILE}" $dd_opts 2>&1`
+ 	if [ $? -ne 0 ]; then
+ 		ocf_exit_reason "Failed to write status file ${STATUSFILE}"
+ 		ocf_log err "dd said: $err_output"
+ 		return $OCF_ERR_GENERIC
+ 	fi
+-	test -f ${STATUSFILE}
++	test -f "${STATUSFILE}"
+ 	if [ $? -ne 0 ]; then
+ 		ocf_exit_reason "Cannot stat the status file ${STATUSFILE}"
+ 		return $OCF_ERR_GENERIC
+ 	fi
+-	cat ${STATUSFILE} > /dev/null
++	cat "${STATUSFILE}" > /dev/null
+ 	if [ $? -ne 0 ]; then
+ 		ocf_exit_reason "Cannot read the status file ${STATUSFILE}"
+ 		return $OCF_ERR_GENERIC
+@@ -791,9 +807,9 @@ Filesystem_validate_all()
+ 	# NOTE: Without inserting the $FSTYPE module, this step may be imprecise
+ 	# TODO: This is Linux specific crap.
+ 	if [ ! -z "$FSTYPE" -a "$FSTYPE" != none ]; then
+-		cut -f2 /proc/filesystems |grep -q ^$FSTYPE$
++		cut -f2 /proc/filesystems |grep -q "^${FSTYPE}$"
+ 		if [ $? -ne 0 ]; then
+-			modpath=/lib/modules/`uname -r` 
++			modpath=/lib/modules/`uname -r`
+ 			moddep=$modpath/modules.dep
+ 			# Do we have $FSTYPE in modules.dep?
+ 			cut -d' ' -f1 $moddep |grep -q "^$modpath.*$FSTYPE\.k\?o:$"
+@@ -826,7 +842,7 @@ set_blockdevice_var() {
+ 	blockdevice=no
+ 
+ 	# these are definitely not block devices
+-	case $FSTYPE in
++	case "$FSTYPE" in
+ 	nfs4|nfs|smbfs|cifs|none|glusterfs|ceph|tmpfs|overlay|overlayfs|rozofs|zfs|cvfs) return;;
+ 	esac
+ 
+@@ -834,7 +850,7 @@ set_blockdevice_var() {
+ 		return
+ 	fi
+ 
+-	case $DEVICE in
++	case "$DEVICE" in
+ 	-*) # Oh... An option to mount instead...  Typically -U or -L
+ 		;;
+ 	/dev/null) # Special case for BSC
+@@ -863,7 +879,7 @@ if [ -n "${OCF_RESKEY_force_unmount}" ]; then
+ 	FORCE_UNMOUNT=$OCF_RESKEY_force_unmount
+ fi
+ 
+-DEVICE=$OCF_RESKEY_device
++DEVICE="$OCF_RESKEY_device"
+ FSTYPE=$OCF_RESKEY_fstype
+ if [ ! -z "$OCF_RESKEY_options" ]; then
+ 	options="-o $OCF_RESKEY_options"
+@@ -899,10 +915,10 @@ if [ -z "$OCF_RESKEY_directory" ]; then
+ 		exit $OCF_ERR_CONFIGURED 
+ 	fi
+ else
+-	MOUNTPOINT=$(echo $OCF_RESKEY_directory | sed 's/\/*$//')
++	MOUNTPOINT="$(echo "$OCF_RESKEY_directory" | sed 's/\/*$//')"
+ 	: ${MOUNTPOINT:=/}
+ 	if [ -e "$MOUNTPOINT" ] ; then
+-		CANONICALIZED_MOUNTPOINT=$(readlink -f "$MOUNTPOINT")
++		CANONICALIZED_MOUNTPOINT="$(readlink -f "$MOUNTPOINT")"
+ 		if [ $? -ne 0 ]; then
+ 			ocf_exit_reason "Could not canonicalize $MOUNTPOINT because readlink failed"
+ 			exit $OCF_ERR_GENERIC
+@@ -947,7 +963,7 @@ CLUSTERSAFE=0
+ is_option "ro" &&
+ 	CLUSTERSAFE=2
+ 
+-case $FSTYPE in
++case "$FSTYPE" in
+ nfs4|nfs|smbfs|cifs|none|gfs2|glusterfs|ceph|ocfs2|overlay|overlayfs|tmpfs|cvfs)
+ 	CLUSTERSAFE=1 # this is kind of safe too
+ 	;;
+
+From eca9a96ad3356df3636bfa3187afe1b1954693b2 Mon Sep 17 00:00:00 2001
+From: Reid wahl <nrwahl@protonmail.com>
+Date: Fri, 10 Jul 2020 16:38:04 -0700
+Subject: [PATCH 2/3] Filesystem: POSIX-compliant syntax for portability
+
+Updated to use POSIX `$()` instead of Bourne-shell backticks, and to
+use `grep ... >/dev/null 2>&1` instead of `grep -q`. (Note: `grep -q`
+only suppresses `stdout` anyway. `grep -q -s` would be required to
+suppress both `stdout` and `stderr`.)
+---
+ heartbeat/Filesystem | 33 +++++++++++++++++----------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem
+index 9a52aa712..34ade20d7 100755
+--- a/heartbeat/Filesystem
++++ b/heartbeat/Filesystem
+@@ -90,7 +90,7 @@ fi
+ : ${OCF_RESKEY_force_unmount=${OCF_RESKEY_force_unmount_default}}
+ 
+ # Variables used by multiple methods
+-HOSTOS=`uname`
++HOSTOS=$(uname)
+ TAB='	'
+ 
+ # The status file is going to an extra directory, by default
+@@ -100,7 +100,7 @@ prefix=${OCF_RESKEY_statusfile_prefix}
+ suffix="${OCF_RESOURCE_INSTANCE}"
+ [ "$OCF_RESKEY_CRM_meta_clone" ] &&
+ 	suffix="${suffix}_$OCF_RESKEY_CRM_meta_clone"
+-suffix="${suffix}_`uname -n`"
++suffix="${suffix}_$(uname -n)"
+ STATUSFILE="${OCF_RESKEY_directory}/$prefix$suffix"
+ 
+ #######################################################################
+@@ -329,7 +329,7 @@ determine_blockdevice() {
+ 		: ;;
+ 	*)
+ 		match_string="${TAB}${CANONICALIZED_MOUNTPOINT}${TAB}"
+-		DEVICE=`list_mounts | grep "$match_string" | cut -d"$TAB" -f1`
++		DEVICE=$(list_mounts | grep "$match_string" | cut -d"$TAB" -f1)
+ 		if [ -b "$DEVICE" ]; then
+ 			blockdevice=yes
+ 		fi
+@@ -354,7 +354,7 @@ bind_kernel_check() {
+ 			exit(1);
+ 	}'
+ 	[ $? -ne 0 ] &&
+-		ocf_log warn "kernel `uname -r` cannot handle read only bind mounts"
++		ocf_log warn "kernel $(uname -r) cannot handle read only bind mounts"
+ }
+ 
+ bind_root_mount_check() {
+@@ -369,7 +369,7 @@ bind_mount() {
+ 	if is_bind_mount && [ "$options" != "-o bind" ]
+ 	then
+ 		bind_kernel_check
+-		bind_opts=`echo "$options" | sed 's/bind/remount/'`
++		bind_opts=$(echo "$options" | sed 's/bind/remount/')
+ 		$MOUNT $bind_opts "$MOUNTPOINT"
+ 	else
+ 		true # make sure to return OK
+@@ -469,7 +469,7 @@ trigger_udev_rules_if_needed()
+ 			refresh_flag="yes"
+ 		fi
+ 	else
+-		tmp="`echo $DEVICE|awk '{$1=""; print substr($0,2)}'`"
++		tmp="$(echo $DEVICE|awk '{$1=""; print substr($0,2)}')"
+ 		case "$DEVICE" in 
+ 		-U*|--uuid*) 
+ 			tmp="/dev/disk/by-uuid/$tmp" 
+@@ -498,7 +498,7 @@ Filesystem_start()
+ {
+ 	# Check if there are any mounts mounted under the mountpoint
+ 	match_string="${TAB}${CANONICALIZED_MOUNTPOINT}"
+-	if list_mounts | grep -q -E "$match_string/\w+" >/dev/null 2>&1; then
++	if list_mounts | grep -E "$match_string/\w+" >/dev/null 2>&1; then
+ 		ocf_log err "There is one or more mounts mounted under $MOUNTPOINT."
+ 		return $OCF_ERR_CONFIGURED
+ 	fi
+@@ -602,14 +602,14 @@ signal_processes() {
+ 		return
+ 	fi
+ 	for pid in $pids; do
+-		ocf_log info "sending signal $sig to: `ps -f $pid | tail -1`"
++		ocf_log info "sending signal $sig to: $(ps -f $pid | tail -1)"
+ 		kill -s $sig $pid
+ 	done
+ }
+ try_umount() {
+ 	local SUB="$1"
+ 	$UMOUNT $umount_force "$SUB"
+-	list_mounts | grep -q "${TAB}${SUB}${TAB}" >/dev/null 2>&1 || {
++	list_mounts | grep "${TAB}${SUB}${TAB}" >/dev/null 2>&1 || {
+ 		ocf_log info "unmounted $SUB successfully"
+ 		return $OCF_SUCCESS
+ 	}
+@@ -693,7 +693,7 @@ Filesystem_stop()
+ Filesystem_status()
+ {
+ 	match_string="${TAB}${CANONICALIZED_MOUNTPOINT}${TAB}"
+-	if list_mounts | grep -q "$match_string" >/dev/null 2>&1; then
++	if list_mounts | grep "$match_string" >/dev/null 2>&1; then
+ 		rc=$OCF_SUCCESS
+ 		msg="$MOUNTPOINT is mounted (running)"
+ 	else
+@@ -728,7 +728,7 @@ Filesystem_monitor_10()
+ 		return $OCF_SUCCESS
+ 	fi
+ 	dd_opts="iflag=direct bs=4k count=1"
+-	err_output=`dd if="$DEVICE" $dd_opts 2>&1 >/dev/null`
++	err_output=$(dd if="$DEVICE" $dd_opts 2>&1 >/dev/null)
+ 	if [ $? -ne 0 ]; then
+ 		ocf_exit_reason "Failed to read device $DEVICE"
+ 		ocf_log err "dd said: $err_output"
+@@ -751,7 +751,7 @@ Filesystem_monitor_20()
+ 	fi
+ 	status_dir=$(dirname "$STATUSFILE")
+ 	[ -d "$status_dir" ] || mkdir -p "$status_dir"
+-	err_output=`echo "${OCF_RESOURCE_INSTANCE}" | dd of="${STATUSFILE}" $dd_opts 2>&1`
++	err_output=$(echo "${OCF_RESOURCE_INSTANCE}" | dd of="${STATUSFILE}" $dd_opts 2>&1)
+ 	if [ $? -ne 0 ]; then
+ 		ocf_exit_reason "Failed to write status file ${STATUSFILE}"
+ 		ocf_log err "dd said: $err_output"
+@@ -807,12 +807,13 @@ Filesystem_validate_all()
+ 	# NOTE: Without inserting the $FSTYPE module, this step may be imprecise
+ 	# TODO: This is Linux specific crap.
+ 	if [ ! -z "$FSTYPE" -a "$FSTYPE" != none ]; then
+-		cut -f2 /proc/filesystems |grep -q "^${FSTYPE}$"
++		cut -f2 /proc/filesystems | grep "^${FSTYPE}$" >/dev/null 2>&1
+ 		if [ $? -ne 0 ]; then
+-			modpath=/lib/modules/`uname -r`
++			modpath=/lib/modules/$(uname -r)
+ 			moddep=$modpath/modules.dep
+ 			# Do we have $FSTYPE in modules.dep?
+-			cut -d' ' -f1 $moddep |grep -q "^$modpath.*$FSTYPE\.k\?o:$"
++			cut -d' ' -f1 $moddep \
++				| grep "^${modpath}.*${FSTYPE}\.k\?o:$" >/dev/null 2>&1
+ 			if [ $? -ne 0 ]; then
+ 				ocf_log info "It seems we do not have $FSTYPE support"
+ 			fi
+@@ -846,7 +847,7 @@ set_blockdevice_var() {
+ 	nfs4|nfs|smbfs|cifs|none|glusterfs|ceph|tmpfs|overlay|overlayfs|rozofs|zfs|cvfs|lustre) return;;
+ 	esac
+ 
+-	if `is_option "loop"`; then
++	if $(is_option "loop"); then
+ 		return
+ 	fi
+ 
+
+From 5517712f4bb6e90b23cde6310c03509c9061cb36 Mon Sep 17 00:00:00 2001
+From: Reid wahl <nrwahl@protonmail.com>
+Date: Fri, 10 Jul 2020 16:44:17 -0700
+Subject: [PATCH 3/3] Filesystem: Convert leading space characters to tabs
+
+A few lines started with spaces instead of tabs. Tabs are the
+convention in this file.
+---
+ heartbeat/Filesystem | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem
+index 34ade20d7..501e5a0d0 100755
+--- a/heartbeat/Filesystem
++++ b/heartbeat/Filesystem
+@@ -359,10 +359,10 @@ bind_kernel_check() {
+ 
+ bind_root_mount_check() {
+ 	if [ "$(df -P "$1"  | awk 'END{print $6}')" = "/" ]; then
+-                return 1
+-        else
+-                return 0
+-        fi
++		return 1
++	else
++		return 0
++	fi
+ }
+ 
+ bind_mount() {
+@@ -571,10 +571,10 @@ get_pids()
+ 	local procs
+ 	local mmap_procs
+ 
+-        if is_bind_mount && ocf_is_true "$FORCE_UNMOUNT" && ! bind_root_mount_check "$DEVICE"; then
+-                ocf_log debug "Change force_umount from '$FORCE_UNMOUNT' to 'safe'"
+-                FORCE_UNMOUNT=safe
+-        fi
++	if is_bind_mount && ocf_is_true "$FORCE_UNMOUNT" && ! bind_root_mount_check "$DEVICE"; then
++		ocf_log debug "Change force_umount from '$FORCE_UNMOUNT' to 'safe'"
++		FORCE_UNMOUNT=safe
++	fi
+ 
+ 	if ocf_is_true  "$FORCE_UNMOUNT"; then
+ 		if [ "X${HOSTOS}" = "XOpenBSD" ];then
diff --git a/SOURCES/bz1861001-sybaseASE-add-logfile-parameter.patch b/SOURCES/bz1861001-sybaseASE-add-logfile-parameter.patch
new file mode 100644
index 0000000..b294584
--- /dev/null
+++ b/SOURCES/bz1861001-sybaseASE-add-logfile-parameter.patch
@@ -0,0 +1,53 @@
+From d62d8776df8aaa1da32e8452b3816505d1ea1f7f Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Wed, 28 Oct 2020 15:06:47 +0100
+Subject: [PATCH] sybaseASE: add logfile parameter
+
+---
+ heartbeat/sybaseASE.in | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/heartbeat/sybaseASE.in b/heartbeat/sybaseASE.in
+index 7ff30bd31..fef76474e 100755
+--- a/heartbeat/sybaseASE.in
++++ b/heartbeat/sybaseASE.in
+@@ -115,6 +115,13 @@ fi
+ interfaces_file_default="${OCF_RESKEY_sybase_home}/interfaces"
+ : ${OCF_RESKEY_interfaces_file=${interfaces_file_default}}
+ 
++if [ $__OCF_ACTION != "meta-data" ]; then
++	logfile_default="$OCF_RESKEY_sybase_home/$OCF_RESKEY_sybase_ase/install/$OCF_RESKEY_server_name.log"
++else
++	logfile_default="detect"
++fi
++: ${OCF_RESKEY_logfile=${logfile_default}}
++
+ export LD_POINTER_GUARD=0
+ 
+ #######################################################################################
+@@ -122,7 +129,7 @@ export LD_POINTER_GUARD=0
+ #######################################################################################
+ declare login_string=""
+ declare RUNSERVER_SCRIPT=$OCF_RESKEY_sybase_home/$OCF_RESKEY_sybase_ase/install/RUN_$OCF_RESKEY_server_name
+-declare CONSOLE_LOG=$OCF_RESKEY_sybase_home/$OCF_RESKEY_sybase_ase/install/$OCF_RESKEY_server_name.log
++declare CONSOLE_LOG="$OCF_RESKEY_logfile"
+ 
+ ##################################################################################################
+ # This function will be called by Pacemaker to get the meta data of resource agent "sybaseASE".  #
+@@ -223,6 +230,16 @@ meta_data()
+ 			<content type="string"/>
+ 		</parameter>
+ 
++		<parameter name="logfile">
++			<longdesc lang="en">
++				Logfile
++			</longdesc>
++			<shortdesc lang="en">
++				Logfile
++			</shortdesc>
++			<content type="string" default="$logfile_default" />
++		</parameter>
++
+ 	</parameters>
+ 
+ 	<actions>
diff --git a/SOURCES/bz1872999-aws-vpc-move-ip-add-region-parameter.patch b/SOURCES/bz1872999-aws-vpc-move-ip-add-region-parameter.patch
new file mode 100644
index 0000000..4fef3d5
--- /dev/null
+++ b/SOURCES/bz1872999-aws-vpc-move-ip-add-region-parameter.patch
@@ -0,0 +1,81 @@
+--- ClusterLabs-resource-agents-e711383f/heartbeat/aws-vpc-move-ip	2020-09-23 11:57:38.855067216 +0200
++++ aws-vpc-move-ip.tmp	2020-09-23 11:57:17.993045991 +0200
+@@ -37,13 +37,17 @@
+ # Defaults
+ OCF_RESKEY_awscli_default="/usr/bin/aws"
+ OCF_RESKEY_profile_default="default"
++OCF_RESKEY_region_default=""
+ OCF_RESKEY_routing_table_role_default=""
+ OCF_RESKEY_monapi_default="false"
+ 
+ : ${OCF_RESKEY_awscli=${OCF_RESKEY_awscli_default}}
+ : ${OCF_RESKEY_profile=${OCF_RESKEY_profile_default}}
++: ${OCF_RESKEY_region=${OCF_RESKEY_region_default}}
+ : ${OCF_RESKEY_routing_table_role=${OCF_RESKEY_routing_table_role_default}}
+ : ${OCF_RESKEY_monapi=${OCF_RESKEY_monapi_default}}
++
++[ -n "$OCF_RESKEY_region" ] && region_opt="--region $OCF_RESKEY_region"
+ #######################################################################
+ 
+ 
+@@ -87,6 +91,14 @@
+ <content type="string" default="${OCF_RESKEY_profile_default}" />
+ </parameter>
+ 
++<parameter name="region">
++<longdesc lang="en">
++Valid AWS region name (e.g., 'us-west-2')
++</longdesc>
++<shortdesc lang="en">region name</shortdesc>
++<content type="string" default="${OCF_RESKEY_region_default}" />
++</parameter>
++
+ <parameter name="ip" required="1">
+ <longdesc lang="en">
+ VPC private IP address
+@@ -151,7 +163,7 @@
+ execute_cmd_as_role(){
+ 	cmd=$1
+ 	role=$2
+-	output="$($OCF_RESKEY_awscli sts assume-role --role-arn $role --role-session-name AWSCLI-RouteTableUpdate --profile $OCF_RESKEY_profile --output=text)"
++	output="$($OCF_RESKEY_awscli sts assume-role --role-arn $role --role-session-name AWSCLI-RouteTableUpdate --profile $OCF_RESKEY_profile $region_opt --output=text)"
+ 	export AWS_ACCESS_KEY_ID="$(echo $output | awk -F" " '$4=="CREDENTIALS" {print $5}')"
+ 	export AWS_SECRET_ACCESS_KEY="$(echo $output | awk -F" " '$4=="CREDENTIALS" {print $7}')"
+ 	export AWS_SESSION_TOKEN="$(echo $output | awk -F" " '$4=="CREDENTIALS" {print $8}')"
+@@ -198,11 +210,11 @@
+ 		for rtb in $(echo $OCF_RESKEY_routing_table | sed -e 's/,/ /g'); do
+ 			ocf_log info "monitor: check routing table (API call) - $rtb"
+ 			if [[ -z "${OCF_RESKEY_routing_table_role}" ]]; then
+-				cmd="$OCF_RESKEY_awscli --profile $OCF_RESKEY_profile --output text ec2 describe-route-tables --route-table-ids $rtb --query RouteTables[*].Routes[?DestinationCidrBlock=='$OCF_RESKEY_ip/32'].InstanceId"
++				cmd="$OCF_RESKEY_awscli --profile $OCF_RESKEY_profile $region_opt --output text ec2 describe-route-tables --route-table-ids $rtb --query RouteTables[*].Routes[?DestinationCidrBlock=='$OCF_RESKEY_ip/32'].InstanceId"
+ 				ocf_log debug "executing command: $cmd"
+ 				ROUTE_TO_INSTANCE="$($cmd)"
+ 			else
+-				cmd="$OCF_RESKEY_awscli --output text ec2 describe-route-tables --route-table-ids $rtb --query RouteTables[*].Routes[?DestinationCidrBlock=='$OCF_RESKEY_ip/32'].InstanceId"
++				cmd="$OCF_RESKEY_awscli $region_opt --output text ec2 describe-route-tables --route-table-ids $rtb --query RouteTables[*].Routes[?DestinationCidrBlock=='$OCF_RESKEY_ip/32'].InstanceId"
+ 				ROUTE_TO_INSTANCE="$(execute_cmd_as_role "$cmd" $OCF_RESKEY_routing_table_role)"
+ 			fi
+ 			ocf_log debug "Overlay IP is currently routed to ${ROUTE_TO_INSTANCE}"
+@@ -283,11 +295,11 @@
+ 
+ 	for rtb in $(echo $OCF_RESKEY_routing_table | sed -e 's/,/ /g'); do
+ 		if [[ -z "${OCF_RESKEY_routing_table_role}" ]]; then
+-			cmd="$OCF_RESKEY_awscli --profile $OCF_RESKEY_profile --output text ec2 replace-route --route-table-id $rtb --destination-cidr-block ${OCF_RESKEY_ip}/32 --network-interface-id $EC2_NETWORK_INTERFACE_ID"
++			cmd="$OCF_RESKEY_awscli --profile $OCF_RESKEY_profile $region_opt --output text ec2 replace-route --route-table-id $rtb --destination-cidr-block ${OCF_RESKEY_ip}/32 --network-interface-id $EC2_NETWORK_INTERFACE_ID"
+ 			ocf_log debug "executing command: $cmd"
+ 			$cmd
+ 		else
+-			cmd="$OCF_RESKEY_awscli --output text ec2 replace-route --route-table-id $rtb --destination-cidr-block ${OCF_RESKEY_ip}/32 --network-interface-id $EC2_NETWORK_INTERFACE_ID"
++			cmd="$OCF_RESKEY_awscli $region_opt --output text ec2 replace-route --route-table-id $rtb --destination-cidr-block ${OCF_RESKEY_ip}/32 --network-interface-id $EC2_NETWORK_INTERFACE_ID"
+ 			update_response="$(execute_cmd_as_role "$cmd" $OCF_RESKEY_routing_table_role)"
+ 		fi
+ 		rc=$?
+@@ -397,7 +409,7 @@
+ 		ec2ip_monitor;;
+ 	validate-all)
+ 		exit $?;;
+-	*)	
++	*)
+ 		echo $USAGE
+ 		exit $OCF_ERR_UNIMPLEMENTED
+ 		;;
diff --git a/SOURCES/bz1881114-galera-recover-joining-non-existing-cluster.patch b/SOURCES/bz1881114-galera-recover-joining-non-existing-cluster.patch
new file mode 100644
index 0000000..17b823a
--- /dev/null
+++ b/SOURCES/bz1881114-galera-recover-joining-non-existing-cluster.patch
@@ -0,0 +1,51 @@
+From 028bd6aab181104fe68166c8ec9c0485e12f9376 Mon Sep 17 00:00:00 2001
+From: Damien Ciabrini <dciabrin@redhat.com>
+Date: Fri, 18 Sep 2020 18:34:22 +0200
+Subject: [PATCH] galera: recover from joining a non existing cluster
+
+galera being a M/S resource, the resource agent decides
+when and how to promote a resource based on the current
+state of the galera cluster. If there's no cluster,
+a resource is promoted as the bootstrap node. Otherwise
+it is promoted as a joiner node.
+
+There can be some time between the moment when a node is
+promoted and when the promote operation effectively
+takes place. So if a node is promoted for joining a cluster,
+all the running galera nodes are stopped before the promote
+operation start, the joining node won't be able to join the
+cluster, and it can't bootstrap a new one either because it
+doesn't have the most recent copy of the DB.
+
+In that case, do not make the promotion fail, and force
+a demotion instead. This ensures that a normal bootstrap
+election will take place eventually, without blocking
+the joining node due to a failed promotion.
+---
+ heartbeat/galera | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/heartbeat/galera b/heartbeat/galera
+index 74f11d8c5..d2f4faa86 100755
+--- a/heartbeat/galera
++++ b/heartbeat/galera
+@@ -727,9 +727,16 @@ galera_promote()
+             ocf_log info "Node <${NODENAME}> is bootstrapping the cluster"
+             extra_opts="--wsrep-cluster-address=gcomm://"
+         else
+-            ocf_exit_reason "Failure, Attempted to promote Master instance of $OCF_RESOURCE_INSTANCE before bootstrap node has been detected."
+-            clear_last_commit
+-            return $OCF_ERR_GENERIC
++            # We are being promoted without having the bootstrap
++            # attribute in the CIB, which means we are supposed to
++            # join a cluster; however if we end up here, there is no
++            # Master remaining right now, which means there is no
++            # cluster to join anymore. So force a demotion, and and
++            # let the RA decide later which node should be the next
++            # bootstrap node.
++            ocf_log warn "There is no running cluster to join, demoting ourself"
++            clear_master_score
++            return $OCF_SUCCESS
+         fi
+     fi
+ 
diff --git a/SOURCES/bz1886262-podman-recover-from-killed-conmon.patch b/SOURCES/bz1886262-podman-recover-from-killed-conmon.patch
new file mode 100644
index 0000000..3fa5934
--- /dev/null
+++ b/SOURCES/bz1886262-podman-recover-from-killed-conmon.patch
@@ -0,0 +1,63 @@
+From 3aa0dda4e0c2a3b801d65aeacc4fdfd713a604f2 Mon Sep 17 00:00:00 2001
+From: Damien Ciabrini <damien.ciabrini@gmail.com>
+Date: Tue, 27 Oct 2020 18:01:36 +0100
+Subject: [PATCH] podman: recover from killed conmon side process
+
+When podman containers are created by the resource-agent, the podman
+runtime spawns a side process (conmon) to monitor the container and
+record the exit status.
+
+If the conmon process dies unexpectedly (e.g. kill -9), the podman
+container can still be stopped, even if the cli returns a generic
+error.
+
+Try to distinguish this specific failure condition and make the stop
+operation resilient; when it happens, just log a warning and finish
+the usual stop actions.
+---
+ heartbeat/podman | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/heartbeat/podman b/heartbeat/podman
+index 81b00ee6f..9f8c2a091 100755
+--- a/heartbeat/podman
++++ b/heartbeat/podman
+@@ -419,6 +419,7 @@ podman_start()
+ podman_stop()
+ {
+ 	local timeout=60
++	local rc
+ 	podman_simple_status
+ 	if [ $? -eq  $OCF_NOT_RUNNING ]; then
+ 		remove_container
+@@ -434,16 +435,27 @@ podman_stop()
+ 
+ 	if ocf_is_true "$OCF_RESKEY_force_kill"; then
+ 		ocf_run podman kill $CONTAINER
++		rc=$?
+ 	else
+ 		ocf_log debug "waiting $timeout second[s] before killing container"
+ 		ocf_run podman stop -t=$timeout $CONTAINER
++		rc=$?
+ 		# on stop, systemd will automatically delete any transient
+ 		# drop-in conf that has been created earlier
+ 	fi
+ 
+-	if [ $? -ne 0 ]; then
+-		ocf_exit_reason "Failed to stop container, ${CONTAINER}, based on image, ${OCF_RESKEY_image}."
+-		return $OCF_ERR_GENERIC
++	if [ $rc -ne 0 ]; then
++		# If the stop failed, it could be because the controlling conmon
++		# process died unexpectedly. If so, a generic error code is returned
++		# but the associated container exit code is -1. If that's the case,
++		# assume there's no failure and continue with the rm as usual.
++		if [ $rc -eq 125 ] && \
++		   podman inspect --format '{{.State.Status}}:{{.State.ExitCode}}' $CONTAINER | grep -wq "stopped:-1"; then
++			ocf_log warn "Container ${CONTAINER} had an unexpected stop outcome. Trying to remove it anyway."
++		else
++			ocf_exit_reason "Failed to stop container, ${CONTAINER}, based on image, ${OCF_RESKEY_image}."
++			return $OCF_ERR_GENERIC
++		fi
+ 	fi
+ 
+ 	remove_container
diff --git a/SOURCES/bz1890068-gcp-pd-move-fix-partially-matched-disk_name.patch b/SOURCES/bz1890068-gcp-pd-move-fix-partially-matched-disk_name.patch
new file mode 100644
index 0000000..83aef93
--- /dev/null
+++ b/SOURCES/bz1890068-gcp-pd-move-fix-partially-matched-disk_name.patch
@@ -0,0 +1,58 @@
+From 2927279ba1677e9dda202121176a8245a7ef76ca Mon Sep 17 00:00:00 2001
+From: tositaka77 <45960626+tositaka77@users.noreply.github.com>
+Date: Wed, 14 Oct 2020 22:22:56 +0900
+Subject: [PATCH] fixes and improvements
+
+- Fixed "regional" PD functionality in attach_disk()
+- Improve to exact match disk_name with disks.source in detach_disk()
+---
+ heartbeat/gcp-pd-move.in | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/heartbeat/gcp-pd-move.in b/heartbeat/gcp-pd-move.in
+index f82bd25e5..e99cc71f8 100644
+--- a/heartbeat/gcp-pd-move.in
++++ b/heartbeat/gcp-pd-move.in
+@@ -49,6 +49,7 @@ else:
+ CONN = None
+ PROJECT = None
+ ZONE = None
++REGION = None
+ LIST_DISK_ATTACHED_INSTANCES = None
+ INSTANCE_NAME = None
+ 
+@@ -148,6 +149,7 @@ def populate_vars():
+   global INSTANCE_NAME
+   global PROJECT
+   global ZONE
++  global REGION
+   global LIST_DISK_ATTACHED_INSTANCES
+ 
+   # Populate global vars
+@@ -175,6 +177,7 @@ def populate_vars():
+   PROJECT = get_metadata('project/project-id')
+   if PARAMETERS['disk_scope'] in ['detect', 'regional']:
+     ZONE = get_metadata('instance/zone').split('/')[-1]
++    REGION = ZONE[:-2] 
+   else:
+     ZONE = PARAMETERS['disk_scope']
+   LIST_DISK_ATTACHED_INSTANCES = get_disk_attached_instances(
+@@ -255,7 +258,7 @@ def detach_disk(instance, disk_name):
+ 
+   device_name = None
+   for disk in response['disks']:
+-    if disk_name in disk['source']:
++    if disk_name == re.sub('.*disks/',"",disk['source']):
+       device_name = disk['deviceName']
+       break
+ 
+@@ -273,6 +276,9 @@ def detach_disk(instance, disk_name):
+ 
+ def attach_disk(instance, disk_name):
+   location = 'zones/%s' % ZONE
++  if PARAMETERS['disk_scope'] == 'regional':
++    location = 'regions/%s' % REGION
++
+   prefix = 'https://www.googleapis.com/compute/v1'
+   body = {
+     'source': '%(prefix)s/projects/%(project)s/%(location)s/disks/%(disk)s' % {
diff --git a/SOURCES/bz1891835-galera-set-bootstrap-attribute-before-promote.patch b/SOURCES/bz1891835-galera-set-bootstrap-attribute-before-promote.patch
new file mode 100644
index 0000000..7dfdc48
--- /dev/null
+++ b/SOURCES/bz1891835-galera-set-bootstrap-attribute-before-promote.patch
@@ -0,0 +1,36 @@
+From ac213f158ff851422d78ae8f56b022e8e30751bc Mon Sep 17 00:00:00 2001
+From: Damien Ciabrini <damien.ciabrini@gmail.com>
+Date: Mon, 26 Oct 2020 14:54:05 +0100
+Subject: [PATCH] galera: set bootstrap attribute before promote
+
+When the master detection takes place, the node chosen for
+becoming the master is given two attributes in the CIB:
+a master score and a bootstrap flag. The master score makes
+pacemaker schedule a promote operation, and the bootstrap flag
+drives how the galera server is started.
+
+The order in which we set the attributes is racy; it may happen
+that a promote operation is started before the current master
+detection function has set the bootstrap flag, in which case
+the promotion will fail.
+
+Reverse the order in which we set the attributes on a bootstrap
+node to close the race.
+---
+ heartbeat/galera | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/heartbeat/galera b/heartbeat/galera
+index d2f4faa86..b4d7e187d 100755
+--- a/heartbeat/galera
++++ b/heartbeat/galera
+@@ -587,8 +587,8 @@ detect_first_master()
+     fi
+ 
+     ocf_log info "Promoting $best_node to be our bootstrap node"
+-    set_master_score $best_node
+     set_bootstrap_node $best_node
++    set_master_score $best_node
+ }
+ 
+ detect_safe_to_bootstrap()
diff --git a/SOURCES/bz1891855-galera-recover-2-node-cluster.patch b/SOURCES/bz1891855-galera-recover-2-node-cluster.patch
new file mode 100644
index 0000000..22ab885
--- /dev/null
+++ b/SOURCES/bz1891855-galera-recover-2-node-cluster.patch
@@ -0,0 +1,80 @@
+--- a/heartbeat/galera	2020-10-28 16:28:48.125700714 +0100
++++ b/heartbeat/galera	2020-10-28 16:31:14.932820752 +0100
+@@ -81,6 +81,11 @@
+     . /etc/default/clustercheck
+ fi
+ 
++# Parameter defaults
++
++OCF_RESKEY_two_node_mode_default="false"
++: ${OCF_RESKEY_two_node_mode=${OCF_RESKEY_two_node_mode_default}}
++
+ #######################################################################
+ 
+ usage() {
+@@ -249,6 +254,16 @@
+ <content type="string" default="" />
+ </parameter>
+ 
++<parameter name="two_node_mode" unique="0" required="0">
++<longdesc lang="en">
++If running in a 2-node pacemaker cluster, rely on pacemaker quorum
++to allow automatic recovery even when the other node is unreachable.
++Use it with caution! (and fencing)
++</longdesc>
++<shortdesc lang="en">Special recovery when running on a 2-node cluster</shortdesc>
++<content type="boolean" default="${OCF_RESKEY_two_node_mode_default}"/>
++</parameter>
++
+ </parameters>
+ 
+ <actions>
+@@ -400,6 +415,27 @@
+     return 0
+ }
+ 
++is_two_node_mode_active()
++{
++    # crm_node or corosync-quorumtool cannot access various corosync
++    # flags when running inside a bundle, so only count the cluster
++    # members
++    ocf_is_true "$OCF_RESKEY_two_node_mode" && ${HA_SBIN_DIR}/crm_mon -1X | xmllint --xpath "count(//nodes/node[@type='member'])" - | grep -q -w 2
++}
++
++is_last_node_in_quorate_partition()
++{
++    # when a network split occurs in a 2-node cluster, pacemaker
++    # fences the other node and try to retain quorum. So until
++    # the fencing is resolved (and the status of the peer node
++    # is clean), we shouldn't consider ourself quorate.
++    local partition_members=$(${HA_SBIN_DIR}/crm_node -p | wc -w)
++    local quorate=$(${HA_SBIN_DIR}/crm_node -q)
++    local clean_members=$(${HA_SBIN_DIR}/crm_mon -1X | xmllint --xpath 'count(//nodes/node[@type="member" and @unclean="false"])' -)
++
++    [ "$partition_members" = 1 ] && [ "$quorate" = 1 ] && [ "$clean_members" = 2 ]
++}
++
+ master_exists()
+ {
+     if [ "$__OCF_ACTION" = "demote" ]; then
+@@ -518,8 +554,20 @@
+     done
+ 
+     for node in $nodes_recovered $nodes; do
++        # On clean shutdown, galera sets the last stopped node as 'safe to bootstrap',
++        # so use this hint when we can
+         safe_to_bootstrap=$(get_safe_to_bootstrap $node)
+ 
++        # Special case for 2-node clusters: during a network split, rely on
++        # pacemaker's quorum to check whether we can restart galera
++        if [ "$safe_to_bootstrap" != "1" ] && [ "$node" = "$NODENAME" ] && is_two_node_mode_active; then
++            is_last_node_in_quorate_partition
++            if [ $? -eq 0 ]; then
++                ocf_log warn "Survived a split in a 2-node cluster, considering ourselves safe to bootstrap"
++                safe_to_bootstrap=1
++            fi
++        fi
++
+         if [ "$safe_to_bootstrap" = "1" ]; then
+             # Galera marked the node as safe to boostrap during shutdown. Let's just
+             # pick it as our bootstrap node.
diff --git a/SOURCES/bz1895811-aws-vpc-move-ip-dont-warn-for-expected-scenarios.patch b/SOURCES/bz1895811-aws-vpc-move-ip-dont-warn-for-expected-scenarios.patch
new file mode 100644
index 0000000..385e034
--- /dev/null
+++ b/SOURCES/bz1895811-aws-vpc-move-ip-dont-warn-for-expected-scenarios.patch
@@ -0,0 +1,84 @@
+From 8d459216c9718269303b9caf227a971d73ec4df9 Mon Sep 17 00:00:00 2001
+From: Reid Wahl <nrwahl@protonmail.com>
+Date: Thu, 27 Aug 2020 01:34:01 -0700
+Subject: [PATCH] aws-vpc-move-ip: Don't warn for expected scenarios
+
+Make log levels more appropriate to the situation. Before this patch, a
+normal start looked like this:
+
+Operation start for aws-vip (ocf:heartbeat:aws-vpc-move-ip) returned: 'ok' (0)
+ >  stderr: Nov 09 02:38:20 INFO: EC2: Moving IP address 10.0.1.65 to this host by adjusting routing table rtb-01b4ea1ae0ec0a4d9
+ >  stderr: Nov 09 02:38:20 INFO: monitor: check routing table (API call) - rtb-01b4ea1ae0ec0a4d9
+ >  stderr: Nov 09 02:38:22 WARNING: IP 10.0.1.65 not assigned to running interface
+ >  stderr: Nov 09 02:38:22 INFO: EC2: Adjusting routing table and locally configuring IP address
+ >  stderr: RTNETLINK answers: Cannot assign requested address
+ >  stderr: Nov 09 02:38:24 WARNING: command failed, rc 2
+ >  stderr: Nov 09 02:38:24 INFO: monitor: check routing table (API call) - rtb-01b4ea1ae0ec0a4d9
+
+Now it looks like this:
+
+Operation start for aws-vip (ocf:heartbeat:aws-vpc-move-ip) returned: 'ok' (0)
+ >  stderr: Nov 09 02:40:43 INFO: EC2: Moving IP address 10.0.1.65 to this host by adjusting routing table rtb-01b4ea1ae0ec0a4d9
+ >  stderr: Nov 09 02:40:43 INFO: monitor: check routing table (API call) - rtb-01b4ea1ae0ec0a4d9
+ >  stderr: Nov 09 02:40:44 INFO: IP 10.0.1.65 not assigned to running interface
+ >  stderr: Nov 09 02:40:44 INFO: EC2: Adjusting routing table and locally configuring IP address
+ >  stderr: Nov 09 02:40:46 INFO: monitor: check routing table (API call) - rtb-01b4ea1ae0ec0a4d9
+
+Under normal circumstances, the call to `ec2ip_drop()` within
+`ec2ip_get_and_configure` should not be required at all. The drop
+function deletes the address before the get_and_configure function
+immediately re-adds the address. This call could probably be removed
+altogether. Instead, I left the call and silenced its output just in
+case of unexpected edge cases.
+
+Resolves: RHBZ#1895811
+
+Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
+---
+ heartbeat/aws-vpc-move-ip | 23 ++++++++++++++++++++---
+ 1 file changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/heartbeat/aws-vpc-move-ip b/heartbeat/aws-vpc-move-ip
+index a5b28ad92..72a89ecb1 100755
+--- a/heartbeat/aws-vpc-move-ip
++++ b/heartbeat/aws-vpc-move-ip
+@@ -270,7 +270,13 @@ ec2ip_monitor() {
+ 	ocf_log debug "executing command: $cmd"
+ 	RESULT=$($cmd | grep "$OCF_RESKEY_ip")
+ 	if [ -z "$RESULT" ]; then
+-		ocf_log warn "IP $OCF_RESKEY_ip not assigned to running interface"
++		if [ "$__OCF_ACTION" = "monitor" ] && ! ocf_is_probe; then
++			level="error"
++		else
++			level="info"
++		fi
++
++		ocf_log "$level" "IP $OCF_RESKEY_ip not assigned to running interface"
+ 		return $OCF_NOT_RUNNING
+ 	fi
+ 
+@@ -282,11 +288,22 @@ ec2ip_monitor() {
+ ec2ip_drop() {
+ 	cmd="ip addr delete ${OCF_RESKEY_ip}/32 dev $OCF_RESKEY_interface"
+ 	ocf_log debug "executing command: $cmd"
+-	$cmd
++	output=$($cmd 2>&1)
+ 	rc=$?
++
+ 	if [ "$rc" -gt 0 ]; then
+-		ocf_log warn "command failed, rc $rc"
++		if [ "$__OCF_ACTION" = "start" ]; then
++			# expected to fail during start
++			level="debug"
++		else
++			level="warn"
++		fi
++
++		ocf_log "$level" "command failed, rc $rc"
++		ocf_log "$level" "output/error: $output"
+ 		return $OCF_ERR_GENERIC
++	else
++		ocf_log debug "output/error: $output"
+ 	fi
+ 
+ 	# delete remaining route-entries if any
diff --git a/SOURCES/bz1897570-aws-add-imdsv2-support.patch b/SOURCES/bz1897570-aws-add-imdsv2-support.patch
new file mode 100644
index 0000000..09772cc
--- /dev/null
+++ b/SOURCES/bz1897570-aws-add-imdsv2-support.patch
@@ -0,0 +1,97 @@
+From 8f10d0eb1e33d38ab6e89015a903620c54edd7c1 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Fri, 13 Nov 2020 16:36:20 +0100
+Subject: [PATCH] AWS agents: add support for IMDSv2
+
+---
+ heartbeat/aws-vpc-move-ip    | 5 +++--
+ heartbeat/aws-vpc-route53.in | 3 ++-
+ heartbeat/awseip             | 9 +++++----
+ heartbeat/awsvip             | 7 ++++---
+ 4 files changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/heartbeat/aws-vpc-move-ip b/heartbeat/aws-vpc-move-ip
+index 72a89ecb1..cbb629b00 100755
+--- a/heartbeat/aws-vpc-move-ip
++++ b/heartbeat/aws-vpc-move-ip
+@@ -215,7 +215,8 @@ ec2ip_validate() {
+ 		return $OCF_ERR_CONFIGURED
+ 	fi
+ 
+-	EC2_INSTANCE_ID="$(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
++	TOKEN=$(curl -X 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")
+ 
+ 	if [ -z "${EC2_INSTANCE_ID}" ]; then
+ 		ocf_exit_reason "Instance ID not found. Is this a EC2 instance?"
+@@ -329,7 +330,7 @@ ec2ip_get_instance_eni() {
+ 	fi
+ 	ocf_log debug "MAC address associated with interface ${OCF_RESKEY_interface}: ${MAC_ADDR}"
+ 
+-	cmd="curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC_ADDR}/interface-id"
++	cmd="curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC_ADDR}/interface-id -H \"X-aws-ec2-metadata-token: $TOKEN\""
+ 	ocf_log debug "executing command: $cmd"
+ 	EC2_NETWORK_INTERFACE_ID="$(eval $cmd)"
+ 	rc=$?
+diff --git a/heartbeat/aws-vpc-route53.in b/heartbeat/aws-vpc-route53.in
+index b06b93726..4fb17019b 100644
+--- a/heartbeat/aws-vpc-route53.in
++++ b/heartbeat/aws-vpc-route53.in
+@@ -347,7 +347,8 @@ r53_monitor() {
+ _get_ip() {
+ 	case $OCF_RESKEY_ip in
+ 		local|public)
+-			IPADDRESS="$(curl -s http://169.254.169.254/latest/meta-data/${OCF_RESKEY_ip}-ipv4)";;
++			TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
++			IPADDRESS=$(curl -s http://169.254.169.254/latest/meta-data/${OCF_RESKEY_ip}-ipv4 -H "X-aws-ec2-metadata-token: $TOKEN");;
+ 		*.*.*.*)
+ 			IPADDRESS="${OCF_RESKEY_ip}";;
+ 	esac
+diff --git a/heartbeat/awseip b/heartbeat/awseip
+index 445a03666..de1967774 100755
+--- a/heartbeat/awseip
++++ b/heartbeat/awseip
+@@ -149,12 +149,12 @@ awseip_start() {
+     awseip_monitor && return $OCF_SUCCESS
+ 
+     if [ -n "${PRIVATE_IP_ADDRESS}" ]; then
+-        NETWORK_INTERFACES_MACS="$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/)"
++        NETWORK_INTERFACES_MACS=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/ -H "X-aws-ec2-metadata-token: $TOKEN")
+         for MAC in ${NETWORK_INTERFACES_MACS}; do
+-            curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC}/local-ipv4s |
++            curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC}/local-ipv4s -H "X-aws-ec2-metadata-token: $TOKEN" |
+                 grep -q "^${PRIVATE_IP_ADDRESS}$"
+             if [ $? -eq 0 ]; then
+-                NETWORK_ID="$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC}/interface-id)"
++                NETWORK_ID=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC}/interface-id -H "X-aws-ec2-metadata-token: $TOKEN")
+             fi
+         done
+         $AWSCLI --profile $OCF_RESKEY_profile ec2 associate-address  \
+@@ -244,7 +244,8 @@ AWSCLI="${OCF_RESKEY_awscli}"
+ ELASTIC_IP="${OCF_RESKEY_elastic_ip}"
+ ALLOCATION_ID="${OCF_RESKEY_allocation_id}"
+ PRIVATE_IP_ADDRESS="${OCF_RESKEY_private_ip_address}"
+-INSTANCE_ID="$(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
++TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
++INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id -H "X-aws-ec2-metadata-token: $TOKEN")
+ 
+ case $__OCF_ACTION in
+     start)
+diff --git a/heartbeat/awsvip b/heartbeat/awsvip
+index 3eb31e6ae..8050107e8 100755
+--- a/heartbeat/awsvip
++++ b/heartbeat/awsvip
+@@ -206,9 +206,10 @@ esac
+ 
+ AWSCLI="${OCF_RESKEY_awscli}"
+ SECONDARY_PRIVATE_IP="${OCF_RESKEY_secondary_private_ip}"
+-INSTANCE_ID="$(curl -s http://169.254.169.254/latest/meta-data/instance-id)"
+-MAC_ADDRESS="$(curl -s http://169.254.169.254/latest/meta-data/mac)"
+-NETWORK_ID="$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC_ADDRESS}/interface-id)"
++TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
++INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id -H "X-aws-ec2-metadata-token: $TOKEN")
++MAC_ADDRESS=$(curl -s http://169.254.169.254/latest/meta-data/mac -H "X-aws-ec2-metadata-token: $TOKEN")
++NETWORK_ID=$(curl -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/${MAC_ADDRESS}/interface-id -H "X-aws-ec2-metadata-token: $TOKEN")
+ 
+ case $__OCF_ACTION in
+     start)
diff --git a/SOURCES/bz1898690-crypt-make-key_file-crypt_type_not-unique.patch b/SOURCES/bz1898690-crypt-make-key_file-crypt_type_not-unique.patch
new file mode 100644
index 0000000..8cecc16
--- /dev/null
+++ b/SOURCES/bz1898690-crypt-make-key_file-crypt_type_not-unique.patch
@@ -0,0 +1,31 @@
+From 16236f76d086187f6ae6202153519c1eb2fe4f87 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Tue, 24 Nov 2020 10:49:14 +0100
+Subject: [PATCH] crypt: make key_file and crypt_type parameters not unique
+
+---
+ heartbeat/crypt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/heartbeat/crypt b/heartbeat/crypt
+index 0e49b6c2d..7d0a5607c 100755
+--- a/heartbeat/crypt
++++ b/heartbeat/crypt
+@@ -86,7 +86,7 @@ The resulting block device path is /dev/mapper/name.
+ <content type="string" default="${OCF_RESKEY_crypt_dev_default}" />
+ </parameter>
+ 
+-<parameter name="key_file" unique="1" required="1">
++<parameter name="key_file" unique="0" required="1">
+ <longdesc lang="en">
+ Key file path containing the encryption passphrase
+ (aka key; see cryptsetup(8)).  For LUKS, the passphrase as of the key_file
+@@ -96,7 +96,7 @@ parameter is used to decrypt a randomly selected key when the device was created
+ <content type="string" default="${OCF_RESKEY_key_file_default}" />
+ </parameter>
+ 
+-<parameter name="crypt_type" unique="1" required="1">
++<parameter name="crypt_type" unique="0" required="1">
+ <longdesc lang="en">
+ Encryption (device) type (e.g. "luks" or "luks2").
+ 
diff --git a/SOURCES/bz1899551-NovaEvacuate-fix-delay_evacuate-unset.patch b/SOURCES/bz1899551-NovaEvacuate-fix-delay_evacuate-unset.patch
new file mode 100644
index 0000000..7af35cc
--- /dev/null
+++ b/SOURCES/bz1899551-NovaEvacuate-fix-delay_evacuate-unset.patch
@@ -0,0 +1,33 @@
+From 11ac2db8f55aa3e6858d6c1b2ab29ee36b612f03 Mon Sep 17 00:00:00 2001
+From: Michele Baldessari <michele@acksyn.org>
+Date: Tue, 17 Nov 2020 15:16:29 +0100
+Subject: [PATCH] Fix delay_evacuate being unset
+
+In Ie2fe784202d754eda38092479b1ab3ff4d02136a we added an additional
+parameter to allow for setting a delay on the evacuation.
+While it was tested with a specific delay, the case with a delay
+being unset was missed.
+Since OCF does not set the defaults from the metadata specification
+for a parameter, we need to manually set it ourselves.
+
+This fixes the following error:
+Nov 17 13:00:21 database-1.foo.local pacemaker-execd     [185805] (log_op_output)    notice: nova-evacuate_monitor_10000[1038417] error output [ /usr/lib/ocf/resource.d/openstack/NovaEvacuate: line 228: [: !=: unary operator expected ]
+
+Change-Id: I0b7aacd67b77bc44c67fe7da4c494807abbbb4f3
+---
+
+diff --git a/heartbeat/NovaEvacuate b/heartbeat/NovaEvacuate
+index 596f520..8aa778c 100644
+--- a/heartbeat/NovaEvacuate
++++ b/heartbeat/NovaEvacuate
+@@ -359,6 +359,10 @@
+         fence_options="${fence_options} -e ${OCF_RESKEY_endpoint_type}"
+     fi
+ 
++    if [ -z "${OCF_RESKEY_evacuate_delay}" ]; then
++        OCF_RESKEY_evacuate_delay=0
++    fi
++
+     if [ $rc != $OCF_SUCCESS ]; then
+         exit $rc
+     fi
diff --git a/SOURCES/bz1900015-podman-recover-from-storage-out-of-sync.patch b/SOURCES/bz1900015-podman-recover-from-storage-out-of-sync.patch
new file mode 100644
index 0000000..e022612
--- /dev/null
+++ b/SOURCES/bz1900015-podman-recover-from-storage-out-of-sync.patch
@@ -0,0 +1,64 @@
+From 52d09b57a499ed7b3757e0e2954c2783198d5b23 Mon Sep 17 00:00:00 2001
+From: Damien Ciabrini <damien.ciabrini@gmail.com>
+Date: Mon, 9 Nov 2020 20:42:19 +0100
+Subject: [PATCH] podman: recover from podman's storage being out of sync
+
+If a system crash while podman is stopping a container (e.g. a fencing action
+took place), it might happen that on reboot, podman is not able to recreate
+a container as requested by the resource agent.
+
+When such a start operation fails, it might be because the internal storage
+layer still references an old container with the same name, even though podman
+itself thinks there is no such container. If so, purge the storage layer to try
+to clean the corruption and try recreating the container.
+---
+ heartbeat/podman | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/heartbeat/podman b/heartbeat/podman
+index 81b00ee6f..d4d608ca3 100755
+--- a/heartbeat/podman
++++ b/heartbeat/podman
+@@ -345,6 +345,32 @@ create_transient_drop_in_dependency()
+ }
+ 
+ 
++run_new_container()
++{
++	local opts=$1
++	local image=$2
++	local cmd=$3
++	local rc
++	
++	ocf_log info "running container $CONTAINER for the first time"
++	ocf_run podman run $opts $image $cmd
++	rc=$?
++	if [ $rc -eq 125 ]; then
++		# If an internal podman error occurred, it might be because
++		# the internal storage layer still references an old container
++		# with the same name, even though podman itself thinks there
++		# is no such container. If so, purge the storage layer to try
++		# to clean the corruption and try again.
++		ocf_log warn "Internal podman error while creating new container $CONTAINER. Retrying."
++		ocf_run podman rm --storage $CONTAINER
++		ocf_run podman run $opts $image $cmd
++		rc=$?
++	fi
++	
++	return $rc
++}
++
++
+ podman_start()
+ {
+ 	local cid
+@@ -378,8 +404,7 @@ podman_start()
+ 		# make sure any previous container matching our container name is cleaned up first.
+ 		# we already know at this point it wouldn't be running
+ 		remove_container
+-		ocf_log info "running container $CONTAINER for the first time"
+-		ocf_run podman run $run_opts $OCF_RESKEY_image $OCF_RESKEY_run_cmd
++		run_new_container "$run_opts" $OCF_RESKEY_image "$OCF_RESKEY_run_cmd"
+ 	fi
+ 	rc=$?
+ 
diff --git a/SOURCES/bz1901357-crypt-1-support-symlink-devices.patch b/SOURCES/bz1901357-crypt-1-support-symlink-devices.patch
new file mode 100644
index 0000000..6b4f385
--- /dev/null
+++ b/SOURCES/bz1901357-crypt-1-support-symlink-devices.patch
@@ -0,0 +1,23 @@
+From 4ded33d34505af19ddf19bfa125b5e6c243ebd94 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Thu, 26 Nov 2020 12:56:03 +0100
+Subject: [PATCH] crypt: allow encrypted_dev to be symlink to support using
+ devices in /dev/disk/... or UUID
+
+---
+ heartbeat/crypt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/heartbeat/crypt b/heartbeat/crypt
+index 7d0a5607c..3ca28b92d 100755
+--- a/heartbeat/crypt
++++ b/heartbeat/crypt
+@@ -177,7 +177,7 @@ crypt_validate_all() {
+ 			 esac
+ 		esac
+ 	fi
+-	if [ ! -b "$encrypted_dev" ]; then
++	if [ ! -b "$encrypted_dev" ] && [ ! -L "$encrypted_dev" ]; then
+ 		ocf_exit_reason "Encrypted device $encrypted_dev not accessible"
+ 		return $OCF_ERR_ARGS
+ 	fi
diff --git a/SOURCES/bz1901357-crypt-2-dont-sanity-check-during-probe.patch b/SOURCES/bz1901357-crypt-2-dont-sanity-check-during-probe.patch
new file mode 100644
index 0000000..4e259d4
--- /dev/null
+++ b/SOURCES/bz1901357-crypt-2-dont-sanity-check-during-probe.patch
@@ -0,0 +1,44 @@
+From 6a45c28cd074e14a7bc2e2531b15595b9985965c Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Tue, 1 Dec 2020 10:11:52 +0100
+Subject: [PATCH] crypt: avoid failing for LVM exclusive by not running full
+ sanity check during probes
+
+---
+ heartbeat/crypt | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/heartbeat/crypt b/heartbeat/crypt
+index 3ca28b92d..05bded7c5 100755
+--- a/heartbeat/crypt
++++ b/heartbeat/crypt
+@@ -177,6 +177,13 @@ crypt_validate_all() {
+ 			 esac
+ 		esac
+ 	fi
++
++	# return early for probes where device might not be available yet
++	# e.g. LVM exclusive volumes
++	if ocf_is_probe; then
++		return $OCF_SUCCESS
++	fi
++
+ 	if [ ! -b "$encrypted_dev" ] && [ ! -L "$encrypted_dev" ]; then
+ 		ocf_exit_reason "Encrypted device $encrypted_dev not accessible"
+ 		return $OCF_ERR_ARGS
+@@ -294,11 +301,13 @@ crypt_stop() {
+ crypt_monitor() {
+ 	cryptsetup status $crypt_dev $disable_locks >/dev/null 2>&1
+ 	if [ $? -eq 0 ]; then
+-		[ -L $crypt_dev_path ] && return $OCF_SUCCESS
++		if [ -b "$encrypted_dev" ] || [ -L $crypt_dev_path ]; then
++			return $OCF_SUCCESS
++		fi
+ 		return $OCF_ERR_GENERIC
+ 	fi
+ 
+-        [ "$__OCF_ACTION" = "monitor" ] && ! ocf_is_probe && ocf_exit_reason "Crypt resource not running"
++	[ "$__OCF_ACTION" = "monitor" ] && ! ocf_is_probe && ocf_exit_reason "Crypt resource not running"
+ 	return $OCF_NOT_RUNNING
+ }
+ 
diff --git a/SOURCES/bz1902208-LVM-activate-stop-before-storage-service.patch b/SOURCES/bz1902208-LVM-activate-stop-before-storage-service.patch
new file mode 100644
index 0000000..1486b29
--- /dev/null
+++ b/SOURCES/bz1902208-LVM-activate-stop-before-storage-service.patch
@@ -0,0 +1,60 @@
+From 79fb4b2d3d862f4e83b1df72107b6322b420ea34 Mon Sep 17 00:00:00 2001
+From: Reid Wahl <nrwahl@protonmail.com>
+Date: Sat, 28 Nov 2020 18:10:03 -0800
+Subject: [PATCH] LVM-activate: Stop before blk-availability.service
+
+If storage services (e.g., iscsi-shutdown.service) stop before an
+LVM-activate resource stops, the managed VG may become unavailable. Then
+the LVM-activate resource may fail to deactivate the volume group and
+thus fail its stop operation.
+
+This commit adds a systemd drop-in "After=blk-availability.service"
+directive for resource-agents-deps.target during the LVM-activate start
+op. blk-availability includes "After=" directives for other storage
+services and thus serves as a convenient wrapper.
+
+blk-availability is not enabled by default, and a "Wants=" drop-in
+that's created after Pacemaker starts would not be able to start
+blk-availability automatically. So here we also start blk-availability
+during LVM_start().
+
+Resolves RHBZ#1902208
+
+Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
+---
+ heartbeat/LVM-activate | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/heartbeat/LVM-activate b/heartbeat/LVM-activate
+index 94f9e5813..b8abd7579 100755
+--- a/heartbeat/LVM-activate
++++ b/heartbeat/LVM-activate
+@@ -830,6 +830,28 @@ lvm_start() {
+ 	local rc
+ 	local vol
+ 
++        if systemd_is_running ; then
++        	# Create drop-in to deactivate VG before stopping
++		# storage services during shutdown/reboot.
++		after=$(systemctl show resource-agents-deps.target.d \
++			--property=After | cut -d'=' -f2)
++
++		case "$after" in
++			*" blk-availability.service "*)
++				;;
++			*)
++				systemd_drop_in "99-LVM-activate" "After" \
++					"blk-availability.service"
++				;;
++		esac
++
++		# If blk-availability isn't started, the "After="
++		# directive has no effect.
++		if ! systemctl is-active blk-availability.service ; then
++			systemctl start blk-availability.service
++		fi
++        fi
++
+ 	if lvm_status ; then
+ 		ocf_log info "${vol}: is already active."
+ 		return $OCF_SUCCESS
diff --git a/SOURCES/bz1903677-ocf-shellfuncs-fix-traceback-redirection-bash5.patch b/SOURCES/bz1903677-ocf-shellfuncs-fix-traceback-redirection-bash5.patch
new file mode 100644
index 0000000..8472065
--- /dev/null
+++ b/SOURCES/bz1903677-ocf-shellfuncs-fix-traceback-redirection-bash5.patch
@@ -0,0 +1,45 @@
+From 908431d416076e3ceb70cc95871957d15265a949 Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Wed, 2 Dec 2020 16:48:32 +0100
+Subject: [PATCH] ocf-shellfuncs: make ocf_is_bash4() detect Bash v4 or greater
+ (which it was supposed to according to the comments)
+
+---
+ heartbeat/ocf-shellfuncs.in | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/heartbeat/ocf-shellfuncs.in b/heartbeat/ocf-shellfuncs.in
+index b8d47e3d5..ac75dfc87 100644
+--- a/heartbeat/ocf-shellfuncs.in
++++ b/heartbeat/ocf-shellfuncs.in
+@@ -907,13 +907,18 @@ ocf_unique_rundir()
+ # NB: FD 9 may be used for tracing with bash >= v4 in case
+ # OCF_TRACE_FILE is set to a path.
+ #
+-ocf_is_bash4() {
++ocf_bash_has_xtracefd() {
+ 	echo "$SHELL" | grep bash > /dev/null &&
+-			[ ${BASH_VERSINFO[0]} = "4" ]
++			[ ${BASH_VERSINFO[0]} -ge 4 ]
++}
++# for backwards compatibility
++ocf_is_bash4() {
++	ocf_bash_has_xtracefd
++	return $?
+ }
+ ocf_trace_redirect_to_file() {
+ 	local dest=$1
+-	if ocf_is_bash4; then
++	if ocf_bash_has_xtracefd; then
+ 		exec 9>$dest
+ 		BASH_XTRACEFD=9
+ 	else
+@@ -922,7 +927,7 @@ ocf_trace_redirect_to_file() {
+ }
+ ocf_trace_redirect_to_fd() {
+ 	local fd=$1
+-	if ocf_is_bash4; then
++	if ocf_bash_has_xtracefd; then
+ 		BASH_XTRACEFD=$fd
+ 	else
+ 		exec 2>&$fd
diff --git a/SOURCES/bz1913932-1-gcp-vpc-move-add-project-parameter.patch b/SOURCES/bz1913932-1-gcp-vpc-move-add-project-parameter.patch
new file mode 100644
index 0000000..16cfb10
--- /dev/null
+++ b/SOURCES/bz1913932-1-gcp-vpc-move-add-project-parameter.patch
@@ -0,0 +1,86 @@
+From 560683500b3f9d5d8e183a569daea27422ae5268 Mon Sep 17 00:00:00 2001
+From: Reid Wahl <nrwahl@protonmail.com>
+Date: Thu, 7 Jan 2021 12:25:04 -0800
+Subject: [PATCH] gcp-vpc-move-route, gcp-vpc-move-vip: Parameterize project ID
+
+Resolves: RHBZ#1913932
+Resolves: RHBZ#1913936
+
+Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
+---
+ heartbeat/gcp-vpc-move-route.in | 13 ++++++++++++-
+ heartbeat/gcp-vpc-move-vip.in   | 16 ++++++++++++++--
+ 2 files changed, 26 insertions(+), 3 deletions(-)
+
+diff --git a/heartbeat/gcp-vpc-move-route.in b/heartbeat/gcp-vpc-move-route.in
+index d8e8ea8dd..179eba15a 100644
+--- a/heartbeat/gcp-vpc-move-route.in
++++ b/heartbeat/gcp-vpc-move-route.in
+@@ -106,6 +106,16 @@ Name of the VPC network
+ <content type="string" default="default" />
+ </parameter>
+ 
++<parameter name="project">
++<longdesc lang="en">
++Project ID of the instance. It can be useful to set this attribute if
++the instance is in a shared service project. Otherwise, the agent should
++be able to determine the project ID automatically.
++</longdesc>
++<shortdesc lang="en">Project ID</shortdesc>
++<content type="string" default="default" />
++</parameter>
++
+ <parameter name="interface">
+ <longdesc lang="en">
+ Name of the network interface
+@@ -215,7 +225,8 @@ def validate(ctx):
+   try:
+     ctx.instance = get_metadata('instance/name')
+     ctx.zone = get_metadata('instance/zone').split('/')[-1]
+-    ctx.project = get_metadata('project/project-id')
++    ctx.project = os.environ.get(
++        'OCF_RESKEY_project', get_metadata('project/project-id'))
+   except Exception as e:
+     logger.error(
+         'Instance information not found. Is this a GCE instance ?: %s', str(e))
+diff --git a/heartbeat/gcp-vpc-move-vip.in b/heartbeat/gcp-vpc-move-vip.in
+index 01d91a59d..e792f71d5 100755
+--- a/heartbeat/gcp-vpc-move-vip.in
++++ b/heartbeat/gcp-vpc-move-vip.in
+@@ -75,6 +75,16 @@ METADATA = \
+       <shortdesc lang="en">Host list</shortdesc>
+       <content type="string" default="" />
+     </parameter>
++    <parameter name="project" unique="0" required="0">
++      <longdesc lang="en">
++        Project ID of the instance. It can be useful to set this
++        attribute if the instance is in a shared service project.
++        Otherwise, the agent should be able to determine the project ID
++        automatically.
++      </longdesc>
++      <shortdesc lang="en">Project ID</shortdesc>
++      <content type="string" default="default" />
++    </parameter>
+     <parameter name="stackdriver_logging" unique="0" required="0">
+       <longdesc lang="en">If enabled (set to true), IP failover logs will be posted to stackdriver logging</longdesc>
+       <shortdesc lang="en">Stackdriver-logging support</shortdesc>
+@@ -267,7 +277,8 @@ def get_instances_list(project, exclude):
+ def gcp_alias_start(alias):
+   my_aliases = get_localhost_aliases()
+   my_zone = get_metadata('instance/zone').split('/')[-1]
+-  project = get_metadata('project/project-id')
++  project = os.environ.get(
++        'OCF_RESKEY_project', get_metadata('project/project-id'))
+ 
+   if alias in my_aliases:
+     # TODO: Do we need to check alias_range_name?
+@@ -315,7 +326,8 @@ def gcp_alias_start(alias):
+ def gcp_alias_stop(alias):
+   my_aliases = get_localhost_aliases()
+   my_zone = get_metadata('instance/zone').split('/')[-1]
+-  project = get_metadata('project/project-id')
++  project = os.environ.get(
++        'OCF_RESKEY_project', get_metadata('project/project-id'))
+ 
+   if alias in my_aliases:
+     logger.info('Removing %s from %s' % (alias, THIS_VM))
diff --git a/SOURCES/bz1913932-2-gcp-vpc-move-route-fixes.patch b/SOURCES/bz1913932-2-gcp-vpc-move-route-fixes.patch
new file mode 100644
index 0000000..a94f0ee
--- /dev/null
+++ b/SOURCES/bz1913932-2-gcp-vpc-move-route-fixes.patch
@@ -0,0 +1,106 @@
+From 523c4cee64b3b8ee9f603a940d83a6628531078d Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Tue, 19 Jan 2021 10:56:47 +0100
+Subject: [PATCH 1/2] gcp-vpc-move-route: fix stop-action when route stopped,
+ and fix check_conflicting_routes()
+
+---
+ heartbeat/gcp-vpc-move-route.in | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/heartbeat/gcp-vpc-move-route.in b/heartbeat/gcp-vpc-move-route.in
+index 179eba15a..9fe985832 100644
+--- a/heartbeat/gcp-vpc-move-route.in
++++ b/heartbeat/gcp-vpc-move-route.in
+@@ -252,8 +252,19 @@ def validate(ctx):
+ def check_conflicting_routes(ctx):
+   fl = '(destRange = "%s*") AND (network = "%s") AND (name != "%s")' % (
+       ctx.ip, ctx.vpc_network_url, ctx.route_name)
+-  request = ctx.conn.routes().list(project=ctx.project, filter=fl)
+-  response = request.execute()
++  try:
++    request = ctx.conn.routes().list(project=ctx.project, filter=fl)
++    response = request.execute()
++  except googleapiclient.errors.HttpError as e:
++    if e.resp.status == 404:
++      logger.error('VPC network not found')
++      if 'stop' in sys.argv[1]:
++        sys.exit(OCF_SUCCESS)
++      else:
++        sys.exit(OCF_ERR_CONFIGURED)
++    else:
++      raise
++
+   route_list = response.get('items', None)
+   if route_list:
+     logger.error(
+@@ -353,16 +364,16 @@ def route_monitor(ctx):
+   logger.info('GCP route monitor: checking route table')
+ 
+   # Ensure that there is no route that we are not aware of that is also handling our IP
+-  check_conflicting_routes
++  check_conflicting_routes(ctx)
+ 
+   try:
+     request = ctx.conn.routes().get(project=ctx.project, route=ctx.route_name)
+     response = request.execute()
+   except googleapiclient.errors.HttpError as e:
+-    if 'Insufficient Permission' in e.content:
+-      return OCF_ERR_PERM
+-    elif e.resp.status == 404:
++    if e.resp.status == 404:
+       return OCF_NOT_RUNNING
++    elif 'Insufficient Permission' in e.content:
++      return OCF_ERR_PERM
+     else:
+       raise
+ 
+
+From 50dbfc3230e87b8d29163c235e6866d15fd6fc1b Mon Sep 17 00:00:00 2001
+From: Oyvind Albrigtsen <oalbrigt@redhat.com>
+Date: Tue, 19 Jan 2021 11:50:22 +0100
+Subject: [PATCH 2/2] gcp-vpc-move-vip: correctly return error when no
+ instances are returned
+
+---
+ heartbeat/gcp-vpc-move-vip.in | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/heartbeat/gcp-vpc-move-vip.in b/heartbeat/gcp-vpc-move-vip.in
+index e792f71d5..bbbd87b7a 100755
+--- a/heartbeat/gcp-vpc-move-vip.in
++++ b/heartbeat/gcp-vpc-move-vip.in
+@@ -263,8 +263,14 @@ def get_instances_list(project, exclude):
+   hostlist = []
+   request = CONN.instances().aggregatedList(project=project)
+   while request is not None:
+-    response = request.execute()
+-    zones = response.get('items', {})
++    try:
++      response = request.execute()
++      zones = response.get('items', {})
++    except googleapiclient.errors.HttpError as e:
++      if e.resp.status == 404:
++        logger.debug('get_instances_list(): no instances found')
++        return ''
++
+     for zone in zones.values():
+       for inst in zone.get('instances', []):
+         if inst['name'] != exclude:
+@@ -303,9 +309,13 @@ def gcp_alias_start(alias):
+       break
+ 
+   # Add alias IP range to localhost
+-  add_alias(
+-      project, my_zone, THIS_VM, alias,
+-      os.environ.get('OCF_RESKEY_alias_range_name'))
++  try:
++    add_alias(
++        project, my_zone, THIS_VM, alias,
++        os.environ.get('OCF_RESKEY_alias_range_name'))
++  except googleapiclient.errors.HttpError as e:
++    if e.resp.status == 404:
++      sys.exit(OCF_ERR_CONFIGURED)
+ 
+   # Verify that the IP range has been added
+   my_aliases = get_localhost_aliases()
diff --git a/SPECS/resource-agents.spec b/SPECS/resource-agents.spec
index 8738405..089ec99 100644
--- a/SPECS/resource-agents.spec
+++ b/SPECS/resource-agents.spec
@@ -70,7 +70,7 @@
 Name:		resource-agents
 Summary:	Open Source HA Reusable Cluster Resource Scripts
 Version:	4.1.1
-Release:	60%{?rcver:%{rcver}}%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist}
+Release:	86%{?rcver:%{rcver}}%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist}
 License:	GPLv2+ and LGPLv2+
 URL:		https://github.com/ClusterLabs/resource-agents
 %if 0%{?fedora} || 0%{?centos_version} || 0%{?rhel}
@@ -215,7 +215,7 @@ Patch123:	bz1744190-pgsql-1-set-primary-standby-initial-score.patch
 Patch124:	bz1744190-pgsql-2-improve-start-checks.patch
 Patch125:	bz1820523-exportfs-1-add-symlink-support.patch
 Patch126:	bz1832321-rabbitmq-cluster-increase-wait-timeout.patch
-Patch127:	bz1818997-nfsserver-fix-nfsv4-only-support.patch
+Patch127:	bz1818997-nfsserver-1-fix-nfsv4-only-support.patch
 Patch128:	bz1830716-NovaEvacuate-suppress-expected-error.patch
 Patch129:	bz1836945-db2-hadr-promote-standby-node.patch
 Patch130:	bz1633251-gcp-pd-move-4-fixes-and-improvements.patch
@@ -223,12 +223,47 @@ Patch131:	bz1633251-gcp-pd-move-5-bundle.patch
 Patch132:	bz1839721-podman-force-rm-container-if-rm-fails.patch
 Patch133:	bz1820523-exportfs-2-fix-monitor-action.patch
 Patch134:	bz1843999-aliyun-vpc-move-ip-log-output-when-failing.patch
-Patch135:	bz1845574-azure-events-handle-exceptions-in-urlopen.patch
+Patch135:	bz1845574-azure-events-1-handle-exceptions-in-urlopen.patch
 Patch136:	bz1845581-nfsserver-dont-log-error-message-file-doesnt-exist.patch
 Patch137:	bz1845583-exportfs-1-describe-clientspec-format-in-metadata.patch
 Patch138:	bz1845583-exportfs-2-fix-typo.patch
 Patch139:	bz1814896-Filesystem-fast_stop-default-to-no-for-GFS2.patch
 Patch140:	bz1836186-pgsql-support-Pacemaker-v2.03-output.patch
+Patch141:	bz1819965-3-azure-events-decode-when-type-not-str.patch
+Patch142:	bz1818997-nfsserver-2-stop-nfsdcld-if-present.patch
+Patch143:	bz1818997-3-nfsserver-nfsnotify-fix-selinux-label-issue.patch
+Patch144:	bz1845574-azure-events-2-import-urlerror-encode-postdata.patch
+Patch145:	bz1846733-gcp-vpc-move-vip-1-support-multiple-alias-ips.patch
+Patch146:	bz1846733-gcp-vpc-move-vip-2-fix-list-sort.patch
+Patch147:	bz1850778-azure-lb-fix-redirect-issue.patch
+Patch148:	bz1640587-pgsql-ignore-masters-re-promote.patch
+Patch149:	bz1795535-pgsql-1-add-postgresql-12-support.patch
+Patch150:	bz1795535-pgsql-2-fix-uppercase-hostname-support.patch
+Patch151:	bz1858752-Filesystem-support-whitespace-device-dir.patch
+Patch152:	bz1872999-aws-vpc-move-ip-add-region-parameter.patch
+Patch153:	bz1881114-galera-recover-joining-non-existing-cluster.patch
+Patch154:	bz1815013-redis-parse-password-correctly-based-on-version.patch
+Patch155:	bz1763249-manpages-fix-pcs-syntax.patch
+Patch156:	bz1890068-gcp-pd-move-fix-partially-matched-disk_name.patch
+Patch157:	bz1848025-sybaseASE-run-verify-for-start-action-only.patch
+Patch158:	bz1861001-sybaseASE-add-logfile-parameter.patch
+Patch159:	bz1891835-galera-set-bootstrap-attribute-before-promote.patch
+Patch160:	bz1891855-galera-recover-2-node-cluster.patch
+Patch161:	bz1471182-crypt-1-new-ra.patch
+Patch162:	bz1471182-crypt-2-fix-bashism.patch
+Patch163:	bz1471182-crypt-3-fix-missing-and.patch
+Patch164:	bz1895811-aws-vpc-move-ip-dont-warn-for-expected-scenarios.patch
+Patch165:	bz1897570-aws-add-imdsv2-support.patch
+Patch166:	bz1886262-podman-recover-from-killed-conmon.patch
+Patch167:	bz1900015-podman-recover-from-storage-out-of-sync.patch
+Patch168:	bz1898690-crypt-make-key_file-crypt_type_not-unique.patch
+Patch169:	bz1899551-NovaEvacuate-fix-delay_evacuate-unset.patch
+Patch170:	bz1901357-crypt-1-support-symlink-devices.patch
+Patch171:	bz1902208-LVM-activate-stop-before-storage-service.patch
+Patch172:	bz1901357-crypt-2-dont-sanity-check-during-probe.patch
+Patch173:	bz1903677-ocf-shellfuncs-fix-traceback-redirection-bash5.patch
+Patch174:	bz1913932-1-gcp-vpc-move-add-project-parameter.patch
+Patch175:	bz1913932-2-gcp-vpc-move-route-fixes.patch
 
 # bundle patches
 Patch1000:	7-gcp-bundled.patch
@@ -268,7 +303,14 @@ Requires: /usr/sbin/fuser /bin/mount
 Requires: /sbin/fsck
 Requires: /usr/sbin/fsck.ext2 /usr/sbin/fsck.ext3 /usr/sbin/fsck.ext4
 Requires: /usr/sbin/fsck.xfs
-Requires: /sbin/mount.nfs /sbin/mount.nfs4 /usr/sbin/mount.cifs
+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%{?rhel} && 0%{?rhel} < 8) || (0%{?centos} && 0%{?centos} < 8)
+Requires: /usr/sbin/mount.cifs
+%else
+Recommends: /usr/sbin/mount.cifs
+%endif
+%endif
 
 # IPaddr2
 Requires: /sbin/ip
@@ -518,6 +560,41 @@ exit 1
 %patch138 -p1
 %patch139 -p1
 %patch140 -p1
+%patch141 -p1
+%patch142 -p1
+%patch143 -p1
+%patch144 -p1
+%patch145 -p1
+%patch146 -p1
+%patch147 -p1
+%patch148 -p1
+%patch149 -p1
+%patch150 -p1
+%patch151 -p1 -F1
+%patch152 -p1
+%patch153 -p1
+%patch154 -p1 -F1
+%patch155 -p1
+%patch156 -p1
+%patch157 -p1
+%patch158 -p1
+%patch159 -p1
+%patch160 -p1
+%patch161 -p1
+%patch162 -p1
+%patch163 -p1
+%patch164 -p1
+%patch165 -p1
+%patch166 -p1
+%patch167 -p1
+%patch168 -p1
+%patch169 -p1 -F2
+%patch170 -p1
+%patch171 -p1
+%patch172 -p1
+%patch173 -p1
+%patch174 -p1
+%patch175 -p1
 
 chmod 755 heartbeat/nova-compute-wait
 chmod 755 heartbeat/NovaEvacuate
@@ -1081,6 +1158,116 @@ ccs_update_schema > /dev/null 2>&1 ||:
 %endif
 
 %changelog
+* Tue Jan 19 2021 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-86
+- gcp-vpc-move-route, gcp-vpc-move-vip: add project parameter
+
+  Resolves: rhbz#1913932
+
+* Thu Dec  3 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-81
+- ocf-shellfuncs: fix traceback redirection for Bash 5+
+
+  Resolves: rhbz#1903677
+
+* Tue Dec  1 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-80
+- crypt: support symlink devices, and dont run sanity checks for probes
+
+  Resolves: rhbz#1901357
+
+* Mon Nov 30 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-79
+- LVM-activate: add drop-in during start-action to avoid getting
+  fenced during reboot
+
+  Resolves: rhbz#1902208
+
+* Wed Nov 25 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-77
+- NovaEvacuate: set delay_evacuate to 0 when it's not set
+
+  Resolves: rhbz#1899551
+
+* Tue Nov 24 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-76
+- podman: recover from killed conmon process
+- podman: recover from podman's storage being out of sync
+- crypt: make key_file and crypt_type parameters not unique
+
+  Resolves: rhbz#1886262
+  Resolves: rhbz#1900015
+  Resolves: rhbz#1898690
+
+* Fri Nov 13 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-75
+- AWS agents: add support for IMDSv2
+
+  Resolves: rhbz#1897570
+
+* Wed Nov 11 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-74
+- aws-vpc-move-ip: don't warn for expected scenarios
+
+  Resolves: rhbz#1895811
+
+* Mon Nov  2 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-73
+- crypt: new resource agent
+
+  Resolves: rhbz#1471182
+
+* Wed Oct 28 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-72
+- sybaseASE: Run verify_all() for start operation only
+- sybaseASE: add logfile parameter
+- galera: set bootstrap attribute before promote
+- galera: recover after network split in a 2-node cluster
+
+  Resolves: rhbz#1848025
+  Resolves: rhbz#1861001
+  Resolves: rhbz#1891835
+  Resolves: rhbz#1891855
+
+* Tue Oct 27 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-71
+- redis: parse password correctly based on version
+- all agents: fix pcs syntax in manpage for pcs 0.10+
+- gcp-pd-move: dont stop partially matched "disk_name"
+
+  Resolves: rhbz#1815013
+  Resolves: rhbz#1763249
+  Resolves: rhbz#1890068
+
+* Wed Oct  7 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-70
+- galera: recover from joining a non existing cluster
+
+  Resolves: rhbz#1881114
+
+* Wed Sep 23 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-69
+- pgsql: ignore masters re-promote
+- pgsql: add PostgreSQL 12 support
+- Make Samba/CIFS dependency weak
+- Filesystem: Support whitespace in device or directory name
+- aws-vpc-move-ip: add region parameter
+
+  Resolves: rhbz#1640587
+  Resolves: rhbz#1795535
+  Resolves: rhbz#1828600
+  Resolves: rhbz#1858752
+  Resolves: rhbz#1872999
+
+* Thu Aug 20 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-68
+- azure-lb: fix redirect issue
+
+  Resolves: rhbz#1850778
+
+* Wed Aug 19 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-67
+- gcp-vpc-move-vip: add support for multiple alias IPs
+
+  Resolves: rhbz#1846733
+
+* Thu Jul 30 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-65
+- azure-events: handle exceptions in urlopen
+
+  Resolves: rhbz#1845574
+
+* Mon Jul 27 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-64
+- nfsserver: fix NFSv4-only support
+- azure-events: new resource agent for Azure
+
+  Resolves: rhbz#1818997
+  Resolves: rhbz#1819965
+
 * Thu Jun 25 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-60
 - Upgrade bundled python-httplib2 to fix CVE-2020-11078
 
@@ -1097,11 +1284,9 @@ ccs_update_schema > /dev/null 2>&1 ||:
   Resolves: rhbz#1814896
 
 * Wed Jun 10 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-55
-- azure-events: handle exceptions in urlopen
 - nfsserver: dont log error message when /etc/sysconfig/nfs does not exist
 - exportfs: describe clientspec format in metadata
 
-  Resolves: rhbz#1845574
   Resolves: rhbz#1845581
   Resolves: rhbz#1845583
 
@@ -1123,11 +1308,9 @@ ccs_update_schema > /dev/null 2>&1 ||:
   Resolves: rhbz#1633251
 
 * Wed May 27 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-51
-- nfsserver: fix NFSv4-only support
 - NovaEvacuate: suppress expected initial error message
 - db2 (HADR): promote standby node when master node disappears
 
-  Resolves: rhbz#1818997
   Resolves: rhbz#1830716
   Resolves: rhbz#1836945
 
@@ -1144,12 +1327,6 @@ ccs_update_schema > /dev/null 2>&1 ||:
   Resolves: rhbz#1759115
   Resolves: rhbz#1744190
 
-* Thu Apr 16 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-48
-- azure-events: new resource agent for Azure
-
-  Resolves: rhbz#1633251
-  Resolves: rhbz#1819965
-
 * Mon Apr  6 2020 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.1.1-47
 - aws-vpc-move-ip: delete remaining route entries