Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package sapstartsrv-resource-agents for 
openSUSE:Factory checked in at 2022-09-21 14:43:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sapstartsrv-resource-agents (Old)
 and      /work/SRC/openSUSE:Factory/.sapstartsrv-resource-agents.new.2083 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "sapstartsrv-resource-agents"

Wed Sep 21 14:43:21 2022 rev:5 rq:1005157 version:0.9.1+git.1663751963.e0ef8a2

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/sapstartsrv-resource-agents/sapstartsrv-resource-agents.changes
  2021-04-29 22:53:02.669989564 +0200
+++ 
/work/SRC/openSUSE:Factory/.sapstartsrv-resource-agents.new.2083/sapstartsrv-resource-agents.changes
        2022-09-21 14:44:21.566063443 +0200
@@ -1,0 +2,21 @@
+Wed Sep 14 09:37:25 UTC 2022 - abr...@suse.com
+
+- Version bump to 0.9.1
+- man page updates based on customer feedback on conferences
+- remove 'BuildRequire python3-mock' as this is no longer needed
+  for the tests
+
+-------------------------------------------------------------------
+Fri Feb 25 11:18:02 UTC 2022 - abr...@suse.com
+
+- Add systemd support for the resource agent to interact with the
+  new SAP unit files for sapstartsrv.
+  As the new version of the SAP Startup Framework will use systemd
+  unit files to control the sapstartsrv process instead of the
+  previous used SysV init script, we need to adapt the handling of
+  sapstartsrv inside the resource agents to support both ways.
+  (bsc#1189529)
+- prevent false posivite with pgrep in function '_get_status' 
+ (bsc#1193568)
+
+-------------------------------------------------------------------

Old:
----
  sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04.tar.gz

New:
----
  sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ sapstartsrv-resource-agents.spec ++++++
--- /var/tmp/diff_new_pack.JyhFY1/_old  2022-09-21 14:44:22.010064603 +0200
+++ /var/tmp/diff_new_pack.JyhFY1/_new  2022-09-21 14:44:22.018064624 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package sapstartsrv-resource-agents
 #
-# Copyright (c) 2020-2021 SUSE LLC.
+# Copyright (c) 2020-2022 SUSE LLC.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
 License:        GPL-2.0
 Group:          Productivity/Clustering/HA
 Summary:        Resource agent for SAP instance specific sapstartsrv service
-Version:        0.9.0+git.1619681975.ad20a04
+Version:        0.9.1+git.1663751963.e0ef8a2
 Release:        0
 URL:            https://github.com/SUSE/SAPStartSrv-resourceAgent
 Source0:        %{name}-%{version}.tar.gz
@@ -34,7 +34,6 @@
 Requires:       pacemaker > 1.1.1
 Requires:       python3
 %if %{with test}
-BuildRequires:  python3-mock
 BuildRequires:  python3-pytest
 %endif
 

++++++ _service ++++++
--- /var/tmp/diff_new_pack.JyhFY1/_old  2022-09-21 14:44:22.054064718 +0200
+++ /var/tmp/diff_new_pack.JyhFY1/_new  2022-09-21 14:44:22.058064728 +0200
@@ -4,8 +4,8 @@
     <param name="scm">git</param>
     <param name="exclude">.git</param>
     <param name="filename">sapstartsrv-resource-agents</param>
-    <param name="versionformat">0.9.0+git.%ct.%h</param>
-    <param name="revision">ad20a04897921e678909b6da9d87ffdae9b32293</param>
+    <param name="versionformat">0.9.1+git.%ct.%h</param>
+    <param name="revision">e0ef8a2c4cf21d373f0085e4cd11fecb76ed87aa</param>
   </service>
 
   <service name="recompress" mode="disabled">

++++++ sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04.tar.gz -> 
sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/_service 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/_service
--- old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/_service       
2021-04-29 09:39:35.000000000 +0200
+++ new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/_service       
2022-09-21 11:19:23.000000000 +0200
@@ -4,7 +4,7 @@
     <param name="scm">git</param>
     <param name="exclude">.git</param>
     <param name="filename">sapstartsrv-resource-agents</param>
-    <param name="versionformat">0.9.0+git.%ct.%h</param>
+    <param name="versionformat">0.9.1+git.%ct.%h</param>
     <param name="revision">%%VERSION%%</param>
   </service>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/SAPStartSrv_basic_cluster.7
 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/SAPStartSrv_basic_cluster.7
--- 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/SAPStartSrv_basic_cluster.7
        2021-04-29 09:39:35.000000000 +0200
+++ 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/SAPStartSrv_basic_cluster.7
        2022-09-21 11:19:23.000000000 +0200
@@ -1,6 +1,6 @@
-.\" Version: 0.1.0
+.\" Version: 0.9.1
 .\"
-.TH SAPStartSrv_basic_cluster 7 "05 Jan 2021" "" "SAPStartSrv"
+.TH SAPStartSrv_basic_cluster 7 "02 Feb 2022" "" "SAPStartSrv"
 .\"
 .SH NAME
 SAPStartSrv_basic_cluster \- basic settings to make SAPStartSrv work
@@ -18,6 +18,12 @@
 \fBsystemd services\fR
 
 The services sapinit, sapping and sappong are needed for this cluster.
+
+For SystemV style saphostagent and sapstartsrv, the sapinit script needs to be
+enabled.
+For systemd style saphostagent and sapstartsrv, the service saphostagent needs
+to be enabled and running, instance services SAP${SID}_${INO} need to be 
disabled.
+See also REQUIREMENTS in man page ocf_suse_SAPStartSrv(7).
 .PP
 \fBtcp_retries2 = 9\fR
 
@@ -33,6 +39,27 @@
 for default SAP application server and central services configuration.
 .\" TODO NFS mount options for smooth takeover of sap instances, e.g. soft?
 .PP
+\fBUsers and groups\fR
+
+Technical users and groups, such as <sid>adm are defined locally in the Linux
+system. Further user <sid>adm needs to be in  group haclient.
+See man page passwd(5) and usermod(8.
+
+\fBHostnames\fR
+
+Name resolution of the cluster nodes and the virtual IP address must be done
+locally on all cluster nodes. See man page hosts(5).
+
+\fBTime synchronization\fR
+
+Strict time synchronization between the cluster nodes is mandatory, e.g. per 
NTP.
+See man page chrony.conf(5).
+
+\fBNFS mounted filesystems\fR
+
+The shared filesystems /sapmnt/$SID/ and /usr/sap/$SID/ can be statically 
mounted
+on all cluster nodes. See man page fstab(5) and example below.
+.PP
 \fB* CRM Basics\fR
 
 \fBstonith-enabled = true\fR
@@ -57,14 +84,14 @@
 .br
 .\" TODO A value of '1' ...
 
-\fBmigration-threshold = 3\fR
+\fBmigration-threshold = 1\fR
 
 The crm rsc_default parameter migration-threshold defines how many errors on a
 resource can be detected before this resource will be moved to another node.
-See also \fBfailure-timeout\fR .
+For ENSA1 the migration-threshold needs to be 1 always. For ENSA2 the value 
could
+be higher. See also \fBfailure-timeout\fR .
 .\" TODO needed for resource monitor option on-fail=restart
 .br
-.\" TODO A value of '3' ... ENSA2
 
 \fBrecord-pending = true\fR
 
@@ -74,7 +101,6 @@
 \'starting\' and \'stopping\' in crm_mon. Also the sap_suse_cluster_connector
 interface uses this information.
 .br
-.\" TODO The value 'true' is needed for the sap_suse_cluster_connector 
interface.
 
 \fBfailure-timeout = 86400\fR
 
@@ -114,8 +140,8 @@
 Shown are specific parameters which are needed. Some general parameters are
 left out.
 .br
-This example has been taken from a three-node cluster SLE-HA 15 GA with
-diskless SBD:
+This example has been taken from an ENSA2 three-node cluster SLE-HA 15 GA
+with diskless SBD:
 .PP
 .RS 4
 property cib-bootstrap-options: \\
@@ -153,8 +179,8 @@
  record-pending=true 
 .RE
 
-This example has been taken from a two-node cluster SLE-HA 15 GA with
-disk-based SBD. An optional priority fecing is configured and the SBD
+This example has been taken from an ENSA2 two-node cluster SLE-HA 15 GA
+with disk-based SBD. An optional priority fecing is configured and the SBD
 pcmk_delay_max has been reduced:
 .PP
 .RS 4
@@ -242,12 +268,61 @@
 .RE
 .br
 .PP
+\fB* systemd services for the SAP instance\fR
+.PP
+In case systemd style init is used for the SAP instance:
+saphostagent needs to be enabled and running, instance services need
+to be disabled. Example SID is HA1, instance number is 10.
+.PP
+.RS 4
+.br
+# systemctl list-unit-files | grep -i sap
+.br
+# systemctl status SAPHA1_10.service
+.br
+# systemd-cgls -u SAP.slice
+.br
+# systemd-cgls -u SAPHA1_10.service
+.RE
+.br
+.PP
+\fB* SAP instance profile\fR
+.PP
+Check the instance profile for HA specific settings.
+Example SID is EN2, instance number is 10.
+.PP
+.RS 4
+.br
+# su - en2adm
+.br
+~> sapcontrol -nr 10 -function GetStartProfile |\\
+.br
+grep -e art_Program_ -e Autostart -e halib
+.br
+~> exit
+.RE
+.br
+.PP
+\fB* sidadm group membership\fR
+.PP
+Check if the sidadm user is member of the HA specific haclient group.
+Example SID is EN2.
+.PP
+.RS 4
+.br
+# groups en2adm
+.RE
+.br
+.PP
 .\"
 .SH FILES
 .TP
 /etc/passwd
 the local user database
 .TP
+/etc/groups
+the local group database
+.TP
 /etc/hosts
 the local hostname resolution database
 .TP
@@ -270,7 +345,8 @@
 \fBocf_suse_SAPStartSrv\fP(7) , \fBsap_suse_cluster_connector\fP(8) ,
 \fBocf_pacemaker_ping\fP(7) , \fBocf_heartbeat_ethmonitor\fP(7) ,
 \fBattrd_updater\fP(8) , \fBsbd\fP(8) , \fBstonith_sbd\fP(8) , \fBcrm\fP(8) ,
-\fBcorosync.conf\fP(5) , \fBvotequorum\fP(5) ,
+\fBcorosync.conf\fP(5) , \fBvotequorum\fP(5) , \fBhosts\fP(5) , \fBfstab\fP(5) 
,
+\fBpasswd\fP(5) , \fBgroups\fP(8) , \fBusermod\fP(8) , \fBchrony.conf\fP(5) ,
 .br
 https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
 .\" TODO https://pracucci.com/linux-tcp-rto-min-max-and-tcp-retries2.html
@@ -283,7 +359,7 @@
 .\"
 .SH COPYRIGHT
 .br
-(c) 2020-2021 SUSE LLC
+(c) 2020-2022 SUSE LLC
 .br
 SAPStartSrv comes with ABSOLUTELY NO WARRANTY.
 .br
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/SAPStartSrv_maintenance_procedures.7
 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/SAPStartSrv_maintenance_procedures.7
--- 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/SAPStartSrv_maintenance_procedures.7
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/SAPStartSrv_maintenance_procedures.7
       2022-09-21 11:19:23.000000000 +0200
@@ -0,0 +1,232 @@
+.\ Version: 0.9.1
+.\"
+.TH SAPStartSrv_maintenance_examples 7 "23 Jun 2022" "" "SAPStartSrv"
+.\"
+.SH NAME
+SAPStartSrv_maintenance_examples \- maintenance examples for SAPStartSrv
+.PP
+.\"
+.SH DESCRIPTION
+.\"
+Maintenance examples for SAPStartSrv and SUSE HA for SAP Enqueue Standalone
+clusters.
+Please see ocf_suse_SAPStartSrv(7), SAPStartSrv_basic_cluster(7) and 
sap_suse_cluster_connector(8) for more examples and read the REQUIREMENTS 
section there.
+.PP
+.\"
+.SH EXAMPLES
+.PP
+\fB*\fR Check status of Linux cluster and ENSA replication pair.
+
+This steps should be performed before doing anything with the cluster, and
+after something has been done.
+.PP
+.RS 2
+# cs_clusterstate -i
+.br
+# crm_mon -1r
+.br
+# crm configure show | grep cli-
+.br
+# su - en1adm -c "sapcontrol -nr 00 -function GetSystemInstanceList"
+.br
+# su - en1adm -c "sapcontrol -nr 00 -function GetProcessList"
+.br
+# su - en1adm -c "sapcontrol -nr 00 -function HACheckMaintenanceMode"
+.br
+# su - en1adm -c "sapcontrol -nr 00 -function HAGetFailoverConfig"
+.br
+# cs_clusterstate -i
+.RE
+.PP
+\fB*\fR Set resource group of ASCS into maintenance.
+
+This is needed to allow manual actions on the ASCS group??s resources.
+In this example, SID is EN1, instance number of ASCS is 00.
+It is neccessary to wait for each step to complete and to check the result.
+See also exmaple below.
+.PP
+.RS 2
+# crm resource maintenance grp_EN1_ASCS00 on
+.br
+# crm configure show grp_EN1_ASCS00
+.RE
+.PP
+\fB*\fR Get resource group of ASCS back from maintenance.
+
+This is needed to put back under cluster control the ASCS group??s resources.
+In this example, SID is EN1, instance number of ASCS is 00.
+It is neccessary to wait for each step to complete and to check the result.
+See also exmaple above.
+.PP
+.RS 2
+# crm resource refresh grp_EN1_ASCS00
+.br
+# crm resource maintenance grp_EN1_ASCS00 off
+.br
+# crm configure show grp_EN1_ASCS00
+.RE
+.PP
+\fB*\fR Set whole Linux cluster into maintenance.
+
+.RS 2
+# crm configure property maintenance-mode=true
+.br
+# crm_attribute --query -t crm_config -n maintenance-mode
+.RE
+.PP
+\fB*\fR Remove left-over maintenance attribute from overall Linux cluster.
+
+This could be done to avoid confusion caused by different maintenance 
procedures.
+See above overview on maintenance procedures whith running Linux cluster.
+Before doing so, check for cluster attribute maintenance-mode="false".
+.PP
+.RS 2
+# crm_attribute --delete -t crm_config -n maintenance-mode
+.br
+# crm_attribute --query -t crm_config -n maintenance-mode
+.RE
+.PP
+\fB*\fR Remove left-over standby attribute from Linux cluster nodes.
+
+This could be done to avoid confusion caused by different maintenance 
procedures.
+See above overview on maintenance procedures whith running Linux cluster.
+Before doing so for all nodes, check for node attribute standby="off" on all 
nodes.
+.PP
+.RS 2
+# crm_attribute --delete -t node -N node1 -n standby
+.br
+# crm_attribute --query -t node -N node1 -n standby
+.RE
+.PP
+\fB*\fR Remove left-over maintenance attribute from resource.
+
+This should usually not be needed.
+See above overview on maintenance procedures whith running Linux cluster.
+.PP
+.RS 2
+# crm_resource --resource grp_EN1_ASCS00 --delete-parameter maintenance --meta
+.\" .br
+.\" # TODO check
+.RE
+.PP
+\fB*\fR Disable Linux cluster on all cluster nodes.
+
+On any cluster node the cluster will not start automatically on boot anymore.
+Nevertheless a currently running cluster will keep running.
+.PP
+.RS 2
+# crm cluster run "crm cluster disable" 
+.br
+# crm cluster run "systemctl status pacemaker" | grep pacemaker.service
+.RE
+.PP
+\fB*\fR Start Linux cluster on all cluster nodes.
+.PP
+.RS 2
+# crm cluster run "crm cluster start"
+.br
+# crm cluster run "systemctl status pacemaker" | grep pacemaker.service
+.RE
+.PP
+\fB*\fR Perform an ASCS takeover by using SAP tools.
+
+In this example, SID is EN1, instance number of ASCS is 00, instance number
+of ERS is 10.
+Only two nodes are in the Linux cluster.
+As consequence of ASCS takeover, the cluster will move the ERS. 
+It is neccessary to wait for each step to complete and to check the result.
+.PP
+.RS 2
+# su - en1adm -c "sapcontrol -nr 00 -function HAFailoverToNode ''"
+.br
+# crm resource clear rsc_sap_EN1_ASCS00
+.br
+# crm resource cleanup rsc_sap_EN1_ERS10
+.RE
+.PP
+.\" \fB*\fR Overview on SAP Rolling Kernel Switch procedure.
+.\" .PP
+.\" TODO SAP notes 2254173, 2077934, 1872602, 953653 
+.\" TODO SUM
+.\" TODO SAP note 2464065
+.\" .RE
+.\" .PP
+\fB*\fR Overview on simple procedure for stopping and temporarily disabling 
the Linux cluster.
+ASCS and ERS instances get fully stopped.
+
+This procedure can be used to update SAP instances, OS or hardware.
+ASCS and ERS roles and resource status remains unchanged.
+It is neccessary to wait for each step to complete and to check the result.
+It also is neccessary to test and document the whole procedure before applying
+in production. The ASCS instance will not be available from step 1.2 to step 
3.3.
+This is not compliant to official SAP upgrade procedures, like Rolling Kernel 
Switch.
+.PP
+.RS 2
+1.1 stopping ERS instance
+.br
+1.2 stopping ASCS instance
+.br
+1.3 disabling pacemaker on all cluster node
+.br
+1.4 stopping cluster on all cluster node
+.PP
+2. doing the maintenance activity
+.PP
+3.1 enabling pacemaker on all cluster nodes
+.br
+3.2 starting cluster on all cluster nodes
+.br
+3.3 starting ASCS instance
+.br
+3.4 starting ERS instance
+.RE
+.PP
+\fB*\fR Overview on maintenance procedure for Linux cluster or OS. ASCS and 
ERS instances
+remain running.
+
+.RS 2
+1. Check status of Linux cluster and ASCS/ERS, see above.
+.br
+2. Set the Linux cluster into maintenance mode.
+.br
+3. Stop Linux Cluster on all nodes.
+.br
+4. Perform maintenance on Linux cluster or OS.
+.br
+5. Start Linux cluster on all nodes.
+.br
+6. Let Linux cluster detect status of ASCS/ERS resources.
+.br
+7. Set cluster ready for operations.
+.br
+8. Check status of Linux cluster and ASCS/ERS, see above.
+.RE
+.PP
+.\"
+.SH BUGS
+Please report feedback and suggestions to feedb...@suse.com.
+.PP
+.\"
+.SH SEE ALSO
+\fBocf_suse_SAPStartSrv\fP(7) ,  \fBSAPStartSrv_basic_cluster\fP(7) ,
+\fBsap_suse_cluster_connector\fP(8) ,
+\fBcrm\fP(8) , \fBcrm_simulate\fP(8) , \fBcrm_report\fP(8) , \fBcibadmin\fP(8) 
,
+\fBsbd\fP(8) , \fBcorosync-cfgtool\fP(8) ,
+\fBsystemctl\fP(8) ,
+\fBcs_clusterstate\fP(8) , \fBcs_wait_for_idle\fP(8) , 
\fBcs_show_ensa_status\fP(8) ,
+\fBha_related_sap_notes\fP(7)
+.PP
+.\"
+.SH AUTHORS
+F.Herschel, L.Pinne
+.PP
+.\"
+.SH COPYRIGHT
+.br
+(c) 2020-2022 SUSE LLC
+.br
+SAPStartSrv comes with ABSOLUTELY NO WARRANTY.
+.br
+For details see the GNU General Public License at
+http://www.gnu.org/licenses/gpl.html
+.\"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/ocf_suse_SAPStartSrv.7
 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/ocf_suse_SAPStartSrv.7
--- 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/ocf_suse_SAPStartSrv.7
     2021-04-29 09:39:35.000000000 +0200
+++ 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/ocf_suse_SAPStartSrv.7
     2022-09-21 11:19:23.000000000 +0200
@@ -1,6 +1,6 @@
-.\" Version: 0.1.0
+.\" Version: 0.9.1
 .\"
-.TH ocf_suse_SAPStartSrv 7 "01 Feb 2021" "" "OCF resource agents"
+.TH ocf_suse_SAPStartSrv 7 "23 Jun 2022" "" "OCF resource agents"
 .\"
 .SH NAME
 SAPStartSrv \- Manages sapstartsv for a single SAP instance as an HA resource.
@@ -13,7 +13,7 @@
 .\"
 .SH DESCRIPTION
 
-\fBSAPStartSrv\fP is an resource agent for managing the sapstartsrv process for
+\fBSAPStartSrv\fP is a resource agent for managing the sapstartsrv process for
 a single SAP instance as an HA resource.
 .PP
 One SAP instance is defined by having exactly one instance profile.
@@ -93,8 +93,8 @@
 \fBmonitor\fR
 .RS 4
 The SAPStartSrv resource must by intention not define a monitor operation.
-This is, because the failing sapstartsrv must never force an SAPInstance
-restart which would happen, as the two resources reside in one resource group.
+This is, because the failing sapstartsrv must never force a SAPInstance 
restart.
+That would happen because the two resources reside in one resource group.
 .\" TODO op monitor on-fail="ignore"
 .RE
 .PP
@@ -121,11 +121,11 @@
 .SH EXAMPLES
 * Example configuration for SAP ASCS instance resource group in an ENSA2 setup.
 .br
-SAP system name is EVA, SAP service is ASCS, SAP instance number is 00, SAP 
virtual hostname is sapeva. An loadbalancer is used together with dedicated IP 
netmask configuration for specific public cloud environments. The SAPInstance 
has been given a fencing priority, a crm property priority-fencing-delay is 
needed to make this work. See SAPStartSrv_basic_cluster(7).
+SAP system name is EVA, SAP service is ASCS, SAP instance number is 00, SAP 
virtual hostname is sapeva. An loadbalancer is used together with dedicated IP 
netmask configuration for specific public cloud environments. The SAPInstance 
has been given a fencing priority, a crm property priority-fencing-delay is 
needed to make this work. See SAPStartSrv_basic_cluster(7). The shown 
SAPInstance monitor timeout is a trade-off between fast recovery of the ASCS 
vs. resilience against sporadic temporary NFS issues. You may slightly increase 
it to fit your infrastructure. Too short ASCS monitor timeouts likely will 
conflict with the instance??s internal recovery.
 The also needed ERS instance group and location constraint is shown in another 
example.
 .PP
 .RS 4
-primitive rsc_SAPStartSrv_EVA_ASCS00 SAPStartSrv \\
+primitive rsc_SAPStartSrv_EVA_ASCS00 ocf:suse:SAPStartSrv \\
 .br
  params InstanceName=EVA_ASCS00_sapeva
 .PP
@@ -172,8 +172,9 @@
 .br
 SAP system name is EN2, SAP service is ERS, SAP instance number is 10, SAP 
virtual hostname is sapeva. An IP address is configured as usual for on-premise 
use.
 If possible, the ERS instance should run on a different node than the ASCS.
-The also needed ASCSS instance group is shown in another example.
+The also needed ASCS instance group is shown in another example.
 .PP
+.RS 4
 primitive rsc_SAPStartSrv_EN2_ERS10 ocf:suse:SAPStartSrv \\
 .br
  params InstanceName=EN2_ERS10_sapen2er
@@ -214,6 +215,50 @@
 .br
 .RE
 .PP
+* Example SAP ASCS instance profile adapted for ENSA2 HA setup.
+.br
+SAP SID is EN2, instance number is 00, virtual hostname is sapen2er, service 
is _ENQ .
+Optionally you could limit the number of restarts of services, this is not 
done here. 
+The instance profile /sapmnt/EN2/profile/EN2_ASCS00_sapen2er is adpated like 
this:
+.PP
+.RS 4
+# ... some more above
+.br
+_ENQ = enq.sap$(SAPSYSTEMNAME)_$(INSTANCE_NAME)
+.br
+Execute_04 = local rm -f $(_ENQ)
+.br
+Execute_05 = local ln -s -f $(DIR_EXECUTABLE)/enq_server$(FT_EXE) $(_ENQ)
+.br
+Start_Program_01 = local $(_ENQ) pf=$(_PF)
+.br
+# some more below ...
+.br
+.RE
+.PP
+* Example SAP ERS instance profile adapted for ENSA2 HA setup.
+.br
+SAP SID is EN2, instance number is 10, virtual hostname is sapen2er, service 
is _ENQR .
+See also man page sap_suse_cluster_connector(8).
+The instance profile /sapmnt/EN2/profile/EN2_ERS10_sapen2er is adpated like 
this:
+.PP
+.RS 4
+# ... some more above
+.br
+_ENQR = enqr.sap$(SAPSYSTEMNAME)_$(INSTANCE_NAME)
+.br
+Execute_02 = local rm -f $(_ENQR)
+.br
+Execute_03 = local ln -s -f $(DIR_EXECUTABLE)/enq_replicator$(FT_EXE) $(_ENQR)
+.br
+Start_Program_00 = local $(_ENQR) pf=$(_PF) NR=$(SCSID)
+.br
+service/halib_cluster_connector = /usr/bin/sap_suse_cluster_connector
+.br
+service/halib = $(DIR_CT_RUN)/saphascriptco.so
+.br
+.RE
+.PP
 * Search for log entries of SAPStartSrv, show errors only:
 .PP
 .RS 4
@@ -229,7 +274,7 @@
 # cibadmin -Ql | grep rsc_SAPStartSrv_EN2_ERS10.*fail-count
 .RE
 .PP
-* Manually trigger an SAPStartSRv probe action for instance ADA_ASCS00_engine.
+* Manually trigger a SAPStartSrv probe action for instance ADA_ASCS00_engine.
 Output goes to the usual logfiles.
 .PP
 .RS 4
@@ -244,8 +289,9 @@
 .PP
 .\" TODO example for checking enqueue table?
 .\" TODO example for checking process list?
+.PP
 .\"
-.SH FILES
+.SH FILES 
 .TP
 /usr/lib/ocf/resource.d/suse/SAPStartSrv
 the resource agent
@@ -256,7 +302,7 @@
 /usr/sap/$SID/$InstanceName/exe/
 default path for the sapstartsrv executable
 .TP
-/usr/sap/$SID/SYS/profile/
+/sapmnt/$SID/profile/ (resp. /usr/sap/$SID/SYS/profile/)
 default path for DIR_PROFILE
 .TP
 /usr/sap/sapservices
@@ -282,7 +328,7 @@
 .PP
 * SAP instance profile Autostart feature is disabled for ASCS and ERS.
 .PP
-* SAP instance profile entry Restart_Program_xx is replaced by 
Start_Program_xx for ERS. 
+* For ENSA1 and ENSA2 HA setups, the ASCS instance profile entry for the 
enqueue service _ENQ, Restart_Program_xx is replaced by Start_Program_xx. Same 
for the ERS instance profile entry for the enqueue replicator service _ENQR. 
Other services stay untouched. 
 .PP
 * The sapinit boot script does not read entries from sapservices file at boot. 
Thus services sapping and sappong to handle sapservices file at system boot.
 .PP
@@ -292,23 +338,46 @@
 .PP
 * It is not allowed to block resources from being controlled manually. Thus 
BLOCK_RESOURCES in /etc/sap_suse_cluster_connector is not allowed anymore.
 .PP
+* You need SAP hostagent installed and started on your systems.
+For SystemV style, the sapinit script needs to be enabled.
+For systemd style, the service saphostagent needs to be enabled and running.
+Instance services SAP${SID}_${INO} need to be disabled. 
+The systemd enabled saphostagent and sapstartsrv is supported from
+sapstartsrv-resource-agents 0.9.1 onwards.
+An appropriate SAPInstance resource agent is needed, newer than November 2021.
+Please refer to the OS documentation for the systemd version.
+Please refer to SAP documentation for the SAP HANA version.
+Combining systemd style hostagent with SystemV style instance is allowed.
+However, all nodes in one Linux cluster have to use the same style.
+.PP
 ./"
 .SH BUGS
 .\" In case of any problem, please use your favourite SAP support process to
 .\" open a request for the component BC-OP-LNX-SUSE.
+The trace_ra resourcre tracing feature is not implemented so far.
+.br
 Please report feedback and suggestions to feedb...@suse.com.
 .PP
 .\"
 .SH SEE ALSO
 \fBocf_heartbeat_SAPInstance\fP(7) , \fBocf_heartbeat_IPaddr2\fP(7) ,
-\fBSAPStartSrv_basic_cluster\fP(7) ,
+\fBSAPStartSrv_basic_cluster\fP(7) , \fBsystemctl\fP(1) ,
 .\" TODO aws-vpc-route53 gcp-vpc-move-route
 .\" TODO SAPStartSrv-showAttr(8) ?
 \fBsapservices-move\fP(8) , \fBsap_suse_cluster_connector\fP(8) ,
-\fBcrm\fP(8) , \fBnfs\fP(5) , \fBmount\fP(8) , \fBha_related_suse_tids\fP(7) ,
+\fBcrm\fP(8) , \fBnfs\fP(5) , \fBmount\fP(8) ,
+\fBha_related_suse_tids\fP(7) , \fBha_related_sap_notes\fP(7) ,
 .br
 https://documentation.suse.com/sbp/all/?context=sles-sap ,
 .br
+https://www.suse.com/support/kb/doc/?id=000019244 ,
+.br
+https://www.suse.com/support/kb/doc/?id=000019293 ,
+.br
+https://www.suse.com/support/kb/doc/?id=000019924 ,
+.br
+https://www.suse.com/support/kb/doc/?id=000019944 ,
+.br
 https://www.suse.com/support/kb/doc/?id=7023714 ,
 .br
 
http://clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/s-ocf-return-codes.html
 ,
@@ -316,22 +385,32 @@
 
https://help.sap.com/doc/e9a0eddf6eb14a82bcbe3be3c9a58c7e/1610%20001/en-US/frameset.htm?frameset.htm
 ,
 .br
 
https://help.sap.com/viewer/fe1db4ed6c5510148f66fbccd85f175f/7.02.22/en-US/47e023f3bf423c83e10000000a42189c.html
+.br
+https://wiki.scn.sap.com/wiki/display/SI/Troubleshooting+for+Enqueue+Failover+in+ASCS+with+ERS
 .\" .br
 .\" 
https://blogs.sap.com/2018/04/03/high-availability-with-standalone-enqueue-server-2/
 ,
 .\" .br
 .\" https://blogs.sap.com/2020/08/27/evolution-of-ensa2-and-erp2.../ ,
 .br
-https://launchpad.support.sap.com/#/notes/2711036 ,
+https://launchpad.support.sap.com/#/notes/1763512 ,
 .br
-https://launchpad.support.sap.com/#/notes/2630416 ,
+https://launchpad.support.sap.com/#/notes/1872602 ,
 .br
-https://launchpad.support.sap.com/#/notes/2501860 ,
+https://launchpad.support.sap.com/#/notes/2077934 ,
+.br
+https://launchpad.support.sap.com/#/notes/2254173 ,
 .br
 https://launchpad.support.sap.com/#/notes/2464065 ,
 .br
-https://launchpad.support.sap.com/#/notes/2254173 ,
+https://launchpad.support.sap.com/#/notes/2501860 ,
 .br
-https://launchpad.support.sap.com/#/notes/2077934 ,
+https://launchpad.support.sap.com/#/notes/2625407 ,
+.br
+https://launchpad.support.sap.com/#/notes/2630416 ,
+.br
+https://launchpad.support.sap.com/#/notes/2711036 ,
+.br
+https://launchpad.support.sap.com/#/notes/2717369 ,
 .br
 https://launchpad.support.sap.com/#/notes/953653
 .PP
@@ -341,7 +420,7 @@
 .PP
 .\"
 .SH COPYRIGHT
-(c) 2020-2021 SUSE LLC
+(c) 2020-2022 SUSE LLC
 .br
 The resource agent SAPStartSrv comes with ABSOLUTELY NO WARRANTY.
 .br
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/sapping.7 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/sapping.7
--- old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/sapping.7  
2021-04-29 09:39:35.000000000 +0200
+++ new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/sapping.7  
2022-09-21 11:19:23.000000000 +0200
@@ -1,6 +1,6 @@
-.\" Version: 0.1.0
+.\" Version: 0.9.1
 .\"
-.TH sapping/sappong 7 "01 Feb 2021" "" "SAPStartSrv"
+.TH sapping/sappong 7 "02 Feb 2022" "" "SAPStartSrv"
 .\"
 .SH NAME
 sapping \- service for hiding sapservices file from sapinit service at system 
boot.
@@ -11,7 +11,7 @@
 .SH DESCRIPTION
 \fBsapping\fP is a systemd service for hiding sapservices file from sapinit 
service at system boot.
 .br
-\fBsappong\fP is a systemd service for un-hiding sapservices file after 
sapinit service has been started at system boot.
+\fBsappong\fP is a systemd service for unhiding sapservices file after sapinit 
service has been started at system boot.
 .br
 The services are intended to be called at boot time. Administrative use during 
regular operations is not intended.
 .PP
@@ -58,7 +58,7 @@
 .\"
 .SH COPYRIGHT
 .br
-(c) 2020 SUSE LLC
+(c) 2020-2022 SUSE LLC
 .br
 sapping/sappong comes with ABSOLUTELY NO WARRANTY.
 .br
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/sapservices-move.8
 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/sapservices-move.8
--- 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/man/sapservices-move.8
 2021-04-29 09:39:35.000000000 +0200
+++ 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/man/sapservices-move.8
 2022-09-21 11:19:23.000000000 +0200
@@ -1,6 +1,6 @@
-.\" Version: 0.1.0
+.\" Version: 0.9.1
 .\"
-.TH sapservices-move 8 "27 Jan 2021" "" "SAPStartSrv"
+.TH sapservices-move 8 "02 Feb 2022" "" "SAPStartSrv"
 .\"
 .SH NAME
 sapservices-move \- hiding sapservices file from sapinit service at system 
boot.
@@ -16,7 +16,7 @@
 .br
  \- sapping is hiding the sapservices file from sapinit service at system boot.
 .br
- \- sappong is restoring the sapservices file after sapinit service has been 
started.
+ \- sappong is unhiding the sapservices file after sapinit service has been 
started.
 
 Hiding the sapservices file from sapinit is necessary in certain HA cluster 
setups. Affected are HA clusters for SAP enqueue replication where cluster 
nodes have concurrent access to all instance working directories, e.g. by 
simplified NFS mount structure.
 In such environments sapstartsrv needs to be started specific for each SAP 
instance (e.g. ASCS/ERS), to avoid side effects with other instances.
@@ -96,9 +96,9 @@
 .\"
 .SH COPYRIGHT
 .br
-(c) 2020-2021 SUSE LLC
+(c) 2020-2022 SUSE LLC
 .br
-sapping/sappong comes with ABSOLUTELY NO WARRANTY.
+sapservices-move comes with ABSOLUTELY NO WARRANTY.
 .br
 For details see the GNU General Public License at
 http://www.gnu.org/licenses/gpl.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/ra/SAPStartSrv.in 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/ra/SAPStartSrv.in
--- 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/ra/SAPStartSrv.in  
    2021-04-29 09:39:35.000000000 +0200
+++ 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/ra/SAPStartSrv.in  
    2022-09-21 11:19:23.000000000 +0200
@@ -9,14 +9,14 @@
 # Based on code from: Fabian Herschel
 # Support:
 # License:      GNU General Public License (GPL)
-# Copyright:    (c) 2020 SUSE LLC
+# Copyright:    (c) 2020-2022 SUSE LLC
 #
 # An example usage:
 #      See usage() function below for more details...
 #
 # OCF instance parameters:
-#      - OCF_RESKEY_InstanceName
-#      - not currently OCF_RESKEY_START_PROFILE (optional, well known 
directories will be
+#       - OCF_RESKEY_InstanceName
+#       - not currently OCF_RESKEY_START_PROFILE (optional, well known 
directories will be
 #     searched by default)
 #
 #   - supports sapstartsrv for SAP instances NW7.40 or newer, SAP S/4HANA ABAP 
Platform 1909
@@ -47,6 +47,9 @@
 MONITOR_SERVICES_DEFAULT = \
     
'disp+work|msg_server|enserver|enrepserver|jcontrol|jstart|enq_server|enq_replicator'
 
+SYSTEMCTL = '/usr/bin/systemctl'
+
+
 class ProcessResult(object):
     """
     Class to store subprocess.Popen output information and offer some
@@ -62,7 +65,7 @@
     def __init__(self, cmd, returncode, output, err):
         self.cmd = cmd
         self.returncode = returncode
-        self.output = output.decode() # Make it compatiable with python2 and 3
+        self.output = output.decode()  # Make it compatiable with python2 and 3
         self.err = err.decode()
 
 
@@ -90,6 +93,7 @@
         self.sidadm = None
         self.instance_name = None
         self.instance_number = None
+        self.systemd_unit_name = None
         self.virtual_host = None
         self.dir_executable = None
         self.saptstartsrv_path = None
@@ -104,6 +108,8 @@
         result = run_command(
             'pgrep -f -l "sapstartsrv.*pf=.*{}_{}_{}"'.format(
                 self.sid, self.instance_name, self.virtual_host))
+        if result.returncode == 0 and not re.match(r'.*\bsapstartsrv\b.*', 
result.output):
+            result.returncode = 1
         logger.info('Current status: %d. Output: %s' % (result.returncode, 
result.output))
         return result
 
@@ -134,10 +140,10 @@
 
         if ocf.have_binary(self.saptstartsrv_path) and 
ocf.have_binary(self.sapcontrol_path):
             return ocf.OCF_SUCCESS
-        else:
-            logger.error(
-                'Cannot find sapstartsrv and sapcontrol executable in %s' %
-                (self.dir_executable))
+
+        logger.error(
+            'Cannot find sapstartsrv and sapcontrol executable in %s' %
+            (self.dir_executable))
 
         # Find executables in standard locations. E.g: 
/usr/sap/HA1/ASCS00/exe/run
         self.dir_executable = '/usr/sap/{}/{}/exe/run'.format(self.sid, 
self.instance_name)
@@ -175,20 +181,21 @@
         Initialize variables
         '''
 
-        if len(self.full_name.split('_')) != 3:
-          logger.error('InstanceName parsing error. It must follow 
SID_NAME00_VIRTHOST syntax')
-          return ocf.OCF_ERR_ARGS
+        if len(self.full_name.split('_')) < 3:
+            logger.error('InstanceName parsing error. It must follow 
SID_NAME00_VIRTHOST syntax')
+            return ocf.OCF_ERR_ARGS
 
         try:
-          self.sid = self.full_name.split('_')[0]
-          self.instance_name = self.full_name.split('_')[1]
-          self.virtual_host = '_'.join(self.full_name.split('_')[2:])
-          instance_data = re.match('[a-zA-Z]+([0-9]{2})', 
self.instance_name).groups()
-          self.instance_number = instance_data[0]
-          self.sidadm = '{}adm'.format(self.sid.lower())
+            self.sid = self.full_name.split('_')[0]
+            self.instance_name = self.full_name.split('_')[1]
+            self.virtual_host = '_'.join(self.full_name.split('_')[2:])
+            instance_data = re.match('[a-zA-Z]+([0-9]{2})', 
self.instance_name).groups()
+            self.instance_number = instance_data[0]
+            self.sidadm = '{}adm'.format(self.sid.lower())
+            self.systemd_unit_name = 
'SAP{}_{}.service'.format(self.sid.upper(), self.instance_number)
         except (IndexError, AttributeError):
-          logger.error('InstanceName parsing error. It must follow 
SID_NAME00_VIRTHOST syntax')
-          return ocf.OCF_ERR_ARGS
+            logger.error('InstanceName parsing error. It must follow 
SID_NAME00_VIRTHOST syntax')
+            return ocf.OCF_ERR_ARGS
 
         result = self._find_executables()
         if result != ocf.OCF_SUCCESS:
@@ -204,11 +211,67 @@
 
         return ocf.OCF_SUCCESS
 
-    def start(self):
+    def _is_unit_active(self):
+        '''
+        Run systemctl is-active unit_name
+        '''
+        result = run_command(
+            '{} is-active {}'.format(SYSTEMCTL, self.systemd_unit_name))
+        return result.returncode == 0
+
+    def _get_systemd_unit(self):
+        '''
+        Run systemctl list-unit-files unit_name
+        '''
+        pattern = r'.*\s%s.*' % self.systemd_unit_name
+        result = run_command(
+            '{} list-unit-files {}'.format(SYSTEMCTL, self.systemd_unit_name))
+        if result.returncode == 0 and not re.match(pattern, result.output):
+            result.returncode = 1
+        return result.returncode == 0
+
+    def _chk_systemd_support(self):
+        '''
+        Check availability of SAP systemd support
+        '''
+        if ocf.have_binary(SYSTEMCTL):
+            unit_file = '/etc/systemd/system/{}'.format(self.systemd_unit_name)
+            if os.path.exists(unit_file):
+                return True
+            if self._get_systemd_unit():
+                return True
+
+        return False
+
+    def _start_systemd_style(self):
+        '''
+        Run systemctl start unit
+        '''
+        if self._is_unit_active():
+            logger.info(
+                'systemd service %s is active' % (self.systemd_unit_name))
+            return ocf.OCF_SUCCESS
+
+        logger.warn(
+            'systemd service %s is not active, it will be started using 
systemd' %
+            (self.systemd_unit_name))
+        result = run_command(
+            '{} start {}'.format(SYSTEMCTL, self.systemd_unit_name))
+        if result.returncode == 0:
+            return ocf.OCF_SUCCESS
+
+        logger.error(
+            'error during start of systemd unit %s!' %
+            (self.systemd_unit_name))
+        if ocf.is_probe():
+            return ocf.OCF_NOT_RUNNING
+
+        return ocf.OCF_ERR_GENERIC
+
+    def _start_sys5_style(self):
         '''
         Run sapstartsrv command
         '''
-        self._inititialize()
         run_command('rm -f /tmp/.sapstream5{}13'.format(self.instance_number))
         run_command('rm -f /tmp/.sapstream5{}14'.format(self.instance_number))
         start_result = run_command('{} pf={} -D -u {}'.format(
@@ -217,18 +280,29 @@
         result = self._get_status()
         if result.returncode == 0:
             logger.info(
-                'sapstartsrv for SAP Instance %s-%s started: %s' %
+                'sapstartsrv for SAP Instance %s_%s started: %s' %
                 (self.sid, self.instance_name, start_result.output))
             return ocf.OCF_SUCCESS
 
         logger.error(
-            'sapstartsrv for SAP Instance %s-%s start failed: %s' %
+            'sapstartsrv for SAP Instance %s_%s start failed: %s' %
             (self.sid, self.instance_name, start_result.err))
+
         return ocf.OCF_NOT_RUNNING
 
+    def start(self):
+        '''
+        Start sapstartsrv
+        '''
+        self._inititialize()
+        if self._chk_systemd_support():
+            return self._start_systemd_style()
+
+        return self._start_sys5_style()
+
     def stop(self):
         '''
-        Run sapcontrol command to with StopService
+        Run sapcontrol command with StopService
         '''
         self._inititialize()
         result = self._get_status()
@@ -237,18 +311,18 @@
                 '{} -nr {} -function StopService'.format(
                     self.sapcontrol_path, self.instance_number))
             logger.info(
-                'Stopping sapstartsrv of SAP Instance %s-%s: %s' %
-                (self.sid, self.instance_number, stop_result.output))
+                'Stopping sapstartsrv of SAP Instance %s_%s: %s' %
+                (self.sid, self.instance_name, stop_result.output))
             if stop_result.returncode == 0:
                 return ocf.OCF_SUCCESS
 
             logger.error(
-                'SAP Instance %s-%s stop failed: %s' %
-                (self.sid, self.instance_number, stop_result.err))
+                'SAP Instance %s_%s stop failed: %s' %
+                (self.sid, self.instance_name, stop_result.err))
             return ocf.OCF_ERR_GENERIC
 
         logger.info(
-            'SAP Instance %s-%s already stopped' % (self.sid, 
self.instance_number))
+            'SAP Instance %s_%s already stopped' % (self.sid, 
self.instance_name))
         return ocf.OCF_SUCCESS
 
     def status(self):
@@ -270,8 +344,8 @@
         if ocf.is_probe():
             if self._get_status().returncode == 0:
                 return ocf.OCF_SUCCESS
-            else:
-                return ocf.OCF_NOT_RUNNING
+
+            return ocf.OCF_NOT_RUNNING
         '''
         For regular monitors always return success, because recover of 
sapstartsrv is already handeled by SAPInstance
         This might be changed in a next-generation edition
@@ -317,8 +391,8 @@
     sapstartsrv_agent.add_parameter(
         name='InstanceName',
         shortdesc='Instance name: SID_INSTANCE_VIR-HOSTNAME',
-        longdesc='The full qualified SAP instance name. e.g. 
HA1_ASCS00_sapha1as. ' \
-            'Usually this is the name of the SAP instance profile.',
+        longdesc='The full qualified SAP instance name. e.g. 
HA1_ASCS00_sapha1as. '
+                 'Usually this is the name of the SAP instance profile.',
         content_type='string',
         required=True,
         unique=True,
@@ -328,8 +402,8 @@
     sapstartsrv_agent.add_parameter(
         name='START_PROFILE',
         shortdesc='Start profile name',
-        longdesc='The name of the SAP Instance profile. Specify this 
parameter, if you have ' \
-            'changed the name of the SAP Instance profile after the default 
SAP installation.',
+        longdesc='The name of the SAP Instance profile. Specify this 
parameter, if you have '
+                 'changed the name of the SAP Instance profile after the 
default SAP installation.',
         content_type='string',
         unique=True,
         default=''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/sapstartsrv-resource-agents.changes
 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/sapstartsrv-resource-agents.changes
--- 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/sapstartsrv-resource-agents.changes
    2021-04-29 09:39:35.000000000 +0200
+++ 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/sapstartsrv-resource-agents.changes
    2022-09-21 11:19:23.000000000 +0200
@@ -1,4 +1,25 @@
 -------------------------------------------------------------------
+Wed Sep 14 09:37:25 UTC 2022 - abr...@suse.com
+
+- Version bump to 0.9.1
+- man page updates based on customer feedback on conferences
+- remove 'BuildRequire python3-mock' as this is no longer needed
+  for the tests
+
+-------------------------------------------------------------------
+Fri Feb 25 11:18:02 UTC 2022 - abr...@suse.com
+
+- Add systemd support for the resource agent to interact with the
+  new SAP unit files for sapstartsrv.
+  As the new version of the SAP Startup Framework will use systemd
+  unit files to control the sapstartsrv process instead of the
+  previous used SysV init script, we need to adapt the handling of
+  sapstartsrv inside the resource agents to support both ways.
+  (bsc#1189529)
+- prevent false posivite with pgrep in function '_get_status' 
+ (bsc#1193568)
+
+-------------------------------------------------------------------
 Thu Apr 22 13:05:47 UTC 2021 - abr...@suse.com
 
 - remove deprecated option "syslog" from the sapping.service and
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/sapstartsrv-resource-agents.spec
 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/sapstartsrv-resource-agents.spec
--- 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/sapstartsrv-resource-agents.spec
       2021-04-29 09:39:35.000000000 +0200
+++ 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/sapstartsrv-resource-agents.spec
       2022-09-21 11:19:23.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package sapstartsrv-resource-agents
 #
-# Copyright (c) 2020-2021 SUSE LLC.
+# Copyright (c) 2020-2022 SUSE LLC.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -34,7 +34,6 @@
 Requires:       pacemaker > 1.1.1
 Requires:       python3
 %if %{with test}
-BuildRequires:  python3-mock
 BuildRequires:  python3-pytest
 %endif
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/tests/SAPStartSrv_test.py
 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/tests/SAPStartSrv_test.py
--- 
old/sapstartsrv-resource-agents-0.9.0+git.1619681975.ad20a04/tests/SAPStartSrv_test.py
      2021-04-29 09:39:35.000000000 +0200
+++ 
new/sapstartsrv-resource-agents-0.9.1+git.1663751963.e0ef8a2/tests/SAPStartSrv_test.py
      2022-09-21 11:19:23.000000000 +0200
@@ -49,6 +49,7 @@
         self._instance_name = 'ASCS'
         self._instance_number = '00'
         self._virtualhost = 'virthost'
+        self._systemd_unit_name = 'SAPPRD_00.service'
         self._agent = SAPStartSrv.SapStartSrv(
             '{}_{}{}_{}'.format(
                 self._sid, self._instance_name, self._instance_number, 
self._virtualhost))
@@ -88,12 +89,156 @@
         mock_process.communicate.assert_called_once_with()
         mock_process_result.assert_called_once_with('cmd', 0, 'output', 
'error')
 
+    @mock.patch('SAPStartSrv.run_command')
+    def test_is_unit_active(self, mock_run_command):
+        mock_result = mock.Mock(output='output', returncode=0)
+        mock_run_command.return_value = mock_result
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        result = self._agent._is_unit_active()
+        assert result is True
+        mock_run_command.assert_called_once_with(
+            '/usr/bin/systemctl is-active SAPPRD_00.service')
+
+    @mock.patch('SAPStartSrv.run_command')
+    def test_is_unit_not_active(self, mock_run_command):
+        mock_result = mock.Mock(output='output', returncode=1)
+        mock_run_command.return_value = mock_result
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        result = self._agent._is_unit_active()
+        assert result is False
+        mock_run_command.assert_called_once_with(
+            '/usr/bin/systemctl is-active SAPPRD_00.service')
+
+    @mock.patch('SAPStartSrv.run_command')
+    def test_get_systemd_unit_success(self, mock_run_command):
+        mock_result = mock.Mock(output='UNIT FILE    STATE  
\nSAPPRD_00.service\n\n1 unit files listed.\n', returncode=0)
+        mock_run_command.return_value = mock_result
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        result = self._agent._get_systemd_unit()
+        assert result is True
+        mock_run_command.assert_called_once_with(
+            '/usr/bin/systemctl list-unit-files SAPPRD_00.service')
+
+    @mock.patch('SAPStartSrv.run_command')
+    def test_get_systemd_unit_error(self, mock_run_command):
+        mock_result = mock.Mock(output='output', returncode=1)
+        mock_run_command.return_value = mock_result
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        result = self._agent._get_systemd_unit()
+        assert result is False
+        mock_run_command.assert_called_once_with(
+            '/usr/bin/systemctl list-unit-files SAPPRD_00.service')
+
+    @mock.patch('ocf.have_binary')
+    @mock.patch('os.path.exists')
+    def test_chk_systemd_support_binary_success(
+            self, mock_exists, mock_have_binary):
+
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        mock_have_binary.return_value = True
+        mock_exists.return_value = False
+
+        get_systemd_unit_mock = mock.Mock(return_value=False)
+        self._agent._get_systemd_unit = get_systemd_unit_mock
+
+        result = self._agent._chk_systemd_support()
+        assert result is False
+
+        mock_have_binary.assert_called_once_with(
+            '/usr/bin/systemctl'
+        )
+
+    @mock.patch('ocf.have_binary')
+    def test_chk_systemd_support_binary_error(
+            self, mock_have_binary):
+
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        mock_have_binary.return_value = False
+
+        result = self._agent._chk_systemd_support()
+        assert result is False
+
+        mock_have_binary.assert_called_once_with(
+            '/usr/bin/systemctl'
+        )
+
+    @mock.patch('ocf.have_binary')
+    @mock.patch('os.path.exists')
+    def test_chk_systemd_support_binary_success_exists_success(
+            self, mock_exists, mock_have_binary):
+
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        mock_have_binary.return_value = True
+        mock_exists.return_value = True
+
+        result = self._agent._chk_systemd_support()
+        assert result is True
+
+        mock_have_binary.assert_called_once_with(
+            '/usr/bin/systemctl'
+        )
+        mock_exists.assert_called_once_with(
+            '/etc/systemd/system/SAPPRD_00.service'
+        )
+
+    @mock.patch('ocf.have_binary')
+    @mock.patch('os.path.exists')
+    def test_chk_systemd_support_binary_success_exists_error(
+            self, mock_exists, mock_have_binary):
+
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        mock_have_binary.return_value = True
+        mock_exists.return_value = False
+
+        get_systemd_unit_mock = mock.Mock(return_value=False)
+        self._agent._get_systemd_unit = get_systemd_unit_mock
+
+        result = self._agent._chk_systemd_support()
+        assert result is False
+
+        mock_have_binary.assert_called_once_with(
+            '/usr/bin/systemctl'
+        )
+        mock_exists.assert_called_once_with(
+            '/etc/systemd/system/SAPPRD_00.service'
+        )
+
+    @mock.patch('ocf.have_binary')
+    @mock.patch('os.path.exists')
+    def test_chk_systemd_support_binary_success_exists_error_get_unit(
+            self, mock_exists, mock_have_binary):
+
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+
+        mock_have_binary.return_value = True
+        mock_exists.return_value = False
+
+        get_systemd_unit_mock = mock.Mock(return_value=True)
+        self._agent._get_systemd_unit = get_systemd_unit_mock
+
+        result = self._agent._chk_systemd_support()
+        assert result is True
+
+        mock_have_binary.assert_called_once_with(
+            '/usr/bin/systemctl'
+        )
+        mock_exists.assert_called_once_with(
+            '/etc/systemd/system/SAPPRD_00.service'
+        )
 
     @mock.patch('ocf.logger.info')
     @mock.patch('SAPStartSrv.run_command')
     def test_get_status(self, mock_run_command, mock_logger):
 
-        mock_result = mock.Mock(output='output', returncode=0)
+        mock_result = mock.Mock(output=' sapstartsrv ', returncode=0)
         mock_run_command.return_value = mock_result
         self._agent.sid = 'PRD'
         self._agent.instance_name = 'ASCS00'
@@ -103,8 +248,21 @@
         assert result == mock_result
         mock_run_command.assert_called_once_with(
             'pgrep -f -l "sapstartsrv.*pf=.*PRD_ASCS00_virthost"')
-        mock_logger.assert_called_once_with('Current status: 0. Output: 
output')
+        mock_logger.assert_called_once_with('Current status: 0. Output:  
sapstartsrv ')
 
+        mock_run_command.reset_mock()
+        mock_logger.reset_mock()
+        mock_result = mock.Mock(output='output', returncode=0)
+        mock_run_command.return_value = mock_result
+        self._agent.sid = 'PRD'
+        self._agent.instance_name = 'ASCS00'
+        self._agent.virtual_host = 'virthost'
+
+        result = self._agent._get_status()
+        assert result == mock_result
+        mock_run_command.assert_called_once_with(
+            'pgrep -f -l "sapstartsrv.*pf=.*PRD_ASCS00_virthost"')
+        mock_logger.assert_called_once_with('Current status: 1. Output: 
output')
 
     @mock.patch('ocf.OCF_SUCCESS', 0)
     @mock.patch('ocf.have_binary')
@@ -390,8 +548,7 @@
     @mock.patch('ocf.logger.info')
     @mock.patch('ocf.OCF_SUCCESS', 0)
     @mock.patch('SAPStartSrv.run_command')
-    def test_start_success(self, mock_run_command, mock_logger):
-        self._agent._inititialize = mock.Mock()
+    def test_start_sys5_style_success(self, mock_run_command, mock_logger):
         self._agent.instance_name = 'ASCS00'
         self._agent.instance_number = '00'
         self._agent.saptstartsrv_path = '/mock/sapstartsrv'
@@ -406,11 +563,9 @@
         get_status_mock = mock.Mock(return_value=get_status_result_mock)
         self._agent._get_status = get_status_mock
 
-        ocf_returncode = self._agent.start()
+        ocf_returncode = self._agent._start_sys5_style()
         assert ocf_returncode == 0
 
-        self._agent._inititialize.assert_called_once_with()
-
         mock_run_command.assert_has_calls([
             mock.call('rm -f /tmp/.sapstream50013'),
             mock.call('rm -f /tmp/.sapstream50014'),
@@ -418,13 +573,12 @@
         ])
 
         mock_logger.assert_called_once_with(
-            'sapstartsrv for SAP Instance PRD-ASCS00 started: output')
+            'sapstartsrv for SAP Instance PRD_ASCS00 started: output')
 
     @mock.patch('ocf.logger.error')
     @mock.patch('ocf.OCF_NOT_RUNNING', 1)
     @mock.patch('SAPStartSrv.run_command')
-    def test_start_error(self, mock_run_command, mock_logger):
-        self._agent._inititialize = mock.Mock()
+    def test_start_sys5_style_error(self, mock_run_command, mock_logger):
         self._agent.instance_name = 'ASCS00'
         self._agent.instance_number = '00'
         self._agent.saptstartsrv_path = '/mock/sapstartsrv'
@@ -432,18 +586,16 @@
         self._agent.sid = 'PRD'
         self._agent.sidadm = 'prdadm'
 
-        start_mock = mock.Mock(output='output', err='error')
-        mock_run_command.side_effect = [None, None, start_mock]
+        start_sys5_style_mock = mock.Mock(output='output', err='error')
+        mock_run_command.side_effect = [None, None, start_sys5_style_mock]
 
         get_status_result_mock = mock.Mock(returncode=1)
         get_status_mock = mock.Mock(return_value=get_status_result_mock)
         self._agent._get_status = get_status_mock
 
-        ocf_returncode = self._agent.start()
+        ocf_returncode = self._agent._start_sys5_style()
         assert ocf_returncode == 1
 
-        self._agent._inititialize.assert_called_once_with()
-
         mock_run_command.assert_has_calls([
             mock.call('rm -f /tmp/.sapstream50013'),
             mock.call('rm -f /tmp/.sapstream50014'),
@@ -451,13 +603,164 @@
         ])
 
         mock_logger.assert_called_once_with(
-            'sapstartsrv for SAP Instance PRD-ASCS00 start failed: error')
+            'sapstartsrv for SAP Instance PRD_ASCS00 start failed: error')
+
+    @mock.patch('ocf.logger.info')
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    def test_start_systemd_style_success_running(self, mock_logger):
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+        is_unit_active_mock = mock.Mock(return_value=True)
+        self._agent._is_unit_active = is_unit_active_mock
+
+        result = self._agent._start_systemd_style()
+        assert result == 0
+
+        mock_logger.assert_called_once_with(
+            'systemd service SAPPRD_00.service is active')
+
+    @mock.patch('ocf.logger.warn')
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    @mock.patch('SAPStartSrv.run_command')
+    def test_start_systemd_style_success_not_running(self, mock_run_command, 
mock_logger):
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+        is_unit_active_mock = mock.Mock(return_value=False)
+        self._agent._is_unit_active = is_unit_active_mock
+
+        start_mock = mock.Mock(output='output', err='error', returncode=0)
+        mock_run_command.return_value = start_mock
+
+        result = self._agent._start_systemd_style()
+        assert result == 0
+
+        mock_run_command.assert_called_once_with(
+            '/usr/bin/systemctl start SAPPRD_00.service')
+
+        mock_logger.assert_called_once_with(
+            'systemd service SAPPRD_00.service is not active, it will be 
started using systemd')
+
+    @mock.patch('ocf.logger.error')
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    @mock.patch('ocf.OCF_NOT_RUNNING', 7)
+    @mock.patch('ocf.is_probe')
+    @mock.patch('SAPStartSrv.run_command')
+    def test_start_systemd_style_error_probe(self, mock_run_command, 
mock_is_probe, mock_logger):
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+        is_unit_active_mock = mock.Mock(return_value=False)
+        self._agent._is_unit_active = is_unit_active_mock
+
+        start_mock = mock.Mock(output='output', err='error', returncode=1)
+        mock_run_command.return_value = start_mock
+        mock_is_probe.return_value = True
+
+        result = self._agent._start_systemd_style()
+        assert result == 7
+
+        mock_run_command.assert_called_once_with(
+            '/usr/bin/systemctl start SAPPRD_00.service')
+
+        mock_logger.assert_called_once_with(
+            'error during start of systemd unit SAPPRD_00.service!')
+
+    @mock.patch('ocf.logger.error')
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    @mock.patch('ocf.OCF_ERR_GENERIC', 1)
+    @mock.patch('ocf.is_probe')
+    @mock.patch('SAPStartSrv.run_command')
+    def test_start_systemd_style_error_not_probe(
+        self, mock_run_command, mock_is_probe, mock_logger):
+        self._agent.systemd_unit_name = 'SAPPRD_00.service'
+        is_unit_active_mock = mock.Mock(return_value=False)
+        self._agent._is_unit_active = is_unit_active_mock
+
+        start_mock = mock.Mock(output='output', err='error', returncode=1)
+        mock_run_command.return_value = start_mock
+        mock_is_probe.return_value = False
+
+        result = self._agent._start_systemd_style()
+        assert result == 1
+
+        mock_run_command.assert_called_once_with(
+            '/usr/bin/systemctl start SAPPRD_00.service')
+
+        mock_logger.assert_called_once_with(
+            'error during start of systemd unit SAPPRD_00.service!')
+
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    def test_start_systemd_style_success(self):
+        self._agent._inititialize = mock.Mock()
+
+        chk_systemd_support_mock = mock.Mock(return_value=True)
+        self._agent._chk_systemd_support = chk_systemd_support_mock
+        start_systemd_style_mock = mock.Mock(return_value=0)
+        self._agent._start_systemd_style = start_systemd_style_mock
+
+        result = self._agent.start()
+        assert result == 0
+
+        self._agent._inititialize.assert_called_once_with()
+
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    def test_start_success_sys5_style(self):
+        self._agent._inititialize = mock.Mock()
+
+        chk_systemd_support_mock = mock.Mock(return_value=False)
+        self._agent._chk_systemd_support = chk_systemd_support_mock
+        start_sys5_style_mock = mock.Mock(return_value=0)
+        self._agent._start_sys5_style = start_sys5_style_mock
+
+        result = self._agent.start()
+        assert result == 0
+
+        self._agent._inititialize.assert_called_once_with()
+
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    def test_start_error_sys5_style(self):
+        self._agent._inititialize = mock.Mock()
+
+        chk_systemd_support_mock = mock.Mock(return_value=False)
+        self._agent._chk_systemd_support = chk_systemd_support_mock
+        start_sys5_style_mock = mock.Mock(return_value=1)
+        self._agent._start_sys5_style = start_sys5_style_mock
+
+        result = self._agent.start()
+        assert result == 1
+
+        self._agent._inititialize.assert_called_once_with()
+
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    def test_start_success_systemd_style(self):
+        self._agent._inititialize = mock.Mock()
+
+        chk_systemd_support_mock = mock.Mock(return_value=True)
+        self._agent._chk_systemd_support = chk_systemd_support_mock
+        start_systemd_style_mock = mock.Mock(return_value=0)
+        self._agent._start_systemd_style = start_systemd_style_mock
+
+        result = self._agent.start()
+        assert result == 0
+
+        self._agent._inititialize.assert_called_once_with()
+
+    @mock.patch('ocf.OCF_SUCCESS', 0)
+    def test_start_error_systemd_style(self):
+        self._agent._inititialize = mock.Mock()
+
+        chk_systemd_support_mock = mock.Mock(return_value=True)
+        self._agent._chk_systemd_support = chk_systemd_support_mock
+        start_systemd_style_mock = mock.Mock(return_value=1)
+        self._agent._start_systemd_style = start_systemd_style_mock
+
+        result = self._agent.start()
+        assert result == 1
+
+        self._agent._inititialize.assert_called_once_with()
 
     @mock.patch('ocf.logger.info')
     @mock.patch('ocf.OCF_SUCCESS', 0)
     @mock.patch('SAPStartSrv.run_command')
     def test_stop_success(self, mock_run_command, mock_logger):
         self._agent._inititialize = mock.Mock()
+        self._agent.instance_name = 'ASCS00'
         self._agent.instance_number = '00'
         self._agent.sapcontrol_path = '/mock/sapcontrol'
         self._agent.sid = 'PRD'
@@ -476,14 +779,14 @@
         mock_run_command.assert_called_once_with('/mock/sapcontrol -nr 00 
-function StopService')
 
         mock_logger.assert_called_once_with(
-            'Stopping sapstartsrv of SAP Instance PRD-00: output')
+            'Stopping sapstartsrv of SAP Instance PRD_ASCS00: output')
 
     @mock.patch('ocf.logger.info')
     @mock.patch('ocf.OCF_SUCCESS', 0)
     @mock.patch('SAPStartSrv.run_command')
     def test_stop_already_stopped(self, mock_run_command, mock_logger):
         self._agent._inititialize = mock.Mock()
-        self._agent.instance_number = '00'
+        self._agent.instance_name = 'ASCS00'
         self._agent.sid = 'PRD'
 
         self._agent._get_status = 
mock.Mock(return_value=mock.Mock(returncode=1))
@@ -497,13 +800,14 @@
         assert mock_run_command.call_count == 0
 
         mock_logger.assert_called_once_with(
-            'SAP Instance PRD-00 already stopped')
+            'SAP Instance PRD_ASCS00 already stopped')
 
     @mock.patch('ocf.logger.error')
     @mock.patch('ocf.OCF_ERR_GENERIC', 1)
     @mock.patch('SAPStartSrv.run_command')
     def test_stop_error(self, mock_run_command, mock_logger):
         self._agent._inititialize = mock.Mock()
+        self._agent.instance_name = 'ASCS00'
         self._agent.instance_number = '00'
         self._agent.sapcontrol_path = '/mock/sapcontrol'
         self._agent.sid = 'PRD'
@@ -522,7 +826,7 @@
         mock_run_command.assert_called_once_with('/mock/sapcontrol -nr 00 
-function StopService')
 
         mock_logger.assert_called_once_with(
-            'SAP Instance PRD-00 stop failed: error')
+            'SAP Instance PRD_ASCS00 stop failed: error')
 
     @mock.patch('ocf.OCF_SUCCESS', 0)
     def test_status_success(self):

Reply via email to