From 4bd499ecc35a4131a53f5089267b8396dd0adc88 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Thu, 17 Jul 2025 10:47:23 +0200 Subject: [PATCH 01/17] Adding support for system wide functions Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 24 ++++++++++++++++++++++++ roles/sap_control/tasks/prepare.yml | 17 ++++++++++++++++- roles/sap_control/tasks/sapcontrol.yml | 5 +++-- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index c1c65f3..dab403a 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -3,16 +3,30 @@ sap_sid: "initial" sap_control_function: "initial" sap_control_name_header: "initial" +sap_control_system_scope: "ALL" +sap_control_system_waittimeout: 180 +sap_control_system_softtimeout: 480 +sap_control_system_force: 0 + nowait: false sap_control_start: "StartWait 180 2" sap_control_stop: "StopWait 180 2" +sap_control_startsystem: "StartSystem {{ sap_control_system_scope }} {{ sap_control_system_waittimeout }}" +sap_control_stopsystem: "StopSystem {{ sap_control_system_scope }} {{ sap_control_system_waittimeout }} {{ sap_control_system_softtimeout }}" +sap_control_restartsystem: "RestartSystem {{ sap_control_system_scope }} {{ sap_control_system_waittimeout }} {{ sap_control_system_softtimeout }} {{ sap_control_system_runlevel }}" +sap_control_updatesystem: "UpdateSystem {{ sap_control_system_waittimeout }} {{ sap_control_system_softtimeout }} {{ sap_control_system_force }}" +sap_control_waitforstopped: "WaitforStopped {{ sap_control_system_waittimeout }} 2" +sap_control_waitforstarted: "WaitforStarted {{ sap_control_system_waittimeout }} 2" + # get_all_sap_sid_dir_nw: "/sapmnt" # get_all_sap_sid_dir_hana: "/hana/shared" # Functions sap_control_functions_list: + - restartsystem_all_nw + - updatesystem_all_nw - restart_all_sap - stop_all_sap - start_all_sap @@ -30,6 +44,16 @@ sap_control_functions_list: - start_sap_hana # Functions flow +restartsystem_all_nw_list: + - sap_control_function_current: "nw_stopsystem" + - sap_control_function_current: "nw_waitforstopped" + - sap_control_function_current: "nw_startsystem" + - sap_control_function_current: "nw_waitforstarted" + +updatesystem_all_nw_list: + - sap_control_function_current: "nw_updatesystem" + - sap_control_function_current: "nw_waitforstarted" + restart_all_sap_list: - sap_control_function_current: "nw_stop" - sap_control_function_current: "hana_stop" diff --git a/roles/sap_control/tasks/prepare.yml b/roles/sap_control/tasks/prepare.yml index a15777f..394c398 100644 --- a/roles/sap_control/tasks/prepare.yml +++ b/roles/sap_control/tasks/prepare.yml @@ -9,7 +9,7 @@ ansible.builtin.set_fact: sap_control_name_header: "{{ sap_type | upper }} {{ funct_type | capitalize }}" -- name: SAP Control +- name: SAP Control (not System wide functions) vars: sap_control_execute_sid: "{{ item.SID }}" sap_control_execute_type: "{{ item.Type }}" @@ -19,3 +19,18 @@ loop: "{{ sap_facts_register.ansible_facts.sap }}" when: - "item.InstanceType | lower == sap_type | lower" + - "not funct_type is match('.*system')" + +- name: SAP Control (System wide functions) + vars: + sap_control_execute_sid: "{{ item.SID }}" + sap_control_execute_type: "{{ item.Type }}" + sap_control_execute_instance_nr: "{{ item.NR }}" + sap_control_execute_instance_type: "{{ item.InstanceType }}" + ansible.builtin.include_tasks: "sapcontrol.yml" + loop: "{{ sap_facts_register.ansible_facts.sap }}" + when: + - "item.InstanceType | lower == sap_type | lower" + - "funct_type is match('.*system')" + - "item.TYPE | lower == 'ascs' + or item.TYPE | lower == 'scs'" diff --git a/roles/sap_control/tasks/sapcontrol.yml b/roles/sap_control/tasks/sapcontrol.yml index af3cda8..6df4894 100644 --- a/roles/sap_control/tasks/sapcontrol.yml +++ b/roles/sap_control/tasks/sapcontrol.yml @@ -12,9 +12,9 @@ ansible.builtin.include_tasks: functions/sapstartsrv.yml # Execute sapcontrol -- name: SAP {{ sap_control_name_header }} - Executing sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] }} +- name: SAP {{ sap_control_name_header }} - Executing sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] | regex_replace('\\{\\{([^\\}]+)\\}\\}', '\\1') | template }} ansible.builtin.shell: | - source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] }} + source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] | regex_replace('\\{\\{([^\\}]+)\\}\\}', '\\1') | template }} args: executable: /bin/bash become: true @@ -28,3 +28,4 @@ when: - "'nw' in sap_type" - "'stop' in funct_type" + - "not funct_type is match('.*system')" From 371f2996c160161f28f30917dfa0c45db6c61255 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Thu, 17 Jul 2025 11:00:03 +0200 Subject: [PATCH 02/17] Nested Jinja makes the use of dynamic variables inside sapcontrol functions complicated. Falling back to declarative commands. Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 17 ++++++----------- roles/sap_control/tasks/sapcontrol.yml | 4 ++-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index dab403a..500c213 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -3,21 +3,16 @@ sap_sid: "initial" sap_control_function: "initial" sap_control_name_header: "initial" -sap_control_system_scope: "ALL" -sap_control_system_waittimeout: 180 -sap_control_system_softtimeout: 480 -sap_control_system_force: 0 - nowait: false sap_control_start: "StartWait 180 2" sap_control_stop: "StopWait 180 2" -sap_control_startsystem: "StartSystem {{ sap_control_system_scope }} {{ sap_control_system_waittimeout }}" -sap_control_stopsystem: "StopSystem {{ sap_control_system_scope }} {{ sap_control_system_waittimeout }} {{ sap_control_system_softtimeout }}" -sap_control_restartsystem: "RestartSystem {{ sap_control_system_scope }} {{ sap_control_system_waittimeout }} {{ sap_control_system_softtimeout }} {{ sap_control_system_runlevel }}" -sap_control_updatesystem: "UpdateSystem {{ sap_control_system_waittimeout }} {{ sap_control_system_softtimeout }} {{ sap_control_system_force }}" -sap_control_waitforstopped: "WaitforStopped {{ sap_control_system_waittimeout }} 2" -sap_control_waitforstarted: "WaitforStarted {{ sap_control_system_waittimeout }} 2" +sap_control_startsystem: "StartSystem ALL 180" # function StartSystem waittimeout +sap_control_stopsystem: "StopSystem ALL 180 480" # function StopSystem waittimeout softtimeout +sap_control_restartsystem: "RestartSystem ALL 180 480" # function RestartSystem waittimeout softtimeout +sap_control_updatesystem: "UpdateSystem 180 480 0" # function UpdateSystem waittimeout softtimeout force +sap_control_waitforstopped: "WaitforStopped 180 2" # function WaitforStopped waittimeout delay +sap_control_waitforstarted: "WaitforStarted 180 2" # function WaitforStarted waittimeout delay # get_all_sap_sid_dir_nw: "/sapmnt" # get_all_sap_sid_dir_hana: "/hana/shared" diff --git a/roles/sap_control/tasks/sapcontrol.yml b/roles/sap_control/tasks/sapcontrol.yml index 6df4894..97e6611 100644 --- a/roles/sap_control/tasks/sapcontrol.yml +++ b/roles/sap_control/tasks/sapcontrol.yml @@ -12,9 +12,9 @@ ansible.builtin.include_tasks: functions/sapstartsrv.yml # Execute sapcontrol -- name: SAP {{ sap_control_name_header }} - Executing sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] | regex_replace('\\{\\{([^\\}]+)\\}\\}', '\\1') | template }} +- name: SAP {{ sap_control_name_header }} - Executing sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] }} ansible.builtin.shell: | - source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] | regex_replace('\\{\\{([^\\}]+)\\}\\}', '\\1') | template }} + source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ vars['sap_control_' + funct_type] }} args: executable: /bin/bash become: true From 696973b65fc7652bd8ec4b3f70aa00cfb823b6c0 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Thu, 17 Jul 2025 16:04:40 +0200 Subject: [PATCH 03/17] Adding steps to make sure that the system is started before attempting RKS Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index 500c213..510fb90 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -46,6 +46,8 @@ restartsystem_all_nw_list: - sap_control_function_current: "nw_waitforstarted" updatesystem_all_nw_list: + - sap_control_function_current: "nw_startsystem" + - sap_control_function_current: "nw_waitforstarted" - sap_control_function_current: "nw_updatesystem" - sap_control_function_current: "nw_waitforstarted" From 8ac635bab4e890375a9dd6874c550b73820d3ead Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Thu, 17 Jul 2025 17:18:42 +0200 Subject: [PATCH 04/17] Enhance debug output for SAP Control parameters Signed-off-by: Nicolas Bettembourg --- roles/sap_control/tasks/main.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/roles/sap_control/tasks/main.yml b/roles/sap_control/tasks/main.yml index 880eec9..6d8f8fd 100644 --- a/roles/sap_control/tasks/main.yml +++ b/roles/sap_control/tasks/main.yml @@ -104,10 +104,18 @@ ansible.builtin.debug: msg: - "Starting sap_control with the following parameters: " - - "{{ sap_control_function }}" - - "{{ sap_control_start }}" - - "{{ sap_control_stop }}" - - "{{ nowait }}" + - "Function: {{ sap_control_function }}" + - "Standard commands:" + - " Start: {{ sap_control_start }}" + - " Stop: {{ sap_control_stop }}" + - "System commands (if applicable):" + - " StartSystem: {{ sap_control_startsystem }}" + - " StopSystem: {{ sap_control_stopsystem }}" + - " RestartSystem: {{ sap_control_restartsystem }}" + - " UpdateSystem: {{ sap_control_updatesystem }}" + - " WaitforStopped: {{ sap_control_waitforstopped }}" + - " WaitforStarted: {{ sap_control_waitforstarted }}" + - "NoWait: {{ nowait }}" # Start SAP Control - name: SAP Control From 96da78a0382fb1f15d70ffac6ecbd5453ac09955 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 10:23:17 +0200 Subject: [PATCH 05/17] Commit for testing purpose Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 20 ++++++++++++++++ roles/sap_control/tasks/sapcontrol.yml | 9 ++++++- roles/sap_control/tasks/sapcontrol_async.yml | 25 ++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 roles/sap_control/tasks/sapcontrol_async.yml diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index 510fb90..9d1dd18 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -14,6 +14,26 @@ sap_control_updatesystem: "UpdateSystem 180 480 0" # function UpdateSystem wait sap_control_waitforstopped: "WaitforStopped 180 2" # function WaitforStopped waittimeout delay sap_control_waitforstarted: "WaitforStarted 180 2" # function WaitforStarted waittimeout delay +sap_control_startsystem_waitforasync: + test_function: "{{ sap_control_waitforstarted }}" + +sap_control_stopsystem_waitforasync: + test_function: "{{ sap_control_waitforstopped }}" + +sap_control_restartsystem_waitforasync: + test_function: "GetSystemInstanceList" + retries: 60 + delay: 10 + until: + - test_function_result.stdout not in ['YELLOW', 'RED', 'GREY'] + +sap_control_updatesystem_waitforasync: + test_function: "GetSystemUpdateList" + retries: 60 + delay: 10 + until: + - test_function_result.stdout not in ['YELLOW', 'RED', 'GREY'] + # get_all_sap_sid_dir_nw: "/sapmnt" # get_all_sap_sid_dir_hana: "/hana/shared" diff --git a/roles/sap_control/tasks/sapcontrol.yml b/roles/sap_control/tasks/sapcontrol.yml index 97e6611..aa181a2 100644 --- a/roles/sap_control/tasks/sapcontrol.yml +++ b/roles/sap_control/tasks/sapcontrol.yml @@ -22,10 +22,17 @@ register: sapcontrol_status failed_when: "'FAIL' in sapcontrol_status.stdout" +# Include sapcontrol async tasks +- name: SAP {{ sap_control_name_header }} - Include async tasks + vars: + async_function_dict: "{{ vars['sap_control_' + funct_type + '_waitforasync'] }}" + ansible.builtin.include_tasks: sapcontrol_async.yml + when: + - funct_type is match('.*system') + # Cleanipc - name: SAP {{ sap_control_name_header }} - Cleanipc ansible.builtin.include_tasks: functions/cleanipc.yml when: - "'nw' in sap_type" - "'stop' in funct_type" - - "not funct_type is match('.*system')" diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml new file mode 100644 index 0000000..a916c1d --- /dev/null +++ b/roles/sap_control/tasks/sapcontrol_async.yml @@ -0,0 +1,25 @@ +--- +- 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 }} + ansible.builtin.shell: | + source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ async_function_dict.test_function }} + args: + executable: /bin/bash + become: true + become_user: "{{ passed_sap_sid | lower }}adm" + register: sapcontrol_async_status +# failed_when: "'FAIL' in sapcontrol_async_status.stdout" + retries: "{{ async_function_dict.retries | default(0) | int }}" + delay: "{{ async_function_dict.delay | default(0) | int }}" + until: "{{ async_function_dict.until | default([]) }}" + failed_when: false + +- name: Debug stdout + ansible.builtin.debug: + msg: | + Async function {{ async_function_dict.test_function }} for SAP SID {{ passed_sap_sid }} + is done with result: + {{ sapcontrol_async_status.stdout }} + +- name: Fail + ansible.builtin.fail: + msg: "FAIL" From a202456130f9a8b4ecfd557135915302d84dfec4 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 10:49:27 +0200 Subject: [PATCH 06/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 33 +++++++++++++++++++---------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index 9d1dd18..74a1db0 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -15,24 +15,35 @@ sap_control_waitforstopped: "WaitforStopped 180 2" # function WaitforStopped wa sap_control_waitforstarted: "WaitforStarted 180 2" # function WaitforStarted waittimeout delay sap_control_startsystem_waitforasync: - test_function: "{{ sap_control_waitforstarted }}" + test_function: "GetSystemInstanceList" + retries: 60 + delay: 10 + until: + - not (test_function_result.stdout | regex_search('GRAY\s*$', multiline=True) or + test_function_result.stdout | regex_search('RED\s*$', multiline=True) or + test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True)) + - test_function_result.stdout | regex_search('GREEN\s*$', multiline=True) -sap_control_stopsystem_waitforasync: - test_function: "{{ sap_control_waitforstopped }}" +sap_control_restartsystem_waitforasync: "{{ sap_control_startsystem_waitforasync }}" -sap_control_restartsystem_waitforasync: +sap_control_stopsystem_waitforasync: test_function: "GetSystemInstanceList" retries: 60 delay: 10 until: - - test_function_result.stdout not in ['YELLOW', 'RED', 'GREY'] + - not (test_function_result.stdout | regex_search('GREEN\s*$', multiline=True) or + test_function_result.stdout | regex_search('RED\s*$', multiline=True) or + test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True)) + - test_function_result.stdout | regex_search('GRAY\s*$', multiline=True) sap_control_updatesystem_waitforasync: test_function: "GetSystemUpdateList" retries: 60 delay: 10 until: - - test_function_result.stdout not in ['YELLOW', 'RED', 'GREY'] + - not (test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True) or + test_function_result.stdout | regex_search('RED\s*$', multiline=True) or + test_function_result.stdout | regex_search('GREY\s*$', multiline=True)) # get_all_sap_sid_dir_nw: "/sapmnt" # get_all_sap_sid_dir_hana: "/hana/shared" @@ -42,6 +53,7 @@ sap_control_updatesystem_waitforasync: sap_control_functions_list: - restartsystem_all_nw - updatesystem_all_nw + - startsystem_all_nw - restart_all_sap - stop_all_sap - start_all_sap @@ -58,18 +70,17 @@ sap_control_functions_list: - stop_sap_hana - start_sap_hana + # Functions flow restartsystem_all_nw_list: - - sap_control_function_current: "nw_stopsystem" - - sap_control_function_current: "nw_waitforstopped" + - sap_control_function_current: "nw_restartsystem" + +startsystem_all_nw_list: - sap_control_function_current: "nw_startsystem" - - sap_control_function_current: "nw_waitforstarted" updatesystem_all_nw_list: - sap_control_function_current: "nw_startsystem" - - sap_control_function_current: "nw_waitforstarted" - sap_control_function_current: "nw_updatesystem" - - sap_control_function_current: "nw_waitforstarted" restart_all_sap_list: - sap_control_function_current: "nw_stop" From 52cf4fd6293dc772bb1ca9d236cc23104537cde5 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 10:57:22 +0200 Subject: [PATCH 07/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/tasks/sapcontrol_async.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml index a916c1d..5bf256d 100644 --- a/roles/sap_control/tasks/sapcontrol_async.yml +++ b/roles/sap_control/tasks/sapcontrol_async.yml @@ -6,11 +6,12 @@ executable: /bin/bash become: true become_user: "{{ passed_sap_sid | lower }}adm" - register: sapcontrol_async_status -# failed_when: "'FAIL' in sapcontrol_async_status.stdout" + register: test_function_result +# failed_when: "'FAIL' in test_function_result.stdout" retries: "{{ async_function_dict.retries | default(0) | int }}" delay: "{{ async_function_dict.delay | default(0) | int }}" until: "{{ async_function_dict.until | default([]) }}" + # until: "{% for condition in async_function_dict.until_conditions %}{{ condition }}{% if not loop.last %} and {% endif %}{% endfor %}" failed_when: false - name: Debug stdout @@ -18,7 +19,7 @@ msg: | Async function {{ async_function_dict.test_function }} for SAP SID {{ passed_sap_sid }} is done with result: - {{ sapcontrol_async_status.stdout }} + {{ test_function_result.stdout }} - name: Fail ansible.builtin.fail: From 452249be847e8ba510a682b5bf1b91d5adef17c6 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 11:03:01 +0200 Subject: [PATCH 08/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index 74a1db0..a308a98 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -24,7 +24,15 @@ sap_control_startsystem_waitforasync: test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True)) - test_function_result.stdout | regex_search('GREEN\s*$', multiline=True) -sap_control_restartsystem_waitforasync: "{{ sap_control_startsystem_waitforasync }}" +sap_control_restartsystem_waitforasync: + test_function: "GetSystemInstanceList" + retries: 60 + delay: 10 + until: + - not (test_function_result.stdout | regex_search('GRAY\s*$', multiline=True) or + test_function_result.stdout | regex_search('RED\s*$', multiline=True) or + test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True)) + - test_function_result.stdout | regex_search('GREEN\s*$', multiline=True) sap_control_stopsystem_waitforasync: test_function: "GetSystemInstanceList" From 74f3a97b89784b6421166e0b8c869d546cf934ac Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 11:04:19 +0200 Subject: [PATCH 09/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/tasks/sapcontrol_async.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml index 5bf256d..27966dc 100644 --- a/roles/sap_control/tasks/sapcontrol_async.yml +++ b/roles/sap_control/tasks/sapcontrol_async.yml @@ -10,7 +10,7 @@ # failed_when: "'FAIL' in test_function_result.stdout" retries: "{{ async_function_dict.retries | default(0) | int }}" delay: "{{ async_function_dict.delay | default(0) | int }}" - until: "{{ async_function_dict.until | default([]) }}" + until: async_function_dict.until | default([]) # until: "{% for condition in async_function_dict.until_conditions %}{{ condition }}{% if not loop.last %} and {% endif %}{% endfor %}" failed_when: false From ac4c126e456dc23fdb4b40aacd64f82789211d8d Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 11:26:37 +0200 Subject: [PATCH 10/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/tasks/sapcontrol_async.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml index 27966dc..e4f83d3 100644 --- a/roles/sap_control/tasks/sapcontrol_async.yml +++ b/roles/sap_control/tasks/sapcontrol_async.yml @@ -1,4 +1,8 @@ --- +- name: Pause for 5 Seconds + ansible.builtin.wait_for: + timeout: 5 + - 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 }} ansible.builtin.shell: | source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ async_function_dict.test_function }} From 005d04f96a8821156ccd68aa126eb07996ac279e Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 11:31:48 +0200 Subject: [PATCH 11/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/tasks/sapcontrol_async.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml index e4f83d3..eaa7a50 100644 --- a/roles/sap_control/tasks/sapcontrol_async.yml +++ b/roles/sap_control/tasks/sapcontrol_async.yml @@ -3,6 +3,15 @@ ansible.builtin.wait_for: timeout: 5 +- name: Debug values + ansible.builtin.debug: + msg: | + Async function {{ async_function_dict.test_function }} for SAP SID {{ passed_sap_sid }} + with retries: {{ async_function_dict.retries | default(0) | int }} + and delay: {{ async_function_dict.delay | default(0) | int }} + and until conditions: {{ async_function_dict.until | default([]) }} + is being executed. + - 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 }} ansible.builtin.shell: | source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ async_function_dict.test_function }} From 84d32adae4cd544eff3cdb13bcfe9e48a5446198 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 11:59:13 +0200 Subject: [PATCH 12/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 26 ++++++-------------- roles/sap_control/tasks/sapcontrol_async.yml | 5 ++-- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index a308a98..ac6a398 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -18,40 +18,28 @@ sap_control_startsystem_waitforasync: test_function: "GetSystemInstanceList" retries: 60 delay: 10 - until: - - not (test_function_result.stdout | regex_search('GRAY\s*$', multiline=True) or - test_function_result.stdout | regex_search('RED\s*$', multiline=True) or - test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True)) - - test_function_result.stdout | regex_search('GREEN\s*$', multiline=True) + until_false: 'GRAY\s*$|RED\s*$|YELLOW\s*$' + until_true: 'GREEN\s*$' sap_control_restartsystem_waitforasync: test_function: "GetSystemInstanceList" retries: 60 delay: 10 - until: - - not (test_function_result.stdout | regex_search('GRAY\s*$', multiline=True) or - test_function_result.stdout | regex_search('RED\s*$', multiline=True) or - test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True)) - - test_function_result.stdout | regex_search('GREEN\s*$', multiline=True) + until_false: 'GRAY\s*$|RED\s*$|YELLOW\s*$' + until_true: 'GREEN\s*$' sap_control_stopsystem_waitforasync: test_function: "GetSystemInstanceList" retries: 60 delay: 10 - until: - - not (test_function_result.stdout | regex_search('GREEN\s*$', multiline=True) or - test_function_result.stdout | regex_search('RED\s*$', multiline=True) or - test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True)) - - test_function_result.stdout | regex_search('GRAY\s*$', multiline=True) + until_false: 'GREEN\s*$|RED\s*$|YELLOW\s*$' + until_true: 'GRAY\s*$' sap_control_updatesystem_waitforasync: test_function: "GetSystemUpdateList" retries: 60 delay: 10 - until: - - not (test_function_result.stdout | regex_search('YELLOW\s*$', multiline=True) or - test_function_result.stdout | regex_search('RED\s*$', multiline=True) or - test_function_result.stdout | regex_search('GREY\s*$', multiline=True)) + until_false: 'GRAY\s*$|RED\s*$|YELLOW\s*$|GREEN\s*$' # get_all_sap_sid_dir_nw: "/sapmnt" # get_all_sap_sid_dir_hana: "/hana/shared" diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml index eaa7a50..a406bce 100644 --- a/roles/sap_control/tasks/sapcontrol_async.yml +++ b/roles/sap_control/tasks/sapcontrol_async.yml @@ -23,8 +23,9 @@ # failed_when: "'FAIL' in test_function_result.stdout" retries: "{{ async_function_dict.retries | default(0) | int }}" delay: "{{ async_function_dict.delay | default(0) | int }}" - until: async_function_dict.until | default([]) - # until: "{% for condition in async_function_dict.until_conditions %}{{ condition }}{% if not loop.last %} and {% endif %}{% endfor %}" + until: > + (async_function_dict.until_false is defined and not test_function_result.stdout | regex_search(async_function_dict.until_false, multiline=True)) and + (async_function_dict.until_true is defined and test_function_result.stdout | regex_search(async_function_dict.until_true, multiline=True)) failed_when: false - name: Debug stdout From af52a3563e265aec84c3ce23d97a0b29d7e14e34 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 12:01:30 +0200 Subject: [PATCH 13/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index ac6a398..9f9a60c 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -50,6 +50,7 @@ sap_control_functions_list: - restartsystem_all_nw - updatesystem_all_nw - startsystem_all_nw + - stopsystem_all_nw - restart_all_sap - stop_all_sap - start_all_sap From 38aa8f91dd1c00382c2ea2809a978bdff65862c7 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 15:00:26 +0200 Subject: [PATCH 14/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index 9f9a60c..44bf8b2 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -6,7 +6,6 @@ sap_control_name_header: "initial" nowait: false sap_control_start: "StartWait 180 2" sap_control_stop: "StopWait 180 2" - sap_control_startsystem: "StartSystem ALL 180" # function StartSystem waittimeout sap_control_stopsystem: "StopSystem ALL 180 480" # function StopSystem waittimeout softtimeout sap_control_restartsystem: "RestartSystem ALL 180 480" # function RestartSystem waittimeout softtimeout @@ -14,6 +13,8 @@ sap_control_updatesystem: "UpdateSystem 180 480 0" # function UpdateSystem wait sap_control_waitforstopped: "WaitforStopped 180 2" # function WaitforStopped waittimeout delay sap_control_waitforstarted: "WaitforStarted 180 2" # function WaitforStarted waittimeout delay +# Parameters to handle async functions + sap_control_startsystem_waitforasync: test_function: "GetSystemInstanceList" retries: 60 From c1c9243802b70406a189f49faf1ab18da104ded5 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 16:16:41 +0200 Subject: [PATCH 15/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/defaults/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index 44bf8b2..f67d95f 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -76,6 +76,9 @@ restartsystem_all_nw_list: startsystem_all_nw_list: - sap_control_function_current: "nw_startsystem" +stopsystem_all_nw_list: + - sap_control_function_current: "nw_stopsystem" + updatesystem_all_nw_list: - sap_control_function_current: "nw_startsystem" - sap_control_function_current: "nw_updatesystem" From 0c1bc0cc7cd88de410a502a8d2a6a4fc3bd4f81b Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 16:16:44 +0200 Subject: [PATCH 16/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/README.md | 3 ++- roles/sap_control/defaults/main.yml | 2 +- roles/sap_control/tasks/sapcontrol_async.yml | 15 ++++----------- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/roles/sap_control/README.md b/roles/sap_control/README.md index 0409cef..8e513fb 100644 --- a/roles/sap_control/README.md +++ b/roles/sap_control/README.md @@ -7,6 +7,7 @@ This Ansible Role executes basic SAP administration tasks on Linux operating sys This Ansible Role executes basic SAP administration tasks on Linux operating systems, including: - Start/Stop/Restart of SAP HANA Database Server - Start/Stop/Restart of SAP NetWeaver Application Server +- Start/Stop/Restart/Update of SAP Netweaver System - Multiple Automatic discovery and Start/Stop/Restart of SAP HANA Database Server or SAP NetWeaver Application Server ## Example execution @@ -62,7 +63,7 @@ Assumptions for executing this role include: | :--- |:--- | :--- | | `SID` | SAP system SID | no, only if you are targetting a single SAP system| | `nowait` | Default: `false` | no, use only when absolutely sure! This will bypass all waiting and ignore all necessary steps for a graceful stop / start| -| `sap_control_function` | Function to execute:
  • `restart_all_sap`
  • `restart_all_nw`
  • `restart_all_hana`
  • `restart_sap_nw`
  • `restart_sap_hana`
  • `stop_all_sap`
  • `start_all_sap`
  • `stop_all_nw`
  • `start_all_nw`
  • `stop_all_hana`
  • `start_all_hana`
  • `stop_sap_nw`
  • `start_sap_nw`
  • `stop_sap_hana`
  • `start_sap_hana`
