Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion roles/sap_ha_pacemaker_cluster/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,19 @@ sap_ha_pacemaker_cluster_hana_hook_chksrv: false
# SAP Hana global.ini path calculated from SID
sap_ha_pacemaker_cluster_hana_global_ini_path: '' # Default: /usr/sap/<SID>/SYS/global/hdb/custom/config/global.ini

# Disable auto-detection of SAPHanaSR-angi package and use Classic
# SAP Hana nameserver.ini path calculated from SID
sap_ha_pacemaker_cluster_hana_nameserver_ini_path: '' # Default: /usr/sap/<SID>/SYS/global/hdb/custom/config/nameserver.ini

# (angi): Disable auto-detection of SAPHanaSR-angi package and use Classic
sap_ha_pacemaker_cluster_saphanasr_angi_detection: true

# (angi): Enable SAPHanaFilesystem resource creation
sap_ha_pacemaker_cluster_hana_create_filesystem_resource: true

# Optional: Define a node as a majority-maker node.
# This node is excluded from SAP resources setup.
sap_ha_pacemaker_cluster_quorum_majority_maker_node: ''

################################################################################
# NetWeaver generic definitions
################################################################################
Expand Down
15 changes: 15 additions & 0 deletions roles/sap_ha_pacemaker_cluster/handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,18 @@
ansible.builtin.systemd_service:
daemon_reload: true
listen: "systemd daemon-reload"


# TODO: this is currently not working:
# stderr: '/usr/sap/RH1/HDB02/exe/hdbnsutil: error while loading shared libraries: libhdbns.so:
# cannot open shared object file: No such file or directory'

#- name: "Reload HANA HA/DR providers"
# become: true
# become_user: "{{ sap_ha_pacemaker_cluster_hana_sid | lower }}adm"
# ansible.builtin.command:
# argv:
# - "/usr/sap/{{ sap_ha_pacemaker_cluster_hana_sid }}/HDB{{ sap_ha_pacemaker_cluster_hana_instance_nr }}/exe/hdbnsutil"
# - -reloadHADRProviders
# changed_when: false
# listen: "reload HADR Providers"
18 changes: 17 additions & 1 deletion roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ argument_specs:
# - hana_scaleup_costopt
- hana_scaleup_perf
# - hana_scaleup_perf_dr
# - hana_scaleout
- hana_scaleout
- nwas_abap_ascs_ers
# - nwas_abap_pas_aas
- nwas_java_scs_ers
Expand Down Expand Up @@ -340,6 +340,10 @@ argument_specs:
- name: crypto_cipher
value: aes256

sap_ha_pacemaker_cluster_quorum_majority_maker_node:
description:
- Define a host name that is configured only as a majority-maker node.
- This is an optional host, typically in HANA scale-out HA environments, to add an empty cluster member for the purpose of adding a quorum vote to the otherwise even number of hosts.

##########################################################################
# Parameters that are optionally imported from 'ha_cluster' LSR parameters
Expand Down Expand Up @@ -589,13 +593,25 @@ argument_specs:
description:
- Path with location of global.ini for srHook update

sap_ha_pacemaker_cluster_hana_nameserver_ini_path:
default: "/usr/sap/<SID>/SYS/global/hdb/custom/config/nameserver.ini"
description:
- Path with the location of the nameserver.ini for scale-out updates.

sap_ha_pacemaker_cluster_saphanasr_angi_detection:
type: bool
default: true
description:
- Disabling this variable enables to use Classic SAPHanaSR agents even on server,
where SAPHanaSR-angi is available.
- Value `false` (Classic) is ignored when only SAPHanaSR-angi packages are available.

sap_ha_pacemaker_cluster_hana_create_filesystem:
type: bool
default: true
description:
- Controls if the SAPHanaFileystem resource is created in an 'angi' setup.

