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 c1c65f3..558e91e 100644
--- a/roles/sap_control/defaults/main.yml
+++ b/roles/sap_control/defaults/main.yml
@@ -6,6 +6,41 @@ 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
+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
+
+# Parameters to handle async functions in sapcontrol_async.yml
+
+sap_control_startsystem_waitforasync:
+ test_function: "GetSystemInstanceList"
+ retries: 60
+ delay: 10
+ until_false: 'GRAY\s*$|RED\s*$|YELLOW\s*$'
+ until_true: 'GREEN\s*$'
+
+sap_control_restartsystem_waitforasync:
+ test_function: "GetSystemInstanceList"
+ retries: 60
+ delay: 10
+ until_false: 'GRAY\s*$|RED\s*$|YELLOW\s*$'
+ until_true: 'GREEN\s*$'
+
+sap_control_stopsystem_waitforasync:
+ test_function: "GetSystemInstanceList"
+ retries: 60
+ delay: 10
+ until_false: 'GREEN\s*$|RED\s*$|YELLOW\s*$'
+ until_true: 'GRAY\s*$'
+
+sap_control_updatesystem_waitforasync:
+ test_function: "GetSystemUpdateList"
+ retries: 60
+ delay: 10
+ 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"
@@ -13,6 +48,10 @@ sap_control_stop: "StopWait 180 2"
# Functions
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
@@ -29,7 +68,21 @@ sap_control_functions_list:
- stop_sap_hana
- start_sap_hana
+
# Functions flow
+restartsystem_all_nw_list:
+ - sap_control_function_current: "nw_restartsystem"
+
+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"
+
restart_all_sap_list:
- sap_control_function_current: "nw_stop"
- sap_control_function_current: "hana_stop"
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
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..aa181a2 100644
--- a/roles/sap_control/tasks/sapcontrol.yml
+++ b/roles/sap_control/tasks/sapcontrol.yml
@@ -22,6 +22,14 @@
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
diff --git a/roles/sap_control/tasks/sapcontrol_async.yml b/roles/sap_control/tasks/sapcontrol_async.yml
new file mode 100644
index 0000000..ebe65bc
--- /dev/null
+++ b/roles/sap_control/tasks/sapcontrol_async.yml
@@ -0,0 +1,29 @@
+---
+- 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 }}
+ args:
+ executable: /bin/bash
+ become: true
+ become_user: "{{ passed_sap_sid | lower }}adm"
+ 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_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
+ ansible.builtin.debug:
+ msg: |
+ Async function {{ async_function_dict.test_function }} for SAP SID {{ passed_sap_sid }}
+ is done with result:
+ {{ test_function_result.stdout }}