| yes, only this is required to detect the Instance Number which is used with SAP Host Agent `sapcontrol` CLI


_Note: Executions using `all` will automatically detect any System IDs and corresponding Instance Numbers_ | +| `sap_control_function` | Function to execute:
  • `restart_all_sap`
  • `restart_all_nw`
  • `restart_all_hana`
  • `restart_sap_nw`
  • `restart_sap_hana`
  • `stop_all_sap`
  • `start_all_sap`
  • `stop_all_nw`
  • `start_all_nw`
  • `stop_all_hana`
  • `start_all_hana`
  • `stop_sap_nw`
  • `start_sap_nw`
  • `stop_sap_hana`
  • `start_sap_hana`
  • `restartsystem_all_nw`
  • `updatesystem_all_nw`
  • `startsystem_all_nw`
  • `stopsystem_all_nw`
| yes, only this is required to detect the Instance Number which is used with SAP Host Agent `sapcontrol` CLI


_Note: Executions using `all` will automatically detect any System IDs and corresponding Instance Numbers_ | ## Ansible Role workflow and structure diff --git a/roles/sap_control/defaults/main.yml b/roles/sap_control/defaults/main.yml index f67d95f..558e91e 100644 --- a/roles/sap_control/defaults/main.yml +++ b/roles/sap_control/defaults/main.yml @@ -13,7 +13,7 @@ sap_control_updatesystem: "UpdateSystem 180 480 0" # function UpdateSystem wait sap_control_waitforstopped: "WaitforStopped 180 2" # function WaitforStopped waittimeout delay sap_control_waitforstarted: "WaitforStarted 180 2" # function WaitforStarted waittimeout delay -# Parameters to handle async functions +# Parameters to handle async functions in sapcontrol_async.yml sap_control_startsystem_waitforasync: test_function: "GetSystemInstanceList" diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml index a406bce..8940fe8 100644 --- a/roles/sap_control/tasks/sapcontrol_async.yml +++ b/roles/sap_control/tasks/sapcontrol_async.yml @@ -3,15 +3,6 @@ ansible.builtin.wait_for: timeout: 5 -- name: Debug values - ansible.builtin.debug: - msg: | - Async function {{ async_function_dict.test_function }} for SAP SID {{ passed_sap_sid }} - with retries: {{ async_function_dict.retries | default(0) | int }} - and delay: {{ async_function_dict.delay | default(0) | int }} - and until conditions: {{ async_function_dict.until | default([]) }} - is being executed. - - 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 }} ansible.builtin.shell: | source ~/.profile && sapcontrol -nr {{ passed_sap_nr }} -function {{ async_function_dict.test_function }} @@ -24,8 +15,10 @@ retries: "{{ async_function_dict.retries | default(0) | int }}" delay: "{{ async_function_dict.delay | default(0) | int }}" until: > - (async_function_dict.until_false is defined and not test_function_result.stdout | regex_search(async_function_dict.until_false, multiline=True)) and - (async_function_dict.until_true is defined and test_function_result.stdout | regex_search(async_function_dict.until_true, multiline=True)) + (async_function_dict.until_false is not defined + or async_function_dict.until_false is defined and not test_function_result.stdout | regex_search(async_function_dict.until_false, multiline=True)) and + (async_function_dict.until_true is not defined or + async_function_dict.until_true is defined and test_function_result.stdout | regex_search(async_function_dict.until_true, multiline=True)) failed_when: false - name: Debug stdout From e4317cf46f65828f057a458fc6c96690d5c46bd9 Mon Sep 17 00:00:00 2001 From: Nicolas Bettembourg Date: Fri, 18 Jul 2025 16:20:20 +0200 Subject: [PATCH 17/17] Signed-off-by: Nicolas Bettembourg --- roles/sap_control/tasks/sapcontrol_async.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml index 8940fe8..ebe65bc 100644 --- a/roles/sap_control/tasks/sapcontrol_async.yml +++ b/roles/sap_control/tasks/sapcontrol_async.yml @@ -27,7 +27,3 @@ Async function {{ async_function_dict.test_function }} for SAP SID {{ passed_sap_sid }} is done with result: {{ test_function_result.stdout }} - -- name: Fail - ansible.builtin.fail: - msg: "FAIL"