##########################################################################
# NetWeaver specific parameters
##########################################################################
Expand Down
39 changes: 39 additions & 0 deletions roles/sap_ha_pacemaker_cluster/tasks/RedHat/post_steps_hana.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# SPDX-License-Identifier: Apache-2.0
---
# Starting SAPHana clone immediately after cluster configuration can lead to
# HANA shutdown. Following steps will leave enough time for resource agents
# to load HANA configuration before disabling maintenance.
#
# TODO:
# Add RedHat specific steps to mitigate issues with abrupt start of cluster.

- name: "SAP HA Install Pacemaker - (SAPHana*) pcs resource cleanup"
ansible.builtin.command:
cmd: pcs resource cleanup {{ __sap_ha_pacemaker_cluster_hanacontroller_resource_name
if (__sap_ha_pacemaker_cluster_saphanasr_angi_available
or (sap_ha_pacemaker_cluster_host_type | select('search', 'hana_scaleout') | length > 0))
else __sap_ha_pacemaker_cluster_hana_resource_name }}
changed_when: true

- name: "SAP HA Install Pacemaker - (SAPHana* clone) pcs resource refresh"
ansible.builtin.command:
cmd: pcs resource refresh {{ __sap_ha_pacemaker_cluster_hanacontroller_resource_clone_name
if (__sap_ha_pacemaker_cluster_saphanasr_angi_available
or (sap_ha_pacemaker_cluster_host_type | select('search', 'hana_scaleout') | length > 0))
else __sap_ha_pacemaker_cluster_hana_resource_clone_name }}
changed_when: true

# Sleep 30 is added to leave enough time for agents to load data from HANA.
# TODO: Add detection for Idle HANA, to ensure that Resource Agents loaded data.
- name: "SAP HA Install Pacemaker - Sleep wait for SAP HANA to become idle"
ansible.builtin.command:
cmd: sleep {{ 1 if ansible_check_mode else 30 }}
changed_when: false

- name: "SAP HA Install Pacemaker - (SAPHana* clone) Remove resource maintenance"
ansible.builtin.command:
cmd: pcs resource meta {{ __sap_ha_pacemaker_cluster_hanacontroller_resource_clone_name
if (__sap_ha_pacemaker_cluster_saphanasr_angi_available
or (sap_ha_pacemaker_cluster_host_type | select('search', 'hana_scaleout') | length > 0))
else __sap_ha_pacemaker_cluster_hana_resource_clone_name }} maintenance=
changed_when: true

This file was deleted.

15 changes: 15 additions & 0 deletions roles/sap_ha_pacemaker_cluster/tasks/RedHat/pre_steps_hana.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,18 @@
when:
- __sap_ha_pacemaker_cluster_saphanasr_angi_check is defined
- __sap_ha_pacemaker_cluster_saphanasr_angi_check.rc == 0


# Make sure that "Autostart" is disabled in the HANA profiles.
# The profile path is '/hana/shared/<SID>/profile/<SID>_HDB<instance>_<host>'.
- name: "SAP HA Prepare Pacemaker - Disable 'Autostart' in the HANA instance profiles"
ansible.builtin.replace:
path: "/hana/shared/{{ sap_ha_pacemaker_cluster_hana_sid }}/profile/{{ sap_ha_pacemaker_cluster_hana_sid }}_HDB{{ sap_ha_pacemaker_cluster_hana_instance_nr }}_{{ ansible_hostname }}"
backup: true
regexp: 'Autostart\s*=\s*1'
replace: 'Autostart = 0'
# Throttle and retry loop was added to combat NFS write lockups on Azure NFS
throttle: 1
retries: "{{ 1 if ansible_check_mode else 30 }}"
delay: "{{ 1 if ansible_check_mode else 10 }}"
ignore_errors: "{{ ansible_check_mode }}"
31 changes: 31 additions & 0 deletions roles/sap_ha_pacemaker_cluster/tasks/ascertain_sap_landscape.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,37 @@
when:
- sap_ha_pacemaker_cluster_host_type | select('search', 'hana_scaleup') | length > 0

# Majority-maker: The role does not handle the simultaneous setup of a quorum-only node.
- name: "SAP HA Prepare Pacemaker - Fail if the majority-maker node is in the play hosts list"
ansible.builtin.assert:
that:
- sap_ha_pacemaker_cluster_quorum_majority_maker_node not in ansible_play_hosts
fail_msg: |
This role does not handle the simultaneous setup of SAP hosts and a quorum-only
cluster node, also called 'majority-maker'.

