Skip to content

Commit dfce2e5

Browse files
nbttmbrgrainerleber
andcommitted
Add SAP System-level Function Support with Asynchronous Status Tracking (#1)
* Adding support for system wide functions * Nested Jinja makes the use of dynamic variables inside sapcontrol functions complicated. Falling back to declarative commands. * Adding steps to make sure that the system is started before attempting RKS * Enhance debug output for SAP Control parameters --------- Signed-off-by: Nicolas Bettembourg <[email protected]> Co-authored-by: Rainer Leber <[email protected]>
1 parent 58a17b4 commit dfce2e5

File tree

6 files changed

+122
-9
lines changed

6 files changed

+122
-9
lines changed

roles/sap_control/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This Ansible Role executes basic SAP administration tasks on Linux operating sys
77
This Ansible Role executes basic SAP administration tasks on Linux operating systems, including:
88
- Start/Stop/Restart of SAP HANA Database Server
99
- Start/Stop/Restart of SAP NetWeaver Application Server
10+
- Start/Stop/Restart/Update of SAP Netweaver System
1011
- Multiple Automatic discovery and Start/Stop/Restart of SAP HANA Database Server or SAP NetWeaver Application Server
1112

1213
## Example execution
@@ -62,7 +63,7 @@ Assumptions for executing this role include:
6263
| :--- |:--- | :--- |
6364
| `SID` | SAP system SID | no, only if you are targetting a single SAP system|
6465
| `nowait` | Default: `false` | no, use only when absolutely sure! This will bypass all waiting and ignore all necessary steps for a graceful stop / start|
65-
| `sap_control_function` | Function to execute:<br/><ul><li>`restart_all_sap`</li><li>`restart_all_nw`</li><li>`restart_all_hana`</li><li>`restart_sap_nw`</li><li>`restart_sap_hana`</li><li>`stop_all_sap`</li><li>`start_all_sap`</li><li>`stop_all_nw`</li><li>`start_all_nw`</li><li>`stop_all_hana`</li><li>`start_all_hana`</li><li>`stop_sap_nw`</li><li>`start_sap_nw`</li><li>`stop_sap_hana`</li><li>`start_sap_hana`</li></ul> | yes, only this is required to detect the Instance Number which is used with SAP Host Agent `sapcontrol` CLI<br/><br/><br/>_Note: Executions using `all` will automatically detect any System IDs and corresponding Instance Numbers_ |
66+
| `sap_control_function` | Function to execute:<br/><ul><li>`restart_all_sap`</li><li>`restart_all_nw`</li><li>`restart_all_hana`</li><li>`restart_sap_nw`</li><li>`restart_sap_hana`</li><li>`stop_all_sap`</li><li>`start_all_sap`</li><li>`stop_all_nw`</li><li>`start_all_nw`</li><li>`stop_all_hana`</li><li>`start_all_hana`</li><li>`stop_sap_nw`</li><li>`start_sap_nw`</li><li>`stop_sap_hana`</li><li>`start_sap_hana`</li><li>`restartsystem_all_nw`</li><li>`updatesystem_all_nw`</li><li>`startsystem_all_nw`</li><li>`stopsystem_all_nw`</li></ul> | yes, only this is required to detect the Instance Number which is used with SAP Host Agent `sapcontrol` CLI<br/><br/><br/>_Note: Executions using `all` will automatically detect any System IDs and corresponding Instance Numbers_ |
6667

6768
## Ansible Role workflow and structure
6869

roles/sap_control/defaults/main.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,41 @@ sap_control_name_header: "initial"
66
nowait: false
77
sap_control_start: "StartWait 180 2"
88
sap_control_stop: "StopWait 180 2"
9+
sap_control_startsystem: "StartSystem ALL 180" # function StartSystem waittimeout
10+
sap_control_stopsystem: "StopSystem ALL 180 480" # function StopSystem waittimeout softtimeout
11+
sap_control_restartsystem: "RestartSystem ALL 180 480" # function RestartSystem waittimeout softtimeout
12+
sap_control_updatesystem: "UpdateSystem 180 480 0" # function UpdateSystem waittimeout softtimeout force
13+
sap_control_waitforstopped: "WaitforStopped 180 2" # function WaitforStopped waittimeout delay
14+
sap_control_waitforstarted: "WaitforStarted 180 2" # function WaitforStarted waittimeout delay
15+
16+
# Parameters to handle async functions in sapcontrol_async.yml
17+
18+
sap_control_startsystem_waitforasync:
19+
test_function: "GetSystemInstanceList"
20+
retries: 60
21+
delay: 10
22+
until_false: 'GRAY\s*$|RED\s*$|YELLOW\s*$'
23+
until_true: 'GREEN\s*$'
24+
25+
sap_control_restartsystem_waitforasync:
26+
test_function: "GetSystemInstanceList"
27+
retries: 60
28+
delay: 10
29+
until_false: 'GRAY\s*$|RED\s*$|YELLOW\s*$'
30+
until_true: 'GREEN\s*$'
31+
32+
sap_control_stopsystem_waitforasync:
33+
test_function: "GetSystemInstanceList"
34+
retries: 60
35+
delay: 10
36+
until_false: 'GREEN\s*$|RED\s*$|YELLOW\s*$'
37+
until_true: 'GRAY\s*$'
38+
39+
sap_control_updatesystem_waitforasync:
40+
test_function: "GetSystemUpdateList"
41+
retries: 60
42+
delay: 10
43+
until_false: 'GRAY\s*$|RED\s*$|YELLOW\s*$|GREEN\s*$'
944

1045
# get_all_sap_sid_dir_nw: "/sapmnt"
1146
# get_all_sap_sid_dir_hana: "/hana/shared"
@@ -22,6 +57,10 @@ sap_control_instance_type_sortorder:
2257

2358
# Functions
2459
sap_control_functions_list:
60+
- restartsystem_all_nw
61+
- updatesystem_all_nw
62+
- startsystem_all_nw
63+
- stopsystem_all_nw
2564
- restart_all_sap
2665
- stop_all_sap
2766
- start_all_sap
@@ -38,7 +77,21 @@ sap_control_functions_list:
3877
- stop_sap_hana
3978
- start_sap_hana
4079

80+
4181
# Functions flow
82+
restartsystem_all_nw_list:
83+
- sap_control_function_current: "nw_restartsystem"
84+
85+
startsystem_all_nw_list:
86+
- sap_control_function_current: "nw_startsystem"
87+
88+
stopsystem_all_nw_list:
89+
- sap_control_function_current: "nw_stopsystem"
90+
91+
updatesystem_all_nw_list:
92+
- sap_control_function_current: "nw_startsystem"
93+
- sap_control_function_current: "nw_updatesystem"
94+
4295
restart_all_sap_list:
4396
- sap_control_function_current: "nw_stop"
4497
- sap_control_function_current: "hana_stop"

roles/sap_control/tasks/main.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,18 @@
104104
ansible.builtin.debug:
105105
msg:
106106
- "Starting sap_control with the following parameters: "
107-
- "{{ sap_control_function }}"
108-
- "{{ sap_control_start }}"
109-
- "{{ sap_control_stop }}"
110-
- "{{ nowait }}"
107+
- "Function: {{ sap_control_function }}"
108+
- "Standard commands:"
109+
- " Start: {{ sap_control_start }}"
110+
- " Stop: {{ sap_control_stop }}"
111+
- "System commands (if applicable):"
112+
- " StartSystem: {{ sap_control_startsystem }}"
113+
- " StopSystem: {{ sap_control_stopsystem }}"
114+
- " RestartSystem: {{ sap_control_restartsystem }}"
115+
- " UpdateSystem: {{ sap_control_updatesystem }}"
116+
- " WaitforStopped: {{ sap_control_waitforstopped }}"
117+
- " WaitforStarted: {{ sap_control_waitforstarted }}"
118+
- "NoWait: {{ nowait }}"
111119

112120
# Start SAP Control
113121
- name: SAP Control

roles/sap_control/tasks/prepare.yml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111

1212
- name: Prepare - Sort sap_facts_register by sap_control_instance_type_sortorder
1313
ansible.builtin.set_fact:
14-
sorted_sap_facts: "{{ (sorted_sap_facts | default([]) | unique) + ( __type_list | difference(sorted_sap_facts | default([]))) }}"
14+
sorted_sap_facts: "{{ (sorted_sap_facts | default([]) | unique) + (__type_list | difference(sorted_sap_facts | default([]))) }}"
1515
loop: "{{ sap_control_instance_type_sortorder | reverse if funct_type == 'stop' else sap_control_instance_type_sortorder }}"
1616
vars:
1717
__type_list: "{{ sap_facts_register.ansible_facts.sap | selectattr('TYPE', 'equalto', item) | list }}"
18-
when:
18+
when:
1919
- __type_list | length > 0
20-
20+
2121
- name: Prepare - SAP Control
2222
vars:
2323
sap_control_execute_sid: "{{ item.SID }}"
@@ -28,4 +28,18 @@
2828
loop: "{{ sorted_sap_facts }}"
2929
when:
3030
- item.InstanceType | lower == sap_type | lower
31-
...
31+
- not funct_type is match('.*system')
32+
33+
- name: Prepare - SAP Control (System wide functions)
34+
vars:
35+
sap_control_execute_sid: "{{ item.SID }}"
36+
sap_control_execute_type: "{{ item.Type }}"
37+
sap_control_execute_instance_nr: "{{ item.NR }}"
38+
sap_control_execute_instance_type: "{{ item.InstanceType }}"
39+
ansible.builtin.include_tasks: "sapcontrol.yml"
40+
loop: "{{ sorted_sap_facts }}"
41+
when:
42+
- item.InstanceType | lower == sap_type | lower
43+
- funct_type is match('.*system')
44+
- item.TYPE | lower == 'ascs'
45+
or item.TYPE | lower == 'scs'

roles/sap_control/tasks/sapcontrol.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
register: sapcontrol_status
2323
failed_when: "'FAIL' in sapcontrol_status.stdout"
2424

25+
# Include sapcontrol async tasks
26+
- name: SAP {{ sap_control_name_header }} - Include async tasks
27+
vars:
28+
async_function_dict: "{{ vars['sap_control_' + funct_type + '_waitforasync'] }}"
29+
ansible.builtin.include_tasks: sapcontrol_async.yml
30+
when:
31+
- funct_type is match('.*system')
32+
2533
# Cleanipc
2634
- name: SAP {{ sap_control_name_header }} - Cleanipc
2735
ansible.builtin.include_tasks: functions/cleanipc.yml
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
- name: Pause for 5 Seconds
3+
ansible.builtin.wait_for:
4+
timeout: 5
5+
6+
- name: SAP {{ sap_control_name_header }} - Checking if Async action is over by executing sapcontrol -nr {{ passed_sap_nr }} -function {{ async_function_dict.test_function }}
7+
ansible.builtin.shell: |
8+
source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ async_function_dict.test_function }}
9+
args:
10+
executable: /bin/bash
11+
become: true
12+
become_user: "{{ passed_sap_sid | lower }}adm"
13+
register: test_function_result
14+
# failed_when: "'FAIL' in test_function_result.stdout"
15+
retries: "{{ async_function_dict.retries | default(0) | int }}"
16+
delay: "{{ async_function_dict.delay | default(0) | int }}"
17+
until: >
18+
(async_function_dict.until_false is not defined
19+
or async_function_dict.until_false is defined and not test_function_result.stdout | regex_search(async_function_dict.until_false, multiline=True)) and
20+
(async_function_dict.until_true is not defined or
21+
async_function_dict.until_true is defined and test_function_result.stdout | regex_search(async_function_dict.until_true, multiline=True))
22+
failed_when: false
23+
24+
- name: Debug stdout
25+
ansible.builtin.debug:
26+
msg: |
27+
Async function {{ async_function_dict.test_function }} for SAP SID {{ passed_sap_sid }}
28+
is done with result:
29+
{{ test_function_result.stdout }}

0 commit comments

Comments
 (0)