Remove the majority-maker node from the target hosts of the playbook run.
when:
- sap_ha_pacemaker_cluster_quorum_majority_maker_node | length > 0

# Scale-out
- name: "SAP HA Prepare Pacemaker - Verify that for 'hana_scaleout' types a minimum of 4 HANA hosts is used"
ansible.builtin.assert:
that:
- ansible_play_hosts | difference(sap_ha_pacemaker_cluster_quorum_majority_maker_node | split(',')) | length > 3
fail_msg: |
There are less than 4 HANA target hosts available for a scale-out setup.

Play hosts:
{{ ansible_play_hosts | to_nice_yaml }}
Excluded majority-maker hosts: {{ sap_ha_pacemaker_cluster_quorum_majority_maker_node }}

Available hosts:
{{ ansible_play_hosts | difference(sap_ha_pacemaker_cluster_quorum_majority_maker_node | split(',')) | to_nice_yaml }}
when:
- sap_ha_pacemaker_cluster_host_type | select('search', 'hana_scaleout') | length > 0


# Host type rules:
# - there can only be 0 or 1 HANA type in the list
# - there can only be 0 or 1 NW (A)SCS/ERS type in the list
Expand Down
24 changes: 19 additions & 5 deletions roles/sap_ha_pacemaker_cluster/tasks/configure_srhook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
path: "{{ __sap_ha_pacemaker_cluster_hana_global_ini_path }}"
marker: ""
block: |
[ha_dr_provider_{{ srhook_item.provider }}]
[ha_dr_provider_{{ __hook_classname }}]
provider = {{ srhook_item.provider }}
path = {{ srhook_item.path }}
{% for option in srhook_item.options | d([]) -%}
Expand All @@ -56,8 +56,13 @@
loop_control:
loop_var: srhook_item
label: "{{ srhook_item.provider }}"
when: "('[ha_dr_provider_' + srhook_item.provider + ']') | lower
when: "('[ha_dr_provider_' + __hook_classname + ']') | lower
not in __sap_ha_pacemaker_cluster_global_ini_contents.stdout | lower"
vars:
__hook_classname:
"{{ srhook_item.provider | lower
if ansible_os_family == 'RedHat'
else srhook_item.provider }}"

# Separate task to create [trace] block so hooks can be appended to it
- name: "SAP HA Pacemaker srHook - Add [trace] block in global.ini"
Expand All @@ -74,14 +79,19 @@
ansible.builtin.lineinfile:
path: "{{ __sap_ha_pacemaker_cluster_hana_global_ini_path }}"
insertafter: "^\\[trace\\]"
line: "ha_dr_{{ srhook_item.provider }} = info"
line: "ha_dr_{{ __hook_classname }} = info"
loop: "{{ __sap_ha_pacemaker_cluster_hana_hooks }}"
loop_control:
loop_var: srhook_item
label: "{{ srhook_item.provider }}"
when:
- "('ha_dr_' + srhook_item.provider + ' = info') | lower
- "('ha_dr_' + __hook_classname + ' = info') | lower
not in __sap_ha_pacemaker_cluster_global_ini_contents.stdout | lower"
vars:
__hook_classname:
"{{ srhook_item.provider | lower
if ansible_os_family == 'RedHat'
else srhook_item.provider }}"

# jinja2 template contains logic to add extra entries if:
# TkOver hook is present or SAPHanaSR-angi is used.
Expand All @@ -92,5 +102,9 @@
mode: "0440"
owner: root
group: root
src: templates/sudofile_20-saphana.j2
src: templates/sudofile_20-saphana_{{ __sudofile_suffix }}.j2
validate: visudo -cf %s
vars:
__sudofile_suffix:
"{{ 'angi_' if __sap_ha_pacemaker_cluster_saphanasr_angi_available
else '' }}{{ ansible_os_family }}"
Loading